我目前正在系统Verilog中研究Shift-Add算法(32x32位乘法)。System找不到任何错误,我的代码按照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经过两天的调试,没有发现任何错误,我想问你是否可以帮助我。我正在分配每个输出(至少我认为是这样)。那我的错误在哪里?是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位。
发布于 2020-11-13 00:35:49
在注释中,有许多变量没有在第二个case语句中赋值,从而导致合成生成闩锁。为了避免这种情况,您需要递归地分配case语句和条件语句的所有分支中的所有var。
但是,如果有一个默认值可以分配给所有这些值,则可以使用与第二个始终块中的模式类似的模式,只需在'case‘语句之前分配默认值。这样,您甚至不需要默认子句,并且可以在第二个始终块中消除它。
always @(*) begin
// set default values
rst_flag = 0;
fin_res = 0;
finished_o = 0;
tmp = 0;
result_o = 0;
case (state_p)
STATE_A: begin
rst_flag = 1;
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;
// are you sure that you do not need a latch here?
if (rst_flag == 1) finished_o = 1;
if (start_i == 1) finished_o = 0;
end
// you do not need 'default' here.
endcase
end我的修复将导致组合行为,并应摆脱锁存在合成,但它看起来不像你所期望的那样。看来你真的需要一个门闩。
..。
https://stackoverflow.com/questions/64810439
复制相似问题