Vous êtes sur la page 1sur 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

Vous aimerez peut-être aussi