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 /// @page pIntegration How to integrate the UVM scoreboard 00026 /// The UVM scoreboard is easily integrated into your existing testbench environment. 00027 /// 00028 /// @section sCompile Compiling the UVM scoreboard 00029 /// 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. 00030 /// 00031 /// @section sAcccess Accessing the UVM scoreboard from your own code 00032 /// Once the UVM scoreboard is compiled with the verification environment then it is accessible either by explicit scoping: 00033 /// 00034 /// @code 00035 /// class myclass; 00036 /// pk_syoscb::cl_syoscb my_new_scb; 00037 /// ... 00038 /// @endcode 00039 /// 00040 /// or by importing the complete package into your scope: 00041 /// 00042 /// @code 00043 /// import pk_syoscb::*; 00044 /// 00045 /// class myclass; 00046 /// cl_syoscb my_new_scb; 00047 /// ... 00048 /// @endcode 00049 /// 00050 /// @section sInstantiation Instantiating the UVM scoreboard 00051 /// 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: 00052 /// 00053 /// @code 00054 /// import pk_syoscb::*; 00055 /// 00056 /// class cl_scbtest_env extends uvm_env; 00057 /// 00058 /// cl_syoscb syoscb; 00059 /// cl_syoscb_cfg syoscb_cfg; 00060 /// 00061 /// `uvm_component_utils_begin(cl_scbtest_env) 00062 /// `uvm_field_object(syoscb, UVM_ALL_ON) 00063 /// `uvm_field_object(syoscb_cfg, UVM_ALL_ON) 00064 /// `uvm_component_utils_end 00065 /// 00066 /// ... 00067 /// 00068 /// endclass: cl_scbtest_env 00069 /// 00070 /// function void cl_scbtest_env::build_phase(uvm_phase phase); 00071 /// super.build_phase(phase); 00072 /// 00073 /// // Create the scoreboard configuration object 00074 /// this.syoscb_cfg = cl_syoscb_cfg::type_id::create("syoscb_cfg"); 00075 /// 00076 /// // Pass the scoreboard configuration object to the config_db 00077 /// uvm_config_db #(cl_syoscb_cfg)::set(this, "syoscb", "cfg", this.syoscb_cfg); 00078 /// 00079 /// // Create the scoreboard 00080 /// this.syoscb = cl_syoscb::type_id::create("syoscb", this); 00081 /// 00082 /// ... 00083 /// 00084 /// endfunction: build_phase 00085 /// @endcode 00086 /// 00087 /// @section sConfiguration Configuring the UVM scoreboard 00088 /// 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: 00089 /// 00090 /// @code 00091 /// function void cl_scbtest_env::build_phase(uvm_phase phase); 00092 /// super.build_phase(phase); 00093 /// 00094 /// // Create the scoreboard configuration object 00095 /// this.syoscb_cfg = cl_syoscb_cfg::type_id::create("syoscb_cfg"); 00096 /// 00097 /// // Configure the scoreboard 00098 /// this.syoscb_cfg.set_queues({"Q1", "Q2"}); 00099 /// void'(this.syoscb_cfg.set_primary_queue("Q1")); 00100 /// void'(this.syoscb_cfg.set_producer("P1", {"Q1", "Q2"})); 00101 /// 00102 /// // Pass the scoreboard configuration object to the config_db 00103 /// uvm_config_db #(cl_syoscb_cfg)::set(this, "syoscb", "cfg", this.syoscb_cfg); 00104 /// 00105 /// // Create the scoreboard 00106 /// this.syoscb = cl_syoscb::type_id::create("syoscb", this); 00107 /// 00108 /// ... 00109 /// 00110 /// endfunction: build_phase 00111 /// @endcode 00112 /// 00113 /// @section sFunctionAPIHookUp Function based API hook up 00114 /// The function based API is very easy to use once you have done the configuration and instantiation 00115 /// of the scoreboard as describe above. 00116 /// 00117 /// Whenever you need to add an UVM sequence item to a queue produced by a specified producer then you simply 00118 /// invoke the cl_syoscb::add_item() method: 00119 /// 00120 /// @code 00121 /// // *NOTE*: Assumes syoscb is handle to an instance of the scoreboard and 00122 /// // item1 is a handle to a UVM sequence item 00123 /// 00124 /// ... 00125 /// 00126 /// // Insert UVM sequence item for queue: Q1, for producer: P1 00127 /// syoscb.add_item("Q1", "P1", item1); 00128 /// @endcode 00129 /// 00130 /// 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 00131 /// and finally invoke the configured compare method. 00132 /// 00133 /// The UVM environment will typically contain a handle to the scoreboard as described above. This can then be utilized if UVM sequences 00134 /// needs to be added from a test case: 00135 /// 00136 /// @code 00137 /// class cl_scbtest_seq_item extends uvm_sequence_item; 00138 /// //------------------------------------- 00139 /// // Randomizable variables 00140 /// //------------------------------------- 00141 /// rand int unsigned int_a; 00142 /// 00143 /// //------------------------------------- 00144 /// // UVM Macros 00145 /// //------------------------------------- 00146 /// `uvm_object_utils_begin(cl_scbtest_seq_item) 00147 /// `uvm_field_int(int_a, UVM_ALL_ON) 00148 /// `uvm_object_utils_end 00149 /// 00150 /// //------------------------------------- 00151 /// // Constructor 00152 /// //------------------------------------- 00153 /// function cl_scbtest_seq_item::new (string name = "cl_scbtest_seq_item"); 00154 /// super.new(name); 00155 /// endfunction 00156 /// endclass: cl_scbtest_seq_item 00157 /// 00158 /// class cl_scbtest_test extends uvm_test; 00159 /// //------------------------------------- 00160 /// // Non randomizable variables 00161 /// //------------------------------------- 00162 /// cl_scbtest_env scbtest_env; 00163 /// 00164 /// //------------------------------------- 00165 /// // UVM Macros 00166 /// //------------------------------------- 00167 /// `uvm_component_utils(cl_scbtest_test) 00168 /// 00169 /// //------------------------------------- 00170 /// // Constructor 00171 /// //------------------------------------- 00172 /// function new(string name = "cl_scbtest_test", uvm_component parent = null); 00173 /// super.new(name, parent); 00174 /// endfunction: new 00175 /// 00176 /// //------------------------------------- 00177 /// // UVM Phase methods 00178 /// //------------------------------------- 00179 /// function void build_phase(uvm_phase phase); 00180 /// super.build_phase(phase); 00181 /// scbtest_env = cl_scbtest_env::type_id::create("scbtest_env", this); 00182 /// endfunction: build_phase 00183 /// 00184 /// task run_phase(uvm_phase phase); 00185 /// super.run_phase(phase); 00186 /// begin 00187 /// cl_scbtest_seq_item item1; 00188 /// item1 = cl_scbtest_seq_item::type_id::create("item1"); 00189 /// item1.int_a = 'h3a; 00190 /// scbtest_env.syoscb.add_item("Q1", "P1", item1); 00191 /// end 00192 /// begin 00193 /// cl_scbtest_seq_item item1; 00194 /// item1 = cl_scbtest_seq_item::type_id::create("item1"); 00195 /// item1.int_a = 'h3a; 00196 /// scbtest_env.syoscb.add_item("Q2", "P1", item1); 00197 /// end 00198 /// endtask: run_phase 00199 /// endclass: cl_scbtest_test 00200 /// @endcode 00201 /// 00202 /// @section sTLMAPIHookUp TLM based API hook up 00203 /// The TLM API is even easier to use than the function based API. The scoreboard provides generic UVM subscribers which 00204 /// can be connected to anything which has a UVM analysis port (e.g. a UVM monitor). Typically, the UVM agents inside the UVM environment 00205 /// contain one or more monitors with UVM analysis ports which should be connected to the scoreboard. The following example has two agents which 00206 /// each has a monitor. The monitors are connected to Q1 and Q2 in the scoreboard: 00207 /// 00208 /// @code 00209 /// import pk_syoscb::*; 00210 /// 00211 /// class cl_scbtest_env extends uvm_env; 00212 /// 00213 /// cl_syoscb syoscb; 00214 /// cl_syoscb_cfg syoscb_cfg; 00215 /// myagent agent1; 00216 /// myagent agent2; 00217 /// 00218 /// ... 00219 /// 00220 /// function void build_phase(uvm_phase phase); 00221 /// 00222 /// ... 00223 /// 00224 /// // Configure and create the scoreboard 00225 /// // Create and configure the agents 00226 /// 00227 /// ... 00228 /// 00229 /// endfunction: build_phase 00230 /// 00231 /// ... 00232 /// 00233 /// function void connect_phase(uvm_phase phase); 00234 /// super.connect_phase(phase); 00235 /// 00236 /// begin 00237 /// cl_syoscb_subscriber subscriber; 00238 /// 00239 /// // Get the subscriber for Producer: P1 for queue: Q1 and connect it 00240 /// // to the UVM monitor producing transactions for this queue 00241 /// subscriber = this.syoscb.get_subscriber("Q1", "P1"); 00242 /// this.agent1.mon.<analysis port>.connect(subscriber.analysis_export); 00243 /// 00244 /// // Get the subscriber for Producer: P1 for queue: Q2 and connect it 00245 /// // to the UVM monitor producing transactions for this queue 00246 /// subscriber = this.syoscb.get_subscriber("Q2", "P1"); 00247 /// this.agent1.mon.<analysis port>.connect(subscriber.analysis_export); 00248 /// end 00249 /// endfunction: connect_phase 00250 /// @endcode 00251 /// 00252 /// @section sFactory Factory overwrites 00253 /// 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. 00254 /// 00255 /// <B>NOTE: This MUST be done before creating the scoreboard!</B> 00256 /// 00257 /// The following queue implementations are available: 00258 /// 00259 /// -# Standard SV queue (cl_syoscb_queue_std) 00260 /// 00261 /// and the following compare algorithms are available: 00262 /// 00263 /// -# Out-of-Order (cl_syoscb_compare_ooo) 00264 /// -# In-Order (cl_syoscb_compare_io) 00265 /// 00266 /// The following example shows how they are configured: 00267 /// 00268 /// @code 00269 /// cl_syoscb_queue::set_type_override_by_type(cl_syoscb_queue::get_type(), 00270 /// cl_syoscb_queue_std::get_type(), 00271 /// "*"); 00272 /// 00273 /// factory.set_type_override_by_type(cl_syoscb_compare_base::get_type(), 00274 /// cl_syoscb_compare_ooo::get_type(), 00275 /// "*"); 00276 /// @endcode 00277 /// 00278 /// The full build phase, including the factory overwrites, of cl_scbtest_env is shown here for completeness: 00279 /// 00280 /// @code 00281 /// function void cl_scbtest_env::build_phase(uvm_phase phase); 00282 /// super.build_phase(phase); 00283 /// 00284 /// // Use the standard SV queue implementation as scoreboard queue 00285 /// cl_syoscb_queue::set_type_override_by_type(cl_syoscb_queue::get_type(), 00286 /// cl_syoscb_queue_std::get_type(), 00287 /// "*"); 00288 /// 00289 /// // Set the compare strategy to be OOO 00290 /// factory.set_type_override_by_type(cl_syoscb_compare_base::get_type(), 00291 /// cl_syoscb_compare_ooo::get_type(), 00292 /// "*"); 00293 /// 00294 /// // Create the scoreboard configuration object 00295 /// this.syoscb_cfg = cl_syoscb_cfg::type_id::create("syoscb_cfg"); 00296 /// 00297 /// // Configure the scoreboard 00298 /// this.syoscb_cfg.set_queues({"Q1", "Q2"}); 00299 /// void'(this.syoscb_cfg.set_primary_queue("Q1")); 00300 /// void'(this.syoscb_cfg.set_producer("P1", {"Q1", "Q2"})); 00301 /// 00302 /// // Pass the scoreboard configuration object to the config_db 00303 /// uvm_config_db #(cl_syoscb_cfg)::set(this, "syoscb", "cfg", this.syoscb_cfg); 00304 /// 00305 /// // Create the scoreboard 00306 /// this.syoscb = cl_syoscb::type_id::create("syoscb", this); 00307 /// 00308 /// ... 00309 /// 00310 /// endfunction: build_phase 00311 /// @endcode 00312 /// 00313 /// @page pImplementationNotes Implementation notes 00314 /// 00315 /// @section sGeneralErrorHandling General error handling 00316 /// 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. 00317 /// @section sErrorCategories Error categories 00318 /// There are several ERROR categories. The following table lists them with some explanation: 00319 /// 00320 /// <table> 00321 /// <tr> 00322 /// <th>Error Category</th> 00323 /// <th>Description</th> 00324 /// </tr> 00325 /// <tr> 00326 /// <td>IMPL_ERROR</td> 00327 /// <td>Implementation error. Something is really broken</td> 00328 /// </tr> 00329 /// <tr> 00330 /// <td>QUEUE_ERROR</td> 00331 /// <td>A queue related error, e.g. the queue could not be found</td> 00332 /// </tr> 00333 /// <tr> 00334 /// <td>CFG_ERROR</td> 00335 /// <td>Configuration error. Usually, because the configuration object is missing</td> 00336 /// </tr> 00337 /// <tr> 00338 /// <td>TYPE_ERROR</td> 00339 /// <td>Type error. Typically issued when $cast() fails</td> 00340 /// </tr> 00341 /// <tr> 00342 /// <td>COMPARE_ERROR</td> 00343 /// <td>Compare error. Issued, e.g. when the in order compare fails</td> 00344 /// </tr> 00345 ///</table> 00346 /// 00347 /// @section sMultipleQueueRefs Multiple queue references 00348 /// Both the top level class cl_syoscb and the configuration class cl_syoscb_cfg contains 00349 /// handles to all queues. The former uses an ordinary array which provides a fast way of 00350 /// looping over the queues and the latter an associative which makes it easy to find 00351 /// a queue using only its name. 00352 00353 package pk_syoscb; 00354 //////////////////////////////////////////////////////////////////////////// 00355 // Imported packages 00356 //////////////////////////////////////////////////////////////////////////// 00357 import uvm_pkg::*; 00358 `include "uvm_macros.svh" 00359 00360 //////////////////////////////////////////////////////////////////////////// 00361 // Type definitions 00362 //////////////////////////////////////////////////////////////////////////// 00363 typedef class cl_syoscb; 00364 typedef class cl_syoscb_cfg; 00365 typedef class cl_syoscb_queue; 00366 00367 //////////////////////////////////////////////////////////////////////////// 00368 // Package source files 00369 //////////////////////////////////////////////////////////////////////////// 00370 `include "cl_syoscb_cfg_pl.svh" 00371 `include "cl_syoscb_cfg.svh" 00372 `include "cl_syoscb_item.svh" 00373 `include "cl_syoscb_queue_iterator_base.svh" 00374 `include "cl_syoscb_queue_iterator_std.svh" 00375 `include "cl_syoscb_queue.svh" 00376 `include "cl_syoscb_queue_std.svh" 00377 `include "cl_syoscb_compare_base.svh" 00378 `include "cl_syoscb_compare.svh" 00379 `include "cl_syoscb_compare_ooo.svh" 00380 `include "cl_syoscb_compare_io.svh" 00381 `include "cl_syoscb_report_catcher.svh" 00382 `include "cl_syoscb_subscriber.svh" 00383 `include "cl_syoscb.svh" 00384 endpackage: pk_syoscb 00385 00386 `endif // __PK_SYOSCB_SV__
|
Project: SyoSil ApS UVM Scoreboard, Revision: 1.0.2.1 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 Version: 1.6.1 IDV SV Filter Version: 2.6.2 Thu Jun 4 23:02:22 2015 |