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

Subversion Repositories qaz_libs

[/] [qaz_libs/] [trunk/] [avalon_lib/] [sim/] [src/] [amm_monitor/] [altera_avalon_mm_monitor_transactions.sv] - Blame information for rev 31

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 31 qaztronic
// (C) 2001-2016 Intel Corporation. All rights reserved.
2
// Your use of Intel Corporation's design tools, logic functions and other
3
// software and tools, and its AMPP partner logic functions, and any output
4
// files any of the foregoing (including device programming or simulation
5
// files), and any associated documentation or information are expressly subject
6
// to the terms and conditions of the Intel Program License Subscription
7
// Agreement, Intel MegaCore Function License Agreement, or other applicable
8
// license agreement, including, without limitation, that your use is for the
9
// sole purpose of programming logic devices manufactured by Intel and sold by
10
// Intel or its authorized distributors.  Please refer to the applicable
11
// agreement for further details.
12
 
13
 
14
// $File: //acds/rel/16.1/ip/sopc/components/verification/altera_avalon_mm_monitor_bfm/altera_avalon_mm_monitor_transactions.sv $
15
// $Revision: #1 $
16
// $Date: 2016/08/07 $
17
// $Author: swbranch $
18
//-----------------------------------------------------------------------------
19
// =head1 NAME
20
// altera_avalon_mm_monitor_transactions
21
// =head1 SYNOPSIS
22
// Memory Mapped Avalon Bus Protocol Checker
23
//-----------------------------------------------------------------------------
24
// =head1 DESCRIPTION
25
// This module implements Avalon MM protocol transaction recording.
26
//-----------------------------------------------------------------------------
27
 
28
`timescale 1ps / 1ps
29
 
30
module altera_avalon_mm_monitor_transactions(
31
                                             clk,
32
                                             reset,
33
                                             tap
34
                                            );
35
 
36
   // =head1 PARAMETERS
37
   parameter AV_ADDRESS_W               = 32;   // address width
38
   parameter AV_SYMBOL_W                = 8;    // default symbol is byte
39
   parameter AV_NUMSYMBOLS              = 4;    // number of symbols per word
40
   parameter AV_BURSTCOUNT_W            = 3;    // burst port width
41
 
42
   // deprecated parameter
43
   parameter AV_WRITERESPONSE_W         = 8;
44
   parameter AV_READRESPONSE_W          = 8;
45
 
46
   parameter AV_CONSTANT_BURST_BEHAVIOR = 1;    // Address, burstcount, transactionid and
47
                                                // avm_writeresponserequest need to be held constant
48
                                                // in burst transaction
49
   parameter AV_BURST_LINEWRAP          = 0;    // line wrapping addr is set to 1
50
   parameter AV_BURST_BNDR_ONLY         = 0;    // addr is multiple of burst size
51
   parameter REGISTER_WAITREQUEST       = 0;    // Waitrequest is registered at the slave
52
   parameter AV_MAX_PENDING_READS       = 1;    // maximum pending read transfer count
53
   parameter AV_MAX_PENDING_WRITES      = 0;    // maximum pending write transfer count
54
   parameter AV_FIX_READ_LATENCY        = 0;    // fixed read latency in cycles
55
 
56
   parameter USE_READ                   = 1;    // use read port
57
   parameter USE_WRITE                  = 1;    // use write port
58
   parameter USE_ADDRESS                = 1;    // use address port
59
   parameter USE_BYTE_ENABLE            = 1;    // use byteenable port
60
   parameter USE_BURSTCOUNT             = 0;    // use burstcount port
61
   parameter USE_READ_DATA              = 1;    // use readdata port
62
   parameter USE_READ_DATA_VALID        = 1;    // use readdatavalid port
63
   parameter USE_WRITE_DATA             = 1;    // use writedata port
64
   parameter USE_BEGIN_TRANSFER         = 0;    // use begintransfer port
65
   parameter USE_BEGIN_BURST_TRANSFER   = 0;    // use begintbursttransfer port
66
   parameter USE_WAIT_REQUEST           = 1;    // use waitrequest port
67
   parameter USE_ARBITERLOCK            = 0;    // Use arbiterlock pin on interface
68
   parameter USE_LOCK                   = 0;    // Use lock pin on interface
69
   parameter USE_DEBUGACCESS            = 0;    // Use debugaccess pin on interface
70
   parameter USE_TRANSACTIONID          = 0;    // Use transactionid interface pin
71
   parameter USE_WRITERESPONSE          = 0;    // Use write response interface pins
72
   parameter USE_READRESPONSE           = 0;    // Use read response interface pins
73
   parameter USE_CLKEN                  = 0;    // Use clken interface pins
74
 
75
   parameter AV_READ_WAIT_TIME         = 0;  // Fixed wait time cycles when
76
   parameter AV_WRITE_WAIT_TIME        = 0;  // USE_WAIT_REQUEST is 0
77
 
78
   localparam AV_DATA_W = AV_SYMBOL_W * AV_NUMSYMBOLS;
79
   localparam MAX_BURST_SIZE           = USE_BURSTCOUNT ? 2**(lindex(AV_BURSTCOUNT_W)) : 1;
80
   localparam AV_TRANSACTIONID_W       = 8;
81
   localparam INT_W = 32;
82
   localparam FIFO_MAX_LEVEL   = 100;
83
   localparam FIFO_THRESHOLD   = 50;
84
   parameter  STORE_COMMAND            = 1; // Store commands inside command queue
85
   parameter  STORE_RESPONSE           = 1; // Store responses inside response queue
86
 
87
   localparam TAP_W = 1 +                                                  // clken
88
                      1 +                                                  // arbiterlock
89
                      1 +                                                  // lock
90
                      1 +                                                  // debugaccess
91
                      ((AV_TRANSACTIONID_W == 0)? 1:AV_TRANSACTIONID_W) +  // transactionid
92
                      ((AV_TRANSACTIONID_W == 0)? 1:AV_TRANSACTIONID_W) +  // readid
93
                      ((AV_TRANSACTIONID_W == 0)? 1:AV_TRANSACTIONID_W) +  // writeid
94
                      2 +                                                  // response
95
                      1 +                                                  // writeresponserequest
96
                      1 +                                                  // writeresponsevalid
97
                      1 +                                                  // waitrequest
98
                      1 +                                                  // readdatavalid
99
                      ((AV_DATA_W == 0)? 1:AV_DATA_W) +                    // readdata
100
                      1 +                                                  // write
101
                      1 +                                                  // read
102
                      ((AV_ADDRESS_W == 0)? 1:AV_ADDRESS_W) +              // address
103
                      ((AV_NUMSYMBOLS == 0)? 1:AV_NUMSYMBOLS) +            // byteenable
104
                      ((AV_BURSTCOUNT_W == 0)? 1:AV_BURSTCOUNT_W) +        // burstcount
105
                      1 +                                                  // beginbursttransfer
106
                      1 +                                                  // begintransfer
107
                      ((AV_DATA_W == 0)? 1:AV_DATA_W);                     // writedata
108
 
109
   // =head1 PINS
110
   // =head2 Clock Interface
111
   input                                             clk;
112
   input                                             reset;
113
 
114
   // =head2 Avalon Monitor Interface
115
   // Interface consists of Avalon Memory-Mapped Interface.
116
   // =cut
117
 
118
   // =pod
119
   input  [TAP_W-1:0]                                tap;
120
   // =cut
121
 
122
   function int lindex;
123
      // returns the left index for a vector having a declared width
124
      // when width is 0, then the left index is set to 0 rather than -1
125
      input [31:0] width;
126
      lindex = (width > 0) ? (width-1) : 0;
127
   endfunction
128
 
129
   //--------------------------------------------------------------------------
130
   // synthesis translate_off
131
 
132
   import verbosity_pkg::*;
133
   import avalon_mm_pkg::*;
134
 
135
   localparam VERSION = "16.1";
136
 
137
   typedef logic [lindex(AV_ADDRESS_W):0                                ] AvalonAddress_t;
138
   typedef logic [lindex(AV_BURSTCOUNT_W):0                             ] AvalonBurstCount_t;
139
   typedef logic [lindex(AV_TRANSACTIONID_W):0                          ] AvalonTransactionId_t;
140
   typedef logic [lindex(MAX_BURST_SIZE):0][lindex(AV_NUMSYMBOLS):0     ] AvalonByteEnable_t;
141
   typedef logic [lindex(MAX_BURST_SIZE):0][lindex(AV_DATA_W):0         ] AvalonData_t;
142
   typedef logic [lindex(MAX_BURST_SIZE):0][lindex(INT_W):0             ] AvalonIdle_t;
143
   typedef logic [lindex(MAX_BURST_SIZE):0][lindex(INT_W):0             ] AvalonLatency_t;
144
   typedef logic [lindex(MAX_BURST_SIZE):0][lindex(AV_READRESPONSE_W):0 ] AvalonReadResponse_t;
145
   typedef logic [lindex(MAX_BURST_SIZE):0][lindex(AV_WRITERESPONSE_W):0] AvalonWriteResponse_t;
146
   typedef logic [lindex(MAX_BURST_SIZE):0][1:0]                          AvalonReadResponseStatus_t;
147
 
148
   typedef struct packed {
149
                          Request_t               request;
150
                          AvalonAddress_t         address;
151
                          AvalonBurstCount_t      burst_count;
152
                          AvalonData_t            data;
153
                          AvalonByteEnable_t      byte_enable;
154
                          AvalonIdle_t            idle;
155
                          int                     burst_cycle;
156
                          logic                   arbiterlock;
157
                          logic                   lock;
158
                          logic                   debugaccess;
159
                          AvalonTransactionId_t   transaction_id;
160
                          time                        begin_time;
161
                          } Command_t;
162
 
163
   typedef struct packed {
164
                          Request_t                   request;
165
                          AvalonAddress_t             address;
166
                          AvalonBurstCount_t          burst_count;
167
                          AvalonData_t                data;
168
                          AvalonByteEnable_t          byte_enable;
169
                          AvalonLatency_t             wait_latency;
170
                          AvalonLatency_t             read_latency;
171
                          int                         write_latency;
172
                          int                         seq_count;
173
                          int                         burst_size;
174
                          AvalonTransactionId_t       read_id;
175
                          AvalonTransactionId_t       write_id;
176
                          AvalonReadResponseStatus_t  read_response;
177
                          AvalonResponseStatus_t      write_response;
178
                          time                        begin_time;
179
                          time                        end_time;
180
                          } Response_t;
181
 
182
   // unpack Avalon bus interface tap into individual port signals
183
   logic                                  avs_waitrequest;
184
   logic                                  avs_readdatavalid;
185
   logic [lindex(AV_DATA_W):0]            avs_readdata;
186
   logic                                  avs_write;
187
   logic                                  avs_read;
188
   logic [lindex(AV_ADDRESS_W):0]         avs_address;
189
   logic [lindex(AV_NUMSYMBOLS):0]        avs_byteenable;
190
   logic [lindex(AV_BURSTCOUNT_W):0]      avs_burstcount;
191
   logic                                  avs_beginbursttransfer;
192
   logic                                  avs_begintransfer;
193
   logic [lindex(AV_DATA_W):0]            avs_writedata;
194
 
195
   logic                                  avs_arbiterlock;
196
   logic                                  avs_lock;
197
   logic                                  avs_debugaccess;
198
 
199
   logic [lindex(AV_TRANSACTIONID_W):0]   avs_transactionid;
200
   logic [lindex(AV_TRANSACTIONID_W):0]   avs_readid;
201
   logic [lindex(AV_TRANSACTIONID_W):0]   avs_writeid;
202
   logic [1:0]                            avs_response;
203
   logic                                  avs_writeresponserequest;
204
   logic                                  avs_writeresponsevalid;
205
   logic                                  avs_clken;
206
   logic                                  clken_register = 1'b1;
207
 
208
   string               message                       = "*uninitialized*";
209
   int                  transaction_fifo_max          = FIFO_MAX_LEVEL;
210
   int                  transaction_fifo_threshold    = FIFO_THRESHOLD;
211
 
212
   int                  response_addr_offset          = 0;
213
   int                  command_addr_offset           = 0;
214
   int                  command_sequence_counter      = 1;
215
 
216
   Command_t            command_queue[$];
217
   Command_t            current_command               = '0;
218
   Command_t            client_command                = '0;
219
 
220
   Response_t           write_response_queue[$];
221
   Response_t           read_response_queue[$];
222
   Response_t           new_response                  = '0;
223
 
224
   Response_t           return_response               = 'x;
225
   Response_t           completed_command             = 'x;
226
   Response_t           completed_read_command        = 'x;
227
   Response_t           completed_write_command        = 'x;
228
   Response_t           issued_read_command_queue[$];
229
   Response_t           issued_write_command_queue[$];
230
 
231
   AvalonResponseStatus_t     null_response_status;
232
 
233
   int                  consolidate_write_burst_transactions = 1;
234
   int                  wait_time = 0;
235
   int                  write_burst_response_counter = 0;
236
   int                  write_latency = 0;
237
   int                  write_burst_command_counter = 0;
238
   int                  read_latency = 0;
239
   int                  command_waitrequested_start = 0;
240
   int                  read_response_burst_counter = 0;
241
   bit                  start_construct_complete_read_response = 0;
242
   bit                  start_construct_complete_write_response = 0;
243
   int                  clock_counter = 0;
244
   int                  current_time = 0;
245
   int                  clock_snapshot[$];
246
   AvalonBurstCount_t   avs_burstcount_int;
247
 
248
   //--------------------------------------------------------------------------
249
   // =head1 Public Methods API
250
   // This section describes the public methods in the application programming
251
   // interface (API). In this case the application program is the test bench
252
   // which instantiates and controls and queries state of this component.
253
   // Test programs must only use these public access methods and events to
254
   // communicate with this BFM component. The API and the module pins
255
   // are the only interfaces in this component that are guaranteed to be
256
   // stable. The API will be maintained for the life of the product.
257
   // While we cannot prevent a test program from directly accessing internal
258
   // tasks, functions, or data private to the BFM, there is no guarantee that
259
   // these will be present in the future. In fact, it is best for the user
260
   // to assume that the underlying implementation of this component can
261
   // and will change.
262
   //--------------------------------------------------------------------------
263
   event signal_fatal_error; // public
264
      // Signal that a fatal error has occurred. Terminates simulation.
265
 
266
   event signal_transaction_fifo_threshold; // public
267
      // Signal that the transaction FIFO threshold level has been exceeded
268
 
269
   event signal_transaction_fifo_overflow; // public
270
      // Signal that the FIFO is full and further transactions are being dropped
271
 
272
   function automatic string get_version();  // public
273
      // Return component version as a string of three integers separated by
274
      // periods. For example, version 9.1 sp1 is encoded as "9.1.1".
275
      string ret_version = "10.1";
276
      return ret_version;
277
   endfunction
278
 
279
   function automatic void set_transaction_fifo_max( // public
280
      int  level
281
   );
282
      // Set the maximum fullness level of the FIFO. The event
283
      // signal_transaction_fifo_max is triggered when this
284
      // level is exceeded.
285
      transaction_fifo_max = level;
286
   endfunction
287
 
288
   function automatic int get_transaction_fifo_max();
289
      // Get the maximum transaction FIFO depth.
290
      return transaction_fifo_max;
291
   endfunction
292
 
293
   function automatic void set_transaction_fifo_threshold( // public
294
      int  level
295
   );
296
      // Set the threshold alert level of the FIFO. The event
297
      // signal_transaction_fifo_threshold is triggered when this
298
      // level is exceeded.
299
      transaction_fifo_threshold = level;
300
   endfunction
301
 
302
   function automatic int get_transaction_fifo_threshold();
303
      // Get the transaction FIFO threshold level.
304
      return transaction_fifo_threshold;
305
   endfunction
306
 
307
   //--------------------------------------------------------------------------
308
   // Command Transaction API
309
   //--------------------------------------------------------------------------
310
   event signal_command_received; // public
311
   // This event notifies the test bench that a command has been detected
312
   // on the Avalon port.
313
   // The testbench can respond with a set_interface_wait_time
314
   // call on receiving this event to dynamically back pressure the driving
315
   // Avalon master. Alternatively, wait_time which was previously set may
316
   // be used continuously for a set of transactions.
317
 
318
   function automatic void set_command_transaction_mode( // public
319
       int mode
320
   );
321
      // By default, write burst commands are consolidated into a single
322
      // command transaction containing the write data for all burst cycles
323
      // in that command. This mode is set when the mode argument equals 0.
324
      // When the mode argument is set to 1, the default is overridden and
325
      // write burst commands yield one command transaction per burst cycle.
326
 
327
      $sformat(message, "%m: method called arg0 %0d ", mode);
328
      print(VERBOSITY_DEBUG, message);
329
      consolidate_write_burst_transactions = (mode == 0) ? 1:0;
330
   endfunction
331
 
332
   function automatic void pop_command(); // public
333
      // Pop the command descriptor from the queue so that it can be
334
      // queried with the get_command methods by the test bench.
335
      $sformat(message, "%m: method called");
336
      print(VERBOSITY_DEBUG, message);
337
 
338
      client_command = command_queue.pop_back();
339
 
340
      case(client_command.request)
341
         REQ_READ:   $sformat(message, "%m: read addr %0x",
342
                              client_command.address);
343
         REQ_WRITE:  $sformat(message,"%m: write addr %0x",
344
                              client_command.address);
345
         REQ_IDLE:   $sformat(message, "%m: idle transaction");
346
         default:    $sformat(message, "%m: illegal transaction");
347
      endcase
348
      print(VERBOSITY_DEBUG, message);
349
   endfunction
350
 
351
   function automatic int get_command_queue_size(); // public
352
      // Query the command queue to determine number of pending commands
353
      $sformat(message, "%m: method called");
354
      print(VERBOSITY_DEBUG, message);
355
 
356
      return command_queue.size();
357
   endfunction
358
 
359
   function automatic Request_t get_command_request(); // public
360
      // Get the received command descriptor to determine command request type.
361
      // A command type may be REQ_READ or REQ_WRITE. These type values
362
      // are defined in the enumerated type called Request_t which is
363
      // imported with the package named avalon_mm_pkg.
364
      $sformat(message, "%m: method called");
365
      print(VERBOSITY_DEBUG, message);
366
 
367
      return client_command.request;
368
   endfunction
369
 
370
   function automatic logic [lindex(AV_ADDRESS_W):0] get_command_address(); // public
371
      // Query the received command descriptor for the transaction address.
372
      $sformat(message, "%m: method called");
373
      print(VERBOSITY_DEBUG, message);
374
 
375
      return client_command.address;
376
   endfunction
377
 
378
   function automatic [lindex(AV_BURSTCOUNT_W):0] get_command_burst_count();// public
379
      // Query the received command descriptor for the transaction burst count.
380
      $sformat(message, "%m: method called");
381
      print(VERBOSITY_DEBUG, message);
382
 
383
      return client_command.burst_count;
384
   endfunction
385
 
386
   function automatic logic [AV_DATA_W-1:0] get_command_data( // public
387
      int index
388
   );
389
      // Query the received command descriptor for the transaction write data.
390
      // The burst commands with burst count greater than 1, the index
391
      // selects the write data cycle.
392
      $sformat(message, "%m: method called arg0 %0d", index);
393
      print(VERBOSITY_DEBUG, message);
394
 
395
      if (__check_transaction_index(index))
396
         return client_command.data[index];
397
      else
398
         return('x);
399
   endfunction
400
 
401
   function automatic logic [AV_NUMSYMBOLS-1:0] get_command_byte_enable(// public
402
      int index
403
   );
404
      // Query the received command descriptor for the transaction byte enable.
405
      // The burst commands with burst count greater than 1, the index
406
      // selects the data cycle.
407
      $sformat(message, "%m: method called arg0 %0d", index);
408
      print(VERBOSITY_DEBUG, message);
409
 
410
      if (__check_transaction_index(index))
411
         return client_command.byte_enable[index];
412
      else
413
         return('x);
414
   endfunction
415
 
416
   function automatic int get_command_burst_cycle();  // public
417
      // Write burst commands are received and processed by the slave BFM as
418
      // a sequence of discrete commands. The number of commands corresponds
419
      // to the burst count. A separate command descriptor is constructed for
420
      // each write burst cycle, corresponding to a partially completed burst.
421
      // Write data is incrementally added to each new descriptor in each burst
422
      // cycle until the command descriptor in final burst cycle contains
423
      // the full burst command data array.
424
      // The burst cycle field returned by this method tells the test bench
425
      // which burst cycle was active when this descriptor was constructed.
426
      // This facility enables the testbench to query partially completed
427
      // write burst operations. In other words, the testbench can query
428
      // the write data word on each burst cycle as it arrives and begin to
429
      // process it immediately rather than waiting until the entire burst
430
      // has been received. This makes it possible to perform pipelined write
431
      // burst processing in the test bench.
432
      $sformat(message, "%m: method called");
433
      print(VERBOSITY_DEBUG, message);
434
 
435
      return client_command.burst_cycle;
436
   endfunction
437
 
438
   function automatic logic get_command_arbiterlock(); // public
439
      // Query the received command descriptor for the transaction arbiterlock.
440
      $sformat(message, "%m: method called");
441
      print(VERBOSITY_DEBUG, message);
442
      return client_command.arbiterlock;
443
   endfunction
444
 
445
   function automatic logic get_command_lock(); // public
446
      // Query the received command descriptor for the transaction lock.
447
      $sformat(message, "%m: method called");
448
      print(VERBOSITY_DEBUG, message);
449
      return client_command.lock;
450
   endfunction
451
 
452
   function automatic logic get_command_debugaccess(); // public
453
      // Query the received command descriptor for the transaction debugaccess.
454
      $sformat(message, "%m: method called");
455
      print(VERBOSITY_DEBUG, message);
456
      return client_command.debugaccess;
457
   endfunction
458
 
459
   function automatic logic [AV_TRANSACTIONID_W-1:0] get_command_transaction_id(); // public
460
      // Query the received command descriptor for the transaction ID.
461
      $sformat(message, "%m: method called");
462
      print(VERBOSITY_DEBUG, message);
463
 
464
      return client_command.transaction_id;
465
   endfunction
466
 
467
   function automatic logic [AV_TRANSACTIONID_W-1:0] get_command_write_response_request(); // public
468
      $sformat(message, "%m: This API is no longer supported.");
469
      print(VERBOSITY_DEBUG, message);
470
 
471
      return 0;
472
   endfunction
473
 
474
   function automatic time get_command_begin_time(); // public
475
      // Returns the begin time of the transaction in the response descriptor that
476
      // has been popped from the response queue.
477
      $sformat(message, "%m: method called");
478
      print(VERBOSITY_DEBUG, message);
479
 
480
      return client_command.begin_time;
481
   endfunction
482
 
483
 
484
   //--------------------------------------------------------------------------
485
   // Response Transaction API
486
   //--------------------------------------------------------------------------
487
   event signal_read_response_complete; // public
488
   // This event signals that the read response has been received and
489
   // pushed into the response queue.
490
 
491
   event signal_write_response_complete; // public
492
   // This event signals that the write response has been received and
493
   // pushed into the response queue.
494
 
495
   event signal_response_complete; // public
496
   // This event will fire when either signal_read_response_complete
497
   // or signal_write_response_complete fires and indicates that either
498
   // a read or a write response has been received and pushed into the
499
   // response queue.
500
 
501
   function automatic int get_command_issued_queue_size(); // public
502
      // Query the issued command queue to determine the number of
503
      // commands that have been driven to the system interconnect
504
      // fabric, but have not yet completed.
505
      $sformat(message, "%m: method called");
506
      print(VERBOSITY_DEBUG, message);
507
 
508
      return (issued_read_command_queue.size() + issued_write_command_queue.size());
509
   endfunction
510
 
511
   function automatic logic [lindex(AV_ADDRESS_W):0] get_response_address(); // public
512
      // Returns the transaction address in the response descriptor that
513
      // has been popped from the response queue.
514
      $sformat(message, "%m: called");
515
      print(VERBOSITY_DEBUG, message);
516
 
517
      return return_response.address;
518
   endfunction
519
 
520
   function automatic logic [AV_NUMSYMBOLS-1:0] get_response_byte_enable(// public
521
      int index
522
   );
523
      // Returns the value of the byte enables in the response descriptor
524
      // that has been popped from the response queue. Each cycle of a
525
      // burst response is addressed individually by the specified index.
526
      $sformat(message, "%m: method called arg0 %0d", index);
527
      print(VERBOSITY_DEBUG, message);
528
 
529
      if (__check_transaction_index(index))
530
         return return_response.byte_enable[index];
531
      else
532
         return 'x;
533
   endfunction
534
 
535
   function automatic logic [lindex(AV_BURSTCOUNT_W):0] get_response_burst_size();// public
536
      // Returns the size of the response transaction burst in the
537
      // response descriptor that has been popped from the response queue.
538
      $sformat(message, "%m: method called");
539
      print(VERBOSITY_DEBUG, message);
540
 
541
      return return_response.burst_count;
542
   endfunction
543
 
544
   function automatic logic [AV_DATA_W-1:0] get_response_data( //public
545
      int index
546
   );
547
      // Returns the transaction data in the response descriptor
548
      // that has been popped from the response queue. Each cycle in a
549
      // burst response is addressed individually by the specified index.
550
      // In the case of read responses, the data is the data captured on
551
      // the avs_readdata interface pin. In the case of write responses,
552
      // the data on the driven avs_writedata pin is captured and
553
      // reflected here.
554
      $sformat(message, "%m: method called arg0 %0d", index);
555
      print(VERBOSITY_DEBUG, message);
556
 
557
      if (__check_transaction_index(index))
558
         return return_response.data[index];
559
      else
560
         return 'x;
561
   endfunction
562
 
563
   function automatic int get_response_latency( // public
564
      int index = 0
565
   );
566
      // Returns the transaction read latency in the response descriptor
567
      // that has been popped from the response queue. Each cycle in a
568
      // burst read has its own latency entry. For write transaction
569
      // responses the returned value will always be 0.
570
      $sformat(message, "%m: method called arg0 %0d", index);
571
      print(VERBOSITY_DEBUG, message);
572
 
573
      if (return_response.request == REQ_READ)
574
         if (__check_transaction_index(index)) begin
575
            return return_response.read_latency[index];
576
         end else begin
577
            return -1;
578
         end
579
      else if (return_response.request == REQ_WRITE) begin
580
         if (index > 0) begin
581
            $sformat(message, "%m: Write response does not require burst index. Index value will be ignored");
582
            print(VERBOSITY_WARNING, message);
583
         end
584
         return return_response.write_latency;
585
      end else begin
586
         return -1;
587
      end
588
   endfunction
589
 
590
   function automatic time get_response_begin_time(); // public
591
      // Returns the begin time of the transaction in the response descriptor that
592
      // has been popped from the response queue.
593
      $sformat(message, "%m: method called");
594
      print(VERBOSITY_DEBUG, message);
595
 
596
      return return_response.begin_time;
597
   endfunction
598
 
599
   function automatic time get_response_end_time(); // public
600
      // Returns the begin time of the transaction in the response descriptor that
601
      // has been popped from the response queue.
602
      $sformat(message, "%m: method called. Returning %0t", return_response.end_time);
603
      print(VERBOSITY_DEBUG, message);
604
 
605
      return return_response.end_time;
606
   endfunction
607
 
608
   function automatic Request_t get_response_request(); // public
609
      // Returns the transaction command type in the response descriptor
610
      // that has been popped from the response queue.
611
      $sformat(message, "%m: method called");
612
      print(VERBOSITY_DEBUG, message);
613
 
614
      return return_response.request;
615
   endfunction
616
 
617
   function automatic int get_response_queue_size(); // public
618
      // Queries the write and read response queue to determine
619
      // number of response descriptors currently stored in the BFM.
620
      // This is the number of responses the test program can immediately
621
      // pop off the response queue for further processing.
622
      $sformat(message, "%m: method called");
623
      print(VERBOSITY_DEBUG, message);
624
 
625
      return read_response_queue.size() + write_response_queue.size();
626
   endfunction
627
 
628
   function automatic int get_response_wait_time( // public
629
      int index
630
   );
631
      // Returns the wait time for a transaction in the response descriptor
632
      // that has been popped from the response queue. Each cycle in a burst
633
      // has its own wait time entry.
634
      $sformat(message, "%m: method called arg0 %0d", index);
635
      print(VERBOSITY_DEBUG, message);
636
 
637
      if (__check_transaction_index(index))
638
         return return_response.wait_latency[index];
639
      else
640
         return -1;
641
   endfunction
642
 
643
   function automatic void pop_response(); // public
644
      // Pop the transaction descriptor from the queue so that it can be
645
      // queried with the get_response methods by the test bench.
646
 
647
      int read_queue_head_seq_count = read_response_queue[$].seq_count;
648
      int write_queue_head_seq_count = write_response_queue[$].seq_count;
649
 
650
      $sformat(message, "%m: method called");
651
      print(VERBOSITY_DEBUG, message);
652
 
653
      if (read_queue_head_seq_count == write_queue_head_seq_count) begin
654
         $sformat(message,
655
                  "%m: Identical sequence count in read and write response queues");
656
         print(VERBOSITY_ERROR, message);
657
         -> signal_fatal_error;
658
         return;
659
      end else begin
660
         if ((read_response_queue.size() > 0) &&
661
            ((read_queue_head_seq_count < write_queue_head_seq_count) ||
662
            (write_queue_head_seq_count == 0))) begin
663
 
664
            return_response = read_response_queue.pop_back();
665
            $sformat(message,"%m: Pop read response");
666
            print(VERBOSITY_DEBUG, message);
667
         end else if (write_response_queue.size() > 0) begin
668
            return_response = write_response_queue.pop_back();
669
            $sformat(message,"%m: Pop write response");
670
            print(VERBOSITY_DEBUG, message);
671
         end else begin
672
            $sformat(message,"%m: Failed to pop from response queues");
673
            print(VERBOSITY_ERROR, message);
674
            -> signal_fatal_error;
675
            return;
676
         end
677
      end
678
 
679
      if (return_response.seq_count == 0) begin
680
         // sequence counter is initialized to 1
681
         $sformat(message,"%m:  Response transaction has sequence count of 0");
682
         print(VERBOSITY_WARNING, message);
683
      end
684
 
685
      __print_response("Master Response", return_response);///foo
686
 
687
   endfunction
688
 
689
   function automatic AvalonResponseStatus_t get_read_response_status( // public
690
      int index
691
   );
692
      // Returns the transaction response status in the read response
693
      // descriptor that has been popped from the response queue.
694
      // If API is called when read response is not enabled, it will
695
      // return default value i.e. OKAY
696
      $sformat(message, "%m: called");
697
      print(VERBOSITY_DEBUG, message);
698
 
699
      if (return_response.request == REQ_READ) begin
700
         if (USE_READRESPONSE == 1) begin
701
            return AvalonResponseStatus_t'(return_response.read_response[index]);
702
         end else begin
703
            $sformat(message, "%m: Read response is disabled, returning default value");
704
            print(VERBOSITY_WARNING, message);
705
            return null_response_status;
706
         end
707
      end else begin
708
         $sformat(message, "%m: Read response queried on write response transaction");
709
         print(VERBOSITY_WARNING, message);
710
         return null_response_status;
711
      end
712
   endfunction
713
 
714
   function automatic AvalonReadResponse_t get_response_read_response( // public
715
      int index
716
   );
717
      // API is no longer supported
718
      $sformat(message, "%m: API is not longer supported. Please use get_read_response_status API");
719
      print(VERBOSITY_WARNING, message);
720
 
721
      return '0;
722
   endfunction
723
 
724
   function automatic AvalonWriteResponse_t get_response_write_response( // public
725
      int index
726
   );
727
      // API is no longer supported
728
      $sformat(message, "%m: API is not longer supported.  Please use get_write_response_status API");
729
      print(VERBOSITY_WARNING, message);
730
 
731
      return '0;
732
   endfunction
733
 
734
   function automatic AvalonTransactionId_t get_response_read_id(); // public
735
      // Returns the read id of transaction in the response descriptor that
736
      // has been popped from the response queue.
737
      $sformat(message, "%m: called");
738
      print(VERBOSITY_DEBUG, message);
739
      if (return_response.request == REQ_WRITE) begin
740
         $sformat(message, "%m: Read response queried on write response transaction");
741
         print(VERBOSITY_WARNING, message);
742
      end
743
      return return_response.read_id;
744
   endfunction
745
 
746
   function automatic AvalonResponseStatus_t get_write_response_status(); // public
747
      // Returns the transaction response status in the write response
748
      // descriptor that has been popped from the response queue.
749
      // If API is called when write response is not enabled or enabled but
750
      // write response not requested, it will return default value i.e. OKAY
751
      $sformat(message, "%m: called");
752
      print(VERBOSITY_DEBUG, message);
753
      if (return_response.request == REQ_WRITE) begin
754
         if (USE_WRITERESPONSE == 1) begin
755
            return return_response.write_response;
756
         end else begin
757
            $sformat(message,
758
               "%m: Write response is disabled or enabled but no write response requested, returning default value");
759
            print(VERBOSITY_WARNING, message);
760
            return null_response_status;
761
         end
762
      end else begin
763
         $sformat(message, "%m: Write response queried on read response transaction");
764
         print(VERBOSITY_WARNING, message);
765
         return null_response_status;
766
      end
767
   endfunction
768
 
769
   function automatic AvalonTransactionId_t get_response_write_id(); // public
770
      // Returns the write id of transaction in the response descriptor that
771
      // has been popped from the response queue.
772
      $sformat(message, "%m: called");
773
      print(VERBOSITY_DEBUG, message);
774
      if (return_response.request == REQ_READ) begin
775
         $sformat(message, "%m: Write response queried on read response transaction");
776
         print(VERBOSITY_WARNING, message);
777
      end
778
      return return_response.write_id;
779
   endfunction
780
 
781
   function automatic logic get_clken();  // public
782
      // Return the clken status
783
      $sformat(message, "%m: method called");
784
      print(VERBOSITY_DEBUG, message);
785
      return clken_register;
786
   endfunction
787
 
788
   function automatic int get_write_response_queue_size(); // public
789
      // Queries the write response queue to determine
790
      // number of response descriptors currently stored in the BFM.
791
      // This is the number of responses the test program can immediately
792
      // pop off the response queue for further processing.
793
 
794
      $sformat(message, "%m: method called");
795
      print(VERBOSITY_DEBUG, message);
796
 
797
      return write_response_queue.size();
798
   endfunction
799
 
800
   function automatic int get_read_response_queue_size(); // public
801
      // Queries the read response queue to determine
802
      // number of response descriptors currently stored in the BFM.
803
      // This is the number of responses the test program can immediately
804
      // pop off the response queue for further processing.
805
 
806
      $sformat(message, "%m: method called");
807
      print(VERBOSITY_DEBUG, message);
808
 
809
      return read_response_queue.size();
810
   endfunction
811
 
812
   task automatic init(); // public
813
      // Initializes the counters and clear the queue.
814
      $sformat(message, "%m: method called");
815
      print(VERBOSITY_DEBUG, message);
816
 
817
      __init_descriptors();
818
      __init_queues();
819
   endtask
820
 
821
   // =cut
822
   //--------------------------------------------------------------------------
823
   // Private Methods
824
   // Note that private methods and events are prefixed with '__'
825
   //--------------------------------------------------------------------------
826
 
827
   event __command_issued;
828
 
829
   function automatic int __check_transaction_index(int index);
830
      if (index > lindex(MAX_BURST_SIZE)) begin
831
         $sformat(message,"%m: Cycle index %0d exceeds MAX_BURST_SIZE-1 %0d",
832
                  index, lindex(MAX_BURST_SIZE));
833
         print(VERBOSITY_ERROR, message);
834
         ->signal_fatal_error;
835
         return 0;
836
      end else begin
837
         return 1;
838
      end
839
   endfunction
840
 
841
   function automatic void __print_response(string text,
842
                                            Response_t response);
843
      string message = "";
844
      print_divider(VERBOSITY_DEBUG);
845
      $sformat(message, "%m: %s", text);
846
      print(VERBOSITY_DEBUG, message);
847
      $sformat(message, "Request:     %s", __request_str(response.request));
848
      print(VERBOSITY_DEBUG, message);
849
      $sformat(message, "Address:     %0x", response.address);
850
      print(VERBOSITY_DEBUG, message);
851
      $sformat(message, "Burst Count: %0x", response.burst_count);
852
      print(VERBOSITY_DEBUG, message);
853
 
854
      for (int i=0; i
855
         if (response.request == REQ_WRITE) begin
856
            $sformat(message, "  index: %0d wait: %0d",
857
                     i, response.wait_latency[i]);
858
         end else if (response.request == REQ_READ) begin
859
            $sformat(message,
860
                     "  index: %0d data: %0x wait: %0d read latency: %0d",
861
                     i, response.data[i],
862
                     response.wait_latency[i], response.read_latency[i]);
863
         end else begin
864
            $sformat(message, "    Invalid request field");
865
         end
866
         print(VERBOSITY_DEBUG, message);
867
      end
868
   endfunction
869
 
870
   function automatic void __init_descriptors();
871
      new_response = '0;
872
      current_command = '0;
873
      return_response = '0;
874
      completed_command = '0;
875
      command_addr_offset = 0;
876
      response_addr_offset = 0;
877
      client_command = '0;
878
      return_response = '0;
879
      command_sequence_counter = 1;
880
      wait_time = 0;
881
      write_burst_response_counter = 0;
882
      write_latency = 0;
883
      write_burst_command_counter = 0;
884
      read_latency = 0;
885
      command_waitrequested_start = 0;
886
      start_construct_complete_read_response = 0;
887
      start_construct_complete_write_response = 0;
888
      read_response_burst_counter = 0;
889
   endfunction
890
 
891
   function automatic void __init_queues();
892
      issued_read_command_queue = {};
893
      issued_write_command_queue = {};
894
      read_response_queue = {};
895
      write_response_queue = {};
896
      command_queue = {};
897
   endfunction
898
 
899
   function automatic string __request_str(Request_t request);
900
      case(request)
901
        REQ_READ:  return "Read";
902
        REQ_WRITE: return "Write";
903
        REQ_IDLE:  return "Idle";
904
      endcase
905
   endfunction
906
 
907
   //--------------------------------------------------------------------------
908
   // Local Machinery
909
   //--------------------------------------------------------------------------
910
   always @(signal_fatal_error) abort_simulation();
911
 
912
   always @(*) begin
913
      {
914
        avs_clken,
915
        avs_arbiterlock,
916
        avs_lock,
917
        avs_debugaccess,
918
        avs_transactionid,
919
        avs_readid,
920
        avs_writeid,
921
        avs_response,
922
        avs_writeresponserequest,
923
        avs_writeresponsevalid,
924
 
925
        avs_waitrequest,
926
        avs_readdatavalid,
927
        avs_readdata,
928
 
929
        avs_write,
930
        avs_read,
931
        avs_address,
932
        avs_byteenable,
933
        avs_burstcount,
934
        avs_beginbursttransfer,
935
        avs_begintransfer,
936
        avs_writedata
937
       } <= tap;
938
 
939
   end
940
 
941
   assign avs_burstcount_int = (USE_BURSTCOUNT ? avs_burstcount : 'd1);
942
 
943
//-----------------------------------------------------------------------------
944
// This two block monitoring the response transaction
945
//-----------------------------------------------------------------------------
946
   always @(posedge clk or posedge reset) begin
947
      clock_counter = clock_counter +1;
948
      if (reset) begin
949
         init();
950
      end else begin
951
         if (!USE_CLKEN || avs_clken == 1) begin
952
            sampled_response();
953
         end
954
      end
955
   end
956
 
957
   always @(posedge clk or posedge reset) begin
958
      if (reset) begin
959
         init();
960
      end else begin
961
         if (!USE_CLKEN || avs_clken == 1) begin
962
            if ((get_command_issued_queue_size() == 0) &&
963
               (start_construct_complete_write_response == 0) &&
964
               start_construct_complete_read_response == 0) begin
965
               @__command_issued;
966
            end
967
 
968
            if (issued_write_command_queue.size() > 0) begin
969
               if (start_construct_complete_write_response == 0) begin
970
                  completed_write_command = issued_write_command_queue.pop_back();
971
                  start_construct_complete_write_response = 1;
972
               end
973
            end
974
 
975
            if (issued_read_command_queue.size() > 0) begin
976
               if (read_response_burst_counter == 0 &&
977
                   start_construct_complete_read_response == 0) begin
978
                  completed_read_command = issued_read_command_queue.pop_back();
979
                  start_construct_complete_read_response = 1;
980
               end
981
            end
982
 
983
            if (start_construct_complete_read_response)
984
               monitor_response(completed_read_command);
985
 
986
            if (start_construct_complete_write_response)
987
               monitor_response(completed_write_command);
988
 
989
         end
990
      end
991
   end
992
 
993
//-----------------------------------------------------------------------------
994
// This task monitoring the command port info and pass it to response
995
// transaction.
996
//-----------------------------------------------------------------------------
997
   task automatic sampled_response();
998
 
999
      if (avs_read) begin
1000
         response_addr_offset = 0;
1001
         new_response.request                  = REQ_READ;
1002
         new_response.data                     = 'x;
1003
         new_response.wait_latency             = 'x;
1004
         new_response.byte_enable              = 'x;
1005
         new_response.write_latency            = 'x;
1006
         new_response.burst_count              = avs_burstcount_int;
1007
         new_response.burst_size               = avs_burstcount_int;
1008
         new_response.seq_count                = command_sequence_counter++;;
1009
         new_response.address                  = avs_address;
1010
         new_response.read_id                  = 'x;
1011
         new_response.read_response            = 'x;
1012
         new_response.begin_time               = $time;
1013
 
1014
         if (USE_READ_DATA_VALID || USE_BURSTCOUNT)
1015
            new_response.read_latency = 'x;
1016
         else
1017
            new_response.read_latency = AV_FIX_READ_LATENCY;
1018
 
1019
         if (avs_waitrequest) begin
1020
            wait_time++;
1021
            return;
1022
         end
1023
 
1024
         new_response.wait_latency[response_addr_offset] = wait_time;
1025
         new_response.byte_enable[response_addr_offset] = avs_byteenable;
1026
         issued_read_command_queue.push_front(new_response);
1027
         -> __command_issued;
1028
         write_burst_response_counter = 0;
1029
         wait_time = 0;
1030
         clock_snapshot.push_front(clock_counter);
1031
      end else if (avs_write) begin
1032
         if (write_burst_response_counter == 0) begin
1033
            write_burst_response_counter = avs_burstcount_int;
1034
            new_response.seq_count = command_sequence_counter++;;
1035
            response_addr_offset = 0;
1036
         end
1037
 
1038
         new_response.read_latency                        = 'x;
1039
         new_response.request                             = REQ_WRITE;
1040
         new_response.data[response_addr_offset]          = avs_writedata;
1041
         new_response.byte_enable[response_addr_offset]   = avs_byteenable;
1042
         new_response.write_latency                       = 'x;
1043
         if (response_addr_offset == 0) begin
1044
            new_response.burst_count                      = avs_burstcount_int;
1045
            new_response.burst_size                       = avs_burstcount_int;
1046
            new_response.address                          = avs_address;
1047
            new_response.begin_time                       = $time;
1048
         end
1049
         new_response.read_id                             = 'x;
1050
         new_response.read_response                       = 'x;
1051
 
1052
         if (avs_waitrequest) begin
1053
            wait_time++;
1054
            return;
1055
         end
1056
 
1057
         new_response.wait_latency[response_addr_offset] = wait_time;
1058
 
1059
         if (USE_WRITERESPONSE == 0) begin
1060
            if (response_addr_offset == (new_response.burst_count-1)) begin
1061
               if (STORE_RESPONSE == 1) begin
1062
                  if (get_response_queue_size() < transaction_fifo_max) begin
1063
                     new_response.end_time = $time;
1064
                     write_response_queue.push_front(new_response);
1065
                     if (get_response_queue_size() > transaction_fifo_threshold)
1066
                        ->signal_transaction_fifo_threshold;
1067
                  end else begin
1068
                     $sformat(message, "%m(%0d): FIFO overflow! Transaction dropped.", `__LINE__);
1069
                     print(VERBOSITY_WARNING, message);
1070
                     ->signal_transaction_fifo_overflow;
1071
                  end
1072
               end
1073
               -> signal_write_response_complete;
1074
            end
1075
         end else begin
1076
            if (response_addr_offset == (new_response.burst_count-1)) begin
1077
               issued_write_command_queue.push_front(new_response);
1078
               -> __command_issued;
1079
            end
1080
         end
1081
 
1082
         response_addr_offset++;
1083
         write_burst_response_counter--;
1084
         wait_time = 0;
1085
      end
1086
 
1087
   endtask
1088
 
1089
//-----------------------------------------------------------------------------
1090
// This task monitoring the response port and construct a full response
1091
// transaction.
1092
//-----------------------------------------------------------------------------
1093
   task automatic monitor_response(ref Response_t completed_response);
1094
      case(completed_response.request)
1095
         REQ_WRITE: begin
1096
            // no response transaction while USE_WRITERESPONSE = 0
1097
            if (USE_WRITERESPONSE == 1) begin
1098
               if (!avs_writeresponsevalid) begin
1099
                  write_latency++;
1100
                  return;
1101
               end
1102
 
1103
               completed_response.write_id               = avs_writeid;
1104
               completed_response.write_latency          = write_latency;
1105
 
1106
               if (!$cast(completed_response.write_response, avs_response))
1107
                  begin
1108
                     $sformat(message, "%m: Response value is not valid when write response is valid");
1109
                     print(VERBOSITY_FAILURE, message);
1110
                  end
1111
 
1112
               write_latency = 0;
1113
 
1114
               if (STORE_RESPONSE == 1) begin
1115
                  if (get_response_queue_size() < transaction_fifo_max) begin
1116
                     completed_response.end_time = $time;
1117
                     write_response_queue.push_front(completed_response);
1118
                     if (get_response_queue_size() > transaction_fifo_threshold) begin
1119
                        ->signal_transaction_fifo_threshold;
1120
                     end
1121
                  end else begin
1122
                     $sformat(message, "%m(%0d): FIFO overflow! Transaction dropped.", `__LINE__);
1123
                     print(VERBOSITY_WARNING, message);
1124
                     ->signal_transaction_fifo_overflow;
1125
                  end
1126
               end
1127
               -> signal_write_response_complete;
1128
               start_construct_complete_write_response = 0;
1129
            end
1130
         end
1131
         REQ_READ: begin
1132
            if (USE_READ_DATA_VALID || USE_BURSTCOUNT) begin
1133
               if (!avs_readdatavalid) begin
1134
                  read_latency++;
1135
                  return;
1136
               end
1137
               completed_response.data[read_response_burst_counter] = avs_readdata;
1138
               completed_response.read_latency[read_response_burst_counter] = read_latency;
1139
 
1140
               if (USE_READRESPONSE) begin
1141
                  completed_response.read_id = avs_readid;
1142
 
1143
                  if (!$cast(completed_response.read_response[read_response_burst_counter], avs_response))
1144
                     begin
1145
                        $sformat(message, "%m: Response value is not valid when read response is valid");
1146
                        print(VERBOSITY_FAILURE, message);
1147
                     end
1148
               end
1149
 
1150
               read_latency = 0;
1151
 
1152
            end else begin
1153
               if (AV_FIX_READ_LATENCY > 0) begin
1154
                  if (clock_counter - clock_snapshot[$] < AV_FIX_READ_LATENCY) begin
1155
                     return;
1156
                  end
1157
                  current_time = clock_snapshot.pop_back();
1158
               end
1159
 
1160
               completed_response.read_latency[0]     = AV_FIX_READ_LATENCY;
1161
               completed_response.data[0]             = avs_readdata;
1162
 
1163
               if (USE_READRESPONSE) begin
1164
                  completed_response.read_id          = avs_readid;
1165
 
1166
                  if (!$cast(completed_response.read_response[0], avs_response))
1167
                     begin
1168
                        $sformat(message, "%m: Response value is not valid when read response is valid");
1169
                        print(VERBOSITY_FAILURE, message);
1170
                     end
1171
               end
1172
               read_latency = 0;
1173
            end
1174
 
1175
            if (read_response_burst_counter == completed_response.burst_count-1) begin
1176
               if (STORE_RESPONSE == 1) begin
1177
                  if (get_response_queue_size() < transaction_fifo_max) begin
1178
                     completed_response.end_time = $time;
1179
                     read_response_queue.push_front(completed_response);
1180
                     if (get_response_queue_size() > transaction_fifo_threshold)
1181
                        ->signal_transaction_fifo_threshold;
1182
                  end else begin
1183
                     $sformat(message, "%m(%0d): FIFO overflow! Transaction dropped.", `__LINE__);
1184
                     print(VERBOSITY_WARNING, message);
1185
                     ->signal_transaction_fifo_overflow;
1186
                  end
1187
               end
1188
               ->signal_read_response_complete;
1189
               read_response_burst_counter = 0;
1190
               start_construct_complete_read_response = 0;
1191
            end else begin
1192
               read_response_burst_counter++;
1193
            end
1194
         end
1195
      endcase
1196
   endtask
1197
 
1198
   always @(signal_read_response_complete or
1199
            signal_write_response_complete or
1200
            posedge reset) begin
1201
      if (!reset) begin
1202
         ->signal_response_complete;
1203
      end
1204
   end
1205
 
1206
 
1207
//-----------------------------------------------------------------------------
1208
// This block monitoring the command transaction
1209
//-----------------------------------------------------------------------------
1210
   always @(posedge clk or posedge reset) begin
1211
      clken_register <= avs_clken;
1212
      if (reset) begin
1213
         init();
1214
      end else begin
1215
         if (!USE_CLKEN || avs_clken == 1) begin
1216
            monitor_command();
1217
         end
1218
      end
1219
   end
1220
 
1221
//-----------------------------------------------------------------------------
1222
// This task monitoring the command port and construct a full command
1223
// transaction.
1224
//-----------------------------------------------------------------------------
1225
   task automatic monitor_command();
1226
      if (avs_write) begin
1227
         if (write_burst_command_counter == 0) begin
1228
            write_burst_command_counter = avs_burstcount_int;
1229
            command_addr_offset = 0;
1230
         end
1231
 
1232
         current_command.request                   = REQ_WRITE;
1233
         current_command.data[command_addr_offset] = avs_writedata;
1234
         current_command.byte_enable[command_addr_offset]  = avs_byteenable;
1235
         if (command_addr_offset == 0) begin
1236
            current_command.address                   = avs_address;
1237
            current_command.burst_count               = avs_burstcount_int;
1238
            current_command.transaction_id            = avs_transactionid;
1239
         end
1240
 
1241
         current_command.burst_cycle               = command_addr_offset;
1242
         current_command.arbiterlock               = avs_arbiterlock;
1243
         current_command.lock                      = avs_lock;
1244
         current_command.debugaccess               = avs_debugaccess;
1245
 
1246
         if (command_waitrequested_start == 0) begin
1247
            if ((consolidate_write_burst_transactions &&
1248
               (command_addr_offset == current_command.burst_count-1)) ||
1249
               !consolidate_write_burst_transactions) begin
1250
               if (STORE_COMMAND == 1) begin
1251
                  if (get_command_queue_size() < transaction_fifo_max) begin
1252
                     current_command.begin_time = $time;
1253
                     command_queue.push_front(current_command);
1254
                     if (get_command_queue_size() > transaction_fifo_threshold)
1255
                        ->signal_transaction_fifo_threshold;
1256
                  end else begin
1257
                     $sformat(message, "%m(%0d): FIFO overflow! Transaction dropped.", `__LINE__);
1258
                     print(VERBOSITY_WARNING, message);
1259
                     ->signal_transaction_fifo_overflow;
1260
                  end
1261
               end
1262
               ->signal_command_received;
1263
            end
1264
            if (avs_waitrequest) begin
1265
               command_waitrequested_start = 1;
1266
               return;
1267
            end
1268
         end else begin
1269
            if (avs_waitrequest)
1270
               return;
1271
            else
1272
               command_waitrequested_start = 0;
1273
         end
1274
         command_addr_offset++;
1275
         write_burst_command_counter--;
1276
      end else if (avs_read) begin
1277
 
1278
         current_command = 'x;
1279
         write_burst_command_counter = 0;
1280
         command_addr_offset = 0;
1281
 
1282
         current_command.request                   = REQ_READ;
1283
         current_command.address                   = avs_address;
1284
         current_command.data                      = 'x;
1285
         current_command.byte_enable               = avs_byteenable;
1286
         current_command.burst_count               = avs_burstcount_int;
1287
         current_command.arbiterlock               = avs_arbiterlock;
1288
         current_command.lock                      = avs_lock;
1289
         current_command.debugaccess               = avs_debugaccess;
1290
         current_command.transaction_id            = avs_transactionid;
1291
 
1292
         if (command_waitrequested_start == 0) begin
1293
            if (STORE_COMMAND == 1) begin
1294
               if (get_command_queue_size() < transaction_fifo_max) begin
1295
                  current_command.begin_time = $time;
1296
                  command_queue.push_front(current_command);
1297
                  if (get_command_queue_size() > transaction_fifo_threshold)
1298
                     ->signal_transaction_fifo_threshold;
1299
               end else begin
1300
                  $sformat(message, "%m(%0d): FIFO overflow! Transaction dropped.", `__LINE__);
1301
                  print(VERBOSITY_WARNING, message);
1302
                  ->signal_transaction_fifo_overflow;
1303
               end
1304
            end
1305
            ->signal_command_received;
1306
            if (avs_waitrequest) begin
1307
               command_waitrequested_start = 1;
1308
               return;
1309
            end
1310
         end else begin
1311
            if (avs_waitrequest)
1312
               return;
1313
            else
1314
               command_waitrequested_start = 0;
1315
         end
1316
      end
1317
   endtask
1318
 
1319
   // synthesis translate_on
1320
endmodule
1321
 
1322
 
1323
 

powered by: WebSVN 2.1.0

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