【发布时间】:2020-11-12 19:22:59
【问题描述】:
我目前正在研究 System Verilog 中的 Shift-Add 算法(32x32 位乘法)。 System Verilog 找不到任何错误,根据 GTKwave,我的代码工作正常。当我用 yosys 合成我的电路时,会添加锁存器。这就是问题所在。我不想在我的电路中使用闩锁。这是我的代码:
module multiplier(
input logic clk_i,
input logic rst_i,
input logic start_i,
input logic [31:0] a_i,
input logic [31:0] b_i,
output logic finished_o,
output logic [63:0] result_o
);
typedef enum logic [1:0] { STATE_A, STATE_B} state_t;
state_t state_p, state_n;
logic [63:0] fin_res;
logic [63:0] tmp;
logic rst_flag;
integer i;
always @(posedge clk_i or posedge rst_i) begin
if (rst_i == 1'b1) begin
state_p <= STATE_B;
end
else begin
state_p <= state_n;
end
end
always @(*)begin
state_n = state_p;
case (state_p)
STATE_A: if (start_i == 0) state_n = STATE_B;
STATE_B: if (start_i == 1) state_n = STATE_A;
default: state_n = state_p;
endcase
end
always @(*) begin
case (state_p)
STATE_A: begin
rst_flag = 1;
fin_res = 0;
finished_o = 0;
tmp = 0;
for (i = 0; i < 32; i = i + 1) begin
if (a_i[i] == 1'b1) begin
tmp = b_i;
tmp = tmp << i;
fin_res = fin_res + tmp;
end
end
end
STATE_B: begin
result_o = fin_res;
if (rst_flag == 1) finished_o = 1;
if (start_i == 1) finished_o = 0;
end
default: begin
finished_o = 0;
result_o = 0;
end
endcase
end
endmodule
只花了 2 天时间进行调试并没有发现任何错误,我想问你是否可以帮助我。我正在分配每个输出(至少我是这么认为的)。那么我的错误在哪里?是for循环吗?但是这有什么问题呢?提前感谢您的帮助:)
代码片段的一些有用信息:start_i 是开始信号。如果设置为 1,则应该开始乘法。 finished_o 是完成标志。如果设置为 1,CPU 将知道计算已完成。 a_i 和 b_i 是应该相乘的输入。 result_o是finished_o设置为1时可以读取的乘法结果。
根据 yosys 我得到以下锁存器:
64 DLATCH_N
64 DLATCH_P
我认为 for 循环中的 fin_res 可能有问题,因为逻辑变量与锁存器一样长,正好是 64 位
【问题讨论】:
-
但是您确实使用第二个 case 语句编写了一个闩锁。例如,您不会在每种情况下都分配 finished_o(您使用 'if' 而没有其他情况)。
-
还有
rst_flag,因为如果state_p不是STATE_A,则不会分配它 -
是的,但即使修复了这些,也不会改变任何关于闩锁的事情。
-
好的,我修好了。有时重写整个代码比寻找错误更好......谢谢帮助:)
-
还有
fin_res,可能还有tmp。
标签: verilog system-verilog cpu-architecture hdl yosys