Forum: FPGA, VHDL & Co. Verilog Programm Fehler


von Walter.K (Gast)


Lesenswert?

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

von Günter -. (guenter)


Lesenswert?

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

von Walter.K (Gast)


Lesenswert?

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.

von Günter -. (guenter)


Lesenswert?

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.

von Walter.K (Gast)


Lesenswert?

Slave_a und slave_b sind outputs, sie sind doch kein Registern, es ist 
unglaublich warum kann ich die Fehler nicht finden

von na (Gast)


Lesenswert?

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.

von Günter -. (guenter)


Lesenswert?

@ 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?

von Horst Gschwandtner (Gast)


Lesenswert?

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

von Walter.K (Gast)


Angehängte Dateien:

Lesenswert?

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

von Günter -. (guenter)


Lesenswert?

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?

von Walter.K (Gast)


Lesenswert?

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

von Günter -. (guenter)


Lesenswert?

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

von Walter.K (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.