Verilog-Fallaussage
Der case
-Anweisung prüft, ob der angegebene Ausdruck mit einem der anderen Ausdrücke in der Liste übereinstimmt, und verzweigt entsprechend. Es wird typischerweise verwendet, um einen Multiplexer zu implementieren. Das if-else-Konstrukt ist möglicherweise nicht geeignet, wenn viele Bedingungen überprüft werden müssen, und würde anstelle eines Multiplexers in einen Prioritätscodierer synthetisiert werden.
Syntax
Ein Verilog Fall Anweisung beginnt mit dem case
Schlüsselwort und endet mit dem endcase
Stichwort. Der Ausdruck in Klammern wird genau einmal ausgewertet und mit der Liste der Alternativen in der Reihenfolge verglichen, in der sie geschrieben wurden, und die Anweisungen, für die die Alternative zum angegebenen Ausdruck passt, werden ausgeführt. Ein Block mit mehreren Anweisungen muss gruppiert werden und sich innerhalb von begin
befinden und end
.
// Here 'expression' should match one of the items (item 1,2,3 or 4)
case (<expression>)
case_item1 : <single statement>
case_item2,
case_item3 : <single statement>
case_item4 : begin
<multiple statements>
end
default : <statement>
endcase
Wenn keines der Fallelemente mit dem angegebenen Ausdruck übereinstimmt, werden Anweisungen innerhalb von default
Artikel wird ausgeführt. Die default
Die Anweisung ist optional und es kann nur einen default
geben Aussage in einer Fallaussage. Case-Anweisungen können verschachtelt werden.
Die Ausführung verlässt den case-Block, ohne etwas zu tun, wenn keines der Elemente mit dem Ausdruck und einem default
übereinstimmt Aussage ist nicht gegeben.
Beispiel
Das unten gezeigte Designmodul hat ein 2-Bit-Auswahlsignal, um einen der drei anderen 3-Bit-Eingänge an das aufgerufene Ausgangssignal zu leiten. Ein case
-Anweisung wird verwendet, um die korrekte Eingabe der Ausgabe basierend auf dem Wert von sel zuzuweisen. Da sel ein 2-Bit-Signal ist, kann es 2
2
haben Kombinationen, 0 bis 3. Die default-Anweisung hilft, die Ausgabe auf 0 zu setzen, wenn sel 3 ist.
module my_mux (input [2:0] a, b, c, // Three 3-bit inputs
[1:0] sel, // 2-bit select signal to choose from a, b, c
output reg [2:0] out); // Output 3-bit signal
// This always block is executed whenever a, b, c or sel changes in value
always @ (a, b, c, sel) begin
case(sel)
2'b00 : out = a; // If sel=0, output is a
2'b01 : out = b; // If sel=1, output is b
2'b10 : out = c; // If sel=2, output is c
default : out = 0; // If sel is anything else, out is always 0
endcase
end
endmodule
Hardware-Schema
Der RTL-Code wird ausgearbeitet, um ein Hardware-Schema zu erhalten, das einen 4-zu-1-Multiplexer darstellt.
Beachten Sie, dass der Ausgang null ist, wenn sel 3 ist, und den zugewiesenen Eingängen für andere Werte entspricht.
Simulationsprotokollncsim> run [0] a=0x4 b=0x1 c=0x1 sel=0b11 out=0x0 [10] a=0x5 b=0x5 c=0x5 sel=0b10 out=0x5 [20] a=0x1 b=0x5 c=0x6 sel=0b01 out=0x5 [30] a=0x5 b=0x4 c=0x1 sel=0b10 out=0x1 [40] a=0x5 b=0x2 c=0x5 sel=0b11 out=0x0 ncsim: *W,RNQUIE: Simulation is complete.
In einer case-Anweisung ist der Vergleich nur erfolgreich, wenn jedes Bit des Ausdrucks mit einer der Alternativen einschließlich 0, 1, x und z übereinstimmt. Wenn im oben gezeigten Beispiel eines der Bits in sel entweder x oder z ist, wird default
-Anweisung wird ausgeführt, da keine der anderen Alternativen zutrifft. In einem solchen Fall werden nur Nullen ausgegeben.
ncsim> run [0] a=0x4 b=0x1 c=0x1 sel=0bxx out=0x0 [10] a=0x3 b=0x5 c=0x5 sel=0bzx out=0x0 [20] a=0x5 b=0x2 c=0x1 sel=0bxx out=0x0 [30] a=0x5 b=0x6 c=0x5 sel=0bzx out=0x0 [40] a=0x5 b=0x4 c=0x1 sel=0bxz out=0x0 [50] a=0x6 b=0x5 c=0x2 sel=0bxz out=0x0 [60] a=0x5 b=0x7 c=0x2 sel=0bzx out=0x0 [70] a=0x7 b=0x2 c=0x6 sel=0bzz out=0x0 [80] a=0x0 b=0x5 c=0x4 sel=0bxx out=0x0 [90] a=0x5 b=0x5 c=0x5 sel=0bxz out=0x0 ncsim: *W,RNQUIE: Simulation is complete.
Wenn die Case-Anweisung im Design x und z in den Case-Item-Alternativen enthält, wären die Ergebnisse ganz anders.
module my_mux (input [2:0] a, b, c,
[1:0] sel,
output reg [2:0] out);
// Case items have x and z and sel has to match the exact value for
// output to be assigned with the corresponding input
always @ (a, b, c, sel) begin
case(sel)
2'bxz : out = a;
2'bzx : out = b;
2'bxx : out = c;
default : out = 0;
endcase
end
endmodule
Simulationsprotokoll ncsim> run [0] a=0x4 b=0x1 c=0x1 sel=0bxx out=0x1 [10] a=0x3 b=0x5 c=0x5 sel=0bzx out=0x5 [20] a=0x5 b=0x2 c=0x1 sel=0bxx out=0x1 [30] a=0x5 b=0x6 c=0x5 sel=0bzx out=0x6 [40] a=0x5 b=0x4 c=0x1 sel=0bxz out=0x5 [50] a=0x6 b=0x5 c=0x2 sel=0bxz out=0x6 [60] a=0x5 b=0x7 c=0x2 sel=0bzx out=0x7 [70] a=0x7 b=0x2 c=0x6 sel=0bzz out=0x0 [80] a=0x0 b=0x5 c=0x4 sel=0bxx out=0x4 [90] a=0x5 b=0x5 c=0x5 sel=0bxz out=0x5 ncsim: *W,RNQUIE: Simulation is complete.
Wie unterscheidet sich ein Fall von if-else ?
Die case
Anweisung unterscheidet sich von if-else-if
auf zwei Arten:
- Ausdrücke in einem
if-else
Block sind allgemeiner, während in einemcase
-Block wird ein einzelner Ausdruck mit mehreren Elementen abgeglichen case
liefert ein definitives Ergebnis, wenn ein Ausdruck X- und Z-Werte enthält
Verilog