0
votes

While implementing Verilog code in behavioral modeling we are using reg as output. But, when I have to use module instantiation and connect it using a wire, it's showing an error while implementation. Is there any other way where I can use module instantiation to connect outputs of different module instances to implement combinational logic as it's illegal to connect the reg output of the previous model to a wire? Note that I have to apply behavioral modeling hence no assignment statements are allowed. This is an example to connect two half adders to one full adder.

module half_adder(input wire a,b,output reg sum,output reg carry);
always@(a or b)
begin
sum = a^b ;
carry= a & b ;
end 
endmodule

module full_adder(input wire a,b,c,output reg sum,output reg carry);
    wire s1,c1,c2;
    half_adder gate1(a,b,s1,c1);
    half_adder gate2(s1,c,sum,c2);
    always@(a or b or c)
    begin
    carry = c1|c2;
    end
endmodule

Error (10663): Verilog HDL Port Connection error at full_adder.v(14): output or inout port "sum" must be connected to a structural net expression

2

2 Answers

0
votes

In standard old verilog a reg cannot be connected to a reg using module connection or a continuous assignment. System verilog allows it. So, one of the solutions could be to switch to system verilog.

As for verilog, in half_adder port sum is declared as a reg. Instance gate2 connects variable of type reg to the port of type reg. This is illegal. This type of an assignment can only happen inside a procedural (i.e. always) block. Instance gate1 bypasses this issue by connecting port to the wire s1.

So, you can follow the similar path. Create another wire s2 as in the following example.

module full_adder(input wire a,b,c,output reg sum,output reg carry);
    wire s1,c1, s2, c2;

    half_adder gate1(a,b,s1,c1);
    half_adder gate2(s1,c,s2,c2); // use s2 here

    always@*
       carry = c1|c2;
    
    always @*
       sum = s2; // now you can s2 assign to the 'sum' port
  
    endmodule

Another way is to declare the 'sum' port as a wire. A register can be connected to a wire, using port connections or continuous assignment.

   module full_adder(input wire a,b,c,
      output sum, // declares it as a wire
       output reg carry);

  ... 
    half_adder gate2(s1,c,sum,c2); // now it works this way.

And btw, do not use @(a,b,c). It is always error prone and is just wrong in your case. It should be @(c1,c2). But it is much better to use @*.

0
votes

You should not declare sum as a reg in the full_adder module because it is not being assigned inside a procedural block (such as always). A reg is not a "net" type. Change:

module full_adder(input wire a,b,c,output reg sum,output reg carry);

to:

module full_adder(input wire a,b,c,output sum,output reg carry);

You also have an incorrect sensitivity list. Change:

always@(a or b or c)

to:

always @*

Now, the always block will trigger when the signals on the RHS of the assignments change.