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

Subversion Repositories uart2bus_testbench

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 16 HanySalah
//
2
// -------------------------------------------------------------
3
//    Copyright 2010-2011 Mentor Graphics Corporation
4
//    All Rights Reserved Worldwide
5
//
6
//    Licensed under the Apache License, Version 2.0 (the
7
//    "License"); you may not use this file except in
8
//    compliance with the License.  You may obtain a copy of
9
//    the License at
10
//
11
//        http://www.apache.org/licenses/LICENSE-2.0
12
//
13
//    Unless required by applicable law or agreed to in
14
//    writing, software distributed under the License is
15
//    distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
16
//    CONDITIONS OF ANY KIND, either express or implied.  See
17
//    the License for the specific language governing
18
//    permissions and limitations under the License.
19
// -------------------------------------------------------------
20
//
21
 
22
 
23
//------------------------------------------------------------------------------
24
// Class: uvm_reg_fifo
25
//
26
// This special register models a DUT FIFO accessed via write/read,
27
// where writes push to the FIFO and reads pop from it.
28
//
29
// Backdoor access is not enabled, as it is not yet possible to force
30
// complete FIFO state, i.e. the write and read indexes used to access
31
// the FIFO data.
32
//
33
//------------------------------------------------------------------------------
34
 
35
class uvm_reg_fifo extends uvm_reg;
36
 
37
    local uvm_reg_field value;
38
    local int m_set_cnt;
39
    local int unsigned m_size;
40
 
41
    // Variable: fifo
42
    //
43
    // The abstract representation of the FIFO. Constrained
44
    // to be no larger than the size parameter. It is public
45
    // to enable subtypes to add constraints on it and randomize.
46
    //
47
    rand uvm_reg_data_t fifo[$];
48
 
49
    constraint valid_fifo_size {
50
      fifo.size() <= m_size;
51
    }
52
 
53
 
54
    //----------------------
55
    // Group: Initialization
56
    //----------------------
57
 
58
    // Function: new
59
    //
60
    // Creates an instance of a FIFO register having ~size~ elements of
61
    // ~n_bits~ each.
62
    //
63
    function new(string name = "reg_fifo",
64
                 int unsigned size,
65
                 int unsigned n_bits,
66
                 int has_cover);
67
       super.new(name,n_bits,has_cover);
68
       m_size = size;
69
    endfunction
70
 
71
 
72
    // Funtion: build
73
    //
74
    // Builds the abstract FIFO register object. Called by
75
    // the instantiating block, a  subtype.
76
    //
77
    virtual function void build();
78
        value = uvm_reg_field::type_id::create("value");
79
        value.configure(this, get_n_bits(), 0, "RW", 0, 32'h0, 1, 0, 1);
80
    endfunction
81
 
82
 
83
    // Function: set_compare
84
    //
85
    // Sets the compare policy during a mirror (read) of the DUT FIFO.
86
    // The DUT read value is checked against its mirror only when both the
87
    // ~check~ argument in the  call and the compare policy
88
    // for the field is .
89
    //
90
    function void set_compare(uvm_check_e check=UVM_CHECK);
91
       value.set_compare(check);
92
    endfunction
93
 
94
 
95
    //---------------------
96
    // Group: Introspection
97
    //---------------------
98
 
99
    // Function: size
100
    //
101
    // The number of entries currently in the FIFO.
102
    //
103
    function int unsigned size();
104
      return fifo.size();
105
    endfunction
106
 
107
 
108
    // Function: capacity
109
    //
110
    // The maximum number of entries, or depth, of the FIFO.
111
 
112
    function int unsigned capacity();
113
      return m_size;
114
    endfunction
115
 
116
 
117
    //--------------
118
    // Group: Access
119
    //--------------
120
 
121
    //  Function: write
122
    //
123
    //  Pushes the given value to the DUT FIFO. If auto-prediction is enabled,
124
    //  the written value is also pushed to the abstract FIFO before the
125
    //  call returns. If auto-prediction is not enabled (via
126
    //  ), the value is pushed to abstract
127
    //  FIFO only when the write operation is observed on the target bus.
128
    //  This mode requires using the  class.
129
    //  If the write is via an  operation, the abstract FIFO
130
    //  already contains the written value and is thus not affected by
131
    //  either prediction mode.
132
 
133
 
134
    //  Function: read
135
    //
136
    //  Reads the next value out of the DUT FIFO. If auto-prediction is
137
    //  enabled, the frontmost value in abstract FIFO is popped.
138
 
139
 
140
    // Function: set
141
    //
142
    // Pushes the given value to the abstract FIFO. You may call this
143
    // method several times before an  as a means of preloading
144
    // the DUT FIFO. Calls to ~set()~ to a full FIFO are ignored. You
145
    // must call  to update the DUT FIFO with your set values.
146
    //
147
    virtual function void set(uvm_reg_data_t  value,
148
                              string          fname = "",
149
                              int             lineno = 0);
150
      // emulate write, with intention of update
151
      value &= ((1 << get_n_bits())-1);
152
      if (fifo.size() == m_size) begin
153
        return;
154
      end
155
      super.set(value,fname,lineno);
156
      m_set_cnt++;
157
      fifo.push_back(this.value.value);
158
    endfunction
159
 
160
 
161
    // Function: update
162
    //
163
    // Pushes (writes) all values preloaded using  to the DUT.
164
    // You must ~update~ after ~set~ before any blocking statements,
165
    // else other reads/writes to the DUT FIFO may cause the mirror to
166
    // become out of sync with the DUT.
167
    //
168
    virtual task update(output uvm_status_e      status,
169
                        input  uvm_path_e        path = UVM_DEFAULT_PATH,
170
                        input  uvm_reg_map       map = null,
171
                        input  uvm_sequence_base parent = null,
172
                        input  int               prior = -1,
173
                        input  uvm_object        extension = null,
174
                        input  string            fname = "",
175
                        input  int               lineno = 0);
176
       uvm_reg_data_t upd;
177
       if (!m_set_cnt || fifo.size() == 0)
178
          return;
179
       m_update_in_progress = 1;
180
       for (int i=fifo.size()-m_set_cnt; m_set_cnt > 0; i++, m_set_cnt--) begin
181
         if (i >= 0) begin
182
            //uvm_reg_data_t val = get();
183
            //super.update(status,path,map,parent,prior,extension,fname,lineno);
184
            write(status,fifo[i],path,map,parent,prior,extension,fname,lineno);
185
         end
186
       end
187
       m_update_in_progress = 0;
188
    endtask
189
 
190
 
191
    // Function: mirror
192
    //
193
    // Reads the next value out of the DUT FIFO. If auto-prediction is
194
    // enabled, the frontmost value in abstract FIFO is popped. If
195
    // the ~check~ argument is set and comparison is enabled with
196
    // .
197
 
198
 
199
    // Function: get
200
    //
201
    // Returns the next value from the abstract FIFO, but does not pop it.
202
    // Used to get the expected value in a  operation.
203
    //
204
    virtual function uvm_reg_data_t get(string fname="", int lineno=0);
205
       //return fifo.pop_front();
206
       return fifo[0];
207
    endfunction
208
 
209
 
210
    // Function: do_predict
211
    //
212
    // Updates the abstract (mirror) FIFO based on  and
213
    //  operations.  When auto-prediction is on, this method
214
    // is called before each read, write, peek, or poke operation returns.
215
    // When auto-prediction is off, this method is called by a
216
    //  upon receipt and conversion of an observed bus
217
    // operation to this register.
218
    //
219
    // If a write prediction, the observed
220
    // write value is pushed to the abstract FIFO as long as it is
221
    // not full and the operation did not originate from an .
222
    // If a read prediction, the observed read value is compared
223
    // with the frontmost value in the abstract FIFO if 
224
    // enabled comparison and the FIFO is not empty.
225
    //
226
    virtual function void do_predict(uvm_reg_item      rw,
227
                                     uvm_predict_e     kind = UVM_PREDICT_DIRECT,
228
                                     uvm_reg_byte_en_t be = -1);
229
 
230
      super.do_predict(rw,kind,be);
231
 
232
      if (rw.status == UVM_NOT_OK)
233
        return;
234
 
235
      case (kind)
236
 
237
        UVM_PREDICT_WRITE,
238
        UVM_PREDICT_DIRECT:
239
        begin
240
           if (fifo.size() != m_size && !m_update_in_progress)
241
             fifo.push_back(this.value.value);
242
        end
243
 
244
        UVM_PREDICT_READ:
245
        begin
246
           uvm_reg_data_t value = rw.value[0] & ((1 << get_n_bits())-1);
247
           uvm_reg_data_t mirror_val;
248
           if (fifo.size() == 0) begin
249
             return;
250
           end
251
           mirror_val = fifo.pop_front();
252
           if (this.value.get_compare() == UVM_CHECK && mirror_val != value) begin
253
              `uvm_warning("MIRROR_MISMATCH",
254
               $sformatf("Observed DUT read value 'h%0h != mirror value 'h%0h",value,mirror_val))
255
           end
256
        end
257
 
258
      endcase
259
 
260
    endfunction
261
 
262
 
263
    // Group: Special Overrides
264
 
265
    // Task: pre_write
266
    //
267
    // Special pre-processing for a  or .
268
    // Called as a result of a  or . It is an error to
269
    // attempt a write to a full FIFO or a write while an update is still
270
    // pending. An update is pending after one or more calls to .
271
    // If in your application the DUT allows writes to a full FIFO, you
272
    // must override ~pre_write~ as appropriate.
273
    //
274
    virtual task pre_write(uvm_reg_item rw);
275
      if (m_set_cnt && !m_update_in_progress) begin
276
        `uvm_error("Needs Update","Must call update() after set() and before write()")
277
        rw.status = UVM_NOT_OK;
278
        return;
279
      end
280
      if (fifo.size() >= m_size && !m_update_in_progress) begin
281
        `uvm_error("FIFO Full","Write to full FIFO ignored")
282
        rw.status = UVM_NOT_OK;
283
        return;
284
      end
285
    endtask
286
 
287
 
288
    // Task: pre_read
289
    //
290
    // Special post-processing for a  or .
291
    // Aborts the operation if the internal FIFO is empty. If in your application
292
    // the DUT does not behave this way, you must override ~pre_write~ as
293
    // appropriate.
294
    //
295
    //
296
    virtual task pre_read(uvm_reg_item rw);
297
      // abort if fifo empty
298
      if (fifo.size() == 0) begin
299
        rw.status = UVM_NOT_OK;
300
        return;
301
      end
302
    endtask
303
 
304
 
305
    function void post_randomize();
306
      m_set_cnt = 0;
307
    endfunction
308
 
309
endclass
310
 

powered by: WebSVN 2.1.0

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