Altera_Forum
Honored Contributor
14 years agoTrying to develop my own Cordic core at VHDL.. problems
Hello i am trying to develop my own Cordic core at VHDL.. but i am having some problems.
I basically have a block of gain and a block of angles that works like that (just a snap)
...
case indice_i is
when "000000" => angulo_o_r <= to_sfixed(0.7854, 4, -27);
when "000001" => angulo_o_r <= to_sfixed(0.4636, 4, -27);
when "000010" => angulo_o_r <= to_sfixed(0.2450, 4, -27);
when "000011" => angulo_o_r <= to_sfixed(0.1244, 4, -27);
when "000100" => angulo_o_r <= to_sfixed(0.0624, 4, -27);
...
And i have my main CORDIC core... i am trying to do something like this (matlab)
ka = 1;
for j=1:n;
Kvalues(j) = ka
angles(j) = atan(ka);
ka = ka * 0.5;
end;
for l=1:n;
K = Kvalues(l);
phase_rads = angles(l);
tmp_real = real;
However for doesnt work the same way in VHDL, so i tried to make a state machine with the following states: INIT (reset state) -> CALC_CORDIC -> INCREMENT_COUNTER->CALC_CORDIC (24 times) then -> FINISH Where my counter is the input for my angle/gain blocks and i use the output from those blocks in my calc_cordic. Too bad it isn't working and i don't know why.. I am getting this error
Error (10028): Can't resolve multiple constant drivers for net "angulo_indice" at cordic.vhd(66)
But i don't have multiple constant drivers for that net.. my code is here
-- Logic to advance to the next state
process (clk_i, rst_i_n)
begin
if rst_i_n = '0' then
state <= init;
elsif (rising_edge(clk_i)) then
case state is
when init=>
if ena_i = '1' and working = '0' then
state <= corrigi_q;
else
state <= init;
end if;
when corrigi_q=>
if finish_quadrante = '1' then
state <= calcula_cordic;
else
state <= corrigi_q;
end if;
when calcula_cordic=>
if finish_cordic ='1' then
state <= fim;
end if;
if finish_calc = '1' then
state <= incrementa_cont;
end if;
if finish_calc = '0' and finish_cordic = '0' then
state <= calcula_cordic;
end if;
when incrementa_cont =>
state <= calcula_cordic;
when fim =>
state <= init;
end case;
end if;
end process;
-- Output depends solely on the current state
process (state)
begin
case state is
when init =>
pi <= to_sfixed (3.1416, 4, -27);
pi_2 <= to_sfixed (1.57, 4, -27);
parte_real <= (others => '0');
parte_imaginaria <= (others => '0');
temp_parte_real <= (others => '0');
acc_phase <= (others => '0');
acc_phase_rads <= (others => '0');
K <= (others => '0');
indice <= (others => '0');
ganho_indice <= (others => '0');
angulo_indice <= (others => '0');
tmp_mult_im_k <= (others => '0');
tmp_mult_re_k <= (others => '0');
magnitude_o_r <= (others => '0');
fase_o_r <= (others => '0');
finish_quadrante <= '0';
finish_cordic <= '0';
finish_calc <= '0';
working <= '0';
when corrigi_q =>
working <= '1';
parte_real <= to_sfixed(real_i, 4, -27);
parte_imaginaria <= to_sfixed(imag_i, 4, -27);
if parte_real < "0" then
temp_parte_real <= parte_real;
if parte_imaginaria > "0" then
parte_real <= parte_imaginaria;
parte_imaginaria <= resize(((not temp_parte_real) + to_sfixed(1, 4, -27)),4,-27); --negativo
acc_phase_rads <= resize(((not pi_2) + to_sfixed(1, 4, -27)),4,-27);--negativo
else
parte_real <= resize(((not parte_imaginaria) + to_sfixed(1, 4, -27)),4,-27); --negativo
parte_imaginaria <= temp_parte_real;
acc_phase_rads <= pi_2;
end if;
else
acc_phase_rads <= (others => '0');
end if;
finish_quadrante <= '1';
when calcula_cordic =>
K <= to_sfixed(ganho_indice, 4, -27);
acc_phase <= to_sfixed(angulo_indice, 4, -27);
temp_parte_real <= parte_real;
if parte_imaginaria >= "0" then
tmp_mult_re_k <= temp_parte_real * K;
tmp_mult_im_k <= parte_imaginaria * K;
parte_real <= resize((parte_real + tmp_mult_im_k),4,-27);
parte_imaginaria <= resize((parte_imaginaria - tmp_mult_re_k),4,-27);
acc_phase_rads <= resize((acc_phase_rads - acc_phase),4,-27);
else
tmp_mult_re_k <= temp_parte_real * K;
tmp_mult_im_k <= parte_imaginaria * K;
parte_real <= resize((parte_real - tmp_mult_im_k),4,-27);
parte_imaginaria <= resize((parte_imaginaria + tmp_mult_re_k),4,-27);
acc_phase_rads <= resize((acc_phase_rads + acc_phase),4,-27);
end if;
if indice < 24 then finish_calc <= '1'; end if;
if indice = 24 then
finish_calc <= '0';
finish_cordic <= '1';
fase_o_r <= resize((not acc_phase_rads) + to_sfixed(1, 4, -27),4,-27) ;
magnitude_o_r <= resize(parte_real * to_sfixed(0.60723, 4, -27),4,-27);
end if;
when incrementa_cont =>
indice <= indice + 1;
finish_calc <= '0';
when fim =>
fase_o <= to_slv(fase_o_r);
magnitude_o <= to_slv(magnitude_o_r);
working <= '0';
end case;
end process;
end rtl;
and my gain/angle blocks declarations
component angulo_atan is
port(
indice_i : in std_logic_vector (5 downto 0);
angulo_o : out std_logic_vector (31 downto 0) );
end component;
component ganho_k is
port(
indice_i : in std_logic_vector (5 downto 0);
ganho_o : out std_logic_vector (31 downto 0) );
end component;
angulo_inst : angulo_atan
port map(
indice_i => std_logic_vector(indice),
angulo_o => angulo_indice);
ganho_inst : ganho_k
port map(
indice_i => std_logic_vector(indice),
ganho_o => ganho_indice);
ANY HELP IS rEALLY apreciated