Line 1... |
Line 1... |
#include <stdio.h>
|
#include <stdio.h>
|
#include <stdlib.h>
|
#include <stdlib.h>
|
#include <unistd.h>
|
#include <unistd.h>
|
#include <sys/stat.h>
|
#include <sys/stat.h>
|
#include <string.h>
|
#include <string.h>
|
|
#include <string>
|
#include <math.h>
|
#include <math.h>
|
#include <ctype.h>
|
#include <ctype.h>
|
#include <assert.h>
|
#include <assert.h>
|
|
|
#define COREDIR "fft-core"
|
#define COREDIR "fft-core"
|
Line 32... |
Line 33... |
"// License: GPL, v3, as defined and found on www.gnu.org,\n"
|
"// License: GPL, v3, as defined and found on www.gnu.org,\n"
|
"// http://www.gnu.org/licenses/gpl.html\n"
|
"// http://www.gnu.org/licenses/gpl.html\n"
|
"//\n"
|
"//\n"
|
"//\n"
|
"//\n"
|
"///////////////////////////////////////////////////////////////////////////\n";
|
"///////////////////////////////////////////////////////////////////////////\n";
|
const char prjname[] = "A Doubletime Pipelined FFT\n";
|
const char prjname[] = "A Doubletime Pipelined FFT";
|
const char creator[] = "// Creator: Dan Gisselquist, Ph.D.\n"
|
const char creator[] = "// Creator: Dan Gisselquist, Ph.D.\n"
|
"// Gisselquist Tecnology, LLC\n";
|
"// Gisselquist Tecnology, LLC\n";
|
|
|
int lgval(int vl) {
|
int lgval(int vl) {
|
int lg;
|
int lg;
|
Line 52... |
Line 53... |
for(r=1; r<vl; r<<=1)
|
for(r=1; r<vl; r<<=1)
|
;
|
;
|
return r;
|
return r;
|
}
|
}
|
|
|
int lgdelay(int nbits, int xtra) {
|
int bflydelay(int nbits, int xtra) {
|
int cbits = nbits + xtra;
|
int cbits = nbits + xtra;
|
int delay = nbits + 2;
|
int delay;
|
if (nbits+1<cbits)
|
if (nbits+1<cbits)
|
delay = nbits+4;
|
delay = nbits+4;
|
else
|
else
|
delay = cbits+3;
|
delay = cbits+3;
|
return lgval(delay);
|
return delay;
|
|
}
|
|
|
|
int lgdelay(int nbits, int xtra) {
|
|
// The butterfly code needs to compare a valid address, of this
|
|
// many bits, with an address two greater. This guarantees we
|
|
// have enough bits for that comparison. We'll also end up with
|
|
// more storage space to look for these values, but without a
|
|
// redesign that's just what we'll deal with.
|
|
return lgval(bflydelay(nbits, xtra)+3);
|
}
|
}
|
|
|
void build_quarters(const char *fname) {
|
void build_quarters(const char *fname) {
|
FILE *fp = fopen(fname, "w");
|
FILE *fp = fopen(fname, "w");
|
if (NULL == fp) {
|
if (NULL == fp) {
|
Line 98... |
Line 108... |
"\tparameter\tLGWIDTH=8, ODD=0, INVERSE=0,SHIFT=0,ROUND=0;\n"
|
"\tparameter\tLGWIDTH=8, ODD=0, INVERSE=0,SHIFT=0,ROUND=0;\n"
|
"\tinput\t i_clk, i_rst, i_ce, i_sync;\n"
|
"\tinput\t i_clk, i_rst, i_ce, i_sync;\n"
|
"\tinput\t [(2*IWIDTH-1):0] i_data;\n"
|
"\tinput\t [(2*IWIDTH-1):0] i_data;\n"
|
"\toutput\treg [(2*OWIDTH-1):0] o_data;\n"
|
"\toutput\treg [(2*OWIDTH-1):0] o_data;\n"
|
"\toutput\treg o_sync;\n"
|
"\toutput\treg o_sync;\n"
|
"\t\n"
|
"\t\n");
|
|
fprintf(fp,
|
"\treg\t wait_for_sync;\n"
|
"\treg\t wait_for_sync;\n"
|
"\treg\t[2:0] pipeline;\n"
|
"\treg\t[2:0] pipeline;\n"
|
"\n"
|
"\n"
|
"\treg\t[(IWIDTH):0] sum_r, sum_i, diff_r, diff_i;\n"
|
"\treg\t[(IWIDTH):0] sum_r, sum_i, diff_r, diff_i;\n"
|
"\twire\t[(IWIDTH):0] n_diff_i;\n"
|
"\twire\t[(IWIDTH):0] n_diff_r, n_diff_i;\n"
|
|
"\tassign n_diff_r = -diff_r;\n"
|
"\tassign n_diff_i = -diff_i;\n"
|
"\tassign n_diff_i = -diff_i;\n"
|
"\n"
|
"\n"
|
"\treg\t[(2*OWIDTH-1):0] ob_a;\n"
|
"\treg\t[(2*OWIDTH-1):0] ob_a;\n"
|
"\twire\t[(2*OWIDTH-1):0] ob_b;\n"
|
"\twire\t[(2*OWIDTH-1):0] ob_b;\n"
|
"\treg\t[(OWIDTH-1):0] ob_b_r, ob_b_i;\n"
|
"\treg\t[(OWIDTH-1):0] ob_b_r, ob_b_i;\n"
|
Line 123... |
Line 135... |
"\twire\tsigned\t[(IWIDTH-1):0]\ti_data_r, i_data_i;\n"
|
"\twire\tsigned\t[(IWIDTH-1):0]\ti_data_r, i_data_i;\n"
|
"\tassign\ti_data_r = i_data[(2*IWIDTH-1):(IWIDTH)];\n"
|
"\tassign\ti_data_r = i_data[(2*IWIDTH-1):(IWIDTH)];\n"
|
"\tassign\ti_data_i = i_data[(IWIDTH-1):0];\n"
|
"\tassign\ti_data_i = i_data[(IWIDTH-1):0];\n"
|
"\n"
|
"\n"
|
"\treg [(2*OWIDTH-1):0] omem;\n"
|
"\treg [(2*OWIDTH-1):0] omem;\n"
|
"\n"
|
"\n");
|
|
fprintf(fp,
|
"\twire [(IWIDTH-1):0] rnd;\n"
|
"\twire [(IWIDTH-1):0] rnd;\n"
|
"\tgenerate\n"
|
"\tgenerate\n"
|
"\tif ((ROUND)&&((IWIDTH+1-OWIDTH-SHIFT)>0))\n"
|
"\tif ((ROUND)&&((IWIDTH+1-OWIDTH-SHIFT)>0))\n"
|
"\t\tassign rnd = { {(IWIDTH-1){1'b0}}, 1'b1 };\n"
|
"\t\tassign rnd = { {(IWIDTH-1){1'b0}}, 1'b1 };\n"
|
"\telse\n"
|
"\telse\n"
|
Line 170... |
Line 183... |
"\t\t\t\tbegin\n"
|
"\t\t\t\tbegin\n"
|
"\t\t\t\t\tob_b_r <= diff_r[(IWIDTH-SHIFT):(IWIDTH+1-OWIDTH-SHIFT)];\n"
|
"\t\t\t\t\tob_b_r <= diff_r[(IWIDTH-SHIFT):(IWIDTH+1-OWIDTH-SHIFT)];\n"
|
"\t\t\t\t\tob_b_i <= diff_i[(IWIDTH-SHIFT):(IWIDTH+1-OWIDTH-SHIFT)];\n"
|
"\t\t\t\t\tob_b_i <= diff_i[(IWIDTH-SHIFT):(IWIDTH+1-OWIDTH-SHIFT)];\n"
|
// "\t\t\t\t\tob_b_r <= { (OWIDTH) {1'b0} };\n"
|
// "\t\t\t\t\tob_b_r <= { (OWIDTH) {1'b0} };\n"
|
// "\t\t\t\t\tob_b_i <= { (OWIDTH) {1'b0} };\n"
|
// "\t\t\t\t\tob_b_i <= { (OWIDTH) {1'b0} };\n"
|
"\t\t\t\tend else if (~INVERSE) begin\n"
|
"\t\t\t\tend else if (INVERSE==0) begin\n"
|
"\t\t\t\t\t// on Odd, W = e^{-j2pi 1/4} = -j\n"
|
"\t\t\t\t\t// on Odd, W = e^{-j2pi 1/4} = -j\n"
|
"\t\t\t\t\tob_b_r <= diff_i[(IWIDTH-SHIFT):(IWIDTH+1-OWIDTH-SHIFT)];\n"
|
"\t\t\t\t\tob_b_r <= diff_i[(IWIDTH-SHIFT):(IWIDTH+1-OWIDTH-SHIFT)];\n"
|
"\t\t\t\t\tob_b_i <= diff_r[(IWIDTH-SHIFT):(IWIDTH+1-OWIDTH-SHIFT)];\n"
|
"\t\t\t\t\tob_b_i <= n_diff_r[(IWIDTH-SHIFT):(IWIDTH+1-OWIDTH-SHIFT)];\n"
|
// "\t\t\t\t\tob_b_r <= { (OWIDTH) {1'b0} };\n"
|
// "\t\t\t\t\tob_b_r <= { (OWIDTH) {1'b0} };\n"
|
// "\t\t\t\t\tob_b_i <= { (OWIDTH) {1'b0} };\n"
|
// "\t\t\t\t\tob_b_i <= { (OWIDTH) {1'b0} };\n"
|
"\t\t\t\tend else begin\n"
|
"\t\t\t\tend else begin\n"
|
"\t\t\t\t\t// on Odd, W = e^{j2pi 1/4} = j\n"
|
"\t\t\t\t\t// on Odd, W = e^{j2pi 1/4} = j\n"
|
"\t\t\t\t\tob_b_r <= n_diff_i[(IWIDTH-SHIFT):(IWIDTH+1-OWIDTH-SHIFT)];\n"
|
"\t\t\t\t\tob_b_r <= n_diff_i[(IWIDTH-SHIFT):(IWIDTH+1-OWIDTH-SHIFT)];\n"
|
Line 532... |
Line 545... |
"endmodule;\n");
|
"endmodule;\n");
|
|
|
fclose(fp);
|
fclose(fp);
|
}
|
}
|
|
|
void build_butterfly(const char *fname) {
|
void build_butterfly(const char *fname, int xtracbits) {
|
FILE *fp = fopen(fname, "w");
|
FILE *fp = fopen(fname, "w");
|
if (NULL == fp) {
|
if (NULL == fp) {
|
fprintf(stderr, "Could not open \'%s\' for writing\n", fname);
|
fprintf(stderr, "Could not open \'%s\' for writing\n", fname);
|
perror("O/S Err was:");
|
perror("O/S Err was:");
|
return;
|
return;
|
Line 616... |
Line 629... |
|
|
fprintf(fp,
|
fprintf(fp,
|
"module\tbutterfly(i_clk, i_rst, i_ce, i_coef, i_left, i_right, i_aux,\n"
|
"module\tbutterfly(i_clk, i_rst, i_ce, i_coef, i_left, i_right, i_aux,\n"
|
"\t\to_left, o_right, o_aux);\n"
|
"\t\to_left, o_right, o_aux);\n"
|
"\t// Public changeable parameters ...\n"
|
"\t// Public changeable parameters ...\n"
|
"\tparameter IWIDTH=16,CWIDTH=IWIDTH+4,OWIDTH=IWIDTH+1;\n"
|
"\tparameter IWIDTH=%d,CWIDTH=IWIDTH+%d,OWIDTH=IWIDTH+1;\n"
|
"\t// Parameters specific to the core that should not be changed.\n"
|
"\t// Parameters specific to the core that should not be changed.\n"
|
"\tparameter MPYDELAY=5'd20, // (IWIDTH+1 < CWIDTH)?(IWIDTH+4):(CWIDTH+3),\n"
|
"\tparameter MPYDELAY=%d'd%d, // (IWIDTH+1 < CWIDTH)?(IWIDTH+4):(CWIDTH+3),\n"
|
"\t\t\tSHIFT=0, ROUND=0;\n"
|
"\t\t\tSHIFT=0, ROUND=0;\n"
|
"\t// The LGDELAY should be the base two log of the MPYDELAY. If\n"
|
"\t// The LGDELAY should be the base two log of the MPYDELAY. If\n"
|
"\t// this value is fractional, then round up to the nearest\n"
|
"\t// this value is fractional, then round up to the nearest\n"
|
"\t// integer: LGDELAY=ceil(log(MPYDELAY)/log(2));\n"
|
"\t// integer: LGDELAY=ceil(log(MPYDELAY)/log(2));\n"
|
"\tparameter\tLGDELAY=5;\n"
|
"\tparameter\tLGDELAY=%d;\n"
|
"\tinput\t\ti_clk, i_rst, i_ce;\n"
|
"\tinput\t\ti_clk, i_rst, i_ce;\n"
|
"\tinput\t\t[(2*CWIDTH-1):0] i_coef;\n"
|
"\tinput\t\t[(2*CWIDTH-1):0] i_coef;\n"
|
"\tinput\t\t[(2*IWIDTH-1):0] i_left, i_right;\n"
|
"\tinput\t\t[(2*IWIDTH-1):0] i_left, i_right;\n"
|
"\tinput\t\ti_aux;\n"
|
"\tinput\t\ti_aux;\n"
|
"\toutput\twire [(2*OWIDTH-1):0] o_left, o_right;\n"
|
"\toutput\twire [(2*OWIDTH-1):0] o_left, o_right;\n"
|
"\toutput\twire o_aux;\n"
|
"\toutput\twire o_aux;\n"
|
"\n"
|
"\n", 16, xtracbits, lgdelay(16,xtracbits),
|
|
bflydelay(16, xtracbits), lgdelay(16,xtracbits));
|
|
fprintf(fp,
|
"\twire\t[(OWIDTH-1):0] o_left_r, o_left_i, o_right_r, o_right_i;\n"
|
"\twire\t[(OWIDTH-1):0] o_left_r, o_left_i, o_right_r, o_right_i;\n"
|
"\n"
|
"\n"
|
"\treg\t[(2*IWIDTH-1):0]\tr_left, r_right;\n"
|
"\treg\t[(2*IWIDTH-1):0]\tr_left, r_right;\n"
|
"\treg\t\t\t\tr_aux, r_aux_2;\n"
|
"\treg\t\t\t\tr_aux, r_aux_2;\n"
|
"\treg\t[(2*CWIDTH-1):0]\tr_coef, r_coef_2;\n"
|
"\treg\t[(2*CWIDTH-1):0]\tr_coef, r_coef_2;\n"
|
Line 689... |
Line 704... |
"\t\t\t// Need to delay the sum side--nothing else happens\n"
|
"\t\t\t// Need to delay the sum side--nothing else happens\n"
|
"\t\t\t// to it, but it needs to stay synchronized with the\n"
|
"\t\t\t// to it, but it needs to stay synchronized with the\n"
|
"\t\t\t// right side.\n"
|
"\t\t\t// right side.\n"
|
"\t\t\tfifo_left[fifo_addr] <= { r_aux_2, r_sum_r, r_sum_i };\n"
|
"\t\t\tfifo_left[fifo_addr] <= { r_aux_2, r_sum_r, r_sum_i };\n"
|
"\t\t\tfifo_addr <= fifo_addr + 1;\n"
|
"\t\t\tfifo_addr <= fifo_addr + 1;\n"
|
"\t\t\tovalid <= (ovalid) || (fifo_addr > MPYDELAY+1);\n"
|
"\n"
|
|
"\t\t\tovalid <= (ovalid) || (fifo_addr > (MPYDELAY+1));\n"
|
"\t\tend\n"
|
"\t\tend\n"
|
"\n"
|
"\n"
|
"\twire\tsigned\t[(CWIDTH-1):0] ir_coef_r, ir_coef_i;\n"
|
"\twire\tsigned\t[(CWIDTH-1):0] ir_coef_r, ir_coef_i;\n"
|
"\tassign\tir_coef_r = r_coef_2[(2*CWIDTH-1):CWIDTH];\n"
|
"\tassign\tir_coef_r = r_coef_2[(2*CWIDTH-1):CWIDTH];\n"
|
"\tassign\tir_coef_i = r_coef_2[(CWIDTH-1):0];\n"
|
"\tassign\tir_coef_i = r_coef_2[(CWIDTH-1):0];\n"
|
Line 926... |
Line 942... |
(inv)?"i":"", (inv)?"i":"",
|
(inv)?"i":"", (inv)?"i":"",
|
(inv)?"i":"", (odd)?'o':'e',stage<<1,
|
(inv)?"i":"", (odd)?'o':'e',stage<<1,
|
(inv)?"i":"");
|
(inv)?"i":"");
|
{
|
{
|
FILE *cmem;
|
FILE *cmem;
|
char memfile[128], *ptr;
|
|
|
|
strncpy(memfile, fname, 125);
|
{
|
|
char *memfile, *ptr;
|
|
|
|
memfile = new char[strlen(fname)+128];
|
|
strcpy(memfile, fname);
|
if ((NULL != (ptr = strrchr(memfile, '/')))&&(ptr>memfile)) {
|
if ((NULL != (ptr = strrchr(memfile, '/')))&&(ptr>memfile)) {
|
ptr++;
|
ptr++;
|
sprintf(ptr, "%scmem_%c%d.hex", (inv)?"i":"", (odd)?'o':'e', stage*2);
|
sprintf(ptr, "%scmem_%c%d.hex", (inv)?"i":"", (odd)?'o':'e', stage*2);
|
} else {
|
} else {
|
sprintf(memfile, "%s/%scmem_%c%d.hex",
|
sprintf(memfile, "%s/%scmem_%c%d.hex",
|
COREDIR, (inv)?"i":"",
|
COREDIR, (inv)?"i":"",
|
(odd)?'o':'e', stage*2);
|
(odd)?'o':'e', stage*2);
|
}
|
}
|
// strcpy(&memfile[strlen(memfile)-2], ".hex");
|
// strcpy(&memfile[strlen(memfile)-2], ".hex");
|
cmem = fopen(memfile, "w");
|
cmem = fopen(memfile, "w");
|
|
if (NULL == cmem) {
|
|
fprintf(stderr, "Could not open/write \'%s\' with FFT coefficients.\n", memfile);
|
|
perror("Err from O/S:");
|
|
exit(-2);
|
|
}
|
|
|
|
delete[] memfile;
|
|
}
|
// fprintf(cmem, "// CBITS = %d, inv = %s\n", cbits, (inv)?"true":"false");
|
// fprintf(cmem, "// CBITS = %d, inv = %s\n", cbits, (inv)?"true":"false");
|
for(int i=0; i<stage/2; i++) {
|
for(int i=0; i<stage/2; i++) {
|
int k = 2*i+odd;
|
int k = 2*i+odd;
|
double W = ((inv)?1:-1)*2.0*M_PI*k/(double)(2*stage);
|
double W = ((inv)?1:-1)*2.0*M_PI*k/(double)(2*stage);
|
double c, s;
|
double c, s;
|
Line 1039... |
Line 1066... |
"\tbutterfly #(.IWIDTH(IWIDTH),.CWIDTH(CWIDTH),.OWIDTH(OWIDTH),\n"
|
"\tbutterfly #(.IWIDTH(IWIDTH),.CWIDTH(CWIDTH),.OWIDTH(OWIDTH),\n"
|
"\t\t\t.MPYDELAY(%d\'d%d),.LGDELAY(LGBDLY),.SHIFT(BFLYSHIFT))\n"
|
"\t\t\t.MPYDELAY(%d\'d%d),.LGDELAY(LGBDLY),.SHIFT(BFLYSHIFT))\n"
|
"\t\tbfly(i_clk, i_rst, i_ce, ib_c,\n"
|
"\t\tbfly(i_clk, i_rst, i_ce, ib_c,\n"
|
"\t\t\tib_a, ib_b, ib_sync, ob_a, ob_b, ob_sync);\n"
|
"\t\t\tib_a, ib_b, ib_sync, ob_a, ob_b, ob_sync);\n"
|
"endmodule;\n",
|
"endmodule;\n",
|
lgdelay(nbits, xtra), (1<xtra)?(nbits+4):(nbits+xtra+3));
|
lgdelay(nbits, xtra), bflydelay(nbits, xtra));
|
}
|
}
|
|
|
void usage(void) {
|
void usage(void) {
|
fprintf(stderr,
|
fprintf(stderr,
|
"USAGE:\tfftgen [-f <size>] [-d dir] [-c cbits] [-n nbits] [-m mxbits] [-s01]\n"
|
"USAGE:\tfftgen [-f <size>] [-d dir] [-c cbits] [-n nbits] [-m mxbits] [-s01]\n"
|
Line 1082... |
Line 1109... |
int nbitsin = 16, xtracbits = 4;
|
int nbitsin = 16, xtracbits = 4;
|
int nbitsout, maxbitsout = -1;
|
int nbitsout, maxbitsout = -1;
|
bool bitreverse = true, inverse=false, interactive = false,
|
bool bitreverse = true, inverse=false, interactive = false,
|
verbose_flag = false;
|
verbose_flag = false;
|
FILE *vmain;
|
FILE *vmain;
|
char fname[128], coredir[1024] = "fft-core";
|
std::string coredir = "fft-core", cmdline = "";
|
|
|
|
|
if (argc <= 1)
|
if (argc <= 1)
|
usage();
|
usage();
|
|
|
|
cmdline = argv[0];
|
|
for(int argn=1; argn<argc; argn++) {
|
|
cmdline += " ";
|
|
cmdline += argv[argn];
|
|
}
|
|
|
for(int argn=1; argn<argc; argn++) {
|
for(int argn=1; argn<argc; argn++) {
|
if ('-' == argv[argn][0]) {
|
if ('-' == argv[argn][0]) {
|
for(int j=1; (argv[argn][j])&&(j<100); j++) {
|
for(int j=1; (argv[argn][j])&&(j<100); j++) {
|
switch(argv[argn][j]) {
|
switch(argv[argn][j]) {
|
case '0':
|
case '0':
|
Line 1111... |
Line 1143... |
case 'd':
|
case 'd':
|
if (argn+1 >= argc) {
|
if (argn+1 >= argc) {
|
printf("No extra number of coefficient bits given\n");
|
printf("No extra number of coefficient bits given\n");
|
usage(); exit(-1);
|
usage(); exit(-1);
|
}
|
}
|
strcpy(coredir, argv[++argn]);
|
coredir = argv[++argn];
|
j += 200;
|
j += 200;
|
break;
|
break;
|
case 'f':
|
case 'f':
|
if (argn+1 >= argc) {
|
if (argn+1 >= argc) {
|
printf("No FFT Size given\n");
|
printf("No FFT Size given\n");
|
Line 1240... |
Line 1272... |
nbitsout = maxbitsout;
|
nbitsout = maxbitsout;
|
|
|
|
|
{
|
{
|
struct stat sbuf;
|
struct stat sbuf;
|
if (lstat(coredir, &sbuf)==0) {
|
if (lstat(coredir.c_str(), &sbuf)==0) {
|
if (!S_ISDIR(sbuf.st_mode)) {
|
if (!S_ISDIR(sbuf.st_mode)) {
|
fprintf(stderr, "\'%s\' already exists, and is not a directory!\n", coredir);
|
fprintf(stderr, "\'%s\' already exists, and is not a directory!\n", coredir.c_str());
|
fprintf(stderr, "I will stop now, lest I overwrite something you care about.\n");
|
fprintf(stderr, "I will stop now, lest I overwrite something you care about.\n");
|
fprintf(stderr, "To try again, please remove this file.\n");
|
fprintf(stderr, "To try again, please remove this file.\n");
|
exit(-1);
|
exit(-1);
|
}
|
}
|
} else
|
} else
|
mkdir(coredir, 0755);
|
mkdir(coredir.c_str(), 0755);
|
if (access(coredir, X_OK|W_OK) != 0) {
|
if (access(coredir.c_str(), X_OK|W_OK) != 0) {
|
fprintf(stderr, "I have no access to the directory \'%s\'.\n", coredir);
|
fprintf(stderr, "I have no access to the directory \'%s\'.\n", coredir.c_str());
|
exit(-1);
|
exit(-1);
|
}
|
}
|
}
|
}
|
|
|
sprintf(fname, "%s/%sfftmain.v", coredir, (inverse)?"i":"");
|
{
|
vmain = fopen(fname, "w");
|
std::string fname_string;
|
|
|
|
fname_string = coredir;
|
|
fname_string += "/";
|
|
if (inverse) fname_string += "i";
|
|
fname_string += "fftmain.v";
|
|
|
|
vmain = fopen(fname_string.c_str(), "w");
|
if (NULL == vmain) {
|
if (NULL == vmain) {
|
fprintf(stderr, "Could not open \'%s\' for writing\n", fname);
|
fprintf(stderr, "Could not open \'%s\' for writing\n", fname_string.c_str());
|
perror("Err from O/S:");
|
perror("Err from O/S:");
|
exit(-1);
|
exit(-1);
|
}
|
}
|
|
}
|
|
|
fprintf(vmain, "/////////////////////////////////////////////////////////////////////////////\n");
|
fprintf(vmain, "/////////////////////////////////////////////////////////////////////////////\n");
|
fprintf(vmain, "//\n");
|
fprintf(vmain, "//\n");
|
fprintf(vmain, "// Filename: %sfftmain.v\n", (inverse)?"i":"");
|
fprintf(vmain, "// Filename: %sfftmain.v\n", (inverse)?"i":"");
|
fprintf(vmain, "//\n");
|
fprintf(vmain, "//\n");
|
Line 1305... |
Line 1345... |
fprintf(vmain, "//\t\t\tThis has the same format as o_left.\n");
|
fprintf(vmain, "//\t\t\tThis has the same format as o_left.\n");
|
fprintf(vmain, "//\t\to_sync\tA one bit output indicating the first valid sample\n");
|
fprintf(vmain, "//\t\to_sync\tA one bit output indicating the first valid sample\n");
|
fprintf(vmain, "//\t\t\tproduced by this FFT following a reset. Ever after,\n");
|
fprintf(vmain, "//\t\t\tproduced by this FFT following a reset. Ever after,\n");
|
fprintf(vmain, "//\t\t\tthis will indicate the first sample of an FFT frame.\n");
|
fprintf(vmain, "//\t\t\tthis will indicate the first sample of an FFT frame.\n");
|
fprintf(vmain, "//\n");
|
fprintf(vmain, "//\n");
|
|
fprintf(vmain, "// Arguments:\tThis file was computer generated using the\n");
|
|
fprintf(vmain, "//\t\tfollowing command line:\n");
|
|
fprintf(vmain, "//\n");
|
|
fprintf(vmain, "//\t\t%% %s\n", cmdline.c_str());
|
|
fprintf(vmain, "//\n");
|
fprintf(vmain, "%s", creator);
|
fprintf(vmain, "%s", creator);
|
fprintf(vmain, "//\n");
|
fprintf(vmain, "//\n");
|
fprintf(vmain, "%s", cpyleft);
|
fprintf(vmain, "%s", cpyleft);
|
|
|
|
|
Line 1361... |
Line 1406... |
lgsize, lgtmp-2, lgdelay(nbits,xtracbits),
|
lgsize, lgtmp-2, lgdelay(nbits,xtracbits),
|
fftsize);
|
fftsize);
|
fprintf(vmain, "\t\t\t(~i_rst), i_right, w_o%d, w_os%d);\n", fftsize, fftsize);
|
fprintf(vmain, "\t\t\t(~i_rst), i_right, w_o%d, w_os%d);\n", fftsize, fftsize);
|
fprintf(vmain, "\n\n");
|
fprintf(vmain, "\n\n");
|
|
|
sprintf(fname, "%s/%sfftstage_e%d.v", coredir, (inverse)?"i":"", fftsize);
|
{
|
build_stage(fname, fftsize/2, 0, nbits, inverse, xtracbits); // Even stage
|
std::string fname;
|
sprintf(fname, "%s/%sfftstage_o%d.v", coredir, (inverse)?"i":"", fftsize);
|
char numstr[12];
|
build_stage(fname, fftsize/2, 1, nbits, inverse, xtracbits); // Odd stage
|
|
|
fname = coredir + "/";
|
|
if (inverse) fname += "i";
|
|
fname += "fftstage_e";
|
|
sprintf(numstr, "%d", fftsize);
|
|
fname += numstr;
|
|
fname += ".v";
|
|
build_stage(fname.c_str(), fftsize/2, 0, nbits, inverse, xtracbits); // Even stage
|
|
|
|
fname = coredir + "/";
|
|
if (inverse) fname += "i";
|
|
fname += "fftstage_o";
|
|
sprintf(numstr, "%d", fftsize);
|
|
fname += numstr;
|
|
fname += ".v";
|
|
build_stage(fname.c_str(), fftsize/2, 1, nbits, inverse, xtracbits); // Odd stage
|
|
}
|
|
|
nbits += 1; // New number of input bits
|
nbits += 1; // New number of input bits
|
tmp_size >>= 1; lgtmp--;
|
tmp_size >>= 1; lgtmp--;
|
dropbit = 0;
|
dropbit = 0;
|
fprintf(vmain, "\n\n");
|
fprintf(vmain, "\n\n");
|
Line 1392... |
Line 1453... |
lgsize, lgtmp-2, lgdelay(nbits,xtracbits), (dropbit)?0:0,
|
lgsize, lgtmp-2, lgdelay(nbits,xtracbits), (dropbit)?0:0,
|
tmp_size);
|
tmp_size);
|
fprintf(vmain, "\t\t\t\t\t\tw_s%d, w_o%d, w_o%d, w_os%d);\n", tmp_size<<1, tmp_size<<1, tmp_size, tmp_size);
|
fprintf(vmain, "\t\t\t\t\t\tw_s%d, w_o%d, w_o%d, w_os%d);\n", tmp_size<<1, tmp_size<<1, tmp_size, tmp_size);
|
fprintf(vmain, "\n\n");
|
fprintf(vmain, "\n\n");
|
|
|
sprintf(fname, "%s/%sfftstage_e%d.v", coredir, (inverse)?"i":"", tmp_size);
|
{
|
build_stage(fname, tmp_size/2, 0, nbits, inverse, xtracbits); // Even stage
|
std::string fname;
|
sprintf(fname, "%s/%sfftstage_o%d.v", coredir, (inverse)?"i":"", tmp_size);
|
char numstr[12];
|
build_stage(fname, tmp_size/2, 1, nbits, inverse, xtracbits); // Odd stage
|
|
|
fname = coredir + "/";
|
|
if (inverse) fname += "i";
|
|
fname += "fftstage_e";
|
|
sprintf(numstr, "%d", tmp_size);
|
|
fname += numstr;
|
|
fname += ".v";
|
|
build_stage(fname.c_str(), tmp_size/2, 0, nbits, inverse, xtracbits); // Even stage
|
|
|
|
fname = coredir + "/";
|
|
if (inverse) fname += "i";
|
|
fname += "fftstage_o";
|
|
sprintf(numstr, "%d", tmp_size);
|
|
fname += numstr;
|
|
fname += ".v";
|
|
build_stage(fname.c_str(), tmp_size/2, 1, nbits, inverse, xtracbits); // Odd stage
|
|
}
|
|
|
|
|
dropbit ^= 1;
|
dropbit ^= 1;
|
nbits = obits;
|
nbits = obits;
|
tmp_size >>= 1; lgtmp--;
|
tmp_size >>= 1; lgtmp--;
|
Line 1481... |
Line 1558... |
fprintf(vmain, "\t\tend\n");
|
fprintf(vmain, "\t\tend\n");
|
fprintf(vmain, "\n\n");
|
fprintf(vmain, "\n\n");
|
fprintf(vmain, "endmodule\n");
|
fprintf(vmain, "endmodule\n");
|
fclose(vmain);
|
fclose(vmain);
|
|
|
sprintf(fname, "%s/butterfly.v", coredir);
|
{
|
build_butterfly(fname);
|
std::string fname;
|
|
|
|
fname = coredir + "/butterfly.v";
|
|
build_butterfly(fname.c_str(), xtracbits);
|
|
|
sprintf(fname, "%s/shiftaddmpy.v", coredir);
|
fname = coredir + "/shiftaddmpy.v";
|
build_multiply(fname);
|
build_multiply(fname.c_str());
|
|
|
sprintf(fname, "%s/qtrstage.v", coredir);
|
fname = coredir + "/qtrstage.v";
|
build_quarters(fname);
|
build_quarters(fname.c_str());
|
|
|
sprintf(fname, "%s/dblstage.v", coredir);
|
fname = coredir + "/dblstage.v";
|
build_dblstage(fname);
|
build_dblstage(fname.c_str());
|
|
|
if (bitreverse) {
|
if (bitreverse) {
|
sprintf(fname, "%s/dblreverse.v", coredir);
|
fname = coredir + "/dblreverse.v";
|
build_dblreverse(fname);
|
build_dblreverse(fname.c_str());
|
|
}
|
}
|
}
|
}
|
}
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|