Search code examples
binaryverilogsystem-verilogsigned

2 bit signed Multiplier


Design a 2-bit signed multiplier using one instantiation of your 4-bit adder. Remember that you need to sign extend your two 2-bit inputs to a full 4-bits.

This was my assignment and I came up with following code but some of my outputs are wrong. Can anyone tell me what I am doing wrong?

module mult(C,A,B);
    output signed[3:0]C;
    input signed[1:0]A,B;
    reg signed[3:0]sA,sB;

    assign sA = {A[1],A[1],A};
    assign sB = {B[1],B[1],B};
    
    wire carry;
    wire signed[3:0] A1;
    wire signed[3:0] A2;
    wire signed[3:0] sum0;
    
    and(A1[0],sA[0],sB[0]);
    and(A1[1],sA[1],sB[0]);
    and(A1[2],sA[2],sB[0]);
    and(A1[3],sA[3],sB[0]);
    
    
    assign A2[0] = 0;
    and(A2[1],sA[0],sB[1]);
    and(A2[2],sA[1],sB[1]);
    and(A2[3],sA[2],sB[1]);
    
 
    adder4bit a1(.A(A1),.B(A2),.Co(carry),.sum(sum0));
    assign C[0] = sum0[0];
    assign C[1] = sum0[1];
    assign C[2] = sum0[2];
    assign C[3] = sum0[3];
endmodule

module adder4bit(A,B,sum,Co);
    input signed[3:0]A,B;
    output signed [4:0]sum;
    reg signed[4:0]a,b;
    output Co;
    
    wire Ci;
    assign Ci = 1'b0;
    assign a = {A[3],A};
    assign b = {B[3],B};
    
    FA a0(.A(a[0]),.B(b[0]),.Ci(Ci),.sum(sum[0]),.Co(w1));
    FA a1(.A(a[1]),.B(b[1]),.Ci(w1),.sum(sum[1]),.Co(w2));
    FA a2(.A(a[2]),.B(b[2]),.Ci(w2),.sum(sum[2]),.Co(w3));
    FA a3(.A(a[3]),.B(b[3]),.Ci(w3),.sum(sum[3]),.Co(w4));
    FA a4(.A(a[4]),.B(b[4]),.Ci(w4),.sum(sum[4]),.Co(Co));
endmodule

module FA(A,B,Ci,Co,sum);
    
    input A,B,Ci;
    output sum,Co;
    
    assign sum = (A^B)^Ci;
    assign Co = (B&Ci) | (A&Ci) | (A&B);
    
endmodule

Solution

  • There were some signals declared as reg connected to port outputs, reg must be assigned in procedural blocks.

    I also made the carry bits in the adder an explicit wire vector, instead of multiple implicit wires. Implicit wires are dangerous a typo leads to a disconnection.

    Also I declared the sum0 in the multiplier to have the same width as the output in of the sum port where it is connected, even though the bit 4 will not be used.

    In terms of logic you made only one mistake, the A * B = A * B[0] - 2*A * B[1] instead of A * B[0] + 2*B[1] if B is a 2-bit signed integer. Because B[1] is the sign bit, thus B = B[0] - 2*B[1]. I fixed this by using the unary - directly in the port connection, I will leave it to you to write this structurally.

    module mult(C,A,B);
      output signed[3:0]C;
      input signed[1:0]A,B;
      wire signed[3:0]sA,sB;
    
      assign sA = {A[1],A[1],A};
      assign sB = {B[1],B[1],B};
    
      wire carry;
      wire signed[3:0] A1;
      wire signed[3:0] A2;
      wire signed[4:0] sum0;
    
      and(A1[0],sA[0],sB[0]);
      and(A1[1],sA[1],sB[0]);
      and(A1[2],sA[2],sB[0]);
      and(A1[3],sA[3],sB[0]);
    
    
      assign A2[0] = 0;
      and(A2[1],sA[0],sB[1]);
      and(A2[2],sA[1],sB[1]);
      and(A2[3],sA[2],sB[1]);
    
      // FIXME: Notice that I am passing -A2, the simulator will
      // negate the signal automatically. Maybe for your assignment
      // you are requried to expand this using logic primitives...
      adder4bit a1(.A(A1),.B(-A2),.Co(carry),.sum(sum0));
      assign C[0] = sum0[0];
      assign C[1] = sum0[1];
      assign C[2] = sum0[2];
      assign C[3] = sum0[3];
    endmodule
    
    module adder4bit(A,B,sum,Co);
      input signed[3:0]A,B;
      output signed [4:0]sum;
      wire signed[4:0]a,b;
      output Co;
      wire [4:1] w;  
      wire Ci;
      assign Ci = 1'b0;
      assign a = {A[3],A};
      assign b = {B[3],B};
      
      
      FA a0(.A(a[0]),.B(b[0]),.Ci(Ci),.sum(sum[0]),.Co(w[1]));
      FA a1(.A(a[1]),.B(b[1]),.Ci(w[1]),.sum(sum[1]),.Co(w[2]));
      FA a2(.A(a[2]),.B(b[2]),.Ci(w[2]),.sum(sum[2]),.Co(w[3]));
      FA a3(.A(a[3]),.B(b[3]),.Ci(w[3]),.sum(sum[3]),.Co(w[4]));
      FA a4(.A(a[4]),.B(b[4]),.Ci(w[4]),.sum(sum[4]),.Co(Co));
    endmodule
    
    
    module FA(A,B,Ci,Co,sum);
        
      input A,B,Ci;
      output sum,Co;
    
      assign sum = (A^B)^Ci;
      assign Co = (B&Ci) | (A&Ci) | (A&B);
        
    endmodule