From 438161fda132c10604f49c16aa81a0fc27021aeb Mon Sep 17 00:00:00 2001 From: Jan Novotny Date: Thu, 30 Apr 2015 14:17:53 +0200 Subject: [PATCH] added sensor clock generation files addn ADC readout and control --- hw/clockgen.vhd | 255 +++++++++++++++++++++++++++++++++++++++++++++++ hw/lx_adc_if.vhd | 119 ++++++++++++++++++++++ 2 files changed, 374 insertions(+) create mode 100644 hw/clockgen.vhd create mode 100644 hw/lx_adc_if.vhd diff --git a/hw/clockgen.vhd b/hw/clockgen.vhd new file mode 100644 index 0000000..84f36be --- /dev/null +++ b/hw/clockgen.vhd @@ -0,0 +1,255 @@ +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(1 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; + + signal cntra : unsigned(15 downto 0) := (others => '0'); + signal pixel : integer range 0 to 1024; + + 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; + + type states_i is (i0, i1, i2, i3, i4, i5, i6, i7, i8); + signal state_i : states_i; + + signal t1 : unsigned(15 downto 0); + signal t2 : unsigned(15 downto 0); + signal t3 : unsigned(15 downto 0); + signal t4 : unsigned(15 downto 0); + signal t5 : unsigned(15 downto 0); + signal t6 : unsigned(15 downto 0); + signal t7 : unsigned(15 downto 0); + + signal t1_i : std_logic_vector(15 downto 0); + signal t2_i : std_logic_vector(15 downto 0); + signal t3_i : std_logic_vector(15 downto 0); + signal t4_i : std_logic_vector(15 downto 0); + signal t5_i : std_logic_vector(15 downto 0); + signal t6_i : std_logic_vector(15 downto 0); + signal t7_i : std_logic_vector(15 downto 0); + + + 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 + begin + wait until clk_i'event and clk_i = '1'; + if reset_i = '1' then + bank <= '0'; + end if; + ce_o <= '0'; + bls_o <= "0000"; + if adc_drdy_i = '1' then + mem_o <= std_logic_vector(resize(unsigned(adc_data_i), mem_o'length)); + addr_o <= bank & std_logic_vector(to_unsigned((pixel-1),10)); + bls_o <= "1111"; + ce_o <= '1'; + if pixel = 1024 then + bank <= not bank; + end if; + end if; + end process; + + interf : process + begin + wait until clk_i'event and clk_i = '1'; + if reset_i = '1' then -- set default timing + t1 <= "0000000000000010"; --2 + t2 <= "0000000000001001"; --9 + t3 <= "0000010001111101"; --1149 + t4 <= "0000000000001110"; --14 + t5 <= "0000000000000010"; --2 + t6 <= "0000001001010111"; --599 + t7 <= "0000001010010010"; --658 + t1_i <= "0000000000000010"; --2 + t2_i <= "0000000000001001"; --9 + t3_i <= "0000010001111101"; --1149 + t4_i <= "0000000000001110"; --14 + t5_i <= "0000000000000010"; --2 + t6_i <= "0000001001010111"; --599 + t7_i <= "0000001010010010"; --658 + data_o <= (others => '0'); + run_readout <= '0'; + elsif ce_i = '1' and bls_i /= "0000" then + if addr_i = "00" then + t1_i <= data_i(15 downto 0); + t2_i <= data_i(31 downto 16); + elsif addr_i = "01" then + t3_i <= data_i(15 downto 0); + t4_i <= data_i(31 downto 16); + elsif addr_i = "10" then + t5_i <= data_i(15 downto 0); + t6_i <= data_i(31 downto 16); + elsif addr_i = "11" then + run_readout <= data_i(30); --start/stop the readout + if data_i(31) = '1' then --update timing constnts + t1 <= unsigned(t1_i); + t2 <= unsigned(t2_i); + t3 <= unsigned(t3_i); + t4 <= unsigned(t4_i); + t5 <= unsigned(t5_i); + t6 <= unsigned(t6_i); + t7 <= unsigned(t7_i); + else + t7_i <= data_i(15 downto 0); + end if; + end if; + end if; + if addr_i = "11" then + data_o <= (others => '0'); + data_o(0) <= not bank; + end if; + end process; + + + proc : process(clk_i, reset_i) + begin + if reset_i='1' then + state_i <= i0; + cntra <= (others => '0'); + pixel <= 0; + phi_st <= '0'; + elsif rising_edge(clk_i) then + conv_start <= '0'; + -- if start_readout = '1' then + -- pixel <= 0; + -- end if; + if cntra = 0 then + 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 <= '1'; + cntra<=t3; + when i3 => + ph_rst <= '0'; + phi_st <= '0'; + state_i <= i4; + cntra<=t4; + when i4 => + phi_1 <= '0'; + state_i <= i5; + cntra<=t5; + when i5 => + phi_2 <= '1'; + state_i <= i6; + cntra <= t6; + when i6 => + state_i <= i0; + conv_start <= '1'; + -- start the readout from adc + cntra <= t7; + if run_readout = '1' and pixel = 0 then + phi_st <= '1'; + end if; + if pixel = 1024 then + pixel <= 0; + else + pixel <= pixel + 1; + end if; + when others => + --set 0 to phi1 + phi_1 <= '1'; + phi_2 <= '0'; + state_i <= i0; + cntra <= (others => '0'); + end case; + --else + -- cntrb <= cntrb + 1; + --end if; + 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; diff --git a/hw/lx_adc_if.vhd b/hw/lx_adc_if.vhd new file mode 100644 index 0000000..d11fb4d --- /dev/null +++ b/hw/lx_adc_if.vhd @@ -0,0 +1,119 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.util_pkg.all; +use work.lx_dad_pkg.all; + +entity lx_adc_if is +generic +( + adc_res : positive := 18; + conv_cycles : integer := 85 +); +port +( + clk_i : in std_logic; + rst_i : in std_logic; + conv_start : in std_logic; + + sck_o : out std_logic; + cnv_o : out std_logic; + data_o : out std_logic_vector((adc_res-1) downto 0); + drdy_o : out std_logic; + + sck_i : in std_logic; + SDI : in std_logic +); +end lx_adc_if; + +architecture rtl of lx_adc_if is + signal received : std_logic_vector((adc_res-1) downto 0); + signal ckout : std_logic; + --signal active_bit_t integer range 0 to (adc_res-1); + signal active_bit_r : integer range 0 to (adc_res-1); + + signal conv_cnter : integer range 0 to conv_cycles; + + type states_i is (conv, reading, iddle); + signal state_i : states_i; + signal convert : std_logic; + + signal drdy_i : std_logic; + signal drdy_i_last : std_logic; + +begin + + data_sync: process + begin + wait until clk_i'event and clk_i = '1'; + drdy_i_last <= drdy_i; + drdy_o <= '0'; + if drdy_i = '1' and drdy_i_last = '0' then + data_o <= received; + drdy_o <= '1'; + end if; + end process; + + adc_readout: process(sck_i, rst_i) + begin + if rst_i = '1' then + received <= (others => '0'); + active_bit_r <= 17; + drdy_i <= '0'; + elsif falling_edge(sck_i) then + if convert = '1' and active_bit_r = 17 then + received(active_bit_r) <= SDI; + active_bit_r <= 16; + drdy_i <= '0'; + elsif active_bit_r /= 17 then + if active_bit_r = 0 then + drdy_i <= '1'; + active_bit_r <= 17; + end if; + received(active_bit_r) <= SDI; + end if; + end if; + end process; + + sck_o <= ckout; + adc_control: process(clk_i, rst_i) + begin + if rst_i = '1' then + ckout <= '0'; + conv_cnter <= 0; + elsif rising_edge(clk_i) then + case state_i is + when iddle => + if conv_start = '1' then + state_i <= conv; + cnv_o <= '1'; + convert <= '1'; + end if; + when conv => + if conv_cnter = (conv_cycles - 1) then + conv_cnter <= 0; + state_i <= reading; + else + conv_cnter <= conv_cnter + 1; + end if; + when reading => + if conv_cnter < (adc_res-1) then + if ckout = '1' then + conv_cnter <= conv_cnter + 1; + end if; + ckout <= not ckout; + else + state_i <= iddle; + conv_cnter <= 0; + cnv_o <= '0'; + convert <= '0'; + end if; + end case; + end if; + end process; +end architecture; + + + + + -- 2.39.2