0

I am new to Verilog and trying to write a code that will add three 5-bit numbers into a 2's complement output using CSA. So the problem that I facing is that how to initially declare my inputs, where some of them are in the following format:

x is in 2's complement 1.4 format , y is in 2's complement 2.3 format, and z is in unsigned 5.0 format

and here is my 2 modules

module fulladder
        ( input a,b,cin,
            output sum,carry
            );

assign sum = a ^ b ^ cin;
assign carry = (a & b) | (cin & b) | (a & cin);

endmodule; 

module Top
    (   input [4:0] x,y,z,
        output [7:0] s,
        output cout
        );

reg  [4:0] x;         //(Q1.4)
reg  [4:0] y;         //(Q2.3)          
wire [4:0] c1,s1,c2;



fulladder fa_inst10(x[0],y[0],z[0],s1[0],c1[0]);
fulladder fa_inst11(x[1],y[1],z[1],s1[1],c1[1]);
fulladder fa_inst12(x[2],y[2],z[2],s1[2],c1[2]);
fulladder fa_inst13(x[3],y[3],z[3],s1[3],c1[3]);
fulladder fa_inst14(x[4],y[4],z[4],s1[4],c1[4]);


fulladder fa_inst20(s1[1],c1[0],1'b0,s[1],c2[1]);
fulladder fa_inst21(s1[2],c1[1],c2[1],s[2],c2[2]);
fulladder fa_inst22(s1[3],c1[2],c2[2],s[3],c2[3]);
fulladder fa_inst22(s1[4],c1[3],c2[3],s[4],c2[4]);
fulladder fa_inst23(1'b0,c1[4],c2[4],s[5],cout); 

assign s[0] = s1[0];

endmodule;

I checked a lot of sources but none of them tells how exactly declare fractions in Verilog. And I also would appreciate if someone explains how to do bits alignment for the output, since my inputs are all in a different format. I calculated that my output should be 7.4 bit long.

ViniLL
  • 107
  • 1
  • 5
  • 14
  • i think that you need to make all of them of the same format first, like Q9.0, getting rid of fractions by shifting left, then add them, and then change format back to the appropriate one, i.e. Q9.4 – Serge Feb 12 '18 at 01:42
  • Thank you, Serge, I did almost the same except that output is 7.4 – ViniLL Feb 17 '18 at 22:54

1 Answers1

1

You have to manually align the binary points as @serge mentioned.

The largest fraction section is 4. Therefore (z) the pure integer needs 4 factional bits. The unsigned integer needs an extra MSB set to 0 so in twos complement it can be combined with the signed numbers.

// x => 1.4 format (signed)
// y => 2.3 format (signed)
// z => 5.0 format (unsigned)

reg [9:0] x_i, y_i, z_i; // format 6.4 (signed)
x_i = { 5{x[5]}, x      }; // 5 int bits
y_i = { 4{y[5]}, y, 1'b0}; // 4 int bits + 1 frac bit
z_i = { 1'b0,    z, 4'b0}; // 1 int bits (always positive) + 4 frac bits

A general answer on Fixed-point with Verilog is here.

Morgan
  • 19,934
  • 8
  • 58
  • 84
  • Hi Morgan, thank you for your answer, so if I am getting it right, you just shifted 4 bits to the left for the first two inputs, but I did not get why we need to convert 3rd input to the fraction bits as well? Or did you just shift decimal point for the 4 positions to the left? And will Verilog realize that I want to operate with fractions at this point? Also that means that I am still using reg[4:0] for first two inputs or I just assigning it directly in format of x_i y_i like you mentioned? – ViniLL Feb 12 '18 at 19:58
  • For twos complement there is no such thing as signed and unsigned it is all about how you interpret the bits. forcing the MSB to 0 means it is always positive (ie same as if it was unsigned). Verilog has no concept of fractional bits. We have essentially multiplied by 2^4 to give 4 notional fractional bits, it is up to you to keep track of them! – Morgan Feb 13 '18 at 09:08
  • Thank you Morgan, I think I am getting it better now. – ViniLL Feb 17 '18 at 17:20
  • I was first really confused with fractions, but now I understood that we choose how we want to represent the fixed-point number. I also think there is another solution, where we can directly extend the inputs according to the output. Since the output will become [10:0] (sum + cout + 1'b0) bits, we extend x by replicating its MSB 5 times , y by replicating its MSB 4 times and adding 2'b0 to the right and adding 2'b0 to the left of z and 3'b0 to the right of it. – ViniLL Feb 17 '18 at 17:30
  • @DanF. That sounds about right. I would just check that you are allowing the same number of fraction bits in each input after you have extended them, ie correctly aligned the binary point. – Morgan Feb 18 '18 at 12:42
  • Yeah, I keep the track of them and in test bench I just declare in $monitor where I want to see the binary point for the inputs and output – ViniLL Feb 18 '18 at 19:51