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

Como gerar números aleatórios em VHDL


O VHDL tem um gerador pseudo-aleatório embutido, mas ele só pode gerar números de ponto flutuante entre 0 e 1. Felizmente, você pode derivar disso qualquer outro tipo de formato de dados aleatório que precise. Continue lendo este artigo para descobrir como produzir real ou integer valores de qualquer intervalo, bem como aleatório std_logic_vector sequências e time valores.



O uniform procedimento do pacote IEEE MATH_REAL é a base para os algoritmos descritos neste artigo. Observe que uniform depende de software para gerar números aleatórios. Portanto, nenhum desses algoritmos é sintetizável. Você só pode usá-los em testbenches.
procedure UNIFORM(variable SEED1, SEED2 : inout POSITIVE;
                  variable X : out REAL);

A listagem acima mostra o protótipo do uniform procedimento. Ele precisa de duas variáveis ​​de semente para funcionar e as modificará toda vez que você chamar o procedimento. A saída, X, é o número aleatório, que sempre tem um valor entre 0 e 1.

Assim como outros geradores de números pseudo-aleatórios, uniform irá gerar a mesma sequência de números quando chamado com os mesmos valores iniciais. Devido a esse comportamento, você pode executar novamente o testbench e obter o mesmo resultado ao usar os mesmos valores de semente.

Consulte o documento Efficient and Portable Combined Random Number Generators de Pierre L'Ecuyer para obter uma descrição detalhada de como esse algoritmo funciona. Você também pode visualizar uma implementação real do algoritmo no simulador VHDL de código aberto GHDL.

O caso de teste


Todos os exemplos neste artigo usam o valor 999 para ambas as sementes. Declaramos as variáveis ​​de semente conforme listado abaixo na região declarativa de um processo. Em seguida, implementamos nossos algoritmos de randomização personalizados 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 usando o formulário abaixo. O arquivo Zip também contém um projeto ModelSim com um script que compila e executa a simulação para você.




Valor real aleatório


O uniform procedimento gera um real aleatório valor entre 0,0 e 1,0. Os real type é o formato de ponto flutuante do VHDL. No entanto, é provável que você queira que o número aleatório esteja em um intervalo 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;

Felizmente, podemos traduzir facilmente a saída de uniform multiplicando com uma escala e adicionando um deslocamento a ela. O código acima mostra uma função que retorna um real aleatório valor dentro de um intervalo mínimo/máximo.

Valor inteiro aleatório


Para gerar um integer aleatório valor dentro de um intervalo especificado, você deve multiplicar por uma escala e adicionar um deslocamento a ela. Mas há uma armadilha que você deve evitar. Você não pode simplesmente gerar um real aleatório valor dentro do intervalo e arredonde-o para um integer .



A ilustração acima mostra o problema. No exemplo, pretendemos gerar um integer aleatório valor no intervalo -1 a 1. Se basearmos nosso integer em um real aleatório que vai precisamente para os pontos finais, os inteiros min e max recebem apenas metade da probabilidade de serem escolhidos. Arredondando para 0 integer value acontece na metade das vezes, mesmo que haja três opções 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;

No código acima, corrigimos o problema de arredondamento do endpoint ajustando o real aleatório valor para incluir um adicional de 0,5 acima e abaixo dos pontos de extremidade.

Std_logic_vector aleatório


Existem muitas maneiras de preencher um vetor com valores aleatórios, mas esse método funciona com vetores de qualquer comprimento. Estou usando um loop for para percorrer o vetor e selecionar um valor aleatório para cada bit. No código abaixo, o len parâmetro determina o comprimento do std_logic_vector aleatório para retornar.
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


Às vezes você precisa gerar um time aleatório valor em seu testbench. Talvez você queira simular uma interface externa que grava rajadas de dados em momentos aleatórios. Seja qual for o motivo, aleatório time os valores são fáceis de produzir.
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 gerar um time aleatório valor em VHDL, você deve primeiro converter os valores mínimo e máximo desejados para real tipos. Então, depois que a fórmula de randomização fizer sua mágica, você converte o resultado de volta para um VHDL time modelo. Observe que você deve fornecer a unidade de tempo de simulação que está usando no simulador como argumento para esta função, conforme mostrado no código acima.

O pacote aleatório OSVVM


Por fim, como alternativa à criação manual do algoritmo de randomização, você pode usar o pacote Random da biblioteca OSVVM. Possui múltiplas funções sobrecarregadas para gerar valores aleatórios para todos os tipos de VHDL.

Open Source VHDL Verification Methodology (OSVVM) é uma biblioteca VHDL para criar testbenches estruturados. O pacote Random é apenas um dos muitos pacotes úteis nesta biblioteca.
library osvvm;
use osvvm.RandomPkg.all;

O código acima mostra como importar o pacote OSVVM. ModelSim inclui a biblioteca pronta para uso, então você não precisa baixá-la para este simulador. Consulte o arquivo RandomPck.vhd do repositório OSVVM GitHub para encontrar uma função de randomização adequada para suas necessidades.





VHDL

  1. Como criar uma lista de strings em VHDL
  2. Como parar a simulação em um testbench VHDL
  3. Como criar um controlador PWM em VHDL
  4. Como criar uma lista vinculada em VHDL
  5. Como usar um procedimento em um processo em VHDL
  6. Como usar uma função impura em VHDL
  7. Como usar uma função em VHDL
  8. Como criar uma máquina de estado finito em VHDL
  9. Como usar um procedimento em VHDL
  10. Como gerar números aleatórios em Java