Teddy Minz Posted May 13, 2019 Report Share Posted May 13, 2019 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 Quote Link to comment Share on other sites More sharing options...
David Black Posted May 13, 2019 Report Share Posted May 13, 2019 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). Teddy Minz 1 Quote Link to comment Share on other sites More sharing options...
Teddy Minz Posted May 14, 2019 Author Report Share Posted May 14, 2019 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. Quote Link to comment Share on other sites More sharing options...
Roman Popov Posted May 14, 2019 Report Share Posted May 14, 2019 Xilinx HLS tools have very limited SystemC support, you should probably code your FFT in pure C++. Teddy Minz 1 Quote Link to comment Share on other sites More sharing options...
David Black Posted May 14, 2019 Report Share Posted May 14, 2019 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. Quote Link to comment Share on other sites More sharing options...
Teddy Minz Posted May 15, 2019 Author Report Share Posted May 15, 2019 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++ ? Quote Link to comment Share on other sites More sharing options...
Roman Popov Posted May 15, 2019 Report Share Posted May 15, 2019 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. Teddy Minz 1 Quote Link to comment Share on other sites More sharing options...
Teddy Minz Posted May 21, 2019 Author Report Share Posted May 21, 2019 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 ^^ module.cpp #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) {} module.h #include "systemc.h" #include <iostream> SC_MODULE(MULT) { public: // Constructeur MULT(int var_a, int var_b); MULT(); //SC_CTOR(MULT); void multiplication(void); void afficherResult() const; private: int A, B, result; }; main.cpp #include "module.h" int sc_main(int argc, char* argv[]) { MULT mult1; mult1.multiplication(); // Print result mult1.afficherResult(); 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 Quote Link to comment Share on other sites More sharing options...
Roman Popov Posted May 21, 2019 Report Share Posted May 21, 2019 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: Quote 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); MULT(sc_module_name); This is a hack that allows SystemC kernel to track lifetime of constructor. Teddy Minz 1 Quote Link to comment Share on other sites More sharing options...
Teddy Minz Posted May 21, 2019 Author Report Share Posted May 21, 2019 Thanks a lot @Roman Popov ! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.