在verilog中编写纹波进位加法器



我正试图在verilog中编写一个纹波进位加法器。

module half_adder(a,b,sum,carry);
   input a,b;
   output sum,carry;
   assign sum=a^b;
   assign carry=a&b;
endmodule

module full_adder(a,b,cin,sum,cout);
   input a,b,cin;
   output sum,cout;
   wire   t1,t2;
   half_adder h(a,b,t1,t2);
   assign cout=t1&cin;
   assign sum=t1^cin;
   assign cout=t2|cout;
endmodule // full_adder
module ripple_carry_adder(input1,input2,answer);
   input [31:0] input1,input2;
   output [31:0] answer;
   integer       carry,t;
   genvar        i;
   initial begin
     assign carry=1'b0;
   end
   for(i=0;i<=31;i=i+1)
     begin
        full_adder f(input1[i],input2[i],carry,answer[i],t);
        assign carry=t;
     end
endmodule

然而,当我使用iverilog模拟器进行编译时,会显示以下错误日志(重复错误已删除):

   ripple_carry_adder.v:28: warning: Couldn't build unique name for unnamed generate block - using internal name $gen1
    ripple_carry_adder.v:30: warning: Port 3 (cin) of full_adder expects 1 bits, got 32.
    ripple_carry_adder.v:30:        : Pruning (signed) 31 high bits of the expression.
    ripple_carry_adder.v:30: error: reg t; cannot be driven by primitives or continuous assignment.
    ripple_carry_adder.v:30: error: Output port expression must support continuous assignment.
    ripple_carry_adder.v:30:      : Port cout of full_adder is connected to t
    ripple_carry_adder.v:31: error: reg carry; cannot be driven by primitives or continuous assignment.
    ripple_carry_adder.v:28: warning: Couldn't build unique name for unnamed generate block - using internal name $gen1
    ripple_carry_adder.v:30: warning: Port 3 (cin) of full_adder expects 1 bits, got 32.
    ripple_carry_adder.v:30:        : Pruning (signed) 31 high bits of the expression.
    ripple_carry_adder.v:30: error: reg t; cannot be driven by primitives or continuous assignment.
    ripple_carry_adder.v:30: error: Output port expression must support continuous assignment.
    ripple_carry_adder.v:30:      : Port cout of full_adder is connected to t
    ripple_carry_adder.v:31: error: reg carry; cannot be driven by primitives or continuous assignment.

我哪里错了?

编辑:现在使用generate语句。仍然对carry的类型有疑问。

module ripple_carry_adder(input1,input2,answer);
   input [31:0] input1,input2;
   output [31:0] answer;
   wire          carry;
   wire          t;
   initial begin
     carry=1'b0;
   end
   genvar        i;
   generate for(i=0;i<=31;i=i+1)
     begin
        full_adder f(input1[i],input2[i],carry,answer[i],t);
        carry=t;
     end endgenerate
endmodule

您应该去掉初始块。您可以删除t。然后使用生成块:

   wire [31:0] carry;
   genvar i;
   full_adder f(input1[0],input2[0],1'b0,answer[0],carry[0]);
   generate // optional in IEEE std 1364-2005 and IEEE std 1800
   for(i=1;i<=31;i=i+1)
     begin
        full_adder f(input1[i],input2[i],carry[i-1],answer[i],carry[i]);
        //assign carry=t;
     end
   endgenerate
endmodule

或者,与1364-1995年的旧风格一起工作的东西:

full_adder f[31:0](input1[31:0],input2[31:0],{carry[30:0],1'b0},answer[31:0],carry[31:0]);
  1. assign语句不能在语句块内部使用。只要有begin/end块,就可以在不使用assign关键字的情况下设置语句的左侧。例如:

    initial begin
         carry = 1'b0
    end
    
  2. 不能在过程块或循环(例如full_adder)中实例化模块,需要使用generate语句。你声明了一个genvar,所以我认为你是想这么做的,但你似乎没有generate语句。

  3. 不能从模块的输出驱动reg/integer类型,只能从过程块驱动reg/integers。将类型tinteger改为wire[31:0]

最新更新