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

Subversion Repositories wb2axip

[/] [wb2axip/] [trunk/] [rtl/] [axilrd2wbsp.v] - Blame information for rev 16

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 16 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    axilrd2wbsp.v (AXI lite to wishbone slave, read channel)
4
//
5
// Project:     Pipelined Wishbone to AXI converter
6
//
7
// Purpose:     Bridge an AXI lite read channel pair to a single wishbone read
8
//              channel.
9
//
10
// Creator:     Dan Gisselquist, Ph.D.
11
//              Gisselquist Technology, LLC
12
//
13
////////////////////////////////////////////////////////////////////////////////
14
//
15
// Copyright (C) 2016-2019, Gisselquist Technology, LLC
16
//
17
// This file is part of the pipelined Wishbone to AXI converter project, a
18
// project that contains multiple bus bridging designs and formal bus property
19
// sets.
20
//
21
// The bus bridge designs and property sets are free RTL designs: you can
22
// redistribute them and/or modify any of them under the terms of the GNU
23
// Lesser General Public License as published by the Free Software Foundation,
24
// either version 3 of the License, or (at your option) any later version.
25
//
26
// The bus bridge designs and property sets are distributed in the hope that
27
// they will be useful, but WITHOUT ANY WARRANTY; without even the implied
28
// warranty of MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29
// GNU Lesser General Public License for more details.
30
//
31
// You should have received a copy of the GNU Lesser General Public License
32
// along with these designs.  (It's in the $(ROOT)/doc directory.  Run make
33
// with no target there if the PDF file isn't present.)  If not, see
34
// <http://www.gnu.org/licenses/> for a copy.
35
//
36
// License:     LGPL, v3, as defined and found on www.gnu.org,
37
//              http://www.gnu.org/licenses/lgpl.html
38
//
39
////////////////////////////////////////////////////////////////////////////////
40
//
41
//
42
`default_nettype        none
43
//
44
module  axilrd2wbsp(i_clk, i_axi_reset_n,
45
        // AXI read address channel signals
46
        o_axi_arready, i_axi_araddr, i_axi_arcache, i_axi_arprot, i_axi_arvalid,
47
        // AXI read data channel signals   
48
        o_axi_rresp, o_axi_rvalid, o_axi_rdata, i_axi_rready,
49
        // We'll share the clock and the reset
50
        o_wb_cyc, o_wb_stb, o_wb_addr,
51
                i_wb_ack, i_wb_stall, i_wb_data, i_wb_err
52
`ifdef  FORMAL
53
        , f_first, f_mid, f_last
54
`endif
55
        );
56
        localparam C_AXI_DATA_WIDTH     = 32;// Width of the AXI R&W data
57
        parameter C_AXI_ADDR_WIDTH      = 28;   // AXI Address width
58
        localparam AW                   = C_AXI_ADDR_WIDTH-2;// WB Address width
59
        parameter LGFIFO                =  3;
60
 
61
        input   wire                    i_clk;  // Bus clock
62
        input   wire                    i_axi_reset_n;  // Bus reset
63
 
64
// AXI read address channel signals
65
        output  reg                     o_axi_arready;  // Read address ready
66
        input   wire    [C_AXI_ADDR_WIDTH-1:0]   i_axi_araddr;   // Read address
67
        input   wire    [3:0]            i_axi_arcache;  // Read Cache type
68
        input   wire    [2:0]            i_axi_arprot;   // Read Protection type
69
        input   wire                    i_axi_arvalid;  // Read address valid
70
 
71
// AXI read data channel signals   
72
        output  reg [1:0]                o_axi_rresp;   // Read response
73
        output  reg                     o_axi_rvalid;  // Read reponse valid
74
        output  wire [C_AXI_DATA_WIDTH-1:0] o_axi_rdata;    // Read data
75
        input   wire                    i_axi_rready;  // Read Response ready
76
 
77
        // We'll share the clock and the reset
78
        output  reg                             o_wb_cyc;
79
        output  reg                             o_wb_stb;
80
        output  reg [(AW-1):0]                   o_wb_addr;
81
        input   wire                            i_wb_ack;
82
        input   wire                            i_wb_stall;
83
        input   [(C_AXI_DATA_WIDTH-1):0] i_wb_data;
84
        input   wire                            i_wb_err;
85
`ifdef  FORMAL
86
        // Output connections only used in formal mode
87
        output  wire    [LGFIFO:0]               f_first;
88
        output  wire    [LGFIFO:0]               f_mid;
89
        output  wire    [LGFIFO:0]               f_last;
90
`endif
91
 
92
        localparam      DW = C_AXI_DATA_WIDTH;
93
 
94
        wire    w_reset;
95
        assign  w_reset = (!i_axi_reset_n);
96
 
97
        reg                     r_stb;
98
        reg     [AW-1:0] r_addr;
99
 
100
        localparam      FLEN=(1<<LGFIFO);
101
 
102
        reg     [DW-1:0] dfifo           [0:(FLEN-1)];
103
        reg                     fifo_full, fifo_empty;
104
 
105
        reg     [LGFIFO:0]       r_first, r_mid, r_last, r_next;
106
        wire    [LGFIFO:0]       w_first_plus_one;
107
        wire    [LGFIFO:0]       next_first, next_last, next_mid, fifo_fill;
108
        reg                     wb_pending, last_ack;
109
        reg     [LGFIFO:0]       wb_outstanding;
110
 
111
 
112
        initial o_wb_cyc = 1'b0;
113
        initial o_wb_stb = 1'b0;
114
        always @(posedge i_clk)
115
        if ((w_reset)||((o_wb_cyc)&&(i_wb_err))||(err_state))
116
                o_wb_stb <= 1'b0;
117
        else if (r_stb || ((i_axi_arvalid)&&(o_axi_arready)))
118
                o_wb_stb <= 1'b1;
119
        else if ((o_wb_cyc)&&(!i_wb_stall))
120
                o_wb_stb <= 1'b0;
121
 
122
        always @(*)
123
                o_wb_cyc = (wb_pending)||(o_wb_stb);
124
 
125
        always @(posedge i_clk)
126
        if (r_stb && !i_wb_stall)
127
                o_wb_addr <= r_addr;
128
        else if ((o_axi_arready)&&((!o_wb_stb)||(!i_wb_stall)))
129
                o_wb_addr <= i_axi_araddr[AW+1:2];
130
 
131
        // Shadow request
132
        // r_stb, r_addr
133
        initial r_stb = 1'b0;
134
        always @(posedge i_clk)
135
        begin
136
                if ((i_axi_arvalid)&&(o_axi_arready)&&(o_wb_stb)&&(i_wb_stall))
137
                begin
138
                        r_stb  <= 1'b1;
139
                        r_addr <= i_axi_araddr[AW+1:2];
140
                end else if ((!i_wb_stall)||(!o_wb_cyc))
141
                        r_stb <= 1'b0;
142
 
143
                if ((w_reset)||(o_wb_cyc)&&(i_wb_err)||(err_state))
144
                        r_stb <= 1'b0;
145
        end
146
 
147
        initial wb_pending     = 0;
148
        initial wb_outstanding = 0;
149
        initial last_ack    = 1;
150
        always @(posedge i_clk)
151
        if ((w_reset)||(!o_wb_cyc)||(i_wb_err)||(err_state))
152
        begin
153
                wb_pending     <= 1'b0;
154
                wb_outstanding <= 0;
155
                last_ack       <= 1;
156
        end else case({ (o_wb_stb)&&(!i_wb_stall), i_wb_ack })
157
        2'b01: begin
158
                wb_outstanding <= wb_outstanding - 1'b1;
159
                wb_pending <= (wb_outstanding >= 2);
160
                last_ack <= (wb_outstanding <= 2);
161
                end
162
        2'b10: begin
163
                wb_outstanding <= wb_outstanding + 1'b1;
164
                wb_pending <= 1'b1;
165
                last_ack <= (wb_outstanding == 0);
166
                end
167
        default: begin end
168
        endcase
169
 
170
        assign  next_first = r_first + 1'b1;
171
        assign  next_last  = r_last + 1'b1;
172
        assign  next_mid   = r_mid + 1'b1;
173
        assign  fifo_fill  = (r_first - r_last);
174
 
175
        initial fifo_full  = 1'b0;
176
        initial fifo_empty = 1'b1;
177
        always @(posedge i_clk)
178
        if (w_reset)
179
        begin
180
                fifo_full  <= 1'b0;
181
                fifo_empty <= 1'b1;
182
        end else case({ (o_axi_rvalid)&&(i_axi_rready),
183
                                (i_axi_arvalid)&&(o_axi_arready) })
184
        2'b01: begin
185
                fifo_full  <= (next_first[LGFIFO-1:0] == r_last[LGFIFO-1:0])
186
                                        &&(next_first[LGFIFO]!=r_last[LGFIFO]);
187
                fifo_empty <= 1'b0;
188
                end
189
        2'b10: begin
190
                fifo_full <= 1'b0;
191
                fifo_empty <= 1'b0;
192
                end
193
        default: begin end
194
        endcase
195
 
196
        initial o_axi_arready = 1'b1;
197
        always @(posedge i_clk)
198
        if (w_reset)
199
                o_axi_arready <= 1'b1;
200
        else if ((o_wb_cyc && i_wb_err) || err_state)
201
                // On any error, drop the ready flag until it's been flushed
202
                o_axi_arready <= 1'b0;
203
        else if ((i_axi_arvalid)&&(o_axi_arready)&&(o_wb_stb)&&(i_wb_stall))
204
                // On any request where we are already busy, r_stb will get
205
                // set and we drop arready
206
                o_axi_arready <= 1'b0;
207
        else if (!o_axi_arready && o_wb_stb && i_wb_stall)
208
                // If we've already stalled on o_wb_stb, remain stalled until
209
                // the bus clears
210
                o_axi_arready <= 1'b0;
211
        else if (fifo_full && (!o_axi_rvalid || !i_axi_rready))
212
                // If the FIFO is full, we must remain not ready until at
213
                // least one acknowledgment is accepted 
214
                o_axi_arready <= 1'b0;
215
        else if ( (!o_axi_rvalid || !i_axi_rready)
216
                        && (i_axi_arvalid && o_axi_arready))
217
                o_axi_arready  <= (next_first[LGFIFO-1:0] != r_last[LGFIFO-1:0])
218
                                        ||(next_first[LGFIFO]==r_last[LGFIFO]);
219
        else
220
                o_axi_arready <= 1'b1;
221
 
222
        initial r_first = 0;
223
        always @(posedge i_clk)
224
        if (w_reset)
225
                r_first <= 0;
226
        else if ((i_axi_arvalid)&&(o_axi_arready))
227
                r_first <= r_first + 1'b1;
228
 
229
        initial r_mid = 0;
230
        always @(posedge i_clk)
231
        if (w_reset)
232
                r_mid <= 0;
233
        else if ((o_wb_cyc)&&((i_wb_ack)||(i_wb_err)))
234
                r_mid <= r_mid + 1'b1;
235
        else if ((err_state)&&(r_mid != r_first))
236
                r_mid <= r_mid + 1'b1;
237
 
238
        initial r_last = 0;
239
        always @(posedge i_clk)
240
        if (w_reset)
241
                r_last <= 0;
242
        else if ((o_axi_rvalid)&&(i_axi_rready))
243
                r_last <= r_last + 1'b1;
244
 
245
        always @(posedge i_clk)
246
        if ((o_wb_cyc)&&((i_wb_ack)||(i_wb_err)))
247
                dfifo[r_mid[(LGFIFO-1):0]] <= i_wb_data;
248
 
249
        reg     [LGFIFO:0]       err_loc;
250
        always @(posedge i_clk)
251
        if ((o_wb_cyc)&&(i_wb_err))
252
                err_loc <= r_mid;
253
 
254
        wire    [DW-1:0] read_data;
255
 
256
        assign  read_data = dfifo[r_last[LGFIFO-1:0]];
257
        assign  o_axi_rdata = read_data[DW-1:0];
258
        initial o_axi_rresp = 2'b00;
259
        always @(posedge i_clk)
260
        if (w_reset)
261
                o_axi_rresp <= 0;
262
        else if ((!o_axi_rvalid)||(i_axi_rready))
263
        begin
264
                if ((!err_state)&&((!o_wb_cyc)||(!i_wb_err)))
265
                        o_axi_rresp <= 2'b00;
266
                else if ((!err_state)&&(o_wb_cyc)&&(i_wb_err))
267
                begin
268
                        if (o_axi_rvalid)
269
                                o_axi_rresp <= (r_mid == next_last) ? 2'b10 : 2'b00;
270
                        else
271
                                o_axi_rresp <= (r_mid == r_last) ? 2'b10 : 2'b00;
272
                end else if (err_state)
273
                begin
274
                        if (next_last == err_loc)
275
                                o_axi_rresp <= 2'b10;
276
                        else if (o_axi_rresp[1])
277
                                o_axi_rresp <= 2'b11;
278
                end else
279
                        o_axi_rresp <= 0;
280
        end
281
 
282
 
283
        reg     err_state;
284
        initial err_state  = 0;
285
        always @(posedge i_clk)
286
        if (w_reset)
287
                err_state <= 0;
288
        else if (r_first == r_last)
289
                err_state <= 0;
290
        else if ((o_wb_cyc)&&(i_wb_err))
291
                err_state <= 1'b1;
292
 
293
        initial o_axi_rvalid = 1'b0;
294
        always @(posedge i_clk)
295
        if (w_reset)
296
                o_axi_rvalid <= 0;
297
        else if ((o_wb_cyc)&&((i_wb_ack)||(i_wb_err)))
298
                o_axi_rvalid <= 1'b1;
299
        else if ((o_axi_rvalid)&&(i_axi_rready))
300
        begin
301
                if (err_state)
302
                        o_axi_rvalid <= (next_last != r_first);
303
                else
304
                        o_axi_rvalid <= (next_last != r_mid);
305
        end
306
 
307
        // Make Verilator happy
308
        // verilator lint_off UNUSED
309
        // verilator lint_on  UNUSED
310
 
311
`ifdef  FORMAL
312
        reg     f_past_valid;
313
        initial f_past_valid = 1'b0;
314
        always @(posedge i_clk)
315
                f_past_valid <= 1'b1;
316
 
317
        always @(*)
318
        if (!f_past_valid)
319
                assume(w_reset);
320
 
321
        always @(*)
322
        if (err_state)
323
                assert(!o_axi_arready);
324
 
325
        always @(*)
326
        if (err_state)
327
                assert((!o_wb_cyc)&&(!o_axi_arready));
328
 
329
        always @(*)
330
        if ((fifo_empty)&&(!w_reset))
331
                assert((!fifo_full)&&(r_first == r_last)&&(r_mid == r_last));
332
 
333
        always @(*)
334
        if (fifo_full)
335
                assert((!fifo_empty)
336
                        &&(r_first[LGFIFO-1:0] == r_last[LGFIFO-1:0])
337
                        &&(r_first[LGFIFO] != r_last[LGFIFO]));
338
 
339
        always @(*)
340
        assert(fifo_fill <= (1<<LGFIFO));
341
 
342
        always @(*)
343
        if (fifo_full)
344
                assert(!o_axi_arready);
345
        always @(*)
346
                assert(fifo_full == (fifo_fill == (1<<LGFIFO)));
347
        always @(*)
348
        if (fifo_fill == (1<<LGFIFO))
349
                assert(!o_axi_arready);
350
        always @(*)
351
                assert(wb_pending == (wb_outstanding != 0));
352
 
353
        always @(*)
354
                assert(last_ack == (wb_outstanding <= 1));
355
 
356
 
357
        assign  f_first = r_first;
358
        assign  f_mid   = r_mid;
359
        assign  f_last  = r_last;
360
 
361
        wire    [LGFIFO:0]       f_wb_nreqs, f_wb_nacks, f_wb_outstanding;
362
        fwb_master #(
363
                .AW(AW), .DW(DW), .F_LGDEPTH(LGFIFO+1)
364
                ) fwb(i_clk, w_reset,
365
                o_wb_cyc, o_wb_stb, 1'b0, o_wb_addr, 32'h0, 4'h0,
366
                        i_wb_ack, i_wb_stall, i_wb_data, i_wb_err,
367
                f_wb_nreqs,f_wb_nacks, f_wb_outstanding);
368
 
369
        always @(*)
370
        if (o_wb_cyc)
371
                assert(f_wb_outstanding == wb_outstanding);
372
 
373
        always @(*)
374
        if (o_wb_cyc)
375
                assert(wb_outstanding <= (1<<LGFIFO));
376
 
377
        wire    [LGFIFO:0]       wb_fill;
378
        assign  wb_fill = r_first - r_mid;
379
        always @(*)
380
                assert(wb_fill <= fifo_fill);
381
        always @(*)
382
        if (o_wb_stb)
383
                assert(wb_outstanding+1+((r_stb)?1:0) == wb_fill);
384
 
385
        else if (o_wb_cyc)
386
                assert(wb_outstanding == wb_fill);
387
 
388
        always @(*)
389
        if (r_stb)
390
        begin
391
                assert(o_wb_stb);
392
                assert(!o_axi_arready);
393
        end
394
 
395
        wire    [LGFIFO:0]       f_axi_rd_outstanding,
396
                                f_axi_wr_outstanding,
397
                                f_axi_awr_outstanding;
398
 
399
        faxil_slave #(
400
                .C_AXI_ADDR_WIDTH(C_AXI_ADDR_WIDTH),
401
                .F_LGDEPTH(LGFIFO+1),
402
                .F_OPT_NO_WRITES(1'b1),
403
                .F_AXI_MAXWAIT(0),
404
                .F_AXI_MAXDELAY(0)
405
                ) faxil(i_clk, i_axi_reset_n,
406
                //
407
                // AXI write address channel signals
408
                1'b0, i_axi_araddr, i_axi_arcache, i_axi_arprot, 1'b0,
409
                // AXI write data channel signals
410
                1'b0, 32'h0, 4'h0, 1'b0,
411
                // AXI write response channel signals
412
                2'b00, 1'b0, 1'b0,
413
                // AXI read address channel signals
414
                o_axi_arready, i_axi_araddr, i_axi_arcache, i_axi_arprot,
415
                        i_axi_arvalid,
416
                // AXI read data channel signals
417
                o_axi_rresp, o_axi_rvalid, o_axi_rdata, i_axi_rready,
418
                f_axi_rd_outstanding, f_axi_wr_outstanding,
419
                f_axi_awr_outstanding);
420
 
421
        always @(*)
422
                assert(f_axi_wr_outstanding == 0);
423
        always @(*)
424
                assert(f_axi_awr_outstanding == 0);
425
        always @(*)
426
                assert(f_axi_rd_outstanding == fifo_fill);
427
 
428
        wire    [LGFIFO:0]       f_mid_minus_err, f_err_minus_last,
429
                                f_first_minus_err;
430
        assign  f_mid_minus_err  = f_mid - err_loc;
431
        assign  f_err_minus_last = err_loc - f_last;
432
        assign  f_first_minus_err = f_first - err_loc;
433
        always @(*)
434
        if (o_axi_rvalid)
435
        begin
436
                if (!err_state)
437
                        assert(!o_axi_rresp[1]);
438
                else if (err_loc == f_last)
439
                        assert(o_axi_rresp == 2'b10);
440
                else if (f_err_minus_last < (1<<LGFIFO))
441
                        assert(!o_axi_rresp[1]);
442
                else
443
                        assert(o_axi_rresp[1]);
444
        end
445
 
446
        always @(*)
447
        if (err_state)
448
                assert(o_axi_rvalid == (r_first != r_last));
449
        else
450
                assert(o_axi_rvalid == (r_mid != r_last));
451
 
452
        always @(*)
453
        if (err_state)
454
                assert(f_first_minus_err <= (1<<LGFIFO));
455
 
456
        always @(*)
457
        if (err_state)
458
                assert(f_first_minus_err != 0);
459
 
460
        always @(*)
461
        if (err_state)
462
                assert(f_mid_minus_err <= f_first_minus_err);
463
 
464
        always @(*)
465
        if ((f_past_valid)&&(i_axi_reset_n)&&(f_axi_rd_outstanding > 0))
466
        begin
467
                if (err_state)
468
                        assert((!o_wb_cyc)&&(f_wb_outstanding == 0));
469
                else if (!o_wb_cyc)
470
                        assert((o_axi_rvalid)&&(f_axi_rd_outstanding>0)
471
                                        &&(wb_fill == 0));
472
        end
473
 
474
        // WB covers
475
        always @(*)
476
                cover(o_wb_cyc && o_wb_stb);
477
 
478
        always @(*)
479
        if (LGFIFO > 2)
480
                cover(o_wb_cyc && f_wb_outstanding > 2);
481
 
482
        always @(posedge i_clk)
483
                cover(o_wb_cyc && i_wb_ack
484
                        && $past(o_wb_cyc && i_wb_ack)
485
                        && $past(o_wb_cyc && i_wb_ack,2));
486
 
487
        // AXI covers
488
        always @(*)
489
                cover(o_axi_rvalid && i_axi_rready);
490
 
491
        always @(posedge i_clk)
492
                cover(i_axi_arvalid && o_axi_arready
493
                        && $past(i_axi_arvalid && o_axi_arready)
494
                        && $past(i_axi_arvalid && o_axi_arready,2));
495
 
496
        always @(posedge i_clk)
497
                cover(o_axi_rvalid && i_axi_rready
498
                        && $past(o_axi_rvalid && i_axi_rready)
499
                        && $past(o_axi_rvalid && i_axi_rready,2));
500
`endif
501
endmodule

powered by: WebSVN 2.1.0

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