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_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
//    Copyright 2010-2013 Cadence Design Systems, Inc.
6
//    All Rights Reserved Worldwide
7
//
8
//    Licensed under the Apache License, Version 2.0 (the
9
//    "License"); you may not use this file except in
10
//    compliance with the License.  You may obtain a copy of
11
//    the License at
12
//
13
//        http://www.apache.org/licenses/LICENSE-2.0
14
//
15
//    Unless required by applicable law or agreed to in
16
//    writing, software distributed under the License is
17
//    distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
18
//    CONDITIONS OF ANY KIND, either express or implied.  See
19
//    the License for the specific language governing
20
//    permissions and limitations under the License.
21
// -------------------------------------------------------------
22
//
23
 
24
//------------------------------------------------------------------------------
25
//
26
// Title: Register Access Test Sequences
27
//
28
// This section defines sequences that test DUT register access via the
29
// available frontdoor and backdoor paths defined in the provided register
30
// model.
31
//------------------------------------------------------------------------------
32
 
33
typedef class uvm_mem_access_seq;
34
 
35
//------------------------------------------------------------------------------
36
//
37
// Class: uvm_reg_single_access_seq
38
//
39
// Verify the accessibility of a register
40
// by writing through its default address map
41
// then reading it via the backdoor, then reversing the process,
42
// making sure that the resulting value matches the mirrored value.
43
//
44
// If bit-type resource named
45
// "NO_REG_TESTS" or "NO_REG_ACCESS_TEST"
46
// in the "REG::" namespace
47
// matches the full name of the register,
48
// the register is not tested.
49
//
50
//| uvm_resource_db#(bit)::set({"REG::",regmodel.blk.r0.get_full_name()},
51
//|                            "NO_REG_TESTS", 1, this);
52
//
53
// Registers without an available backdoor or
54
// that contain read-only fields only,
55
// or fields with unknown access policies
56
// cannot be tested.
57
//
58
// The DUT should be idle and not modify any register during this test.
59
//
60
//------------------------------------------------------------------------------
61
 
62
class uvm_reg_single_access_seq extends uvm_reg_sequence #(uvm_sequence #(uvm_reg_item));
63
 
64
   // Variable: rg
65
   // The register to be tested
66
   uvm_reg rg;
67
 
68
   `uvm_object_utils(uvm_reg_single_access_seq)
69
 
70
   function new(string name="uvm_reg_single_access_seq");
71
     super.new(name);
72
   endfunction
73
 
74
   virtual task body();
75
      uvm_reg_map maps[$];
76
 
77
      if (rg == null) begin
78
         `uvm_error("uvm_reg_access_seq", "No register specified to run sequence on")
79
         return;
80
      end
81
 
82
      // Registers with some attributes are not to be tested
83
      if (uvm_resource_db#(bit)::get_by_name({"REG::",rg.get_full_name()},
84
                                             "NO_REG_TESTS", 0) != null ||
85
          uvm_resource_db#(bit)::get_by_name({"REG::",rg.get_full_name()},
86
                                             "NO_REG_ACCESS_TEST", 0) != null )
87
            return;
88
 
89
      // Can only deal with registers with backdoor access
90
      if (rg.get_backdoor() == null && !rg.has_hdl_path()) begin
91
         `uvm_error("uvm_reg_access_seq", {"Register '",rg.get_full_name(),
92
         "' does not have a backdoor mechanism available"})
93
         return;
94
      end
95
 
96
      // Registers may be accessible from multiple physical interfaces (maps)
97
      rg.get_maps(maps);
98
 
99
      // Cannot test access if register contains RO or OTHER fields
100
      begin
101
         uvm_reg_field fields[$];
102
 
103
         rg.get_fields(fields);
104
         foreach (maps[k]) begin
105
                int ro;
106
                ro=0;
107
                foreach (fields[j]) begin
108
               if (fields[j].get_access(maps[k]) == "RO") begin
109
                  ro++;
110
               end
111
               if (!fields[j].is_known_access(maps[k])) begin
112
                  `uvm_warning("uvm_reg_access_seq", {"Register '",rg.get_full_name(),
113
                    "' has field with unknown access type '",
114
                    fields[j].get_access(maps[k]),"', skipping"})
115
                  return;
116
               end
117
                end
118
                if(ro==fields.size()) begin
119
                        `uvm_warning("uvm_reg_access_seq", {"Register '",
120
                rg.get_full_name(),"' has only RO fields in map ",maps[k].get_full_name(),", skipping"})
121
                return;
122
                end
123
         end
124
      end
125
 
126
      // Access each register:
127
      // - Write complement of reset value via front door
128
      // - Read value via backdoor and compare against mirror
129
      // - Write reset value via backdoor
130
      // - Read via front door and compare against mirror
131
      foreach (maps[j]) begin
132
         uvm_status_e status;
133
         uvm_reg_data_t  v, exp;
134
 
135
         `uvm_info("uvm_reg_access_seq", {"Verifying access of register '",
136
             rg.get_full_name(),"' in map '", maps[j].get_full_name(),
137
             "' ..."}, UVM_LOW)
138
 
139
         v = rg.get();
140
 
141
         rg.write(status, ~v, UVM_FRONTDOOR, maps[j], this);
142
 
143
         if (status != UVM_IS_OK) begin
144
            `uvm_error("uvm_reg_access_seq", {"Status was '",status.name(),
145
                                 "' when writing '",rg.get_full_name(),
146
                                 "' through map '",maps[j].get_full_name(),"'"})
147
         end
148
         #1;
149
 
150
         rg.mirror(status, UVM_CHECK, UVM_BACKDOOR, uvm_reg_map::backdoor(), this);
151
         if (status != UVM_IS_OK) begin
152
            `uvm_error("uvm_reg_access_seq", {"Status was '",status.name(),
153
                                 "' when reading reset value of register '",
154
                                 rg.get_full_name(), "' through backdoor"})
155
         end
156
 
157
         rg.write(status, v, UVM_BACKDOOR, maps[j], this);
158
         if (status != UVM_IS_OK) begin
159
            `uvm_error("uvm_reg_access_seq", {"Status was '",status.name(),
160
                                 "' when writing '",rg.get_full_name(),
161
                                 "' through backdoor"})
162
         end
163
 
164
         rg.mirror(status, UVM_CHECK, UVM_FRONTDOOR, maps[j], this);
165
         if (status != UVM_IS_OK) begin
166
            `uvm_error("uvm_reg_access_seq", {"Status was '",status.name(),
167
                                 "' when reading reset value of register '",
168
                                 rg.get_full_name(), "' through map '",
169
                                 maps[j].get_full_name(),"'"})
170
         end
171
      end
172
   endtask: body
173
endclass: uvm_reg_single_access_seq
174
 
175
 
176
//------------------------------------------------------------------------------
177
//
178
// Class: uvm_reg_access_seq
179
//
180
// Verify the accessibility of all registers in a block
181
// by executing the  sequence on
182
// every register within it.
183
//
184
// If bit-type resource named
185
// "NO_REG_TESTS" or "NO_REG_ACCESS_TEST"
186
// in the "REG::" namespace
187
// matches the full name of the block,
188
// the block is not tested.
189
//
190
//| uvm_resource_db#(bit)::set({"REG::",regmodel.blk.get_full_name(),".*"},
191
//|                            "NO_REG_TESTS", 1, this);
192
//
193
//------------------------------------------------------------------------------
194
 
195
class uvm_reg_access_seq extends uvm_reg_sequence #(uvm_sequence #(uvm_reg_item));
196
 
197
   // Variable: model
198
   //
199
   // The block to be tested. Declared in the base class.
200
   //
201
   //| uvm_reg_block model;
202
 
203
 
204
   // Variable: reg_seq
205
   //
206
   // The sequence used to test one register
207
   //
208
   protected uvm_reg_single_access_seq reg_seq;
209
 
210
   `uvm_object_utils(uvm_reg_access_seq)
211
 
212
   function new(string name="uvm_reg_access_seq");
213
     super.new(name);
214
   endfunction
215
 
216
 
217
   // Task: body
218
   //
219
   // Executes the Register Access sequence.
220
   // Do not call directly. Use seq.start() instead.
221
   //
222
   virtual task body();
223
 
224
      if (model == null) begin
225
         `uvm_error("uvm_reg_access_seq", "No register model specified to run sequence on")
226
         return;
227
      end
228
 
229
      uvm_report_info("STARTING_SEQ",{"\n\nStarting ",get_name()," sequence...\n"},UVM_LOW);
230
 
231
      reg_seq = uvm_reg_single_access_seq::type_id::create("single_reg_access_seq");
232
 
233
      this.reset_blk(model);
234
      model.reset();
235
 
236
      do_block(model);
237
   endtask: body
238
 
239
 
240
   // Task: do_block
241
   //
242
   // Test all of the registers in a block
243
   //
244
   protected virtual task do_block(uvm_reg_block blk);
245
      uvm_reg regs[$];
246
 
247
      if (uvm_resource_db#(bit)::get_by_name({"REG::",blk.get_full_name()},
248
                                             "NO_REG_TESTS", 0) != null ||
249
          uvm_resource_db#(bit)::get_by_name({"REG::",blk.get_full_name()},
250
                                             "NO_REG_ACCESS_TEST", 0) != null )
251
         return;
252
 
253
      // Iterate over all registers, checking accesses
254
      blk.get_registers(regs, UVM_NO_HIER);
255
      foreach (regs[i]) begin
256
         // Registers with some attributes are not to be tested
257
         if (uvm_resource_db#(bit)::get_by_name({"REG::",regs[i].get_full_name()},
258
                                                "NO_REG_TESTS", 0) != null ||
259
             uvm_resource_db#(bit)::get_by_name({"REG::",regs[i].get_full_name()},
260
                                                "NO_REG_ACCESS_TEST", 0) != null )
261
              continue;
262
 
263
         // Can only deal with registers with backdoor access
264
         if (regs[i].get_backdoor() == null && !regs[i].has_hdl_path()) begin
265
            `uvm_warning("uvm_reg_access_seq", {"Register '",regs[i].get_full_name(),
266
                   "' does not have a backdoor mechanism available"})
267
            continue;
268
         end
269
 
270
         reg_seq.rg = regs[i];
271
         reg_seq.start(null,this);
272
      end
273
 
274
      begin
275
         uvm_reg_block blks[$];
276
 
277
         blk.get_blocks(blks);
278
         foreach (blks[i]) begin
279
            do_block(blks[i]);
280
         end
281
      end
282
   endtask: do_block
283
 
284
 
285
   // Task: reset_blk
286
   //
287
   // Reset the DUT that corresponds to the specified block abstraction class.
288
   //
289
   // Currently empty.
290
   // Will rollback the environment's phase to the ~reset~
291
   // phase once the new phasing is available.
292
   //
293
   // In the meantime, the DUT should be reset before executing this
294
   // test sequence or this method should be implemented
295
   // in an extension to reset the DUT.
296
   //
297
   virtual task reset_blk(uvm_reg_block blk);
298
   endtask
299
 
300
endclass: uvm_reg_access_seq
301
 
302
 
303
 
304
//------------------------------------------------------------------------------
305
//
306
// Class: uvm_reg_mem_access_seq
307
//
308
// Verify the accessibility of all registers and memories in a block
309
// by executing the  and
310
//  sequence respectively on every register
311
// and memory within it.
312
//
313
// Blocks and registers with the NO_REG_TESTS or
314
// the NO_REG_ACCESS_TEST attribute are not verified.
315
//
316
//------------------------------------------------------------------------------
317
 
318
class uvm_reg_mem_access_seq extends uvm_reg_sequence #(uvm_sequence #(uvm_reg_item));
319
 
320
   `uvm_object_utils(uvm_reg_mem_access_seq)
321
 
322
   function new(string name="uvm_reg_mem_access_seq");
323
     super.new(name);
324
   endfunction
325
 
326
   virtual task body();
327
 
328
      if (model == null) begin
329
         `uvm_error("uvm_reg_mem_access_seq", "Register model handle is null")
330
         return;
331
      end
332
 
333
      uvm_report_info("STARTING_SEQ",
334
            {"\n\nStarting ",get_name()," sequence...\n"},UVM_LOW);
335
 
336
      if (uvm_resource_db#(bit)::get_by_name({"REG::",model.get_full_name()},
337
                                             "NO_REG_TESTS", 0) == null) begin
338
        if (uvm_resource_db#(bit)::get_by_name({"REG::",model.get_full_name()},
339
                                               "NO_REG_ACCESS_TEST", 0) == null) begin
340
           uvm_reg_access_seq sub_seq = new("reg_access_seq");
341
           this.reset_blk(model);
342
           model.reset();
343
           sub_seq.model = model;
344
           sub_seq.start(null,this);
345
        end
346
        if (uvm_resource_db#(bit)::get_by_name({"REG::",model.get_full_name()},
347
                                               "NO_MEM_ACCESS_TEST", 0) == null) begin
348
           uvm_mem_access_seq sub_seq = new("mem_access_seq");
349
           this.reset_blk(model);
350
           model.reset();
351
           sub_seq.model = model;
352
           sub_seq.start(null,this);
353
        end
354
      end
355
 
356
   endtask: body
357
 
358
 
359
   // Any additional steps required to reset the block
360
   // and make it accessibl
361
   virtual task reset_blk(uvm_reg_block blk);
362
   endtask
363
 
364
 
365
endclass: uvm_reg_mem_access_seq

powered by: WebSVN 2.1.0

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