В испытательном стенде SystemVerilog UVM мы рандомизируем объекты транзакций и для некоторых конкретных тестов создаем дополнительные ограничения. Однако эти ограничения тестового набора используются механизмом рандомизации только в том случае, если вы вызываете метод тестового набора randomize()
, а не obj.randomize()
. Это довольно запутанно.
Интересно, почему все ограничения на объект не используются независимо от того, какой рандомизация вызывается? Почему ограничения имеют область действия?
Например:
class trans;
rand int addr;
constraint addr_c; // Method 1: constraint prototype
function void post_randomize();
$display("addr %d",addr);
endfunction
endclass
//////////////////// Test case code /////////////////
// Method 1: extend constraint prototype addr_c external to test class.
// constraint trans::addr_c { addr > 0 && addr < 10; }
// works but requires prototype, careful if trans is in another package
class my_test;
trans trans1;
// Method 2: Add constraint to the test
constraint test_constraint_c { trans1.addr > 11 && trans1.addr < 20; }
function new();
trans1 = new;
repeat (20) begin
// This doesn't use test_constraint_c (why??)
assert(trans1.randomize()) else $display("TEST", "Randomization Failed");
// This uses test_constraint_c
assert(randomize(trans1)) else $display("TEST", "Randomization Failed");
end
endfunction
endclass
module tb;
my_test test1;
initial test1 = new;
endmodule
У вас есть 2 класса, которые не связаны друг с другом: trans
и my_test
.
Класс trans
не знает об ограничении test_constraint_c
, потому что ограничение является лишь частью класса my_test
. Таким образом, когда вы вызываете функцию randomize
для объекта (trans1.randomize()
), она не имеет ограничений для применения.
В тесте, когда вы вызываете метод randomize
для переменной trans1
, он будет применять любые активные ограничения в классе my_test
, а именно test_constraint_c
.
Альтернативный подход — расширить класс trans
новым блоком ограничения.