library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.lx_dad_pkg.all; entity clockgen is port ( -- inputs clk_i : in std_logic; reset_i : in std_logic; sck_i : in std_logic; SDI : in std_logic; -- outputs phi_1 : out std_logic; phi_2 : out std_logic; phi_st : out std_logic; ph_rst : out std_logic; -- LED : out std_logic; sck_o : out std_logic; cnv_o : out std_logic; mem_o : out std_logic_vector(31 downto 0); --memory related outputs addr_o : out std_logic_vector(10 downto 0); bls_o : out std_logic_vector(3 downto 0); ce_o : out std_logic; -- mem related inputs addr_i : in std_logic_vector(3 downto 0); data_i : in std_logic_vector(31 downto 0); ce_i : in std_logic; bls_i : in std_logic_vector(3 downto 0); data_o : out std_logic_vector(31 downto 0) ); end clockgen; architecture rtl of clockgen is --constant CLK_MASTER_FREQ: unsigned := 50000000; constant pixel_max: integer := 2047; signal cntra : unsigned(31 downto 0) := (others => '0'); signal pixel : integer range 0 to pixel_max; signal spd_cntr : integer range 0 to 3; signal spd_timer : integer range 0 to 255; signal cntrb : unsigned(31 downto 0) := (others => '0'); signal bank : std_logic; signal run_readout : std_logic; signal conv_start : std_logic; signal adc_data_i : std_logic_vector(17 downto 0); signal adc_drdy_i : std_logic; signal run_single : std_logic; signal run_single_last : std_logic; signal run_single_i : std_logic; signal finished : std_logic:='0'; signal finished_i : std_logic:='0'; signal stability_m : std_logic; type states_i is (i0, i1, i2, i3, i4, i5, i6, i7, i8, iddle); signal state_i : states_i; type meas_states is (normal, multi_per_pixel, leakage); signal state_meas : meas_states; signal t1 : unsigned(31 downto 0); signal t2 : unsigned(31 downto 0); signal t3 : unsigned(31 downto 0); signal t4 : unsigned(31 downto 0); signal t5 : unsigned(31 downto 0); signal t6 : unsigned(31 downto 0); signal t7 : unsigned(31 downto 0); signal t8 : unsigned(31 downto 0); signal t9 : unsigned(31 downto 0) ; signal pixel_last : integer range 0 to pixel_max; signal pixel_cnt : integer range 0 to pixel_max; signal pixel_addr : integer range 0 to pixel_max; signal store_samples_s : std_logic; signal sync_multi_s : std_logic; signal alive_cntr : integer range 0 to 24999999:=0; signal LED_latch : std_logic:='1'; begin snsor_adc_interface:lx_adc_if generic map ( adc_res => 18, conv_cycles => 85 ) port map ( clk_i => clk_i, rst_i => reset_i, conv_start => conv_start, sck_o => sck_o, cnv_o => cnv_o, data_o => adc_data_i, drdy_o => adc_drdy_i, sck_i => sck_i, SDI => sdi ); -- adc_read : process(reset_i,clk_i) -- begin -- if reset_i = '1' then -- elsif rising_edge(clk_i) then -- if adc_drdy_i = '1' and pixel < 1025 then --mem_o <= std_logic_vector(resize(unsigned(adc_data_i), mem_o'length)); -- mem_o <= std_logic_vector(to_unsigned((pixel),32)); -- addr_o <= bank & std_logic_vector(to_unsigned((pixel),10)); -- bls_o <= "1111"; -- ce_o <= '1'; -- end if; -- end if; -- end process; interf : process(reset_i,clk_i) begin if reset_i = '1' then -- set default timing t1 <= "00000000000000000000000000000110"; --6 t2 <= "00000000000000000000001111101000"; --9 t3 <= "00000000000000000000010001111101"; --1149 t4 <= "00000000000000000000001111101000"; --14 t5 <= "00000000000000000000000000000110"; --6 t6 <= "00000000000000000000001001010111"; --599 t7 <= "00000000000000000000001010010010"; --658 t8 <= "00000000000000000001001100010000"; --4880 t9 <= "00000000000000000000000111110011"; pixel_last <= 1023; data_o <= (others => '0'); run_single <= '0'; run_readout <= '0'; elsif rising_edge(clk_i) then run_single <= '0'; if finished = '1' then run_readout <= '0'; finished_i <= '1'; end if; if ce_i = '1' and bls_i /= "0000" then if addr_i = "0000" then run_readout <= data_i(0); --start/stop the readout if data_i(1) = '1' then run_readout <= '1'; run_single <= '1'; end if; if data_i(3) = '1' then state_meas <= normal; elsif data_i(4) = '1' then state_meas <= leakage; elsif data_i(5) = '1' then state_meas <= multi_per_pixel; end if; elsif addr_i = "0001" then t1 <= unsigned(data_i); elsif addr_i = "0010" then t2 <= unsigned(data_i); elsif addr_i = "0011" then t3 <= unsigned(data_i); elsif addr_i = "0100" then t4 <= unsigned(data_i); elsif addr_i = "0101" then t5 <= unsigned(data_i); elsif addr_i = "0110" then t6 <= unsigned(data_i); elsif addr_i <= "0111" then t7 <= unsigned(data_i); elsif addr_i <= "1000" then t8 <= unsigned(data_i); elsif addr_i <= "1001" then t9 <= unsigned(data_i); elsif addr_i <= "1100" then pixel_last <= to_integer(unsigned(data_i)); end if; end if; if ce_i = '1' then if addr_i = "0000" then data_o <= (others => '0'); data_o(2) <= not bank; data_o(6) <= finished_i; data_o(0) <= run_readout; if state_meas = leakage then data_o(4) <= '1'; elsif state_meas = normal then data_o(3) <= '1'; elsif state_meas = multi_per_pixel then data_o(5) <= '1'; end if; finished_i <= '0'; elsif addr_i = "0001" then data_o <= std_logic_vector(t1); elsif addr_i = "0010" then data_o <= std_logic_vector(t2); elsif addr_i = "0011" then data_o <= std_logic_vector(t3); elsif addr_i = "0100" then data_o <= std_logic_vector(t4); elsif addr_i = "0101" then data_o <= std_logic_vector(t5); elsif addr_i = "0110" then data_o <= std_logic_vector(t6); elsif addr_i = "0111" then data_o <= std_logic_vector(t7); elsif addr_i = "1000" then data_o <= std_logic_vector(t8); elsif addr_i = "1001" then data_o <= std_logic_vector(t9); elsif addr_i = "1100" then data_o <= std_logic_vector(to_unsigned(pixel_last, 32)); else data_o <= "00000000000000000000000000000000"; end if; end if; end if; end process; proc : process(clk_i, reset_i) begin if reset_i='1' then state_i <= iddle; cntra <= (others => '0'); pixel <= 0; phi_st <= '0'; bank <= '0'; ce_o <= '0'; bls_o <= "0000"; spd_cntr <= 3; pixel_cnt <= 1023; pixel_addr <= 0; conv_start <= '0'; store_samples_s <= '0'; sync_multi_s <= '0'; elsif rising_edge(clk_i) then ce_o <= '0'; bls_o <= "0000"; conv_start <= '0'; sync_multi_s <= '0'; finished <= '0'; if run_single = '1' then run_single_i <= '1'; end if; if run_readout = '1' then cntrb <= cntrb + 1; else cntrb <= (others => '0'); end if; if (state_meas = multi_per_pixel) and (store_samples_s = '1') then if sync_multi_s = '1' then spd_timer <= 125 - 1; else if spd_timer > 0 then spd_timer <= spd_timer - 1; else spd_timer <= 125 - 1; conv_start <= '1'; end if; end if; end if; if adc_drdy_i = '1' and store_samples_s = '1' then mem_o <= "00000000000000" & adc_data_i; addr_o <= bank & std_logic_vector(to_unsigned((pixel_addr),addr_o'length -1)); bls_o <= "1111"; ce_o <= '1'; if pixel_addr /= (2 ** (addr_o'length - 1)) - 1 then pixel_addr <= pixel_addr + 1; else store_samples_s <= '0'; end if; end if; if cntra = 0 then case state_meas is when leakage => case state_i is when i0 => if pixel > 1023 then bank <= not bank; state_i <= iddle; if run_single_i = '1' and run_single_last = '0' then run_single_last <= '1'; end if; if run_single_i = '1' and run_single_last = '1' then run_single_i <= '0'; run_single_last <= '0'; finished <= '1'; end if; pixel_addr <= 0; store_samples_s <= '1'; end if; pixel <= pixel +1; conv_start <= '1'; cntra <= t9; when others => pixel <= 0; cntra <= (others => '0'); ph_rst <= '0'; if cntrb > t8 then state_i <= i0; cntra <= t9; cntrb <= (others => '0'); ph_rst <= '1'; end if; end case; when normal | multi_per_pixel => case state_i is when i0 => state_i <= i1; cntra<=t1; phi_2 <= '0'; when i1 => state_i <= i2; phi_1 <= '1'; cntra<=t2; when i2 => state_i <= i3; ph_rst <= '0'; cntra<=t3; when i3 => ph_rst <= '1'; phi_st <= '0'; state_i <= i4; cntra<=t4; when i4 => phi_1 <= '0'; if pixel_cnt = 0 then bank <= not bank; state_i <= iddle; cntra <= (others => '0'); if run_single_i = '1' and run_single_last = '0' then run_single_last <= '1'; end if; if run_single_i = '1' and run_single_last = '1' then run_single_i <= '0'; run_single_last <= '0'; finished <= '1'; end if; else pixel_cnt <= pixel_cnt - 1; state_i <= i5; cntra<=t5; end if; when i5 => phi_2 <= '1'; state_i <= i6; cntra <= t6; when i6 => state_i <= i0; -- start the readout from adc cntra <= t7; if run_readout = '1' then if pixel > 0 then if state_meas = normal then conv_start <= '1'; else sync_multi_s <= '1'; end if; end if; if pixel = 0 then pixel_addr <= 0; store_samples_s <= '1'; phi_st <= '1'; end if; end if; pixel <= pixel + 1; when others => if cntrb > t8 then cntrb <= (others => '0'); state_i <= i1; end if; pixel <= 0; phi_1 <= '0'; phi_2 <= '0'; ph_rst <= '0'; cntra <= (others => '0'); pixel_cnt <= pixel_last; end case; when others => pixel_cnt <= 0; end case; else cntra <= cntra - 1; end if; end if; end process; alive : process(clk_i,reset_i) begin if reset_i = '1' then alive_cntr <= 0; --LED <= '1'; LED_latch<= '1'; elsif rising_edge(clk_i) then alive_cntr<=alive_cntr+1; if alive_cntr = 24999999 then LED_latch <= not LED_latch; -- LED <= LED_latch; alive_cntr<=0; end if; end if; end process; end architecture;