Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Industrial programming >> VHDL

Gerando Números Aleatórios em VHDL: De Uniforme a OSVVM

VHDL inclui um gerador pseudo-aleatório embutido que produz valores de ponto flutuante no intervalo [0, 1]. Escalando e deslocando esses valores, você pode criar dados aleatórios de qualquer tipo — real, integer, std_logic_vector ou time — adequados para testbenches. O guia a seguir mostra como construir esses geradores com o procedimento uniform do pacote IEEE MATH_REAL e como aproveitar o pacote Random do OSVVM para ainda mais flexibilidade.

O procedimento uniform, definido no pacote IEEE MATH_REAL, é a base dos exemplos abaixo:

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

Ele requer duas variáveis de seed que são atualizadas a cada chamada. A saída, X, é um número real pseudo-aleatório entre 0 e 1. Como o algoritmo é determinístico, o mesmo par de seeds inicial produzirá exatamente a mesma sequência de números — uma propriedade essencial para testbenches repetíveis.

Para um entendimento mais profundo do algoritmo subjacente, consulte o artigo Efficient and Portable Combined Random Number Generators de Pierre L'Ecuyer, ou inspecione a implementação incluída no simulador GHDL.

O caso de teste

Todos os exemplos abaixo usam 999 como ambos os valores de seed. Declare as seeds na região declarativa do processo e implemente as funções de randomização como funções impuras dentro do mesmo processo:

variable seed1, seed2 : integer := 999; 

Você pode baixar um testbench completo contendo todos os exemplos deste artigo como arquivo ZIP. O arquivo também inclui um projeto ModelSim com script que compila e roda a simulação.

Valor real aleatório

O procedimento uniform retorna um número real no intervalo [0.0, 1.0]. Para mapear isso para um intervalo arbitrário [min_val, max_val], multiplique pela largura e adicione o offset:

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 inteiro aleatório

Gerar um inteiro aleatório a partir de um valor real é complicado porque arredondamento simples enviesa a probabilidade dos valores extremos. A função a seguir corrige esse viés adicionando 0.5 antes de arredondar:

Gerando Números Aleatórios em 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; 

O ajuste garante que todo inteiro no intervalo [min_val, max_val] tenha chance igual de ser selecionado.

std_logic_vector aleatório

Para preencher um std_logic_vector de comprimento arbitrário com bits aleatórios, itere sobre cada posição e atribua '1' quando o real aleatório exceder 0.5, caso contrário '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 tempo aleatório

Quando você precisa de um timestamp aleatório — por exemplo, para simular tráfego de dados em rajadas — pode escalar um real aleatório para o intervalo desejado e converter de volta para o tipo time do 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; 

Note que você deve fornecer a unidade de tempo do simulador (ex: ns) para a função.

O pacote Random do OSVVM

Para usuários que preferem uma solução pronta, o pacote Random do OSVVM oferece um rico conjunto de funções sobrecarregadas que geram valores aleatórios para todos os tipos VHDL padrão. Importe o pacote com:

library osvvm; use osvvm.RandomPkg.all; 

O ModelSim vem com OSVVM pré-instalado, então nenhum download adicional é necessário nessa plataforma. Para outros simuladores, consulte o arquivo RandomPck.vhd do repositório GitHub do OSVVM.

VHDL

  1. Criando Listas de Strings em VHDL: Boas Práticas e Exemplo
  2. Finalizando Graciosamente uma Simulação de Testbench VHDL
  3. Implementando um Controlador PWM em VHDL: Projeto, Simulação e Demo em FPGA
  4. Implementando Lista Encadeada Dinâmica em VHDL com Tipos Protegidos e Ponteiros de Acesso
  5. Aproveitando Procedimentos In-Process para Design de FSM em VHDL Mais Limpo
  6. Usando Funções Impuras em VHDL: Melhorando Legibilidade e Manutenibilidade de FSM
  7. Dominando Funções VHDL: Guia Prático para Design Eficiente
  8. Projetando uma Máquina de Estados Finitos em VHDL: Exemplo Prático de Semáforo
  9. Usando Procedimentos em VHDL: Simplifique seu Design com Código Reutilizável
  10. Gerar Números Aleatórios em Java: Guia Prático com Random e Math.random