Mod-12 Loadable Up - Down Counter
Mod-12 Loadable Up - Down Counter
Rst->
Clk->
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
• 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.
• Mode
❖ 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-------------------------
logic [3:0]datain;
logic [3:0]dataout;
logic rst;
logic load;
logic mode;
output rst;
output datain;
output load;
output mode;
endclocking
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;
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;
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
//------------------Write monitor--------------------
class write_monitor;
virtual count_if.wr_mon wr_mon_if;
trans wr_data;
trans data2rm;
mailbox #(trans)mon2rm;
endclass
//----------------------------------Read monitor--------------------
class read_monitor;
virtual count_if.rd_mon rdmon_if;
trans data2sb;
trans rd_data;
endclass
//--------------------Reference Model--------------------------
class count_model;
trans w_data;
static logic [3:0] ref_count=0;
endclass
//-----------------------------ScoreBoard-------------------------
class count_sb;
event DONE;
trans sb_data;
trans rm_data;
trans cov_data;
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
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
endclass
//--------------------Environment-----------------------
class con_env;
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;
//-----------------------Test cases--------------------------------
class test;
con_env env;
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