Quartus 5.1, EPM7128 (długawe...)

Witam,

Mam następujący problem: Chcę użyć pamięci (banków) o łącznej przestrzeni adresowej 24 bity. Z uP będę podawał po zresetowaniu maszyny stanu sygnałem "rst", w kolejnych taktach sygnału zegarowgo "clk" 3 porcje 8-bitowe adresu "Din". Po ich przesłaniu PLD ma wystawić na piny "Dout" podłączone do banków pamięci cały kompletny 24-bitowy adres. Dalsza zmiana sygnału "clk" ma nie mieć wpływu na adresy. Kod, którym chciałem to zrealizować (po skróceniu ilości bitów adresów) zamieszczam poniżej:

-------------------------------------------- LIBRARY ieee; USE ieee.std_logic_1164.all;

ENTITY Test_IO IS PORT( clk : IN STD_LOGIC; rst : IN STD_LOGIC; Din : IN STD_LOGIC_VECTOR(1 downto 0); Dout : OUT STD_LOGIC_VECTOR(3 downto 0) ); END Test_IO;

ARCHITECTURE Test_IO_architecture OF Test_IO IS TYPE t_state IS ( s0, s1, s2, s3 ); SIGNAL state, state_nx: t_state; BEGIN

PROCESS ( clk, rst ) BEGIN IF rst = '0' THEN state <= s0; -- resetowanie ukladu / start maszyny ELSIF ( clk'EVENT and clk = '1' ) THEN state <= state_nx; -- przejscie do nastepnego stanu maszyny ELSE state <= state; -- taki rzut na bandę, z braku pomyslow END IF; END PROCESS;

PROCESS ( state, Din ) VARIABLE tmp1: STD_LOGIC_VECTOR(1 downto 0); VARIABLE tmp2: STD_LOGIC_VECTOR(1 downto 0); BEGIN CASE state IS WHEN s0 =>

state_nx <= s1; WHEN s1 => -- przepisanie 1-ej czesci adresu tmp1 := Din; state_nx <= s2; WHEN s2 => -- przepisanie 2-ej czesci adresu tmp2 := Din; state_nx <= s3; WHEN s3 => -- przepisanie czesci adresu na wyjscie Dout <= tmp1 & tmp2; state_nx <= s3; END CASE; END PROCESS; END Test_IO_architecture;

-----------------------------------------

Na symulacji wygląda wszystko bardzo ładnie, ale zastanawia mnie warning: "Info: Found combinational loop of 1 nodes".

Poniżej wybrana część z komilacji projektu:

----------------------------------------- Info:

******************************************************************* Info: Running Quartus II Fitter Info: Version 5.1 Build 213 01/19/2006 Service Pack 1 SJ Web Edition Info: Processing started: Thu Feb 23 17:00:56 2006 Info: Command: quartus_fit --read_settings_files=off

--write_settings_files=off Test1 -c Test1 Info: Selected device EPM7128SLC84-15 for design "Test1" Info: Quartus II Fitter was successful. 0 errors, 0 warnings [...] Info:

******************************************************************* Info: Running Quartus II Timing Analyzer [...] Info: Command: quartus_tan --read_settings_files=off

--write_settings_files=off Test1 -c Test1 Info: Started post-fitting delay annotation Info: Delay annotation completed successfully Warning: Timing Analysis does not support the analysis of latches as synchronous elements for the currently selected device family Info: Found combinational loop of 1 nodes Info: Node "Test_IO:inst|Dout[0]~46" Info: Found combinational loop of 1 nodes Info: Node "Test_IO:inst|Dout[1]~42" Info: Found combinational loop of 1 nodes Info: Node "Test_IO:inst|Dout[2]~38" Info: Found combinational loop of 1 nodes Info: Node "Test_IO:inst|Dout[3]~34" Info: Found combinational loop of 1 nodes Info: Node "Test_IO:inst|tmp2[0]~26" Info: Found combinational loop of 1 nodes Info: Node "Test_IO:inst|tmp2[1]~22" Info: Found combinational loop of 1 nodes Info: Node "Test_IO:inst|tmp1[0]~26" Info: Found combinational loop of 1 nodes Info: Node "Test_IO:inst|tmp1[1]~22" [..ciach..]

-----------------------------------------

Czy mam się tym przejmować - o co chodzi z grubsza wiem - ale nie mam pomysłu na wyeliminowanie przyczyny.

Pozdrawiam, Grzegorz Kępiński

Reply to
invalid unparseable
Loading thread data ...

"Grzegorz Kępiński":

zobacz w quartus rtl view [tools] czy dostales to, czego oczekujesz; moim zdaniem sa tu pewne niezgrabnosci, asynchroniczny reset, rejestry jako latche i stany s1-s3 jako latch-enable; trudnosci przy pierwszym uzywaniu hdl biora sie stad [miedzy innymi], ze konstrukcje przydatne w modelowaniu/symulacji wykorzystuje sie takze do syntezy;

ja akurat znam vhdl jedynie z widzenia, wiec moja poprawka moze wygladac topornie z punktu widzenia skladni, ale daje po syntezie obrazek, jaki chyba realizuje to, co opisales na poczatku;

LIBRARY ieee; USE ieee.std_logic_1164.all;

ENTITY test_io IS PORT( clk : IN STD_LOGIC; rst : IN STD_LOGIC; Din : IN STD_LOGIC_VECTOR(1 downto 0); Dout : OUT STD_LOGIC_VECTOR(3 downto 0) ); END Test_IO;

ARCHITECTURE Test_IO_architecture OF Test_IO IS TYPE t_state IS ( s0, s1, s2, s3 ); SIGNAL state, state_nx: t_state; signal tmp1: STD_LOGIC_VECTOR(1 downto 0); signal tmp2: STD_LOGIC_VECTOR(1 downto 0); signal D: STD_LOGIC_VECTOR(3 downto 0);

BEGIN PROCESS ( clk, rst ) BEGIN IF rst = '0' THEN state <= s0; -- resetowanie ukladu / start maszyny ELSIF ( clk'EVENT and clk = '1' ) THEN state <= state_nx; -- przejscie do nastepnego stanu maszyny ELSE state <= state; END IF; END PROCESS;

PROCESS ( state, Din )

-- VARIABLE tmp1: STD_LOGIC_VECTOR(1 downto 0);

-- VARIABLE tmp2: STD_LOGIC_VECTOR(1 downto 0); BEGIN CASE state IS WHEN s0 =>

state_nx <= s1; WHEN s1 =>

-- tmp1 := Din; state_nx <= s2; WHEN s2 =>

-- tmp2 := Din; state_nx <= s3; WHEN s3 =>

-- Dout <= tmp1 & tmp2; state_nx <= s3; END CASE; END PROCESS;

process (clk) begin if ( clk'EVENT and clk = '1' ) then if (state = s1) then tmp1 <= Din; else tmp1 <= tmp1; end if; if (state = s2) then tmp2 <= Din; else tmp2 <= tmp2; end if; if (state = s3) then D <= tmp1 & tmp2; else D <= D; end if;

end if; end process; Dout <= D; END test_io_architecture;

JA

Reply to
JA

[..]

Trzeba bardzo uważać na takie typy sygnałów...

Zmienna typu "t_state" realizowana jest po prostu jako kolekcja sygnałów jednobitowych (drutów!) i stan s1 oznacza że jest jedynka na jednym drucie a zera na innych... Jeśli teraz w procesie kombinatoryjnym zmiana "state_nx" nastąpi bardzo blisko, tuż przed użyciem jej w procesie synchronicznym (czyli tuż przed lub w trakcie trwania rosnącego zbocza "clk") to będzie bida, gdy poprzedni stan zniknie a nowy się jeszcze nie pojawi - wszystkie bity stanu będą zero, i nam maszynka stanów zgłupieje...

Miałem taki przypadek bardzo niedawno - zrobiłem projekt UARTa w VHDL i tam odbiornik RX miał właśnie taką maszynkę stanów w której przechodziłem ze stanu czekania na bit startu asynchronicznie do stanu synchronizacji trwającego 1/2 czasu trwania bitu tylko na podstawie stanu wejścia RXDATA. Umnkęło mojej uwadze to, że zmiana RXDATA nastąpi całkowicie asynchronicznie do sygnału zegarowego który taktuje moją maszynę stanów - no i mój UART miał dziwną tendencję do "zakleszczania" się po kilku dniach pracy... Długie i bolesne testy kończyły się niemożnością powtórzenia problemu w labie i dopiero podłączenie wejścia mojego UARTU do wyjścia generatora fali prostokątnej i zmodulowania tej fali FM dało gwarancję zakleszczenia się UARTA za każdym razem :-))) Wtedy łatwo już było o diagnozę i naprawę błędu: puściłem linię RXDATA przez zatrzask sterowany przeciwnym zboczem zegara RXCLOCK (16x baud) i UART pracuje jak ta lala...

W sumie trochę zawiodłem się na implementacji maszyny stanów w VHDL... Synteza takiej zmiennej na luźnych bitach to chyba nienajlepszy pomysł... To coś jakbyś miał w kodzie w C maszynę stanów i zmienna stanów była liczbą integer ale w pewnych okolicznościach przyjmowała wartość dwa i siedem ósmych zamiast równych 2 lub 3 :-))) Twój kod w C też by mocno zgłupiał z taką zmienną stanu.

Reply to
Pszemol

"Pszemol":

?

odpowiadasz na moj post, czy autora watku ? napisalem, ze asynchroniczny reset jest zlym pomyslem, ale zapomnialem to poprawic w swojej wersji; a co do 't_state', to ja wiem, co to znaczy kodowanie maszyny stanow 'one hot'; takie kodowanie jest obecnie 'default' we wspolczesnych syntetyzatorach hardware, ale zawsze mozna to zmienic;

swieta racja, tyle, ze nie jest to wlasnosc kodowania 'one hot', a ogolnie wlasnoscia elektroniki, ze sygnaly rozchodza sie ze skonczona szybkoscia; stany FSM, jesli czyms steruja [ a po to sie tworzy FS], trzeba zdekodowac, co trwa skonczony czas, i oczywiscie calosc nie moze pracowac z wieksza czestotliwoscia, niz to wynika z czasu dekodowania; akurat 'one hot' jest najlepszym mozliwym kodowaniem FSM, z punktu widzenia szybkosci; za to zuzywa najwiecej FF, co kiedyc bylo minusem, we wspolczesnych FPGA nie jest, raczej logiki kombinacyjnej zabraknie niz FF;

no w tym tkwi sedno, ktorego nie dostrzegaja poczatkujacy uzytkownicy FPGA, ze asynchroniczne sygnaly 'set, reset, start' itd. nie docieraja do wszystkich FF w tym samym czasie, co musi doprowadzic od czasu do czasu do niezdefiniowanego stanu ukladu;

nie bardzo rozumiem powyzsza konkluzje ... :( w vhdl i verilog da sie zrobic FSM dokladnie taka, jaka chcemy, jaka jest wymagana specyfikacja;

problem z verilog czy vhdl polega na tym, ze jezyki te powstaly do MODELOWANIA procesow, nie tworzenia hardware'u, w zwiazku z tym narzedzia syntezy czesto musza sie 'domyslac', co autor mial na mysli, nie zawsze trafnie; innymi slowy, trzeba znac architekture kosci, ktora sie programuje, by sobie wyobrazic, co kompilator zrobi z naszego RTL;

JA

Reply to
JA

Oczywiście dodaję tylko swoje skromne doświadczenie jako komentarz do Twojego przykładowego kodu... :-)

Loozik - ja Cię o nic nie oskarżam :-)) Ja się uczę dopiero...

Ty może wiesz, ale inni może nie

- pisałem do grupy nie do Ciebie na priva...

No własnie ja jestem tym początkującym który nie dostrzegł

- z tym że nie chodziło u mnie o reset (który nawiasem mówiąc też jest asynchroniczny) ale o asynchroniczne wejście danych przełączające stan maszyny.

I o tej niedoskonałości VHDL bardzo łatwo się zapomina... Człowiek czasem niesłusznie podchodzi to tego jak do języka C :-(

Reply to
Pszemol

"JA" napisal:

Sorry ze sie wetne - poczatkujacy (do ktorych i ja sie zaliczam) uzywaja asynchronicznego resetu bo opisujacy go kod wystepuje w VHDLowym "Hello World" w kazdej (bo powiedzmy - wszystkich mi znanych) ksiazce do nauki VHDL :)) Czy mam rozumiec ze: if reset='1' then xxxx elsif clk'EVENT and clk='1' then yyy

nalezaloby zamienic na cos w rodzaju if clk'EVENT and clk='1' then if reset then xxx else yyyy chyba ze sie DOBRZE wie co sie robi? Pozdrawiam GRG

Reply to
Gregor

"Pszemol" :

[...]

o wyrozumialosc prosze, piatkowa noc, kolejne piwo ... absolutnie nie chcialem, by post mial wymowe: 'nie ucz pan ojca ...';

ja bym powiedzial nieco inaczej, nie tyle vhdl jest niedoskonaly, ile ma w sobie mnostwo wlasciwosci, ktore w hardware albo maja sensu, albo prowadza do nieoczekiwanego dzialnia;

JA

Reply to
JA

"Gregor":

[...]

wlasnie; trzeba sobie uswiadomic, ze w fpga czy asic sygnal od zrodla dociera do adresatow [np. reset do rejestrow] w roznym czasie, nawet jesli ta roznica to tylko 0.5 ns, to moze sie zdarzyc taka koincydencja czasowa reset i zegara, ze czesc przerzutnikow jeszcze ma reset, gdy przychodzi zbocze clock, a czesc juz nie, a to zwykle prowadzi do jakichs nieprzewidzianych stanow ukladu;

chyba ze sie wie, co sie robi :)

JA

Reply to
JA

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.