Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
13 years ago

Fixed Point VHDL Support in Quartus

I am asking how people have found the synthesis results with the new VHDL2008 package for fixed point. I have created a design that is a cascaded filter simulating a three phase RL load for a motor control application. I haven't synthesized it into quartus yet, but even if it compiles just fine, I am wondering if anyone in the community at large has had any issues with the implementation of these packages in Quartus?

This will be very influential in doing various types of controllers; PI, sliding mode, model reference adaptive control, etc . . .

Thanks, James


library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
use ieee.fixed_pkg.all;
entity ModelVoltage is
     port(
         MCLK         : in STD_LOGIC;
         HRST         : in STD_LOGIC;
         START      : in std_logic;
         VA         : in STD_LOGIC;
         VB         : in STD_LOGIC;
         VC         : in STD_LOGIC;
         DCBUSVOLTS : in STD_LOGIC_VECTOR(11 downto 0);
         VAx         : out sfixed(16 downto -16);
         VBx         : out sfixed(16 downto -16);
         VCx         : out sfixed(16 downto -16);
         Vn         : out sfixed(16 downto -16);
         IA         : out sfixed(16 downto -16);
         IB         : out sfixed(16 downto -16);
         IC         : out sfixed(16 downto -16); 
         DONE       : out std_logic
         );
end ModelVoltage;
architecture RTL of ModelVoltage is       
type stateType is (S0,S1,S2,S3,S4,S5,S6,S7,S8);
signal state : stateType;
constant Cx: integer := 8;
constant Dx: integer := 16;
constant R : integer := 16;
constant N : integer := 16;
constant P : integer := 16;
constant M : integer := 40;  
type abcType is record
    a         : sfixed(R downto -N);
    b         : sfixed(R downto -N);
    c         : sfixed(R downto -N);    
    n         : sfixed(R downto -N);
    nX         : sfixed(R downto -N);
    
    aR         : sfixed(P downto -M);
    bR         : sfixed(P downto -M);
    cR         : sfixed(P downto -M);
    
    aV         : sfixed(R downto -N);
    bV         : sfixed(R downto -N);
    cV         : sfixed(R downto -N);
    aVk1     : sfixed(R downto -N);
    bVk1     : sfixed(R downto -N);
    cVk1     : sfixed(R downto -N);    
    
    ak         : sfixed(P downto -M);
    bk         : sfixed(P downto -M);
    ck         : sfixed(P downto -M);
    
    ak1     : sfixed(P downto -M);
    bk1     : sfixed(P downto -M);
    ck1     : sfixed(P downto -M);
    
end record;
signal v : abcType;
signal i : abcType;    
constant RecipThree : sfixed(8 downto -8) := to_sfixed(0.333,8,-8);
constant Rx          : sfixed(8 downto -8) := to_sfixed(0.55,8,-8);
constant Ts2        : sfixed(8 downto -24) := to_sfixed(0.0004,8,-24);
begin
                                                                    
    process(all) begin
        if HRST then
            v.a <= to_sfixed(0,R,-N); 
            v.b <= to_sfixed(0,R,-N);
            v.c <= to_sfixed(0,R,-N);
            
        elsif rising_edge(MCLK) then
            if START then
                if VA then
                    v.a <= to_sfixed(signed(DCBUSVOLTS),R,-N);
                else
                    v.a <= to_sfixed(-200,R,-N);
                end if;
                
                if VB then
                    v.b <= to_sfixed(signed(DCBUSVOLTS),R,-N);
                else
                    v.b <=  to_sfixed(-200,R,-N);
                end if;
                
                if VC then
                    v.c <= to_sfixed(signed(DCBUSVOLTS),R,-N);
                else
                    v.c <= to_sfixed(-200,R,-N);
                end if;
            end if;
        end if;
    end process; 
    
    VAx <= v.Av;
    VBx <= v.Bv;
    VCx <= v.Cv;
    
    process(all) begin
        if HRST then
            v.n <= to_sfixed(0,R,-N);
        elsif rising_edge(MCLK) then
            if state = S2 then
                v.n <= resize((v.a + v.b + v.c),R,-N);
            end if;
        end if;
    end process; 
    
    process(all) begin
        if HRST then
            v.nX <= to_sfixed(0,R,-N);
        elsif rising_edge(MCLK) then
            if state = S3 then
                v.nX <= resize(RecipThree*v.n,R,-N);
            end if;
        end if;
    end process; 
    
    /*--------------------------------
       Resistive voltage drop
    --------------------------------*/
    process(all) begin
        if HRST then
            v.aR <= to_sfixed(0,P,-M);
            v.bR <= to_sfixed(0,P,-M);
            v.cR <= to_sfixed(0,P,-M);     
        elsif rising_edge(MCLK) then
            if state = S4 then
                v.aR <= resize(Rx*i.ak,P,-M);
                v.bR <= resize(Rx*i.bk,P,-M);
                v.cR <= resize(Rx*i.ck,P,-M);
            end if;
        end if;
    end process;
    process(all) begin
        if HRST then
            v.aV <= to_sfixed(0,R,-N);
            v.bV <= to_sfixed(0,R,-N);
            v.cV <= to_sfixed(0,R,-N);     
        elsif rising_edge(MCLK) then
            if state = S5 then
                v.aV <= resize((v.a - v.aR - v.nX),R,-N);
                v.bV <= resize((v.b - v.bR - v.nX),R,-N);
                v.cV <= resize((v.c - v.cR - v.nX),R,-N);
            end if;
        end if;
    end process;
    
    process(all) begin
        if HRST then
            i.ak <= to_sfixed(0,P,-M);
            i.bk <= to_sfixed(0,P,-M);
            i.ck <= to_sfixed(0,P,-M);     
        elsif rising_edge(MCLK) then
            if state = S6 then
                i.ak <= resize(((v.aV + v.aVk1)*Ts2 + i.ak1),P,-M);
                i.bk <= resize(((v.bV + v.bVk1)*Ts2 + i.bk1),P,-M);
                i.ck <= resize(((v.cV + v.cVk1)*Ts2 + i.ck1),P,-M);
            end if;
        end if;
    end process;
    
    process(all) begin
        if HRST then
            i.ak1 <= to_sfixed(0,P,-M);
            i.bk1 <= to_sfixed(0,P,-M);
            i.ck1 <= to_sfixed(0,P,-M);
            v.aVk1 <= to_sfixed(0,R,-N);
            v.bVk1 <= to_sfixed(0,R,-N);
            v.cVk1 <= to_sfixed(0,R,-N);
            
        elsif rising_edge(MCLK) then
            if state = S7 then
                i.ak1 <= i.ak;
                i.bk1 <= i.bk;
                i.ck1 <= i.ck;
                v.aVk1 <= v.aV;
                v.bVk1 <= v.bV;
                v.cVk1 <= v.cV;
            end if;
        end if;
    end process;
    
    IA <= i.ak(16 downto -16);
    IB <= i.bk(16 downto -16);
    IC <= i.ck(16 downto -16);
    
    
    process(all) begin
        if HRST then
            state <= S0; 
            done <= '0';
        elsif rising_edge(MCLK) then
            case state is 
                when S0 => 
                if START then
                    state <= S1;
                else
                    state <= S0;
                end if;      
                done <= '0';
                
                when S1 =>
                state <= S2;
                
                when S2 =>
                state <= S3;
                
                when S3 =>
                state <= S4;
                
                when S4 =>
                state <= S5;
                
                when S5 =>
                state <= S6;
                
                when S6 =>
                state <= S7;
                
                when S7 =>
                state <= S0;
                done <= '1';
                
                when others => 
                null;
                
            end case;
        end if;
    end process;
end RTL;

18 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks Dave. I will do that, I appreciate it. Best, James

    My new VHDL:

    California <= std_logic(FPGA_JOBS)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi, I am using Quartus 12.0 SP1 with MdoelSim Altera Starter Edition

    and try to use fixed_pkg.

    As you wrote, ModelSim understands very well

    but Quartus does'nt.

    I had to add the D Bishop package and adapt my use statements ("ieee_proposed")

    A little constraint, but not found until I was in this thread.

    Maybe for next year, Altera would include fixed_pkg in Quartus

    Happy year-end !
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi,

    I am doing my Final year project including the floating point calculation. Anyone here know how to convert floating point number into integer with using the floating point package float_pkg_c.vhdl ? I already tried with the code below (a simply floating point addition and convert the summation into integer) but it show me this error --> "Error (10454): VHDL syntax error at float_pkg_c.vhdl(4314): right bound of range must be a constant" .Anyone here can help me to solve it? thanks.

    Code:

    library ieee;

    use ieee.std_logic_1164.all;

    library ieee_proposed;

    use ieee_proposed.fixed_float_types.all; -- ieee in the release

    use ieee_proposed.float_pkg.all; -- ieee.float_pkg.all; in the release

    entity round is port (

    a, b : in std_logic_vector (31 downto 0);

    Sum : out integer;

    Clk, reset : in std_ulogic);

    end round;

    architecture RTL of round is

    signal afp, bfp, Sumfp : float32; -- same as "float (8 downto 23)"

    begin

    afp <= to_float (a, afp); -- SLV to float, using afp' range

    bfp <= to_float (b, bfp); -- SLV to float, using bfp' range

    process (clk, reset)

    begin

    if reset = '1' then

    Sumfp <= (others => '0');

    elsif rising_edge (clk) then

    Sumfp <= afp + bfp;

    Sum <= to_integer (Sumfp,round_inf,true);

    end if;

    end process;

    end RTL;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    In contrast to IEEE fixed point package, floating point package is effectively useless for logic synthesis because it's not able to generate any pipelining.

    You should use the Altera floating point MegaFunctions instead, they provide al operations you want.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    In contrast to IEEE fixed point package, floating point package is effectively useless for logic synthesis because it's not able to generate any pipelining.

    You should use the Altera floating point MegaFunctions instead, they provide al operations you want.

    --- Quote End ---

    But i am using the quartus 2 version 9.0 and altera DE2 board with cyclone 2 device. is it support for megafunction? since i had download the design example of megafunction using my quartus 2 but it said this version is not compatible to open this design example project.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    When using newer incompatible *.qsf files (e.g. from Quartus 11 or 12) with Quartus 9, a few lines have to be manually deleted. Quartus is telling you which lines are incompatble.

    But incompatible example designs hasn't to do with floating point MegaFunctions. They are available in Quartus since long.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    When using newer incompatible *.qsf files (e.g. from Quartus 11 or 12) with Quartus 9, a few lines have to be manually deleted. Quartus is telling you which lines are incompatble.

    But incompatible example designs hasn't to do with floating point MegaFunctions. They are available in Quartus since long.

    --- Quote End ---

    Noted. i had tried a simple floating point summation and convert it into integer using megafunction, it's is work. But the problem is i need to round toward positive infinity for my DSP coding but megafunction only support for round to nearest only. Any others way to make it?