labor-mst/src/feedback_top.vhd
Greek e6b05276d8 Major Rewrite of feedback_loop
Another scaling factor was added and both input signals can now be
independenly scaled. In Single Input Mode only Input 1 is passed to the
output (negated if configured as negative feddback). In double input
mode Input 2 is added/subtracted from Input 1 (in1 +/- in2). The delay
line is only applied to Input 2.
Addsub was removed from the design (all Additions and Subtractions are
directly implemented in VHDL code).
Config signals were latched to follow the data flow path and prevent
glitches on certain events.
Vivado Project updated.
Single Package containing all needed pre-calculated sine arrays.
General Code Cleanup.
2021-03-28 12:32:56 +02:00

295 lines
10 KiB
VHDL

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.typedef_package.all;
entity feedback_top is
port (
--XILLYBUS
xillybus_clk : in std_logic;
fifo_rd_data : out std_logic_vector(DEBUG_FIFO_DATA_WIDTH-1 downto 0);
fifo_ren : in std_logic;
fifo_empty : out std_logic;
mem_addr : in std_logic_vector(CONFIG_MEM_ADDR_WIDTH downto 0);
mem_wr_data : in std_logic_vector(CONFIG_MEM_DATA_WIDTH-1 downto 0);
mem_wen : in std_logic;
mem_full : out std_logic;
--FPGA
clk_in : in std_logic;
areset : in std_logic;
areset_debug : in std_logic;
async_pulse : in std_logic;
astandby : in std_logic;
adc_data_in1 : in std_logic;
adc_data_in2 : in std_logic;
adc_cs_n : out std_logic;
adc_sclk : out std_logic;
dac_data_out : out std_logic;
dac_cs_n : out std_logic;
dac_ldac : out std_logic;
dac_sclk : out std_logic;
--DEBUG
leds : out std_logic_vector(LED_WIDTH-1 downto 0)
);
end entity;
architecture arch of feedback_top is
--*****COMPONENT DECLARATION*****
component clockgen is
generic (
CLKFBOUT_MULT : integer := 41;
CLKIN1_PERIOD : real := 10.000000;
CLKOUT0_DIVIDE : integer := 41;
DIVCLK_DIVIDE : integer := 5
);
port (
clk_in : in std_logic;
clk_out : out std_logic
);
end component;
component synchronizer is
generic (
SYNC_STAGES : integer := 2
);
port (
clk : in std_logic;
input : in std_logic;
output : out std_logic
);
end component;
component feedback_loop is
port (
clk : in std_logic;
reset : in std_logic;
adc_data_in1 : in std_logic; -- PMOD-AD1
adc_data_in2 : in std_logic; -- PMOD-AD1
adc_cs_n : out std_logic; -- PMOD-AD1
adc_sclk : out std_logic; -- PMOD-AD1
dac_data_out : out std_logic; -- PMOD-DA3
dac_cs_n : out std_logic; -- PMOD-DA3
dac_ldac : out std_logic; -- PMOD-DA3
dac_sclk : out std_logic; -- PMOD-DA3
-- DYNAMIC CONFIGURATION
addsub_mode : in std_logic; -- (1=ADD, 0=SUB)
add_input_mux : in std_logic; -- (1=Double Input 2, 0=Single Input)
delay : in std_logic_vector(DELAY_WIDTH-1 downto 0); -- Unsigned delay clock count
factor1 : in std_logic_vector(FACTOR_WIDTH-1 downto 0); -- Q1.x Fixed Point
factor2 : in std_logic_vector(FACTOR_WIDTH-1 downto 0); -- Q1.x Fixed Point
-- DEBUG
reset_debug : in std_logic;
adc_data1_max : out std_logic_vector(ADC_DATA_WIDTH-1 downto 0);
adc_data2_max : out std_logic_vector(ADC_DATA_WIDTH-1 downto 0);
scaler_max : out std_logic_vector(DAC_DATA_WIDTH-1 downto 0);
dac_max : out std_logic_vector(DAC_DATA_WIDTH-1 downto 0)
);
end component;
component feedback_controller is
port (
clk : in std_logic;
reset : in std_logic;
sync_pulse : in std_logic;
mem_addr : out std_logic_vector(CONFIG_MEM_ADDR_WIDTH-1 downto 0);
mem_ren : out std_logic;
mem_data : in std_logic_vector(CONFIG_DATA_WIDTH-1 downto 0);
addsub_mode : out std_logic;
add_input_mux : out std_logic;
delay : out std_logic_vector(DELAY_WIDTH-1 downto 0);
factor1 : out std_logic_vector(FACTOR_WIDTH-1 downto 0);
factor2 : out std_logic_vector(FACTOR_WIDTH-1 downto 0)
);
end component;
component xillybus_link is
generic (
DEBUG_SEND_INTERVAL : integer := 20000000
);
port (
--***XILLYBUS IF***
xillybus_clk : in std_logic;
-- FIFO
fifo_rd_data : out std_logic_vector(DEBUG_FIFO_DATA_WIDTH-1 downto 0);
fifo_ren : in std_logic;
fifo_empty : out std_logic;
-- RAM
mem_addr : in std_logic_vector(CONFIG_MEM_ADDR_WIDTH downto 0);
mem_wr_data : in std_logic_vector(CONFIG_MEM_DATA_WIDTH-1 downto 0);
mem_wen : in std_logic;
--***FPGA IF***
fpga_clk : in std_logic;
reset : in std_logic;
-- Dynamic Configuration
config_addr : in std_logic_vector(CONFIG_MEM_ADDR_WIDTH-1 downto 0);
config_ren : in std_logic;
config_data : out std_logic_vector(CONFIG_DATA_WIDTH-1 downto 0);
-- DEBUG
adc_data1_max : in std_logic_vector(ADC_DATA_WIDTH-1 downto 0);
adc_data2_max : in std_logic_vector(ADC_DATA_WIDTH-1 downto 0);
scaler_max : in std_logic_vector(DAC_DATA_WIDTH-1 downto 0);
dac_max : in std_logic_vector(DAC_DATA_WIDTH-1 downto 0)
);
end component;
--*****SIGNAL DECLARATION*****
signal clk_20, reset, sync_pulse, standby, reset_debug : std_logic := '0';
signal addsub_mode, add_input_mux : std_logic := '0';
signal delay : std_logic_vector(DELAY_WIDTH-1 downto 0) := (others => '0');
signal factor1, factor2 : std_logic_vector(FACTOR_WIDTH-1 downto 0) := (others => '0');
signal adc_data1_max, adc_data2_max : std_logic_vector(ADC_DATA_WIDTH-1 downto 0) := (others => '0');
signal scaler_max, dac_max : std_logic_vector(DAC_DATA_WIDTH-1 downto 0) := (others => '0');
signal config_addr : std_logic_vector(CONFIG_MEM_ADDR_WIDTH-1 downto 0) := (others => '0');
signal config_ren : std_logic := '0';
signal config_data : std_logic_vector(CONFIG_DATA_WIDTH-1 downto 0) := (others => '0');
signal sync_led : std_logic := '0';
begin
clockgen_inst : clockgen
generic map (
CLKFBOUT_MULT => CLKFBOUT_MULT,
CLKIN1_PERIOD => CLKIN1_PERIOD,
CLKOUT0_DIVIDE => CLKOUT0_DIVIDE,
DIVCLK_DIVIDE => DIVCLK_DIVIDE
)
port map(
clk_in => clk_in,
clk_out => clk_20
);
reset_sync : synchronizer
generic map (
SYNC_STAGES => SYNC_STAGES
)
port map (
clk => clk_20,
input => areset,
output => reset
);
sync_pulse_sync : synchronizer
generic map (
SYNC_STAGES => SYNC_STAGES
)
port map (
clk => clk_20,
input => async_pulse,
output => sync_pulse
);
standby_sync : synchronizer
generic map (
SYNC_STAGES => SYNC_STAGES
)
port map (
clk => clk_20,
input => astandby,
output => standby
);
reset_debug_sync : synchronizer
generic map (
SYNC_STAGES => SYNC_STAGES
)
port map (
clk => clk_20,
input => areset_debug,
output => reset_debug
);
feedback_loop_inst : feedback_loop
port map (
clk => clk_20,
reset => reset,
adc_data_in1 => adc_data_in1,
adc_data_in2 => adc_data_in2,
adc_cs_n => adc_cs_n,
adc_sclk => adc_sclk,
dac_data_out => dac_data_out,
dac_cs_n => dac_cs_n,
dac_ldac => dac_ldac,
dac_sclk => dac_sclk,
addsub_mode => addsub_mode,
add_input_mux => add_input_mux,
delay => delay,
factor1 => factor1,
factor2 => factor2,
reset_debug => reset_debug,
adc_data1_max => adc_data1_max,
adc_data2_max => adc_data2_max,
scaler_max => scaler_max,
dac_max => dac_max
);
feedback_controller_inst : feedback_controller
port map (
clk => clk_20,
reset => reset or standby,
sync_pulse => sync_pulse,
mem_addr => config_addr,
mem_ren => config_ren,
mem_data => config_data,
addsub_mode => addsub_mode,
add_input_mux => add_input_mux,
delay => delay,
factor1 => factor1,
factor2 => factor2
);
xillybus_link_inst : xillybus_link
generic map (
DEBUG_SEND_INTERVAL => DEBUG_SEND_INTERVAL
)
port map (
xillybus_clk => xillybus_clk,
fifo_rd_data => fifo_rd_data,
fifo_ren => fifo_ren,
fifo_empty => fifo_empty,
mem_addr => mem_addr,
mem_wr_data => mem_wr_data,
mem_wen => mem_wen,
fpga_clk => clk_20,
reset => reset,
config_addr => config_addr,
config_ren => config_ren,
config_data => config_data,
adc_data1_max => adc_data1_max,
adc_data2_max => adc_data2_max,
scaler_max => scaler_max,
dac_max => dac_max
);
-- Connect standy to mem_full signal, to prevent simutanuoys read/writing on memory
mem_full <= not standby;
-- Connect leds
led_prc : process(all)
begin
leds <= (others => '0');
leds(LED_WIDTH-1) <= standby;
leds(LED_WIDTH-2) <= sync_led;
end process;
sync_debug : process(all)
begin
if rising_edge(clk_20) then
if (reset = '1') then
sync_led <= '0';
else
if (sync_pulse = '1') then
sync_led <= '1';
end if;
end if;
end if;
end process;
end architecture;