Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / fnx / vlib / CSRFmwork / src / CSRAccessor.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: CSRAccessor.vr
4// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
5// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
6//
7// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8//
9// This program is free software; you can redistribute it and/or modify
10// it under the terms of the GNU General Public License as published by
11// the Free Software Foundation; version 2 of the License.
12//
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21//
22// For the avoidance of doubt, and except that if any non-GPL license
23// choice is available it will apply instead, Sun elects to use only
24// the General Public License version 2 (GPLv2) at this time for any
25// software where a choice of GPL license versions is made
26// available with the language indicating that GPLv2 or any later version
27// may be used, or where a choice of which version of the GPL is applied is
28// otherwise unspecified.
29//
30// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
31// CA 95054 USA or visit www.sun.com if you need additional information or
32// have any questions.
33//
34// ========== Copyright Header End ============================================
35#include "report_macros.vri"
36
37class CSRAccessor extends AccessorBase {
38
39 //=================================================
40 // Constructor
41 //=================================================
42
43 task new ( CSRState ShadowState,
44 bit [CSRT_ADDR_OFFSET_WIDTH-1:0] input_addr_offset ,
45 bit [CSRT_DATA_WIDTH-1:0] input_por_value ,
46 bit [CSRT_DATA_WIDTH-1:0] input_rmask ,
47 bit [CSRT_DATA_WIDTH-1:0] input_read_only_mask ,
48 bit [CSRT_DATA_WIDTH-1:0] input_write_mask ,
49 bit [CSRT_DATA_WIDTH-1:0] input_clear_mask ,
50 bit [CSRT_DATA_WIDTH-1:0] input_set_mask ,
51 bit [CSRT_DATA_WIDTH-1:0] input_toggle_mask ,
52 string input_name ,
53 integer input_num_fields ,
54 CSRAccessMethod input_access_methods[],
55 integer input_access_level[],
56 string input_access_name[],
57 integer input_default_access_method
58 ) {
59
60
61 super.new ( ShadowState,
62 input_addr_offset,
63 input_por_value,
64 input_rmask,
65 input_read_only_mask,
66 input_write_mask,
67 input_clear_mask,
68 input_set_mask,
69 input_toggle_mask,
70 input_name,
71 input_num_fields);
72
73 csr_check_enabled = CSRT_CHECK_ENABLED;
74
75 set_method_array(input_access_methods, input_access_level, input_access_name);
76
77 DefaultMethod = input_default_access_method;
78 } // end task new
79
80
81 //=================================================
82 // Read function
83 //=================================================
84 function bit [CSRT_DATA_WIDTH-1:0] read (integer method = CSRT_USE_DEFAULT_METHOD){
85
86 if (method == CSRT_USE_DEFAULT_METHOD)
87 method = DefaultMethod;
88
89
90 QuickReport(CSRReport, RTYP_CSR_DEBUG_1,"CSRAccessor: %s read(): %s register: Addr %0h",
91 get_method_name(method),
92 get_name(),
93 get_addr_offset());
94
95
96 check_method(method);
97
98 if (method == CSRT_STUB) {
99 QuickReport(CSRReport, RTYP_CSR_DEBUG_1,"CSRAccessor: Stub read of %s register: ", get_name());
100 } // end if CSRT_STUB
101 else {
102 read = access_methods[method].read(get_addr_offset());
103 }
104 } // end function read
105
106
107 //=================================================
108 // Write task
109 //=================================================
110 task write (bit [CSRT_DATA_WIDTH-1:0] csr_data, integer method = CSRT_USE_DEFAULT_METHOD ){
111
112 if (method == CSRT_USE_DEFAULT_METHOD)
113 method = DefaultMethod;
114
115 QuickReport(CSRReport, RTYP_CSR_DEBUG_1,"CSRAccessor: %s write(): %s register: Addr %0h : data %0h",
116 get_method_name(method),
117 get_name(),
118 get_addr_offset(),
119 csr_data);
120
121 check_method(method);
122
123 // Ensure only one modifying transaction per register
124 semaphore_get (WAIT, ShadowState.csr_write_trans_sem, 1);
125
126 // Perform Hardware Write
127 if (method != CSRT_STUB)
128 access_methods[method].write(get_addr_offset(), csr_data);
129
130 if (access_level[method] == CSRT_FULL_ACCESS || method == CSRT_OMNI) {
131 update_shadow_data (csr_data);
132 }
133 else if (access_level[method] == CSRT_HW_ACCESS) {
134 //Can not reliably update shadow state when register supports
135 //HW access control. It is up to the user to use set_shadow_csr.
136 //Setting X value will provide a trival match when comparing shadow state
137 update_shadow_data (64'hx);
138 }
139 else
140 QuickReport(CSRReport, RTYP_CSR_ALERT,"CSRAccessor::write: Unable to update shadow state for %s register using current access method ",
141 get_name());
142
143 semaphore_put (ShadowState.csr_write_trans_sem, 1);
144
145 QuickReport(CSRReport, RTYP_CSR_DEBUG_3,"%0d:CSRAccessor::write: %s register:\t%0h\n",get_cycle(),get_name(),csr_data);
146 } // end task write
147
148
149 //=================================================
150 // Check Register Function
151 //=================================================
152 // The following change was made on 9/21/01 -RFT
153 // This function should really be based on a wild card match, allowing
154 // a don't care setting for the shadow data. This is necessary for registers
155 // that don't have a specific POR value because they are not connected to
156 // reset.
157 //
158 function integer check_register (integer method = CSRT_USE_DEFAULT_METHOD) {
159
160 bit [CSRT_DATA_WIDTH-1:0] actual_data;
161 bit [CSRT_DATA_WIDTH-1:0] expected_data;
162 bit [CSRT_DATA_WIDTH-1:0] diff_vector = 64'h0;
163 integer index = 0;
164 bit success = 1;
165
166 if (method == CSRT_USE_DEFAULT_METHOD)
167 method = DefaultMethod;
168
169 if (csr_check_enabled) {
170 printf("inside csr_check_enabled \n");
171 actual_data = read(method);
172 expected_data = get_shadow_data();
173
174 while (index < CSRT_DATA_WIDTH) {
175
176 //If expected_data indicates a wildcard, then skip comparison
177 if (expected_data[index] !== 1'bx)
178 if (actual_data[index] !== expected_data[index]) {
179 diff_vector[index] = 1'b1;
180 success = 1'b0;
181 }
182
183 ++index;
184 }
185 // After the actual data is screened for X's it is okay to apply a wildcard
186 // comparision. This allows expected data to contain the wildcards.
187 if (!success) {
188
189 //These are not report calls because there is no good way to print leading
190 //zeros in data without printing 512 bits by default.
191 QuickReport(CSRReport, RTYP_CSR_ERROR, "CSRAccessor::check_register:ERROR - %s REGISTER MISMATCHED.",
192 get_name() );
193 printf("\tACTUAL = 64'h%h\n\tEXPECTED = 64'h%h\n\tDiff Vector = 64'h%h\n",
194 actual_data,
195 expected_data,
196 diff_vector);
197
198 check_register = CSRT_MISMATCH_RETURN_CODE;
199 }
200 else
201 check_register = CSRT_SUCCESSFUL_RETURN_CODE;
202 printf("Data match: \tACTUAL = 64'h%h\n\tEXPECTED = 64'h%h\n\t",
203 actual_data,
204 expected_data);
205 } //check enabled
206
207 else {
208 QuickReport(CSRReport, RTYP_CSR_ALERT,"CSR %s REGISTER CHECKING DISABLED", get_name());
209 check_register = CSRT_SUCCESSFUL_RETURN_CODE;
210 }
211 } // end function check_register
212
213
214 //=================================================
215 // Reset Task
216 //=================================================
217
218 task reset () {
219
220 QuickReport(CSRReport, RTYP_CSR_DEBUG_3,"%0d:CSRAccessor::reset: %s register\t%0h",
221 get_cycle(),get_name(),get_por_value());
222
223 semaphore_get (WAIT, ShadowState.csr_write_trans_sem, 1);
224 set_shadow_data(get_por_value());
225 semaphore_put (ShadowState.csr_write_trans_sem, 1);
226 } // end task reset
227
228
229 //=================================================
230 // Read Field Function
231 //=================================================
232 function bit [CSRT_DATA_WIDTH-1:0] read_field ( integer field_id,
233 integer method = CSRT_USE_DEFAULT_METHOD) {
234 bit [CSRT_DATA_WIDTH-1:0] temp_data;
235
236 if (method == CSRT_USE_DEFAULT_METHOD)
237 method = DefaultMethod;
238
239 if (field_id < get_max_num_fields()) {
240 QuickReport(CSRReport, RTYP_CSR_DEBUG_3,"%0d:CSR read_field(): %s register %s field:\t%0h",
241 get_cycle(),get_name(),reg_field[field_id].get_field_name(),read_field);
242
243 temp_data = read(method);
244 temp_data = temp_data & reg_field[field_id].get_field_mask();
245 temp_data = temp_data >> reg_field[field_id].get_field_position();
246 read_field = temp_data;
247 }
248 else {
249 QuickReport(CSRReport, RTYP_CSR_ERROR, "CSRAccessor::read_field: Invalid field_id %0h", field_id);
250 }
251 } // end function read_field
252
253
254 //=================================================
255 // Write Field Task
256 //=================================================
257 task write_field ( integer field_id,
258 bit [CSRT_DATA_WIDTH-1:0] field_data,
259 integer method = CSRT_USE_DEFAULT_METHOD ) {
260
261 bit [CSRT_DATA_WIDTH-1:0] curr_data;
262 bit [CSRT_DATA_WIDTH-1:0] revised_data;
263 bit [CSRT_DATA_WIDTH-1:0] field_positioned_data;
264 bit [CSRT_DATA_WIDTH-1:0] zero_field_mask;
265 bit [CSRT_DATA_WIDTH-1:0] refresh_bit_mask;
266
267 if (method == CSRT_USE_DEFAULT_METHOD)
268 method = DefaultMethod;
269
270 if (field_id < get_max_num_fields()) {
271
272 QuickReport(CSRReport, RTYP_CSR_DEBUG_3,"%0d:CSR write_field(): %s register %s field:\t%0h",
273 get_cycle(),get_name(),reg_field[field_id].get_field_name(),field_data);
274
275
276 semaphore_get (WAIT, ShadowState.csr_write_trans_sem, 1);
277
278 field_positioned_data = reg_field[field_id].get_field_mask() & (field_data << reg_field[field_id].get_field_position());
279 curr_data = read(method);
280 zero_field_mask = ~(reg_field[field_id].get_field_mask());
281 refresh_bit_mask = zero_field_mask & get_write_mask ();
282 revised_data = (curr_data & refresh_bit_mask) | field_positioned_data;
283
284 if (access_level[method] == CSRT_FULL_ACCESS || method == CSRT_OMNI) {
285 update_shadow_data (revised_data);
286 }
287 else if (access_level[method] == CSRT_HW_ACCESS) {
288 //Can not reliably update shadow state when register supports
289 //HW access control. It is up to the user to use set_shadow_csr.
290 //Setting X value will provide a trival match when comparing shadow state
291 update_shadow_data (64'hx);
292 }
293 else
294 QuickReport(CSRReport, RTYP_CSR_ALERT,"CSRAccessor::write_field: Unable to update shadow state for %s register using current access method ",
295 get_name());
296
297 access_methods[method].write(get_addr_offset(), revised_data);
298
299 semaphore_put (ShadowState.csr_write_trans_sem, 1);
300 }
301 else {
302 QuickReport(CSRReport, RTYP_CSR_ERROR, "CSRAccessor::write_field: Invalid field_id %0h", field_id);
303 }
304 } // end task write_field
305
306
307 //=================================================
308 // Write Fields Task
309 //=================================================
310 task write_fields(CSRFieldAggregate field_aggregate, integer method = CSRT_USE_DEFAULT_METHOD, bit use_method_read = 0) {
311 bit [CSRT_DATA_WIDTH-1:0] curr_data;
312 bit [CSRT_DATA_WIDTH-1:0] revised_data;
313 bit [CSRT_DATA_WIDTH-1:0] field_positioned_data = 0;
314 bit [CSRT_DATA_WIDTH-1:0] zero_field_mask = 0;
315 bit [CSRT_DATA_WIDTH-1:0] refresh_bit_mask = 0;
316
317 CSRAggregateContainer field_container;
318
319 zero_field_mask = ~zero_field_mask;
320
321 if (method == CSRT_USE_DEFAULT_METHOD)
322 method = DefaultMethod;
323
324 semaphore_get (WAIT, ShadowState.csr_write_trans_sem, 1);
325
326 if (use_method_read)
327 curr_data = read(method);
328 else
329 curr_data = get_shadow_data();
330
331 field_container = field_aggregate.pop();
332
333 while (field_container != null) {
334 if (field_container.field_id < get_max_num_fields()) {
335
336 // CSRReport.report(RTYP_INFO,"%0d:CSR write_fields(): %s register %s field:\t%0h\n", get_cycle(), get_name(),
337 // reg_field[field_container.field_id].get_field_name(), field_container.field_data);
338
339 field_positioned_data |= (reg_field[field_container.field_id].get_field_mask() &
340 (field_container.field_data << reg_field[field_container.field_id].get_field_position()));
341 zero_field_mask &= ~(reg_field[field_container.field_id].get_field_mask());
342 refresh_bit_mask |= zero_field_mask & get_write_mask();
343 } else {
344 QuickReport(CSRReport, RTYP_CSR_ERROR, "CSRAccessor::write_fields: Invalid field_id %0h", field_container.field_id);
345 }
346 field_container = field_aggregate.pop();
347 }
348
349 revised_data = (curr_data & refresh_bit_mask) | field_positioned_data;
350
351 if (access_level[method] == CSRT_FULL_ACCESS || method == CSRT_OMNI) {
352 update_shadow_data (revised_data);
353 } else if (access_level[method] == CSRT_HW_ACCESS) {
354 //Can not reliably update shadow state when register supports HW access control. It is up to the user to use set_shadow_csr.
355 //Setting X value will provide a trival match when comparing shadow state
356 update_shadow_data (64'hx);
357 } else
358 QuickReport(CSRReport, RTYP_CSR_ALERT,"CSRAccessor: (write_fields) Unable to update shadow state for %s register using current access method",
359 get_name());
360
361 if (curr_data !== revised_data) {
362 QuickReport(CSRReport, RTYP_CSR_DEBUG_1,"CSRAccessor: %s write_fields(): %s register: Addr %0h : data %0h", get_method_name(method), get_name(),
363 get_addr_offset(), revised_data);
364 access_methods[method].write(get_addr_offset(), revised_data);
365 } else {
366 QuickReport(CSRReport, RTYP_CSR_DEBUG_1,"CSRAccessor: %s write_fields(): %s register: Addr %0h : data %0h %s", get_method_name(method),
367 get_name(), get_addr_offset(), revised_data, " -- Not writing due to current_data == new_data");
368 }
369
370 semaphore_put (ShadowState.csr_write_trans_sem, 1);
371 } // end task write_fields
372
373
374 //=================================================
375 // Set Shadow CSR Task
376 //=================================================
377 task set_shadow_csr(bit [CSRT_DATA_WIDTH-1:0] new_data, integer field_id = -1) {
378 bit [CSRT_DATA_WIDTH-1:0] curr_data;
379 bit [CSRT_DATA_WIDTH-1:0] revised_data;
380 bit [CSRT_DATA_WIDTH-1:0] field_positioned_data;
381 bit [CSRT_DATA_WIDTH-1:0] zero_field_mask;
382
383 semaphore_get (WAIT, ShadowState.csr_write_trans_sem, 1);
384
385 QuickReport(CSRReport, RTYP_CSR_DEBUG_1, "CSRAccessor: set_shadow_csr(): %s register: Addr %0h : data %0h",
386 get_name(), get_addr_offset(), new_data);
387
388 if (field_id == -1)
389 //No field specfied - set entire CSR
390 set_shadow_data (new_data);
391 else {
392 if (field_id < get_max_num_fields()) {
393 field_positioned_data = reg_field[field_id].get_field_mask() & (new_data << reg_field[field_id].get_field_position());
394 curr_data = get_shadow_data();
395 zero_field_mask = ~(reg_field[field_id].get_field_mask());
396 revised_data = (curr_data & zero_field_mask) | field_positioned_data;
397 set_shadow_data (revised_data);
398 }
399 else
400 QuickReport(CSRReport, RTYP_CSR_ALERT,"CSRAccessor::set_shadow_csr: Field ID out of range\n");
401 }
402
403 semaphore_put (ShadowState.csr_write_trans_sem, 1);
404 } // end task set_shadow_csr()
405
406
407 //=================================================
408 // Get Shadow CSR Function
409 //=================================================
410 function bit [CSRT_DATA_WIDTH-1:0] get_shadow_csr(integer field_id = -1) {
411 bit [CSRT_DATA_WIDTH-1:0] temp_data;
412
413 QuickReport(CSRReport, RTYP_CSR_DEBUG_1, "CSRAccessor: get_shadow_csr(): %s register: Addr %0h", get_name(), get_addr_offset());
414
415 if (field_id == -1)
416 //No field specfied - return entire CSR
417 get_shadow_csr = get_shadow_data();
418 else {
419 temp_data = get_shadow_data();
420 temp_data = temp_data & reg_field[field_id].get_field_mask();
421 temp_data = temp_data >> reg_field[field_id].get_field_position();
422 get_shadow_csr = temp_data;
423 }
424 } // end function get_shadow_csr()
425
426} // end class CSRAccessor
427
428
429