Reputation: 11
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
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