Cómo generar números aleatorios en VHDL
VHDL tiene un generador pseudoaleatorio incorporado, pero solo puede generar números de coma flotante entre 0 y 1. Afortunadamente, puede derivar de esto cualquier otro tipo de formato de datos aleatorios que necesite. Continúe leyendo este artículo para descubrir cómo producir real
o integer
valores de cualquier rango, así como std_logic_vector
aleatorios secuencias y time
valores.
El uniform
El procedimiento del paquete IEEE MATH_REAL es la base de los algoritmos descritos en este artículo. Tenga en cuenta que uniform
depende del software para generar números aleatorios. Por lo tanto, ninguno de estos algoritmos es sintetizable. Solo puedes usarlos en bancos de pruebas.
procedure UNIFORM(variable SEED1, SEED2 : inout POSITIVE; variable X : out REAL);
La lista anterior muestra el prototipo del uniform
procedimiento. Necesita dos variables iniciales para funcionar y las modificará cada vez que llame al procedimiento. La salida, X, es el número aleatorio, que siempre tiene un valor entre 0 y 1.
Al igual que otros generadores de números pseudoaleatorios, uniform
generará la misma secuencia de números cuando se llame con los mismos valores iniciales. Debido a este comportamiento, puede volver a ejecutar el banco de pruebas y obtener el mismo resultado al usar los mismos valores iniciales.
Consulte el documento Generadores de números aleatorios combinados eficientes y portátiles de Pierre L'Ecuyer para obtener una descripción detallada de cómo funciona este algoritmo. También puede ver una implementación real del algoritmo en el simulador VHDL de código abierto de GHDL.
El caso de prueba
Todos los ejemplos de este artículo utilizan el valor 999 para ambas semillas. Declaramos las variables semilla como se enumeran a continuación en la región declarativa de un proceso. Luego, implementamos nuestros algoritmos de aleatorización personalizados como funciones impuras dentro del mismo proceso.
variable seed1, seed2 : integer := 999;
Puede descargar un banco de pruebas completo que contiene todos los ejemplos de este artículo utilizando el formulario a continuación. El archivo Zip también contiene un proyecto ModelSim con un script que compila y ejecuta la simulación por usted.
Valor real aleatorio
El uniform
procedimiento genera un real
aleatorio valor entre 0,0 y 1,0. El real
type es el formato de coma flotante de VHDL. Sin embargo, lo más probable es que desee que el número aleatorio esté en un rango diferente.
impure function rand_real(min_val, max_val : real) return real is variable r : real; begin uniform(seed1, seed2, r); return r * (max_val - min_val) + min_val; end function;
Afortunadamente, podemos traducir fácilmente la salida de uniform
multiplicando con una escala y agregándole una compensación. El código anterior muestra una función que devuelve un real
aleatorio valor dentro de un rango mínimo/máximo.
Valor entero aleatorio
Para generar un integer
aleatorio valor dentro de un rango específico, debe multiplicar por una escala y agregarle una compensación. Pero hay una trampa que tienes que evitar. No puede simplemente generar un real
aleatorio valor dentro del rango y redondearlo a un integer
.
La ilustración anterior muestra el problema. En el ejemplo, pretendemos generar un integer
aleatorio valor en el rango -1 a 1. Si basamos nuestro integer
en un real
aleatorio eso va precisamente a los puntos finales, los enteros mínimo y máximo solo obtienen la mitad de la probabilidad de ser elegidos. Redondeando a 0 integer
el valor ocurre la mitad de las veces, aunque hay tres opciones de números.
impure function rand_int(min_val, max_val : integer) return integer is variable r : real; begin uniform(seed1, seed2, r); return integer( round(r * real(max_val - min_val + 1) + real(min_val) - 0.5)); end function;
En el código anterior, corregimos el problema de redondeo del punto final ajustando el real
aleatorio valor para incluir un 0,5 adicional por encima y por debajo de los puntos finales.
Vector estándar_lógico aleatorio
Hay muchas formas de llenar un vector con valores aleatorios, pero este método funciona con vectores de cualquier longitud. Estoy usando un ciclo for para atravesar el vector y seleccionar un valor aleatorio para cada bit. En el siguiente código, el len
El parámetro determina la longitud del std_logic_vector
aleatorio para volver.
impure function rand_slv(len : integer) return std_logic_vector is variable r : real; variable slv : std_logic_vector(len - 1 downto 0); begin for i in slv'range loop uniform(seed1, seed2, r); slv(i) := '1' when r > 0.5 else '0'; end loop; return slv; end function;
Valor de tiempo aleatorio
A veces necesitas generar un time
aleatorio valor en su banco de pruebas. Tal vez desee simular una interfaz externa que escribe ráfagas de datos en momentos aleatorios. Sea cual sea el motivo, time
aleatorios los valores son fáciles de producir.
impure function rand_time(min_val, max_val : time; unit : time := ns) return time is variable r, r_scaled, min_real, max_real : real; begin uniform(seed1, seed2, r); min_real := real(min_val / unit); max_real := real(max_val / unit); r_scaled := r * (max_real - min_real) + min_real; return real(r_scaled) * unit; end function;
Para generar un time
aleatorio valor en VHDL, primero debe convertir los valores mínimo y máximo deseados a real
tipos Luego, después de que la fórmula de aleatorización haya hecho su magia, vuelve a convertir el resultado a un VHDL time
escribe. Tenga en cuenta que debe proporcionar la unidad de tiempo de simulación que está utilizando en el simulador como argumento para esta función, como se muestra en el código anterior.
El paquete aleatorio OSVVM
Finalmente, como alternativa a la elaboración manual del algoritmo de aleatorización, puede usar el paquete Random de la biblioteca OSVVM. Tiene múltiples funciones sobrecargadas para generar valores aleatorios para todo tipo de tipos de VHDL.
La Metodología de verificación VHDL de código abierto (OSVVM) es una biblioteca VHDL para crear bancos de pruebas estructurados. El paquete Random es solo uno de los muchos paquetes útiles de esta biblioteca.
library osvvm; use osvvm.RandomPkg.all;
El código anterior muestra cómo importar el paquete OSVVM. ModelSim incluye la biblioteca lista para usar, por lo que no tiene que descargarla para este simulador. Consulte el archivo RandomPck.vhd del repositorio OSVVM GitHub para encontrar una función de aleatorización adecuada para sus necesidades.
VHDL
- Cómo crear una lista de cadenas en VHDL
- Cómo detener la simulación en un banco de pruebas VHDL
- Cómo crear un controlador PWM en VHDL
- Cómo crear una lista enlazada en VHDL
- Cómo usar un procedimiento en un proceso en VHDL
- Cómo usar una función impura en VHDL
- Cómo usar una función en VHDL
- Cómo crear una máquina de estados finitos en VHDL
- Cómo usar un procedimiento en VHDL
- Cómo crear un temporizador en VHDL
- Cómo generar números aleatorios en Java