hallo zusammen, /******************************************************************/ module adr_decoder( clk, // Clock Eingang adress, // Eingangsadresse sel, slave_a, slave_b); // Info Codes input clk, sel; input [4:0] adress; output [31:0] slave_a; output [31:0] slave_b; reg [4:0] adress_reg; reg sel_A_B; always@(posedge clk) begin: select_output adress_reg = adress; sel_A_B = sel; case(adress_reg) 5'b00000: begin (38) if(!sel_A_B) assign slave_a = 32'b00000000000000000000000000000001; else assign slave_b = 32'b00000000000000000000000000000001; end 5'b00001: begin if(!sel_A_B) assign slave_a = 32'b00000000000000000000000000000010; else assign slave_b = 32'b00000000000000000000000000000010; end endcase end endmodule /**********************************************************************/ Kann mir bitte jemanden erklären, warum wenn ich das Programm compilieren möchte bekomme ich diese Fehlermeldung: Error: Verilog HDL Procedural Assignment error at adr_decoder.v(38): object "slave_a" on left-hand side of assignment must have a variable data type Danke
Du kannst nicht ein assign statment in einem always block nehmen. Nimm einfach mal das assign statements raus. Also:
1 | (38) if(!sel_A_B) slave_a = 32'b00000000000000000000000000000001; |
Für die Zahl könntest du auch schreiben 32'd1 oder 32'h1. Dann würde das nicht so lang werden. Gruß, Günter
To Günter Vielen dank für deine Antwort, aber mit oder ohne assign nichts hat sich geändert, ich bekomme immer die gleiche Fehlermeldung.
Also ich hab das gerade mal ausprobiert und wenn du slave_a und slave_b als reg machst dann gehen die Compilierfehler weg. Was du dann noch machen solltest ist alle Zuweisungen als non-blocking assignments (<=) umzuwandeln. Dann entspricht das Simulationsergebnis auch der Implementierung.
Slave_a und slave_b sind outputs, sie sind doch kein Registern, es ist unglaublich warum kann ich die Fehler nicht finden
Du hast einen Denkfehler dabei: In Verilog gibt es zwei Datentypen: reg und wire. Etwas was als reg definiert wird, ist deswegen noch lange kein Register, sondern ist nur vom Datentyp reg, kann also beschrieben werden. Das hat aber nichts mit input oder output zu tun, jeder Eingang und Ausgang braucht trotzdem einen Datentyp.
@ na Damit habe ich auch immer meine Probleme mit. D.h. ob es eine Register wird entscheidet das drum herum. Also z.B. in Walters Fall hat er einen always @(posedge clk) block. Das würde doch bedeuten hier wird alles synchron zum clk signal getaktet. Da werden dann alle reg als Registers? Worüber ich mich wundere, einen Multiplexer kann ich mit einem wire Type z.B. erstellen:
1 | wire [1:0] sel; |
2 | wire out; |
3 | wire in_0, in_1, in_2, in_3; |
4 | |
5 | assign out = (sel == 2'b00) ? in_0 : |
6 | (sel == 2'b01) ? in_1 : |
7 | (sel == 2'b10) ? in_2 : |
8 | in_3; |
Jetzt kann das ja auch in einen always Block gepackt werden. Dann wird daraus:
1 | wire [1:0] sel; |
2 | reg out; |
3 | wire in_0, in_1, in_2, in_3; |
4 | |
5 | always @(*) begin |
6 | case(sel) |
7 | 2'b00: out = in_0; |
8 | 2'b01: out = in_1; |
9 | 2'b10: out = in_2; |
10 | default: out = in_3; |
11 | endcase |
12 | end |
-- Ich weiss garnicht ob ich das jetzt richtig mit den blocking assignments gemacht habe oder ob es non-blocking sein müssen? -- Auf jeden Fall muss ich für den Fall mit dem always jetzt auf einmal out als reg definieren, obwohl es immer noch wie vorher als wire funktioniert?
Habe schon lange nichts mehr in Verilog programmiert aber Du brauchst ein Reg da Du die Werte ein einer @Anweisung uebernimmst und dann auf unbestimmte Zeit speichern willst. output [31:0] slave_a; output [31:0] slave_b; und reg [31:0] slave_a; reg [31:0] slave_b; mit output alleine kannst Du keine Werte in slave_a behalten, es wäre also nur möglich slave_a = xyz; aber nicht @edge if... elseif... elseif... dazu brauchst Du ein Register. Es reicht, wenn Du reg und output den gleichen Namen gibst. Falls Du das nicht möchtest musst Du in der @ Anweisung deine Werte ins reg schreiben und irgendwo assign slave_a = myreg; mfg Horst
Hallo zusammen, Ich habe ein Adressen decoder mit verilog geschrieben,als Eingang clk, und 5 Bit Adresse, als Ausgang 1 von 62 outputs pro steigende Flanke muss ein 1 haben und die anderen 0,einfacher gibt es nicht! Als ich das simulieren wollte, hatte ich als Egbebnis nicht was ich erwartet habe.(Quartus II). Kann mir bitte jemanden helfen um die Fehler zu finden. Grüsse Walter
Also ich habe jetzt nicht genau deine Fehlerbeschreibung verstanden. Ich vermute mal das du mit dem sel Signal zwischen slave_a1 und slave_b1 umschalten möchtest und erwartest dann das der andere Ausgang 0 ist? Jetzt ist da nur ein Problem. Unten ist nur der Ausschnitt der case Anweisung für adress = 0.
1 | case(adress) |
2 | 5'b00000: |
3 | begin |
4 | if(!sel_A_B) slave_a1 <= 32'b00000000000000000000000000000001; |
5 | else slave_b1 <= 32'b00000000000000000000000000000001; |
6 | end |
Nehmen wir mal an adress=0 und slave_b1 ist selektiert. Mit der positiven Flanke vom clk Signal wird der Code einmal durchlaufen und slave_b1 erhält den Wert 1 zugewiesen. -- In dem Durchlauf hat slave_a1 keine Zuweisung bekommen. -- Jetzt wird umgeschaltet auf slave_a1. In dem Durchgang wird slave_a1 der Wert 1 zugewiesen und hier umgekehrt, wird slave_b1 nichts zugewiesen. D.h. slave_b1 hat immer noch den Wert vom vorherigen Durchgang. Ist das vielleicht der Fehler den du siehst?
Vielen Dank für die Antwort. Nein das ist nicht ein Problem und es läuft ganz ok.Das Probleme liegt in der Simulation: Wenn ich zB die Adressen von 0 bis 15 als input lege sollte normalaweise jedes Mal mit einer steigende Flanke ein Ausgang selektiert(zB für Adresse 00000 und sel=0 wird slave_a[0] selektiert....usw ).Leider für die Adressen 2,4,8 bekomme ich nicht was ich erwarte für diesen drei wird immer der Ausgang von der Adresse 0 ausgewählt. woran liegt das? Gruss WAlter
Ich habe das gerade mal versucht und sehe eigentlich nicht das Problem was du beschreibst. Hier der Teil der Testbench der die Daten füttert:
1 | always begin |
2 | #TB clk <= ~clk; |
3 | end |
4 | |
5 | initial begin |
6 | $monitor("clk: %d adr: %d sel: %d slave_a1: %d slave_b1: %d",clk, adress, sel, slave_a1, slave_b1); |
7 | end |
8 | |
9 | |
10 | initial begin |
11 | |
12 | clk = 0; |
13 | sel = 0; |
14 | |
15 | for (i = 0; i <16; i = i + 1) begin |
16 | @(negedge clk) adress = i; |
17 | end |
18 | |
19 | #50 $finish(); |
20 | |
21 | end |
Die Instantinzierung ist rausgelassen. Der Ausgang von slave_a1 zählt hoch wie es die Logik beschreibt. Was du hier aber siehst ist das Verhalten das ich beschrieben habe. slave_b1 bekommt nichts zugewiesen in dem Fall.
1 | clk: 0 adr: x sel: 0 slave_a1: x slave_b1: x |
2 | clk: 1 adr: x sel: 0 slave_a1: x slave_b1: x |
3 | clk: 0 adr: 0 sel: 0 slave_a1: x slave_b1: x |
4 | clk: 1 adr: 0 sel: 0 slave_a1: 1 slave_b1: x |
5 | clk: 0 adr: 1 sel: 0 slave_a1: 1 slave_b1: x |
6 | clk: 1 adr: 1 sel: 0 slave_a1: 2 slave_b1: x |
7 | clk: 0 adr: 2 sel: 0 slave_a1: 2 slave_b1: x |
8 | clk: 1 adr: 2 sel: 0 slave_a1: 4 slave_b1: x |
9 | clk: 0 adr: 3 sel: 0 slave_a1: 4 slave_b1: x |
10 | clk: 1 adr: 3 sel: 0 slave_a1: 8 slave_b1: x |
11 | clk: 0 adr: 4 sel: 0 slave_a1: 8 slave_b1: x |
12 | clk: 1 adr: 4 sel: 0 slave_a1: 16 slave_b1: x |
13 | clk: 0 adr: 5 sel: 0 slave_a1: 16 slave_b1: x |
14 | clk: 1 adr: 5 sel: 0 slave_a1: 32 slave_b1: x |
15 | clk: 0 adr: 6 sel: 0 slave_a1: 32 slave_b1: x |
16 | clk: 1 adr: 6 sel: 0 slave_a1: 64 slave_b1: x |
17 | clk: 0 adr: 7 sel: 0 slave_a1: 64 slave_b1: x |
18 | clk: 1 adr: 7 sel: 0 slave_a1: 128 slave_b1: x |
19 | clk: 0 adr: 8 sel: 0 slave_a1: 128 slave_b1: x |
20 | clk: 1 adr: 8 sel: 0 slave_a1: 256 slave_b1: x |
21 | clk: 0 adr: 9 sel: 0 slave_a1: 256 slave_b1: x |
22 | clk: 1 adr: 9 sel: 0 slave_a1: 512 slave_b1: x |
23 | clk: 0 adr: 10 sel: 0 slave_a1: 512 slave_b1: x |
24 | clk: 1 adr: 10 sel: 0 slave_a1: 1024 slave_b1: x |
25 | clk: 0 adr: 11 sel: 0 slave_a1: 1024 slave_b1: x |
26 | clk: 1 adr: 11 sel: 0 slave_a1: 2048 slave_b1: x |
27 | clk: 0 adr: 12 sel: 0 slave_a1: 2048 slave_b1: x |
28 | clk: 1 adr: 12 sel: 0 slave_a1: 4096 slave_b1: x |
29 | clk: 0 adr: 13 sel: 0 slave_a1: 4096 slave_b1: x |
30 | clk: 1 adr: 13 sel: 0 slave_a1: 8192 slave_b1: x |
31 | clk: 0 adr: 14 sel: 0 slave_a1: 8192 slave_b1: x |
32 | clk: 1 adr: 14 sel: 0 slave_a1: 16384 slave_b1: x |
33 | clk: 0 adr: 15 sel: 0 slave_a1: 16384 slave_b1: x |
34 | clk: 1 adr: 15 sel: 0 slave_a1: 32768 slave_b1: x |
35 | clk: 0 adr: 15 sel: 0 slave_a1: 32768 slave_b1: x |
36 | clk: 1 adr: 15 sel: 0 slave_a1: 32768 slave_b1: x |
37 | clk: 0 adr: 15 sel: 0 slave_a1: 32768 slave_b1: x |
Das sieht schön aus. Ich hab das mit dem graphischen Simulator von Altera Quartus II und ich hab viele Lücken gefunden komisch!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.