diff --git a/tb/serDiv/scripts/compile.sh b/tb/serDiv/scripts/compile.sh new file mode 100755 index 00000000..6a526440 --- /dev/null +++ b/tb/serDiv/scripts/compile.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +vlib ./work + +vlog -sv ../../../alu_div.sv || exit 1 +vlog -sv +incdir+../ ../tb.sv || exit 1 diff --git a/tb/serDiv/scripts/sim.sh b/tb/serDiv/scripts/sim.sh new file mode 100755 index 00000000..444ac272 --- /dev/null +++ b/tb/serDiv/scripts/sim.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +#default no batch mode +BATCHMODE=0 + + +###################### +# helper function +LIGHT_GREEN_COL="\033[1;32m" +LIGHT_RED_COL="\033[1;31m" +NO_COL="\033[0m" +function check_exitcode() { + + if [ $1 -ne 0 ] ; then + echo -en "$LIGHT_RED_COL$2 [ FAILED ]$NO_COL \n"; + exit 1; + else + echo -en "$LIGHT_GREEN_COL$2 [ OK ]$NO_COL \n"; + fi +} +###################### + + +###################### +# check args, +# otherwise use default +###################### +if [ $1 -eq 0 ]; then +BATCHMODE=1 +fi + +###################### +#compile sourcefiles +###################### + +./compile.sh +check_exitcode $? "compile sources" +###################### + + +###################### +#start modelsim in batch mode +###################### + +if [ ${BATCHMODE} -eq 1 ] ; then + vsim -c -t ps -do tb_nogui.do +else + ###################### + #start modelsim normally + ###################### + + vsim -t 1ps -do tb.do +fi diff --git a/tb/serDiv/scripts/tb.do b/tb/serDiv/scripts/tb.do new file mode 100644 index 00000000..adc493d8 --- /dev/null +++ b/tb/serDiv/scripts/tb.do @@ -0,0 +1,30 @@ +############################################################################### +## Title : testbench starter script (with GUI) +## Project : Approximate Cholesky Solver +## Purpose : compiles all sources and generates the testvectors +## Author : Michael Schaffner (schaffner@iis.ee.ethz.ch) +############################################################################### +## File ID : $Id: tb.do 756 2014-06-20 12:41:06Z michscha $ +## SVN Rev. : $Revision: 756 $ +## Date: : $Date: 2014-06-20 14:41:06 +0200 (Fri, 20 Jun 2014) $ +## Modified by : $Author: michscha $ +############################################################################### +## Major Changes: +## Date | Author | Description +## 2014/01/18 | schaffner | created +############################################################################### +## Description: +## +## +############################################################################### +## Copyright (c) 2014 Disney Research Zurich, Integrated Systems Lab ETH Zurich +############################################################################### + +#vsim -sva -assertdebug -t ps tb +vsim -voptargs="+acc" -t ps tb + +#turn off disturbing warnings... +#set NumericStdNoWarnings 1 + +do wave.do +run -all diff --git a/tb/serDiv/scripts/tb_nogui.do b/tb/serDiv/scripts/tb_nogui.do new file mode 100644 index 00000000..3074eaa7 --- /dev/null +++ b/tb/serDiv/scripts/tb_nogui.do @@ -0,0 +1,33 @@ +############################################################################### +## Title : testbench starter script (no GUI) +## Project : Approximate Cholesky Solver +## Purpose : compiles all sources and generates the testvectors +## Author : Michael Schaffner (schaffner@iis.ee.ethz.ch) +############################################################################### +## File ID : $Id: tb_nogui.do 756 2014-06-20 12:41:06Z michscha $ +## SVN Rev. : $Revision: 756 $ +## Date: : $Date: 2014-06-20 14:41:06 +0200 (Fri, 20 Jun 2014) $ +## Modified by : $Author: michscha $ +############################################################################### +## Major Changes: +## Date | Author | Description +## 2014/01/18 | schaffner | created +############################################################################### +## Description: +## +## +############################################################################### +## Copyright (c) 2014 Disney Research Zurich, Integrated Systems Lab ETH Zurich +############################################################################### + +vsim -t ps \ + tb + +#turn off disturbing warnings... +set StdArithNoWarnings 1 +set StdNumNoWarnings 1 +set NumericStdNoWarnings 1 + +run -all +exit -f + diff --git a/tb/serDiv/scripts/wave.do b/tb/serDiv/scripts/wave.do new file mode 100644 index 00000000..f4b1e8b5 --- /dev/null +++ b/tb/serDiv/scripts/wave.do @@ -0,0 +1,95 @@ +onerror {resume} +quietly WaveActivateNextPane {} 0 +add wave -noupdate /tb/AcqTrig_T +add wave -noupdate /tb/C_ACQ_DEL +add wave -noupdate /tb/C_APPL_DEL +add wave -noupdate /tb/C_CLK_HI +add wave -noupdate /tb/C_CLK_LO +add wave -noupdate /tb/C_LOG_WIDTH +add wave -noupdate /tb/C_WIDTH +add wave -noupdate /tb/Clk_CI +add wave -noupdate /tb/EndOfSim_T +add wave -noupdate /tb/InRdy_SO +add wave -noupdate /tb/InVld_SI +add wave -noupdate /tb/NumStim_T +add wave -noupdate /tb/OpA_DI +add wave -noupdate /tb/OpA_T +add wave -noupdate /tb/OpBShift_DI +add wave -noupdate /tb/OpBSign_SI +add wave -noupdate /tb/OpB_DI +add wave -noupdate /tb/OpB_T +add wave -noupdate /tb/OpCode_SI +add wave -noupdate /tb/OutRdy_SI +add wave -noupdate /tb/OutVld_SO +add wave -noupdate /tb/Res_DO +add wave -noupdate /tb/Rst_RBI +add wave -noupdate /tb/StimEnd_T +add wave -noupdate /tb/StimStart_T +add wave -noupdate /tb/TestName_T +add wave -noupdate -divider internal +add wave -noupdate /tb/i_mut/Clk_CI +add wave -noupdate /tb/i_mut/Rst_RBI +add wave -noupdate /tb/i_mut/OpA_DI +add wave -noupdate /tb/i_mut/OpB_DI +add wave -noupdate -radix unsigned /tb/i_mut/OpBShift_DI +add wave -noupdate /tb/i_mut/OpBSign_SI +add wave -noupdate /tb/OpBIsZero_SI +add wave -noupdate /tb/i_mut/OpCode_SI +add wave -noupdate /tb/i_mut/InVld_SI +add wave -noupdate /tb/i_mut/InRdy_SO +add wave -noupdate /tb/i_mut/OutRdy_SI +add wave -noupdate /tb/i_mut/OutVld_SO +add wave -noupdate -radix decimal /tb/i_mut/Res_DO +add wave -noupdate /tb/i_mut/ResReg_DN +add wave -noupdate /tb/i_mut/ResReg_DP +add wave -noupdate /tb/i_mut/AReg_DN +add wave -noupdate -radix decimal /tb/i_mut/AReg_DP +add wave -noupdate /tb/i_mut/BReg_DN +add wave -noupdate -radix decimal /tb/i_mut/BReg_DP +add wave -noupdate /tb/i_mut/RemSel_SN +add wave -noupdate /tb/i_mut/RemSel_SP +add wave -noupdate /tb/i_mut/CompInv_SN +add wave -noupdate /tb/i_mut/CompInv_SP +add wave -noupdate /tb/i_mut/ResInv_SN +add wave -noupdate /tb/i_mut/ResInv_SP +add wave -noupdate /tb/i_mut/AddMux_D +add wave -noupdate /tb/i_mut/AddOut_D +add wave -noupdate /tb/i_mut/BMux_D +add wave -noupdate /tb/i_mut/OutMux_D +add wave -noupdate /tb/i_mut/Cnt_DN +add wave -noupdate /tb/i_mut/Cnt_DP +add wave -noupdate /tb/i_mut/CntZero_S +add wave -noupdate /tb/i_mut/ARegEn_S +add wave -noupdate /tb/i_mut/BRegEn_S +add wave -noupdate /tb/i_mut/ResRegEn_S +add wave -noupdate /tb/i_mut/ABComp_S +add wave -noupdate /tb/i_mut/PmSel_S +add wave -noupdate /tb/i_mut/State_SN +add wave -noupdate /tb/i_mut/State_SP +add wave -noupdate /tb/OpA_DI +add wave -noupdate /tb/OpB_DI +add wave -noupdate /tb/Res_DO +add wave -noupdate /tb/Clk_CI +add wave -noupdate /tb/Rst_RBI +add wave -noupdate /tb/StimStart_T +add wave -noupdate /tb/StimEnd_T +add wave -noupdate /tb/EndOfSim_T +add wave -noupdate /tb/NumStim_T +TreeUpdate [SetDefaultTree] +WaveRestoreCursors {{Cursor 1} {89306315 ps} 0} +quietly wave cursor active 1 +configure wave -namecolwidth 348 +configure wave -valuecolwidth 194 +configure wave -justifyvalue left +configure wave -signalnamewidth 1 +configure wave -snapdistance 10 +configure wave -datasetprefix 0 +configure wave -rowmargin 4 +configure wave -childrowmargin 2 +configure wave -gridoffset 0 +configure wave -gridperiod 1 +configure wave -griddelta 40 +configure wave -timeline 0 +configure wave -timelineunits ps +update +WaveRestoreZoom {186977012 ps} {187704368 ps} diff --git a/tb/serDiv/tb.sv b/tb/serDiv/tb.sv new file mode 100644 index 00000000..eb424ec3 --- /dev/null +++ b/tb/serDiv/tb.sv @@ -0,0 +1,345 @@ +/////////////////////////////////////////////////////////////////////////////// +// File : TB for Simple Serial Divider +// Ver : 1.0 +// Date : 15.03.2016 +/////////////////////////////////////////////////////////////////////////////// +// +// Description: this is a simple serial divider for signed integers (int32). +// +/////////////////////////////////////////////////////////////////////////////// +// +// Authors : Michael Schaffner (schaffner@iis.ee.ethz.ch) +// Andreas Traber (traber@iis.ee.ethz.ch) +// +// Copyright (c) 2016 Integrated Systems Laboratory, ETH Zurich +/////////////////////////////////////////////////////////////////////////////// + + +// tb package +module tb; + + // leave this + timeunit 1ps; + timeprecision 1ps; + +/////////////////////////////////////////////////////////////////////////////// +// MUT signal declarations +/////////////////////////////////////////////////////////////////////////////// + time C_CLK_HI = 5ns; // set clock high time + time C_CLK_LO = 5ns; // set clock low time + time C_APPL_DEL = 2ns; // set stimuli application delay + time C_ACQ_DEL = 8ns; // set response aquisition delay + + parameter C_WIDTH = 32; + parameter C_LOG_WIDTH = 6; + + longint OpA_T, OpA_tmp; + longint OpB_T, OpB_tmp; + + logic [C_WIDTH-1:0] OpA_DI; + logic [C_WIDTH-1:0] OpB_DI; + logic [C_LOG_WIDTH-1:0] OpBShift_DI; + logic OpBIsZero_SI; + + logic OpBSign_SI; + logic [1:0] OpCode_SI; + logic [1:0] OpCode_tmp; + + logic InVld_SI; + + logic OutRdy_SI; + logic OutVld_SO; + logic [C_WIDTH-1:0] Res_DO; + +/////////////////////////////////////////////////////////////////////////////// +// TB signal declarations +/////////////////////////////////////////////////////////////////////////////// + + logic Clk_CI, Rst_RBI; + logic StimStart_T, StimEnd_T, EndOfSim_T; + longint NumStim_T; + logic AcqTrig_T; + string TestName_T; + +/////////////////////////////////////////////////////////////////////////////// +// use to ensure proper ATI timing +/////////////////////////////////////////////////////////////////////////////// + + task automatic applWaitCyc(ref logic Clk_C, input int unsigned n); + if (n > 0) + begin + repeat (n) @(posedge(Clk_C)); + #(C_APPL_DEL); + end + endtask + + task automatic acqWaitCyc(ref logic Clk_C, input int unsigned n); + if (n > 0) + begin + repeat (n) @(posedge(Clk_C)); + #(C_ACQ_DEL); + end + endtask + + task automatic applWait(ref logic Clk_C, ref logic SigToWaitFor_S); + do begin + @(posedge(Clk_C)); + #(C_APPL_DEL); + end while(SigToWaitFor_S == 1'b0); + endtask + + task automatic acqWait(ref logic Clk_C, ref logic SigToWaitFor_S); + do begin + @(posedge(Clk_C)); + #(C_ACQ_DEL); + end while(SigToWaitFor_S == 1'b0); + endtask + + task automatic acqWait2(ref logic Clk_C, ref logic SigToWaitFor_S, ref logic SigToWaitFor2_S); + do begin + @(posedge(Clk_C)); + #(C_ACQ_DEL); + end while(SigToWaitFor_S == 1'b0 || SigToWaitFor2_S == 1'b0); + endtask + + +/////////////////////////////////////////////////////////////////////////////// +// Clock Process +/////////////////////////////////////////////////////////////////////////////// + + always @* + begin + do begin + Clk_CI = 1; #(C_CLK_HI); + Clk_CI = 0; #(C_CLK_LO); + end while (EndOfSim_T == 1'b0); + // generate one extra cycle to allow response acquisition to complete + Clk_CI = 1; #(C_CLK_HI); + Clk_CI = 0; #(C_CLK_LO); + end + + +/////////////////////////////////////////////////////////////////////////////// +// MUT +/////////////////////////////////////////////////////////////////////////////// + + + assign OpBIsZero_SI = ~(|OpB_DI); + riscv_alu_div #(.C_WIDTH(C_WIDTH), .C_LOG_WIDTH(C_LOG_WIDTH)) i_mut (.*); + +/////////////////////////////////////////////////////////////////////////////// +// application process +/////////////////////////////////////////////////////////////////////////////// + + initial // process runs just once + begin : p_stim + + longint signed k, j, i; + bit ok, randBit; + + StimStart_T = 0; + StimEnd_T = 0; + NumStim_T = 0; + TestName_T = ""; + AcqTrig_T = 0; + + Rst_RBI = 0; + + OpA_T = 0; + OpB_T = 0; + + OpA_DI = 0; + OpB_DI = 0; + OpBShift_DI = 0; + OpBSign_SI = 0; + OpCode_SI = 0; + InVld_SI = 0; + + applWaitCyc(Clk_CI,100); + + Rst_RBI <= 1'b1; + + applWaitCyc(Clk_CI,100); + + + $display("stimuli application started"); + StimStart_T <= 1'b1; + applWaitCyc(Clk_CI,100); + + /////////////////////////////////////////////// + // unsigned division test + + `include "tb_udiv.sv" + + /////////////////////////////////////////////// + // unsigned modulo test + + `include "tb_urem.sv" + + /////////////////////////////////////////////// + // signed div test + + `include "tb_div.sv" + + /////////////////////////////////////////////// + // signed div test + + `include "tb_rem.sv" + + /////////////////////////////////////////////// + + applWaitCyc(Clk_CI,400); + + StimEnd_T <= 1; + $display("stimuli application ended"); + + end + + +/////////////////////////////////////////////////////////////////////////////// +// acquisition process +/////////////////////////////////////////////////////////////////////////////// + + + initial // process runs just once + begin : p_acq + + /////////////////////////////////////////////// + // define vars, init... + /////////////////////////////////////////////// + + longint acqCnt, errCnt, res, act; + + OutRdy_SI = 0; + EndOfSim_T = 0; + + acqWait(Clk_CI,StimStart_T); + + $display("response acquisition started"); + + /////////////////////////////////////////////// + // acquisiton and verification + /////////////////////////////////////////////// + + + while (1) + begin + + // wait for acquisition trigger + do begin + acqWaitCyc(Clk_CI,1); + if (StimEnd_T == 1) + begin + EndOfSim_T <= 1; + $display("response acquisition ended"); + $finish(); + end + end while(AcqTrig_T == 1'b0); + + acqCnt = 0; + + $display(""); + $display("------------------------------------------------"); + $display("%s", TestName_T); + $display("------------------------------------------------"); + $display(""); + + $display("checking %00d vectors",NumStim_T); + $display(""); + + do begin + + OutRdy_SI = 1'b1; + + applWait(Clk_CI, InVld_SI); + + OpCode_tmp = OpCode_SI; + OpA_tmp = OpA_T; + OpB_tmp = OpB_T; + + ////////////////////////// + // udiv / udiv + if(OpCode_SI[1] == 1'b0) + begin + + res = OpA_tmp/OpB_tmp; + + if((OpB_tmp == 0) && (OpCode_SI[0] == 0)) + begin + res = 2**C_WIDTH-1; + end + else if ((OpB_tmp == 0) && (OpCode_SI[0] == 1'b1)) + begin + res = -1; + end + else if ((OpA_tmp == -(2**(C_WIDTH-1))) && (OpB_tmp == -1) && (OpCode_SI[0] == 1'b1)) + begin + res = -(2**(C_WIDTH-1)); + end + + acqWait(Clk_CI, OutVld_SO); + + // interpret result correctly! + if (OpCode_tmp[0] == 1'b1) + act = $signed(Res_DO); + else + act = $unsigned(Res_DO); + + if(res !== act) + begin + $display("vector %d> %d / %d = %d != %d -> error!",acqCnt,OpA_tmp,OpB_tmp,res,act); + errCnt++; + $stop(); + end else + begin + $display("vector %d> %d / %d = %d == %d ",acqCnt,OpA_tmp,OpB_tmp,res,act); + end + ////////////////////////// + // rem / urem + end else if(OpCode_SI[1] == 1'b1) + begin + + res = OpA_tmp % OpB_tmp; + + if((OpB_tmp == 0)) + begin + res = OpA_tmp; + end + + acqWait(Clk_CI, OutVld_SO); + + // interpret result correctly! + if (OpCode_tmp[0] == 1'b1) + act = $signed(Res_DO); + else + act = $unsigned(Res_DO); + + if(res !== act) + begin + $display("vector %d> %d mod %d = %d != %d -> error!",acqCnt,OpA_tmp,OpB_tmp, res,act); + errCnt++; + $stop(); + end else + begin + $display("vector %d> %d mod %d = %d == %d ",acqCnt,OpA_tmp,OpB_tmp,res,act); + end + end + // status + acqCnt++; + end + while (acqCnt < NumStim_T); + + + end + /////////////////////////////////////////////// + + + + EndOfSim_T <= 1; + $display("response acquisition ended"); + $finish(); + /////////////////////////////////////////////// + + end + +endmodule diff --git a/tb/serDiv/tb_div.sv b/tb/serDiv/tb_div.sv new file mode 100644 index 00000000..581672af --- /dev/null +++ b/tb/serDiv/tb_div.sv @@ -0,0 +1,188 @@ +/////////////////////////////////////////////// +// unsigned division test + +// init +NumStim_T = 5+1000; + +TestName_T = "div test"; + +AcqTrig_T <= 1; +applWaitCyc(Clk_CI,2); +AcqTrig_T <= 0; +applWaitCyc(Clk_CI,2); + +/////////////////////////////////////////////// +applWait(Clk_CI, OutVld_SO); + +OpCode_SI = 1; + +OpA_T = 100; +OpB_T = -10; + +OpA_DI = OpA_T; +OpB_DI = OpB_T; +OpBSign_SI = (OpB_T & (1<<(C_WIDTH-1))) > 0; + +// depending on the sign of B, we have to calculate the shift differently +if (OpBSign_SI == 1'b1) +begin + OpBShift_DI = 31-$clog2((~OpB_DI)+1); +end +else begin + OpBShift_DI = 32-$clog2(OpB_T+1); +end + +OpB_DI = OpB_T << OpBShift_DI; + +InVld_SI = 1; + +applWaitCyc(Clk_CI,1); +/////////////////////////////////////////////// +applWait(Clk_CI, OutVld_SO); + +InVld_SI = 0; + + +OpA_T = -100; +OpB_T = -10; + +OpA_DI = OpA_T; +OpB_DI = OpB_T; +OpBSign_SI = (OpB_T & (1<<(C_WIDTH-1))) > 0; + +// depending on the sign of B, we have to calculate the shift differently +if (OpBSign_SI == 1'b1) +begin + OpBShift_DI = 31-$clog2((~OpB_DI)+1); +end +else begin + OpBShift_DI = 32-$clog2(OpB_T+1); +end + +OpB_DI = OpB_T << OpBShift_DI; + +InVld_SI = 1; + +applWaitCyc(Clk_CI,1); +/////////////////////////////////////////////// +applWait(Clk_CI, OutVld_SO); + +InVld_SI = 0; + + +OpA_T = -100; +OpB_T = 0; + +OpA_DI = OpA_T; +OpB_DI = OpB_T; +OpBSign_SI = (OpB_T & (1<<(C_WIDTH-1))) > 0; + +// depending on the sign of B, we have to calculate the shift differently +if (OpBSign_SI == 1'b1) +begin + OpBShift_DI = 31-$clog2((~OpB_DI)+1); +end +else begin + OpBShift_DI = 32-$clog2(OpB_T+1); +end + +OpB_DI = OpB_T << OpBShift_DI; + +InVld_SI = 1; + +applWaitCyc(Clk_CI,1); +/////////////////////////////////////////////// +applWait(Clk_CI, OutVld_SO); + +InVld_SI = 0; + + +OpA_T = -(2**(C_WIDTH-1)); +OpB_T = 1; + +OpA_DI = OpA_T; +OpB_DI = OpB_T; +OpBSign_SI = (OpB_T & (1<<(C_WIDTH-1))) > 0; + +// depending on the sign of B, we have to calculate the shift differently +if (OpBSign_SI == 1'b1) +begin + OpBShift_DI = 31-$clog2((~OpB_DI)+1); +end +else begin + OpBShift_DI = 32-$clog2(OpB_T+1); +end + +OpB_DI = OpB_T << OpBShift_DI; + +InVld_SI = 1; + +applWaitCyc(Clk_CI,1); +/////////////////////////////////////////////// +applWait(Clk_CI, OutVld_SO); + +InVld_SI = 0; + + +OpA_T = -(2**(C_WIDTH-1)); +OpB_T = -1; + +OpA_DI = OpA_T; +OpB_DI = OpB_T; +OpBSign_SI = (OpB_T & (1<<(C_WIDTH-1))) > 0; + +// depending on the sign of B, we have to calculate the shift differently +if (OpBSign_SI == 1'b1) +begin + OpBShift_DI = 31-$clog2((~OpB_DI)+1); +end +else begin + OpBShift_DI = 32-$clog2(OpB_T+1); +end + +OpB_DI = OpB_T << OpBShift_DI; + +InVld_SI = 1; + +applWaitCyc(Clk_CI,1); +applWait(Clk_CI, OutVld_SO); + +InVld_SI = 0; + + +//////////////////// +// a couple of random stimuli + +for (k = 0; k < 1000; k++) begin + + + ok = randomize(OpA_T) with {OpA_T>=(-2**(C_WIDTH-1)); OpA_T<=(2**(C_WIDTH-1)-1);}; + ok = randomize(OpB_T) with {OpB_T>=(-2**(C_WIDTH-1)); OpB_T<=(2**(C_WIDTH-1)-1);}; + + OpA_DI = OpA_T; + OpB_DI = OpB_T; + OpBSign_SI = (OpB_T & (1<<(C_WIDTH-1))) > 0; + + // depending on the sign of B, we have to calculate the shift differently + if (OpBSign_SI == 1'b1) + begin + OpBShift_DI = 31-$clog2((~OpB_DI)+1); + end + else begin + OpBShift_DI = 32-$clog2(OpB_T+1); + end + + OpB_DI = OpB_T << OpBShift_DI; + + InVld_SI = 1; + + applWaitCyc(Clk_CI,1); + applWait(Clk_CI, OutVld_SO); + + InVld_SI = 0; + +end + +applWaitCyc(Clk_CI, 100); + +/////////////////////////////////////////////// diff --git a/tb/serDiv/tb_rem.sv b/tb/serDiv/tb_rem.sv new file mode 100644 index 00000000..2a94fea9 --- /dev/null +++ b/tb/serDiv/tb_rem.sv @@ -0,0 +1,183 @@ +/////////////////////////////////////////////// +// unsigned division test + +// init +NumStim_T = 5+1000; + +TestName_T = "rem test"; + +AcqTrig_T <= 1; +applWaitCyc(Clk_CI,2); +AcqTrig_T <= 0; +applWaitCyc(Clk_CI,2); + +/////////////////////////////////////////////// +applWait(Clk_CI, OutVld_SO); + +OpCode_SI = 3; + +OpA_T = 100; +OpB_T = -10; + +OpA_DI = OpA_T; +OpB_DI = OpB_T; +OpBSign_SI = (OpB_T & (1<<(C_WIDTH-1))) > 0; + +// depending on the sign of B, we have to calculate the shift differently +if (OpBSign_SI == 1'b1) +begin + OpBShift_DI = 31-$clog2((~OpB_DI)+1); +end +else begin + OpBShift_DI = 32-$clog2(OpB_T+1); +end + +OpB_DI = OpB_T << OpBShift_DI; + +InVld_SI = 1; + +applWaitCyc(Clk_CI,1); +/////////////////////////////////////////////// +applWait(Clk_CI, OutVld_SO); + +InVld_SI = 0; + +OpA_T = -100; +OpB_T = -10; + +OpA_DI = OpA_T; +OpB_DI = OpB_T; +OpBSign_SI = (OpB_T & (1<<(C_WIDTH-1))) > 0; + +// depending on the sign of B, we have to calculate the shift differently +if (OpBSign_SI == 1'b1) +begin + OpBShift_DI = 31-$clog2((~OpB_DI)+1); +end +else begin + OpBShift_DI = 32-$clog2(OpB_T+1); +end + +OpB_DI = OpB_T << OpBShift_DI; + +InVld_SI = 1; + +applWaitCyc(Clk_CI,1); +/////////////////////////////////////////////// +applWait(Clk_CI, OutVld_SO); + +InVld_SI = 0; + +OpA_T = -100; +OpB_T = 0; + +OpA_DI = OpA_T; +OpB_DI = OpB_T; +OpBSign_SI = (OpB_T & (1<<(C_WIDTH-1))) > 0; + +// depending on the sign of B, we have to calculate the shift differently +if (OpBSign_SI == 1'b1) +begin + OpBShift_DI = 31-$clog2((~OpB_DI)+1); +end +else begin + OpBShift_DI = 32-$clog2(OpB_T+1); +end + +OpB_DI = OpB_T << OpBShift_DI; + +InVld_SI = 1; + +applWaitCyc(Clk_CI,1); +/////////////////////////////////////////////// +applWait(Clk_CI, OutVld_SO); + +InVld_SI = 0; + +OpA_T = -(2**(C_WIDTH-1)); +OpB_T = 1; + +OpA_DI = OpA_T; +OpB_DI = OpB_T; +OpBSign_SI = (OpB_T & (1<<(C_WIDTH-1))) > 0; + +// depending on the sign of B, we have to calculate the shift differently +if (OpBSign_SI == 1'b1) +begin + OpBShift_DI = 31-$clog2((~OpB_DI)+1); +end +else begin + OpBShift_DI = 32-$clog2(OpB_T+1); +end + +OpB_DI = OpB_T << OpBShift_DI; + +InVld_SI = 1; + +applWaitCyc(Clk_CI,1); +/////////////////////////////////////////////// +applWait(Clk_CI, OutVld_SO); + +InVld_SI = 0; + +OpA_T = -(2**(C_WIDTH-1)); +OpB_T = -1; + +OpA_DI = OpA_T; +OpB_DI = OpB_T; +OpBSign_SI = (OpB_T & (1<<(C_WIDTH-1))) > 0; + +// depending on the sign of B, we have to calculate the shift differently +if (OpBSign_SI == 1'b1) +begin + OpBShift_DI = 31-$clog2((~OpB_DI)+1); +end +else begin + OpBShift_DI = 32-$clog2(OpB_T+1); +end + +OpB_DI = OpB_T << OpBShift_DI; + +InVld_SI = 1; + +applWaitCyc(Clk_CI,1); +//////////////////// +applWait(Clk_CI, OutVld_SO); +InVld_SI = 0; + + +//////////////////// +// a couple of random stimuli + +for (k = 0; k < 1000; k++) begin + + ok = randomize(OpA_T) with {OpA_T>=(-2**(C_WIDTH-1)); OpA_T<=(2**(C_WIDTH-1)-1);}; + ok = randomize(OpB_T) with {OpB_T>=(-2**(C_WIDTH-1)); OpB_T<=(2**(C_WIDTH-1)-1);}; + + OpA_DI = OpA_T; + OpB_DI = OpB_T; + OpBSign_SI = (OpB_T & (1<<(C_WIDTH-1))) > 0; + + // depending on the sign of B, we have to calculate the shift differently + if (OpBSign_SI == 1'b1) + begin + OpBShift_DI = 31-$clog2((~OpB_DI)+1); + end + else begin + OpBShift_DI = 32-$clog2(OpB_T+1); + end + + OpB_DI = OpB_T << OpBShift_DI; + + InVld_SI = 1; + + applWaitCyc(Clk_CI,1); + applWait(Clk_CI, OutVld_SO); + + InVld_SI = 0; + +end + +applWaitCyc(Clk_CI, 100); + +/////////////////////////////////////////////// diff --git a/tb/serDiv/tb_udiv.sv b/tb/serDiv/tb_udiv.sv new file mode 100644 index 00000000..5fb40d3e --- /dev/null +++ b/tb/serDiv/tb_udiv.sv @@ -0,0 +1,126 @@ +/////////////////////////////////////////////// +// unsigned division test + +// init +NumStim_T = 6+1000; + +TestName_T = "udiv test"; + +AcqTrig_T <= 1; +applWaitCyc(Clk_CI,2); +AcqTrig_T <= 0; +applWaitCyc(Clk_CI,2); + +/////////////////////////////////////////////// +applWait(Clk_CI, OutVld_SO); + +OpBSign_SI = 0; +OpCode_SI = 0; + +OpA_T = 100; +OpB_T = 2; + +OpA_DI = OpA_T; +OpBShift_DI = 32-$clog2(OpB_T+1); +OpB_DI = OpB_T << OpBShift_DI; +InVld_SI = 1; + +applWaitCyc(Clk_CI,1); +//////////////////// +applWait(Clk_CI, OutVld_SO); + +InVld_SI = 0; + +OpA_T = 2**32-1; +OpB_T = 1; + +OpA_DI = OpA_T; +OpBShift_DI = 32-$clog2(OpB_T+1); +OpB_DI = OpB_T << OpBShift_DI; +InVld_SI = 1; + +applWaitCyc(Clk_CI,1); +//////////////////// +applWait(Clk_CI, OutVld_SO); + +InVld_SI = 0; + +OpA_T = 1; +OpB_T = 2**32-1; + +OpA_DI = OpA_T; +OpBShift_DI = 32-$clog2(OpB_T+1); +OpB_DI = OpB_T << OpBShift_DI; +InVld_SI = 1; + +applWaitCyc(Clk_CI,1); +//////////////////// +applWait(Clk_CI, OutVld_SO); + +InVld_SI = 0; + +OpA_T = 0; +OpB_T = 5456; + +OpA_DI = OpA_T; +OpBShift_DI = 32-$clog2(OpB_T+1); +OpB_DI = OpB_T << OpBShift_DI; +InVld_SI = 1; + +applWaitCyc(Clk_CI,1); +//////////////////// +applWait(Clk_CI, OutVld_SO); + +InVld_SI = 0; + +OpA_T = 875; +OpB_T = 0; + +OpA_DI = OpA_T; +OpBShift_DI = 32-$clog2(OpB_T+1); +OpB_DI = OpB_T << OpBShift_DI; +InVld_SI = 1; + +applWaitCyc(Clk_CI,1); +//////////////////// +applWait(Clk_CI, OutVld_SO); + +InVld_SI = 0; + +OpA_T = 0; +OpB_T = 0; + +OpA_DI = OpA_T; +OpBShift_DI = 32-$clog2(OpB_T+1); +OpB_DI = OpB_T << OpBShift_DI; +InVld_SI = 1; + +applWaitCyc(Clk_CI,1); +//////////////////// +applWait(Clk_CI, OutVld_SO); +InVld_SI = 0; + + +//////////////////// +// a couple of random stimuli + +for (k = 0; k < 1000; k++) begin + + ok = randomize(OpA_T) with {OpA_T>=0; OpA_T<=2**C_WIDTH-1;}; + ok = randomize(OpB_T) with {OpB_T>=0; OpB_T<=2**C_WIDTH-1;}; + + OpA_DI = OpA_T; + OpBShift_DI = 32-$clog2(OpB_T+1); + OpB_DI = OpB_T << OpBShift_DI; + InVld_SI = 1; + + applWaitCyc(Clk_CI,1); + applWait(Clk_CI, OutVld_SO); + + InVld_SI = 0; + +end + +applWaitCyc(Clk_CI, 100); + +/////////////////////////////////////////////// diff --git a/tb/serDiv/tb_urem.sv b/tb/serDiv/tb_urem.sv new file mode 100644 index 00000000..48c435fa --- /dev/null +++ b/tb/serDiv/tb_urem.sv @@ -0,0 +1,125 @@ +/////////////////////////////////////////////// +// unsigned division test + +// init +NumStim_T = 6+1000; + +TestName_T = "urem test"; + +AcqTrig_T <= 1; +applWaitCyc(Clk_CI,2); +AcqTrig_T <= 0; +applWaitCyc(Clk_CI,2); + +/////////////////////////////////////////////// + +OpBSign_SI = 0; +OpCode_SI = 2; + +OpA_T = 100; +OpB_T = 2; + +OpA_DI = OpA_T; +OpBShift_DI = 32-$clog2(OpB_T+1); +OpB_DI = OpB_T << OpBShift_DI; +InVld_SI = 1; + +applWaitCyc(Clk_CI,1); +//////////////////// +applWait(Clk_CI, OutVld_SO); + +InVld_SI = 0; + +OpA_T = 2**32-1; +OpB_T = 1; + +OpA_DI = OpA_T; +OpBShift_DI = 32-$clog2(OpB_T+1); +OpB_DI = OpB_T << OpBShift_DI; +InVld_SI = 1; + +applWaitCyc(Clk_CI,1); +//////////////////// +applWait(Clk_CI, OutVld_SO); + +InVld_SI = 0; + +OpA_T = 1; +OpB_T = 2**32-1; + +OpA_DI = OpA_T; +OpBShift_DI = 32-$clog2(OpB_T+1); +OpB_DI = OpB_T << OpBShift_DI; +InVld_SI = 1; + +applWaitCyc(Clk_CI,1); +//////////////////// +applWait(Clk_CI, OutVld_SO); + +InVld_SI = 0; + +OpA_T = 0; +OpB_T = 5456; + +OpA_DI = OpA_T; +OpBShift_DI = 32-$clog2(OpB_T+1); +OpB_DI = OpB_T << OpBShift_DI; +InVld_SI = 1; + +applWaitCyc(Clk_CI,1); +//////////////////// +applWait(Clk_CI, OutVld_SO); + +InVld_SI = 0; + +OpA_T = 875; +OpB_T = 0; + +OpA_DI = OpA_T; +OpBShift_DI = 32-$clog2(OpB_T+1); +OpB_DI = OpB_T << OpBShift_DI; +InVld_SI = 1; + +applWaitCyc(Clk_CI,1); +//////////////////// +applWait(Clk_CI, OutVld_SO); + +InVld_SI = 0; + +OpA_T = 0; +OpB_T = 0; + +OpA_DI = OpA_T; +OpBShift_DI = 32-$clog2(OpB_T+1); +OpB_DI = OpB_T << OpBShift_DI; +InVld_SI = 1; + +applWaitCyc(Clk_CI,1); + +applWait(Clk_CI, OutVld_SO); +InVld_SI = 0; + +//////////////////// +// a couple of random stimuli + +for (k = 0; k < 1000; k++) begin + + applWait(Clk_CI, OutVld_SO); + + ok = randomize(OpA_T) with {OpA_T>=0; OpA_T<=2**C_WIDTH-1;}; + ok = randomize(OpB_T) with {OpB_T>=0; OpB_T<=2**C_WIDTH-1;}; + + OpA_DI = OpA_T; + OpBShift_DI = 32-$clog2(OpB_T+1); + OpB_DI = OpB_T << OpBShift_DI; + InVld_SI = 1; + + applWaitCyc(Clk_CI,1); + applWait(Clk_CI, OutVld_SO); + + InVld_SI = 0; + +end + +applWaitCyc(Clk_CI,100); +///////////////////////////////////////////////