Operadores

Operadores

Aritméticos

Realizan operaciones aritméticas:

+ (suma)

- (resta)

* (multiplicación)

/ (división)

% (resto/módulo)

donde + y - pueden ser operadores unarios (-z) o binarios (x - y)

Ejemplo

parameter n = 4; 
reg [3:0] a, c, f, g, count; 
f = a + c; 
g = c - n; 
count = (count + 1) % 16;   // puede contar de 0 a 15

Relacionales

Comparan dos operandos y devuelven un único bit 1 o 0.

Se sintetizan como comparadores.

Los valores de wire y reg se consideran positivos, p.ej. (-3'b001)==3'b111 y (-3d001)>3d110 mientras que los enteros se consideran números con signo, p.ej. -1<6.

< (menor que)

> (mayor que)

<= (menor o igual que)

>= (mayor o igual que)

== (igual a)

!= (no igual a)

Ejemplo

if (x == y) e = 1; /* equivalente: e = (x == y); */
else        e = 0;    

// Comparar en complemento a 2 a>b
reg [3:0] a, b; 
if (a[3] == b[3]) a[2:0] > b[2:0]; 
else              b[3];

Bit-wise (a nivel de bit)

Comparan bit a bit dos operandos.

Notación idéntica a operadores reductores (unarios).

~ (NOT bitwise)

& (AND bitwise)

| (OR bitwise)

^ (XOR bitwise)

^~, ~^ (XNOR bitwise)

Ejemplo

module and2 (
 input [1:0] a, b,
 output [1:0] c
);

  assign c = a & b;

endmodule //and2

and2

Lógicos

Operan de forma similar a los bitwise sólo para operandos de un solo bit, y devuelven un solo bit 1 ó 0.

Pueden trabajar con expresiones, números enteros o grupos de bits y tratan todos los valores distintos de cero como 1.

Normalmente se utilizan en sentencias condicionales (if ... else) ya que funcionan con expresiones.

! (NOT lógico)

&& (AND lógico)

|| (OR lógico)

== (igualdad lógica)

!= (desigualdad lógica)

=== (igualdad case)

!== (desigualdad case)

En === y !== se tienen en cuenta bits con valores x o z para la comparación bitwise, en cambio cuando aparecen == y != el resultado de la comparación es siempre x y estos últimos son sintetizables por contra de los primeros.

Ejemplo

wire [7:0] x,y,z;     // variables multibit
reg a;
...
if ((x==y)&&(z)) a=1; // a = 1 si x igual que y, y z no es cero
else a = !x;          // a = 0 si x es algo distinto a cero

Reductores

Operan sobre todos los bits de un vector y devuelven un valor de un solo bit.

Son la versión unaria (un solo argumento) de los operadores bitwise anteriores.

& (AND reductor)

| (OR reductor)

^ (XOR reductor)

~& (NAND reductor)

~| (NOR reductor)

~^, ^~ (XNOR reductor)

Ejemplo

module chk_zero (
 input [2:0] a,
 output z
);
  assign z = ~|a; // NOR reductor

endmodule //chk_zero

chk_zero

Desplazamiento

Desplazan el primer operando el número de bits especificado por el segundo operando.

Las posiciones sobrantes se rellenan con ceros, tanto en desplazamentos a derecha como a izquierda (no hay extensión de signo).

<< (desplazamiento a izquierda)

>> (desplazamiento a derecha)

Ejemplo

assign c = a << 2; /* c = a deplazado a la izquierda 2 bits;
                      las posiciones vacantes se rellenan con 0’s */

Condicional

Similar al utilizado en C/C++. Se evalúa una de la las dos expresiones basadas en una condición (operador ternario).

Se sintetiza a base de multiplexores.

Sintaxis

conditional_expression ? true_expression : false_expression

Ejemplo

assign a = (inc == 2) ? a+1 : a-1; */ se incrementa o decrementa a si el valor de inc coincide */
assign a = (g) ? x : y;

cond

Concatenación

Combina dos o más operandos para formar un vector mayor.

{ } (concatenación)

Ejemplos

wire [1:0] a, b;   wire [2:0] x;   wire [3:0] y;
assign x = {1’b0, a};                          // x[2]=0,  x[1]=a[1],  x[0]=a[0]
assign y = {a, b};                             /* y[3]=a[1],  y[2]=a[0], y[1]=b[1], y[0]=b[0] */
assign foo = { a[4:3], 1’b0, c[1:0] };
assign foo = { a[4], a[3], 1’b0, c[1], c[0] }; // equivalente a la anterior
assign {cout, sum} = a + b + cin;              // concatenación de un resultado

Repetición

Hace múltiples copias de un item.

{n{item}} (n réplicas de item)

Ejemplos

wire [1:0] a, b;   wire [4:0] x, y;
assign x = {2{1’b0}, a};  // equivalente a x = {0,0,a}
assign y = {2{a}, 3{b}};  // equivalente a y = {a,a,b,b,b}
wire [3:0] z = {4{1’b1}}; // equivalente a z = 4’b1111

Se debe evitar realizar repeticiones nulas ya que ocasionan errores en algunos sintetizadores, p.ej.

parameter n=5, m=5; 
assign x = {(n-m){a}}

Precedencia

La siguiente tabla muestra la precedencia de los operadores de mayor a menor.

Los operadores del mismo nivel evalúan de izquierda a derecha.

Se recomienda utilizar paréntesis para definir el orden de precedencia y mejorar la legibilidad del código.

Operador Descripción
[ ] selección de bits ó parte
( ) paréntesis
!,~ NOT lógico y bit-wise
&,|,~&,~|,^,~^,^~ reducción AND, OR, NAND, NOR, XOR, XNOR
+,- (unario) signo positivo o negativo
{ } concatenación
{{ }} repetición
*,/,% (binario) multiplicación, división y resto (no siempre sintetizable)
+,- (binario) suma y resta
<<,>> desplazamientos a izquierda y derecha
<,>,<=,>= comparaciones
==,!= igualdad y desigualdad
& AND bit-wise
^,^~,~^ XOR bit-wise, XNOR bit-wise
| OR bit-wise
&& AND lógico
|| OR lógico
? : (ternario) condicional

Otras consideraciones importantes:

  • Un registro se considera como número no negativo en las operaciones aritméticas.
  • Si cualquier bit de un operando en una operación aritmética es X o Z, el resultado es X.

Ejemplos

4'hc > 10        (TRUE)
8'd12 && 9'h1    (TRUE)
8'h0 || 0        (FALSE)
!8'h6            (FALSE)
~4'b0111         (4'b1000)
2'b01 & 2'b11    (2'b01)
4'h8 | 4'h1      (4'h9)
&16'h324d        (1'b0)
|16'h1           (1'b1)
8'hfe << 3       (8'hf0)

Introducción Sintaxis