URL
https://opencores.org/ocsvn/dblclockfft/dblclockfft/trunk
Subversion Repositories dblclockfft
Compare Revisions
- This comparison shows the changes necessary to convert path
/dblclockfft/trunk
- from Rev 31 to Rev 32
- ↔ Reverse comparison
Rev 31 → Rev 32
/README.md
0,0 → 1,45
# A Double-Clocked FFT Core Generator |
|
The Double Clocked FFT project contains all of the software necessary to |
create the IP to generate an arbitrary sized FFT that will clock two samples |
in at each clock cycle, and after some pipeline delay it will clock two |
samples out at every clock cycle. |
|
The FFT generated by this approach is very configurable. By simple adjustment |
of a command line parameter, the FFT may be made to be a forward FFT or an |
inverse FFT. The number of bits processed, kept, and maintained by this |
FFT are also configurable. Even the number of bits used for the twiddle |
factors, or whether or not to bit reverse the outputs, are all configurable |
parts to this FFT core. |
|
These features make the Double Clocked FFT very different and unique among the |
other open HDL cores you may fine. |
|
For those who wish to get started right away, please download the package, |
change into the ``sw`` directory and run ``make``. There is no need to |
run a configure script, ``fftgen`` is completely portable C++. Then, once |
built, go ahead and run ``fftgen`` without any arguments. This will cause |
``fftgen`` to print a usage statement to the screen. Review the usage |
statement, and run ``fftgen`` a second time with the arguments you need. |
|
Alternatively, you _could_ read the specification. |
|
## Genesis |
This FFT comes from my attempts to design and implement a signal processing |
algorithm inside a generic FPGA, but only on a limited budget. As such, |
I don't yet have the FPGA board I wish to place this algorithm onto, neither |
do I have any expensive modeling or simulation capabilities. I'm using |
Verilator for my modeling and simulation needs. This makes |
using a vendor supplied IP core, such as an FFT, difficult if not impossible |
to use. |
|
My problem was made worse when I learned that the published maximum clock |
speed for a device wasn't necessarily the maximum clock speed that I could |
achieve. My design needed to process the incoming signal at 500 MHz to be |
commercially viable. 500 MHz is not necessarily a clock speed |
that can be easily achieved. 250 MHz, on the other hand, is much more within |
the realm of possibility. Achieving a 500 MHz performance with a 250 MHz |
clock, however, requires an FFT that accepts two samples per clock. |
|
This, then, was and is the genesis of this project. |
|
/bench/cpp/Makefile
48,7 → 48,9
OBJDR:= ../../sw/fft-core/obj_dir |
VSRCD = ../../sw/fft-core |
TBODR:= ../rtl/obj_dir |
VINC := -I/usr/share/verilator/include -I$(OBJDR)/ -I$(TBODR)/ |
VERILATOR_ROOT ?= $(shell bash -c 'verilator -V|grep VERILATOR_ROOT | head -1 | sed -e " s/^.*=\s*//"') |
VROOT := $(VERILATOR_ROOT) |
VINC := -I$(VROOT)/include -I$(OBJDR)/ -I$(TBODR)/ |
# MPYLB:= $(OBJDR)/Vshiftaddmpy__ALL.a |
MPYLB:= $(OBJDR)/Vlongbimpy__ALL.a |
DBLRV:= $(OBJDR)/Vdblreverse__ALL.a |
59,7 → 61,6
FFTLB:= $(OBJDR)/Vfftmain__ALL.a |
IFTLB:= $(TBODR)/Vifft_tb__ALL.a |
STGLB:= $(OBJDR)/Vfftstage_o2048__ALL.a |
VERILATOR_ROOT := /usr/share/verilator |
|
mpy_tb: mpy_tb.cpp fftsize.h twoc.h $(MPYLB) |
g++ -g $(VINC) $< twoc.cpp $(MPYLB) $(VERILATOR_ROOT)/include/verilated.cpp -o $@ |
/doc/src/gqtekspec.cls
29,6 → 29,8
\usepackage[dvips]{pstricks} |
\usepackage{hhline} |
\usepackage{colortbl} |
\definecolor{webgreen}{rgb}{0,0.5,0} |
\usepackage[dvips,colorlinks=true,linkcolor=webgreen]{hyperref} |
\newdateformat{headerdate}{\THEYEAR/\twodigit{\THEMONTH}/\twodigit{\THEDAY}} |
\setlength{\hoffset}{0.25in} |
\setlength{\voffset}{-0.5in} |
/doc/src/spec.tex
21,7 → 21,7
for more details. |
|
You should have received a copy of the GNU General Public License along |
with this program. If not, see \hbox{<http://www.gnu.org/licenses/>} for a copy. |
with this program. If not, see \texttt{http://www.gnu.org/licenses/} for a copy. |
\end{license} |
\begin{revisionhistory} |
0.2 & 6/2/2015 & Gisselquist & Superficial formatting changes\\\hline |
/sw/fftgen.cpp
28,7 → 28,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015, Gisselquist Technology, LLC |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
143,7 → 143,7
const char cpyleft[] = |
"////////////////////////////////////////////////////////////////////////////////\n" |
"//\n" |
"// Copyright (C) 2015, Gisselquist Technology, LLC\n" |
"// Copyright (C) 2015-2016, Gisselquist Technology, LLC\n" |
"//\n" |
"// This program is free software (firmware): you can redistribute it and/or\n" |
"// modify it under the terms of the GNU General Public License as published\n" |
2241,7 → 2241,7
"\t\ta real FFT) at one clock per two real input samples.\n" |
"\t-c <cbits>\tCauses all internal complex coefficients to be\n" |
"\t\tlonger than the corresponding data bits, to help avoid\n" |
"\t\tcoefficient truncation errors. The default is %d bits lnoger\n" |
"\t\tcoefficient truncation errors. The default is %d bits longer\n" |
"\t\tthan the data bits.\n" |
"\t-d <dir>\tPlaces all of the generated verilog files into <dir>.\n" |
"\t\tThe default is a subdirectory of the current directory named %s.\n" |
2661,28 → 2661,26
fprintf(vmain, "//\t\t\tforce the reset of all of the internals to this routine.\n"); |
fprintf(vmain, "//\t\t\tFurther, following a reset, the o_sync line will go\n"); |
fprintf(vmain, "//\t\t\thigh the same time the first output sample is valid.\n"); |
fprintf(vmain, "// i_ce\tA clock enable line. If this line is set, this module\n"); |
fprintf(vmain, "//\ti_ce\tA clock enable line. If this line is set, this module\n"); |
fprintf(vmain, "//\t\t\twill accept two complex values as inputs, and produce\n"); |
fprintf(vmain, "//\t\t\ttwo (possibly empty) complex values as outputs.\n"); |
fprintf(vmain, "//\t\ti_left\tThe first of two complex input samples. This value\n"); |
fprintf(vmain, "//\t\t\tis split into two two\'s complement numbers, of \n"); |
fprintf(vmain, "//\t\t\t%d bits each, with the real portion in the high\n", nbitsin); |
fprintf(vmain, "//\t\t\torder bits, and the imaginary portion taking the\n"); |
fprintf(vmain, "//\t\t\tbottom %d bits.\n", nbitsin); |
fprintf(vmain, "//\t\ti_right\tThis is the same thing as i_left, only this is the\n"); |
fprintf(vmain, "//\t\t\tsecond of two such samples. Hence, i_left would\n"); |
fprintf(vmain, "//\t\t\tcontain input sample zero, i_right would contain\n"); |
fprintf(vmain, "//\t\t\tsample one. On the next clock i_left would contain\n"); |
fprintf(vmain, "//\t\t\tinput sample two, i_right number three and so forth.\n"); |
fprintf(vmain, "//\t\to_left\tThe first of two output samples, of the same\n"); |
fprintf(vmain, "//\t\t\tformat as i_left, only having %d bits for each of\n", nbitsout); |
fprintf(vmain, "//\t\t\tthe real and imaginary components, leading to %d\n", nbitsout*2); |
fprintf(vmain, "//\t\t\tbits total.\n"); |
fprintf(vmain, "//\t\to_right\tThe second of two output samples produced each clock.\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\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, "//\ti_left\tThe first of two complex input samples. This value is split\n"); |
fprintf(vmain, "//\t\t\tinto two two\'s complement numbers, %d bits each, with\n", nbitsin); |
fprintf(vmain, "//\t\t\tthe real portion in the high order bits, and the\n"); |
fprintf(vmain, "//\t\t\timaginary portion taking the bottom %d bits.\n", nbitsin); |
fprintf(vmain, "//\ti_right\tThis is the same thing as i_left, only this is the second of\n"); |
fprintf(vmain, "//\t\t\ttwo such samples. Hence, i_left would contain input\n"); |
fprintf(vmain, "//\t\t\tsample zero, i_right would contain sample one. On the\n"); |
fprintf(vmain, "//\t\t\tnext clock i_left would contain input sample two,\n"); |
fprintf(vmain, "//\t\t\ti_right number three and so forth.\n"); |
fprintf(vmain, "//\to_left\tThe first of two output samples, of the same format as i_left,\n"); |
fprintf(vmain, "//\t\t\tonly having %d bits for each of the real and imaginary\n", nbitsout); |
fprintf(vmain, "//\t\t\tcomponents, leading to %d bits total.\n", nbitsout*2); |
fprintf(vmain, "//\to_right\tThe second of two output samples produced each clock. This has\n"); |
fprintf(vmain, "//\t\t\tthe same format as o_left.\n"); |
fprintf(vmain, "//\to_sync\tA one bit output indicating the first valid sample produced by\n"); |
fprintf(vmain, "//\t\t\tthis FFT following a reset. Ever after, this will\n"); |
fprintf(vmain, "//\t\t\tindicate the first sample of an FFT frame.\n"); |
fprintf(vmain, "//\n"); |
fprintf(vmain, "// Arguments:\tThis file was computer generated using the\n"); |
fprintf(vmain, "//\t\tfollowing command line:\n"); |