|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 uvm_scorboard. For our requirement, we can use uvm_in_order_comparator, but we will see develop our own scoreboard by extending uvm_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 `uvm_analysis_imp_decl(<_portname>), to declare uvm_analysis_imp_<_portname> class.
2) The above macro, creates write_<_portname>(). This method has to be define as per our requirements.


1) 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 `uvm_analysis_imp_decl macros should not be defined inside the class.


`uvm_analysis_imp_decl(_rcvd_pkt)
`uvm_analysis_imp_decl(_sent_pkt)


2) Declare a scoreboard by extending uvm_scoreboard class.


class Scoreboard extends uvm_scoreboard;

endclass : Scoreboard


3) Declare the utility macro.


`uvm_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.


uvm_analysis_imp_rcvd_pkt #(Packet,Scoreboard) Rcvr2Sb_port;
uvm_analysis_imp_sent_pkt #(Packet,Scoreboard) Drvr2Sb_port;


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


function new(string name, uvm_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 `uvm_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 `uvm_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))
uvm_report_info(get_type_name(),
$psprintf("Sent packet and received packet matched"), UVM_LOW);
else
uvm_report_error(get_type_name(),
$psprintf("Sent packet and received packet mismatched"), UVM_LOW);
end
else
uvm_report_error(get_type_name(),
$psprintf("No more packets in the expected queue to compare"), UVM_LOW);
endfunction : write_rcvd_pkt


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


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

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

`uvm_analysis_imp_decl(_rcvd_pkt)
`uvm_analysis_imp_decl(_sent_pkt)

class Scoreboard extends uvm_scoreboard;
`uvm_component_utils(Scoreboard)

Packet exp_que[$];

uvm_analysis_imp_rcvd_pkt #(Packet,Scoreboard) Rcvr2Sb_port;
uvm_analysis_imp_sent_pkt #(Packet,Scoreboard) Drvr2Sb_port;

function new(string name, uvm_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))
uvm_report_info(get_type_name(),
$psprintf("Sent packet and received packet matched"), UVM_LOW);
else
uvm_report_error(get_type_name(),
$psprintf("Sent packet and received packet mismatched"), UVM_LOW);
end
else
uvm_report_error(get_type_name(),
$psprintf("No more packets to in the expected queue to compare"), UVM_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();
uvm_report_info(get_type_name(),
$psprintf("Scoreboard Report %s", this.sprint()), UVM_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);

foreach(Rcvr[i])
Rcvr[i].Rcvr2Sb_port.connect(Sbd.Rcvr2Sb_port);

(S)Environemnt class code

`ifndef GUARD_ENV
`define GUARD_ENV

class Environment extends uvm_env;

`uvm_component_utils(Environment)

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

Scoreboard Sbd;

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

virtual function void build();
super.build();
uvm_report_info(get_full_name(),"START of build ",UVM_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);

uvm_report_info(get_full_name(),"END of build ",UVM_LOW);
endfunction

virtual function void connect();
super.connect();
uvm_report_info(get_full_name(),"START of connect ",UVM_LOW);

Drvr.seq_item_port.connect(Seqncr.seq_item_export);

Drvr.Drvr2Sb_port.connect(Sbd.Drvr2Sb_port);

foreach(Rcvr[i])
Rcvr[i].Rcvr2Sb_port.connect(Sbd.Rcvr2Sb_port);

uvm_report_info(get_full_name(),"END of connect ",UVM_LOW);
endfunction

endclass : Environment
`endif


(S)Download the Source Code


uvm_switch_8.tar
Browse the code in uvm_switch_8.tar


(S)Command to run the simulation


VCS Users : make vcs
Questa Users: make questa



(S)Log report after simulation

UVM_INFO @ 0 [RNTST] Running test test1...
UVM_INFO @ 0: uvm_test_top.t_env [uvm_test_top.t_env] START of build
UVM_INFO @ 0: uvm_test_top.t_env [uvm_test_top.t_env] END of build
UVM_INFO @ 0: uvm_test_top.t_env [uvm_test_top.t_env] START of connect
UVM_INFO @ 0: uvm_test_top.t_env [uvm_test_top.t_env] END of connect
----------------------------------------------------------------------
Name Type Size Value
----------------------------------------------------------------------
Seqncr Sequencer - Seqncr@14
rsp_export uvm_analysis_export - rsp_export@16
seq_item_export uvm_seq_item_pull_+ - seq_item_export@40
default_sequence string 19 uvm_random_sequence
count integral 32 -1
max_random_count integral 32 'd10
sequences array 5 -
[0] string 19 uvm_random_sequence
[1] string 23 uvm_exhaustive_sequ+
[2] string 19 uvm_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
----------------------------------------------------------------------
UVM_INFO @ 30: uvm_test_top.t_env.Drvr [uvm_test_top.t_env.Drvr]
Start of reset_dut() method
UVM_INFO @ 70: uvm_test_top.t_env.Drvr [uvm_test_top.t_env.Drvr]
End of reset_dut() method
UVM_INFO @ 70: uvm_test_top.t_env.Drvr [uvm_test_top.t_env.Drvr]
Start of cfg_dut() method
UVM_INFO @ 110: uvm_test_top.t_env.Drvr [uvm_test_top.t_env.Drvr]
Port 0 Address 00
UVM_INFO @ 130: uvm_test_top.t_env.Drvr [uvm_test_top.t_env.Drvr]
Port 1 Address 01
UVM_INFO @ 150: uvm_test_top.t_env.Drvr [uvm_test_top.t_env.Drvr]
Port 2 Address 02
UVM_INFO @ 170: uvm_test_top.t_env.Drvr [uvm_test_top.t_env.Drvr]
Port 3 Address 03
UVM_INFO @ 190: uvm_test_top.t_env.Drvr [uvm_test_top.t_env.Drvr]
End of cfg_dut() method
UVM_INFO @ 210: uvm_test_top.t_env.Drvr [uvm_test_top.t_env.Drvr]
Driving packet ...
UVM_INFO @ 590: uvm_test_top.t_env.Drvr [uvm_test_top.t_env.Drvr]
Driving packet ...
UVM_INFO @ 610: uvm_test_top.t_env.Rcvr0 [uvm_test_top.t_env.Rcvr0]
Received packet ...
UVM_INFO @ 610: uvm_test_top.t_env.Sbd [Scoreboard]
Sent packet and received packet matched
UVM_INFO @ 970: uvm_test_top.t_env.Drvr [uvm_test_top.t_env.Drvr]
Driving packet ...
UVM_INFO @ 990: uvm_test_top.t_env.Rcvr0 [uvm_test_top.t_env.Rcvr0]
Received packet ...
UVM_INFO @ 990: uvm_test_top.t_env.Sbd [Scoreboard]
Sent packet and received packet matched
UVM_INFO @ 1000: uvm_test_top.t_env.Sbd [Scoreboard]
Scoreboard Report
----------------------------------------------------------------------
Name Type Size Value
----------------------------------------------------------------------
Sbd Scoreboard - Sbd@52
Drvr2Sb uvm_analysis_imp_s+ - Drvr2Sb@56
Rcvr2Sb uvm_analysis_imp_r+ - Rcvr2Sb@54
----------------------------------------------------------------------


--- UVM Report Summary ---

** Report counts by severity
UVM_INFO : 21
UVM_WARNING : 0
UVM_ERROR : 0
UVM_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