Как повторно заполнить ГСЧ статического процесса? - PullRequest
0 голосов
/ 15 марта 2019

У меня в тестовом стенде запущен процесс always, который вызывает $urandom_range() Можно ли перезапустить это, пока я запускаю тестовый стенд?

Я думаю, это как-то связано с srandom, но не может заставить его работать.

1 Ответ

1 голос
/ 15 марта 2019

Можно запустить генератор случайных чисел для потока (т. Е. Используемый $urandom и т. Д.), Вызвав $urandom с целочисленным аргументом, например:

 $urandom(12345);

Вы упомянули srandom. Это еще один способ взаимодействия с генератором случайных чисел потока, который заключается в использовании класса process, который объявлен в пакете std. Этот класс процесса имеет метод с именем srandom, который порождает текущий поток из целого числа.

Чтобы использовать класс process, сначала вам понадобится переменная класса process:

   std::process p;

и затем вам нужно присвоить эту переменную с возвращаемым значением статического метода класса процесса, называемого self:

   p = process::self(); 

Если вы не знакомы с объектно-ориентированным дизайном, не беспокойтесь. Доверьтесь мне. Это то, что вам нужно сделать. Думайте об этих двух линиях как о неком магическом заклинании. После того, как мы выпустили это магическое заклинание, мы можем вызвать метод srandom для заполнения генератора случайных чисел потока, например:

  p.srandom(12345);

Итак, в чем разница между srandom и $urandom? Или, говоря иначе:

Если я устанавливаю начальное число с помощью метода srandom класса процесса, устанавливает ли это генератор случайных чисел потока в то же состояние, что и установка того же начального числа с помощью $urandom?

Разницы нет. За исключением того, что есть.

Что? Давайте добавим немного кода (как показано в конце этого ответа) EDA Playground: https://www.edaplayground.com/x/4yN4

Давайте запустим генератор случайных чисел нашего потока, используя srandom:

   p.srandom(9);

затем сгенерируем четыре случайных числа:

   repeat(4) $display( $urandom ); 

и посмотрим, что мы получим:

# KERNEL:  659167701
# KERNEL: 3562992094
# KERNEL: 2163162795
# KERNEL: 4088777565 

Тогда давайте запустим генератор случайных чисел нашего потока, используя $urandom:

   $urandom(9);

и снова давайте сгенерируем четыре случайных числа

  repeat(4) $display( $urandom ); 

и снова посмотрим, что мы получим:

# KERNEL: 3562992094
# KERNEL: 2163162795
# KERNEL: 4088777565
# KERNEL: 3967046865 

На первый взгляд, похоже, что мы сгенерировали четыре случайных числа. Однако при ближайшем рассмотрении мы видим, что первое число второй ($urandom) серии совпадает со вторым числом первой серии (srandom). Почему это может быть? Ну, это потому, что вызов $urandom для установки начального числа не только устанавливает начальное значение, но и генерирует случайное число, тогда как вызов srandom только устанавливает начальное значение.


module M;
  initial
    begin
      string randstate;
      std::process p;
      p = process::self();
      $display("p.srandom(9)");
      p.srandom(9);
      repeat(4) $display( $urandom );
      $display("$urandom(9)");
      $urandom(9);
      repeat(4) $display( $urandom );
    end
endmodule

Смотрите также мой ответ здесь, в котором есть полезные справочные материалы:

urandom_range (), urandom (), random () в verilog

...