OpenCores
URL https://opencores.org/ocsvn/uart2bus_testbench/uart2bus_testbench/trunk

Subversion Repositories uart2bus_testbench

[/] [uart2bus_testbench/] [trunk/] [tb/] [uvm_src/] [reg/] [sequences/] [uvm_reg_mem_shared_access_seq.svh] - Blame information for rev 16

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 16 HanySalah
//
2
// -------------------------------------------------------------
3
//    Copyright 2004-2008 Synopsys, Inc.
4
//    Copyright 2010 Mentor Graphics Corporation
5
//    All Rights Reserved Worldwide
6
//
7
//    Licensed under the Apache License, Version 2.0 (the
8
//    "License"); you may not use this file except in
9
//    compliance with the License.  You may obtain a copy of
10
//    the License at
11
//
12
//        http://www.apache.org/licenses/LICENSE-2.0
13
//
14
//    Unless required by applicable law or agreed to in
15
//    writing, software distributed under the License is
16
//    distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
17
//    CONDITIONS OF ANY KIND, either express or implied.  See
18
//    the License for the specific language governing
19
//    permissions and limitations under the License.
20
// -------------------------------------------------------------
21
//
22
 
23
//------------------------------------------------------------------------------
24
// Title: Shared Register and Memory Access Test Sequences
25
//------------------------------------------------------------------------------
26
// This section defines sequences for testing registers and memories that are
27
// shared between two or more physical interfaces, i.e. are associated with
28
// more than one  instance.
29
//------------------------------------------------------------------------------
30
 
31
 
32
//------------------------------------------------------------------------------
33
// Class: uvm_reg_shared_access_seq
34
//
35
// Verify the accessibility of a shared register
36
// by writing through each address map
37
// then reading it via every other address maps
38
// in which the register is readable and the backdoor,
39
// making sure that the resulting value matches the mirrored value.
40
//
41
// If bit-type resource named
42
// "NO_REG_TESTS" or "NO_REG_SHARED_ACCESS_TEST"
43
// in the "REG::" namespace
44
// matches the full name of the register,
45
// the register is not tested.
46
//
47
//| uvm_resource_db#(bit)::set({"REG::",regmodel.blk.r0.get_full_name()},
48
//|                            "NO_REG_TESTS", 1, this);
49
//
50
// Registers that contain fields with unknown access policies
51
// cannot be tested.
52
//
53
// The DUT should be idle and not modify any register during this test.
54
//
55
//------------------------------------------------------------------------------
56
 
57
class uvm_reg_shared_access_seq extends uvm_reg_sequence #(uvm_sequence #(uvm_reg_item));
58
 
59
   // Variable: rg
60
   // The register to be tested
61
   uvm_reg rg;
62
 
63
   `uvm_object_utils(uvm_reg_shared_access_seq)
64
 
65
   function new(string name="uvm_reg_shared_access_seq");
66
     super.new(name);
67
   endfunction
68
 
69
 
70
   virtual task body();
71
      uvm_reg_data_t  other_mask;
72
      uvm_reg_data_t  wo_mask[$];
73
      uvm_reg_field fields[$];
74
      uvm_reg_map maps[$];
75
 
76
      if (rg == null) begin
77
         `uvm_error("uvm_reg_shared_access_seq", "No register specified to run sequence on");
78
         return;
79
      end
80
 
81
      // Registers with some attributes are not to be tested
82
      if (uvm_resource_db#(bit)::get_by_name({"REG::",rg.get_full_name()},
83
                                             "NO_REG_TESTS", 0) != null ||
84
          uvm_resource_db#(bit)::get_by_name({"REG::",rg.get_full_name()},
85
                                             "NO_REG_SHARED_ACCESS_TEST", 0) != null )
86
        return;
87
 
88
      // Only look at shared registers
89
      if (rg.get_n_maps() < 2) return;
90
      rg.get_maps(maps);
91
 
92
      // Let's see what kind of bits we have...
93
      rg.get_fields(fields);
94
 
95
      // Identify unpredictable bits and the ones we shouldn't change
96
      other_mask = 0;
97
      foreach (fields[k]) begin
98
         int lsb, w;
99
 
100
         lsb = fields[k].get_lsb_pos();
101
         w   = fields[k].get_n_bits();
102
 
103
         if (!fields[k].is_known_access(maps[0])) begin
104
            repeat (w) begin
105
               other_mask[lsb++] = 1'b1;
106
            end
107
         end
108
      end
109
 
110
      // WO bits will always readback as 0's but the mirror
111
      // with return what is supposed to have been written
112
      // so we cannot use the mirror-check function
113
      foreach (maps[j]) begin
114
         uvm_reg_data_t  wo;
115
         wo = 0;
116
         foreach (fields[k]) begin
117
            int lsb, w;
118
 
119
            lsb = fields[k].get_lsb_pos();
120
            w   = fields[k].get_n_bits();
121
 
122
            if (fields[k].get_access(maps[j]) == "WO") begin
123
               repeat (w) begin
124
                  wo[lsb++] = 1'b1;
125
               end
126
            end
127
         end
128
         wo_mask[j] = wo;
129
      end
130
 
131
      // Try to write through each map
132
      foreach (maps[j]) begin
133
         uvm_status_e status;
134
         uvm_reg_data_t  prev, v;
135
 
136
         // The mirror should contain the initial value
137
         prev = rg.get();
138
 
139
         // Write a random value, except in those "don't touch" fields
140
         v = ({$random, $random} & ~other_mask) | (prev & other_mask);
141
 
142
         `uvm_info("uvm_reg_shared_access_seq", $sformatf("Writing register %s via map \"%s\"...",
143
                                    rg.get_full_name(), maps[j].get_full_name), UVM_LOW);
144
 
145
         `uvm_info("uvm_reg_shared_access_seq", $sformatf("Writing 'h%h over 'h%h", v, prev),UVM_DEBUG);
146
 
147
         rg.write(status, v, UVM_FRONTDOOR, maps[j], this);
148
         if (status != UVM_IS_OK) begin
149
            `uvm_error("uvm_reg_shared_access_seq", $sformatf("Status was %s when writing register \"%s\" through map \"%s\".",
150
                                        status.name(), rg.get_full_name(), maps[j].get_full_name()));
151
         end
152
 
153
         foreach (maps[k]) begin
154
            uvm_reg_data_t  actual, exp;
155
 
156
            `uvm_info("uvm_reg_shared_access_seq", $sformatf("Reading register %s via map \"%s\"...",
157
                                       rg.get_full_name(), maps[k].get_full_name()), UVM_LOW);
158
 
159
            // Was it what we expected?
160
            exp = rg.get() & ~wo_mask[k];
161
 
162
            rg.read(status, actual, UVM_FRONTDOOR, maps[k], this);
163
            if (status != UVM_IS_OK) begin
164
               `uvm_error("uvm_reg_shared_access_seq", $sformatf("Status was %s when reading register \"%s\" through map \"%s\".",
165
                                           status.name(), rg.get_full_name(), maps[k].get_full_name()));
166
            end
167
 
168
            `uvm_info("uvm_reg_shared_access_seq", $sformatf("Read 'h%h, expecting 'h%h",
169
                                        actual, exp),UVM_DEBUG);
170
 
171
            if (actual !== exp) begin
172
               `uvm_error("uvm_reg_shared_access_seq", $sformatf("Register \"%s\" through map \"%s\" is 'h%h instead of 'h%h after writing 'h%h via map \"%s\" over 'h%h.",
173
                                           rg.get_full_name(), maps[k].get_full_name(),
174
                                           actual, exp, v, maps[j].get_full_name(), prev));
175
            end
176
         end
177
      end
178
   endtask: body
179
endclass: uvm_reg_shared_access_seq
180
 
181
 
182
//------------------------------------------------------------------------------
183
// Class: uvm_mem_shared_access_seq
184
//------------------------------------------------------------------------------
185
//
186
// Verify the accessibility of a shared memory
187
// by writing through each address map
188
// then reading it via every other address maps
189
// in which the memory is readable and the backdoor,
190
// making sure that the resulting value matches the written value.
191
//
192
// If bit-type resource named
193
// "NO_REG_TESTS", "NO_MEM_TESTS",
194
// "NO_REG_SHARED_ACCESS_TEST" or "NO_MEM_SHARED_ACCESS_TEST"
195
// in the "REG::" namespace
196
// matches the full name of the memory,
197
// the memory is not tested.
198
//
199
//| uvm_resource_db#(bit)::set({"REG::",regmodel.blk.mem0.get_full_name()},
200
//|                            "NO_MEM_TESTS", 1, this);
201
//
202
// The DUT should be idle and not modify the memory during this test.
203
//
204
//------------------------------------------------------------------------------
205
 
206
class uvm_mem_shared_access_seq extends uvm_reg_sequence #(uvm_sequence #(uvm_reg_item));
207
 
208
   // variable: mem
209
   // The memory to be tested
210
   uvm_mem mem;
211
 
212
   `uvm_object_utils(uvm_mem_shared_access_seq)
213
 
214
   function new(string name="uvm_mem_shared_access_seq");
215
     super.new(name);
216
   endfunction
217
 
218
   virtual task body();
219
      int read_from;
220
      uvm_reg_map maps[$];
221
 
222
      if (mem == null) begin
223
         `uvm_error("uvm_mem_shared_access_seq", "No memory specified to run sequence on");
224
         return;
225
      end
226
 
227
      // Memories with some attributes are not to be tested
228
      if (uvm_resource_db#(bit)::get_by_name({"REG::",mem.get_full_name()},
229
                                             "NO_REG_TESTS", 0) != null ||
230
          uvm_resource_db#(bit)::get_by_name({"REG::",mem.get_full_name()},
231
                                             "NO_MEM_TESTS", 0) != null ||
232
          uvm_resource_db#(bit)::get_by_name({"REG::",mem.get_full_name()},
233
                                             "NO_REG_SHARED_ACCESS_TEST", 0) != null ||
234
          uvm_resource_db#(bit)::get_by_name({"REG::",mem.get_full_name()},
235
                                             "NO_MEM_SHARED_ACCESS_TEST", 0) != null )
236
            return;
237
 
238
      // Only look at shared memories
239
      if (mem.get_n_maps() < 2) return;
240
      mem.get_maps(maps);
241
 
242
      // We need at least a backdoor or a map that can read
243
      // the shared memory
244
      read_from = -1;
245
      if (mem.get_backdoor() == null) begin
246
         foreach (maps[j]) begin
247
            string right;
248
            right = mem.get_access(maps[j]);
249
            if (right == "RW" ||
250
                right == "RO") begin
251
               read_from = j;
252
               break;
253
            end
254
         end
255
         if (read_from < 0) begin
256
            `uvm_warning("uvm_mem_shared_access_seq", $sformatf("Memory \"%s\" cannot be read from any maps or backdoor. Shared access not verified.", mem.get_full_name()));
257
            return;
258
         end
259
      end
260
 
261
      // Try to write through each map
262
      foreach (maps[j]) begin
263
 
264
         `uvm_info("uvm_mem_shared_access_seq", $sformatf("Writing shared memory \"%s\" via map \"%s\".",
265
                                    mem.get_full_name(), maps[j].get_full_name()), UVM_LOW);
266
 
267
         // All addresses
268
         for (int offset = 0; offset < mem.get_size(); offset++) begin
269
            uvm_status_e status;
270
            uvm_reg_data_t  prev, v;
271
 
272
            // Read the initial value
273
            if (mem.get_backdoor() != null) begin
274
               mem.peek(status, offset, prev);
275
               if (status != UVM_IS_OK) begin
276
                  `uvm_error("uvm_mem_shared_access_seq", $sformatf("Status was %s when reading initial value of \"%s\"[%0d] through backdoor.",
277
                                              status.name(), mem.get_full_name(), offset));
278
               end
279
            end
280
            else begin
281
               mem.read(status, offset, prev, UVM_FRONTDOOR, maps[read_from], this);
282
               if (status != UVM_IS_OK) begin
283
                  `uvm_error("uvm_mem_shared_access_seq", $sformatf("Status was %s when reading initial value of \"%s\"[%0d] through map \"%s\".",
284
                                              status.name(), mem.get_full_name(),
285
                                              offset, maps[read_from].get_full_name()));
286
               end
287
            end
288
 
289
 
290
            // Write a random value,
291
            v = {$random, $random};
292
 
293
            mem.write(status, offset, v, UVM_FRONTDOOR, maps[j], this);
294
            if (status != UVM_IS_OK) begin
295
               `uvm_error("uvm_mem_shared_access_seq", $sformatf("Status was %s when writing \"%s\"[%0d] through map \"%s\".",
296
                                           status.name(), mem.get_full_name(), offset, maps[j].get_full_name()));
297
            end
298
 
299
            // Read back from all other maps
300
            foreach (maps[k]) begin
301
               uvm_reg_data_t  actual, exp;
302
 
303
               mem.read(status, offset, actual, UVM_FRONTDOOR, maps[k], this);
304
               if (status != UVM_IS_OK) begin
305
                  `uvm_error("uvm_mem_shared_access_seq", $sformatf("Status was %s when reading %s[%0d] through map \"%s\".",
306
                                              status.name(), mem.get_full_name(), offset, maps[k].get_full_name()));
307
               end
308
 
309
               // Was it what we expected?
310
               exp = v;
311
               if (mem.get_access(maps[j]) == "RO") begin
312
                  exp = prev;
313
               end
314
               if (mem.get_access(maps[k]) == "WO") begin
315
                  exp = 0;
316
               end
317
               // Trim to number of bits
318
               exp &= (1 << mem.get_n_bits()) - 1;
319
               if (actual !== exp) begin
320
                  `uvm_error("uvm_mem_shared_access_seq", $sformatf("%s[%0d] through map \"%s\" is 'h%h instead of 'h%h after writing 'h%h via map \"%s\" over 'h%h.",
321
                                              mem.get_full_name(), offset, maps[k].get_full_name(),
322
                                              actual, exp, v, maps[j].get_full_name(), prev));
323
               end
324
            end
325
         end
326
      end
327
   endtask: body
328
endclass: uvm_mem_shared_access_seq
329
 
330
 
331
 
332
//------------------------------------------------------------------------------
333
// Class: uvm_reg_mem_shared_access_seq
334
//------------------------------------------------------------------------------
335
//
336
// Verify the accessibility of all shared registers
337
// and memories in a block
338
// by executing the 
339
// and 
340
// sequence respectively on every register and memory within it.
341
//
342
// If bit-type resource named
343
// "NO_REG_TESTS", "NO_MEM_TESTS",
344
// "NO_REG_SHARED_ACCESS_TEST" or "NO_MEM_SHARED_ACCESS_TEST"
345
// in the "REG::" namespace
346
// matches the full name of the block,
347
// the block is not tested.
348
//
349
//| uvm_resource_db#(bit)::set({"REG::",regmodel.blk.get_full_name(),".*"},
350
//|                            "NO_REG_TESTS", 1, this);
351
//
352
//------------------------------------------------------------------------------
353
 
354
class uvm_reg_mem_shared_access_seq extends uvm_reg_sequence #(uvm_sequence #(uvm_reg_item));
355
 
356
   // Variable: model
357
   //
358
   // The block to be tested
359
   //
360
   //| uvm_reg_block model;
361
 
362
 
363
   // Variable: reg_seq
364
   //
365
   // The sequence used to test one register
366
   //
367
   protected uvm_reg_shared_access_seq reg_seq;
368
 
369
 
370
   // Variable: mem_seq
371
   //
372
   // The sequence used to test one memory
373
   //
374
   protected uvm_mem_shared_access_seq mem_seq;
375
 
376
   `uvm_object_utils(uvm_reg_mem_shared_access_seq)
377
 
378
   function new(string name="uvm_reg_mem_shared_access_seq");
379
     super.new(name);
380
   endfunction
381
 
382
 
383
   // Task: body
384
   //
385
   // Executes the Shared Register and Memory sequence
386
   //
387
   virtual task body();
388
 
389
      if (model == null) begin
390
         `uvm_error("uvm_reg_mem_shared_access_seq", "No register model specified to run sequence on");
391
         return;
392
      end
393
 
394
      uvm_report_info("STARTING_SEQ",{"\n\nStarting ",get_name()," sequence...\n"},UVM_LOW);
395
 
396
      reg_seq = uvm_reg_shared_access_seq::type_id::create("reg_shared_access_seq");
397
      mem_seq = uvm_mem_shared_access_seq::type_id::create("reg_shared_access_seq");
398
 
399
      this.reset_blk(model);
400
      model.reset();
401
 
402
      do_block(model);
403
   endtask: body
404
 
405
 
406
   // Task: do_block
407
   //
408
   // Test all of the registers and memories in a block
409
   //
410
   protected virtual task do_block(uvm_reg_block blk);
411
      uvm_reg regs[$];
412
      uvm_mem mems[$];
413
 
414
      if (uvm_resource_db#(bit)::get_by_name({"REG::",blk.get_full_name()},
415
                                             "NO_REG_TESTS", 0) != null ||
416
          uvm_resource_db#(bit)::get_by_name({"REG::",blk.get_full_name()},
417
                                             "NO_MEM_TESTS", 0) != null ||
418
          uvm_resource_db#(bit)::get_by_name({"REG::",blk.get_full_name()},
419
                                             "NO_REG_SHARED_ACCESS_TEST", 0) != null ||
420
          uvm_resource_db#(bit)::get_by_name({"REG::",blk.get_full_name()},
421
                                             "NO_MEM_SHARED_ACCESS_TEST", 0) != null )
422
        return;
423
 
424
      this.reset_blk(model);
425
      model.reset();
426
 
427
      // Iterate over all registers, checking accesses
428
      blk.get_registers(regs, UVM_NO_HIER);
429
      foreach (regs[i]) begin
430
         // Registers with some attributes are not to be tested
431
         if (uvm_resource_db#(bit)::get_by_name({"REG::",regs[i].get_full_name()},
432
                                                "NO_REG_TESTS", 0) != null ||
433
             uvm_resource_db#(bit)::get_by_name({"REG::",regs[i].get_full_name()},
434
                                                "NO_REG_SHARED_ACCESS_TEST", 0) != null )
435
           continue;
436
         reg_seq.rg = regs[i];
437
         reg_seq.start(this.get_sequencer(), this);
438
      end
439
 
440
      // Iterate over all memories, checking accesses
441
      blk.get_memories(mems, UVM_NO_HIER);
442
      foreach (mems[i]) begin
443
         // Registers with some attributes are not to be tested
444
         if (uvm_resource_db#(bit)::get_by_name({"REG::",mems[i].get_full_name()},
445
                                                "NO_REG_TESTS", 0) != null ||
446
             uvm_resource_db#(bit)::get_by_name({"REG::",mems[i].get_full_name()},
447
                                                "NO_MEM_TESTS", 0) != null ||
448
             uvm_resource_db#(bit)::get_by_name({"REG::",mems[i].get_full_name()},
449
                                                "NO_REG_SHARED_ACCESS_TEST", 0) != null ||
450
             uvm_resource_db#(bit)::get_by_name({"REG::",mems[i].get_full_name()},
451
                                                "NO_MEM_SHARED_ACCESS_TEST", 0) != null )
452
            continue;
453
         mem_seq.mem = mems[i];
454
         mem_seq.start(this.get_sequencer(), this);
455
      end
456
 
457
      begin
458
         uvm_reg_block blks[$];
459
 
460
         blk.get_blocks(blks);
461
         foreach (blks[i]) begin
462
            do_block(blks[i]);
463
         end
464
      end
465
   endtask: do_block
466
 
467
 
468
   //
469
   // task: reset_blk
470
   // Reset the DUT that corresponds to the specified block abstraction class.
471
   //
472
   // Currently empty.
473
   // Will rollback the environment's phase to the ~reset~
474
   // phase once the new phasing is available.
475
   //
476
   // In the meantime, the DUT should be reset before executing this
477
   // test sequence or this method should be implemented
478
   // in an extension to reset the DUT.
479
   //
480
   virtual task reset_blk(uvm_reg_block blk);
481
   endtask
482
 
483
 
484
endclass: uvm_reg_mem_shared_access_seq
485
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.