Files
vhdl/projects/cordic/src/cordic_top.vhd
T
jens 00ae5a7810 - added cordic
git-svn-id: http://moon:8086/svn/vhdl/trunk@1412 cc03376c-175c-47c8-b038-4cd826a8556b
2021-03-21 10:37:40 +00:00

461 lines
11 KiB
VHDL

--------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 11:52:30 10/02/05
-- Design Name:
-- Module Name: cordic_top - Behavioral
-- Project Name:
-- Target Device:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.MATH_REAL.ALL;
USE ieee.numeric_std.ALL;
use work.fixed_ja.all;
use work.cordic_pkg.all;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity cordic_top is
Generic
(
nbits : integer := 8;
nbits_int : integer := 2;
nbits_out : integer := 8;
nbits_out_int : integer := 2
);
Port (
rst : in std_logic;
clk : in std_logic;
ce : in std_logic;
xin : in sfixed_t;
yin : in sfixed_t;
zin : in sfixed_t;
xout : out sfixed_t;
yout : out sfixed_t;
zout : out sfixed_t;
ready : out std_logic;
valid : out std_logic;
cordic_mode : in cordic_mode_t
);
end cordic_top;
architecture Behavioral of cordic_top is
-----------------------------------------------------------------------
COMPONENT cordic_stage_pre is
GENERIC
(
nbits : integer;
nbits_int : integer;
nbits_out : integer;
nbits_int_out : integer;
reg_mode : reg_mode_t
);
PORT
(
rst : in std_logic;
clk : in std_logic;
ce : in std_logic;
xin : in sfixed_t;
yin : in sfixed_t;
zin : in sfixed_t;
xout : out sfixed_t;
yout : out sfixed_t;
zout : out sfixed_t;
cordic_mode : in cordic_mode_t;
ready : OUT std_logic;
valid : out std_logic
);
END COMPONENT;
COMPONENT cordic_stage
GENERIC
(
nbits : integer;
nbits_int : integer;
nbits_out : integer;
nbits_int_out : integer;
reg_mode : reg_mode_t
);
PORT(
rst : IN std_logic;
clk : IN std_logic;
ce : IN std_logic;
xin : IN sfixed_t;
yin : IN sfixed_t;
zin : IN sfixed_t;
xout : OUT sfixed_t;
yout : OUT sfixed_t;
zout : OUT sfixed_t;
coeff : in sfixed_t;
dir_cw : in std_logic;
stage_count : IN integer;
cordic_mode : in cordic_mode_t;
ready : OUT std_logic;
valid : out std_logic
);
END COMPONENT;
COMPONENT cordic_stage_post is
GENERIC
(
nbits : integer;
nbits_int : integer;
nbits_out : integer;
nbits_int_out : integer;
reg_mode : reg_mode_t
);
PORT
(
rst : in std_logic;
clk : in std_logic;
ce : in std_logic;
xin : in sfixed_t;
yin : in sfixed_t;
zin : in sfixed_t;
xout : out sfixed_t;
yout : out sfixed_t;
zout : out sfixed_t;
cordic_mode : in cordic_mode_t;
ready : OUT std_logic;
valid : out std_logic
);
END COMPONENT;
COMPONENT rom_arctan is
GENERIC
(
nbits : integer := 8;
nbits_int : integer := 0
);
PORT
(
addr : in unsigned(6 downto 0);
dout : out sfixed_t
);
END COMPONENT;
-----------------------------------------------------------------------
type state_type is (st_input, st_ready, st_pre_stage_in, st_pre_stage_out, st_proc_stage_in, st_proc_stage_out, st_post_stage_in, st_post_stage_out);
constant zero_sfix : sfixed_t := to_sfixed(0.0, nbits_out, nbits_out_int);
-- Define number of LSB guard bits
constant guard_nbits : integer := integer(log2(real(nbits))+0.5);
-- Define number of internal stage bits
constant stage_nbits : integer := nbits + guard_nbits; -- add more internal precision
constant stage_nbits_int : integer := nbits_int;
-- Set number of coefficient bits
constant coeff_nbits : integer := stage_nbits - stage_nbits_int;
constant coeff_nbits_int : integer := 0; -- coeffs have no integer part
-- Set number of iteration with respect to bit size
constant max_stage_count : integer := stage_nbits;
-- INPUT
-- Input pre stage
signal pre_stage_en : std_logic;
signal xin_pre, yin_pre, zin_pre : sfixed_t(sproto(nbits, nbits_int)'high downto sproto(nbits, nbits_int)'low);
-- Output pre stage
signal pre_stage_ready, pre_stage_valid : std_logic;
signal xout_pre, yout_pre, zout_pre : sfixed_t(sproto(stage_nbits, stage_nbits_int)'high downto sproto(stage_nbits, stage_nbits_int)'low);
-- Input processing stage
signal proc_stage_en: std_logic;
signal xin_stage, yin_stage, zin_stage : sfixed_t(sproto(stage_nbits, stage_nbits_int)'high downto sproto(stage_nbits, stage_nbits_int)'low);
-- Output processing stage
signal proc_stage_ready, proc_stage_valid : std_logic;
signal xout_stage, yout_stage, zout_stage : sfixed_t(sproto(stage_nbits, stage_nbits_int)'high downto sproto(stage_nbits, stage_nbits_int)'low);
-- Input post stage
signal post_stage_en : std_logic;
signal xin_post, yin_post, zin_post : sfixed_t(sproto(stage_nbits, stage_nbits_int)'high downto sproto(stage_nbits, stage_nbits_int)'low);
-- Output post stage
signal post_stage_ready, post_stage_valid : std_logic;
signal xout_post, yout_post, zout_post : sfixed_t(sproto(nbits, nbits_int)'high downto sproto(nbits, nbits_int)'low);
-- ROM
signal rom_addr : unsigned (6 downto 0);
signal rom_data : sfixed_t(sproto(coeff_nbits, coeff_nbits_int)'high downto sproto(coeff_nbits, coeff_nbits_int)'low);
-- Misc.
signal state, next_state : state_type;
signal count : integer range 0 to max_stage_count-1 := 0;
signal count_en, dir_cw, valid_s : std_logic;
begin
-----------------------------------------------------------------------
cordic_proc_mode : process(rst, zin_stage, yin_stage, cordic_mode)
begin
if (rst = '1') then
dir_cw <= '0';
else
dir_cw <= '0';
case cordic_mode is
when cordic_mode_rotate =>
if (zin_stage(zin_stage'high) = '1') then
dir_cw <= '1';
end if;
when cordic_mode_vector =>
if (yin_stage(yin_stage'high) = '1') then
dir_cw <= '0';
else
dir_cw <= '1';
end if;
when others => null;
end case;
end if;
end process;
-----------------------------------------------------------------------
counter: process (clk, rst, count, count_en)
begin
if (rst = '1') then
count <= 0;
rom_addr <= (others => '0');
else
if (clk'event and clk = '1') then
rom_addr <= to_unsigned(count, rom_addr'length);
if (count_en = '1' and count < max_stage_count-1) then
count <= count + 1 after tpd;
else
count <= 0;
end if;
end if;
end if;
end process;
-----------------------------------------------------------------------
OUTPUT_PROC: process (clk, rst, state, xout_stage, yout_stage, zout_stage)
begin
if (rst='1') then
valid <= '0';
xout <= zero_sfix after tpd;
yout <= zero_sfix after tpd;
zout <= zero_sfix after tpd;
-- assign other outputs to reset value
elsif (clk'event and clk = '1') then
valid <= '0';
if(post_stage_valid = '1') then
xout <= xout_post;
yout <= yout_post;
zout <= zout_post;
valid <= '1';
end if;
end if;
end process;
-----------------------------------------------------------------------
--Insert the following in the architecture after the begin keyword
FSM_PROC: process (clk, rst, xout_stage, yout_stage, zout_stage)
begin
if (rst='1') then
state <= st_ready;
-- assign other outputs to reset value
elsif (clk'event and clk = '1') then
state <= next_state after tpd;
-- assign other outputs to internal signals
end if;
end process;
--MOORE State Machine - Outputs based on state only
Control_proc: process (state, xin, yin, zin, xout_pre, yout_pre, zout_pre, xout_stage, yout_stage, zout_stage)
begin
--insert statements to decode internal output signals
--below is simple example
ready <= '0';
valid_s <= '0';
count_en <= '0';
pre_stage_en <= '0';
proc_stage_en <= '0';
post_stage_en <= '0';
xin_pre <= xin;
yin_pre <= yin;
zin_pre <= zin;
xin_stage <= xout_stage;
yin_stage <= yout_stage;
zin_stage <= zout_stage;
xin_post <= xout_stage;
yin_post <= yout_stage;
zin_post <= zout_stage;
case (state) is
when st_ready =>
ready <= '1';
when st_pre_stage_in =>
pre_stage_en <= '1';
when st_pre_stage_out =>
count_en <= '1';
proc_stage_en <= '1';
xin_stage <= xout_pre;
yin_stage <= yout_pre;
zin_stage <= zout_pre;
when st_proc_stage_in =>
count_en <= '1';
proc_stage_en <= '1';
when st_post_stage_in =>
post_stage_en <= '1';
when others =>
end case;
end process;
NEXT_STATE_DECODE: process (state, ce, count)
begin
--declare default state for next_state to avoid latches
next_state <= state; --default is to stay in current state
--insert statements to decode next_state
--below is a simple example
case (state) is
when st_ready =>
if ce = '1' then
next_state <= st_input;
end if;
when st_input =>
if ce = '0' then
next_state <= st_pre_stage_in;
end if;
when st_pre_stage_in =>
next_state <= st_pre_stage_out;
when st_pre_stage_out =>
next_state <= st_proc_stage_in;
when st_proc_stage_in =>
if (count = max_stage_count-2) then
next_state <= st_post_stage_in;
end if;
when st_post_stage_in =>
next_state <= st_ready;
when others =>
next_state <= st_ready;
end case;
end process;
-----------------------------------------------------------------------
Inst_cordic_stage_pre: cordic_stage_pre
GENERIC MAP
(
nbits => nbits,
nbits_int => nbits_int,
nbits_out => stage_nbits,
nbits_int_out => stage_nbits_int,
reg_mode => reg_mode_in
)
PORT MAP
(
rst => rst,
clk => clk,
ce => pre_stage_en,
xin => xin_pre,
yin => yin_pre,
zin => zin_pre,
xout => xout_pre,
yout => yout_pre,
zout => zout_pre,
ready => pre_stage_ready,
valid => pre_stage_valid,
cordic_mode => cordic_mode
);
Inst_cordic_stage: cordic_stage
GENERIC MAP
(
nbits => stage_nbits,
nbits_int => stage_nbits_int,
nbits_out => stage_nbits,
nbits_int_out => stage_nbits_int,
reg_mode => reg_mode_in
)
PORT MAP
(
rst => rst,
clk => clk,
ce => proc_stage_en,
xin => xin_stage,
yin => yin_stage,
zin => zin_stage,
xout => xout_stage,
yout => yout_stage,
zout => zout_stage,
coeff => rom_data,
dir_cw => dir_cw,
stage_count => count,
ready => proc_stage_ready,
valid => proc_stage_valid,
cordic_mode => cordic_mode
);
Inst_cordic_stage_post: cordic_stage_post
GENERIC MAP
(
nbits => stage_nbits,
nbits_int => stage_nbits_int,
nbits_out => nbits_out,
nbits_int_out => nbits_out_int,
reg_mode => reg_mode_in
)
PORT MAP
(
rst => rst,
clk => clk,
ce => post_stage_en,
xin => xin_post,
yin => yin_post,
zin => zin_post,
xout => xout_post,
yout => yout_post,
zout => zout_post,
ready => post_stage_ready,
valid => post_stage_valid,
cordic_mode => cordic_mode
);
Inst_rom_arctan: rom_arctan
GENERIC MAP
(
nbits => coeff_nbits,
nbits_int => coeff_nbits_int
)
PORT MAP
(
addr => rom_addr,
dout => rom_data
);
--------------------------------------------------------------------
end Behavioral;