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

Subversion Repositories dblclockfft

[/] [dblclockfft/] [trunk/] [sw/] [bitreverse.cpp] - Blame information for rev 37

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 36 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    bitreverse.cpp
4
//
5
// Project:     A General Purpose Pipelined FFT Implementation
6
//
7
// Purpose:     
8
//
9
// Creator:     Dan Gisselquist, Ph.D.
10
//              Gisselquist Technology, LLC
11
//
12
////////////////////////////////////////////////////////////////////////////////
13
//
14
// Copyright (C) 2015-2018, Gisselquist Technology, LLC
15
//
16
// This program is free software (firmware): you can redistribute it and/or
17
// modify it under the terms of  the GNU General Public License as published
18
// by the Free Software Foundation, either version 3 of the License, or (at
19
// your option) any later version.
20
//
21
// This program is distributed in the hope that it will be useful, but WITHOUT
22
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
23
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
24
// for more details.
25
//
26
// You should have received a copy of the GNU General Public License along
27 37 dgisselq
// with this program.  (It's in the $(ROOT)/doc directory.  Run make with no
28 36 dgisselq
// target there if the PDF file isn't present.)  If not, see
29
// <http://www.gnu.org/licenses/> for a copy.
30
//
31
// License:     GPL, v3, as defined and found on www.gnu.org,
32
//              http://www.gnu.org/licenses/gpl.html
33
//
34
//
35
////////////////////////////////////////////////////////////////////////////////
36
//
37
//
38
#define _CRT_SECURE_NO_WARNINGS   //  ms vs 2012 doesn't like fopen
39
#include <stdio.h>
40
#include <stdlib.h>
41
 
42
#ifdef _MSC_VER //  added for ms vs compatibility
43
 
44
#include <io.h>
45
#include <direct.h>
46
#define _USE_MATH_DEFINES
47
#else
48
// And for G++/Linux environment
49
 
50
#include <unistd.h>     // Defines the R_OK/W_OK/etc. macros
51
#include <sys/stat.h>
52
#endif
53
 
54
#include <string.h>
55
#include <string>
56
#include <math.h>
57
#include <ctype.h>
58
#include <assert.h>
59
 
60
#include "defaults.h"
61
#include "legal.h"
62
#include "bitreverse.h"
63
 
64
void    build_snglbrev(const char *fname, const bool async_reset) {
65
        FILE    *fp = fopen(fname, "w");
66
        if (NULL == fp) {
67
                fprintf(stderr, "Could not open \'%s\' for writing\n", fname);
68
                perror("O/S Err was:");
69
                return;
70
        }
71
 
72
        std::string     resetw("i_reset");
73
        if (async_reset)
74
                resetw = std::string("i_areset_n");
75
 
76
        char    *modulename = strdup(fname), *pslash;
77
        modulename[strlen(modulename)-2] = '\0';
78
        pslash = strrchr(modulename, '/');
79
        if (pslash != NULL)
80
                strcpy(modulename, pslash+1);
81
 
82
        fprintf(fp,
83
SLASHLINE
84
"//\n"
85
"// Filename:\t%s.v\n"
86
"//\n"
87
"// Project:\t%s\n"
88
"//\n"
89
"// Purpose:\tThis module bitreverses a pipelined FFT input.  It differes\n"
90
"//             from the dblreverse module in that this is just a simple and\n"
91
"//     straightforward bitreverse, rather than one written to handle two\n"
92
"//     words at once.\n"
93
"//\n"
94
"//\n%s"
95
"//\n", modulename, prjname, creator);
96
        fprintf(fp, "%s", cpyleft);
97
        fprintf(fp, "//\n//\n`default_nettype\tnone\n//\n");
98
        fprintf(fp,
99
"module %s(i_clk, %s, i_ce, i_in, o_out, o_sync);\n"
100
        "\tparameter\t\t\tLGSIZE=%d, WIDTH=24;\n"
101 37 dgisselq
        "\tinput\twire\t\t\ti_clk, %s, i_ce;\n"
102
        "\tinput\twire\t[(2*WIDTH-1):0]\ti_in;\n"
103
        "\toutput\treg\t[(2*WIDTH-1):0]\to_out;\n"
104 36 dgisselq
        "\toutput\treg\t\t\to_sync;\n", modulename, resetw.c_str(),
105
                TST_DBLREVERSE_LGSIZE,
106
                resetw.c_str());
107
 
108
        fprintf(fp,
109
"       reg     [(LGSIZE):0]    wraddr;\n"
110
"       wire    [(LGSIZE):0]    rdaddr;\n"
111
"\n"
112
"       reg     [(2*WIDTH-1):0] brmem   [0:((1<<(LGSIZE+1))-1)];\n"
113
"\n"
114
"       genvar  k;\n"
115
"       generate for(k=0; k<LGSIZE; k=k+1)\n"
116 37 dgisselq
"       begin : DBL\n"
117 36 dgisselq
"               assign rdaddr[k] = wraddr[LGSIZE-1-k];\n"
118 37 dgisselq
"       end endgenerate\n"
119 36 dgisselq
"       assign  rdaddr[LGSIZE] = !wraddr[LGSIZE];\n"
120
"\n"
121
"       reg     in_reset;\n"
122
"\n"
123
"       initial in_reset = 1'b1;\n");
124
 
125
        if (async_reset)
126
                fprintf(fp, "\talways @(posedge i_clk, negedge i_areset_n)\n\t\tif (!i_areset_n)\n");
127
        else
128
                fprintf(fp, "\talways @(posedge i_clk)\n\t\tif (i_reset)\n");
129
        fprintf(fp,
130
"                       in_reset <= 1'b1;\n"
131
"               else if ((i_ce)&&(&wraddr[(LGSIZE-1):0]))\n"
132
"                       in_reset <= 1'b0;\n"
133
"\n"
134
"       initial wraddr = 0;\n");
135
 
136
        if (async_reset)
137
                fprintf(fp, "\talways @(posedge i_clk, negedge i_areset_n)\n\t\tif (!i_areset_n)\n");
138
        else
139
                fprintf(fp, "\talways @(posedge i_clk)\n\t\tif (i_reset)\n");
140
        fprintf(fp,
141
"                       wraddr <= 0;\n"
142
"               else if (i_ce)\n"
143
"               begin\n"
144
"                       brmem[wraddr] <= i_in;\n"
145
"                       wraddr <= wraddr + 1;\n"
146
"               end\n"
147
"\n"
148
"       always @(posedge i_clk)\n"
149
"               if (i_ce) // If (i_reset) we just output junk ... not a problem\n"
150
"                       o_out <= brmem[rdaddr]; // w/o a sync pulse\n"
151
"\n"
152
"       initial o_sync = 1'b0;\n");
153
 
154
        if (async_reset)
155
                fprintf(fp, "\talways @(posedge i_clk, negedge i_areset_n)\n\t\tif (!i_areset_n)\n");
156
        else
157
                fprintf(fp, "\talways @(posedge i_clk)\n\t\tif (i_reset)\n");
158
        fprintf(fp,
159
"                       o_sync <= 1'b0;\n"
160
"               else if ((i_ce)&&(!in_reset))\n"
161
"                       o_sync <= (wraddr[(LGSIZE-1):0] == 0);\n"
162
"\n");
163
 
164
 
165
        if (formal_property_flag) {
166
                fprintf(fp,
167
"`ifdef\tFORMAL\n"
168 37 dgisselq
"`define\tASSERT        assert\n"
169 36 dgisselq
"`ifdef BITREVERSE\n"
170 37 dgisselq
"`define\tASSUME        assume\n");
171 36 dgisselq
                if (async_reset)
172
                        fprintf(fp,
173
                "\n\talways @($global_clock)\n"
174
                        "\t\tassume(i_clk != $past(i_clk));\n\n");
175
 
176
                fprintf(fp,
177
"`else\n"
178
"`define\tASSUME        assert\n"
179
"`endif\n"
180
"\n"
181
        "\treg  f_past_valid;\n"
182
        "\tinitial      f_past_valid = 1'b0;\n"
183
        "\talways @(posedge i_clk)\n"
184
                "\t\tf_past_valid <= 1'b1;\n\n");
185
 
186
                if (async_reset)
187
                        fprintf(fp,
188
        "\tinitial      `ASSUME(!i_areset_n);\n"
189
        "\talways @($global_clock)\n"
190
        "\tif (!$rose(i_clk)))\n"
191
                "\t\t`ASSERT(!$rose(i_areset_n));\n\n"
192
        "\talways @($global_clock)\n"
193
        "\tif (!$rose(i_clk))\n"
194
        "\tbegin\n"
195
                "\t\t`ASSUME($stable(i_ce));\n"
196
                "\t\t`ASSUME($stable(i_in));\n"
197
                "\t\t//\n"
198
                "\t\tif (i_areset_n)\n"
199
                "\t\tbegin\n"
200
                "\t\t\t`ASSERT($stable(o_out));\n"
201
                "\t\t\t`ASSERT($stable(o_sync));\n"
202
                "\t\tend\n"
203
        "\tend\n"
204
"\n"
205
        "\talways @(posedge i_clk)\n"
206
                "\tif ((!f_past_valid)||(!i_areset_n))\n"
207
                "\tbegin\n");
208
                else
209
                        fprintf(fp,
210
        "\tinitial      `ASSUME(i_reset);\n"
211
        "\talways @(posedge i_clk)\n"
212
                "\tif ((!f_past_valid)||($past(i_reset)))\n"
213
                "\tbegin\n");
214
 
215
                fprintf(fp,
216
                "\t\t`ASSERT(wraddr == 0);\n"
217
                "\t\t`ASSERT(in_reset);\n"
218
                "\t\t`ASSERT(!o_sync);\n");
219
                fprintf(fp, "\tend\n");
220
 
221
 
222
                fprintf(fp, "`ifdef     BITREVERSE\n"
223
                                "\talways @(posedge i_clk)\n"
224
                                "\t\tassume((i_ce)||($past(i_ce))||($past(i_ce,2)));\n"
225
                                "`endif // BITREVERSE\n\n");
226
 
227
                fprintf(fp,
228
"\t\t(* anyconst *) reg [LGSIZE:0]\tf_const_addr;\n"
229
"\t\twire\t[LGSIZE:0]\tf_reversed_addr;\n"
230
"\t\treg\t              f_addr_loaded;\n"
231
"\t\treg\t[(2*WIDTH-1):0]\tf_addr_value;\n"
232
"\n"
233
"\t\tgenerate for(k=0; k<LGSIZE; k=k+1)\n"
234
"\t\t\tassign\tf_reversed_addr[k] = f_const_addr[LGSIZE-1-k];\n"
235
"\t\tendgenerate\n"
236
"\t\tassign\tf_reversed_addr[LGSIZE] = f_const_addr[LGSIZE];\n"
237
"\n"
238
"\t\tinitial\tf_addr_loaded = 1'b0;\n"
239
"\t\talways @(posedge i_clk)\n"
240
"\t\tif (i_reset)\n"
241
"\t\t\tf_addr_loaded <= 1'b0;\n"
242
"\t\telse if (i_ce)\n"
243
"\t\tbegin\n"
244
"\t\t\tif (wraddr == f_const_addr)\n"
245
"\t\t\t\tf_addr_loaded <= 1'b1;\n"
246
"\t\t\telse if (rdaddr == f_const_addr)\n"
247
"\t\t\t\tf_addr_loaded <= 1'b0;\n"
248
"\t\tend\n"
249
"\n"
250
"\t\talways @(posedge i_clk)\n"
251
"\t\tif ((i_ce)&&(wraddr == f_const_addr))\n"
252
"\t\tbegin\n"
253
"\t\t\tf_addr_value <= i_in;\n"
254
"\t\t\t`ASSERT(!f_addr_loaded);\n"
255
"\t\tend\n"
256
"\n"
257
"\t\talways @(posedge i_clk)\n"
258
"\t\tif ((f_past_valid)&&(!$past(i_reset))\n"
259
"\t\t\t\t&&($past(f_addr_loaded))&&(!f_addr_loaded))\n"
260
"\t\t\tassert(o_out == f_addr_value);\n"
261
"\n"
262
                "\t\talways @(*)\n"
263
                "\t\tif (o_sync)\n"
264
                        "\t\t\tassert(wraddr[LGSIZE-1:0] == 1);\n"
265
"\n"
266
"\t\talways @(*)\n"
267
"\t\tif ((wraddr[LGSIZE]==f_const_addr[LGSIZE])\n"
268
"\t\t\t\t&&(wraddr[LGSIZE-1:0]\n"
269
"\t\t\t\t\t\t<= f_const_addr[LGSIZE-1:0]))\n"
270
"\t\t\t`ASSERT(!f_addr_loaded);\n"
271
"\n"
272
"\t\talways @(*)\n"
273
"\t\tif ((rdaddr[LGSIZE]==f_const_addr[LGSIZE])&&(f_addr_loaded))\n"
274
"\t\t\t`ASSERT(wraddr[LGSIZE-1:0]\n"
275
"\t\t\t\t\t<= f_reversed_addr[LGSIZE-1:0]+1);\n"
276
"\n"
277
"\t\talways @(*)\n"
278
"\t\tif (f_addr_loaded)\n"
279
"\t\t\t`ASSERT(brmem[f_const_addr] == f_addr_value);\n"
280
"\n"
281
"\n\n");
282
 
283
                fprintf(fp,
284
"`endif\t// FORMAL\n");
285
        }
286
 
287
        fprintf(fp,
288
"endmodule\n");
289
 
290
        fclose(fp);
291
        free(modulename);
292
}
293
 
294
void    build_dblreverse(const char *fname, const bool async_reset) {
295
        FILE    *fp = fopen(fname, "w");
296
        if (NULL == fp) {
297
                fprintf(stderr, "Could not open \'%s\' for writing\n", fname);
298
                perror("O/S Err was:");
299
                return;
300
        }
301
 
302
        std::string     resetw("i_reset");
303
        if (async_reset)
304
                resetw = std::string("i_areset_n");
305
 
306
        char    *modulename = strdup(fname), *pslash;
307
        modulename[strlen(modulename)-2] = '\0';
308
        pslash = strrchr(modulename, '/');
309
        if (pslash != NULL)
310
                strcpy(modulename, pslash+1);
311
 
312
        fprintf(fp,
313
SLASHLINE
314
"//\n"
315
"// Filename:\t%s.v\n"
316
"//\n"
317
"// Project:\t%s\n"
318
"//\n"
319
"// Purpose:\tThis module bitreverses a pipelined FFT input.  Operation is\n"
320
"//             expected as follows:\n"
321
"//\n"
322
"//             i_clk   A running clock at whatever system speed is offered.\n",
323
        modulename, prjname);
324
 
325
        if (async_reset)
326
                fprintf(fp,
327
"//             i_areset_n      An active low asynchronous reset signal,\n"
328
"//                             that resets all internals\n");
329
        else
330
                fprintf(fp,
331
"//             i_reset A synchronous reset signal, that resets all internals\n");
332
 
333
        fprintf(fp,
334
"//             i_ce    If this is one, one input is consumed and an output\n"
335
"//                     is produced.\n"
336
"//             i_in_0, i_in_1\n"
337
"//                     Two inputs to be consumed, each of width WIDTH.\n"
338
"//             o_out_0, o_out_1\n"
339
"//                     Two of the bitreversed outputs, also of the same\n"
340
"//                     width, WIDTH.  Of course, there is a delay from the\n"
341
"//                     first input to the first output.  For this purpose,\n"
342
"//                     o_sync is present.\n"
343
"//             o_sync  This will be a 1\'b1 for the first value in any block.\n"
344
"//                     Following a reset, this will only become 1\'b1 once\n"
345
"//                     the data has been loaded and is now valid.  After that,\n"
346
"//                     all outputs will be valid.\n"
347
"//\n"
348
"//     20150602 -- This module has undergone massive rework in order to\n"
349
"//             ensure that it uses resources efficiently.  As a result,\n"
350
"//             it now optimizes nicely into block RAMs.  As an unfortunately\n"
351
"//             side effect, it now passes it\'s bench test (dblrev_tb) but\n"
352
"//             fails the integration bench test (fft_tb).\n"
353
"//\n"
354
"//\n%s"
355
"//\n", creator);
356
        fprintf(fp, "%s", cpyleft);
357
        fprintf(fp, "//\n//\n`default_nettype\tnone\n//\n");
358
        fprintf(fp,
359
"\n\n"
360
"//\n"
361
"// How do we do bit reversing at two smples per clock?  Can we separate out\n"
362
"// our work into eight memory banks, writing two banks at once and reading\n"
363
"// another two banks in the same clock?\n"
364
"//\n"
365
"//     mem[00xxx0] = s_0[n]\n"
366
"//     mem[00xxx1] = s_1[n]\n"
367
"//     o_0[n] = mem[10xxx0]\n"
368
"//     o_1[n] = mem[11xxx0]\n"
369
"//     ...\n"
370
"//     mem[01xxx0] = s_0[m]\n"
371
"//     mem[01xxx1] = s_1[m]\n"
372
"//     o_0[m] = mem[10xxx1]\n"
373
"//     o_1[m] = mem[11xxx1]\n"
374
"//     ...\n"
375
"//     mem[10xxx0] = s_0[n]\n"
376
"//     mem[10xxx1] = s_1[n]\n"
377
"//     o_0[n] = mem[00xxx0]\n"
378
"//     o_1[n] = mem[01xxx0]\n"
379
"//     ...\n"
380
"//     mem[11xxx0] = s_0[m]\n"
381
"//     mem[11xxx1] = s_1[m]\n"
382
"//     o_0[m] = mem[00xxx1]\n"
383
"//     o_1[m] = mem[01xxx1]\n"
384
"//     ...\n"
385
"//\n"
386
"//     The answer is that, yes we can but: we need to use four memory banks\n"
387
"//     to do it properly.  These four banks are defined by the two bits\n"
388
"//     that determine the top and bottom of the correct address.  Larger\n"
389
"//     FFT\'s would require more memories.\n"
390
"//\n"
391
"//\n");
392
        fprintf(fp,
393
"module %s(i_clk, %s, i_ce, i_in_0, i_in_1,\n"
394
        "\t\to_out_0, o_out_1, o_sync);\n"
395
        "\tparameter\t\t\tLGSIZE=%d, WIDTH=24;\n"
396 37 dgisselq
        "\tinput\twire\t\t\ti_clk, %s, i_ce;\n"
397
        "\tinput\twire\t[(2*WIDTH-1):0]\ti_in_0, i_in_1;\n"
398 36 dgisselq
        "\toutput\twire\t[(2*WIDTH-1):0]\to_out_0, o_out_1;\n"
399
        "\toutput\treg\t\t\to_sync;\n", modulename,
400
                resetw.c_str(), TST_DBLREVERSE_LGSIZE, resetw.c_str());
401
 
402
        fprintf(fp,
403
"\n"
404
        "\treg\t\t\tin_reset;\n"
405
        "\treg\t[(LGSIZE-1):0]\tiaddr;\n"
406
        "\twire\t[(LGSIZE-3):0]\tbraddr;\n"
407
"\n"
408
        "\tgenvar\tk;\n"
409
        "\tgenerate for(k=0; k<LGSIZE-2; k=k+1)\n"
410
        "\tbegin : gen_a_bit_reversed_value\n"
411
                "\t\tassign braddr[k] = iaddr[LGSIZE-3-k];\n"
412
        "\tend endgenerate\n"
413
"\n"
414
        "\tinitial iaddr = 0;\n"
415
        "\tinitial in_reset = 1\'b1;\n"
416
        "\tinitial o_sync = 1\'b0;\n");
417
 
418
        if (async_reset)
419
                fprintf(fp, "\talways @(posedge i_clk, negedge i_areset_n)\n\t\tif (!i_areset_n)\n");
420
        else
421
                fprintf(fp, "\talways @(posedge i_clk)\n\t\tif (i_reset)\n");
422
        fprintf(fp,
423
                "\t\tbegin\n"
424
                        "\t\t\tiaddr <= 0;\n"
425
                        "\t\t\tin_reset <= 1\'b1;\n"
426
                        "\t\t\to_sync <= 1\'b0;\n"
427
                "\t\tend else if (i_ce)\n"
428
                "\t\tbegin\n"
429
                        "\t\t\tiaddr <= iaddr + { {(LGSIZE-1){1\'b0}}, 1\'b1 };\n"
430
                        "\t\t\tif (&iaddr[(LGSIZE-2):0])\n"
431
                                "\t\t\t\tin_reset <= 1\'b0;\n"
432
                        "\t\t\tif (in_reset)\n"
433
                                "\t\t\t\to_sync <= 1\'b0;\n"
434
                        "\t\t\telse\n"
435
                                "\t\t\t\to_sync <= ~(|iaddr[(LGSIZE-2):0]);\n"
436
                "\t\tend\n"
437
"\n"
438
        "\treg\t[(2*WIDTH-1):0]\tmem_e [0:((1<<(LGSIZE))-1)];\n"
439
        "\treg\t[(2*WIDTH-1):0]\tmem_o [0:((1<<(LGSIZE))-1)];\n"
440
"\n"
441
        "\talways @(posedge i_clk)\n"
442
                "\t\tif (i_ce)\tmem_e[iaddr] <= i_in_0;\n"
443
        "\talways @(posedge i_clk)\n"
444
                "\t\tif (i_ce)\tmem_o[iaddr] <= i_in_1;\n"
445
"\n"
446
"\n"
447
        "\treg [(2*WIDTH-1):0] evn_out_0, evn_out_1, odd_out_0, odd_out_1;\n"
448
"\n"
449
        "\talways @(posedge i_clk)\n"
450
                "\t\tif (i_ce)\n\t\t\tevn_out_0 <= mem_e[{!iaddr[LGSIZE-1],1\'b0,braddr}];\n"
451
        "\talways @(posedge i_clk)\n"
452
                "\t\tif (i_ce)\n\t\t\tevn_out_1 <= mem_e[{!iaddr[LGSIZE-1],1\'b1,braddr}];\n"
453
        "\talways @(posedge i_clk)\n"
454
                "\t\tif (i_ce)\n\t\t\todd_out_0 <= mem_o[{!iaddr[LGSIZE-1],1\'b0,braddr}];\n"
455
        "\talways @(posedge i_clk)\n"
456
                "\t\tif (i_ce)\n\t\t\todd_out_1 <= mem_o[{!iaddr[LGSIZE-1],1\'b1,braddr}];\n"
457
"\n"
458
        "\treg\tadrz;\n"
459
        "\talways @(posedge i_clk)\n"
460
                "\t\tif (i_ce) adrz <= iaddr[LGSIZE-2];\n"
461
"\n"
462
        "\tassign\to_out_0 = (adrz)?odd_out_0:evn_out_0;\n"
463
        "\tassign\to_out_1 = (adrz)?odd_out_1:evn_out_1;\n"
464
"\n");
465
 
466
        if (formal_property_flag) {
467
                fprintf(fp,
468
"`ifdef\tFORMAL\n"
469 37 dgisselq
"`define\tASSERT        assert\n"
470 36 dgisselq
"`ifdef BITREVERSE\n"
471 37 dgisselq
"`define\tASSUME        assume\n");
472 36 dgisselq
                if (async_reset)
473
                        fprintf(fp,
474
                "\n\talways @($global_clock)\n"
475
                        "\t\tassume(i_clk != $past(i_clk));\n\n");
476
 
477
                fprintf(fp,
478
"`else\n"
479
"`define\tASSUME        assert\n"
480
"`endif\n"
481
"\n"
482
        "\treg  f_past_valid;\n"
483
        "\tinitial      f_past_valid = 1'b0;\n"
484
        "\talways @(posedge i_clk)\n"
485
                "\t\tf_past_valid <= 1'b1;\n\n");
486
 
487
                if (async_reset)
488
                        fprintf(fp,
489
        "\tinitial      `ASSUME(!i_areset_n);\n"
490
        "\talways @($global_clock)\n"
491
        "\tif (!$rose(i_clk)))\n"
492
                "\t\t`ASSERT(!$rose(i_areset_n));\n\n"
493
        "\talways @($global_clock)\n"
494
        "\tif (!$rose(i_clk))\n"
495
        "\tbegin\n"
496
                "\t\t`ASSUME($stable(i_ce));\n"
497
                "\t\t`ASSUME($stable(i_in_0));\n"
498
                "\t\t`ASSUME($stable(i_in_1));\n"
499
                "\t\t//\n"
500
                "\t\tif (i_areset_n)\n"
501
                "\t\tbegin\n"
502
                "\t\t\t`ASSERT($stable(o_out_0));\n"
503
                "\t\t\t`ASSERT($stable(o_out_1));\n"
504
                "\t\t\t`ASSERT($stable(o_sync));\n"
505
                "\t\tend\n"
506
        "\tend\n"
507
"\n"
508
        "\talways @(posedge i_clk)\n"
509
                "\tif ((!f_past_valid)||(!i_areset_n))\n"
510
                "\tbegin\n");
511
                else
512
                        fprintf(fp,
513
        "\tinitial      `ASSUME(i_reset);\n"
514
        "\talways @(posedge i_clk)\n"
515
                "\tif ((!f_past_valid)||($past(i_reset)))\n"
516
                "\tbegin\n");
517
 
518
                fprintf(fp,
519
                "\t\t`ASSERT(iaddr == 0);\n"
520
                "\t\t`ASSERT(in_reset);\n"
521
                "\t\t`ASSERT(!o_sync);\n");
522
                fprintf(fp, "\tend\n");
523
 
524
 
525
                fprintf(fp, "`ifdef     BITREVERSE\n"
526
                                "\talways @(posedge i_clk)\n"
527
                                "\t\tassume((i_ce)||($past(i_ce))||($past(i_ce,2)));\n"
528
                                "`endif // BITREVERSE\n\n");
529
 
530
 
531
                fprintf(fp,
532
        "\t\t(* anyconst *) reg [LGSIZE-1:0]    f_const_addr;\n"
533
        "\t\twire       [LGSIZE-3:0]    f_reversed_addr;\n"
534
        "\t\t// reg     [LGSIZE:0]      f_now;\n"
535
        "\t\treg                        f_addr_loaded_0, f_addr_loaded_1;\n"
536
        "\t\treg        [(2*WIDTH-1):0] f_data_0, f_data_1;\n"
537
        "\t\twire                       f_writing, f_reading;\n"
538
"\n"
539
        "\t\tgenerate for(k=0; k<LGSIZE-2; k=k+1)\n"
540
        "\t\t   assign  f_reversed_addr[k] = f_const_addr[LGSIZE-3-k];\n"
541
        "\t\tendgenerate\n"
542
"\n"
543
        "\t\tassign     f_writing=(f_const_addr[LGSIZE-1]==iaddr[LGSIZE-1]);\n"
544
        "\t\tassign     f_reading=(f_const_addr[LGSIZE-1]!=iaddr[LGSIZE-1]);\n"
545
        "\t\tinitial    f_addr_loaded_0 = 1'b0;\n"
546
        "\t\tinitial    f_addr_loaded_1 = 1'b0;\n"
547
        "\t\talways @(posedge i_clk)\n"
548
        "\t\tif (i_reset)\n"
549
        "\t\tbegin\n"
550
        "\t             f_addr_loaded_0 <= 1'b0;\n"
551
        "\t             f_addr_loaded_1 <= 1'b0;\n"
552
        "\t\tend else if (i_ce)\n"
553
        "\t\tbegin\n"
554
        "\t\t   if (iaddr == f_const_addr)\n"
555
        "\t\t   begin\n"
556
        "\t\t           f_addr_loaded_0 <= 1'b1;\n"
557
        "\t\t           f_addr_loaded_1 <= 1'b1;\n"
558
        "\t\t   end\n"
559
"\n"
560
        "\t\t   if (f_reading)\n"
561
        "\t\t   begin\n"
562
        "\t\t           if ((braddr == f_const_addr[LGSIZE-3:0])\n"
563
        "\t\t                   &&(iaddr[LGSIZE-2] == 1'b0))\n"
564
        "\t\t                   f_addr_loaded_0 <= 1'b0;\n"
565
"\n"
566
        "\t\t           if ((braddr == f_const_addr[LGSIZE-3:0])\n"
567
        "\t\t                   &&(iaddr[LGSIZE-2] == 1'b1))\n"
568
        "\t\t                   f_addr_loaded_1 <= 1'b0;\n"
569
        "\t\t   end\n"
570
        "\t\tend\n"
571
"\n"
572
        "\t\talways @(posedge i_clk)\n"
573
        "\t\tif ((i_ce)&&(iaddr == f_const_addr))\n"
574
        "\t\tbegin\n"
575
        "\t\t   f_data_0 <= i_in_0;\n"
576
        "\t\t   f_data_1 <= i_in_1;\n"
577
        "\t\t   `ASSERT(!f_addr_loaded_0);\n"
578
        "\t\t   `ASSERT(!f_addr_loaded_1);\n"
579
        "\t\tend\n"
580
"\n"
581
        "\t\talways @(posedge i_clk)\n"
582
        "\t\tif ((f_past_valid)&&(!$past(i_reset))\n"
583
        "\t\t           &&($past(f_addr_loaded_0))&&(!f_addr_loaded_0))\n"
584
        "\t\tbegin\n"
585
        "\t\t   assert(!$past(iaddr[LGSIZE-2]));\n"
586
        "\t\t   if (f_const_addr[LGSIZE-2])\n"
587
        "\t\t           assert(o_out_1 == f_data_0);\n"
588
        "\t\t   else\n"
589
        "\t\t           assert(o_out_0 == f_data_0);\n"
590
        "\t\tend\n"
591
"\n"
592
        "\t\talways @(posedge i_clk)\n"
593
        "\t\tif ((f_past_valid)&&(!$past(i_reset))\n"
594
        "\t\t           &&($past(f_addr_loaded_1))&&(!f_addr_loaded_1))\n"
595
        "\t\tbegin\n"
596
        "\t\t   assert($past(iaddr[LGSIZE-2]));\n"
597
        "\t\t   if (f_const_addr[LGSIZE-2])\n"
598
        "\t\t           assert(o_out_1 == f_data_1);\n"
599
        "\t\t   else\n"
600
        "\t\t           assert(o_out_0 == f_data_1);\n"
601
        "\t\tend\n"
602
"\n"
603
        "\t\talways @(*)\n"
604
        "\t\t   `ASSERT(o_sync == ((iaddr[LGSIZE-2:0] == 1)&&(!in_reset)));\n"
605
"\n"
606
        "\t\t// Before writing to a section, the loaded flags should be\n"
607
        "\t\t// zero\n"
608
        "\t\talways @(*)\n"
609
        "\t\tif (f_writing)\n"
610
        "\t\tbegin\n"
611
        "\t\t   `ASSERT(f_addr_loaded_0 == (iaddr[LGSIZE-2:0]\n"
612
        "\t\t                           > f_const_addr[LGSIZE-2:0]));\n"
613
        "\t\t   `ASSERT(f_addr_loaded_1 == (iaddr[LGSIZE-2:0]\n"
614
        "\t\t                           > f_const_addr[LGSIZE-2:0]));\n"
615
        "\t\tend\n"
616
"\n"
617
        "\t\t// If we were writing, and now we are reading, then both\n"
618
        "\t\t// f_addr_loaded flags must be set\n"
619
        "\t\talways @(posedge i_clk)\n"
620
        "\t\tif ((f_past_valid)&&(!$past(i_reset))\n"
621
        "\t\t           &&($past(f_writing))&&(f_reading))\n"
622
        "\t\tbegin\n"
623
        "\t\t   `ASSERT(f_addr_loaded_0);\n"
624
        "\t\t   `ASSERT(f_addr_loaded_1);\n"
625
        "\t\tend\n"
626
"\n"
627
        "\t\talways @(*)\n"
628
        "\t\tif (f_writing)\n"
629
        "\t\t   `ASSERT(f_addr_loaded_0 == f_addr_loaded_1);\n"
630
"\n"
631
        "\t\t// When reading, and the loaded flag is zero, our pointer\n"
632
        "\t\t// must not have hit the address of interest yet\n"
633
        "\t\talways @(*)\n"
634
        "\t\tif ((!in_reset)&&(f_reading))\n"
635
        "\t\t   `ASSERT(f_addr_loaded_0 ==\n"
636
        "\t\t           ((!iaddr[LGSIZE-2])&&(iaddr[LGSIZE-3:0]\n"
637
        "\t\t                   <= f_reversed_addr[LGSIZE-3:0])));\n"
638
        "\t\talways @(*)\n"
639
        "\t\tif ((!in_reset)&&(f_reading))\n"
640
        "\t\t   `ASSERT(f_addr_loaded_1 ==\n"
641
        "\t\t           ((!iaddr[LGSIZE-2])||(iaddr[LGSIZE-3:0]\n"
642
        "\t\t                   <= f_reversed_addr[LGSIZE-3:0])));\n"
643
        "\t\talways @(*)\n"
644
        "\t\tif ((in_reset)&&(f_reading))\n"
645
        "\t\tbegin\n"
646
        "\t\t   `ASSERT(!f_addr_loaded_0);\n"
647
        "\t\t   `ASSERT(!f_addr_loaded_1);\n"
648
        "\t\tend\n"
649
"\n"
650
        "\t\talways @(*)\n"
651
        "\t\tif(iaddr[LGSIZE-1])\n"
652
        "\t\t   `ASSERT(!in_reset);\n"
653
"\n"
654
        "\t\talways @(*)\n"
655
        "\t\tif (f_addr_loaded_0)\n"
656
        "\t\t   `ASSERT(mem_e[f_const_addr] == f_data_0);\n"
657
        "\t\talways @(*)\n"
658
        "\t\tif (f_addr_loaded_1)\n"
659
        "\t\t   `ASSERT(mem_o[f_const_addr] == f_data_1);\n"
660
"\n\n");
661
 
662
 
663
                fprintf(fp,
664
"`endif\t// FORMAL\n");
665
        }
666
 
667
        fprintf(fp,
668
"endmodule\n");
669
 
670
        fclose(fp);
671
        free(modulename);
672
}

powered by: WebSVN 2.1.0

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