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

Subversion Repositories axi_master

[/] [axi_master/] [trunk/] [src/] [base/] [axi_master_single.v] - Blame information for rev 18

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 eyalhoc
/////////////////////////////////////////////////////////////////////
2
////                                                             ////
3
////  Author: Eyal Hochberg                                      ////
4
////          eyal@provartec.com                                 ////
5
////                                                             ////
6
////  Downloaded from: http://www.opencores.org                  ////
7
/////////////////////////////////////////////////////////////////////
8
////                                                             ////
9
//// Copyright (C) 2010 Provartec LTD                            ////
10
//// www.provartec.com                                           ////
11
//// info@provartec.com                                          ////
12
////                                                             ////
13
//// This source file may be used and distributed without        ////
14
//// restriction provided that this copyright statement is not   ////
15
//// removed from the file and that any derivative work contains ////
16
//// the original copyright notice and the associated disclaimer.////
17
////                                                             ////
18
//// This source file is free software; you can redistribute it  ////
19
//// and/or modify it under the terms of the GNU Lesser General  ////
20
//// Public License as published by the Free Software Foundation.////
21
////                                                             ////
22
//// This source is distributed in the hope that it will be      ////
23
//// useful, but WITHOUT ANY WARRANTY; without even the implied  ////
24
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR     ////
25
//// PURPOSE.  See the GNU Lesser General Public License for more////
26
//// details. http://www.gnu.org/licenses/lgpl.html              ////
27
////                                                             ////
28
/////////////////////////////////////////////////////////////////////
29 6 eyalhoc
 
30
OUTFILE PREFIX_single.v
31
 
32
INCLUDE def_axi_master.txt
33
 
34
module PREFIX_single(PORTS);
35
 
36
   parameter                           MASTER_NUM  = 0;
37
   parameter                           MASTER_ID   = 0;
38
   parameter                           MASTER_PEND = 0;
39 12 eyalhoc
 
40
CREATE prgen_rand.v DEFCMD(DEFINE NOT_IN_LIST)
41 6 eyalhoc
`include "prgen_rand.v"
42
 
43
   parameter                           MAX_CMDS    = 16; //Depth of command FIFO
44
   parameter                           DATA_LOG    = LOG2(EXPR(DATA_BITS/8));
45
   parameter                           PEND_BITS   =
46
                                       (MAX_CMDS <= 16)  ? 4 :
47
                                       (MAX_CMDS <= 32)  ? 5 :
48
                                       (MAX_CMDS <= 64)  ? 6 :
49
                                       (MAX_CMDS <= 128) ? 7 :
50
                                       (MAX_CMDS <= 256) ? 8 :
51
                                       (MAX_CMDS <= 512) ? 9 : 0; //0 is ilegal
52
 
53
 
54
   input                               clk;
55
   input                               reset;
56
 
57
   port                                GROUP_STUB_AXI;
58
 
59
   output                              idle;
60
   output                              scrbrd_empty;
61
 
62
 
63
 
64
   //random parameters   
65
   integer                             GROUP_AXI_MASTER_RAND = GROUP_AXI_MASTER_RAND.DEFAULT;
66
 
67
   reg                                 AWVALID_pre;
68
   reg                                 WVALID_pre;
69
   wire                                BREADY_pre;
70
   reg                                 ARVALID_pre;
71
   wire                                RREADY_pre;
72
 
73
   reg                                 enable = 0;
74
   reg                                 rd_enable = 0;
75
   reg                                 wr_enable = 0;
76
   reg                                 wait_for_write = 0;
77 14 eyalhoc
   reg                                 err_on_wr_resp = 1;
78
   reg                                 err_on_rd_resp = 1;
79 6 eyalhoc
 
80
   reg                                 scrbrd_enable = 0;
81
   reg [LEN_BITS-1:0]                   wvalid_cnt;
82
 
83
   reg                                 rd_cmd_push = 0;
84
   wire                                rd_cmd_pop;
85
   wire [PEND_BITS:0]                  rd_cmd_fullness;
86
   wire                                rd_cmd_empty;
87
   wire                                rd_cmd_full;
88
   reg [ADDR_BITS-1:0]                  rd_cmd_addr_in;
89
   reg [LEN_BITS-1:0]                   rd_cmd_len_in;
90
   reg [SIZE_BITS-1:0]                  rd_cmd_size_in;
91
   wire [ADDR_BITS-1:0]         rd_cmd_addr;
92
   wire [LEN_BITS-1:0]                  rd_cmd_len;
93
   wire [SIZE_BITS-1:0]         rd_cmd_size;
94
 
95
   reg                                 rd_resp_push = 0;
96
   wire                                rd_resp_pop;
97
   wire                                rd_resp_empty;
98
   wire                                rd_resp_full;
99
   reg [ADDR_BITS-1:0]                  rd_resp_addr_in;
100
   reg [SIZE_BITS-1:0]                  rd_resp_size_in;
101
   wire [ADDR_BITS-1:0]         rd_resp_addr;
102
   wire [SIZE_BITS-1:0]         rd_resp_size;
103
 
104
   reg                                 wr_cmd_push = 0;
105
   wire                                wr_cmd_pop;
106
   wire [PEND_BITS:0]                  wr_cmd_fullness;
107
   wire                                wr_cmd_empty;
108
   wire                                wr_cmd_full;
109
   reg [ADDR_BITS-1:0]                  wr_cmd_addr_in;
110
   reg [LEN_BITS-1:0]                   wr_cmd_len_in;
111
   reg [SIZE_BITS-1:0]                  wr_cmd_size_in;
112
   wire [ADDR_BITS-1:0]         wr_cmd_addr;
113
   wire [LEN_BITS-1:0]                  wr_cmd_len;
114
   wire [SIZE_BITS-1:0]         wr_cmd_size;
115
 
116
   reg                                 wr_data_push = 0;
117
   wire                                wr_data_pop;
118
   wire [PEND_BITS:0]                  wr_data_fullness;
119
   wire                                wr_data_empty;
120
   wire                                wr_data_full;
121
   reg [ADDR_BITS-1:0]                  wr_data_addr_in;
122
   reg [LEN_BITS-1:0]                   wr_data_len_in;
123
   reg [SIZE_BITS-1:0]                  wr_data_size_in;
124
   wire [ADDR_BITS-1:0]         wr_data_addr;
125
   wire [LEN_BITS-1:0]                  wr_data_len;
126
   wire [SIZE_BITS-1:0]         wr_data_size;
127
   wire [DATA_BITS/8-1:0]               wr_data_strb;
128
   wire [7:0]                           wr_data_bytes;
129
   wire [ADDR_BITS-1:0]         wr_data_addr_prog;
130
   wire [7:0]                           wr_data_offset;
131
 
132
   wire                                wr_resp_push;
133
   reg                                 wr_resp_pop = 0;
134
   wire                                wr_resp_empty;
135
   wire                                wr_resp_full;
136
   wire [1:0]                          wr_resp_resp_in;
137
   wire [1:0]                          wr_resp_resp;
138
 
139
   reg                                 wr_fifo_push = 0;
140
   wire                                wr_fifo_pop;
141
   wire                                wr_fifo_empty;
142
   wire                                wr_fifo_full;
143
   reg [DATA_BITS-1:0]                 wr_fifo_data_in;
144
   wire [DATA_BITS-1:0]                wr_fifo_data;
145
 
146
   wire                                rd_fifo_push;
147
   reg                                 rd_fifo_pop = 0;
148
   wire                                rd_fifo_empty;
149
   wire                                rd_fifo_full;
150
   wire [DATA_BITS-1:0]                rd_fifo_data_in;
151
   wire [1:0]                          rd_fifo_resp_in;
152
   wire [DATA_BITS-1:0]                rd_fifo_data;
153
   wire [1:0]                          rd_fifo_resp;
154
 
155
   reg                                 scrbrd_push = 0;
156
   reg                                 scrbrd_pop = 0;
157
   wire                                scrbrd_empty;
158
   wire                                scrbrd_full;
159
   reg [ADDR_BITS-1:0]                 scrbrd_addr_in;
160
   reg [DATA_BITS-1:0]                 scrbrd_data_in;
161
   reg [DATA_BITS-1:0]                 scrbrd_mask_in;
162
   wire [ADDR_BITS-1:0]                scrbrd_addr;
163
   wire [DATA_BITS-1:0]                scrbrd_data;
164
   wire [DATA_BITS-1:0]                scrbrd_mask;
165
 
166
   integer                             wr_fullness;
167
   integer                             rd_fullness;
168
   integer                             rd_completed;
169
   integer                             wr_completed;
170
   integer                             wr_pend_max = MASTER_PEND;
171
   integer                             rd_pend_max = MASTER_PEND;
172
   wire                                wr_hold;
173
   wire                                rd_hold;
174
 
175
   integer                             rand_chk_num = 0;
176
 
177
 
178
   assign                              idle = rd_cmd_empty & rd_resp_empty & wr_cmd_empty & wr_data_empty & wr_resp_empty;
179
 
180
   always @(rand_chk_num)
181
     if (rand_chk_num > 0)
182
       insert_rand_chk_loop(rand_chk_num);
183
 
184
   always @(posedge enable)
185
     begin
186
        @(posedge clk);
187
        wr_enable = 1;
188
        repeat (50) @(posedge clk);
189
        rd_enable = 1;
190
     end
191
 
192
   //for incremental data
193
   reg [DATA_BITS-1:0]                 base_data = 0;
194
   integer                             ww;
195
   initial
196
     begin
197
        ww=0;
198
        while (ww < DATA_BITS/8)
199
          begin
200
             base_data = base_data + ((MASTER_NUM + ww) << (ww*8));
201
             ww = ww + 1;
202
          end
203
     end
204
 
205
   assign         rd_cmd_pop   = ARVALID & ARREADY;
206
   assign         rd_resp_pop  = RVALID & RREADY & RLAST;
207
   assign         rd_fifo_push = RVALID & RREADY;
208
   assign         wr_cmd_pop   = AWVALID & AWREADY;
209
   assign         wr_data_pop  = WVALID & WREADY & WLAST;
210
   assign         wr_fifo_pop  = WVALID & WREADY;
211
   assign         wr_resp_push = BVALID & BREADY;
212
 
213
   assign         RREADY_pre = 1;
214
   assign         BREADY_pre = 1;
215
 
216
 
217
   always @(posedge clk or posedge reset)
218
     if (reset)
219
       AWVALID_pre <= #FFD 1'b0;
220
     else if ((wr_cmd_fullness == 1) & wr_cmd_pop)
221
       AWVALID_pre <= #FFD 1'b0;
222
     else if ((!wr_cmd_empty) & wr_enable)
223
       AWVALID_pre <= #FFD 1'b1;
224
 
225
 
226
   assign         AWADDR  = wr_cmd_addr;
227
   assign         AWLEN   = wr_cmd_len;
228
   assign         AWSIZE  = wr_cmd_size;
229 14 eyalhoc
   assign         AWID    = MASTER_ID;
230 6 eyalhoc
   assign         AWBURST = 2'd1; //INCR only
231
   assign         AWCACHE = 4'd0; //not supported
232
   assign         AWPROT  = 4'd0; //not supported
233
   assign         AWLOCK  = 2'd0; //not supported
234
 
235
   always @(posedge clk or posedge reset)
236
     if (reset)
237
       ARVALID_pre <= #FFD 1'b0;
238
     else if (((rd_cmd_fullness == 1)) & rd_cmd_pop)
239
       ARVALID_pre <= #FFD 1'b0;
240
     else if ((!rd_cmd_empty) & rd_enable)
241
       ARVALID_pre <= #FFD 1'b1;
242
 
243
   assign         ARADDR  = rd_cmd_addr;
244
   assign         ARLEN   = rd_cmd_len;
245
   assign         ARSIZE  = rd_cmd_size;
246
   assign         ARID    = MASTER_ID;
247
   assign         ARBURST = 2'd1; //INCR only
248
   assign         ARCACHE = 4'd0; //not supported
249
   assign         ARPROT  = 4'd0; //not supported
250
   assign         ARLOCK  = 2'd0; //not supported
251
 
252
   assign         rd_fifo_data_in = RDATA;
253 14 eyalhoc
   assign         rd_fifo_resp_in = RRESP;
254 6 eyalhoc
 
255
   assign         wr_data_bytes = 1'b1 << wr_data_size;
256
 
257
   assign         wr_data_strb =
258
                  wr_data_size == 'd0 ? 1'b1       :
259
                  wr_data_size == 'd1 ? 2'b11      :
260
                  wr_data_size == 'd2 ? 4'b1111    :
261
                  wr_data_size == 'd3 ? {8{1'b1}}  :
262
                  wr_data_size == 'd4 ? {16{1'b1}} : 'd0;
263
 
264
   assign         wr_data_addr_prog = wr_data_addr + (wvalid_cnt * wr_data_bytes);
265
 
266
   always @(posedge clk or posedge reset)
267
     if (reset)
268
       WVALID_pre <= #FFD 1'b0;
269
     else if ((wr_data_fullness == 1) & wr_data_pop)
270
       WVALID_pre <= #FFD 1'b0;
271
     else if ((!wr_data_empty) & wr_enable)
272
       WVALID_pre <= #FFD 1'b1;
273
 
274
 
275
   assign         wr_data_offset = wr_data_addr_prog[DATA_LOG-1:0];
276
 
277
   assign         WID   = MASTER_ID;
278
   assign         WDATA = wr_fifo_empty ? 0 : wr_fifo_data;
279
   assign         WSTRB = wr_data_strb << wr_data_offset;
280
 
281
 
282
   always @(posedge clk or posedge reset)
283
     if (reset)
284
       wvalid_cnt <= #FFD {LEN_BITS{1'b0}};
285
     else if (wr_data_pop)
286
       wvalid_cnt <= #FFD {LEN_BITS{1'b0}};
287
     else if (WVALID & WREADY)
288
       wvalid_cnt <= #FFD wvalid_cnt + 1'b1;
289
 
290
   assign         WLAST = WVALID & (wvalid_cnt == wr_data_len);
291
 
292
   assign         wr_resp_resp_in = BRESP;
293
 
294
   always @(posedge clk or posedge reset)
295
     if (reset)
296
       begin
297
          wr_fullness <= #FFD 0;
298
          rd_fullness <= #FFD 0;
299
          rd_completed <= #FFD 0;
300
          wr_completed <= #FFD 0;
301
       end
302
     else
303
       begin
304
          wr_fullness <= #FFD wr_fullness + wr_cmd_pop - wr_resp_push;
305
          rd_fullness <= #FFD rd_fullness + rd_cmd_pop - rd_resp_pop;
306
          rd_completed <= #FFD rd_completed + rd_resp_pop;
307
          wr_completed <= #FFD wr_completed + wr_resp_push;
308
       end
309
 
310
   assign         wr_hold = wr_fullness >= wr_pend_max;
311
   assign         rd_hold = (rd_fullness >= rd_pend_max) | (wait_for_write & (wr_completed <= rd_completed + rd_fullness));
312
 
313
 
314
 
315
   task insert_rd_cmd;
316
      input [ADDR_BITS-1:0]  addr;
317
      input [LEN_BITS-1:0]   len;
318
      input [SIZE_BITS-1:0]  size;
319
 
320
      begin
321
         rd_cmd_addr_in  = addr;
322
         rd_cmd_len_in   = len;
323
         rd_cmd_size_in  = size;
324
         rd_resp_addr_in = addr;
325
         rd_resp_size_in = size;
326
 
327
         if (rd_cmd_full) enable = 1; //start stub not started yet
328
 
329 10 eyalhoc
         #FFD; wait ((!rd_cmd_full) & (!rd_resp_full));
330 6 eyalhoc
         @(negedge clk); #FFD;
331
         rd_cmd_push  = 1;
332
         rd_resp_push = 1;
333
         @(posedge clk); #FFD;
334
         rd_cmd_push  = 0;
335
         rd_resp_push = 0;
336
      end
337
   endtask
338
 
339
   task insert_wr_cmd;
340
      input [ADDR_BITS-1:0]  addr;
341
      input [LEN_BITS-1:0]   len;
342
      input [SIZE_BITS-1:0]  size;
343
 
344
      begin
345
         wr_cmd_addr_in  = addr;
346
         wr_cmd_len_in   = len;
347
         wr_cmd_size_in  = size;
348
         wr_data_addr_in = addr;
349
         wr_data_len_in  = len;
350
         wr_data_size_in = size;
351
 
352
         if (wr_cmd_full) enable = 1; //start stub not started yet
353
 
354 10 eyalhoc
         #FFD; wait ((!wr_cmd_full) & (!wr_data_full));
355 6 eyalhoc
         @(negedge clk); #FFD;
356
         wr_cmd_push  = 1;
357
         wr_data_push = 1;
358
         @(posedge clk); #FFD;
359
         wr_cmd_push  = 0;
360
         wr_data_push = 0;
361
      end
362
   endtask
363
 
364
   task insert_wr_data;
365
      input [DATA_BITS-1:0]  wdata;
366
 
367
      begin
368
         wr_fifo_data_in  = wdata;
369
 
370 10 eyalhoc
         #FFD; wait (!wr_fifo_full);
371 6 eyalhoc
         @(negedge clk); #FFD;
372
         wr_fifo_push = 1;
373
         @(posedge clk); #FFD;
374
         wr_fifo_push = 0;
375
      end
376
   endtask
377
 
378
   task insert_wr_incr_data;
379
      input [ADDR_BITS-1:0]  addr;
380
      input [LEN_BITS-1:0]   len;
381
      input [SIZE_BITS-1:0]  size;
382
 
383
      integer valid_cnt;
384
      integer wdata_cnt;
385
      reg [7:0] data_cnt;
386
      integer bytes;
387
      reg [DATA_BITS-1:0] add_data;
388
      reg [DATA_BITS-1:0] next_data;
389
      begin
390
         //insert data
391
         valid_cnt = 0;
392
         while (valid_cnt <= len)
393
           begin
394
              bytes = 1'b1 << size;
395
              wdata_cnt = valid_cnt+(addr[DATA_LOG-1:0]/bytes);
396
              data_cnt  = ((wdata_cnt)/(DATA_BITS/(bytes*8))) * (DATA_BITS/8);
397
              add_data  = {DATA_BITS/8{data_cnt}};
398
              next_data = (use_addr_base ? addr : base_data) + add_data;
399
              insert_wr_data(next_data);
400
              valid_cnt = valid_cnt+1;
401
           end
402
         //insert command
403
         insert_wr_cmd(addr, len, size);
404
      end
405
   endtask
406
 
407
   task insert_scrbrd;
408
      input [ADDR_BITS-1:0]  addr;
409
      input [DATA_BITS-1:0]  data;
410
      input [DATA_BITS-1:0]  mask;
411
      begin
412
         scrbrd_enable = 1;
413
         scrbrd_addr_in  = addr;
414
         scrbrd_data_in  = data;
415
         scrbrd_mask_in  = mask;
416
 
417 10 eyalhoc
         #FFD; wait (!scrbrd_full);
418 6 eyalhoc
         @(negedge clk); #FFD;
419
         scrbrd_push = 1;
420
         @(posedge clk); #FFD;
421
         scrbrd_push = 0;
422
      end
423
   endtask
424
 
425
   task insert_scrbrd_incr_data;
426
      input [ADDR_BITS-1:0]  addr;
427
      input [LEN_BITS-1:0]   len;
428
      input [SIZE_BITS-1:0]  size;
429
 
430
      integer valid_cnt;
431
      integer wdata_cnt;
432
      reg [7:0] data_cnt;
433
      integer bytes;
434
      reg [DATA_BITS-1:0] add_data;
435
      reg [DATA_BITS-1:0] next_data;
436
      reg [DATA_BITS:0] strb;
437
      reg [DATA_BITS-1:0] mask;
438
      reg [ADDR_BITS-1:0] next_addr;
439
      begin
440
         valid_cnt = 0;
441
         while (valid_cnt <= len)
442
           begin
443
              bytes = 1'b1 << size;
444
              wdata_cnt = valid_cnt+(addr[DATA_LOG-1:0]/bytes);
445
              data_cnt  = ((wdata_cnt)/(DATA_BITS/(bytes*8))) * (DATA_BITS/8);
446
              add_data  = {DATA_BITS/8{data_cnt}};
447
              next_data = (use_addr_base ? addr : base_data) + add_data;
448
              next_addr = addr + (bytes * valid_cnt);
449
              strb = (1 << (bytes*8)) - 1;
450
              mask = strb << (next_addr[DATA_LOG-1:0]*8);
451
              insert_scrbrd(next_addr, next_data, mask);
452
              valid_cnt = valid_cnt+1;
453
           end
454
      end
455
   endtask
456
 
457
   task insert_rd_scrbrd;
458
      input [ADDR_BITS-1:0]  addr;
459
      input [LEN_BITS-1:0]   len;
460
      input [SIZE_BITS-1:0]  size;
461
 
462
      begin
463
         insert_scrbrd_incr_data(addr, len, size);
464
         insert_rd_cmd(addr, len, size);
465
      end
466
   endtask
467
 
468
   task insert_wr_rd_scrbrd;
469
      input [ADDR_BITS-1:0]  addr;
470
      input [LEN_BITS-1:0]   len;
471
      input [SIZE_BITS-1:0]  size;
472
 
473
      begin
474
         wait_for_write=1;
475
         insert_wr_incr_data(addr, len, size);
476
         insert_rd_scrbrd(addr, len, size);
477
      end
478
   endtask
479
 
480
   task insert_wr_rd_scrbrd_rand;
481
      reg [ADDR_BITS-1:0]  addr;
482
      reg [LEN_BITS-1:0]   len;
483
      reg [SIZE_BITS-1:0]  size;
484 10 eyalhoc
 
485 18 eyalhoc
      integer size_bytes;
486
      integer burst_bytes;
487 6 eyalhoc
      begin
488 10 eyalhoc
         if (DATA_BITS==32) size_max = 2'b10;
489 6 eyalhoc
         len   = rand(len_min, len_max);
490
         size  = rand(size_min, size_max);
491 18 eyalhoc
         size_bytes  = 1 << size;
492
         burst_bytes = size_bytes * (len+1);
493
         addr  = rand_align(addr_min, addr_max, size_bytes);
494
         if (addr[11:0] + burst_bytes > 16'h1000) //don't cross 4KByte page
495
           begin
496
              addr = addr - burst_bytes;
497
           end
498 10 eyalhoc
 
499
         if (ahb_bursts)
500
           begin
501
              len   =
502
                      len[3] ? 15 :
503
                      len[2] ? 7 :
504
                      len[1] ? 3 : 0;
505
              if (len > 0)
506
                size = (DATA_BITS == 64) ? 2'b11 : 2'b10; //AHB bursts always full data
507
 
508
              addr = align(addr, EXPR(DATA_BITS/8)*(len+1)); //address aligned to burst size
509
           end
510 6 eyalhoc
         insert_wr_rd_scrbrd(addr, len, size);
511
      end
512
   endtask
513
 
514
   task insert_rand_chk;
515
      input [31:0]  num;
516
 
517
      rand_chk_num = num;
518
   endtask
519
 
520
   task insert_rand_chk_loop;
521
      input [31:0]  num;
522
 
523
      integer i;
524
      begin
525
         i = 0;
526
         while (i < num)
527
           begin
528
              insert_wr_rd_scrbrd_rand;
529
              i = i + 1;
530
           end
531
      end
532
   endtask
533
 
534
   task insert_wr_single;
535
      input [ADDR_BITS-1:0]  addr;
536
      input [DATA_BITS-1:0]  wdata;
537
 
538
      reg [SIZE_BITS-1:0] size;
539
      begin
540
         size = EXPR((DATA_BITS/32)+1);
541
         insert_wr_data(wdata);
542
         insert_wr_cmd(addr, 0, size);
543
      end
544
   endtask
545
 
546
   task get_rd_resp;
547
      output [DATA_BITS-1:0] rdata;
548
      output [1:0] resp;
549
 
550
      reg [DATA_BITS-1:0] rdata;
551
      reg [1:0] resp;
552
      begin
553 10 eyalhoc
         #FFD; wait (!rd_fifo_empty);
554 6 eyalhoc
         rdata = rd_fifo_data;
555
         resp = rd_fifo_resp;
556
         @(negedge clk); #FFD;
557
         rd_fifo_pop = 1;
558
         @(posedge clk); #FFD;
559
         rd_fifo_pop = 0;
560 14 eyalhoc
         if ((resp != 2'b00) && (err_on_rd_resp))
561
           $display("PREFIX_MASTER%0d: RRESP_ERROR: Received RRESP 2'b%0b.\tTime: %0d ns.", MASTER_NUM, resp, $time);
562 6 eyalhoc
      end
563
   endtask
564
 
565
   task get_scrbrd;
566
      output [ADDR_BITS-1:0] addr;
567
      output [DATA_BITS-1:0] rdata;
568
      output [DATA_BITS-1:0] mask;
569
 
570
      reg [ADDR_BITS-1:0] addr;
571
      reg [DATA_BITS-1:0] rdata;
572
      reg [DATA_BITS-1:0] mask;
573
      begin
574 10 eyalhoc
         #FFD; wait (!scrbrd_empty);
575 6 eyalhoc
         addr = scrbrd_addr;
576
         rdata = scrbrd_data;
577
         mask = scrbrd_mask;
578
         @(negedge clk); #FFD;
579
         scrbrd_pop = 1;
580
         @(posedge clk); #FFD;
581
         scrbrd_pop = 0;
582
      end
583
   endtask
584
 
585
   task get_wr_resp;
586
      output [1:0] resp;
587
 
588
      reg [1:0] resp;
589
      begin
590 10 eyalhoc
         #FFD; wait (!wr_resp_empty);
591 6 eyalhoc
         resp = wr_resp_resp;
592
         @(negedge clk); #FFD;
593
         wr_resp_pop = 1;
594
         @(posedge clk); #FFD;
595
         wr_resp_pop = 0;
596 14 eyalhoc
         if ((resp != 2'b00) && (err_on_wr_resp))
597
           $display("PREFIX_MASTER%0d: BRESP_ERROR: Received BRESP 2'b%0b.\tTime: %0d ns.", MASTER_NUM, resp, $time);
598 6 eyalhoc
      end
599
   endtask
600
 
601
   task insert_rd_single;
602
      input [ADDR_BITS-1:0]  addr;
603
 
604
      reg [SIZE_BITS-1:0] size;
605
      begin
606
         size = EXPR((DATA_BITS/32)+1);
607
         insert_rd_cmd(addr, 0, size);
608
      end
609
   endtask
610
 
611
   task read_single_ack;
612
      input [ADDR_BITS-1:0]  addr;
613
      output [DATA_BITS-1:0] rdata;
614
      output [1:0]           resp;
615
 
616
      reg [1:0] resp;
617
      begin
618
         insert_rd_single(addr);
619
         get_rd_resp(rdata, resp);
620
      end
621
   endtask
622
 
623
   task write_single_ack;
624
      input [ADDR_BITS-1:0]  addr;
625
      input [DATA_BITS-1:0]  wdata;
626
      output [1:0]           resp;
627
 
628
      reg [1:0] resp;
629
      begin
630
         insert_wr_single(addr, wdata);
631
         get_wr_resp(resp);
632
      end
633
   endtask
634
 
635
   task read_single;
636
      input [ADDR_BITS-1:0]  addr;
637
      output [DATA_BITS-1:0] rdata;
638
 
639
      reg [1:0] resp;
640
      begin
641
         read_single_ack(addr, rdata, resp);
642
      end
643
   endtask
644
 
645
   task check_single;
646
      input [ADDR_BITS-1:0]  addr;
647
      input [DATA_BITS-1:0]  expected;
648
 
649
      reg [1:0] resp;
650
      reg [DATA_BITS-1:0] rdata;
651
      begin
652
         read_single_ack(addr, rdata, resp);
653
         if (rdata !== expected)
654 14 eyalhoc
           $display("PREFIX_MASTER%0d: CHK_SINGLE_ERROR: Address: 0x%0h, Expected: 0x%0h, Received: 0x%0h.\tTime: %0d ns.", MASTER_NUM, addr, expected, rdata, $time);
655 6 eyalhoc
      end
656
   endtask
657
 
658
   task write_and_check_single;
659
      input [ADDR_BITS-1:0]  addr;
660
      input [DATA_BITS-1:0]  data;
661
 
662
      begin
663
         write_single(addr, data);
664
         check_single(addr, data);
665
      end
666
   endtask
667
 
668
   task write_single;
669
      input [ADDR_BITS-1:0]  addr;
670
      input [DATA_BITS-1:0]  wdata;
671
 
672
      reg [1:0] resp;
673
      begin
674
         write_single_ack(addr, wdata, resp);
675
      end
676
   endtask
677
 
678
   task chk_scrbrd;
679
      reg [ADDR_BITS-1:0] addr;
680
      reg [DATA_BITS-1:0] mask;
681
      reg [DATA_BITS-1:0] expected_data;
682
      reg [DATA_BITS-1:0] rdata;
683
      reg [DATA_BITS-1:0] rdata_masked;
684
      reg [1:0] resp;
685
 
686
      begin
687
         if (!wr_resp_empty) get_wr_resp(resp);
688
         get_scrbrd(addr, expected_data, mask);
689
         get_rd_resp(rdata, resp);
690
         expected_data = expected_data & mask; //TBD insert z as dontcare (for print)
691
         rdata_masked = rdata & mask;
692
 
693
         if (expected_data !== rdata_masked)
694 14 eyalhoc
           $display("PREFIX_MASTER%0d: SCRBRD_ERROR: Address: 0x%0h, Expected: 0x%0h, Received: 0x%0h.\tTime: %0d ns.", MASTER_NUM, addr, expected_data, rdata, $time);
695 6 eyalhoc
      end
696
   endtask
697
 
698
   always @(posedge scrbrd_enable)
699
     begin
700
        while (scrbrd_enable)
701
          begin
702
             chk_scrbrd;
703
          end
704
     end
705
 
706
 
707
CREATE prgen_fifo.v DEFCMD(DEFINE STUB)
708
   prgen_fifo_stub #(ADDR_BITS+LEN_BITS+SIZE_BITS, MAX_CMDS)
709
   rd_cmd_list(
710
               .clk(clk),
711
               .reset(reset),
712
               .push(rd_cmd_push),
713
               .pop(rd_cmd_pop),
714
               .din({
715
                     rd_cmd_size_in,
716
                     rd_cmd_len_in,
717
                     rd_cmd_addr_in
718
                     }),
719
               .dout({
720
                      rd_cmd_size,
721
                      rd_cmd_len,
722
                      rd_cmd_addr
723
                      }),
724
               .fullness(rd_cmd_fullness),
725
               .empty(rd_cmd_empty),
726
               .full(rd_cmd_full)
727
               );
728
 
729
   prgen_fifo_stub #(ADDR_BITS+SIZE_BITS, MAX_CMDS)
730
   rd_resp_list(
731
                .clk(clk),
732
                .reset(reset),
733
                .push(rd_resp_push),
734
                .pop(rd_resp_pop),
735
                .din({
736
                      rd_resp_addr_in,
737
                      rd_resp_size_in
738
                      }),
739
                .dout({
740
                       rd_resp_addr,
741
                       rd_resp_size
742
                       }),
743
                .empty(rd_resp_empty),
744
                .full(rd_resp_full)
745
                );
746
 
747
   prgen_fifo_stub #(ADDR_BITS+LEN_BITS+SIZE_BITS, MAX_CMDS)
748
   wr_cmd_list(
749
               .clk(clk),
750
               .reset(reset),
751
               .push(wr_cmd_push),
752
               .pop(wr_cmd_pop),
753
               .din({
754
                     wr_cmd_size_in,
755
                     wr_cmd_len_in,
756
                     wr_cmd_addr_in
757
                     }),
758
               .dout({
759
                      wr_cmd_size,
760
                      wr_cmd_len,
761
                      wr_cmd_addr
762
                      }),
763
               .fullness(wr_cmd_fullness),
764
               .empty(wr_cmd_empty),
765
               .full(wr_cmd_full)
766
               );
767
 
768
   prgen_fifo_stub #(ADDR_BITS+LEN_BITS+SIZE_BITS, MAX_CMDS)
769
   wr_data_list(
770
                .clk(clk),
771
                .reset(reset),
772
                .push(wr_data_push),
773
                .pop(wr_data_pop),
774
                .din({
775
                      wr_data_size_in,
776
                      wr_data_len_in,
777
                      wr_data_addr_in
778
                      }),
779
                .dout({
780
                       wr_data_size,
781
                       wr_data_len,
782
                       wr_data_addr
783
                       }),
784
                .fullness(wr_data_fullness),
785
                .empty(wr_data_empty),
786
                .full(wr_data_full)
787
                );
788
 
789
   prgen_fifo_stub #(2, MAX_CMDS)
790
   wr_resp_list(
791
                .clk(clk),
792
                .reset(reset),
793
                .push(wr_resp_push),
794
                .pop(wr_resp_pop),
795
                .din(wr_resp_resp_in),
796
                .dout(wr_resp_resp),
797
                .empty(wr_resp_empty),
798
                .full(wr_resp_full)
799
                );
800
 
801
 
802
   prgen_fifo_stub #(DATA_BITS, MAX_CMDS*EXPR(2^LEN_BITS))
803
   wr_data_fifo(
804
                .clk(clk),
805
                .reset(reset),
806
                .push(wr_fifo_push),
807
                .pop(wr_fifo_pop),
808
                .din(wr_fifo_data_in),
809
                .dout(wr_fifo_data),
810
                .empty(wr_fifo_empty),
811
                .full(wr_fifo_full)
812
                );
813
 
814
   prgen_fifo_stub #(DATA_BITS+2, MAX_CMDS*EXPR(2^LEN_BITS))
815
   rd_data_fifo(
816
                .clk(clk),
817
                .reset(reset),
818
                .push(rd_fifo_push),
819
                .pop(rd_fifo_pop),
820
                .din({
821
                      rd_fifo_data_in,
822
                      rd_fifo_resp_in
823
                      }),
824
                .dout({
825
                       rd_fifo_data,
826
                       rd_fifo_resp
827
                       }),
828
                .empty(rd_fifo_empty),
829
                .full(rd_fifo_full)
830
                );
831
 
832
   prgen_fifo_stub #(ADDR_BITS+2*DATA_BITS, MAX_CMDS*EXPR(2^LEN_BITS))
833
   scrbrd_fifo(
834
                .clk(clk),
835
                .reset(reset),
836
                .push(scrbrd_push),
837
                .pop(scrbrd_pop),
838
               .din({
839
                     scrbrd_addr_in,
840
                     scrbrd_data_in,
841
                     scrbrd_mask_in
842
                     }),
843
                .dout({
844
                       scrbrd_addr,
845
                       scrbrd_data,
846
                       scrbrd_mask
847
                       }),
848
                .empty(scrbrd_empty),
849
                .full(scrbrd_full)
850
                );
851
 
852
 
853
CREATE axi_master_stall.v
854
   PREFIX_stall
855
     PREFIX_stall (
856 18 eyalhoc
                   .clk(clk),
857
                   .reset(reset),
858 6 eyalhoc
 
859 18 eyalhoc
                   .rd_hold(rd_hold),
860
                   .wr_hold(wr_hold),
861
 
862
                   .ARVALID_pre(ARVALID_pre),
863
                   .RREADY_pre(RREADY_pre),
864
                   .AWVALID_pre(AWVALID_pre),
865
                   .WVALID_pre(WVALID_pre),
866
                   .BREADY_pre(BREADY_pre),
867
 
868
                   .ARREADY(ARREADY),
869
                   .AWREADY(AWREADY),
870
                   .WREADY(WREADY),
871
 
872
                   .ARVALID(ARVALID),
873
                   .RREADY(RREADY),
874
                   .AWVALID(AWVALID),
875
                   .WVALID(WVALID),
876
                   .BREADY(BREADY)
877
                   );
878 6 eyalhoc
 
879
 
880
endmodule
881
 
882
 

powered by: WebSVN 2.1.0

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