Search code examples
verilogoverlapmodelsimwave

Kind stuck on the output when the output overlap


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

Solution

  • 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