Wie funktionieren For-Schleifen in Verilog? Warum kann ich nicht erreichen, was ich will?

Dies ist mein Code für einen einfachen 2-1 8-Bit-Multiplexer, wo SW[17]mein Selektor ist.

Wenn es an ist, zeige Y = SW[15:8], wenn es aus ist, zeige X = SW[7:0].

module part2 (SW, LEDR, LEDG);

    input [17:0] SW; //inputs
    output [17:0] LEDR; //light every switch
    output [7:0] LEDG;  //byte desired

    //All switches to red leds.
    assign LEDR = SW;       

    //Green leds get the desired byte.
    assign LEDG[0] = (~SW[17] & SW[0]) | (SW[17] & SW[8]);
    assign LEDG[1] = (~SW[17] & SW[1]) | (SW[17] & SW[9]);
    assign LEDG[2] = (~SW[17] & SW[2]) | (SW[17] & SW[10]);
    assign LEDG[3] = (~SW[17] & SW[3]) | (SW[17] & SW[11]);
    assign LEDG[4] = (~SW[17] & SW[4]) | (SW[17] & SW[12]);
    assign LEDG[5] = (~SW[17] & SW[5]) | (SW[17] & SW[13]);
    assign LEDG[6] = (~SW[17] & SW[6]) | (SW[17] & SW[14]);
    assign LEDG[7] = (~SW[17] & SW[7]) | (SW[17] & SW[15]);

endmodule

Dieser Code ist einfach, aber ich versuche ihn zu optimieren und die 8 Zeilen zu ersetzen.

Ich wollte eine Art Schleife verwenden, aber ich bin gescheitert:

integer index;
initial
   begin
   for(index = 0; index < 8; index  = index+1)
       begin
       assign LEDG[index] = (~SW[17] & SW[index]) | (SW[17] & SW[index+8]);
       end
   end

Ich habe es auch versucht und bin gescheitert:

//Green leds get the desired byte.
always @(SW) begin
    if (~SW[17])
        assign LEDG = SW[7:0]; 
    else
        assign LEDG = SW[15:5];
end

Ich erhalte eine Fehlermeldung, die besagt, dass der linke Teil der Zuweisung einen variablen Datentyp haben muss.

Antworten (1)

Entfernen Sie in einem 'always'-Block die Zuweisung, verwenden Sie einfach LEDG[index] = ... Ändern Sie außerdem die Ausgangsdeklaration in 'output reg [7:0] LEDG'. Der Reg-Datentyp ist der variable Datentyp, auf den in der Fehlermeldung verwiesen wird.

Können Sie mir das erklären? Warum funktioniert es, wenn ich das mache? Und da dies nicht wirklich Softwareprogrammierung ist (wo weniger Zeilen besser sind), welcher der drei Codes wird effizienter sein?
Ein Always-Block gibt eine Reihe von Verfahrensanweisungen an, die in der Reihenfolge ausgeführt werden, in der sie geschrieben wurden. Der reg-Datentyp kann seinen Wert behalten, während der Rest des Always-Blocks abgeschlossen ist, während der 'wire'-Datentyp (der Standardtyp) dies nicht tut. Reg muss in jedem Always-Block verwendet werden, auch wenn dieser bestimmte Block kurz ist und sofort endet. Assign wird für Drahttypen verwendet und kann als Verbindung physischer Drähte zwischen Hardwareteilen oder als Pfad für die Übertragung eines Signals angesehen werden.
Danke, und warum funktioniert die for-Schleife nicht? Es kompiliert, aber das Ergebnis ist nicht das, was ich will.
Ich bin hier vielleicht abwesend, aber ich denke, dass "anfängliche" Blöcke nur einmal ausgeführt werden, sodass die Ausgabe einmal bestimmt und danach nie aktualisiert wird.
initial wird nur einmal "ausgeführt", wie Sie sagen.