#system-verilog
#system-verilog
Вопрос:
Мне интересно, как можно использовать оператор импликации, если я хочу выбирать между разными диапазонами адресов. Я использую if/else
условие, но, похоже, решатель ограничений не принимает никакого решения для этого.
constraint ctCopy { mode == C_CMD -> if (addr_range == "DST_SRAM") {dstAddr inside {[0:'hFFFF]}; }
else if (addr_range == "DST_AXI") {dstAddr inside {['h30000:'h3FFFF]}; }
else if (addr_range == "DST_AHB") {dstAddr inside {[20000:'h2FFFF]}; }
else {dstAddr inside {[0:'hFFFF]}; }
mode == C_CMD -> if (addr_range == "SRC_SRAM") {srcAddr inside {[0:'hFFFF]}; }
else if (addr_range == "SRC_AXI") {srcAddr inside {[0:'h30000]}; }
else {srcAddr inside {[0:'hFFFF]}; }
mode == C_CMD -> cSize inside {[2:10]} ;
}
Я пытаюсь использовать with
ограничение, но решатель не принимает. Вот фрагмент:
Trn0.randomize() with { mode == C_CMD; addr_range == "DST_AHB";};
небольшой пример для воспроизведения, как показано ниже
class top;
rand logic [3:0] mode;
rand logic [16:0] dstAddr;
rand logic [16:0] srcAddr;
string addr_range;
rand logic [4:0] copySize;
constraint ctCopy { mode == 1 -> if (addr_range == "DST_SRAM") {dstAddr inside {[0:'hFFFF]}; }
else if (addr_range == "DST_AXI") {dstAddr inside {['h30000:'h3FFFF]}; }
else if (addr_range == "DST_AHB") {dstAddr inside {[20000:'h2FFFF]}; }
else {dstAddr inside {[0:'hFFFF]}; }
mode == 1 -> if (addr_range == "SRC_SRAM") {srcAddr inside {[0:'hFFFF]}; }
else if (addr_range == "SRC_AXI") {srcAddr inside {[0:'h30000]}; }
else {srcAddr inside {[0:'hFFFF]}; }
mode == 1 -> copySize inside {[2:10]} ;
}
endclass
module tb;
initial begin
top tb = new;
tb.randomize() with { mode == 1; addr_range == "DST_AHB";};
$display("dstAddr=
,srcAddr=
",tb.dstAddr,tb.srcAddr);
end
endmodule
Автономный пример в:
Ответ №1:
addr_range
имеет тип string
, что означает, что он не может быть rand
переменной. Один из способов решить вашу проблему — установить addr_range
перед вызовом randomize
:
module tb;
initial begin
top tb = new;
tb.addr_range = "DST_AHB";
tb.randomize() with { mode == 1; };
$display("dstAddr=
,srcAddr=
",tb.dstAddr,tb.srcAddr);
end
endmodule
Другой способ — использовать перечисления вместо строк, если вы хотите addr_range
быть случайными.
При запуске с Cadence на edaplayground он генерирует предупреждающие сообщения о том, что некоторые значения в вашем ограничении находятся вне диапазона. Например, вы объявили dstAddr
как 17-битное значение, но 'h3FFFF
требуется не менее 18 бит. Вы должны исправить свои значения.