Forum Discussion
26 Replies
- Altera_Forum
Honored Contributor
Another way is to directly use the math libraries that your HDL supports. Usually this already comes with Quartus. For example, in VHDL you could simply add the math_real library, and call arctan(). Probably the Cordic method provides better/faster results, but I guess this is the simplest way if you just want to add an arctan function.
use ieee.math_real.all; ... variable x:real:=0.0; variable n:integer:=0; ... /* some manipulation on x */ ... n:=integer(arctan(x)); - Altera_Forum
Honored Contributor
i just checked, actually the VHDL math_real library already implements Cordic. If you're using VHDL, you can put your mind at rest with the arctan() method. I'm not too sure with other HDL languages though.
- Altera_Forum
Honored Contributor
The arctan() function in the library expects a real as input where Angela specified 18 bits, which I presume to be a std_logic_vector or a constrained integer type.
Second, if the compiler will synthesize the library function, we end up with combinatorial implementation which may be too slow. But the library function can do double duty: first serve as a guidance into Cordic and second to use in the testbench. - Altera_Forum
Honored Contributor
--- Quote Start --- The arctan() function in the library expects a real as input where Angela specified 18 bits... --- Quote End --- Yes, you have a point. Maybe we can do some conversion to real first? --- Quote Start --- Second, if the compiler will synthesize the library function, we end up with combinatorial implementation which may be too slow. But the library function can do double duty: first serve as a guidance into Cordic and second to use in the testbench. --- Quote End --- I think Quartus should be able to synthesise the library function, since I looked the arctan() function up in the math_real.vhd IEEE package inside the Quartus distribution. But not too sure on how fast this algorithm is going to be. Probably, we can study the CORDIC() function inside the same file to see if it will be fast enough? - Altera_Forum
Honored Contributor
The real type is only supported by Quartus (and other vendors synthesis tools) for simulation and compile time caculations, e.g. generation of look-up tables or constant initialization. It's not synthesizable. As ieee.math_real exclusively contains operation with the real type, it's not suited for synthesis as well.
- Altera_Forum
Honored Contributor
FvM was quicker than me to state that the type real is not synthesizable. (I needed to check first ...)
Any function described by a for loop will ultimately end up being combinatorial (and thus usually too slow), pipelining to speed it up is however plain manual labor. New VHDL constructs to make this easier would be very interesting -> System-VHDL? - Altera_Forum
Honored Contributor
Yes, that was why I recasted the result back to integer, a synthesizable type. I agree that real itself isn't synthesizable, but it's allowed for calculations. I assumed a real input to go into the arctan() function, but if it's a std_logic_vector, we need some kind of conversion to real first.
The arctan() function just serves as the calculation, where it will give a real result (which isn't synthesizable). But we can re-cast this result to integer (or others) that would make it synthesizable? - Altera_Forum
Honored Contributor
Unfortunately casting won't help. The actual operand presented to the synthesis would still be a real, which is not synthesizable.
Writing an integer equivalent for the arctan() function as given in the ieee_math_real is not that difficult. I'll might give it a shot later tonight (after finishing my other work duties). - Altera_Forum
Honored Contributor
cool... tell us about it. :)
I just tried the arctan() function, and Quartus compiles without errors. I believe Quartus should throw an error if something if not synthesizable right? Or at least a warning? I saw (in RTL Viewer) that some logic was generated from this (mostly muxes), but have not done P&R nor verified it working on a board yet. Here, I assigned a bunch of output ports directly to "integer". There's a catch when using this method though. Your input to arctan() should be a "constant real", means not something that can be varied during runtime. The code I submitted previously assumes that x is a constant and doesn't change during runtime (which is unlikely). Does anyone know of a workaround for this (Quartus can't synthesize non-constant reals)? - Altera_Forum
Honored Contributor
--- Quote Start --- Writing an integer equivalent for the arctan() function as given in the ieee_math_real is not that difficult. --- Quote End --- Thinking about this again, and the fact that Quartus only synthesizes real during "compile time" to generate LUTs and doesn't support varying reals during runtime, I think yes, writing an integer equivalent of arctan() would be the way to go. Do post it up when it's ready... :) Probably they might just include it in the next revision of VHDL. ;)