Search code examples
floating-pointvhdlintel-fpga

How to use sin, arcsin functions in vhdl Quatus 2 16.1 Lite?


I am using Quatus 2 Prime 16.1 Lite version.
what i am trying to do as follows, I have compiled float_pkg_c,fixed_pkg_c under ieee_proposed library as in shown in below link in comment. and i am using to_float to convert real variable to std logic vector as follows,

phi_c <= to_std_logic_vector( to_float(phi_c_F, float32'high, -float32'low) );

below phi_c_F is a variable which is to be calculated using sin, arcsin of math_real library.and i found operators in math_real non-synthesize, and i want there xx.dddddddd at least 10 decimal points. then, phi_c is send via Avalon memory mapping (32bits std logic vector) to HPS system.

in below code pre_digital,rp are integers and are signals which calculates in another process.

library ieee;
library ieee_proposed;
USE ieee.std_logic_1164.all;
use ieee.math_real.all;
use ieee.STD_LOGIC_ARITH.ALL;
use ieee.STD_LOGIC_UNSIGNED.ALL;
use ieee_proposed.float_pkg.ALL;
use ieee_proposed.fixed_pkg.ALL;
use ieee_proposed.fixed_float_types.ALL;

inside architecture,

PROCESS(clk_50,start_cal)
variable Pr_F,rp_rad_s_F,F_c_F,ph_c_F,t_p_F,l_c_F,r_c_F,Ar_F,pre_R ,r_s: float (4 downto -27); 
BEGIN
--r_s := 8.98;
--r_c_F := 3.44;
--l_c_F := 5.67;
IF rising_edge(clk_50)  AND start_cal ='1'  THEN

pre_R           := to_float(pre_digital,4 ,27) ;       
Pr_F            := 3.3 * (pre_R / 65535.0);    
rpm_rad_s_F     := to_float(rp,4 ,27) * (2.0 * MATH_PI / 60.0);
Ar_F            := MATH_PI*r_s*r_s;
F_c_F           := Pr_F * Ar_F;             
ph_c_F          := arcsin((r_c_F / l_c_F) * sin(rp_rad_s_F *  to_float(t,4 ,27)));

ph_c_F_vctr  <= to_std_logic_vector(ph_c_F);
END IF;
END PROCESS;    

when compiling soc.system i get error,

Error (10511): VHDL Qualified Expression error at test_pipe.vhd(136): ARCSIN type specified in Qualified Expression must match UNRESOLVED_float type that is implied for expression by context


Solution

  • Judging by your code and requirements, it seems you are not aware of the capabilities of an FPGA. An FPGA consist of a collection of programmable logic lookup tables, combined with some hardwired multipliers. Except for the newest generation Altera (Stratix 10 e.g.), these multipliers are fixed-point only and would require extra logic in the LUTs to realize floating-point kind of operations. Also, the multipliers only offer limited precision: ~18 bit.

    You seem to want full floating point precision (64 bit) and perform very complex operations, as division and trigonometric functions (sin/arcsin). A lot of logic is required to realize these functions. Trigonometric functions are not even implemented in the float_pkg library. You will probably have to use a CORDIC-like component to realize such a function.

    But just think about what you seem to want to achieve in your code:

    • 2 * floating-point division
    • 8 * floating-point multiplication
    • 1 * sin()
    • 1 * arcsin()

    All within one clock cycle! clk_50 seems to indicate 50 MHz... That's not going to work. You need to pipeline it properly.

    What you want to realize on your FPGA is advanced stuff. You really need to know what you are doing. Please start simple, by flashing a LED or something.

    Likely you should just run this code on a general purpose processor and not use an FPGA...