Способ иметь функцию вроде urandom_range (); который будет возвращать уникальные значения? - PullRequest
0 голосов
/ 10 марта 2020

Я хочу иметь urandom_range (); который не будет повторять значение, когда оно выбрано в симуляции? Если он исчерпал запас «доступных» номеров, то, возможно, он может повториться.

Есть ли в systemverilog какое-либо ключевое слово, которое поможет быстро обойти это?

Здесь не эксперт по SV, поэтому пример действительно поможет! Спасибо

Ответы [ 2 ]

1 голос
/ 10 марта 2020

randc делает именно это. (cycli c randomization)

class A;
  randc bit[7:0] m;
endclass

Каждый раз, когда вы вызываете randomize() для одного и того же объекта, он не будет повторять значение для m, пока не будут заданы все возможные значения.

Симуляторы имеют ограничения на то, насколько большим может быть значение cycli c, но стандарт требует минимум 8 бит. Если у вас есть большее значение, то вы можете использовать оператор inside.

class A;
      rand bit[23:0] r;
      bit [23:0] list[$];
      constraint c { !(r inside {list}); }
      function void post_randomize();
        list.push_back(r);
      endfunction   
endclass

Если вы действительно ожидаете циклического перемещения по списку, сначала может быть проще построить список, а затем shuffle через список.

bit [7:0] list[20];

for(int i=0;i<20;i++) list[i] = i+10; // range 10-29
list.shuffle();
// cycle through list[0] ... list[29]
list.shuffle();
// cycle through list[0] ... list[29]
1 голос
/ 10 марта 2020

Вы можете объявить переменную с rand c идентификатором. Это называется «циклический случайный выбор» и обеспечит именно то, что вам требуется.

Примечание: Для этого требуется лицензия, поддерживающая рандомизацию и случайные величины. Большинство коммерческих симуляторов обеспечивают это, но по более высокой цене. Если вы ограничены этим и вам нужно использовать только системные вызовы - $ urandom или $ urandom_range, я бы реализовал нечто вроде очереди, которая отслеживает все возвращаемые значения.

function automatic void find_unique_num();

    int c;
    int vals[$];
    bit found;
    do begin
      c = $urandom_range(10, 1);
      foreach(vals[i]) 
        if (c == vals[i]) found = 1;
    end
    while (!found);
    vals.push_back(c);
    return c

endfunction
...