El lugar natural de definición de qué variables queremos aleatorizar y cómo es dentro de una clase de systemVerilog.
Veamos un primer ejemplo:
class Bus;
rand bit [4:0] addr1;
rand bit [4:0] addr2;
rand bit [7:0] data;
rand bit enable;
constraint word_align1 {addr1[1:0] == 2'b0;}
constraint word_align2 {addr2[1:0] == 2'b0;}
constraint addr_data_dep {addr1==0 -> data==0;}
endclass
En este ejemplo sencillo indicamos :
- En las líneas 2 , 3, 4 y 5 que las variables aleatorizables son addr y data.
- En las líneas 6, 7 y 8 indicamos unas restricciones (expresiones) que debe de cumplir la aleatorización (digamos que estas expresiones tienen que ser ciertas. Fijémonos que estas restricciones pueden afectar únicamente a una variable o a varias de ellas de manera conjunta.
Veamos otro ejemplo en el cual en lugar de utilizar la palabra reservada «rand» utilizamos «randc«
class inData;
randc bit[2:0] b;
endclass

El “ramdom solver” iterará a través de todos los valores en un orden aleatorio, a continuación, reiniciará un nuevo ciclo con un orden diferente.
Podemos observar en el siguiente Laboratorio virtual el diferente comportamiento de usar rand y randc.

Tipos de restricción
Inside keyword
Puede tener una forma bastante simple, como la del siguiente ejemplo
class inData;
rand bit[2:0] b;
constraint bc {b inside {0, 3, [5:7]};};
endclass
Podría involucrar a varias variables aleatorizables
class inData;
rand bit[7:0] b;
rand bit[7:0] c;
constraint bc {b inside {0, 3, [c+1:255]};};
endclass
Implication keyword
Implication constraints:
class inData
rand int len;
rand enum {little,big} mode;
constraint c1 {mode == little ->len <10 ;};
constraint c2 {mode == big -> len >100;};
endclass
- Si modo es “little”, entonces “len” debe de ser <10
- Si modo es “big”, entonces “len” debe de ser >100
Dist keyword
class id;
rand int x;
constraint{x dist {100 := 1, 200 := 2, 300 := 5};}
endclass;
- x puede tomar los valores 100, 200, 300 con probabilidad 1/8, 2/8, 5/8 (Pesos 1,2,5).
- x no puede tomar ningún otro valor (Como 97, 262, etc.)
Por supuesto, este tipo de restricción se puede combinar con la implicación
constraint c {a -> b dist {0 := 1, 1 := 4;};}
- si “a” es verdadera entonces “b” se distribuye de acuerdo con la distribución indicada por dist
Solving order
Veamos el siguiente ejemplo:
class B;
rand bit s;
rand bit [31:0] d;
constraint c { s -> d == 0; }
constraint order { solve s before d; }
endclass
- primero los elementos en s se resolverán (aleatorizarán) desactivando todas las restricciones que incluyen un elemento que es diferente de s; luego s se toma como un valor fijo y d se resuelve después de activar de nuevo todas las restricciones
Veamos otro ejemplo:
class B;
rand bit a, b;
rand bit [7:0] c;
constraint c1 { a ->b;};
constraint c2 { a &b -> c inside {[0:4]};};
constraint c3 {c inside {[0:3]} ->a==0;}
constraint order { solve a,b before c; }
endclass
- primero c2 y c3 se desactivan (puesto que afectan a algunas variables diferentes a y b) , a y b se aleatorizan con sólo c1 activo. A continuación, c2 y c3 se reactivan; y se realiza la aleatorización de c calculando todas las combinaciones legales en función de los valores de a y b que se habían aleatorizado con anterioridad.
Veamos el funcionamiento en el siguiente laboratorio virtual
