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

Subversion Repositories wb2axip

[/] [wb2axip/] [trunk/] [rtl/] [wbm2axisp.v] - Blame information for rev 10

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

Line No. Rev Author Line
1 2 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3 8 dgisselq
// Filename:    wbm2axisp.v (Wishbone master to AXI slave, pipelined)
4 2 dgisselq
//
5
// Project:     Pipelined Wishbone to AXI converter
6
//
7
// Purpose:     The B4 Wishbone SPEC allows transactions at a speed as fast as
8
//              one per clock.  The AXI bus allows transactions at a speed of
9
//      one read and one write transaction per clock.  These capabilities work
10
//      by allowing requests to take place prior to responses, such that the
11
//      requests might go out at once per clock and take several clocks, and
12
//      the responses may start coming back several clocks later.  In other
13
//      words, both protocols allow multiple transactions to be "in flight" at
14
//      the same time.  Current wishbone to AXI converters, however, handle only
15
//      one transaction at a time: initiating the transaction, and then waiting
16
//      for the transaction to complete before initiating the next.
17
//
18
//      The purpose of this core is to maintain the speed of both busses, while
19
//      transiting from the Wishbone (as master) to the AXI bus (as slave) and
20
//      back again.
21
//
22 8 dgisselq
//      Since the AXI bus allows transactions to be reordered, whereas the
23 2 dgisselq
//      wishbone does not, this core can be configured to reorder return
24
//      transactions as well.
25
//
26
// Creator:     Dan Gisselquist, Ph.D.
27
//              Gisselquist Technology, LLC
28
//
29
////////////////////////////////////////////////////////////////////////////////
30
//
31 3 dgisselq
// Copyright (C) 2016, Gisselquist Technology, LLC
32 2 dgisselq
//
33
// This program is free software (firmware): you can redistribute it and/or
34
// modify it under the terms of  the GNU General Public License as published
35
// by the Free Software Foundation, either version 3 of the License, or (at
36
// your option) any later version.
37
//
38
// This program is distributed in the hope that it will be useful, but WITHOUT
39
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
40
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
41
// for more details.
42
//
43
// You should have received a copy of the GNU General Public License along
44
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
45
// target there if the PDF file isn't present.)  If not, see
46
// <http://www.gnu.org/licenses/> for a copy.
47
//
48
// License:     GPL, v3, as defined and found on www.gnu.org,
49
//              http://www.gnu.org/licenses/gpl.html
50
//
51
//
52
////////////////////////////////////////////////////////////////////////////////
53
//
54
//
55 8 dgisselq
`default_nettype        none
56
//
57 2 dgisselq
module wbm2axisp #(
58 8 dgisselq
        parameter C_AXI_ID_WIDTH        = 3, // The AXI id width used for R&W
59 2 dgisselq
                                             // This is an int between 1-16
60 8 dgisselq
        parameter C_AXI_DATA_WIDTH      = 32,// Width of the AXI R&W data
61
        parameter C_AXI_ADDR_WIDTH      = 28,   // AXI Address width (log wordsize)
62
        parameter DW                    =  8,   // Wishbone data width
63
        parameter AW                    = 26,   // Wishbone address width (log wordsize)
64
        parameter [0:0] STRICT_ORDER      = 1     // Reorder, or not? 0 -> Reorder
65 2 dgisselq
        ) (
66
        input                           i_clk,  // System clock
67 6 dgisselq
        // input                        i_reset,// Wishbone reset signal--unused
68 2 dgisselq
 
69
// AXI write address channel signals
70 5 dgisselq
        input                           i_axi_awready, // Slave is ready to accept
71 6 dgisselq
        output  reg     [C_AXI_ID_WIDTH-1:0]     o_axi_awid,     // Write ID
72
        output  reg     [C_AXI_ADDR_WIDTH-1:0]   o_axi_awaddr,   // Write address
73 5 dgisselq
        output  wire    [7:0]            o_axi_awlen,    // Write Burst Length
74
        output  wire    [2:0]            o_axi_awsize,   // Write Burst size
75
        output  wire    [1:0]            o_axi_awburst,  // Write Burst type
76 6 dgisselq
        output  wire    [0:0]             o_axi_awlock,   // Write lock type
77 5 dgisselq
        output  wire    [3:0]            o_axi_awcache,  // Write Cache type
78
        output  wire    [2:0]            o_axi_awprot,   // Write Protection type
79
        output  wire    [3:0]            o_axi_awqos,    // Write Quality of Svc
80
        output  reg                     o_axi_awvalid,  // Write address valid
81 8 dgisselq
 
82 2 dgisselq
// AXI write data channel signals
83 5 dgisselq
        input                           i_axi_wready,  // Write data ready
84
        output  reg     [C_AXI_DATA_WIDTH-1:0]   o_axi_wdata,    // Write data
85
        output  reg     [C_AXI_DATA_WIDTH/8-1:0] o_axi_wstrb,    // Write strobes
86 8 dgisselq
        output  wire                    o_axi_wlast,    // Last write transaction
87 5 dgisselq
        output  reg                     o_axi_wvalid,   // Write valid
88 8 dgisselq
 
89 2 dgisselq
// AXI write response channel signals
90 5 dgisselq
        input   [C_AXI_ID_WIDTH-1:0]     i_axi_bid,      // Response ID
91
        input   [1:0]                    i_axi_bresp,    // Write response
92
        input                           i_axi_bvalid,  // Write reponse valid
93
        output  wire                    o_axi_bready,  // Response ready
94 8 dgisselq
 
95 2 dgisselq
// AXI read address channel signals
96 5 dgisselq
        input                           i_axi_arready,  // Read address ready
97
        output  wire    [C_AXI_ID_WIDTH-1:0]     o_axi_arid,     // Read ID
98 6 dgisselq
        output  wire    [C_AXI_ADDR_WIDTH-1:0]   o_axi_araddr,   // Read address
99 5 dgisselq
        output  wire    [7:0]            o_axi_arlen,    // Read Burst Length
100
        output  wire    [2:0]            o_axi_arsize,   // Read Burst size
101
        output  wire    [1:0]            o_axi_arburst,  // Read Burst type
102 6 dgisselq
        output  wire    [0:0]             o_axi_arlock,   // Read lock type
103 5 dgisselq
        output  wire    [3:0]            o_axi_arcache,  // Read Cache type
104
        output  wire    [2:0]            o_axi_arprot,   // Read Protection type
105
        output  wire    [3:0]            o_axi_arqos,    // Read Protection type
106
        output  reg                     o_axi_arvalid,  // Read address valid
107 8 dgisselq
 
108
// AXI read data channel signals
109 5 dgisselq
        input   [C_AXI_ID_WIDTH-1:0]     i_axi_rid,     // Response ID
110
        input   [1:0]                    i_axi_rresp,   // Read response
111
        input                           i_axi_rvalid,  // Read reponse valid
112
        input   [C_AXI_DATA_WIDTH-1:0]   i_axi_rdata,    // Read data
113
        input                           i_axi_rlast,    // Read last
114
        output  wire                    o_axi_rready,  // Read Response ready
115 2 dgisselq
 
116
        // We'll share the clock and the reset
117 3 dgisselq
        input                           i_wb_cyc,
118
        input                           i_wb_stb,
119
        input                           i_wb_we,
120 6 dgisselq
        input           [(AW-1):0]       i_wb_addr,
121
        input           [(DW-1):0]       i_wb_data,
122 4 dgisselq
        input           [(DW/8-1):0]     i_wb_sel,
123 3 dgisselq
        output  reg                     o_wb_ack,
124
        output  wire                    o_wb_stall,
125 6 dgisselq
        output  reg     [(DW-1):0]       o_wb_data,
126 3 dgisselq
        output  reg                     o_wb_err
127 2 dgisselq
);
128
 
129
//*****************************************************************************
130
// Parameter declarations
131
//*****************************************************************************
132
 
133 8 dgisselq
        localparam      LG_AXI_DW       = ( C_AXI_DATA_WIDTH ==   8) ? 3
134
                                        : ((C_AXI_DATA_WIDTH ==  16) ? 4
135
                                        : ((C_AXI_DATA_WIDTH ==  32) ? 5
136
                                        : ((C_AXI_DATA_WIDTH ==  64) ? 6
137
                                        : ((C_AXI_DATA_WIDTH == 128) ? 7
138
                                        : 8))));
139 2 dgisselq
 
140 8 dgisselq
        localparam      LG_WB_DW        = ( DW ==   8) ? 3
141
                                        : ((DW ==  16) ? 4
142
                                        : ((DW ==  32) ? 5
143
                                        : ((DW ==  64) ? 6
144
                                        : ((DW == 128) ? 7
145
                                        : 8))));
146
        localparam      LGFIFOLN = C_AXI_ID_WIDTH;
147
        localparam      FIFOLN = (1<<LGFIFOLN);
148
 
149
 
150 2 dgisselq
//*****************************************************************************
151
// Internal register and wire declarations
152
//*****************************************************************************
153
 
154
// Things we're not changing ...
155 8 dgisselq
        assign o_axi_awlen   = 8'h0;    // Burst length is one
156
        assign o_axi_awsize  = 3'b101;  // maximum bytes per burst is 32
157 5 dgisselq
        assign o_axi_awburst = 2'b01;   // Incrementing address (ignored)
158
        assign o_axi_arburst = 2'b01;   // Incrementing address (ignored)
159 6 dgisselq
        assign o_axi_awlock  = 1'b0;    // Normal signaling
160
        assign o_axi_arlock  = 1'b0;    // Normal signaling
161 5 dgisselq
        assign o_axi_awcache = 4'h2;    // Normal: no cache, no buffer
162
        assign o_axi_arcache = 4'h2;    // Normal: no cache, no buffer
163 6 dgisselq
        assign o_axi_awprot  = 3'b010;  // Unpriviledged, unsecure, data access
164
        assign o_axi_arprot  = 3'b010;  // Unpriviledged, unsecure, data access
165 8 dgisselq
        assign o_axi_awqos   = 4'h0;    // Lowest quality of service (unused)
166
        assign o_axi_arqos   = 4'h0;    // Lowest quality of service (unused)
167 2 dgisselq
 
168 8 dgisselq
        reg     wb_mid_cycle, wb_last_cyc_stb, wb_mid_abort;
169
        wire    wb_cyc_stb;
170 2 dgisselq
// Command logic
171 8 dgisselq
// Transaction ID logic
172
        wire    [(LGFIFOLN-1):0] fifo_head;
173
        reg     [(C_AXI_ID_WIDTH-1):0]   transaction_id;
174
 
175
        initial transaction_id = 0;
176
        always @(posedge i_clk)
177
                if ((i_wb_stb)&&(!o_wb_stall))
178
                        transaction_id <= transaction_id + 1'b1;
179
 
180
        assign  fifo_head = transaction_id;
181
 
182
        wire    [(DW/8-1):0]                     no_sel;
183
        wire    [(LG_AXI_DW-4):0]        axi_bottom_addr;
184
        assign  no_sel = 0;
185
        assign  axi_bottom_addr = 0;
186
 
187
 
188 2 dgisselq
// Write address logic
189
 
190 8 dgisselq
        initial o_axi_awvalid = 0;
191 2 dgisselq
        always @(posedge i_clk)
192 5 dgisselq
                o_axi_awvalid <= (!o_wb_stall)&&(i_wb_stb)&&(i_wb_we)
193 8 dgisselq
                        ||(o_axi_awvalid)&&(!i_axi_awready);
194 2 dgisselq
 
195 6 dgisselq
        generate
196 8 dgisselq
 
197
        initial o_axi_awid = -1;
198
        always @(posedge i_clk)
199
                if ((i_wb_stb)&&(!o_wb_stall))
200
                        o_axi_awid <= transaction_id;
201
 
202
        if (C_AXI_DATA_WIDTH == DW)
203 6 dgisselq
        begin
204
                always @(posedge i_clk)
205 8 dgisselq
                        if ((i_wb_stb)&&(!o_wb_stall)) // 26 bit address becomes 28 bit ...
206
                                o_axi_awaddr <= { i_wb_addr[AW-1:0], axi_bottom_addr };
207
        end else if (C_AXI_DATA_WIDTH / DW == 2)
208 6 dgisselq
        begin
209 8 dgisselq
 
210 6 dgisselq
                always @(posedge i_clk)
211 8 dgisselq
                        if ((i_wb_stb)&&(!o_wb_stall)) // 26 bit address becomes 28 bit ...
212
                                o_axi_awaddr <= { i_wb_addr[AW-1:1], axi_bottom_addr };
213
 
214
        end else if (C_AXI_DATA_WIDTH / DW == 4)
215
        begin
216
                always @(posedge i_clk)
217
                        if ((i_wb_stb)&&(!o_wb_stall)) // 26 bit address becomes 28 bit ...
218
                                o_axi_awaddr <= { i_wb_addr[AW-1:2], axi_bottom_addr };
219 6 dgisselq
        end endgenerate
220
 
221 2 dgisselq
 
222
// Read address logic
223 8 dgisselq
        assign  o_axi_arid   = o_axi_awid;
224 5 dgisselq
        assign  o_axi_araddr = o_axi_awaddr;
225
        assign  o_axi_arlen  = o_axi_awlen;
226
        assign  o_axi_arsize = 3'b101;  // maximum bytes per burst is 32
227 8 dgisselq
        initial o_axi_arvalid = 1'b0;
228 2 dgisselq
        always @(posedge i_clk)
229 5 dgisselq
                o_axi_arvalid <= (!o_wb_stall)&&(i_wb_stb)&&(!i_wb_we)
230 8 dgisselq
                        ||(o_axi_arvalid)&&(!i_axi_arready);
231 2 dgisselq
 
232
// Write data logic
233 4 dgisselq
        generate
234 8 dgisselq
        if (C_AXI_DATA_WIDTH == DW)
235 4 dgisselq
        begin
236 8 dgisselq
 
237 4 dgisselq
                always @(posedge i_clk)
238 8 dgisselq
                        if ((i_wb_stb)&&(!o_wb_stall))
239
                                o_axi_wdata <= i_wb_data;
240
 
241 4 dgisselq
                always @(posedge i_clk)
242 8 dgisselq
                        if ((i_wb_stb)&&(!o_wb_stall))
243
                                o_axi_wstrb<= i_wb_sel;
244
 
245
        end else if (C_AXI_DATA_WIDTH/2 == DW)
246
        begin
247
 
248
                always @(posedge i_clk)
249
                        if ((i_wb_stb)&&(!o_wb_stall))
250
                                o_axi_wdata <= { i_wb_data, i_wb_data };
251
 
252
                always @(posedge i_clk)
253
                        if ((i_wb_stb)&&(!o_wb_stall))
254
                        case(i_wb_addr[0])
255
                        1'b0:o_axi_wstrb<={  no_sel,i_wb_sel };
256
                        1'b1:o_axi_wstrb<={i_wb_sel,  no_sel };
257 4 dgisselq
                        endcase
258 8 dgisselq
 
259
        end else if (C_AXI_DATA_WIDTH/4 == DW)
260 4 dgisselq
        begin
261 8 dgisselq
 
262 4 dgisselq
                always @(posedge i_clk)
263 8 dgisselq
                        if ((i_wb_stb)&&(!o_wb_stall))
264
                                o_axi_wdata <= { i_wb_data, i_wb_data, i_wb_data, i_wb_data };
265
 
266 4 dgisselq
                always @(posedge i_clk)
267 8 dgisselq
                        if ((i_wb_stb)&&(!o_wb_stall))
268
                        case(i_wb_addr[1:0])
269
                        2'b00:o_axi_wstrb<={   no_sel,   no_sel,   no_sel, i_wb_sel };
270
                        2'b01:o_axi_wstrb<={   no_sel,   no_sel, i_wb_sel,   no_sel };
271
                        2'b10:o_axi_wstrb<={   no_sel, i_wb_sel,   no_sel,   no_sel };
272
                        2'b11:o_axi_wstrb<={ i_wb_sel,   no_sel,   no_sel,   no_sel };
273
                        endcase
274
 
275 4 dgisselq
        end endgenerate
276
 
277 5 dgisselq
        assign  o_axi_wlast = 1'b1;
278 8 dgisselq
        initial o_axi_wvalid = 0;
279 2 dgisselq
        always @(posedge i_clk)
280 5 dgisselq
                o_axi_wvalid <= ((!o_wb_stall)&&(i_wb_stb)&&(i_wb_we))
281 8 dgisselq
                        ||(o_axi_wvalid)&&(!i_axi_wready);
282 2 dgisselq
 
283 8 dgisselq
        // Read data channel / response logic
284 5 dgisselq
        assign  o_axi_rready = 1'b1;
285
        assign  o_axi_bready = 1'b1;
286 2 dgisselq
 
287 8 dgisselq
        wire    [(LGFIFOLN-1):0] n_fifo_head, nn_fifo_head;
288
        assign  n_fifo_head = fifo_head+1'b1;
289
        assign  nn_fifo_head = { fifo_head[(LGFIFOLN-1):1]+1'b1, fifo_head[0] };
290
 
291
 
292 2 dgisselq
        wire    w_fifo_full;
293 8 dgisselq
        reg     [(LGFIFOLN-1):0] fifo_tail;
294
 
295 2 dgisselq
        generate
296 8 dgisselq
        if (C_AXI_DATA_WIDTH == DW)
297 2 dgisselq
        begin
298 8 dgisselq
                if (STRICT_ORDER == 0)
299
                begin
300
                        reg     [(C_AXI_DATA_WIDTH-1):0] reorder_fifo_data [0:(FIFOLN-1)];
301 3 dgisselq
 
302 8 dgisselq
                        always @(posedge i_clk)
303
                                if ((o_axi_rready)&&(i_axi_rvalid))
304
                                        reorder_fifo_data[i_axi_rid] <= i_axi_rdata;
305
                        always @(posedge i_clk)
306
                                o_wb_data <= reorder_fifo_data[fifo_tail];
307
                end else begin
308
                        reg     [(C_AXI_DATA_WIDTH-1):0] reorder_fifo_data;
309 6 dgisselq
 
310 8 dgisselq
                        always @(posedge i_clk)
311
                                reorder_fifo_data <= i_axi_rdata;
312
                        always @(posedge i_clk)
313
                                o_wb_data <= reorder_fifo_data;
314
                end
315
        end else if (C_AXI_DATA_WIDTH / DW == 2)
316
        begin
317
                reg             reorder_fifo_addr [0:(FIFOLN-1)];
318
 
319
                reg             low_addr;
320
                always @(posedge i_clk)
321
                        if ((i_wb_stb)&&(!o_wb_stall))
322
                                low_addr <= i_wb_addr[0];
323
                always @(posedge i_clk)
324
                        if ((o_axi_arvalid)&&(i_axi_arready))
325
                                reorder_fifo_addr[o_axi_arid] <= low_addr;
326
 
327
                if (STRICT_ORDER == 0)
328 4 dgisselq
                begin
329 8 dgisselq
                        reg     [(C_AXI_DATA_WIDTH-1):0] reorder_fifo_data [0:(FIFOLN-1)];
330 3 dgisselq
 
331 8 dgisselq
                        always @(posedge i_clk)
332
                                if ((o_axi_rready)&&(i_axi_rvalid))
333
                                        reorder_fifo_data[i_axi_rid] <= i_axi_rdata;
334
                        always @(posedge i_clk)
335
                                reorder_fifo_data[i_axi_rid] <= i_axi_rdata;
336
                        always @(posedge i_clk)
337
                        case(reorder_fifo_addr[fifo_tail])
338
                        1'b0: o_wb_data <=reorder_fifo_data[fifo_tail][(  DW-1):    0 ];
339
                        1'b1: o_wb_data <=reorder_fifo_data[fifo_tail][(2*DW-1):(  DW)];
340
                        endcase
341
                end else begin
342
                        reg     [(C_AXI_DATA_WIDTH-1):0] reorder_fifo_data;
343 3 dgisselq
 
344 4 dgisselq
                        always @(posedge i_clk)
345 8 dgisselq
                                reorder_fifo_data <= i_axi_rdata;
346 4 dgisselq
                        always @(posedge i_clk)
347 8 dgisselq
                        case(reorder_fifo_addr[fifo_tail])
348
                        1'b0: o_wb_data <=reorder_fifo_data[(  DW-1):    0 ];
349
                        1'b1: o_wb_data <=reorder_fifo_data[(2*DW-1):(  DW)];
350
                        endcase
351
                end
352
        end else if (C_AXI_DATA_WIDTH / DW == 4)
353
        begin
354
                reg     [1:0]    reorder_fifo_addr [0:(FIFOLN-1)];
355 3 dgisselq
 
356 8 dgisselq
 
357
                reg     [1:0]    low_addr;
358
                always @(posedge i_clk)
359
                        if ((i_wb_stb)&&(!o_wb_stall))
360
                                low_addr <= i_wb_addr[1:0];
361
                always @(posedge i_clk)
362
                        if ((o_axi_arvalid)&&(i_axi_arready))
363
                                reorder_fifo_addr[o_axi_arid] <= low_addr;
364
 
365
                if (STRICT_ORDER == 0)
366
                begin
367
                        reg     [(C_AXI_DATA_WIDTH-1):0] reorder_fifo_data [0:(FIFOLN-1)];
368
 
369 4 dgisselq
                        always @(posedge i_clk)
370 8 dgisselq
                                if ((o_axi_rready)&&(i_axi_rvalid))
371
                                        reorder_fifo_data[i_axi_rid] <= i_axi_rdata;
372
                        always @(posedge i_clk)
373 6 dgisselq
                        case(reorder_fifo_addr[fifo_tail][1:0])
374 8 dgisselq
                        2'b00: o_wb_data <=reorder_fifo_data[fifo_tail][(  DW-1):    0 ];
375
                        2'b01: o_wb_data <=reorder_fifo_data[fifo_tail][(2*DW-1):(  DW)];
376
                        2'b10: o_wb_data <=reorder_fifo_data[fifo_tail][(3*DW-1):(2*DW)];
377
                        2'b11: o_wb_data <=reorder_fifo_data[fifo_tail][(4*DW-1):(3*DW)];
378 4 dgisselq
                        endcase
379 8 dgisselq
                end else begin
380
                        reg     [(C_AXI_DATA_WIDTH-1):0] reorder_fifo_data;
381 4 dgisselq
 
382
                        always @(posedge i_clk)
383 8 dgisselq
                                reorder_fifo_data <= i_axi_rdata;
384
                        always @(posedge i_clk)
385
                        case(reorder_fifo_addr[fifo_tail][1:0])
386
                        2'b00: o_wb_data <=reorder_fifo_data[(  DW-1): 0];
387
                        2'b01: o_wb_data <=reorder_fifo_data[(2*DW-1):(  DW)];
388
                        2'b10: o_wb_data <=reorder_fifo_data[(3*DW-1):(2*DW)];
389
                        2'b11: o_wb_data <=reorder_fifo_data[(4*DW-1):(3*DW)];
390
                        endcase
391 4 dgisselq
                end
392 8 dgisselq
        end
393 4 dgisselq
 
394 8 dgisselq
        endgenerate
395 4 dgisselq
 
396 8 dgisselq
        wire    axi_rd_ack, axi_wr_ack, axi_ard_req, axi_awr_req, axi_wr_req,
397
                axi_rd_err, axi_wr_err;
398
        //
399
        assign  axi_ard_req = (o_axi_arvalid)&&(i_axi_arready);
400
        assign  axi_awr_req = (o_axi_awvalid)&&(i_axi_awready);
401
        assign  axi_wr_req  = (o_axi_wvalid )&&(i_axi_wready);
402
        //
403
        assign  axi_rd_ack = (i_axi_rvalid)&&(o_axi_rready);
404
        assign  axi_wr_ack = (i_axi_bvalid)&&(o_axi_bready);
405
        assign  axi_rd_err = (axi_rd_ack)&&(i_axi_rresp[1]);
406
        assign  axi_wr_err = (axi_wr_ack)&&(i_axi_bresp[1]);
407 2 dgisselq
 
408 8 dgisselq
        //
409
        // We're going to need a FIFO on the return to make certain that we can
410
        // select the right bits from the return value, in the case where
411
        // DW != the axi data width.
412
        //
413
        // If we aren't using a strict order, this FIFO is can be used as a
414
        // reorder buffer as well, to place our out of order bus responses
415
        // back into order.  Responses on the wishbone, however, are *always*
416
        // done in order.
417
`ifdef  FORMAL
418
        reg     [31:0]   reorder_count;
419
`endif
420
        integer k;
421
        generate
422
        if (STRICT_ORDER == 0)
423
        begin
424
                // Reorder FIFO
425
                //
426
                // FIFO reorder buffer
427
                reg     [(FIFOLN-1):0]   reorder_fifo_valid;
428
                reg     [(FIFOLN-1):0]   reorder_fifo_err;
429 2 dgisselq
 
430 8 dgisselq
                initial reorder_fifo_valid = 0;
431
                initial reorder_fifo_err = 0;
432
 
433
 
434
                initial fifo_tail = 0;
435
                initial o_wb_ack  = 0;
436
                initial o_wb_err  = 0;
437 2 dgisselq
                always @(posedge i_clk)
438
                begin
439 8 dgisselq
                        if (axi_rd_ack)
440 2 dgisselq
                        begin
441 5 dgisselq
                                reorder_fifo_valid[i_axi_rid] <= 1'b1;
442 8 dgisselq
                                reorder_fifo_err[i_axi_rid] <= axi_rd_err;
443 2 dgisselq
                        end
444 8 dgisselq
                        if (axi_wr_ack)
445 2 dgisselq
                        begin
446 5 dgisselq
                                reorder_fifo_valid[i_axi_bid] <= 1'b1;
447 8 dgisselq
                                reorder_fifo_err[i_axi_bid] <= axi_wr_err;
448 2 dgisselq
                        end
449
 
450
                        if (reorder_fifo_valid[fifo_tail])
451
                        begin
452 8 dgisselq
                                o_wb_ack <= (!wb_abort)&&(!reorder_fifo_err[fifo_tail]);
453
                                o_wb_err <= (!wb_abort)&&( reorder_fifo_err[fifo_tail]);
454
                                fifo_tail <= fifo_tail + 1'b1;
455 2 dgisselq
                                reorder_fifo_valid[fifo_tail] <= 1'b0;
456
                                reorder_fifo_err[fifo_tail]   <= 1'b0;
457
                        end else begin
458
                                o_wb_ack <= 1'b0;
459
                                o_wb_err <= 1'b0;
460
                        end
461
 
462
                        if (!i_wb_cyc)
463
                        begin
464 8 dgisselq
                                // reorder_fifo_valid <= 0;
465
                                // reorder_fifo_err   <= 0;
466 2 dgisselq
                                o_wb_err <= 1'b0;
467
                                o_wb_ack <= 1'b0;
468
                        end
469
                end
470
 
471 8 dgisselq
`ifdef  FORMAL
472
                always @(*)
473
                begin
474
                        reorder_count = 0;
475
                        for(k=0; k<FIFOLN; k=k+1)
476
                                if (reorder_fifo_valid[k])
477
                                        reorder_count = reorder_count + 1;
478
                end
479
 
480
                reg     [(FIFOLN-1):0]   f_reorder_fifo_valid_zerod,
481
                                        f_reorder_fifo_err_zerod;
482
                always @(*)
483
                        f_reorder_fifo_valid_zerod <=
484
                                ((reorder_fifo_valid >> fifo_tail)
485
                                | (reorder_fifo_valid << (FIFOLN-fifo_tail)));
486
                always @(*)
487
                        assert((f_reorder_fifo_valid_zerod & (~((1<<f_fifo_used)-1)))==0);
488
                //
489
                always @(*)
490
                        f_reorder_fifo_err_zerod <=
491
                                ((reorder_fifo_valid >> fifo_tail)
492
                                | (reorder_fifo_valid << (FIFOLN-fifo_tail)));
493
                always @(*)
494
                        assert((f_reorder_fifo_err_zerod & (~((1<<f_fifo_used)-1)))==0);
495
`endif
496
 
497 3 dgisselq
                reg     r_fifo_full;
498 8 dgisselq
                initial r_fifo_full = 0;
499 2 dgisselq
                always @(posedge i_clk)
500
                begin
501 8 dgisselq
                        if ((i_wb_stb)&&(!o_wb_stall)
502 2 dgisselq
                                        &&(reorder_fifo_valid[fifo_tail]))
503
                                r_fifo_full <= (fifo_tail==n_fifo_head);
504 8 dgisselq
                        else if ((i_wb_stb)&&(!o_wb_stall))
505 2 dgisselq
                                r_fifo_full <= (fifo_tail==nn_fifo_head);
506
                        else if (reorder_fifo_valid[fifo_tail])
507
                                r_fifo_full <= 1'b0;
508
                        else
509
                                r_fifo_full <= (fifo_tail==n_fifo_head);
510
                end
511
                assign w_fifo_full = r_fifo_full;
512
        end else begin
513 6 dgisselq
                //
514 8 dgisselq
                // Strict ordering
515 6 dgisselq
                //
516 8 dgisselq
                reg     reorder_fifo_valid;
517
                reg     reorder_fifo_err;
518
 
519
                initial reorder_fifo_valid = 1'b0;
520
                initial reorder_fifo_err   = 1'b0;
521 2 dgisselq
                always @(posedge i_clk)
522 8 dgisselq
                        if (axi_rd_ack)
523
                        begin
524
                                reorder_fifo_valid <= 1'b1;
525
                                reorder_fifo_err   <= axi_rd_err;
526
                        end else if (axi_wr_ack)
527
                        begin
528
                                reorder_fifo_valid <= 1'b1;
529
                                reorder_fifo_err   <= axi_wr_err;
530
                        end else begin
531
                                reorder_fifo_valid <= 1'b0;
532
                                reorder_fifo_err   <= 1'b0;
533
                        end
534
 
535
                always @(*)
536
                        reorder_count = (reorder_fifo_valid) ? 1 : 0;
537
 
538
                initial fifo_tail = 0;
539 2 dgisselq
                always @(posedge i_clk)
540 8 dgisselq
                        if (reorder_fifo_valid)
541
                                fifo_tail <= fifo_tail + 6'h1;
542
 
543
                initial o_wb_ack  = 0;
544 2 dgisselq
                always @(posedge i_clk)
545 8 dgisselq
                        o_wb_ack <= (reorder_fifo_valid)&&(i_wb_cyc)&&(!wb_abort);
546
 
547
                initial o_wb_err  = 0;
548
                always @(posedge i_clk)
549
                        o_wb_err <= (reorder_fifo_err)&&(i_wb_cyc)&&(!wb_abort);
550
 
551
                reg     r_fifo_full;
552
                initial r_fifo_full = 0;
553
                always @(posedge i_clk)
554
                begin
555
                        if ((i_wb_stb)&&(!o_wb_stall)
556
                                        &&(reorder_fifo_valid))
557
                                r_fifo_full <= (fifo_tail==n_fifo_head);
558
                        else if ((i_wb_stb)&&(!o_wb_stall))
559
                                r_fifo_full <= (fifo_tail==nn_fifo_head);
560
                        else if (reorder_fifo_valid[fifo_tail])
561
                                r_fifo_full <= 1'b0;
562
                        else
563
                                r_fifo_full <= (fifo_tail==n_fifo_head);
564
                end
565
 
566
                assign w_fifo_full = r_fifo_full;
567 3 dgisselq
        end endgenerate
568 2 dgisselq
 
569 8 dgisselq
        //
570
        // Wishbone abort logic
571
        //
572
 
573
        // Did we just accept something?
574
        always @(posedge i_clk)
575
                wb_cyc_stb <= (i_wb_cyc)&&(i_wb_stb)&&(!o_wb_stall);
576
 
577
        // Else, are we mid-cycle?
578
        initial wb_mid_cycle = 0;
579
        always @(posedge i_clk)
580
                if ((fifo_head != fifo_tail)
581
                                ||(o_axi_arvalid)||(o_axi_awvalid)
582
                                ||(o_axi_wvalid)
583
                                ||(i_wb_cyc)&&(i_wb_stb)&&(!o_wb_stall))
584
                        wb_mid_cycle <= 1'b1;
585
                else
586
                        wb_mid_cycle <= 1'b0;
587
 
588
        always @(posedge i_clk)
589
                if (wb_mid_cycle)
590
                        wb_mid_abort <= (wb_mid_abort)||(!i_wb_cyc);
591
                else
592
                        wb_mid_abort <= 1'b0;
593
 
594
        wire    wb_abort;
595
        assign  wb_abort = ((wb_mid_cycle)&&(!i_wb_cyc))||(wb_mid_abort);
596
 
597 2 dgisselq
        // Now, the difficult signal ... the stall signal
598
        // Let's build for a single cycle input ... and only stall if something
599
        // outgoing is valid and nothing is ready.
600
        assign  o_wb_stall = (i_wb_cyc)&&(
601 8 dgisselq
                                (w_fifo_full)||(wb_mid_abort)
602 5 dgisselq
                                ||((o_axi_awvalid)&&(!i_axi_awready))
603
                                ||((o_axi_wvalid )&&(!i_axi_wready ))
604
                                ||((o_axi_arvalid)&&(!i_axi_arready)));
605 8 dgisselq
 
606
 
607
/////////////////////////////////////////////////////////////////////////
608
//
609
//
610
//
611
// Formal methods section
612
//
613
// These are only relevant when *proving* that this translator works
614
//
615
//
616
//
617
/////////////////////////////////////////////////////////////////////////
618
`ifdef  FORMAL
619
        reg     f_err_state;
620
//
621
`ifdef  WBM2AXISP
622
// If we are the top-level of the design ...
623
`define ASSUME  assume
624
`define FORMAL_CLOCK    assume(i_clk == !f_last_clk); f_last_clk <= i_clk;
625
`else
626
`define ASSUME  assert
627
`define FORMAL_CLOCK    f_last_clk <= i_clk; // Clock will be given to us valid already
628
`endif
629
 
630
        // Parameters
631
        initial assert(   (C_AXI_DATA_WIDTH / DW == 4)
632
                        ||(C_AXI_DATA_WIDTH / DW == 2)
633
                        ||(C_AXI_DATA_WIDTH      == DW));
634
        //
635
        initial assert( C_AXI_ADDR_WIDTH - LG_AXI_DW + LG_WB_DW == AW);
636
 
637
        //
638
        // Setup
639
        //
640
 
641
        reg     f_past_valid, f_last_clk;
642
 
643
        always @($global_clock)
644
        begin
645
                `FORMAL_CLOCK
646
 
647
                // Assume our inputs will only change on the positive edge
648
                // of the clock
649
                if (!$rose(i_clk))
650
                begin
651
                        // AXI inputs
652
                        `ASSUME($stable(i_axi_awready));
653
                        `ASSUME($stable(i_axi_wready));
654
                        `ASSUME($stable(i_axi_bid));
655
                        `ASSUME($stable(i_axi_bresp));
656
                        `ASSUME($stable(i_axi_bvalid));
657
                        `ASSUME($stable(i_axi_arready));
658
                        `ASSUME($stable(i_axi_rid));
659
                        `ASSUME($stable(i_axi_rresp));
660
                        `ASSUME($stable(i_axi_rvalid));
661
                        `ASSUME($stable(i_axi_rdata));
662
                        `ASSUME($stable(i_axi_rlast));
663
                        // Wishbone inputs
664
                        `ASSUME($stable(i_wb_cyc));
665
                        `ASSUME($stable(i_wb_stb));
666
                        `ASSUME($stable(i_wb_we));
667
                        `ASSUME($stable(i_wb_addr));
668
                        `ASSUME($stable(i_wb_data));
669
                        `ASSUME($stable(i_wb_sel));
670
                end
671
        end
672
 
673
        initial f_past_valid = 1'b0;
674
        always @(posedge i_clk)
675
                f_past_valid <= 1'b1;
676
 
677
        //////////////////////////////////////////////
678
        //
679
        //
680
        // Assumptions about the WISHBONE inputs
681
        //
682
        //
683
        //////////////////////////////////////////////
684
        wire    i_reset;
685
        assign  i_reset = !f_past_valid;
686
 
687
        wire    [(C_AXI_ID_WIDTH-1):0]   f_wb_nreqs, f_wb_nacks,f_wb_outstanding;
688
        fwb_slave #(.DW(DW),.AW(AW),
689
                        .F_MAX_STALL(0),
690
                        .F_MAX_ACK_DELAY(0),
691
                        .F_LGDEPTH(C_AXI_ID_WIDTH),
692
                        .F_MAX_REQUESTS((1<<(C_AXI_ID_WIDTH))-2))
693
                f_wb(i_clk, i_reset,
694
                                i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr,
695
                                        i_wb_data, i_wb_sel,
696
                                o_wb_ack, o_wb_stall, o_wb_data, o_wb_err,
697
                        f_wb_nreqs, f_wb_nacks, f_wb_outstanding);
698
 
699
        wire    [(C_AXI_ID_WIDTH-1):0]   f_axi_rd_outstanding,
700
                                        f_axi_wr_outstanding,
701
                                        f_axi_awr_outstanding;
702
 
703
        wire    [((1<<C_AXI_ID_WIDTH)-1):0]      f_axi_rd_id_outstanding,
704
                                                f_axi_wr_id_outstanding,
705
                                                f_axi_awr_id_outstanding;
706
 
707
        faxi_master #(
708
                .C_AXI_ID_WIDTH(C_AXI_ID_WIDTH),
709
                .C_AXI_DATA_WIDTH(C_AXI_DATA_WIDTH),
710
                .C_AXI_ADDR_WIDTH(C_AXI_ADDR_WIDTH),
711
                .F_AXI_MAXSTALL(3),
712
                .F_AXI_MAXDELAY(3),
713
                .F_STRICT_ORDER(STRICT_ORDER),
714
                .F_CONSECUTIVE_IDS(1'b1),
715
                .F_OPT_BURSTS(1'b0),
716
                .F_CHECK_IDS(1'b1))
717
                f_axi(.i_clk(i_clk), .i_axi_reset_n(!i_reset),
718
                        // Write address channel
719
                        .i_axi_awready(i_axi_awready),
720
                        .i_axi_awid(   o_axi_awid),
721
                        .i_axi_awaddr( o_axi_awaddr),
722
                        .i_axi_awlen(  o_axi_awlen),
723
                        .i_axi_awsize( o_axi_awsize),
724
                        .i_axi_awburst(o_axi_awburst),
725
                        .i_axi_awlock( o_axi_awlock),
726
                        .i_axi_awcache(o_axi_awcache),
727
                        .i_axi_awprot( o_axi_awprot),
728
                        .i_axi_awqos(  o_axi_awqos),
729
                        .i_axi_awvalid(o_axi_awvalid),
730
                        // Write data channel
731
                        .i_axi_wready( i_axi_wready),
732
                        .i_axi_wdata(  o_axi_wdata),
733
                        .i_axi_wstrb(  o_axi_wstrb),
734
                        .i_axi_wlast(  o_axi_wlast),
735
                        .i_axi_wvalid( o_axi_wvalid),
736
                        // Write response channel
737
                        .i_axi_bid(    i_axi_bid),
738
                        .i_axi_bresp(  i_axi_bresp),
739
                        .i_axi_bvalid( i_axi_bvalid),
740
                        .i_axi_bready( o_axi_bready),
741
                        // Read address channel
742
                        .i_axi_arready(i_axi_arready),
743
                        .i_axi_arid(   o_axi_arid),
744
                        .i_axi_araddr( o_axi_araddr),
745
                        .i_axi_arlen(  o_axi_arlen),
746
                        .i_axi_arsize( o_axi_arsize),
747
                        .i_axi_arburst(o_axi_arburst),
748
                        .i_axi_arlock( o_axi_arlock),
749
                        .i_axi_arcache(o_axi_arcache),
750
                        .i_axi_arprot( o_axi_arprot),
751
                        .i_axi_arqos(  o_axi_arqos),
752
                        .i_axi_arvalid(o_axi_arvalid),
753
                        // Read data channel
754
                        .i_axi_rid(    i_axi_rid),
755
                        .i_axi_rresp(  i_axi_rresp),
756
                        .i_axi_rvalid( i_axi_rvalid),
757
                        .i_axi_rdata(  i_axi_rdata),
758
                        .i_axi_rlast(  i_axi_rlast),
759
                        .i_axi_rready( o_axi_rready),
760
                        // Counts
761
                        .f_axi_rd_outstanding( f_axi_rd_outstanding),
762
                        .f_axi_wr_outstanding( f_axi_wr_outstanding),
763
                        .f_axi_awr_outstanding( f_axi_awr_outstanding),
764
                        // Outstanding ID's
765
                        .f_axi_rd_id_outstanding( f_axi_rd_id_outstanding),
766
                        .f_axi_wr_id_outstanding( f_axi_wr_id_outstanding),
767
                        .f_axi_awr_id_outstanding(f_axi_awr_id_outstanding)
768
                );
769
 
770
 
771
 
772
        //////////////////////////////////////////////
773
        //
774
        //
775
        // Assumptions about the AXI inputs
776
        //
777
        //
778
        //////////////////////////////////////////////
779
 
780
 
781
        //////////////////////////////////////////////
782
        //
783
        //
784
        // Assertions about the AXI4 ouputs
785
        //
786
        //
787
        //////////////////////////////////////////////
788
 
789
        wire    [(LGFIFOLN-1):0] f_last_transaction_id;
790
        assign  f_last_transaction_id = transaction_id- 1;
791
        always @(posedge i_clk)
792
                if (f_past_valid)
793
                begin
794
                        assert(o_axi_awid == f_last_transaction_id);
795
                        if ($past(o_wb_stall))
796
                                assert($stable(o_axi_awid));
797
                end
798
 
799
        // Write response channel
800
        always @(posedge i_clk)
801
                // We keep bready high, so the other condition doesn't
802
                // need to be checked
803
                assert(o_axi_bready);
804
 
805
        // AXI read data channel signals
806
        always @(posedge i_clk)
807
                // We keep o_axi_rready high, so the other condition's
808
                // don't need to be checked here
809
                assert(o_axi_rready);
810
 
811
        //
812
        // Let's look into write requests
813
        //
814
        initial assert(!o_axi_awvalid);
815
        initial assert(!o_axi_wvalid);
816
        always @(posedge i_clk)
817
        if ((f_past_valid)&&($past(i_wb_stb))&&($past(i_wb_we))&&(!$past(o_wb_stall)))
818
        begin
819
                // Following any write request that we accept, awvalid and
820
                // wvalid should both be true
821
                assert(o_axi_awvalid);
822
                assert(o_axi_wvalid);
823
        end
824
 
825
        // Let's assume all responses will come within 120 clock ticks
826
        parameter       [(C_AXI_ID_WIDTH-1):0]   F_AXI_MAXDELAY = 3,
827
                                                F_AXI_MAXSTALL = 3; // 7'd120;
828
        localparam      [(C_AXI_ID_WIDTH):0]     F_WB_MAXDELAY = F_AXI_MAXDELAY + 4;
829
 
830
        //
831
        // AXI write address channel
832
        //
833
        always @(posedge i_clk)
834
        if ((f_past_valid)&&($past(i_wb_cyc))&&(!$past(o_wb_stall)))
835
        begin
836
                if (!$past(i_wb_stb))
837
                        assert(!o_axi_awvalid);
838
                else
839
                        assert(o_axi_awvalid == $past(i_wb_we));
840
        end
841
        //
842
        generate
843
        if (C_AXI_DATA_WIDTH      == DW)
844
        begin
845
                always @(posedge i_clk)
846
                if ((f_past_valid)&&($past(i_wb_cyc))&&($past(i_wb_stb))&&($past(i_wb_we))
847
                        &&(!$past(o_wb_stall)))
848
                        assert(o_axi_awaddr == { $past(i_wb_addr[AW-1:0]), axi_bottom_addr });
849
 
850
        end else if (C_AXI_DATA_WIDTH / DW == 2)
851
        begin
852
 
853
                always @(posedge i_clk)
854
                if ((f_past_valid)&&($past(i_wb_cyc))&&($past(i_wb_stb))&&($past(i_wb_we))
855
                        &&(!$past(o_wb_stall)))
856
                        assert(o_axi_awaddr == { $past(i_wb_addr[AW-1:1]), axi_bottom_addr });
857
 
858
        end else if (C_AXI_DATA_WIDTH / DW == 4)
859
        begin
860
 
861
                always @(posedge i_clk)
862
                if ((f_past_valid)&&($past(i_wb_cyc))&&($past(i_wb_stb))&&($past(i_wb_we))
863
                        &&(!$past(o_wb_stall)))
864
                        assert(o_axi_awaddr == { $past(i_wb_addr[AW-1:2]), axi_bottom_addr });
865
 
866
        end endgenerate
867
 
868
        //
869
        // AXI write data channel
870
        //
871
        always @(posedge i_clk)
872
        if ((f_past_valid)&&($past(i_wb_cyc))&&(!$past(o_wb_stall)))
873
        begin
874
                if (!$past(i_wb_stb))
875
                        assert(!o_axi_wvalid);
876
                else
877
                        assert(o_axi_wvalid == $past(i_wb_we));
878
        end
879
        //
880
        generate
881
        if (C_AXI_DATA_WIDTH == DW)
882
        begin
883
 
884
                always @(posedge i_clk)
885
                if ((f_past_valid)&&($past(i_wb_stb))&&($past(i_wb_we)))
886
                begin
887
                        assert(o_axi_wdata == $past(i_wb_data));
888
                        assert(o_axi_wstrb == $past(i_wb_sel));
889
                end
890
 
891
        end else if (C_AXI_DATA_WIDTH / DW == 2)
892
        begin
893
 
894
                always @(posedge i_clk)
895
                if ((f_past_valid)&&($past(i_wb_stb))&&($past(i_wb_we)))
896
                begin
897
                        case($past(i_wb_addr[0]))
898
                        1'b0: assert(o_axi_wdata[(  DW-1): 0] == $past(i_wb_data));
899
                        1'b1: assert(o_axi_wdata[(2*DW-1):DW] == $past(i_wb_data));
900
                        endcase
901
 
902
                        case($past(i_wb_addr[0]))
903
                        1'b0: assert(o_axi_wstrb == {  no_sel,$past(i_wb_sel)});
904
                        1'b1: assert(o_axi_wstrb == {  $past(i_wb_sel),no_sel});
905
                        endcase
906
                end
907
 
908
        end else if (C_AXI_DATA_WIDTH / DW == 4)
909
        begin
910
 
911
                always @(posedge i_clk)
912
                if ((f_past_valid)&&($past(i_wb_stb))&&(!$past(o_wb_stall))&&($past(i_wb_we)))
913
                begin
914
                        case($past(i_wb_addr[1:0]))
915
                        2'b00: assert(o_axi_wdata[  (DW-1):    0 ] == $past(i_wb_data));
916
                        2'b00: assert(o_axi_wdata[(2*DW-1):(  DW)] == $past(i_wb_data));
917
                        2'b00: assert(o_axi_wdata[(3*DW-1):(2*DW)] == $past(i_wb_data));
918
                        2'b11: assert(o_axi_wdata[(4*DW-1):(3*DW)] == $past(i_wb_data));
919
                        endcase
920
 
921
                        case($past(i_wb_addr[1:0]))
922
                        2'b00: assert(o_axi_wstrb == { {(3){no_sel}},$past(i_wb_sel)});
923
                        2'b01: assert(o_axi_wstrb == { {(2){no_sel}},$past(i_wb_sel), {(1){no_sel}}});
924
                        2'b10: assert(o_axi_wstrb == { {(1){no_sel}},$past(i_wb_sel), {(2){no_sel}}});
925
                        2'b11: assert(o_axi_wstrb == {       $past(i_wb_sel),{(3){no_sel}}});
926
                        endcase
927
                end
928
        end endgenerate
929
 
930
        //
931
        // AXI read address channel
932
        //
933
        initial assert(!o_axi_arvalid);
934
        always @(posedge i_clk)
935
        if ((f_past_valid)&&($past(i_wb_cyc))&&(!$past(o_wb_stall)))
936
        begin
937
                if (!$past(i_wb_stb))
938
                        assert(!o_axi_arvalid);
939
                else
940
                        assert(o_axi_arvalid == !$past(i_wb_we));
941
        end
942
        //
943
        generate
944
        if (C_AXI_DATA_WIDTH == DW)
945
        begin
946
                always @(posedge i_clk)
947
                        if ((f_past_valid)&&($past(i_wb_stb))&&($past(!i_wb_we))
948
                                &&(!$past(o_wb_stall)))
949
                                assert(o_axi_araddr == $past({ i_wb_addr[AW-1:0], axi_bottom_addr }));
950
 
951
        end else if (C_AXI_DATA_WIDTH / DW == 2)
952
        begin
953
 
954
                always @(posedge i_clk)
955
                        if ((f_past_valid)&&($past(i_wb_stb))&&($past(!i_wb_we))
956
                                &&(!$past(o_wb_stall)))
957
                                assert(o_axi_araddr == $past({ i_wb_addr[AW-1:1], axi_bottom_addr }));
958
 
959
        end else if (C_AXI_DATA_WIDTH / DW == 4)
960
        begin
961
                always @(posedge i_clk)
962
                        if ((f_past_valid)&&($past(i_wb_stb))&&($past(!i_wb_we))
963
                                &&(!$past(o_wb_stall)))
964
                                assert(o_axi_araddr == $past({ i_wb_addr[AW-1:2], axi_bottom_addr }));
965
 
966
        end endgenerate
967
 
968
        //
969
        // AXI write response channel
970
        //
971
 
972
 
973
        //
974
        // AXI read data channel signals
975
        //
976
        always @(posedge i_clk)
977
                `ASSUME(f_axi_rd_outstanding <= f_wb_outstanding);
978
        //
979
        always @(posedge i_clk)
980
                `ASSUME(f_axi_rd_outstanding + f_axi_wr_outstanding  <= f_wb_outstanding);
981
        always @(posedge i_clk)
982
                `ASSUME(f_axi_rd_outstanding + f_axi_awr_outstanding <= f_wb_outstanding);
983
        //
984
        always @(posedge i_clk)
985
                `ASSUME(f_axi_rd_outstanding + f_axi_wr_outstanding +2 > f_wb_outstanding);
986
        always @(posedge i_clk)
987
                `ASSUME(f_axi_rd_outstanding + f_axi_awr_outstanding +2 > f_wb_outstanding);
988
 
989
        // Make sure we only create one request at a time
990
        always @(posedge i_clk)
991
                assert((!o_axi_arvalid)||(!o_axi_wvalid));
992
        always @(posedge i_clk)
993
                assert((!o_axi_arvalid)||(!o_axi_awvalid));
994
 
995
        // Now, let's look into that FIFO.  Without it, we know nothing about the ID's
996
 
997
        // Error handling
998
        always @(posedge i_clk)
999
                if (!i_wb_cyc)
1000
                        f_err_state <= 0;
1001
                else if (o_wb_err)
1002
                        f_err_state <= 1;
1003
        always @(posedge i_clk)
1004
                if ((f_past_valid)&&($past(f_err_state))&&(
1005
                                (!$past(o_wb_stall))||(!$past(i_wb_stb))))
1006
                        `ASSUME(!i_wb_stb);
1007
 
1008
        // Head and tail pointers
1009
 
1010
        // The head should only increment when something goes through
1011
        always @(posedge i_clk)
1012
                if ((f_past_valid)&&((!$past(i_wb_stb))||($past(o_wb_stall))))
1013
                        assert($stable(fifo_head));
1014
 
1015
        // Can't overrun the FIFO
1016
        wire    [(LGFIFOLN-1):0] f_fifo_tail_minus_one;
1017
        assign  f_fifo_tail_minus_one = fifo_tail - 1'b1;
1018
        always @(posedge i_clk)
1019
                if ((f_past_valid)&&($past(fifo_head == f_fifo_tail_minus_one)))
1020
                        assert(fifo_head != fifo_tail);
1021
 
1022
        reg                     f_pre_ack;
1023
 
1024
        wire    [(LGFIFOLN-1):0] f_fifo_used;
1025
        assign  f_fifo_used = fifo_head - fifo_tail;
1026
 
1027
        initial assert(fifo_tail == 0);
1028
        initial assert(reorder_fifo_valid        == 0);
1029
        initial assert(reorder_fifo_err          == 0);
1030
        initial f_pre_ack = 1'b0;
1031
        always @(posedge i_clk)
1032
        begin
1033
                f_pre_ack <= (!wb_abort)&&((axi_rd_ack)||(axi_wr_ack));
1034
                if (STRICT_ORDER)
1035
                begin
1036
                        `ASSUME((!axi_rd_ack)||(!axi_wr_ack));
1037
 
1038
                        if (f_past_valid)
1039
                                assert((!$past(i_wb_cyc))
1040
                                        ||(o_wb_ack == $past(f_pre_ack)));
1041
                end
1042
        end
1043
 
1044
        //
1045
        // Verify that there are no outstanding requests outside of the FIFO
1046
        // window.  This should never happen, but the formal tools need to know
1047
        // that.
1048
        //
1049
        always @(*)
1050
        begin
1051
                assert((f_axi_rd_id_outstanding&f_axi_wr_id_outstanding)==0);
1052
                assert((f_axi_rd_id_outstanding&f_axi_awr_id_outstanding)==0);
1053
 
1054
                if (fifo_head == fifo_tail)
1055
                begin
1056
                        assert(f_axi_rd_id_outstanding  == 0);
1057
                        assert(f_axi_wr_id_outstanding  == 0);
1058
                        assert(f_axi_awr_id_outstanding == 0);
1059
                end
1060
 
1061
                for(k=0; k<(1<<LGFIFOLN); k=k+1)
1062
                begin
1063
                        if (      ((fifo_tail < fifo_head)&&(k <  fifo_tail))
1064
                                ||((fifo_tail < fifo_head)&&(k >= fifo_head))
1065
                                ||((fifo_head < fifo_tail)&&(k >= fifo_head)&&(k < fifo_tail))
1066
                                //||((fifo_head < fifo_tail)&&(k >=fifo_tail))
1067
                                )
1068
                        begin
1069
                                assert(f_axi_rd_id_outstanding[k]==0);
1070
                                assert(f_axi_wr_id_outstanding[k]==0);
1071
                                assert(f_axi_awr_id_outstanding[k]==0);
1072
                        end
1073
                end
1074
        end
1075
 
1076
        generate
1077
        if (STRICT_ORDER)
1078
        begin : STRICTREQ
1079
 
1080
                reg     [C_AXI_ID_WIDTH-1:0]     f_last_axi_id;
1081
                wire    [C_AXI_ID_WIDTH-1:0]     f_next_axi_id,
1082
                                                f_expected_last_id;
1083
                assign  f_next_axi_id = f_last_axi_id + 1'b1;
1084
                assign  f_expected_last_id = fifo_head - 1'b1 - f_fifo_used;
1085
 
1086
                initial f_last_axi_id = -1;
1087
                always @(posedge i_clk)
1088
                        if (i_reset)
1089
                                f_last_axi_id = -1;
1090
                        else if ((axi_rd_ack)||(axi_wr_ack))
1091
                                f_last_axi_id <= f_next_axi_id;
1092
                        else if (f_fifo_used == 0)
1093
                                assert(f_last_axi_id == fifo_head-1'b1);
1094
 
1095
                always @(posedge i_clk)
1096
                        if (axi_rd_ack)
1097
                                `ASSUME(i_axi_rid == f_next_axi_id);
1098
                        else if (axi_wr_ack)
1099
                                `ASSUME(i_axi_bid == f_next_axi_id);
1100
        end endgenerate
1101
 
1102
        reg     f_pending, f_returning;
1103
        initial f_pending = 1'b0;
1104
        always @(*)
1105
                f_pending <= (o_axi_arvalid)||(o_axi_awvalid);
1106
        always @(*)
1107
                f_returning <= (axi_rd_ack)||(axi_wr_ack);
1108
 
1109
        reg     [(LGFIFOLN):0]   f_pre_count;
1110
 
1111
        always @(*)
1112
                f_pre_count <= f_axi_awr_outstanding
1113
                        + f_axi_rd_outstanding
1114
                        + reorder_count
1115
                        + { {(LGFIFOLN){1'b0}}, (o_wb_ack) }
1116
                        + { {(LGFIFOLN){1'b0}}, (f_pending) };
1117
        always @(posedge i_clk)
1118
                assert((wb_abort)||(o_wb_err)||(f_pre_count == f_wb_outstanding));
1119
 
1120
        always @(posedge i_clk)
1121
                assert((wb_abort)||(o_wb_err)||(f_fifo_used == f_wb_outstanding
1122
                                        // + {{(LGFIFOLN){1'b0}},f_past_valid)(i_wb_stb)&&(!o_wb_ack)}
1123
                                        - {{(LGFIFOLN){1'b0}},(o_wb_ack)}));
1124
 
1125
        always @(posedge i_clk)
1126
                if (o_axi_wvalid)
1127
                        assert(f_fifo_used != 0);
1128
        always @(posedge i_clk)
1129
                if (o_axi_arvalid)
1130
                        assert(f_fifo_used != 0);
1131
        always @(posedge i_clk)
1132
                if (o_axi_awvalid)
1133
                        assert(f_fifo_used != 0);
1134
 
1135
`endif
1136 2 dgisselq
endmodule

powered by: WebSVN 2.1.0

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