Professional Documents
Culture Documents
Este tutorial pretende ser una gua de aprendizaje para el diseo HDL usando Verilog. Los
conceptos del diseo se explican a lo largo de los ejemplos que se van desarrollando. Cada
apunte a la sintaxis, representacin de constantes, directivas, etc se introduce a medida que
van siendo necesarios para el desarrollo del ejemplo. Por todo esto y debido a la estructura de
su contenido, no se puede considerar este tutorial una gua de consulta sino de aprendizaje de
este lenguaje.
Acerca del lenguaje
1 INTRODUCCIN..............................................................................................................................4
1.1 ACERCA DEL LENGUAJE ................................................................................................................4
1.2 NIVELES DE ABSTRACCIN EN VERILOG........................................................................................4
2 MI PRIMER DISEO .......................................................................................................................5
2.1 INTRODUCCIN .............................................................................................................................5
2.2 ALGUNAS CONSIDERACIONES ACERCA DEL LENGUAJE ..................................................................6
2.3 NMEROS EN VERILOG .................................................................................................................6
2.4 TIPOS DE DATOS ............................................................................................................................6
3 PROCESOS ........................................................................................................................................7
3.1 ASIGNACIN CONTINUA ................................................................................................................9
3.2 TEMPORIZACIONES ........................................................................................................................9
3.3 EVENTOS .....................................................................................................................................10
4 MDULOS Y JERARQUAS.........................................................................................................10
4.1 CONEXIONADO ............................................................................................................................10
5 TESTBENCH....................................................................................................................................11
5.1 ESTRUCTURA DE UN TESTBENCH .................................................................................................11
5.2 MDULO TEST .............................................................................................................................11
5.2.1 Interfaz de entrada/salida...................................................................................................12
5.2.2 Generacin de estmulos ....................................................................................................12
6 MODELADO DE MEMORIAS EN VERILOG............................................................................14
6.1 USO DE PARMETROS ..................................................................................................................15
7 OPERADORES EN VERILOG ......................................................................................................15
7.1 OPERADORES ARITMTICOS ........................................................................................................15
7.2 OPERADORES RELACIONALES ......................................................................................................16
7.3 OPERADORES DE IGUALDAD ........................................................................................................16
7.4 OPERADORES LGICOS ................................................................................................................16
7.5 OPERADORES BIT A BIT (BIT-WISE) ..............................................................................................16
7.6 OPERADORES DE REDUCCIN ......................................................................................................16
7.7 OPERADORES DE DESPLAZAMIENTO ............................................................................................17
7.8 OPERADOR DE CONCATENACIN .................................................................................................17
7.9 OPERADOR CONDICIONAL ...........................................................................................................17
7.10 PRECEDENCIA DE LOS OPERADORES ............................................................................................17
8 ESTRUCTURAS MS COMUNES ...............................................................................................17
8.1 SENTENCIAS CONDICIONALES IF ELSE .......................................................................................17
8.2 SENTENCIA CASE .........................................................................................................................18
8.3 SENTENCIA CASEZ Y CASEX .........................................................................................................19
8.4 SENTENCIAS DE BUCLE ................................................................................................................19
8.4.1 Sentencia forever ................................................................................................................19
8.4.2 Sentencia repeat .................................................................................................................19
8.4.3 Sentencia while ...................................................................................................................19
8.4.4 Bucle for .............................................................................................................................20
9 DIRECTIVAS DE COMPILACIN..............................................................................................20
9.1 DEFINE ........................................................................................................................................20
9.2 INCLUDE ......................................................................................................................................20
9.3 IFDEF ELSE - ENDIF ...................................................................................................................20
9.4 TIMESCALE..................................................................................................................................21
10 FUNCIONES DEL SISTEMA ....................................................................................................21
11 TAREAS EN VERILOG..............................................................................................................22
Acerca del lenguaje
1 Introduccin
1.1 Acerca del lenguaje
Verilog es un lenguaje de descripcin hardware (Hardware Description Language, HDL)
utilizado para describir sistemas digitales, tales como procesadores, memorias o un simple flip-
flop. Esto significa que realmente un lenguaje de descripcin hardware puede utilizarse para
describir cualquier hardware (digital) a cualquier nivel.
La descripcin del sistema puede ser tan sencilla como la de un flip-flop, tal y como se refleja
en la Figura 1-1, o un sistema complejo de ms de un milln de transistores, tal es el caso de
un procesador. Verilog es uno de los estndares HDL disponibles hoy en da en la industria
para el diseo hardware. Este lenguaje nos permite la descripcin del diseo a diferentes
niveles, denominados niveles de abstraccin.
module ff(d,clk,q,q_bar);
input d,clk;
d q output q,q_bar;
module mux(f,a,b,sel);
a g1 input a,b,sel;
output f;
g4 g3 f
and #5 g1(f1,a,nsel),
b
g2 g2(f2,b,sel);
sel
or #5 g3(f,f1,f2);
not g4(nsel,sel);
endmodule
Nivel de transferencia de registro o nivel RTL. Los diseos descritos a nivel RTL
especifican las caractersticas de un circuito mediante operaciones y la transferencia de
Introduccin
module ff(d,clk,q,q_bar);
input d,clk;
d q output q,q_bar;
reg q,q_bar;
DFF always @(posedge clk)
begin
clk q_bar
q <= #1 d; // Retardo de 1 unidad
q_bar <= #1 !d; // Retardo de 1 unidad
end
endmodule
2 Mi primer diseo
2.1 Introduccin
La descripcin de un diseo en Verilog comienza con la sentencia:
module <nombre_mdulo> <(definicin las seales de interfaz)>;
En segundo lugar se declaran las entradas/salidas:
input/output <width> seal;
Seguidamente se describe el mdulo/diseo (tarea que veremos ms adelante) y se termina la
descripcin con:
endmodule //Notar que a diferencia de las dems sentencias, no se introduce ;
La Figura 2-1 muestra las diferentes partes en la descripcin de un diseo.
module ejemplo1(a,b,sel,clk,en,f);
a ejemplo1
//Inputs-Ouputs
input a,b,sel,clk,en;
f output f;
b
sel
//Descripcin del diseo
......
clk en
endmodule
1Si bien se define el nivel de comportamiento como un nivel diferente al nivel RTL, hay que decir que ste ltimo se
puede englobar dentro del nivel de comportamiento como una descripcin a bajo nivel.
Algunas consideraciones acerca del lenguaje
La Figura 2-2 muestra algunos ejemplos de definicin de nmeros enteros. Verilog expande el
valor hasta rellenar el tamao especificado. El nmero se expande de derecha a izquierda
siguiendo los siguientes criterios:
Cuando el tamao es menor que el
valor se truncan los bits ms Bit ms significativo Se rellena con
significativos. 0 0
Cuando el tamao es mayor que el 1 0
valor, se rellenan con el valor del
bit ms significativo del nmero, z z
siguiendo el convenio que se x x
muestra en la Figura 2-3. Figura 2-3 Bit de relleno.
Los nmeros negativos se especifican poniendo el signo - delante del tamao de la
constante, tal y como se especifica en el siguiente ejemplo:
-8d2 11111110
La representacin interna de los nmeros negativos en Verilog se realiza en complemento a 2.
De los diferentes tipos de registers slo utilizaremos el tipo reg y el tipo integer
(estos ltimos solo en la construccin de los testbenches).
La Figura 2-4 introduce la definicin de los nodos, tanto wire como reg para el ejemplo1.
module ejemplo1(a,b,sel,clk,en,f);
a ejemplo1
net2 //Inputs-Ouputs
net1 net4 input a,b,sel,clk,en;
0 & net5
dff output f;
0
0
f
b wire f;
net3
sel
//Descripcin de los nodos internos
reg net5;
wire net1,net2,net3,net4;
clk en
// Descripcin del diseo
endmodule
No piense el usuario que la declaracin de un nodo tipo reg lleva asociado la sntesis del
mismo mediante un elemento secuencial, tal y como se observa en la Figura 2-4. La Figura 2-5
muestra la descripcin del ejemplo1 declarando net4 tipo reg. Si observamos el diseo final
vemos que es idntico. La diferencia est en la forma de definir el cdigo.
module ejemplo1(a,b,sel,clk,en,f);
a ejemplo1
net2 //Inputs-Ouputs
net1 net4 input a,b,sel,clk,en;
0 & net5
dff output f;
0
0
f
b wire f;
net3
sel
//Descripcin de los nodos internos
reg net4,net5;
wire net1,net2,net3;
clk en
// Descripcin del diseo
endmodule
3 Procesos
El concepto de procesos que se ejecutan en paralelo es una de las caractersticas
fundamentales del lenguaje, siendo ese uno de los aspectos diferenciales con respecto al
lenguaje procedural como el lenguaje C.
Always. Este tipo de proceso se ejecuta continuamente a modo de bucle. Tal y como
su nombre indica, se ejecuta siempre. Este proceso es totalmente sintetizable. La
ejecucin de este proceso est controlada por una temporizacin (es decir, se ejecuta
cada determinado tiempo) o por eventos. En este ltimo caso, si el bloque se ejecuta
por ms de un evento, al conjunto de eventos se denomina lista sensible. La sintaxis de
este proceso es pues:
always <temporizacin> o <@(lista sensible)>
La Figura 3-1 muestra dos ejemplo de utilizacin de los procesos initial y always. De estos
ejemplos se pueden apuntar las siguientes anotaciones:
Todas las asignaciones que se realizan dentro de un proceso initial o always se deben de
realizar sobre variables tipo reg y NUNCA sobre nodos tipo wire. La Figura 3-2 muestra un
ejemplo de asignacin errnea sobre nodos tipo wire en un proceso initial.
Figura 3-2 a) Error de asignacin de valores a variables tipo wire. B) Cdigo corregido.
La variable puede ser tanto una variable interna como una seal del interfaz del mdulo. La
asignacin puede ser de un nodo tipo wire, de una variable tipo reg, de una constante numrica
o una funcin de todas ellas.
Asignacin continua
La variable slo puede estar declarada tipo net (en nuestro caso tipo wire). La asignacin
continua debe estar declarada fuera de cualquier proceso y nuca dentro de bloques always o
bloques initial. La Figura 3-3 muestra una serie de ejemplos de asignaciones continuas.
3.2 Temporizaciones
Las temporizaciones se consiguen mediante el uso de retardos. El retardo se especifica
mediante el smbolo # seguido de las unidades de tiempo de retardo. La Figura 3-4 muestra el
efecto del operador retardo. En ella se observa que los retardos especificados son
acumulativos.
initial reset
begin
clk = 0; clk
reset = 0;
#5 reset = 1;
#4 clk = 1; t=0 t=5 t=9
reset = 0;
end
En el ejemplo anterior, las dos primeras asignaciones se ejecutan en tiempo 0. Cinco unidades
de tiempo ms tarde se realiza la tercera asignacin y cuatro unidades ms tarde de esta
ltima se ejecutan la cuarta y quinta asignacin. La Figura 3-5 muestra un ejemplo de control
de asignacin en un proceso always.
always
#5 clk = !clk; clk
3.3 Eventos
La segunda manera de controlar el instante en que se produce una asignacin procedural o la
ejecucin de un proceso always es por el cambio de una variable, denominndose control por
eventos. Para ello se emplea el carcter @ seguido del evento.
Evento Descripcin
always @(a) Cada vez que vara a se evala la expresin
b = b+c;
always @(a or b or c) Cada vez que vara a o b o c se evala la expresin.
d = a+b; En este caso, a, b y c conforman la lista sensible.
Evento Descripcin
always @(posedge clk or posedge mr) Cada vez que se produce un flanco de subida de clk o
b <= b+c; de mr se evala la expresin
always @(posedge clk or negedge mr) Cada vez que se produce un flanco de subida de clk o
b <= b+c; de bajada de mr se evala la expresin
4 Mdulos y jerarquas
Tal y como se coment en el aparatado 2.1, el identificador module se utiliza para la definicin
de mdulos/diseos. Estos mdulos pueden utilizarse para construir diseos de mayor
complejidad, creando lo que se denomina un diseo con jerarqua. La manera de incluir un
mdulo en un diseo es:
master_name instante_name(port_list);
La Figura 4-1 muestra un ejemplo de un mdulo, denominado muxt, formado por dos mdulos,
denominados mux, y cuya declaracin de interfaz es la que a continuacin se muestra:
Module mux(a,b,sl,y); //a, b, out son seales de 8 bits
4.1 Conexionado
El conexionado de un mdulo dentro de un diseo se puede realizar de dos formas: por orden
(conexin implcita) o por nombre (conexin explcita).
Estructura de un testbench
En el conexionado por orden, utilizado en mux0 en el ejemplo anterior, las seales utilizadas en
la llamada al bloque se asignan a las seales internas por orden. En ese caso, si se tiene en
cuenta la declaracin del mdulo:
module mux(a,b,sl,y); //a, b, out son seales de 8 bits
y la llamada al mismo:
mux mux0(in0,in1,sel,y0);
5 Testbench
El propsito de un testbench no es otro que verificar el correcto funcionamiento de un
mdulo/diseo. La escritura de un testbench es casi tan compleja como la realizacin en RTL
del mdulo a verificar, a partid de ahora DUT (Desing Under Test). Una de las ventajas que
presenta la escritura de un testbench es la posibilidad de no tener que ser sintetizable y, por
tanto RTL.
Para escribir un testbench el diseador debe tener siempre presente las especificaciones
de diseo, en la que quedan reflejadas las funciones del diseo y, por tanto, las
funciones a verificar.
module tb;
//nodos internas
wire [7:0] din, count;
wire reset,clk,enable,load;
//Dut
cnt dut(.clk (clk),
.reset (reset). reset
clk
.di (din), test dut
.en (enable),
reset clk enable clk reset
.lo (load),
en en
.do (count));
load
//Test ld lo do
test test(.clk (clk),
din
.reset (reset), din di
.en (enable), 8
.din (din), cnt test cnt 8
.ld (load), count
tb
.cnt (count));
initial
begin
$shm_open(waves.shm);
$shm_probe(tb,AS);
end
endmodule
Seal de reset (asncrona). La Figura 5-3 muestra la generacin de una seal de reset
de forma asncrona. Esta seal se inicializa a 0 en tiempo 0. Despus de 35 unidades
de tiempo se activa a 1 y tras 50 unidades de tiempo, respecto al ltimo evento, se
pone de nuevo a 0.
initial
begin
reset
reset = 1b0;
#35
reset = 1b1; t=0 t=35 t=85
#50
reset = 1b0
end
initial
begin
reset = 1b0; clk
repeat(2)
@(posedge clk) #1; reset
reset = 1b1;
1 1
@(posedge clk) #1;
reset = 1b0; t=0
end
Seal de reloj. La seal de reloj, por sus caractersticas, se genera usando otro tipo de
procesos, generalmente always. La Figura 5-5 muestra la generacin de una seal de
reloj de 5 unidades de tiempo de semiperiodo. Hacer notar que para que la seal de
reloj se genere de forma correcta hay que inicializar la variable clk a cero.
`define SPER 5
...
clk
always #`SPER clk = !clk;
initial
begin
clk = 1b0 t=0 t=5 t=10 t=15 t=20 t=25
end
Seales de control/datos. Al igual que ocurra con el reset, estas seales pueden ser
asncronas o sncronas. En este ltimo caso habr que tener en cuenta la seal de reloj
para generarlas. La Figura 5-6 muestra un test para el contador que estamos
desarrollando.
Hay que destacar como en el mdulo de test presentado existen dos procesos que se ejecutan
en paralelo. El primero de ellos corresponde al always para la generacin de la seal de reloj.
El segundo corresponde al bloque initial. Debido a la existencia de un bloque always y para
poder parar la simulacin se hace necesario el uso del comando $finish que, al ejecutarse, para
la simulacin.
Mdulo test
//Seal de reloj
always #`SPER clk = !clk;
//Reset, seales de control y datos
initial
begin
reset = 1b0;
#35
reset = 1b1;
en = 1b0;
ld = 1b0;
din = 8b0;
#50
reset = 1b0
//Enable count
@(posedge) clk) #1;
en = 1b1;
//Dejar 30 ciclos contando
repeat(30)
@(posedge) clk) #1;
//Deshabilitar contaje durante 10 ciclos
en = 1b0;
repeat(10)
@(posedge) clk) #1;
//Volvemos a habilitar contaje
@(posedge) clk) #1;
en = 1b1;
//Habilitamos carga de nuevo dato
@(posedge) clk) #1;
ld = 1b1;
din = 8h4A;
@(posedge) clk) #1;
ld = 1b0;
//Esperamos 10 ciclos de reloj y repetimos la operacin
//deshabilitando el contaje
@(posedge) clk) #1;
en = 1b0;
ld = 1b1;
din = 8hF0;
@(posedge) clk) #1;
en = 1b1;
//Habilitamos 30 ciclos de reloj y finalizamos
repeat(30)
@(posedge) clk) #1;
$finish;
end
As, para el caso de querer modelar una memoria de 128 palabras de 8 bits, la declaracin
sera:
reg [7:0] core[127:0]
input clk,we;
input [addr-1:0] addr;
inpu [width-1:0] data;
output [width-1:0] q;
wire [width-1:0] q;
assign #1 q = core[addr]
endmodule
...
reg_sram ram128x8(.data(), .q(), .clk(), .we(), .addr()); //128x8 bits
reg_sram #(16,1024,10)ram1024x16(.data(), .q(), .clk(), .we(), .addr()); //1024x16 bits
7 Operadores en Verilog
Los operadores aritmticos y/o lgicos se utilizan para construir expresiones. Estas
expresiones se realizan sobre uno o ms operandos. Estos ltimos pueden ser nodos, registros
constantes, etc..
- a = b c;
* a = b * c;
/ a = b / c; Resultado: Se devuelve la parte entera de la divisin
%* a = b % c; Resultado: Se devuelve el mdulo de la divisin
El resultado del mdulo toma el signo del primer operando.
Si algn bit del operando tiene el valor x, el resultado completo es x.
Los nmeros negativos se representan en complemento a 2.
Operador Smbolo
Unary, Multiplicacin, Divisin, Mdulo +,-,*,%
Suma, Resta, Desplazamientos +,-,<<,>>
Relacin, Igualdad <,>,<=,>=,==,!=,===,!===
Reduccin &,!&,^,~^,|,~|
Lgicos &&,||
Condicional ?:
Figura 7-1 Orden de precedencia de los operadores en Verilog.
8 Estructuras ms comunes
En este apartado se presentan las estructuras ms comunes para la descripcin de
comportamiento en Verilog. A continuacin se presentan cada una de ellas por separado
indicando, adems de un ejemplo, si son sintetizables o no.
sentencias;
....
else
sentencias;
//Condicional simple
if (enable)
q<= #1 data;
//Condicional multiple
if (reset == 1b1)
count<= #1 8b0;
else if (enable == 1b1 && up_en == 1b1)
count<= #1 count + 1b1;
else if (enable == 1b1 && down_en == 1b1)
count<= #1 count 1b1;
else
count<= #1 count;
case (expresin)
<caso1>: sentencias;
<caso2>: begin
sentencias;
sentencias;
end
<caso3>: sentencias;
....
....
<default>: sentencias;
endcase
En el ejemplo de la Figura 8-2 hay que destacar que no se estn cubriendo todos los casos ya
que no se evalan los posibles valores de la variable sel en estado de alta impedancia (z) o
desconocido (x). La sentencia case reconoce tanto el valor z como x como valores lgicos.
//Ejemplo
case (sel)
2b00: y = ina;
2b01: y = inb;
2b10: y = inc;
2b11: y = ind;
default: $display(Valor de sel errneo);
endcase
casez (opcode)
4b1zzz: out = a; // Esta sentencia se ejecuta siempre que el bit ms significativo
sea 1.
4b01??: out = b; // El smbolo ? siempre se considera como indiferente, luego en
este caso es equivalente a poner 4b01zz
4b001?: out = c;
default: $display(Error en el opcode);
endcase
En caso de englobar mas de una sentencia o asignacin, stas se deben incluir entre begin
end.
initial
begin
clk = 0;
forever #5 clk = !clk;
end
En caso de englobar mas de una sentencia o asignacin, stas se deben incluir entre begin
end.
En caso de englobar mas de una sentencia o asignacin, stas se deben incluir entre begin
end.
loc = 0;
if (data = 0)) //Ejemplo de clculo del bit ms significativo
loc = 32;
else while (data[0] == 1b0) begin
loc = loc + 1;
data = data >> 1;
end
En caso de englobar mas de una sentencia o asignacin, stas se deben incluir entre begin
end.
9 Directivas de compilacin
Verilog ofrece una serie de directivas de compilacin que permiten, entre otras cosas, obtener
diferentes cdigos a partir de una nica descripcin. A continuacin se detallan las ms
comunes. La sintaxis para la definicin de una directiva es:
`directiva <nombre> <valor>
9.1 Define
La directiva define permite definir un valor. Ejemplo:
`define TD 1
....
9.2 Include
La directiva define permite incluir un fichero. En este caso, el fichero a incluir puede contener,
por ejemplo, la definicin de otros mdulos.
`include modulos.v
....
`define SUMA
...
Timescale
9.4 Timescale
La directiva timescale permite definir las unidades de tiempo con las que se va a trabajar. La
sintaxis de esta directiva es:
`timescale <unidad de tiempo> / <resolucin>
$fclose(id);
$fdisplay: Esta funcin imprime, en el momento de ejecutarse, en un fichero un
mensaje. Se puede aadir, adems, una lista de variables. El mensaje debe ser
declarado entre , seguido de la lista de variables a imprimir. Al final del mensaje se
introduce un retorno de carro y avance de lnea. Ejemplo:
$fdisplay (file_id, Tiempo: %d, Valor: %h, %o, %b, $time, data);
$write: Esta funcin es idntica al $display pero no introduce avance de lnea ni
retorno de carro. Ejemplo:
$write (Tiempo: %d, Valor: %h, %o, %b, $time, data);
$fdisplay: Esta funcin es idntica al $fdisplay pero ero no introduce avance de
lnea ni retorno de carro. Ejemplo:
$fwrite (file_id, Tiempo: %d, Valor: %h, %o, %b, $time, data);
11 Tareas en Verilog
Las tareas son usadas en la mayor parte de los lenguajes de programacin, conocidas
comnmente como procedimientos o subrutinas. Las tareas tienen la finalidad de reducir el
cdigo del diseo y sus llamadas se realizan en tiempo de compilacin. Las tareas ofrecen la
posibilidad de permitir parmetros de entrada y/o salida usando para ello nodos declarados en
el mdulo que realiza las llamadas. Las tareas:
Se definen en el mdulo en el que se utilizan, si bien pueden estar definidas en un
fichero aparte y ser incluidas mediante la directiva include de Verilog.
Pueden incluir retardos del tipo #delay, posedge o negedge.
Pueden tener cualquier nmero de entradas/salidas.
La definicin de entradas y/o salidas marcan el orden en que stas deben pasarse a la
tarea.
Las variables que se declaran dentro de una tarea son locales a dicha tarea.
Las tareas pueden usar y/o asignar valores a cualquier seal declarada como global en
el diseo.
Una tarea puede llamar a otra tarea o funcin.
Pueden utilizarse para modelar tanto lgica combinacional como secuencial.
La llamada a una tarea no se puede realizar dentro de una expresin.
La Figura 11-2 muestra una posible llamada a la funcin declarada en el ejemplo anterior.
module operador(a,b);
input [7:0] a,b;
reg [7:0] aandb;
reg [7:0] aorb;
...
always @( a or b)
logia_oper(a,b,aandb,aorb);
...
Sintaxis y llamada a una funcin
endmodule
12 Funciones en Verilog
Una funcin en Verilog se asemeja a una tarea con las siguientes salvedades:
No pueden incluir elementos de retardo.
Pueden tener cualquier nmero de entradas pero slo una salida.
Solo se pueden utilizar para modelar lgica combinacional.
Una funcin puede llamar a otra funcin pero no a una tarea.
La Figura 12-2 muestra una posible llamada a la funcin declarada en el ejemplo anterior.
module operador(a,b);
input [7:0] a,b;
wire [7:0] aandb;
...
assign aandb = logia_oper(a,b);
...
endmodule