Práctica No. 4 Maquinas de Estado
Datos de la práctica
Carrera INGENIERIA ELECTRONICA
Semestre Grupo
Tipo Practica Laboratorio
Simulación Fecha
Asignatura Electrónica Digital II Unidad Temática
No Alumnos por practica 2 No. Alumnos por reporte 2 Nombre del Profesor
Nombre(s) de Alumno(s)
Tiempo estimado Vo. Bo Del Profesor Comentarios
OBJETIVOS:
Objetivo General
Familiarizarse con el lenguaje Verilog para la realización de ejercicios como maquinas de estado finito.
Objetivos Específicos
1. Realizar un flashback de ciertas instrucciones del lenguaje de Verilog.
2. Diseñar una maquina de estado finito mediante la detección de una secuencia.
MEDIOS A UTILIZAR:
Laboratorio de Simulación PC
Introducción
Máquinas de estado
Definición
Son circuitos secuenciales que tienen un número determinado de estados (2n). Pueden ser retroalimentados (flip flops, biestables) o máquinas sincrónicas temporizadas cuando utilizan las primeras para crear circuitos cuyas entradas son examinadas y cuyas salidas cambian con respecto a una señal de reloj controlada. En cualquier caso, se tienen unas entradas, unas salidas y unos estados.
Algunos conceptos a tener en cuenta para la representación de máquinas de estados finitos son:
elementos de almacenamiento.
En esta práctica veremos que a partir de especificaciones se obtienen diagramas de estados para modelos de Mealy y Moore. Se describen tres ejemplos escritos en Verilog para su verificación en la FPGA.
Trabajo previo
1. Realizar el Diagrama de estado de este ejemplo (previa lectura e investigación por parte del docente y el estudiante). Conocer el funcionamiento de las máquinas de estado de Moore y Mealy.
2. Traer la guía de Laboratorio de manera digital.
Uso de Assign module compuertas(
input A, input B, output [5:0]C );
assign C[0] = A & B; assign C[1] = ~(A & B); assign C[2] = A | B; assign C[3] = ~(A | B); DESARROLLO O PROCEDIMIENTO:
I Parte FlashBack
1. Cree un nuevo proyecto en ISE Project Navigator llamado compuertas.
2. Recordemos un poco la configuración inicial mostrada en la Figura 1. para poder trabajar con el programa ISE y el Kit FPGA.
3. El código del programa del proyecto compuertas debe quedar como la figura de al lado.
4. Cree un archivo UCF con los pines a utilizar en la tarjeta.
Operacion Simbología
AND &
NAND ~ &
OR |
NOR ~ |
NET "A" LOC = "P11"; NET "B" LOC = "L3";
5. Cree un nuevo proyecto llamado multiplexor y pruebe las diferentes formas de hacer el programa.
Multiplexores
Uso de Archivos Top
6. Vamos a unir los archivos compuertas y multiplexor a través de un archivo top como se muestra en el siguiente código.
Usando always e if
module multiplexor( input A,
input B, input S, output C );
always@ (A or B or S) if (S == 1)
C = A; else
C = B; endmodule
Usando Case
module multiplexor( input A,
input B, input S, output reg C );
always@ (A or B or S) case (S)
0: C = B; 1: C = A; endcase
endmodule
Usando assign
module multiplexor( input A,
input B, input S, output C );
assign C = S ? A:B; endmodule
module top( input A, input B, output [6:0]C, input S );
compuertas U1 (.A(A), .B(B), .C(C[5:0])); multiplexor U2 (.A(A), .B(B), .S(S), .C(C[6]));
II Parte Detector de Secuencia
1. Crear un nuevo proyecto en ISE Project Navigator.
2. Las entradas del módulo principal son: mclk y btn, que corresponden a la señal de reloj y los botones (que utilizaremos para introducir un 1 o un 0) respectivamente.
3. La salida del sistema será a través de un led (ld) que encenderá si el código introducido es verdadero.
4. El código del módulo principal es el siguiente:
module Seq_Detector_top( input wire mclk,
input wire [3:0] btn, output wire ld );
wire clr, clk190, clkp, btn01;
assign clr = btn [3]; //btn[3] es reiniciar assign btn01 = btn[0] | btn [1]; //función or
clkdiv U1 (.clk (mclk), .clr(clr),
.clk190(clk190) );
clock_pulse U2 (.inp(btn01), .cclk(clk190),
.clr(clr), .outp(clkp) );
seqdeta U3 (.clk(clkp), .clr(clr),
.din(btn[1]), .dout(ld[0]) );
Recuerde que en los laboratorios de electrónica digital I, en el ejercicio 2 creábamos un módulo principal y dentro de llamábamos a módulos secundarios. En este ejemplo haremos lo mismo. El método para realizar conexiones entre módulos es usando nombres.
Los módulos secundarios son los siguientes:
Módulo Clock Divider
Asigna a la salida una frecuencia más lenta que el reloj propio (mclk = 50 MHz)de la tarjeta. En este módulo designamos 3 salidas de 190 Hz, 47.7 Hz y 3 Hz, que se conexionan con el módulo principal.
//Divisor de Reloj module clkdiv( input wire mclk, input wire clr, output wire clk190, output wire clk48, output wire clk3 );
reg [24:0] q;
//25-bit counter
always @ (posedge mclk or posedge clr)
begin if(clr == 1) q <= 0; else q <= q + 1; end
assign clk190 = q [17]; //190 Hz assign clk48 = q [19]; //47.7 Hz assign clk3 = q [24]; //3 Hz
Módulo clock_pulse
Un circuito muy útil que produce un único pulso de reloj es el módulo clock_pulse, cuya función es como fuente de reloj para detectar la secuencia de los números 1101. La función OR de los botones btn[0] y btn[1] son la entrada al módulo clock_pulse, esto significa que cada vez que presionamos uno de los dos botones se genera un pulso de reloj. Sin embargo, si presionamos btn[1] introducimos un estado lógico alto (1) o un 0 si presionamos btn[0]. Observe que se usa un reloj de 190 Hz como la entrada cclk al módulo clock_pulse. La salida clkp no se producirá por lo menos 5 ms después de pulsar alguno de los botones.
module clock_pulse( input wire inp, input wire cclk, input wire clr, output wire outp );
reg delay1; reg delay2; reg delay3;
always @(posedge cclk or posedge clr) begin
if (clr==1) begin delay1 <= 0; delay2 <= 0; delay3 <= 0; end
else begin
delay1 <= inp; delay2 <= delay1; delay3 <= delay2; end
La secuencia a detectar es 1101, el programa se presenta a continuación.
Módulo SeqDet
module seqdeta( input wire clk, input wire clr, input wire din, output reg dout );
reg [2:0] present_state, next_state;
parameter S0 = 0, S1= 1, S2 = 2, S3 = 3, S4 = 4;
//state registers
always @ (posedge clk or posedge clr) begin
if (clr == 1)
present_state <= S0; else
present_state <= next_state; end
//C1 module always @(*) begin
case (present_state) S0: if (din == 1) next_state <= S1; else
next_state <= S0; S1: if (din == 1) next_state <= S2; else
next_state <= S0; S2: if (din == 0) next_state <= S3; else
III. Trabajo a Entregar
1. Presentar su circuito funcionando al docente encargado del laboratorio con sus conclusiones.
2. Salve todos los archivos simulados en memoria que tenga disponible y presente un reporte con lo desarrollado en esta práctica de laboratorio e incluya conclusiones.
S3: if (din == 1) next_state <= S4; else
next_state <= S0; S4: if (din == 0) next_state <= S0; else
next_state <= S2; default next_state <= S2; endcase
end
//C2 module always @(*) begin
if(present_state == S4) dout = 1;