Forum Discussion

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

Addition problem in Quartus

So, after break the head for some minutes trying to find out why an simple addition didnt work, i went to see the RTL and found an weird thing:

https://dl.dropboxusercontent.com/u/38797606/Untitled.png

so, beyond putting an '0' on the last bit, it magically merges an vector of 32 bits into one of 31 bits (see big arrow on the image)?

the bigger vectors (of 46 bits) also have this issue.


library IEEE;use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity COUNTEUR_XYR_HIRES is Port ( 
    CODEUR1 : IN  STD_LOGIC_VECTOR (1  downto 0);
    CODEUR2 : IN  STD_LOGIC_VECTOR (1  downto 0);
    RELATION: IN  STD_LOGIC_VECTOR (23 downto 0);
    POSX    : OUT STD_LOGIC_VECTOR (31 downto 0);
    POSY    : OUT STD_LOGIC_VECTOR (31 downto 0);
    ROT     : OUT STD_LOGIC_VECTOR (15 downto 0);  --0-360 degrees+7 bits
    RESET   : IN  STD_LOGIC;
    H       : IN  STD_LOGIC
);
end COUNTEUR_XYR_HIRES;
architecture Behavioral of COUNTEUR_XYR_HIRES is
signal intPosX : Integer; --pas (32 bit) * 14 bits => 46 bits
signal intPosY : Integer; --pas (32 bit) * 14 bits => 46 bits
signal buffPosX : std_logic_vector(45 downto 0); 
signal buffPosY : std_logic_vector(45 downto 0); 
signal buffRot :  std_logic_vector(31 downto 0); 
signal subSubRot, subIncRot : std_logic_vector(31 downto 0);
signal nextSubRot, nextIncRot : std_logic_vector(31 downto 0);
--signal lastCod1, lastCod2: std_logic_vector(1 downto 0);
signal SINUS, COSINUS: STD_LOGIC_VECTOR(15 downto 0);
component TABLE_SINUS is Port (  
    H       : in  STD_LOGIC;
    ANGLE   : in  STD_LOGIC_VECTOR(15 downto 0);
    SINUS   : out STD_LOGIC_VECTOR(15 downto 0);
    COSINUS : out STD_LOGIC_VECTOR(15 downto 0)
);
end component;
begin
    POSX <= buffPosX(45 downto 14);
    POSY <= buffPosY(45 downto 14);
    ROT  <=  buffRot(31 downto 16);
    
    buffPosX <= std_logic_vector(to_unsigned(intPosX,46));
    buffPosY <= std_logic_vector(to_unsigned(intPosY,46));
    --buffRot  <= std_logic_vector(to_unsigned(intRot,32)) ;
    
    subSubRot <= STD_LOGIC_VECTOR(TO_UNSIGNED(TO_INTEGER(UNSIGNED(buffRot)) - TO_INTEGER(UNSIGNED(RELATION)),32));
    subIncRot <= STD_LOGIC_VECTOR(TO_UNSIGNED(TO_INTEGER(UNSIGNED(buffRot)) + TO_INTEGER(UNSIGNED(RELATION)),32));
    nextIncRot(23 downto 0) <= subIncRot(23 downto 0);
    nextSubRot(23 downto 0) <= subSubRot(23 downto 0);
    
    async : process(subIncRot, subSubRot)
    begin
        if(subIncRot(31 downto 24)=x"B4")then
            nextIncRot(31 downto 24) <= x"00";
        else
            nextIncRot(31 downto 24) <= subIncRot(31 downto 24);
        end if;
        if(subSubRot(31 downto 24)=x"FF")then
            nextSubRot(31 downto 24) <= x"B3";
        else
            nextSubRot(31 downto 24) <= subSubRot(31 downto 24);
        end if;
    end process;
    
    sin:TABLE_SINUS PORT MAP(
        H => H,
        ANGLE => buffRot(31 downto 16),
        SINUS => SINUS,
        COSINUS => COSINUS
    );
  
  onHorloge : process (H)
  begin
        if(H'event and H='1')then
            if(RESET='1')then
                intPosX<=0;
                intPosY<=0;
                buffRot <= x"00000000";
            else
                if(CODEUR1(0)='1')then
                    buffRot <= nextIncRot;
                    if(COSINUS(15)='0')then --cosinus>0
                        intPosX <= intPosX + TO_INTEGER(UNSIGNED(COSINUS(14 downto 0)));
                    else
                        intPosX <= intPosX - TO_INTEGER(UNSIGNED(COSINUS(14 downto 0)));
                    end if;
                    if(SINUS(15)='0')then
                        intPosY <= intPosY - TO_INTEGER(UNSIGNED(SINUS(14 downto 0)));
                    else
                        intPosY <= intPosY + TO_INTEGER(UNSIGNED(SINUS(14 downto 0)));
                    end if;
                elsif(CODEUR1(1)='1')then
                    buffRot <= nextSubRot;
                    if(COSINUS(15)='0')then --cosinus>0
                        intPosX <= intPosX - TO_INTEGER(UNSIGNED(COSINUS(14 downto 0)));
                    else
                        intPosX <= intPosX + TO_INTEGER(UNSIGNED(COSINUS(14 downto 0)));
                    end if;
                    if(SINUS(15)='0')then
                        intPosY <= intPosY + TO_INTEGER(UNSIGNED(SINUS(14 downto 0)));
                    else
                        intPosY <= intPosY - TO_INTEGER(UNSIGNED(SINUS(14 downto 0)));
                    end if;
                elsif(CODEUR2(0)='1')then
                    buffRot <= nextIncRot;
                    if(COSINUS(15)='0')then --cosinus>0, mais ici on subtraient
                        intPosX <= intPosX - TO_INTEGER(UNSIGNED(COSINUS(14 downto 0)));
                    else
                        intPosX <= intPosX + TO_INTEGER(UNSIGNED(COSINUS(14 downto 0)));
                    end if;
                    if(SINUS(15)='0')then
                        intPosY <= intPosY + TO_INTEGER(UNSIGNED(SINUS(14 downto 0)));
                    else
                        intPosY <= intPosY - TO_INTEGER(UNSIGNED(SINUS(14 downto 0)));
                    end if;
                elsif(CODEUR2(1)='1')then
                    buffRot <= nextSubRot;
                    if(COSINUS(15)='0')then --cosinus>0
                        intPosX <= intPosX + TO_INTEGER(UNSIGNED(COSINUS(14 downto 0)));
                    else
                        intPosX <= intPosX - TO_INTEGER(UNSIGNED(COSINUS(14 downto 0)));
                    end if;
                    if(SINUS(15)='0')then
                        intPosY <= intPosY - TO_INTEGER(UNSIGNED(SINUS(14 downto 0)));
                    else
                        intPosY <= intPosY + TO_INTEGER(UNSIGNED(SINUS(14 downto 0)));
                    end if;
                end if;
            end if;
        end if;
    end process;
end Behavioral;

I contourned the problem by shifting 1 bit all the vectors relative (thus, lost 1 bit reolution). but still, why cant i make a "simple" (32 bit) addition?

20 Replies