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

Subversion Repositories wb2axip

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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