Reputation: 355
This is my first time programming in verilog hdl and I am having trouble figuring out what is wrong with my code. I need to design a simple ALU in behavioral code.
So far I have created a subtractor and adder module.( I need to add more modules but I would like to get these working in the ALU module before I add the others).
I have the following modules in seperate .v files in the same project (pretty sure this is behavioral?):
module adder3bit( sum, co, a, b);
parameter n = 2;
output reg [n:0] sum;
output reg co;
input [n:0] a;
input [n:0] b;
always @(a, b)
{co, sum} = a + b;
endmodule
module subtract3bit(diff, bo, a, b);
parameter n = 2;
output reg [n:0] diff;
output reg bo;
input [n:0] a;
input [n:0] b;
always @(a, b)
{bo, diff} = a - b;
endmodule
I tested these and see that they are working.
Now I am trying to call them in the main ALU module:
module alu( out, overflow, a, b,sel);
input [2:0] a, b;
input sel;
output [2:0] out;
output overflow;
always @(a,b,sel)
begin
if(sel=='b0)
adder3bit A1(out,overflow,a,b);
if(sel=='b1)
subtract3bit S1( out, overflow, a, b);
end
endmodule
My syntax may be wrong, but it is showing errors. I am just very unfamiliar with verilog. I feel how I first felt with learning C. Help would be much appreciated.
I know it is calling the modules correctly but I think it is something to do with the if statements.
Thank you I hope to learn something new!
Upvotes: 0
Views: 5039
Reputation: 408
The main problem is that you want to call module. Modules are not functions or tasks you cannot call them. What you can and should do with module is instantiate it in another module (in this case ALU module). Modules cannot be instantiated inside procedural blocks (e.x. always in your code). Both adder and subtractor will produce new result on every change of it's inputs so you only need to properly drive input's of this modules and the read its outputs.
I advice you to declare module's port in a more readable way:
module adder3bit #(
parameter N = 2
) (
output reg [N:0] sum,
output reg co,
input [N:0] a,
input [N:0] b
);
always @(a, b)
{co, sum} = a + b;
endmodule
In ALU you can instantiate adder3bit like this:
module alu (
input [2:0] a,
input [2:0] b,
input sel,
output [2:0] out,
output overflow
)
localparam SIZE = 3;
wire [SIZE - 1 : 0] diff;
wire [SIZE - 1 : 0] sum;
wire co;
wire bo;
adder3bit #(
.N(SIZE)
) adder (
.a(a),
.b(b),
.sum(sum),
.co(co)
);
subtract3bit #(
.N(SIZE)
) subtractor (
.a(a),
.b(b),
.diff(diff),
.bo(bo)
);
always @(*)
begin
if(sel=='b0)
{out,overflow) = {sum, co};
if(sel=='b1)
{out,overflow) = {diff, bo};
end
endmodule
And one more thing, your module has parameters which defines size of it inputs and outputs but it's name suggest that it is fixed to three which can be confusing.
Upvotes: 2
Reputation: 63
You cant instantiate a module inside an always block in verilog. Instead you can change the modules adder3bit and substract3bit into tasks and you can use the code as you have written now. the solution will be like this
task adder3bit;
parameter n = 2;
input [n:0] a;
input [n:0] b;
output reg [n:0] sum;
output reg co;
begin
always @(*) {co, sum} = a + b;
endtask
task subtract3bit;
parameter n = 2;
input [n:0] a;
input [n:0] b;
output reg [n:0] diff;
output reg bo;
begin
always @(*) {bo, diff} = a - b;
endtask
module alu( out, overflow, a, b,sel);
input [2:0] a, b;
input sel;
output [2:0] out;
output overflow;
always @(a,b,sel)
begin
if(sel=='b0)
adder3bit (a,b,out,overflow);
if(sel=='b1)
subtract3bit ( a,b,out,overflow);
end
endmodule
Upvotes: -1