Altera_Forum
Honored Contributor
12 years agoAddition 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?