1 |
4 |
vladimirar |
//----------------------------------------------------------------------
|
2 |
|
|
// Copyright 2014-2015 SyoSil ApS
|
3 |
|
|
// All Rights Reserved Worldwide
|
4 |
|
|
//
|
5 |
|
|
// Licensed under the Apache License, Version 2.0 (the
|
6 |
|
|
// "License"); you may not use this file except in
|
7 |
|
|
// compliance with the License. You may obtain a copy of
|
8 |
|
|
// the License at
|
9 |
|
|
//
|
10 |
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
11 |
|
|
//
|
12 |
|
|
// Unless required by applicable law or agreed to in
|
13 |
|
|
// writing, software distributed under the License is
|
14 |
|
|
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
15 |
|
|
// CONDITIONS OF ANY KIND, either express or implied. See
|
16 |
|
|
// the License for the specific language governing
|
17 |
|
|
// permissions and limitations under the License.
|
18 |
|
|
//----------------------------------------------------------------------
|
19 |
|
|
/// Class which base concet of a queue. All queues must extend this class
|
20 |
|
|
/// and implement the queue API.
|
21 |
|
|
class cl_syoscb_queue extends uvm_component;
|
22 |
|
|
//-------------------------------------
|
23 |
|
|
// Non randomizable variables
|
24 |
|
|
//-------------------------------------
|
25 |
|
|
/// Handle to the configuration
|
26 |
|
|
protected cl_syoscb_cfg cfg;
|
27 |
|
|
|
28 |
|
|
/// List of iterators registered with queue
|
29 |
|
|
protected cl_syoscb_queue_iterator_base iterators[cl_syoscb_queue_iterator_base];
|
30 |
|
|
|
31 |
|
|
/// Current number of iterators
|
32 |
|
|
protected int unsigned iter_idx;
|
33 |
|
|
|
34 |
|
|
/// Semaphore guarding exclusive access to the queue when
|
35 |
|
|
/// multiple iterators are in play
|
36 |
|
|
protected semaphore iter_sem;
|
37 |
|
|
|
38 |
|
|
// Counter for counting the number of inserts
|
39 |
|
|
protected int unsigned cnt_add_item = 0;
|
40 |
|
|
|
41 |
|
|
//-------------------------------------
|
42 |
|
|
// UVM Macros
|
43 |
|
|
//-------------------------------------
|
44 |
|
|
`uvm_component_utils_begin(cl_syoscb_queue)
|
45 |
|
|
`uvm_field_object(cfg, UVM_DEFAULT)
|
46 |
|
|
// TBD::JSA: Lacks a user defined implementation of field macro
|
47 |
|
|
// for completeness since: `uvm_field_aa_object-object does not exist
|
48 |
|
|
`uvm_field_int(iter_idx, UVM_DEFAULT)
|
49 |
|
|
`uvm_field_int(cnt_add_item, UVM_DEFAULT)
|
50 |
|
|
`uvm_component_utils_end
|
51 |
|
|
|
52 |
|
|
//-------------------------------------
|
53 |
|
|
// Constructor
|
54 |
|
|
//-------------------------------------
|
55 |
|
|
extern function new(string name, uvm_component parent);
|
56 |
|
|
|
57 |
|
|
//-------------------------------------
|
58 |
|
|
// UVM Phase methods
|
59 |
|
|
//-------------------------------------
|
60 |
|
|
extern function void build_phase(uvm_phase phase);
|
61 |
|
|
extern function void check_phase(uvm_phase phase);
|
62 |
|
|
extern function void report_phase(uvm_phase phase);
|
63 |
|
|
|
64 |
|
|
//-------------------------------------
|
65 |
|
|
// Queue API
|
66 |
|
|
//-------------------------------------
|
67 |
|
|
// Basic queue functions
|
68 |
|
|
extern virtual function bit add_item(string producer, uvm_sequence_item item);
|
69 |
|
|
extern virtual function bit delete_item(int unsigned idx);
|
70 |
|
|
extern virtual function cl_syoscb_item get_item(int unsigned idx);
|
71 |
|
|
extern virtual function int unsigned get_size();
|
72 |
|
|
extern virtual function bit empty();
|
73 |
|
|
extern virtual function bit insert_item(string producer, uvm_sequence_item item, int unsigned idx);
|
74 |
|
|
|
75 |
|
|
// Iterator support functions
|
76 |
|
|
extern virtual function cl_syoscb_queue_iterator_base create_iterator();
|
77 |
|
|
extern virtual function bit delete_iterator(cl_syoscb_queue_iterator_base iterator);
|
78 |
|
|
|
79 |
|
|
// Locator support functions
|
80 |
|
|
// TBD::JSA: Locator not implemented yet
|
81 |
|
|
|
82 |
|
|
// Misc support functions
|
83 |
|
|
extern function cl_syoscb_cfg get_cfg();
|
84 |
|
|
endclass: cl_syoscb_queue
|
85 |
|
|
|
86 |
|
|
function cl_syoscb_queue::new(string name, uvm_component parent);
|
87 |
|
|
super.new(name, parent);
|
88 |
|
|
|
89 |
|
|
this.iter_sem = new(1);
|
90 |
|
|
this.iter_idx = 0;
|
91 |
|
|
endfunction: new
|
92 |
|
|
|
93 |
|
|
/// Gets the global scoreboard configuration
|
94 |
|
|
function void cl_syoscb_queue::build_phase(uvm_phase phase);
|
95 |
|
|
if (!uvm_config_db #(cl_syoscb_cfg)::get(this, "", "cfg", this.cfg)) begin
|
96 |
|
|
`uvm_fatal("CFG_ERROR", $sformatf("[%s]: Configuration object not passed.", this.cfg.get_scb_name()))
|
97 |
|
|
end
|
98 |
|
|
endfunction
|
99 |
|
|
|
100 |
|
|
/// Checks if the queue is empty. If not then a UVM error is issued.
|
101 |
|
|
function void cl_syoscb_queue::check_phase(uvm_phase phase);
|
102 |
|
|
// Check that this queue is empty. If not then issue an error
|
103 |
|
|
if(!this.empty()) begin
|
104 |
|
|
// *NOTE*: Using this.get_name() is sufficient since the component
|
105 |
|
|
// instance name is the queue name by definition
|
106 |
|
|
`uvm_error("QUEUE_ERROR", $sformatf("[%s]: Queue %s not empty, entries: %0d", this.cfg.get_scb_name(), this.get_name(), this.get_size()));
|
107 |
|
|
end
|
108 |
|
|
endfunction
|
109 |
|
|
|
110 |
|
|
/// Prints queue stats
|
111 |
|
|
function void cl_syoscb_queue::report_phase(uvm_phase phase);
|
112 |
|
|
string stats;
|
113 |
|
|
|
114 |
|
|
stats = $sformatf("Inserts: %0d, Macthed: %0d, Orphans: %0d", this.cnt_add_item, this.cnt_add_item-this.get_size(), this.get_size());
|
115 |
|
|
|
116 |
|
|
// *NOTE*: Using this.get_name() is sufficient since the component
|
117 |
|
|
// instance name is the queue name by definition
|
118 |
|
|
`uvm_info("QUEUE", $sformatf("[%s]: Statistics for queue: %s:\n%s", this.cfg.get_scb_name(), this.get_name(), stats), UVM_NONE)
|
119 |
|
|
endfunction
|
120 |
|
|
|
121 |
|
|
/// Queue API: Adds an uvm_sequence_item. The implementation must wrap this in a
|
122 |
|
|
/// cl_syoscb_item object before the item is inserted
|
123 |
|
|
function bit cl_syoscb_queue::add_item(string producer, uvm_sequence_item item);
|
124 |
|
|
`uvm_fatal("IMPL_ERROR", $sformatf("[%s]: cl_syoscb_queue::add_item() *MUST* be overwritten", this.cfg.get_scb_name()));
|
125 |
|
|
return(1'b0);
|
126 |
|
|
endfunction
|
127 |
|
|
|
128 |
|
|
/// Queue API: Deletes the item at index idx from the queue
|
129 |
|
|
function bit cl_syoscb_queue::delete_item(int unsigned idx);
|
130 |
|
|
`uvm_fatal("IMPL_ERROR", $sformatf("[%s]: cl_syoscb_queue::delete_item() *MUST* be overwritten", this.cfg.get_scb_name()));
|
131 |
|
|
return(1'b0);
|
132 |
|
|
endfunction
|
133 |
|
|
|
134 |
|
|
/// Queue API: Gets the item at index idx from the queue
|
135 |
|
|
function cl_syoscb_item cl_syoscb_queue::get_item(int unsigned idx);
|
136 |
|
|
`uvm_fatal("IMPL_ERROR", $sformatf("[%s]: cl_syoscb_queue::get_item() *MUST* be overwritten", this.cfg.get_scb_name()));
|
137 |
|
|
return(null);
|
138 |
|
|
endfunction
|
139 |
|
|
|
140 |
|
|
/// Queue API: Returns the current size of the queue
|
141 |
|
|
function int unsigned cl_syoscb_queue::get_size();
|
142 |
|
|
`uvm_fatal("IMPL_ERROR", $sformatf("[%s]: cl_syoscb_queue::get_size() *MUST* be overwritten", this.cfg.get_scb_name()));
|
143 |
|
|
return(0);
|
144 |
|
|
endfunction
|
145 |
|
|
|
146 |
|
|
/// Queue API: Returns whether or not the queue is empty. 1'b0 means thet te queue
|
147 |
|
|
/// is not empty. 1'b1 means that the queue is empty
|
148 |
|
|
function bit cl_syoscb_queue::empty();
|
149 |
|
|
`uvm_fatal("IMPL_ERROR", $sformatf("[%s]: cl_syoscb_queue::empty() *MUST* be overwritten", this.cfg.get_scb_name()));
|
150 |
|
|
return(0);
|
151 |
|
|
endfunction
|
152 |
|
|
|
153 |
|
|
/// Queue API: Inserts a uvm_sequence_item at index idx. The implementation must wrap
|
154 |
|
|
/// the uvm_sequence_item in a cl_syoscb_item before it is inserted.
|
155 |
|
|
function bit cl_syoscb_queue::insert_item(string producer, uvm_sequence_item item, int unsigned idx);
|
156 |
|
|
`uvm_fatal("IMPL_ERROR", $sformatf("[%s]: cl_syoscb_queue::insert_item() *MUST* be overwritten", this.cfg.get_scb_name()));
|
157 |
|
|
return(1'b0);
|
158 |
|
|
endfunction
|
159 |
|
|
|
160 |
|
|
/// Queue API: Creates an iterator for this queue.
|
161 |
|
|
function cl_syoscb_queue_iterator_base cl_syoscb_queue::create_iterator();
|
162 |
|
|
`uvm_fatal("IMPL_ERROR", $sformatf("[%s]: cl_syoscb_queue::create_iterator() *MUST* be overwritten", this.cfg.get_scb_name()));
|
163 |
|
|
return(null);
|
164 |
|
|
endfunction
|
165 |
|
|
|
166 |
|
|
/// Queue API: Deletes a given iterator for this queue.
|
167 |
|
|
function bit cl_syoscb_queue::delete_iterator(cl_syoscb_queue_iterator_base iterator);
|
168 |
|
|
`uvm_fatal("IMPL_ERROR", $sformatf("[%s]: cl_syoscb_queue::delete_item() *MUST* be overwritten", this.cfg.get_scb_name()));
|
169 |
|
|
return(1'b0);
|
170 |
|
|
endfunction
|
171 |
|
|
|
172 |
|
|
function cl_syoscb_cfg cl_syoscb_queue::get_cfg();
|
173 |
|
|
return(this.cfg);
|
174 |
|
|
endfunction
|