Add TB for serial divider

This commit is contained in:
Andreas Traber 2016-03-16 18:53:21 +01:00
parent b35c431632
commit b55241e3da
10 changed files with 1184 additions and 0 deletions

6
tb/serDiv/scripts/compile.sh Executable file
View file

@ -0,0 +1,6 @@
#!/bin/bash
vlib ./work
vlog -sv ../../../alu_div.sv || exit 1
vlog -sv +incdir+../ ../tb.sv || exit 1

53
tb/serDiv/scripts/sim.sh Executable file
View file

@ -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

30
tb/serDiv/scripts/tb.do Normal file
View file

@ -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

View file

@ -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

95
tb/serDiv/scripts/wave.do Normal file
View file

@ -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}

345
tb/serDiv/tb.sv Normal file
View file

@ -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

188
tb/serDiv/tb_div.sv Normal file
View file

@ -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);
///////////////////////////////////////////////

183
tb/serDiv/tb_rem.sv Normal file
View file

@ -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);
///////////////////////////////////////////////

126
tb/serDiv/tb_udiv.sv Normal file
View file

@ -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);
///////////////////////////////////////////////

125
tb/serDiv/tb_urem.sv Normal file
View file

@ -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);
///////////////////////////////////////////////