Saturday, 12 April 2014

CHAPTER 16



Computer ArithmeticandVerilog HDL Fundamentals
Chapter 16
Additional Floating-Point Topics
Verilog Code Figures











PS: IF YOU NEED ANY BOOK,NOTES,PROJECT,LAB EXPERIMENT ANYTHING RELATED TO ENGINEERING JUST REPLY ME ON THE COMMENT SECTION




















Page 657, Figure 16.7

//behavioral floating-point adder-based rounding
module mem_flp_add_based_round (fract_a, rslt);

//list inputs and outputs
input [5:0] fract_a;
output [4:0] rslt;

//list wire and reg
wire [5:0] fract_a;
reg [4:0] rslt;

//define memory size
//mem_round is an array of 64 5-bit registers
reg [4:0] mem_round [0:63];

//define memory contents
//load mem_round from file fract.round
initial
begin
      $readmemb ("fract.round", mem_round);
end

//use the fraction fract_a to access the memory
always @ (fract_a)
begin
      rslt = mem_round [fract_a];
end

endmodule


//test bench for floating-point adder-based rounding
module mem_flp_add_based_round_tb;

//inputs are reg and outputs are wire for test benches
reg [5:0] fract_a;
wire [4:0] rslt;

//display variables
initial
$monitor ("fraction = %b, rounded result = %b",
               fract_a, rslt);

//apply input vectors for fraction
initial
begin
      #0       fract_a = 6'b00000_1;
      #10      fract_a = 6'b00000_0;
      #10      fract_a = 6'b00110_0;
      #10      fract_a = 6'b00110_1;
      #10      fract_a = 6'b01011_0;
      #10      fract_a = 6'b01011_1;
      #10      fract_a = 6'b01111_0;
      #10      fract_a = 6'b01111_1;
      #10      fract_a = 6'b10011_0;
      #10      fract_a = 6'b10011_1;
      #10      fract_a = 6'b10111_0;
      #10      fract_a = 6'b10111_1;
      #10      fract_a = 6'b11011_0;
      #10      fract_a = 6'b11011_1;
      #10      fract_a = 6'b11110_0;
      #10      fract_a = 6'b11110_1;

      #10      $stop;

end

//instantiate the module into the test bench
mem_flp_add_based_round inst1 (
      .fract_a(fract_a),
      .rslt(rslt)
      );

endmodule












































Page 665, Figure 16.14

//dataflow for floating-point adder-based rounding
module adder_based_round_df (x, rslt);

input [1:6] x;
output [4:0] rslt;

//define internal wires
wire        net1, net2, net3, net4, net5, net6, net7,
            net8, net9, net10, net11, net12, net13,
            net14, net15, net16, net17, net18, net19;

//define logic for rslt[4]
assign      net1 = x[2] & x[3] & x[4] & x[5] & x[6],
            rslt[4] = x[1] | net1;

//define logic for rslt[3]
assign      net2 = x[1] & x[2],
            net3 = x[2] & ~x[3],
            net4 = x[2] & ~x[5],
            net5 = x[2] & ~x[6],
            net6 = x[2] & ~x[4],
            net7 = ~x[2] & x[3] & x[4] & x[5] & x[6],
            rslt[3] = net2 | net3 | net4 | net5 | net6 | net7;

//define logic for rslt[2]
assign      net8 = x[3] & ~x[4],
            net9 = x[3] & ~x[6],
            net10 = x[3] & ~x[5],
            net11 = x[1] & x[2] & x[3],
            net12 = ~x[3] & x[4] & x[5] & x[6],
            rslt[2] = net8 | net9 | net10 | net11 | net12;

//define logic for rslt[1]
assign      net13 = x[4] & ~x[5],
            net14 = x[4] & ~x[6],
            net15 = ~x[4] & x[5] & x[6],
            net16 = x[1] & x[2] & x[3] & x[4],
            rslt[1] = net13 | net14 | net15 | net16;

//define logic for rslt[0]
assign      net17 = ~x[5] & x[6],
            net18 = x[5] & ~x[6],
            net19 = x[1] & x[2] & x[3] & x[4] & x[5],
            rslt[0] = net17 | net18 | net19;

endmodule


//test bench for floating-point adder-based rounding
module adder_based_round_df_tb;

reg [1:6] x;
wire [4:0] rslt;

//display variables
initial
$monitor ("fraction = %b, rounded result = %b", x, rslt);

initial           //apply input vectors for fraction
begin
      #0       x = 6'b00000_1;
      #10      x = 6'b00000_0;
      #10      x = 6'b00110_0;
      #10      x = 6'b00110_1;
      #10      x = 6'b01011_0;
      #10      x = 6'b01011_1;
      #10      x = 6'b01111_0;
      #10      x = 6'b01111_1;
      #10      x = 6'b10011_0;
      #10      x = 6'b10011_1;
      #10      x = 6'b10111_0;
      #10      x = 6'b10111_1;
      #10      x = 6'b11011_0;
      #10      x = 6'b11011_1;
      #10      x = 6'b11110_0;
      #10      x = 6'b11110_1;

      #10      $stop;
end

//instantiate the module into the test bench
adder_based_round_df inst1 (
      .x(x),
      .rslt(rslt)
      );

endmodule
































Page 669  Figure 16.19

//behavioral adder-based rounding
module adder_based_round_bh2 (flp_a, flp_b, sign, exponent,
                                 exp_unbiased, sum);

input [15:0] flp_a, flp_b;
output [10:3] sum;
output sign;
output [3:0] exponent, exp_unbiased;

//variables used in an always block are declared as registers
reg sign_a, sign_b;
reg [3:0] exp_a, exp_b;
reg [3:0] exp_a_bias, exp_b_bias;
reg [10:3] fract_a, fract_b;
reg [2:0] guard_a, guard_b;
reg [3:0] ctr_align;
reg [10:3] sum;
reg sign;
reg [3:0] exponent, exp_unbiased;
reg cout;

always @ (flp_a or flp_b)
begin
      sign_a = flp_a[15];
      sign_b = flp_b[15];

      exp_a = flp_a[14:11];
      exp_b = flp_b[14:11];

      fract_a = flp_a[10:3];
      fract_b = flp_b[10:3];

      guard_a = flp_a[2:0];
      guard_b = flp_b[2:0];

//bias exponents
      exp_a_bias = exp_a + 4'b0111;
      exp_b_bias = exp_b + 4'b0111;

//align fractions
      if (exp_a_bias < exp_b_bias)
         ctr_align = exp_b_bias - exp_a_bias;

         while (ctr_align)
            begin
               {fract_a, guard_a} = {fract_a, guard_a} >> 1;
               exp_a_bias = exp_a_bias + 1;
               ctr_align = ctr_align - 1;
            end









      if (exp_b_bias < exp_a_bias)
         ctr_align = exp_a_bias - exp_b_bias;

         while (ctr_align)
            begin
               {fract_b, guard_b} = {fract_b, guard_b} >> 1;
               exp_b_bias = exp_b_bias + 1;
               ctr_align = ctr_align - 1;
            end

//add fractions
      {cout, sum[10:3]} = fract_a[10:3] + fract_b[10:3];

//execute adder-based rounding
      if ((guard_a[2] | guard_b[2]) == 1)
         sum[10:3] = sum[10:3] + 8'b0000_0001;

//normalize result
      if (cout == 1)
         begin
            {cout, sum[10:3]} = {cout, sum[10:3]} >> 1;
            exp_b_bias = exp_b_bias + 1;
         end

      sign = sign_a;
      exponent = exp_b_bias;
      exp_unbiased = exp_b_bias - 4'b0111;

end

endmodule


//test bench for behavioral adder-based rounding
module adder_based_round_bh2_tb;

reg [15:0] flp_a, flp_b;
wire [10:3] sum;
wire sign;
wire [3:0] exponent, exp_unbiased;

//display variables
initial
$monitor ("sign=%b, exp_biased=%b, exp_unbiased=%b, sum=%b",
               sign, exponent, exp_unbiased, sum[10:3]);

//apply input vectors
initial
begin
            //+12 + +35 = +47
            //          s --e- ------f------
      #0    flp_a = 16'b0_0100_1100_0000_000;
            flp_b = 16'b0_0110_1000_1100_000;


            //+26 + +20 = +46
            //          s --e- ------f------
      #10   flp_a = 16'b0_0101_1101_0000_000;
            flp_b = 16'b0_0101_1010_0000_000;


            //+26.5 + +4.375 = +30.875
            //          s --e- ------f------
      #10   flp_a = 16'b0_0101_1101_0100_000;
            flp_b = 16'b0_0011_1000_1100_000;

          //+11 + +34 = +45
            //          s --e- ------f------
      #10   flp_a = 16'b0_0100_1011_0000_000;
            flp_b = 16'b0_0110_1000_1000_000;


            //+58.2500 + +9.4375 = +67.6875
            //          s --e- ------f------
      #10   flp_a = 16'b0_0110_1110_1001_000;
            flp_b = 16'b0_0100_1001_0111_000;


            //+50.2500 + +9.4375 = +59.6875
            //          s --e- ------f------
      #10   flp_a = 16'b0_0110_1100_1001_000;
            flp_b = 16'b0_0100_1001_0111_000;


            //+51.2500 + +11.0625 = +62.3125
            //          s --e- ------f------
      #10   flp_a = 16'b0_0110_1100_1101_000;
            flp_b = 16'b0_0100_1011_0001_000;


            //+12.75000 + +4.34375 = +17.09375
            //          s --e- ------f------
      #10   flp_a = 16'b0_0100_1100_1100_000;
            flp_b = 16'b0_0011_1000_1011_000;

      #10   $stop;

end


//instantiate the module into the test bench
adder_based_round_bh2 inst1 (
      .flp_a(flp_a),
      .flp_b(flp_b),
      .sum(sum),
      .sign(sign),
      .exponent(exponent),
      .exp_unbiased(exp_unbiased)
      );

endmodule








Page 675, Figure 16.24

//behavioral truncation, adder-based, von neumann rounding
module trunc_add_von_round (flp_a, flp_b, sign, exponent,
               exp_unbiased, sum, sum_trunc, sum_add, sum_von);

input [15:0] flp_a, flp_b;
output [10:3] sum, sum_trunc, sum_add, sum_von;
output sign;
output [3:0] exponent, exp_unbiased;

//variables used in an always block are declared as registers
reg sign_a, sign_b;
reg [3:0] exp_a, exp_b;
reg [3:0] exp_a_bias, exp_b_bias;
reg [10:3] fract_a, fract_b;
reg [2:0] guard_a, guard_b;
reg [3:0] ctr_align;
reg [10:3] sum, sum_trunc, sum_add, sum_von;
reg sign;
reg [3:0] exponent, exp_unbiased;
reg cout;

always @ (flp_a or flp_b)
begin
      sign_a = flp_a[15];
      sign_b = flp_b[15];

      exp_a = flp_a[14:11];
      exp_b = flp_b[14:11];

      fract_a = flp_a[10:3];
      fract_b = flp_b[10:3];

      guard_a = flp_a[2:0];
      guard_b = flp_b[2:0];

//bias exponents
      exp_a_bias = exp_a + 4'b0111;
      exp_b_bias = exp_b + 4'b0111;

     if (exp_a_bias < exp_b_bias)                                                  //align fractions
         ctr_align = exp_b_bias - exp_a_bias;

         while (ctr_align)
            begin
               {fract_a, guard_a} = {fract_a, guard_a} >> 1;
               exp_a_bias = exp_a_bias + 1;
               ctr_align = ctr_align - 1;
            end








      if (exp_b_bias < exp_a_bias)
         ctr_align = exp_a_bias - exp_b_bias;

         while (ctr_align)
            begin
               {fract_b, guard_b} = {fract_b, guard_b} >> 1;
               exp_b_bias = exp_b_bias + 1;
               ctr_align = ctr_align - 1;
            end

//add fractions
      {cout, sum[10:3]} = fract_a[10:3] + fract_b[10:3];

      if (cout == 1)                //postnormalize result
         begin
            {cout, sum[10:3]} = {cout, sum[10:3]} >> 1;
            exp_b_bias = exp_b_bias + 1;
         end

//execute truncation rounding
      sum_trunc = sum[10:3];

//execute adder-based rounding
      if ((guard_a[2] == 1) | (guard_b[2] == 1))
         sum_add = sum[10:3] + 8'b0000_0001;
      else
         sum_add = sum[10:3];

//execute von neumann rounding
      if ((guard_a != 3'b000) | (guard_b != 3'b000))
         sum_von = {sum[10:4], 1'b1};
      else
         sum_von = sum[10:3];

      sign = sign_a;
      exponent = exp_b_bias;
      exp_unbiased = exp_b_bias - 4'b0111;

end

endmodule


//test bench for truncation, adder-based, von neumann rounding
module trunc_add_von_round_tb;

reg [15:0] flp_a, flp_b;
wire [10:3] sum, sum_trunc, sum_add, sum_von;
wire sign;
wire [3:0] exponent, exp_unbiased;

//display variables
initial             
$monitor ("sign=%b, exp_unbiased=%b, sum_trunc=%b,
               sum_add=%b, sum_von=%b",
               sign, exp_unbiased, sum_trunc, sum_add, sum_von);




//apply input vectors
initial             
begin
            //(+63.500) + (+7.875) = +71.375
            //          s --e- ------f------
      #0    flp_a = 16'b0_0110_1111_1110_000;
            flp_b = 16'b0_0011_1111_1100_000;

            //(+35) + (+12) = +47
            //          s --e- ------f------
      #10   flp_a = 16'b0_0110_1000_1100_000;
            flp_b = 16'b0_0100_1100_0000_000;

          //(+26.5) + (+4.375) = +30.875
            //          s --e- ------f------
      #10   flp_a = 16'b0_0101_1101_0100_000;
            flp_b = 16'b0_0011_1000_1100_000;

            //(+58.2500) + (+9.4375) = +67.6875
            //          s --e- ------f------
      #10   flp_a = 16'b0_0110_1110_1001_000;
            flp_b = 16'b0_0100_1001_0111_000;

            //(+50.2500) + (+9.4375) = +59.6875
            //          s --e- ------f------
      #10   flp_a = 16'b0_0110_1100_1001_000;
            flp_b = 16'b0_0100_1001_0111_000;

            //(+12.75000) + (+4.34375) = +17.09375
            //          s --e- ------f------
      #10   flp_a = 16'b0_0100_1100_1100_000;
            flp_b = 16'b0_0011_1000_1011_000;

            //(+51.2500) + (+11.0625) = +62.3125
            //          s --e- ------f------
      #10   flp_a = 16'b0_0110_1100_1101_000;
            flp_b = 16'b0_0100_1011_0001_000;

            //(+42.250) + (+9.875) = +52.125
            //          s --e- ------f------
      #10   flp_a = 16'b0_0110_1010_1001_000;
            flp_b = 16'b0_0100_1001_0111_000;

      #10   $stop;
end

//instantiate the module into the test bench
trunc_add_von_round inst1 (
      .flp_a(flp_a),
      .flp_b(flp_b),
      .sum(sum),
      .sum_trunc(sum_trunc),
      .sum_add(sum_add),
      .sum_von(sum_von),
      .sign(sign),
      .exponent(exponent),
      .exp_unbiased(exp_unbiased)
      );


endmodule

No comments:

Post a Comment