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

Subversion Repositories wb2axip

[/] [wb2axip/] [trunk/] [bench/] [formal/] [faxi_master.v] - Blame information for rev 13

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

Line No. Rev Author Line
1 10 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    faxi_master.v (Formal properties of an AXI master)
4
//
5
// Project:     Pipelined Wishbone to AXI converter
6
//
7
// Purpose:
8
//
9
// Creator:     Dan Gisselquist, Ph.D.
10
//              Gisselquist Technology, LLC
11
//
12
////////////////////////////////////////////////////////////////////////////////
13
//
14
// Copyright (C) 2017, Gisselquist Technology, LLC
15
//
16
// This program is free software (firmware): you can redistribute it and/or
17
// modify it under the terms of  the GNU General Public License as published
18
// by the Free Software Foundation, either version 3 of the License, or (at
19
// your option) any later version.
20
//
21
// This program is distributed in the hope that it will be useful, but WITHOUT
22
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
23
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
24
// for more details.
25
//
26
// You should have received a copy of the GNU General Public License along
27
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
28
// target there if the PDF file isn't present.)  If not, see
29
// <http://www.gnu.org/licenses/> for a copy.
30
//
31
// License:     GPL, v3, as defined and found on www.gnu.org,
32
//              http://www.gnu.org/licenses/gpl.html
33
//
34
//
35
////////////////////////////////////////////////////////////////////////////////
36
//
37
//
38
`default_nettype        none
39
//
40
module faxi_master #(
41
        parameter C_AXI_ID_WIDTH        = 3, // The AXI id width used for R&W
42
                                             // This is an int between 1-16
43
        parameter C_AXI_DATA_WIDTH      = 128,// Width of the AXI R&W data
44
        parameter C_AXI_ADDR_WIDTH      = 28,   // AXI Address width (log wordsize)
45
        localparam DW                   = C_AXI_DATA_WIDTH,
46
        localparam AW                   = C_AXI_ADDR_WIDTH,
47
        parameter       [(C_AXI_ID_WIDTH-1):0]   F_AXI_MAXSTALL = 3,
48
        parameter       [(C_AXI_ID_WIDTH-1):0]   F_AXI_MAXDELAY = 3,
49
        parameter [0:0] F_STRICT_ORDER    = 0,     // Reorder, or not? 0 -> Reorder
50
        parameter [0:0] F_CONSECUTIVE_IDS= 0,      // 0=ID's must be consecutive
51
        parameter [0:0] F_OPT_BURSTS    = 1'b1,   // Check burst lengths
52
        parameter [0:0] F_CHECK_IDS       = 1'b1  // Check ID's upon issue&return
53
        ) (
54
        input                           i_clk,  // System clock
55
        input                           i_axi_reset_n,
56
 
57
// AXI write address channel signals
58
        input                           i_axi_awready, // Slave is ready to accept
59
        input   wire    [C_AXI_ID_WIDTH-1:0]     i_axi_awid,     // Write ID
60
        input   wire    [AW-1:0] i_axi_awaddr,   // Write address
61
        input   wire    [7:0]            i_axi_awlen,    // Write Burst Length
62
        input   wire    [2:0]            i_axi_awsize,   // Write Burst size
63
        input   wire    [1:0]            i_axi_awburst,  // Write Burst type
64
        input   wire    [0:0]             i_axi_awlock,   // Write lock type
65
        input   wire    [3:0]            i_axi_awcache,  // Write Cache type
66
        input   wire    [2:0]            i_axi_awprot,   // Write Protection type
67
        input   wire    [3:0]            i_axi_awqos,    // Write Quality of Svc
68
        input   wire                    i_axi_awvalid,  // Write address valid
69
 
70
// AXI write data channel signals
71
        input   wire                    i_axi_wready,  // Write data ready
72
        input   wire    [DW-1:0] i_axi_wdata,    // Write data
73
        input   wire    [DW/8-1:0]       i_axi_wstrb,    // Write strobes
74
        input   wire                    i_axi_wlast,    // Last write transaction
75
        input   wire                    i_axi_wvalid,   // Write valid
76
 
77
// AXI write response channel signals
78
        input   wire [C_AXI_ID_WIDTH-1:0] i_axi_bid,     // Response ID
79
        input   wire [1:0]               i_axi_bresp,    // Write response
80
        input   wire                    i_axi_bvalid,  // Write reponse valid
81
        input   wire                    i_axi_bready,  // Response ready
82
 
83
// AXI read address channel signals
84
        input   wire                    i_axi_arready,  // Read address ready
85
        input   wire    [C_AXI_ID_WIDTH-1:0]     i_axi_arid,     // Read ID
86
        input   wire    [AW-1:0] i_axi_araddr,   // Read address
87
        input   wire    [7:0]            i_axi_arlen,    // Read Burst Length
88
        input   wire    [2:0]            i_axi_arsize,   // Read Burst size
89
        input   wire    [1:0]            i_axi_arburst,  // Read Burst type
90
        input   wire    [0:0]             i_axi_arlock,   // Read lock type
91
        input   wire    [3:0]            i_axi_arcache,  // Read Cache type
92
        input   wire    [2:0]            i_axi_arprot,   // Read Protection type
93
        input   wire    [3:0]            i_axi_arqos,    // Read Protection type
94
        input   wire                    i_axi_arvalid,  // Read address valid
95
 
96
// AXI read data channel signals
97
        input   wire [C_AXI_ID_WIDTH-1:0] i_axi_rid,     // Response ID
98
        input   wire [1:0]               i_axi_rresp,   // Read response
99
        input   wire                    i_axi_rvalid,  // Read reponse valid
100
        input   wire [DW-1:0]            i_axi_rdata,    // Read data
101
        input   wire                    i_axi_rlast,    // Read last
102
        input   wire                    i_axi_rready,  // Read Response ready
103
        //
104
        output  reg     [(C_AXI_ID_WIDTH-1):0]   f_axi_rd_outstanding,
105
        output  reg     [(C_AXI_ID_WIDTH-1):0]   f_axi_wr_outstanding,
106
        output  reg     [(C_AXI_ID_WIDTH-1):0]   f_axi_awr_outstanding,
107
        output  reg [((1<<C_AXI_ID_WIDTH)-1):0]  f_axi_rd_id_outstanding,
108
        output  reg [((1<<C_AXI_ID_WIDTH)-1):0]  f_axi_awr_id_outstanding,
109
        output  reg [((1<<C_AXI_ID_WIDTH)-1):0]  f_axi_wr_id_outstanding
110
 
111
);
112
        reg [((1<<C_AXI_ID_WIDTH)-1):0]  f_axi_wr_id_complete;
113
 
114
//*****************************************************************************
115
// Parameter declarations
116
//*****************************************************************************
117
 
118
        localparam      LG_AXI_DW       = ( C_AXI_DATA_WIDTH ==   8) ? 3
119
                                        : ((C_AXI_DATA_WIDTH ==  16) ? 4
120
                                        : ((C_AXI_DATA_WIDTH ==  32) ? 5
121
                                        : ((C_AXI_DATA_WIDTH ==  64) ? 6
122
                                        : ((C_AXI_DATA_WIDTH == 128) ? 7
123
                                        : 8))));
124
 
125
        localparam      LG_WB_DW        = ( DW ==   8) ? 3
126
                                        : ((DW ==  16) ? 4
127
                                        : ((DW ==  32) ? 5
128
                                        : ((DW ==  64) ? 6
129
                                        : ((DW == 128) ? 7
130
                                        : 8))));
131
        localparam      LGFIFOLN = C_AXI_ID_WIDTH;
132
        localparam      FIFOLN = (1<<LGFIFOLN);
133
 
134
 
135
//*****************************************************************************
136
// Internal register and wire declarations
137
//*****************************************************************************
138
 
139
// Things we're not changing ...
140
        always @(*)
141
        begin
142
        assert(i_axi_awlen   == 8'h0);  // Burst length is one
143
        assert(i_axi_awsize  == 3'b101);        // maximum bytes per burst is 32
144
        assert(i_axi_awburst == 2'b01); // Incrementing address (ignored)
145
        assert(i_axi_arburst == 2'b01); // Incrementing address (ignored)
146
        assert(i_axi_awlock  == 1'b0);  // Normal signaling
147
        assert(i_axi_arlock  == 1'b0);  // Normal signaling
148
        assert(i_axi_awcache == 4'h2);  // Normal: no cache, no buffer
149
        assert(i_axi_arcache == 4'h2);  // Normal: no cache, no buffer
150
        assert(i_axi_awprot  == 3'b010);// Unpriviledged, unsecure, data access
151
        assert(i_axi_arprot  == 3'b010);// Unpriviledged, unsecure, data access
152
        assert(i_axi_awqos   == 4'h0);  // Lowest quality of service (unused)
153
        assert(i_axi_arqos   == 4'h0);  // Lowest quality of service (unused)
154
        end
155
 
156
        // wire w_fifo_full;
157
        wire    axi_rd_ack, axi_wr_ack, axi_ard_req, axi_awr_req, axi_wr_req,
158
                axi_rd_err, axi_wr_err;
159
        //
160
        assign  axi_ard_req = (i_axi_arvalid)&&(i_axi_arready);
161
        assign  axi_awr_req = (i_axi_awvalid)&&(i_axi_awready);
162
        assign  axi_wr_req  = (i_axi_wvalid )&&(i_axi_wready);
163
        //
164
        assign  axi_rd_ack = (i_axi_rvalid)&&(i_axi_rready);
165
        assign  axi_wr_ack = (i_axi_bvalid)&&(i_axi_bready);
166
        assign  axi_rd_err = (axi_rd_ack)&&(i_axi_rresp[1]);
167
        assign  axi_wr_err = (axi_wr_ack)&&(i_axi_bresp[1]);
168
 
169
        //
170
        // Setup
171
        //
172
        reg     f_past_valid;
173
        integer k;
174
 
175
        initial f_past_valid = 1'b0;
176
        always @(posedge i_clk)
177
                f_past_valid <= 1'b1;
178
        always @(*)
179
                if (!f_past_valid)
180
                        assert(!i_axi_reset_n);
181
 
182
        //
183
        // All signals must be synchronous with the clock
184
        //
185
        always @($global_clock)
186
        if (f_past_valid) begin
187
                // Assume our inputs will only change on the positive edge
188
                // of the clock
189
                if (!$rose(i_clk))
190
                begin
191
                        // AXI inputs
192
                        assume($stable(i_axi_awready));
193
                        assume($stable(i_axi_wready));
194
                        //
195
                        assume($stable(i_axi_bid));
196
                        assume($stable(i_axi_bresp));
197
                        assume($stable(i_axi_bvalid));
198
                        assume($stable(i_axi_arready));
199
                        //
200
                        assume($stable(i_axi_rid));
201
                        assume($stable(i_axi_rresp));
202
                        assume($stable(i_axi_rvalid));
203
                        assume($stable(i_axi_rdata));
204
                        assume($stable(i_axi_rlast));
205
                        //
206
                        // AXI outputs
207
                        //
208
                        assert($stable(i_axi_awvalid));
209
                        assert($stable(i_axi_awid));
210
                        assert($stable(i_axi_awlen));
211
                        assert($stable(i_axi_awsize));
212
                        assert($stable(i_axi_awlock));
213
                        assert($stable(i_axi_awcache));
214
                        assert($stable(i_axi_awprot));
215
                        assert($stable(i_axi_awqos));
216
                        //
217
                        assert($stable(i_axi_wvalid));
218
                        assert($stable(i_axi_wdata));
219
                        assert($stable(i_axi_wstrb));
220
                        assert($stable(i_axi_wlast));
221
                        //
222
                        assert($stable(i_axi_arvalid));
223
                        assert($stable(i_axi_arid));
224
                        assert($stable(i_axi_arlen));
225
                        assert($stable(i_axi_arsize));
226
                        assert($stable(i_axi_arburst));
227
                        assert($stable(i_axi_arlock));
228
                        assert($stable(i_axi_arprot));
229
                        assert($stable(i_axi_arqos));
230
                        //
231
                        assert($stable(i_axi_bready));
232
                        //
233
                        assert($stable(i_axi_rready));
234
                        //
235
                        // Formal outputs
236
                        //
237
                        assert($stable(f_axi_rd_outstanding));
238
                        assert($stable(f_axi_wr_outstanding));
239
                        assert($stable(f_axi_awr_outstanding));
240
                end
241
        end
242
 
243
        ////////////////////////////////////////////////////
244
        //
245
        //
246
        // Reset properties
247
        //
248
        //
249
        ////////////////////////////////////////////////////
250
 
251
        always @(posedge i_clk)
252
        if ((f_past_valid)&&(!$past(i_axi_reset_n)))
253
        begin
254
                assert(!i_axi_arvalid);
255
                assert(!i_axi_awvalid);
256
                assert(!i_axi_wvalid);
257
                assume(!i_axi_bvalid);
258
                assume(!i_axi_rvalid);
259
        end
260
 
261
        ////////////////////////////////////////////////////
262
        //
263
        //
264
        // Stability assumptions, AXI inputs/responses
265
        //
266
        //
267
        ////////////////////////////////////////////////////
268
 
269
        // Assume any response from the bus will not change prior to that
270
        // response being accepted
271
        always @(posedge i_clk)
272
        if (f_past_valid)
273
        begin
274
                if ((f_past_valid)&&($past(i_axi_rvalid))&&(!$past(i_axi_rready)))
275
                begin
276
                        assume(i_axi_rid    == $past(i_axi_rid));
277
                        assume(i_axi_rresp  == $past(i_axi_rresp));
278
                        assume(i_axi_rdata  == $past(i_axi_rdata));
279
                        assume(i_axi_rlast  == $past(i_axi_rlast));
280
                end
281
 
282
                if ((f_past_valid)&&($past(i_axi_bvalid))&&(!$past(i_axi_bready)))
283
                begin
284
                        assume(i_axi_bid    == $past(i_axi_bid));
285
                        assume(i_axi_bresp  == $past(i_axi_bresp));
286
                end
287
        end
288
 
289
        // Nothing should be returning a result on the first clock
290
        initial assume(!i_axi_bvalid);
291
        initial assume(!i_axi_rvalid);
292
        //
293
        initial assert(!i_axi_arvalid);
294
        initial assert(!i_axi_awvalid);
295
        initial assert(!i_axi_wvalid);
296
 
297
        //////////////////////////////////////////////
298
        //
299
        //
300
        // Stability assumptions, AXI outputs/requests
301
        //
302
        //
303
        //////////////////////////////////////////////
304
 
305
        // Read address chanel
306
        always @(posedge i_clk)
307
        if ((f_past_valid)&&($past(i_axi_arvalid))&&(!$past(i_axi_arready)))
308
        begin
309
                assert(i_axi_arvalid);
310
                assert($stable(i_axi_arid));
311
                assert($stable(i_axi_araddr));
312
                assert($stable(i_axi_arlen));
313
                assert($stable(i_axi_arsize));
314
                assert($stable(i_axi_arburst));
315
                assert($stable(i_axi_arlock));
316
                assert($stable(i_axi_arcache));
317
                assert($stable(i_axi_arprot));
318
                assert($stable(i_axi_arqos));
319
                assert($stable(i_axi_arvalid));
320
        end
321
 
322
        // If valid, but not ready, on any channel is true, nothing changes
323
        // until valid && ready
324
        always @(posedge i_clk)
325
        if ((f_past_valid)&&($past(i_axi_awvalid))&&(!$past(i_axi_awready)))
326
        begin
327
                assert($stable(i_axi_awid));
328
                assert($stable(i_axi_awaddr));
329
                assert($stable(i_axi_awlen));
330
                assert($stable(i_axi_awsize));
331
                assert($stable(i_axi_awburst));
332
                assert($stable(i_axi_awlock));
333
                assert($stable(i_axi_awcache));
334
                assert($stable(i_axi_awprot));
335
                assert($stable(i_axi_awqos));
336
                assert($stable(i_axi_awvalid));
337
        end
338
 
339
        always @(posedge i_clk)
340
        if ((f_past_valid)&&($past(i_axi_wvalid))&&(!$past(i_axi_wready)))
341
        begin
342
                // AXI write data channel signals
343
                assert($stable(i_axi_wdata));
344
                assert($stable(i_axi_wstrb));
345
                assert($stable(i_axi_wlast));
346
                assert($stable(i_axi_wvalid));
347
        end
348
 
349
        //
350
        //
351
 
352
        ///////////////////////////////////////////////////////////////////
353
        //
354
        //
355
        // Insist upon a maximum delay before a request is accepted
356
        //
357
        //
358
        ///////////////////////////////////////////////////////////////////
359
 
360
        //
361
        // AXI write address channel
362
        //
363
        //
364
        reg     [(C_AXI_ID_WIDTH):0]     f_axi_awstall;
365
        initial f_axi_awstall = 0;
366
        always @(posedge i_clk)
367
                if ((!i_axi_reset_n)||(!i_axi_awvalid)||(i_axi_awready))
368
                        f_axi_awstall <= 0;
369
                else
370
                        f_axi_awstall <= f_axi_awstall + 1'b1;
371
        always @(*)
372
                assume((F_AXI_MAXSTALL==0)||(f_axi_awstall < F_AXI_MAXSTALL));
373
 
374
        //
375
        // AXI write data channel
376
        //
377
        //
378
        // AXI explicitly allows write bursts with zero strobes.  This is part
379
        // of how a transaction is aborted (if at all).
380
        //always @(*) if (i_axi_wvalid) assert(|i_axi_wstrb);
381
 
382
        reg     [(C_AXI_ID_WIDTH):0]     f_axi_wstall;
383
        initial f_axi_wstall = 0;
384
        always @(posedge i_clk)
385
                if ((!i_axi_reset_n)||(!i_axi_wvalid)||(i_axi_wready))
386
                        f_axi_wstall <= 0;
387
                else
388
                        f_axi_wstall <= f_axi_wstall + 1'b1;
389
        always @(*)
390
                assume((F_AXI_MAXSTALL==0)||(f_axi_wstall < F_AXI_MAXSTALL));
391
 
392
 
393
        //
394
        // AXI read address channel
395
        //
396
        //
397
        reg     [(C_AXI_ID_WIDTH):0]     f_axi_arstall;
398
        initial f_axi_arstall = 0;
399
        always @(posedge i_clk)
400
                if ((!i_axi_reset_n)||(!i_axi_arvalid)||(i_axi_arready))
401
                        f_axi_arstall <= 0;
402
                else
403
                        f_axi_arstall <= f_axi_arstall + 1'b1;
404
        always @(*)
405
                assume((F_AXI_MAXSTALL==0)||(f_axi_arstall < F_AXI_MAXSTALL));
406
 
407
 
408
        ////////////////////////////////////////////////////////////////////////
409
        //
410
        //
411
        // Count outstanding transactions
412
        //
413
        //
414
        ////////////////////////////////////////////////////////////////////////
415
        initial f_axi_awr_outstanding = 0;
416
        always @(posedge i_clk)
417
                if (!i_axi_reset_n)
418
                        f_axi_awr_outstanding <= 0;
419
                else case({ (axi_awr_req), (axi_wr_ack) })
420
                        2'b10: f_axi_awr_outstanding <= f_axi_awr_outstanding + 1'b1;
421
                        2'b01: f_axi_awr_outstanding <= f_axi_awr_outstanding - 1'b1;
422
                        default: begin end
423
                endcase
424
 
425
        initial f_axi_wr_outstanding = 0;
426
        always @(posedge i_clk)
427
                if (!i_axi_reset_n)
428
                        f_axi_wr_outstanding <= 0;
429
                else case({ (axi_wr_req)&&(i_axi_wlast), (axi_wr_ack) })
430
                2'b01: f_axi_wr_outstanding <= f_axi_wr_outstanding - 1'b1;
431
                2'b10: f_axi_wr_outstanding <= f_axi_wr_outstanding + 1'b1;
432
                endcase
433
 
434
        initial f_axi_rd_outstanding = 0;
435
        always @(posedge i_clk)
436
                if (!i_axi_reset_n)
437
                        f_axi_rd_outstanding <= 0;
438
                else case({ (axi_ard_req), (axi_rd_ack)&&(i_axi_rlast) })
439
                2'b01: f_axi_rd_outstanding <= f_axi_rd_outstanding - 1'b1;
440
                2'b10: f_axi_rd_outstanding <= f_axi_rd_outstanding + 1'b1;
441
                endcase
442
 
443
        // Do not let the number of outstanding requests overflow
444
        always @(posedge i_clk)
445
                assert(f_axi_wr_outstanding < {(C_AXI_ID_WIDTH){1'b1}});
446
        always @(posedge i_clk)
447
                assert(f_axi_awr_outstanding < {(C_AXI_ID_WIDTH){1'b1}});
448
        always @(posedge i_clk)
449
                assert(f_axi_rd_outstanding < {(C_AXI_ID_WIDTH){1'b1}});
450
 
451
        ////////////////////////////////////////////////////////////////////////
452
        //
453
        //
454
        // Insist that all responses are returned in less than a maximum delay
455
        // In this case, we count responses within a burst, rather than entire
456
        // bursts.
457
        //
458
        //
459
        ////////////////////////////////////////////////////////////////////////
460
 
461
        reg     [(C_AXI_ID_WIDTH):0]     f_axi_wr_ack_delay,
462
                                        f_axi_awr_ack_delay,
463
                                        f_axi_rd_ack_delay;
464
 
465
        initial f_axi_rd_ack_delay = 0;
466
        always @(posedge i_clk)
467
                if ((!i_axi_reset_n)||(axi_rd_ack))
468
                        f_axi_rd_ack_delay <= 0;
469
                else if (f_axi_rd_outstanding > 0)
470
                        f_axi_rd_ack_delay <= f_axi_rd_ack_delay + 1'b1;
471
 
472
        initial f_axi_wr_ack_delay = 0;
473
        always @(posedge i_clk)
474
                if ((!i_axi_reset_n)||(axi_wr_ack))
475
                        f_axi_wr_ack_delay <= 0;
476
                else if (f_axi_wr_outstanding > 0)
477
                        f_axi_wr_ack_delay <= f_axi_wr_ack_delay + 1'b1;
478
 
479
        initial f_axi_awr_ack_delay = 0;
480
        always @(posedge i_clk)
481
                if ((!i_axi_reset_n)||(axi_wr_ack))
482
                        f_axi_awr_ack_delay <= 0;
483
                else if (f_axi_awr_outstanding > 0)
484
                        f_axi_awr_ack_delay <= f_axi_awr_ack_delay + 1'b1;
485
 
486
        always @(posedge i_clk)
487
                assume((F_AXI_MAXDELAY==0)||(f_axi_rd_ack_delay < F_AXI_MAXDELAY));
488
 
489
        always @(posedge i_clk)
490
                assume((F_AXI_MAXDELAY==0)||(f_axi_wr_ack_delay < F_AXI_MAXDELAY));
491
 
492
        always @(posedge i_clk)
493
                assume((F_AXI_MAXDELAY==0)||(f_axi_awr_ack_delay < F_AXI_MAXDELAY));
494
 
495
        ////////////////////////////////////////////////////////////////////////
496
        //
497
        //
498
        // Assume all acknowledgements must follow requests
499
        //
500
        // The outstanding count is a count of bursts, but the acknowledgements
501
        // we are looking for are individual.  Hence, there should be no
502
        // individual acknowledgements coming back if there's no outstanding
503
        // burst.
504
        //
505
        //
506
        ////////////////////////////////////////////////////////////////////////
507
 
508
        //
509
        // AXI write response channel
510
        //
511
        always @(posedge i_clk)
512
                if ((!axi_awr_req)&&(axi_wr_ack))
513
                        assume(f_axi_awr_outstanding > 0);
514
        always @(posedge i_clk)
515
                if ((!axi_wr_req)&&(axi_wr_ack))
516
                        assume(f_axi_wr_outstanding > 0);
517
 
518
        //
519
        // AXI read data channel signals
520
        //
521
        initial f_axi_rd_outstanding = 0;
522
        always @(posedge i_clk)
523
                if ((!axi_ard_req)&&(axi_rd_ack))
524
                        assume(f_axi_rd_outstanding > 0);
525
 
526
        ///////////////////////////////////////////////////////////////////
527
        //
528
        //
529
        // Manage the ID buffer.  Basic rules apply such as you can't
530
        // make a request of an already requested ID # before that ID
531
        // is returned, etc.
532
        //
533
        // Elements in this buffer reference transactions--possibly burst
534
        // transactions and not necessarily the individual values.
535
        //
536
        //
537
        /////////////////////////////////////////////////////////////////// 
538
        // Now, let's look into that FIFO.  Without it, we know nothing about
539
        // the ID's
540
 
541
        initial f_axi_rd_id_outstanding = 0;
542
        initial f_axi_wr_id_outstanding = 0;
543
        initial f_axi_awr_id_outstanding = 0;
544
        initial f_axi_wr_id_complete = 0;
545
        always @(posedge i_clk)
546
                if (!i_axi_reset_n)
547
                begin
548
                        f_axi_rd_id_outstanding <= 0;
549
                        f_axi_wr_id_outstanding <= 0;
550
                        f_axi_wr_id_complete <= 0;
551
                        f_axi_awr_id_outstanding <= 0;
552
                end else begin
553
                // When issuing a write
554
                if (axi_awr_req)
555
                begin
556
                        if ((F_CONSECUTIVE_IDS)&&(F_CHECK_IDS))
557
                                assert(f_axi_awr_id_outstanding[i_axi_awid+1'b1] == 1'b0);
558
                        assert((!F_CHECK_IDS)
559
                                ||(f_axi_awr_id_outstanding[i_axi_awid] == 1'b0));
560
                        assert((!F_CHECK_IDS)
561
                                ||(f_axi_wr_id_complete[i_axi_awid] == 1'b0));
562
                        f_axi_awr_id_outstanding[i_axi_awid] <= 1'b1;
563
                        f_axi_wr_id_complete[i_axi_awid] <= 1'b0;
564
                end
565
 
566
                if (axi_wr_req)
567
                begin
568
                        if ((F_CONSECUTIVE_IDS)&&(F_CHECK_IDS))
569
                                assert(f_axi_wr_id_outstanding[i_axi_awid+1'b1] == 1'b0);
570
                        assert((!F_CHECK_IDS)
571
                                ||(f_axi_wr_id_outstanding[i_axi_awid] == 1'b0));
572
                        f_axi_wr_id_outstanding[i_axi_awid] <= 1'b1;
573
                        if (i_axi_wlast)
574
                        begin
575
                                assume(f_axi_wr_id_complete[i_axi_awid] == 1'b0);
576
                                f_axi_wr_id_complete[i_axi_awid] <= 1'b1;
577
                        end
578
                end
579
 
580
                // When issuing a read
581
                if (axi_ard_req)
582
                begin
583
                        if ((F_CONSECUTIVE_IDS)&&(F_CHECK_IDS))
584
                                assert(f_axi_rd_id_outstanding[i_axi_arid+1'b1] == 1'b0);
585
                        assert((!F_CHECK_IDS)
586
                                ||(f_axi_rd_id_outstanding[i_axi_arid] == 1'b0));
587
                        f_axi_rd_id_outstanding[i_axi_arid] <= 1'b1;
588
                end
589
 
590
                // When a write is acknowledged
591
                if (axi_wr_ack)
592
                begin
593
                        if (F_CHECK_IDS)
594
                        begin
595
                                assume(f_axi_awr_id_outstanding[i_axi_bid]);
596
                                assume(f_axi_wr_id_outstanding[i_axi_bid]);
597
                                assume((!F_STRICT_ORDER)||(!F_CONSECUTIVE_IDS)
598
                                        ||(!f_axi_wr_id_outstanding[i_axi_bid-1'b1]));
599
                                assume((!F_STRICT_ORDER)||(!F_CONSECUTIVE_IDS)
600
                                        ||(!f_axi_awr_id_outstanding[i_axi_bid-1'b1]));
601
                                assume(f_axi_wr_id_complete[i_axi_bid]);
602
                        end
603
                        f_axi_awr_id_outstanding[i_axi_bid] <= 1'b0;
604
                        f_axi_wr_id_outstanding[i_axi_bid]  <= 1'b0;
605
                        f_axi_wr_id_complete[i_axi_bid]     <= 1'b0;
606
                end
607
 
608
                // When a read is acknowledged
609
                if (axi_rd_ack)
610
                begin
611
                        if (F_CHECK_IDS)
612
                        begin
613
                                assume(f_axi_rd_id_outstanding[i_axi_rid]);
614
                                assume((!F_STRICT_ORDER)||(!F_CONSECUTIVE_IDS)
615
                                        ||(!f_axi_rd_id_outstanding[i_axi_rid-1'b1]));
616
                        end
617
 
618
                        if (i_axi_rlast)
619
                                f_axi_rd_id_outstanding[i_axi_rid] <= 1'b0;
620
                end
621
        end
622
 
623
 
624
        reg     [LGFIFOLN:0]     f_axi_rd_id_outstanding_count,
625
                                f_axi_awr_id_outstanding_count,
626
                                f_axi_wr_id_outstanding_count;
627
 
628
        initial f_axi_rd_id_outstanding_count = 0;
629
        initial f_axi_awr_id_outstanding_count = 0;
630
        initial f_axi_wr_id_outstanding_count = 0;
631
        always @(*)
632
        begin
633
                //
634
                f_axi_rd_id_outstanding_count = 0;
635
                for(k=0; k< FIFOLN; k=k+1)
636
                        if (f_axi_rd_id_outstanding[k])
637
                                f_axi_rd_id_outstanding_count
638
                                        = f_axi_rd_id_outstanding_count +1;
639
                //
640
                f_axi_wr_id_outstanding_count = 0;
641
                for(k=0; k< FIFOLN; k=k+1)
642
                        if (f_axi_wr_id_outstanding[k])
643
                                f_axi_wr_id_outstanding_count = f_axi_wr_id_outstanding_count +1;
644
                f_axi_awr_id_outstanding_count = 0;
645
                for(k=0; k< FIFOLN; k=k+1)
646
                        if (f_axi_awr_id_outstanding[k])
647
                                f_axi_awr_id_outstanding_count = f_axi_awr_id_outstanding_count +1;
648
        end
649
 
650
        always @(*)
651
                assert((!F_CHECK_IDS)||(f_axi_awr_outstanding== f_axi_awr_id_outstanding_count));
652
 
653
        always @(*)
654
                assert((!F_CHECK_IDS)||(f_axi_wr_outstanding == f_axi_wr_id_outstanding_count));
655
 
656
        always @(*)
657
                assert((!F_CHECK_IDS)||(f_axi_rd_outstanding == f_axi_rd_id_outstanding_count));
658
 
659
        always @(*)
660
                assume( ((f_axi_wr_id_complete)&(~f_axi_awr_id_outstanding)) == 0);
661
 
662
        generate if (F_OPT_BURSTS)
663
        begin
664
                reg     [(8-1):0]        f_rd_pending    [0:(FIFOLN-1)];
665
                reg     [(8-1):0]        f_wr_pending,
666
                                        f_rd_count, f_wr_count;
667
 
668
                reg     r_last_rd_id_valid,
669
                        r_last_wr_id_valid;
670
 
671
                reg     [(C_AXI_ID_WIDTH-1):0]   r_last_wr_id, r_last_rd_id;
672
 
673
                initial r_last_wr_id_valid = 1'b0;
674
                initial r_last_rd_id_valid = 1'b0;
675
                always @(posedge i_clk)
676
                if (!i_axi_reset_n)
677
                begin
678
                        r_last_wr_id_valid <= 1'b0;
679
                        r_last_rd_id_valid <= 1'b0;
680
                        f_wr_count <= 0;
681
                        f_rd_count <= 0;
682
                end else begin
683
                        if (axi_awr_req)
684
                        begin
685
                                f_wr_pending <= i_axi_awlen+9'h1;
686
                                assert(f_wr_pending == 0);
687
                                r_last_wr_id_valid <= 1'b1;
688
                        end
689
 
690
                        if (axi_ard_req)
691
                                f_rd_pending[i_axi_arid] <= i_axi_arlen+9'h1;
692
 
693
 
694
                        if ((axi_wr_req)&&(i_axi_wlast))
695
                        begin
696
                                f_wr_count <= 0;
697
                                r_last_wr_id_valid <= 1'b0;
698
                                assert(
699
                                        // Either this is the last
700
                                        // of a series of requests we've
701
                                        // been waiting for,
702
                                        (f_wr_pending == f_wr_count - 9'h1)
703
                                        // *or* the only value
704
                                        // associated with an as yet
705
                                        // to be counted request
706
                                        ||((axi_awr_req)&&(i_axi_awlen == 0)));
707
                        end else if (axi_wr_req)
708
                                f_wr_count <= f_wr_count + 1'b1;
709
 
710
                        if (axi_rd_ack)
711
                        begin
712
                                if (i_axi_rlast)
713
                                        r_last_rd_id_valid <= 1'b0;
714
                                else
715
                                        r_last_rd_id_valid <= 1'b1;
716
 
717
                                r_last_rd_id <= i_axi_rid;
718
                                if ((axi_rd_ack)&&(r_last_rd_id_valid))
719
                                        assume(i_axi_rid == r_last_rd_id);
720
                        end
721
 
722
                        if ((axi_rd_ack)&&(i_axi_rlast))
723
                                assert(f_rd_count == f_rd_pending[i_axi_rid]-9'h1);
724
                        if ((axi_rd_ack)&&(i_axi_rlast))
725
                                f_rd_count <= 0;
726
                        else if (axi_rd_ack)
727
                                f_rd_count <= f_rd_count + 1'b1;
728
                end
729
        end else begin
730
                always @(*) begin
731
                        // Since we aren't allowing bursts, *every*
732
                        // write data and read data must always be the last
733
                        // value
734
                        assert((i_axi_wlast)||(!i_axi_wvalid));
735
                        assume((i_axi_rlast)||(!i_axi_rvalid));
736
 
737
                        assert((!i_axi_arvalid)||(i_axi_arlen==0));
738
                        assert((!i_axi_awvalid)||(i_axi_awlen==0));
739
                end
740
 
741
                always @(posedge i_clk)
742
                        if (i_axi_awvalid)
743
                                assert(i_axi_awlen == 0);
744
                always @(posedge i_clk)
745
                        if (i_axi_arvalid)
746
                                assert(i_axi_arlen == 0);
747
                always @(posedge i_clk)
748
                        if (i_axi_wvalid)
749
                                assert(i_axi_wlast);
750
                always @(posedge i_clk)
751
                        if (i_axi_rvalid)
752
                                assume(i_axi_rlast);
753
        end endgenerate
754
 
755
`endif
756
endmodule

powered by: WebSVN 2.1.0

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