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_arbiter_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_arbiter_pkg;
30
 
31
  // --------------------------------------------------------------------
32
  //
33
  import axi4_models_pkg::*;
34
  import bfm_pkg::*;
35
  import logger_pkg::*;
36
 
37
 
38
  // --------------------------------------------------------------------
39
  //
40
  virtual class base_request_class #(A, N, I);
41
 
42
    string kind;
43
    int id = -1;
44
 
45
    //--------------------------------------------------------------------
46
    //
47
    pure virtual function void write_ax_if(axi4_channel_if_class #(A, N, I) channel);
48
    pure virtual function void copy_ax_if(axi4_channel_if_class #(A, N, I) channel);
49
 
50
 
51
  // --------------------------------------------------------------------
52
  //
53
  endclass: base_request_class
54
 
55
 
56
  // --------------------------------------------------------------------
57
  //
58
  class write_request_class #(A, N, I)
59
    extends base_request_class #(A, N, I);
60
 
61
    logic [(A-1):0]    awaddr;
62
    logic [1:0]        awburst;
63
    logic [(I-1):0]    awid;
64
    logic [7:0]        awlen;
65
    logic [2:0]        awsize;
66
    logic [3:0]        awcache;
67
    logic              awlock;
68
    logic [2:0]        awprot;
69
    logic [3:0]        awqos;
70
    logic [3:0]        awregion;
71
 
72
 
73
    // --------------------------------------------------------------------
74
    //
75
    function void write_ax_if(axi4_channel_if_class #(A, N, I) channel);
76
      axi4_aw_if_class #(A, N, I) aw_if_h;
77
      $cast(aw_if_h, channel);
78
      aw_if_h.awaddr    = awaddr;
79
      aw_if_h.awburst   = awburst;
80
      aw_if_h.awid      = awid;
81
      aw_if_h.awlen     = awlen;
82
      aw_if_h.awsize    = awsize;
83
      aw_if_h.awcache   = awcache;
84
      aw_if_h.awlock    = awlock;
85
      aw_if_h.awprot    = awprot;
86
      aw_if_h.awqos     = awqos;
87
      aw_if_h.awregion  = awregion;
88
    endfunction: write_ax_if
89
 
90
 
91
    // --------------------------------------------------------------------
92
    //
93
    function void copy_ax_if(axi4_channel_if_class #(A, N, I) channel);
94
      axi4_aw_if_class #(A, N, I) aw_if_h;
95
      $cast(aw_if_h, channel);
96
      awaddr    = aw_if_h.awaddr;
97
      awburst   = aw_if_h.awburst;
98
      awid      = aw_if_h.awid;
99
      awlen     = aw_if_h.awlen;
100
      awsize    = aw_if_h.awsize;
101
      awcache   = aw_if_h.awcache;
102
      awlock    = aw_if_h.awlock;
103
      awprot    = aw_if_h.awprot;
104
      awqos     = aw_if_h.awqos;
105
      awregion  = aw_if_h.awregion;
106
    endfunction: copy_ax_if
107
 
108
 
109
    //--------------------------------------------------------------------
110
    function new(int id);
111
      super.new;
112
      this.kind = "WRITE";
113
      this.id = id;
114
    endfunction: new
115
 
116
 
117
  // --------------------------------------------------------------------
118
  //
119
  endclass: write_request_class
120
 
121
 
122
  // --------------------------------------------------------------------
123
  //
124
  class read_request_class #(A, N, I)
125
    extends base_request_class #(A, N, I);
126
 
127
    logic [(A-1):0]    araddr;
128
    logic [1:0]        arburst;
129
    logic [(I-1):0]    arid;
130
    logic [7:0]        arlen;
131
    logic [2:0]        arsize;
132
    logic [3:0]        arcache;
133
    logic              arlock;
134
    logic [2:0]        arprot;
135
    logic [3:0]        arqos;
136
    logic [3:0]        arregion;
137
 
138
    // --------------------------------------------------------------------
139
    //
140
    function void write_ax_if(axi4_channel_if_class #(A, N, I) channel);
141
      axi4_ar_if_class #(A, N, I) ar_if_h;
142
      $cast(ar_if_h, channel);
143
      ar_if_h.araddr    = araddr;
144
      ar_if_h.arburst   = arburst;
145
      ar_if_h.arid      = arid;
146
      ar_if_h.arlen     = arlen;
147
      ar_if_h.arsize    = arsize;
148
      ar_if_h.arcache   = arcache;
149
      ar_if_h.arlock    = arlock;
150
      ar_if_h.arprot    = arprot;
151
      ar_if_h.arqos     = arqos;
152
      ar_if_h.arregion  = arregion;
153
    endfunction: write_ax_if
154
 
155
 
156
    // --------------------------------------------------------------------
157
    //
158
    function void copy_ax_if(axi4_channel_if_class #(A, N, I) channel);
159
      axi4_ar_if_class #(A, N, I) ar_if_h;
160
      $cast(ar_if_h, channel);
161
      araddr    = ar_if_h.araddr;
162
      arburst   = ar_if_h.arburst;
163
      arid      = ar_if_h.arid;
164
      arlen     = ar_if_h.arlen;
165
      arsize    = ar_if_h.arsize;
166
      arcache   = ar_if_h.arcache;
167
      arlock    = ar_if_h.arlock;
168
      arprot    = ar_if_h.arprot;
169
      arqos     = ar_if_h.arqos;
170
      arregion  = ar_if_h.arregion;
171
    endfunction: copy_ax_if
172
 
173
 
174
    //--------------------------------------------------------------------
175
    function new(int id);
176
      super.new;
177
      this.kind = "READ";
178
      this.id = id;
179
    endfunction: new
180
 
181
 
182
  // --------------------------------------------------------------------
183
  //
184
  endclass: read_request_class
185
 
186
 
187
  // --------------------------------------------------------------------
188
  //
189
  class requester_class #(A, N, I)
190
    extends axi4_slave_model_class #(A, N, I);
191
 
192
    mailbox #(base_request_class #(A, N, I)) q;
193
    semaphore read_done;
194
    semaphore write_done;
195
    int id = -1;
196
    logger_class log;
197
 
198
 
199
    // --------------------------------------------------------------------
200
    //
201
    task automatic run_read_interface;
202
      read_request_class #(A, N, I) r_req_h;
203
      read_done = new;
204
      forever
205
        @(axi4_s.cb_s)
206
        begin
207
          ar_q_h.q.get(ar_if_h);
208
          log.debug($sformatf("%m | start"));
209
          log.debug($sformatf("%m | araddr = 0x%h", ar_if_h.araddr));
210
          log.debug($sformatf("%m | arlen  = 0x%h", ar_if_h.arlen));
211
          r_req_h = new(id);
212
          r_req_h.copy_ax_if(ar_if_h);
213
          q.put(r_req_h);
214
          read_done.get();
215
          log.debug($sformatf("%m | done"));
216
        end
217
    endtask: run_read_interface
218
 
219
 
220
    // --------------------------------------------------------------------
221
    //
222
    task run_write_interface;
223
      write_request_class #(A, N, I) w_req_h;
224
      write_done = new;
225
      forever
226
        @(axi4_s.cb_s)
227
        begin
228
          aw_q_h.q.get(aw_if_h);
229
          log.debug($sformatf("%m | start"));
230
          log.debug($sformatf("%m | awaddr = 0x%h", aw_if_h.awaddr));
231
          log.debug($sformatf("%m | awlen  = 0x%h", aw_if_h.awlen));
232
          w_req_h = new(id);
233
          w_req_h.copy_ax_if(aw_if_h);
234
          q.put(w_req_h);
235
          write_done.get();
236
          log.debug($sformatf("%m | done"));
237
        end
238
    endtask: run_write_interface
239
 
240
 
241
    // --------------------------------------------------------------------
242
    //
243
    task run_model;
244
      wait(axi4_s.cb_s.aresetn);
245
      axi4_s.zero_cycle_delay();
246
 
247
      aw_q_h.run_q();
248
      w_q_h.run_q();
249
      b_q_h.run_q();
250
      ar_q_h.run_q();
251
      r_q_h.run_q();
252
 
253
      fork
254
        run_read_interface();
255
      join_none
256
 
257
      fork
258
        run_write_interface();
259
      join_none
260
 
261
    endtask: run_model
262
 
263
 
264
    //--------------------------------------------------------------------
265
    function new(int id, virtual axi4_if  #(.A(A), .N(N), .I(I)) axi4_s);
266
      super.new(axi4_s);
267
      this.aw_q_h = new(axi4_s, 2);
268
      this.w_q_h = new(axi4_s, 16);
269
      this.b_q_h = new(axi4_s, 2);
270
      this.ar_q_h = new(axi4_s, 2);
271
      this.r_q_h = new(axi4_s, 16);
272
      this.id = id;
273
      this.q = new(1);
274
      this.log = new();
275
    endfunction: new
276
 
277
 
278
  // --------------------------------------------------------------------
279
  //
280
  endclass: requester_class
281
 
282
 
283
  // --------------------------------------------------------------------
284
  //
285
  class axi4_granter_class #(A, N, I)
286
    extends axi4_master_model_class #(A, N, I);
287
 
288
    logger_class log;
289
 
290
 
291
    // --------------------------------------------------------------------
292
    //
293
    task run_model;
294
      wait(axi4_m.cb_s.aresetn);
295
      axi4_m.zero_cycle_delay();
296
 
297
      aw_q_h.run_q();
298
      w_q_h.run_q();
299
      b_q_h.run_q();
300
      ar_q_h.run_q();
301
      r_q_h.run_q();
302
    endtask: run_model
303
 
304
 
305
    //--------------------------------------------------------------------
306
    function new(virtual axi4_if  #(.A(A), .N(N), .I(I)) axi4_m);
307
      super.new(axi4_m);
308
      this.aw_q_h = new(axi4_m, 2);
309
      this.w_q_h = new(axi4_m, 16);
310
      this.b_q_h = new(axi4_m, 2);
311
      this.ar_q_h = new(axi4_m, 2);
312
      this.r_q_h = new(axi4_m, 16);
313
      this.log = new();
314
    endfunction: new
315
 
316
 
317
  // --------------------------------------------------------------------
318
  //
319
  endclass: axi4_granter_class
320
 
321
 
322
  // --------------------------------------------------------------------
323
  //
324
  class axi4_arbiter_class #(A, N, I);
325
 
326
    axi4_granter_class #(A, N, I) g_h;
327
    requester_class #(A, N, I) r_h[];
328
    mailbox #(int) grant;
329
    int count = -1;
330
    int current = 0, previous;
331
    logger_class log;
332
 
333
 
334
    // --------------------------------------------------------------------
335
    //
336
    task automatic do_read(requester_class #(A, N, I) r_h);
337
      int id;
338
      read_request_class #(A, N, I) r_req_h;
339
      base_request_class #(A, N, I) request;
340
      log.debug($sformatf("%m | read grant for %d", r_h.id));
341
      r_h.q.get(request);
342
      $cast(r_req_h, request);
343
 
344
      g_h.ar_if_h = new(g_h.axi4_m);
345
      r_req_h.write_ax_if(g_h.ar_if_h);
346
      g_h.ar_q_h.q.put(g_h.ar_if_h);
347
 
348
      for(int i = 0; i < r_h.ar_if_h.arlen + 1; i++)
349
      begin
350
        g_h.r_if_h = new(g_h.axi4_m);
351
        r_h.r_if_h = new(r_h.axi4_s);
352
        g_h.r_q_h.q.get(g_h.r_if_h);
353
        r_h.r_if_h.copy(g_h.r_if_h);
354
        r_h.r_q_h.q.put(r_h.r_if_h);
355
        @(r_h.axi4_s.cb_s);
356
      end
357
 
358
      r_h.read_done.put();
359
      grant.get(id);
360
      log.debug($sformatf("%m | read grant for %d done", id));
361
    endtask: do_read
362
 
363
 
364
    // --------------------------------------------------------------------
365
    //
366
    task automatic do_write(requester_class #(A, N, I) r_h);
367
      int id;
368
      write_request_class #(A, N, I) w_req_h;
369
      base_request_class #(A, N, I) request;
370
      log.debug($sformatf("%m | write grant for %d", r_h.id));
371
      r_h.q.get(request);
372
      $cast(w_req_h, request);
373
 
374
      g_h.aw_if_h = new(g_h.axi4_m);
375
      w_req_h.write_ax_if(g_h.aw_if_h);
376
      g_h.aw_q_h.q.put(g_h.aw_if_h);
377
 
378
      for(int i = 0; i < r_h.aw_if_h.awlen + 1; i++)
379
      begin
380
        r_h.w_if_h = new(r_h.axi4_s);
381
        g_h.w_if_h = new(g_h.axi4_m);
382
        r_h.w_q_h.q.get(r_h.w_if_h);
383
        g_h.w_if_h.copy(r_h.w_if_h);
384
        g_h.w_q_h.q.put(g_h.w_if_h);
385
        @(r_h.axi4_s.cb_s);
386
      end
387
 
388
      g_h.b_q_h.q.get(g_h.b_if_h);
389
      r_h.b_if_h = new(r_h.axi4_s);
390
      r_h.b_if_h.copy(g_h.b_if_h);
391
      r_h.b_q_h.q.put(r_h.b_if_h);
392
      r_h.write_done.put();
393
      grant.get(id);
394
      log.debug($sformatf("%m | write grant for %d done", id));
395
    endtask: do_write
396
 
397
 
398
    // --------------------------------------------------------------------
399
    //
400
    task automatic give_grant(requester_class #(A, N, I) r_h);
401
      base_request_class #(A, N, I) request;
402
      grant.put(r_h.id);
403
      r_h.q.peek(request);
404
      log.debug($sformatf("%m | %d got grant for %s", r_h.id, request.kind));
405
 
406
      if(request.kind.toupper == "WRITE")
407
        do_write(r_h);
408
      else if(request.kind.toupper == "READ")
409
        do_read(r_h);
410
      else
411
        $stop;
412
 
413
      current = (current + count + 1) % count;
414
      log.debug($sformatf("%m | new current = %d", current));
415
    endtask: give_grant
416
 
417
 
418
    // --------------------------------------------------------------------
419
    //
420
    task automatic do_arbitration;
421
      wait(g_h.axi4_m.cb_m.aresetn);
422
      g_h.axi4_m.zero_cycle_delay();
423
      forever
424
        @(g_h.axi4_m.cb_m)
425
        begin
426
          for(int i = current; i < current + count; i++)
427
            if(r_h[i % count].q.num > 0)
428
            begin
429
              give_grant(r_h[i % count]);
430
              break;
431
            end
432
        end
433
    endtask: do_arbitration
434
 
435
 
436
    //--------------------------------------------------------------------
437
    function void debug_enable;
438
      log.debug_enable();
439
      g_h.log.debug_enable();
440
      foreach(r_h[i])
441
        r_h[i].log.debug_enable();
442
    endfunction: debug_enable
443
 
444
 
445
    //--------------------------------------------------------------------
446
    function new
447
      (
448
        virtual axi4_if  #(A, N, I) axi4_s[],
449
        virtual axi4_if  #(.A(A), .N(N), .I(I)) axi4_m
450
      );
451
      this.grant = new(1);
452
      this.g_h = new(axi4_m);
453
      this.count = axi4_s.size;
454
      this.r_h = new[axi4_s.size];
455
      this.log = new;
456
 
457
      foreach(axi4_s[i])
458
        r_h[i] = new(i, axi4_s[i]);
459
 
460
      fork
461
        do_arbitration();
462
      join_none
463
    endfunction: new
464
 
465
 
466
  // --------------------------------------------------------------------
467
  //
468
  endclass: axi4_arbiter_class
469
 
470
 
471
// --------------------------------------------------------------------
472
//
473
endpackage: axi4_arbiter_pkg
474
 

powered by: WebSVN 2.1.0

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