Pages Menu
TwitterFacebook



BANNER2_ALT

Posted by on Mar 23, 2015 in Verilog | 1 comment

Máquina de Estados

Máquina de Estados

Máquina de Estados

Uno de los aspectos más destacados y frecuentes en los diseños Verilog, es la realización de máquinas de estados. En esta sección, se propone un método para la estructuración de una máquina de estados, empleando tres procesos.

  • Asignación asíncrona del siguiente estado, partiendo de de las entradas al diseño y del estado en el que se encuentre.
  • Asignación síncrona, donde el flanco de reloj hace que el estado actual sea el que se ha estado preparando.
  • Asignación de las salidas.
maquinas de estado

Máquina de Estados

A continuación en el siguiente ejemplo se modela un semáforo en Verilog, mediante una máquina de estados:

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.

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.

La programación se muestra a continuación:

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

Maquina de Estados

Imagen Representativa

 

1 Comment

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

Post a Reply

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *