6. Source HDL
6.1. System VHDL
6.1.1. Top.vhd
--- -- Engineer: Peter Littlewood
-- Create Date: 11:57:23 02/08/2014 -- Module Name: top - Behavioral -- Target Devices: XC7Z020
-- Tool versions: ISE P5.8f -- Dependencies:
---
fft_point_size : integer := 4096 );
Port (
clk_i : in STD_LOGIC;
rst_i : in STD_LOGIC;
bypass_i : in STD_LOGIC;
SW1 : in STD_LOGIC;
SW2 : in STD_LOGIC;
SW3 : in STD_LOGIC;
SW4 : in STD_LOGIC;
start_cancel : in STD_LOGIC;
ifft_oflow : out STD_LOGIC;
ADC_SCK : out STD_LOGIC;
ADC_MISO : in STD_LOGIC;
ADC_CONV : out STD_LOGIC;
DAC_SCK : out STD_LOGIC;
DAC_MOSI : out STD_LOGIC;
DAC_CS : out STD_LOGIC
);
end top;
architecture Behavioral of top is --- -- Signal Declaration -- --- --clk manager signals
signal clk_100mhz : std_logic := '0';
signal clk_40mhz : std_logic := '0';
signal clk_fft : std_logic := '0';
signal mgr_locked : std_logic := '0';
--rst signals
signal rst_aasd : std_logic := '0';
--DAC Signals
signal DAC_SCK_s : std_logic := '0';
signal DAC_CS_s : std_logic := '0';
signal DAC_MOSI_s : std_logic := '0';
--ADC signals
signal adc_data_out : std_logic_vector(15 downto 0) := (OTHERS => '0');
signal adc0_data : signed(12 downto 0) := (OTHERS => '0');
signal ADC_SCK_s : std_logic := '0';
signal ADC_MISO_s : std_logic := '0';
signal ADC_CS_s : std_logic_vector(0 downto 0) := (OTHERS => '0');
--DC Canceller signals
signal dc_offset : signed(12 downto 0) := (OTHERS => '0');
signal adc0_no_dc : signed(12 downto 0) := (OTHERS => '0');
--Hilbert Signals
signal hilbert_data_in : signed(12 downto 0) := (OTHERS => '0');
signal adc0_i : std_logic_vector(12 downto 0) := (OTHERS => '0');
signal adc0_q : std_logic_vector(12 downto 0) := (OTHERS => '0');
--FFT Signals
signal fft_ready_for_data : std_logic := '0';
signal fft_xn_index : std_logic_vector(11 downto 0) := (OTHERS =>
'0');
signal fft_busy : std_logic := '0';
signal fft_early_done : std_logic := '0';
signal fft_done : std_logic := '0';
signal fft_data_valid : std_logic := '0';
signal fft_xk_index : std_logic_vector(11 downto 0) := (OTHERS =>
'0');
signal fft_xk_re_data_out : std_logic_vector(25 downto 0) := (OTHERS => '0');
signal fft_xk_im_data_out : std_logic_vector(25 downto 0) := (OTHERS => '0');
--One Shot Pulse Signals
signal one_shot_pulse : std_logic := '0';
--Rectangular to Polar Signals
signal cordic_polar_magnitude_out : std_logic_vector(25 downto 0) := (OTHERS =>
'0');
signal cordic_polar_phase_out : std_logic_vector(25 downto 0) :=
(OTHERS => '0');
signal cordic_polar_index : std_logic_vector(11 downto 0) :=
(OTHERS => '0');
--Averager Signals
signal average_polar_magnitude_out : std_logic_vector(25 downto 0) := (OTHERS =>
'0');
signal average_polar_index : std_logic_vector(11 downto 0) :=
(OTHERS => '0');
--Corrector Signals
signal start_cancel_debounce : std_logic := '0';
signal correction_polar_magnitude_out : std_logic_vector(25 downto 0) :=
(OTHERS => '0');
signal average_accum :
std_logic_vector(25 downto 0) := (OTHERS => '0');
signal correction_magnitude_index : std_logic_vector(11 downto 0) :=
(OTHERS => '0');
signal cordic_polar_magnitude_out_delay : std_logic_vector(25 downto 0) :=
(OTHERS => '0');
signal cordic_polar_phase_out_delay : std_logic_vector(25 downto 0) :=
(OTHERS => '0');
--Corrected Magnitude Signals
signal corrected_magnitude : std_logic_vector(25 downto 0) :=
(OTHERS => '0');
--Polar to Rectangular Signals
signal cordic_recta_I_out : std_logic_vector(25 downto 0) := (OTHERS => '0');
signal cordic_recta_Q_out : std_logic_vector(25 downto 0) := (OTHERS =>
'0');
signal fft_early_done_delay : std_logic := '0';
--IFFT Signals
signal ifft_ready_for_data : std_logic := '0';
signal ifft_xn_index : std_logic_vector(11 downto 0) := (OTHERS =>
'0');
signal ifft_busy : std_logic := '0';
signal ifft_early_done : std_logic := '0';
signal ifft_done : std_logic := '0';
signal ifft_data_valid : std_logic := '0';
signal ifft_xk_index : std_logic_vector(11 downto 0) := (OTHERS => '0');
signal ifft_xk_re_data_out : std_logic_vector(25 downto 0) := (OTHERS => '0');
signal ifft_xk_im_data_out : std_logic_vector(25 downto 0) := (OTHERS => '0');
--Combined Output Signals
signal iq_data_combined : std_logic_vector(26 downto 0) := (OTHERS => '0');
--Chipscope ICON/ILA
--signal CONTROL0 : std_logic_vector(35 downto 0) := (OTHERS => '0');
--- -- Component Declaration -- --- component FFT_7_1 is PORT (
clk : IN STD_LOGIC;
ce : IN STD_LOGIC;
start : IN STD_LOGIC;
xn_re : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
xn_im : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
fwd_inv : IN STD_LOGIC;
fwd_inv_we : IN STD_LOGIC;
rfd : OUT STD_LOGIC;
xn_index : OUT STD_LOGIC_VECTOR(11 DOWNTO 0);
busy : OUT STD_LOGIC;
edone : OUT STD_LOGIC;
done : OUT STD_LOGIC;
dv : OUT STD_LOGIC;
xk_index : OUT STD_LOGIC_VECTOR(11 DOWNTO 0);
xk_re : OUT STD_LOGIC_VECTOR(25 DOWNTO 0);
xk_im : OUT STD_LOGIC_VECTOR(25 DOWNTO 0) );
end component FFT_7_1;
COMPONENT IFFT_7_1
scale_sch : IN STD_LOGIC_VECTOR(11 DOWNTO 0);
scale_sch_we : IN STD_LOGIC;
rfd : OUT STD_LOGIC;
xn_index : OUT STD_LOGIC_VECTOR(11 DOWNTO 0);
busy : OUT STD_LOGIC;
edone : OUT STD_LOGIC;
done : OUT STD_LOGIC;
dv : OUT STD_LOGIC;
xk_index : OUT STD_LOGIC_VECTOR(11 DOWNTO 0);
xk_re : OUT STD_LOGIC_VECTOR(25 DOWNTO 0);
xk_im : OUT STD_LOGIC_VECTOR(25 DOWNTO 0);
ovflo : OUT STD_LOGIC
ADC_SCK <= ADC_SCK_s;
ADC_MISO_s <= ADC_MISO;
ADC_CONV <= ADC_CS_s(0);
adc0_data <= signed('0' & adc_data_out(11 downto 0));
DAC_SCK <= DAC_SCK_s;
DAC_MOSI <= DAC_MOSI_s;
DAC_CS <= DAC_CS_s;
--- -- Component Instantiation -- ---
CLK_DISTRIBUTION : entity work.clk_mgr Port Map (
CLK_IN1 => clk_i, --100MHz CLK_100 => clk_100mhz, CLK_40 => clk_40mhz, LOCKED => mgr_locked );
fft_clk_gen : entity work.clk_divider Generic Map (
n => 90 )
Port Map (
clk_i => clk_100mhz, rst_n => rst_aasd, clk_out => clk_fft );
oneshot : entity work.oneshot Generic Map (
keep_high => 0 )
Port Map (
clk_i => clk_fft,
rst_i => rst_aasd,
trig_in => mgr_locked, pulse_out => one_shot_pulse );
RST_SYNC : entity work.rst_sync_deassert Port Map (
rst_n => rst_i, --rst_i is a button press, which is logic 1 when pressed clk => clk_100mhz,
rst_aasd => rst_aasd );
--George : entity work.Chipscope -- Port Map (
-- CONTROL0 => CONTROL0 -- );
--Alex : entity work.ILA0 -- Port Map (
--Marty : entity work.ILA1 -- Port Map (
-- CONTROL => CONTROL0, -- CLK => clk_fft, -- TRIG0(0) => clk_40mhz, -- TRIG1(0) => clk_fft,
-- TRIG2 => std_logic_vector(adc0_data), -- TRIG3 => std_logic_vector(adc0_no_dc), -- TRIG4 => std_logic_vector(dc_offset), -- TRIG5 => fft_xk_index,
-- TRIG6 => fft_xk_re_data_out, -- TRIG7 => adc0_i,
-- TRIG8 => adc0_q,
-- TRIG9 => fft_xk_im_data_out, -- TRIG10 => ifft_xk_re_data_out, -- TRIG11 => ifft_xk_im_data_out,
-- TRIG12 => iq_data_combined, -- TRIG13 => cordic_recta_I_out, -- TRIG14 => cordic_recta_Q_out -- );
--Steve : entity work.ILA2 -- Port Map (
-- CONTROL => CONTROL0, -- CLK => clk_fft, -- TRIG0 => adc0_i, -- TRIG1 => adc0_q, -- TRIG2 => fft_xk_index, -- TRIG3 => fft_xk_re_data_out, -- TRIG4 => fft_xk_im_data_out, -- TRIG5 => average_accum, -- TRIG6 => cordic_polar_index,
-- TRIG7 => average_polar_magnitude_out, -- TRIG8 => average_polar_index,
-- TRIG9 => cordic_polar_magnitude_out, -- TRIG10 => corrected_magnitude,
-- TRIG11 => ifft_xn_index, -- TRIG12 => ifft_xk_index, -- TRIG13 => ifft_xk_re_data_out, -- TRIG14 => ifft_xk_im_data_out,
-- TRIG15 => correction_polar_magnitude_out -- );
--Jerry : entity work.ILA4 -- Port Map (
-- CONTROL => CONTROL0, -- CLK => clk_fft, -- TRIG0 => adc0_i, -- TRIG1 => adc0_q,
-- TRIG2 => ifft_xk_re_data_out, -- TRIG3 => ifft_xk_im_data_out, -- TRIG4 => iq_data_combined, -- TRIG5 => ifft_xk_index -- );
tone_gen : entity work.sine_generator Port Map (
clk_spi => clk_100mhz, clk_fft => clk_fft,
ce => mgr_locked, DAC_SCK => DAC_SCK_s, DAC_CS => DAC_CS_s, DAC_MOSI => DAC_MOSI_s );
ADC_SPI : entity work.SPI_Interface Generic Map (
slaves => 1, --number of spi slaves
d_width => adc_data_out'length --data bus width )
Port Map (
clock => clk_40mhz, reset_n => rst_aasd, enable => mgr_locked, cpol => '1', rx_data => adc_data_out );
dc_cancel : entity work.dc_cancellation Generic Map (
data_width => adc0_data'length )
Port Map (
clk => clk_fft,
rst => rst_aasd,
signal_input => adc0_data, signal_output => adc0_no_dc, dc_output => dc_offset );
--Debug MUX to bypass the DC cancellation module, and input the adc data directly to the Hilbert & FFT
with bypass_i select
hilbert_data_in <= adc0_no_dc when '1',
adc0_data when '0',
adc0_data when OTHERS;
Herbert : entity work.hilbert Port Map (
clk => clk_fft, nd => mgr_locked, rfd => OPEN, rdy => OPEN,
din => std_logic_vector(hilbert_data_in), dout_i => adc0_i, --signed
dout_q => adc0_q --signed ); fwd_inv_we => one_shot_pulse,
rfd => fft_ready_for_data, xn_index => fft_xn_index,
busy => fft_busy,
edone => fft_early_done, done => fft_done,
dv => fft_data_valid,
xk_index => fft_xk_index, xk_re => fft_xk_re_data_out, xk_im => fft_xk_im_data_out );
--- -- Convert from rectangular to polar,
-- shift index to sychronize.
--- rect_to_polar : entity work.CORDIC_polar -- Index shift by 34 PORT MAP (
clk => clk_fft,
x_in => fft_xk_re_data_out, y_in => fft_xk_im_data_out,
x_out => cordic_polar_magnitude_out, phase_out => cordic_polar_phase_out );
polar_index : entity work.shift_reg -- Index shift by 34 Generic Map (
data_width => fft_xk_index'length, num_shifts => 34
)
Port Map (
clk_i => clk_fft,
din => fft_xk_index, dout => cordic_polar_index );
--- -- Average the magnitude of the polar signal
--- four_point_avg : entity work.average_IQ -- Index shift by 1
Generic Map (
FFT_point_size => fft_point_size,
data_width => cordic_polar_magnitude_out'length, address_width => log2_float(fft_point_size),
avg_points => 4 )
Port Map (
clk_i => clk_fft,
enable => mgr_locked,
rst_i => rst_aasd,
addr_in => cordic_polar_index,
data_in => cordic_polar_magnitude_out, data_valid => OPEN,
average_out => average_polar_magnitude_out,
addr_out => average_polar_index
);
--- -- calculate correction factor
-- shift the magnitude and phase
--- start_cancellation : entity work.btn_debounce
Port Map (
clk => clk_40mhz,
button_in => start_cancel,
button_db => start_cancel_debounce );
average_correction : entity work.corrector --index shift by 1 Generic Map (
fft_point_size => fft_point_size,
data_width => cordic_polar_magnitude_out'length, address_width => log2_float(fft_point_size)
)
Port Map (
clk_i => clk_fft,
start => start_cancel_debounce, din_index => average_polar_index,
data_in => average_polar_magnitude_out, accum_o => average_accum,
dout_index => correction_magnitude_index,
data_out => correction_polar_magnitude_out );
translate_magnitude_delay : entity work.shift_reg -- Index shift by 2 Generic Map (
data_width => cordic_polar_magnitude_out'length, num_shifts => 2
)
Port Map (
clk_i => clk_fft,
din => cordic_polar_magnitude_out, dout => cordic_polar_magnitude_out_delay );
translate_phase_delay : entity work.shift_reg -- Index shift by 2 Generic Map (
data_width => cordic_polar_phase_out'length, num_shifts => 2
)
Port Map (
clk_i => clk_fft,
din => cordic_polar_phase_out, dout => cordic_polar_phase_out_delay );
---
-- Subtract the correction from the magnitude, pass the phase through ---
corrected_magnitude <= std_logic_vector(abs(signed(cordic_polar_magnitude_out_delay) - signed(correction_polar_magnitude_out)));
--- -- convert back from polar to rectangular
---
polar_to_rect : entity work.CORDIC_rectangular -- Index shift by 34 Port Map (
clk => clk_fft,
x_in => corrected_magnitude, y_in => (OTHERS => '0'),
phase_in => cordic_polar_phase_out_delay, x_out => cordic_recta_I_out,
y_out => cordic_recta_Q_out );
early_done_delay : entity work.shift_reg -- Index shift by 34+34+2 Generic Map (
data_width => 1, num_shifts => 70 )
Port Map (
clk_i => clk_fft,
din(0) => fft_early_done, dout(0) => fft_early_done_delay );
IFFT : IFFT_7_1 Port Map (
clk => clk_fft,
ce => mgr_locked,
start => fft_early_done_delay, xn_re => cordic_recta_I_out, xn_im => cordic_recta_Q_out, fwd_inv => '0',
fwd_inv_we => one_shot_pulse, scale_sch => "101010101010", scale_sch_we => one_shot_pulse,
rfd => ifft_ready_for_data, xn_index => ifft_xn_index,
busy => ifft_busy, edone => ifft_early_done, done => ifft_done, dv => ifft_data_valid, xk_index => ifft_xk_index,
xk_re => ifft_xk_re_data_out, xk_im => ifft_xk_im_data_out, ovflo => ifft_oflow
);
iq_data_combined <=
std_logic_vector(resize(signed(ifft_xk_re_data_out),iq_data_combined'length)+
resize(signed(ifft_xk_im_data_out),iq_data_combined'length));
end Behavioral;