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_bit_bash_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: Bit Bashing Test Sequences
25
//------------------------------------------------------------------------------
26
// This section defines classes that test individual bits of the registers
27
// defined in a register model.
28
//------------------------------------------------------------------------------
29
 
30
//------------------------------------------------------------------------------
31
// Class: uvm_reg_single_bit_bash_seq
32
//
33
// Verify the implementation of a single register
34
// by attempting to write 1's and 0's to every bit in it,
35
// via every address map in which the register is mapped,
36
// making sure that the resulting value matches the mirrored value.
37
//
38
// If bit-type resource named
39
// "NO_REG_TESTS" or "NO_REG_BIT_BASH_TEST"
40
// in the "REG::" namespace
41
// matches the full name of the register,
42
// the register is not tested.
43
//
44
//| uvm_resource_db#(bit)::set({"REG::",regmodel.blk.r0.get_full_name()},
45
//|                            "NO_REG_TESTS", 1, this);
46
//
47
// Registers that contain fields with unknown access policies
48
// cannot be tested.
49
//
50
// The DUT should be idle and not modify any register during this test.
51
//
52
//------------------------------------------------------------------------------
53
 
54
class uvm_reg_single_bit_bash_seq extends uvm_reg_sequence #(uvm_sequence #(uvm_reg_item));
55
 
56
   // Variable: rg
57
   // The register to be tested
58
   uvm_reg rg;
59
 
60
   `uvm_object_utils(uvm_reg_single_bit_bash_seq)
61
 
62
   function new(string name="uvm_reg_single_bit_bash_seq");
63
     super.new(name);
64
   endfunction
65
 
66
   virtual task body();
67
      uvm_reg_field fields[$];
68
      string mode[`UVM_REG_DATA_WIDTH];
69
      uvm_reg_map maps[$];
70
      uvm_reg_data_t  dc_mask;
71
      uvm_reg_data_t  reset_val;
72
      int n_bits;
73
      string field_access;
74
 
75
      if (rg == null) begin
76
         `uvm_error("uvm_reg_bit_bash_seq", "No register specified to run sequence on");
77
         return;
78
      end
79
 
80
      // Registers with some attributes are not to be tested
81
      if (uvm_resource_db#(bit)::get_by_name({"REG::",rg.get_full_name()},
82
                                             "NO_REG_TESTS", 0) != null ||
83
          uvm_resource_db#(bit)::get_by_name({"REG::",rg.get_full_name()},
84
                                             "NO_REG_BIT_BASH_TEST", 0) != null )
85
            return;
86
 
87
      n_bits = rg.get_n_bytes() * 8;
88
 
89
      // Let's see what kind of bits we have...
90
      rg.get_fields(fields);
91
 
92
      // Registers may be accessible from multiple physical interfaces (maps)
93
      rg.get_maps(maps);
94
 
95
      // Bash the bits in the register via each map
96
      foreach (maps[j]) begin
97
         uvm_status_e status;
98
         uvm_reg_data_t  val, exp, v;
99
         int next_lsb;
100
 
101
         next_lsb = 0;
102
         dc_mask  = 0;
103
         foreach (fields[k]) begin
104
            int lsb, w, dc;
105
 
106
            field_access = fields[k].get_access(maps[j]);
107
            dc = (fields[k].get_compare() == UVM_NO_CHECK);
108
            lsb = fields[k].get_lsb_pos();
109
            w   = fields[k].get_n_bits();
110
            // Ignore Write-only fields because
111
            // you are not supposed to read them
112
            case (field_access)
113
             "WO", "WOC", "WOS", "WO1", "NOACCESS": dc = 1;
114
            endcase
115
            // Any unused bits on the right side of the LSB?
116
            while (next_lsb < lsb) mode[next_lsb++] = "RO";
117
 
118
            repeat (w) begin
119
               mode[next_lsb] = field_access;
120
               dc_mask[next_lsb] = dc;
121
               next_lsb++;
122
            end
123
         end
124
         // Any unused bits on the left side of the MSB?
125
         while (next_lsb < `UVM_REG_DATA_WIDTH)
126
            mode[next_lsb++] = "RO";
127
 
128
         `uvm_info("uvm_reg_bit_bash_seq", $sformatf("Verifying bits in register %s in map \"%s\"...",
129
                                    rg.get_full_name(), maps[j].get_full_name()),UVM_LOW);
130
 
131
         // Bash the kth bit
132
         for (int k = 0; k < n_bits; k++) begin
133
            // Cannot test unpredictable bit behavior
134
            if (dc_mask[k]) continue;
135
 
136
            bash_kth_bit(rg, k, mode[k], maps[j], dc_mask);
137
         end
138
 
139
      end
140
   endtask: body
141
 
142
 
143
   task bash_kth_bit(uvm_reg         rg,
144
                     int             k,
145
                     string          mode,
146
                     uvm_reg_map     map,
147
                     uvm_reg_data_t  dc_mask);
148
      uvm_status_e status;
149
      uvm_reg_data_t  val, exp, v;
150
      bit bit_val;
151
 
152
      `uvm_info("uvm_reg_bit_bash_seq", $sformatf("...Bashing %s bit #%0d", mode, k),UVM_HIGH);
153
 
154
      repeat (2) begin
155
         val = rg.get();
156
         v   = val;
157
         exp = val;
158
         val[k] = ~val[k];
159
         bit_val = val[k];
160
 
161
         rg.write(status, val, UVM_FRONTDOOR, map, this);
162
         if (status != UVM_IS_OK) begin
163
            `uvm_error("uvm_reg_bit_bash_seq", $sformatf("Status was %s when writing to register \"%s\" through map \"%s\".",
164
                                        status.name(), rg.get_full_name(), map.get_full_name()));
165
         end
166
 
167
         exp = rg.get() & ~dc_mask;
168
         rg.read(status, val, UVM_FRONTDOOR, map, this);
169
         if (status != UVM_IS_OK) begin
170
            `uvm_error("uvm_reg_bit_bash_seq", $sformatf("Status was %s when reading register \"%s\" through map \"%s\".",
171
                                        status.name(), rg.get_full_name(), map.get_full_name()));
172
         end
173
 
174
         val &= ~dc_mask;
175
         if (val !== exp) begin
176
            `uvm_error("uvm_reg_bit_bash_seq", $sformatf("Writing a %b in bit #%0d of register \"%s\" with initial value 'h%h yielded 'h%h instead of 'h%h",
177
                                        bit_val, k, rg.get_full_name(), v, val, exp));
178
         end
179
      end
180
   endtask: bash_kth_bit
181
 
182
endclass: uvm_reg_single_bit_bash_seq
183
 
184
 
185
//------------------------------------------------------------------------------
186
// Class: uvm_reg_bit_bash_seq
187
//
188
//
189
// Verify the implementation of all registers in a block
190
// by executing the  sequence on it.
191
//
192
// If bit-type resource named
193
// "NO_REG_TESTS" or "NO_REG_BIT_BASH_TEST"
194
// in the "REG::" namespace
195
// matches the full name of the block,
196
// the block is not tested.
197
//
198
//| uvm_resource_db#(bit)::set({"REG::",regmodel.blk.get_full_name(),".*"},
199
//|                            "NO_REG_TESTS", 1, this);
200
//
201
//------------------------------------------------------------------------------
202
 
203
class uvm_reg_bit_bash_seq extends uvm_reg_sequence #(uvm_sequence #(uvm_reg_item));
204
 
205
   // Variable: model
206
   //
207
   // The block to be tested. Declared in the base class.
208
   //
209
   //| uvm_reg_block model;
210
 
211
 
212
   // Variable: reg_seq
213
   //
214
   // The sequence used to test one register
215
   //
216
   protected uvm_reg_single_bit_bash_seq reg_seq;
217
 
218
   `uvm_object_utils(uvm_reg_bit_bash_seq)
219
 
220
   function new(string name="uvm_reg_bit_bash_seq");
221
     super.new(name);
222
   endfunction
223
 
224
 
225
   // Task: body
226
   //
227
   // Executes the Register Bit Bash sequence.
228
   // Do not call directly. Use seq.start() instead.
229
   //
230
   virtual task body();
231
 
232
      if (model == null) begin
233
         `uvm_error("uvm_reg_bit_bash_seq", "No register model specified to run sequence on");
234
         return;
235
      end
236
 
237
      uvm_report_info("STARTING_SEQ",{"\n\nStarting ",get_name()," sequence...\n"},UVM_LOW);
238
 
239
      reg_seq = uvm_reg_single_bit_bash_seq::type_id::create("reg_single_bit_bash_seq");
240
 
241
      this.reset_blk(model);
242
      model.reset();
243
 
244
      do_block(model);
245
   endtask
246
 
247
 
248
   // Task: do_block
249
   //
250
   // Test all of the registers in a given ~block~
251
   //
252
   protected virtual task do_block(uvm_reg_block blk);
253
      uvm_reg regs[$];
254
 
255
      if (uvm_resource_db#(bit)::get_by_name({"REG::",blk.get_full_name()},
256
                                             "NO_REG_TESTS", 0) != null ||
257
          uvm_resource_db#(bit)::get_by_name({"REG::",blk.get_full_name()},
258
                                             "NO_REG_BIT_BASH_TEST", 0) != null )
259
         return;
260
 
261
      // Iterate over all registers, checking accesses
262
      blk.get_registers(regs, UVM_NO_HIER);
263
      foreach (regs[i]) begin
264
         // Registers with some attributes are not to be tested
265
         if (uvm_resource_db#(bit)::get_by_name({"REG::",regs[i].get_full_name()},
266
                                                "NO_REG_TESTS", 0) != null ||
267
             uvm_resource_db#(bit)::get_by_name({"REG::",regs[i].get_full_name()},
268
                                                "NO_REG_BIT_BASH_TEST", 0) != null )
269
            continue;
270
 
271
         reg_seq.rg = regs[i];
272
         reg_seq.start(null,this);
273
      end
274
 
275
      begin
276
         uvm_reg_block blks[$];
277
 
278
         blk.get_blocks(blks);
279
         foreach (blks[i]) begin
280
            do_block(blks[i]);
281
         end
282
      end
283
   endtask: do_block
284
 
285
 
286
   // Task: reset_blk
287
   //
288
   // Reset the DUT that corresponds to the specified block abstraction class.
289
   //
290
   // Currently empty.
291
   // Will rollback the environment's phase to the ~reset~
292
   // phase once the new phasing is available.
293
   //
294
   // In the meantime, the DUT should be reset before executing this
295
   // test sequence or this method should be implemented
296
   // in an extension to reset the DUT.
297
   //
298
   virtual task reset_blk(uvm_reg_block blk);
299
   endtask
300
 
301
endclass: uvm_reg_bit_bash_seq
302
 

powered by: WebSVN 2.1.0

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