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

Subversion Repositories qaz_libs

[/] [qaz_libs/] [trunk/] [axi4_lib/] [sim/] [src/] [axi4_models/] [axi4_memory_pkg.sv] - Blame information for rev 31

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 31 qaztronic
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
//// Copyright (C) 2015 Authors and OPENCORES.ORG                 ////
4
////                                                              ////
5
//// This source file may be used and distributed without         ////
6
//// restriction provided that this copyright statement is not    ////
7
//// removed from the file and that any derivative work contains  ////
8
//// the original copyright notice and the associated disclaimer. ////
9
////                                                              ////
10
//// This source file is free software; you can redistribute it   ////
11
//// and/or modify it under the terms of the GNU Lesser General   ////
12
//// Public License as published by the Free Software Foundation; ////
13
//// either version 2.1 of the License, or (at your option) any   ////
14
//// later version.                                               ////
15
////                                                              ////
16
//// This source is distributed in the hope that it will be       ////
17
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
18
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
19
//// PURPOSE.  See the GNU Lesser General Public License for more ////
20
//// details.                                                     ////
21
////                                                              ////
22
//// You should have received a copy of the GNU Lesser General    ////
23
//// Public License along with this source; if not, download it   ////
24
//// from http://www.opencores.org/lgpl.shtml                     ////
25
////                                                              ////
26
//////////////////////////////////////////////////////////////////////
27
 
28
 
29
package axi4_memory_pkg;
30
 
31
  // --------------------------------------------------------------------
32
  //
33
  import axi4_models_pkg::*;
34
  import bfm_pkg::*;
35
  import logger_pkg::*;
36
 
37
 
38
  // --------------------------------------------------------------------
39
  //
40
  class memory_tr_class #(A, N, I, type WORD_T = byte)
41
    extends transaction_class #(memory_tr_class #(A, N, I));
42
 
43
    rand int addr;
44
    rand int size;
45
    rand byte data[];
46
 
47
    constraint default_addr
48
    {
49
      addr[$clog2(N*8)-1:0] == 0;
50
    }
51
 
52
    constraint default_size
53
    {
54
      size dist {N := 40, [N*2:N*15] := 40, [N*16:N*255] := 20};
55
    }
56
 
57
 
58
    //--------------------------------------------------------------------
59
    //
60
    function void init(int addr, int size);
61
      this.data = new[size];
62
      this.addr = addr;
63
      this.size = size;
64
    endfunction: init
65
 
66
 
67
    //--------------------------------------------------------------------
68
    //
69
    function void random(int addr, int size);
70
      this.data = new[size];
71
      assert(this.randomize() with
72
      {
73
        this.addr == addr;  // why not working?
74
        this.size == size;
75
      });
76
      this.addr = addr;
77
      this.size = size;
78
    endfunction: random
79
 
80
 
81
    // --------------------------------------------------------------------
82
    //
83
    task constant(int addr, int size, byte value[]);
84
      init(addr, size);
85
      this.data = new[size];
86
      for(int i = 0; i < size; i += value.size)
87
        foreach(value[k])
88
          data[i + k] = value[k];
89
    endtask: constant
90
 
91
 
92
    // --------------------------------------------------------------------
93
    //
94
    task automatic counting(int addr, int count);
95
      byte word[];
96
      int word_size = $bits(WORD_T) / 8; // word size in bytes
97
      init(addr, count * word_size);
98
      for(WORD_T i = 0; i < count; i++)
99
      begin
100
        word = {<< byte{i}};
101
        foreach(word[k])
102
          data[addr + (i * word_size) + k] = word[k];
103
      end
104
    endtask: counting
105
 
106
 
107
    // --------------------------------------------------------------------
108
    //
109
    function void copy(TR_T from);
110
      init(from.addr, from.size);
111
      this.data = new[from.size];
112
      foreach(from.data[i])
113
        this.data[i] = from.data[i];
114
    endfunction: copy
115
 
116
 
117
    //--------------------------------------------------------------------
118
    function new;
119
      a_word_t_mod_n: assert($bits(WORD_T) % 8 == 0) else $fatal;
120
    endfunction: new
121
 
122
 
123
  // --------------------------------------------------------------------
124
  //
125
  endclass: memory_tr_class
126
 
127
 
128
  // --------------------------------------------------------------------
129
  //
130
  class axi4_memory_class #(A, N, I, type WORD_T = byte)
131
    extends axi4_slave_model_class #(.A(A), .N(N), .I(I));
132
 
133
    logger_class log;
134
    byte memory [*];
135
 
136
 
137
    // --------------------------------------------------------------------
138
    //
139
    function void clear_all;
140
      memory.delete;
141
    endfunction: clear_all
142
 
143
 
144
    // --------------------------------------------------------------------
145
    //
146
    function void compare(memory_tr_class #(A, N, I, WORD_T) tr_h);
147
      foreach(tr_h.data[i])
148
        if(memory.exists(tr_h.addr + i))
149
        begin
150
          if(memory[tr_h.addr + i] != tr_h.data[i])
151
            log.error($sformatf("%m | 1 memory[0x%8.h] = 0x%2.h | 0x%2.h", tr_h.addr + i, memory[tr_h.addr + i], tr_h.data[i]));
152
        end
153
        else
154
          log.error($sformatf("%m | 2 memory[0x%8.h] = 0x%2.h | 0x%2.h", tr_h.addr + i, 'bx, tr_h.data[i]));
155
    endfunction: compare
156
 
157
 
158
    // --------------------------------------------------------------------
159
    //
160
    task display_memory(int offset, int count);
161
      for(int i = 0; i < count; i++)
162
        if(memory.exists(offset + i))
163
          $display("^^^ %16.t | %m | memory[0x%8.x] = 0x%2.x", $time, offset + i, memory[offset + i]);
164
        else
165
          $display("^^^ %16.t | %m | memory[0x%8.x] = 0x%2.x", $time, offset + i, 8'hxx);
166
    endtask: display_memory
167
 
168
 
169
    // --------------------------------------------------------------------
170
    //
171
    task constant_fill(int offset, int count, int value);
172
      for(int i = 0; i < count; i++)
173
        memory[offset + i] = value;
174
    endtask: constant_fill
175
 
176
 
177
    // --------------------------------------------------------------------
178
    //
179
    task counting_fill(int offset, int count);
180
      for(int i = 0; i < count; i++)
181
        memory[offset + i] = i;
182
    endtask: counting_fill
183
 
184
 
185
    // --------------------------------------------------------------------
186
    //
187
    task dump_words(int offset, ref byte data[]);
188
      foreach(data[i])
189
        if(memory.exists(offset + i))
190
          data[i] = memory[offset + i];
191
        else
192
          data[i] = 'bx;
193
    endtask: dump_words
194
 
195
 
196
    // --------------------------------------------------------------------
197
    //
198
    function reg [7:0] dump(int offset);
199
      if(memory.exists(offset))
200
        return(memory[offset]);
201
      else
202
        return('bx);
203
    endfunction: dump
204
 
205
 
206
    // --------------------------------------------------------------------
207
    //
208
    task load_words(int offset, byte data[]);
209
      foreach(data[i])
210
        memory[offset + i] = data[i];
211
    endtask: load_words
212
 
213
 
214
    // --------------------------------------------------------------------
215
    //
216
    task load(int offset, reg [7:0] data);
217
      memory[offset] = data;
218
    endtask: load
219
 
220
 
221
    // --------------------------------------------------------------------
222
    //
223
    task run_read_interface;
224
      int result;
225
      logic [9:0] delay = 0;
226
      int memory_addr;
227
 
228
      forever
229
        @(axi4_s.cb_s)
230
        begin
231
          result = ar_q_h.q.try_peek(ar_if_h);
232
          if(result != 0)
233
          begin
234
            log.debug($sformatf("araddr = 0x%h", ar_if_h.araddr));
235
            log.debug($sformatf("arlen  = 0x%h", ar_if_h.arlen));
236
            delay = $urandom_range(9, 0);
237
            if(delay > 6)
238
              repeat($urandom_range(50, 1))
239
                @(axi4_s.cb_s);
240
 
241
            for(int i = 0; i < ar_if_h.arlen + 1; i++)
242
            begin
243
              memory_addr = ar_if_h.araddr + (i * (2 ** ar_if_h.arsize));
244
              for(int i = 0; i < ar_if_h.N; i++)
245
              begin
246
                if(memory.exists(memory_addr))
247
                  r_if_h.rdata[i*8 +: 8] = memory[memory_addr];
248
                else
249
                  r_if_h.rdata[i*8 +: 8] = 8'hxx;
250
 
251
                memory_addr++;
252
              end
253
              log.debug($sformatf("rdata  = 0x%h", r_if_h.rdata));
254
 
255
              if(i == ar_if_h.arlen)
256
              begin
257
                ar_q_h.q.get(ar_if_h);
258
                r_if_h.rlast = 1;
259
              end
260
              else
261
                r_if_h.rlast = 0;
262
 
263
              r_if_h.rid = 0;
264
              r_if_h.rresp = 0;
265
 
266
              r_q_h.q.put(r_if_h);
267
              r_if_h = new(axi4_s);
268
 
269
              @(axi4_s.cb_s);
270
            end
271
            r_if_h.rlast = 0;
272
          end
273
        end
274
    endtask: run_read_interface
275
 
276
 
277
    // --------------------------------------------------------------------
278
    //
279
    task run_write_interface;
280
 
281
      int result;
282
      logic [9:0] delay = 0;
283
      int memory_addr;
284
 
285
      forever
286
        @(axi4_s.cb_s)
287
        begin
288
          result = aw_q_h.q.try_peek(aw_if_h);
289
          if(result != 0)
290
          begin
291
            memory_addr = aw_if_h.awaddr;
292
            log.debug($sformatf("awaddr = 0x%h", aw_if_h.awaddr));
293
 
294
            delay = $urandom_range(9, 0);
295
            if(delay > 6)
296
              repeat($urandom_range(8, 1))
297
                @(axi4_s.cb_s);
298
 
299
            for(int i = 0; i < aw_if_h.awlen + 1; i++)
300
            begin
301
              w_q_h.q.get(w_if_h);
302
              log.debug($sformatf("wdata = 0x%h", w_if_h.wdata));
303
              for(int k = 0; k < aw_if_h.N; k++)
304
              begin
305
                memory[memory_addr] = w_if_h.wdata[k*8 +: 8];
306
                memory_addr++;
307
              end
308
 
309
              if(i == aw_if_h.awlen)
310
              begin
311
                b_if_h.bresp = 0;
312
                b_if_h.bid = aw_if_h.awid;
313
                b_q_h.q.put(b_if_h);
314
                b_if_h = new(axi4_s);
315
                aw_q_h.q.get(aw_if_h);
316
              end
317
 
318
              @(axi4_s.cb_s);
319
            end
320
          end
321
        end
322
 
323
    endtask: run_write_interface
324
 
325
 
326
    // --------------------------------------------------------------------
327
    //
328
    task run_model;
329
      wait(axi4_s.cb_s.aresetn);
330
      axi4_s.zero_cycle_delay();
331
 
332
      aw_q_h.run_q();
333
      w_q_h.run_q();
334
      b_q_h.run_q();
335
      ar_q_h.run_q();
336
      r_q_h.run_q();
337
 
338
      fork
339
        run_write_interface();
340
      join_none
341
 
342
      fork
343
        run_read_interface();
344
      join_none
345
    endtask: run_model
346
 
347
 
348
    //--------------------------------------------------------------------
349
    function new(virtual axi4_if  #(.A(A), .N(N), .I(I)) axi4_s);
350
      super.new(axi4_s);
351
      a_word_t_mod_n: assert($bits(WORD_T) % 8 == 0) else $fatal;
352
      this.aw_q_h = new(axi4_s, 2);
353
      this.w_q_h = new(axi4_s, 16);
354
      this.b_q_h = new(axi4_s, 2);
355
      this.ar_q_h = new(axi4_s, 2);
356
      this.r_q_h = new(axi4_s, 16);
357
      this.log = new();
358
    endfunction: new
359
 
360
 
361
  // --------------------------------------------------------------------
362
  //
363
  endclass: axi4_memory_class
364
 
365
 
366
// --------------------------------------------------------------------
367
//
368
endpackage: axi4_memory_pkg
369
 

powered by: WebSVN 2.1.0

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