【问题标题】:How to force a single bit in an array of bits in systemverilog?如何在systemverilog的位数组中强制一个位?
【发布时间】:2019-01-17 10:47:05
【问题描述】:

我现在正试图在位数组中强制位。要“强制”的位的位置取决于变量 i 而其他位保持 0。 例如,如果我有数组位 [2:0] Ai=0 时,我希望A 成为3'b001i=1A 应该是3'b010i=2A 应该是3'b100 但我必须使用 force 语句,因为我正在编写测试台来测试信号路径。 有谁知道我该怎么做?

更新 1:@Serge 我必须使用这样声明的 force 语句:bit [31:0] A 我试过这个:force A[31:0] = 32'd0; for (int i=0;i

update2:我现在已经生成了一个脚本来逐个强制信号 但是,我不确定我是否遇到错误 执行此语句时 a[31:0] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,`TOP_TB.clk_1T,0}; a[1] 保持为 0。相反,1T clk 出现在 a[0]。有谁知道发生了什么?

update3:感谢您的帮助!!我实际上认为 0 被解释为 32 位,但我真的不知道为什么 1T clk 出现在位 0 而不是位 1(我使用的是 questasim) .顺便说一句,我通过生成脚本并将内容复制并粘贴到脚本生成的文本文件中来解决了这个问题。

【问题讨论】:

  • 欢迎来到 Stack Overflow。添加您已经尝试过的内容会对您有所帮助,因此我们可以看到您到底遇到了什么问题。 (例如,当 i 为 0 时,您想强制值 3'b001,还是只强制 A 的位 [0]?无论哪种情况,有什么问题?)请编辑您的提供此信息的问题,请不要在评论中添加。
  • 在您的解释中“强制”是什么意思? Verilog 能够force 测试台中的网络,使其无法更改。这是不可合成的。您的意思是force 语句还是只是将值分配给“数组”的一部分?这个数组是什么:netvar?它是如何宣布的?您需要提供您的编码尝试,以便我们更好地了解您的意图。

标签: system-verilog test-bench


【解决方案1】:

你可以在 verilog 中使用位索引来做你想做的事。这就像在 C 中对数组进行索引。例如:

array_a[i] <= new_value;

在上面的代码中,如果i为0,它会将new_value赋给bit 0,其余的保持不变。

【讨论】:

    【解决方案2】:

    来自语言参考手册(IEEE Std 1800-2017),第 10.6.2 节(“强制和释放程序语句”):

    赋值的左侧可以是对奇异变量、网络、向量网络的常数位选择、向量网络的常数部分选择或这些的串联的引用。它不应是变量或具有用户定义的网络类型的网络的位选择或部分选择。

    看来不能直接做你想做的事。

    我最好的选择是或多或少地做你想做的事情(我只是强迫一个位,而让其他位正常发展),请记住,力分配的 LHS 应该是恒定的,类似于这个:

    module dut (
        input   logic   [31:0]  a,
        input   logic   [31:0]  b,
        output  logic   [31:0]  z
    );
    
        always_comb z = a & b;
    
    endmodule: dut
    
    module tb;
        logic [31:0] a;
        logic [31:0] b;
        logic [31:0] z;
    
        dut dut (.*);
    
        logic clk = 0;
        initial forever
            #(5ns) clk = !clk;
    
        logic [5:0] sel;
        initial forever begin
            case (sel)
                6'd0: force z[0] = clk;
                6'd1: force z[1] = clk;
                6'd2: force z[2] = clk;
                6'd3: force z[3] = clk;
                6'd4: force z[4] = clk;
                6'd5: force z[5] = clk;
                6'd6: force z[6] = clk;
                6'd7: force z[7] = clk;
                6'd8: force z[8] = clk;
                6'd9: force z[9] = clk;
                6'd10: force z[10] = clk;
                6'd11: force z[11] = clk;
                6'd12: force z[12] = clk;
                6'd13: force z[13] = clk;
                6'd14: force z[14] = clk;
                6'd15: force z[15] = clk;
                6'd16: force z[16] = clk;
                6'd17: force z[17] = clk;
                6'd18: force z[18] = clk;
                6'd19: force z[19] = clk;
                6'd20: force z[20] = clk;
                6'd21: force z[21] = clk;
                6'd22: force z[22] = clk;
                6'd23: force z[23] = clk;
                6'd24: force z[24] = clk;
                6'd25: force z[25] = clk;
                6'd26: force z[26] = clk;
                6'd27: force z[27] = clk;
                6'd28: force z[28] = clk;
                6'd29: force z[29] = clk;
                6'd30: force z[30] = clk;
                6'd31: force z[31] = clk;
            endcase
            @(clk or sel);
            release z[0];
            release z[1];
            release z[2];
            release z[3];
            release z[4];
            release z[5];
            release z[6];
            release z[7];
            release z[8];
            release z[9];
            release z[10];
            release z[11];
            release z[12];
            release z[13];
            release z[14];
            release z[15];
            release z[16];
            release z[17];
            release z[18];
            release z[19];
            release z[20];
            release z[21];
            release z[22];
            release z[23];
            release z[24];
            release z[25];
            release z[26];
            release z[27];
            release z[28];
            release z[29];
            release z[30];
            release z[31];
        end
    
        initial begin
            a = 32'h0055aaffaa55ff00;
            b = 32'habcdef0123456789;
            sel = 6'd0;
            #(98ns);
            sel = 6'd6;
        end
    endmodule: tb
    

    这适用于我的 ModelSim 版本(INTEL FPGA STARTER EDITION 10.6c)。

    至于为什么你的代码:

    a[31:0] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,`TOP_TB.clk_1T,0};
    

    不起作用,我最好的猜测是每个“0”都被解释为一个整数 0,即32'd0。然后你就可以有效地得到一些东西了:

    a[31:0] = {960'd0, `TOP_TB.clk_1T, 32'd0};
    

    RHS 被截断以仅适合 32 位。截断当然意味着“32'd0”剩下的任何东西都被丢弃了,但你的编译器真的应该对此提出警告。比如:

    a[31:0] = {30'b0,`TOP_TB.clk_1T,1'b0};
    

    为我工作。当然,您也可以将该构造插入我在示例中使用的“案例”中。

    【讨论】:

      【解决方案3】:

      Systemverilog 不允许你强制一个向量的位片,所以你必须强制整个网络。这里一个好的策略是强制网络: force A = A ^ my_force_vector; 并将 my_force_vector 设置为您想要强制的位。

      在此处查看此答案:https://stackoverflow.com/a/50845703/6262513

      【讨论】:

      • 看过里面的代码,其实force语句的RHS不是常量。我想强制特定的信号位为时钟信号,所以我认为这种方法行不通,因为“my_force_vector”只分配一次,但不是连续的
      • 您可以为此创建更精细的力:force A = (A &amp; ~my_force_vector) | (my_force_vector &amp; clock_vector); 使用 my_force_vector 将网络驱动为 0。时钟向量可能如下所示:clock_vector = {myclk1, myclk2...};
      • EDA 操场上的工作示例:edaplayground.com/x/3RaC
      猜你喜欢
      • 2023-02-25
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多