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

Subversion Repositories wb2axip

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

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

powered by: WebSVN 2.1.0

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