1 @page pIntegration How to integrate the UVM scoreboard
2 The UVM scoreboard is easily integrated into your existing testbench environment.
3 The following steps should be followed to start using the UVM scoreboard:
5 -# Compile the UVM scoreboard
6 -# Access the UVM scoreboard from your own code
7 -# Perform cactory overrides
8 -# Instantiate the UVM scoreboard
9 -# Configure the UVM scoreboard
10 -# Add sequence items to the scoreboard
11 -# Use the scoreboard wrapper for multiple similar scoreboards
13 @section sCompile Compiling the UVM scoreboard
14 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. Refer to your vendor's manual for further information on how to include packages.
16 @section sAcccess Accessing the UVM scoreboard from your own code
17 Once the UVM scoreboard is compiled with the verification environment, it is accessible either by explicit scoping:
21 pk_syoscb::cl_syoscb my_new_scb;
25 or by importing the complete package into your scope:
35 @section sFactory Factory overrides
36 Before instantiating the scoreboard, the desired queue type and compare algorithm need to be set in the scoreboard's configuration object. This is done by factory overrides since the queue type and compare algorithm can be changed on a per-test basis.
38 <B>NOTE: This MUST be done before creating the scoreboard!</B>
40 The queue type and compare algorithm should <b> not </b> be overwritten with a call to the UVM configuration databse. Instead, the scoreboard configuration object should be used.
42 The factory overrides are done in the build phase of the cl_syoscb, depending on the value of the
43 cl_syoscb_cfg.queue_type and cl_syoscb_cfg.compare_type configuration knobs. If no overwriting is performed, the test will fail, as the default queue and comparison types are set to \c USER_DEFINED, a placeholder value for user-defined queue types and comparison types.
45 The scoreboard comes with a number of built-in queue types and comparison algorithms (see \ref pQueueImplementationNotes and \ref pCompareImplementationNotes).
46 The following queue implementations are available:
48 -# Standard SV queue (cl_syoscb_queue_std)
49 -# MD5 queue (cl_syoscb_queue_hash_md5)
51 and the following compare algorithms are available:
53 -# Out of Order (OOO, cl_syoscb_compare_ooo)
54 -# In Order (IO, cl_syoscb_compare_io).
55 -# In Order with 2 queues, high performance (IO_2HP, cl_syoscb_compare_io_2hp)
56 -# In Order by Producer (IOP, cl_syoscb_compare_iop)
58 Setting the queue topology is done with the method \c set_queue_type in cl_syoscb_cfg. For example, the following line shows how to select the MD5 queue topology for a scoreboard.
61 this.syoscb_cfg.set_queue_type(pk_syoscb::SYOSCB_QUEUE_MD5);
64 The following line shows an example of how to change the compare strategy. Here, OOO comparisons are enabled.
67 this.syoscb_cfg.set_compare_type(pk_syoscb::SYOSCB_COMPARE_OOO);
70 All of the enum values used for selecting queue type and compare algorithm can be found in <b>src/syoscb_common.svh</b>.
72 @section sInstantiation Instantiating the UVM scoreboard
73 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 \c uvm_config_db.
78 class cl_scbtest_env extends uvm_env;
81 cl_syoscb_cfg syoscb_cfg;
83 `uvm_component_utils_begin(cl_scbtest_env)
84 `uvm_field_object(syoscb, UVM_ALL_ON)
85 `uvm_field_object(syoscb_cfg, UVM_ALL_ON)
86 `uvm_component_utils_end
90 endclass: cl_scbtest_env
92 function void cl_scbtest_env::build_phase(uvm_phase phase);
93 super.build_phase(phase);
95 // Create the scoreboard configuration object
96 this.syoscb_cfg = cl_syoscb_cfg::type_id::create("syoscb_cfg");
98 // Pass the scoreboard configuration object to the config_db
99 uvm_config_db #(cl_syoscb_cfg)::set(this, "syoscb", "cfg", this.syoscb_cfg);
101 // Create the scoreboard
102 this.syoscb = cl_syoscb::type_id::create("syoscb", this);
106 endfunction: build_phase
109 @section sConfiguration Configuring the UVM scoreboard
110 A default configuration is not created, so a configuration object must be constructed, configured and set in the UVM configuration database for each scoreboard instance to pick it up. One must create a separate scoreboard configuration object for each scoreboard instance. It cannot be reused!
111 The following example shows a scoreboard with two queues, Q1 and Q2, with Q1 as the primary queue. Furthermore, one producer P1 is added to both queues:
114 function void cl_scbtest_env::build_phase(uvm_phase phase);
115 super.build_phase(phase);
117 // Create the scoreboard configuration object
118 this.syoscb_cfg = cl_syoscb_cfg::type_id::create("syoscb_cfg");
120 // Configure the scoreboard
121 this.syoscb_cfg.set_queues({"Q1", "Q2"});
122 void'(this.syoscb_cfg.set_primary_queue("Q1"));
123 void'(this.syoscb_cfg.set_producer("P1", {"Q1", "Q2"}));
125 // Pass the scoreboard configuration object to the config_db
126 uvm_config_db #(cl_syoscb_cfg)::set(this, "syoscb", "cfg", this.syoscb_cfg);
128 // Create the scoreboard
129 this.syoscb = cl_syoscb::type_id::create("syoscb", this);
133 endfunction: build_phase
136 For more info about the configuration options, see \ref pConfiguration.
138 @subsection ssBuild Full build phase
140 The full build phase of our example environment \c cl_scbtest_env is shown here for completeness:
143 function void cl_scbtest_env::build_phase(uvm_phase phase);
144 super.build_phase(phase);
146 // Use the MD5 queue implementation as scoreboard queue
147 this.syoscb_cfg.set_queue_type(pk_syoscb::SYOSCB_QUEUE_MD5);
149 // Set the compare strategy to be OOO
150 this.syoscb_cfg.set_compare_type(pk_syoscb::SYOSCB_COMPARE_OOO);
152 // Create the scoreboard configuration object
153 this.syoscb_cfg = cl_syoscb_cfg::type_id::create("syoscb_cfg");
155 // Configure the scoreboard
156 this.syoscb_cfg.set_queues({"Q1", "Q2"});
157 void'(this.syoscb_cfg.set_primary_queue("Q1"));
158 void'(this.syoscb_cfg.set_producer("P1", {"Q1", "Q2"}));
160 // Pass the scoreboard configuration object to the config_db
161 uvm_config_db #(cl_syoscb_cfg)::set(this, "syoscb", "cfg", this.syoscb_cfg);
163 // Create the scoreboard
164 this.syoscb = cl_syoscb::type_id::create("syoscb", this);
168 endfunction: build_phase
171 @section sAddSequenceItems Add sequence items to the scoreboard
172 @subsection ssFunctionAPIHookUp Function based API hook up
173 The function based API is very easy to use once you have done the configuration and instantiation
174 of the scoreboard as described above.
176 Whenever you need to add a UVM sequence item to a queue produced by a specified producer, simply
177 invoke the cl_syoscb::add_item() method:
180 // *NOTE*: Assumes syoscb is handle to an instance of the scoreboard and
181 // item1 is a handle to a UVM sequence item
185 // Insert UVM sequence item for queue: Q1, for producer: P1
186 syoscb.add_item("Q1", "P1", item1);
189 Invoking the cl_syoscb::add_item() method will wrap the UVM sequence item in a cl_syoscb_item object, add it to the correct queue and finally invoke the configured compare algorithm.
191 The UVM environment will typically contain a handle to the scoreboard as described above.
192 This can then be utilized if UVM sequence item needs to be added from a test case:
195 class cl_scbtest_seq_item extends uvm_sequence_item;
196 //-------------------------------------
197 // Randomizable variables
198 //-------------------------------------
199 rand int unsigned int_a;
201 //-------------------------------------
203 //-------------------------------------
204 `uvm_object_utils_begin(cl_scbtest_seq_item)
205 `uvm_field_int(int_a, UVM_ALL_ON)
206 `uvm_object_utils_end
208 //-------------------------------------
210 //-------------------------------------
211 function cl_scbtest_seq_item::new (string name = "cl_scbtest_seq_item");
214 endclass: cl_scbtest_seq_item
216 class cl_scbtest_test extends uvm_test;
217 //-------------------------------------
218 // Non randomizable variables
219 //-------------------------------------
220 cl_scbtest_env scbtest_env;
222 //-------------------------------------
224 //-------------------------------------
225 `uvm_component_utils(cl_scbtest_test)
227 //-------------------------------------
229 //-------------------------------------
230 function new(string name = "cl_scbtest_test", uvm_component parent = null);
231 super.new(name, parent);
234 //-------------------------------------
236 //-------------------------------------
237 function void build_phase(uvm_phase phase);
238 super.build_phase(phase);
239 scbtest_env = cl_scbtest_env::type_id::create("scbtest_env", this);
240 endfunction: build_phase
242 task run_phase(uvm_phase phase);
243 super.run_phase(phase);
245 cl_scbtest_seq_item item1;
246 item1 = cl_scbtest_seq_item::type_id::create("item1");
248 scbtest_env.syoscb.add_item("Q1", "P1", item1);
251 cl_scbtest_seq_item item1;
252 item1 = cl_scbtest_seq_item::type_id::create("item1");
254 scbtest_env.syoscb.add_item("Q2", "P1", item1);
257 endclass: cl_scbtest_test
260 @subsection ssTLMAPIHookUp TLM based API hook up
262 The TLM API is even easier to use than the function based API.
263 The scoreboard provides a generic UVM subscribers for each producer on each queue. This subscriber can cbe onnected to anything which has a UVM analysis port (e.g. a UVM monitor).
264 Typically, the UVM agents inside the UVM environment contain one or more monitors with UVM analysis ports which should be connected to the scoreboard.
265 The following example shows two agents, each of which has a monitor.
266 The monitors are connected to Q1 and Q2 in the scoreboard, acting as producer P1:
271 class cl_scbtest_env extends uvm_env;
274 cl_syoscb_cfg syoscb_cfg;
280 function void build_phase(uvm_phase phase);
284 // Configure and create the scoreboard
285 // Create and configure the agents
289 endfunction: build_phase
293 function void connect_phase(uvm_phase phase);
294 super.connect_phase(phase);
297 cl_syoscb_subscriber subscriber;
299 // Get the subscriber for Producer: P1 for queue: Q1 and connect it
300 // to the UVM monitor producing transactions for this queue
301 subscriber = this.syoscb.get_subscriber("Q1", "P1");
302 this.agent1.mon.<analysis port>.connect(subscriber.analysis_export);
304 // Get the subscriber for Producer: P1 for queue: Q2 and connect it
305 // to the UVM monitor producing transactions for this queue
306 subscriber = this.syoscb.get_subscriber("Q2", "P1");
307 this.agent1.mon.<analysis port>.connect(subscriber.analysis_export);
309 endfunction: connect_phase
310 endclass: cl_scbtest_env
313 @section sMultipleSCBintances Multiple SCB instances & filter transforms
315 The SyoSil UVM scoreboard also comes with a scoreboard wrapper, cl_syoscbs_base, which can be used to instantiate several scoreboards with similar configurations.
317 A configuration wrapper, cl_syoscbs_cfg, is used to configure the scoreboard wrapper. The configuration wrapper contains N configuration objects, one for each wrapped scoreboard. The wrapped scoreboards may have different queue / producer names and numbers of queues/producers, or they may be the same. See the figure below for a UML diagram of the relationship between individual scoreboards and their configurations, and the scoreboard wrapper and its configuration object.
319 \image html syoscbs.drawio.png
320 \image latex syoscbs.pdf width=0.5\textwidth
322 @subsection ssFilterTransforms Filter transforms
323 Since UVM analysis ports are parameterized with the types of items they will accept, and the SyoSil scoreboard's cl_syoscb_subscriber expects input items to be of type \c uvm_sequence_item, a transformation must be used to upcast sequence items to this datatype before they are inserted. When using a single scoreboard, this transformation can easily be instantiated manually, or items can be upcast in a monitor before being written to the attached subscriber.
325 In the case where 100's or 1000's of scoreboards are used, manually instantiating and connecting all of these transforms can become tedious. Instead, the scoreboard wrapper offers <b>filter transforms</b> to automate the process. When creating the scoreboard wrapper cl_syoscbs, it must be parameterized with the type of sequence items that will be input. It then automatically instantiates a transformation object for each subscriber, and connects its output to the input of the subscriber. Now, instead of retrieving the subscribers for each queue/producer, a filter transform for each scoreboard's queue/producer combination should be retrieved.
327 The default filter transform pk_utils_uvm::filter_trfm, included in <b>lib/pk_utils_uvm.sv</b>, simply upcasts its input to a \c uvm_sequence_item before passing it on to the scoreboard. If more complex transforms are required, you can extend cl_syoscbs_base and implement cl_syoscb_base#create_filter to suit your needs.
329 The class cl_syoscbs_base serves as the base class for the scoreboard wrapper, and a default implementation is included in cl_syoscbs. The default implementation should be enough for most applications
331 In the example below, a scoreboard wrapper with 10 scoreboards is created. Each scoreboard has two queues, DUT and REF, each of which has two producers, P1 and P2.
332 In the environment's build phase, the scoreboard wrapper and config object are created. After initializing the configuration object, it is passed to the scoreboard wrapper with the UVM configuration database.
333 In the environment's connect phase, each DUT agent is connected to filter transforms associated with their respective scoreboard.
334 The parameter \c FIN is the input type to the filter transforms. The filter transforms convert this type to a \c uvm_sequence_item which is passed into the scoreboard.
339 class cl_scbs_env#(type FIN = my_seq_item) extends uvm_env;
341 cl_syoscbs#(FIN) syoscbs;
342 cl_syoscbs_cfg syoscbs_cfg;
343 dut_agent dut_agents[NUM_SCB];
344 ref_agent ref_agents[NUM_SCB];
345 string producers[] = '{"P1", "P2"};
346 string queues[] = '{"DUT", "REF"};
350 function void build_phase(uvm_phase phase);
351 super.build_phase(phase);
352 this.syoscbs_cfg = cl_syoscbs_cfg::type_id::create("syoscbs_cfg");
353 //Create an scb wrapper named my_syoscbs with 10 scoreboards. They will be named "scb[i]",
354 //and each will have queues named "DUT", "REF", and each queue will have producers "P1" and "P2"
355 this.syoscbs_cfg.init("syoscbs", NUM_SCB, "scb", queues, producers);
357 uvm_config_db #(cl_syoscbs_cfg)::set(this, "", "syoscbs", this.syoscbs_cfg);
359 this.syoscbs = cl_syoscbs#(FIN)::type_id::create("syoscbs");
361 ... //Create and configure all dut agents and ref agents
362 endfunction: build_phase
364 function void connect_phase(uvm_phase phase);
365 //Each DUT agent is connected to a separate scoreboard
366 foreach(dut_agents[i]) begin
367 pk_utils_uvm::filter_trfm#(FIN, uvm_sequence_item) filter_trfm_p1;
368 pk_utils_uvm::filter_trfm#(FIN, uvm_sequence_item) filter_trfm_p2;
370 //Get handles to the filter transforms connected to DUT queue for P1 and P2, scoreboard 'i'
371 filter_trfm_p1 = this.syoscbs.get_filter_trfm("DUT", "P1", i);
372 filter_trfm_p2 = this.syoscbs.get_filter_trfm("DUT", "P2", i);
373 //Connect agents to filter transforms
374 dut_agents[i].p1_anls_port.connect(filter_trfm_p1.analysis_export);
375 dut_agents[i].p2_anls_port.connect(filter_trfm_p2.analsysi_export);
377 // ... Perform the same procedure for reference model ports
378 endfunction: connect_phase
382 The included testcases also include several tests using the scoreboard wrapper, which can be used as a starting point. See cl_scbs_test_base and cl_tb_env_scbs.
383 See <b>tb/test/scbs/cl_scbs_test_base</b> and <b>tb/cl_tb_env_scbs</b>.