100% found this document useful (1 vote)
614 views11 pages

Fixed Point Adder Verilog

The document contains Verilog code for a shift-add multiplier and fixed point adder. The shift-add multiplier code includes a top module that uses shift registers to left shift the multiplicand and right shift the multiplier over multiple clock cycles to generate the partial products and accumulate the sum. The fixed point adder code includes a top module that adjusts the integer and fraction parts of two fixed point numbers to have the same radix point, adds the adjusted values, and outputs the sum with overflow detection and truncation/padding to a specified output format. Test benches are provided to test each module by applying test inputs and comparing the outputs to ideal real number results.

Uploaded by

Uday A Korat
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
614 views11 pages

Fixed Point Adder Verilog

The document contains Verilog code for a shift-add multiplier and fixed point adder. The shift-add multiplier code includes a top module that uses shift registers to left shift the multiplicand and right shift the multiplier over multiple clock cycles to generate the partial products and accumulate the sum. The fixed point adder code includes a top module that adjusts the integer and fraction parts of two fixed point numbers to have the same radix point, adds the adjusted values, and outputs the sum with overflow detection and truncation/padding to a specified output format. Test benches are provided to test each module by applying test inputs and comparing the outputs to ideal real number results.

Uploaded by

Uday A Korat
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

Home Work: 2

Uday A Korat
Red Id: 818480618

Uday A Korat | SAN DIEGO STATE UNIVERSITY

Question: 1 Shift and Add Multiplier


Verilog Code:

Top Module:

`timescale 1ns / 1ns


module shift_add_multiplier #(parameter WL = 4) //word length parameter of input and output
(input [WL-1:0]a, //multiplicand
input [WL-1:0]b, //multiplier
input CLK, //clock signal
input RST, //control signal to reset all register
input LOAD,//control signal to load input value in register
output [2*WL-1:0]Mult_out);
reg [2*WL-1:0] partial_product; // partial product accumulator
reg [2*WL-1:0] reg_a; //register for multiplicand
reg [WL-1:0] reg_b; //register for multiplier
assign Mult_out = partial_product;
always @(posedge CLK) begin
//control signal RESET with highest priority
if (RST) begin
reg_a<=0;
reg_b<=0;
partial_product<=0;
end
//control signal to LOAD input value in register
else if (LOAD) begin
reg_a<=a;
reg_b<=b;
partial_product<=0;
end
else begin//partial product generation and addition
if(reg_b[0]) begin
//if LSB of multiplier is 1
//then add shfted muliplicand according iteration value
partial_product <= partial_product + reg_a;
end

//left shift for multiplicand


reg_a <= reg_a<<1;
//right shift for multiplier
reg_b <= reg_b>>1;
Uday A Korat | SAN DIEGO STATE UNIVERSITY

end
//multiplier output after
//every partial product generation and addition
end
endmodule

Test Bench:

`timescale 1ns / 1ns


module tb_shift_add_multiplier;
// Inputs
reg [3:0] a;
reg [3:0] b;
reg CLK;
reg RST;
reg LOAD;
// Outputs
wire [7:0] Mult_out;
// Instantiate the Unit Under Test (UUT)
shift_add_multiplier uut (
.a(a),
.b(b),
.CLK(CLK),
.RST(RST),
.LOAD(LOAD),
.Mult_out(Mult_out));
parameter ClockPeriod = 50;
initial CLK = 0;
always #(ClockPeriod/2) CLK = ~CLK;
initial begin
LOAD = 0; RST = 0;
a = 4'b1000; b = 4'b1001;
@(posedge CLK) RST = 1;LOAD = 0;
@(posedge CLK) LOAD = 1; RST = 0;
@(posedge CLK) LOAD =0;
#300 $finish;
end
endmodule

Uday A Korat | SAN DIEGO STATE UNIVERSITY

Waveform:

Uday A Korat | SAN DIEGO STATE UNIVERSITY

Question: 2 Fixed Point Adder


Verilog Code:

Top Module:

`timescale 1ns / 1ns


`define WIO1 (WIO >= 2)? (WIO+frc_len-2) : frc_len
`define Max_len ((int_len+frc_len-2)>= (WIO+frc_len-1)) ? (int_len+frc_len-2) : (WIO+frc_len-1)
`define trun_size (WIO < int_len)? ((int_len+frc_len-1)-(WIO+frc_len-1)) : 1
module FixedPoint_Adder #(parameter WI1 = 3, //INPUT-1 integer length
WF1 = 4, //INPUT-1 fraction length
WI2 = 4, //INPUT-2 integer length
WF2 = 3, //INPUT-2 fraction length
WIO = (WI1>WI2)? WI1+1:WI2+1, //OUTPUT integer length
WFO = (WF1>WF2)? WF1:WF2) //OUTPUT fraction length
(input signed [WI1+WF1-1:0] in1,
input signed [WI2+WF2-1:0] in2,
output reg overFlow,
output reg signed [WIO+WFO-1:0] FixedPoint_Add_Out);
parameter int_len = (WI1>WI2)? WI1:WI2; //width for integer part of sum
parameter frc_len = (WF1>WF2)? WF1:WF2;// width for fraction part of sum
reg [int_len+frc_len-1:0] reg_in1; //register for INPUT1 = IN1
reg [int_len+frc_len-1:0] reg_in2; //register for INPUT2 = IN2
reg [int_len+frc_len-1:frc_len] int_in1; //register for Integer part of IN1
reg [int_len+frc_len-1:frc_len] int_in2; // register for Integer part of IN2
reg [frc_len-1:0] frc_in1; //register for Fraction part of IN1
reg [frc_len-1:0] frc_in2; //register for Fraction part of IN2
//reg [(`trun_size)-1:0] reg_trun;
//reg [(`trun_size)-1:0] reg_sign;
wire [int_len+frc_len:0] tmp; // wired connection of SUM
reg sign_bit;
reg [WIO-1:0] int_out; // Integer register for output SUM
reg [WFO-1:0] frc_out; // Fraction part register for output SUM
//---------------------------------------------------------------------------//
//ADJUSTING NUMBERS TO MAKE EQUAL RADIX POINT PLACE
//--------------------------------------------------------------------------//
//INTEGER adjustment

Uday A Korat | SAN DIEGO STATE UNIVERSITY

always @* begin
if (WI1 <= WI2) begin
int_in1 = {{(WI2-WI1){in1[WI1+WF1-1]}}, in1[WI1+WF1-1:WF1]};
int_in2 = in2[WI2+WF2-1:WF2];
end
else begin
int_in2 = {{(WI1-WI2){in2[WI2+WF2-1]}}, in2[WI2+WF2-1:WF2]};
int_in1 = in1[WI1+WF1-1:WF1];
end
end
//--------------------------------------------------------------------------//
//FRACTION adjustment
always @* begin
if (WF1 <= WF2) begin
frc_in1 = { in1[WF1-1:0], {(WF2-WF1){1'b0}}};
frc_in2 = in2[WF2-1:0];
end
else begin
frc_in2 = {in2[WF2-1:0], {(WF1-WF2){1'b0}}};
frc_in1 = in1[WF1-1:0];
end
end
//--------------------------------------------------------------------------//
//new adjusted NUMBERS
always @* begin
reg_in1 = {int_in1 , frc_in1};
reg_in2 = {int_in2 , frc_in2};
end
//-------------------------------------------------------// ADDITION of bit adjusted two input
assign tmp = reg_in1 + reg_in2;
//----------------------------------------------------------------------//
//adjust bits for OUTPUT_FRACTION as user define output fraction bitwidth
//padding with zero or truncation from least significant bits
always @* begin
if (WFO >= frc_len) begin
frc_out = {tmp[frc_len-1:0], {(WFO-frc_len){1'b0}}};
end

Uday A Korat | SAN DIEGO STATE UNIVERSITY

else begin //(WFO<frc_len)


frc_out = tmp[frc_len-1:frc_len-WFO];
end
end
//--------------------------------------------------------------------//
// signbit of OutPut
always @* begin
if ((in1[WI1+WF1-1] == in2[WI2+WF2-1])) begin
sign_bit = tmp[int_len+frc_len];
end
else begin
sign_bit = tmp[int_len+frc_len-1];
end
end
//--------------------------------------------------------------------//
//OUTPUT_INTEGER SignBit Padding , Truncation and Overflow conditions
always @* begin
if (WIO >= int_len) begin
if ((in1[WI1+WF1-1] == in2[WI2+WF2-1])) begin
int_out = {{(WIO-int_len){sign_bit}} , tmp[int_len+frc_len-1:frc_len] };
if (int_out[WIO-1] == in1[WI1+WF1-1]) begin// overflow checking for corner case
overFlow = 1'b0;
end
else begin
overFlow = 1'b1;
end
end
else begin
int_out = {{(WIO-int_len){sign_bit}} , tmp[int_len+frc_len-1:frc_len] };
overFlow = 1'b0;
end
end
else begin // (WIO<int_len)
if (WIO == 1) begin
int_out = {sign_bit}; //Signbit only for integer part if WIO = 1
end
else begin

Uday A Korat | SAN DIEGO STATE UNIVERSITY

int_out = {sign_bit , tmp[`WIO1:frc_len]};


end
end
end
//-----------------------------------------------------------------------//
//overFlow
// comparison of truncated bit and sign bit to check error in output and
// generate overflow
always @* begin
if(WIO < int_len) begin
if ( tmp[`Max_len: WIO+frc_len-1] == ({(`trun_size){tmp[int_len+frc_len-1]}})) begin
overFlow = 1'b0;
end
else begin
overFlow = 1'b1;
end
end
end
//------------------------------------------------------------------//
// Final Answer with truncation and adjustment
always @* begin
FixedPoint_Add_Out <= {int_out,frc_out};
end
endmodule

Uday A Korat | SAN DIEGO STATE UNIVERSITY

Test Bench:

`timescale 1ns / 1ns


module tb_FixedPoint_Adder;
//Inputs
reg [6:0] in1;
reg [6:0] in2;
// Outputs
wire [9:0] Out1;
wire [6:0] Out2;
wire [3:0]Out3;
wire overFlow1;
wire overFlow2;
wire overFlow3;
//Real Number Presentation
real in1_real, in2_real;
real out1_real, out2_real, out3_real;
real Floatout1, Floatout2, Floatout3;
//===== Function Definition
function real FixedToFloat;
input [63:0] in;
input integer WI;
input integer WF;
integer i;
real retVal;
begin
retVal = 0;
for (i = 0; i < WI+WF-1; i = i+1) begin
if (in[i] == 1'b1) begin
retVal = retVal + (2.0**(i-WF));
end
end
FixedToFloat = retVal - (in[WI+WF-1] * (2.0**(WI-1)));
end
endfunction
// Instantiate the Unit Under Test (UUT)
//WIO>max(WI1,WI2) , WFO>max(WF1,WF2)
FixedPoint_Adder #(.WI1(3),
.WF1(4),
.WI2(4),
.WF2(3),
.WIO(5),
.WFO(5))

Uday A Korat | SAN DIEGO STATE UNIVERSITY

uut01 (.in1(in1), .in2(in2), .overFlow(overFlow1), .FixedPoint_Add_Out(Out1));//Output1


//WIO=max(WI1,WI2), WFO < max(WF1,WF2)
FixedPoint_Adder #(.WI1(3),
.WF1(4),
.WI2(4),
.WF2(3),
.WIO(4),
.WFO(3))
uut02 (.in1(in1), .in2(in2), .overFlow(overFlow2), .FixedPoint_Add_Out(Out2));
//WIO<min(WI1,WI2), WFO <min(WF1,WF2)
FixedPoint_Adder #(.WI1(3),
.WF1(4),
.WI2(4),
.WF2(3),
.WIO(2),
.WFO(2))
uut03 (.in1(in1), .in2(in2), .overFlow(overFlow3), .FixedPoint_Add_Out(Out3));
initial begin
// Initialize Inputs
in1 = 7'b011_1111;
in2 = 7'b0111_111;
// Wait 100 ns for global reset to finish
#100;
in1 = 7'b111_0000;
in2 = 7'b0110_000;
// Wait 100 ns for global reset to finish
#100;
in1 = 7'b100_0000;
in2 = 7'b0011_000;
// Wait 100 ns for global
#100;
$finish;
end
always @ in1 in1_real = FixedToFloat(in1, 3, 4); //convert in1 to real
always @ in2 in2_real = FixedToFloat(in2, 4, 3); //convert in2 to real
always @ Out1 out1_real = FixedToFloat(Out1, 5, 5);//convert Out2 to real
always @ (in1_real or in2_real) Floatout1 = in1_real + in2_real;//Ideal Output
always @ Out2 out2_real = FixedToFloat(Out2, 4, 3);//convert Out2 to real
always @ (in1_real or in2_real) Floatout2 = in1_real + in2_real;//Ideal Output
always @ Out3 out3_real = FixedToFloat(Out3, 2, 2);//convert Out3 to real
always @ (in1_real or in2_real) Floatout3 = in1_real + in2_real;//Ideal Output
endmodule

Uday A Korat | SAN DIEGO STATE UNIVERSITY

Wave Form:

Uday A Korat | SAN DIEGO STATE UNIVERSITY

You might also like