Sunday, August 17, 2014

SystemVerilog: Clocking block + assert statements

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

No comments:

Post a Comment