add SV example
This commit is contained in:
+56
@@ -0,0 +1,56 @@
|
||||
module counter_assertion(clk, rst, data, updown, load, count);
|
||||
|
||||
input logic clk, rst;
|
||||
input logic updown, load;
|
||||
input logic [3:0] data, count;
|
||||
|
||||
|
||||
property reset_prpty;
|
||||
@(posedge clk) rst |=> (count == 4'b0);
|
||||
endproperty
|
||||
|
||||
sequence up_seq;
|
||||
!load && updown;
|
||||
endsequence
|
||||
|
||||
sequence down_seq;
|
||||
!load && !updown;
|
||||
endsequence
|
||||
|
||||
property up_count_prpty;
|
||||
@(posedge clk) disable iff(rst)
|
||||
up_seq |=> (count == ($past(count, 1) + 1'b1));
|
||||
endproperty
|
||||
|
||||
property down_count_prpty;
|
||||
@(posedge clk) disable iff(rst)
|
||||
down_seq |=> (count == ($past(count, 1) - 1'b1));
|
||||
endproperty
|
||||
|
||||
property count_Fto0_prpty;
|
||||
@(posedge clk) disable iff(rst)
|
||||
(!load && updown) && (count == 4'hF) |=> (count == 4'b0);
|
||||
endproperty
|
||||
|
||||
property count_0toF_prpty;
|
||||
@(posedge clk) disable iff(rst)
|
||||
(!load && !updown) && (count == 4'b0) |=> (count == 4'hF);
|
||||
endproperty
|
||||
|
||||
property load_prpty;
|
||||
@(posedge clk) disable iff(rst)
|
||||
load |=> (count == $past(data, 1));
|
||||
endproperty
|
||||
|
||||
|
||||
|
||||
|
||||
RST: assert property (reset_prpty);
|
||||
UP_COUNT: assert property (up_count_prpty);
|
||||
DOWN_COUNT: assert property (down_count_prpty);
|
||||
F2O: assert property (count_Fto0_prpty);
|
||||
O2F: assert property (count_0toF_prpty);
|
||||
LOAD: assert property (load_prpty);
|
||||
|
||||
endmodule
|
||||
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
class counter_env;
|
||||
|
||||
virtual counter_if.WR_BFM wr_if;
|
||||
virtual counter_if.WR_MON wrmon_if;
|
||||
virtual counter_if.RD_MON rdmon_if;
|
||||
|
||||
mailbox #(counter_trans) gen2wr = new;
|
||||
mailbox #(counter_trans) wrmon2rm = new;
|
||||
mailbox #(counter_trans) rm2sb = new;
|
||||
mailbox #(counter_trans) rdmon2sb = new;
|
||||
|
||||
counter_gen gen_h;
|
||||
counter_wr_bfm wr_h;
|
||||
counter_wr_mon wrmon_h;
|
||||
counter_rd_mon rdmon_h;
|
||||
counter_rm rm_h;
|
||||
counter_sb sb_h;
|
||||
|
||||
function new( virtual counter_if.WR_BFM wr_if,
|
||||
virtual counter_if.WR_MON wrmon_if,
|
||||
virtual counter_if.RD_MON rdmon_if);
|
||||
this.wr_if = wr_if;
|
||||
this.wrmon_if = wrmon_if;
|
||||
this.rdmon_if = rdmon_if;
|
||||
endfunction
|
||||
|
||||
|
||||
task build();
|
||||
gen_h = new(gen2wr);
|
||||
wr_h = new(wr_if, gen2wr);
|
||||
wrmon_h = new(wrmon_if, wrmon2rm);
|
||||
rdmon_h = new(rdmon_if, rdmon2sb);
|
||||
rm_h = new(wrmon2rm, rm2sb);
|
||||
sb_h = new(rm2sb, rdmon2sb);
|
||||
endtask
|
||||
|
||||
task reset();
|
||||
@(wr_if.wr_cb);
|
||||
wr_if.wr_cb.rst <= 1;
|
||||
@(wr_if.wr_cb);
|
||||
@(wr_if.wr_cb);
|
||||
@(wr_if.wr_cb);
|
||||
@(wr_if.wr_cb);
|
||||
@(wr_if.wr_cb);
|
||||
wr_if.wr_cb.rst <= 0;
|
||||
|
||||
endtask
|
||||
|
||||
task start();
|
||||
gen_h.start();
|
||||
wr_h.start();
|
||||
wrmon_h.start();
|
||||
rdmon_h.start();
|
||||
rm_h.start();
|
||||
sb_h.start();
|
||||
endtask
|
||||
|
||||
task stop();
|
||||
wait(sb_h.DONE.triggered);
|
||||
endtask
|
||||
|
||||
task run();
|
||||
reset();
|
||||
start();
|
||||
stop();
|
||||
sb_h.report();
|
||||
endtask
|
||||
|
||||
endclass: counter_env
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
class counter_gen;
|
||||
|
||||
counter_trans trans_h;
|
||||
counter_trans trans2wr_h;
|
||||
|
||||
mailbox #(counter_trans) gen2wr;
|
||||
|
||||
function new(mailbox #(counter_trans) gen2wr);
|
||||
this.gen2wr = gen2wr;
|
||||
trans_h = new;
|
||||
endfunction
|
||||
|
||||
virtual task start();
|
||||
fork
|
||||
begin
|
||||
trans_h.trans_id++;
|
||||
trans_h.load = 1;
|
||||
trans_h.data = 0;
|
||||
trans2wr_h = new trans_h;
|
||||
gen2wr.put(trans2wr_h);
|
||||
|
||||
for(int i = 0; i < (no_of_transaction - 1); i++)
|
||||
begin
|
||||
trans_h.trans_id++;
|
||||
assert(trans_h.randomize());
|
||||
trans2wr_h = new trans_h;
|
||||
gen2wr.put(trans2wr_h);
|
||||
end
|
||||
end
|
||||
join_none
|
||||
endtask
|
||||
|
||||
endclass: counter_gen
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
interface counter_if(input logic clk);
|
||||
|
||||
logic rst, updown, load;
|
||||
logic [3:0] data;
|
||||
logic [3:0] data_out;
|
||||
|
||||
clocking wr_cb@(posedge clk);
|
||||
output load, updown, rst;
|
||||
output data;
|
||||
endclocking
|
||||
|
||||
clocking wrmon_cb@(posedge clk);
|
||||
input data;
|
||||
input load, rst, updown;
|
||||
endclocking
|
||||
|
||||
clocking rdmon_cb@(posedge clk);
|
||||
input data_out;
|
||||
endclocking
|
||||
|
||||
modport WR_BFM(clocking wr_cb);
|
||||
modport WR_MON(clocking wrmon_cb);
|
||||
modport RD_MON(clocking rdmon_cb);
|
||||
|
||||
endinterface: counter_if
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package counter_pkg;
|
||||
|
||||
int no_of_transaction;
|
||||
|
||||
`include "counter_trans.sv"
|
||||
`include "counter_gen.sv"
|
||||
`include "counter_wr_bfm.sv"
|
||||
`include "counter_wr_mon.sv"
|
||||
`include "counter_rd_mon.sv"
|
||||
`include "counter_rm.sv"
|
||||
`include "counter_sb.sv"
|
||||
`include "counter_env.sv"
|
||||
|
||||
endpackage
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
class counter_rd_mon;
|
||||
|
||||
virtual counter_if.RD_MON rdmon_if;
|
||||
|
||||
mailbox #(counter_trans) rdmon2sb;
|
||||
|
||||
counter_trans trans_h;
|
||||
counter_trans rd2sb_h;
|
||||
|
||||
function new( virtual counter_if.RD_MON rdmon_if,
|
||||
mailbox #(counter_trans) rdmon2sb);
|
||||
this.rdmon_if = rdmon_if;
|
||||
this.rdmon2sb = rdmon2sb;
|
||||
trans_h = new;
|
||||
endfunction
|
||||
|
||||
task monitor();
|
||||
@(rdmon_if.rdmon_cb)
|
||||
trans_h.data_out = rdmon_if.rdmon_cb.data_out;
|
||||
if($isunknown(rdmon_if.rdmon_cb.data_out))
|
||||
trans_h.data_out = 0;
|
||||
endtask
|
||||
|
||||
task start();
|
||||
fork
|
||||
forever
|
||||
begin
|
||||
monitor();
|
||||
trans_h.display("DATA FROM READ MONITOR");
|
||||
rd2sb_h = new trans_h;
|
||||
rdmon2sb.put(rd2sb_h);
|
||||
end
|
||||
join_none
|
||||
endtask
|
||||
|
||||
endclass: counter_rd_mon
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
class counter_rm;
|
||||
|
||||
mailbox #(counter_trans) rm2sb, wrmon2rm;
|
||||
|
||||
counter_trans wrmon2rm_h, temp_h;
|
||||
|
||||
int count;
|
||||
|
||||
function new(mailbox #(counter_trans) wrmon2rm, mailbox #(counter_trans) rm2sb);
|
||||
this.rm2sb = rm2sb;
|
||||
this.wrmon2rm = wrmon2rm;
|
||||
temp_h = new();
|
||||
endfunction
|
||||
|
||||
task model();
|
||||
++count;
|
||||
if(count > 1)
|
||||
begin
|
||||
temp_h.rst = wrmon2rm_h.rst;
|
||||
temp_h.load = wrmon2rm_h.load;
|
||||
temp_h.updown = wrmon2rm_h.updown;
|
||||
temp_h.data = wrmon2rm_h.data;
|
||||
if(wrmon2rm_h.rst)
|
||||
temp_h.data_out = 0;
|
||||
else if(wrmon2rm_h.load)
|
||||
temp_h.data_out = wrmon2rm_h.data;
|
||||
else if(wrmon2rm_h.updown)
|
||||
temp_h.data_out = ++temp_h.data_out;
|
||||
else if(!wrmon2rm_h.updown)
|
||||
temp_h.data_out = --temp_h.data_out;
|
||||
end
|
||||
endtask
|
||||
|
||||
task start();
|
||||
fork
|
||||
forever
|
||||
begin
|
||||
wrmon2rm.get(wrmon2rm_h);
|
||||
rm2sb.put(temp_h);
|
||||
temp_h = new temp_h;
|
||||
model();
|
||||
end
|
||||
join_none
|
||||
endtask
|
||||
|
||||
endclass :counter_rm
|
||||
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
class counter_sb;
|
||||
|
||||
mailbox #(counter_trans) rm2sb, rdmon2sb;
|
||||
|
||||
event DONE;
|
||||
|
||||
int count_transaction, data_verified;
|
||||
|
||||
counter_trans cov_h, rcvd_h;
|
||||
|
||||
covergroup counter_cov;
|
||||
option.per_instance = 1;
|
||||
RST: coverpoint cov_h.rst {bins r[] = {0,1};}
|
||||
LD: coverpoint cov_h.load {bins l[] = {0,1};}
|
||||
UD: coverpoint cov_h.updown {bins ud[] = {0,1};}
|
||||
DATA: coverpoint cov_h.data {bins d[] = {[0:15]};}
|
||||
DOUT: coverpoint cov_h.data_out {bins dout[] = {[0:15]};}
|
||||
|
||||
LDxDATA: cross LD, DATA;
|
||||
UDxDOUT: cross UD, DOUT;
|
||||
RSTxLDxDATA: cross RST, LD, DATA;
|
||||
RSTxLDxUD: cross RST, LD, UD;
|
||||
endgroup
|
||||
|
||||
function new(mailbox #(counter_trans) rm2sb, mailbox #(counter_trans) rdmon2sb);
|
||||
this.rm2sb = rm2sb;
|
||||
this.rdmon2sb = rdmon2sb;
|
||||
counter_cov = new();
|
||||
endfunction
|
||||
|
||||
task start;
|
||||
fork
|
||||
forever
|
||||
begin
|
||||
rm2sb.get(rcvd_h);
|
||||
cov_h = rcvd_h;
|
||||
counter_cov.sample();
|
||||
//--------------------//
|
||||
rdmon2sb.get(cov_h);
|
||||
check(rcvd_h);
|
||||
end
|
||||
join_none
|
||||
endtask
|
||||
|
||||
task check(counter_trans rcvd_h);
|
||||
|
||||
count_transaction++;
|
||||
|
||||
if(cov_h.compare(rcvd_h))
|
||||
begin
|
||||
counter_cov.sample();
|
||||
data_verified++;
|
||||
end
|
||||
|
||||
if(count_transaction >= no_of_transaction)
|
||||
->DONE;
|
||||
endtask
|
||||
|
||||
function void report;
|
||||
$display("--------------SCOREBOARD REPORT----------------");
|
||||
$display("Number of transactions received : %0d", count_transaction);
|
||||
$display("Number of transactions verified : %0d", data_verified);
|
||||
$display("-----------------------------------------------");
|
||||
endfunction
|
||||
|
||||
|
||||
|
||||
|
||||
endclass :counter_sb
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
class counter_trans;
|
||||
|
||||
rand bit [3:0] data;
|
||||
rand bit rst;
|
||||
rand bit load;
|
||||
rand bit updown;
|
||||
|
||||
bit [3:0] data_out;
|
||||
|
||||
static int trans_id;
|
||||
|
||||
|
||||
//Constraints to control frequency of reset and load
|
||||
constraint r1{rst dist {0:=50, 1:=1};}
|
||||
constraint l1{load dist {0:=20, 1:=1};}
|
||||
|
||||
function void post_randomize();
|
||||
this.display("RANDOMIZED DATA");
|
||||
endfunction
|
||||
|
||||
function void display(string message);
|
||||
$display("-------------------------------------------------");
|
||||
$display("%s",message);
|
||||
$display("\tTransaction ID: %d", trans_id);
|
||||
$display("\tRESET = %d\n\tLOAD = %d\n\tUP-DOWN = %d\n\tDATA = %d", rst, load, updown, data);
|
||||
$display("-------------------------------------------------");
|
||||
endfunction
|
||||
|
||||
function bit compare(counter_trans rcvd);
|
||||
compare = 1'b1;
|
||||
if(this.data_out != rcvd.data_out)
|
||||
begin
|
||||
compare = 1'b0;
|
||||
$display("DATA MISMATCH");
|
||||
$display(this.data_out, " != ", rcvd.data_out);
|
||||
$stop;
|
||||
end
|
||||
endfunction
|
||||
|
||||
endclass: counter_trans
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
class counter_wr_bfm;
|
||||
|
||||
virtual counter_if.WR_BFM wr_if;
|
||||
|
||||
mailbox #(counter_trans) gen2wr;
|
||||
|
||||
counter_trans trans_h;
|
||||
|
||||
function new( virtual counter_if.WR_BFM wr_if,
|
||||
mailbox #(counter_trans) gen2wr);
|
||||
this.wr_if = wr_if;
|
||||
this.gen2wr = gen2wr;
|
||||
this.trans_h = new;
|
||||
endfunction
|
||||
|
||||
task drive();
|
||||
@(wr_if.wr_cb);
|
||||
wr_if.wr_cb.rst <= trans_h.rst;
|
||||
wr_if.wr_cb.load <= trans_h.load;
|
||||
wr_if.wr_cb.updown <= trans_h.updown;
|
||||
wr_if.wr_cb.data <= trans_h.data;
|
||||
endtask
|
||||
|
||||
task start();
|
||||
fork
|
||||
forever
|
||||
begin
|
||||
gen2wr.get(trans_h);
|
||||
drive();
|
||||
end
|
||||
join_none
|
||||
endtask
|
||||
|
||||
endclass: counter_wr_bfm
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
class counter_wr_mon;
|
||||
|
||||
virtual counter_if.WR_MON wrmon_if;
|
||||
|
||||
mailbox #(counter_trans) wrmon2rm;
|
||||
|
||||
counter_trans trans_h, wrmon2rm_h;
|
||||
|
||||
function new( virtual counter_if.WR_MON wrmon_if,
|
||||
mailbox #(counter_trans) wrmon2rm);
|
||||
this.wrmon_if = wrmon_if;
|
||||
this.wrmon2rm = wrmon2rm;
|
||||
this.trans_h = new;
|
||||
endfunction
|
||||
|
||||
task monitor();
|
||||
@(wrmon_if.wrmon_cb)
|
||||
begin
|
||||
trans_h.rst = wrmon_if.wrmon_cb.rst;
|
||||
trans_h.load = wrmon_if.wrmon_cb.load;
|
||||
trans_h.updown = wrmon_if.wrmon_cb.updown;
|
||||
trans_h.data = wrmon_if.wrmon_cb.data;
|
||||
trans_h.display("DATA FROM WRITE MONITOR");
|
||||
end
|
||||
endtask
|
||||
|
||||
task start();
|
||||
fork
|
||||
forever
|
||||
begin
|
||||
monitor();
|
||||
wrmon2rm_h = new trans_h;
|
||||
wrmon2rm.put(wrmon2rm_h);
|
||||
end
|
||||
join_none
|
||||
endtask
|
||||
|
||||
endclass: counter_wr_mon
|
||||
|
||||
Vendored
+37
@@ -0,0 +1,37 @@
|
||||
`include "test.sv"
|
||||
|
||||
module top;
|
||||
|
||||
reg clk;
|
||||
|
||||
counter_if intf(clk);
|
||||
|
||||
counter DUV( .clk(clk),
|
||||
.rst(intf.rst),
|
||||
.load(intf.load),
|
||||
.updown(intf.updown),
|
||||
.data(intf.data),
|
||||
.data_out(intf.data_out));
|
||||
|
||||
bind DUV counter_assertion C_A( .clk(clk),
|
||||
.rst(intf.rst),
|
||||
.load(intf.load),
|
||||
.updown(intf.updown),
|
||||
.data(intf.data),
|
||||
.count(intf.data_out));
|
||||
|
||||
test test_h;
|
||||
|
||||
initial
|
||||
begin
|
||||
test_h = new(intf, intf, intf);
|
||||
test_h.build_and_run();
|
||||
end
|
||||
|
||||
initial
|
||||
begin
|
||||
clk = 0;
|
||||
forever #10 clk = ~clk;
|
||||
end
|
||||
|
||||
endmodule: top
|
||||
Reference in New Issue
Block a user