Máquina de Estados en Verilog
Una Máquina de Estados en Verilog es uno de los circuitos secuenciales digitales más usados. Uno de los aspectos más destacados y frecuentes en los diseños Verilog, es la realización de máquinas de estados. Aquí te indicamos que es y como programarla en Verilog. En esta sección, se propone un método para la estructuración de una máquina de estados, empleando tres procesos.
- La Asignación asíncrona del siguiente estado, partiendo de de las entradas al diseño y del estado en el que se encuentre.
- Se asigna una señal síncrona, donde el flanco de reloj hace que el estado actual sea el que se ha estado preparando.
- Asignación de las salidas.

A continuación en el siguiente ejemplo se modela un semáforo en Verilog, mediante una máquina de estados:
Máquina de Estados en Verilog – Ejemplo de semáforo
[code languaje=»cpp»]
module semaforo (clk, rst, color);
input clk;
input rst;
output [1:0] color;
reg [1:0] state, nextState;
reg [8:0] cnt;
// Asignación asíncrona del siguiente estado
always @(state, cnt)
case(state)
0: // Color Rojo
if (cnt == 100) nextState = 1;
else nextState = 0;
1: // Color Ambar
if (cnt == 120) nextState = 2;
else nextState = 1;
2: // Color Verde
if (cnt == 200) nextState = 0;
else nextState = 2;
default: nextState = 0;
endcase
// Asignación síncrona: Actualización del estado
always @(posedge clk or negedge rst)
if(rst == 0) state = 0;
else state = nextState;
// Asignación de las salidas
always @(state)
if(state == 0) color = 2’b00; // Color Rojo
else if(state == 1) color = 2’b01; // Color Ámbar
else color = 2’b10; // Color Verde
// Contador
always @(posedge clk or negedge rst)
if(rst == 0) cnt = 0;
else cnt = cnt + 1;
endmodule
[/code]
En este ejemplo direccionamos una señal de reloj para prender automáticamente tres LEDs de diferentes colores (verde, ámbar, rojo) asignando un contador que dure determinado tiempo para prender cada uno de los LEDs.
Máquina de Estados en Verilog – Práctica de Contador Ascendente
Con displays de 7 Segmentos
Práctica Contador:
Esta práctica consiste en crear un contador ascendente de un segundo (1 Hz) utilizando una señal de reloj para hacer el cambio de estados (clk) y mostrándolo en los diplays de 7 segmentos.
Máquina de Estados en Verilog código de ejemplo:
[code languaje=»cpp»]
module Contador (clock_50mhz, clock_1hz, segmentos, comun,estado);
input clock_50mhz; //entrada de oscilación del cristal externo
output reg clock_1hz; //clock 1 segundo
output reg [6:0] segmentos = 7’h3F; //apagar segmentos
output reg comun = 0; //encender display1
output reg [3:0] estado = 0; //estado inicial para conectar 2 LEDs, 00, 01, 10, 11, 00 y se repite
reg [25:0] cuenta_para_1hz = 0; //inicialización de la variable que servirá para generar la salida de 1hz
parameter [6:0] cero = ~7’h3F;
parameter [6:0] uno = ~7’h06;
parameter [6:0] dos = ~7’h5B;
parameter [6:0] tres = ~7’h4F;
parameter [6:0] cuatro = ~7’h66;
parameter [6:0] cinco = ~7’h6D;
parameter [6:0] seis = ~7’h7D;
parameter [6:0] siete = ~7’h07;
parameter [6:0] ocho = ~7’h7F;
parameter [6:0] nueve = ~7’h6F;
parameter [6:0] ha = ~7’h77;
parameter [6:0] hb = ~7’h7C;
parameter [6:0] hc = ~7’h39;
parameter [6:0] hd = ~7’h5E;
parameter [6:0] he = ~7’h79;
parameter [6:0] hf = ~7’h71;
always @(posedge clock_50mhz)
begin
cuenta_para_1hz = cuenta_para_1hz + 1;
if(cuenta_para_1hz == 25_000_000)
begin
clock_1hz = ~clock_1hz; //genera la señal de oscilación, esta señal empezó en 0, valor inicial
cuenta_para_1hz = 0; // reset a el contador
end
end
always @(posedge clock_1hz)
begin
case(estado)
0: estado <= 1;
1: estado <= 2;
2: estado <= 3;
3: estado <= 4;
4: estado <= 5;
5: estado <= 6;
6: estado <= 7;
7: estado <= 8;
8: estado <= 9;
9: estado <= 10;
10: estado <= 11;
11: estado <= 12;
12: estado <= 13;
13: estado <= 14;
14: estado <= 15;
15: estado <= 0;
endcase
end
always @(estado)
begin
case(estado)
0: segmentos = cero;
1: segmentos = uno;
2: segmentos = dos;
3: segmentos = tres;
4: segmentos = cuatro;
5: segmentos = cinco;
6: segmentos = seis;
7: segmentos = siete;
8: segmentos = ocho;
9: segmentos = nueve;
10: segmentos = ha;
11: segmentos = hb;
12: segmentos = hc;
13: segmentos = hd;
14: segmentos = he;
15: segmentos = hf;
endcase
end
endmodule
[/code]
Una vez compilado nuestro programa procedemos a declarar nuestros pines de salida a cualquier display de 7 segmentos de nuestro FPGA, como lo muestra la siguiente imagen:


PIN_17
Ya asignados los pines de salida y el Clk de nuestro FPGA, compilaremos y cargaremos nuestro programa con el programador USB Blaster, si siguieron correctamente los pasos anteriores se demostrará en físico un contador ascendente del 0 al 9 con una señal de reloj de un segundo (1 Hz).

ERROR:HDLCompilers:247 – «semaforo.v» line 31 Reference to vector wire ‘color’ is not a legal reg or variable lvalue
ERROR:HDLCompilers:44 – «semaforo.v» line 31 Illegal left hand side of blocking assignment
ERROR:HDLCompilers:247 – «semaforo.v» line 32 Reference to vector wire ‘color’ is not a legal reg or variable lvalue
ERROR:HDLCompilers:44 – «semaforo.v» line 32 Illegal left hand side of blocking assignment
ERROR:HDLCompilers:247 – «semaforo.v» line 33 Reference to vector wire ‘color’ is not a legal reg or variable lvalue
ERROR:HDLCompilers:44 – «semaforo.v» line 33 Illegal left hand side of blocking assignment
Analysis of file failed.