Saturday, 12 April 2014

chapter 11



Computer Arithmetic
and
Verilog HDL Fundamentals

Chapter 11

Decimal Division

Verilog Code Figures


































Page 532, Figure 11.2

//mixed-design for bcd restoring division
module div_bcd (a, b, start, rslt, cout_quot);

input [7:0] a;
input [3:0] b;
input start;
output [7:0] rslt;
output cout_quot;

wire [3:0] b_bar;

//define internal registers
reg [3:0] b_neg;
reg [7:0] rslt;
reg [3:0] count;
reg [3:0] quot;
reg cout_quot;

assign b_bar = ~b;

always @ (b_bar)
      b_neg = b_bar + 1;

always @ (posedge start)
begin
      rslt = a;
      count = 4'b0100;

      if ((a!=0) && (b!=0))
         while (count)
            begin
               rslt = rslt << 1;
               rslt = {(rslt[7:4] + b_neg), rslt[3:0]};
                  if (rslt[7] == 1)       //restore
                     begin
                        rslt = {(rslt[7:4]+b), rslt[3:1], 1'b0};
                        count = count - 1;
                     end

                  else                    //no restore
                     begin
                        rslt = {rslt[7:1], 1'b1};
                        count = count - 1;
                     end
            end

      if (rslt[3:0] > 4'b1001)      //convert to bcd
         {cout_quot, rslt[3:0]} = rslt[3:0] + 4'b0110;

      else
         cout_quot = 1'b0;
end

endmodule



//test bench for bcd restoring division
module div_bcd_tb;

reg [7:0] a;
reg [3:0] b;
reg start;
wire [7:0] rslt;
wire cout_quot;

//display variables
initial
$monitor ("a=%b, b=%b, quot_tens=%b, quot_units=%b, rem=%b",
            a, b, {{3{1'b0}}, cout_quot}, rslt[3:0], rslt[7:4]);

//apply input vectors
initial
begin
      #0    start = 1'b0;

            //60 / 7; quot = 8, rem = 4
            a = 8'b0011_1100;                b = 4'b0111;
      #10   start = 1'b1;
      #10   start = 1'b0;

            //13 / 5; quot = 2, rem = 3
      #10   a = 8'b0000_1101;                b = 4'b0101;
      #10   start = 1'b1;
      #10   start = 1'b0;

            //60 / 7; quot = 8, rem = 4
      #10   a = 8'b0011_1100;                b = 4'b0111;
      #10   start = 1'b1;
      #10   start = 1'b0;

            //82 / 6; quot = 13, rem = 4
      #10   a = 8'b0101_0010;                b = 4'b0110;
      #10   start = 1'b1;
      #10   start = 1'b0;

            //56 / 7; quot = 8, rem = 0
      #10   a = 8'b0011_1000;                b = 4'b0111;
      #10   start = 1'b1;
      #10   start = 1'b0;

            //100 / 7; quot = 14, rem = 2
      #10   a = 8'b0110_0100;                b = 4'b0111;
      #10   start = 1'b1;
      #10   start = 1'b0;

          //110 / 7; quot = 15, rem = 5
      #10   a = 8'b0110_1110;                b = 4'b0111;
      #10   start = 1'b1;
      #10   start = 1'b0;

            //99 / 9; quot = 11, rem = 0
      #10   a = 8'b0110_0011;                b = 4'b1001;
      #10   start = 1'b1;
      #10   start = 1'b0;


            //99 / 8; quot = 12, rem = 3
      #10   a = 8'b0110_0011;                b = 4'b1000;
      #10   start = 1'b1;
      #10   start = 1'b0;

            //52 / 5; quot = 10, rem = 2
      #10   a = 8'b0011_0100;                b = 4'b0101;
      #10   start = 1'b1;
      #10   start = 1'b0;

            //0 / 5; quot = 0, rem = 0; invalid dividend
      #10   a = 8'b0000_0000;                b = 4'b0101;
      #10   start = 1'b1;
      #10   start = 1'b0;

            //86 / 5; overflow; results are indeterminate
      #10   a = 8'b0101_0110;                b = 4'b0101;
      #10   start = 1'b1;
      #10   start = 1'b0;

      #10   $stop;
end

//instantiate the module into the test bench
div_bcd inst1 (
      .a(a),
      .b(b),
      .start(start),
      .rslt(rslt),
      .cout_quot(cout_quot)
      );
endmodule


























Page 541, Figure 11.8

//mixed-design bcd restoring division using a multiplexor
module div_bcd_mux (a, b, start, rslt, cout_quot);

input [7:0] a;                //dividend
input [3:0] b;                //divisor
input start;
output [7:0] rslt;            //rslt[7:4] is rem; rslt[3:0] is quot
output cout_quot;
wire [3:0] b_bar;

reg [3:0] b_neg;              //define internal registers
reg [7:0] rslt;
reg [3:0] count;
reg [4:0] sum;
reg cout, cout_quot;

assign b_bar = ~b;            //1s complement of divisor
always @ (b_bar)
      b_neg = b_bar + 1;      //2s complement of divisor

always @ (posedge start)
begin
      rslt = a;
      count = 4'b0100;

         if ((a!=0) && (b!=0))
            while (count)
            begin
               rslt = rslt << 1;
               sum = rslt[7:4] + b_neg;
               cout = sum[4];

               if (cout == 0)
                  begin
                     rslt[0] = cout;            //q0 = cout
                     rslt[7:4] = rslt[7:4];
                     count = count -1;
                  end

               else
                  begin
                     rslt[0] = cout;            //q0 = cout
                     rslt[7:4] = sum[3:0];
                     count = count - 1;
                  end
            end

   if (rslt[3:0] > 4'b1001)
      {cout_quot, rslt[3:0]} = rslt[3:0] + 4'b0110;

   else
      cout_quot = 1'b0;

end

endmodule

//test bench for restoring division
module div_bcd_mux_tb;

reg [7:0] a;
reg [3:0] b;
reg start;
wire [7:0] rslt;
wire cout_quot;

//display variables
initial
$monitor ("a=%b, b=%b, quot_tens=%b, quot_units=%b, rem=%b",
            a, b, {{3{1'b0}}, cout_quot}, rslt[3:0], rslt[7:4]);

//apply input vectors
initial
begin
      #0    start = 1'b0;

            //13 / 5; quot = 2, rem = 3
            a = 8'b0000_1101;                b = 4'b0101;
      #10   start = 1'b1;
      #10   start = 1'b0;

            //60 / 7; quot = 8, rem = 4
      #10   a = 8'b0011_1100;                b = 4'b0111;
      #10   start = 1'b1;
      #10   start = 1'b0;

          //82 / 6; quot = 13, rem = 4
      #10   a = 8'b0101_0010;                b = 4'b0110;
      #10   start = 1'b1;
      #10   start = 1'b0;

            //56 / 7; quot = 8, rem = 0
      #10   a = 8'b0011_1000;                b = 4'b0111;
      #10   start = 1'b1;
      #10   start = 1'b0;

            //100 / 7; quot = 14, rem = 2
      #10   a = 8'b0110_0100;                b = 4'b0111;
      #10   start = 1'b1;
      #10   start = 1'b0;

            //110 / 7; quot = 15, rem = 5
      #10   a = 8'b0110_1110;                b = 4'b0111;
      #10   start = 1'b1;
      #10   start = 1'b0;

            //99 / 9; quot = 11, rem = 0
      #10   a = 8'b0110_0011;                b = 4'b1001;
      #10   start = 1'b1;
      #10   start = 1'b0;

            //0 / 5; quot = 0, rem = 0; invalid dividend
      #10   a = 8'b0000_0000;                b = 4'b0101;
      #10   start = 1'b1;
      #10   start = 1'b0;


            //86 / 5; overflow; results are indeterminate
      #10   a = 8'b0101_0110;                b = 4'b0101;
      #10   start = 1'b1;
      #10   start = 1'b0;

      #10   $stop;
end

//instantiate the module into the test bench
div_bcd_mux inst1 (
      .a(a),
      .b(b),
      .start(start),
      .rslt(rslt),
      .cout_quot(cout_quot)
      );

endmodule



No comments:

Post a Comment