Jump to content

Synthetizable FFT function in SystemC

Teddy Minz

Recommended Posts

Hi everyone,

As part of my job I try to implement a FFT function in my ZedBoard. I found some example including one in the SystemC folder unfortunately not synthesizable. Furthermore, I use a free version of Vivado HLS  and this tool is very restrictive (few things are synthesizable). So, I will going to have to code my own version of this function (8k/16k/32k FFT). For doing this, I started by cut the FFT's mathematical formula and try to code a exponential function. I realized I can't use the "math.h" library and then I have to code all with only logic gates. At this level, I prefer to code directly in VHDL. Does anyone have a experience with this synthesis tool and can give me a simpler way to achieve my goal ? Maybe I see the problem of the wrong angle.

Best regards

Link to comment
Share on other sites

You paint a very bleak and incorrect picture of the HLS tool. I will suggest that you need to get some training on its use. Xilinx have many examples and their documentation is quite good. Document UG902 clearly documents the HLS math library which supports all manner of synthesizable operations. For instance:

  • Trigonometric Functions: acos, atan, cospi, acospi, atan2, sin, asin, atan2pi, sincos, asinpi, cos, sinpi, tan, tanpi

  • Hyperbolic Functions: acosh, asinh, cosh, atanh, sinh, tanh

  • Exponential Functions: exp, exp10, exp2, expm1, frexp, idexp, modf

  • Logarithmic Functions: ilogb, log, log10, log1p

  • Power Functions: cbrt, hypot, pow, rsqrt, sqrt

  • Error Functions: erf, erfc

  • Gamma Functions: lgamma, lgamma_r, tgamma

  • Rounding Functions: ceil, floor, llrint, llround, lrint, lround, nearbyint, rint, round, trunc

and that's only a few. 

Perhaps your grasp of C++ and what can or cannot be synthesized is limited. For instance, dynamically allocated memory is forbidden because it is not reasonable to expect silicon to grow new logic during operation.

Please read the fine manual (RTFM).


Link to comment
Share on other sites

Thanks for your answer. Sorry for my question maybe evident.

Effectively, I begin with SystemC and I am not yet very comfortable with the HLS tools.

Nevertheless, is my approach good? I want to say, Is cut the FFT's mathematical formula will allow me to implement it ? Is the simpler way to do this ? The goal is to code a FFT with SystemC and not to use the logicore provided by Xilinx. I've see a fft's library but it need Xilinx's Logicore.

Link to comment
Share on other sites

I agree with @Roman Popov on the choice of inputs to the HLS tool. The sweet spot for Vivado_HLS is C++. Much simpler to code for most folks.

That said, it can be done.

Why wouldn't you want to use Xilinx' Logicore though? One of the best ways of raising the level of abstraction (which is what using C++ or SystemC do) is to reuse somebody else's effort. Tested and probably fairly optimized. Otherwise, you are effectively reinventing the wheel.


Link to comment
Share on other sites

I didn't use Xilinx's LogiCore because I want to compare the execution time of a VHDL design generated from SystemC-encoded FFT block with the execution time of a FFT block on CPU and precisely with a design who use Xilinx's IP. The objective isn't to have high accuracy but just an order of magnitude between this 3 methods. At the base I didn't want to reinvent the wheel. I thought I could get a SystemC-encoded FFT block and compared it fairly quickly.

Excuse me, my questions are maybe silly but I really want to understand.
If I code a FFT in pure C++ shall I have problems for testing ? When I code in SystemC I can declare input/output with "sc_in" and "sc_out" and I find them when I import my IP within Vivado. How I can do that in pure C++ ? 

Link to comment
Share on other sites

If you code your FFT as a pure C++ function, Vivado HLS will generate inputs and outputs automatically from function parameters and based on INTERFACE pragmas. And you can import generated RTL into Vivado IP integrator.  Check out Xilinx documentation, and ask on Xilinx forums. 

Please also note that you can implement FFT in a various ways (with different micro-architectures), and achieve various performance vs area numbers. And HLS also requires quite a lot of learning to achieve good results.


Link to comment
Share on other sites

Hi everyone,

Thanks to you, I was able to advance. I have follow your advice and I succeeded to synthesize a FFT function in pure C++ with Vivado HLS.

Now, I would like to insert this function in a structure SystemC. For do this I have create a little project "multiplication" . But I think I have difficulties to understand the "SC_CTOR"... I have try to create standard constructor like in C++ but SystemC don't like my constructor ^^


#include "module.h"

using namespace std;

void MULT::multiplication(void)
	result = A * B;

void MULT::afficherResult() const
    cout << A << " * " << B  << " = " << result << endl;

MULT::MULT() : A(4), B(5), result(0)

MULT::MULT(int var_a, int var_b) : A(var_a), B(var_b), result(0)


#include "systemc.h"
#include <iostream>


	// Constructeur
	MULT(int var_a, int var_b);

    void multiplication(void);
    void afficherResult() const;


	int A, B, result;


#include "module.h"

int sc_main(int argc, char* argv[])
	MULT mult1;


	// Print result

	return 0;

With this code I have the following error :
Error: (E533) module name stack is empty: did you forget to add a sc_module_name parameter to your module constructor?

Why this code work if I declare a classic  C++ class but it doesn't with a SC_MODULE? With SystemC we cannot create constructor like that ?

Best regards

Link to comment
Share on other sites

55 minutes ago, Teddy Minz said:

Why this code work if I declare a classic  C++ class but it doesn't with a SC_MODULE? In SystemC we cannot create constructor like that ?

From SystemC standard:


5.2.3 Constraints on usage

Every class derived (directly or indirectly) from class sc_module shall have at least one constructor. Every
such constructor shall have one and only one parameter of class sc_module_name but may have further
parameters of classes other than sc_module_name. That parameter is not required to be the first parameter
of the constructor.

SystemC requires that you add sc_module_name as a parameter to module constructors, like this:

MULT(sc_module_name, int var_a, int var_b);

This is a hack that allows SystemC kernel to track lifetime of constructor.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...