Академический Документы
Профессиональный Документы
Культура Документы
HDL VERILOG
3
BLOQUE I
Diseo de Circuitos
Combinacionales
4
Bloque I: ndice
Tipos de descripciones
Sintaxis bsica
5
Estructura de descripciones Verilog
module mi_circuito (
input x, y, Declaracin del mdulo con sus
input z, entradas y salidas: input, output,
output f1, f2 inout
);
6
Ejemplo: circuito votador
a
Expresin lgica:
b votador z z=ab+ac+bc
c
endmodule
7
Tipos de descripciones
Descripcin funcional
Modela circuitos combinaciones.
Consiste en asignaciones de las salidas de manera continua
utilizando assign.
Todas las sentencias assign se ejecutan de manera concurrente.
endmodule
z=ab+ac+bc
8
Tipos de descripciones
module votador(
Descripcin procedimental input a,b,c,
output reg z)
Permite el uso de estructuras de
control always @(a,b,c)
if(a==1)
La descripcin es algortmica, if(b==1 || c==1)
z=1;
igual que el software else
z=0;
Facilita la creacin de funciones else
complejas if(b==1 && c==1)
z=1;
Se basa en la sentencia always else
z=0;
Todas las sentencias always se endmodule
ejecutan de forma concurrente
z=ab+ac+bc
9
Tipos de descripciones
a and1 out1
b
Descripcin estructural and3
out3
or1 z
c
Se conectan mdulos que ya estn
definidos previamente and2 out2
Las puertas lgicas bsicas ya estn
module votador(
predefinidas en Verilog (and, nand, input a,b,c,
or, nor, xor, xnor, not, buf, etc.) output z)
Es muy til para la interconexin de wire out1,out2,out3;
los mdulos que se creen
and and1(out1,a,b);
Observe que se utilizan wires para and and2(out2,b,c);
conectar salidas y entradas de and and3(out3,a,c);
puertas or or1(z,out1,out2,out3);
endmodule
Sintaxis puertas: GATE instance_name(outputs, inputs)
z=ab+ac+bc 10
Tipos de descripciones
Todas las sentencias assign y always se ejecutan de
manera concurrente.
La descripcin estructural se utiliza para la
interconexin de los diferentes mdulos que se
creen.
Las descripciones estructurales conforman la jerarqua
del sistema que se est diseando.
11
Tipos de descripciones
Ejemplo de descripcin de un SUMADOR DE 4 bits a
partir de 4 FULL-ADDER
b3 b2 b1 b0 a3 a2 a1 a0
cout4 FA 4bits
SUMADOR4 cin
s3 s2 s1 s0
a3 b3 a2 b2 a1 b1 a0 b0
s3 s2 s1 s0
12
Tipos de descripciones
Pasos:
Descripcin de un mdulo para el FULL-ADDER de
un bit.
Descripcin de un mdulo donde se utilizan 4 FULL-
ADDER de un bit y se interconectan los cables de
los mdulos.
13
Tipos de descripciones
a b
module fulladder( s
input a, cin a b cout s
input b, 0 0 0 0 0
input cin, 0 0 1 0 1
output s, 0 1 0 0 1
output cout); 0 1 1 1 0
1 0 0 0 1
assign s = a ^ b ^ cin; 1 0 1 1 0
assign cout = a & b | a & cin | b & cin; 1 1 0 1 0
endmodule 1 1 1 1 1
s=abc
cout=ab + acin + bcin
14
Tipos de descripciones
Unin de 4 FULL-ADDER: conexin posicional.
a3 b3 a2 b2 a1 b1 a0 b0
module sumador4(
input [3:0] a, cout4 cout3 cout2 cout1 cin
input [3:0] b, FA3 FA2 FA1 FA0
input cin,
output [3:0] s,
output cout4); s3 s2 s1 s0
wire cout1,cout2,cout3;
endmodule
15
Tipos de descripciones
Unin de 4 FULL-ADDER: conexin nombrada.
a3 b3 a2 b2 a1 b1 a0 b0
module sumador4(
input [3:0] a, cout4 cout3 cout2 cout1 cin
input [3:0] b, FA3 FA2 FA1 FA0
input cin,
output [3:0] s,
output cout4); s3 s2 s1 s0
wire cout1,cout2,cout3;
endmodule
16
Tipos de descripciones
Descripcin procedimental
module sumador4(
El tipo de descripcin utilizada
input [3:0] a, para el mdulo no influye en cmo
input [3:0] b, se comporta ste.
input cin,
output [3:0] s,
output cout4); Se pierde la estructura interna. La
herramienta de sntesis genera un
reg [4:0] res;
always @(a,b,cin)
hardware equivalente.
res = a + b + cin;
assign cout=res[4];
assign s = res[3:0];
endmodule
17
Tipos de seales
Existen dos tipos bsicos de seales
wire: corresponden a cables fsicos que interconectan
componentes, por tanto, no tienen memoria.
reg: (tambin llamada variable). Son utilizados para almacenar
valores, tienen memoria.
Los tipos (reg) se utilizan para modelar el
almacenamiento de datos
Todos los asignamientos que se realicen dentro de un
procedimiento (always) deben ser sobre una seal
tipo reg
18
Puertos de entrada/salida
Cuando se declaran mdulos se puede especificar si
un puerto es tipo wire o reg
Si no se indica nada es por defecto
module mi_circuito (
wire input wire x,
Los cables (wire) son utilizados input z,
con la sentencia assign output reg mem
);
Los registro (reg) son asignados ...
en los procedimientos endmodule
19
Arrays
Los arrays son agrupaciones de bits, motivos:
Los puertos de entrada/salida se agrupan (buses) para trabajar con
mayor comodidad
Los registros pueden ser de varios bits
Sintaxis: [M:N]
module comparador_gel (
A3 input wire [3:0] a,
A2
A1
input [3:0] b,
G
A0 output g,e,l
COMPARADOR E
GEL );
B3 L ...
B2
B1
endmodule
B0
20
Sintaxis bsica
Literales
Sentencia assign
Sentencia always
Expresiones y operadores
Sentencias condicionales
21
Sintaxis bsica
Verilog distingue entre maysculas y minsculas
Se pueden escribir comentarios:
Comentario en linea: precedido de doble barra //
wire a; // Este cable se conecta con f2
wire a;
22
Sintaxis bsica
Literales: Se puede expresar en varios formatos
Ejemplo: 00101010 en binario
23
Sintaxis bsica
Ejemplo de literales: Circuito que siempre tiene sus
salidas a uno
module siempre_uno (
input x,
output [7:0] salida1,
output [3:0] salida2
);
endmodule
24
Sentencia assign
Todas las sentencias assign se module otro_ejemplo (
ejecutan de manera input x, y, z,
output f1, f2
concurrente );
En el ejemplo la salida f2 es assign f1 = x & y;
equivalente a: assign f2 = f1 & z;
endmodule
assign f2 = x & y & z;
25
Sentencia always
Un bloque always se ejecuta concurrentemente con los
dems bloques always y assign que hay en la
descripcin HDL
Los bloques always tienen una lista de sensibilidad:
La lista de sensibilidad consiste en una lista de seales.
El cdigo del bloque always se ejecuta slo si cambia alguna de las
seales de la lista de sensibilidad.
La sintaxis es:
always @(a,b)
c = a | b;
26
Sentencia always
Una sentencia always suele
contener varias sentencias, en
cuyo caso, debe utilizar un module (input a, b, c, d
output reg f1,
bloque begin end output reg f2);
always @(a,b,c,d)
Los bloques begin/end se utilizan begin
f1 = a | b;
para agrupar un conjunto de f2 = c & d;
sentencias. end
endmodule
Son ampliamente utilizados
27
Sentencia always
Importante regla general sobre la lista de sensibilidad:
Siempre que se est describiendo un componente combinacional,
se debe incluir en la lista de sensibilidad todas las entradas del
componente
Se puede simplificar la sintaxis mediante: always @(*)
=
input e, f, g, h, input e, f, g, h,
output f1, f2); output f1, f2);
always @(a,b,c,d,e,f,g,h) always @(*)
begin begin
... ...
end end
endmodule endmodule
28
Operadores
Operadores a nivel de bits:
Operador Ejemplo de cdigo Verilog
& c = a&b; // Operacin AND de todos los bits
| c = a|b; // Operacin OR de todos los bits
^ c = a^b; // Operacin XOR de todos los bits
~ b = ~a; // Inversin de todo los bits
29
Operadores
Ms operadores a nivel de bits
Operador Ejemplo de cdigo Verilog
module complemento_a1(
input [15:0] palabra,
output [15:0] complemento_1);
endmodule
31
Operadores
Operadores relacionales: devuelven 1 si es verdadera
la condicin
Operador Ejemplo de cdigo en Verilog
< a < b; //Es a menor que b?
> a > b; //Es a mayor que b?
>= a >= b; //Es a mayor o igual que b?
<= a <= b; //Es a menor o igual que b?
== a == b; //Devuelve 1 si a es igual que b
!= a != b; //Devuelve 1 si a es distinto de b
32
Operadores
Operadores lgicos: No confundirlos con los
operadores a nivel de bits.
|| a || b; // Devuelve 1 si a b es verdadero
!a; // Devuelve 1 si a es falso 0 si a
!
// es verdadero
33
Operadores
Operadores aritmticos
34
Operadores
Otros operadores
Operador Ejemplos en cdigo Verilog
<< b = a << 1; //Desplazamiento a la
//izq. de un bit
>> b = a >> 1; //Desplazamiento a la
//der. de un bit
?: c = sel ? a : b; // si sel es uno
//entonces c = a,sino entonces c = b
{} {a, b, c} = 3'b101; // Conatenacin:
// Asigna una palabra a bits
// individuales: a=1, b=0 y c=1
36
Sentencias condicionales
Si hay ms de una sentencia tras una condicin, hay
que utilizar bloques begin end
always @(a)
always @(a) begin
begin if ( a > 0 )
if ( a > 0 ) begin
f1 = 1; f1 = 1;
f2 = 1; ERROR Correcto
f2 = 1;
else end
f1 = 0; else
end f1 = 0;
end
37
Sentencias condicionales
module comparador_gel(
Ejemplo de input [3:0] a,
input [3:0] b,
comparador GEL output g, //
output e, //
si a < b => (g,e,l) = (0,0,1)
si a = b => (g,e,l) = (0,1,0)
output l);
reg g, e, l;
always @(a, b)
A3 begin
A2 g = 0;
A1 G e = 0;
A0 l = 0;
COMPARADOR E if (a > b)
GEL g =1;
B3 L
else if (a < b)
B2 l = 1;
B1 else
B0 e = 1;
end
endmodule
38
Sentencias condicionales
reg [1:0] x;
Sentencia case always @(x)
begin
Se utiliza dentro de un proceso case(x)
always 0:
salida_1 = 1;
Si alguno de los casos tiene ms de 1:
una sentencia hay que utilizar un begin
salida_1 = 1;
bloque begin end salida_2 = 0;
Se puede utilizar default para los end
2:
casos no enumerados salida_2 = 1;
3:
salida_1 = 0;
endcase
end
39
Sentencias condicionales
module mux8_1(
Multiplexor 8:1 input [2:0] s,
input [7:0] in,
Ejemplo de acceso a output out);
elementos individuales de reg out;
un array always @(s, in)
case (s)
in0 3'h0: out = in[0];
in1 3'h1: out = in[1];
in2 3'h2: out = in[2];
in3 3'h3: out = in[3];
in4 out 3'h4: out = in[4];
in5 3'h5: out = in[5];
in6 3'h6: out = in[6];
in7 default: out = in[7];
endcase
s2 s1 s0 endmodule
40
BLOQUE II
Diseo de Circuitos Secuenciales
41
Bloque II: ndice
Sintaxis II
Biestables
Mquinas de estados
Registros
Contadores
42
Sintaxis II
Definicin de constantes
Operador de concatenacin
43
Sintaxis II
Dentro de un mdulo se pueden definir constantes
utilizando parameter
Es til en la definicin de mquinas de estados
Ejemplo:
parameter uno_con_tres_bits = 3'b001,
ultimo = 3'b111;
reg [2:0] a;
a = ultimo;
44
Sintaxis II
module concatena(
El operador concatenar se utiliza input a,b,c,
para agrupar seales para output reg igual_a_3
);
que formen un array
always @(*)
Sintaxis: {seal, seal, ....} case({a,b,c})
3'b011:
Ejemplo: igual_a_3 = 1;
Detector del nmero 3 default:
igual_a_3 = 0;
endcase
endmodule
45
Sintaxis II
Deteccin de flanco
Sirve para que un proceso slo se ejecute en determinados flancos
de reloj de una o varias seales de entrada.
Se indica en la lista de sensibilidad de un proceso mediante un
prefijo a la seal:
El prefijo posedge detecta el flanco de subida
El prefijo negedge detecta el flanco de bajada
46
Sintaxis II
Ejemplo de deteccin de flanco negativo de un reloj
module detector_flanco(
input clk,
output reg z);
47
Sintaxis II
Asignamiento bloqueante signo =
Si en un proceso se desea que la salida cambie inmediatamente,
se debe utilizar una asignacin bloqueante.
Esto modela una salida combinacional.
Importa el orden en que se efectan las asignaciones bloqueantes
puesto que las acciones en un proceso se ejecutan
secuencialmente
48
Sintaxis II
Asignamiento no bloqueante signo <=
La asignacin no bloqueante modela las escrituras en flip-flops.
Se calculan primero los valores de la derecha de la asignacin de
todas las asignaciones <=, tras esto, se asignan todas
simultneamente.
Cuando se tiene una serie de asignaciones no bloqueantes, no
importa el orden en que son escritas.
49
Sintaxis II
module no_bloqueante(input a,clk, module bloqueante(input a,clk,
output reg z1); output reg z2);
reg q; reg q;
always @(posedge clk) always @(posedge clk)
begin begin
q <= a; q = a;
z1 <= q; z2 = q;
end end
endmodule endmodule
clk
a
z1
z2
50
Biestables
Ejemplo de biestables: module biestable_d(
input ck,d,
output reg q);
q
D always @ (posedge clk)
q <= d;
clk
endmodule
clk
51
Biestables
Ejemplo de biestable D disparado en flanco negativo
module biestable_d(
input ck,d,
q output reg q);
D always @ (negedge clk)
q <= d;
ck
endmodule
clk
52
Biestables
Biestable D con reset module biestable_d(
input ck,d,reset,
asncrono output reg q);
ck
clk
d
reset
q
53
Biestables
Biestable D con reset sncrono
module biestable_d(
clk input ck,d,reset,
output reg q);
54
Biestables
Biestable JK module jk_flip_flop (
input clk,
input j,
input k,
J q
output reg q);
K always @(negedge clk)
ck
case ({j,k})
2'b11 : q <= ~q; // Cambio
JK 2'b01 : q <= 1'b0; // reset.
00 01 11 10
q 2'b10 : q <= 1'b1; // set.
0 0 0 1 1 2'b00 : q <= q; //
endcase
1 1 0 0 1
endmodule
Q
55
Biestables
Biestable T
module biestable_t(
q input ck,
T input t,
output reg q);
ck
always @(negedge ck)
T=1 if (t == 1)
q <= ~q;
T=0 T=0
q= q= endmodule
0 1
T=1
56
Biestables
Ejercicios: Realice los siguientes biestables, sabiendo
las seales CL y PR son sncronas
CL PR CL PR CL PR CL PR
S q J q q q
D T
R K
ck ck ck ck
57
Mquinas de estado
1/0 Se utilizar una estructura
B 0/0 general del cdigo en la que hay 2
1/0
procesos
A
1/0 C Uno de asignacin de
1/1
0/0 siguientes estados
58
Mquinas de estado
module mi_diagrama_de_estados(
input LISTA_DE_ENTRADAS,
output reg LISTA_DE_SALIDAS);
59
Mquinas de estado
En la estructura general hay que completar 4 partes de
cdigo:
Definicin y asignacin de estados, segn el nmero de estados
utilizaremos mas o menos bits.
Definicin de registros para almacenar el estado actual y el
siguiente. Deben ser del mismo tamao en bits que el utilizado en
el punto anterior
Proceso de cambio de estado: Siempre es el mismo cdigo
Proceso de clculo de siguiente estado y salida: Hay que
rellenar el cdigo correspondiente las transiciones del
diagrama de estados
60
Mquinas de estado
1/0
module maquina_estados(
input x, clk, reset,
output reg z); B 0/0
1/0
parameter A = 2'b00,
B = 2'b01, Asignacin
C = 2'b10,
D = 2'b11; de estados 1/0
A C
reg [1:0] current_state,next_state;
1/1
0/0
always @(posedge clk, posedge reset)
begin
if(reset) 0/0 0/0
current_state <= A; D
else
current_state <= next_state;
end Proceso
de asignacin
SIGUE ->
de siguiente estado
61
Mquinas de estado
El proceso de calculo del siguiente estado y salida se
realiza con una nica sentencia case
La sentencia case debe contemplar todos los estados del diagrama
de estados
Antes de la sentencia case se recomienda establecer por defecto a
cero todas las salidas.
62
Mquinas de estado
1/0
always @(current_state,x)
begin Salida a cero
z = 0; B 0/0
1/0
case(current_state)
A:
if(x == 1)
next_state = B; Estado A 1/0
else C
next_state = A; A
1/1
B: 0/0
if(x == 1)
next_state = B;
else Estado B
next_state = C; 0/0 0/0
D
63
Mquinas de estado
C: 1/0
if(x == 1)
next_state = B; Estado C
else B 0/0
next_state = D;
1/0
D:
if(x == 1)
begin
z = 1; 1/0
A C
next_state = B; Estado D 1/1
end 0/0
else
next_state = A;
endcase
end 0/0 0/0
endmodule
D
64
Registros
Registro con carga en paralelo y module registro(
input ck,
clear x x x x input cl,
3 2 1 0
input ld,
input [3:0] x,
CL output [3:0] z
);
LD REG
CK reg [3:0] q;
65
Registros
module reg_shl(
Registro de desplazamiento input ck,
input cl,
xL input en,
input xl,
output zl
CL );
EN REG
reg [3:0] q;
CK
always @(posedge ck, negedge cl)
zL if (cl == 0)
q <= 0;
else if (en == 1)
CL, EN Operation Type q <= {q[2:0], xl};
0x q0 async.
assign zl = q[3];
11 q SHL(q) sync.
endmodule
10 qq sync.
66
Contadores
Contador ascendente con clear
module count_mod16(
input ck,
input cl,
CL output [3:0] z);
COUNT
CK reg [3:0] q;
67
Contadores
module rev_counter1(
input ck,
Contador ascendente/ input cl,en, ud,
descendente con clear output [3:0] z, output c);
reg [3:0] q;
CL
EN always @(posedge ck, posedge cl)
COUNT C begin
UD
if (cl == 1)
CK q <= 0;
else if (en == 1)
z3 z2 z1 z0 if (ud == 0)
q <= q + 1;
else
CL, EN, UD Operation Type q <= q - 1;
1xx q0 async. end
00x qq sync. assign z = q;
010 q q+1|mod 16 sync. assign c = ud ? ~(|q) : &q;
endmodule
011 q q-1|mod 16 sync.
68
Bloque III
Simulacin y verificacin
69
Bloque III: ndice
Prueba y verificacin de circuitos.
Prueba y verificacin de mdulos Verilog.
Estructura general del testbench.
El testbench de un circuito combinacional.
Ejemplo: testbench de un decodificador 2:4
El testbench de un circuito secuencial.
Ejemplo: testbench de un contador mdulo 16.
70
Prueba y verificacin de circuitos
Introduccin
Los circuitos reales ya implementados deben ser probados para
verificar que su funcionamiento se ajusta a las especificaciones.
Esto permitir detectar problemas de en su funcionamiento.
Lo mismo ocurre con las descripciones Verilog de los circuitos.
Pueden tener errores y es necesario detectarlos, antes incluso de
pasar a la fase de implementacin del circuito a partir de su
descripcin en Verilog.
Esto se consigue gracias a la simulacin del funcionamiento y
posterior verificacin de los circuitos descritos en Verilog.
71
Prueba y verificacin de circuitos
Cmo se prueba un circuito real?
Obviamente, no basta con conectarlo a una fuente de alimentacin
adecuada y observar su comportamiento.
Adems ser necesario darle diferentes valores a sus entradas e ir
viendo si el valor de sus salidas es el correcto en cada momento.
Para ello se debe conectar el circuito a probar a otros equipos
adicionales, que generaran seales especiales como la de reloj, o a
circuitos auxiliares que generen seales de entrada de diversos
valores.
Mediante el osciloscopio u otros equipos, el usuario verifica que las
salidas obtenidas para las distintas entradas son las correctas.
72
Prueba y verificacin de mdulos Verilog
Cmo se prueba un mdulo Verilog?
La descripcin de un mdulo en Verilog no es un circuito real, pero
hay herramientas que simulan su funcionamiento.
Para probar un mdulo Verilog no basta con introducirlo en una
herramienta de simulacin y darle al botn simular funcionamiento.
Esto sera simplemente el equivalente a conectar un circuito real a
una fuente de alimentacin.
Debemos disear en Verilog un mdulo especial llamado testbench y
ese ser el que le suministraremos al simulador para que simule su
funcionamiento.
El modulo testbench contiene al modulo a probar y se encarga de
suministrarle entradas con distintos valores para que luego el usuario
pueda comprobar si las salidas del mdulo son las correctas.
73
Estructura general del testbench
El testbench (o tb) es un mdulo Verilog sin entradas ni salidas.
75
El testbench de un circuito combinacional
Ejemplo: testbench de un decodificador 2:4
76
Ejemplo: testbench de DEC 2:4
Establecemos 1ns como unidad base para medir retrasos y tiempos de espera.
initial begin
$monitor("EN=%b A=%b Q=%b tiempo=%0dns",tb_EN,tb_A,tb_Q,$time);
{tb_EN, tb_A[1:0]} = 3'b000; Asignamos un valor inicial a las entradas,
#800; tratndolas como un nico vector de 3 bits.
$finish;
end Esta sentencia introduce una espera de 800ns
antes de pasar a la siguiente sentencia.
$finish detiene la simulacin.
always begin Bloque always. Repite siempre las mismas
#100; // Espera 100ns sentencias indefinidamente, en un bucle infinito.
{tb_EN, tb_A[1:0]} = {tb_EN, tb_A[1:0]} + 3'b001;
end Cada 100ns cambiamos el valor de las entradas de
endmodule forma cmoda, considerndolas como un nico vector
de tres bits al que le sumamos una unidad.
78
Ejemplo: testbench de DEC 2:4
Estos son los mensajes que muestra en pantalla la
herramienta de simulacin cuando le pedimos que simule
el funcionamiento del mdulo de testbench.
80
El testbench de un circuito secuencial
81
El testbench de un circuito secuencial
Ejemplo: testbench de un contador mdulo 16
Este es el mdulo secuencial que queremos
module contador_mod_16( probar. Es un contador ascendente de 4 bits
input CK, con carga sncrona en paralelo y seal de fin
input LD, de cuenta (la salida CY).
input EN,
input [3:0] X, Aqu vemos la entrada de la seal de reloj,
output reg [3:0] Q,
CK, propia de un circuito secuencial.
output CY La entrada de control LD (carga o LOAD) debe
); provocar la carga sncrona en el contador del
assign CY = &Q; valor presente en la entrada X.
always @(posedge CK) La entrada de control EN (ENABLE) habilita la
if (LD == 1) operacin de cuenta ascendente.
Q <= X; El contador est sincronizado con los flancos
else if (EN == 1) de subida del reloj (posedge CK)
Q <= Q + 4'b0001; LD tiene prioridad sobre EN si se activan ambas. Si no
endmodule se activa ninguna de las dos, la salida Q no cambia.
82
Ejemplo: testbench contador md. 16
`timescale 1ns / 1ps
El mdulo de testbench de un circuito secuencial
es diferente al de un circuito combinacional, pero
module contador_mod_16_tb;
hay cosas que se hacen siempre de igual forma:
reg tb_CK;
Se declara como un mdulo sin entradas ni salidas.
reg tb_LD;
reg tb_EN;
reg [3:0] tb_X; Igual que siempre, se declaran las variables
wire [3:0] tb_Q; necesarias de tipo reg y de tipo wire.
wire tb_CY;
contador_mod_16 instancia_de_contador_mod_16 (
.CK(tb_CK),
.LD(tb_LD),
.EN(tb_EN),
.X(tb_X), Como siempre, se crea una instancia del
.Q(tb_Q), mdulo a probar (el contador),
conectndola a las variables
.CY(tb_CY)
previamente declaradas.
);
/* Sigue en la pgina siguiente */
83
Ejemplo: testbench contador md. 16
La sentencia always repite
/* Viene de la pgina anterior */ indefinidamente, en bucle, las acciones
de interior del bloque begin-end.
always begin
#50;
La variable tb_CK invierte su valor cada 50ns, generndose
de esta forma una seal de reloj de perodo 100ns que se
tb_CK = ~tb_CK;
inyecta como entrada a la instancia del contador.
end
El bloque initial se ejecuta en paralelo con el always.
initial begin
$monitor("CK=%b LD=%b EN=%b X=%b Q=%b CY=%b tiempo=%0dns",
tb_CK,tb_LD,tb_EN,tb_X,tb_Q,tb_CY,$time);
tb_CK = 0;
Al usar $monitor veremos en pantalla
tb_LD = 1;
los cambios de valor de las variables.
tb_EN = 0;
tb_X = 4'b1100;
Le damos a las entradas del contador los
/* Sigue en la pgina siguiente */ valores iniciales que creamos oportunos.
84
Ejemplo: testbench contador md. 16
/* Viene de la pgina anterior */ En el bloque initial, tras darle valores
/* Sigue el bloque initial */ iniciales a las variables, iremos cambiando
@(negedge tb_CK); sus valores cada un cierto tiempo.
tb_X = 4'b0011;
@(negedge tb_CK); Esta sentencia se queda esperando un tiempo,
tb_X = 4'b1101; hasta que tb_CK cambie de 1 a 0 (flanco de bajada).
tb_EN = 1;
Por tanto la variable tb_X tomar el valor 4b0011
@(negedge tb_CK);
justo despus del flanco de bajada de tb_CK.
tb_LD = 0;
tb_X = 4'b1001;
Escribir repeat ( 5 ) delante de la sentencia
repeat ( 5 )
@negedge tb_CK; es ms cmodo y equivale
@(negedge tb_CK); a escribir 5 veces seguidas la sentencia
tb_EN = 0; @negedge tb_CK;
@(negedge tb_CK);
$finish; Tras haber cambiado las entradas del contador de
end /* del bloque initial */ la manera que hayamos estimado conveniente,
endmodule ordenamos con $finish que finalice la simulacin.
85
Ejemplo: testbench contador md. 16
CK=0 LD=1 EN=0 X=1100 Q=xxxx CY=x tiempo=0ns Gracias a la sentencia
CK=1 LD=1 EN=0 X=1100 Q=1100 CY=0 tiempo=50ns $monitor, al simular el
CK=0 LD=1 EN=0 X=0011 Q=1100 CY=0 tiempo=100ns
testbench se nos informa
de los cambios en los
CK=1 LD=1 EN=0 X=0011 Q=0011 CY=0 tiempo=150ns
valores de las variables de
CK=0 LD=1 EN=1 X=1101 Q=0011 CY=0 tiempo=200ns
entrada (CK, LD, EN, y X ) y
CK=1 LD=1 EN=1 X=1101 Q=1101 CY=0 tiempo=250ns
de salida (Q y CY) del
CK=0 LD=0 EN=1 X=1001 Q=1101 CY=0 tiempo=300ns circuito a probar.
CK=1 LD=0 EN=1 X=1001 Q=1110 CY=0 tiempo=350ns
CK=0 LD=0 EN=1 X=1001 Q=1110 CY=0 tiempo=400ns Podemos verificar,
CK=1 LD=0 EN=1 X=1001 Q=1111 CY=1 tiempo=450ns analizando el resultado de
CK=0 LD=0 EN=1 X=1001 Q=1111 CY=1 tiempo=500ns la simulacin, si el circuito
CK=1 LD=0 EN=1 X=1001 Q=0000 CY=0 tiempo=550ns bajo prueba, el contador
CK=0 LD=0 EN=1 X=1001 Q=0000 CY=0 tiempo=600ns mdulo 16, se comporta
CK=1 LD=0 EN=1 X=1001 Q=0001 CY=0 tiempo=650ns correctamente.
CK=0 LD=0 EN=1 X=1001 Q=0001 CY=0 tiempo=700ns
Por ejemplo: Si LD=0 y
CK=1 LD=0 EN=1 X=1001 Q=0010 CY=0 tiempo=750ns EN=0, aunque CK pasa de
CK=0 LD=0 EN=0 X=1001 Q=0010 CY=0 tiempo=800ns valer 0 a valer 1, vemos
CK=1 LD=0 EN=0 X=1001 Q=0010 CY=0 tiempo=850ns que la salida Q no cambia
Stopped at time : 900 ns de valor (correcto).
86
Ejemplo: testbench contador md. 16
CK=0 LD=1 EN=0 X=1100 Q=xxxx CY=x tiempo=0ns
CK=1 LD=1 EN=0 X=1100 Q=1100 CY=0 tiempo=50ns
Adems de informar al usuario mediante informacin textual en pantalla, la
CK=0 LD=1 EN=0 X=0011 Q=1100 CY=0 tiempo=100ns
herramienta de simulacin tambin muestra las formas de onda de las variables
CK=1 LD=1 EN=0 X=0011 Q=0011 CY=0 tiempo=150ns
declaradas en el mdulo testbench, que son: tb_CK, tb_LD, tb_EN, tb_X, tb_Q y tb_CY.
CK=0 LD=1 EN=1 X=1101 Q=0011 CY=0 tiempo=200ns
CK=1 LD=1 EN=1 X=1101 Q=1101 CY=0 tiempo=250ns
CK=0 LD=0 EN=1 X=1001 Q=1101 CY=0 tiempo=300ns
CK=1 LD=0 EN=1 X=1001 Q=1110 CY=0 tiempo=350ns
CK=0 LD=0 EN=1 X=1001 Q=1110 CY=0 tiempo=400ns
CK=1 LD=0 EN=1 X=1001 Q=1111 CY=1 tiempo=450ns
CK=0 LD=0 EN=1 X=1001 Q=1111 CY=1 tiempo=500ns
CK=1 LD=0 EN=1 X=1001 Q=0000 CY=0 tiempo=550ns
CK=0 LD=0 EN=1 X=1001 Q=0000 CY=0 tiempo=600ns
CK=1 LD=0 EN=1 X=1001 Q=0001 CY=0 tiempo=650ns
CK=0 LD=0 EN=1 X=1001 Q=0001 CY=0 tiempo=700ns
Podemos verificar, analizando las formas de onda detenidamente, que el testbench est
CK=1 LD=0 EN=1 X=1001 Q=0010 CY=0 tiempo=750ns
cambiando los valores de las entradas del circuito bajo prueba segn habamos previsto
CK=0 LD=0
y queEN=0 X=1001
las salidas Q=0010
de dicho CY=0
circuito tiempo=800ns
evolucionan tambin de forma correcta.
CK=1 LD=0 EN=0 X=1001 Q=0010 CY=0 tiempo=850ns
Stopped at time : 900 ns
87
Ejemplo: testbench contador md. 16
La generacin de una seal de reloj peridica es una tarea necesaria en los
testbench de circuitos secuenciales.
always begin
#50;
tb_CK = ~tb_CK;
end
88
Ejemplo: testbench contador md. 16
initial begin
$monitor("CK=%b LD=%b EN=%b X=%b Q=%b CY=%b tiempo=%0dns",
tb_CK,tb_LD,tb_EN,tb_X,tb_Q,tb_CY,$time);
tb_CK = 0;
tb_LD = 1;
tb_EN = 0;
tb_X = 4'b1100;
Comprobamos que los valores de las variables
tb_CK, tb_LD, tb_EN y tb_X en el instante 0ns
@(negedge tb_CK);
son los que programamos al principio del
tb_X = 4'b0011;
bloque initial del testbench.
@(negedge tb_CK);
tb_X = 4'b1101;
tb_EN = 1;
@(negedge tb_CK);
tb_LD = 0;
tb_X = 4'b1001;
/* Sigue en la pgina siguiente */
89
Ejemplo: testbench contador md. 16
initial begin
$monitor("CK=%b LD=%b EN=%b X=%b Q=%b CY=%b tiempo=%0dns",
tb_CK,tb_LD,tb_EN,tb_X,tb_Q,tb_CY,$time);
tb_CK = 0;
tb_LD = 1;
tb_EN = 0;
tb_X = 4'b1100; Comprobamos que, tal y como habamos programado
usando la sentencia @(negedge tb_CK), el testbench
@(negedge tb_CK);
no pone la variable tb_X a valor 0011 (binario) hasta
que no se produce un flanco de bajada en tb_CK.
tb_X = 4'b0011;
@(negedge tb_CK);
tb_X = 4'b1101;
tb_EN = 1;
@(negedge tb_CK);
tb_LD = 0;
tb_X = 4'b1001;
/* Sigue en la pgina siguiente */
90
Ejemplo: testbench contador md. 16
initial begin
$monitor("CK=%b LD=%b EN=%b X=%b Q=%b CY=%b tiempo=%0dns",
tb_CK,tb_LD,tb_EN,tb_X,tb_Q,tb_CY,$time);
tb_CK = 0;
tb_LD = 1;
tb_EN = 0;
tb_X = 4'b1100;
92
Ejemplo: testbench contador md. 16
An no hemos comprobado si las formas de onda de salida son correctas.
Solo hemos comprobado que las entradas del contador cambian como habamos
planeado al disear el mdulo de testbench.
95
Bloque IV: ndice
Introduccin
Definicin de FPGA
96
Introduccin
El lenguaje verilog que hemos visto en las transparencias anteriores,
permite la descripcin de circuitos simples pero tambin de otros mucho
ms complejos cmo podra ser un microprocesador.
Dichas descripciones tienen dos objetivos principales:
Simular el comportamiento del circuito.
Verificar que se cumplen las especificaciones deseadas.
Implementar el diseo.
La implementacin final puede llevarse a cabo mediante dispositivos
programables o mediante ASIC.
En esta asignatura se utilizar un dispositivo programable denominado
FPGA para la realizacin de los diseos.
Se dispone de herramientas de desarrollo que permiten realizar una
implementacin automtica de un diseo descrito en verilog sobre una
FPGA
97
Definicin de FPGA
Una FPGA
(Field-Programmable Gate
Array) es un dispositivo
programable:
Permite implementar
cualquier circuito digital.
La nica limitacin es la
cantidad de puertas del
circuito.
El desarrollo se realiza
sobre una placa de
entrenamiento.
98
Principales fabricantes y modelos de
FPGA
Xilinx:
Spartan
Otros
Virtex
Actel
Lattice
Altera:
Arria
Xilinx Cyclone
Stratix
Altera Actel:
Igloo
Cuota de mercado
ProASIC
SmartFusion
99
Recursos internos de una FPGA
En general, una FPGA contiene los siguientes recursos internos:
Recursos lgicos:
Slices, agrupados en CLB (Configurable Logic
Blocks).
Memoria BRAM (Block RAM).
Multiplicadores empotrados.
Recursos de interconexin:
Interconexin programable.
Bloques de entrada/salida IOB (Input/Output Blocks).
Otros recursos:
Bferes de reloj.
Lgica de escaneo de pines (boundary scan logic)
normalmente mediante conexin JTAG (Join Test
Action Group).
100
Estructura general de la FPGA modelo
Virtex-II de Xilinx
BRAM IOB
Interconexin
programable
Multiplicadores
CLB
empotrados
Gestin
reloj
101
Estructura general de la FPGA modelo
Virtex-II de Xilinx
Cada CLB de la Virtex-II
permite generar
funciones
combinacionales y
secuenciales.
Contiene:
4 Slices
Conexionado hacia
los CLBs vecinos
Una matriz de conexin
que permite su conexin
con el resto de elementos
de la FPGA.
102
Unidad bsica de programacin: slice
Cada slice incluye bsicamente:
2 biestables D.
Virtex-II 2 bloques de carry.
2 bloques LUT
(Look-Up Table).
Multiplexores que permiten
diferentes configuraciones
PR
Los bloques LUT
LUT Carry D
CE Q Son programables (equivalen a una
ROM 16x1) y pueden implementar
CL cualquier funcin de 4 variables
Las dos LUTs del mismo slice se
pueden combinar para formar
funciones combinacionales de ms
PR
variables.
LUT Carry D
Los biestables D
CE Q Dispone de Pr y Cl (configurables en
modo asncronos o sncronos)
CL
Pueden trabajar en modo latch o en
modo registro.
103
Unidad bsica de programacin: BRAM y
Multiplicador
BRAM 18Kx1 configurable
como:
Memoria de uno o dos
puertos
16kx1, 8kx2, 1kx18,
Conectada a la red
general a travs de 4
matrices de conexin.
Multiplicador:
18 x 18 bits
Complemento a 2.
104
Unidad bsica de programacin: IOB
IOB
Admiten diferentes tipos de seales:
Diferencial (dos pads
consecutivos)
Single-ended
Tres partes:
Entrada
Salida
Control de salida (triestado)
Cada parte tiene dos biestables
configurables como latch o registro.
Cada pin o pad puede configurarse
como entrada, salida o bidireccional
La impedancia (o resistencia) de
salida se puede controlar digitalmente.
Cada 2 o 4 pads tiene un matriz de
conexin que los conecta al conjunto.
Permite transferencias al doble de
velocidad DDR.
105
Unidad bsica de programacin:
Interconexin
La mayora de las seales se envan por la red de lneas
horizontales y verticales a la que los diferentes CLB, IOB, etc,
tienen acceso a travs de la matriz de interconexin programable.
106
Unidad bsica de programacin:
Long lines Interconexin
Bidireccionales
24 horizontales por cada fila y columna
Abarcan toda la FPGA
Hex lines
Unidireccionales
120 por cada fila y columna.
Conectan un bloque con su tercero o sexto
Double lines
Unidireccionales
40 por cada fila y columna
Conectan un bloque con su contiguo o al
siguiente.
Direct connect lines
Conectan un CLB con sus contiguos
(incluyendo la diagonal ).
16 en total
Fast connect lines
Internas al CLB, salidas de las LUTs a las
entradas de otras LUTs
107
Unidad bsica de programacin:
Programacin
Una FPGA puede estar en dos estados: Configuracin y Operacin.
Cuando la FPGA despierta despus del encendido, se encuentra en modo
configuracin con todas sus salidas inactivas.
La configuracin requiere el envo de un patrn de bits con el mapa de
conexiones internas por unos pines especiales que sta posee (JTAG o
serial synchronous).
Una vez configurada, la FPGA pasa al modo operacin, realizando la
funcin lgica con la que se configur.
Hay varias formas de configurar la FPGA:
108
Bibliografa y referencias
Online: Verilog-1995 Quick Reference Guide by Stuart Sutherland of
Sutherland HDL, Inc., Portland, Oregon, USA at
http://www.sutherland-hdl.com/online_verilog_ref_guide/vlog_ref_top.html
Verilog Tutorial: http://www.asic-world.com/verilog/veritut.html
Verilog HDL Quick Reference Guide (Verilog-2001 standard)
http://sutherland-hdl.com/online_verilog_ref_guide/verilog_2001_ref_guide.pdf
Introduction to Verilog. Peter Nyasulu. URL:
http://www.csd.uoc.gr/ ~hy220/ 2009f/ lectures/ verilog-notes/ VerilogIntroduction.pdf
109