pk_syoscb.sv

00001 `ifndef __PK_SYOSCB_SV__
00002 `define __PK_SYOSCB_SV__
00003 
00004 /// @mainpage
00005 /// User and implementation documentation for the UVM scoreboard
00006 ///
00007 /// This documentation provides the following additional documentation, besides
00008 /// the normal source code documentation:
00009 ///
00010 ///   -# Getting started: \ref pGettingStarted
00011 ///   -# How to integrate the UVM scoreboard: \ref pIntegration
00012 ///   -# Implementation notes: \ref pImplementationNotes
00013 ///
00014 /// It is assumed that the reader is familiar with the UVM scoreboard architecture
00015 /// described in the SyoSil paper on the subject: Versatile UVM Scoreboarding located in
00016 /// in the <b>docs</b> directory.
00017 ///
00018 /// @page pGettingStarted Getting started
00019 /// This software package also provides some simple examples beside the source code for the UVM scoreboard. Before starting to integrate the UVM scoreboard into your own code then it might be beneficial to look at the provided examples. An example testbench is placed in the <b>tb</b> directory and the tests are in the <b>tb/test</b> directory.
00020 ///
00021 /// To run the examples you need to select a Vendor since the examples can be run with all of the three major SystemVerilog simulator vendors: Mentor Graphics, Cadence and Synopsys. See <b>README.txt</b> for a description of how to select the vendor.
00022 ///
00023 /// Once the vendor has been selected then the available Make targets for that vendor can be listed by typing: "make". Typically, you run the simulation with: <b>make sim</b>.
00024 ///
00025 /// In general you can type: <b>make help</b> to get information about what Make options are available.
00026 ///
00027 /// @page pIntegration How to integrate the UVM scoreboard
00028 /// The UVM scoreboard is easily integrated into your existing testbench environment.
00029 ///
00030 /// @section sCompile Compiling the UVM scoreboard
00031 /// To get the UVM scoreboard compiled you need to add <b>src/pk_syoscb.sv</b> to your list of files that are complied when compiling your testbench. How this is done is highly dependent on the verification environment since some environments compile everything into different libraries and some do not etc.
00032 ///
00033 /// @section sAcccess Accessing the UVM scoreboard from your own code
00034 /// Once the UVM scoreboard is compiled with the verification environment then it is accessible either by explicit scoping:
00035 ///
00036 /// @code
00037 ///   class myclass;
00038 ///     pk_syoscb::cl_syoscb my_new_scb;
00039 ///     ...
00040 /// @endcode
00041 ///
00042 /// or by importing the complete package into your scope:
00043 ///
00044 /// @code
00045 ///   import pk_syoscb::*;
00046 ///
00047 ///   class myclass;
00048 ///     cl_syoscb my_new_scb;
00049 ///     ...
00050 /// @endcode
00051 ///
00052 /// @section sInstantiation Instantiating the UVM scoreboard
00053 /// The UVM scoreboard itself needs to be instantiated along with the configuration object. The simplest way to to this is to add the UVM scoreboard and the configuration object to the UVM environment - note that the configuration object is passed to the scoreboard via the config_db:
00054 ///
00055 /// @code
00056 ///   import pk_syoscb::*;
00057 ///
00058 ///   class cl_scbtest_env extends uvm_env;
00059 ///
00060 ///     cl_syoscb     syoscb;   
00061 ///     cl_syoscb_cfg syoscb_cfg;
00062 ///    
00063 ///     `uvm_component_utils_begin(cl_scbtest_env)
00064 ///       `uvm_field_object(syoscb,     UVM_ALL_ON)
00065 ///       `uvm_field_object(syoscb_cfg, UVM_ALL_ON)
00066 ///     `uvm_component_utils_end
00067 ///    
00068 ///     ... 
00069 ///
00070 ///   endclass: cl_scbtest_env
00071 ///
00072 ///   function void cl_scbtest_env::build_phase(uvm_phase phase);
00073 ///     super.build_phase(phase);
00074 ///   
00075 ///     // Create the scoreboard configuration object
00076 ///     this.syoscb_cfg = cl_syoscb_cfg::type_id::create("syoscb_cfg");
00077 ///
00078 ///     // Pass the scoreboard configuration object to the config_db
00079 ///     uvm_config_db #(cl_syoscb_cfg)::set(this, "syoscb", "cfg", this.syoscb_cfg);
00080 ///
00081 ///     // Create the scoreboard
00082 ///     this.syoscb = cl_syoscb::type_id::create("syoscb", this);
00083 ///   
00084 ///     ...
00085 ///               
00086 ///   endfunction: build_phase
00087 /// @endcode
00088 ///
00089 /// @section sConfiguration Configuring the UVM scoreboard
00090 /// The UVM scoreboard configuration object needs to be configured after it has been created. The following example shows how two queues Q1 and Q2 wit Q1 as the primary queue. Furthermore, one producer P1 is added to both queues:
00091 ///
00092 /// @code
00093 ///   function void cl_scbtest_env::build_phase(uvm_phase phase);
00094 ///     super.build_phase(phase);
00095 ///   
00096 ///     // Create the scoreboard configuration object
00097 ///     this.syoscb_cfg = cl_syoscb_cfg::type_id::create("syoscb_cfg");
00098 ///
00099 ///     // Configure the scoreboard
00100 ///     this.syoscb_cfg.set_queues({"Q1", "Q2"});
00101 ///     void'(this.syoscb_cfg.set_primary_queue("Q1")); 
00102 ///     void'(this.syoscb_cfg.set_producer("P1", {"Q1", "Q2"})); 
00103 ///
00104 ///     // Pass the scoreboard configuration object to the config_db
00105 ///     uvm_config_db #(cl_syoscb_cfg)::set(this, "syoscb", "cfg", this.syoscb_cfg);
00106 ///
00107 ///     // Create the scoreboard
00108 ///     this.syoscb = cl_syoscb::type_id::create("syoscb", this);
00109 ///               
00110 ///     ...
00111 ///
00112 ///   endfunction: build_phase
00113 /// @endcode
00114 ///
00115 /// @section sFunctionAPIHookUp Function based API hook up
00116 /// The function based API is very easy to use once you have done the configuration and instantiation
00117 /// of the scoreboard as describe above.
00118 ///
00119 /// Whenever you need to add an UVM sequence item to a queue produced by a specified producer then you simply
00120 /// invoke the cl_syoscb::add_item() method:
00121 ///
00122 /// @code
00123 ///   // *NOTE*: Assumes syoscb is handle to an instance of the scoreboard and
00124 ///   //         item1 is a handle to a UVM sequence item
00125 ///
00126 ///   ...
00127 ///
00128 ///   // Insert UVM sequence item for queue: Q1, for producer: P1
00129 ///   syoscb.add_item("Q1", "P1", item1);
00130 /// @endcode
00131 ///
00132 /// Invoking the cl_syoscb::add_item() method will simply wrap the UVM sequence item in a cl_syoscb_item object, add it the correct queue
00133 /// and finally invoke the configured compare method.
00134 ///
00135 /// The UVM environment will typically contain a handle to the scoreboard as described above. This can then be utilized if UVM sequences
00136 /// needs to be added from a test case:
00137 ///
00138 /// @code
00139 ///   class cl_scbtest_seq_item extends uvm_sequence_item;
00140 ///     //-------------------------------------
00141 ///     // Randomizable variables
00142 ///     //-------------------------------------
00143 ///     rand int unsigned int_a;
00144 ///   
00145 ///     //-------------------------------------
00146 ///     // UVM Macros
00147 ///     //-------------------------------------
00148 ///     `uvm_object_utils_begin(cl_scbtest_seq_item)
00149 ///       `uvm_field_int(int_a, UVM_ALL_ON)
00150 ///     `uvm_object_utils_end
00151 ///   
00152 ///     //-------------------------------------
00153 ///     // Constructor
00154 ///     //-------------------------------------
00155 ///     function cl_scbtest_seq_item::new (string name = "cl_scbtest_seq_item");
00156 ///        super.new(name);
00157 ///     endfunction
00158 ///   endclass: cl_scbtest_seq_item
00159 ///
00160 ///   class cl_scbtest_test extends uvm_test;
00161 ///     //-------------------------------------
00162 ///     // Non randomizable variables
00163 ///     //-------------------------------------
00164 ///     cl_scbtest_env scbtest_env;
00165 ///   
00166 ///     //-------------------------------------
00167 ///     // UVM Macros
00168 ///     //-------------------------------------
00169 ///     `uvm_component_utils(cl_scbtest_test)
00170 ///   
00171 ///     //-------------------------------------
00172 ///     // Constructor
00173 ///     //-------------------------------------
00174 ///     function new(string name = "cl_scbtest_test", uvm_component parent = null);
00175 ///       super.new(name, parent);
00176 ///     endfunction: new
00177 ///   
00178 ///     //-------------------------------------
00179 ///     // UVM Phase methods
00180 ///     //-------------------------------------
00181 ///     function void build_phase(uvm_phase phase);
00182 ///       super.build_phase(phase);
00183 ///       scbtest_env = cl_scbtest_env::type_id::create("scbtest_env", this);
00184 ///     endfunction: build_phase
00185 ///   
00186 ///     task run_phase(uvm_phase phase);
00187 ///       super.run_phase(phase);
00188 ///       begin
00189 ///         cl_scbtest_seq_item item1;
00190 ///         item1 = cl_scbtest_seq_item::type_id::create("item1");
00191 ///         item1.int_a = 'h3a;
00192 ///         scbtest_env.syoscb.add_item("Q1", "P1", item1);
00193 ///       end
00194 ///       begin
00195 ///         cl_scbtest_seq_item item1;
00196 ///         item1 = cl_scbtest_seq_item::type_id::create("item1");
00197 ///         item1.int_a = 'h3a;
00198 ///         scbtest_env.syoscb.add_item("Q2", "P1", item1);
00199 ///       end
00200 ///     endtask: run_phase
00201 ///   endclass: cl_scbtest_test
00202 /// @endcode
00203 ///
00204 /// @section sTLMAPIHookUp TLM based API hook up
00205 /// The TLM API is even easier to use than the function based API. The scoreboard provides generic UVM subscribers which
00206 /// can be connected to anything which has a UVM analysis port (e.g. a UVM monitor). Typically, the UVM agents inside the UVM environment
00207 /// contain one or more monitors with UVM analysis ports which should be connected to the scoreboard. The following example has two agents which
00208 /// each has a monitor. The monitors are connected to Q1 and Q2 in the scoreboard:
00209 ///
00210 /// @code
00211 ///   import pk_syoscb::*;
00212 ///
00213 ///   class cl_scbtest_env extends uvm_env;
00214 ///
00215 ///     cl_syoscb     syoscb;   
00216 ///     cl_syoscb_cfg syoscb_cfg;
00217 ///     myagent       agent1;
00218 ///     myagent       agent2;
00219 ///
00220 ///     ...
00221 ///
00222 ///     function void build_phase(uvm_phase phase);
00223 ///       
00224 ///       ...     
00225 ///
00226 ///       // Configure and create the scoreboard
00227 ///       // Create and configure the agents
00228 ///       
00229 ///       ...     
00230 ///
00231 ///     endfunction: build_phase
00232 ///
00233 ///     ...
00234 ///
00235 ///     function void connect_phase(uvm_phase phase);
00236 ///       super.connect_phase(phase);
00237 ///
00238 ///       begin
00239 ///         cl_syoscb_subscriber subscriber;
00240 ///
00241 ///         // Get the subscriber for Producer: P1 for queue: Q1 and connect it
00242 ///         // to the UVM monitor producing transactions for this queue
00243 ///         subscriber = this.syoscb.get_subscriber("Q1", "P1");
00244 ///         this.agent1.mon.<analysis port>.connect(subscriber.analysis_export);
00245 ///
00246 ///         // Get the subscriber for Producer: P1 for queue: Q2 and connect it
00247 ///         // to the UVM monitor producing transactions for this queue
00248 ///         subscriber = this.syoscb.get_subscriber("Q2", "P1");
00249 ///         this.agent1.mon.<analysis port>.connect(subscriber.analysis_export);
00250 ///       end
00251 ///     endfunction: connect_phase
00252 ///   @endcode
00253 ///  
00254 /// @section sFactory Factory overwrites
00255 /// Finally, the wanted queue and compare algorithm implementation needs to be selected. This is done by factory overwrites since they can be changed test etc.
00256 ///
00257 /// <B>NOTE: This MUST be done before creating the scoreboard!</B>
00258 ///
00259 /// The following queue implementations are available:
00260 ///
00261 ///   -# Standard SV queue (cl_syoscb_queue_std)
00262 ///
00263 /// and the following compare algorithms are available:
00264 ///
00265 ///   -# Out-of-Order (cl_syoscb_compare_ooo)
00266 ///   -# In-Order (cl_syoscb_compare_io)
00267 ///
00268 /// The following example shows how they are configured:
00269 ///
00270 /// @code
00271 ///   cl_syoscb_queue::set_type_override_by_type(cl_syoscb_queue::get_type(),              
00272 ///                                              cl_syoscb_queue_std::get_type(),
00273 ///                                              "*");
00274 ///
00275 ///   factory.set_type_override_by_type(cl_syoscb_compare_base::get_type(),
00276 ///                                     cl_syoscb_compare_ooo::get_type(),
00277 ///                                     "*");
00278 /// @endcode
00279 ///
00280 /// The full build phase, including the factory overwrites, of cl_scbtest_env is shown here for completeness:
00281 ///
00282 /// @code
00283 ///   function void cl_scbtest_env::build_phase(uvm_phase phase);
00284 ///     super.build_phase(phase);
00285 ///
00286 ///     // Use the standard SV queue implementation as scoreboard queue
00287 ///     cl_syoscb_queue::set_type_override_by_type(cl_syoscb_queue::get_type(),              
00288 ///                                                cl_syoscb_queue_std::get_type(),
00289 ///                                                "*");
00290 ///
00291 ///     // Set the compare strategy to be OOO
00292 ///     factory.set_type_override_by_type(cl_syoscb_compare_base::get_type(),
00293 ///                                       cl_syoscb_compare_ooo::get_type(),
00294 ///                                       "*");
00295 ///
00296 ///     // Create the scoreboard configuration object
00297 ///     this.syoscb_cfg = cl_syoscb_cfg::type_id::create("syoscb_cfg");
00298 ///
00299 ///     // Configure the scoreboard
00300 ///     this.syoscb_cfg.set_queues({"Q1", "Q2"});
00301 ///     void'(this.syoscb_cfg.set_primary_queue("Q1")); 
00302 ///     void'(this.syoscb_cfg.set_producer("P1", {"Q1", "Q2"})); 
00303 ///
00304 ///     // Pass the scoreboard configuration object to the config_db
00305 ///     uvm_config_db #(cl_syoscb_cfg)::set(this, "syoscb", "cfg", this.syoscb_cfg);
00306 ///
00307 ///     // Create the scoreboard
00308 ///     this.syoscb = cl_syoscb::type_id::create("syoscb", this);
00309 ///               
00310 ///     ...
00311 ///
00312 ///   endfunction: build_phase
00313 /// @endcode
00314 ///
00315 /// @page pImplementationNotes Implementation notes
00316 ///
00317 /// @section sAPIs Implementation APIs
00318 ///
00319 /// The following APIs have been defined for easy extension fo the scoreboard classes:
00320 ///
00321 ///   -# Configuration API: cl_syoscb_cfg
00322 ///   -# Item API: cl_syoscb_item
00323 ///   -# Queue API: cl_syoscb_queue
00324 ///   -# Compare API: cl_syoscb_compare_base
00325 ///   -# Subscriber API: cl_syoscb_subscriber
00326 ///   -# Iterator API: cl_syoscb_queue_iterator_base
00327 ///
00328 /// @section sGeneralErrorHandling General error handling
00329 /// In general when a lower level method detects an error then two concepts are used. Primarily, the method will either issue a UVM info with some information about what went wrong or issue a UVM error/fatal immediately. The first one will then return <b>1'b0</b> to signal that something went wrong. Thus, it is up to the parent levels to catch the error and convert them into UVM errors/fatals etc. This method was chosen since the parent level typically provides more and better information when things go wrong. 
00330 /// @section sErrorCategories Error categories
00331 /// There are several ERROR categories. The following table lists them with some explanation:
00332 ///
00333 ///  <table>
00334 ///  <tr>
00335 ///    <th>Error Category</th>
00336 ///    <th>Description</th>
00337 ///  </tr>
00338 ///  <tr>
00339 ///    <td>IMPL_ERROR</td>
00340 ///    <td>Implementation error. Something is really broken</td>
00341 ///  </tr>
00342 ///  <tr>
00343 ///    <td>QUEUE_ERROR</td>
00344 ///    <td>A queue related error, e.g. the queue could not be found</td>
00345 ///  </tr>
00346 ///  <tr>
00347 ///    <td>CFG_ERROR</td>
00348 ///    <td>Configuration error. Usually, because the configuration object is missing</td>
00349 ///  </tr>
00350 ///  <tr>
00351 ///    <td>TYPE_ERROR</td>
00352 ///    <td>Type error. Typically issued when $cast() fails</td>
00353 ///  </tr>
00354 ///  <tr>
00355 ///    <td>COMPARE_ERROR</td>
00356 ///    <td>Compare error. Issued, e.g. when the in order compare fails</td>
00357 ///  </tr>
00358 ///</table>
00359 ///   
00360 /// @section sMultipleQueueRefs Multiple queue references
00361 /// Both the top level class cl_syoscb and the configuration class cl_syoscb_cfg contains
00362 /// handles to all queues. The former uses an ordinary array which provides a fast way of
00363 /// looping over the queues and the latter an associative which makes it easy to find
00364 /// a queue using only its name.
00365 
00366 package pk_syoscb;
00367   ////////////////////////////////////////////////////////////////////////////
00368   // Imported packages
00369   ////////////////////////////////////////////////////////////////////////////
00370   import uvm_pkg::*;
00371   `include "uvm_macros.svh"
00372 
00373   ////////////////////////////////////////////////////////////////////////////
00374   // Type definitions
00375   ////////////////////////////////////////////////////////////////////////////
00376   typedef class cl_syoscb;
00377   typedef class cl_syoscb_cfg;
00378   typedef class cl_syoscb_queue;
00379 
00380   ////////////////////////////////////////////////////////////////////////////
00381   // Package source files
00382   ////////////////////////////////////////////////////////////////////////////
00383   `include "cl_syoscb_cfg_pl.svh"
00384   `include "cl_syoscb_cfg.svh"
00385   `include "cl_syoscb_item.svh"
00386   `include "cl_syoscb_queue_iterator_base.svh"
00387   `include "cl_syoscb_queue_iterator_std.svh"
00388   `include "cl_syoscb_queue.svh"
00389   `include "cl_syoscb_queue_std.svh"
00390   `include "cl_syoscb_compare_base.svh"
00391   `include "cl_syoscb_compare.svh"
00392   `include "cl_syoscb_compare_ooo.svh"
00393   `include "cl_syoscb_compare_io.svh"
00394   `include "cl_syoscb_report_catcher.svh"
00395   `include "cl_syoscb_subscriber.svh"
00396   `include "cl_syoscb.svh"
00397 endpackage: pk_syoscb
00398 
00399 `endif //  __PK_SYOSCB_SV__
 All Classes Functions Variables

Project: SyoSil ApS UVM Scoreboard, Revision: 1.0.2.3

Copyright 2014-2015 SyoSil ApS
All Rights Reserved Worldwide

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
doxygen
Doxygen Version: 1.6.1
IDV SV Filter Version: 2.6.2
Mon Sep 28 02:57:58 2015
Find a documentation bug? Report bugs to: bugs.intelligentdv.com Project: DoxygenFilterSV