Почему $urandom_range возвращает одно и то же значение?

Я запускаю тестовый стенд с UVM. В одной из задач run_phase() компонента я выполняю fork...join_none, чтобы запустить следующий цикл, который проходит через всю симуляцию:

fork
   forever @(posedge trigger) begin
      force dut.a = $urandom_range('h00,'hFF);
      force dut.b = $urandom_range( 'h0, 'hF);
      force dut.c = $urandom_range('h00,'hFF);
      force dut.d = $urandom_range( 'h0, 'hF);
      force dut.e = $urandom_range('h00,'hFF);
      force dut.f = $urandom_range( 'h0, 'hF);
   end

 ...
 some other stuff
 ...
join_none

Дело в том, что сигналы a, c и e приводятся к одному и тому же значению. То же самое для b, d и e.

Если позже появляется новая постановка триггера, новые значения рандомизируются и форсируются, но снова я получаю a == c == e и b == d == e.

Кажется, что $urandom_range вызывается только один раз для выбора каждого параметра (от 0 до FF и от 0 до F), а возвращаемое значение повторно используется для трех команд force.


РЕДАКТИРОВАТЬ: мне удалось воспроизвести проблему на минимальном ТБ: http://www.edaplayground.com/x/4_ph

Похоже, проблема с поставщиком, которого я использую, при выборе других инструментов проблема исчезает.


РЕДАКТИРОВАТЬ 2: я точно не понял, почему это происходит, но, похоже, это связано с тем фактом, что оператор force подобен непрерывному присваиванию (т. е. если сигнал RHS изменится в будущем, принудительно LHS будет следовать за ним до тех пор, пока force не станет выпускомd, это не похоже на присваивание '=').

Итак, я предполагаю, что проблема заключается в использовании возвращаемого значения функции в качестве RHS. (Я не знаю, какое время жизни имеет это возвращаемое значение)

Решение в моем случае состояло в том, чтобы сохранить значение $urandom в переменной со статическим временем жизни, а затем принудительно перевести эту переменную в RTL (как предложил Дж. Рейд)


person chinocolerico    schedule 29.09.2016    source источник
comment
Насколько близок код, который вы опубликовали, к тому, что вы на самом деле выполнили?   -  person dave_59    schedule 30.09.2016
comment
@ dave_59 Я отредактировал пост, указав дополнительный контекст. Я пытаюсь воссоздать его в EDA Playground, но на данный момент у меня проблемы с моей учетной записью.   -  person chinocolerico    schedule 30.09.2016


Ответы (3)


Почему бы не использовать класс со случайными переменными и ограничениями???

// outside of the test-bench
class my_stimulus;
    rand bit [7:0] a, c, e;  // can be logic if you like
    rand bit [3:0] b, d, f;  // rand won't give X or Z

    constraint c1 { 
        unique {a, c, e}; 
        unique {b, d, f};       
    }       
endclass;   

// inside the actual testbench 
my_stimulus to_dut = new; 

fork
   forever @(posedge trigger) begin
    if (!(to_dut.randomize()) $error;
    force dut.a = to_dut.a;
    ...
    force dut.f = to_dut.f;
   end
...
join_none   

Уникальное ограничение либо вызовет ошибку, либо каждый раз будет давать вам уникальные значения. Наличие указанного размера устраняет необходимость устанавливать границы, но это можно сделать и с другим ограничением.

person J Reid    schedule 06.10.2016

Две проблемы с вашим кодом. Во-первых, у вас обратные аргументы для $urandom_range; это (max,min), а min является необязательным значением по умолчанию 0. Некоторые симуляторы поймут это, но это не стандарт .

Вторая проблема заключается в том, что вы неоднократно форсируете одно и то же выражение. симулятор может не увидеть это как новое выражение и больше не вызывать $urandom. Попробуйте поставить оператор release перед каждым оператором force.

 forever @(posedge trigger) begin
      release dut.a; force dut.a = $urandom_range('hFF);
      release dut.b; force dut.b = $urandom_range('hF);
      release dut.c; force dut.c = $urandom_range('hFF);
      release dut.d; force dut.d = $urandom_range('hF);
      release dut.e; force dut.e = $urandom_range('hFF);
      release dut.f; force dut.f = $urandom_range('hF);
   end
person dave_59    schedule 30.09.2016
comment
Хороший улов с перевернутым диапазоном. Я попытался выпустить сигналы, но не повезло. На самом деле, когда блок запускается повторно, сигналы обновляются до новых случайных значений... просто выбранные значения остаются теми же. - person chinocolerico; 30.09.2016

Я столкнулся с очень похожей проблемой с «urandom_range» в качестве OP с использованием NCSIM. Тем не менее, "urandom" работал просто отлично. Не должно быть никаких причин, по которым «urandom» не должен работать в вашем случае вместо «urandom_range» (конечно, при условии, что «urandom» работает правильно). Результат "urandom" будет просто усечен.

СПРАВОЧНАЯ ИНФОРМАЦИЯ: На всякий случай, если кому-то интересно, я столкнулся с ошибкой в ​​NCSIM в отношении «urandom_range» (но не «urandom»), где первый вызов функции всегда возвращал минимальное указанное значение, несмотря ни на что. Но все последующие вызовы работали нормально.

person zoozoc    schedule 01.12.2016
comment
Я добавил дополнительную информацию по моему вопросу, надеюсь, это поможет - person chinocolerico; 02.12.2016