Aleatorización

La aletaorización corre a cargo de la llamada al método predefinido “randomize” a cualquier objeto del tipo definido por la clase.

Definir un objeto, requiere el uso de la declaración del objeto y de la instanciación.

  • Evidentemente para poder hacer esto la clase que se referencia debe de ser visible
  • Evidentemente ambas acciones (declarar e instanciar) se pueden hacer en una única línea: Bus P =new;
  • La función new() es el contructor – sin valor de retorno. El constructor se puede omitir en la clase: en este caso, se asigna el espacio para el nuevo objeto y se conservan los valores iniciales de las propiedades.
  • new() puede tomar argumentos:

Llegado a este punto supongamos que quiero aleatorizar . Bastaría, si ya tenemos el objeto construido , en llamar el método “randomize” . En el siguiente ejemplo mostramos la construcción y la realización de dos randomizaciones:

Cada vez que aleatorizamos una clase, se selecciona aleatoriamente una entre todas las combinaciones posibles de todas las variables aleatorias que satisfacen todas las restricciones que hemos colocado. En el caso de que no haya ninguna combinación posible, la función randomize dará un “0”

Acciones adicionales en el método randomize

Añadir más restricciones

Se realiza con la palabra reservada “with”

Se puede observar que al randomizar indicamos una restricción adicional expresada entre las llaves. Además de todas las restricciones dadas en la clase, para sólo esta aleatorización agregamos la restricción que addr[0] o addr[1] debe ser 1.

Cambiar el carácter de las variables

  • Las clases pueden tener miembros rand y no-rand
  • al aleatorizar una clase, aleatorizamos solo las variables aleatorias, los no aleatorios mantienen sus valores
  • Las restricciones pueden mezclar en sus expresiones variables rand y no rand

Veamos un ejemplo

Cuando llamámos al método randomize podemos cambiar el caracter de dichas variables

  • inst.randomize(a) : poniendo como argumento la variable a indicamos que solo esta variable va a ser considerada como randomizable. La variable b será considerada como variable estática.
  • inst.randomize(a,c): El efecto sobre a y b es el mismo del ejemplo anterior; sin embargo la variable c que era estática, pasa a ser ahora en esta randomización como variable.

Métodos adicionales

constraint_mode

Veamos el siguiente ejemplo. Como puede observarse podemos inhabilitar antes de cada llamada a randomize las restricciones que deseemos con tan solo llamar el método constraint_mode asociadas a dicha restricción y poniendo como argumento un cero.

Cuando deseemos podremos volver a habilitar la restricción con el mismo método asociada a la misma y con un argumento uno.

rand_mode

Tomando como ejemplo el código anterior en el que tenemos dos variables aleatorizables : addr y data Después de esta declaración: bus.addr.rand_mode(0);

“addr” dentro del objeto “bus” se considera como una variable no-rand(no aleatorizado cuando realizamos el randomize())

Para volver a su situación rand, usamos: bus.addr.rand_mode(1);

pre_randomize y post_randomize

En nuestra clase podemos definir unas funciones pre_randomize y post_randomize. Veamos el siguiente ejemplo:

Dichos métodos serán ejecutados automáticamente (sin necesidad de llamarlos explícitamente) justo antes y después de que tenga lugar la aleatorización al llamar randomize()

el flujo de ejecución será el siguiente:

  • frame.pre_randomize();
  • frame is randomized
  • frame.post_randomize();

Veamos el funcionamiento en el siguiente laboratorio virtual

randcase

A veces lo que deseamos aleatorizar mediante el “solver” es la ejecución de un determinada rutina u otra en función de unos pesos que indiquen la probabilidad de las mismas. Eso lo realizaremos mediante “randcase“. Veamos el siguiente ejemplo

Podemos observar en el “fork join_any” central que realizamos dos operaciones concurrentes representadas cada una de ellas con un randcase. Estas operaciones concurrentes tienen una mayor probabilidad de ser operaciones de lectura (en este caso de una FIFO) que de escritura. Si ambos procesos concurrentes coinciden con la misma rutina, ésta se realiza una única vez. Si la rutina es diferente se realizarán ambas (lo cual permitiría lectura y escritura simultánea de la FIFO).

Con esta estructura podemos lograr un vaciado progresivo random de la FIFO, sin impedir que puedan haber escrituras o escrituras y lecturas simultáneas.