`timescale 1ns/1ps module mult_piped_8x8_2sC_tb; reg [7:0] a_stim, b_stim; wire [15:0] y_out; wire [7:0] a_in, b_in; parameter period = 10; reg clock, reset; // reset = active HIGH integer timebase; // pipe-delayed stimulus and reponse reg[7:0] aR[8:0]; reg[7:0] bR[8:0]; reg[15:0] yR[8:0]; // 2sC 8x8 multiply function function[15:0] multiply_8x8_2sC; input[7:0] a,b; reg[7:0] a_mag,b_mag; reg[14:0] y_mag; reg[14:0] y_neg; begin if (~a[7]) // true if a[7] is '0' a_mag = a[6:0]; else a_mag = 128 - a[6:0]; // max(a_mag) = 128, thus 8 bits case (b[7]) 0: b_mag = b[6:0]; 1: b_mag = 128 - b[6:0]; endcase y_mag = a_mag * b_mag; // max(y_mag) = 16384, thus 15 bits if ((a[7] ^ b[7]) & (y_mag != 0)) // if (a * b) is -ve AND non-zero begin // y_mag >=1, <= 16256, thus need only 14 bits y_neg = 32768 - y_mag[13:0]; // max(y_neg) = 32767, thus need 15 bits multiply_8x8_2sC = {1'b1,y_neg}; end else multiply_8x8_2sC = y_mag; end endfunction initial begin // $vw_dumpvars(); // 1, mult_piped_8x8_2sC // 1, DUT - name not decalred // 1, mult_piped_8x8_2sC - name not declared clock = 1; timebase = 0; reset = 0; a_stim = 0; b_stim = 0; // header for display table $display("A B yR[7] y_out"); end // timebase always begin #(period / 2) ; clock = ~clock; end always @(negedge clock) begin timebase = timebase + 1; if (timebase > 65544) $stop; end // stimulus always @(timebase) begin a_stim = a_stim + 1; case (timebase) 1: reset = 1; 2: reset = 0; endcase if (timebase % 256 == 0) begin b_stim = b_stim + 1; // $stop; // for debug purposes end if ((timebase % 16 == 0) & (timebase > 256)) begin // $stop; // for debug purposes end end // response checking always @ (posedge clock) begin // the a and b inputs are put into a delay-pipe so that // at the pipelined multiplier outputs, it is easy to see // in a waveform viewer the inputs corresponding to output aR[7] = aR[6]; bR[7] = bR[6]; // pipeline statements yR[7] = yR[6]; aR[6] = aR[5]; bR[6] = bR[5]; yR[6] = yR[5]; aR[5] = aR[4]; bR[5] = bR[4]; yR[5] = yR[4]; aR[4] = aR[3]; bR[4] = bR[3]; yR[4] = yR[3]; aR[3] = aR[2]; bR[3] = bR[2]; yR[3] = yR[2]; aR[2] = aR[1]; bR[2] = bR[1]; yR[2] = yR[1]; aR[1] = aR[0]; bR[1] = bR[0]; yR[1] = yR[0]; // multiply result (a*b) appears after +clk aR[0] = a_stim; bR[0] = b_stim; yR[0] = multiply_8x8_2sC (aR[0],bR[0]); // this function implements the multiply algorithmically // now compare mulitplier DUT o/p with yR[7] #(period/4) ; $display(aR[7],bR[7], yR[7],y_out); if (y_out != yR[7]) begin $display("Error: y_out is %d, should be %d", y_out, yR[7]); $stop; end end // DUT assign a_in = a_stim; assign b_in = b_stim; mult_piped_8x8_2sC DUT (a_in, b_in, clock, reset, y_out); endmodule