Forum Discussion
Altera_Forum
Honored Contributor
14 years agoMy final version of the RTL code
--=============================
-- Cordic
-- Implementacao do algoritmo de cordic para obter magnitude e angulo a partir de um numero complexo
--=============================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.all;
use work.fixed_float_types.all;
use work.fixed_pkg.all;
-- entity declaration
entity cordic is
port(
clk_i : in std_logic;
rst_i_n : in std_logic;
ena_i : in std_logic;
real_i : in std_logic_vector(31 downto 0);
imag_i : in std_logic_vector(31 downto 0);
fase_o : out std_logic_vector(31 downto 0);
magnitude_o : out std_logic_vector(31 downto 0)
);
end cordic;
architecture rtl of cordic is
-- Build an enumerated type for the state machine
type state_type is (init, corrige_q_p1, corrige_q_p2, calcula_cordic_p1, calcula_cordic_p2, incrementa_cont, fim);
-- Register to hold the current state
signal state : state_type;
signal next_state : state_type;
-- Registers to control the state machine flow
signal finish_quadrante : std_logic;
signal finish_cordic : std_logic;
signal finish_calc : std_logic;
-- Internal signals
signal parte_real,parte_imaginaria, temp_parte_real : sfixed (4 downto -27);
constant pi : sfixed (4 downto -27) := to_sfixed (3.1416, 4, -27);
constant pi_2 : sfixed (4 downto -27) := to_sfixed (1.57, 4, -27);
signal fase_o_r, magnitude_o_r : sfixed (4 downto -27);
signal acc_phase, acc_phase_rads, K : sfixed (4 downto -27);
signal indice : unsigned (5 downto 0);
signal working : std_logic;
signal variavel_nova : std_logic;
signal indice2 : unsigned (5 downto 0);
signal angulo_indice : std_logic_vector(31 downto 0);
signal ganho_indice : std_logic_vector(31 downto 0);
signal tmp_mult_im_k: sfixed (sfixed_high ( 4, -27, '*', 4, -27) downto sfixed_low ( 4, -27, '*', 4, -27));
signal tmp_mult_re_k: sfixed (sfixed_high ( 4, -27, '*', 4, -27) downto sfixed_low ( 4, -27, '*', 4, -27));
signal corrige_q_p1_end : std_logic;
-- Instantiation of other modules
component angulo_atan is
port(
clk_i : in std_logic;
rst_i_n : in std_logic;
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(
clk_i : in std_logic;
rst_i_n : in std_logic;
indice_i : in std_logic_vector (5 downto 0);
ganho_o : out std_logic_vector (31 downto 0) );
end component;
begin
angulo_inst : angulo_atan
port map(
clk_i => clk_i,
rst_i_n => rst_i_n,
indice_i => std_logic_vector(indice),
angulo_o => angulo_indice);
ganho_inst : ganho_k
port map(
clk_i => clk_i,
rst_i_n => rst_i_n,
indice_i => std_logic_vector(indice2),
ganho_o => ganho_indice);
-- Output depends solely on the current state
process (clk_i, rst_i_n, state)
begin
if rst_i_n = '0' then
next_state <= init;
elsif (rising_edge(clk_i)) then
state <= next_state;
case state is
when init =>
indice2 <=(others => '0');
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');
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';
corrige_q_p1_end <= '0';
next_state <= corrige_q_p1;
when corrige_q_p1 =>
working <= '1';
parte_real <= to_sfixed(real_i, 4, -27);
parte_imaginaria <= to_sfixed(imag_i, 4, -27);
next_state <= corrige_q_p2;
when corrige_q_p2 =>
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;
next_state <= calcula_cordic_p1;
when calcula_cordic_p1 =>
K <= to_sfixed(ganho_indice, 4, -27);
acc_phase <= to_sfixed(angulo_indice, 4, -27);
temp_parte_real <= parte_real;
next_state <= calcula_cordic_p2;
variavel_nova <= '1';
when calcula_cordic_p2 =>
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 next_state <= incrementa_cont;
elsif indice = 24 then
next_state <= fim ;
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 =>
next_state <= calcula_cordic_p1;
if variavel_nova = '1' then
variavel_nova <= '0';
indice <= indice + 1;
indice2 <= indice2 + 1;
end if;
when fim =>
fase_o <= to_slv(fase_o_r);
magnitude_o <= to_slv(magnitude_o_r);
next_state <= init;
end case;
end if;
end process;
end rtl;
It isnt working.. i am having the following problem in modelsim. I have circled the parts of my simualtion with problems.. the signals in this part of my code when corrige_q_p2 =>
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 are changing way too fast.. and i am having the following warning Error: :work:fixed_pkg: Unbounded number passed, was a literal used?