系统Verilog循环

系统Verilog循环,verilog,system-verilog,cpu-architecture,hdl,yosys,Verilog,System Verilog,Cpu Architecture,Hdl,Yosys,我目前正在系统Verilog中进行移位加法算法(32x32位乘法)。系统Verilog找不到任何错误,我的代码根据GTKwave正常工作。当我用yosys合成电路时,将添加锁存器。这就是问题所在。我的电路不需要插销。这是我的密码: module multiplier( input logic clk_i, input logic rst_i, input logic start_i, input logic [31:0] a_i,

我目前正在系统Verilog中进行移位加法算法(32x32位乘法)。系统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
模块乘法器(
输入逻辑时钟i,
输入逻辑rst_i,
输入逻辑启动i,
输入逻辑[31:0]a_i,
输入逻辑[31:0]b_i,
输出逻辑已完成,
输出逻辑[63:0]结果\u o
);
typedef枚举逻辑[1:0]{STATE_A,STATE_B}STATE_t;
州,州,州;
逻辑[63:0]fin_res;
逻辑[63:0]tmp;
逻辑rst_标志;
整数i;
始终@(posedge clk_i或posedge rst_i)开始
如果(rst_i==1'b1)开始

从注释中可以看出,在第二个case语句中没有分配一组变量,从而导致合成生成锁存。为了避免这种情况,您需要递归地分配case语句和条件语句的所有分支中的所有变量

但是,如果有一个默认值可以分配给所有这些值,则可以使用类似于第二个always块的模式,只需在“case”语句之前分配默认值。这样,您甚至不需要default子句,也可以在第二个always块中去掉它

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
始终@(*)开始
//设置默认值
rst_标志=0;
fin_res=0;
成品_o=0;
tmp=0;
结果_o=0;
案件(州)
A国:开始
rst_标志=1;
对于(i=0;i<32;i=i+1)开始
如果(a_i[i]==1'b1)开始
tmp=b_i;

tmp=tmp从注释中可以看出,在第二个case语句中没有分配一组变量,从而导致合成生成锁存。为了避免这种情况,您需要递归地分配case语句和条件语句的所有分支中的所有变量

但是,如果有一个默认值可以分配给所有这些值,则可以使用类似于第二个always块的模式,只需在“case”语句之前分配默认值。这样,您甚至不需要default子句,也可以在第二个always块中去掉它

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
始终@(*)开始
//设置默认值
rst_标志=0;
fin_res=0;
成品_o=0;
tmp=0;
结果_o=0;
案件(州)
A国:开始
rst_标志=1;
对于(i=0;i<32;i=i+1)开始
如果(a_i[i]==1'b1)开始
tmp=b_i;

tmp=tmp,但您确实使用第二个case语句编写了一个闩锁。e、 例如,您不会在每种情况下都分配完成的o(您使用“if”而没有其他选项)。同样使用
rst\u标志
,因为如果
state\u p
不是
state\u A
则不会分配它。是的,但即使修复了这些,也不会改变闩锁的任何内容。好的,我修复了它。有时候重写整个代码比搜索bug要好。。。Thx for the help guys:)还有
fin_res
,可能还有
tmp
。但是您确实用第二个case语句编写了一个闩锁。e、 例如,您不会在每种情况下都分配完成的o(您使用“if”而没有其他选项)。同样使用
rst\u标志
,因为如果
state\u p
不是
state\u A
则不会分配它。是的,但即使修复了这些,也不会改变闩锁的任何内容。好的,我修复了它。有时候重写整个代码比搜索bug要好。。。谢谢大家:)还有
fin\u res
,可能还有
tmp
。是的,你说得对。锁存器在我的代码中是必需的。我重写了整个代码,所以我现在没有任何锁存。谢谢你的帮助:)是的,你是对的。锁存器在我的代码中是必需的。我重写了整个代码,所以我现在没有任何锁存。谢谢您的帮助:)