0

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
Filburt
  • 17,626
  • 12
  • 64
  • 115
diniebee
  • 5
  • 4

2 Answers2

1

Take care of following points while HDL coding:

  1. Use <= for sequential hardware and = for combinational hardware
  2. Never use assign inside always or visa-versa
  3. Instantiate module in proper way, i.e

<module name> #(parameter <paramters_list>) <instant_name >

  1. Specify input transition wrt to clock edges, avoid use of explicit use of # delay

Hierarchical topology of Blocks:

enter image description here

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:

enter image description here

Prakash Darji
  • 990
  • 6
  • 13
  • i am sorry. but can i know why we need to have Y1 and so on for the wave? and what is their function ? – diniebee May 24 '16 at 17:21
  • If you connect only Y to all modules then for example is S=011, then not only OR module drive your Y but all other modules also drive it, suppose all others driving it to 8'b0000_0000 and OR module drive it to 8'b0000_0011 then Y becomes 8'b0000_00XX. so we need to pass separate signals, because single wire can not be multi-driven. – Prakash Darji May 25 '16 at 01:19
0

For starters, modules GateOr and GateAnd will have illegal ranges in their S signal...

input [BITS - 14:0] S;

with BITS = 8 makes it... well, [-6:0]. Apart from that, you are driving all the outputs at once to Y. And given that you are doing a logical-OR, not an AND, in your modules, all of them will be active at once.

I'm sorry to say, your design is completely wrong. You should make each sub-block clock-independent (use an always @(*) block instead of the clock driven one), then in the top module instantiate all of them, each of them with their output driven to Y_Add, Y_Tolak, Y_Darab, Y_GateOr and Y_GateAnd signals. Finally, in the top level you can have a clocked block that says something like:

always @(posedge clk)
begin:
  if (enb == 1'b1):
    case (S)
      3'b000: Y <= Y_Add;
      3'b001: Y <= Y_Tolak;
      [...]
    endcase
end

And make sure Y is a reg, not a wire. Basically, you will be implementing a register with the value driven from a multiplexer.

eSedano
  • 312
  • 2
  • 13