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

Subversion Repositories dblclockfft

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 36 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    butterfly.cpp
4
//
5
// Project:     A General Purpose Pipelined FFT Implementation
6
//
7 37 dgisselq
// Purpose:     Builds one of two butterflies: either a butterfly implementation
8
//              using hardware optimized multiplies, or one that uses a logic
9
//      soft-multiply.
10 36 dgisselq
//
11
// Creator:     Dan Gisselquist, Ph.D.
12
//              Gisselquist Technology, LLC
13
//
14
////////////////////////////////////////////////////////////////////////////////
15
//
16
// Copyright (C) 2015-2018, Gisselquist Technology, LLC
17
//
18 37 dgisselq
// This file is part of the general purpose pipelined FFT project.
19 36 dgisselq
//
20 37 dgisselq
// The pipelined FFT project is free software (firmware): you can redistribute
21
// it and/or modify it under the terms of the GNU Lesser General Public License
22
// as published by the Free Software Foundation, either version 3 of the
23
// License, or (at your option) any later version.
24 36 dgisselq
//
25 37 dgisselq
// The pipelined FFT project is distributed in the hope that it will be useful,
26
// but WITHOUT ANY WARRANTY; without even the implied warranty of
27
// MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
28
// General Public License for more details.
29
//
30
// You should have received a copy of the GNU Lesser General Public License
31
// along with this program.  (It's in the $(ROOT)/doc directory.  Run make
32
// with no target there if the PDF file isn't present.)  If not, see
33 36 dgisselq
// <http://www.gnu.org/licenses/> for a copy.
34
//
35 37 dgisselq
// License:     LGPL, v3, as defined and found on www.gnu.org,
36
//              http://www.gnu.org/licenses/lgpl.html
37 36 dgisselq
//
38
//
39
////////////////////////////////////////////////////////////////////////////////
40
//
41
//
42
#define _CRT_SECURE_NO_WARNINGS   //  ms vs 2012 doesn't like fopen
43
#include <stdio.h>
44
#include <stdlib.h>
45
 
46
#ifdef _MSC_VER //  added for ms vs compatibility
47
 
48
#include <io.h>
49
#include <direct.h>
50
#define _USE_MATH_DEFINES
51
#define R_OK    4       /* Test for read permission.  */
52
#define W_OK    2       /* Test for write permission.  */
53
#define X_OK    0       /* !!!!!! execute permission - unsupported in windows*/
54
#define F_OK    0       /* Test for existence.  */
55
 
56
#if _MSC_VER <= 1700
57
 
58
int lstat(const char *filename, struct stat *buf) { return 1; };
59
#define S_ISDIR(A)      0
60
 
61
#else
62
 
63
#define lstat   _stat
64
#define S_ISDIR _S_IFDIR
65
 
66
#endif
67
 
68
#define mkdir(A,B)      _mkdir(A)
69
 
70
#define access _access
71
 
72
#else
73
// And for G++/Linux environment
74
 
75
#include <unistd.h>     // Defines the R_OK/W_OK/etc. macros
76
#include <sys/stat.h>
77
#endif
78
 
79
#include <string.h>
80
#include <string>
81
#include <math.h>
82
#include <ctype.h>
83
#include <assert.h>
84
 
85
#include "defaults.h"
86
#include "legal.h"
87
#include "rounding.h"
88
#include "fftlib.h"
89
#include "bldstage.h"
90
#include "bitreverse.h"
91
#include "softmpy.h"
92
#include "butterfly.h"
93
 
94
void    build_butterfly(const char *fname, int xtracbits, ROUND_T rounding,
95
                        int     ckpce, const bool async_reset) {
96
        FILE    *fp = fopen(fname, "w");
97
        if (NULL == fp) {
98
                fprintf(stderr, "Could not open \'%s\' for writing\n", fname);
99
                perror("O/S Err was:");
100
                return;
101
        }
102
        const   char    *rnd_string;
103
        if (rounding == RND_TRUNCATE)
104
                rnd_string = "truncate";
105
        else if (rounding == RND_FROMZERO)
106
                rnd_string = "roundfromzero";
107
        else if (rounding == RND_HALFUP)
108
                rnd_string = "roundhalfup";
109
        else
110
                rnd_string = "convround";
111
 
112
        //if (ckpce >= 3)
113
                //ckpce = 3;
114
        if (ckpce <= 1)
115
                ckpce = 1;
116
 
117
        std::string     resetw("i_reset");
118
        if (async_reset)
119
                resetw = std::string("i_areset_n");
120
 
121
 
122
        fprintf(fp,
123
SLASHLINE
124
"//\n"
125
"// Filename:\tbutterfly.v\n"
126
"//\n"
127
"// Project:\t%s\n"
128
"//\n"
129
"// Purpose:\tThis routine caculates a butterfly for a decimation\n"
130
"//             in frequency version of an FFT.  Specifically, given\n"
131
"//     complex Left and Right values together with a coefficient, the output\n"
132
"//     of this routine is given by:\n"
133
"//\n"
134
"//             L' = L + R\n"
135
"//             R' = (L - R)*C\n"
136
"//\n"
137
"//     The rest of the junk below handles timing (mostly), to make certain\n"
138
"//     that L' and R' reach the output at the same clock.  Further, just to\n"
139
"//     make certain that is the case, an 'aux' input exists.  This aux value\n"
140
"//     will come out of this routine synchronized to the values it came in\n"
141
"//     with.  (i.e., both L', R', and aux all have the same delay.)  Hence,\n"
142
"//     a caller of this routine may set aux on the first input with valid\n"
143
"//     data, and then wait to see aux set on the output to know when to find\n"
144
"//     the first output with valid data.\n"
145
"//\n"
146
"//     All bits are preserved until the very last clock, where any more bits\n"
147
"//     than OWIDTH will be quietly discarded.\n"
148
"//\n"
149
"//     This design features no overflow checking.\n"
150
"//\n"
151
"// Notes:\n"
152
"//     CORDIC:\n"
153
"//             Much as we might like, we can't use a cordic here.\n"
154
"//             The goal is to accomplish an FFT, as defined, and a\n"
155
"//             CORDIC places a scale factor onto the data.  Removing\n"
156
"//             the scale factor would cost two multiplies, which\n"
157
"//             is precisely what we are trying to avoid.\n"
158
"//\n"
159
"//\n"
160
"//     3-MULTIPLIES:\n"
161
"//             It should also be possible to do this with three multiplies\n"
162
"//             and an extra two addition cycles.\n"
163
"//\n"
164
"//             We want\n"
165
"//                     R+I = (a + jb) * (c + jd)\n"
166
"//                     R+I = (ac-bd) + j(ad+bc)\n"
167
"//             We multiply\n"
168
"//                     P1 = ac\n"
169
"//                     P2 = bd\n"
170
"//                     P3 = (a+b)(c+d)\n"
171
"//             Then\n"
172
"//                     R+I=(P1-P2)+j(P3-P2-P1)\n"
173
"//\n"
174
"//             WIDTHS:\n"
175
"//             On multiplying an X width number by an\n"
176
"//             Y width number, X>Y, the result should be (X+Y)\n"
177
"//             bits, right?\n"
178
"//             -2^(X-1) <= a <= 2^(X-1) - 1\n"
179
"//             -2^(Y-1) <= b <= 2^(Y-1) - 1\n"
180
"//             (2^(Y-1)-1)*(-2^(X-1)) <= ab <= 2^(X-1)2^(Y-1)\n"
181
"//             -2^(X+Y-2)+2^(X-1) <= ab <= 2^(X+Y-2) <= 2^(X+Y-1) - 1\n"
182
"//             -2^(X+Y-1) <= ab <= 2^(X+Y-1)-1\n"
183
"//             YUP!  But just barely.  Do this and you'll really want\n"
184
"//             to drop a bit, although you will risk overflow in so\n"
185
"//             doing.\n"
186
"//\n"
187
"//     20150602 -- The sync logic lines have been completely redone.  The\n"
188
"//             synchronization lines no longer go through the FIFO with the\n"
189
"//             left hand sum, but are kept out of memory.  This allows the\n"
190
"//             butterfly to use more optimal memory resources, while also\n"
191
"//             guaranteeing that the sync lines can be properly reset upon\n"
192
"//             any reset signal.\n"
193
"//\n"
194
"//\n%s"
195
"//\n", prjname, creator);
196
        fprintf(fp, "%s", cpyleft);
197
        fprintf(fp, "//\n//\n`default_nettype\tnone\n//\n");
198
 
199
        fprintf(fp,
200
"module\tbutterfly(i_clk, %s, i_ce, i_coef, i_left, i_right, i_aux,\n"
201
                "\t\to_left, o_right, o_aux);\n"
202
        "\t// Public changeable parameters ...\n", resetw.c_str());
203
 
204
        fprintf(fp,
205
        "\tparameter IWIDTH=%d,", TST_BUTTERFLY_IWIDTH);
206
#ifdef  TST_BUTTERFLY_CWIDTH
207
        fprintf(fp, "CWIDTH=%d,", TST_BUTTERFLY_CWIDTH);
208
#else
209
        fprintf(fp, "CWIDTH=IWIDTH+%d,", xtracbits);
210
#endif
211
#ifdef  TST_BUTTERFLY_OWIDTH
212
        fprintf(fp, "OWIDTH=%d;\n", TST_BUTTERFLY_OWIDTH);
213
        // OWIDTH = TST_BUTTERFLY_OWIDTH;
214
#else
215
        fprintf(fp, "OWIDTH=IWIDTH+1;\n");
216
#endif
217
        fprintf(fp, "\tparameter\tSHIFT=0;\n");
218
 
219
        fprintf(fp,
220
        "\t// The number of clocks per each i_ce.  The actual number can be\n"
221
        "\t// more, but the algorithm depends upon at least this many for\n"
222
        "\t// extra internal processing.\n"
223
        "\tparameter    CKPCE=%d;\n", ckpce);
224
 
225
        fprintf(fp,
226
        "\t//\n"
227
        "\t// Local/derived parameters that are calculated from the above\n"
228
        "\t// params.  Apart from algorithmic changes below, these should not\n"
229
        "\t// be adjusted\n"
230
        "\t//\n"
231
        "\t// The first step is to calculate how many clocks it takes our\n"
232
        "\t// multiply to come back with an answer within.  The time in the\n"
233
        "\t// multiply depends upon the input value with the fewest number of\n"
234
        "\t// bits--to keep the pipeline depth short.  So, let's find the\n"
235
        "\t// fewest number of bits here.\n"
236
        "\tlocalparam MXMPYBITS = \n"
237
                "\t\t((IWIDTH+2)>(CWIDTH+1)) ? (CWIDTH+1) : (IWIDTH + 2);\n"
238
        "\t//\n"
239
        "\t// Given this \"fewest\" number of bits, we can calculate the\n"
240
        "\t// number of clocks the multiply itself will take.\n"
241
        "\tlocalparam   MPYDELAY=((MXMPYBITS+1)/2)+2;\n"
242
        "\t//\n"
243
        "\t// In an environment when CKPCE > 1, the multiply delay isn\'t\n"
244
        "\t// necessarily the delay felt by this algorithm--measured in\n"
245
        "\t// i_ce\'s.  In particular, if the multiply can operate with more\n"
246
        "\t// operations per clock, it can appear to finish \"faster\".\n"
247
        "\t// Since most of the logic in this core operates on the slower\n"
248
        "\t// clock, we'll need to map that speed into the number of slower\n"
249
        "\t// clock ticks that it takes.\n"
250
        "\tlocalparam   LCLDELAY = (CKPCE == 1) ? MPYDELAY\n"
251
                "\t\t: (CKPCE == 2) ? (MPYDELAY/2+2)\n"
252
                "\t\t: (MPYDELAY/3 + 2);\n"
253
        "\tlocalparam   LGDELAY = (MPYDELAY>64) ? 7\n"
254
                        "\t\t\t: (MPYDELAY > 32) ? 6\n"
255
                        "\t\t\t: (MPYDELAY > 16) ? 5\n"
256
                        "\t\t\t: (MPYDELAY >  8) ? 4\n"
257
                        "\t\t\t: (MPYDELAY >  4) ? 3\n"
258
                        "\t\t\t: 2;\n"
259
        "\tlocalparam   AUXLEN=(LCLDELAY+3);\n"
260
        "\tlocalparam   MPYREMAINDER = MPYDELAY - CKPCE*(MPYDELAY/CKPCE);\n"
261
"\n\n");
262
 
263
 
264
        fprintf(fp,
265 37 dgisselq
        "\tinput\twire\ti_clk, %s, i_ce;\n"
266
        "\tinput\twire\t[(2*CWIDTH-1):0] i_coef;\n"
267
        "\tinput\twire\t[(2*IWIDTH-1):0] i_left, i_right;\n"
268
        "\tinput\twire\ti_aux;\n"
269 36 dgisselq
        "\toutput\twire [(2*OWIDTH-1):0] o_left, o_right;\n"
270
        "\toutput\treg\to_aux;\n\n", resetw.c_str());
271 37 dgisselq
 
272
        if (formal_property_flag) fprintf(fp,
273
"`ifdef FORMAL\n"
274
        "\tlocalparam   F_LGDEPTH = (AUXLEN > 64) ? 7\n"
275
                        "\t\t\t: (AUXLEN > 32) ? 6\n"
276
                        "\t\t\t: (AUXLEN > 16) ? 5\n"
277
                        "\t\t\t: (AUXLEN >  8) ? 4\n"
278
                        "\t\t\t: (AUXLEN >  4) ? 3 : 2;\n"
279
"\n"
280
        "\tlocalparam   F_DEPTH = AUXLEN;\n"
281
        "\tlocalparam   [F_LGDEPTH-1:0] F_D = F_DEPTH[F_LGDEPTH-1:0]-1;\n"
282
"\n"
283
        "\treg  signed  [IWIDTH-1:0]    f_dlyleft_r  [0:F_DEPTH-1];\n"
284
        "\treg  signed  [IWIDTH-1:0]    f_dlyleft_i  [0:F_DEPTH-1];\n"
285
        "\treg  signed  [IWIDTH-1:0]    f_dlyright_r [0:F_DEPTH-1];\n"
286
        "\treg  signed  [IWIDTH-1:0]    f_dlyright_i [0:F_DEPTH-1];\n"
287
        "\treg  signed  [CWIDTH-1:0]    f_dlycoeff_r [0:F_DEPTH-1];\n"
288
        "\treg  signed  [CWIDTH-1:0]    f_dlycoeff_i [0:F_DEPTH-1];\n"
289
        "\treg  signed  [F_DEPTH-1:0]   f_dlyaux;\n"
290
"\n"
291
        "\twire signed  [IWIDTH:0]              f_predifr, f_predifi;\n"
292
        "\twire signed  [IWIDTH+CWIDTH+3-1:0]   f_predifrx, f_predifix;\n"
293
        "\twire signed  [CWIDTH:0]              f_sumcoef;\n"
294
        "\twire signed  [IWIDTH+1:0]            f_sumdiff;\n"
295
        "\twire signed  [IWIDTH:0]              f_sumr, f_sumi;\n"
296
        "\twire signed  [IWIDTH+CWIDTH+3-1:0]   f_sumrx, f_sumix;\n"
297
        "\twire signed  [IWIDTH:0]              f_difr, f_difi;\n"
298
        "\twire signed  [IWIDTH+CWIDTH+3-1:0]   f_difrx, f_difix;\n"
299
        "\twire signed  [IWIDTH+CWIDTH+3-1:0]   f_widecoeff_r, f_widecoeff_i;\n"
300
"\n"
301
        "\twire [(CWIDTH):0]    fp_one_ic, fp_two_ic, fp_three_ic, f_p3c_in;\n"
302
        "\twire [(IWIDTH+1):0]  fp_one_id, fp_two_id, fp_three_id, f_p3d_in;\n"
303
"`endif\n\n");
304
 
305 36 dgisselq
        fprintf(fp,
306
        "\treg\t[(2*IWIDTH-1):0]\tr_left, r_right;\n"
307
        "\treg\t[(2*CWIDTH-1):0]\tr_coef, r_coef_2;\n"
308
        "\twire\tsigned\t[(IWIDTH-1):0]\tr_left_r, r_left_i, r_right_r, r_right_i;\n"
309
        "\tassign\tr_left_r  = r_left[ (2*IWIDTH-1):(IWIDTH)];\n"
310
        "\tassign\tr_left_i  = r_left[ (IWIDTH-1):0];\n"
311
        "\tassign\tr_right_r = r_right[(2*IWIDTH-1):(IWIDTH)];\n"
312
        "\tassign\tr_right_i = r_right[(IWIDTH-1):0];\n"
313
"\n"
314
        "\treg\tsigned\t[(IWIDTH):0]\tr_sum_r, r_sum_i, r_dif_r, r_dif_i;\n"
315
"\n"
316
        "\treg  [(LGDELAY-1):0] fifo_addr;\n"
317
        "\twire [(LGDELAY-1):0] fifo_read_addr;\n"
318
        "\tassign\tfifo_read_addr = fifo_addr - LCLDELAY[(LGDELAY-1):0];\n"
319
        "\treg  [(2*IWIDTH+1):0]        fifo_left [ 0:((1<<LGDELAY)-1)];\n"
320
"\n");
321
        fprintf(fp,
322
        "\t// Set up the input to the multiply\n"
323
        "\talways @(posedge i_clk)\n"
324 37 dgisselq
        "\tif (i_ce)\n"
325
        "\tbegin\n"
326
                "\t\t// One clock just latches the inputs\n"
327
                "\t\tr_left <= i_left;  // No change in # of bits\n"
328
                "\t\tr_right <= i_right;\n"
329
                "\t\tr_coef  <= i_coef;\n"
330
                "\t\t// Next clock adds/subtracts\n"
331
                "\t\tr_sum_r <= r_left_r + r_right_r; // Now IWIDTH+1 bits\n"
332
                "\t\tr_sum_i <= r_left_i + r_right_i;\n"
333
                "\t\tr_dif_r <= r_left_r - r_right_r;\n"
334
                "\t\tr_dif_i <= r_left_i - r_right_i;\n"
335
                "\t\t// Other inputs are simply delayed on second clock\n"
336
                "\t\tr_coef_2<= r_coef;\n"
337
        "\tend\n"
338 36 dgisselq
"\n");
339
        fprintf(fp,
340
        "\t// Don\'t forget to record the even side, since it doesn\'t need\n"
341
        "\t// to be multiplied, but yet we still need the results in sync\n"
342
        "\t// with the answer when it is ready.\n"
343
        "\tinitial fifo_addr = 0;\n");
344
        if (async_reset)
345 37 dgisselq
                fprintf(fp, "\talways @(posedge i_clk, negedge i_areset_n)\n\tif (!i_areset_n)\n");
346 36 dgisselq
        else
347 37 dgisselq
                fprintf(fp, "\talways @(posedge i_clk)\n\tif (i_reset)\n");
348 36 dgisselq
        fprintf(fp,
349 37 dgisselq
                        "\t\tfifo_addr <= 0;\n"
350
                "\telse if (i_ce)\n"
351
                        "\t\t// Need to delay the sum side--nothing else happens\n"
352
                        "\t\t// to it, but it needs to stay synchronized with the\n"
353
                        "\t\t// right side.\n"
354
                        "\t\tfifo_addr <= fifo_addr + 1;\n"
355 36 dgisselq
"\n"
356
        "\talways @(posedge i_clk)\n"
357 37 dgisselq
        "\tif (i_ce)\n"
358
                "\t\tfifo_left[fifo_addr] <= { r_sum_r, r_sum_i };\n"
359 36 dgisselq
"\n"
360
        "\twire\tsigned\t[(CWIDTH-1):0] ir_coef_r, ir_coef_i;\n"
361
        "\tassign\tir_coef_r = r_coef_2[(2*CWIDTH-1):CWIDTH];\n"
362
        "\tassign\tir_coef_i = r_coef_2[(CWIDTH-1):0];\n"
363
        "\twire\tsigned\t[((IWIDTH+2)+(CWIDTH+1)-1):0]\tp_one, p_two, p_three;\n"
364
"\n"
365
"\n");
366
        fprintf(fp,
367
        "\t// Multiply output is always a width of the sum of the widths of\n"
368
        "\t// the two inputs.  ALWAYS.  This is independent of the number of\n"
369
        "\t// bits in p_one, p_two, or p_three.  These values needed to\n"
370
        "\t// accumulate a bit (or two) each.  However, this approach to a\n"
371
        "\t// three multiply complex multiply cannot increase the total\n"
372
        "\t// number of bits in our final output.  We\'ll take care of\n"
373
        "\t// dropping back down to the proper width, OWIDTH, in our routine\n"
374
        "\t// below.\n"
375
"\n"
376
"\n");
377
        fprintf(fp,
378
        "\t// We accomplish here \"Karatsuba\" multiplication.  That is,\n"
379
        "\t// by doing three multiplies we accomplish the work of four.\n"
380
        "\t// Let\'s prove to ourselves that this works ... We wish to\n"
381
        "\t// multiply: (a+jb) * (c+jd), where a+jb is given by\n"
382
        "\t//\ta + jb = r_dif_r + j r_dif_i, and\n"
383
        "\t//\tc + jd = ir_coef_r + j ir_coef_i.\n"
384
        "\t// We do this by calculating the intermediate products P1, P2,\n"
385
        "\t// and P3 as\n"
386
        "\t//\tP1 = ac\n"
387
        "\t//\tP2 = bd\n"
388
        "\t//\tP3 = (a + b) * (c + d)\n"
389
        "\t// and then complete our final answer with\n"
390
        "\t//\tac - bd = P1 - P2 (this checks)\n"
391
        "\t//\tad + bc = P3 - P2 - P1\n"
392
        "\t//\t        = (ac + bc + ad + bd) - bd - ac\n"
393
        "\t//\t        = bc + ad (this checks)\n"
394
"\n"
395
"\n");
396
        fprintf(fp,
397
        "\t// This should really be based upon an IF, such as in\n"
398
        "\t// if (IWIDTH < CWIDTH) then ...\n"
399
        "\t// However, this is the only (other) way I know to do it.\n"
400
        "\tgenerate if (CKPCE <= 1)\n"
401
        "\tbegin\n"
402
"\n"
403
                "\t\twire\t[(CWIDTH):0]\tp3c_in;\n"
404
                "\t\twire\t[(IWIDTH+1):0]\tp3d_in;\n"
405
                "\t\tassign\tp3c_in = ir_coef_i + ir_coef_r;\n"
406
                "\t\tassign\tp3d_in = r_dif_r + r_dif_i;\n"
407
                "\n"
408
                "\t\t// We need to pad these first two multiplies by an extra\n"
409
                "\t\t// bit just to keep them aligned with the third,\n"
410
                "\t\t// simpler, multiply.\n"
411
                "\t\tlongbimpy #(CWIDTH+1,IWIDTH+2) p1(i_clk, i_ce,\n"
412
                                "\t\t\t\t{ir_coef_r[CWIDTH-1],ir_coef_r},\n"
413 37 dgisselq
                                "\t\t\t\t{r_dif_r[IWIDTH],r_dif_r}, p_one");
414
                if (formal_property_flag) fprintf(fp,
415
"\n`ifdef\tFORMAL\n"
416
                                "\t\t\t\t, fp_one_ic, fp_one_id\n"
417
"`endif\n"
418
                        "\t\t\t");
419
                fprintf(fp, ");\n"
420 36 dgisselq
                "\t\tlongbimpy #(CWIDTH+1,IWIDTH+2) p2(i_clk, i_ce,\n"
421
                                "\t\t\t\t{ir_coef_i[CWIDTH-1],ir_coef_i},\n"
422 37 dgisselq
                                "\t\t\t\t{r_dif_i[IWIDTH],r_dif_i}, p_two");
423
                if (formal_property_flag) fprintf(fp,
424
"\n`ifdef\tFORMAL\n"
425
                                "\t\t\t\t, fp_two_ic, fp_two_id\n"
426
"`endif\n"
427
                        "\t\t\t");
428
                fprintf(fp, ");\n"
429 36 dgisselq
                "\t\tlongbimpy #(CWIDTH+1,IWIDTH+2) p3(i_clk, i_ce,\n"
430 37 dgisselq
                        "\t\t\t\tp3c_in, p3d_in, p_three");
431
                if (formal_property_flag) fprintf(fp,
432
"\n`ifdef\tFORMAL\n"
433
                                "\t\t\t\t, fp_three_ic, fp_three_id\n"
434
"`endif\n"
435
                        "\t\t\t");
436
                fprintf(fp, ");\n"
437 36 dgisselq
"\n");
438
 
439
        ///////////////////////////////////////////
440
        ///
441
        ///     Two clocks per CE, so CE, no-ce, CE, no-ce, etc
442
        ///
443
        fprintf(fp,
444
        "\tend else if (CKPCE == 2)\n"
445
        "\tbegin : CKPCE_TWO\n"
446
                "\t\t// Coefficient multiply inputs\n"
447
                "\t\treg                [2*(CWIDTH)-1:0]        mpy_pipe_c;\n"
448
                "\t\t// Data multiply inputs\n"
449
                "\t\treg                [2*(IWIDTH+1)-1:0]      mpy_pipe_d;\n"
450
                "\t\twire       signed  [(CWIDTH-1):0]  mpy_pipe_vc;\n"
451
                "\t\twire       signed  [(IWIDTH):0]    mpy_pipe_vd;\n"
452
                "\t\t//\n"
453
                "\t\treg        signed  [(CWIDTH+1)-1:0]        mpy_cof_sum;\n"
454
                "\t\treg        signed  [(IWIDTH+2)-1:0]        mpy_dif_sum;\n"
455
"\n"
456
                "\t\tassign     mpy_pipe_vc =  mpy_pipe_c[2*(CWIDTH)-1:CWIDTH];\n"
457
                "\t\tassign     mpy_pipe_vd =  mpy_pipe_d[2*(IWIDTH+1)-1:IWIDTH+1];\n"
458
"\n"
459
                "\t\treg                        mpy_pipe_v;\n"
460
                "\t\treg                        ce_phase;\n"
461
"\n"
462
                "\t\treg        signed  [(CWIDTH+IWIDTH+3)-1:0] mpy_pipe_out;\n"
463
                "\t\treg        signed [IWIDTH+CWIDTH+3-1:0]    longmpy;\n"
464 37 dgisselq
"\n");
465
                if (formal_property_flag) fprintf(fp,
466
"`ifdef FORMAL\n"
467
                "\t\twire       [CWIDTH:0]      f_past_ic;\n"
468
                "\t\twire       [IWIDTH+1:0]    f_past_id;\n"
469
                "\t\twire       [CWIDTH:0]      f_past_mux_ic;\n"
470
                "\t\twire       [IWIDTH+1:0]    f_past_mux_id;\n"
471 36 dgisselq
"\n"
472 37 dgisselq
                "\t\treg        [CWIDTH:0]      f_rpone_ic, f_rptwo_ic, f_rpthree_ic,\n"
473
                                        "\t\t\t\t\tf_rp2one_ic, f_rp2two_ic, f_rp2three_ic;\n"
474
                "\t\treg        [IWIDTH+1:0]    f_rpone_id, f_rptwo_id, f_rpthree_id,\n"
475
                                        "\t\t\t\t\tf_rp2one_id, f_rp2two_id, f_rp2three_id;\n"
476
"`endif\n\n");
477
 
478
                fprintf(fp,
479 36 dgisselq
"\n"
480
                "\t\tinitial    ce_phase = 1'b0;\n"
481
                "\t\talways @(posedge i_clk)\n"
482
                "\t\tif (i_reset)\n"
483
                        "\t\t\tce_phase <= 1'b0;\n"
484
                "\t\telse if (i_ce)\n"
485
                        "\t\t\tce_phase <= 1'b1;\n"
486
                "\t\telse\n"
487
                        "\t\t\tce_phase <= 1'b0;\n"
488
"\n"
489
                "\t\talways @(*)\n"
490
                        "\t\t\tmpy_pipe_v = (i_ce)||(ce_phase);\n"
491
"\n"
492
                "\t\talways @(posedge i_clk)\n"
493
                "\t\tif (ce_phase)\n"
494
                "\t\tbegin\n"
495
                        "\t\t\tmpy_pipe_c[2*CWIDTH-1:0] <=\n"
496
                                "\t\t\t\t\t{ ir_coef_r, ir_coef_i };\n"
497
                        "\t\t\tmpy_pipe_d[2*(IWIDTH+1)-1:0] <=\n"
498
                                "\t\t\t\t\t{ r_dif_r, r_dif_i };\n"
499
"\n"
500
                        "\t\t\tmpy_cof_sum  <= ir_coef_i + ir_coef_r;\n"
501
                        "\t\t\tmpy_dif_sum <= r_dif_r + r_dif_i;\n"
502
"\n"
503
                "\t\tend else if (i_ce)\n"
504
                "\t\tbegin\n"
505
                        "\t\t\tmpy_pipe_c[2*(CWIDTH)-1:0] <= {\n"
506
                                "\t\t\t\tmpy_pipe_c[(CWIDTH)-1:0], {(CWIDTH){1'b0}} };\n"
507
                        "\t\t\tmpy_pipe_d[2*(IWIDTH+1)-1:0] <= {\n"
508
                                "\t\t\t\tmpy_pipe_d[(IWIDTH+1)-1:0], {(IWIDTH+1){1'b0}} };\n"
509
                "\t\tend\n"
510
"\n");
511
        fprintf(fp,
512
                "\t\tlongbimpy #(CWIDTH+1,IWIDTH+2) mpy0(i_clk, mpy_pipe_v,\n"
513 37 dgisselq
                        "\t\t\t\tmpy_cof_sum, mpy_dif_sum, longmpy\n");
514
                if (formal_property_flag) fprintf(fp,
515
"`ifdef FORMAL\n"
516
                        "\t\t\t\t, f_past_ic, f_past_id\n"
517
"`endif\n");
518
        fprintf(fp,"\t\t\t);\n"
519 36 dgisselq
"\n");
520
 
521
        fprintf(fp,
522
                "\t\tlongbimpy #(CWIDTH+1,IWIDTH+2) mpy1(i_clk, mpy_pipe_v,\n"
523
                        "\t\t\t\t{ mpy_pipe_vc[CWIDTH-1], mpy_pipe_vc },\n"
524
                        "\t\t\t\t{ mpy_pipe_vd[IWIDTH  ], mpy_pipe_vd },\n"
525 37 dgisselq
                        "\t\t\t\tmpy_pipe_out\n");
526
                if (formal_property_flag) fprintf(fp,
527
"`ifdef FORMAL\n"
528
                        "\t\t\t\t, f_past_mux_ic, f_past_mux_id\n"
529
"`endif\n");
530
        fprintf(fp,"\t\t\t);\n"
531
"\n");
532 36 dgisselq
 
533
        fprintf(fp,
534
                "\t\treg\tsigned\t[((IWIDTH+2)+(CWIDTH+1)-1):0]\n"
535
                        "\t\t\t\t\trp_one, rp_two, rp_three,\n"
536
                        "\t\t\t\t\trp2_one, rp2_two, rp2_three;\n"
537
"\n"
538
                "\t\talways @(posedge i_clk)\n"
539
                "\t\tif (((i_ce)&&(!MPYDELAY[0]))\n"
540
                "\t\t\t||((ce_phase)&&(MPYDELAY[0])))\n"
541 37 dgisselq
                "\t\tbegin\n"
542
                        "\t\t\trp_one <= mpy_pipe_out;\n");
543
                if (formal_property_flag) fprintf(fp,
544
"`ifdef FORMAL\n"
545
                        "\t\t\tf_rpone_ic <= f_past_mux_ic;\n"
546
                        "\t\t\tf_rpone_id <= f_past_mux_id;\n"
547
"`endif\n");
548
                fprintf(fp,
549
                "\t\tend\n\n");
550
                fprintf(fp,
551 36 dgisselq
                "\t\talways @(posedge i_clk)\n"
552
                "\t\tif (((i_ce)&&(MPYDELAY[0]))\n"
553
                "\t\t\t||((ce_phase)&&(!MPYDELAY[0])))\n"
554 37 dgisselq
                "\t\tbegin\n"
555
                        "\t\t\trp_two <= mpy_pipe_out;\n");
556
                if (formal_property_flag) fprintf(fp,
557
"`ifdef FORMAL\n"
558
                        "\t\t\tf_rptwo_ic <= f_past_mux_ic;\n"
559
                        "\t\t\tf_rptwo_id <= f_past_mux_id;\n"
560
"`endif\n");
561
                fprintf(fp,
562
                "\t\tend\n\n");
563
                fprintf(fp,
564 36 dgisselq
                "\t\talways @(posedge i_clk)\n"
565
                "\t\tif (i_ce)\n"
566 37 dgisselq
                "\t\tbegin\n"
567
                        "\t\t\trp_three <= longmpy;\n");
568
                if (formal_property_flag) fprintf(fp,
569
"`ifdef FORMAL\n"
570
                        "\t\t\tf_rpthree_ic <= f_past_ic;\n"
571
                        "\t\t\tf_rpthree_id <= f_past_id;\n"
572
"`endif\n");
573
                fprintf(fp,
574
                "\t\tend\n"
575
"\n\n");
576
 
577
 
578
                fprintf(fp,
579 36 dgisselq
                "\t\t// Our outputs *MUST* be set on a clock where i_ce is\n"
580
                "\t\t// true for the following logic to work.  Make that\n"
581
                "\t\t// happen here.\n"
582
                "\t\talways @(posedge i_clk)\n"
583
                "\t\tif (i_ce)\n"
584 37 dgisselq
                "\t\tbegin\n"
585 36 dgisselq
                        "\t\t\trp2_one<= rp_one;\n"
586
                        "\t\t\trp2_two <= rp_two;\n"
587 37 dgisselq
                        "\t\t\trp2_three<= rp_three;\n");
588
                if (formal_property_flag) fprintf(fp,
589
"`ifdef FORMAL\n"
590
                        "\t\t\tf_rp2one_ic <= f_rpone_ic;\n"
591
                        "\t\t\tf_rp2one_id <= f_rpone_id;\n"
592 36 dgisselq
"\n"
593 37 dgisselq
 
594
                        "\t\t\tf_rp2two_ic <= f_rptwo_ic;\n"
595
                        "\t\t\tf_rp2two_id <= f_rptwo_id;\n"
596
"\n"
597
 
598
                        "\t\t\tf_rp2three_ic <= f_rpthree_ic;\n"
599
                        "\t\t\tf_rp2three_id <= f_rpthree_id;\n"
600
"`endif\n");
601
                fprintf(fp,
602
                "\t\tend\n"
603
"\n"
604 36 dgisselq
                "\t\tassign     p_one   = rp2_one;\n"
605
                "\t\tassign     p_two   = (!MPYDELAY[0])? rp2_two  : rp_two;\n"
606
                "\t\tassign     p_three = ( MPYDELAY[0])? rp_three : rp2_three;\n"
607
"\n"
608
                "\t\t// verilator lint_off UNUSED\n"
609
                "\t\twire\t[2*(IWIDTH+CWIDTH+3)-1:0]\tunused;\n"
610
                "\t\tassign\tunused = { rp2_two, rp2_three };\n"
611
                "\t\t// verilator lint_on  UNUSED\n"
612
"\n");
613 37 dgisselq
                if (formal_property_flag) fprintf(fp,
614
"`ifdef FORMAL\n"
615
                "\t\tassign fp_one_ic = f_rp2one_ic;\n"
616
                "\t\tassign fp_one_id = f_rp2one_id;\n"
617
"\n"
618
                "\t\tassign fp_two_ic = (!MPYDELAY[0])? f_rp2two_ic : f_rptwo_ic;\n"
619
                "\t\tassign fp_two_id = (!MPYDELAY[0])? f_rp2two_id : f_rptwo_id;\n"
620
"\n"
621
                "\t\tassign fp_three_ic= (MPYDELAY[0])? f_rpthree_ic : f_rp2three_ic;\n"
622
                "\t\tassign fp_three_id= (MPYDELAY[0])? f_rpthree_id : f_rp2three_id;\n"
623
"`endif\n\n");
624 36 dgisselq
 
625 37 dgisselq
 
626 36 dgisselq
        /////////////////////////
627
        ///
628
        ///     Three clock per CE, so CE, no-ce, no-ce*, CE
629
        ///
630
        fprintf(fp,
631
"\tend else if (CKPCE <= 3)\n\tbegin : CKPCE_THREE\n");
632
 
633
        fprintf(fp,
634
        "\t\t// Coefficient multiply inputs\n"
635
        "\t\treg\t\t[3*(CWIDTH+1)-1:0]\tmpy_pipe_c;\n"
636
        "\t\t// Data multiply inputs\n"
637
        "\t\treg\t\t[3*(IWIDTH+2)-1:0]\tmpy_pipe_d;\n"
638
        "\t\twire\tsigned       [(CWIDTH):0]    mpy_pipe_vc;\n"
639
        "\t\twire\tsigned       [(IWIDTH+1):0]  mpy_pipe_vd;\n"
640
        "\n"
641
        "\t\tassign\tmpy_pipe_vc =  mpy_pipe_c[3*(CWIDTH+1)-1:2*(CWIDTH+1)];\n"
642
        "\t\tassign\tmpy_pipe_vd =  mpy_pipe_d[3*(IWIDTH+2)-1:2*(IWIDTH+2)];\n"
643
        "\n"
644
        "\t\treg\t\t\tmpy_pipe_v;\n"
645
        "\t\treg\t\t[2:0]\tce_phase;\n"
646
        "\n"
647
        "\t\treg\tsigned        [  (CWIDTH+IWIDTH+3)-1:0]       mpy_pipe_out;\n"
648
"\n");
649 37 dgisselq
        if (formal_property_flag) fprintf(fp,
650
"`ifdef FORMAL\n"
651
                "\t\twire\t[CWIDTH:0]   f_past_ic;\n"
652
                "\t\twire\t[IWIDTH+1:0] f_past_id;\n"
653
"\n"
654
                "\t\treg\t[CWIDTH:0]    f_rpone_ic, f_rptwo_ic, f_rpthree_ic,\n"
655
                                        "\t\t\t\t\tf_rp2one_ic, f_rp2two_ic, f_rp2three_ic,\n"
656
                                        "\t\t\t\t\tf_rp3one_ic;\n"
657
                "\t\treg\t[IWIDTH+1:0]  f_rpone_id, f_rptwo_id, f_rpthree_id,\n"
658
                                        "\t\t\t\t\tf_rp2one_id, f_rp2two_id, f_rp2three_id,\n"
659
                                        "\t\t\t\t\tf_rp3one_id;\n"
660
"`endif\n"
661
"\n");
662
 
663 36 dgisselq
        fprintf(fp,
664
        "\t\tinitial\tce_phase = 3'b011;\n"
665
        "\t\talways @(posedge i_clk)\n"
666
        "\t\tif (i_reset)\n"
667
                "\t\t\tce_phase <= 3'b011;\n"
668
        "\t\telse if (i_ce)\n"
669
                "\t\t\tce_phase <= 3'b000;\n"
670
        "\t\telse if (ce_phase != 3'b011)\n"
671
                "\t\t\tce_phase <= ce_phase + 1'b1;\n"
672
"\n"
673
        "\t\talways @(*)\n"
674
                "\t\t\tmpy_pipe_v = (i_ce)||(ce_phase < 3'b010);\n"
675
"\n");
676
 
677
        fprintf(fp,
678
        "\t\talways @(posedge i_clk)\n"
679 37 dgisselq
        "\t\tif (ce_phase == 3\'b000)\n"
680
        "\t\tbegin\n"
681
                "\t\t\t// Second clock\n"
682
                "\t\t\tmpy_pipe_c[3*(CWIDTH+1)-1:(CWIDTH+1)] <= {\n"
683
                "\t\t\t\tir_coef_r[CWIDTH-1], ir_coef_r,\n"
684
                "\t\t\t\tir_coef_i[CWIDTH-1], ir_coef_i };\n"
685
                "\t\t\tmpy_pipe_c[CWIDTH:0] <= ir_coef_i + ir_coef_r;\n"
686
                "\t\t\tmpy_pipe_d[3*(IWIDTH+2)-1:(IWIDTH+2)] <= {\n"
687
                "\t\t\t\tr_dif_r[IWIDTH], r_dif_r,\n"
688
                "\t\t\t\tr_dif_i[IWIDTH], r_dif_i };\n"
689
                "\t\t\tmpy_pipe_d[(IWIDTH+2)-1:0] <= r_dif_r + r_dif_i;\n"
690 36 dgisselq
"\n"
691 37 dgisselq
        "\t\tend else if (mpy_pipe_v)\n"
692
        "\t\tbegin\n"
693
                "\t\t\tmpy_pipe_c[3*(CWIDTH+1)-1:0] <= {\n"
694
                "\t\t\t\tmpy_pipe_c[2*(CWIDTH+1)-1:0], {(CWIDTH+1){1\'b0}} };\n"
695
                "\t\t\tmpy_pipe_d[3*(IWIDTH+2)-1:0] <= {\n"
696
                "\t\t\t\tmpy_pipe_d[2*(IWIDTH+2)-1:0], {(IWIDTH+2){1\'b0}} };\n"
697
        "\t\tend\n"
698 36 dgisselq
"\n");
699
        fprintf(fp,
700
                "\t\tlongbimpy #(CWIDTH+1,IWIDTH+2) mpy(i_clk, mpy_pipe_v,\n"
701 37 dgisselq
                        "\t\t\t\tmpy_pipe_vc, mpy_pipe_vd, mpy_pipe_out\n");
702
        if (formal_property_flag) fprintf(fp,
703
"`ifdef FORMAL\n"
704
                        "\t\t\t\t, f_past_ic, f_past_id\n"
705
"`endif\n");
706
        fprintf(fp,
707
                "\t\t\t);\n"
708 36 dgisselq
"\n");
709
 
710
        fprintf(fp,
711
        "\t\treg\tsigned\t[((IWIDTH+2)+(CWIDTH+1)-1):0]\n"
712
                                "\t\t\t\trp_one,  rp_two,  rp_three,\n"
713
                                "\t\t\t\trp2_one, rp2_two, rp2_three,\n"
714
                                "\t\t\t\trp3_one;\n"
715
"\n");
716
 
717
        fprintf(fp,
718
        "\t\talways @(posedge i_clk)\n"
719
        "\t\tif (MPYREMAINDER == 0)\n"
720
        "\t\tbegin\n\n"
721
        "\t\t   if (i_ce)\n"
722 37 dgisselq
        "\t\t   begin\n"
723
        "\t\t           rp_two   <= mpy_pipe_out;\n");
724
        if (formal_property_flag) fprintf(fp,
725
"`ifdef FORMAL\n"
726
        "\t\t           f_rptwo_ic <= f_past_ic;\n"
727
        "\t\t           f_rptwo_id <= f_past_id;\n"
728
"`endif\n");
729
        fprintf(fp,
730
        "\t\t   end else if (ce_phase == 3'b000)\n"
731
        "\t\t   begin\n"
732
        "\t\t           rp_three <= mpy_pipe_out;\n");
733
        if (formal_property_flag) fprintf(fp,
734
"`ifdef FORMAL\n"
735
        "\t\t           f_rpthree_ic <= f_past_ic;\n"
736
        "\t\t           f_rpthree_id <= f_past_id;\n"
737
"`endif\n");
738
        fprintf(fp,
739
        "\t\t   end else if (ce_phase == 3'b001)\n"
740
        "\t\t   begin\n"
741
        "\t\t           rp_one   <= mpy_pipe_out;\n");
742
        if (formal_property_flag) fprintf(fp,
743
"`ifdef FORMAL\n"
744
        "\t\t           f_rpone_ic <= f_past_ic;\n"
745
        "\t\t           f_rpone_id <= f_past_id;\n"
746
"`endif\n");
747
        fprintf(fp,
748
        "\t\t   end\n"
749 36 dgisselq
        "\t\tend else if (MPYREMAINDER == 1)\n"
750
        "\t\tbegin\n\n"
751
        "\t\t   if (i_ce)\n"
752 37 dgisselq
        "\t\t   begin\n"
753
        "\t\t           rp_one   <= mpy_pipe_out;\n");
754
        if (formal_property_flag) fprintf(fp,
755
"`ifdef FORMAL\n"
756
        "\t\t           f_rpone_ic <= f_past_ic;\n"
757
        "\t\t           f_rpone_id <= f_past_id;\n"
758
"`endif\n");
759
        fprintf(fp,
760
        "\t\t   end else if (ce_phase == 3'b000)\n"
761
        "\t\t   begin\n"
762
        "\t\t           rp_two   <= mpy_pipe_out;\n");
763
        if (formal_property_flag) fprintf(fp,
764
"`ifdef FORMAL\n"
765
        "\t\t           f_rptwo_ic <= f_past_ic;\n"
766
        "\t\t           f_rptwo_id <= f_past_id;\n"
767
"`endif\n");
768
        fprintf(fp,
769
        "\t\t   end else if (ce_phase == 3'b001)\n"
770
        "\t\t   begin\n"
771
        "\t\t           rp_three <= mpy_pipe_out;\n");
772
        if (formal_property_flag) fprintf(fp,
773
"`ifdef FORMAL\n"
774
        "\t\t           f_rpthree_ic <= f_past_ic;\n"
775
        "\t\t           f_rpthree_id <= f_past_id;\n"
776
"`endif\n");
777
        fprintf(fp,
778
        "\t\t   end\n"
779 36 dgisselq
        "\t\tend else // if (MPYREMAINDER == 2)\n"
780
        "\t\tbegin\n\n"
781
        "\t\t   if (i_ce)\n"
782 37 dgisselq
        "\t\t   begin\n"
783
        "\t\t           rp_three <= mpy_pipe_out;\n");
784
        if (formal_property_flag) fprintf(fp,
785
"`ifdef FORMAL\n"
786
        "\t\t           f_rpthree_ic <= f_past_ic;\n"
787
        "\t\t           f_rpthree_id <= f_past_id;\n"
788
"`endif\n");
789
        fprintf(fp,
790
        "\t\t   end else if (ce_phase == 3'b000)\n"
791
        "\t\t   begin\n"
792
        "\t\t           rp_one   <= mpy_pipe_out;\n");
793
        if (formal_property_flag) fprintf(fp,
794
"`ifdef FORMAL\n"
795
        "\t\t           f_rpone_ic <= f_past_ic;\n"
796
        "\t\t           f_rpone_id <= f_past_id;\n"
797
"`endif\n");
798
        fprintf(fp,
799
        "\t\t   end else if (ce_phase == 3'b001)\n"
800
        "\t\t   begin\n"
801
        "\t\t           rp_two   <= mpy_pipe_out;\n");
802
        if (formal_property_flag) fprintf(fp,
803
"`ifdef FORMAL\n"
804
        "\t\t           f_rptwo_ic <= f_past_ic;\n"
805
        "\t\t           f_rptwo_id <= f_past_id;\n"
806
"`endif\n");
807
        fprintf(fp,
808
        "\t\t   end\n"
809 36 dgisselq
        "\t\tend\n\n");
810
 
811
        fprintf(fp,
812
        "\t\talways @(posedge i_clk)\n"
813
        "\t\tif (i_ce)\n"
814
        "\t\tbegin\n"
815
                "\t\t\trp2_one   <= rp_one;\n"
816
                "\t\t\trp2_two   <= rp_two;\n"
817
                "\t\t\trp2_three <= (MPYREMAINDER == 2) ? mpy_pipe_out : rp_three;\n"
818 37 dgisselq
                "\t\t\trp3_one   <= (MPYREMAINDER == 0) ? rp2_one : rp_one;\n");
819
 
820
        if (formal_property_flag) fprintf(fp,
821
"`ifdef FORMAL\n"
822
                        "\t\t\tf_rp2one_ic <= f_rpone_ic;\n"
823
                        "\t\t\tf_rp2one_id <= f_rpone_id;\n"
824
"\n"
825
                        "\t\t\tf_rp2two_ic <= f_rptwo_ic;\n"
826
                        "\t\t\tf_rp2two_id <= f_rptwo_id;\n"
827
"\n"
828
                        "\t\t\tf_rp2three_ic <= (MPYREMAINDER==2) ? f_past_ic : f_rpthree_ic;\n"
829
                        "\t\t\tf_rp2three_id <= (MPYREMAINDER==2) ? f_past_id : f_rpthree_id;\n"
830
                        "\t\t\tf_rp3one_ic <= (MPYREMAINDER==0) ? f_rp2one_ic : f_rpone_ic;\n"
831
                        "\t\t\tf_rp3one_id <= (MPYREMAINDER==0) ? f_rp2one_id : f_rpone_id;\n"
832
"`endif\n");
833
 
834
 
835 36 dgisselq
        fprintf(fp,
836 37 dgisselq
                "\t\tend\n"
837
"\n"
838 36 dgisselq
        "\t\tassign\tp_one   = rp3_one;\n"
839
        "\t\tassign\tp_two   = rp2_two;\n"
840
        "\t\tassign\tp_three = rp2_three;\n"
841
"\n");
842 37 dgisselq
        if (formal_property_flag) fprintf(fp,
843
"`ifdef FORMAL\n"
844
                "\t\tassign     fp_one_ic = f_rp3one_ic;\n"
845
                "\t\tassign     fp_one_id = f_rp3one_id;\n"
846
"\n"
847
                "\t\tassign     fp_two_ic = f_rp2two_ic;\n"
848
                "\t\tassign     fp_two_id = f_rp2two_id;\n"
849
"\n"
850
                "\t\tassign     fp_three_ic = f_rp2three_ic;\n"
851
                "\t\tassign     fp_three_id = f_rp2three_id;\n"
852
"`endif\n"
853
"\n");
854 36 dgisselq
 
855
        fprintf(fp,
856
"\tend endgenerate\n");
857
 
858
        fprintf(fp,
859
        "\t// These values are held in memory and delayed during the\n"
860
        "\t// multiply.  Here, we recover them.  During the multiply,\n"
861
        "\t// values were multiplied by 2^(CWIDTH-2)*exp{-j*2*pi*...},\n"
862
        "\t// therefore, the left_x values need to be right shifted by\n"
863
        "\t// CWIDTH-2 as well.  The additional bits come from a sign\n"
864
        "\t// extension.\n"
865
        "\twire\tsigned\t[(IWIDTH+CWIDTH):0]    fifo_i, fifo_r;\n"
866
        "\treg\t\t[(2*IWIDTH+1):0]      fifo_read;\n"
867 37 dgisselq
        "\tassign\tfifo_r = { {2{fifo_read[2*(IWIDTH+1)-1]}},\n"
868
                "\t\tfifo_read[(2*(IWIDTH+1)-1):(IWIDTH+1)], {(CWIDTH-2){1\'b0}} };\n"
869
        "\tassign\tfifo_i = { {2{fifo_read[(IWIDTH+1)-1]}},\n"
870
                "\t\tfifo_read[((IWIDTH+1)-1):0], {(CWIDTH-2){1\'b0}} };\n"
871 36 dgisselq
"\n"
872
"\n"
873
        "\treg\tsigned\t[(CWIDTH+IWIDTH+3-1):0] mpy_r, mpy_i;\n"
874
"\n");
875
        fprintf(fp,
876
        "\t// Let's do some rounding and remove unnecessary bits.\n"
877
        "\t// We have (IWIDTH+CWIDTH+3) bits here, we need to drop down to\n"
878
        "\t// OWIDTH, and SHIFT by SHIFT bits in the process.  The trick is\n"
879
        "\t// that we don\'t need (IWIDTH+CWIDTH+3) bits.  We\'ve accumulated\n"
880
        "\t// them, but the actual values will never fill all these bits.\n"
881
        "\t// In particular, we only need:\n"
882
        "\t//\t IWIDTH bits for the input\n"
883
        "\t//\t     +1 bit for the add/subtract\n"
884
        "\t//\t+CWIDTH bits for the coefficient multiply\n"
885
        "\t//\t     +1 bit for the add/subtract in the complex multiply\n"
886
        "\t//\t ------\n"
887
        "\t//\t (IWIDTH+CWIDTH+2) bits at full precision.\n"
888
        "\t//\n"
889
        "\t// However, the coefficient multiply multiplied by a maximum value\n"
890
        "\t// of 2^(CWIDTH-2).  Thus, we only have\n"
891
        "\t//\t   IWIDTH bits for the input\n"
892
        "\t//\t       +1 bit for the add/subtract\n"
893
        "\t//\t+CWIDTH-2 bits for the coefficient multiply\n"
894
        "\t//\t       +1 (optional) bit for the add/subtract in the cpx mpy.\n"
895
        "\t//\t -------- ... multiply.  (This last bit may be shifted out.)\n"
896
        "\t//\t (IWIDTH+CWIDTH) valid output bits.\n"
897
        "\t// Now, if the user wants to keep any extras of these (via OWIDTH),\n"
898
        "\t// or if he wishes to arbitrarily shift some of these off (via\n"
899
        "\t// SHIFT) we accomplish that here.\n"
900
"\n");
901
        fprintf(fp,
902
        "\twire\tsigned\t[(OWIDTH-1):0]\trnd_left_r, rnd_left_i, rnd_right_r, rnd_right_i;\n\n");
903
 
904
        fprintf(fp,
905
        "\twire\tsigned\t[(CWIDTH+IWIDTH+3-1):0]\tleft_sr, left_si;\n"
906
        "\tassign       left_sr = { {(2){fifo_r[(IWIDTH+CWIDTH)]}}, fifo_r };\n"
907
        "\tassign       left_si = { {(2){fifo_i[(IWIDTH+CWIDTH)]}}, fifo_i };\n\n");
908
 
909
        fprintf(fp,
910
        "\t%s #(CWIDTH+IWIDTH+3,OWIDTH,SHIFT+4) do_rnd_left_r(i_clk, i_ce,\n"
911
        "\t\t\t\tleft_sr, rnd_left_r);\n\n",
912
                rnd_string);
913
        fprintf(fp,
914
        "\t%s #(CWIDTH+IWIDTH+3,OWIDTH,SHIFT+4) do_rnd_left_i(i_clk, i_ce,\n"
915
        "\t\t\t\tleft_si, rnd_left_i);\n\n",
916
                rnd_string);
917
        fprintf(fp,
918
        "\t%s #(CWIDTH+IWIDTH+3,OWIDTH,SHIFT+4) do_rnd_right_r(i_clk, i_ce,\n"
919
        "\t\t\t\tmpy_r, rnd_right_r);\n\n", rnd_string);
920
        fprintf(fp,
921
        "\t%s #(CWIDTH+IWIDTH+3,OWIDTH,SHIFT+4) do_rnd_right_i(i_clk, i_ce,\n"
922
        "\t\t\t\tmpy_i, rnd_right_i);\n\n", rnd_string);
923
        fprintf(fp,
924
        "\talways @(posedge i_clk)\n"
925 37 dgisselq
        "\tif (i_ce)\n"
926
        "\tbegin\n"
927
                "\t\t// First clock, recover all values\n"
928
                "\t\tfifo_read <= fifo_left[fifo_read_addr];\n"
929
                "\t\t// These values are IWIDTH+CWIDTH+3 bits wide\n"
930
                "\t\t// although they only need to be (IWIDTH+1)\n"
931
                "\t\t// + (CWIDTH) bits wide.  (We\'ve got two\n"
932
                "\t\t// extra bits we need to get rid of.)\n"
933
                "\t\tmpy_r <= p_one - p_two;\n"
934
                "\t\tmpy_i <= p_three - p_one - p_two;\n"
935
        "\tend\n"
936 36 dgisselq
"\n");
937
 
938
        fprintf(fp,
939
        "\treg\t[(AUXLEN-1):0]\taux_pipeline;\n"
940
        "\tinitial\taux_pipeline = 0;\n");
941
        if (async_reset)
942 37 dgisselq
                fprintf(fp, "\talways @(posedge i_clk, negedge i_areset_n)\n\tif (!i_areset_n)\n");
943 36 dgisselq
        else
944 37 dgisselq
                fprintf(fp, "\talways @(posedge i_clk)\n\tif (i_reset)\n");
945 36 dgisselq
        fprintf(fp,
946 37 dgisselq
        "\t\taux_pipeline <= 0;\n"
947
        "\telse if (i_ce)\n"
948
        "\t\taux_pipeline <= { aux_pipeline[(AUXLEN-2):0], i_aux };\n"
949 36 dgisselq
"\n");
950
        fprintf(fp,
951
        "\tinitial o_aux = 1\'b0;\n");
952
        if (async_reset)
953 37 dgisselq
                fprintf(fp, "\talways @(posedge i_clk, negedge i_areset_n)\n\tif (!i_areset_n)\n");
954 36 dgisselq
        else
955 37 dgisselq
                fprintf(fp, "\talways @(posedge i_clk)\n\tif (i_reset)\n");
956 36 dgisselq
        fprintf(fp,
957 37 dgisselq
                "\t\to_aux <= 1\'b0;\n"
958
                "\telse if (i_ce)\n"
959
                "\tbegin\n"
960
                        "\t\t// Second clock, latch for final clock\n"
961
                        "\t\to_aux <= aux_pipeline[AUXLEN-1];\n"
962
                "\tend\n"
963 36 dgisselq
"\n");
964
 
965
        fprintf(fp,
966
        "\t// As a final step, we pack our outputs into two packed two\'s\n"
967
        "\t// complement numbers per output word, so that each output word\n"
968
        "\t// has (2*OWIDTH) bits in it, with the top half being the real\n"
969
        "\t// portion and the bottom half being the imaginary portion.\n"
970
        "\tassign       o_left = { rnd_left_r, rnd_left_i };\n"
971
        "\tassign       o_right= { rnd_right_r,rnd_right_i};\n"
972
"\n");
973
 
974 37 dgisselq
        fprintf(fp,
975
"`ifdef FORMAL\n");
976 36 dgisselq
        if (formal_property_flag) {
977
                fprintf(fp,
978
        "\tinitial\tf_dlyaux[0] = 0;\n"
979
        "\talways @(posedge i_clk)\n"
980
        "\tif (i_reset)\n"
981
                "\t\tf_dlyaux\t<= 0;\n"
982
        "\telse if (i_ce)\n"
983
                "\t\tf_dlyaux\t<= { f_dlyaux[F_DEPTH-2:0], i_aux };\n"
984
"\n"
985
        "\talways @(posedge i_clk)\n"
986
        "\tif (i_ce)\n"
987
        "\tbegin\n"
988
        "\t     f_dlyleft_r[0]   <= i_left[ (2*IWIDTH-1):IWIDTH];\n"
989
        "\t     f_dlyleft_i[0]   <= i_left[ (  IWIDTH-1):0];\n"
990
        "\t     f_dlyright_r[0]  <= i_right[(2*IWIDTH-1):IWIDTH];\n"
991
        "\t     f_dlyright_i[0]  <= i_right[(  IWIDTH-1):0];\n"
992
        "\t     f_dlycoeff_r[0]  <= i_coef[ (2*CWIDTH-1):CWIDTH];\n"
993
        "\t     f_dlycoeff_i[0]  <= i_coef[ (  CWIDTH-1):0];\n"
994
        "\tend\n"
995
"\n"
996
        "\tgenvar       k;\n"
997
        "\tgenerate for(k=1; k<F_DEPTH; k=k+1)\n"
998
        "\tbegin : F_PROPAGATE_DELAY_LINES\n"
999
"\n"
1000
"\n"
1001
                "\t\talways @(posedge i_clk)\n"
1002
                "\t\tif (i_ce)\n"
1003
                "\t\tbegin\n"
1004
                "\t\t   f_dlyleft_r[k]  <= f_dlyleft_r[ k-1];\n"
1005
                "\t\t   f_dlyleft_i[k]  <= f_dlyleft_i[ k-1];\n"
1006
                "\t\t   f_dlyright_r[k] <= f_dlyright_r[k-1];\n"
1007
                "\t\t   f_dlyright_i[k] <= f_dlyright_i[k-1];\n"
1008
                "\t\t   f_dlycoeff_r[k] <= f_dlycoeff_r[k-1];\n"
1009
                "\t\t   f_dlycoeff_i[k] <= f_dlycoeff_i[k-1];\n"
1010
                "\t\tend\n"
1011
"\n"
1012
        "\tend endgenerate\n"
1013
"\n"
1014
"`ifndef VERILATOR\n"
1015 37 dgisselq
        "\t//\n"
1016
        "\t// Make some i_ce restraining assumptions.  These are necessary\n"
1017
        "\t// to get the design to pass induction.\n"
1018
        "\t//\n"
1019 36 dgisselq
        "\tgenerate if (CKPCE <= 1)\n"
1020
        "\tbegin\n"
1021
"\n"
1022 37 dgisselq
                "\t\t// No primary i_ce assumption.  i_ce can be anything\n"
1023
                "\t\t//\n"
1024
                "\t\t// First induction i_ce assumption: No more than one\n"
1025
                "\t\t// empty cycle between used cycles.  Without this\n"
1026
                "\t\t// assumption, or one like it, induction would never\n"
1027
                "\t\t// complete.\n"
1028
                "\t\talways @(posedge i_clk)\n"
1029
                "\t\tif ((!$past(i_ce)))\n"
1030
                        "\t\t\tassume(i_ce);\n"
1031 36 dgisselq
"\n"
1032 37 dgisselq
                "\t\t// Second induction i_ce assumption: avoid skipping an\n"
1033
                "\t\t// i_ce and thus stretching out the i_ce cycle two i_ce\n"
1034
                "\t\t// cycles in a row.  Without this assumption, induction\n"
1035
                "\t\t// would still complete, it would just take longer\n"
1036
                "\t\talways @(posedge i_clk)\n"
1037
                "\t\tif (($past(i_ce))&&(!$past(i_ce,2)))\n"
1038
                        "\t\t\tassume(i_ce);\n"
1039
"\n"
1040 36 dgisselq
        "\tend else if (CKPCE == 2)\n"
1041
        "\tbegin : F_CKPCE_TWO\n"
1042
"\n"
1043 37 dgisselq
                "\t\t// Primary i_ce assumption: Every i_ce cycle is followed\n"
1044
                "\t\t// by a non-i_ce cycle, so the multiplies can be\n"
1045
                "\t\t// multiplexed\n"
1046
                "\t\talways @(posedge i_clk)\n"
1047
                "\t\tif ($past(i_ce))\n"
1048
                        "\t\t\tassume(!i_ce);\n"
1049
 
1050
                "\t\t// First induction assumption: Don't let this stretch\n"
1051
                "\t\t// out too far.  This is necessary to pass induction\n"
1052
                "\t\talways @(posedge i_clk)\n"
1053
                "\t\tif ((!$past(i_ce))&&(!$past(i_ce,2)))\n"
1054
                        "\t\t\tassume(i_ce);\n"
1055 36 dgisselq
"\n"
1056 37 dgisselq
                "\t\talways @(posedge i_clk)\n"
1057
                "\t\tif ((!$past(i_ce))&&($past(i_ce,2))\n"
1058
                        "\t\t\t\t&&(!$past(i_ce,3))&&(!$past(i_ce,4)))\n"
1059
                        "\t\t\tassume(i_ce);\n"
1060
"\n"
1061 36 dgisselq
        "\tend else if (CKPCE == 3)\n"
1062
        "\tbegin : F_CKPCE_THREE\n"
1063
"\n"
1064 37 dgisselq
                "\t\t// Primary i_ce assumption: Following any i_ce cycle,\n"
1065
                "\t\t// there must be two clock cycles with i_ce de-asserted\n"
1066
                "\t\talways @(posedge i_clk)\n"
1067
                "\t\tif (($past(i_ce))||($past(i_ce,2)))\n"
1068
                        "\t\t\tassume(!i_ce);\n"
1069 36 dgisselq
"\n"
1070 37 dgisselq
                "\t\t// Induction assumption: Allow i_ce's every third or\n"
1071
                "\t\t// fourth clock, but don't allow them to be separated\n"
1072
                "\t\t// further than that\n"
1073
                "\t\talways @(posedge i_clk)\n"
1074
                "\t\tif ((!$past(i_ce))&&(!$past(i_ce,2))&&(!$past(i_ce,3)))\n"
1075
                        "\t\t\tassume(i_ce);\n"
1076
"\n"
1077
                "\t\t// Second induction assumption, to speed up the proof:\n"
1078
                "\t\t// If it's the earliest possible opportunity for an\n"
1079
                "\t\t// i_ce, and the last i_ce was late, don't let this one\n"
1080
                "\t\t// be late as well.\n"
1081
                "\t\talways @(posedge i_clk)\n"
1082
                "\t\tif ((!$past(i_ce))&&(!$past(i_ce,2))\n"
1083
                        "\t\t\t&&($past(i_ce,3))&&(!$past(i_ce,4))\n"
1084
                        "\t\t\t&&(!$past(i_ce,5))&&(!$past(i_ce,6)))\n"
1085
                        "\t\t\tassume(i_ce);\n"
1086
"\n"
1087 36 dgisselq
        "\tend endgenerate\n"
1088
"`endif\n"
1089
"\n"
1090
        "\treg  [F_LGDEPTH:0]   f_startup_counter;\n"
1091
        "\tinitial      f_startup_counter = 0;\n"
1092
        "\talways @(posedge i_clk)\n"
1093
        "\tif (i_reset)\n"
1094
        "\t     f_startup_counter <= 0;\n"
1095
        "\telse if ((i_ce)&&(!(&f_startup_counter)))\n"
1096
        "\t     f_startup_counter <= f_startup_counter + 1;\n"
1097
"\n"
1098
        "\talways @(*)\n"
1099
        "\tbegin\n"
1100
        "\t     f_sumr = f_dlyleft_r[F_D] + f_dlyright_r[F_D];\n"
1101
        "\t     f_sumi = f_dlyleft_i[F_D] + f_dlyright_i[F_D];\n"
1102
        "\tend\n"
1103
"\n"
1104
        "\tassign\tf_sumrx = { {(4){f_sumr[IWIDTH]}}, f_sumr, {(CWIDTH-2){1'b0}} };\n"
1105
        "\tassign\tf_sumix = { {(4){f_sumi[IWIDTH]}}, f_sumi, {(CWIDTH-2){1'b0}} };\n"
1106
"\n"
1107
        "\talways @(*)\n"
1108
        "\tbegin\n"
1109
        "\t     f_difr = f_dlyleft_r[F_D] - f_dlyright_r[F_D];\n"
1110
        "\t     f_difi = f_dlyleft_i[F_D] - f_dlyright_i[F_D];\n"
1111
        "\tend\n"
1112
"\n"
1113
        "\tassign\tf_difrx = { {(CWIDTH+2){f_difr[IWIDTH]}}, f_difr };\n"
1114
        "\tassign\tf_difix = { {(CWIDTH+2){f_difi[IWIDTH]}}, f_difi };\n"
1115
"\n"
1116
        "\tassign\tf_widecoeff_r ={ {(IWIDTH+3){f_dlycoeff_r[F_D][CWIDTH-1]}},\n"
1117
                                        "\t\t\t\t\t\tf_dlycoeff_r[F_D] };\n"
1118
        "\tassign\tf_widecoeff_i ={ {(IWIDTH+3){f_dlycoeff_i[F_D][CWIDTH-1]}},\n"
1119
                                        "\t\t\t\t\t\tf_dlycoeff_i[F_D] };\n"
1120
"\n"
1121
        "\talways @(posedge i_clk)\n"
1122
        "\tif (f_startup_counter > {1'b0, F_D})\n"
1123
        "\tbegin\n"
1124
        "\t     assert(aux_pipeline == f_dlyaux);\n"
1125
        "\t     assert(left_sr == f_sumrx);\n"
1126
        "\t     assert(left_si == f_sumix);\n"
1127
        "\t     assert(aux_pipeline[AUXLEN-1] == f_dlyaux[F_D]);\n"
1128
"\n"
1129
        "\t     if ((f_difr == 0)&&(f_difi == 0))\n"
1130
        "\t     begin\n"
1131
        "\t             assert(mpy_r == 0);\n"
1132
        "\t             assert(mpy_i == 0);\n"
1133
        "\t     end else if ((f_dlycoeff_r[F_D] == 0)\n"
1134
        "\t                     &&(f_dlycoeff_i[F_D] == 0))\n"
1135
        "\t     begin\n"
1136
        "\t             assert(mpy_r == 0);\n"
1137
        "\t             assert(mpy_i == 0);\n"
1138
        "\t     end\n"
1139
"\n"
1140
        "\t     if ((f_dlycoeff_r[F_D] == 1)&&(f_dlycoeff_i[F_D] == 0))\n"
1141
        "\t     begin\n"
1142
        "\t             assert(mpy_r == f_difrx);\n"
1143
        "\t             assert(mpy_i == f_difix);\n"
1144
        "\t     end\n"
1145
"\n"
1146
        "\t     if ((f_dlycoeff_r[F_D] == 0)&&(f_dlycoeff_i[F_D] == 1))\n"
1147
        "\t     begin\n"
1148
        "\t             assert(mpy_r == -f_difix);\n"
1149
        "\t             assert(mpy_i ==  f_difrx);\n"
1150
        "\t     end\n"
1151
"\n"
1152
        "\t     if ((f_difr == 1)&&(f_difi == 0))\n"
1153
        "\t     begin\n"
1154
        "\t             assert(mpy_r == f_widecoeff_r);\n"
1155
        "\t             assert(mpy_i == f_widecoeff_i);\n"
1156
        "\t     end\n"
1157
"\n"
1158
        "\t     if ((f_difr == 0)&&(f_difi == 1))\n"
1159
        "\t     begin\n"
1160
        "\t             assert(mpy_r == -f_widecoeff_i);\n"
1161
        "\t             assert(mpy_i ==  f_widecoeff_r);\n"
1162
        "\t     end\n"
1163
        "\tend\n"
1164
"\n");
1165
 
1166
                fprintf(fp,
1167
        "\t// Let's see if we can improve our performance at all by\n"
1168
        "\t// moving our test one clock earlier.  If nothing else, it should\n"
1169
        "\t// help induction finish one (or more) clocks ealier than\n"
1170
        "\t// otherwise\n"
1171
"\n\n"
1172
        "\talways @(*)\n"
1173
        "\tbegin\n"
1174
                "\t\tf_predifr = f_dlyleft_r[F_D-1] - f_dlyright_r[F_D-1];\n"
1175
                "\t\tf_predifi = f_dlyleft_i[F_D-1] - f_dlyright_i[F_D-1];\n"
1176
        "\tend\n"
1177
"\n"
1178
        "\tassign       f_predifrx = { {(CWIDTH+2){f_predifr[IWIDTH]}}, f_predifr };\n"
1179
        "\tassign       f_predifix = { {(CWIDTH+2){f_predifi[IWIDTH]}}, f_predifi };\n"
1180
"\n"
1181
        "\talways @(*)\n"
1182
        "\tbegin\n"
1183
                "\t\tf_sumcoef = f_dlycoeff_r[F_D-1] + f_dlycoeff_i[F_D-1];\n"
1184
                "\t\tf_sumdiff = f_predifr + f_predifi;\n"
1185
        "\tend\n"
1186
"\n"
1187
        "\t// Induction helpers\n"
1188
        "\talways @(posedge i_clk)\n"
1189
        "\tif (f_startup_counter >= { 1'b0, F_D })\n"
1190
        "\tbegin\n"
1191
                "\t\tif (f_dlycoeff_r[F_D-1] == 0)\n"
1192
                        "\t\t\tassert(p_one == 0);\n"
1193
                "\t\tif (f_dlycoeff_i[F_D-1] == 0)\n"
1194
                        "\t\t\tassert(p_two == 0);\n"
1195
"\n"
1196
                "\t\tif (f_dlycoeff_r[F_D-1] == 1)\n"
1197
                        "\t\t\tassert(p_one == f_predifrx);\n"
1198
                "\t\tif (f_dlycoeff_i[F_D-1] == 1)\n"
1199
                        "\t\t\tassert(p_two == f_predifix);\n"
1200
"\n"
1201
                "\t\tif (f_predifr == 0)\n"
1202
                        "\t\t\tassert(p_one == 0);\n"
1203
                "\t\tif (f_predifi == 0)\n"
1204
                        "\t\t\tassert(p_two == 0);\n"
1205
"\n"
1206
                "\t\t// verilator lint_off WIDTH\n"
1207
                "\t\tif (f_predifr == 1)\n"
1208
                        "\t\t\tassert(p_one == f_dlycoeff_r[F_D-1]);\n"
1209
                "\t\tif (f_predifi == 1)\n"
1210
                        "\t\t\tassert(p_two == f_dlycoeff_i[F_D-1]);\n"
1211
                "\t\t// verilator lint_on  WIDTH\n"
1212
"\n"
1213
                "\t\tif (f_sumcoef == 0)\n"
1214
                        "\t\t\tassert(p_three == 0);\n"
1215
                "\t\tif (f_sumdiff == 0)\n"
1216
                        "\t\t\tassert(p_three == 0);\n"
1217
                "\t\t// verilator lint_off WIDTH\n"
1218
                "\t\tif (f_sumcoef == 1)\n"
1219
                        "\t\t\tassert(p_three == f_sumdiff);\n"
1220
                "\t\tif (f_sumdiff == 1)\n"
1221
                        "\t\t\tassert(p_three == f_sumcoef);\n"
1222
                "\t\t// verilator lint_on  WIDTH\n"
1223
"`ifdef VERILATOR\n"
1224 37 dgisselq
                "\t\t// Check that the multiplies match--but *ONLY* if using\n"
1225
                "\t\t// Verilator, and not if using formal proper\n"
1226 36 dgisselq
                "\t\tassert(p_one   == f_predifr * f_dlycoeff_r[F_D-1]);\n"
1227
                "\t\tassert(p_two   == f_predifi * f_dlycoeff_i[F_D-1]);\n"
1228
                "\t\tassert(p_three == f_sumdiff * f_sumcoef);\n"
1229
"`endif // VERILATOR\n"
1230
        "\tend\n\n");
1231
 
1232
                fprintf(fp,
1233 37 dgisselq
        "\t// The following logic formally insists that our version of the\n"
1234
        "\t// inputs to the multiply matches what the (multiclock) multiply\n"
1235
        "\t// thinks its inputs were.  While this may seem redundant, the\n"
1236
        "\t// proof will not complete in any reasonable amount of time\n"
1237
        "\t// without these assertions.\n"
1238
"\n"
1239
        "\tassign\tf_p3c_in = f_dlycoeff_i[F_D-1] + f_dlycoeff_r[F_D-1];\n"
1240
        "\tassign\tf_p3d_in = f_predifi + f_predifr;\n"
1241
"\n"
1242
        "\talways @(*)\n"
1243
        "\tif (f_startup_counter >= { 1'b0, F_D })\n"
1244
        "\tbegin\n"
1245
                "\t\tassert(fp_one_ic == { f_dlycoeff_r[F_D-1][CWIDTH-1],\n"
1246
                                "\t\t\t\tf_dlycoeff_r[F_D-1][CWIDTH-1:0] });\n"
1247
                "\t\tassert(fp_two_ic == { f_dlycoeff_i[F_D-1][CWIDTH-1],\n"
1248
                                "\t\t\t\tf_dlycoeff_i[F_D-1][CWIDTH-1:0] });\n"
1249
                "\t\tassert(fp_one_id == { f_predifr[IWIDTH], f_predifr });\n"
1250
                "\t\tassert(fp_two_id == { f_predifi[IWIDTH], f_predifi });\n"
1251
                "\t\tassert(fp_three_ic == f_p3c_in);\n"
1252
                "\t\tassert(fp_three_id == f_p3d_in);\n"
1253
        "\tend\n"
1254
"\n");
1255
 
1256
 
1257
                fprintf(fp,
1258 36 dgisselq
        "\t// F_CHECK will be set externally by the solver, so that we can\n"
1259
        "\t// double check that the solver is actually testing what we think\n"
1260
        "\t// it is testing.  We'll set it here to MPYREMAINDER, which will\n"
1261
        "\t// essentially eliminate the check--unless overridden by the\n"
1262
        "\t// solver.\n"
1263
        "\tparameter    F_CHECK = MPYREMAINDER;\n"
1264
        "\tinitial      assert(MPYREMAINDER == F_CHECK);\n\n");
1265
 
1266 37 dgisselq
        } else {
1267
                fprintf(fp, "// Set the formal_property_flag to enable formal\n"
1268
                        "// property generation\n");
1269
        }
1270 36 dgisselq
                fprintf(fp,
1271
"`endif // FORMAL\n");
1272
 
1273
        fprintf(fp,
1274
"endmodule\n");
1275
        fclose(fp);
1276
}
1277
 
1278
void    build_hwbfly(const char *fname, int xtracbits, ROUND_T rounding,
1279
                int ckpce, const bool async_reset) {
1280
        FILE    *fp = fopen(fname, "w");
1281
        if (NULL == fp) {
1282
                fprintf(stderr, "Could not open \'%s\' for writing\n", fname);
1283
                perror("O/S Err was:");
1284
                return;
1285
        }
1286
 
1287
        const   char    *rnd_string;
1288
        if (rounding == RND_TRUNCATE)
1289
                rnd_string = "truncate";
1290
        else if (rounding == RND_FROMZERO)
1291
                rnd_string = "roundfromzero";
1292
        else if (rounding == RND_HALFUP)
1293
                rnd_string = "roundhalfup";
1294
        else
1295
                rnd_string = "convround";
1296
 
1297
        std::string     resetw("i_reset");
1298
        if (async_reset)
1299
                resetw = std::string("i_areset_n");
1300
 
1301
 
1302
        fprintf(fp,
1303
SLASHLINE
1304
"//\n"
1305
"// Filename:\thwbfly.v\n"
1306
"//\n"
1307
"// Project:\t%s\n"
1308
"//\n"
1309
"// Purpose:\tThis routine is identical to the butterfly.v routine found\n"
1310
"//             in 'butterfly.v', save only that it uses the verilog\n"
1311
"//     operator '*' in hopes that the synthesizer would be able to optimize\n"
1312
"//     it with hardware resources.\n"
1313
"//\n"
1314
"//     It is understood that a hardware multiply can complete its operation in\n"
1315
"//     a single clock.\n"
1316
"//\n"
1317
"// Operation:\n"
1318
"//\n"
1319
"//     Given two inputs, A (i_left) and B (i_right), and a complex\n"
1320
"//     coefficient C (i_coeff), return two outputs, O1 and O2, where:\n"
1321
"//\n"
1322
"//             O1 = A + B, and\n"
1323
"//             O2 = (A - B)*C\n"
1324
"//\n"
1325
"//     This operation is commonly known as a Decimation in Frequency (DIF)\n"
1326
"//     Radix-2 Butterfly.\n"
1327
"//     O1 and O2 are rounded before being returned in (o_left) and o_right\n"
1328
"//     to OWIDTH bits.  If SHIFT is one, an extra bit is dropped from these\n"
1329
"//     values during the rounding process.\n"
1330
"//\n"
1331
"//     Further, since these outputs will take some number of clocks to\n"
1332
"//     calculate, we'll pipe a value (i_aux) through the system and return\n"
1333
"//     it with the results (o_aux), so you can synchronize to the outgoing\n"
1334
"//     output stream.\n"
1335
"//\n"
1336
"//\n%s"
1337
"//\n", prjname, creator);
1338
        fprintf(fp, "%s", cpyleft);
1339
        fprintf(fp, "//\n//\n`default_nettype\tnone\n//\n");
1340
        fprintf(fp,
1341
"module hwbfly(i_clk, %s, i_ce, i_coef, i_left, i_right, i_aux,\n"
1342
                "\t\to_left, o_right, o_aux);\n"
1343
        "\t// Public changeable parameters ...\n"
1344
        "\t//   - IWIDTH, number of bits in each component of the input\n"
1345
        "\t//   - CWIDTH, number of bits in each component of the twiddle factor\n"
1346
        "\t//   - OWIDTH, number of bits in each component of the output\n"
1347
        "\tparameter IWIDTH=16,CWIDTH=IWIDTH+%d,OWIDTH=IWIDTH+1;\n"
1348
        "\t// Drop an additional bit on the output?\n"
1349
        "\tparameter\t\tSHIFT=0;\n"
1350
        "\t// The number of clocks per clock enable, 1, 2, or 3.\n"
1351
        "\tparameter\t[1:0]\tCKPCE=%d;\n\t//\n", resetw.c_str(), xtracbits,
1352
                ckpce);
1353
 
1354
        fprintf(fp,
1355 37 dgisselq
        "\tinput\twire\ti_clk, %s, i_ce;\n"
1356
        "\tinput\twire\t[(2*CWIDTH-1):0]\ti_coef;\n"
1357
        "\tinput\twire\t[(2*IWIDTH-1):0]\ti_left, i_right;\n"
1358
        "\tinput\twire\ti_aux;\n"
1359 36 dgisselq
        "\toutput\twire\t[(2*OWIDTH-1):0]\to_left, o_right;\n"
1360
        "\toutput\treg\to_aux;\n\n"
1361
"\n", resetw.c_str());
1362
 
1363
        fprintf(fp,
1364
        "\treg\t[(2*IWIDTH-1):0]        r_left, r_right;\n"
1365
        "\treg\t                        r_aux, r_aux_2;\n"
1366
        "\treg\t[(2*CWIDTH-1):0]        r_coef;\n"
1367
        "\twire signed  [(IWIDTH-1):0]  r_left_r, r_left_i, r_right_r, r_right_i;\n"
1368
        "\tassign\tr_left_r  = r_left[ (2*IWIDTH-1):(IWIDTH)];\n"
1369
        "\tassign\tr_left_i  = r_left[ (IWIDTH-1):0];\n"
1370
        "\tassign\tr_right_r = r_right[(2*IWIDTH-1):(IWIDTH)];\n"
1371
        "\tassign\tr_right_i = r_right[(IWIDTH-1):0];\n"
1372
        "\treg  signed  [(CWIDTH-1):0]  ir_coef_r, ir_coef_i;\n"
1373
"\n"
1374
        "\treg  signed  [(IWIDTH):0]    r_sum_r, r_sum_i, r_dif_r, r_dif_i;\n"
1375
"\n"
1376
        "\treg  [(2*IWIDTH+2):0]        leftv, leftvv;\n"
1377
"\n"
1378
        "\t// Set up the input to the multiply\n"
1379
        "\tinitial r_aux   = 1\'b0;\n"
1380
        "\tinitial r_aux_2 = 1\'b0;\n");
1381
        if (async_reset)
1382
                fprintf(fp, "\talways @(posedge i_clk, negedge i_areset_n)\n\t\tif (!i_areset_n)\n");
1383
        else
1384
                fprintf(fp, "\talways @(posedge i_clk)\n\t\tif (i_reset)\n");
1385
        fprintf(fp,
1386
                "\t\tbegin\n"
1387
                        "\t\t\tr_aux <= 1\'b0;\n"
1388
                        "\t\t\tr_aux_2 <= 1\'b0;\n"
1389
                "\t\tend else if (i_ce)\n"
1390
                "\t\tbegin\n"
1391
                        "\t\t\t// One clock just latches the inputs\n"
1392
                        "\t\t\tr_aux <= i_aux;\n"
1393
                        "\t\t\t// Next clock adds/subtracts\n"
1394
                        "\t\t\t// Other inputs are simply delayed on second clock\n"
1395
                        "\t\t\tr_aux_2 <= r_aux;\n"
1396
                "\t\tend\n"
1397
        "\talways @(posedge i_clk)\n"
1398
                "\t\tif (i_ce)\n"
1399
                "\t\tbegin\n"
1400
                        "\t\t\t// One clock just latches the inputs\n"
1401
                        "\t\t\tr_left <= i_left;        // No change in # of bits\n"
1402
                        "\t\t\tr_right <= i_right;\n"
1403
                        "\t\t\tr_coef  <= i_coef;\n"
1404
                        "\t\t\t// Next clock adds/subtracts\n"
1405
                        "\t\t\tr_sum_r <= r_left_r + r_right_r; // Now IWIDTH+1 bits\n"
1406
                        "\t\t\tr_sum_i <= r_left_i + r_right_i;\n"
1407
                        "\t\t\tr_dif_r <= r_left_r - r_right_r;\n"
1408
                        "\t\t\tr_dif_i <= r_left_i - r_right_i;\n"
1409
                        "\t\t\t// Other inputs are simply delayed on second clock\n"
1410
                        "\t\t\tir_coef_r <= r_coef[(2*CWIDTH-1):CWIDTH];\n"
1411
                        "\t\t\tir_coef_i <= r_coef[(CWIDTH-1):0];\n"
1412
                "\t\tend\n"
1413
        "\n\n");
1414
        fprintf(fp,
1415
"\t// See comments in the butterfly.v source file for a discussion of\n"
1416
"\t// these operations and the appropriate bit widths.\n\n");
1417
        fprintf(fp,
1418
        "\twire\tsigned [((IWIDTH+1)+(CWIDTH)-1):0]     p_one, p_two;\n"
1419
        "\twire\tsigned [((IWIDTH+2)+(CWIDTH+1)-1):0]   p_three;\n"
1420
"\n"
1421
        "\tinitial leftv    = 0;\n"
1422
        "\tinitial leftvv   = 0;\n");
1423
        if (async_reset)
1424
                fprintf(fp, "\talways @(posedge i_clk, negedge i_areset_n)\n\t\tif (!i_areset_n)\n");
1425
        else
1426
                fprintf(fp, "\talways @(posedge i_clk)\n\t\tif (i_reset)\n");
1427
        fprintf(fp,
1428
                "\t\tbegin\n"
1429
                        "\t\t\tleftv <= 0;\n"
1430
                        "\t\t\tleftvv <= 0;\n"
1431
                "\t\tend else if (i_ce)\n"
1432
                "\t\tbegin\n"
1433
                        "\t\t\t// Second clock, pipeline = 1\n"
1434
                        "\t\t\tleftv <= { r_aux_2, r_sum_r, r_sum_i };\n"
1435
"\n"
1436
                        "\t\t\t// Third clock, pipeline = 3\n"
1437
                        "\t\t\t//   As desired, each of these lines infers a DSP48\n"
1438
                        "\t\t\tleftvv <= leftv;\n"
1439
                "\t\tend\n"
1440
"\n");
1441
 
1442
        // Nominally, we should handle code for 1, 2, or 3 clocks per CE, with
1443
        // one clock per CE meaning CE could be constant.  The code below
1444
        // instead handles 1 or 3 clocks per CE, leaving the two clocks per
1445
        // CE optimization(s) unfulfilled.
1446
 
1447
//      fprintf(fp,
1448
//"\tend else if (CKPCI == 2'b01)\n\tbegin\n");
1449
 
1450
        ///////////////////////////////////////////
1451
        ///
1452
        ///     One clock per CE, so CE, CE, CE, CE, CE is possible
1453
        ///
1454
        fprintf(fp,
1455
"\tgenerate if (CKPCE <= 1)\n\tbegin : CKPCE_ONE\n");
1456
 
1457
        fprintf(fp,
1458
        "\t\t// Coefficient multiply inputs\n"
1459
        "\t\treg\tsigned        [(CWIDTH-1):0]  p1c_in, p2c_in;\n"
1460
        "\t\t// Data multiply inputs\n"
1461
        "\t\treg\tsigned        [(IWIDTH):0]    p1d_in, p2d_in;\n"
1462
        "\t\t// Product 3, coefficient input\n"
1463
        "\t\treg\tsigned        [(CWIDTH):0]    p3c_in;\n"
1464
        "\t\t// Product 3, data input\n"
1465
        "\t\treg\tsigned        [(IWIDTH+1):0]  p3d_in;\n"
1466
"\n");
1467
        fprintf(fp,
1468
        "\t\treg\tsigned        [((IWIDTH+1)+(CWIDTH)-1):0]     rp_one, rp_two;\n"
1469
        "\t\treg\tsigned        [((IWIDTH+2)+(CWIDTH+1)-1):0]   rp_three;\n"
1470
"\n");
1471
 
1472
        fprintf(fp,
1473
        "\t\talways @(posedge i_clk)\n"
1474
        "\t\tif (i_ce)\n"
1475
        "\t\tbegin\n"
1476
                "\t\t\t// Second clock, pipeline = 1\n"
1477
                "\t\t\tp1c_in <= ir_coef_r;\n"
1478
                "\t\t\tp2c_in <= ir_coef_i;\n"
1479
                "\t\t\tp1d_in <= r_dif_r;\n"
1480
                "\t\t\tp2d_in <= r_dif_i;\n"
1481
                "\t\t\tp3c_in <= ir_coef_i + ir_coef_r;\n"
1482
                "\t\t\tp3d_in <= r_dif_r + r_dif_i;\n"
1483
        "\t\tend\n\n");
1484
 
1485
        if (formal_property_flag)
1486
                fprintf(fp,
1487
"`ifndef        FORMAL\n");
1488
 
1489
        fprintf(fp,
1490
        "\t\talways @(posedge i_clk)\n"
1491
        "\t\tif (i_ce)\n"
1492
        "\t\tbegin\n"
1493
                "\t\t\t// Third clock, pipeline = 3\n"
1494
                "\t\t\t//   As desired, each of these lines infers a DSP48\n"
1495
                "\t\t\trp_one   <= p1c_in * p1d_in;\n"
1496
                "\t\t\trp_two   <= p2c_in * p2d_in;\n"
1497
                "\t\t\trp_three <= p3c_in * p3d_in;\n"
1498
        "\t\tend\n");
1499
 
1500
        if (formal_property_flag)
1501
                fprintf(fp,
1502
"`else\n"
1503
                "\t\twire       signed  [((IWIDTH+1)+(CWIDTH)-1):0]     pre_rp_one, pre_rp_two;\n"
1504
                "\t\twire       signed  [((IWIDTH+2)+(CWIDTH+1)-1):0]   pre_rp_three;\n"
1505
"\n"
1506
                "\t\tabs_mpy #(CWIDTH,IWIDTH+1,1'b1)\n"
1507
                "\t\t   onei(p1c_in, p1d_in, pre_rp_one);\n"
1508
                "\t\tabs_mpy #(CWIDTH,IWIDTH+1,1'b1)\n"
1509
                "\t\t   twoi(p2c_in, p2d_in, pre_rp_two);\n"
1510
                "\t\tabs_mpy #(CWIDTH+1,IWIDTH+2,1'b1)\n"
1511
                "\t\t   threei(p3c_in, p3d_in, pre_rp_three);\n"
1512
"\n"
1513
                "\t\talways @(posedge i_clk)\n"
1514
                "\t\tif (i_ce)\n"
1515
                "\t\tbegin\n"
1516
                "\t\t   rp_one   = pre_rp_one;\n"
1517
                "\t\t   rp_two   = pre_rp_two;\n"
1518
                "\t\t   rp_three = pre_rp_three;\n"
1519
                "\t\tend\n"
1520
"`endif // FORMAL\n");
1521
 
1522
        fprintf(fp,"\n"
1523
        "\t\tassign\tp_one   = rp_one;\n"
1524
        "\t\tassign\tp_two   = rp_two;\n"
1525
        "\t\tassign\tp_three = rp_three;\n"
1526
"\n");
1527
 
1528
        ///////////////////////////////////////////
1529
        ///
1530
        ///     Two clocks per CE, so CE, no-ce, CE, no-ce, etc
1531
        ///
1532
        fprintf(fp,
1533
        "\tend else if (CKPCE <= 2)\n"
1534
        "\tbegin : CKPCE_TWO\n"
1535
                "\t\t// Coefficient multiply inputs\n"
1536
                "\t\treg                [2*(CWIDTH)-1:0]        mpy_pipe_c;\n"
1537
                "\t\t// Data multiply inputs\n"
1538
                "\t\treg                [2*(IWIDTH+1)-1:0]      mpy_pipe_d;\n"
1539
                "\t\twire       signed  [(CWIDTH-1):0]  mpy_pipe_vc;\n"
1540
                "\t\twire       signed  [(IWIDTH):0]    mpy_pipe_vd;\n"
1541
                "\t\t//\n"
1542
                "\t\treg        signed  [(CWIDTH+1)-1:0]        mpy_cof_sum;\n"
1543
                "\t\treg        signed  [(IWIDTH+2)-1:0]        mpy_dif_sum;\n"
1544
"\n"
1545
                "\t\tassign     mpy_pipe_vc =  mpy_pipe_c[2*(CWIDTH)-1:CWIDTH];\n"
1546
                "\t\tassign     mpy_pipe_vd =  mpy_pipe_d[2*(IWIDTH+1)-1:IWIDTH+1];\n"
1547
"\n"
1548
                "\t\treg                        mpy_pipe_v;\n"
1549
                "\t\treg                        ce_phase;\n"
1550
"\n"
1551
                "\t\treg        signed  [(CWIDTH+IWIDTH+1)-1:0] mpy_pipe_out;\n"
1552
                "\t\treg        signed [IWIDTH+CWIDTH+3-1:0]    longmpy;\n"
1553
"\n"
1554
"\n"
1555
                "\t\tinitial    ce_phase = 1'b1;\n"
1556
                "\t\talways @(posedge i_clk)\n"
1557
                "\t\tif (i_reset)\n"
1558
                        "\t\t\tce_phase <= 1'b1;\n"
1559
                "\t\telse if (i_ce)\n"
1560
                        "\t\t\tce_phase <= 1'b0;\n"
1561
                "\t\telse\n"
1562
                        "\t\t\tce_phase <= 1'b1;\n"
1563
"\n"
1564
                "\t\talways @(*)\n"
1565
                        "\t\t\tmpy_pipe_v = (i_ce)||(!ce_phase);\n"
1566
"\n"
1567
                "\t\talways @(posedge i_clk)\n"
1568
                "\t\tif (!ce_phase)\n"
1569
                "\t\tbegin\n"
1570
                        "\t\t\t// Pre-clock\n"
1571
                        "\t\t\tmpy_pipe_c[2*CWIDTH-1:0] <=\n"
1572
                                "\t\t\t\t\t{ ir_coef_r, ir_coef_i };\n"
1573
                        "\t\t\tmpy_pipe_d[2*(IWIDTH+1)-1:0] <=\n"
1574
                                "\t\t\t\t\t{ r_dif_r, r_dif_i };\n"
1575
"\n"
1576
                        "\t\t\tmpy_cof_sum  <= ir_coef_i + ir_coef_r;\n"
1577
                        "\t\t\tmpy_dif_sum <= r_dif_r + r_dif_i;\n"
1578
"\n"
1579
                "\t\tend else if (i_ce)\n"
1580
                "\t\tbegin\n"
1581
                        "\t\t\t// First clock\n"
1582
                        "\t\t\tmpy_pipe_c[2*(CWIDTH)-1:0] <= {\n"
1583
                                "\t\t\t\tmpy_pipe_c[(CWIDTH)-1:0], {(CWIDTH){1'b0}} };\n"
1584
                        "\t\t\tmpy_pipe_d[2*(IWIDTH+1)-1:0] <= {\n"
1585
                                "\t\t\t\tmpy_pipe_d[(IWIDTH+1)-1:0], {(IWIDTH+1){1'b0}} };\n"
1586
                "\t\tend\n\n");
1587
 
1588
        if (formal_property_flag)
1589
                fprintf(fp, "`ifndef    FORMAL\n");
1590
 
1591
        fprintf(fp,
1592
                "\t\talways @(posedge i_clk)\n"
1593
                "\t\tif (i_ce) // First clock\n"
1594
                        "\t\t\tlongmpy <= mpy_cof_sum * mpy_dif_sum;\n"
1595
"\n"
1596
                "\t\talways @(posedge i_clk)\n"
1597
                "\t\tif (mpy_pipe_v)\n"
1598
                        "\t\t\tmpy_pipe_out <= mpy_pipe_vc * mpy_pipe_vd;\n");
1599
 
1600
        if (formal_property_flag)
1601
                fprintf(fp, "`else\n"
1602
                "\t\twire       signed [IWIDTH+CWIDTH+3-1:0]    pre_longmpy;\n"
1603
                "\t\twire       signed  [(CWIDTH+IWIDTH+1)-1:0] pre_mpy_pipe_out;\n"
1604
"\n"
1605
                "\t\tabs_mpy    #(CWIDTH+1,IWIDTH+2,1)\n"
1606
                "\t\t   longmpyi(mpy_cof_sum, mpy_dif_sum, pre_longmpy);\n"
1607
"\n"
1608
                "\t\talways @(posedge i_clk)\n"
1609
                "\t\tif (i_ce)\n"
1610
                "\t\t   longmpy <= pre_longmpy;\n"
1611
"\n"
1612
"\n"
1613
                "\t\tabs_mpy #(CWIDTH,IWIDTH+1,1)\n"
1614
                "\t\t   mpy_pipe_outi(mpy_pipe_vc, mpy_pipe_vd, pre_mpy_pipe_out);\n"
1615
"\n"
1616
                "\t\talways @(posedge i_clk)\n"
1617
                "\t\tif (mpy_pipe_v)\n"
1618
                "\t\t   mpy_pipe_out <= pre_mpy_pipe_out;\n"
1619
"`endif\n");
1620
 
1621
        fprintf(fp,"\n"
1622
                "\t\treg\tsigned\t[((IWIDTH+1)+(CWIDTH)-1):0]   rp_one,\n"
1623
                                "\t\t\t\t\t\t\trp2_one, rp_two;\n"
1624
                "\t\treg\tsigned\t[((IWIDTH+2)+(CWIDTH+1)-1):0] rp_three;\n"
1625
"\n"
1626
                "\t\talways @(posedge i_clk)\n"
1627
                "\t\tif (!ce_phase) // 1.5 clock\n"
1628
                        "\t\t\trp_one <= mpy_pipe_out;\n"
1629
                "\t\talways @(posedge i_clk)\n"
1630
                "\t\tif (i_ce) // two clocks\n"
1631
                        "\t\t\trp_two <= mpy_pipe_out;\n"
1632
                "\t\talways @(posedge i_clk)\n"
1633
                "\t\tif (i_ce) // Second clock\n"
1634
                        "\t\t\trp_three<= longmpy;\n"
1635
                "\t\talways @(posedge i_clk)\n"
1636
                "\t\tif (i_ce)\n"
1637
                        "\t\t\trp2_one<= rp_one;\n"
1638
"\n"
1639
                "\t\tassign     p_one  = rp2_one;\n"
1640
                "\t\tassign     p_two  = rp_two;\n"
1641
                "\t\tassign     p_three= rp_three;\n"
1642
"\n");
1643
 
1644
        /////////////////////////
1645
        ///
1646
        ///     Three clock per CE, so CE, no-ce, no-ce*, CE
1647
        ///
1648
        fprintf(fp,
1649
"\tend else if (CKPCE <= 2'b11)\n\tbegin : CKPCE_THREE\n");
1650
 
1651
        fprintf(fp,
1652
        "\t\t// Coefficient multiply inputs\n"
1653
        "\t\treg\t\t[3*(CWIDTH+1)-1:0]\tmpy_pipe_c;\n"
1654
        "\t\t// Data multiply inputs\n"
1655
        "\t\treg\t\t[3*(IWIDTH+2)-1:0]\tmpy_pipe_d;\n"
1656
        "\t\twire\tsigned       [(CWIDTH):0]    mpy_pipe_vc;\n"
1657
        "\t\twire\tsigned       [(IWIDTH+1):0]  mpy_pipe_vd;\n"
1658
        "\n"
1659
        "\t\tassign\tmpy_pipe_vc =  mpy_pipe_c[3*(CWIDTH+1)-1:2*(CWIDTH+1)];\n"
1660
        "\t\tassign\tmpy_pipe_vd =  mpy_pipe_d[3*(IWIDTH+2)-1:2*(IWIDTH+2)];\n"
1661
        "\n"
1662
        "\t\treg\t\t\tmpy_pipe_v;\n"
1663
        "\t\treg\t\t[2:0]\tce_phase;\n"
1664
        "\n"
1665
        "\t\treg\tsigned        [  (CWIDTH+IWIDTH+3)-1:0]       mpy_pipe_out;\n"
1666
"\n");
1667
        fprintf(fp,
1668
        "\t\tinitial\tce_phase = 3'b011;\n"
1669
        "\t\talways @(posedge i_clk)\n"
1670
        "\t\tif (i_reset)\n"
1671
                "\t\t\tce_phase <= 3'b011;\n"
1672
        "\t\telse if (i_ce)\n"
1673
                "\t\t\tce_phase <= 3'b000;\n"
1674
        "\t\telse if (ce_phase != 3'b011)\n"
1675
                "\t\t\tce_phase <= ce_phase + 1'b1;\n"
1676
"\n"
1677
        "\t\talways @(*)\n"
1678
                "\t\t\tmpy_pipe_v = (i_ce)||(ce_phase < 3'b010);\n"
1679
"\n");
1680
 
1681
        fprintf(fp,
1682
        "\t\talways @(posedge i_clk)\n"
1683
                "\t\t\tif (ce_phase == 3\'b000)\n"
1684
                "\t\t\tbegin\n"
1685
                        "\t\t\t\t// Second clock\n"
1686
                        "\t\t\t\tmpy_pipe_c[3*(CWIDTH+1)-1:(CWIDTH+1)] <= {\n"
1687
                        "\t\t\t\t\tir_coef_r[CWIDTH-1], ir_coef_r,\n"
1688
                        "\t\t\t\t\tir_coef_i[CWIDTH-1], ir_coef_i };\n"
1689
                        "\t\t\t\tmpy_pipe_c[CWIDTH:0] <= ir_coef_i + ir_coef_r;\n"
1690
                        "\t\t\t\tmpy_pipe_d[3*(IWIDTH+2)-1:(IWIDTH+2)] <= {\n"
1691
                        "\t\t\t\t\tr_dif_r[IWIDTH], r_dif_r,\n"
1692
                        "\t\t\t\t\tr_dif_i[IWIDTH], r_dif_i };\n"
1693
                        "\t\t\t\tmpy_pipe_d[(IWIDTH+2)-1:0] <= r_dif_r + r_dif_i;\n"
1694
"\n"
1695
                "\t\t\tend else if (mpy_pipe_v)\n"
1696
                "\t\t\tbegin\n"
1697
                        "\t\t\t\tmpy_pipe_c[3*(CWIDTH+1)-1:0] <= {\n"
1698
                        "\t\t\t\t\tmpy_pipe_c[2*(CWIDTH+1)-1:0], {(CWIDTH+1){1\'b0}} };\n"
1699
                        "\t\t\t\tmpy_pipe_d[3*(IWIDTH+2)-1:0] <= {\n"
1700
                        "\t\t\t\t\tmpy_pipe_d[2*(IWIDTH+2)-1:0], {(IWIDTH+2){1\'b0}} };\n"
1701
                "\t\t\tend\n\n");
1702
 
1703
        if (formal_property_flag)
1704
                fprintf(fp, "`ifndef\tFORMAL\n");
1705
 
1706
        fprintf(fp,
1707
        "\t\talways @(posedge i_clk)\n"
1708
        "\t\t\tif (mpy_pipe_v)\n"
1709
                        "\t\t\t\tmpy_pipe_out <= mpy_pipe_vc * mpy_pipe_vd;\n"
1710
"\n");
1711
 
1712
        if (formal_property_flag)
1713
                fprintf(fp,
1714
"`else\t// FORMAL\n"
1715
                "\t\twire       signed  [  (CWIDTH+IWIDTH+3)-1:0] pre_mpy_pipe_out;\n"
1716
"\n"
1717
                "\t\tabs_mpy #(CWIDTH+1,IWIDTH+2,1)\n"
1718
                "\t\t   mpy_pipe_outi(mpy_pipe_vc, mpy_pipe_vd, pre_mpy_pipe_out);\n"
1719
                "\t\talways @(posedge i_clk)\n"
1720
                "\t\t   if (mpy_pipe_v)\n"
1721
                "\t\t           mpy_pipe_out <= pre_mpy_pipe_out;\n"
1722
"`endif\t// FORMAL\n\n");
1723
 
1724
 
1725
        fprintf(fp,
1726
        "\t\treg\tsigned\t[((IWIDTH+1)+(CWIDTH)-1):0]\trp_one, rp_two,\n"
1727
                                        "\t\t\t\t\t\trp2_one, rp2_two;\n"
1728
        "\t\treg\tsigned\t[((IWIDTH+2)+(CWIDTH+1)-1):0]\trp_three, rp2_three;\n"
1729
 
1730
"\n");
1731
 
1732
        fprintf(fp,
1733
        "\t\talways @(posedge i_clk)\n"
1734
        "\t\tif(i_ce)\n"
1735
                "\t\t\trp_one <= mpy_pipe_out[(CWIDTH+IWIDTH):0];\n"
1736
        "\t\talways @(posedge i_clk)\n"
1737
        "\t\tif(ce_phase == 3'b000)\n"
1738
                "\t\t\trp_two <= mpy_pipe_out[(CWIDTH+IWIDTH):0];\n"
1739
        "\t\talways @(posedge i_clk)\n"
1740
        "\t\tif(ce_phase == 3'b001)\n"
1741
                "\t\t\trp_three <= mpy_pipe_out;\n"
1742
        "\t\talways @(posedge i_clk)\n"
1743
        "\t\tif (i_ce)\n"
1744
        "\t\tbegin\n"
1745
                "\t\t\trp2_one<= rp_one;\n"
1746
                "\t\t\trp2_two<= rp_two;\n"
1747
                "\t\t\trp2_three<= rp_three;\n"
1748
        "\t\tend\n");
1749
        fprintf(fp,
1750
        "\t\tassign     p_one\t= rp2_one;\n"
1751
        "\t\tassign     p_two\t= rp2_two;\n"
1752
        "\t\tassign\tp_three\t= rp2_three;\n"
1753
"\n");
1754
 
1755
        fprintf(fp,
1756
"\tend endgenerate\n");
1757
 
1758
        fprintf(fp,
1759
        "\twire\tsigned [((IWIDTH+2)+(CWIDTH+1)-1):0]   w_one, w_two;\n"
1760
        "\tassign\tw_one = { {(2){p_one[((IWIDTH+1)+(CWIDTH)-1)]}}, p_one };\n"
1761
        "\tassign\tw_two = { {(2){p_two[((IWIDTH+1)+(CWIDTH)-1)]}}, p_two };\n"
1762
"\n");
1763
 
1764
        fprintf(fp,
1765
        "\t// These values are held in memory and delayed during the\n"
1766
        "\t// multiply.  Here, we recover them.  During the multiply,\n"
1767
        "\t// values were multiplied by 2^(CWIDTH-2)*exp{-j*2*pi*...},\n"
1768
        "\t// therefore, the left_x values need to be right shifted by\n"
1769
        "\t// CWIDTH-2 as well.  The additional bits come from a sign\n"
1770
        "\t// extension.\n"
1771
        "\twire\taux_s;\n"
1772
        "\twire\tsigned\t[(IWIDTH+CWIDTH):0]    left_si, left_sr;\n"
1773
        "\treg\t\t[(2*IWIDTH+2):0]      left_saved;\n"
1774
        "\tassign\tleft_sr = { {2{left_saved[2*(IWIDTH+1)-1]}}, left_saved[(2*(IWIDTH+1)-1):(IWIDTH+1)], {(CWIDTH-2){1\'b0}} };\n"
1775
        "\tassign\tleft_si = { {2{left_saved[(IWIDTH+1)-1]}}, left_saved[((IWIDTH+1)-1):0], {(CWIDTH-2){1\'b0}} };\n"
1776
        "\tassign\taux_s = left_saved[2*IWIDTH+2];\n"
1777
"\n"
1778
        "\t(* use_dsp48=\"no\" *)\n"
1779
        "\treg  signed  [(CWIDTH+IWIDTH+3-1):0] mpy_r, mpy_i;\n"
1780
"\n");
1781
 
1782
        fprintf(fp,
1783
        "\tinitial left_saved = 0;\n"
1784
        "\tinitial o_aux      = 1\'b0;\n");
1785
        if (async_reset)
1786
                fprintf(fp, "\talways @(posedge i_clk, negedge i_areset_n)\n\t\tif (!i_areset_n)\n");
1787
        else
1788
                fprintf(fp, "\talways @(posedge i_clk)\n\t\tif (i_reset)\n");
1789
        fprintf(fp,
1790
        "\t\tbegin\n"
1791
                "\t\t\tleft_saved <= 0;\n"
1792
                "\t\t\to_aux <= 1\'b0;\n"
1793
        "\t\tend else if (i_ce)\n"
1794
        "\t\tbegin\n"
1795
                "\t\t\t// First clock, recover all values\n"
1796
                "\t\t\tleft_saved <= leftvv;\n"
1797
"\n"
1798
                "\t\t\t// Second clock, round and latch for final clock\n"
1799
                "\t\t\to_aux <= aux_s;\n"
1800
        "\t\tend\n"
1801
        "\talways @(posedge i_clk)\n"
1802
        "\t\tif (i_ce)\n"
1803
        "\t\tbegin\n"
1804
                "\t\t\t// These values are IWIDTH+CWIDTH+3 bits wide\n"
1805
                "\t\t\t// although they only need to be (IWIDTH+1)\n"
1806
                "\t\t\t// + (CWIDTH) bits wide.  (We've got two\n"
1807
                "\t\t\t// extra bits we need to get rid of.)\n"
1808
                "\n"
1809
                "\t\t\t// These two lines also infer DSP48\'s.\n"
1810
                "\t\t\t// To keep from using extra DSP48 resources,\n"
1811
                "\t\t\t// they are prevented from using DSP48\'s\n"
1812
                "\t\t\t// by the (* use_dsp48 ... *) comment above.\n"
1813
                "\t\t\tmpy_r <= w_one - w_two;\n"
1814
                "\t\t\tmpy_i <= p_three - w_one - w_two;\n"
1815
        "\t\tend\n"
1816
        "\n");
1817
 
1818
        fprintf(fp,
1819
        "\t// Round the results\n"
1820
        "\twire\tsigned\t[(OWIDTH-1):0]\trnd_left_r, rnd_left_i, rnd_right_r, rnd_right_i;\n\n");
1821
        fprintf(fp,
1822
        "\t%s #(CWIDTH+IWIDTH+1,OWIDTH,SHIFT+2) do_rnd_left_r(i_clk, i_ce,\n"
1823
        "\t\t\t\tleft_sr, rnd_left_r);\n\n",
1824
                rnd_string);
1825
        fprintf(fp,
1826
        "\t%s #(CWIDTH+IWIDTH+1,OWIDTH,SHIFT+2) do_rnd_left_i(i_clk, i_ce,\n"
1827
        "\t\t\t\tleft_si, rnd_left_i);\n\n",
1828
                rnd_string);
1829
        fprintf(fp,
1830
        "\t%s #(CWIDTH+IWIDTH+3,OWIDTH,SHIFT+4) do_rnd_right_r(i_clk, i_ce,\n"
1831
        "\t\t\t\tmpy_r, rnd_right_r);\n\n", rnd_string);
1832
        fprintf(fp,
1833
        "\t%s #(CWIDTH+IWIDTH+3,OWIDTH,SHIFT+4) do_rnd_right_i(i_clk, i_ce,\n"
1834
        "\t\t\t\tmpy_i, rnd_right_i);\n\n", rnd_string);
1835
 
1836
 
1837
        fprintf(fp,
1838
        "\t// As a final step, we pack our outputs into two packed two's\n"
1839
        "\t// complement numbers per output word, so that each output word\n"
1840
        "\t// has (2*OWIDTH) bits in it, with the top half being the real\n"
1841
        "\t// portion and the bottom half being the imaginary portion.\n"
1842
        "\tassign\to_left = { rnd_left_r, rnd_left_i };\n"
1843
        "\tassign\to_right= { rnd_right_r,rnd_right_i};\n"
1844
"\n");
1845
 
1846
        if (formal_property_flag) {
1847
                fprintf(fp,
1848
"`ifdef FORMAL\n"
1849
        "\tlocalparam   F_LGDEPTH = 3;\n"
1850
        "\tlocalparam   F_DEPTH = 5;\n"
1851
        "\tlocalparam   [F_LGDEPTH-1:0] F_D = F_DEPTH-1;\n"
1852
"\n"
1853
        "\treg  signed  [IWIDTH-1:0]    f_dlyleft_r  [0:F_DEPTH-1];\n"
1854
        "\treg  signed  [IWIDTH-1:0]    f_dlyleft_i  [0:F_DEPTH-1];\n"
1855
        "\treg  signed  [IWIDTH-1:0]    f_dlyright_r [0:F_DEPTH-1];\n"
1856
        "\treg  signed  [IWIDTH-1:0]    f_dlyright_i [0:F_DEPTH-1];\n"
1857
        "\treg  signed  [CWIDTH-1:0]    f_dlycoeff_r [0:F_DEPTH-1];\n"
1858
        "\treg  signed  [CWIDTH-1:0]    f_dlycoeff_i [0:F_DEPTH-1];\n"
1859
        "\treg  signed  [F_DEPTH-1:0]   f_dlyaux;\n"
1860
"\n"
1861
        "\talways @(posedge i_clk)\n"
1862
        "\tif (i_reset)\n"
1863
                "\t\tf_dlyaux <= 0;\n"
1864
        "\telse if (i_ce)\n"
1865
                "\t\tf_dlyaux <= { f_dlyaux[F_DEPTH-2:0], i_aux };\n"
1866
"\n"
1867
        "\talways @(posedge i_clk)\n"
1868
        "\tif (i_ce)\n"
1869
        "\tbegin\n"
1870
                "\t\tf_dlyleft_r[0]   <= i_left[ (2*IWIDTH-1):IWIDTH];\n"
1871
                "\t\tf_dlyleft_i[0]   <= i_left[ (  IWIDTH-1):0];\n"
1872
                "\t\tf_dlyright_r[0]  <= i_right[(2*IWIDTH-1):IWIDTH];\n"
1873
                "\t\tf_dlyright_i[0]  <= i_right[(  IWIDTH-1):0];\n"
1874
                "\t\tf_dlycoeff_r[0]  <= i_coef[ (2*CWIDTH-1):CWIDTH];\n"
1875
                "\t\tf_dlycoeff_i[0]  <= i_coef[ (  CWIDTH-1):0];\n"
1876
        "\tend\n"
1877
"\n"
1878
        "\tgenvar       k;\n"
1879
        "\tgenerate for(k=1; k<F_DEPTH; k=k+1)\n"
1880
"\n"
1881
                "\t\talways @(posedge i_clk)\n"
1882
                "\t\tif (i_ce)\n"
1883
                "\t\tbegin\n"
1884
                        "\t\t\tf_dlyleft_r[k]  <= f_dlyleft_r[ k-1];\n"
1885
                        "\t\t\tf_dlyleft_i[k]  <= f_dlyleft_i[ k-1];\n"
1886
                        "\t\t\tf_dlyright_r[k] <= f_dlyright_r[k-1];\n"
1887
                        "\t\t\tf_dlyright_i[k] <= f_dlyright_i[k-1];\n"
1888
                        "\t\t\tf_dlycoeff_r[k] <= f_dlycoeff_r[k-1];\n"
1889
                        "\t\t\tf_dlycoeff_i[k] <= f_dlycoeff_i[k-1];\n"
1890
                "\t\tend\n"
1891
"\n"
1892
        "\tendgenerate\n"
1893
"\n"
1894
"`ifdef VERILATOR"
1895
/*
1896
        "\tgenerate if (CKPCE <= 1)\n"
1897
        "\tbegin\n"
1898
"\n"
1899
        "\t\t// i_ce is allowed to be anything in this mode\n"
1900
"\n"
1901
        "\tend else if (CKPCE == 2)\n"
1902
        "\tbegin : F_CKPCE_TWO\n"
1903
"\n"
1904
                "\t\tassert property (@(posedge i_clk)\n"
1905
                "\t\t   i_ce |=> !i_ce);\n"
1906
        "\n"
1907
        "\tend else if (CKPCE == 3)\n"
1908
        "\tbegin : F_CKPCE_THREE\n"
1909
"\n"
1910
                "\t\tassert property (@(posedge i_clk)\n"
1911
                "\t\t   i_ce |=> !i_ce ##1 !i_ce);\n"
1912
"\n"
1913
        "\tend endgenerate\n"
1914
*/
1915
"\n"
1916
"`else\n"
1917
        "\talways @(posedge i_clk)\n"
1918
        "\tif ((!$past(i_ce))&&(!$past(i_ce,2))&&(!$past(i_ce,3))\n"
1919
                        "\t\t\t&&(!$past(i_ce,4)))\n"
1920
                "\t\tassume(i_ce);\n"
1921
"\n"
1922
        "\tgenerate if (CKPCE <= 1)\n"
1923
        "\tbegin\n"
1924
"\n"
1925
        "\t\t// i_ce is allowed to be anything in this mode\n"
1926
"\n"
1927
        "\tend else if (CKPCE == 2)\n"
1928
        "\tbegin : F_CKPCE_TWO\n"
1929
"\n"
1930
                "\t\talways @(posedge i_clk)\n"
1931
                "\t\t   if ($past(i_ce))\n"
1932
                "\t\t           assume(!i_ce);\n"
1933
        "\n"
1934
        "\tend else if (CKPCE == 3)\n"
1935
        "\tbegin : F_CKPCE_THREE\n"
1936
"\n"
1937
                "\t\talways @(posedge i_clk)\n"
1938
                "\t\t   if (($past(i_ce))||($past(i_ce,2)))\n"
1939
                "\t\t           assume(!i_ce);\n"
1940
"\n"
1941
        "\tend endgenerate\n"
1942
"`endif"
1943
"\n"
1944
        "\treg  [F_LGDEPTH-1:0] f_startup_counter;\n"
1945
        "\tinitial      f_startup_counter = 0;\n"
1946
        "\talways @(posedge i_clk)\n"
1947
        "\tif (i_reset)\n"
1948
                "\t\tf_startup_counter <= 0;\n"
1949
        "\telse if ((i_ce)&&(!(&f_startup_counter)))\n"
1950
                "\t\tf_startup_counter <= f_startup_counter + 1;\n"
1951
"\n"
1952
        "\twire signed  [IWIDTH:0]      f_sumr, f_sumi;\n"
1953
        "\talways @(*)\n"
1954
        "\tbegin\n"
1955
                "\t\tf_sumr = f_dlyleft_r[F_D] + f_dlyright_r[F_D];\n"
1956
                "\t\tf_sumi = f_dlyleft_i[F_D] + f_dlyright_i[F_D];\n"
1957
        "\tend\n"
1958
"\n"
1959
        "\twire signed  [IWIDTH+CWIDTH:0]       f_sumrx, f_sumix;\n"
1960
        "\tassign       f_sumrx = { {(2){f_sumr[IWIDTH]}}, f_sumr, {(CWIDTH-2){1'b0}} };\n"
1961
        "\tassign       f_sumix = { {(2){f_sumi[IWIDTH]}}, f_sumi, {(CWIDTH-2){1'b0}} };\n"
1962
        "\n"
1963
        "\twire signed  [IWIDTH:0]      f_difr, f_difi;\n"
1964
        "\talways @(*)\n"
1965
        "\tbegin\n"
1966
                "\t\tf_difr = f_dlyleft_r[F_D] - f_dlyright_r[F_D];\n"
1967
                "\t\tf_difi = f_dlyleft_i[F_D] - f_dlyright_i[F_D];\n"
1968
        "\tend\n"
1969
"\n"
1970
        "\twire signed  [IWIDTH+CWIDTH+3-1:0]   f_difrx, f_difix;\n"
1971
        "\tassign       f_difrx = { {(CWIDTH+2){f_difr[IWIDTH]}}, f_difr };\n"
1972
        "\tassign       f_difix = { {(CWIDTH+2){f_difi[IWIDTH]}}, f_difi };\n"
1973
"\n"
1974
        "\twire signed  [IWIDTH+CWIDTH+3-1:0]   f_widecoeff_r, f_widecoeff_i;\n"
1975
        "\tassign       f_widecoeff_r = {{(IWIDTH+3){f_dlycoeff_r[F_D][CWIDTH-1]}},\n"
1976
        "\t             f_dlycoeff_r[F_D] };\n"
1977
        "\tassign       f_widecoeff_i = {{(IWIDTH+3){f_dlycoeff_i[F_D][CWIDTH-1]}},\n"
1978
        "\t             f_dlycoeff_i[F_D] };\n"
1979
"\n"
1980
        "\talways @(posedge i_clk)\n"
1981
        "\tif (f_startup_counter > F_D)\n"
1982
        "\tbegin\n"
1983
                "\t\tassert(left_sr == f_sumrx);\n"
1984
                "\t\tassert(left_si == f_sumix);\n"
1985
                "\t\tassert(aux_s == f_dlyaux[F_D]);\n"
1986
"\n"
1987
                "\t\tif ((f_difr == 0)&&(f_difi == 0))\n"
1988
                "\t\tbegin\n"
1989
                "\t\t   assert(mpy_r == 0);\n"
1990
                "\t\t   assert(mpy_i == 0);\n"
1991
                "\t\tend else if ((f_dlycoeff_r[F_D] == 0)\n"
1992
                "\t\t           &&(f_dlycoeff_i[F_D] == 0))\n"
1993
                "\t\tbegin\n"
1994
                "\t             assert(mpy_r == 0);\n"
1995
                "\t\t   assert(mpy_i == 0);\n"
1996
                "\t\tend\n"
1997
"\n"
1998
                "\t\tif ((f_dlycoeff_r[F_D] == 1)&&(f_dlycoeff_i[F_D] == 0))\n"
1999
                "\t\tbegin\n"
2000
                "\t\t   assert(mpy_r == f_difrx);\n"
2001
                "\t\t   assert(mpy_i == f_difix);\n"
2002
                "\t\tend\n"
2003
"\n"
2004
                "\t\tif ((f_dlycoeff_r[F_D] == 0)&&(f_dlycoeff_i[F_D] == 1))\n"
2005
                "\t\tbegin\n"
2006
                "\t\t   assert(mpy_r == -f_difix);\n"
2007
                "\t\t   assert(mpy_i ==  f_difrx);\n"
2008
                "\t\tend\n"
2009
"\n"
2010
                "\t\tif ((f_difr == 1)&&(f_difi == 0))\n"
2011
                "\t\tbegin\n"
2012
                "\t\t   assert(mpy_r == f_widecoeff_r);\n"
2013
                "\t\t   assert(mpy_i == f_widecoeff_i);\n"
2014
                "\t\tend\n"
2015
"\n"
2016
                "\t\tif ((f_difr == 0)&&(f_difi == 1))\n"
2017
                "\t\tbegin\n"
2018
                "\t\t   assert(mpy_r == -f_widecoeff_i);\n"
2019
                "\t\t   assert(mpy_i ==  f_widecoeff_r);\n"
2020
                "\t\tend\n"
2021
        "\tend\n"
2022
"\n");
2023
 
2024
                fprintf(fp,
2025
        "\t// Let's see if we can improve our performance at all by\n"
2026
        "\t// moving our test one clock earlier.  If nothing else, it should\n"
2027
        "\t// help induction finish one (or more) clocks ealier than\n"
2028
        "\t// otherwise\n"
2029
"\n\n"
2030
        "\twire signed  [IWIDTH:0]      f_predifr, f_predifi;\n"
2031
        "\talways @(*)\n"
2032
        "\tbegin\n"
2033
                "\t\tf_predifr = f_dlyleft_r[F_D-1] - f_dlyright_r[F_D-1];\n"
2034
                "\t\tf_predifi = f_dlyleft_i[F_D-1] - f_dlyright_i[F_D-1];\n"
2035
        "\tend\n"
2036
"\n"
2037
        "\twire signed  [IWIDTH+CWIDTH+1-1:0]   f_predifrx, f_predifix;\n"
2038
        "\tassign       f_predifrx = { {(CWIDTH){f_predifr[IWIDTH]}}, f_predifr };\n"
2039
        "\tassign       f_predifix = { {(CWIDTH){f_predifi[IWIDTH]}}, f_predifi };\n"
2040
"\n"
2041
        "\twire signed  [CWIDTH:0]      f_sumcoef;\n"
2042
        "\twire signed  [IWIDTH+1:0]    f_sumdiff;\n"
2043
        "\talways @(*)\n"
2044
        "\tbegin\n"
2045
                "\t\tf_sumcoef = f_dlycoeff_r[F_D-1] + f_dlycoeff_i[F_D-1];\n"
2046
                "\t\tf_sumdiff = f_predifr + f_predifi;\n"
2047
        "\tend\n"
2048
"\n"
2049
        "\t// Induction helpers\n"
2050
        "\talways @(posedge i_clk)\n"
2051
        "\tif (f_startup_counter >= F_D)\n"
2052
        "\tbegin\n"
2053
                "\t\tif (f_dlycoeff_r[F_D-1] == 0)\n"
2054
                        "\t\t\tassert(p_one == 0);\n"
2055
                "\t\tif (f_dlycoeff_i[F_D-1] == 0)\n"
2056
                        "\t\t\tassert(p_two == 0);\n"
2057
"\n"
2058
                "\t\tif (f_dlycoeff_r[F_D-1] == 1)\n"
2059
                        "\t\t\tassert(p_one == f_predifrx);\n"
2060
                "\t\tif (f_dlycoeff_i[F_D-1] == 1)\n"
2061
                        "\t\t\tassert(p_two == f_predifix);\n"
2062
"\n"
2063
                "\t\tif (f_predifr == 0)\n"
2064
                        "\t\t\tassert(p_one == 0);\n"
2065
                "\t\tif (f_predifi == 0)\n"
2066
                        "\t\t\tassert(p_two == 0);\n"
2067
"\n"
2068
                "\t\t// verilator lint_off WIDTH\n"
2069
                "\t\tif (f_predifr == 1)\n"
2070
                        "\t\t\tassert(p_one == f_dlycoeff_r[F_D-1]);\n"
2071
                "\t\tif (f_predifi == 1)\n"
2072
                        "\t\t\tassert(p_two == f_dlycoeff_i[F_D-1]);\n"
2073
                "\t\t// verilator lint_on  WIDTH\n"
2074
"\n"
2075
                "\t\tif (f_sumcoef == 0)\n"
2076
                        "\t\t\tassert(p_three == 0);\n"
2077
                "\t\tif (f_sumdiff == 0)\n"
2078
                        "\t\t\tassert(p_three == 0);\n"
2079
                "\t\t// verilator lint_off WIDTH\n"
2080
                "\t\tif (f_sumcoef == 1)\n"
2081
                        "\t\t\tassert(p_three == f_sumdiff);\n"
2082
                "\t\tif (f_sumdiff == 1)\n"
2083
                        "\t\t\tassert(p_three == f_sumcoef);\n"
2084
                "\t\t// verilator lint_on  WIDTH\n"
2085
"`ifdef VERILATOR\n"
2086
                "\t\tassert(p_one   == f_predifr * f_dlycoeff_r[F_D-1]);\n"
2087
                "\t\tassert(p_two   == f_predifi * f_dlycoeff_i[F_D-1]);\n"
2088
                "\t\tassert(p_three == f_sumdiff * f_sumcoef);\n"
2089
"`endif // VERILATOR\n"
2090
        "\tend\n\n"
2091
"`endif // FORMAL\n");
2092
        }
2093
 
2094
        fprintf(fp,
2095
"endmodule\n");
2096
 
2097
        fclose(fp);
2098
}

powered by: WebSVN 2.1.0

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