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