1. Introducción
Verilog es uno de los lenguajes de descripción de hardware (HDL) más utilizados para el diseño de circuitos digitales. Dentro de este lenguaje, la sentencia case
es una estructura fundamental para describir de manera eficiente las bifurcaciones condicionales. En particular, se emplea con frecuencia en el diseño de máquinas de estados (FSM) y multiplexores.
En este artículo explicaremos en detalle desde lo básico hasta lo avanzado del uso de la sentencia case
en Verilog, incluyendo las precauciones que se deben tomar al implementarla. Presentaremos ejemplos prácticos de código que facilitarán la comprensión incluso a principiantes. ¡Acompáñanos hasta el final!
2. Sintaxis básica de la sentencia case
en Verilog
¿Qué es una sentencia case
?
La sentencia case
en Verilog se utiliza para ejecutar diferentes bloques de código según una condición dada (selector). Su funcionamiento es similar al de switch-case
en el lenguaje C, aunque presenta algunas diferencias importantes.
La sintaxis básica es la siguiente:
case (expresión)
condición1: instrucción1;
condición2: instrucción2;
condición3: instrucción3;
default: instrucción4; // Si no coincide con ninguna condición
endcase
Uso básico de la sentencia case
En el siguiente ejemplo se muestra un case
sencillo que asigna diferentes valores a out
según el valor de la entrada de 2 bits sel
:
module case_example(input [1:0] sel, output reg [3:0] out);
always @(*) begin
case (sel)
2'b00: out = 4'b0001;
2'b01: out = 4'b0010;
2'b10: out = 4'b0100;
2'b11: out = 4'b1000;
default: out = 4'b0000; // Valor por defecto en caso inesperado
endcase
end
endmodule
En este código, el valor de out
depende directamente del valor de sel
. Al incluir una sentencia default
, se asegura un comportamiento definido incluso cuando la entrada no corresponde a los casos esperados.
Diferencias entre case
, casex
y casez
Verilog también incluye dos variantes de la sentencia case
: casex
y casez
. Estas permiten ignorar ciertos bits actuando como comodines.
Sintaxis | Características |
---|---|
case | Requiere coincidencia exacta (comportamiento por defecto) |
casex | Ignora valores X (indefinidos) y Z (alta impedancia) |
casez | Ignora únicamente los valores Z |
Ejemplo de uso de casez
:
casez (sel)
2'b1?: out = 4'b1111; // Coincide si el bit más significativo es 1
2'b01: out = 4'b0001;
default: out = 4'b0000;
endcase
Aquí, 1?
significa que basta con que el bit superior sea 1, sin importar el valor del bit inferior.
3. Ejemplos concretos de uso de la sentencia case
Condicionales básicos
En el siguiente ejemplo se muestra un decodificador simple de CPU que ejecuta diferentes acciones según el valor de la entrada de 8 bits opcode
:
module decoder(input [7:0] opcode, output reg [3:0] control_signal);
always @(*) begin
case (opcode)
8'h00: control_signal = 4'b0001; // NOP
8'h01: control_signal = 4'b0010; // ADD
8'h02: control_signal = 4'b0100; // SUB
default: control_signal = 4'b0000; // Instrucción indefinida
endcase
end
endmodule
Uso en máquinas de estados
La sentencia case
también se utiliza con frecuencia para implementar máquinas de estados finitos (FSM).
typedef enum reg [1:0] {IDLE, RUN, STOP} state_t;
state_t current_state, next_state;
always @(posedge clk) begin
if (reset)
current_state <= IDLE;
else
current_state <= next_state;
end
always @(*) begin
case (current_state)
IDLE: next_state = RUN;
RUN: next_state = STOP;
STOP: next_state = IDLE;
default: next_state = IDLE;
endcase
end
Este código implementa una FSM con tres estados. Cuando se requiere gestionar estados en un circuito, la sentencia case
permite una descripción clara y ordenada.
4. Puntos a tener en cuenta al usar la sentencia case
Al emplear case
en Verilog, es importante considerar lo siguiente:
1. Siempre incluir un caso default
La cobertura de todas las posibles entradas es esencial. En síntesis para FPGA o ASIC, omitir default
puede provocar la generación de latches no deseados.
2. Usar casex
y casez
con precaución
Estas variantes pueden causar coincidencias no previstas. Por ello, es fundamental simular exhaustivamente para confirmar que el comportamiento sea el esperado.
casez (sel)
2'b1?: out = 4'b1111; // Coincide si el bit superior es 1
2'b01: out = 4'b0001;
default: out = 4'b0000;
endcase
En este tipo de código, se debe verificar que no ocurran coincidencias inesperadas.
3. No abusar de la sentencia case
Para bifurcaciones pequeñas, if-else
puede resultar más intuitivo. Se recomienda usar case
cuando haya múltiples alternativas.
5. Conclusión
En este artículo hemos revisado los siguientes puntos sobre la sentencia case
en Verilog:
✅ Sintaxis básica y funcionamiento
✅ Diferencias entre case
, casex
y casez
✅ Ejemplos prácticos (condicionales y FSM)
✅ Precauciones de uso
Un uso adecuado de case
mejora la legibilidad del código y reduce errores de diseño. Es una herramienta clave en la descripción de circuitos digitales. ¡Aplícala en tus próximos proyectos!
Próximos conceptos importantes en Verilog
Una vez comprendida la sentencia case
, el siguiente paso es estudiar las sentencias always
y la diferencia entre lógica combinacional y secuencial. Esto ampliará considerablemente tu dominio de Verilog.