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

Subversion Repositories uart2bus_testbench

[/] [uart2bus_testbench/] [trunk/] [tb/] [uvm_src/] [reg/] [sequences/] [uvm_mem_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: Memory Access Test Sequence
25
//
26
 
27
//
28
// class: uvm_mem_single_access_seq
29
//
30
// Verify the accessibility of a memory
31
// by writing through its default address map
32
// then reading it via the backdoor, then reversing the process,
33
// making sure that the resulting value matches the written value.
34
//
35
// If bit-type resource named
36
// "NO_REG_TESTS", "NO_MEM_TESTS", or "NO_MEM_ACCESS_TEST"
37
// in the "REG::" namespace
38
// matches the full name of the memory,
39
// the memory is not tested.
40
//
41
//| uvm_resource_db#(bit)::set({"REG::",regmodel.blk.mem0.get_full_name()},
42
//|                            "NO_MEM_TESTS", 1, this);
43
//
44
// Memories without an available backdoor
45
// cannot be tested.
46
//
47
// The DUT should be idle and not modify the memory during this test.
48
//
49
 
50
class uvm_mem_single_access_seq extends uvm_reg_sequence #(uvm_sequence #(uvm_reg_item));
51
 
52
   // Variable: mem
53
   //
54
   // The memory to be tested
55
   //
56
   uvm_mem mem;
57
 
58
   `uvm_object_utils(uvm_mem_single_access_seq)
59
 
60
   function new(string name="uam_mem_single_access_seq");
61
     super.new(name);
62
   endfunction
63
 
64
   virtual task body();
65
      string mode;
66
      uvm_reg_map maps[$];
67
      int n_bits;
68
 
69
      if (mem == null) begin
70
         `uvm_error("uvm_mem_access_seq", "No register specified to run sequence on");
71
         return;
72
      end
73
 
74
      // Memories with some attributes are not to be tested
75
      if (uvm_resource_db#(bit)::get_by_name({"REG::",mem.get_full_name()},
76
                                             "NO_REG_TESTS", 0) != null ||
77
          uvm_resource_db#(bit)::get_by_name({"REG::",mem.get_full_name()},
78
                                             "NO_MEM_TESTS", 0) != null ||
79
          uvm_resource_db#(bit)::get_by_name({"REG::",mem.get_full_name()},
80
                                             "NO_MEM_ACCESS_TEST", 0) != null)
81
         return;
82
 
83
      // Can only deal with memories with backdoor access
84
      if (mem.get_backdoor() == null && !mem.has_hdl_path()) begin
85
         `uvm_error("uvm_mem_access_seq", {"Memory '",mem.get_full_name(),
86
             "' does not have a backdoor mechanism available"})
87
         return;
88
      end
89
 
90
      n_bits = mem.get_n_bits();
91
 
92
      // Memories may be accessible from multiple physical interfaces (maps)
93
      mem.get_maps(maps);
94
 
95
      // Walk the memory via each map
96
      foreach (maps[j]) begin
97
         uvm_status_e status;
98
         uvm_reg_data_t  val, exp, v;
99
 
100
         `uvm_info("uvm_mem_access_seq", {"Verifying access of memory '",
101
             mem.get_full_name(),"' in map '", maps[j].get_full_name(),
102
             "' ..."}, UVM_LOW)
103
 
104
         mode = mem.get_access(maps[j]);
105
 
106
         // The access process is, for address k:
107
         // - Write random value via front door
108
         // - Read via backdoor and expect same random value if RW
109
         // - Write complement of random value via back door
110
         // - Read via front door and expect inverted random value
111
         for (int k = 0; k < mem.get_size(); k++) begin
112
            val = $random & uvm_reg_data_t'((1'b1<
113
            if (n_bits > 32)
114
              val = uvm_reg_data_t'(val << 32) | $random;
115
            if (mode == "RO") begin
116
               mem.peek(status, k, exp);
117
               if (status != UVM_IS_OK) begin
118
                  `uvm_error("uvm_mem_access_seq", $sformatf("Status was %s when reading \"%s[%0d]\" through backdoor.",
119
                                              status.name(), mem.get_full_name(), k))
120
               end
121
            end
122
            else exp = val;
123
 
124
            mem.write(status, k, val, UVM_FRONTDOOR, maps[j], this);
125
            if (status != UVM_IS_OK) begin
126
               `uvm_error("uvm_mem_access_seq", $sformatf("Status was %s when writing \"%s[%0d]\" through map \"%s\".",
127
                                           status.name(), mem.get_full_name(), k, maps[j].get_full_name()))
128
            end
129
            #1;
130
 
131
            val = 'x;
132
            mem.peek(status, k, val);
133
            if (status != UVM_IS_OK) begin
134
               `uvm_error("uvm_mem_access_seq", $sformatf("Status was %s when reading \"%s[%0d]\" through backdoor.",
135
                                           status.name(), mem.get_full_name(), k))
136
            end
137
            else begin
138
               if (val !== exp) begin
139
                  `uvm_error("uvm_mem_access_seq", $sformatf("Backdoor \"%s[%0d]\" read back as 'h%h instead of 'h%h.",
140
                                              mem.get_full_name(), k, val, exp))
141
               end
142
            end
143
 
144
            exp = ~exp & ((1'b1<
145
            mem.poke(status, k, exp);
146
            if (status != UVM_IS_OK) begin
147
               `uvm_error("uvm_mem_access_seq", $sformatf("Status was %s when writing \"%s[%0d-1]\" through backdoor.",
148
                                           status.name(), mem.get_full_name(), k))
149
            end
150
 
151
            mem.read(status, k, val, UVM_FRONTDOOR, maps[j], this);
152
            if (status != UVM_IS_OK) begin
153
               `uvm_error("uvm_mem_access_seq", $sformatf("Status was %s when reading \"%s[%0d]\" through map \"%s\".",
154
                                           status.name(), mem.get_full_name(), k, maps[j].get_full_name()))
155
            end
156
            else begin
157
               if (mode == "WO") begin
158
                  if (val !== '0) begin
159
                     `uvm_error("uvm_mem_access_seq", $sformatf("Front door \"%s[%0d]\" read back as 'h%h instead of 'h%h.",
160
                                                 mem.get_full_name(), k, val, 0))
161
                  end
162
               end
163
               else begin
164
                  if (val !== exp) begin
165
                     `uvm_error("uvm_mem_access_seq", $sformatf("Front door \"%s[%0d]\" read back as 'h%h instead of 'h%h.",
166
                                                 mem.get_full_name(), k, val, exp))
167
                  end
168
               end
169
            end
170
         end
171
      end
172
   endtask: body
173
endclass: uvm_mem_single_access_seq
174
 
175
 
176
 
177
 
178
//
179
// class: uvm_mem_access_seq
180
//
181
// Verify the accessibility of all memories in a block
182
// by executing the  sequence on
183
// every memory within it.
184
//
185
// If bit-type resource named
186
// "NO_REG_TESTS", "NO_MEM_TESTS", or "NO_MEM_ACCESS_TEST"
187
// in the "REG::" namespace
188
// matches the full name of the block,
189
// the block is not tested.
190
//
191
//| uvm_resource_db#(bit)::set({"REG::",regmodel.blk.get_full_name(),".*"},
192
//|                            "NO_MEM_TESTS", 1, this);
193
//
194
 
195
class uvm_mem_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: mem_seq
205
   //
206
   // The sequence used to test one memory
207
   //
208
   protected uvm_mem_single_access_seq mem_seq;
209
 
210
   `uvm_object_utils(uvm_mem_access_seq)
211
 
212
   function new(string name="uvm_mem_access_seq");
213
     super.new(name);
214
   endfunction
215
 
216
   // Task: body
217
   //
218
   // Execute the Memory Access sequence.
219
   // Do not call directly. Use seq.start() instead.
220
   //
221
   virtual task body();
222
 
223
      if (model == null) begin
224
         `uvm_error("uvm_mem_access_seq", "No register model specified to run sequence on");
225
         return;
226
      end
227
 
228
      uvm_report_info("STARTING_SEQ",{"\n\nStarting ",get_name()," sequence...\n"},UVM_LOW);
229
 
230
      mem_seq = uvm_mem_single_access_seq::type_id::create("single_mem_access_seq");
231
 
232
      this.reset_blk(model);
233
      model.reset();
234
 
235
      do_block(model);
236
   endtask: body
237
 
238
 
239
   // Task: do_block
240
   //
241
   // Test all of the memories in a given ~block~
242
   //
243
   protected virtual task do_block(uvm_reg_block blk);
244
      uvm_mem mems[$];
245
 
246
      if (uvm_resource_db#(bit)::get_by_name({"REG::",blk.get_full_name()},
247
                                             "NO_REG_TESTS", 0) != null ||
248
          uvm_resource_db#(bit)::get_by_name({"REG::",blk.get_full_name()},
249
                                             "NO_MEM_TESTS", 0) != null ||
250
          uvm_resource_db#(bit)::get_by_name({"REG::",blk.get_full_name()},
251
                                             "NO_MEM_ACCESS_TEST", 0) != null )
252
         return;
253
 
254
      // Iterate over all memories, checking accesses
255
      blk.get_memories(mems, UVM_NO_HIER);
256
      foreach (mems[i]) begin
257
         // Registers with some attributes are not to be tested
258
         if (uvm_resource_db#(bit)::get_by_name({"REG::",mems[i].get_full_name()},
259
                                                "NO_REG_TESTS", 0) != null ||
260
             uvm_resource_db#(bit)::get_by_name({"REG::",mems[i].get_full_name()},
261
                                                "NO_MEM_TESTS", 0) != null ||
262
             uvm_resource_db#(bit)::get_by_name({"REG::",mems[i].get_full_name()},
263
                                                "NO_MEM_ACCESS_TEST", 0) != null )
264
           continue;
265
 
266
         // Can only deal with memories with backdoor access
267
         if (mems[i].get_backdoor() == null &&
268
             !mems[i].has_hdl_path()) begin
269
            `uvm_warning("uvm_mem_access_seq", $sformatf("Memory \"%s\" does not have a backdoor mechanism available",
270
                                               mems[i].get_full_name()));
271
            continue;
272
         end
273
 
274
         mem_seq.mem = mems[i];
275
         mem_seq.start(null, this);
276
      end
277
 
278
      begin
279
         uvm_reg_block blks[$];
280
 
281
         blk.get_blocks(blks);
282
         foreach (blks[i]) begin
283
            do_block(blks[i]);
284
         end
285
      end
286
   endtask: do_block
287
 
288
 
289
   // Task: reset_blk
290
   //
291
   // Reset the DUT that corresponds to the specified block abstraction class.
292
   //
293
   // Currently empty.
294
   // Will rollback the environment's phase to the ~reset~
295
   // phase once the new phasing is available.
296
   //
297
   // In the meantime, the DUT should be reset before executing this
298
   // test sequence or this method should be implemented
299
   // in an extension to reset the DUT.
300
   //
301
   virtual task reset_blk(uvm_reg_block blk);
302
   endtask
303
 
304
 
305
endclass: uvm_mem_access_seq
306
 
307
 

powered by: WebSVN 2.1.0

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