0% found this document useful (0 votes)
198 views

Mod-12 Loadable Up - Down Counter

The document describes a verification plan for a MOD 12 loadable up/down counter digital circuit. The counter can count up or down based on the mode signal and load an initial value. The verification plan details the strategies, components, and coverage model used to verify the design including a generator, drivers, monitors, reference model, and scoreboard.

Uploaded by

Tara Sharma
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
198 views

Mod-12 Loadable Up - Down Counter

The document describes a verification plan for a MOD 12 loadable up/down counter digital circuit. The counter can count up or down based on the mode signal and load an initial value. The verification plan details the strategies, components, and coverage model used to verify the design including a generator, drivers, monitors, reference model, and scoreboard.

Uploaded by

Tara Sharma
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

Verification Plan for the MOD 12

Loadable UP/DOWN Counter


MOD 10 Loadable up/down counter:

Rst->

Clk->

Load-> MOD-12 -> [3:0] Dataout

Mode [Up/Down]->

[3:0] Datain->

An active high-loadable up/down counter is a digital circuit programmed to count up or down based
on user input. The counter can be loaded with an initial value, which sets the starting point for
counting.
When counting up, the counter increments by one on each clock cycle, and when counting down, the
counter decrements by one on each clock cycle. The direction of counting is determined by a control
signal, which can be set to either "up" or "down" mode.
Features:
• Reset
• Mode

❖ UP: Increment by one on each clock cycle.

❖ DOWN: Decrement by one on each clock cycle.

• Load
• Datain

❖ When Load is high, Counter can be loaded with the initial value dat in, which sets the
starting point for counting.
• Dataout

Strategies:
• Reset

❖ Reset should be distributed such that low value should occur number of times than high.

❖ Reference Model: if reset is “1” then output variable made equal to “0”.

• Load

❖ Load should be distributed such that low value should occur number of times than high.

❖ Reference Model: If the Load is high output variable should be datain.

• Mode

❖ Mode can be equally distributed.

❖ Reference Model:

▪ UP: if mode is high then if output variable is “11” then output variable made equal to
“0” otherwise increment by “1”.
▪ DOWN: if mode is low then if output variable is “0” then output variable made equal to
“11” otherwise decrement by “1”.
• Datain

❖ Datain is randomized such that value of datain should be in the range of 0 to 11.

• Dataout

❖ Score board: Dataout is compared with the output variable in reference model.

Transaction:
• Random: Reset, Mode, Load, Datain
Transactors:
• Generator: Generates random transaction.
• Driver: Drives Reset, Load, Mode and Datain signals.
• Monitor: collects the Dataout and random transactions.
• Reference Model: Mimic the design inside the environment from transaction data which is
collected in the monitor.
• Scoreboard: Compares the data in reference model and Dataout generated in the design and
generates coverage.

Coverage Model:
• Reset {implicit bins}
• Load {implicit bins}
• Mode {implicit bins}
• Datain {explicit bin [bin range [0:11]]}
• Dataout {explicit bin [bin range [0:11]]}
• Load X Datain
• Mode X Load X Datain

Call backs:
• Scoreboard : Callback triggers the coverage model.
Mod-12 Loadable Up/down counter Source Code

//---------------------RTL-----------------------

module mod12(clk,rst,datain,dataout,load,mode);
input [3:0]datain;
input clk,rst,load,mode;
output reg [3:0]dataout;

always@(posedge clk)
begin
if(rst)
dataout <= 4'b0000;
else
begin
if(load)
dataout <= datain;
else
begin
if(mode)
begin
if(dataout == 4'b1011)
dataout <= 4'b0000;
else
dataout <= dataout + 1;
end
else
begin
if(dataout == 4'b0000)
dataout <= 4'b1011;
else
dataout <= dataout - 1;
end
end
end
end
endmodule

//----------------------------Interface-------------------------

interface count_if(input bit clk);

logic [3:0]datain;
logic [3:0]dataout;
logic rst;
logic load;
logic mode;

clocking dr_cb@(posedge clk);


default input #1 output #1;

output rst;
output datain;
output load;
output mode;
endclocking

clocking wr_cb@(posedge clk);


default input #1 output #1;
input rst;
input datain;
input load;
input mode;
endclocking

clocking rd_cb@(posedge clk);


default input #1 output #1;
input dataout;
endclocking

modport drv(clocking dr_cb);


modport wr_mon(clocking wr_cb);
modport rd_mon(clocking rd_cb);

endinterface

package pkg;
int no_of_trans=1;
endpackage

import pkg::*;

//------------Transaction-----------------

class trans;
rand bit rst;
rand bit mode;
rand bit load;
rand bit [3:0]datain;

bit [3:0]dataout;

static int no_of_rst;


static int no_of_load;
static int no_of_upcount;
static int no_of_downcount;

constraint c1{datain inside{[0:11]};}


constraint c2{load dist{1:=30 , 0:=70};}
constraint c3{mode dist{0:=50 , 1:=50};}
constraint c4{rst dist{1:=30, 0:=70};}

function void display(input string message);


$display("message=%s",message);
$display("datain=%d",datain);
$display("dataout=%d",dataout);
$display("mode=%d",mode);
$display("load=%d",load);
$display("reset=%d",rst);
endfunction

function void post_randomize();

if(this.rst==1||this.rst==0)
no_of_rst++;
if(this.load==1 || this.load==0)
no_of_load++;
if(this.mode==1)
no_of_upcount++;
if(this.mode==0)
no_of_downcount++;
this.display("randomized data");
endfunction

endclass

//-----------------Generator-------------------

class cou_gen;

trans tr;
trans data2send;

mailbox #(trans) gen2dr;

function new(mailbox #(trans) gen2dr);


this.gen2dr=gen2dr;
this.tr=new();
endfunction

virtual task start();


fork
begin
for(int i=0;i<no_of_trans;i++)
begin
assert(tr.randomize());
data2send=new tr;
gen2dr.put(data2send);
end
end
join_none
endtask

endclass

//------------------Write Driver------------------------

class write_driver;
virtual count_if.drv dr_if;
trans data2duv;

mailbox #(trans)gen2dr;
function new(virtual count_if.drv dr_if, mailbox #(trans) gen2dr);

this.dr_if=dr_if;
this.gen2dr=gen2dr;
endfunction

virtual task drive();


begin
@(dr_if.dr_cb);
dr_if.dr_cb.load <= data2duv.load;
dr_if.dr_cb.datain <= data2duv.datain;
dr_if.dr_cb.mode <= data2duv.mode;
end
endtask

virtual task start();


fork
forever
begin
gen2dr.get(data2duv);
drive();
end
join_none;
endtask
endclass

//------------------Write monitor--------------------

class write_monitor;
virtual count_if.wr_mon wr_mon_if;
trans wr_data;
trans data2rm;

mailbox #(trans)mon2rm;

function new(virtual count_if.wr_mon wr_mon_if, mailbox


#(trans)mon2rm);
this.wr_mon_if=wr_mon_if;
this.mon2rm=mon2rm;
this.wr_data=new();
endfunction

virtual task monitor();


begin
@(wr_mon_if.wr_cb)
begin
wr_data.mode = wr_mon_if.wr_cb.mode;
wr_data.load = wr_mon_if.wr_cb.load;
wr_data.datain = wr_mon_if.wr_cb.datain;
wr_data.display("from write monitor");
end
end
endtask

virtual task start();


fork
forever
begin
monitor();
data2rm=new wr_data;
mon2rm.put(data2rm);
end
join_none
endtask

endclass

//----------------------------------Read monitor--------------------

class read_monitor;
virtual count_if.rd_mon rdmon_if;

trans data2sb;
trans rd_data;

mailbox #(trans) mon2sb;

function new(virtual count_if.rd_mon rdmon_if,mailbox


#(trans)mon2sb);
this.rdmon_if=rdmon_if;
this.mon2sb=mon2sb;
this.rd_data=new();
endfunction

virtual task monitor();


begin
@(rdmon_if.rd_cb);
begin
rd_data.dataout=rdmon_if.rd_cb.dataout;
rd_data.display("from the read monitor");
end
end
endtask

virtual task start();


fork
begin
monitor();
data2sb=new rd_data;
mon2sb.put(data2sb);
end
join_none
endtask

endclass

//--------------------Reference Model--------------------------

class count_model;

trans w_data;
static logic [3:0] ref_count=0;

mailbox #(trans) wrmon2rm;


mailbox #(trans) rm2sb;

function new( mailbox #(trans) wrmon2rm, mailbox #(trans) rm2sb);


this.wrmon2rm=wrmon2rm;
this.rm2sb=rm2sb;
endfunction

virtual task count_mod(trans model_counter);


begin
if(model_counter.rst==1)
ref_count<=0;
else
begin
if(model_counter.load)
ref_count <=model_counter.datain;
wait(model_counter.load==0)
begin
if(model_counter.mode==1)
begin
if(ref_count>12)
ref_count<=4'b0000;
else
ref_count<=ref_count+1'b1;
end
else if(model_counter.mode==0)
begin
if(ref_count==0)
ref_count<=4'd11;
else
ref_count<=ref_count-1'b1;
end
end
end
end
endtask

virtual task start();


fork
forever
begin
wrmon2rm.get(w_data);
count_mod(w_data);
w_data.dataout=ref_count;
rm2sb.put(w_data);
end
join_none
endtask

endclass

//-----------------------------ScoreBoard-------------------------

class count_sb;
event DONE;

trans sb_data;
trans rm_data;
trans cov_data;

mailbox #(trans) ref2sb;


mailbox #(trans) rdm2sb;

static int ref_data=0;


static int rmdata=0;
static int data_verified=0;

covergroup counter_coverage;
reset : coverpoint cov_data.rst;
Load : coverpoint cov_data.load;
Mode : coverpoint cov_data.mode;
IN : coverpoint cov_data.datain { bins datain = {[0:11]};}
OUT : coverpoint cov_data.dataout { bins dataout = {[0:11]};}
ldxdin : cross Load,IN;
moxldxxin: cross Mode,Load,IN;
endgroup

function new(mailbox #(trans) ref2sb, mailbox #(trans) rdm2sb);


this.ref2sb=ref2sb;
this.rdm2sb=rdm2sb;
counter_coverage=new();
endfunction

virtual task start();


fork
forever
begin
ref2sb.get(rm_data);
ref_data++;
rdm2sb.get(sb_data);
rmdata++;
check(sb_data);
end
join_none
endtask

virtual task check(trans rdata);


begin
if(rm_data.dataout==rdata.dataout)
$display("data matched");

else
$display("data not matched");
end
cov_data=rm_data;
counter_coverage.sample();

data_verified++;
if(data_verified >= no_of_trans+2);
begin
-> DONE;
end
endtask

virtual function void report();


$display("%d",rm_data);
$display("%d",data_verified);
endfunction

endclass

//--------------------Environment-----------------------

class con_env;

virtual count_if.drv dr_if;


virtual count_if.wr_mon wrmon_if;
virtual count_if.rd_mon rdmon_if;

mailbox #(trans)gen2dr=new();
mailbox #(trans)mon2rm=new();
mailbox #(trans)mon2sb=new();
mailbox #(trans)rm2sb=new();

cou_gen gen;
write_driver wr_dr;
write_monitor wr_mo;
read_monitor rd_mo;
count_model c_mo;
count_sb c_sb;

function new(virtual count_if.drv dr_if,


virtual count_if.wr_mon wrmon_if,
virtual count_if.rd_mon rdmon_if);
this.dr_if=dr_if;
this.wrmon_if=wrmon_if;
this.rdmon_if=rdmon_if;
endfunction

virtual task build();


gen=new(gen2dr);
wr_dr=new(dr_if,gen2dr);
wr_mo=new(wrmon_if,mon2rm);
rd_mo=new(rdmon_if,mon2sb);
c_mo=new(mon2rm,rm2sb);
c_sb=new(rm2sb,mon2sb);
endtask

virtual task start();


gen.start();
wr_dr.start();
wr_mo.start();
rd_mo.start();
c_mo.start();
c_sb.start();
endtask

virtual task stop();


wait(c_sb.DONE.triggered);
endtask

virtual task run();


start();
stop();
c_sb.report();
endtask
endclass

//-----------------------Test cases--------------------------------

class test;

virtual count_if.drv dr_if;


virtual count_if.wr_mon wrmon_if;
virtual count_if.rd_mon rdmon_if;

con_env env;

function new ( virtual count_if.drv dr_if,


virtual count_if.wr_mon wrmon_if,
virtual count_if.rd_mon rdmon_if);
this.dr_if=dr_if;
this.wrmon_if=wrmon_if;
this.rdmon_if=rdmon_if;
env=new(dr_if,wrmon_if,rdmon_if);
endfunction

virtual task build();


env.build();
endtask

virtual task run();


env.run();
endtask

endclass

//--------------------------------Top Module------------------------

module top();
reg clk;
count_if duv_if(clk);
con_env te;

mod12
DUV(.clk(clk),.datain(duv_if.datain),.load(duv_if.load),.mode(duv_if
.mode),.rst(duv_if.rst),.dataout(duv_if.dataout));

initial
begin
clk=1'b0;
forever
#10 clk=~clk;
end

initial
begin
if($test$plusargs("TEST1"))
begin
te=new(duv_if,duv_if,duv_if);
no_of_trans=2000;
te.build();
te.run();
$finish;
end

if($test$plusargs("TEST2"))
begin
te=new(duv_if,duv_if,duv_if);
no_of_trans=2000;
te.build();
te.run();
$finish;
end
end
endmodule

You might also like