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.
Máquina de Estados en Verilog

Máquina de Estados

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

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

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:

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

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:

vv

Asignación de Pines a un Display de 7 Segmentos

uu

Clk

Señal de Reloj (Clk)

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).

Máquina de Estados en Verilog y FPGA Altera

Imagen Representativa

 

One Response

  1. carlos sanchez abril 9, 2015

Escríbenos tus dudas o comentarios

Usamos Cookies en nuestro sitio WEB

Por favor confirma, si aceptas nuestras cookies de rastreo. También puedes negar el uso de cookies de rastreo y seguir navegando sin que ninguna información sea enviada a servicios de terceros.