library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.typedef_package.all; -- Architecture -- --- ---------- ------ ------- --- --->|ADC|--->|Delay Line|--->|Scaler|--->|ADD/SUB|--->|DAC|---> -- --- ---------- ------ ------- --- -- ^ -- --- ----- --- | --->|ADC|-------------------->|Latch|->| | | -- --- ----- |MUX|-- -- GND--->| | -- --- -- Feedback Loop -- This entity implements the feedback loop as defined above. -- In addition to that, this entity latches and provides various max values that can be used for debug -- purposes. entity 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=ADC Input 2, 0=GND) delay : in std_logic_vector(DELAY_WIDTH-1 downto 0); -- unsigned delay clock count factor : in std_logic_vector(FACTOR_WIDTH-1 downto 0); -- 1Q3 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 entity; architecture arch of feedback_loop is --*****SIGNAL DECLARATION***** signal adc_data1, adc_data2 : std_logic_vector(ADC_DATA_WIDTH-1 downto 0) := (others => '0'); signal adc_done : std_logic := '0'; --*****COMPONENT DECLARATION***** component pmod_ad1_ctrl is generic( TRANSFER_CLK_COUNT : integer := 16; DELAY_CLK_CNT : integer := 2; DATA_WIDTH : integer := 12 ); port ( clk : in std_logic; reset : in std_logic; enable : in std_logic; sdata1 : in std_logic; -- PMOD-AD1 sdata2 : in std_logic; -- PMOD-AD1 sclk : out std_logic;-- PMOD-AD1 cs_n : out std_logic;-- PMOD-AD1 data1 : out std_logic_vector(DATA_WIDTH-1 downto 0); data2 : out std_logic_vector(DATA_WIDTH-1 downto 0); done : out std_logic ); end component; component pmod_da3_ctrl is generic( TRANSFER_CLK_COUNT : integer := 16; DATA_WIDTH : integer := 16 ); port ( clk : in std_logic; reset : in std_logic; start : in std_logic; data : in std_logic_vector(DATA_WIDTH-1 downto 0); cs_n : out std_logic;-- PMOD-DA3 sdata : out std_logic;-- PMOD-DA3 ldac : out std_logic;-- PMOD-DA3 sclk : out std_logic;-- PMOD-DA3 done : out std_logic ); end component; component scaler is generic ( DATA_WIDTH : integer := 12; FACTOR_WIDTH : integer := 4; PIPELINE_STAGES : integer := 1 ); port ( clk : in std_logic; data_in : in std_logic_vector(DATA_WIDTH-1 downto 0); factor : in std_logic_vector(FACTOR_WIDTH-1 downto 0); data_out : out std_logic_vector(DATA_WIDTH+FACTOR_WIDTH-1 downto 0) ); end component; component addsub is generic ( PIPELINE_STAGES : integer := 1; DATA_WIDTH : integer := 16 ); port ( clk : in std_logic; reset : in std_logic; mode : in std_logic; cap : in std_logic; A : in std_logic_vector(DATA_WIDTH-1 downto 0); B : in std_logic_vector(DATA_WIDTH-1 downto 0); RES : out std_logic_vector(DATA_WIDTH-1 downto 0) ); end component; component delay_line is generic ( DATA_WIDTH : integer := 12; DELAY_WIDTH : integer := 8; MAX_DELAY : integer := 200 ); port ( clk : in std_logic; reset : in std_logic; delay : in std_logic_vector(DELAY_WIDTH-1 downto 0); data_in : in std_logic_vector(DATA_WIDTH-1 downto 0); data_out : out std_logic_vector(DATA_WIDTH-1 downto 0) ); end component; --*****SIGNAL DECLARATION***** signal delay_out : std_logic_vector(ADC_DATA_WIDTH downto 0) := (others => '0'); signal latch_out : std_logic_vector(ADC_DATA_WIDTH-1 downto 0) := (others => '0'); signal scaler_out, addsub_out, inputA : std_logic_vector(DAC_DATA_WIDTH-1 downto 0) := (others => '0'); signal scaler_done, addsub_done : std_logic := '0'; begin --*****STAGE I***** adc_inst : pmod_ad1_ctrl generic map( TRANSFER_CLK_COUNT => ADC_TRANSFER_CLK_COUNT, DELAY_CLK_CNT => ADC_DELAY_CLK_CNT, DATA_WIDTH => ADC_DATA_WIDTH ) port map( clk => clk, reset => reset, enable => '1', sdata1 => adc_data_in1, sdata2 => adc_data_in2, sclk => adc_sclk, cs_n => adc_cs_n, data1 => adc_data1, data2 => adc_data2, done => adc_done ); --*****STAGE II***** delay_line_inst : delay_line generic map( DATA_WIDTH => ADC_DATA_WIDTH+1, DELAY_WIDTH => DELAY_WIDTH, MAX_DELAY => MAX_DELAY ) port map( clk => clk, reset => reset, delay => delay, data_in => (adc_done & adc_data1), data_out => delay_out ); --*****STAGE III***** scaler_inst : scaler generic map( DATA_WIDTH => ADC_DATA_WIDTH, FACTOR_WIDTH => FACTOR_WIDTH, PIPELINE_STAGES => 1 ) port map( clk => clk, data_in => delay_out(ADC_DATA_WIDTH-1 downto 0), factor => factor, data_out => scaler_out ); process(clk) begin if (rising_edge(clk)) then if (reset = '1') then scaler_done <= '0'; else scaler_done <= delay_out(ADC_DATA_WIDTH); end if; end if; end process; latch : process(clk) begin if (rising_edge(clk)) then if (reset = '1') then latch_out <= (others => '0'); elsif (adc_done) then latch_out <= adc_data2; end if; end if; end process; --*****STAGE IV***** mux: process(all) begin if (add_input_mux = '1') then inputA <= latch_out & "0000"; else inputA <= (others => '0'); end if; end process; addsub_inst : addsub generic map( PIPELINE_STAGES => 1, DATA_WIDTH => DAC_DATA_WIDTH ) port map( clk => clk, reset => reset, mode => addsub_mode, cap => add_input_mux, A => inputA, B => scaler_out, RES => addsub_out ); process(clk) begin if (rising_edge(clk)) then if (reset = '1') then addsub_done <= '0'; else addsub_done <= scaler_done; end if; end if; end process; --*****STAGE V***** dac_inst : pmod_da3_ctrl generic map( TRANSFER_CLK_COUNT => DAC_TRANSFER_CLK_COUNT, DATA_WIDTH => DAC_DATA_WIDTH ) port map( clk => clk, reset => reset, start => addsub_done, data => addsub_out, cs_n => dac_cs_n, sdata => dac_data_out, ldac => dac_ldac, sclk => dac_sclk, done => open ); --*****DEBUG***** process(clk) begin if (rising_edge(clk)) then if (reset = '1' or reset_debug = '1') then adc_data1_max <= (others => '0'); adc_data2_max <= (others => '0'); dac_max <= (others => '0'); scaler_max <= (others => '0'); -- ADC MAX VALUES elsif (adc_done = '1') then if (to_integer(unsigned(adc_data1)) >= to_integer(unsigned(adc_data1_max))) then adc_data1_max <= adc_data1; elsif (to_integer(unsigned(adc_data2)) >= to_integer(unsigned(adc_data2_max))) then adc_data2_max <= adc_data2; end if; -- DAC MAX VALUES elsif (addsub_done = '1') then if (to_integer(unsigned(addsub_out)) >= to_integer(unsigned(dac_max))) then dac_max <= addsub_out; end if; -- SCALER MAX VALUES elsif (scaler_done = '1') then if (to_integer(unsigned(scaler_out)) >= to_integer(unsigned(scaler_max))) then scaler_max <= scaler_out; end if; end if; end if; end process; end architecture;