Programación en Verilog/Elementos básicos del lenguaje
Antes de comenzar es preciso conocer algunos elementos básicos del lenguaje Verilog.
Comentarios
editarLos comentarios van precedidos de los caracteres //, cuya información hasta el final de la línea es ignorado. También, pueden ir entre /* y */, donde la información entre estos caracteres es ignorada, la diferencia con la anterior alternativa, es que en esta segunda puede haber más de una línea. Ejemplos:
// Esto es un comentario de una linea
/* Esto es un comentario
de varias lineas */
Identificadores
editarUn identificador esta formado por una letra o "_" seguido de letras, números y los caracteres "$" o "_". Este lenguaje si distingue entre mayúsculas y minúsculas.
reg A;
reg A0;
reg data_i;
Números
editarLos números en Verilog pueden especificarse en decimal, hexadecimal, octal o binario. Los números negativos se representan en complemento a2 y el carácter "_" puede utilizarse para una representación más clara del número. La sintaxis para la representación de un número es la siguiente.
<TAMAÑO> <BASE> <VALOR>
- Tamaño: es el número de bits expresado en decimal de la cantidad que viene a continuación. Este dato es opcional, en caso de no darse, por defecto el valor es de 32 bits.
- Base: indica la base en la que se va a expresar el valor. Es opcional, por defecto es decimal.
'b Base binaria 'd Base decimal 'h Base hexadecimal 'o Base octal
- Valor: Verilog tiene 4 valores que cualquier señal puede tomar:
Valor | Significado |
---|---|
0 | Un valor binario de cero. Corresponde a cero voltios. |
1 | Un valor binario de 1. Dependiendo de la tecnología de fabricación, puede corresponder a +5V, +3.3V, o algún otro valor positivo. |
x | Un valor cualquiera. los valores x no son ni 0 o 1, y debería ser tratado como un valor desconocido. |
z | Un valor de alta impedancia de un buffer de tres estados cuando la señal de control no está definida. Corresponde a un wire que no está conectado, o está flotando. |
A continuación, se muestra una serie de ejemplos.
187 // Numero decimal (Utilizado 32 bits)
8'h0a // Numero hexadecimal (Almacenado 00001010)
3'b1 // Numero binario 3 bits (Almacenado 001)
'o73 // Numero octal (Utilizado 32 bits)
2'b1x // Numero de 2 bits (Almacenado 1x)
4'bz // Numero de 4 bits en alta impedancia (Almacenado zzzz)
-4'b10 // Numero binario de 4 bits complemento a2 de 10 (Almacenado 1110)
'b1000_0001 // Numero binario de 8 bits (Utilizado 32 bits)
6'hCA // Numero hexadecimal de 6 bits (Almacenado 001010)
Tipos de datos
editarFundamentalmente existen dos tipos de datos: reg y wire. La sintaxis para declarar esta variables es la siguiente.
<TIPO> [<MSB> : <LSB>] <NOMBRE>;
- Tipo: existen varios tipos de variables, aunque las más destacadas son reg ywire.
reg: Representan variables con capacidad de almacenar información. wire: Representan conexiones estructurales entre componentes. No tienen capacidad de almacenamiento. integer: Registro de 32 bits. real Registro capaz de almacenar números en coma flotante time: Registro sin signo de 64 bits.
- MSB y LSB: Por defecto estas las variables son de un sólo bit, aunque es posible definir vectores de bits.
- Nombre: Indica el nombre de la variable.
A continuación, se muestran varios ejemplos de variables.
reg[5:0] data; // Registro de 6 bits, donde data[0] es el bit menos significativo
wire outA; // Net de un bit
integer numA; // Registro de 32 bits
reg[31:0] numB; // Registro de 32 bits
Operadores
editarLos operadores que proporciona el lenguaje son:
Tipos de operadores
editarBinarios aritméticos
editarEl operador aparece entre dos operandos. Si algún bit es 'X' el resultado es 'X'.
- + (suma o signo positivo): Sirve para indicar una suma entre dos números. También puede actuar como símbolo si se sitúa delante de una expresión.
// B: 4'b1000 C: 4'b10
A = B + C;
D = +8'h01;
// Resultado A: 4'b1010
// Resultado D: 8'h01
- - (resta o signo negativo): Sirve para indicar la resta entre dos números. Si va delante de una expresión modifica el signo de la expresión.
// B: 4'b1000 C: 4'b10
A = B - C;
D = -8'h01;
// Resultado A: 4'b110
// Resultado D: 8'hFF (complemento a2 de 1)
- * (multiplicación): Multiplica dos números de cualquier tipo.
// B: 4'b0100 C: 4'b10
A = B * C;
// Resultado A: 4'b1000
- / (división): Divide dos números de cualquier tipo.
// B: 4'b1000 C: 4'b10
A = B / C;
// Resultado A: 4'b100
- % (resto): Obtiene el resto de la división de dos números de cualquier tipo.
// B: 4'b1000 C: 4'b10
A = B % C;
// Resultado A: 4'b0
Igualdad
editarPermiten comparar dos operandos, retornando 1 ó 0, verdadero o falso respectivamente.
- ==, != (igualdad): El primero devuelve verdadero si los operando son iguales y falso en caso contrario. El segundo indica desigualdad, funcionando al revés que el anterior. Si algún bit es 'X' el resultado también será 'X'.
// A: 4'b1110 B: 4'b1101
if (B != A)...
// Resultado: true
- ===, !== (igualdad): Su funcionalidad es idéntica a la anterior, pero difiere en también se comparan los valores indefinidos ('X') o de alta impedancia ('Z').
// A: 4'b11X0 B: 4'b11X0
if (B === A)...
// Resultado: true
Relacionales
editarPermiten comparar dos operandos, retornando 1 ó 0, verdadero o falso respectivamente. Si algún bit es 'X' el resultado también será 'X'.
- >, >=, <, <= (menor mayor): Poseen el significado habitual (mayor que, mayor o igual que, menor que, menor o igual que, respectivamente).
// A: 4'b1110 B: 4'b1101
if (B > A)...
// Resultado: false
Lógicos
editarAparece entre dos operandos lógicos y proporciona un valor lógico (verdadero o falso).
- ! (negación): Cambia el valor lógico del operando que va justo detrás del operador.
// A: true
if (!A) ...
// Resultado: false
- && (y lógica): El resultado será la combinación de los dos operandos lógicos. Es decir, para que el valor sea verdadero, ambos operandos deben serlo, en caso contrario el resultado será falso.
// A: true B: false
if (A && B) ...
// Resultado: false
- || (o logica): El resultado será la combinación de los dos operandos lógicos. Para que el resultado sea verdadero, bastará con que uno de los operandos lo sea.
// A: true B: false
if (A || B) ...
// Resultado: true
Lógica de bit
editarPermite efectuar operaciones lógicas con los bits de los operandos.
- ~ (negación): Negación bit a bit.
// B: 4'b1110
A = ~B;
// Resultado A: 4'b1
- & (AND): AND bit a bit.
// B: 4'b1110 C: 4'b1101
A = B & C;
// Resultado A: 4'b1100
- | (OR): OR bit a bit.
// B: 4'b1110 C: 4'b1101
A = B | C;
// Resultado A: 4'b1111
- ^ (XOR): XOR bit a bit.
// B: 4'b1110 C: 4'b1101
A = B ^ C;
// Resultado A: 4'b0011
- ~& (NAND): NAND bit a bit.
// B: 4'b1110 C: 4'b1101
A = B ~& C;
// Resultado A: 4'b1100
- ~| (NOR): NOR bit a bit.
// B: 4'b1110 C: 4'b1101
A = B ~| C;
// Resultado A: 4'b0
- ~^ (NOT XOR): NOT XOR bit a bit. También puede ser ^~.
// B: 4'b1110 C: 4'b1101
A = B ~^ C;
// Resultado A: 4'b0011
Lógica de reducción
editarEl resultado de aplicar este operando al único argumento es un sólo bit.
- & (AND): Se realiza un AND de todos los bits.
// B: 4'b1110
A = &B;
// Resultado A: 0
- | (OR): Se realiza un OR de cada uno de los bits del operando.
// B: 4'b1110
A = |B;
// Resultado A: 1
- ^ (XOR): Se realiza un XOR de cada bit.
// B: 4'b1110
A = ^B;
// Resultado A: 1
- ~& (NAND): Se realiza un NAND de todos los bits.
// B: 4'b1110
A = ~&B;
// Resultado A: 1
- ~| (OR): Se realiza un NOR de cada uno de los bits del operando.
// B: 4'b1110
A = ~|B;
// Resultado A: 0
- ~^ (XOR): Se realiza un NOT XOR de cada bit. También puede ser ^~.
// B: 4'b1110
A = ~^B;
// Resultado A: 0
Otros
editar- {,} (Concatenación): Concatenación de dos operandos.
// B: 4'b110 C: 4'b10
A = {B, C};
D = {2{B}};
E = {B, c[1:0]};
// Resultado A: 8'b110_0010
// Resultado D: 8'b110_0110
// Resultado E: 6'b110_10
- << (Desplazamiento izquierda): Desplaza bits a la izquierda, añadiendo ceros.
// A: 8'b1110_1101
A << 2;
// Resultado A: 8'b1011_0100
- >> (Desplazamiento derecha): Desplaza bits a la derecha, añadiendo ceros.
// A: 8'b1110_1101
A >> 3;
// Resultado A: 8'b0001_1101
- ?: (Condicional): Dependiendo del resultado lógico (verdadero o falso) se devolverá un valor u otro.
// A: 1'b1 B: 3'b111 C: 3'b001
A == 1? B : C;
// Resultado A: 3'b111
Precedencia de operadores
editarEl orden de precedencia de los diferentes operadores es el siguiente.
1. Unarios, multiplicación, división y módulo
+, -, *, /, %
2. Suma, resta y desplazamientos
+, -, >>, <<
3. Relación e igualdad
<, >, <=, >=, ==, !=, ===, !===
4. Reducción
&, !&, ^, ~^, |, ~|
5. Lógicos
&&, ||
6. Condicional
?: