Verilog 表达式的计算结果为 'x'

Verilog expression evaluates to 'x'

我正在用 Verilog 编写矩阵乘法模块,我遇到了一个问题,其中表达式的计算结果为一堆 'xxxx':

// multiplies 5x32 matrix by 32x5 matrix
module matmul(input [4959:0] A, input [4959:0] B, output reg [799:0] out);
    integer i,j,k;
    integer start = 0;

    reg [31:0] placeholder_A [4:0][31:0];
    reg [31:0] placeholder_B [31:0][4:0];
    reg [31:0] placeholder_out [4:0][4:0];

  always @(A or B) begin
      // initialize output to zeros
      for (i=0; i<800; i=i+1)
          out[i] = 0;

      // initialize placeholder output to zeros
      for (i=0; i<5; i=i+1)
        for(j=0; j<5; j=j+1)
          placeholder_out[i][j] = 32'd0;

      // turn flat vector A array into matrix
      for (i=0; i<5; i=i+1)
        for(j=0; j<32; j=j+1) begin
          placeholder_A[i][j] = A[start +: 31];
          start = start + 32;
        end
      start = 0;

      // turn flat vector B array into matrix
      for (i=0; i<32; i=i+1)
        for(j=0; j<5; j=j+1) begin
          placeholder_B[i][j] = B[start +: 31];
          start = start + 32;
        end
      start = 0;

      // do the matrix multiplication
      for (i=0; i<5; i=i+1) // A.shape[0]
        for(j=0; j<5; j=j+1) // B.shape[1]
          for(k=0; k<32; k=k+1) // B.shape[0] or A.shape[1]
            placeholder_out[i][j] = placeholder_out[i][j] + (placeholder_A[i][k]*placeholder_B[k][j]); // this is where I am having problems
      start = 0;

      // flatten the output
      for (i=0; i<5; i=i+1)
        for(j=0; j<5; j=j+1) begin
          out[start] = placeholder_out[i][j];
          start = start + 1;
        end
  end
endmodule 

placeholder_out 变量(因此 out 输出)被评估为 'xx...xxx',我不明白为什么。通过测试台检查信号时,placeholder_Aplaceholder_B 都包含有效值。任何帮助,将不胜感激。 您可以在此处 运行 测试平台:https://www.edaplayground.com/x/2P7m

我从代码片段中观察到的几件事。首先,输入没有足够的宽度。所需宽度为 32*5*5=5120。所以我们需要 5120 位的输入向量 (input [5119:0] A, input [5119:0] B)。 linting 工具可能已经发现了这个问题。

其次,start需要在计算开始时初始化为零。这将避免锁定 start 并将从 zeroth 索引计算 A 并避免 X 进一步传播。

  always @(A or B) begin
  //...
    start=0;

我建议使用 always_comb 而不是手动灵敏度,但那是 entirely different topic

附带说明一下,根据我的理解,给定的代码片段将创建大型组合硬件。您可能想要检查综合结果是否存在不同网络上的时序违规并应用一些替代逻辑。