logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

jednoczesny odczyt i zapis do/z kolejki fifo w vhdl

zlootawy 04 Lis 2007 13:00 7558 57
Najlepsze odpowiedzi

Czy w VHDL można jednocześnie zapisywać do FIFO i odczytywać z niego dane przy różnych częstotliwościach zegara, i jak to poprawnie zrealizować?

Tak — do takiego zastosowania użyj dwupokojowej FIFO opartej na Block RAM, bo każdy port może pracować z inną częstotliwością zegara, a jednoczesny odczyt i zapis są przez nią przewidziane [#4445157] Nie adresujesz wtedy komórek samodzielnie; FIFO ukrywa adresowanie i tylko pilnujesz flag typu `fifo_empty`/`fifo_full`, żeby wstrzymywać zapis lub odczyt w odpowiednim momencie [#4444929][#4448143] W Core Generatorze najlepiej wygenerować gotowy komponent FIFO, dodać go do projektu jako IP i podłączyć przez deklarację komponentu oraz `port map`, bo w syntezie jest traktowany jak gotowy black box [#4445157][#4444929] Przy asynchronicznych zegarach model behawioralny FIFO może nie być cyklicznie dokładny, więc do weryfikacji lepiej włączyć structural simulation [#4446656] Nie mieszaj też sztucznie zboczy zegara; jeśli potrzebujesz przesunięcia o pół okresu, lepiej użyć DCM/CLK180 niż inwertować zegar ręcznie [#4447416][#4448955]
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
  • #1 4444801
    zlootawy
    Poziom 10  
    Posty: 54
    Witam,
    w moim projekcie mam zapis danych do kolejki fifo z pewna czestotliwoscia f1. Jednoczesnie inny proces ma zdejmowac dane z fifo, gdy tylko fifo_empty wskaze ze cos w fifo sie znajduje i robi to z f2 wieksza niz f1.

    Takie sa zalozenia... byc moze niezbyt szczesliwe ale wolalbym ich nie zmieniac.

    No i teraz zastanawiam sie jak to madrze zrobic...
    Syntezer stworzyl sobie pamiec ram... a ona ma w jednym momencie zapis lub odczyt czyli jednoczesnie tego robic nie mozna... czy moze jednak mozna?


    Generalnie zapis do fifo powinien miec priorytet... ilosc probek nie bedzie nieskonczona, wiec do rozsadnego poziomu mozna odlozyc w fifo ich na zapas a pozniej swobodnie to przerzucic slowo po slowie w miejsce docelowe.

    No ale tez zalezy mi na jakiejs szybkosci.. moze ktos robil podoba rzecz?

    Pozdrawiam
    Wojtek
  • Pomocny post
    #2 4444865
    firefox_PL
    Poziom 17  
    Posty: 235
    Pomógł: 21
    Ocena: 2
    trochę zagmatwanie to napisałeś, wydaje mi się że nie jesteś w stanie zapisywać do pamięci z jedną częstotliwością i jednocześnie odczytywać z inną, o ile się nie mylę to jedyną opcją byłby zapis na narastającym zboczu zegara i odczyt przy opadającym (czyli coś jak ddr), odczyt i zapis przez dwa różne procesy przy tym samym zboczu zegara raczej nie wyjdzie, ale mogę się mylić
  • #3 4444886
    zlootawy
    Poziom 10  
    Posty: 54
    firefox_PL napisał:
    trochę zagmatwanie to napisałeś, wydaje mi się że nie jesteś w stanie zapisywać do pamięci z jedną częstotliwością i jednocześnie odczytywać z inną, o ile się nie mylę to jedyną opcją byłby zapis na narastającym zboczu zegara i odczyt przy opadającym (czyli coś jak ddr), odczyt i zapis przez dwa różne procesy przy tym samym zboczu zegara raczej nie wyjdzie, ale mogę się mylić



    hmmm.... z f1 chodze po automacie stanu, ktorego zadaniem jest ustawiac sygnal PUSH_FIFO. i tylko to.


    a w innym automacie stanow pracujacym juz z f2 ustawiam POP_FIFO.

    Nie wyjdzie tak?

    Dodano po 4 [minuty]:

    zlootawy napisał:


    hmmm.... z f1 chodze po automacie stanu, ktorego zadaniem jest ustawiac sygnal PUSH_FIFO. i tylko to.


    a w innym automacie stanow pracujacym juz z f2 ustawiam POP_FIFO.

    Nie wyjdzie tak?



    hmm no faktycznie troche zle mysle.... bo clock pamieci bedzie caly czas ten sam...
    ostatecznie moze byc jedna f.. myslalem tylko aby szybciej sobie zaladowac dane do fifo, bo nadchodza one partiami, do fifo zas ladowane slowami... no i w czasie ladowania reszta danych sobie czeka, stad mysl aby dac tu maksimum ile sie da wycisnac.
  • Pomocny post
    #4 4444929
    firefox_PL
    Poziom 17  
    Posty: 235
    Pomógł: 21
    Ocena: 2
    chodzi o to, że aby kod działał to musi to działać na fizycznych układach (innymi słowy być syntezowalne, dlatego np. nie można w jednym procesie wykorzystywać dwóch zegarów, ponieważ nie ma takich przerzutników), a rzeczywiste układy pamięci nie są w stanie w jednym momencie obsługiwać zapis i odczyt, dlatego stosuje się takie technologie jak ddr-sdram (czyli przede wszystkim synchroniczność zapisu/odczytu i wykorzystywanie obu zboczy zegara), po prostu układ pamięci który byś potrzebował nie istnieje (chyba, że gdzieś w krzemowej dolinie w laboratoriach :P)

    Dodano po 5 [minuty]:

    być może jeśli fifo nie jest za duże wykorzystaj coś w rodzaju bufora, dzięki temu cały czas masz dostęp do wszystkich komórek bufora, czyli z jednej strony co każdy takt zegara są wpychane dane (jednocześnie z drugiej strony są wyrzucane), dzięki temu nie musisz czekać na wpisanie całości (o ile dalsze działania/obliczenia na to pozwalają)
  • Pomocny post
    #5 4445157
    pndemon
    Poziom 19  
    Posty: 444
    Pomógł: 35
    Ocena: 18
    kilka faktów:
    - pamięć dostępna na matrycach xilinxa w Block RAMach jest dwuportowa, a każdy z portów może mieć inną częstotliwość
    - podczas tworzenia takiej pamięci musisz określić co stanie się w momencie jednoczesnego odczytu i zapisu (np. odczytane dane będą tymi z przed zapisu)
    - wszystko można prosto zdefiniować w w CORE GENARATOR
    - wspomniany COREGEN może tworzyć bardzo ładne kolejki FIFO na bazie Block RAMów

    pozdrawiam
  • Pomocny post
    #6 4445204
    firefox_PL
    Poziom 17  
    Posty: 235
    Pomógł: 21
    Ocena: 2
    pndemon, dziękuję bardzo za poprawienie moich tez, przynajmniej będę mądrzejszy w przyszłości :)
  • #7 4445231
    zlootawy
    Poziom 10  
    Posty: 54
    firefox_PL napisał:

    być może jeśli fifo nie jest za duże wykorzystaj coś w rodzaju bufora, dzięki temu cały czas masz dostęp do wszystkich komórek bufora, czyli z jednej strony co każdy takt zegara są wpychane dane (jednocześnie z drugiej strony są wyrzucane), dzięki temu nie musisz czekać na wpisanie całości (o ile dalsze działania/obliczenia na to pozwalają)



    Proces zapisywania do fifo to automat stanow.

    Moze dac w drugim procesie zapis, ze jesli AKTUALNY_STAN_FSM_ZAPISU_DO_FIFO = IDLE lub END to wtedy mozna sobie bezpiecznie odczytac z fifo? A w razie stanu ZBIERANIE_DANYCH nalezy czekac...

    tylko ze co gdy w momencie przerzucania danych z fifo do pamieci zewntrznej nadejdzie nowa porcja danych do zapisania do fifo... przerzucanie do zewnetrznej pamieci trwa kilka taktow zegara..

    moze najlepszym wyjsciem bedzie odczekanie na przyjecie wszystkich probek i dopiero wtedy dalsze ich obrabianie.

    a takie fifo moze miec duze rozmiary? kilka tysiecy elementow nie bedzie mu straszne?

    Wojtek

    Dodano po 2 [minuty]:

    pndemon napisał:
    kilka faktów:
    - pamięć dostępna na matrycach xilinxa w Block RAMach jest dwuportowa, a każdy z portów może mieć inną częstotliwość
    - podczas tworzenia takiej pamięci musisz określić co stanie się w momencie jednoczesnego odczytu i zapisu (np. odczytane dane będą tymi z przed zapisu)
    - wszystko można prosto zdefiniować w w CORE GENARATOR
    - wspomniany COREGEN może tworzyć bardzo ładne kolejki FIFO na bazie Block RAMów

    pozdrawiam


    witam,
    stworzylem sobie w CG kolejke FIFO. otrzymalem kod w vhdl. ale po wrzuceniu go do projektu syntezer nic w tym nie wykryl...

    problem jest chyba w linijce

    for all : wrapped_fifo_generator_v4_1 use entity XilinxCoreLib.fifo_generator_v4_1(behavioral)

    co trzeba zrobic zeby komponet otrzymany z CG moc naprawde wykorzystac?
  • Pomocny post
    #8 4445372
    firefox_PL
    Poziom 17  
    Posty: 235
    Pomógł: 21
    Ocena: 2
    musisz go podmapować w innym elemencie, czyli zrobić coś takiego
    wewnątrz architecture (przykład dla wygenerowanego disprom z CG)
    
    component disprom is
     Port(
      a : in  STD_LOGIC_VECTOR(3 downto 0);
      spo : out STD_LOGIC_VECTOR(6 downto 0));
    end component;
    

    potem już w opisie behawioralnym tworzysz sobie port map do twojego elementu (tutaj o nazwie rom)
    
    rom : disprom port map(
     a => romAddr,
     spo => catodes (6 downto 0)
    );
    

    możesz stworzyć kilka takich elementów, nadając indywidualne nazwy i tworząc nowe port map'y, component wpisujesz tylko raz
  • #9 4445402
    zlootawy
    Poziom 10  
    Posty: 54
    pndemon napisał:
    kilka faktów:
    - pamięć dostępna na matrycach xilinxa w Block RAMach jest dwuportowa, a każdy z portów może mieć inną częstotliwość
    - podczas tworzenia takiej pamięci musisz określić co stanie się w momencie jednoczesnego odczytu i zapisu (np. odczytane dane będą tymi z przed zapisu)
    - wszystko można prosto zdefiniować w w CORE GENARATOR
    - wspomniany COREGEN może tworzyć bardzo ładne kolejki FIFO na bazie Block RAMów

    pozdrawiam


    hmmm to brzmi interesujaco. jesli dobrze rozumiem mamy 2 porty wejsciowe (A i B) i jeden wyjsciowy (A). port B sluzy do podawania danych do zapisu do fifo. Port A przyjmuje tylko adres i wypluwa na wyjscie A odczytane slowo. I teraz gdy A jest w Read First Mode oznacza ze na wyjsciu caly czas beda dane odczytywane z fifo. dane zapisywane poprzez port B nie beda w zaden sposob przeszkadzac, beda zapisywane swoim tempem pod adresem umieszczanym w B, a ja za pomoca portu A niezaleznie bede je odczytywal z adresu podanego do A.

    A jaki tryb ustawic dla portu B?

    Dodano po 5 [minuty]:

    firefox_PL napisał:
    musisz go podmapować w innym elemencie, czyli zrobić coś takiego
    wewnątrz architecture (przykład dla wygenerowanego disprom z CG)
    możesz stworzyć kilka takich elementów, nadając indywidualne nazwy i tworząc nowe port map'y, component wpisujesz tylko raz


    robilem tak.. zreszta jesli ustawilem ten wykreowany kod jako top_level to powinno wykryc cale bebechy... a nie ma nic... zadnych rejestrow nie mowiac o pamieci.


    dorzucam printscreena na ktorym widac ze Xilinx nie bardzo odkryl czym jest komponent wewnetrzny.
    Załączniki:
    • jednoczesny odczyt i zapis do/z kolejki fifo w vhdl fifo_cg.JPG (30.89 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • Pomocny post
    #10 4445468
    firefox_PL
    Poziom 17  
    Posty: 235
    Pomógł: 21
    Ocena: 2
    poszukaj w folderze z projektem pliku wrapped_fifo_generator_v4_1.xco, bo takie rozszerzenie chyba mają pliki z CG i spróbuj go dodaj ręcznie jako Add Source (jeśli będzie ten plik to ISE sam go podepnie pod odpowiedni element w drzewie plików)
  • #11 4445505
    zlootawy
    Poziom 10  
    Posty: 54
    firefox_PL napisał:
    poszukaj w folderze z projektem pliku wrapped_fifo_generator_v4_1.xco, bo takie rozszerzenie chyba mają pliki z CG i spróbuj go dodaj ręcznie jako Add Source (jeśli będzie ten plik to ISE sam go podepnie pod odpowiedni element w drzewie plików)



    takiego pliku nie ma, jest fifo_generator_v4_1.xco.. po dodani pojawilu sie na liscie, po kliknieciu w niego otwiera sie Core Generator.

    Po dodaniu go do listy, proba zsyntezowania projektu fifo_generator konczy sie bledem, jak w zalaczniku. Brakuje sterownikow?
    Załączniki:
    • jednoczesny odczyt i zapis do/z kolejki fifo w vhdl masakra.JPG (117.21 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • Pomocny post
    #12 4445524
    pndemon
    Poziom 19  
    Posty: 444
    Pomógł: 35
    Ocena: 18
    z coregen najlepiej korzystać już w Project Navigatorze, tzn. tworzyć jako nowy komponent klikasz w Sources prawym i wybierasz new source, w menu wybierasz IP, następnie wybierasz FIFO i otwiera się wizard. wybierasz co chcesz (w razie wątpliwości klikasz "View Data Sheet" w lewym dolnym rogu). Kiedy dobierzesz już wszystkie parametry do projektu zostanie dodany nowy element, pojawi się na liście sources. teraz tak, aby dodać to do projektu można skorzystać z language templates (w menu edit), wybierasz coregen->vhdl i pojawią się z prawej dwa wycinki kodu - deklaracja komponentu oraz mapowanie portów. deklaracje możesz wrzucić gdzieś do pliku nagłówkowego, albo pomiędzy architecture a begin, jak zamapujesz porty to nowy komponent dołączy do hierarchii twojego projektu.

    tak jeszcze tylko wspomnę, że podczas syntezy projektu, komponenty generowane w coregen nie syntezują się, są widziane jako black box - tak powinno być, gdyż one po prostu już są zsyntezowane.

    co do fifo, to jak na mój gust działa to w ten sposób:
    masz port A i B, jeden jest wejściowy do kolejki a drugi jest wyjściem, każdy ma osobną domenę zegarową. problem zapisu do tej samej komórki pamięci tutaj nie istnieje, bo użytkownik nie ma wpływu na zapis danych - porty nie mają linii adresowych, czyli wrzucasz dane do kolejki (jeśli nie jest pełna, inaczej operacja zapisu się nie powiedzie), one zawsze spadają na sam dół kolejki i tam są gromadzone w taki stosik, jak zaczniesz coś odczytywać z kolejki to po prostu zaczniesz opróżniać stosik od dołu. całym problemem adresowania użytkownik w ogóle się nie zajmuje, najlepiej polecam wspomnianą już dokumentację do FIFO (podczas tworzenia w coregen)

    pozdrawiam
  • #13 4445594
    zlootawy
    Poziom 10  
    Posty: 54
    pndemon napisał:
    z coregen najlepiej korzystać już w Project Navigatorze, tzn. tworzyć jako nowy komponent klikasz w Sources prawym i wybierasz new source, w menu wybierasz IP, następnie wybierasz FIFO i otwiera się wizard. wybierasz co chcesz (w razie wątpliwości klikasz "View Data Sheet" w lewym dolnym rogu). Kiedy dobierzesz już wszystkie parametry do projektu zostanie dodany nowy element, pojawi się na liście sources. teraz tak, aby dodać to do projektu można skorzystać z language templates (w menu edit), wybierasz coregen->vhdl i pojawią się z prawej dwa wycinki kodu - deklaracja komponentu oraz mapowanie portów. deklaracje możesz wrzucić gdzieś do pliku nagłówkowego, albo pomiędzy architecture a begin, jak zamapujesz porty to nowy komponent dołączy do hierarchii twojego projektu.

    tak jeszcze tylko wspomnę, że podczas syntezy projektu, komponenty generowane w coregen nie syntezują się, są widziane jako black box - tak powinno być, gdyż one po prostu już są zsyntezowane.


    aaaaa... no to chyba w tym byl moj problem, ze szukalem na liscie elementu RAM i go nie znajdowalem... pozostaje wiec przetestowac w symulacji czy rzeczywiscie zapisze i odczytam poprawnie jakies dane. Mam nadzieje ze ModelSim sobie poradzi z takimi zsyntezowanymi elementami...

    pndemon napisał:

    co do fifo, to jak na mój gust działa to w ten sposób:
    masz port A i B, jeden jest wejściowy do kolejki a drugi jest wyjściem, każdy ma osobną domenę zegarową. problem zapisu do tej samej komórki pamięci tutaj nie istnieje, bo użytkownik nie ma wpływu na zapis danych - porty nie mają linii adresowych, czyli wrzucasz dane do kolejki (jeśli nie jest pełna, inaczej operacja zapisu się nie powiedzie), one zawsze spadają na sam dół kolejki i tam są gromadzone w taki stosik, jak zaczniesz coś odczytywać z kolejki to po prostu zaczniesz opróżniać stosik od dołu. całym problemem adresowania użytkownik w ogóle się nie zajmuje, najlepiej polecam wspomnianą już dokumentację do FIFO (podczas tworzenia w coregen)

    pozdrawiam


    no tak... rzeczywiscie... patrzylem na Block-RAM tymczasem FIFO oparte na BlockRAM jest uproszczona wersja.
    Dzieki
  • Pomocny post
    #14 4445605
    firefox_PL
    Poziom 17  
    Posty: 235
    Pomógł: 21
    Ocena: 2
    do modelsim'a musisz skompilować biblioteki xilinx'a, bo sam sobie z tym nie poradzi
  • #15 4446656
    zlootawy
    Poziom 10  
    Posty: 54
    firefox_PL napisał:
    do modelsim'a musisz skompilować biblioteki xilinx'a, bo sam sobie z tym nie poradzi



    hmmm.. cos tam mi wypluwa i nic nie kompilowalem...
    pojawia sie za to warning o tresci:

    " Note: Warning in %m at time %t: When using an asynchronous configuration for the FIFO Generator, the behavioral model is not cycle-accurate. You may wish to choose the structural simulation model instead of the behavioral model. This will ensure accurate behavior and latencies during simulation. You can enable this from CORE Generator by selecting Project -> Project Options -> Generation tab -> Structural Simulation. See the FIFO Generator User Guide for more information.
    "


    no i nie wiem co myslec...

    przeszkadza mi tez, ze fifo pracuje z narastajacym zboczem zegara... w CoreGeneratorze nie mozna bylo tego zmienic. Czy ktoras z ponizszych wartosci za to odpowiada?

    generic map(
    			c_has_int_clk => 0,
    			c_rd_freq => 1,
    			c_wr_response_latency => 1,
    			c_has_srst => 0,
    			c_has_rd_data_count => 1,
    			c_din_width => DATA_SIZE_OF_SRAM,
    			c_has_wr_data_count => 1,
    			c_full_flags_rst_val => 0,
    			c_implementation_type => 2,
    			c_family => "virtex2p",
    			c_use_embedded_reg => 0,
    			c_has_wr_rst => 0,
    			c_wr_freq => 1,
    			c_underflow_low => 0,
    			c_has_meminit_file => 0,
    			c_has_overflow => 0,
    			c_preload_latency => 1,
    			c_dout_width => DATA_SIZE_OF_SRAM,
    			c_rd_depth => 1024,
    			c_default_value => "BlankString",
    			c_mif_file_name => "BlankString",
    			c_has_underflow => 0,
    			c_has_rd_rst => 0,
    			c_has_almost_full => 1,
    			c_has_rst => 1,
    			c_data_count_width => 10,
    			c_has_wr_ack => 0,
    			c_use_ecc => 0,
    			c_wr_ack_low => 0,
    			c_common_clock => 0,
    			c_rd_pntr_width => 10,
    			c_use_fwft_data_count => 0,
    			c_has_almost_empty => 1,
    			c_rd_data_count_width => 10,
    			c_enable_rlocs => 0,
    			c_wr_pntr_width => 10,
    			c_overflow_low => 0,
    			c_prog_empty_type => 0,
    			c_optimization_mode => 0,
    			c_wr_data_count_width => 10,
    			c_preload_regs => 0,
    			c_dout_rst_val => "0",
    			c_has_data_count => 0,
    			c_prog_full_thresh_negate_val => 1020,
    			c_wr_depth => 1024,
    			c_prog_empty_thresh_negate_val => 3,
    			c_prog_empty_thresh_assert_val => 2,
    			c_has_valid => 0,
    			c_init_wr_pntr_val => 0,
    			c_prog_full_thresh_assert_val => 1021,
    			c_use_fifo16_flags => 0,
    			c_has_backup => 0,
    			c_valid_low => 0,
    			c_prim_fifo_type => "1kx18",
    			c_count_type => 0,
    			c_prog_full_type => 0,
    			c_memory_type => 1);


    dzieki
  • Pomocny post
    #16 4447416
    pndemon
    Poziom 19  
    Posty: 444
    Pomógł: 35
    Ocena: 18
    Cytat:
    no i nie wiem co myslec...

    no użyty zostanie model behawioralny w symulacji, nie uwzględnia on zależności czasowych w rzeczywistym układzie

    Cytat:
    przeszkadza mi tez, ze fifo pracuje z narastajacym zboczem zegara...

    panowie z xilinxa odradzają mieszanie układów działających na narastające i opadające zbocze
    http://www.xilinx.com/xlnx/xweb/xil_tx_display.jsp?iLanguageID=1&category=&sGlobalNavPick=&sSecondaryNavPick=&multPartNum=1&sTechX_ID=rw_tim_closure#timing1
    jak jest ci potrzebne działanie opóźnione o połowę cyklu, to zastosuj przesunięcie fazy przy pomocy DCMa, broń boże nie stosuj negacji sygnału zegarowego

    Cytat:
    Czy ktoras z ponizszych wartosci za to odpowiada?

    nie mam pojęcia :)
  • Pomocny post
    #17 4448143
    J.A
    Poziom 28  
    Posty: 596
    Pomógł: 159
    Ocena: 12
    zlootawy napisał:
    Generalnie zapis do fifo powinien miec priorytet

    fifo sluzy do sprzegania modulow o roznych zegarach, w tym rowniez
    asynchronicznych, nie ma problemu priorytetu zapisu czy odczytu;
    z twojego, uzytkownika punktu widzenia, adresowanie pamieci
    na ktorej zrobiono fifo to nie twoj problem, jest ukryte;

    firefox_PL napisał:
    opcją byłby zapis na narastającym zboczu zegara
    i odczyt przy opadającym (czyli coś jak ddr)

    do wyjasnien pndemon dodam, ze w ddr-ram chodzi jedynie o zwiekszenie
    szybkosci przesylania danych, przerzutniki odczytujace dane faktycznie
    pracuja na narastajacym zboczu, tyle ze polowa z nich jest polaczona do
    zegara przez inwerter;

    zlootawy napisał:
    Note: Warning in %m at time %t: When using an asynchronous
    /.../
    no i nie wiem co myslec...

    olej :)
    problem w tym, ze jak masz asynchroniczne zegary wpisujacy i odczytujacy,
    to nie wiadomo ktorym z nich taktowac flagi fifo_full, fifo_empty itd;
    sam przeplyw danych powinien byc pokazany na symulatorze poprawnie;

    zlootawy napisał:
    przeszkadza mi tez, ze fifo pracuje z narastajacym zboczem
    zegara /.../

    to polacz w top level fifo do zegara przez inverter raczej, zamiast
    grzebac w tym, co zrobil CoreGen, ale upewnij sie, ze wiesz co czynisz :)
    rzecz w tym, ze dane do fifo prawdopodobnie synchronizujesz gdzies
    przed fifo narastajacym zegarem, wiec jesli do fifo bedziesz chcial
    wpisywac opadajacym, mozesz miec problem z timingiem, bo dane
    beda mialy jedynie pol okresu zegara na ustabilizowanie sie, przy szybkim
    clock [ >100MHz ] moze byc klopot;

    pndemon napisał:
    panowie z xilinxa odradzają mieszanie układów działających
    na narastające i opadające zbocze

    generalnie racja, to zla praktyka, ale nie w tym przypadku, gdy sprzegamy
    zrodlo danych i odbiornik za pomoca fifo;

    pndemon napisał:
    jak jest ci potrzebne działanie opóźnione o połowę cyklu,
    to zastosuj przesunięcie fazy przy pomocy DCMa, broń boże nie stosuj
    negacji sygnału zegarowego

    a z tym to sie calkiem nie zgadzam, dokladnie odwrotnie;
    zle jest wygenerowac sygnal bedacy negacja clock, bo prawdopodobnie
    compilator zastosuje inverter po czym taki zanegowany zegar pojdzie
    na specjalny bufor zegarowy [o duzej wydajnosci pradowej] i dopiero
    potem na port Clk przerzutnikow; w takim przypadku przesuniecie fazy
    miedzy zegarem zanegowanym i 'wprost' jest slabo okreslone i moze
    sie zmienic po kazdej kompilacji;

    nie ma tego problemu, jesli napiszesz FF reagujacy na opadajace
    zbocze;

    
          zle                            niezle
    
    wire  clock_neg = !clock;
    
    always @(posedge clock_neg)      always @(negedge clock)
      FF <= dana;                      FF <= dana;
    


    mam nadzieje, ze idea jest jasna rowniez dla VHDL-owcow :)

    przesuwanie fazy na DCM, procz dodania extra opoznienia
    na routing do bufora zegarowego i z powrotem do FF ma te wade,
    ze przesuwasz clock o x ns, zmienisz czestotliwosc pracy, przestaniesz
    miec przesuniecie o 180 stopni, jesli uzyjesz negedge, niezaleznie
    o frekwencji beedziesz mial te 180 stopni;

    J.A
  • Pomocny post
    #18 4448860
    pndemon
    Poziom 19  
    Posty: 444
    Pomógł: 35
    Ocena: 18
    Cytat:
    a z tym to sie calkiem nie zgadzam, dokladnie odwrotnie;

    hmm... mógłbyś nieco rozwinąć tą myśl, zawsze myślałem że nie powinno się wprowadzać logiki na ścieżce zegarowej, a takie dodanie inwertera moim zdaniem właśnie to spowoduje

    Cytat:
    z powrotem do FF ma te wade, ze przesuwasz clock o x ns,

    z tego co się orientuję to DCM ma standardowo wyjścia CLK, CLK90, CLK180, CLK270, CLK2X, itp.
    jednoczesny odczyt i zapis do/z kolejki fifo w vhdl
    jeśliby więc przyjąć, że podstawowy zegar pochodzi z wyjścia CLK, a ten dla FIFO z CLK180, to czy nie będzie ok?
  • Pomocny post
    #19 4448955
    J.A
    Poziom 28  
    Posty: 596
    Pomógł: 159
    Ocena: 12
    pndemon napisał:
    JA napisał:
    a z tym to sie calkiem nie zgadzam,
    dokladnie odwrotnie;

    hmm... mógłbyś nieco rozwinąć tą myśl, zawsze myślałem,
    że nie powinno się wprowadzać logiki na ścieżce zegarowej,
    a takie dodanie inwertera moim zdaniem właśnie to spowoduje


    fatalnie to opisalem slowami, ale przyklad kodu wyjasnia,
    co mam na mysli;
    nie nalezy 'kombinowac' z clock jesli to nie jest z jakichs
    powodow naprawde konieczne, ale jesli potrzebujesz
    z tych czy innych przyczyn sterowac przerzutniki opadajacym
    zboczem, to umieszczenie w liscie czulosci
    'negedge' czy 'falling_edge' doda co prawda negacje, ale
    wewnatrz komorki, tej najmniejszej struktury fpga, nie wiem,
    jak ja xilinx nazywa;
    z twojego, uzytkownika punktu widzenia, bedzie to FF reagujacy
    na ujemne zbocze, a nie inverter w sciezce zegara;
    jesli nadal niejasno sie wyrazam, to zrobie jakis rysunek
    ilustracyjny ;)

    pndemon napisał:
    z tego co się orientuję to DCM ma standardowo wyjścia
    CLK, CLK90, CLK180, CLK270, CLK2X, itp

    przyznam sie, ze oparlem sie na doswiadczeniach z fpga altery,
    ale nie bardzo sobie wyobrazam, by xilinx - z powodow technicznych,
    byl w stanie zrobic to inaczej;
    owszem, masz wyjscia 90, 180 itd., ale w praktyce oznacza to,
    ze dla podanej przez ciebie czestotliwosci wejsciowej
    software przelicza stopnie na nanosekundy;
    zmienisz czestotliwosc wejsciowa bedziesz mial to samo opoznienie
    w ns a nie ten sam kat fazy;

    --------

    przeczytam dzis wieczorem w domu opis tego modulu DCM
    u xilinxa, a nuz plote bzdury ...



    J.A
  • Pomocny post
    #20 4451428
    J.A
    Poziom 28  
    Posty: 596
    Pomógł: 159
    Ocena: 12
    Cytat:
    przeczytam dzis wieczorem w domu opis tego modulu
    DCM u xilinxa, a nuz plote bzdury ...

    przeczytalem, nie znalazlem wyjasnienia wprost, ale wydaje sie,
    ze mam racje, ze ise oblicza potrzebne opoznienie w ns
    na podstawie okresu zegara wejsciowego, podobnie jak quartus altery;
    altera tez, nawiasem mowiac, nie podaje tej informacji
    otwartym tekstem, trzeba do tego dojsc samemu ogladajac
    efekty kompilacji dostepnymi w quartusie narzedziami;
    J.A
  • #21 4453363
    zlootawy
    Poziom 10  
    Posty: 54
    Cytat:

    to polacz w top level fifo do zegara przez inverter raczej, zamiast
    grzebac w tym, co zrobil CoreGen, ale upewnij sie, ze wiesz co czynisz :)
    rzecz w tym, ze dane do fifo prawdopodobnie synchronizujesz gdzies
    przed fifo narastajacym zegarem, wiec jesli do fifo bedziesz chcial
    wpisywac opadajacym, mozesz miec problem z timingiem, bo dane
    beda mialy jedynie pol okresu zegara na ustabilizowanie sie, przy szybkim
    clock [ >100MHz ] moze byc klopot;



    no wlasnie generalnie pracuje na zboczu opadajacym... wszystkie procesy zalezne od zegara mam na opadajacym. jedyny wyjatek to pobieranie danych z portow wejsciowych do rejestrow. to mam na narastajacym zboczu. nie potrafie mocno tego uzasadnic, fragment kodu otrzymalem z zewneatrz i tak jest zrobione i to dziala.

    zewnetrzny SRAM dziala na zboczu narastajacym.

    w sumie to chyba nie powinno miec znaczenia... ale moze powodem zbocza opadajacego jest to, aby dane do SRAM dobiegly tuz przed narasstajacym zboczem i ustabilizowaly sie?

    czyli koniec koncow padl wniosek, abym dal inwerter przed wejsciem clocka do fifo...

    Dzieki
    Pozdraiwam
    zlootawy
  • Pomocny post
    #22 4454164
    J.A
    Poziom 28  
    Posty: 596
    Pomógł: 159
    Ocena: 12
    zlootawy napisał:
    no wlasnie generalnie pracuje na zboczu opadajacym...
    wszystkie procesy zalezne od zegara mam na opadajacym. jedyny wyjatek to pobieranie
    danych z portow wejsciowych do rejestrow. to mam na narastajacym zboczu.
    nie potrafie mocno tego uzasadnic, fragment kodu otrzymalem z zewneatrz
    i tak jest zrobione i to dziala.


    to jest w zasadzie kwestia umowy, czy wykorzystujesz sie zbocze
    rosnace, czy opadajace, przyjelo sie, ze pozytywne jest zboczem
    pracy, wiec warto sie tego trzymac, bo wiekszosc ukladow
    z ktorymi fpga ma wspolpracowac w koncowej aplikacji tak wlasnie
    dziala;

    zlootawy napisał:
    w sumie to chyba nie powinno miec znaczenia... ale moze powodem
    zbocza opadajacego jest to, aby dane do SRAM dobiegly tuz przed narastajacym
    zboczem i ustabilizowaly sie?


    ale przy positive slope dane 'jeszcze bardziej' by sie ustabilizowaly :)
    nie wiem, dlaczego ktos tak zrobil, pewnie mial swoj powod,
    choc niekoniecznie mial racje ;)

    zlootawy napisał:
    czyli koniec koncow padl wniosek, abym dal inwerter przed
    wejsciem clocka do fifo...


    rozumiem, ze masz na mysli clock wpisujacy do fifo;
    z tego co piszesz, nie ma powodu odwracania fazy clock;
    a w ogole decyzje o pracy na obu zboczach nalezy poprzedzic
    staranna analiza ukladu a zwlaszcza przebiegow symulacji post place&route;

    a przy okazji - piszesz dlugie linijki, [wlasciwie wszyscy procz mnie tak pisza ...]
    ktore wylaza mi poza ekran, musze suwac poziomym suwakiem
    by przeczytac twoje wiadomosci;
    cos mam zle ustawione, ktos wie, co z tym zrobic ?
    oczywiscie nie jest to zaden powazny problem;

    JA
  • Pomocny post
    #23 4454706
    firefox_PL
    Poziom 17  
    Posty: 235
    Pomógł: 21
    Ocena: 2
    J.A. to nie przez autora, wynika to z linku wrzuconego przez pndemon:
    pndemon napisał:
    panowie z xilinxa odradzają mieszanie układów działających na narastające i opadające zbocze
    http://www.xilinx.com/xlnx/xweb/xil_tx_displa...ultPartNum=1&sTechX_ID=rw_tim_closure#timing1


    Dodano po 32 [sekundy]:

    tekst jest zawijany zawsze, ale linki nie dlatego najlepiej stosować [url=...
  • Pomocny post
    #24 4454874
    J.A
    Poziom 28  
    Posty: 596
    Pomógł: 159
    Ocena: 12
    firefox napisał:
    tekst jest zawijany zawsze, /.../

    wlasnie dostrzeglem, ze w pracy jest ok, linijki dostosowuja
    sie do szerokosci przegladarki, uzywam IE,
    w domu tekst sie nie zawija i pojawia sie na dole suwak, mam ... firefox :)
    JA
  • #25 4455742
    zlootawy
    Poziom 10  
    Posty: 54
    J.A napisał:
    firefox napisał:
    tekst jest zawijany zawsze, /.../

    wlasnie dostrzeglem, ze w pracy jest ok, linijki dostosowuja
    sie do szerokosci przegladarki, uzywam IE,
    w domu tekst sie nie zawija i pojawia sie na dole suwak, mam ... firefox :)
    JA


    w moim FF 2.0.0.9 wyswietla prawidlowo..
  • Pomocny post
    #26 4456483
    pndemon
    Poziom 19  
    Posty: 444
    Pomógł: 35
    Ocena: 18
    ja mam 2.0.09 i nie wyświetla poprawnie, stąd można snuć wniosek że to kwestia jakiś ustawień

    no ale wracając do tematu, bo robi się mały off, z tym DCMem to bardziej z mojego punktu widzenia istotna jest kwestia nie tego jak jest obliczane przesunięcie fazowe, ale kwestia tego (jak pisał J. A.)
    Cytat:
    przesuwanie fazy na DCM, procz dodania extra opoznienia
    na routing do bufora zegarowego i z powrotem do FF

    z tego co ja myślałem, to koncepcja jest taka:
    w DCM, na podstawie sygnału referencyjnego, pochodzącego z zewnątrz (wejście CLKIN w DCM), generowany jest sygnał podstawowy CLK0 oraz wszystkie inne przesunięcia, w związku z czym jeśli wszystkie komponenty korzystają z sygnału CLK0, a tylko FIFO z syg. CLK180 to nie będą tu dokładane dodatkowe opóźnienia.
  • Pomocny post
    #27 4458017
    J.A
    Poziom 28  
    Posty: 596
    Pomógł: 159
    Ocena: 12
    pndemon napisał:
    w DCM, na podstawie sygnału referencyjnego, pochodzącego z zewnątrz (wejście CLKIN w DCM),
    generowany jest sygnał podstawowy CLK0 oraz wszystkie inne przesunięcia,
    w związku z czym jeśli wszystkie komponenty korzystają z sygnału CLK0,
    a tylko FIFO z syg. CLK180 to nie będą tu dokładane dodatkowe opóźnienia.

    tak by bylo ok, ja zrozumialem, ze koncept jest taki, by pracowac
    z CLKIN i CLK180;
    jedyne zastrzezenie do uzywania DCM, jesli to nie jest konieczne,
    [a przy clock0 i clock180 nie jest] to fakt, ze pll ma swoj zakres
    czestotliwosci, do ktorych moze sie dostroic;
    nie testowalem doswiadczalnie co sie stanie, jesli pll nastawione
    na clkin = 100MHz dostanie np. 60MHz, ale moze to byc zrodlem nieoczekiwanych
    klopotow;

    -------------------
    a, zapomnialem, dzieki kolegom za uwagi o wyswietlaniu :)

    JA
  • #28 4463745
    zlootawy
    Poziom 10  
    Posty: 54
    J.A napisał:

    tak by bylo ok, ja zrozumialem, ze koncept jest taki, by pracowac
    z CLKIN i CLK180;
    jedyne zastrzezenie do uzywania DCM, jesli to nie jest konieczne,
    [a przy clock0 i clock180 nie jest] to fakt, ze pll ma swoj zakres
    czestotliwosci, do ktorych moze sie dostroic;
    nie testowalem doswiadczalnie co sie stanie, jesli pll nastawione
    na clkin = 100MHz dostanie np. 60MHz, ale moze to byc zrodlem nieoczekiwanych
    klopotow;
    JA



    a skoro jestesmy przy temacie DCM....

    zrobilem symulacje czasowa jego pracy... i dosyc dlugo trwa od poczatku pracy uzyskanie czestotliwosci wyjsciowej... tzn. na wyjsciu wartosc stala i dopiero po 2000 ps (w moim przypadku) sygnal prostokoatny...

    czy w rzeczywistym ukladzie trzeba to jakos uwzglednic?


    pozdrawiam, dzieki
    Wojtek
  • Pomocny post
    #29 4464398
    J.A
    Poziom 28  
    Posty: 596
    Pomógł: 159
    Ocena: 12
    zlootawy napisał:
    zrobilem symulacje czasowa jego pracy... i dosyc dlugo trwa od poczatku pracy
    uzyskanie czestotliwosci wyjsciowej... tzn. na wyjsciu wartosc stala i dopiero
    po 2000 ps (w moim przypadku) sygnal prostokoatny...

    czy w rzeczywistym ukladzie trzeba to jakos uwzglednic?


    tak, w rzeczywistym ukladzie pll potrzebuje okreslonego czasu,
    by zaczac generowac zegar, zdziwiony jestem tym, ze na symulatorze
    ten czas to jedynie 2ns, [mialo byc 20 000ps ?] zwykle w specyfikacji
    jest mowa o kilkuset cyklach zegarowych nim pll zaczyna pracowac zgodnie
    z ustawionymi parametrami;

    J.A
  • Pomocny post
    #30 4464970
    pndemon
    Poziom 19  
    Posty: 444
    Pomógł: 35
    Ocena: 18
    właśnie, też mam pytanie co do DCMa, czy nawet jeśli nic nie robimy z zegarem (pozostawiamy w układzie częstotliwość zewnętrzną), to czy nie warto zawsze dorzucić go do układu, czy nie jest tak że poprawia on sygnał i redukuje ewentualne przesunięcia?

Podsumowanie tematu

✨ Dyskusja dotyczy implementacji jednoczesnego zapisu i odczytu z kolejki FIFO w VHDL, gdzie zapis odbywa się z częstotliwością f1, a odczyt z wyższą f2. Poruszono problem fizycznych ograniczeń pamięci RAM w FPGA, które zwykle nie pozwalają na jednoczesny zapis i odczyt w tym samym cyklu zegara, chyba że stosuje się technologie DDR lub pamięci dwuportowe. Wskazano, że w matrycach Xilinx Block RAM jest dwuportowy i może obsługiwać różne częstotliwości na portach, a zachowanie przy jednoczesnym odczycie i zapisie definiuje się w Core Generatorze (COREGEN), który generuje FIFO oparte na Block RAM. Omówiono kwestie synchronizacji zegarów, zalecenia dotyczące unikania mieszania zboczy narastających i opadających, a także wykorzystania DCM do przesunięcia fazy zegara zamiast negacji sygnału zegarowego. Poruszono też temat symulacji FIFO w ModelSim, gdzie konieczne jest dołączenie bibliotek Xilinx oraz wybór modelu strukturalnego dla dokładności czasowej. Autor omawiał implementację automatu stanów do sterowania FIFO, autoinkrementację adresu w trybie burst SRAM oraz problemy z integracją komponentu FIFO z projektem, w tym błędy pinów i ograniczenia CoreGen dotyczące szerokości słowa danych. Zwrócono uwagę, że komponenty CoreGen są traktowane jako black box podczas syntezy i nie można dynamicznie zmieniać ich parametrów szerokości. Dyskutowano o możliwości składania FIFO o szerokości 1 bit w celu uzyskania większej szerokości, jednak z potencjalnymi problemami opóźnień i wydajności. Wspomniano o ograniczeniach zasobów FPGA (100% wykorzystania sliców) przy implementacji FIFO o dużej szerokości. Poruszono także temat czasu blokady (lock) DCM i jego wpływu na start układu oraz wykorzystania sygnału LOCKED jako wskaźnika gotowości. Wskazano, że FIFO służy do sprzęgania modułów o różnych zegarach, w tym asynchronicznych, a priorytety zapisu i odczytu są zarządzane przez niezależne automaty stanów sterowane flagami fifo_empty i fifo_full.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA