SyoSil ApS UVM Scoreboard  1.0.3.0
cl_scb_test_rnd.svh
1 /// Random test to hit all the coverage holes which are not covered
2 /// by tests derived from cl_scb_test_double_scb.
3 // It is based on cl_scb_test_base and instantiates two scoreboards, syoscb[0] and syoscb[1].
4 // Cfg knobs are randomly generated
5 
7  cl_tb_rnd_test_items rnd_items[];
8 
9 
10  //-------------------------------------
11  // UVM Macros
12  //-------------------------------------
13  `uvm_component_utils_begin(cl_scb_test_rnd)
14  `uvm_field_array_object(rnd_items, UVM_DEFAULT)
15  `uvm_component_utils_end
16 
17  //-------------------------------------
18  // Constructor
19  //-------------------------------------
20  extern function new(string name = "cl_scb_test_rnd", uvm_component parent = null);
21  extern virtual function void pre_build();
22  extern function void split_loops( input string names[],
23  output string primary[],
24  output string secondary[]);
25 
26  //-------------------------------------
27  // UVM Phase methods
28  //-------------------------------------
29  extern virtual function void build_phase(uvm_phase phase);
30  extern task run_phase(uvm_phase phase);
31 endclass : cl_scb_test_rnd
32 
33 
34 function cl_scb_test_rnd::new(string name = "cl_scb_test_rnd",
35  uvm_component parent = null);
36  super.new(name, parent);
37 endfunction : new
38 
39 
40 function void cl_scb_test_rnd::pre_build();
41  string l_queues_name[];
42 
43  this.syoscb_cfgs = cl_syoscb_cfgs::type_id::create("syoscb_cfgs");
44  this.syoscb_cfgs.init(pk_tb::NO_OF_SCB);
45 
46  this.rnd_items = new[pk_tb::NO_OF_SCB];
47 
48  foreach(this.syoscb_cfgs.syoscb_cfg[i]) begin
49  this.rnd_items[i] = cl_tb_rnd_test_items::type_id::create($sformatf("rnd_items%0d", i));
50 
51  // Forward the cfg_rnd handle into rnd_item
52  this.rnd_items[i].cfg_rnd = this.config_create_and_randomize();
53 
54  if(!this.rnd_items[i].randomize()) begin
55  `uvm_fatal("TEST_RND", "Randomization of rnd_items failed!")
56  end
57 
58  `uvm_info("TEST_RND", $sformatf("\n rnd_item %0d: \n %s", i,
59  this.rnd_items[i].sprint()), UVM_NONE)
60 
61  this.syoscb_cfgs.syoscb_cfg[i] = cl_syoscb_cfg::type_id::create($sformatf("syoscb_cfg%0d", i));
62 
63  //Creates a number of queues depending from the randomization field inside rnd_items.rnd_cfg
64  l_queues_name = new[this.rnd_items[i].queues_no];
65 
66  foreach(l_queues_name[i]) begin
67  // Queue names are starting from "Q1"
68  l_queues_name[i] = $sformatf("Q%0d", i+1);
69  end
70 
71  // Set queues
72  this.syoscb_cfgs.syoscb_cfg[i].set_queues(l_queues_name);
73 
74  // Set the primary queue
75  if (this.rnd_items[i].cfg_rnd.dynamic_primary_queue == 1'b0) begin
76  if(!this.syoscb_cfgs.syoscb_cfg[i].set_primary_queue("Q1")) begin
77  `uvm_fatal("CFG_ERROR", "syoscb_cfg.set_primary_queue call failed!")
78  end
79  end
80 
81  // Set producer "P1" for the current generated queues list
82  if(!this.syoscb_cfgs.syoscb_cfg[i].set_producer("P1", l_queues_name)) begin
83  `uvm_fatal("CFG_ERROR", "syoscb_cfg.set_producer call failed!")
84  end
85 
86  this.rnd_items[i].cfg_rnd.set_rnd_fields(this.syoscb_cfgs.syoscb_cfg[i]);
87  end
88 endfunction : pre_build
89 
90 
91 function void cl_scb_test_rnd::build_phase(uvm_phase phase);
92  this.pre_build();
93 
94  super.build_phase(phase);
95 
96  uvm_config_db #(cl_syoscb_cfgs)::set(this, "scb_env",
97  "cfg", this.syoscb_cfgs);
98 
99  this.scb_env = cl_tb_env_scb::type_id::create("scb_env", this);
100 endfunction: build_phase
101 
102 
103 task cl_scb_test_rnd::run_phase(uvm_phase phase);
104  string l_queues_name [];
105  string primary_loop_names [];
106  string secondary_loop_names [];
107 
108  phase.raise_objection(this);
109 
110  super.run_phase(phase);
111 
112  foreach (this.scb_env.syoscb[w]) begin
113  this.syoscb_cfgs.syoscb_cfg[w].get_queues(l_queues_name);
114 
115  l_queues_name.shuffle();
116 
117  this.split_loops(l_queues_name, primary_loop_names, secondary_loop_names);
118 
119  fork
120  begin : primary_iteration
121  `uvm_info("RND_TEST",
122  $sformatf("%0s: Primary iteration: adding item on primary group of queues: ",
123  this.scb_env.syoscb[w].get_name()), UVM_LOW)
124 
125  // Fill primary group of queues
126  for(int unsigned k=0; k < this.rnd_items[w].max_generated_item; k++) begin
127  cl_tb_seq_item item1;
128  item1 = cl_tb_seq_item::type_id::create("item1");
129  if(this.rnd_items[w].enable_duplets && this.rnd_items[w].duplet_insertion_idx == k) begin
130  `uvm_info("RND_TEST", $sformatf("Inserted duplet at position: %d. Duplet value: %d",
131  k, k-1), UVM_MEDIUM)
132  item1.int_a = k-1;
133  end
134  else begin
135  item1.int_a = k;
136  end
137 
138  foreach(primary_loop_names[j]) begin
139  scb_env.syoscb[w].add_item(primary_loop_names[j], "P1", item1);
140  end
141  end
142  `uvm_info("RND_TEST",
143  $sformatf("%0s: Primary iteration done",
144  this.scb_env.syoscb[w].get_name()), UVM_LOW)
145  end : primary_iteration
146 
147  begin : secondary_iteration
148  `uvm_info("RND_TEST",
149  $sformatf("%0s: Secondary iteration: adding item on secondary group of queues: ",
150  this.scb_env.syoscb[w].get_name()), UVM_LOW)
151 
152  // Fill secondary group of queues
153  for(int unsigned k=0; k < this.rnd_items[w].max_generated_item; k++) begin
154  cl_tb_seq_item item1;
155  item1 = cl_tb_seq_item::type_id::create("item1");
156  if(this.rnd_items[w].enable_duplets && this.rnd_items[w].duplet_insertion_idx == k) begin
157  `uvm_info("RND_TEST", $sformatf("inserted duplet at position: %d. Duplet value: %d",
158  k, k-1), UVM_MEDIUM)
159  item1.int_a = k-1;
160  end
161  else begin
162  item1.int_a = k;
163  end
164 
165  foreach(secondary_loop_names[j]) begin
166  scb_env.syoscb[w].add_item(secondary_loop_names[j], "P1", item1);
167  end
168  end
169  `uvm_info("RND_TEST",
170  $sformatf("%0s: Secondary iteration done",
171  this.scb_env.syoscb[w].get_name()), UVM_LOW)
172  end : secondary_iteration
173  join
174  end
175 
176  phase.drop_objection(this);
177 endtask: run_phase
178 
179 
180 // Creates two different groups in order to fill queues in 2 different loops
181 function void cl_scb_test_rnd::split_loops( input string names[],
182  output string primary[],
183  output string secondary[]);
184  int unsigned primary_size;
185  int unsigned secondary_size;
186 
187  // In the primary loop I ever want one element at least
188  primary_size = (($urandom) % (names.size()-1)) +1;
189 
190  // Set the remaining queues as secondary size
191  secondary_size = (names.size()) - primary_size;
192 
193  primary = new[primary_size];
194  secondary = new[secondary_size];
195 
196  foreach(primary[i]) begin
197  primary[i] = names[i];
198  `uvm_info("TEST_RND",$sformatf("Primary #%0d: %0s", i, primary[i]), UVM_DEBUG);
199  end
200 
201  foreach(secondary[i]) begin
202  secondary[i] = names[primary_size+i];
203  `uvm_info("TEST_RND",$sformatf("Secondary #%0d: %0s", i, secondary[i]), UVM_DEBUG);
204  end
205 endfunction: split_loops
Random test to hit all the coverage holes which are not covered by tests derived from cl_scb_test_dou...
Base class for all SCB tests.

Project: SyoSil ApS UVM Scoreboard, Revision: 1.0.3.0

Copyright 2014-2022 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.8.14
Generated with IDV SV Filter Version: 2.6.3
Fri Sep 2 2022 14:38:29
Find a documentation bug? Report bugs to: scoreboard@syosil.com