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:
1 2 3 4 5 6 7 8 9 |
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“
1 2 3 |
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
1 2 3 4 |
class inData; rand bit[2:0] b; constraint bc {b inside {0, 3, [5:7]};}; endclass |
Podría involucrar a varias variables aleatorizables
1 2 3 4 5 |
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:
1 2 3 4 5 6 |
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
1 2 3 4 |
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 puee combinar con la implicación
1 |
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:
1 2 3 4 5 6 |
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 (aletaorizará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:
1 2 3 4 5 6 7 8 |
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