-
1. Data: 2011-05-03 16:59:26
Temat: verilog początki co żle?
Od: ToTylkoJa <m...@n...chce.tego.poczta.fm>
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
-
2. Data: 2011-05-03 17:26:41
Temat: Re: verilog początki co żle?
Od: Michoo <m...@v...pl>
W dniu 03.05.2011 18:59, ToTylkoJa pisze:
> Witam
> Przy pomocy xilinx'a i jego web ISE (czy jak to tam się nazywa) Chciałem
> w verilogu zrobić prosty licznik dziesiętny.
No więc veriloga jeszcze nie znam, ale spróbuję odpowiedzieć na
podstawie znajomości vhdl.
> 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?
> input in,
> output [3:0] out,
Jesteś pewien, że in i out nie powinny mieć takiej samej szerokości?
[...]
> 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
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.
--
Pozdrawiam
Michoo
-
3. Data: 2011-05-03 18:15:20
Temat: Re: verilog początki co żle?
Od: ToTylkoJa <m...@n...chce.tego.poczta.fm>
Użytkownik Michoo napisał:
[ciach]
>
>> input in,
>> output [3:0] out,
> Jesteś pewien, że in i out nie powinny mieć takiej samej szerokości?
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>
> 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ć
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
-
4. Data: 2011-05-03 18:36:57
Temat: Re: verilog początki co żle?
Od: Michoo <m...@v...pl>
W dniu 03.05.2011 20:15, ToTylkoJa pisze:
> Użytkownik Michoo napisał:
> [ciach]
>
>>
>>> input in,
>>> output [3:0] out,
>> Jesteś pewien, że in i out nie powinny mieć takiej samej szerokości?
> 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>
>
>> 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ć
> 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.
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
}
> Poza tym ktoś w książce podał zły
> (niekompilowalny) przykład?
A co? książki piszą ludzie.
> Zastanawiam się czy ten web ISE nie ma jakiś
> ograniczeń, lub ja go źle skonfigurowałem.
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;
--
Pozdrawiam
Michoo
-
5. Data: 2011-05-03 18:59:10
Temat: Re: verilog początki co żle?
Od: "MiSter" <B...@W...PL>
> 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;
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
-
6. Data: 2011-05-03 19:20:40
Temat: Re: verilog początki co żle?
Od: Michoo <m...@v...pl>
W dniu 03.05.2011 20:59, MiSter pisze:
>> 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;
>
>
> 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ł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.
> W drugim przypadku masz klasyczny zatrzask - czyli wyjście może zmienić się
> w takt zegara.
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;
> Po prostu nie ma się co załamywać bo wszystko działa zgodnie z fizyką -
> trzeba się tej fizyki wpierw nauczyć i ją czuć.
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.
--
Pozdrawiam
Michoo
-
7. Data: 2011-05-03 20:44:40
Temat: Re: verilog początki co żle?
Od: Konop <k...@g...pl>
>> 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ć
> 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.
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...
--
Pozdrawiam
Konop
-
8. Data: 2011-05-03 20:49:51
Temat: Re: verilog początki co żle?
Od: Konop <k...@g...pl>
>> 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ć
> 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.
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...
--
Pozdrawiam
Konop
--
Pozdrawiam
Konop