I am very new on verilog. So this is my question:
Implement 16 bits ALU with 16 bit register. This project should meet the following requirement.
1. Design a 16 bitALU : Design a 16 bit ALU that X as input (eg. A,B..) and produces one 16 bit result.The ALU should perform the following functions. Minimum 5 operations for both ALU and LOGIC.
2. Design a 16x16 bit register file.
3. Design a control unit.
So my plan is to make a bunch of module that have operations in each module. Then i gather it at the test bench. But the problem is right now. The output seems to overlap and become red and x.
This is my Add module.
module Add(A,B,Y,S,clk,enb);
parameter BITS=8;
input clk,enb;
input [BITS - 5:0] S;
input [BITS - 1:0] A ,B;
output [BITS - 1:0] Y;
reg [BITS - 1:0] Y;
always @(posedge clk)
begin
if
((enb==1) || (S == 000))
begin
assign Y = A + B;
end
end
endmodule
Tolak module (Minus module)
module Tolak(A,B,Y,S,clk,enb);
parameter BITS=8;
input clk,enb;
input [BITS - 5:0] S;
input [BITS - 1:0] A ,B;
output [BITS - 1:0] Y;
reg [BITS - 1:0] Y;
always @(posedge clk)
begin
if
((enb==1) || (S == 010))
begin
assign Y = A - B;
end
end
endmodule
Darab module (Multiplication module)
module Darab(A,B,Y,S,clk,enb);
parameter BITS=8;
input clk,enb;
input [BITS - 5:0] S;
input [BITS - 1:0] A ,B;
output [BITS - 1:0] Y;
reg [BITS - 1:0] Y;
always @(posedge clk)
begin
if
((enb==1) || (S == 011))
begin
assign Y = A * B;
end
end
endmodule
GateOr module
module GateOr(A,B,Y,S,clk,enb);
parameter BITS=16;
input clk,enb;
input [BITS - 14:0] S;
input [BITS - 1:0] A ,B;
output [BITS - 1:0] Y;
reg [BITS - 1:0] Y;
always @(posedge clk)
begin
if
((enb==1) || (S == 011))
begin
assign Y = A | B ;
end
end
endmodule
GateAnd module
module GateAnd(A,B,Y,S,clk,enb);
parameter BITS=16;
input clk,enb;
input [BITS - 14:0] S;
input [BITS - 1:0] A ,B;
output [BITS - 1:0] Y;
reg [BITS - 1:0] Y;
always @(posedge clk)
begin
if
((enb==1) || (S == 100))
begin
assign Y = A & B;
end
end
endmodule
AND THIS IS MY TEST BENCH
module Maintb ();
parameter SIZE=8;
reg clk, enb ;
reg [SIZE-6:0] S;
reg[SIZE-1:0] A,B;
wire[SIZE-1:0] Y;
initial
begin
clk = 1'b0; enb = 1'b0;
end
// generate clock
always
begin
#(10) clk = !clk;
end
always begin
//#(10);
#10; enb = 1'b1; A=00000001; B=00000000; S=000; //add
#(10); enb = 1'b0;
#10; enb = 1'b1; A=00000001; B=00000000; S=001; //tolak
#(10); enb = 1'b0;
#10; enb = 1'b1; A=00000001; B=00000000; S=010; //darab
#(10); enb = 1'b0;
#10; enb = 1'b1; A=00000001; B=00000000; S=011; //or
#(10); enb = 1'b0;
#10; enb = 1'b1; A=00000001; B=00000000; S=100; //and
//#(10);
end
defparam dut.BITS = SIZE;
defparam dut1.BITS = SIZE;
defparam dut2.BITS = SIZE;
defparam gate.BITS = SIZE;
defparam gate1.BITS = SIZE;
Add dut (A,B,Y,S,clk,enb); //000
Tolak dut1 (A,B,Y,S,clk,enb); //001
Darab dut2 (A,B,Y,S,clk,enb); //010
GateOr gate (A,B,Y,S,clk,enb); //011
GateAnd gate1 (A,B,Y,S,clk,enb);//100
Endmodule
Take care of following points while HDL coding:
<=
for sequential hardware and =
for combinational hardware <module name> #(parameter <paramters_list>) <instant_name >
Hierarchical topology of Blocks:
You can see in Image, ALU is top level entity and contain sub-modules, which are connected to each other or shared signals in top.
Testbench is having highest level top where instance of DUT (Designed Top is to be TESTED)-Design Under Test.
Which basically stimulate signal into the DUT and get response from the same.
Make sure that you are not driving same signal from multiple modules, like in your case it is Y
which is driven by add, sub, mul, AND and OR module of ALU, which needs to be separate.
Removed clk
signal because combinational circuit does'not require clk
at all.
See your clean code with tb, modify it as mentioned upward:
module Add #(parameter BITS=8)(A,B,Y,S,enb);
input wire enb;
input wire [2:0] S;
input wire [BITS - 1:0] A ,B;
output wire [BITS - 1:0] Y;
assign Y = (A + B) & {BITS{enb & (S == 3'b000)}};
endmodule
module Tolak #(parameter BITS=8) (A,B,Y,S,enb);
input enb;
input [2:0] S;
input [BITS - 1:0] A ,B;
output wire [BITS - 1:0] Y;
assign Y = (A - B) & {BITS{enb & (S == 3'b001)}};
endmodule
module Darab #(parameter BITS=8) (A,B,Y,S,enb);
input enb;
input [2:0] S;
input [BITS - 1:0] A ,B;
output wire [BITS - 1:0] Y;
assign Y = (A * B) & {BITS{enb & (S == 3'b010)}}; // truncated to 8 bit only
endmodule
module GateOr #(parameter BITS=8) (A,B,Y,S,enb);
input enb;
input [2:0] S;
input [BITS - 1:0] A ,B;
output wire[BITS - 1:0] Y;
assign Y = (A | B) & {BITS{enb & (S == 3'b011)}}; // truncated to 8 bit only
endmodule
module GateAnd #(parameter BITS=8) (A,B,Y,S,enb);
input enb;
input [2:0] S;
input [BITS - 1:0] A ,B;
output wire [BITS - 1:0] Y;
assign Y = (A & B) & {BITS{enb & (S == 3'b100)}}; // truncated to 8 bit only
endmodule
module Maintb ();
parameter SIZE=8;
reg clk, enb ;
reg [2:0] S;
reg [SIZE -1:0] A,B;
wire [SIZE -1:0] Y,Y1,Y2,Y3,Y4,Y5;
Add #(SIZE) dut (A,B,Y1,S,enb); //000
Tolak #(SIZE) dut1 (A,B,Y2,S,enb); //001
Darab #(SIZE) dut2 (A,B,Y3,S,enb); //010
GateOr #(SIZE) gate (A,B,Y4,S,enb); //011
GateAnd #(SIZE) gate1 (A,B,Y5,S,enb);//100
assign Y = Y1 | Y2 | Y3 | Y4 | Y5;
initial
begin
clk = 1'b0;
enb = 1'b0;
enb = 1'b0; A=8'b0000_0000; B=8'b0001_0000; S=3'b000;
end
// generate clock
always #10 clk = ~clk;
initial
begin
@(posedge clk);
@(posedge clk);
@(posedge clk);
@(posedge clk);
@(posedge clk); enb = 1'b1; A=8'b0000_0001; B=8'b0000_0010; S=3'b000; //add
@(posedge clk); enb = 1'b0;
@(posedge clk); enb = 1'b1; A=8'b0000_0011; B=8'b0010_0000; S=3'b001; //tolak
@(posedge clk); enb = 1'b0;
@(posedge clk); enb = 1'b1; A=8'b0000_1001; B=8'b0000_0000; S=3'b010; //darab
@(posedge clk); enb = 1'b0;
@(posedge clk); enb = 1'b1; A=8'b0010_0001; B=8'b0100_0000; S=3'b011; //or
@(posedge clk); enb = 1'b0;
@(posedge clk); enb = 1'b1; A=8'b1000_0001; B=8'b0000_0000; S=3'b100; //and
@(posedge clk); enb = 1'b0;
@(posedge clk); enb = 1'b0; A=8'b0000_0000; B=8'b0001_0000; S=3'b000; //and
#100 $finish;
end
initial
begin
$monitor("clk %b A-%b B-%b Y-%b S-%b enb-%b",clk, A, B, Y, S, enb);
end
endmodule
Simulation: