Hallo, guten Tag.
Ich bekomme diese Fehlermeldung:
Error (10822): HDL error at ram_ram.vhd(58): couldn't implement
registers for assignments on
this clock edge.
Ich weis nicht, was ich da ändern soll?
Danke.
Gruss
peter schrieb:> if address_z1 <= 255 then> address_z1 := address_z1 +1;> address2 <=address_z1;> end if;> end if;
Kann sein, dass das das Problem ist. Du fragst die Adresse mit
rising_edge ab und inkrementierst sie darauf hin. Da es sich dabei um
eine Variable handelt, wird diese "sofort" geupdatet und nicht erst zum
nächsten Takt.
variable address_z3 : integer range 0 to 255 := 0;
variable address_z2 : integer range 0 to 255 := 0;
variable address_z1 : integer range 0 to 255 := 0;
ändere diese variablen mal in signale um, dann sollte es gehn.
Patrick schrieb:> Kann sein, dass das das Problem ist. Du fragst die Adresse mit> rising_edge ab und inkrementierst sie darauf hin. Da es sich dabei um> eine Variable handelt, wird diese "sofort" geupdatet und nicht erst zum> nächsten Takt.
nope, das waer im Prinzip legitim.
Das Problem ist dass der address_z2 / address_z3 Ramsch nicht im
getakteten Teil des Prozesses stattfindet, sondern im kombinatorischen.
Zeigt wiedermal ein Vorteil der
Du beschreibst Register, deren Ausgänge sich zum einen mit der
Taktflanke ändern sollen, aber gleichzeitig auch unabhängig von der
Taktflanke sein sollen.
Sowas gibt es nicht
z.B. hier:
Danke für eure mühe.
---------------------
......
datain2<=dataout1;
end if;
end if;
end if;
end process;
----------------------
Da hatte ich ein "end if;"vergessen.
jetzt werden die Rams beschrieben gelesen und angezeigt mit Led's.
Die Fehlermeldung war für mich nicht nachvollziehbar.
Danke.
Gruss
peter schrieb:> Die Fehlermeldung war für mich nicht nachvollziehbar.
Du hättest es aber recht leicht anhand der Identebenen (Einrückungen)
sehen können:
1
process(clock)
2
begin
3
ifrising_edge(clock)then
4
endif;
5
6
ifsw0='1'then
7
endif;
8
9
ifsw1='1'then
10
endif;
11
endprocess;
12
13
led_g<=dataout2;
14
endBehavioral;
Die kann man nämlich gut nutzen, um seinen Quelltext verständlich und
lesbar darzustellen...
peter schrieb:> Da hatte ich ein "end if;"vergessen.
Mitnichten! Es hat nicht gefehlt (das hätte der Synthesizer shcon
angemeckert, probiers aus), sondern es war an der falschen Stelle, so
dass du Hardware beschrieben hast, die der Synthesizer nicht umsetzen
kann.
Hmm.., verstehe ich jetzt nicht.
so war es mit der Fehlermeldung:
---------------------
..........
datain2<=dataout1;
end if;
end if;
end process;
---------------------
so ist es ohne der Fehlermeldung:
---------------------
..........
datain2<=dataout1;
end if;
end if;
end if;
end process;
---------------------
Danke.
Gruss
Also, nehme ich mal deine originale VHDL Beschreibung und bekomme damit:
1
WARNING:Xst:819 - "C:/..." line 51: One or more signals are missing in
2
the process sensitivity list. ... The missing signals are:
3
<sw0>, <sw1>, <dataout1>
ALARM! Das hätte man bei einem getakteten Prozess nicht erwartet! Denn
da gehört nur der Takt in die Sensitivliste.
Und dann
1
WARNING:Xst:737 - Found 8-bit latch for signal <address_z2>. Latches
2
may be generated from incomplete case or if statements. We do not recommend
3
the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
4
WARNING:Xst:737 - Found 8-bit latch for signal <address_z3>. Latches ....
5
WARNING:Xst:737 - Found 8-bit latch for signal <datain2>. Latches ....
6
WARNING:Xst:737 - Found 8-bit latch for signal <address1>. Latches ....
ALARM, ALARM, ALARM!!! Warum sollte es bei einem getakteten Prozess
Latches geben? Da muss irgendwas nicht passen!
Und wenn ich jetzt einfach hinten ein "end if;" anhänge, dann bekomme
ich wie erwartet einen Fehler, der genau dieses if anmeckert:
1
ERROR:HDLParsers:164 - "C:/...." Line 87. parse error, unexpected IF, expecting PROCESS
Ergo: du hast das "end if;" VERSCHOBEN. Und zwar so:
1
process(clock)
2
variableaddress_z3:integerrange0to255:=0;
3
variableaddress_z2:integerrange0to255:=0;
4
variableaddress_z1:integerrange0to255:=0;
5
6
begin
7
ifrising_edge(clock)then
8
if(cnt<20000000andsw2='1')then
9
cnt<=cnt+1;
10
else
11
cnt<=0;
12
we2<='0';
13
ifaddress_z1<=255then
14
address_z1:=address_z1+1;
15
address2<=address_z1;
16
endif;
17
endif;
18
-- end if; ---------> hier raus
19
20
ifsw0='1'then
21
address_z1:=0;
22
address_z2:=0;
23
address_z3:=0;
24
endif;
25
26
ifsw1='1'then
27
we2<='1';
28
ifaddress_z2<=255then
29
address_z3:=address_z3+1;
30
address_z2:=address_z2+1;
31
address1<=address_z2;
32
address2<=address_z3;
33
34
datain2<=dataout1;
35
endif;
36
endif;
37
endif;-- <---------- hier rein
38
39
endprocess;
Das ist klar wie Kloßbrühe!
Mit "wait until rising_edge()" wäre das nicht passiert, deshalb verwende
ich es so gern...
1
process
2
variableaddress_z3:integerrange0to255:=0;
3
variableaddress_z2:integerrange0to255:=0;
4
variableaddress_z1:integerrange0to255:=0;
5
6
begin
7
waituntilrising_edge(clock);
8
if(cnt<20000000andsw2='1')then
9
cnt<=cnt+1;
10
else
11
cnt<=0;
12
we2<='0';
13
ifaddress_z1<=255then
14
address_z1:=address_z1+1;
15
address2<=address_z1;
16
endif;
17
endif;
18
19
ifsw0='1'then
20
address_z1:=0;
21
address_z2:=0;
22
address_z3:=0;
23
endif;
24
25
ifsw1='1'then
26
we2<='1';
27
ifaddress_z2<=255then
28
address_z3:=address_z3+1;
29
address_z2:=address_z2+1;
30
address1<=address_z2;
31
address2<=address_z3;
32
33
datain2<=dataout1;
34
endif;
35
endif;
36
37
endprocess;
Achja, Peter: wenn du das Zeug so leicht wieder vergisst, das ich zum
Thema Bibliotheken und Variablen schon alles geschrieben habe, dann
DRUCK ES DIR AUS und häng es an die Wand.
Lothar Miller schrieb:> dann DRUCK ES DIR AUS und häng es an die Wand.
Und was soll das bringen? Er schaut es eh nicht an. Genauso wenig, wie
seine Fehlermeldungen oder ein VHDL-Buch oder sonstwas.
Und gleich kommt sicher irgendwas in der Art:
"Jup, danke. Mein blöder Editor hat einfach das end if verschoben"
Lothar Miller schrieb:> Achja, Peter: wenn du das Zeug so leicht wieder vergisst, das ich zum> Thema Bibliotheken und Variablen schon alles geschrieben habe, dann> DRUCK ES DIR AUS und häng es an die Wand.
Ich bin ja dafuer, dass Peter uns mal den folgenden, unheimlich
komplizierten Design (pardon, das Programm) erklaert, also was machen
die LEDs 1..4?:
1
libraryieee;
2
useieee.std_logic_1164.all;
3
useieee.numeric_std.all;
4
entityvariable_topis
5
port(
6
clk:instd_logic;
7
led1:outstd_logic:='0';
8
led2:outstd_logic:='0';
9
led3:outstd_logic:='0';
10
led4:outstd_logic:='0'
11
);
12
end;
13
architecturertlofvariable_topis
14
constantOUTBIT:naturalrange0to3:=3;
15
signalcnt:unsigned(3downto0):=(others=>'0');
16
begin
17
proc_cntvar:process
18
variablecnt:unsigned(3downto0):=(others=>'0');
19
begin
20
waituntilrising_edge(clk);
21
led1<=cnt(OUTBIT);
22
cnt:=cnt+1;
23
led2<=cnt(OUTBIT);
24
endprocess;
25
proc_cntsig:process
26
begin
27
waituntilrising_edge(clk);
28
led3<=cnt(OUTBIT);
29
cnt<=cnt+1;
30
led4<=cnt(OUTBIT);
31
endprocess;
32
endrtl;
Da Peter ja aus Prinzip keinen Simulator benutzt, haenge ich die TB auch
mal an...
peter schrieb:> Hmmm.. Led2 und 4 gehen an , wenn das 3.Bit von cnt erreicht ist.
Das ist prinzipiell richtig, aber halt nur unvollstaendig...
Auch die LEDs 1 und 3 gehen an. Und interessant sind die Phasenlagen der
4 LEDs... Das kannst du mit einem 4-Kanal Oszilloskop an der echten HW
nachschauen oder eben halt den Simulator bemuehen...