+ Post New Thread
Results 1 to 7 of 7
  1. #1
    Full Member level 2
    Points: 1,057, Level: 7
    FlyingDutch's Avatar
    Join Date
    Dec 2017
    Location
    Bydgoszcz - Poland
    Posts
    131
    Helped
    20 / 20
    Points
    1,057
    Level
    7

    Sine function generator (VHDL)

    Hello,

    I need for resolving Forward/Inverse kinematics problem (in context for robotic arm) to calculate trigonometric functions values. I am going to use in every arm joint quadrature encoders (optical) width 10-bit resolution. Because this arm will have seven joints (seven degree of fridom) I decided to make a controller for arm based on FPGA circuit (I known that this task is also workable on microcontroller), mostly for educational purpose (learning myself settlement of problems using FPGA).
    So first of all, these are assumptions:
    1) The angle is given width 10-bit resolution for full period of sine function (2PI or 360 degrees are divided for 1024 ranges)
    2) Returned values of sine function are in "IEEE-754 Single Precision" format (32-bit float number)
    3) Sine function values are stored in ROM memory (FPGA BRAM bank) for a one quarter of full period.

    First of all to accomplish this task, I wrote a simple program (Borland C++ Builder 6) for generation sine function table in "IEEE-754 Single Precision" format. This application is generating output that we can past direct to coe file (ROM memory content). See screenshot:

    Click image for larger version. 

Name:	SineTableGeneratorC.png 
Views:	11 
Size:	29.2 KB 
ID:	154932

    Here is content of coe file (BRAM ROM memory) generated by this application for 10-bit resolution of full period - 256 values for a quarter of sine function. The values are 32-bit floating point numbers written in binary:

    Code:
    memory_initialization_radix=2;
    memory_initialization_vector=
    00000000000000000000000000000000,
    00111011110010010000111110001000,
    00111100010010010000111010010000,
    00111100100101101100100110110110,
    00111100110010010000101010110000,
    00111100111110110100100110111010,
    00111101000101101100001100101100,
    00111101001011111110000000000111,
    00111101010010001111101100110000,
    00111101011000100001010001101001,
    00111101011110110010101101110100,
    00111101100010100010000000001010,
    00111101100101101010100100000101,
    00111101101000110011000010001100,
    00111101101011111011011010000001,
    00111101101111000011101011000100,
    00111101110010001011110100110110,
    00111101110101010011110110111010,
    00111101111000011011110000101111,
    00111101111011100011100001110111,
    00111101111110101011001001110011,
    00111110000000111001010100000010,
    00111110000010011100111110000111,
    00111110000100000000100010110111,
    00111110000101100100000010000100,
    00111110000111000111011011011110,
    00111110001000101010101110110110,
    00111110001010001101111011111100,
    00111110001011110001000010100010,
    00111110001101010100000010011000,
    00111110001110110110111011001111,
    00111110010000011001101100111000,
    00111110010001111100010111000010,
    00111110010011011110111001100000,
    00111110010101000001010100000010,
    00111110010110100011100110011000,
    00111110011000000101110000010100,
    00111110011001100111110001100110,
    00111110011011001001101010000000,
    00111110011100101011011001010001,
    00111110011110001100111111001100,
    00111110011111101110011011100001,
    00111110100000100111110111000001,
    00111110100001011000011011001111,
    00111110100010001000111010010011,
    00111110100010111001010100000111,
    00111110100011101001101000100010,
    00111110100100011001110111011110,
    00111110100101001010000000110010,
    00111110100101111010000100010111,
    00111110100110101010000010000110,
    00111110100111011001111001111000,
    00111110101000001001101011100101,
    00111110101000111001010111000101,
    00111110101001101000111100010010,
    00111110101010011000011011000100,
    00111110101011000111110011010100,
    00111110101011110111000100111010,
    00111110101100100110001111101111,
    00111110101101010101010011101100,
    00111110101110000100010000101010,
    00111110101110110011000110100001,
    00111110101111100001110101001010,
    00111110110000010000011100011110,
    00111110110000111110111100010110,
    00111110110001101101010100101010,
    00111110110010011011100101010011,
    00111110110011001001101110001011,
    00111110110011110111101111001010,
    00111110110100100101101000001010,
    00111110110101010011011001000010,
    00111110110110000001000001101100,
    00111110110110101110100010000001,
    00111110110111011011111001111001,
    00111110111000001001001001001111,
    00111110111000110110001111111011,
    00111110111001100011001101110101,
    00111110111010010000000010111000,
    00111110111010111100101110111011,
    00111110111011101001010001111001,
    00111110111100010101101011101010,
    00111110111101000001111100001000,
    00111110111101101110000011001011,
    00111110111110011010000000101101,
    00111110111111000101110100100111,
    00111110111111110001011110110011,
    00111111000000001110011111100100,
    00111111000000100100001010110001,
    00111111000000111001110000111101,
    00111111000001001111010010000100,
    00111111000001100100101110000011,
    00111111000001111010000100110110,
    00111111000010001111010110011011,
    00111111000010100100100010101110,
    00111111000010111001101001101011,
    00111111000011001110101011010001,
    00111111000011100011100111011010,
    00111111000011111000011110000101,
    00111111000100001101001111001101,
    00111111000100100001111010110000,
    00111111000100110110100000101011,
    00111111000101001011000000111001,
    00111111000101011111011011011001,
    00111111000101110011110000000111,
    00111111000110000111111111000000,
    00111111000110011100001000000001,
    00111111000110110000001011000110,
    00111111000111000100001000001100,
    00111111000111010111111111010010,
    00111111000111101011110000010010,
    00111111000111111111011011001011,
    00111111001000010010111111111001,
    00111111001000100110011110011001,
    00111111001000111001110110101001,
    00111111001001001101001000100101,
    00111111001001100000010100001010,
    00111111001001110011011001010110,
    00111111001010000110011000000101,
    00111111001010011001010000010101,
    00111111001010101100000010000010,
    00111111001010111110101101001010,
    00111111001011010001010001101010,
    00111111001011100011101111011110,
    00111111001011110110000110100101,
    00111111001100001000010110111011,
    00111111001100011010100000011101,
    00111111001100101100100011001001,
    00111111001100111110011110111100,
    00111111001101010000010011110011,
    00111111001101100010000001101100,
    00111111001101110011101000100011,
    00111111001110000101001000010110,
    00111111001110010110100001000010,
    00111111001110100111110010100101,
    00111111001110111000111100111011,
    00111111001111001010000000000011,
    00111111001111011010111011111001,
    00111111001111101011110000011100,
    00111111001111111100011101100111,
    00111111010000001101000011011010,
    00111111010000011101100001110001,
    00111111010000101101111000101001,
    00111111010000111110001000000001,
    00111111010001001110001111110101,
    00111111010001011110010000000100,
    00111111010001101110001000101010,
    00111111010001111101111001100101,
    00111111010010001101100010110100,
    00111111010010011101000100010011,
    00111111010010101100011101111111,
    00111111010010111011101111111000,
    00111111010011001010111001111010,
    00111111010011011001111100000011,
    00111111010011101000110110010000,
    00111111010011110111101000100000,
    00111111010100000110010010110000,
    00111111010100010100110100111101,
    00111111010100100011001111000111,
    00111111010100110001100001001001,
    00111111010100111111101011000011,
    00111111010101001101101100110010,
    00111111010101011011100110010011,
    00111111010101101001010111100101,
    00111111010101110111000000100110,
    00111111010110000100100001010011,
    00111111010110010001111001101010,
    00111111010110011111001001101010,
    00111111010110101100010001010000,
    00111111010110111001010000011010,
    00111111010111000110000111000111,
    00111111010111010010110101010011,
    00111111010111011111011010111110,
    00111111010111101011111000000110,
    00111111010111111000001100100111,
    00111111011000000100011000100001,
    00111111011000010000011011110010,
    00111111011000011100010110011000,
    00111111011000101000001000010000,
    00111111011000110011110001011010,
    00111111011000111111010001110011,
    00111111011001001010101001011001,
    00111111011001010101111000001100,
    00111111011001100000111110001000,
    00111111011001101011111011001101,
    00111111011001110110101111011000,
    00111111011010000001011010101000,
    00111111011010001011111100111100,
    00111111011010010110010110010001,
    00111111011010100000100110100111,
    00111111011010101010101101111011,
    00111111011010110100101100001100,
    00111111011010111110100001011000,
    00111111011011001000001101011111,
    00111111011011010001110000011110,
    00111111011011011011001010010011,
    00111111011011100100011010111111,
    00111111011011101101100010011110,
    00111111011011110110100000110000,
    00111111011011111111010101110011,
    00111111011100001000000001100111,
    00111111011100010000100100001000,
    00111111011100011000111101010111,
    00111111011100100001001101010011,
    00111111011100101001010011111000,
    00111111011100110001010001001000,
    00111111011100111001000100111111,
    00111111011101000000101111011110,
    00111111011101001000010000100010,
    00111111011101001111101000001011,
    00111111011101010110110110010111,
    00111111011101011101111011000110,
    00111111011101100100110110010111,
    00111111011101101011101000000111,
    00111111011101110010010000010111,
    00111111011101111000101111000101,
    00111111011101111111000100010001,
    00111111011110000101001111111000,
    00111111011110001011010001111011,
    00111111011110010001001010011000,
    00111111011110010110111001001110,
    00111111011110011100011110011110,
    00111111011110100001111010000100,
    00111111011110100111001100000010,
    00111111011110101100010100010110,
    00111111011110110001010010111111,
    00111111011110110110000111111100,
    00111111011110111010110011001101,
    00111111011110111111010100110001,
    00111111011111000011101100101000,
    00111111011111000111111010110000,
    00111111011111001011111111001001,
    00111111011111001111111001110011,
    00111111011111010011101010101100,
    00111111011111010111010001110101,
    00111111011111011010101111001100,
    00111111011111011110000010110001,
    00111111011111100001001100100100,
    00111111011111100100001100100011,
    00111111011111100111000010110000,
    00111111011111101001101111001001,
    00111111011111101100010001101101,
    00111111011111101110101010011101,
    00111111011111110000111001011000,
    00111111011111110010111110011110,
    00111111011111110100111001101101,
    00111111011111110110101011000111,
    00111111011111111000010010101011,
    00111111011111111001110000011001,
    00111111011111111011000100001111,
    00111111011111111100001110001111,
    00111111011111111101001110011000,
    00111111011111111110000100101001,
    00111111011111111110110001000011,
    00111111011111111111010011100110,
    00111111011111111111101100010001,
    00111111011111111111111011000100
    To getting to a point we want to calculate sine function width resolution 10-bit (values from 0 to 1023). So the angle is given width formula:

    angle = n * 0,00613592332229018 (Radians)

    where: 0,00613592332229018 (in radians is angle gain)

    and n is sample number (from 0 to 1023) - which is corresponding full angle (2*PI radians of 360 degrees) See the picture:

    Click image for larger version. 

Name:	SinusF.png 
Views:	7 
Size:	64.2 KB 
ID:	154934

    As we can see when one have sine table for one quarter he can calculate it's values for full period (2*PI in radians or 360 degrees). On the picture is distinquished how have to change 8-bit address (values 0 to 255) of ROM memory (in which is stored sine table for one quarter). One also can see thatr the second half (above PI or 180 degrees) sine function values are identical as in first half, but width negative sign.
    Last edited by FlyingDutch; 11th August 2019 at 16:00.

    •   AltAdvertisement

        
       

  2. #2
    Super Moderator
    Points: 260,308, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    45,460
    Helped
    13829 / 13829
    Points
    260,308
    Level
    100

    Re: Sine function generator (VHDL)

    What's your question?

    It's not clear, which calculations you want to perform in FPGA, but using floating point numbers is generally no good idea. Better use fixed point numbers (signed or unsigned integer values with implied power of two scaling factor).



    •   AltAdvertisement

        
       

  3. #3
    Full Member level 2
    Points: 1,057, Level: 7
    FlyingDutch's Avatar
    Join Date
    Dec 2017
    Location
    Bydgoszcz - Poland
    Posts
    131
    Helped
    20 / 20
    Points
    1,057
    Level
    7

    Re: Sine function generator (VHDL)

    Hello,

    here is next part of this post:

    To make sine function generator in VHDL we need two components:
    1. ROM memory width sinus table for one quarter
    2. Compnent which is changing angle 10 bit (values 0 to 1023) to corresponding values of 8 bit adresses of ROM memory


    Here are project sources files in VHDL (for FPGA Artix-7) - Xilinx Vivado2018.2.

    The main entity (top module) is "SineFunction":
    Code:
    entity SineFunction is
        Port ( clk : in STD_LOGIC;
               reset : in STD_LOGIC;
               strobe : in STD_LOGIC;
               angle : in STD_LOGIC_VECTOR (9 downto 0);
               SineValue : out STD_LOGIC_VECTOR (31 downto 0); --Sine function value in IEEE-754 Single Precision (Float32)
               Sign : out STD_LOGIC); -- Sign: 0 positive, 1 negative
    end SineFunction;
    As one can see we have clock, reset pin, strobe signal (High state on strobe returns sine value for given angle):

    angle - 10 bit values from 0 to 1023

    SineValue - value of sine function as 32 bit float number

    Sign - sign of sine function: 0- positive, 1 -negative

    and here is full code of "SineFunction.vhd":
    Code:
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    
    -- Uncomment the following library declaration if using
    -- arithmetic functions with Signed or Unsigned values
    --use IEEE.NUMERIC_STD.ALL;
    
    -- Uncomment the following library declaration if instantiating
    -- any Xilinx leaf cells in this code.
    --library UNISIM;
    --use UNISIM.VComponents.all;
    
    entity SineFunction is
        Port ( clk : in STD_LOGIC;
               reset : in STD_LOGIC;
               strobe : in STD_LOGIC;
               angle : in STD_LOGIC_VECTOR (9 downto 0);
               SineValue : out STD_LOGIC_VECTOR (31 downto 0); --Sine function value in IEEE-754 Single Precision (Float32)
               Sign : out STD_LOGIC); -- Sign: 0 positive, 1 negative
    end SineFunction;
    
    architecture Behavioral of SineFunction is
       
       component SinProject is
           Port ( clk : in  STD_LOGIC;
                  reset : in  STD_LOGIC;
                  strobe : in  STD_LOGIC;
                  Kat : in  STD_LOGIC_VECTOR (9 downto 0);
                  AddressSinus : out  STD_LOGIC_VECTOR(7 DOWNTO 0);
                  ZnakSinus : out integer range -1 to 1 
                );
       end component;
       
       component SineTable_ROM is
         Port ( 
           clka : in STD_LOGIC;
           ena : in STD_LOGIC;
           addra : in STD_LOGIC_VECTOR ( 7 downto 0 );
           douta : out STD_LOGIC_VECTOR ( 31 downto 0 )
         );
       end component;
       
       signal  OutAddressSinus : STD_LOGIC_VECTOR(7 DOWNTO 0);
       signal  OutZnakSinus :  integer range -1 to 1;
       signal  SinOut32Float : STD_LOGIC_VECTOR ( 31 downto 0 );
    
    begin
    
      C1: SinProject port map (clk, reset, strobe, angle, OutAddressSinus, OutZnakSinus);
      C2: SineTable_ROM port map (clk, strobe, OutAddressSinus, SinOut32Float);
      
      SEQ1: process (clk, OutZnakSinus, SinOut32Float)
       begin 
         if (rising_edge(clk)) then    
           if (OutZnakSinus > 0) then
             SineValue <= SinOut32Float;
             Sign <= '0';
           else
             SineValue <= (b"1" & SinOut32Float(30 DOWNTO 0));
             Sign <= '1';
           end if; 
         end if;      
       end process;
    
    end Behavioral;
    Component "SinProject" changes 10-bit angle (360 degrees) into 8 bit address (0 to 255) for reading values from ROM. Here is full code of "SinProject.vhd":
    Code:
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use ieee.std_logic_unsigned.all;
    use IEEE.NUMERIC_STD.ALL;
    
    -- Uncomment the following library declaration if using
    -- arithmetic functions with Signed or Unsigned values
    --use IEEE.NUMERIC_STD.ALL;
    
    -- Uncomment the following library declaration if instantiating
    -- any Xilinx primitives in this code.
    --library UNISIM;
    --use UNISIM.VComponents.all;
    
    entity SinProject is
        Port ( clk : in  STD_LOGIC;
    	       reset : in  STD_LOGIC;
    	       strobe : in  STD_LOGIC;
               Kat : in  STD_LOGIC_VECTOR (9 downto 0);
               AddressSinus : out  STD_LOGIC_VECTOR(7 DOWNTO 0);
               ZnakSinus : out integer range -1 to 1 
             );
    end SinProject;
    
    architecture Behavioral of SinProject is
        
      signal KatUnsigned : unsigned(9 downto 0); -- definicja syg lokalnego
      signal AddressUnBig : unsigned(9 downto 0); -- definicja syg lokalnego	
      signal AddressUnsigned : unsigned(7 downto 0); -- definicja syg lokalnego
    
    begin
      
      SEQ: process (reset, clk, strobe, Kat)
      begin
        if rising_edge(clk) then
           if (reset = '0') then
    	     AddressSinus <= b"00000000";	
           elsif (strobe = '1') then   
             KatUnsigned <= unsigned(Kat);
    		 if (KatUnsigned < 256) then
    		    AddressUnsigned <= KatUnsigned(7 DOWNTO 0);
    			AddressSinus <= std_logic_vector(AddressUnsigned);
    			ZnakSinus <= 1;
    		 elsif ((KatUnsigned >= 256) and (KatUnsigned < 511)) then
    		    AddressUnBig <= (254-(KatUnsigned-256));
    		    AddressUnsigned <= AddressUnBig(7 DOWNTO 0);
    			AddressSinus <= std_logic_vector(AddressUnsigned);
    			ZnakSinus <= 1;
    		 elsif ((KatUnsigned >= 511) and (KatUnsigned <= 766)) then
    		    AddressUnBig <= (KatUnsigned-511);
    		    AddressUnsigned <= AddressUnBig(7 DOWNTO 0);
    			AddressSinus <= std_logic_vector(AddressUnsigned);
    			ZnakSinus <= -1;	
    		 elsif ((KatUnsigned >= 767) and (KatUnsigned < 1023)) then
    		    AddressUnBig <= (255-(KatUnsigned-767));
    		    AddressUnsigned <= AddressUnBig(7 DOWNTO 0);
    			AddressSinus <= std_logic_vector(AddressUnsigned);
    			ZnakSinus <= -1;		
    		else	
    			AddressSinus <= b"00000000";
    		end if;	 
        end if;
       end if;  -- if rising_edge(clk) then
      end process;  
    
    end Behavioral;
    The last component is "SineTable_ROM":
    Code:
    component SineTable_ROM is
         Port ( 
           clka : in STD_LOGIC;
           ena : in STD_LOGIC;
           addra : in STD_LOGIC_VECTOR ( 7 downto 0 );
           douta : out STD_LOGIC_VECTOR ( 31 downto 0 )
      );
    It had been generated using free Xiluinx IPCore(Memory generator) as ROM memory (in FPGA BRAM block).

    In file "SinProjecttestBench.vhd" is full behavioral simulation of full project:
    Code:
    --------------------------------------------------------------------------------
    -- Company: 
    -- Engineer:
    --
    -- Create Date:   11:08:25 08/04/2019
    -- Design Name:   
    -- Module Name:   C:/Users/mgabr/Spartan6/SinusCosinusFunction01/SinprojecttestBench.vhd
    -- Project Name:  SinusCosinusFunction01
    -- Target Device:  
    -- Tool versions:  
    -- Description:   
    -- 
    -- VHDL Test Bench Created by ISE for module: SinProject
    -- 
    -- Dependencies:
    -- 
    -- Revision:
    -- Revision 0.01 - File Created
    -- Additional Comments:
    --
    -- Notes: 
    -- This testbench has been automatically generated using types std_logic and
    -- std_logic_vector for the ports of the unit under test.  Xilinx recommends
    -- that these types always be used for the top-level I/O of a design in order
    -- to guarantee that the testbench will bind correctly to the post-implementation 
    -- simulation model.
    --------------------------------------------------------------------------------
    LIBRARY ieee;
    USE ieee.std_logic_1164.ALL;
     
    -- Uncomment the following library declaration if using
    -- arithmetic functions with Signed or Unsigned values
    --USE ieee.numeric_std.ALL;
     
    ENTITY SinprojecttestBench IS
    END SinprojecttestBench;
     
    ARCHITECTURE behavior OF SinprojecttestBench IS 
     
        -- Component Declaration for the Unit Under Test (UUT)
        
        COMPONENT SineFunction is
            Port ( clk : in STD_LOGIC;
                   reset : in STD_LOGIC;
                   strobe : in STD_LOGIC;
                   angle : in STD_LOGIC_VECTOR (9 downto 0);
                   SineValue : out STD_LOGIC_VECTOR (31 downto 0); --Sine function value in IEEE-754 Single Precision (Float32)
                   Sign : out STD_LOGIC); -- Sign: 0 positive, 1 negative
        END COMPONENT;
     
       --Inputs
       signal clk : std_logic := '0';
       signal reset : std_logic := '0';
       signal angle : std_logic_vector(9 downto 0) := (others => '0');
       signal strobe : std_logic := '0';
    
       --Outputs
       signal SineValOut : STD_LOGIC_VECTOR(31 DOWNTO 0); 
       signal Signout : STD_LOGIC;
    
       -- Clock period definitions
       constant clk_period : time := 100 ns; --10 Mhz
     
    BEGIN
     
    	-- Instantiate the Unit Under Test (UUT)
       uut: SineFunction PORT MAP (
              clk => clk,
              reset => reset,
              strobe => strobe,
              angle => angle,
              SineValue => SineValOut,
              Sign => Signout
            );
    
       -- Clock process definitions
       clk_process :process
       begin
    		clk <= '0';
    		wait for clk_period/2;
    		clk <= '1';
    		wait for clk_period/2;
       end process;
     
    
       -- Stimulus process
       stim_proc: process
       begin		
          -- hold reset state for 100 ns.
          wait for 100 ns;	
    
          wait for clk_period*10; --1us
    
          -- insert stimulus here 
            reset <= '0';        
    		strobe  <= '0';		
    		angle <= b"0000000000";
    			
    		wait for 1 ms;
    		reset <= '1'; 
    		
    		angle <= b"0000000000";
    		strobe  <= '1';
    		
    		wait for 1 ms;
    		strobe  <= '0';		
    		
    		
    		wait for 1 ms;
    		angle <= b"0000000001";
    		strobe  <= '1';
    		
    		wait for 1 ms;
    		strobe  <= '0';		
    				
    		wait for 1 ms;
    		angle <= b"0010000000"; --128
    		strobe  <= '1';
    		
    		wait for 1 ms;
    		strobe  <= '0';		
    		
    		wait for 1 ms;
    		angle <= b"0011111111"; --255
    		strobe  <= '1';	
    				
    		wait for 1 ms;
    		strobe  <= '0';		
    				
    		wait for 1 ms;
    		angle <= b"0100000000"; --256
    		strobe  <= '1';
    
    		wait for 1 ms;
    		strobe  <= '0';
    		
    		wait for 1 ms;
            angle <= b"0101110010"; --370
            strobe  <= '1';
            
            wait for 1 ms;
            strobe  <= '0';
    
    		wait for 1 ms;
    		angle <= b"0111111111"; --511
    		strobe  <= '1';	
    		
    		wait for 1 ms;
            strobe  <= '0';  
            
            wait for 1 ms;
            angle <= b"1000000000"; --512
            strobe  <= '1';
            
            wait for 1 ms;
            strobe  <= '0';
            
            wait for 1 ms;
            angle <= b"1011111000"; --760
            strobe  <= '1';
            
            wait for 1 ms;
            strobe  <= '0';
            
            wait for 1 ms;
            angle <= b"1110000100"; --900
            strobe  <= '1';
      	
    	    wait for 1 ms;
            strobe  <= '0';  
            
            wait for 1 ms;
            angle <=b"1111111111"; --1023
            strobe  <= '1';
    
          wait;
       end process;
    
    END;
    Here is screenshot width results of simulation:
    Click image for larger version. 

Name:	SineFuncSimulation.png 
Views:	9 
Size:	126.7 KB 
ID:	154935
    To ease I set that SineValue is displayed as decimal number in 32-bit float value. As one can see returned sine values are proper for given angles.

    In zip archive I attached ful project - Vivado 2018.2.

    SinusCosTestProj01.zip

    Any comments and proposals of improvements are warmly welcome

    Jind regards

    - - - Updated - - -

    Quote Originally Posted by FvM View Post
    What's your question?

    It's not clear, which calculations you want to perform in FPGA, but using floating point numbers is generally no good idea. Better use fixed point numbers (signed or unsigned integer values with implied power of two scaling factor).
    Hi,

    I am aware of that. I am going to calculat all Forward/Inverse kinematics problem related to robotic arm on FPGA circuit. Fixed-point numbers arte not very convenient for such calculations even if wide range of values of results. This is the reason why I had written my own module for calculating sine function values.
    I had tested efficient module of 4 floating point operation which is not occupying many resources of FPGA fabric.

    On open cores were few projects of calculating sine function but all fixed-point.

    Basically I would like to use this module to calculations involved in converting angles from seven quadrature encoders to X,Y,Z coordinates of arm end.

    Kind regards
    Last edited by FlyingDutch; 11th August 2019 at 16:35.



    •   AltAdvertisement

        
       

  4. #4
    Super Moderator
    Points: 77,915, Level: 68
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    15,793
    Helped
    3593 / 3593
    Points
    77,915
    Level
    68

    Re: Sine function generator (VHDL)

    Hi,

    On open cores were few projects of calculating sine function but all fixed-point.
    I'd use fixed point, too.
    For a 10 bit resolution input ... why do you need floating point? What benefit do you expect?

    I even doubt if a more than 16 bits (optimally scaled) give a benefit.

    Please do an error calculation first..

    Klaus
    Please don´t contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



  5. #5
    Full Member level 2
    Points: 1,057, Level: 7
    FlyingDutch's Avatar
    Join Date
    Dec 2017
    Location
    Bydgoszcz - Poland
    Posts
    131
    Helped
    20 / 20
    Points
    1,057
    Level
    7

    Re: Sine function generator (VHDL)

    Quote Originally Posted by KlausST View Post
    Hi,


    I'd use fixed point, too.
    For a 10 bit resolution input ... why do you need floating point? What benefit do you expect?

    I even doubt if a more than 16 bits (optimally scaled) give a benefit.

    Klaus
    Hello Klaus,

    I don't want to argue width your arguments - I agree with all of them, but on the contrary why not?

    What argumenst are against to use floating-point: occupation of FPGA resources or speed? In this scenario speed is more than enough even when calculations are made in floating point.

    Kind Regards



    •   AltAdvertisement

        
       

  6. #6
    Super Moderator
    Points: 260,308, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    45,460
    Helped
    13829 / 13829
    Points
    260,308
    Level
    100

    Re: Sine function generator (VHDL)

    I had tested efficient module of 4 floating point operation which is not occupying many resources of FPGA fabric.
    I presume that you have more than one FP calculation in your signal flow. You have to instantiate the FPU many times, or implement the controller as sequential machine, similar to calculation in a regular processor. I don't know if your concept takes this direction. Not impossible, but you are loosing many advantages of parallel FPGA data processing.

    As previously mentioned, there will be an error propagation from angle to magnitude. It sets an upper limit to useful magnitude resolution. You are presenting an isolated sine table unit right now. The resolution requirements are however defined by the overall controller application. Without analyzing it, you can't make substantiated specifications for the sine function unit.

    What arguments are against to use floating-point: occupation of FPGA resources or speed?
    In your application, probably both.

    Over the years, I had a very few FPGA designs that were dealing with floating point numbers. It's usage was always dictated by external data interface specifications, never useful for the respective signal processing task on its own.


    1 members found this post helpful.

  7. #7
    Full Member level 2
    Points: 1,057, Level: 7
    FlyingDutch's Avatar
    Join Date
    Dec 2017
    Location
    Bydgoszcz - Poland
    Posts
    131
    Helped
    20 / 20
    Points
    1,057
    Level
    7

    New trends in High-End FPGAs - EEJournal arti8cle

    Hello Guys,

    I am just reading article from EEJournal titled "High-End FPGA Showdown – Part 1 A Tale of Three Cities". Here is link to this article:

    https://www.eejournal.com/article/hi...owdown-part-1/

    Article is very interesting, desrcibes new features in last High-End FPGAs from Xilinx, Intel, Achronix. One of these features intrigued me, here is quotation from this article:

    All three vendors now offer hardened support for floating point. Achronix has a completely new architecture for their DSP blocks, which they call “Machine Learning Processors” (MLPs). Each MLP contains up to 32 multiplier/accumulators (MACs), 4- to 24-bit integer modes, and various floating-point modes, including native support for Tensorflow’s Bfloat16 format as well as block floating-point format. Most importantly, the Achronix MLP couples embedded memory blocks tightly with the arithmetic units, allowing the MAC operations to run at full 750 MHz without getting hung up waiting for memory through the FPGA fabric.

    Intel also uses variable precision DSP blocks with hardware floating-point (essentially like they’ve offered for years in their FPGAs). Intel’s floating point support is perhaps the broadest and most mature of the three. With Agilex, they have introduced two new floating-point modes, half-precision floating-point (FP16) & Block floating-point (Bfloat16), and they have made architectural adjustments to make their DSP operations even more efficient.

    Xilinx has upgraded their previous DSP48 slices to DSP58 – presumably because they now include hardware floating-point, and their multipliers are upgraded to 27×24. So, with this generation, the other two vendors have joined Intel in offering hardware floating-point support. This is a reversal for Xilinx, who previously claimed that floating point support in FPGAs was a bad idea because floating point is primarily used for training, and FPGAs will primarily target inference.

    In terms of what floating point formats are available, FP32 is supported by Versal (with up to 2.1K multipliers) and Agilex (with up to 8.7K multipliers). Half-precision (FP16) is supported by all three families – Versal with up to 2.1K multipliers, Agilex with up to 17.1K multiplers, and Speedster with up to 5.1K multipliers. Bfloat16 is supported by Agilex (with up to 17.1K multipliers) and Speedster (with up to 5.1K multipliers). For FP24, Versal and Agilex would presumably use the FP32 units, and Speedster has up to 2.6K multipliers. Achronix Speedster also supports up to 81.9K multiplers for block floating point.
    The previous speakers in this thread demonstrated that using floating-point arithmetic is ineffectual in context of FPGAs. And I of course agree with this thesis. So I am wondering why hardware floating-point blocks are present in newest High-End FPGAs from three biggest FPGA vendors. As far as I know the fixed-point arithmetic is enough for learning of artificial neural networks? So what is purpose of these floating-point DSP block, and what benefits they bring.

    Kind Regards

    Sorry I would like to place this post in thread:

    https://www.edaboard.com/showthread....nerator-(VHDL)

    Could I ask administrator to move this post to this thread?

    Thanks and Regards



--[[ ]]--