Browse Source

add SV example

master
Simon Schmidt 2 years ago
parent
commit
c08ef2102f

+ 56
- 0
4-bit-counter-SV-UVM/env/counter_assertion.sv View File

@@ -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
4-bit-counter-SV-UVM/env/counter_env.sv View File

@@ -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
4-bit-counter-SV-UVM/env/counter_gen.sv View File

@@ -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
4-bit-counter-SV-UVM/env/counter_if.sv View File

@@ -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
4-bit-counter-SV-UVM/env/counter_pkg.sv View File

@@ -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
4-bit-counter-SV-UVM/env/counter_rd_mon.sv View File

@@ -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
4-bit-counter-SV-UVM/env/counter_rm.sv View File

@@ -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
4-bit-counter-SV-UVM/env/counter_sb.sv View File

@@ -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
4-bit-counter-SV-UVM/env/counter_trans.sv View File

@@ -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
4-bit-counter-SV-UVM/env/counter_wr_bfm.sv View File

@@ -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
4-bit-counter-SV-UVM/env/counter_wr_mon.sv View File

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


+ 37
- 0
4-bit-counter-SV-UVM/env/top.sv View File

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

+ 25
- 0
4-bit-counter-SV-UVM/rtl/counter.v View File

@@ -0,0 +1,25 @@
//////////////////////////////////////////////////////////////
// 4-bit loadable up-down counter //////
//////////////////////////////////////////////////////////////

module counter(clk, rst, data, updown, load, data_out);
input clk, rst, load;
input updown;
input [3:0] data;

output reg [3:0] data_out;


always@(posedge clk)
begin
if(rst)
data_out <= 4'b0;
else if(load)
data_out <= data;
else
data_out <= ((updown)?(data_out + 1'b1):(data_out -1'b1));
end

endmodule


+ 10
- 0
4-bit-counter-SV-UVM/sim/.gitignore View File

@@ -0,0 +1,10 @@
modelsim.*
transcript*
vlog.*
work/
counter_cov*
fcover*
covhtml*
vcover*
*.log
*.wlf

+ 81
- 0
4-bit-counter-SV-UVM/sim/Makefile View File

@@ -0,0 +1,81 @@
# Makefile for Memory - Regression Testing
RTL= ../rtl/counter.v
work= work #library name
COVOP= -coveropt 3 +cover +acc
SVTB1= ../env/counter_if.sv ../env/counter_assertion.sv ../env/top.sv
INC = +incdir+../env +incdir+../test
SVTB2 = ../env/counter_pkg.sv
TEST = ../test/test.sv
#TEST1 = ../test/test1.sv
#TEST2 = ../test/test2.sv
VSIMOPT= -coverage -novopt -sva -sv_seed 2475652473 work.top
VSIMCOV= coverage save -onexit -assert -directive -cvg -codeAll counter_cov
VSIMBATCH= -c -do "$(VSIMCOV); run -all; exit"
VSIMBATCH1 = -c -do "coverage save -onexit -assert -directive -cvg -codeAll counter_cov1;run -all;exit"
VSIMBATCH2 = -c -do "coverage save -onexit -assert -directive -cvg -codeAll counter_cov2;run -all;exit"
VSIMBATCH3 = -c -do "coverage save -onexit -assert -directive -cvg -codeAll counter_cov3;run -all;exit"
VSIMBATCH4 = -c -do "coverage save -onexit -assert -directive -cvg -codeAll counter_cov4;run -all;exit"
VSIMBATCH5 = -c -do "coverage save -onexit -assert -directive -cvg -codeAll counter_cov5;run -all;exit"
VSIMBATCH6 = -c -do "coverage save -onexit -assert -directive -cvg -codeAll counter_cov6;run -all;exit"
VSIMBATCH7 = -c -do "coverage save -onexit -assert -directive -cvg -codeAll counter_cov7;run -all;exit"
VSIMBATCH8 = -c -do "coverage save -onexit -assert -directive -cvg -codeAll counter_cov8;run -all;exit"
VSIMBATCH9 = -c -do "coverage save -onexit -assert -directive -cvg -codeAll counter_cov9;run -all;exit"


html:
firefox covhtmlreport/menu.html

sv_cmp:
vlib $(work)
vmap work $(work)
vlog -work $(work) $(COVOP) $(RTL) $(SVTB2) $(SVTB1) $(INC) #$(TEST)
run_sim:
vsim $(VSIMBATCH1) $(VSIMOPT) -l test1_sim.log +TEST1 +nowarn3829

run_testg:
vsim -novopt -sva -sv_seed random work.top +TEST1
clear

clean:
rm -rf modelsim.* transcript* vlog.* work vsim.wlf counter_cov* fcover* covhtml* vcover* *.log
clear

TC2:
vsim $(VSIMBATCH2) -coverage -novopt -sva -sv_seed 598761566 -l test2_sim.log work.top +TEST2

TC3:
vsim $(VSIMBATCH3) -coverage -novopt -sva -sv_seed 74473697 -l test3_sim.log work.top +TEST3

TC4:
vsim $(VSIMBATCH4) -coverage -novopt -sva -sv_seed 4275076933 -l test4_sim.log work.top +TEST4

TC5:
vsim $(VSIMBATCH5) -coverage -novopt -sva -sv_seed 3868229417 -l test5_sim.log work.top +TEST5

TC6:
vsim $(VSIMBATCH6) -coverage -novopt -sva -sv_seed 749764269 -l test6_sim.log work.top +TEST6

TC7:
vsim $(VSIMBATCH7) -coverage -novopt -sva -sv_seed 1982889551 -l test7_sim.log work.top +TEST7

TC8:
vsim $(VSIMBATCH8) -coverage -novopt -sva -sv_seed 1987083824 -l test8_sim.log work.top +TEST8

TC9:
vsim $(VSIMBATCH9) -coverage -novopt -sva -sv_seed 1987083824 -l test8_sim.log work.top +TEST9

report:
vcover merge counter_cov counter_cov1 counter_cov2 #counter_cov3 counter_cov4 counter_cov5 counter_cov6 counter_cov7
vcover report -html counter_cov

regress: clean run_test TC2 report html # TC3 TC4 TC5 TC6 TC7 report html

gui:
vsim $(VSIMOPT) -l test1_sim.log +TEST1 +nowarn3829

run_gui: clean sv_cmp gui

run_test: clean sv_cmp run_sim


+ 60
- 0
4-bit-counter-SV-UVM/test/test.sv View File

@@ -0,0 +1,60 @@
import counter_pkg::*;


class counter_trans_load extends counter_trans;

randc logic [3:0] data;

constraint r1 {rst inside {0, 1};}
constraint l1 {load inside {0, 1};}
constraint d1{super.data == data;}

endclass

class test;
virtual counter_if.WR_BFM wr_if;
virtual counter_if.WR_MON wrmon_if;
virtual counter_if.RD_MON rdmon_if;

counter_env env;

counter_trans_load trans_ld_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;

env = new(wr_if, wrmon_if, rdmon_if);
endfunction



task build_and_run;
if($test$plusargs("TEST1"))
begin
no_of_transaction = 250;
env.build();
env.run();
$finish;
end
if($test$plusargs("TEST2"))
begin
trans_ld_h = new();
no_of_transaction = 250;
env.build();
env.gen_h.trans_h = trans_ld_h;
env.run();
$finish;
end
endtask

endclass :test


Loading…
Cancel
Save