Déclaration de cas Verilog
Le case
L'instruction vérifie si l'expression donnée correspond à l'une des autres expressions de la liste et se branche en conséquence. Il est généralement utilisé pour implémenter un multiplexeur. La construction if-else peut ne pas convenir s'il y a de nombreuses conditions à vérifier et se synthétiserait dans un encodeur prioritaire au lieu d'un multiplexeur.
Syntaxe
Un boîtier Verilog l'instruction commence par le case
mot clé et se termine par le endcase
mot-clé. L'expression entre parenthèses sera évaluée exactement une fois et est comparée à la liste des alternatives dans l'ordre où elles sont écrites et les instructions pour lesquelles l'alternative correspond à l'expression donnée sont exécutées. Un bloc de plusieurs instructions doit être regroupé et être compris entre begin
et 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
Si aucun des éléments de cas ne correspond à l'expression donnée, les instructions dans le default
l'élément est exécuté. Le default
l'instruction est facultative et il ne peut y avoir qu'un seul default
déclaration dans une déclaration de cas. Les instructions de cas peuvent être imbriquées.
L'exécution quittera le bloc case sans rien faire si aucun des éléments ne correspond à l'expression et un default
déclaration n'est pas donnée.
Exemple
Le module de conception illustré ci-dessous a un signal de sélection 2 bits pour acheminer l'une des trois autres entrées 3 bits vers le signal de sortie appelé. Un case
L'instruction est utilisée pour affecter l'entrée correcte à la sortie en fonction de la valeur de sel. Puisque sel est un signal 2 bits, il peut en avoir 2
2
combinaisons, de 0 à 3. L'instruction par défaut permet de définir la sortie sur 0 si sel vaut 3.
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
Schéma du matériel
Le code rtl est élaboré pour obtenir un schéma matériel qui représente un multiplexeur 4 à 1.
Vérifiez que la sortie est nulle lorsque sel vaut 3 et correspond aux entrées affectées pour les autres valeurs.
Journal de simulationncsim> 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.
Dans une instruction case, la comparaison ne réussit que lorsque chaque bit de l'expression correspond à l'une des alternatives, y compris 0, 1, x et z. Dans l'exemple ci-dessus, si l'un des bits de sel est x ou z, le default
sera exécutée car aucune des autres alternatives ne correspond. Dans un tel cas, la sortie ne sera que des zéros.
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.
Si l'instruction de cas dans la conception a x et z dans les alternatives d'éléments de cas, les résultats seraient assez différents.
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
Journal de simulation 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.
En quoi un cas est-il différent de if-else ?
Le case
l'instruction est différente de if-else-if
de deux manières :
- Expressions données dans un
if-else
bloc sont plus généraux dans uncase
bloc, une seule expression correspond à plusieurs éléments case
fournira un résultat définitif lorsqu'il y a des valeurs X et Z dans une expression
Verilog