从测试平台我必须破坏总线设计。 我使用随机变量来选择位位置(bit_sel)
bit_sel = $urandom_range(0,MAX_LENGTH-1);
总线位于RTL深处,宽度为MAXLENGTH。
wire [MAX_LENGTH-1:0] BUS_TO_BE_FORCED;
在TB中我正在使用以下行来破坏总线。
force TOP.DUT.....BUS_TO_BE_FORCED[bit_sel] = ~TOP.DUT.....BUS_TO_BE_FORCED[bit_sel];
但我收到编译错误。做这个的最好方式是什么。我想只翻一点。
答案 0 :(得分:2)
LHS必须是矢量网的常量位选择(以及其他内容)。所以,
force TOP.DUT.....BUS_TO_BE_FORCED[0]
没关系,但是
force TOP.DUT.....BUS_TO_BE_FORCED[bit_sel]
是没有的。您可以尝试一个大的case语句,因为选择器不必是常量:
case(bit_sel)
0: force TOP.DUT.....BUS_TO_BE_FORCED[0] = ...
...etc
答案 1 :(得分:2)
您可以使用XOR掩码翻转位:
wire [MAX_LENGTH-1:0] corrupt_bits = 1 << $urandom_range(0,MAX_LENGTH-1);
force BUS_TO_BE_FORCED = corrupt_bits ^ BUS_TO_BE_FORCED;
答案 2 :(得分:0)
编辑:初步答案包含了我的猜测以及完全错误的信息。我不应该首先回答这个问题,因此我必须编写测试台并确认以下陈述以弥补混乱。
1)位选择必须是常量(在编译时)。即使是以下代码(在我看来完全合理)也不会通过详细说明:
integer bit_sel;
initial begin
bit_sel = 0;
force BUS_TO_BE_FORCED[bit_sel] = 1'b1;
end
2)如果在“initial”块内使用,则以下陈述没有问题:
force BUS_TO_BE_FORCED[SOME_PARAM] = ~BUS_TO_BE_FORCED[some_index];
但是,“always”块内的相同语句会导致模拟挂起。可以通过添加延迟来解决此问题:
#1 force BUS_TO_BE_FORCED[SOME_PARAM] = ~BUS_TO_BE_FORCED[some_index];
3)Eric的答案是一种非常优雅的语言限制,但它也受到上面第2节中描述的限制 - 如果你想在“always”块中使用它,你将不得不添加延迟。
答案 3 :(得分:0)
我遇到了类似的问题,并使用另一个宽度相等的矢量来破坏信号。我还将它封装在一个接口中,以便我可以根据需要将它绑定到DUT的任何部分。请参阅以下代码:
import uvm_pkg::*;
`include "uvm_macros.svh"
interface sync_signal_fault_injector #(
parameter int SIGNAL_WIDTH = 1
) (
input clk,
input reset,
input [SIGNAL_WIDTH-1:0] signals
);
bit [SIGNAL_WIDTH-1:0] toggle_bits = '0;
class sync_signal_fault_injector_c extends uvm_object implements fivip_pkg::Injectable;
function new(string name="fault_injector");
super.new(name);
endfunction
virtual function int unsigned get_size();
return SIGNAL_WIDTH;
endfunction
virtual task inject(ref int unsigned indices[], input int unsigned delay);
repeat (delay) @(posedge clk);
foreach (indices[id]) begin
int unsigned bit_index = indices[id];
if (bit_index >= get_size()) begin
`uvm_fatal("BOUNDS",
$sformatf("Tried to access bit %0d but signal bus is only of size %0d", id, get_size())
)
end
// Prepare toggle bits
toggle_bits[bit_index] = 1;
end
force signals = signals ^ toggle_bits;
@(posedge clk);
release signals;
// Reset toggle bits
toggle_bits = '0;
endtask
endclass
sync_signal_fault_injector_c fault_injector = new;
endinterface