początki co żle?

Witam Przy pomocy xilinx'a i jego web ISE (czy jak to tam się nazywa) Chciałem w verilogu zrobić prosty licznik dziesiętny. Niestety ciągle dostaję komunikat błędu. W końcu przepisałem żywcem przykład z książki (W Wrona

- Verilog) i też dostałem :' Xst:528 - Multi-source in Unit <licz_ksiazka> on signal <out<0>>; this signal is connected to multiple drivers.'. Co prawda tylko dla wyjścia <0> a nie jak u mnie dla wszystkich. O co chodzi bo chyba przykład jest poprawny? Na wszelki przypadek załączam przykład: module licz_ksiazka( input cp, input enable, input r, input in, output [3:0] out, input load, input u_nd, output z ); reg [3:0] out_data;

assign out=out_data; assign z =(out_data == 'b0) ? 0: 1;

always @(posedge cp) if (enable && u_nd) out_data <= out_data+1; else if (enable && !u_nd) out_data <= out_data-1; always @(r or load) if (r && load) out_data <= in; else if (r) out_data <= 'b0; endmodule

To może jeszcze to co ja wymyśliłem i tez nie chce wygenerować pliku programującego: module dzies_2( input clk, input zezwol, output przen, output [3:0] q, input reset ); reg zerowanie; reg [3:0] licznik;

assign przen = zezwol & zerowanie ; assign q = licznik ;

always @(reset) begin licznik <= 4'd0; end

always@(posedge clk) begin if (zezwol == 1) begin if (zerowanie == 1) licznik <= 4'd0; else licznik <= licznik + 1; if (licznik == 4'd8) zerowanie <= 1; else zerowanie <= 0; end end

endmodule

pozdrawiam MArek

Reply to
ToTylkoJa
Loading thread data ...

W dniu 03.05.2011 18:59, ToTylkoJa pisze:

No więc veriloga jeszcze nie znam, ale spróbuję odpowiedzieć na podstawie znajomości vhdl.

Jesteś pewien, że in i out nie powinny mieć takiej samej szerokości?

[...]

Powyżej masz dwa "procesy" w których przypisujesz out_data (a więc pośrednio out) - w pierwszym całe out(3 downto 0) a w drugim samo out(3). Coś takiego się nie syntetyzuje bo kompilator nie wie co zrobić jak zajdą oba warunki jednocześnie. Musisz albo wprowadzić sygnały pośrednie i sterujące, albo upchnąć wszystko w jeden proces i odpowiednio rozstrzygnąć za pomocą if-else.

Reply to
Michoo

Użytkownik Michoo napisał: [ciach]

Wstyd sie przyznac błąd przy przepisywaniu książki. Już poprawiłem in oraz out mają tą samą szerokość ale błąd jest nadal generowany. Tym razem tak jak w moim liczniku dla wszystkich wyjść od out<3> do out<0> nadal jest:'Xst:528 - Multi-source in Unit <licz_ksiazka> on signal <out<3>>; this signal is connected to multiple drivers.' i tak jeszcze 3 linijki dla out<2> ,... aż do out<0>

Już to poprawiłem. Wychodzi mi że kompilator nie chce przyjąć dwóch procesów (always @). Zaremowanie linijek od resetu asynchronicznego lub właściwego zlicznia pomaga. Tyle że nigdzie nie przeczytałem że nie może być kilku bloków od innych warunków. Poza tym ktoś w książce podał zły (niekompilowalny) przykład? Zastanawiam się czy ten web ISE nie ma jakiś ograniczeń, lub ja go źle skonfigurowałem.

pozdrawiam MArek

Reply to
ToTylkoJa

W dniu 03.05.2011 20:15, ToTylkoJa pisze:

Jak już pisałem - albo robisz dodatkowe sygnały, albo musisz zrobić jeden proces i odpowiednio rozłożyć if-else: PSEUDOKOD: if(!reset asynchroniczny){ if(zbocze) licz; }else{ resetuj }

A co? książki piszą ludzie.

Z tego co wiem to po prostu sprzęt nie doczekał się ciągle porządnego języka do programowania. Mam teraz na studiach magisterskich na trzech przedmiotach VHDL i jak odkrywam (albo słyszę o) kolejne "ciekawe" zjawiska i niespójności pomiędzy symulacją a syntezą tego samego kodu to człowiek się może załamać.

Najprostszy przykład: process(clk) begin out <= in; end process; NIE działa tak jak się człowiek spodziewa - mimo, że w symulacji ładnie kopiuje wejście na wyjście w takt zegara to w FPGA będzie zmieniać stan wyjść gdy tylko zmienią się wejścia.

Trzeba więc napisać: process(clk) begin if rising_edge(clk) then out <= in; end if; end process;

Reply to
Michoo

A co tu jest nie tak wg Ciebie? Wszystko działa zgodnie z zapisem. Na liście czułości w pierwszym przypadku masz clk więc symulator tylko wylicza nowy stan w chwili zmian sygnału "czułego" - clk. W rzeczywistości to masz współbieżne przypisanie - poprostu out jest połączony "kawałkiem przewodu" z in. W drugim przypadku masz klasyczny zatrzask - czyli wyjście może zmienić się w takt zegara. Po prostu nie ma się co załamywać bo wszystko działa zgodnie z fizyką - trzeba się tej fizyki wpierw nauczyć i ją czuć.

MiSter

Reply to
MiSter

W dniu 03.05.2011 20:59, MiSter pisze:

Właśnie. Czyli zsyntetyzowany core zachowuje się inaczej niż to wynika z opisu. Tylko w takiej sytuacji należałoby zmienić standard języka i dostosować symulatory a nie udawać, że wszystko jest ok.

Mam klasyczny flip-flop (D, bez wyjścia /Q). Latch wyglądałby tak: process(clk) begin if clk='1' then out<= in; end if; end process;

Problemem nie jest fizyka tylko inne zachowanie symulacji i syntezy.

Takie a nie inne działanie wynika z prostego faktu - gdyby kompilator po cichu generował sprzętowy odpowiednik if xxx'event z każdego xxx na liście czułości (a tak by wygladała realizacja tego co opisuje standard) to wszystko byłoby strasznie wolne i zasobożerne. Alternatywą jest wprowadzenie do standardu, że niewymienienie na liście czułości czegoś z prawej strony podstawienia skutkuje błędem, ale "taka zmiana w języku" jest niedopuszczalna. Mamy więc sytuację w której symulacja sobie a synteza sobie, mimo, że symulujemy przecież po to, żeby uzyskać przewidywalne zachowanie po syntezie.

Reply to
Michoo

To specyfika języka... Podobnie jest w VHDL :).

To trochę tak, jakbyś projektował układ... Jeden "blok" (always) to jakby jedna kartka schematu... co Ci wyjdzie, jak na dwóch różnych kartkach będziesz miał wyjścia o tej samej nazwie?? Które będzie "silniejsze"?? Musisz to tak rozrysować/rozpisać, aby miało to sens... Więc sygnał wyjściowy może być przypisywany TYLKO W JEDNYM BLOKU ALWAYS. W przeciwnym wypadku dostaniesz błąd...

Natomiast nic nie stoi na przeszkodzie, żeby w jednym bloku przypisywać wiele sygnałów... Tak więc Twój licznik powinien wyglądać mniej więcej tak:

always @(load or reset or posedge cp) if(reset) out <= 0; else if(load) out <= in; else if(posedge cp) out <= out + 1;

To tak z pamięci piszę, więc nie kopiuj tego w prost, ale wyczuj ogólną ideę.... Aha, oczywiście jest to licznik z asynchronicznym resetem, asynchronicznym load'em, i reset ma wyższy priorytet niż load, cp ma najniższy...

Reply to
Konop

To nie błąd konfiguracji, to specyfika języka (VHDL ma też podobnie)

Musisz pamiętać o tym, że to jest język OPISU SPRZĘTU... a nie język programowania... To znaczy, każdy blok always opisuje jakiś sprzęt... i teraz okazuje się, że sygnał out jest generowany przez dwa różne bloki... To trochę tak, jakbyś rysował schemat układu... Jeden "blok" (always) to jakby jedna kartka schematu... co Ci wyjdzie, jak na dwóch różnych kartkach będziesz miał wyjścia o tej samej nazwie?? Który schemat ma sterować tym wyjściem?? Raz ten, raz ten, ale skąd układ ma wiedzieć kiedy który?? Musisz to tak rozrysować/rozpisać, aby miało to sens... Więc sygnał wyjściowy może być przypisywany TYLKO W JEDNYM BLOKU ALWAYS. W przeciwnym wypadku dostaniesz błąd... Natomiast nic nie stoi na przeszkodzie, żeby w jednym bloku przypisywać wiele sygnałów...

Twój licznik powinien wyglądać mniej więcej tak:

always @(load or reset or posedge cp) if(reset) out <= 0; else if(load) out <= in; else if(posedge cp) out <= out + 1;

To tak z pamięci piszę, więc nie kopiuj tego w prost, ale wyczuj ogólną ideę.... Aha, oczywiście jest to licznik z asynchronicznym resetem, asynchronicznym load'em, i reset ma wyższy priorytet niż load, cp ma najniższy...

Reply to
Konop

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.