Forum Discussion
Verilog real functions and compile time
I am trying to write a Verilog module and synthesize it using Quartus II 8.0, but I am running into some issues.
I have a function which returns a real value, and takes in real values for arguments, let's call this f_real( x ). The purpose of this function is to calculate a LUT at compile time. The inputs to the function are constants/static, and the output is assigned to a signed [15:0] register. Quartus II gives me an error stating that "real variable data types are not supported". I understand for synthesis, I cannot have a module which takes in real or outputs real values, but I am explicitly just calling a function which I hope to be evaluated. I know I can do this in VHDL, but I'd like to be able to perform the same operation in Verilog as the rest of the project is in Verilog. So, in conclusion, is it at all possible to use a function which takes in real values and returns real values to be evaluated at compile time using Verilog in Quartus II?21 Replies
- Altera_Forum
Honored Contributor
Sorry, but that's not clear to me. Does the module output a 16 bit vector or a real variable? Real variables cannot be uses for synthesis, thats true.
- Altera_Forum
Honored Contributor
Outputs to a vector.
Example code:
I am used to the strict typing of VHDL, so I don't know if the $rtoi is required or even necessary.module math_real_test ( output signed y ) ; function real f_real ; input real x ; begin f_real = 5.74857*(x + 0.7071) ; end endfunction assign y = $rtoi(4096.0*f_real(1.0)) ; endmodule - Altera_Forum
Honored Contributor
I am not very familiar with VHDL but I a pretty sure that this is not sythesizable, neither in VHDL nor in Verilog. For me it looks as if you write testbench code. But a testbench is not intended to by systhesized. It's only used in simulation. What do you really want to implement in the FPGA?
- Altera_Forum
Honored Contributor
I am trying to generate a compile-time specified LUT based on static inputs.
You are incorrect in that it is not synthesizable in VHDL. The code below will synthesize with no problems and yield warnings stating the output is stuck at VCC or GND - which is understandable since it obviously doesn't change.
Are there any other questions or suggestions you may have as to being able to do this in Verilog? Should I be looking at SystemVerilog instead of regular Verilog?library ieee ; use ieee.std_logic_1164.all ; use ieee.numeric_std.all ; use ieee.math_real.all ; entity math_real_test is port ( y : out signed(31 downto 0) ) ; end entity ; -- math_real_test architecture arch of math_real_test is function f_real( x : in real ) return real is begin return 5.74857*(x + 0.7071) ; end function ; begin y <= to_signed( integer(4096.0 * f_real( 1.0 )), y'length ) ; end architecture ; -- arch - Altera_Forum
Honored Contributor
Ok, now I understand what you want to do. Try this:
module math_real_test (y); output [31:0] y; function [31:0] f_real; input [31:0] x ; f_real = 5.74857 * (x + 0.7071) ; endfunction assign y = 4096 * f_real(1); endmodule - Altera_Forum
Honored Contributor
That works, but it removes my ability to pass in a real value which is required.
The function should be able to be passed real values and return real values, which are then scaled, rounded and/or truncated appropriately. Any other ideas? - Altera_Forum
Honored Contributor
Well, it seems as if this is a limitation of the Quartus synthesis. Sorry, no further ideas.
- Altera_Forum
Honored Contributor
Maybe you can use a simple text macro instead of a function?
module math_real_test (y); output [31:0] y; `define f_real 5.74857 * (0.7071 + `x) `define x 1.2 assign y = 4096 * `f_real; endmodule - Altera_Forum
Honored Contributor
Thanks for the help, unfortunately that doesn't seem to help me much.
In the end, I wanted to perform trig functions which I had written in Verilog. I basically re-created math_real from VHDL in Verilog, but the lack of real number capabilities in Quartus II puts a damper on using it for synthesis and keeps its use to simulation only. - Altera_Forum
Honored Contributor
Maybe you can help me to understand what the VHDL code does. To my understanding it assigns a 32 bit signed integer value to port y. The value to be assigned is the result of a operation of data type real that is converted to integer before assigning. The verilog code does the same, and it can be systhesized. So, where is the difference?