📄 cordic_par_seq_apb_testcase.v
字号:
`timescale 1ns/1ns
module CORDIC_par_seq_APB_testcase
#(parameter
IObase = 16'hFE00,
random_seed = 42,
TestIterations = 15,
timeout = 200 // used in await()
)
();
localparam
adr_cmd = IObase+0,
adr_status = IObase+0,
adr_angle = IObase+1,
adr_x = IObase+2,
adr_y = IObase+3,
CYCLE_GAP = 1,
POLLING_GAP = 3,
TRANSACTION_GAP = 5,
TOLERANCE = 4;
const real
MAX_CORDIC_GROWTH = 2.3288707;
// localparam signed [15:0] // type seems to have no effect
const int
MIN_sdata = -32768, //{1'b1, {($bits(T_sdata)-1){1'b0}}},
MAX_sdata = ~MIN_sdata,
MIN_input = $rtoi($itor(MIN_sdata) / MAX_CORDIC_GROWTH),
MAX_input = $rtoi($itor(MAX_sdata) / MAX_CORDIC_GROWTH);
int seed = random_seed;
initial begin
$display ("MIN=%d (0x%x), MAX=%d (0x%x)", MIN_sdata, MIN_sdata, MAX_sdata, MAX_sdata);
end
// __________________________________________________________________
//
initial begin : TestSequence
// Do a reset
TestMaster.reset(4);
// Wait for a few clocks
TestMaster.idle(3);
repeat (TestIterations) begin : TestLoop
TestOperation(
$dist_uniform(seed, 0, 1), // reduce
$dist_uniform(seed, MIN_sdata, MAX_sdata), // angle
$dist_uniform(seed, MIN_input, MAX_input), // x
$dist_uniform(seed, MIN_input, MAX_input), // y
$dist_uniform(seed, 0, 2*CYCLE_GAP ), // meanCycleGap
$dist_uniform(seed, 0, 2*POLLING_GAP) // meanPollGap
);
TestMaster.idle($dist_uniform(seed, 0, 2*TRANSACTION_GAP));
end // TestLoop
$display("");
$stop;
end // TestSequence
// __________________________________________________________________
task TestOperation (
input bit reduce,
input T_sdata angle,
input T_sdata x,
input T_sdata y,
input int meanCycleGap,
input int meanPollGap
);
T_sdata
expAngle, expX, expY, // expected results from C model
hwAngle, hwX, hwY; // actual results from hardware
// Evaluate expected result
//
vlog_CORDIC_model(reduce, angle, x, y, expAngle, expX, expY);
// Report input and expected values
//
$display("Started: a=%d, x=%d, y=%d, reduce=%b, time=%t",
angle, x, y, reduce, $time);
$display("Expected: a=%d, x=%d, y=%d",
expAngle,expX,expY);
// Get the hardware to do it
//
RunOperation (
reduce, angle, x, y,
meanCycleGap, meanPollGap,
hwAngle, hwX, hwY
);
// Report hardware results
//
$display("Hardware: a=%d, x=%d, y=%d, time=%t",
hwAngle, hwX, hwY, $time);
if (! (close_enough(hwAngle, expAngle, TOLERANCE) &&
close_enough(hwX, expX, TOLERANCE) &&
close_enough(hwY, expY, TOLERANCE)
))
$display("!! ************************ !!");
$display("---------------------------------------------------------");
endtask // TestOperation
// __________________________________________________________________
// Tasks to encapsulate parts of the test sequence
task RunOperation (
input bit reduce,
input T_sdata angle,
input T_sdata x,
input T_sdata y,
input int meanCycleGap,
input int meanPollGap,
output T_sdata hwAngle,
output T_sdata hwX,
output T_sdata hwY
);
loadInputs (reduce, angle, x, y, meanCycleGap);
await (meanPollGap);
readResults (hwAngle, hwX, hwY, meanCycleGap);
endtask // RunOperation
// __________________________________________________________________
task readResults (
output T_sdata angle, x, y,
input int gap
);
TestMaster.read ( adr_angle, angle );
TestMaster.idle(poisson(gap));
TestMaster.read ( adr_x, x );
TestMaster.idle(poisson(gap));
TestMaster.read ( adr_y, y );
endtask // readResults
// __________________________________________________________________
task loadInputs (
input logic reduce,
input T_sdata angle, x, y,
input int gap
);
TestMaster.write ( adr_angle, angle );
TestMaster.idle(poisson(gap));
TestMaster.write ( adr_x, x );
TestMaster.idle(poisson(gap));
TestMaster.write ( adr_y, y );
TestMaster.idle(poisson(gap));
start ( reduce );
endtask // loadInputs
// __________________________________________________________________
task start (
input bit reduceNotRotate
);
TestMaster.write ( adr_cmd, {15'b0, reduceNotRotate} );
endtask // start
// __________________________________________________________________
task await (
input int poll_interval
);
logic busy;
time limit;
limit = $time + timeout;
do begin
TestMaster.idle ( poisson(poll_interval) );
TestMaster.read ( adr_status, busy );
end while ( busy && ($time < limit) );
if (busy) begin
$display("Error: await() timed out in %m at time %0d", $time);
$stop;
$finish;
end
endtask // await
// __________________________________________________________________
function int poisson(int n);
int seed = 42;
if (n==0)
return 0;
else
return $dist_poisson(seed, n);
endfunction // poisson
// __________________________________________________________________
function int abs(int a);
if (a<0)
return (-a);
else
return a;
endfunction // abs
// __________________________________________________________________
function bit close_enough(int a, int b, int limit);
return (abs(a-b) < limit);
endfunction // close_enough
// __________________________________________________________________
endmodule // CORDIC_par_seq_APB_testcase
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -