Verilog Práctico
Capítulo 2.1. Puertas Lógicas.
Uno de los dispositivos básicos cuando hablamos de circuitos digitales son las puertas lógicas. En este capítulo veremos cómo programar puertas lógicas en la Alhambra.
1. Puerta AND
Tabla de la verdad.
Código.
La forma de implementar un dispositivo en Verilog empieza con module nombre (E/S); y entre paréntesis definimos las entradas y salidas del dispositivo separadas por comas.
module AND (input in1, in2, output out);
Con assign indicamos que el valor de la salida out es la operación & (AND) de las entradas in1, in2.
assign out = in1 & in2;
Lo ponemos todo junto y este es el código de una puerta AND en Verilog:
// AND gate
module AND (input in1, in2, output out);
// asignar la salida a las entradas 1 y 2
// mediante el operador &
assign out = in1 & in2;
endmodule
El archivo pcf es el siguiente, donde 10 y 11 son los switches SW1 y SW2 y la salida 95 corresponde con el LED0. El archivo pcf es el mismo para todas las puertas lógicas explicadas en este capítulo, ya que todas tienen dos entradas y una salida.
set_io in1 10
set_io in2 11
set_io out 95
Lo verificamos, construimos y lo subimos a la Alhambra. Con los switches SW1 y SW2 simulamos las entradas, en el LED0 vemos la salida.
2. Puerta NAND
Tabla de la verdad.
Código
Para construir una puerta NAND solo hay que negar el resultado de (in1 & in2) colocando el operador ~ delante del paréntesis.
// NAND gate
module NAND (input in1, in2, output out);
// asignar la salida a las entradas 1 y 2
// mediante el operador &
assign out = ~(in1 & in2);
endmodule
3. Puerta OR
Tabla de la verdad
Código
// OR gate
module OR (input in1, in2, output out);
// asignar la salida a las entradas 1 y 2
// mediante el operador |
assign out = in1 | in2;
endmodule
4. Puerta NOR
Tabla de la verdad
Código
// NOR gate
module NOR (input in1, in2, output out);
// asignar la salida a las entradas 1 y 2
// mediante el operador |
assign out = ~(in1 | in2);
endmodule
5. Puerta XOR
Tabla de la verdad
Código
// XOR gate
module XOR (input in1, in2, output out);
// asignar la salida a las entradas 1 y 2
// mediante el operador ^
assign out = in1 ^ in2;
endmodule
6. Puerta XNOR
Tabla de la verdad
Código
// XNOR gate
module XNOR (input in1, in2, output out);
// asignar la salida a las entradas 1 y 2
// mediante el operador ^
assign out = ~(in1 ^ in2);
endmodule
Como véis es muy fácil hacer una puerta lógica en Verilog y sintetizarla en la Alhambra.
A partir de aquí se pueden diseñar puertas lógicas de N entradas simplemente declarando más inputs dentro de module (input in1, in2, in3, output out) y asignando la salida a dichas entradas mediante el operador que corresponda, por ejemplo: assign out = ~(in1 & in2 & in3) para una puerta NAND de tres entradas.
Actualización
10 de enero de 2021
Primitivas
Una forma de optimizar circuitos es mediante el uso de primitivas; están incorporadas en Verilog y se utilizan para describir circuitos a nivel de puerta.
Todas las primitivas tienen al menos dos parámetros, el primero es la salida, los siguientes son entradas.
La primitiva and (o, in1, in2); crea una puerta AND de salida o y entradas in1 e in2.
A continuación ejemplos de cómo declarar puertas lógicas mediante primitivas.
module gate (input in1, in2, output o);
// puertas lógicas básicas
and (o, in1, in2);
nand (o, in1, in2);
or (o, in1, in2);
nor (o, in1, in2);
xor (o, in1, in2);
xnor (o, in1, in2);
not (o, in1);
// si lo deseamos, se puede poner nombre
nor N1 (o, in1, in2);
xor XO5 (o, in1, in2);
// puertas lógicas de más de dos entradas
or (o, in1, in2, in3);
nand (o, A, B, C, D);
endmodule
Operaciones con buses
Cómo declarar un bus de datos.
Los buses de datos se declaran entre corchetes, por ejemplo:
[3:0] BUS1 // bus de 4 bits, formato little-endian, bit más significativo a la izquierda
[0:23] BUS2 // bus de 24 bits, formato big-endian, bit más significativo a la derecha
Se pueden hacer operaciones lógicas con buses. La forma de describir el circuito es la siguiente.
module and_bus ( input [3:0] BUS1, BUS2, output [3:0] OUT);
assign OUT = BUS1 & BUS2;
endmodule
Este circuito es equivalente a hacer la operación AND entre cada uno de los bits de mismo peso de cada bus.
Operación de Reducción
Equivale a hacer una operación lógica a todos los bits de un bus.
module or (input [3:0] BUS, output O);
assign O = &BUS;
endmodule
El circuito equivalente es:
Descargas
Descarga el código Verilog de las puertas lógicas aquí abajo: