2
votes

I have written all the code, including the modules, but I can't figure out how to wire the modules to the main program.

The ALU should be:

  • A (4bits) and B (4bits) as inputs, sel (3bits)
  • 1st Module When sel = 000 => Add/ sel= 001 => Sub (A+B or A-B)
  • 2nd Module When sel = 010 => Shift right by 1
  • 3rd Module when sel = 011 => Multiply (A*B)
  • 4th Module When sel = 100 => A XNOR B
  • 5th Module When sel = 101 => Compare A==B
  • I also made a 6th module with a Mux6to1.

It has to be on a gate level. Can't use (+/-). This is the code I've been writing but when I simulate, I just get the result: ZZZZZZZZ. Please, any suggestions would be appreciated, thanks.

For Add/Sub 1 bit:

module Full_Adder_1bit(a,b,cin,sel,sum,cout);
    input a, b, cin;
    input [2:0] sel;
    output sum, cout;
    reg sum, cout;

    reg a_in;

    always @ (a or b or cin or sel)
      begin
       a_in = a^sel[0];
       sum = a^b^cin;
       cout = (a_in&b)|(a_in&cin)|(b&cin);
      end
endmodule

For 4 bit ADD/SUB:

module Full_Adder_4bits (a, b, cin, sel, sum, cout);

    input [3:0] a, b;
    input [2:0] sel;
    input cin;
    output [3:0] sum;
    output  cout;
    wire c1,c2,c3;

    Full_Adder_1bit FA0(a[0],b[0],cin,sel,sum[0],c1);
    Full_Adder_1bit FA1(a[1],b[1],c1,sel,sum[1],c2);
    Full_Adder_1bit FA2(a[2],b[2],c2,sel,sum[2],c3);
    Full_Adder_1bit FA3(a[3],b[3],c3,sel,sum[3],cout);
endmodule

For the Shifter:

module Shifter(dataIn, shiftOut); 
    output [3:0] shiftOut; 
    input [3:0] dataIn; 
    assign shiftOut = dataIn >> 1; 
endmodule 

For the XNOR:

module XNOR(a,b,rxnor);
    input [3:0] a,b;
    output [3:0] rxnor;

    reg rxnor;
    always @ (a or b)
       begin
        rxnor= a~^b; //XNOR
       end
endmodule

For Multiplier:

module mul4 (i0,i1,prod);
    input [3:0] i0, i1;
    output [7:0] prod;
    assign prod = i0*i1;
endmodule

For Compare:

module Compare(B,A,R);
    input  [3:0] A,B;
    output [3:0] R;
    reg     R;

    always@(A,B)
      begin
        if  (A==B)
        R = 4'b0001;
        else if (A==B)
        R = 4'b0000;
        else 
        R = 4'b1111;
      end
 endmodule

For the mux (it is actually 5 to 1 even though the name says 6 to 2):

 module MUX6to2(i0,i1,i2,i3,i4,sel,out);
  input [4:0] i0,i1,i2,i4;
  input [7:0] i3;
  input [2:0] sel;
  output [7:0] out;
  reg [7:0] out;

  always @ (i0 or i1 or i2 or i3 or i4 or sel)

    begin
     case (sel)
     3'b000: out = i0;
     3'b001: out = i0;
     3'b010: out = i1;
     3'b011: out = i2;
     3'b100: out = i3;
     3'b100: out = i4;
     default: out = 8'bx;
     endcase
   end
endmodule

For the ALU:

module ALU(a,b,cin,sel,r,cout);

  input [3:0] a, b;
  input [2:0] sel;
  input cin;
  output [7:0] r;
  output cout;

  wire [3:0] add_out, shift_out, xnor_out, compare_out;
  wire [7:0] mul_out;
  wire cout;

  MUX6to2 output_mux (Full_Adder_4bits, Shifter, XNOR, mul4, Compare, sel[2:0], r);
  Full_Adder_4bits output_adder (a,b,cin,sel [2:0],add_out,cout);
  Shifter output_shifter (a,shift_out);
  XNOR output_XNOR (a,b,xnor_out);
  mul4  output_mul4 (a,b,mul_out);
  Compare output_Compare (a,b,compare_out);

 endmodule
3
I don't see any problems other than in the mux you have two cases for 3'b100. The second one should have been 3'b101. r should never be driving Z. I could understand X if you weren't driving the inputs properly or had bad logic, but there is nothing in here that would drive a Z.Brad Budlong
You can use case statement in top-module and call other modules as function.Jithin
Your compare module also have some strange conditions in if-else.Qiu
For gate level implementation you can't use multiplication by using * operator, use Vedic or Booth multiplication IP.Jithin

3 Answers

1
votes

Why the value of output "r" Hi-Z is you haven't connected anything to output so the default value of wire is propagated in the output

When it comes to your design a decoder is required and for arithmetic operation operand size has to be taken care

Required bit widths are

addition    4 bit + 4 bit = 4 bit + carry,
subtraction 4 bit - 4 bit = 4 bit + borrow,
shifting which of them should be shifted and required bit width needs to be calculated,
multiplication 4*4 bit = 8 bit is needed,
xnor 4 bit xnot 4 bit = 4 bit needed,
compare it is up how we represent if equal with 1 bit or any bit widths

In your Mux logic you have

 3'b100: out = i3;
 3'b100: out = i4;

Here in this both case items are same so synthesizer optimizes and only considers the first statement and ignores the second, in general case should not be coded this way and more over this mux itself is not necessary.

Coming to your top module ALU, the syntax is wrong, this type of assignments are not permitted in verilog HDL

 MUX6to2 output_mux (Full_Adder_4bits, Shifter, XNOR, mul4, Compare, sel[2:0], r);

When integrating all modules you have to be clear about what you are going to connect and widths with hardware in mind map,

Considering your design The adder will result in 4bit + carry but output "r" is 8 bit so other bits should made to constant value or else it will be defaulted to X in case reg or Hi-z in case wire in the output, similar for other operations too.

I have made some modification in the design with a decoder and found to be fully functional,

A (4bits) and B (4bits) as inputs, sel (3bits)
When sel = 000 => Add/ sel= 001 => Sub (A+B or A-B)
When sel = 010 => Shift right by 1
when sel = 011 => Multiply (A*B)
When sel = 100 => A XNOR B
When sel = 101 => Compare A==B

Give a try of the code http://www.edaplayground.com/x/DaF

1
votes

in the module ALU, check the port list which where mapped to multiplexer module as emman said.

MUX6to2 output_mux (Full_Adder_4bits, Shifter, XNOR, mul4, Compare, sel[2:0], r); in this module, the output which declared is of size 8 bit r. but, in some cases add_out, shift_out, xnor_out, compare_outthe size is 4 bits only. so, during the case of these outputs, the output 'r' shows 4 X's.

    module ALU(a,b,cin,sel,r,cout);

      input [3:0] a, b;
      input [2:0] sel;
      input cin;
      output [7:0] r;
      output cout;

      wire [3:0] add_out, shift_out, xnor_out, compare_out;
      wire [7:0] mul_out;
      wire cout;

     // MUX6to2 output_mux (Full_Adder_4bits, Shifter, XNOR, mul4, Compare, sel[2:0], r);
  MUX6to2 output_mux (add_out, shift_out, xnor_out, mul_out, compare_out, sel[2:0], r);

      Full_Adder_4bits output_adder (a,b,cin,sel [2:0],add_out,cout);
      Shifter output_shifter (a,shift_out);
      XNOR output_XNOR (a,b,xnor_out);
      mul4  output_mul4 (a,b,mul_out);
      Compare output_Compare (a,b,compare_out);

     endmodule
0
votes

Does your code compile properly? I can see a problem in this line:

MUX6to2 output_mux (Full_Adder_4bits, Shifter, XNOR, mul4, Compare, sel[2:0], r);

Full_Adder_4bits, Shifter, etc. are names of your modules, not a valid signal names. What you meant is probably this:

Mux6to2 output_mux (adder_out, shifter_out, xnor_out, mul_out, compare_out, sel, r);