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