Я хочу написать параллельное утверждение, которое начинается после того, как запись регистра выполняется на тестируемом устройстве из UVM testbench.Concurrent Assertion - зависимость от UVM-теста
class test extends uvm_test;
bit flag;
task run_phase(uvm_phase phase);
//call register write task , data is chosen in a random fashion
write(addr,data);
flag = 1; // flag gives the time when the register is written.
// after this task the assertions must start depending on data.
endtask
endclass
module top();
//instantiate dut, interface and other stuff
property p1(logic a,logic [4:0] b,logic flag,logic c);
disable iff(!reset || b[i] == 1 || !flag)
/*
default register value is 0, enable assertion only if 0 is written into it.
(0 is for enabling certain feature in DUT and by-default it is enabled.
1 is for disabling that feature. Assertion must never be enabled if b[i] contains 1)
*/
@(posedge clk)
a == 0 |-> $stable(c);
endproperty
assert property p1(dut_top.path_to_dut_signal,uvm_test_top.data,uvm_test_top.flag,dut_top.path_to_dut_other_signal); // gives compile error
// basically I need here dut's signal and the data written to register
// call run_test and set config_db for interface here
initial
begin
// ... run_test
end
Это дает перекрестной ссылке модуля ошибку компиляции, так как uvm_test_top создаются во время выполнения, и я предполагаю, что входы Утверждающих устанавливается во время компиляции.
Итак, я нашел несколько обходных решений для этого.
Объявление некоторых временных и флаг переменных в глобальном пространстве следующим образом:
bit flag; // in global space
logic [4:0] temp;
class test extends uvm_test;
task run_phase(uvm_phase phase);
//call register write task
write(addr,data);
temp=data, flag=1;
// after this task the assertions must start depending on temp.
endtask
endclass
/** In top, **/
property p1(logic a,logic [4:0] b,logic flag,logic c);
disable iff(!reset || b[i] == 0 || flag ==0)
@(posedge clk)
a == 0 |-> $stable(c);
endproperty
assert property p1(dut_top.path_to_dut_signal,temp,flag,dut_top.path_to_dut_other_signal);
// solves the error
Здесь используются два глобальных пространственных переменных; чего лучше избегать.
В любом случае, я могу взять эти переменные в верхней части и получить к ним доступ с помощью $ root в тесте. Но я бы не предпочел использовать $ root для повторного использования и проблем с пакетами (в случае изменения имени моего имени или написания модуля для утверждения, тест получит ошибку).
Мне интересно, есть ли еще какой-нибудь другой способ сделать это? Такое, что я могу отложить выполнение утверждения. Даже если я задержу его на 1 timestamp, я бы оценил uvm_test_top (звучит безумно .. !!).
Кроме того, я не хочу использовать интерфейсные сигналы, так как DUT является агностиком протокола, он может поддерживать разные интерфейсы на основе `ifdefs. (На самом деле это еще один способ обхода !!)
Любая помощь очень ценится.
Спасибо @Tudor. Я никогда не думал конвертировать SVA в _interface _ .. !! Несколько моментов, которые нужно уточнить. ** Во-первых, я понял о передаче интерфейса SVA в логику запуска теста и события.Но «событие» будет запускаться только ** один раз ** во время всего моделирования, и впредь запускать это утверждение только один раз (а не на каждый тактовый импульс после записи регистра). Кроме того, вопросы компиляции; так как ** ** ** ** ** ** ** ** * ** ** * * * * * Поэтому я предпочел бы использовать переменную 'bit register_written' вместо' event register_written'. – sharvil111
** Во-вторых **, это не метод записи UVM-RAL, а только задание _testbench-defined_ write; Думаю, эта информация не имеет значения. Я сделал псевдокод для этого, используя бит вместо события (событие генерирует ошибку компиляции, как ожидалось). Ссылка доступна на [EDAPlayground] (http://www.edaplayground.com/x/AQ5). – sharvil111