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

Generación de números aleatorios en VHDL: De uniforme a OSVVM

VHDL incluye un generador pseudoaleatorio integrado que produce valores de punto flotante en el intervalo [0, 1]. Escalando y desplazando estos valores, puede crear datos aleatorios de cualquier tipo —real, entero, std_logic_vector o time— adecuados para testbenches. La siguiente guía muestra cómo construir estos generadores con el procedimiento uniform del paquete IEEE MATH_REAL y cómo aprovechar el paquete Random de OSVVM para mayor flexibilidad.

El procedimiento uniform, definido en el paquete IEEE MATH_REAL, es la base de los ejemplos siguientes:

procedure UNIFORM(variable SEED1, SEED2 : inout POSITIVE; variable X : out REAL); 

Requiere dos variables semilla que se actualizan en cada llamada. La salida, X, es un número real pseudoaleatorio entre 0 y 1. Como el algoritmo es determinista, el mismo par de semillas iniciales producirá exactamente la misma secuencia de números —una propiedad esencial para testbenches repetibles.

Para una comprensión más profunda del algoritmo subyacente, consulte el artículo de Pierre L'Ecuyer Efficient and Portable Combined Random Number Generators, o inspeccione la implementación incluida con el simulador GHDL.

El caso de prueba

Todos los ejemplos siguientes usan 999 como ambos valores semilla. Declare las semillas en la región declarativa del proceso e implemente las funciones de aleatorización como funciones impuras dentro del mismo proceso:

variable seed1, seed2 : integer := 999; 

Puede descargar un testbench completo que contiene todos los ejemplos de este artículo como archivo ZIP. El archivo también incluye un proyecto ModelSim con un script que compila y ejecuta la simulación.

Valor real aleatorio

El procedimiento uniform devuelve un número real en el rango [0.0, 1.0]. Para mapearlo a un intervalo arbitrario [min_val, max_val], multiplique por la anchura y añada el desplazamiento:

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; 

Valor entero aleatorio

Generar un entero aleatorio a partir de un valor real es complicado porque el redondeo simple sesga la probabilidad de los valores extremos. La siguiente función corrige este sesgo añadiendo 0.5 antes de redondear:

Generación de números aleatorios en VHDL: De uniforme a OSVVM

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; 

El ajuste asegura que cada entero en el intervalo [min_val, max_val] tenga la misma probabilidad de ser seleccionado.

std_logic_vector aleatorio

Para llenar un std_logic_vector de longitud arbitraria con bits aleatorios, itere sobre cada posición y asigne '1' cuando el real aleatorio supere 0.5, en caso contrario '0':

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

Cuando necesite una marca de tiempo aleatoria —por ejemplo, para simular tráfico de datos intermitente— puede escalar un real aleatorio al intervalo deseado y convertir de nuevo a tipo time de VHDL:

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; 

Tenga en cuenta que debe suministrar la unidad de tiempo del simulador (p.ej., ns) a la función.

El paquete Random de OSVVM

Para usuarios que prefieren una solución lista, el paquete Random de OSVVM ofrece un rico conjunto de funciones sobrecargadas que generan valores aleatorios para todos los tipos estándar de VHDL. Importe el paquete con:

library osvvm; use osvvm.RandomPkg.all; 

ModelSim incluye OSVVM preinstalado, por lo que no se requiere descarga adicional en esa plataforma. Para otros simuladores, consulte el archivo RandomPck.vhd del repositorio GitHub de OSVVM.

VHDL

  1. Creación de listas de cadenas en VHDL: Buenas prácticas y ejemplo
  2. Finalizar elegantemente una simulación de testbench VHDL
  3. Implementación de un controlador PWM en VHDL: Diseño, simulación y demo en FPGA
  4. Implementación de lista enlazada dinámica en VHDL con tipos protegidos y punteros de acceso
  5. Aprovechando procedimientos en-proceso para diseños FSM más limpios en VHDL
  6. Uso de funciones impuras en VHDL: Mejorando legibilidad y mantenibilidad de FSM
  7. Dominando funciones VHDL: Guía práctica para diseño eficiente
  8. Diseño de máquina de estados finitos en VHDL: Ejemplo práctico de semáforo
  9. Uso de procedimientos en VHDL: Simplifique su diseño con código reutilizable
  10. Construya un temporizador fiable en VHDL: Contar ciclos de reloj hasta horas
  11. Generar números aleatorios en Java: Guía práctica con Random y Math.random