Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Industrial programming >> VHDL

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

  1. Cómo crear una lista de cadenas en VHDL
  2. Cómo detener la simulación en un banco de pruebas VHDL
  3. Cómo crear un controlador PWM en VHDL
  4. Cómo crear una lista enlazada en VHDL
  5. Cómo usar un procedimiento en un proceso en VHDL
  6. Cómo usar una función impura en VHDL
  7. Cómo usar una función en VHDL
  8. Cómo crear una máquina de estados finitos en VHDL
  9. Cómo usar un procedimiento en VHDL
  10. Cómo crear un temporizador en VHDL
  11. Cómo generar números aleatorios en Java