We will needto add the keyword default before clocking block if we want to use a ##number_of_cycles delay even if we have just 1 clocking block.
Assign values to variables in clocking block by using blocking assignment.
I used this to actually see the effect of each type of clocking block..added this in initial block of testbench:
`ifdef postprocess
$vcdpluson(0,C1);
$vcdplustraceon(C1);
$vcdplusdeltacycleon;
$vcdplusglitchon;
`endif
program automatic testcase #(parameter WIDTH=4)
( input bit clk,
input bit detect,
input logic [WIDTH-1:0] result,
output bit rst,
output bit en,
output bit pld,
output bit mode,
output logic [WIDTH-1:0] preload_data);
`ifdef default_skew
default clocking clk_blk @ (posedge clk);
input detect, result;
output rst, en, pld, mode, preload_data;
endclocking
`endif
`ifdef hash<value>ns_skew
default clocking clk_blk @ (posedge clk);
input #<value1> detect, result;
output #<value2> rst, en, pld, mode, preload_data;
endclocking
`endif
`ifdef 1step_edge_skew
default clocking clk_blk @ (posedge clk);
input #1step detect, result;
output negedge rst, en, pld, mode, preload_data;
endclocking
`endif
initial begin
$monitor ("t=%3t: result=%2d, detect=%b", $time, result, detect);
clk_blk.rst <= 1;
clk_blk.en <= 0;
clk_blk.pld <= 0;
clk_blk.mode <= 0;
repeat (2) @(posedge clk);
clk_blk.rst<=0;
@(posedge clk);
clk_blk.en <= 1;
repeat(17)@(posedge clk);
clk_blk.en <= 0;
repeat (10)@(posedge clk);
$finish;
end
/*Some of the assert statements i used to test different aspects of counter:
assert property (@(posedge clk) result == {WIDTH{1'b1}} -> detect) else flag = 1;
assert property (@(posedge clk) en==0 |=> $stable(result)) else flag = 1;
assert property (@(posedge clk) pld == 1 && en == 1 |=> result == preload_data) else flag = 1;
assert property (@(posedge clk) rst==1 |=> result == {WIDTH{1'b0}}) else flag = 1;
final begin
if (flag) $display ("FAIL");
else $display ("PASS");
end
*/
endprogram
runsim:
if [ -z "$1" ] ##true if len of string is 0
then
echo "No skew specified, using default skews"
vcs -full64 +vcs+lic+wait +v2k -sverilog +lint=PCWM -R +define+default_skew -l vcs.log ../../testbench.sv testcase.sv ../../counter.v
echo "**INFO** Use runsim <skew> to specify skew, valid values for <skew> are default_skew, hash<value>n_skew, 1step_edge_skew"
echo "**INFO** runsim finished test with +define+default_skew"
else
echo $1
vcs -full64 +vcs+lic+wait +v2k -sverilog +lint=PCWM -R +define+$1 -l vcs.log ../../testbench.sv testcase.sv ../../counter.v
echo "**INFO** runsim finished test with +define+$1"
fi
command to run:
runsim <whtever_you_choose_from_default_skew_etc>
Using tasks:
task init(
ref bit clk,
ref bit system_clk,
output bit rst,
output bit en,
output bit pld);
begin
rst <= 1;
en <= 0;
pld <= 0;
end
endtask
`include "tasks.sv"
program automatic testcase #(parameter WIDTH=4)
( ref bit clk, ref bit system_clk,
input bit detect,
input logic [WIDTH-1:0] result,
ref bit rst,
ref bit en,
ref bit pld,
ref bit mode,
output logic [WIDTH-1:0] preload_data);
bit flag;
logic [WIDTH-1:0] X;
default clocking clk_blk @ (posedge clk);
input detect, result;
output rst, en, pld, mode, preload_data;
endclocking
initial begin
$monitor ("t=%3t: en = %b, pld = %b, result=%2d, detect=%b", $time, en, pld, result, detect);
X = $urandom_range(0, {WIDTH{1'b1}});
preload_data = $urandom_range(0, {WIDTH{1'b1}});
init(clk, system_clk, clk_blk.rst, clk_blk.en, clk_blk.pld);
rest of the program follows...
Assign values to variables in clocking block by using blocking assignment.
I used this to actually see the effect of each type of clocking block..added this in initial block of testbench:
`ifdef postprocess
$vcdpluson(0,C1);
$vcdplustraceon(C1);
$vcdplusdeltacycleon;
$vcdplusglitchon;
`endif
program automatic testcase #(parameter WIDTH=4)
( input bit clk,
input bit detect,
input logic [WIDTH-1:0] result,
output bit rst,
output bit en,
output bit pld,
output bit mode,
output logic [WIDTH-1:0] preload_data);
`ifdef default_skew
default clocking clk_blk @ (posedge clk);
input detect, result;
output rst, en, pld, mode, preload_data;
endclocking
`endif
`ifdef hash<value>ns_skew
default clocking clk_blk @ (posedge clk);
input #<value1> detect, result;
output #<value2> rst, en, pld, mode, preload_data;
endclocking
`endif
`ifdef 1step_edge_skew
default clocking clk_blk @ (posedge clk);
input #1step detect, result;
output negedge rst, en, pld, mode, preload_data;
endclocking
`endif
initial begin
$monitor ("t=%3t: result=%2d, detect=%b", $time, result, detect);
clk_blk.rst <= 1;
clk_blk.en <= 0;
clk_blk.pld <= 0;
clk_blk.mode <= 0;
repeat (2) @(posedge clk);
clk_blk.rst<=0;
@(posedge clk);
clk_blk.en <= 1;
repeat(17)@(posedge clk);
clk_blk.en <= 0;
repeat (10)@(posedge clk);
$finish;
end
/*Some of the assert statements i used to test different aspects of counter:
assert property (@(posedge clk) result == {WIDTH{1'b1}} -> detect) else flag = 1;
assert property (@(posedge clk) en==0 |=> $stable(result)) else flag = 1;
assert property (@(posedge clk) pld == 1 && en == 1 |=> result == preload_data) else flag = 1;
assert property (@(posedge clk) rst==1 |=> result == {WIDTH{1'b0}}) else flag = 1;
final begin
if (flag) $display ("FAIL");
else $display ("PASS");
end
*/
endprogram
runsim:
if [ -z "$1" ] ##true if len of string is 0
then
echo "No skew specified, using default skews"
vcs -full64 +vcs+lic+wait +v2k -sverilog +lint=PCWM -R +define+default_skew -l vcs.log ../../testbench.sv testcase.sv ../../counter.v
echo "**INFO** Use runsim <skew> to specify skew, valid values for <skew> are default_skew, hash<value>n_skew, 1step_edge_skew"
echo "**INFO** runsim finished test with +define+default_skew"
else
echo $1
vcs -full64 +vcs+lic+wait +v2k -sverilog +lint=PCWM -R +define+$1 -l vcs.log ../../testbench.sv testcase.sv ../../counter.v
echo "**INFO** runsim finished test with +define+$1"
fi
command to run:
runsim <whtever_you_choose_from_default_skew_etc>
Using tasks:
task init(
ref bit clk,
ref bit system_clk,
output bit rst,
output bit en,
output bit pld);
begin
rst <= 1;
en <= 0;
pld <= 0;
end
endtask
`include "tasks.sv"
program automatic testcase #(parameter WIDTH=4)
( ref bit clk, ref bit system_clk,
input bit detect,
input logic [WIDTH-1:0] result,
ref bit rst,
ref bit en,
ref bit pld,
ref bit mode,
output logic [WIDTH-1:0] preload_data);
bit flag;
logic [WIDTH-1:0] X;
default clocking clk_blk @ (posedge clk);
input detect, result;
output rst, en, pld, mode, preload_data;
endclocking
initial begin
$monitor ("t=%3t: en = %b, pld = %b, result=%2d, detect=%b", $time, en, pld, result, detect);
X = $urandom_range(0, {WIDTH{1'b1}});
preload_data = $urandom_range(0, {WIDTH{1'b1}});
init(clk, system_clk, clk_blk.rst, clk_blk.en, clk_blk.pld);
rest of the program follows...