1

在测试台上,我必须破坏设计中的总线。我正在使用随机变量来选择位位置 ( 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];

但是,我收到编译错误。做这个的最好方式是什么?我只想翻转一点。

4

4 回答 4

3

您可以改为使用 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;
于 2013-06-15T09:32:58.263 回答
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
于 2013-06-14T11:11:03.280 回答
0

编辑:最初的答案包含我的猜测,以及完全错误的信息。我一开始就不应该回答这个问题,因此我不得不编写测试台并确认以下语句以弥补混乱。

1) 位选择必须是一个常数(在编译时)。即使是下面的代码(在我看来完全合理)也不会通过详细说明:

integer bit_sel;
initial begin
    bit_sel = 0;
    force BUS_TO_BE_FORCED[bit_sel] = 1'b1;
end

2)如果在“初始”块内使用,以下语句很好:

force BUS_TO_BE_FORCED[SOME_PARAM] = ~BUS_TO_BE_FORCED[some_index];
  • SOME_PARAM 是一个参数
  • some_index 可能是变量或网络
  • SOME_PARAM = some_index

但是,“always”块中的相同语句会导致模拟挂起。这个问题可以通过添加延迟来解决:

#1 force BUS_TO_BE_FORCED[SOME_PARAM] = ~BUS_TO_BE_FORCED[some_index];

3) Eric 的回答是绕过语言限制的一种非常优雅的方法,但它也受到上面第 2 节中描述的限制 - 如果你想在“always”块中使用它,你必须添加延迟。

于 2013-06-14T14:34:47.280 回答
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
于 2018-06-13T20:24:42.493 回答