Saturday, 12 April 2014








Computer Arithmetic
and
Verilog HDL Fundamentals

Chapter 5

Fixed-Point Subtraction

Verilog Code Figures


































Page 245, Figure 5.2

//structural 8-bit ripple-carry adder/subtractor
module adder_subt_ripple8 (a, b, m, rslt, cout, ovfl);

input [7:0] a, b;
input m;
output [7:0] rslt, cout;
output ovfl;

//define internal nets
wire        net1, net3, net5, net7,
         net9, net11, net13, net15;

//instantiate the xor and the full adder for FA0
xor inst1 (net1, b[0], m);

full_adder inst2 (
      .a(a[0]),
      .b(net1),
      .cin(m),
      .sum(rslt[0]),
      .cout(cout[0])
      );

//instantiate the xor and the full adder for FA1
xor inst3 (net3, b[1], m);

full_adder inst4 (
      .a(a[1]),
      .b(net3),
      .cin(cout[0]),
      .sum(rslt[1]),
      .cout(cout[1])
      );

//instantiate the xor and the full adder for FA2
xor inst5 (net5, b[2], m);

full_adder inst6 (
   .a(a[2]),
   .b(net5),
   .cin(cout[1]),
   .sum(rslt[2]),
   .cout(cout[2])
   );

//instantiate the xor and the full adder for FA3
xor inst7 (net7, b[3], m);

full_adder inst8 (
   .a(a[3]),
   .b(net7),
   .cin(cout[2]),
   .sum(rslt[3]),
   .cout(cout[3])
   );



//instantiate the xor and the full adder for FA4
xor inst9 (net9, b[4], m);

full_adder inst10 (
      .a(a[4]),
      .b(net9),
      .cin(cout[3]),
      .sum(rslt[4]),
      .cout(cout[4])
      );

//instantiate the xor and the full adder for FA5
xor inst11 (net11, b[5], m);

full_adder inst12 (
      .a(a[5]),
      .b(net11),
      .cin(cout[4]),
      .sum(rslt[5]),
      .cout(cout[5])
      );

//instantiate the xor and the full adder for FA6
xor inst13 (net13, b[6], m);

full_adder inst14 (
      .a(a[6]),
      .b(net13),
      .cin(cout[5]),
      .sum(rslt[6]),
      .cout(cout[6])
      );

//instantiate the xor and the full adder for FA7
xor inst15 (net15, b[7], m);

full_adder inst16 (
      .a(a[7]),
      .b(net15),
      .cin(cout[6]),
      .sum(rslt[7]),
      .cout(cout[7])
      );

//instantiate the xor gate to detect overflow
xor inst17 (ovfl, cout[6], cout[7]);

endmodule












//test bench for structural adder-subtractor
module adder_subt_ripple8_tb;

reg [7:0] a, b;
reg m;
wire [7:0] rslt, cout;
wire  ovfl;

initial              //display variables
$monitor ("a=%b, b=%b, m=%b, rslt=%b, ovfl=%b",
               a, b, m, rslt, ovfl);

initial              //apply input vectors
begin
//addition
      #0    a = 8'b0000_0000;                b = 8'b0000_0001;                               m = 1'b0;
      #10      a = 8'b0010_1101;                b = 8'b1100_0101;                            m = 1'b0;
      #10      a = 8'b0000_0110;                b = 8'b0000_0001;                            m = 1'b0;
      #10      a = 8'b0000_0101;                b = 8'b0011_0001;                            m = 1'b0;
     #10      a = 8'b1000_0000;                b = 8'b0101_1100;                            m = 1'b0;
      #10      a = 8'b1110_1101;                b = 8'b0101_0101;                            m = 1'b0;
      #10      a = 8'b1111_1111;                b = 8'b1111_1111;                            m = 1'b0;
      #10      a = 8'b1111_1111;                b = 8'b1111_0001;                            m = 1'b0;

//subtraction
      #10      a = 8'b0000_0000;                b = 8'b0000_0001;                            m = 1'b1;
      #10      a = 8'b0010_1101;                b = 8'b0000_0101;                            m = 1'b1;
      #10      a = 8'b0000_0110;                b = 8'b0000_0001;                            m = 1'b1;
      #10      a = 8'b0001_0101;                b = 8'b0011_0001;                            m = 1'b1;
      #10      a = 8'b1000_0000;                b = 8'b1001_1100;                            m = 1'b1;
      #10      a = 8'b1110_1101;                b = 8'b0101_0101;                            m = 1'b1;
      #10      a = 8'b1111_1111;                b = 8'b1111_1111;                            m = 1'b1;
      #10      a = 8'b1110_1111;                b = 8'b1111_0001;                            m = 1'b1;
  
//overflow
      #10      a = 8'b0111_1111;                b = 8'b0101_0101;                            m = 1'b0;
      #10      a = 8'b1010_1101;                b = 8'b1011_0101;                            m = 1'b0;
      #10      a = 8'b0110_0110;                b = 8'b1100_0001;                            m = 1'b1;
      #10      a = 8'b1000_0101;                b = 8'b0010_0001;                            m = 1'b1;

      #10      $stop;
end

//instantiate the module into the test bench
adder_subt_ripple8 inst1 (
      .a(a),
      .b(b),
      .m(m),
      .rslt(rslt),
      .cout(cout),
      .ovfl(ovfl)
      );
endmodule

















































Page 253, Figure 5.8

//dataflow and built-in primitives for an
//8-bit 2s complementer for add and subtract
module twos_compl_add_sub_8 (b, mode, rslt);

input [7:0] b;
input mode;
output [7:0] rslt;

assign rslt[0] = b[0];

and      inst1  (net1, b[0], mode);
xor      inst2  (rslt[1], b[1], net1);
or       inst3  (net3, b[1], b[0]);

and      inst4  (net4, net3, mode);
xor      inst5  (rslt[2], b[2], net4);
or       inst6  (net6, b[2], net3);

and      inst7  (net7, net6, mode);
xor      inst8  (rslt[3], b[3], net7);
or       inst9  (net9, b[3], net6);

and      inst10 (net10, net9, mode);
xor      inst11 (rslt[4], b[4], net10);
or       inst12 (net12, b[4], net9);

and      inst13 (net13, net12, mode);
xor      inst14 (rslt[5], b[5], net13);
or       inst15 (net15, b[5], net12);

and      inst16 (net16, net15, mode);
xor      inst17 (rslt[6], b[6], net16);
or       inst18 (net18, b[6], net15);

and      inst19 (net19, net18, mode);
xor      inst20 (rslt[7], b[7], net19);

endmodule




















//test bench for 8-bit 2s complementer for add and sub
module twos_compl_add_sub_8_tb;

reg [7:0] b;
reg mode;
wire [7:0] rslt;

//apply input vectors and display variables
initial
begin: apply_stimulus
      reg [9:0] invect;
      for (invect = 0; invect < 512; invect = invect + 1)
         begin
            {b, mode} = invect [9:0];
            #10 $display ("b = %b, mode = %b, rslt = %b",
                           b, mode, rslt);
         end
end

//instantiate the module into the test bench
twos_compl_add_sub_8 inst1 (
      .b(b),
      .mode(mode),
      .rslt(rslt)
      );

endmodule

































Page 260, Figure 5.13

//structural and built-in primitives for an
//8-bit carry lookahead adder/subtractor
module add_sub_cla8 (a, b, mode, sum_diff, cout, ovfl);

input [7:0] a, b;
input mode;

output [7:0] sum_diff;
output cout, ovfl;

//define internal nets
wire [7:0] rslt;
wire     net3, net5, net6, net7, net8,
         net10, net11, net12, net13, net14,
         net16, net17, net18, net19, net20,
         net23, net24, net25, net26,
         net28, net29, net30, net31, net32,
         net34, net35, net36, net37, net38, net39,
         net41, net42, net43, net44, net45, net46,
         net48, net49;

//instantiate the 2s complementer
twos_compl_add_sub_8 inst1 (
      .b(b),
      .mode(mode),
      .rslt(rslt)
      );

//----------------------------------------------
//instantiate the logic for group 0
//----------------------------------------------
//instantiate the logic for FA0 of group 0
full_adder inst2 (
      .a(a[0]),
      .b(rslt[0]),
      .cin(1'b0),
      .sum(sum_diff[0])
      );

//instantiate the logic for FA1 of group 0
and         inst3 (net3, a[0], rslt[0]); //g0

full_adder inst4 (
      .a(a[1]),
      .b(rslt[1]),
      .cin(net3),
      .sum(sum_diff[1])
      );

//instantiate the logic for FA2 of group 0
and         inst5 (net5, a[1], rslt[1]); //g1
xor         inst6 (net6, a[1], rslt[1]); //p1
and         inst7 (net7, net6, a[0], rslt[0]);
or       inst8 (net8, net5, net7); //g1,p1,g0



full_adder inst9 (
      .a(a[2]),
      .b(rslt[2]),
      .cin(net8),
      .sum(sum_diff[2])
      );

//instantiate the logic for FA3 of group 0
and      inst10 (net10, a[2], rslt[2]); //g2
xor      inst11 (net11, a[2], rslt[2]); //p2
and      inst12 (net12, net11, a[1], rslt[1]); //p2,g1
and      inst13 (net13, net11, net6, a[0], rslt[0]); //p2,p1,g0
or       inst14 (net14, net10, net12, net13);//g2,p2,g1,p2,p1,g0

full_adder inst15 (
      .a(a[3]),
      .b(rslt[3]),
      .cin(net14),
      .sum(sum_diff[3])
      );

//instantiate the logic for the carry from group 0 grp0_cy
and   inst16 (net16, a[3], rslt[3]); //g3
xor   inst17 (net17, a[3], rslt[3]); //p3
and   inst18 (net18, net17, a[2], rslt[2]); //p3,g2
and   inst19 (net19, net17, net11, a[1], rslt[1]); //p3,p2,g1
and   inst20 (net20, net17, net11, net6, a[0], rslt[0]);
                                    //p3,p2,p1,g0
or    inst21 (grp0_cy, net16, net18, net19, net20);
                           //g3,p3,g2,p3,p2,g1,p3,p2,p1,g0

//----------------------------------------------
//instantiate the logic for group 1
//----------------------------------------------
//instantiate the logic for FA4 of group 1
full_adder inst22 (
      .a(a[4]),
      .b(rslt[4]),
      .cin(grp0_cy),
      .sum(sum_diff[4])
      );

//instantiate the logic for FA5 of group 1
and      inst23 (net23, a[4], rslt[4]); //g4
xor      inst24 (net24, a[4], rslt[4]); //p4
and      inst25 (net25, net24, grp0_cy); //p4,grp0_cy
or       inst26 (net26, net23, net25); //g4,p4,grp0_cy

full_adder inst27 (
      .a(a[5]),
      .b(rslt[5]),
      .cin(net26),
      .sum(sum_diff[5])
      );

//instantiate the logic for FA6 of group 1
and      inst28 (net28, a[5], rslt[5]); //g5
xor      inst29 (net29, a[5], rslt[5]); //p5
and      inst30 (net30, net29, a[4], rslt[4]); //p5,g4
and      inst31 (net31, net29, net24, grp0_cy); //p5,p4,grp0_cy
or       inst32 (net32, net28, net30, net31);
                           //g5,p5,g4,p5,p4,grp0_cy
full_adder inst33 (
      .a(a[6]),
      .b(rslt[6]),
      .cin(net32),
      .sum(sum_diff[6])
      );

//instantiate the logic for FA7 of group 1
and      inst34 (net34, a[6], rslt[6]); //g6
xor      inst35 (net35, a[6], rslt[6]); //p6
and      inst36 (net36, net35, a[5], rslt[5]); //p6,g5
and      inst37 (net37, net35, net29, a[4], rslt[4]);
                     //p6,p5,g4
and      inst38 (net38, net35, net29, net24, grp0_cy);
                     //p6,p5,p4,grp0_cy
or       inst39 (net39, net34, net36, net37, net38);
                     //g6,p6,g5,p6,p5,g4,p6,p5,p4,grp0_cy

full_adder inst40 (
      .a(a[7]),
      .b(rslt[7]),
      .cin(net39),
      .sum(sum_diff[7])
      );

//instantiate the logic for the carry from group 1 cout
and      inst41 (net41, a[7], rslt[7]); //g7
xor      inst42 (net42, a[7], rslt[7]); //p7
and      inst43 (net43, net42, a[6], rslt[6]); //p7,g6
and      inst44 (net44, net42, net35, a[5], rslt[5]);
                        //p7,p6,g5
and      inst45 (net45, net42, net35, net29, a[4], rslt[4]);
                        //p7,p6,p5,g4
and      inst46 (net46, net42, net35, net29, net24, grp0_cy);
                        //p7,p6,p5,p4,grp0_cy
or       inst47 (cout, net41, net43, net44, net45, net46);
            //g7,p7,g6,p7,p6,g5,p7,p6,p5,g4,p7,p6,p5,p4,grp0_cy

//--------------------------------------------------
//instantiate the logic to detect overflow
//--------------------------------------------------
and      inst48 (net48, a[7], rslt[7], ~sum_diff[7]);
and      inst49 (net49, ~a[7], ~rslt[7], sum_diff[7]);
or       inst50 (ovfl, net48, net49);

endmodule













Page 264, Figure 5.14

//test bench for the 8-bit
//carry lookahead adder/subtractor
module add_sub_cla8_tb;

reg [7:0] a, b;
reg mode;
wire [7:0] sum_diff;
wire cout, ovfl;

//display variables
initial
$monitor ("a=%b, b=%b, mode=%b, sum_diff=%b, ovfl=%b",
               a, b, mode, sum_diff, ovfl);

//apply input vectors
initial
begin
      #0    a = 8'b0000_0000;    b = 8'b0000_0001;    mode = 1'b0;
      #10   a = 8'b0000_0000;    b = 8'b0000_0001;    mode = 1'b1;

      #10   a = 8'b0000_0110;    b = 8'b0000_0011;    mode = 1'b0;
      #10   a = 8'b0000_0110;    b = 8'b0000_0011;    mode = 1'b1;

      #10   a = 8'b0000_1100;    b = 8'b0000_0101;    mode = 1'b0;
      #10   a = 8'b0000_1100;    b = 8'b0000_0101;    mode = 1'b1;

      #10   a = 8'b0000_0001;    b = 8'b1111_1001;    mode = 1'b0;
      #10   a = 8'b0000_0001;    b = 8'b1111_1001;    mode = 1'b1;

      #10   a = 8'b0000_0001;    b = 8'b1000_0001;    mode = 1'b0;
      #10   a = 8'b0000_0001;    b = 8'b1000_0001;    mode = 1'b1;

      #10   a = 8'b1111_0000;    b = 8'b0000_0001;    mode = 1'b0;
      #10   a = 8'b1111_0000;    b = 8'b0000_0001;    mode = 1'b1;

      #10   a = 8'b0110_1101;    b = 8'b0100_0101;    mode = 1'b0;
      #10   a = 8'b0010_1101;    b = 8'b0000_0101;    mode = 1'b1;

      #10   a = 8'b0000_0110;    b = 8'b0000_0001;    mode = 1'b0;
      #10   a = 8'b0000_0110;    b = 8'b0000_0001;    mode = 1'b1;

      #10   a = 8'b0001_0101;    b = 8'b0011_0001;    mode = 1'b0;
      #10   a = 8'b0001_0101;    b = 8'b0011_0001;    mode = 1'b1;

      #10   a = 8'b1000_0000;    b = 8'b1001_1100;    mode = 1'b0;
      #10   a = 8'b1000_0000;    b = 8'b1001_1100;    mode = 1'b1;

      #10   a = 8'b1110_1101;    b = 8'b0101_0101;    mode = 1'b0;
      #10   a = 8'b1110_1101;    b = 8'b0101_0101;    mode = 1'b1;

      #10   a = 8'b1111_1111;    b = 8'b1111_1111;    mode = 1'b0;
      #10   a = 8'b1111_1111;    b = 8'b1111_1111;    mode = 1'b1;

      #10   a = 8'b1110_1111;    b = 8'b1111_0001;    mode = 1'b0;
      #10   a = 8'b1110_1111;    b = 8'b1111_0001;    mode = 1'b1;


      #10   a = 8'b0111_1111;    b = 8'b0101_0101;    mode = 1'b0;
      #10   a = 8'b1010_1101;    b = 8'b1011_0101;    mode = 1'b1;

      #10   a = 8'b0110_0110;    b = 8'b1100_0001;    mode = 1'b0;
      #10   a = 8'b0110_0110;    b = 8'b1100_0001;    mode = 1'b1;

      #10   a = 8'b1000_0101;    b = 8'b0010_0001;    mode = 1'b0;
      #10   a = 8'b1000_0101;    b = 8'b0010_0001;    mode = 1'b1;

      #10   a = 8'b0111_0110;    b = 8'b1101_0101;    mode = 1'b0;
      #10   a = 8'b0111_0110;    b = 8'b1101_0101;    mode = 1'b1;

     #10   a = 8'b0110_0111;    b = 8'b1110_0111;    mode = 1'b0;
      #10   a = 8'b0110_0111;    b = 8'b1110_0111;    mode = 1'b1;

      #10   a = 8'b1111_1111;    b = 8'b1111_1111;    mode = 1'b0;
      #10   a = 8'b1111_1111;    b = 8'b1111_1111;    mode = 1'b1;

      #10      $stop;

end

//instantiate the module into the test bench
add_sub_cla8 inst1 (
      .a(a),
      .b(b),
      .mode(mode),
      .sum_diff(sum_diff),
      .cout(cout),
      .ovfl(ovfl)
      );

endmodule




























Page 267, Figure 5.16

//behavioral 8-bit adder/subtractor
module add_sub_bh (a, b, mode, rslt, ovfl);

input [7:0] a, b;
input  mode;
output [7:0] rslt;
output ovfl;

wire [7:0] a, b;
wire mode;
reg [7:0] rslt;
reg ovfl;

reg [7:0] neg_b = ~b + 1;

always @ (a or b or mode)
begin
//add
      if (mode == 0)
         begin
            rslt = a + b;
            ovfl = (a[7] & b[7] & ~rslt[7]) |
                    ~a[7] & ~b[7] & rslt[7]);
         end

//subtract
      else 
         begin
            rslt = a + neg_b;
            ovfl =   (a[7] & neg_b[7] & ~rslt[7]) |
                  (~a[7] & ~neg_b[7] & rslt[7]);
         end
end

endmodule























//test bench for the 8-bit
//carry lookahead adder/subtractor
module add_sub_bh_tb;

reg [7:0] a, b;
reg mode;

wire [7:0] rslt;
wire ovfl;

//display variables
initial
$monitor ("a=%b, b=%b, mode=%b, result=%b, ovfl=%b",
               a, b, mode, rslt, ovfl);

//apply input vectors
initial
begin
      #0    a = 8'b0000_0000;    b = 8'b0000_0001;    mode = 1'b0;
      #10   a = 8'b0000_0000;    b = 8'b0000_0001;    mode = 1'b1;

      #10   a = 8'b0000_0110;    b = 8'b0000_0011;    mode = 1'b0;
      #10   a = 8'b0000_0110;    b = 8'b0000_0011;    mode = 1'b1;

      #10   a = 8'b0000_1100;    b = 8'b0000_0101;    mode = 1'b0;
      #10   a = 8'b0000_1100;    b = 8'b0000_0101;    mode = 1'b1;

      #10   a = 8'b0000_0001;    b = 8'b1111_1001;    mode = 1'b0;
      #10   a = 8'b0000_0001;    b = 8'b1111_1001;    mode = 1'b1;

      #10   a = 8'b0000_0001;    b = 8'b1000_0001;    mode = 1'b0;
      #10   a = 8'b0000_0001;    b = 8'b1000_0001;    mode = 1'b1;

      #10   a = 8'b1111_0000;    b = 8'b0000_0001;    mode = 1'b0;
      #10   a = 8'b1111_0000;    b = 8'b0000_0001;    mode = 1'b1;

      #10   a = 8'b0110_1101;    b = 8'b0100_0101;    mode = 1'b0;
      #10   a = 8'b0010_1101;    b = 8'b0000_0101;    mode = 1'b1;

      #10   a = 8'b0000_0110;    b = 8'b0000_0001;    mode = 1'b0;
      #10   a = 8'b0000_0110;    b = 8'b0000_0001;    mode = 1'b1;

      #10   a = 8'b0001_0101;    b = 8'b0011_0001;    mode = 1'b0;
      #10   a = 8'b0001_0101;    b = 8'b0011_0001;    mode = 1'b1;

      #10   a = 8'b1000_0000;    b = 8'b1001_1100;    mode = 1'b0;
      #10   a = 8'b1000_0000;    b = 8'b1001_1100;    mode = 1'b1;

      #10   a = 8'b1110_1101;    b = 8'b0101_0101;    mode = 1'b0;
      #10   a = 8'b1110_1101;    b = 8'b0101_0101;    mode = 1'b1;

      #10   a = 8'b1111_1111;    b = 8'b1111_1111;    mode = 1'b0;
      #10   a = 8'b1111_1111;    b = 8'b1111_1111;    mode = 1'b1;

      #10   a = 8'b1110_1111;    b = 8'b1111_0001;    mode = 1'b0;
      #10   a = 8'b1110_1111;    b = 8'b1111_0001;    mode = 1'b1;




      #10   a = 8'b0111_1111;    b = 8'b0101_0101;    mode = 1'b0;
      #10   a = 8'b1010_1101;    b = 8'b1011_0101;    mode = 1'b1;

      #10   a = 8'b0110_0110;    b = 8'b1100_0001;    mode = 1'b0;
      #10   a = 8'b0110_0110;    b = 8'b1100_0001;    mode = 1'b1;

      #10   a = 8'b1000_0101;    b = 8'b0010_0001;    mode = 1'b0;
      #10   a = 8'b1000_0101;    b = 8'b0010_0001;    mode = 1'b1;

      #10   a = 8'b0111_0110;    b = 8'b1101_0101;    mode = 1'b0;
      #10   a = 8'b0111_0110;    b = 8'b1101_0101;    mode = 1'b1;

      #10   a = 8'b0110_0111;    b = 8'b1110_0111;    mode = 1'b0;
      #10   a = 8'b0110_0111;    b = 8'b1110_0111;    mode = 1'b1;

      #10   a = 8'b1111_1111;    b = 8'b1111_1111;    mode = 1'b0;
      #10   a = 8'b1111_1111;    b = 8'b1111_1111;    mode = 1'b1;

      #10   $stop;
end

//instantiate the module into the test bench
add_sub_bh inst1 (
      .a(a),
      .b(b),
      .mode(mode),
      .rslt(rslt),
      .ovfl(ovfl)
      );

endmodule






Computer Arithmetic
and
Verilog HDL Fundamentals

Chapter 6

Fixed-Point Multiplication

Verilog Code Figures

































Page 282, Figure 6.4

//behavioral add-shift multiply
module mul_add_shift3 (a, b, prod, start);

input [3:0] a, b;
input start;
output [7:0] prod;

reg [7:0] prod;
reg [3:0] b_reg;
reg [3:0] count;

always @ (posedge start)
begin
      b_reg = b;
      prod = 0;
      count = 4'b0100;

      if ((a!=0) && (b!=0))
         while (count)
            begin
               prod = {(({4{b_reg[0]}} & a)
                        + prod[7:4]), prod[3:1]};
            b_reg = b_reg >> 1;
            count = count - 1;
            end
end
endmodule


//test bench for add-shift multiplier
module mul_add_shift3_tb;

reg [3:0] a, b;
reg start;
wire [7:0] prod;


//display variables
initial       
$monitor ("a = %b, b = %b, prod = %b",
               a, b, prod);


//apply input vectors
initial 
begin
      #0       start = 1'b0;
               a = 4'b0110;               b = 4'b0110;
      #10      start = 1'b1;
      #10      start = 1'b0;

      #10      a = 4'b0010;               b = 4'b0110;
      #10      start = 1'b1;
      #10      start = 1'b0;

      #10      a = 4'b0111;               b = 4'b0101;
      #10      start = 1'b1;
      #10      start = 1'b0;          

     #10      a = 4'b0111;               b = 4'b0111;
      #10      start = 1'b1;
      #10      start = 1'b0;

      #10      a = 4'b0101;               b = 4'b0101;
      #10      start = 1'b1;
      #10      start = 1'b0;

      #10      a = 4'b0111;               b = 4'b0011;
      #10      start = 1'b1;
      #10      start = 1'b0;

      #10      a = 4'b0100;               b = 4'b0110;
      #10      start = 1'b1;
      #10      start = 1'b0;

      #10      $stop;
end

//instantiate the module into the test bench
mul_add_shift3 inst1 (
      .a(a),
      .b(b),
      .prod(prod),
      .start(start)
      );

endmodule































Page 286, Figure 6.8

//behavioral add-shift multiply
module mul_add_shift5 (a, b, prod, start);

input [3:0] a, b;
input start;
output [7:0] prod;

//define internal registers
reg [7:0] prod;
reg [3:0] count;

always @ (posedge start)
begin
      prod [7:4] = 4'b0000;
      prod [3:0] = b;
      count = 4'b0100;

      if ((a!=0) && (b!=0))
         while (count)
            begin
               if (prod[0] == 1'b0)
                  begin
                     prod = {prod[7], prod[7:1]};
                     count = count - 1;
                  end

               else
                  begin
                     prod = {a[3], (a + prod[7:4]), prod[3:1]};
                     count = count - 1;
                  end
            end
end
endmodule


//test bench for add-shift multiplier
module mul_add_shift5_tb;

reg [3:0] a, b;
reg start;
wire [7:0] prod;

//display variables
initial
$monitor ("a = %b, b = %b, prod = %b",
               a, b, prod);

//apply input vectors
initial
begin
      #0       start = 1'b0;
               a = 4'b0110;               b = 4'b0110;
      #10      start = 1'b1;
      #10      start = 1'b0;


      #10      a = 4'b0010;               b = 4'b0110;
      #10      start = 1'b1;
      #10      start = 1'b0;

      #10      a = 4'b0111;               b = 4'b0101;
      #10      start = 1'b1;
      #10      start = 1'b0;

      #10      a = 4'b0111;               b = 4'b0111;
      #10      start = 1'b1;
      #10      start = 1'b0;

      #10      a = 4'b1111;               b = 4'b0111;
      #10      start = 1'b1;
      #10      start = 1'b0;

      #10      a = 4'b1011;               b = 4'b0111;
      #10      start = 1'b1;
      #10      start = 1'b0;

      #10      a = 4'b1000;               b = 4'b0001;
      #10      start = 1'b1;
      #10      start = 1'b0;

     #10      a = 4'b1010;               b = 4'b0111;
      #10      start = 1'b1;
      #10      start = 1'b0;

      #10      a = 4'b1101;               b = 4'b0101;
      #10      start = 1'b1;
      #10      start = 1'b0;

      #10      a = 4'b0100;               b = 4'b0111;
      #10      start = 1'b1;
      #10      start = 1'b0;
      #10      $stop;
end

//instantiate the module into the test bench
mul_add_shift5 inst1 (
      .a(a),
      .b(b),
      .prod(prod),
      .start(start)
      );

endmodule














Page 296,  Figure 6.12

//mixed-design for the Booth multiply algorithm
module booth4 (a, b, prod);


input [7:0] a, b;
output [15:0] prod;


wire [7:0] a, b;
wire [15:0] prod;


wire [7:0] a_bar;


//define internal wires
wire [15:0] a_ext_pos;
wire [15:0] a_ext_neg;

//define internal registers
reg [7:0] a_neg;
reg [15:0] pp1, pp2, pp3, pp4, pp5, pp6, pp7, pp8;

//test b[1:0] --------------------------------------
assign a_bar = ~a;

always @ (a_bar)
    a_neg = a_bar + 1;

//define 16-bit multiplicand and 2s comp of multiplicand
assign a_ext_pos = {{8{a[7]}}, a};
assign a_ext_neg = {{8{a_neg[7]}}, a_neg};

always @ (b or a_ext_pos or a_ext_neg)
begin
      case (b[1:0])
         2'b00 :
            begin
               pp1 = 16'h00;
               pp2 = 16'h00;
            end

         2'b01 :
            begin
               pp1 = a_ext_neg;
               pp2 = {{7{a[7]}}, a[7:0], 1'b0};
            end

         2'b10 :
            begin
               pp1 = 16'h00;
               pp2 = {a_ext_neg[14:0], 1'b0};
            end




         2'b11 :
            begin
               pp1 = a_ext_neg;
               pp2 = 16'h00;
            end
      endcase

end

//test b[2:1] --------------------------------------
always @ (b or a_ext_pos or a_ext_neg)
begin
      case (b[2:1])
         2'b00: pp3 = 16'h00;

         2'b01: pp3 = {a_ext_pos[13:0], 2'b00};

         2'b10: pp3 = {a_ext_neg[13:0], 2'b00};

         2'b11: pp3 = 16'h00;
      endcase
end

//test b[3:2] --------------------------------------
always @ (b or a_ext_pos or a_ext_neg)
begin
      case (b[3:2])
         2'b00: pp4 = 16'h00;

         2'b01: pp4 = {a_ext_pos[12:0], 3'b000};

         2'b10: pp4 = {a_ext_neg[12:0], 3'b000};

         2'b11: pp4 = 16'h00;
      endcase
end

//test b[4:3] ---------------------------------------
always @ (b or a_ext_pos or a_ext_neg)
begin
      case (b[4:3])
         2'b00: pp5 = 16'h00;

         2'b01: pp5 = {a_ext_pos[11:0], 4'b0000};

         2'b10: pp5 = {a_ext_neg[11:0], 4'b0000};

         2'b11: pp5 = 16'h00;
      endcase
end

//test b[5:4] ---------------------------------------
always @ (b or a_ext_pos or a_ext_neg)
begin
      case (b[5:4])
         2'b00: pp6 = 16'h00;

         2'b01: pp6 = {a_ext_pos[10:0], 5'b00000};

         2'b10: pp6 = {a_ext_neg[10:0], 5'b00000};

         2'b11: pp6 = 16'h00;
      endcase
end

//test b[6:5] ---------------------------------------
always @ (b or a_ext_pos or a_ext_neg)
begin
      case (b[6:5])
         2'b00: pp7 = 16'h00;

         2'b01: pp7 = {a_ext_pos[9:0], 6'b000000};

         2'b10: pp7 = {a_ext_neg[9:0], 6'b000000};

         2'b11: pp7 = 16'h00;
      endcase
end

//test b[7:6] ---------------------------------------
always @ (b or a_ext_pos or a_ext_neg)
begin
      case (b[7:6])
         2'b00: pp8 = 16'h00;

         2'b01: pp8 = {a_ext_pos[8:0], 7'b0000000};

         2'b10: pp8 = {a_ext_neg[8:0], 7'b0000000};

         2'b11: pp8 = 16'h00;
      endcase
end

assign prod = pp1 + pp2 + pp3 + pp4 + pp5 + pp6 + pp7 + pp8;

endmodule


//test bench for booth algorithm
module booth4_tb;

//registers for inputs because they hold values
reg [7:0] a, b;
wire [15:0] prod;

//display operands a, b, and product
initial
$monitor ("a = %b, b = %b, prod = %h", a, b, prod);

//apply input vectors
initial
begin
//for examples 6.6 through 6.10
      #0    a = 8'b0001_1011;
            b = 8'b0111_1000;

      #10   a = 8'b1010_1101;
            b = 8'b0011_1110;


      #10   a = 8'b0100_1010;
            b = 8'b1101_1100;

      #10   a = 8'b1010_0010;
            b = 8'b1101_1100;

      #10   a = 8'b0100_1110;
            b = 8'b0010_1011;

//test b[1:0] ---------------------------------------
      #10   a = 8'b1100_1100;
            b = 8'b1100_1100;

      #10   a = 8'b1100_1100;
            b = 8'b1100_1101;

      #10   a = 8'b1100_1100;
            b = 8'b1100_1110;

      #10   a = 8'b1100_1100;
            b = 8'b1100_1111;


//test b[2:1] ---------------------------------------

      #10   a = 8'b0111_1111;
            b = 8'b1011_1000;

      #10   a = 8'b1011_0011;
            b = 8'b1100_1011;

      #10   a = 8'b0111_0000;
            b = 8'b0111_0100;

      #10   a = 8'b0111_0000;
            b = 8'b0111_0110;


//test b[3:2] ---------------------------------------
      #10   a = 8'b0111_1111;
            b = 8'b1011_0000;

      #10   a = 8'b1011_0011;
            b = 8'b1100_0111;

      #10   a = 8'b0111_0000;
            b = 8'b0111_1000;

      #10   a = 8'b0111_0000;
            b = 8'b0111_1110;

//test b[4:3] ---------------------------------------
      #10   a = 8'b0111_1111;
            b = 8'b1010_0000;

      #10   a = 8'b1011_0011;
            b = 8'b1100_1111;

      #10   a = 8'b0111_0000;
            b = 8'b0111_0000;

      #10   a = 8'b0111_0000;
            b = 8'b0111_1110;


//test b[5:4] ---------------------------------------
      #10   a = 8'b0111_1111;
            b = 8'b1000_0000;

      #10   a = 8'b1011_0011;
            b = 8'b1101_1111;

      #10   a = 8'b0111_0000;
            b = 8'b0110_0000;

      #10   a = 8'b0111_0000;
            b = 8'b0111_1110;


//test b[6:5] ---------------------------------------
      #10   a = 8'b0111_1111;
            b = 8'b1000_0000;

      #10   a = 8'b1011_0011;
            b = 8'b1010_1111;

      #10   a = 8'b0111_0000;
            b = 8'b0101_0000;

      #10   a = 8'b0111_0000;
            b = 8'b0111_1110;

//test b[7:6] ---------------------------------------
      #10   a = 8'b0111_1111;
            b = 8'b0010_0000;

      #10   a = 8'b1011_0011;
            b = 8'b0100_1111;

      #10   a = 8'b0111_0000;
            b = 8'b1011_0000;

      #10   a = 8'b0111_0000;
            b = 8'b1111_1110;

      #10   $stop;
end

//instantiate the module into the test bench
booth4 inst1 (
      .a(a),
      .b(b),
      .prod(prod)
      );

endmodule







Page 313, Figure 6.25

//behavioral and dataflow for bit-pair multiplier
module bit_pair (a, b, prod);

input [7:0] a, b;
output [15:0] prod;

wire [7:0] a, b;
wire [15:0] prod;

//define internal wires
wire [7:0] a_bar;
wire [15:0] a_ext_pos;                          //positive A with sign extension
wire [15:0] a_ext_neg;                          //A negated with sign extension

//define internal registers
reg [7:0] a_neg;
reg [15:0] pp1, pp2, pp3, pp4;                                                //partial products

//1s complement of A
assign a_bar = ~a;

//2s complement of A
always @ (a_bar)
      a_neg = a_bar + 1;

//define a_ext_pos and a_ext_neg
//extend sign of positive A to 16 bits
assign a_ext_pos = {{8{a[7]}}, a};

//extend sign of negative A to 16 bits
assign a_ext_neg = {{8{a_neg[7]}}, a_neg};

//test b[1:0] ----------------------------------------
always @ (b or a_ext_pos or a_ext_neg)
begin
      case (b[1:0])              //test bits 1 and 0 with 0
            2'b00:               //(000) = 0 times multiplicand
                     pp1 = 16'h0000;

          2'b01:               //(010) = +1 times multiplicand
                     pp1 = a_ext_pos;

            2'b10:               //(100) = -2 times multiplicand
                     pp1 = {a_ext_neg[14:8], a_neg, 1'b0};

            2'b11:               //(110) = -1 times multiplicand
                     pp1 = a_ext_neg;
      endcase
end






//test b[3:1] ---------------------------------------------
always @ (b or a_ext_pos or a_ext_neg)
begin
      case (b[3:1])                 //test bits 3 and 2 with 1
         3'b000:                 //0 times multiplicand
                     pp2 = 16'h0000;

         3'b001:                 //+1 times multiplicand
                     pp2 = {a_ext_pos[13:0], 2'b00};

         3'b010:                 //+1 times multiplicand
                     pp2 = {a_ext_pos[13:0], 2'b00};

         3'b011:                 //+2 times multiplicand
                     pp2 = {a_ext_pos[12:0], 3'b000};

         3'b100:                 //-2 times multiplicand
                     pp2 = {a_ext_neg[12:0], 3'b000};

         3'b101:                 //-1 times multiplicand
                     pp2 = {a_ext_neg[13:0], 2'b00};

         3'b110:                 //-1 times multiplicand
                     pp2 = {a_ext_neg[13:0], 2'b00};

         3'b111:                 //0 times multiplicand
                     pp2 = 16'h0000;
      endcase
end

//continued on next page

//test b[5:3] ---------------------------------------------
always @ (b or a_ext_pos or a_ext_neg)
begin
      case (b[5:3])                 //test bits 5 and 4 with 3
         3'b000:                 //0 times multiplicand
                     pp3 = 16'h0000;

         3'b001:                 //+1 times multiplicand
                     pp3 = {a_ext_pos[11:0], 4'b0000};

         3'b010:                 //+1 times multiplicand
                     pp3 = {a_ext_pos[11:0], 4'b0000};

         3'b011:                 //+2 times multiplicand
                     pp3 = {a_ext_pos[10:0], 5'b00000};

         3'b100:                 //-2 times multiplicand
                     pp3 = {a_ext_neg[10:0], 5'b00000};

         3'b101:                 //-1 times multiplicand
                     pp3 = {a_ext_neg[11:0], 4'b0000};

         3'b110:                 //-1 times multiplicand
                     pp3 = {a_ext_neg[11:0], 4'b0000};

         3'b111:                 //0 times multiplicand
                     pp3 = 16'h0000;
      endcase
end

//test b[7:5] --------------------------------------------
always @ (b or a_ext_pos or a_ext_neg)
begin
      case (b[7:5])                 //test bits 7 and 6 with 5
         3'b000:                 //0 times multiplicand
                     pp4 = 16'h0000;

         3'b001:                 //+1 times multiplicand
                     pp4 = {a_ext_pos[9:0], 6'b000000};

         3'b010:                 //+1 times multiplicand
                     pp4 = {a_ext_pos[9:0], 6'b000000};

         3'b011:                 //+2 times multiplicand
                     pp4 = {a_ext_pos[8:0], 7'b0000000};
     
         3'b100:        //-2 times multiplicand
                     pp4 = {a_ext_neg[8:0], 7'b0000000};

         3'b101:        //-1 times multiplicand
                     pp4 = {a_ext_neg[9:0], 6'b000000};

         3'b110:        //-1 times multiplicand
                     pp4 = {a_ext_neg[9:0], 6'b000000};

         3'b111:        //0 times multiplicand
                     pp4 = 16'h0000;
   endcase
end

//define product
assign prod = pp1 + pp2 + pp3 + pp4;

endmodule

























//test bench for the bit-pair multiplier
module bit_pair_tb;


reg [7:0] a, b;
wire [15:0] prod;


//display operands a, b, and prod
initial
$monitor ("a = %b, b = %b, prod = %h", a, b, prod);


//apply input vectors
initial
begin
      #0    a = 8'b1100_0111;                   //a = -57
            b = 8'b1010_1101;                   //b = -83                                    product = ffc7h

     #10   a = 8'b0000_0110;                   //a = +6
            b = 8'b1110_1000;                   //b = -24                                    product = ff70h

      #10   a = 8'b1110_1111;                   //a = -17
            b = 8'b0000_1001;                   //b = +9                                     product = ff67h

      #10   a = 8'b0001_0011;                   //a = +19
            b = 8'b0011_0110;                   //b = +54                                    product = 0402h

      #10   a = 8'b0001_1001;                   //a = +25
            b = 8'b0101_1000;                   //b = +88                                    product = 0898h

      #10   a = 8'b0001_1001;                   //a = +25
            b = 8'b0110_1110;                   //b = +110                                   product = 0abeh

      #10   a = 8'b0011_1101;                   //a = +61
            b = 8'b1110_0011;                   //b = -29                                    product = 1917h

      #10   a = 8'b1100_1111;                   //a = -49
            b = 8'b1110_0001;                   //b = -31                                    product = 05efh

      #10   a = 8'b1111_1111;                   //a = -1
            b = 8'b1111_1111;                   //b = -1                                     product = 0001h

      #10   a = 8'b1111_1111;                   //a = -1
            b = 8'b0000_0001;                   //b = +1                                     product = ffffh

      #10   a = 8'b1100_0111;                   //a = -57
            b = 8'b1000_1100;                   //b = -116                                   product = 19d4h


      #10   a = 8'b0011_1110;                   //a = +62
            b = 8'b0100_1000;                   //b = +72                                    product = 1170h

      #10   $stop;

end

//instantiate the module into the test bench
bit_pair inst1 (
      .a(a),
      .b(b),
      .prod(prod)
      );

endmodule











































Page 321, Figure 6.35

//dataflow 2-input and gate
module and2_df (x1, x2, z1);

input x1, x2;
output z1;
wire x1, x2;
wire z1;

assign z1 = x1 & x2;
endmodule


//dataflow full adder
module full_adder (a, b, cin, sum, cout);

//list all inputs and outputs
input a, b, cin;
output sum, cout;

//define wires
wire a, b, cin;
wire sum, cout;

//continuous assign for dataflow
assign sum = (a ^ b) ^ cin;
assign cout = cin & (a ^ b) | (a & b);

endmodule


//structural array multiplier 4 bits
module array_mul4 (a, b, prod);

//define inputs and outputs
input [3:0] a, b;
output [7:0] prod;

wire [3:0] a, b;
wire [7:0] prod;

//define internal wires
wire     net1, net2, net3, net4, net5, net6, net7, net8,
         net9, net10, net11, net12, net13, net14, net15, net16,
         net17, net18, net19, net20, net21, net22, net23, net24,
         net25, net26, net27, net28, net29, net30, net31, net32;

//instantiate the logic for product[0]
and2_df inst1 (
      .x1(a[0]),
      .x2(b[0]),
      .z1(prod[0])                  //product[0]
      );




//instantiate the logic for product[1]
and2_df inst2 (
      .x1(a[1]),
      .x2(b[0]),
      .z1(net1)
      );

and2_df inst3 (
      .x1(a[0]),
      .x2(b[1]),
      .z1(net2)
      );

full_adder inst4 (
      .a(net1),
      .b(net2),
      .cin(1'b0),
      .sum(prod[1]),                //product[1]
      .cout(net3)
      );

//instantiate the logic for product[2]
and2_df inst5 (
      .x1(a[2]),
      .x2(b[0]),
      .z1(net4)
      );

and2_df inst6 (
      .x1(a[1]),
      .x2(b[1]),
      .z1(net5)
      );

full_adder inst7 (
      .a(net4),
      .b(net5),
      .cin(1'b0),
      .sum(net6),
      .cout(net7)
      );

and2_df inst8 (
      .x1(a[0]),
      .x2(b[2]),
      .z1(net8)
      );

full_adder inst9 (
   .a(net6),
   .b(net8),
   .cin(net3),
   .sum(prod[2]),       //product[2]
   .cout(net9)
   );

//instantiate the logic for product[3]
and2_df inst10 (
      .x1(a[3]),
      .x2(b[0]),
      .z1(net10)
      );

and2_df inst11 (
      .x1(a[2]),
      .x2(b[1]),
      .z1(net11)
      );

full_adder inst12 (
      .a(net10),
      .b(net11),
      .cin(1'b0),
      .sum(net12),
      .cout(net13)
      );

and2_df inst13 (
      .x1(a[1]),
      .x2(b[2]),
      .z1(net14)
      );

full_adder inst14 (
      .a(net12),
      .b(net14),
      .cin(net7),
      .sum(net15),
      .cout(net16)
      );

and2_df inst15 (
      .x1(a[0]),
      .x2(b[3]),
      .z1(net17)
      );

full_adder inst16 (
      .a(net15),
      .b(net17),
      .cin(net9),
      .sum(prod[3]),                //product[3]
      .cout(net18)
      );

//instantiate the logic for product[4]
and2_df inst17 (
      .x1(a[3]),
      .x2(b[1]),
      .z1(net19)
      );

and2_df inst18 (
      .x1(a[2]),
      .x2(b[2]),
      .z1(net20)
      );






full_adder inst19 (
      .a(net19),
      .b(net20),
      .cin(net13),
      .sum(net21),
      .cout(net22)
      );

and2_df inst20 (
      .x1(a[1]),
      .x2(b[3]),
      .z1(net23)
      );

full_adder inst21 (
      .a(net21),
      .b(net23),
      .cin(net16),
      .sum(net24),
      .cout(net25)
      );

full_adder inst22 (
      .a(net24),
      .b(1'b0),
      .cin(net18),
      .sum(prod[4]),                //product[4]
      .cout(net26)
      );

//instantiate the logic for product[5]
and2_df inst23 (
      .x1(a[3]),
      .x2(b[2]),
      .z1(net27)
      );

and2_df inst24 (
      .x1(a[2]),
      .x2(b[3]),
      .z1(net28)
      );

full_adder inst25 (
      .a(net27),
      .b(net28),
      .cin(net22),
      .sum(net29),
      .cout(net30)
      );

full_adder inst26 (
      .a(net29),
      .b(net26),
      .cin(net25),
      .sum(prod[5]),                //product[5]
      .cout(net31)
      );



//instantiate the logic for product[6] and product[7]
and2_df inst27 (
   .x1(a[3]),
   .x2(b[3]),
   .z1(net32)
   );

full_adder inst28 (
   .a(net32),
   .b(net31),
   .cin(net30),
   .sum(prod[6]),       //product[6]
   .cout(prod[7])       //product[7]
   );

endmodule


//test bench for array multiplier 4 bits
module array_mul4_tb;

reg [3:0] a, b;
wire [7:0] prod;

//apply input vectors
initial
begin : apply_stimulus
      reg [8:0] invect;
      for (invect=0; invect<256; invect=invect+1)
      begin
         {a, b} = invect [8:0];
         #10 $display ("a = %d, b = %d, product = %d", a, b, prod);
      end
end

//instantiate the module into the test bench
array_mul4 inst1 (
      .a(a),
      .b(b),
      .prod(prod)
      );

endmodule

















Page 331, Figure 6.41

//behavioral multiplication table lookup
module mul_table_lookup (a, b, start, prod);

input [7:0] a;
input [8:0] b;
input start;
output [19:0] prod;

//define internal registers
reg [19:0] prod;
reg [1:0] count;
reg [19:0] sum;
reg [8:0] b_reg;

//define memory size
//memory is an array of eleven 8-bit registers
reg [10:0] mpcnd_table [0:7];

//define memory contents
//load mpcnd_table from file mem.mpcnd
initial
begin
      $readmemb ("mem.mpcnd", mpcnd_table);
end

always @ (posedge start)
begin
      prod [19:0] = 20'h00000;
      count = 2'b11;
      b_reg = b;
      if ((a!=0) && (b!=0))
         while (count)
            begin
               sum = {{mpcnd_table[b_reg[2:0]], 9'b0000_0000_0}
                     + prod[19:0]};
               prod = {{3{sum[19]}}, sum[19:3]};
               b_reg = b_reg >> 3;
               count = count - 1;
            end
end
endmodule

















//test bench for multiplication using table lookup
module mul_table_lookup_tb;

reg [7:0] a;
reg [8:0] b;
reg start;
wire [19:0] prod;

//display variables
initial
$monitor ("a=%b, b=%b, prod=%b", a, b, prod);

//apply input vectors
initial
begin
      #0    start = 1'b0;
            //6 x 1 = 6 = 00006h
            a = 8'b0000_0110;                b = 9'b0_0000_0001;
      #10   start = 1'b1;
      #10   start = 1'b0;

            //6 x 11 = 66 = 00042h
      #10   a = 8'b0000_0110;                b = 9'b0_0000_1011;
      #10   start = 1'b1;
      #10   start = 1'b0;

            //6 x 6 = 36 = 00024h
      #10   a = 8'b0000_0110;                b = 9'b0_0000_0110;
      #10   start = 1'b1;
      #10   start = 1'b0;

            //6 x 46 = 276 = 00114h
      #10   a = 8'b0000_0110;                b = 9'b0_0010_1110;
      #10   start = 1'b1;
      #10   start = 1'b0;

            //6 x 159 = 954 = 003bah
      #10   a = 8'b0000_0110; b = 9'b0_1001_1111;
      #10   start = 1'b1;
      #10   start = 1'b0;

            //6 x 170 = 1020 = 003fch
      #10   a = 8'b0000_0110; b = 9'b0_1010_1010;
      #10   start = 1'b1;
      #10   start = 1'b0;

            //6 x 255 = 1530 = 005fah
      #10   a = 8'b0000_0110; b = 9'b0_1111_1111;
      #10   start = 1'b1;
      #10   start = 1'b0;
      #10   $stop;
end
//instantiate the module into the test bench
mul_table_lookup inst1 (
      .a(a),
      .b(b),
      .start(start),
      .prod(prod)
      );
endmodule
Page 336, Figure 6.45

//behavioral multiplication table lookup
module mul_table_lookup_neg (a, b, start, prod);

input [7:0] a;
input [8:0] b;
input start;
output [19:0] prod;

//define internal registers
reg [19:0] prod;
reg [1:0] count;
reg [19:0] sum;
reg [8:0] b_reg;

//define memory size
//memory is an array of eight 8-bit registers
reg [10:0] mpcnd_table [0:7];

//define memory contents
//load mpcnd_table from file mem.mpcnd
initial
begin
      $readmemb ("mem.mpcnd", mpcnd_table);
end

always @ (posedge start)
begin
      prod [19:0] = 20'h00000;
      count = 2'b11;
      b_reg = b;
      if ((a!=0) && (b!=0))
         while (count)
            begin
               sum = {{mpcnd_table[b_reg[2:0]], 9'b0000_0000_0}
                     + prod[19:0]};
               prod = {{3{sum[19]}}, sum[19:3]};
               b_reg = b_reg >> 3;
               count = count - 1;
            end
end

endmodule

















//test bench for multiplication using table lookup
module mul_table_lookup_neg_tb;

reg [7:0] a;
reg [8:0] b;
reg start;
wire [19:0] prod;

//display variables
initial
$monitor ("a=%b, b=%b, prod=%b", a, b, prod);

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

            //-30 x 1 = -30 = fffe2h
               a = 8'b1110_0010;                b = 9'b0_0000_0001;
      #10      start = 1'b1;
      #10      start = 1'b0;

      #10      a = 8'b1110_0010; b = 9'b0_0000_1011;
      #10      start = 1'b1;
      #10      start = 1'b0;


            //-30 x 6 = -180 = fff4ch
      #10      a = 8'b1110_0010;                b = 9'b0_0000_0110;
      #10      start = 1'b1;
      #10      start = 1'b0;

            //-30 x 46 = -1380 = ffa9ch
      #10      a = 8'b1110_0010;                b = 9'b0_0010_1110;
      #10      start = 1'b1;
      #10      start = 1'b0;

            //-30 x 159 = -4770 = fed5eh
      #10      a = 8'b1110_0010;                b = 9'b0_1001_1111;
      #10      start = 1'b1;
      #10      start = 1'b0;

            //-30 x 170 = -5100 = fec14h
      #10      a = 8'b1110_0010;                b = 9'b0_1010_1010;
      #10      start = 1'b1;
      #10      start = 1'b0;

            //-30 x 255 = -7650 = fe21eh
      #10      a = 8'b1110_0010;                b = 9'b0_1111_1111;
      #10      start = 1'b1;
      #10      start = 1'b0;

      #10      $stop;

end




//instantiate the module into the test bench
mul_table_lookup_neg inst1 (
      .a(a),
      .b(b),
      .start(start),
      .prod(prod)
      );

endmodule




















































Page 341, Figure 6.51

//behavioral to add two operands
module mem_mul (mpcnd, mplyr, prod);

//list inputs and outputs
input [2:0] mpcnd, mplyr;
output [5:0] prod;

//list wire and reg
wire [2:0] mpcnd, mplyr;//mpcnd and mplyr to address 64 words
reg [5:0] prod;

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

//define memory contents
//load mem_mul from file opnds.mul
initial
begin
   $readmemb ("opnds.mul", mem_mul);
end

//use the operands to access the memory
always @ (mpcnd or mplyr)
begin
   prod = mem_mul [{mpcnd, mplyr}];
end

endmodule


//test bench for mem_mul module
module mem_mul_tb;

reg [2:0] mpcnd, mplyr;
wire [5:0] prod;

//display variables
initial
$monitor ("mpcnd = %b, mplyr = %b, prod = %b",
               mpcnd, mplyr, prod);

//apply input vectors for multiplicand and multiplier
initial
begin
      #0       mpcnd = 3'b000;                  mplyr = 3'b011;
      #10      mpcnd = 3'b001;                  mplyr = 3'b001;
      #10      mpcnd = 3'b001;                  mplyr = 3'b011;
      #10      mpcnd = 3'b001;                  mplyr = 3'b100;
      #10      mpcnd = 3'b001;                  mplyr = 3'b111;
      #10      mpcnd = 3'b010;                  mplyr = 3'b101;
      #10      mpcnd = 3'b010;                  mplyr = 3'b111;
      #10      mpcnd = 3'b011;                  mplyr = 3'b011;
      #10      mpcnd = 3'b110;                  mplyr = 3'b111;
      #10      mpcnd = 3'b100;                  mplyr = 3'b010;
     #10      mpcnd = 3'b100;                  mplyr = 3'b101;
      #10      mpcnd = 3'b100;                  mplyr = 3'b100;
      #10      mpcnd = 3'b101;                  mplyr = 3'b001;
      #10      mpcnd = 3'b101;                  mplyr = 3'b011;
      #10      mpcnd = 3'b101;                  mplyr = 3'b111;
      #10      mpcnd = 3'b110;                  mplyr = 3'b011;
      #10      mpcnd = 3'b110;                  mplyr = 3'b111;
      #10      mpcnd = 3'b111;                  mplyr = 3'b001;
      #10      mpcnd = 3'b111;                  mplyr = 3'b100;
      #10      mpcnd = 3'b111;                  mplyr = 3'b101;
      #10      mpcnd = 3'b111;                  mplyr = 3'b110;
      #10      mpcnd = 3'b111;                  mplyr = 3'b111;
      #10      $stop;
end

mem_mul inst1 (                     //instantiate the module
      .mpcnd(mpcnd),
      .mplyr(mplyr),
      .prod(prod)
      );

endmodule










































Page 346, Figure 6.57

//behavioral add-shift multiply for multiple operands
module mul_add_shift_multi (a, b1, b2, start1, start2,
                              prod8, prod12);

input [3:0] a, b1, b2;
input start1, start2;
output [7:0] prod8;
output [11:0] prod12;


//define internal registers
reg [7:0] prod8;
reg [11:0] prod12;
reg [3:0] count;


//design the behavior for the 4 x 4 multiplier
always @ (posedge start1)
begin
      prod8 [7:4] = 4'b0000;
      prod8 [3:0] = b1;
      count = 4'b0100;
         if ((a!=0) && (b1!=0))
            while (count)
               begin
                  if (prod8[0] == 1'b0)
                     begin
                        prod8 = {prod8[7], prod8[7:1]};
                        count = count - 1;
                     end

                  else
                     begin
                        prod8 = {a[3], (a + prod8[7:4]),
                                 prod8[3:1]};
                        count = count - 1;
                     end
               end
end

//design the behavior for the 8 x 4 multiplier
always @ (posedge start2)
begin
      prod12 [11:4] = 8'b0000_0000;
      prod12 [3:0] = b2;
      count = 4'b0100;
         if ((prod8!=0) && (b2!=0))
            while (count)
               begin
                  if (prod12[0] == 1'b0)
                     begin
                        prod12 = {prod12[11], prod12[11:1]};
                        count = count - 1;
                     end


                  else
                     begin
                        prod12 = {prod8[7],
                                 (prod8 + prod12[11:4]),
                                 prod12[3:1]};
                        count = count - 1;
                     end
               end
end

endmodule


//test bench for add-shift multiplier
module mul_add_shift_multi_tb;

reg [3:0] a, b1, b2;
reg start1, start2;
wire [7:0] prod8;
wire [11:0] prod12;

//display variables
initial
$monitor ("a=%b, b1=%b, b2=%b, start1=%b, start2=%b,
               prod8=%b, prod12=%b",
               a, b1, b2, start1, start2, prod8, prod12);

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

            //7 x 7 x 2 = 98 (062h)
            a=4'b0111;     b1=4'b0111;    b2=4'b0010;
      #10   start1 = 1'b1;
      #10   start1 = 1'b0;
      #10   start2 = 1'b1;
      #10   start2 = 1'b0;

            //3 x 7 x 6 = 126 (07eh)
      #10   a=4'b0011;     b1=4'b0111;    b2= 4'b0110;
      #10   start1 = 1'b1;
      #10   start1 = 1'b0;
      #10   start2 = 1'b1;
      #10   start2 = 1'b0;

          //7 x 5 x 6 = 210 (0d2h)
      #10   a=4'b0111;     b1=4'b0101;    b2=4'b0110;
      #10   start1 = 1'b1;
      #10   start1 = 1'b0;
      #10   start2 = 1'b1;
      #10   start2 = 1'b0;

            //7 x 4 x 5 = 140 (08ch)
      #10   a=4'b0111;     b1=4'b0100;    b2=4'b0101;
      #10   start1 = 1'b1;
      #10   start1 = 1'b0;
      #10   start2 = 1'b1;
      #10   start2 = 1'b0;

            //-1 x 7 x 1 = -7 (ff9h)
      #10   a=4'b1111;     b1=4'b0111;    b2=4'b0001;
      #10   start1 = 1'b1;
      #10   start1 = 1'b0;
      #10   start2 = 1'b1;
      #10   start2 = 1'b0;

            //-5 x 6 x 1 = -30 (fe2h)
      #10   a=4'b1011;     b1=4'b0110;    b2=4'b0001;
      #10   start1 = 1'b1;
      #10   start1 = 1'b0;
      #10   start2 = 1'b1;
      #10   start2 = 1'b0;

            //-6 x 7 x 5 = -210 (f2eh)
      #10   a=4'b1010;     b1=4'b0111;    b2=4'b0101;
      #10   start1 = 1'b1;
      #10   start1 = 1'b0;
      #10   start2 = 1'b1;
      #10   start2 = 1'b0;

            //-4 x 7 x 3 = -84 (fach)
      #10   a=4'b1100;     b1=4'b0111;    b2=4'b0011;
      #10   start1 = 1'b1;
      #10   start1 = 1'b0;
      #10   start2 = 1'b1;
      #10   start2 = 1'b0;

          //-7 x 7 x 7 = -343 (ea9h)
      #10   a=4'b1001;     b1=4'b0111;    b2=4'b0111;
      #10   start1 = 1'b1;
      #10   start1 = 1'b0;
      #10   start2 = 1'b1;
      #10   start2 = 1'b0;

      #20   $stop;
end

//instantiate the module into the test bench
mul_add_shift_multi inst1 (
      .a(a),
      .b1(b1),
      .b2(b2),
      .start1(start1),
      .start2(start2),
      .prod8(prod8),
      .prod12(prod12)
      );

endmodule















     














      
      
     

No comments:

Post a Comment