Se deben colocar todas las entradas en la lista de sensibilidad, y declarar todas las opciones. Por ejemplo, si se utiliza un case, declarar todas las variables en todas las opciones, o, si se utiliza un if, seguirlo con un else, etc.
12 Declaración de operaciones con procesos Body: Por ejemplo, la sintaxis para modelar una compuerta seria: module COMPUERTA(E1, E2, S1);
input E1, E2; output reg S1;
always @ (E1 or E2) begin S1 = E1 & E2; end
endmodule
13 Body: Ejemplo: Multiplexor de 4 a 1, de 4 bits: Declaración de operaciones con procesos module MUX(E0, E1, E2, E3, SEL, S);
input [3:0] E0, E1, E2, E3; input [1:0] SEL; output reg [3:0] S;
always @ (E0 or E1 or E2 or E3 or SEL) case(SEL) 0: S = E0; 1: S = E1; 2: S = E2; 3: S = E3; endcase
endmodule
14 Declaración de operaciones con procesos Body: El ejemplo anterior también se puede modelar de la siguiente forma: module MUX(E0, E1, E2, E3, SEL, S);
input [3:0] E0, E1, E2, E3; input [1:0] SEL; output [3:0] S;
always @ (E0 or E1 or E2 or E3 or SEL) if(SEl == 0) S = E0; else if(SEl == 1) S = E1; else if(SEl == 2) S = E2; else S = E3;
endmodule
15 Declaración de operaciones con procesos Body: NOTA IMPORTANTE:
Si llegáramos a omitir alguna opción de case o un if de los dos modelos anteriores, el sintetizador, al notarlo, inferirá un elemento de memoria (en estos casos un latch), para poder guardar el valor anterior, por lo tanto, YA NO SERÍA COMBINACIONAL.
Lo anterior también se presenta si no escribimos todas las entradas en la lista de sensibilidad.
Los sintetizadores muestran un aviso de precaución cuando se genera un LATCH por esta causa.
16 Creación de bancos de prueba para circuitos combinacionales Body: El banco de prueba (test bench) es un módulo el cual instancia a otro el cual deseamos simular para verificar su comportamiento
17 Ejemplo de un banco de prueba `timescale 1ns / 1ps
module PRUEBA_COMPUERTA;
reg E0, E1; //Entradas wire S; //Salida
//Instancia del modulo a simular COMPUERTA UUT(E0, E1, S);
initial begin E0 = 0; E1 = 0; #10 E0 = 0; E1 = 1; #10 E0 = 1; E1 = 0; #10 E0 = 1; E1 = 1; end
endmodule
18 Ejemplo de un banco de prueba (cont) Body: Al simular obtenemos la siguiente respuesta:
Nota: La directiva de “timescale” sirve para definir las unidades de tiempo.
Implementación de Circuitos Secuenciales
20 Circuitos Secuenciales Body: “El circuito secuencial recibe información binaria de entradas externas. Estas entradas, junto con el estado presente de los elementos de memoria, determinan el valor binario en las terminales de salida”. Morris, Mano, M. Diseño Digital. 3a. ed, Prentice-Hall, 2003
21 Circuitos Secuenciales (cont) Body: Al modelar circuitos secuenciales en Verilog se utilizan procesos (always), las pautas son diferentes en comparación con los enteramente combinacionales.
El la lista de sensibilidad colocamos el temporizador (el reloj) y opcionalmente señales que queramos darle un comportamiento asíncrono.
Si no se declaran todas las opciones se infiere un elemento de memoria, por ejemplo:
if(condicion) var = entrada; no declaramos un else, entonces si “condicion” es ‘0’ el sintetizador entenderá que tiene que guardar el valor anterior y para ello inferirá un elemento de memoria
22 Sentencias bloqueadoras y no bloqueadoras Body: Analice los siguientes procesos, los cuales utilizan sentencias bloqueadoras:
always @ (posedge CLK) A = B;
always @ (posedge CLK) B = A;
No se tiene seguridad de cual se ejecutará primero, si se ejecuta el primer proceso se pierde el valor incial de ‘A’, en caso contrarío ‘B’
Si se ejecutará el primero, lo ideal sería que el valor de ‘A’ inicial se guardará antes de asignarle el valor de ‘B’. Sentencia bloqueadora
23 Sentencias bloqueadoras y no bloqueadoras (cont) Body: Esto se puede arreglar utilizando sentencias no bloqueadoras:
always @ (posedge CLK) A <= B;
always @ (posedge CLK) B <= A;
A la variable de ‘A’ se le asigna el valor que tenía ‘B’ al inicio, y a ‘B’ el que tenía ‘A’.
Las sentencias no bloqueadoras solo se utilizan en procesos. Sentencia no bloqueadora
24 Ejemplo: Body: Al lado del HDL se muestra el circuito inferido: module REGISTRO(CLK, X, A);
input CLK, X; output A;
reg A, B;
always @ (posedge CLK)begin B = X; A = B; end
endmodule
25 Ejemplo: (cont) module REGISTRO(CLK, X, A);
input CLK, X; output A;
reg A, B; always @ (posedge CLK)begin B <= X; A <= B; end
endmodule
26 Consejos: Body: Utilice sentencias bloqueadoras cuando modele un circuito combinacional en un always. Si llegara a usar no bloqueadoras, corre el riesgo de inferir latches no deseados.
Utilice sentencias no bloqueadoras cuando modele un circuito secuencial.
27 Ejemplo: Registro con RESET sincrónico Body: El registro de este ejemplo es de 1 bit, cuya entrada es ‘D’ y salida ‘Q’, sensible al flanco positivo y con RESET sincrónico, el comportamiento puede entenderse con la siguiente figura:
28 Ejemplo: Registro con RESET sincrónico (cont) Body: El HDL sería: module REG_SINC(CLK, RESET, D, Q);
input CLK, RESET, D; output reg Q;
always @ (posedge CLK) if(RESET) Q <= 0; else Q <= D;
endmodule posedge indica que es sensible al flanco positivo, para flanco negativo Indicamos negedge
29 Ejemplo: Registro con RESET asincrónico Body: El registro de este ejemplo es de 1 bit, cuya entrada es ‘D’ y salida ‘Q’, sensible al flanco positivo y con RESET sincrónico, el comportamiento puede entenderse con la siguiente figura:
30 Ejemplo: Registro con RESET asincrónico (cont) Body: El HDL sería: module REG_ASINC(CLK, RESET, D, Q);
input CLK, RESET, D; output reg Q;
always @ (posedge CLK or posedge RESET) if(RESET) Q <= 0; else Q <= D;
endmodule Consejo: La señal asíncrona debe ser la primera por chequear en los if anidados
31 Ejemplo: Registro con RESET sincrónico (cont) Body: Un posible banco de prueba sería (daría como resultado la figura anterior): `timescale 1ns / 1ps module PRUEBA_REG_ASINC(CLK, RESET, D, Q); reg CLK = 0, RESET = 0, D = 0; wire Q;
REG_ASINC uut(CLK, RESET, D, Q);
initial forever #10 CLK = !CLK;
initial begin #20 RESET = 1; #20 RESET = 0; end
endmodule Se le asignan valores iniciales a las entradas Se simula un reloj cuyo periodo es de 2 * 10:
32 Ejemplo: Registro bidireccional Body: En este ejemplo utilizamos puertos bidireccionales y bufers de alta impedancia. module REG_BIDIRR(CLK, RESET, RD, WR, D_OUT);
input CLK, RESET, RD, WR; inout D_OUT; reg VAR;
assign D_OUT = (RD)? VAR: 1'bz;
always @ (posedge CLK) if(RESET) VAR <= 0; else if(WR) VAR <= D_OUT;
endmodule
33 Ejemplo: Registro bidireccional (cont.) Body: Estimular un puerto bidireccional es algo diferente a una entrada o una salida, prácticamente en el banco de prueba se debe modelar un buffer para poder manejar el flujo de datos.
34 Ejemplo: Registro bidireccional (cont.) Body: `timescale 1ns / 1ps
module PRUEBA_REG_BIDIRR_v;
//entradas reg CLK = 0, RESET = 0, RD = 0, WR = 0;
//BIDIRR reg D_TEMP = 0; wire D_OUT;
assign D_OUT = (WR)? D_TEMP: 1'bz;
REG_BIDIRR uut(CLK, RESET, RD, WR, D_OUT);
initial forever #10 CLK = !CLK;
initial begin #20 RESET = 1; #20 RESET = 0; #20 RD = 1; #20 RD = 0; D_TEMP = 1; WR = 1; #20 D_TEMP = 0; WR = 0; #20 RD = 1; end
endmodule Con estas declaraciones evitamos el conflicto del flujo de datos
35 Bancos de memoria Body: Para modelar una banco de memoria se usa una variable tipo “reg” en dos dimensiones: Variable de 8 bits por 1024:
reg [7:0] BANCO [1023:0];
36 Ejemplo: Bancos de 4 bits x 2k, bidireccional module BANCO_4_X_2K(CLK, WR, RD, DIRR, DATO);
input CLK, WR, RD; input [10:0] DIRR; inout [3:0] DATO;
reg [3:0] BANCO [2047:0];
assign DATO = (RD)? BANCO[DIRR]: 4'bz;
always @ (posedge CLK) if(WR) BANCO[DIRR] = DATO;
endmodule
Implementación de Máquinas de Estados Finitos
38 Concepto de Máquina de estados Body: “El circuito secuencial recibe información binaria de entradas externas. Estas entradas, junto con el estado presente de los elementos de memoria, determinan el valor binario en las terminales de salida”. Morris, Mano, M. Diseño Digital. 3a. ed, Prentice-Hall, 2003
39 Máquina de Moore Las salidas solo dependen del estado actual
40 Máquina de Moore (cont.) 1 1 1 1 1 1 1 0 0 0 1 1 0 1 0 1 1 0 0 1 1 0 1 0 1 1 0 1 0 1 1 1 1 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 Salida Z Siguiente Estado A B Entrada X Estado Actual A B Diagrama de estados Salidas se asignan en los estados Entradas controlan transiciones entre estados Tabla de estados
Página anterior | Volver al principio del trabajo | Página siguiente |