Forum: FPGA, VHDL & Co. Was muss ich bitte bei "clock" ändern, es kommt eine Fehlermeldung.


von peter (Gast)


Lesenswert?

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

1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
use ieee.std_logic_arith.all;
5
6
entity ram_ram is port(
7
  clock : in  std_logic;
8
  led_g : out STD_LOGIC_VECTOR(7 downto 0);
9
  sw0   : in  STD_LOGIC;
10
  sw1   : in  STD_LOGIC;
11
  sw2   : in  STD_LOGIC
12
  ); 
13
end ram_ram; 
14
            
15
architecture Behavioral of ram_ram is
16
17
signal we1      : STD_LOGIC :='0';
18
signal address1 : integer range 0 to 255 := 0; 
19
signal datain1  : STD_LOGIC_VECTOR(7 downto 0);
20
signal dataout1 : STD_LOGIC_VECTOR(7 downto 0);
21
22
signal we2      : STD_LOGIC;
23
signal address2 : integer range 0 to 255 := 0; 
24
signal datain2  : STD_LOGIC_VECTOR(7 downto 0);
25
signal dataout2 : STD_LOGIC_VECTOR(7 downto 0);
26
27
signal cnt      : integer range 0 to 50000000 := 0;
28
29
component ram1 port(
30
  we1      : in  STD_LOGIC; 
31
  address1 : in  integer range 0 to 255 := 0; 
32
  datain1  : in  STD_LOGIC_VECTOR(7 downto 0);
33
  dataout1 : out STD_LOGIC_VECTOR(7 downto 0);
34
  clock    : in  std_logic
35
 );
36
end component;
37
38
component ram2 port(
39
  we2      : in  STD_LOGIC; 
40
  address2 : in  integer range 0 to 255 := 0; 
41
  datain2  : in  STD_LOGIC_VECTOR(7 downto 0);
42
  dataout2 : out STD_LOGIC_VECTOR(7 downto 0);
43
  clock    : in  std_logic
44
 );
45
end component;
46
47
begin
48
io1 : ram1  port map(we1,address1,datain1,dataout1,clock);
49
io2 : ram2  port map(we2,address2,datain2,dataout2,clock);
50
51
process(clock)
52
variable address_z3 : integer range 0 to 255 := 0; 
53
variable address_z2 : integer range 0 to 255 := 0; 
54
variable address_z1 : integer range 0 to 255 := 0; 
55
56
begin
57
  if rising_edge(clock) then
58
    if (cnt<20000000 and sw2='1') then        
59
      cnt <= cnt+1;     
60
    else  
61
      cnt <= 0;
62
      we2<='0';
63
      if address_z1 <= 255 then     
64
        address_z1 := address_z1 +1;
65
        address2  <=address_z1;
66
      end if;  
67
    end if;  
68
  end if;
69
  
70
  if sw0='1' then
71
    address_z1:=0;
72
    address_z2:=0;
73
    address_z3:=0;
74
  end if; 
75
  
76
  if sw1='1' then
77
    we2<='1';
78
    if address_z2 <= 255 then   
79
      address_z3 := address_z3 +1;    
80
      address_z2 := address_z2 +1;
81
      address1<=address_z2;
82
      address2<=address_z3;
83
      
84
      datain2<=dataout1;
85
    end if;  
86
  end if; 
87
end process;  
88
89
led_g <= dataout2;
90
end Behavioral;

: Bearbeitet durch Moderator
von Patrick (Gast)


Lesenswert?

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.

von Roger S. (edge)


Lesenswert?

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
1
wait until rising_edge(clock);

Schreibweise.

Cheers, Roger

von Schlumpf (Gast)


Lesenswert?

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:
1
  if rising_edge(clock) then
2
  ...  address2 <= address_z1;
3
  end if;
4
  if sw1='1' then
5
  ...  address2 <= address_z3;
6
  end if;

von peter (Gast)


Lesenswert?

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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
  if rising_edge(clock) then
4
  end if;
5
  
6
  if sw0='1' then
7
  end if; 
8
  
9
  if sw1='1' then
10
  end if; 
11
end process;  
12
13
led_g <= dataout2;
14
end Behavioral;
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.

: Bearbeitet durch Moderator
von peter (Gast)


Lesenswert?

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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
variable address_z3 : integer range 0 to 255 := 0; 
3
variable address_z2 : integer range 0 to 255 := 0; 
4
variable address_z1 : integer range 0 to 255 := 0; 
5
6
begin
7
  if rising_edge(clock) then
8
    if (cnt<20000000 and sw2='1') then        
9
      cnt <= cnt+1;     
10
    else  
11
      cnt <= 0;
12
      we2<='0';
13
      if address_z1 <= 255 then     
14
        address_z1 := address_z1 +1;
15
        address2  <=address_z1;
16
      end if;  
17
    end if;  
18
--   end if;        ---------> hier raus
19
  
20
  if sw0='1' then
21
    address_z1:=0;
22
    address_z2:=0;
23
    address_z3:=0;
24
  end if; 
25
  
26
  if sw1='1' then
27
    we2<='1';
28
    if address_z2 <= 255 then   
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
    end if;  
36
  end if;      
37
 end if;     --      <----------  hier rein 
38
39
end process;
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
variable address_z3 : integer range 0 to 255 := 0; 
3
variable address_z2 : integer range 0 to 255 := 0; 
4
variable address_z1 : integer range 0 to 255 := 0; 
5
6
begin
7
  wait until rising_edge(clock);
8
  if (cnt<20000000 and sw2='1') then        
9
    cnt <= cnt+1;     
10
  else  
11
    cnt <= 0;
12
    we2<='0';
13
    if address_z1 <= 255 then     
14
      address_z1 := address_z1 +1;
15
      address2  <=address_z1;
16
    end if;  
17
  end if;  
18
 
19
  if sw0='1' then
20
    address_z1:=0;
21
    address_z2:=0;
22
    address_z3:=0;
23
  end if; 
24
  
25
  if sw1='1' then
26
    we2<='1';
27
    if address_z2 <= 255 then   
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
    end if;  
35
  end if;      
36
37
end process;

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.

: Bearbeitet durch Moderator
von Schlumpf (Gast)


Lesenswert?

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"

von berndl (Gast)


Angehängte Dateien:

Lesenswert?

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
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
entity variable_top is
5
port (
6
   clk : in std_logic;
7
   led1 : out std_logic := '0';
8
   led2 : out std_logic := '0';
9
   led3 : out std_logic := '0';
10
   led4 : out std_logic := '0'
11
);
12
end;
13
architecture rtl of variable_top is
14
   constant OUTBIT : natural range 0 to 3 := 3;
15
   signal cnt : unsigned (3 downto 0) := (others => '0');
16
begin
17
   proc_cntvar : process
18
      variable cnt : unsigned (3 downto 0) := (others => '0');
19
   begin
20
      wait until rising_edge (clk);
21
      led1 <= cnt (OUTBIT);
22
      cnt := cnt + 1;
23
      led2 <= cnt (OUTBIT);
24
   end process;
25
   proc_cntsig : process
26
   begin
27
      wait until rising_edge (clk);
28
      led3 <= cnt (OUTBIT);
29
      cnt <= cnt + 1;
30
      led4 <= cnt (OUTBIT);
31
   end process;
32
end rtl;
Da Peter ja aus Prinzip keinen Simulator benutzt, haenge ich die TB auch 
mal an...

von peter (Gast)


Lesenswert?

Hmmm.. Led2 und 4 gehen an , wenn das 3.Bit von cnt erreicht ist.

Gruss

von berndl (Gast)


Lesenswert?

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...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.