0

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

0

2 Answers 2

0

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 @*.

Sign up to request clarification or add additional context in comments.

2 Comments

Yes, this was what I did initially but I thought I was being wrong. Also is it possible to put both carry and sum ports under one always block?
yes, you can put them under the same always block. There should be no logical difference. In theory it can slow down the simulation because any event in c1, c2 and s2 will cause re-evaluation of all the statements within the block. Splitting across multiple blocks can make the code more readable and can help avoiding certain types of mistakes but it requires more typing. So, it is up to you.
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.