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

Subversion Repositories wb2axip

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 10 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    fav_slave.v
4
//
5
// Project:     Pipelined Wishbone to AXI converter
6
//
7
// Purpose:     Formal properties of an Avalon slave.  These are the properties
8
//              the module owning the slave should use: they assume inputs from
9
//      the bus master, and assert that the outputs from the slave are valid.
10
//
11
// Creator:     Dan Gisselquist, Ph.D.
12
//              Gisselquist Technology, LLC
13
//
14
////////////////////////////////////////////////////////////////////////////////
15
//
16
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
17
//
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  fav_slave(i_clk, i_reset,
46
                i_av_read,
47
                i_av_write,
48
                i_av_address,
49
                i_av_writedata,
50
                        i_av_byteenable,
51
                i_av_lock,
52
                i_av_waitrequest,       // = wb_stall
53
                //
54
                i_av_writeresponsevalid,
55
                //
56
                i_av_readdatavalid,
57
                i_av_readdata,
58
                i_av_response,  // Error response = 2'b11
59
                f_rd_nreqs, f_rd_nacks, f_rd_outstanding,
60
                f_wr_nreqs, f_wr_nacks, f_wr_outstanding);
61
        parameter       DW=32, AW=14;
62
        parameter       F_LGDEPTH=6;
63
        parameter       [(F_LGDEPTH-1):0]        F_MAX_REQUESTS = 62;
64
        input   wire                    i_clk, i_reset;
65
        input   wire                    i_av_read;
66
        input   wire                    i_av_write;
67
        input   wire    [(AW-1):0]       i_av_address;
68
        input   wire    [(DW-1):0]       i_av_writedata;
69
        input   wire    [(DW/8-1):0]     i_av_byteenable;
70
        input   wire                    i_av_lock;
71
        //
72
        input   wire                    i_av_waitrequest;
73
        input   wire                    i_av_writeresponsevalid;
74
        input   wire                    i_av_readdatavalid;
75
        input   wire    [(DW-1):0]       i_av_readdata;
76
        input   wire    [1:0]            i_av_response;
77
        //
78
        output  reg     [(F_LGDEPTH-1):0] f_rd_nreqs, f_rd_nacks;
79
        output  wire    [(F_LGDEPTH-1):0] f_rd_outstanding;
80
        output  reg     [(F_LGDEPTH-1):0] f_wr_nreqs, f_wr_nacks;
81
        output  wire    [(F_LGDEPTH-1):0] f_wr_outstanding;
82
 
83
        assert  property(F_MAX_REQUESTS < {(F_LGDEPTH){1'b1}});
84
 
85
 
86
 
87
        reg     f_past_valid;
88
        initial f_past_valid = 1'b0;
89
        always @(posedge i_clk)
90
                f_past_valid <= 1'b1;
91
        always @(*)
92
                assert((f_past_valid) || (i_reset));
93
 
94 16 dgisselq
        wire    [AW+(DW/8):0]    f_rd_request;
95
        assign  f_rd_request = { i_av_read,  i_av_byteenable, i_av_address };
96 10 dgisselq
 
97
        wire    [(AW+DW+(DW/8)):0]       f_wr_request;
98
        assign  f_wr_request = { i_av_write, i_av_address, i_av_writedata,
99
                                        i_av_byteenable };
100
 
101 16 dgisselq
        /////////////////////////////
102
        //
103
        // Require that nothing changes, save on a clock tick.
104
        //
105
        // This is only required if yosys is using the clk2fflogic
106
        // command, a command only required if multiple clocks are
107
        // in use.  Since this can greatly slow down formal proofs,
108
        // we limit any code associated with this option to only
109
        // those times the option is in play.
110
        //
111
        /////////////////////////////
112 10 dgisselq
 
113 16 dgisselq
        generate if (F_OPT_CLK2FFLOGIC)
114 10 dgisselq
        begin
115 16 dgisselq
                always @($global_clock)
116
                if ((f_past_valid)&&(!$rose(i_clk)))
117
                begin
118
                        assume($stable(f_rd_request));
119
                        assume($stable(f_wr_request));
120
                        assume($stable(i_av_lock));
121 10 dgisselq
 
122 16 dgisselq
                        assert($stable(i_av_readdatavalid));
123
                        assert($stable(i_av_writeresponsevalid));
124
                        assert($stable(i_av_readdata));
125
                        assert($stable(i_av_response));
126
                end
127
        end endgenerate
128 10 dgisselq
 
129 16 dgisselq
        /////////////////////////////
130
        //
131
        // Assumptions about a slave's inputs
132
        //
133
        /////////////////////////////
134
 
135
 
136
        initial assume(!i_av_read);
137
        initial assume(!i_av_write);
138
        initial assume(!i_av_lock);
139
        //
140
        initial assert(!i_av_readdatavalid);
141
        initial assert(!i_av_writeresponsevalid);
142
        //
143
 
144 10 dgisselq
        always @(posedge i_clk)
145 16 dgisselq
                if (i_reset)
146
                begin
147
                        assume(!i_av_read);
148
                        assume(!i_av_write);
149
                        assume(!i_av_lock);
150
                end
151
 
152
        always @(*)
153
                if (i_av_write)
154
                        assume(|i_av_byteenable);
155
 
156
        // It is a protocol violation to issue both read and write requests
157
        // on the same clock
158
        always @(*)
159
                assume((!i_av_read)||(!i_av_write));
160
 
161
        // Once a read request has been placed upon the bus, it will remain
162
        // there until wait request goes low
163
        always @(posedge i_clk)
164
        if ((f_past_valid)&&($past(i_av_waitrequest))&&($past(i_av_read)))
165
                assume((i_reset)||(f_rd_request == $past(f_rd_request)));
166
 
167
        // Same thing for a write request
168
        always @(posedge i_clk)
169
        if ((f_past_valid)&&($past(i_av_waitrequest))&&($past(i_av_write)))
170
                assume((i_reset)||(f_wr_request == $past(f_wr_request)));
171
 
172
        // A lock request can only be asserted at the same time a read or
173
        // write request is being made.
174
        always @(posedge i_clk)
175 10 dgisselq
                if ((f_past_valid)&&(!$past(i_av_lock)))
176
                        assume((!i_av_lock)||(i_av_read)||(i_av_write));
177
 
178 16 dgisselq
        // A lock request can only be de-asserted following the last read
179
        // or write request made with it asserted
180
        always @(posedge i_clk)
181
                if ((f_past_valid)&&($past(i_av_lock)
182
                                &&(!i_av_read)&&(!i_av_write)))
183
                        assume((i_reset)||(i_av_lock)
184
                                ||(i_av_read)||(i_av_write));
185
 
186
 
187
        /////////////////////////////
188
        //
189
        // Internal state variables
190
        //
191
        /////////////////////////////
192
 
193
        // Count the number of read requests
194 10 dgisselq
        initial f_rd_nreqs = 0;
195
        always @(posedge i_clk)
196
                if (i_reset)
197
                        f_rd_nreqs <= 0;
198
                else if ((i_av_read)&&(!i_av_waitrequest))
199
                        f_rd_nreqs <= f_rd_nreqs + 1'b1;
200
 
201 16 dgisselq
        // Count the number of read acknowledgements
202 10 dgisselq
        initial f_rd_nacks = 0;
203
        always @(posedge i_clk)
204
                if (i_reset)
205
                        f_rd_nacks <= 0;
206
                else if (i_av_readdatavalid)
207
                        f_rd_nacks <= f_rd_nacks + 1'b1;
208
 
209 16 dgisselq
        // The difference between read requests and acknowledgements is
210
        // the number of outstanding read requests
211
        assign  f_rd_outstanding = (i_reset) ? 0 : (f_rd_nreqs - f_rd_nacks);
212 10 dgisselq
 
213 16 dgisselq
        // Count the number of write requests
214 10 dgisselq
        initial f_wr_nreqs = 0;
215
        always @(posedge i_clk)
216
                if (i_reset)
217
                        f_wr_nreqs <= 0;
218
                else if ((i_av_write)&&(!i_av_waitrequest))
219
                        f_wr_nreqs <= f_wr_nreqs + 1'b1;
220
 
221 16 dgisselq
        // Count the number of write acknowledgements/responses
222 10 dgisselq
        initial f_wr_nacks = 0;
223
        always @(posedge i_clk)
224
                if (i_reset)
225
                        f_wr_nacks <= 0;
226
                else if (i_av_writeresponsevalid)
227
                        f_wr_nacks <= f_wr_nacks + 1'b1;
228
 
229
        assign  f_wr_outstanding = f_wr_nreqs - f_wr_nacks;
230
 
231
 
232
        initial assume(!i_av_read);
233
        initial assume(!i_av_write);
234
        initial assume(!i_av_lock);
235
        //
236
        initial assert(!i_av_readdatavalid);
237
        initial assert(!i_av_writeresponsevalid);
238
        //
239
 
240
        always @(posedge i_clk)
241
                if (i_reset)
242
                begin
243
                        assume(!i_av_read);
244
                        assume(!i_av_write);
245
                end
246
 
247
        always @(posedge i_clk)
248
                if ((f_past_valid)&&($past(i_reset)))
249
                begin
250
                        assert(!i_av_readdatavalid);
251
                        assert(!i_av_writeresponsevalid);
252
                        assert(f_rd_nreqs == 0);
253
                        assert(f_rd_nacks == 0);
254
                        assert(f_wr_nreqs == 0);
255
                        assert(f_wr_nacks == 0);
256
                end
257
 
258 16 dgisselq
        // Just like a read and write request cannot both be made at the same
259
        // time, neither can both responses come back at the same time
260 10 dgisselq
        always @(*)
261
                assert((!i_av_writeresponsevalid)||(!i_av_readdatavalid));
262
 
263 16 dgisselq
        // If nothing is outstanding, then there should be no responses.
264
        // If i_reset is asserted, a response may have been registered, and
265
        // so may still return on this clock.
266 10 dgisselq
        always @(posedge i_clk)
267 16 dgisselq
                if ((f_rd_outstanding == 0)&&(!i_reset)
268
                                &&((!i_av_read)||(i_av_waitrequest)))
269 10 dgisselq
                        assert(!i_av_readdatavalid);
270
 
271
        always @(posedge i_clk)
272 16 dgisselq
                if ((f_wr_outstanding == 0)&&(!i_reset)
273
                                &&((!i_av_write)||(i_av_waitrequest)))
274 10 dgisselq
                        assert(!i_av_writeresponsevalid);
275
 
276 16 dgisselq
        always @(*)
277
                assert({1'b0, f_wr_outstanding} + { 1'b0, f_rd_outstanding }
278
                        < F_MAX_REQUESTS);
279
 
280
        generate if (F_OPT_MAX_STALL > 0)
281
        begin
282
                reg     [(LGWAIT-1):0]   stall_count;
283
 
284
                initial stall_count = 0;
285
                always @(posedge i_clk)
286
                        if (i_reset)
287
                                stall_count <= 0;
288
                        else if (((i_av_read)||(i_av_write))&&(i_av_waitrequest))
289
                                stall_count <= stall_count + 1'b1;
290
                        else
291
                                stall_count <= 0;
292
 
293
                always @(*)
294
                        assert((i_reset)||(stall_count < F_OPT_MAX_STALL));
295
        end endgenerate
296
 
297
        generate if (F_OPT_MAX_WAIT > 0)
298
        begin
299
                reg     [(LGWAIT-1):0]   read_wait, write_wait;
300
 
301
                //
302
                // Insist on a minimum amount of time to wait for a *read*
303
                // response.
304
                //
305
                always @(posedge i_clk)
306
                        if (i_reset)
307
                                read_wait <= 0;
308
                        else if ((i_av_readdatavalid)
309
                                        ||((i_av_read)&&(!i_av_waitrequest)))
310
                                read_wait <= 0;
311
                        else if (f_rd_outstanding > 0)
312
                                read_wait <= read_wait + 1'b1;
313
 
314
                always @(*)
315
                        assert((i_av_readdatavalid)
316
                                ||(f_rd_outstanding == 0)
317
                                ||(read_wait < F_OPT_MAX_WAIT));
318
 
319
 
320
                //
321
                // Insist on a minimum amount of time to wait for a *write*
322
                // response.
323
                //
324
                always @(posedge i_clk)
325
                        if (i_reset)
326
                                write_wait <= 0;
327
                        else if ((i_av_writeresponsevalid)
328
                                        ||((i_av_write)&&(!i_av_waitrequest)))
329
                                write_wait <= 0;
330
                        else if (f_wr_outstanding > 0)
331
                                write_wait <= write_wait + 1'b1;
332
 
333
                always @(*)
334
                        assert((i_av_writeresponsevalid)
335
                                ||(f_wr_outstanding == 0)
336
                                ||(write_wait < F_OPT_MAX_WAIT));
337
        end endgenerate
338
 
339 10 dgisselq
endmodule

powered by: WebSVN 2.1.0

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