【问题标题】:Is always block needed for a generate-instantiated module to propagate the sensitivity list?生成实例化模块是否总是需要块来传播敏感度列表?
【发布时间】:2018-04-21 10:10:58
【问题描述】:

我在编写 Verilog 时感到困惑,因为 Verilog 涉及始终块、生成块和实例化的混合。感谢是否有人可以帮助我。

block_A 是一个模块,它会在第一个信号被断言时重置 x。我测试了 block_A 并看到当第一个信号被断言时 x 被重置为 0。这很简单。

module block_A #(parameter N=4) ( 
    input clk, rst, 
    input signed [N-1:0] w [3:0];
    output logic signed [N+2:0] x [3:0]
);

genvar i;
generate
    for (i=0; i<=3; i=i+1) begin
        always_ff @ (posedge clk, posedge rst) begin
            if (rst)    x[i] <= 0;
            else        x[i] <= x_[i];
        end
    end
endgenerate

但是,当我尝试使用生成块将多个 block_A 实例化到顶部模块中时,我观察到了一个非常奇怪的场景。 x[6] 和 x[7] 没有被重置为 0。我做错了吗?我应该创建另一个 always_ff 块并将这个 generate 块放在里面吗?意思是,我们需要传播敏感度列表?将 generate 块放在现有的 always_ff 块下看起来不太明智,因为它是以循环方式生成的。

module top #(parameter N=4) (
    input clk, rst, 
    input signed [N-1:0] w [15:0],
    output logic signed [N+5:0] y [15:0]
};

logic signed [N+2:0] x [15:0];

genvar i;
generate
    for (i=0; i<=15; i=i+1) begin: pipeline_y
        always_ff @ (posedge clk, posedge rst) begin
            if (rst)    y[i] <= 0;
            else        y[i] <= y_[i];
        end
    end
endgenerate

genvar j;
generate
    for (j=0; j<=15; j=j+4) begin: my_block
        block_A #(.N(N)) my_block_A(.w(w[j+3:j]),.x(x[j+3:j]),.rst(rst),.clk(clk));
    end
endgenerate

【问题讨论】:

  • 您的代码没有太大问题。该问题是由模型的其他部分引起的。很难从您的示例和缺少的波形中得出任何结论。你所说的看起来像是某种种族或clk 中的故障的结果。由于 clk 和 rst 之间的竞争,“x”本身也可能出现故障,并导致您提供的代码片段之外的问题。
  • 是的,也许我应该附上完整的代码,但它非常复杂并且涉及很多子模块,这就是我决定提供 sn-p 的原因。无论如何,我设法从根本上导致问题与解压数组有关。而不是写input signed [N-1:0] w [15:0],正确的方式应该是[15:0][N-1:0] w。这将解决“x”问题。谢谢顺便说一句

标签: verilog system-verilog


【解决方案1】:

首先:您的示例代码不正确。两者都有语法错误。如果您提供测试平台也很有帮助,这样我们就可以检查您的代码,而无需自己编写代码。

我可以想象何时使用“生成”可能会令人困惑。

我能想到的最好方法是,当您想要重复“放置”硬件时使用 generate。 这可能是一个模块的实例(就像您在代码末尾所做的那样)或放置与分配相同的逻辑:

wire [7:0] a,b,c [0:3];
generate
   for (i=0; i<4; i=i+1)
      assign a[i] = b[i] ^ c[i];

上面的例子表明 generate 不需要总是带有它。

我已经为您编写了代码并对其进行了模拟,但我必须制作自己的测试台。我在结果中没有看到任何 X-es,但是我不得不大量修改您的代码以解决语法错误,因此我不得不在几个地方猜测它应该是什么。

你的编码风格很不寻常。 block_A中的代码正常写成:

always_ff @ (posedge clk, posedge rst)
begin : a_block
integer i,j;
    if (rst)
       for (i=0; i<4; i=i+1)
          x[i] <= 0;
    else
       for (j=0; j<4; j=j+1)
          x[j] <= x_[j]; // syntax error,there is no x_!
end

这消除了对生成的需要。
为 for 循环使用单独的索引变量只是很好的编码习惯。

【讨论】:

  • 对不起,我只是显示我的代码的 sn-p。我这边没有语法错误。
  • 这样做的原因是代码更长更复杂。无论如何,我可以知道为什么我们不需要为块 A 生成吗?我们不是在重复放置 x 吗?我对此有点困惑。
【解决方案2】:

看来我正在寻找错误方向的解决方案。

在 x[6] 和 x[7] 出现 'X' 状态的原因是由于数组

input signed [N-1:0] w [15:0]

其中 w 是 N 个压缩位的解压缩数组。

block_A #(.N(N)) my_block_A(.w(w[j+3:j]),.x(x[j+3:j]),.rst(rst),.clk(clk));

当 w 被定义为二维压缩数组时,这将起作用。

解决方案:

input signed [15:0][N-1:0] w
logic signed [15:0][N+2:0] x 

【讨论】:

    猜你喜欢
    • 2021-09-13
    • 2012-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多