Programación en Verilog/Elementos básicos del lenguaje

← Introducción Elementos básicos del lenguaje Módulos →


Antes de comenzar es preciso conocer algunos elementos básicos del lenguaje Verilog.


Comentarios

editar

Los 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

editar

Un 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

editar

Los 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

editar

Fundamentalmente 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

editar

Los operadores que proporciona el lenguaje son:

Tipos de operadores

editar

Binarios aritméticos

editar

El 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

editar

Permiten 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

editar

Permiten 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

editar

Aparece 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

editar

Permite 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

editar

El 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


  • {,} (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

editar

El 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

  ?:
← Introducción Elementos básicos del lenguaje Módulos →