DJJJ
DJJJ

Reputation: 11

Error with Multiply-Accumulation Verilog Simulation: Illegal output or inout port connection

I'm trying to build a Multiply-Accumulator (MAC) module for Matrix Multiplier with Verilog.

Here's Verilog Code for the MAC module:

module Multiply_Accumulation(MAC_out, sel, a, b, clk, rstn); //multiply 8bit a, b and accumulate through Adder
    
    input clk, rstn, sel;
    input [8-1:0] a, b;
    output reg [22-1:0] MAC_out;

    reg [22-1:0] Multiply_out;
    reg [22-1:0] Adder_out;
    reg [22-1:0] DFF_out;
    reg [22-1:0] MUX_out;

    multiplier mul1(Multiply_out, a, b);
    adder_22bit Adder(Adder_out, MUX_out, Multiply_out);
    d_ff_22 DFF(DFF_out, Adder_out, clk, rstn); 
    mux2to1_22bit MUX(MUX_out, DFF_out, 0, sel); //reset the accumulation when sel=0

    assign MAC_out=DFF_out; //memory connected to output is write_enabled by top moodule controller when sel=0

endmodule

module d_ff_22(q, d, clk, rstn);

output [22-1:0]q;
input [22-1:0]d;
input clk, rstn;

reg [22-1:0]q;

always @ (posedge clk)

begin
   if(~rstn)
       q<=0;
   else
       q<=d;
end
endmodule

module mux2to1_22bit (out, MAC, zero, sel);
    output reg [22-1:0] out;
    input [22-1:0] MAC;
    input zero;
    input sel;

  always @(sel or MAC or zero) begin
    if (sel == 0)
      out <= zero;
    else
      out <= MAC;
  end

endmodule

module adder_22bit(out, a, b);

input [22-1:0] a,b;
output [22-1:0] out;

assign out = a+b;


endmodule

module multiplier(out, a, b);
input [8-1:0] a,b;
output [22-1:0] out;

assign out = a*b;

endmodule

I'm having problem with the MUX module while loading the design for simulation through Modelsim. The error says:

Error (suppressible): (vsim-3053) Illegal output or inout port connection for port 'out'

It seems like the output of MUX is having a problem with the MAC Module. What is the problem?

I tried to use other methods by changing reg -> wire or wire -> reg in MAC module. And problem keep happening while having error when compiling (Illegal Reference) or loading design. And the main problem might be that MAC module is recursive structure that output of DFF is feeding back information to adder. And also, even if I succeed in loading simulation, the adder module doesn't seem to get information because DFF's output isn't declared at the first time.

Upvotes: 1

Views: 250

Answers (1)

toolic
toolic

Reputation: 61987

Do not declare the output of the Multiply_Accumulation as a reg, and change the other reg signals in the module to type wire:

module Multiply_Accumulation(MAC_out, sel, a, b, clk, rstn); //multiply 8bit a, b and accumulate through Adder
    
    input clk, rstn, sel;
    input [8-1:0] a, b;
    output [22-1:0] MAC_out;

    wire [22-1:0] Multiply_out;
    wire [22-1:0] Adder_out;
    wire [22-1:0] DFF_out;
    wire [22-1:0] MUX_out;

    multiplier mul1(Multiply_out, a, b);
    adder_22bit Adder(Adder_out, MUX_out, Multiply_out);
    d_ff_22 DFF(DFF_out, Adder_out, clk, rstn); 
    mux2to1_22bit MUX(MUX_out, DFF_out, 1'b0, sel); //reset the accumulation when sel=0

    assign MAC_out=DFF_out; //memory connected to output is write_enabled by top moodule controller when sel=0

endmodule

In Verilog (IEEE Std 1364), signals connected to module output ports should be of type wire, not reg. If your simulator supports SystemVerilog features (IEEE Std 1800), your original code will likely compile without errors. Check your simulator documentation to see how to enable these features (it should be possible with Modelsim).


The simulators I used also issued a warning for the unsized 0 constant in this line:

mux2to1_22bit MUX(MUX_out, DFF_out, 0, sel); //reset the accumulation when sel=0

Changing it to a sized constant (1'b0) gets rid of the warning.

Upvotes: 0

Related Questions