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

Czy procedury w maszynie stanów VHDL są syntezowalne?

borsukh 10 Lis 2007 00:23 1932 11
REKLAMA
  • #1 4464384
    borsukh
    Poziom 11  
    Posty: 22
    W większym projekcie nad którym właśnie pracuje natknąłem się na pewien problem - mianowicie z maszyny stanów chcę odwoływać się do procedur i czekać na ich wykonanie. Chciałem się upewnić, że takie podejście będzie syntezowalne więc wykonałem niewielki programik - prosty licznik który odlicza sekundy od 0 do 59 i tak w kółko. Liczba dziesiątek obsługiwana jest przez maszynę stanu która w każdym stanie (0 - 5) odwołuje się do procedury, która z kolei zlicza od 0 do 9 i podaje wynik na wyjście po czym następuje zmiana stanu. Zegar systemowy (50 MHz) jest dzielony aby otrzymać impuls co sekundę.Myślę, że poniższy kod wszystko wyjaśni:

    
    entity Main is
    	port (reset,clk : in STD_LOGIC;
    			out1: inout STD_LOGIC_VECTOR(3 downto 0);
    			out10: out STD_LOGIC_VECTOR(3 downto 0));
    			
    			
    type state_type is (s0,s1,s2,s3,s4,s5);
    end Main;
    
    architecture Behavioral of Main is
    
    constant divide : integer := 49999999;
    signal counter : integer range 49999999 downto 0;
    signal clk_div : STD_LOGIC;
    signal state_pres, state_nxt : state_type;
    signal count9: STD_LOGIC_VECTOR (3 downto 0);
    
    procedure COUNT (signal out1: out STD_LOGIC_VECTOR(3 downto 0);
    					  signal count9: inout STD_LOGIC_VECTOR (3 downto 0)) is
    begin 
    	if reset = '1' then
    		count9 <= (others => '0');
    	elsif rising_edge(clk_div) then
    		if count9 = "1001" then
    			out1 <= count9;
    			count9 <=(others => '0');
    		else			
    			out1 <= count9;                   --linia 1
    			count9 <= count9 + 1;          --linia 2
    		end if;
    	end if;
    end COUNT;
    
    begin
    
    
    
    CLK_DIVIDE:
    process (reset, clk)
    begin
    	if reset = '1' then
    		counter <= 0;
    	elsif rising_edge(clk) then
    		if counter = divide then
    			clk_div <= '1';
    			counter <= 0;
    		else
    			clk_div <= '0';
    			counter <= counter + 1;
    		end if;
    	end if;
    end process CLK_DIVIDE;
    
    STATE_CHANGE:
    process (reset, clk_div)
    begin
    	if reset = '1' then
    		state_pres <= s0;
    	elsif rising_edge(clk_div) then
    		state_pres <= state_nxt;
    	end if;
    end process STATE_CHANGE;
    
    NXT_STATE_LOGIC:
    process (state_pres,clk_div, reset)
    begin
    	case state_pres is
    		when s0 => out10 <= "0000";
    					  COUNT(out1,count9);
    					 if out1 /= "1001" then 
    						 state_nxt <= s0;
    					 else
    						 state_nxt <= s1;
    					 end if;
    		when s1 => out10 <= "0001";
    					  COUNT(out1,count9);
    					 if out1 /= "1001" then
    						 state_nxt <= s1;
    					 else
    						 state_nxt <= s2;
    					 end if;
    		when s2 => out10 <= "0010";
    					  COUNT(out1,count9);
    					 if out1 /= "1001" then
    						 state_nxt <= s2;
    					 else
    						 state_nxt <= s3;
    					 end if;
    		when s3 => out10 <= "0011";
    					  COUNT(out1,count9);
    					 if out1 /= "1001" then
    						 state_nxt <= s3;
    					 else
    						 state_nxt <= s4;
    					 end if;
    		when s4 => out10 <= "0100";
    					  COUNT(out1,count9);
    					 if out1 /= "1001" then
    						 state_nxt <= s4;
    					 else
    						 state_nxt <= s5;
    					 end if;
    		when s5 => out10 <= "0101";
    					  COUNT(out1,count9);
    					 if out1 /= "1001" then
    						 state_nxt <= s5;
    					 else
    						 state_nxt <= s0;
    					 end if;
    	end case;
    end process NXT_STATE_LOGIC;
    
    end Behavioral;
    

    Na początku kod nie działał poprawnie, nie mogłem znaleźć błędu. Okazało się że zamiana miejscami linii 1 i linii 2 (zaznaczone komentarzem w opisie procedury) wszystko naprawiła. Jestem jednak nieco zdziwiony - z tego co wiem nie powinno być żadnej zmiany jako że obie linie to przypisanie wartości do sygnału, które powinno nastąpić równocześnie na następnym zboczu zegara. Jako że jednak teoria często niewiele ma wspólnego z praktyką chciałem poprosić kogoś o wyjaśnienie zjawiska i odpowiedź na pytanie czy jest to poprawnie napisany kod, czy też jest to łut szczęścia że akurat ten a nie inny kompilator (pracuje w Xilinxie) tak to zinterpretował i kod nie będzie działał tak samo na innej platformie (np Altery).
  • REKLAMA
  • #2 4464436
    J.A
    Poziom 28  
    Posty: 596
    Pomógł: 159
    Ocena: 12
    borsukh napisał:
    Na początku kod nie działał poprawnie, nie mogłem znaleźć błędu.
    Okazało się że zamiana miejscami linii 1 i linii 2 (zaznaczone komentarzem w opisie procedury)
    wszystko naprawiła. Jestem jednak nieco zdziwiony - z tego co wiem nie powinno być żadnej
    zmiany jako że obie linie to przypisanie wartości do sygnału, które powinno nastąpić równocześnie
    na następnym zboczu zegara.

          else         
             out1 <= count9;                   --linia 1
             count9 <= count9 + 1;          --linia 2
          end if; 
    

    slaby jestem z teorii symulacji, pracuje z zywym hardware raczej niz
    symuluje, ale jak masz jakiegos pdf z vhdl to zrob search na ciag
    "blocking" i "nonblocking" [ew. "non blocking"]
    w rzeczywistym ukladzie twoj kod opisuje licznik i rejestry, do ktorych
    przepisujesz wartosc licznika;
    stworzyles typowy uklad z "race conditions", zaleznie od opoznien
    na polaczeniach w fpga albo najpierw licznik uaktualni swoja
    wartosc, a pozniej przepisze sie wartosc do out1, albo odwrotnie,
    albo [najbardziej prawdopodobne] cos posredniego, bedziesz zapisywal
    do out1 wartosci licznika w trakcie zmiany jego wartosci;
    jednym slowem - bardzo zle to zrobiles, niezaleznie od typu
    fpga i kompilatora;

    mam nadzieje, ze jasno to wyrazilem, jesli nie, moge postarac sie lepiej ;)

    J.A
  • REKLAMA
  • #3 4464457
    borsukh
    Poziom 11  
    Posty: 22
    Dziękuje za odpowiedź, tak mi się właśnie zdawało że mam tu do czynienia ze zjawiskiem wyścigu. Czy istnieje tutaj jakieś proste rozwiązanie? Kombinowałem trochę z użyciem variable do przetrzymania wartości chwilowej ale one się chyba nie nadają do syntezy.
  • #4 4464464
    J.A
    Poziom 28  
    Posty: 596
    Pomógł: 159
    Ocena: 12
    borsukh napisał:

    Czy istnieje tutaj jakieś proste rozwiązanie?

    rozwiazania moga byc dwa:
    - robisz warunek w ktorym licznik nie liczy i wtedy przepisujesz
    jego wartosc do rejestru;
    - licznik pracuje na narastajacym zboczu zegara, przepisywanie
    na opadajacym [albo odwrotnie];

    Cytat:
    Kombinowałem trochę z użyciem variable do przetrzymania wartości
    chwilowej ale one się chyba nie nadają do syntezy

    chyba nie ...

    -------------
    jeszcze jedna uwaga - chcesz zobaczyc co 'naprawde' zdarzy sie w fpga
    symuluj 'post place&route';

    J.A

    Dodano po 1 [godziny] 20 [minuty]:

    J.A napisał:
    stworzyles typowy uklad z "race conditions", zaleznie od opoznien
    na polaczeniach w fpga albo najpierw licznik uaktuani/.../


    po chwili zastanowienia sie dochodze do wniosku, ze nie mam racji;
    jest to problem wylacznie symulacji;
    sygnal clock jest rozprowadzany dedykowanymi, szybkimi polaczeniami,
    szybszymi niz polaczenia logiki, wiec out1 przepisze stan zlicznika
    zanim ten zacznie sie przelaczac;
    jesli taki jest twoj zamiar, to kod jest ok;

    J.A
  • #5 4467927
    musik79
    Poziom 1  
    Posty: 1
    Witam.
    Czy ktoś ma namiary na książkę(ki) w wersji elektronicznej na temat języka VHDL - materiał potrzebny na studia. Proszę o pomoc.
  • REKLAMA
  • #6 4468428
    tomsik83
    Poziom 11  
    Posty: 29
    Ocena: 1
    Nie jest to tak ze w obrebie procesu czy procedury instrukcje wykonywane sa sekwencyjnie?
    Chyba o to chodzi...

    Po syntezie nie powinno miec to znaczenia...
    sekwencyjnosc instrukcji powinna miec tylko znaczenie dla symulacji.
  • #7 4476322
    [g.d.]
    Poziom 18  
    Posty: 174
    Pomógł: 31
    tomsik83 napisał:
    Nie jest to tak ze w obrebie procesu czy procedury instrukcje wykonywane sa sekwencyjnie?
    Chyba o to chodzi...

    Sekwencyjność poleceń TAK, aktualizacja bieżących wartości sygnałów NIE.
    tomsik83 napisał:

    Po syntezie nie powinno miec to znaczenia...
    sekwencyjnosc instrukcji powinna miec tylko znaczenie dla symulacji.

    Generalnie dobrze byłoby gdyby wyniki symulacji przed i po syntezie jak również działanie układu były takie same.

    Jak na moje oko to program robiący syntezę "dał cienia" i wyszła aktualizacja wartości sygnałów tak jak wartości variable, czyli na bieżąco.

    borsukh napisał:

    Kombinowałem trochę z użyciem variable do przetrzymania wartości chwilowej ale one się chyba nie nadają do syntezy.


    Jak najbardziej naddają sie do syntezy, tylko że ich wartości aktualizowane są natychmiast co po syntezie skutkuje wygenerowaniem logiki. Czyli w ten sposów wartości chwilowej nie przetrzymasz.

    Variable są przydatne jak jest większa logika do zrealizowania. Można sobie najpierw zrobić przypisanie do variable takiej, która ma jakieś sensowne znaczenie i rozsądną nazwę, a dopiero później operować na tej nazwie robiąc przypisania do sygnałów.
  • #8 4476468
    J.A
    Poziom 28  
    Posty: 596
    Pomógł: 159
    Ocena: 12
    [g.d.] napisał:
    Jak na moje oko to program robiący syntezę "dał cienia"

    nie sadze, kompilator xilinx to stara, doswiadczona marka;
    to jest temat na wielogodzinna dyskusje z teoretykami symulacji i syntezy,
    jako praktyk powiem tyle:
    vhdl powstawal w czasach, gdy jeszcze fpga nie bylo na swiecie,
    powstal jako jezyk do modelowania wlasciwie czegokolwiek, niekoniecznie
    elektroniki; stad w nim tyle konstrukcji i zasad, ktore sa nierealizowalne
    w dzisiejszych ukladach programowalnych, dlatego tak latwo napisac kod,
    ktory inaczej zachowuje sie w fpga, a inaczej w symulacji;
    stad tez w vhdl to obledne sprawdzanie zgodnosci typow;
    tworcy verilog starali sie pamietac o tym, ze w fpga sa bramki,
    przerzutniki i druty miedzy nimi i tyle, dlatego ten jezyk jest prostszy
    i jakby blizszy rzeczywistemu sprzetowi;

    J.A
  • REKLAMA
  • #9 4479663
    borsukh
    Poziom 11  
    Posty: 22
    Cytat:
    Jak najbardziej naddają sie do syntezy, tylko że ich wartości aktualizowane są natychmiast co po syntezie skutkuje wygenerowaniem logiki. Czyli w ten sposów wartości chwilowej nie przetrzymasz.


    [g.d.] nie do końca zrozumiałem o co ci chodzi, wprowadzenie czegokolwiek skutkuje wygenerowaniem logiki. Jak ja to rozumiem, wprowadzenie variable do syntezy to wprowadzenie jakiegoś układu asynchronicznego do, w tym wypadku, architektury synchronicznej. Czy wobec tego zmiania sygnału count9 na variable wewnątrz procedury powinna również działać? Po syntezie z takim rozwiązaniem program nie działa w ogóle...
  • #10 4483262
    [g.d.]
    Poziom 18  
    Posty: 174
    Pomógł: 31
    J.A napisał:
    [g.d.] napisał:
    Jak na moje oko to program robiący syntezę "dał cienia"

    nie sadze, kompilator xilinx to stara, doswiadczona marka;
    to jest temat na wielogodzinna dyskusje z teoretykami symulacji i syntezy,
    jako praktyk powiem tyle:
    vhdl powstawal w czasach, gdy jeszcze fpga nie bylo na swiecie,
    powstal jako jezyk do modelowania wlasciwie czegokolwiek, niekoniecznie
    elektroniki; stad w nim tyle konstrukcji i zasad, ktore sa nierealizowalne
    w dzisiejszych ukladach programowalnych, dlatego tak latwo napisac kod,
    ktory inaczej zachowuje sie w fpga, a inaczej w symulacji;
    stad tez w vhdl to obledne sprawdzanie zgodnosci typow;
    tworcy verilog starali sie pamietac o tym, ze w fpga sa bramki,
    przerzutniki i druty miedzy nimi i tyle, dlatego ten jezyk jest prostszy
    i jakby blizszy rzeczywistemu sprzetowi;

    J.A


    Akurat z opinią o xst sie nie zgodzę, wielokronie spotkałem się z sytuacja że nie radził sobie z jakaś konstrukcja. Osobiście większe zaufanie mam do produktu Synplicity.

    W tym projekcie sytuacja nie jest taka prosta - wewnątrz procesu wołana jest procedura, na jej interfejsie nie ma sygnałów: reset oraz clk_div z których korzysta. Nie wgłębiałem sie w symulacje takiego kodu, ale wydaje że programu robiący syntezę może sie w tym pogłubić. Ja osobiście bym powklejałbym tą procedurę ile razy trzeba względnie zrealizował zliczanie w osobnym procesie. Tak jak jest teraz, to wynik zależy od inteligencji programu robiącego syntezę(a ma co optymalizować)

    Jeśli układ po implementacji miałby sie zachowywać inaczej niż kod w symulacji to program do syntezy powinien przynajmniej sypać warning-ami.

    Verilog został stworzony do opisu układów elektronicznych więc pewnie dlatego twórcy pamiętali że w elektronice "sa bramki, przerzutniki..."

    Można możyć konstrukcje VHDL, których program do syntezy nawet nie stara się dokładnie zrealizować w sprzęcie ... tylko po co?

    borsukh napisał:

    [g.d.] nie do końca zrozumiałem o co ci chodzi, wprowadzenie czegokolwiek skutkuje wygenerowaniem logiki. Jak ja to rozumiem, wprowadzenie variable do syntezy to wprowadzenie jakiegoś układu asynchronicznego do, w tym wypadku, architektury synchronicznej.


    Nieprecyzyjnie sie wyraziłem. Chodziło mi o logikę asynchroniczną (jeśli przerzutnik zatrzaskujący sygnał również nazwać logiką). "Architektury synchroniczna" składa się z logiki asynchronicznej poprzecinanej przerzutnikami działajacymi na wspólnym sygnale(ach) zegarowym. Do modelowania tejże logiki asynchronicznej świetnie nadają sie variable, szczególnie jeśli jest on spora.

    borsukh napisał:
    Czy wobec tego zmiania sygnału count9 na variable wewnątrz procedury powinna również działać? Po syntezie z takim rozwiązaniem program nie działa w ogóle...


    Zamienienie count9 na variable napewno sprawi że kolejność "--linia 1" i "--linia 2" będzie mieć znaczenie. Po syntezie i implementacji przekłada sie na to czy za "drutem" count9 będzie wstawiany przerzutnik działający na "clk_div" czy nie. Innymi słowy czy wartości sygnałów którymi on steruje zmienią się natychmiast czy dopiero po zboczu sygnału zegarowego.

    Jesli "--linia 1" jest przed "--linia 2". Czyli nie ma przypisań count9 do innych sygnałów "później w kodzie", to czy jest to variable nie powinno mieć żadnego znaczenia.

    Jesli "--linia 2" jest przed "--linia 1". To wartość out1 będzie sie zmieniać o jeden takt zegara wcześniej w przypadku variable. Czyli nie będzie przerzutnika pomiędzy "drutem" count9, a "drutem" out1. ("logika asynchroniczna")

    Ale ja nie wiem dlaczego po wprowadzeniu variable układ nie działał :D

    Zagmatwałem wielce, być może się gdzieś pomyliłem, jeśli tak to poprawcie :D
  • #11 4483958
    J.A
    Poziom 28  
    Posty: 596
    Pomógł: 159
    Ocena: 12
    [g.d] napisał:
    wielokronie spotkalem sie z sytuacja ze nie radzil sobie z jakas konstrukcja.

    czytam rozne artykuly czy opinie tu i tam i nie spotkalem sie z narzekaniami
    na ise, ale wlasnych doswiadczen nie mam, przyznaje uczciwie;
    co to znaczy nie radzil sobie, - powiedzial, ze nie umie, zrobil logike dzialajaca blednie ?
    [a synplify czy certify dokladnie ten sam rtl przetlumaczyl na dzialajaca netliste ?]
    [g.d] napisał:
    W tym projekcie sytuacja nie jest taka prosta - wewnatrz procesu wolana jest procedura
    /.../

    ja patrze na to tak: w fpga mam ff, bramki i polaczenia miedzy nimi,
    zadna wyrafinowana filozofia;
    jesli musze sie zastanawiac, co zrobi kompilator w zaleznosci od kolejnosci
    linii w kodzie, jak sie zmieni efekt kompilacji jesli zmienie variable na signal
    czy integer, to cos tu nie gra, taki jezyk jest dobry do cwiczen intelektualnych,
    a nie do pracy;
    o szczegolach i subtelnosciach vhdl nie podejmuje sie dyskutowac, bo juz od
    dawna go nie uzywam aktywnie, jedynie czasami musze zrozumiec cos napisanego
    przez innych;
    nie lubie vhdl i dobrowolnie do niego juz nie wroce;
    [g.d] napisał:
    Jesli uklad po implementacji mialby sie zachowywac inaczej niz kod w symulacji

    tylko skad takie ise ma wiedziec, ze bedzie roznica ?
    musialby przesymulowac rtl i netliste post place&route...
    nawiasem mowiac, quartus czasem daje mi ostrzezenia, ze mozliwe jest 'nieadekwatne'
    zachowanie w czasie symulacji, ale nie rozwine tematu, bo jak dotad zawsze
    ignorowalem te warningi;

    a przy okazji - co cie tak ubawilo w pralce ?
    napisalem cos qlupiego, czy zawodzi mnie poczucie humoru ?
    J.A
  • #12 4484296
    [g.d.]
    Poziom 18  
    Posty: 174
    Pomógł: 31
    J.A napisał:
    [g.d] napisał:
    wielokronie spotkalem sie z sytuacja ze nie radzil sobie z jakas konstrukcja.

    czytam rozne artykuly czy opinie tu i tam i nie spotkalem sie z narzekaniami
    na ise, ale wlasnych doswiadczen nie mam, przyznaje uczciwie;
    co to znaczy nie radzil sobie, - powiedzial, ze nie umie, zrobil logike dzialajaca blednie ?
    [a synplify czy certify dokladnie ten sam rtl przetlumaczyl na dzialajaca netliste ?]


    Nie poradził, sobie w sensie że wypisał komunikat że jest błąd składni, albo że coś jest nie supportowane, a w innym programi do syntezy przeszedł bez błędu. No i oczywiście czasami sie zapętlał zajmujac 99% mocy procesora, nie robiąc jednocześnie żadnych postępów.

    J.A napisał:

    ja patrze na to tak: w fpga mam ff, bramki i polaczenia miedzy nimi,
    zadna wyrafinowana filozofia;
    jesli musze sie zastanawiac, co zrobi kompilator w zaleznosci od kolejnosci
    linii w kodzie, jak sie zmieni efekt kompilacji jesli zmienie variable na signal
    czy integer, to cos tu nie gra, taki jezyk jest dobry do cwiczen intelektualnych,
    a nie do pracy;

    Zgadzam sie o tyle ze spora cześć VHDL nie jest przydatna w projektowaniu elektroniki. Co do przypisań typu "blocking" i "non-blocking" to taki sam mechanizm jest w Verilogu. Co do ćwiczeń intelektualnych ... no coż, taka praca :D

    J.A napisał:

    o szczegolach i subtelnosciach vhdl nie podejmuje sie dyskutowac, bo juz od
    dawna go nie uzywam aktywnie, jedynie czasami musze zrozumiec cos napisanego
    przez innych;
    nie lubie vhdl i dobrowolnie do niego juz nie wroce;


    To mogę Ci tylko pozazdrościć.

    J.A napisał:

    [g.d] napisał:
    Jesli uklad po implementacji mialby sie zachowywac inaczej niz kod w symulacji

    tylko skad takie ise ma wiedziec, ze bedzie roznica ?
    musialby przesymulowac rtl i netliste post place&route...
    nawiasem mowiac, quartus czasem daje mi ostrzezenia, ze mozliwe jest 'nieadekwatne'
    zachowanie w czasie symulacji, ale nie rozwine tematu, bo jak dotad zawsze
    ignorowalem te warningi;

    Ja już się tego oduczyłem, po każdej większej zmianie w kodzie studiuje to co jest w tym log-u.

    ISE/Quartus tego nie wie, jedynie sygnalizuje potencjalne pułapki i według mnie warto raz na jakis czas ten log przeczytać, szczególnie jeśli coś nie działa.

    J.A napisał:

    a przy okazji - co cie tak ubawilo w pralce ?
    napisalem cos qlupiego, czy zawodzi mnie poczucie humoru ?
    J.A


    To już na priva :D

Podsumowanie tematu

LABEL_AI_GENERATED
Dyskusja dotyczy syntezowalności procedur w maszynie stanów VHDL, na przykładzie prostego licznika sekundowego z podziałem na dziesiątki i jedności. Poruszono problem wyścigów (race conditions) wynikających z nieprawidłowego przypisywania sygnałów w procesie, zwłaszcza gdy sygnał jest aktualizowany i odczytywany w tym samym cyklu zegara. Zasugerowano, że problem ten może być efektem symulacji, a nie rzeczywistego działania sprzętu, gdyż w FPGA sygnał zegara jest rozprowadzany dedykowanymi ścieżkami, co minimalizuje opóźnienia. Wskazano dwa potencjalne rozwiązania: synchronizację przypisywania wartości licznika do rejestru w różnych fazach zegara lub wprowadzenie warunków blokujących liczenie podczas zapisu. Omówiono różnice między sygnałami (signal) a zmiennymi (variable) w VHDL, podkreślając, że zmienne aktualizują się natychmiast i mogą generować logikę asynchroniczną, co może powodować problemy po syntezie. Zwrócono uwagę, że VHDL powstał jako język do modelowania, niekoniecznie sprzętu, co powoduje rozbieżności między symulacją a syntezą. W dyskusji pojawiły się opinie na temat narzędzi do syntezy, gdzie Xilinx ISE bywa krytykowany za ograniczenia, a Synplicity uznawany za bardziej niezawodny. Podkreślono, że syntezator powinien generować ostrzeżenia, gdy kod może prowadzić do niejednoznaczności działania sprzętu. Wskazano, że najlepszą praktyką jest unikanie wywoływania procedur bez sygnałów zegara i resetu w ich interfejsie oraz rozważenie implementacji licznika w osobnym procesie zamiast wielokrotnego wywoływania procedury w maszynie stanów.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA