|HOME |ABOUT |ARTICLES |ACK |FEEDBACK |TOC |LINKS |BLOG |JOBS |


Tutorials



PHASE 8 SCOREBOARD




In this phase we will see the scoreboard implementation.


Scoreboard



Scoreboard is implemented by extending ovm_scorboard. For our requirement, we can use ovm_in_order_comparator, but we will see develop our own scoreboard by extending ovm_scorboard. Scoreboard has 2 analysis imports. One is used to for getting the packets from the driver and other from the receiver. Then the packets are compared and if they don't match, then error is asserted. For comparison, compare () method of the Packet class is used.

Implement the scoreboard in file Scoreboard.sv.

Steps to create a scoreboard:
1) Useing macro `ovm_analysis_imp_decl(<_portname>), to declare ovm_analysis_imp_<_portname> class.
2) The above macro, creates write_<_portname>(). This method has to be define as per our requirements.


1) Declare a scoreboard by extending ovm_scoreboard class.


class Scoreboard extends ovm_scoreboard;

endclass : Scoreboard


2) We need 2 import, one for expected packet which is sent by driver and received packet which is coming from receiver.
Declare 2 imports using `ovm_analysis_imp_decl macros.


`ovm_analysis_imp_decl(_rcvd_pkt)
`ovm_analysis_imp_decl(_sent_pkt)


3) Declare the utility macro.


`ovm_component_utils(Scoreboard)


4) Declare a queue which stores the expected packets.


Packet exp_que[$];


5) Declare imports for getting expected packets and received packets.


ovm_analysis_imp_rcvd_pkt #(Packet,Scoreboard) Rcvr2Sb_port;
ovm_analysis_imp_sent_pkt #(Packet,Scoreboard) Drvr2Sb_port;


6) In the constructor, create objects for the above two declared imports.


function new(string name, ovm_component parent);
super.new(name, parent);
Rcvr2Sb_port = new("Rcvr2Sb", this);
Drvr2Sb_port = new("Drvr2Sb", this);
endfunction : new


7) Define write_sent_pkt() method which was created by macro `ovm_analysis_imp_decl(_sent_pkt).
In this method, store the received packet in the expected queue.


virtual function void write_sent_pkt(input Packet pkt);
exp_que.push_back(pkt);
endfunction : write_sent_pkt


8) Define write_rcvd_pkt() method which was created by macro `ovm_analysis_imp_decl(_rcvd_pkt)
In this method, get the transaction from the expected queue and compare.


virtual function void write_rcvd_pkt(input Packet pkt);
Packet exp_pkt;
pkt.print();
if(exp_que.size())
begin
exp_pkt = exp_que.pop_front();
exp_pkt.print();
if( pkt.compare(exp_pkt))
ovm_report_info(get_type_name(),
$psprintf("Sent packet and reeived packet mathed"), OVM_LOW);
else
ovm_report_error(get_type_name(),
$psprintf("Sent packet and reeived packet mismatched"), OVM_LOW);
end
else
ovm_report_error(get_type_name(),
$psprintf("No more packets in the expected queue to compare"), OVM_LOW);
endfunction : write_rcvd_pkt


9) Define the report() method to print the Scoreboard information.


virtual function void report();
ovm_report_info(get_type_name(),
$psprintf("Scoreboard Report %s", this.sprint()), OVM_LOW);
endfunction : report

(S)Complete Scoreboard Code
`ifndef GUARD_SCOREBOARD
`define GUARD_SCOREBOARD

`ovm_analysis_imp_decl(_rcvd_pkt)
`ovm_analysis_imp_decl(_sent_pkt)

class Scoreboard extends ovm_scoreboard;
`ovm_component_utils(Scoreboard)

Packet exp_que[$];

ovm_analysis_imp_rcvd_pkt #(Packet,Scoreboard) Rcvr2Sb_port;
ovm_analysis_imp_sent_pkt #(Packet,Scoreboard) Drvr2Sb_port;

function new(string name, ovm_component parent);
super.new(name, parent);
Rcvr2Sb_port = new("Rcvr2Sb", this);
Drvr2Sb_port = new("Drvr2Sb", this);
endfunction : new

virtual function void write_rcvd_pkt(input Packet pkt);
Packet exp_pkt;
pkt.print();

if(exp_que.size())
begin
exp_pkt = exp_que.pop_front();
exp_pkt.print();
if( pkt.compare(exp_pkt))
ovm_report_info(get_type_name(),
$psprintf("Sent packet and reeived packet mathed"), OVM_LOW);
else
ovm_report_error(get_type_name(),
$psprintf("Sent packet and reeived packet mismatched"), OVM_LOW);
end
else
ovm_report_error(get_type_name(),
$psprintf("No more packets to in the expected queue to compare"), OVM_LOW);
endfunction : write_rcvd_pkt

virtual function void write_sent_pkt(input Packet pkt);
exp_que.push_back(pkt);
endfunction : write_sent_pkt


virtual function void report();
ovm_report_info(get_type_name(),
$psprintf("Scoreboard Report %s", this.sprint()), OVM_LOW);
endfunction : report

endclass : Scoreboard
`endif

Environment Class Updates



We will take the instance of scoreboard in the environment and connect its ports to driver and receiver ports.





1) Declare scoreboard object.


Scoreboard Sbd;


2) Construct the scoreboard object using create() method in build() method.


Sbd = Scoreboard::type_id::create("Sbd",this);


3) In connect() method, connect the driver and receiver ports to scoreboard.


Drvr.Drvr2Sb_port.connect(Sbd.Drvr2Sb_port);

Rcvr[0].Rcvr2Sb_port.connect(Sbd.Rcvr2Sb_port);
Rcvr[1].Rcvr2Sb_port.connect(Sbd.Rcvr2Sb_port);
Rcvr[2].Rcvr2Sb_port.connect(Sbd.Rcvr2Sb_port);
Rcvr[3].Rcvr2Sb_port.connect(Sbd.Rcvr2Sb_port);

(S)Environemnt class code

`ifndef GUARD_ENV
`define GUARD_ENV

class Environment extends ovm_env;

`ovm_component_utils(Environment)

Sequencer Seqncr;
Driver Drvr;
Receiver Rcvr[4];

Scoreboard Sbd;

function new(string name , ovm_component parent = null);
super.new(name, parent);
endfunction: new

function void build();
super.build();
ovm_report_info(get_full_name(),"START of build ",OVM_LOW);

Drvr = Driver::type_id::create("Drvr",this);
Seqncr = Sequencer::type_id::create("Seqncr",this);

foreach(Rcvr[i]) begin
Rcvr[i] = Receiver::type_id::create($psprintf("Rcvr%0d",i),this);
Rcvr[i].id = i;
end

Sbd = Scoreboard::type_id::create("Sbd",this);

ovm_report_info(get_full_name(),"END of build ",OVM_LOW);
endfunction

function void connect();
super.connect();
ovm_report_info(get_full_name(),"START of connect ",OVM_LOW);

Drvr.seq_item_port.connect(Seqncr.seq_item_export);

Drvr.Drvr2Sb_port.connect(Sbd.Drvr2Sb_port);

Rcvr[0].Rcvr2Sb_port.connect(Sbd.Rcvr2Sb_port);
Rcvr[1].Rcvr2Sb_port.connect(Sbd.Rcvr2Sb_port);
Rcvr[2].Rcvr2Sb_port.connect(Sbd.Rcvr2Sb_port);
Rcvr[3].Rcvr2Sb_port.connect(Sbd.Rcvr2Sb_port);

ovm_report_info(get_full_name(),"END of connect ",OVM_LOW);
endfunction

endclass : Environment
`endif


(S)Download the Source Code


ovm_switch_8.tar
Browse the code in ovm_switch_8.tar


(S)Command to run the simulation


vcs -sverilog +incdir+$OVM_HOME/src $OVM_HOME/src/ovm_pkg.sv +incdir+. rtl.sv interface.sv top.sv -R +OVM_TESTNAME=test1
qverilog +incdir+$OVM_HOME/src $OVM_HOME/src/ovm_pkg.sv +incdir+. rtl.sv interface.sv top.sv -R +OVM_TESTNAME=test1



(S)Log report after simulation

OVM_INFO @ 0 [RNTST] Running test test1...
OVM_INFO @ 0: ovm_test_top.t_env [ovm_test_top.t_env] START of build
OVM_INFO @ 0: ovm_test_top.t_env [ovm_test_top.t_env] END of build
OVM_INFO @ 0: ovm_test_top.t_env [ovm_test_top.t_env] START of connect
OVM_INFO @ 0: ovm_test_top.t_env [ovm_test_top.t_env] END of connect
----------------------------------------------------------------------
Name Type Size Value
----------------------------------------------------------------------
Seqncr Sequencer - Seqncr@14
rsp_export ovm_analysis_export - rsp_export@16
seq_item_export ovm_seq_item_pull_+ - seq_item_export@40
default_sequence string 19 ovm_random_sequence
count integral 32 -1
max_random_count integral 32 'd10
sequences array 5 -
[0] string 19 ovm_random_sequence
[1] string 23 ovm_exhaustive_sequ+
[2] string 19 ovm_simple_sequence
[3] string 23 Seq_device0_and_dev+
[4] string 19 Seq_constant_length
max_random_depth integral 32 'd4
num_last_reqs integral 32 'd1
num_last_rsps integral 32 'd1
----------------------------------------------------------------------
OVM_INFO @ 30: ovm_test_top.t_env.Drvr [ovm_test_top.t_env.Drvr]
Start of reset_dut() method
OVM_INFO @ 70: ovm_test_top.t_env.Drvr [ovm_test_top.t_env.Drvr]
End of reset_dut() method
OVM_INFO @ 70: ovm_test_top.t_env.Drvr [ovm_test_top.t_env.Drvr]
Start of cfg_dut() method
OVM_INFO @ 110: ovm_test_top.t_env.Drvr [ovm_test_top.t_env.Drvr]
Port 0 Address 00
OVM_INFO @ 130: ovm_test_top.t_env.Drvr [ovm_test_top.t_env.Drvr]
Port 1 Address 01
OVM_INFO @ 150: ovm_test_top.t_env.Drvr [ovm_test_top.t_env.Drvr]
Port 2 Address 02
OVM_INFO @ 170: ovm_test_top.t_env.Drvr [ovm_test_top.t_env.Drvr]
Port 3 Address 03
OVM_INFO @ 190: ovm_test_top.t_env.Drvr [ovm_test_top.t_env.Drvr]
End of cfg_dut() method
OVM_INFO @ 210: ovm_test_top.t_env.Drvr [ovm_test_top.t_env.Drvr]
Driving packet ...
OVM_INFO @ 590: ovm_test_top.t_env.Drvr [ovm_test_top.t_env.Drvr]
Driving packet ...
OVM_INFO @ 610: ovm_test_top.t_env.Rcvr0 [ovm_test_top.t_env.Rcvr0]
Received packet ...
OVM_INFO @ 610: ovm_test_top.t_env.Sbd [Scoreboard]
Sent packet and reeived packet mathed
OVM_INFO @ 970: ovm_test_top.t_env.Drvr [ovm_test_top.t_env.Drvr]
Driving packet ...
OVM_INFO @ 990: ovm_test_top.t_env.Rcvr0 [ovm_test_top.t_env.Rcvr0]
Received packet ...
OVM_INFO @ 990: ovm_test_top.t_env.Sbd [Scoreboard]
Sent packet and reeived packet mathed
OVM_INFO @ 1000: ovm_test_top.t_env.Sbd [Scoreboard]
Scoreboard Report
----------------------------------------------------------------------
Name Type Size Value
----------------------------------------------------------------------
Sbd Scoreboard - Sbd@52
Drvr2Sb ovm_analysis_imp_s+ - Drvr2Sb@56
Rcvr2Sb ovm_analysis_imp_r+ - Rcvr2Sb@54
----------------------------------------------------------------------


--- OVM Report Summary ---

** Report counts by severity
OVM_INFO : 21
OVM_WARNING : 0
OVM_ERROR : 0
OVM_FATAL : 0







Index
Introduction
Specification
Verification Plan
Phase 1 Top
Phase 2 Configuration
Phase 3 Environment N Testcase
Phase 4 Packet
Phase 5 Sequencer N Sequence
Phase 6 Driver
Phase 7 Receiver
Phase 8 Scoreboard

Report a Bug or Comment on This section - Your input is what keeps Testbench.in improving with time!





<< PREVIOUS PAGE

TOP

NEXT PAGE >>

copyright 2007-2017 :: all rights reserved www.testbench.in::Disclaimer