]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-dad.git/commitdiff
added sensor clock generation files addn ADC readout and control
authorJan Novotny <caca@caca>
Thu, 30 Apr 2015 12:17:53 +0000 (14:17 +0200)
committerJan Novotny <caca@caca>
Thu, 30 Apr 2015 12:17:53 +0000 (14:17 +0200)
hw/clockgen.vhd [new file with mode: 0644]
hw/lx_adc_if.vhd [new file with mode: 0644]

diff --git a/hw/clockgen.vhd b/hw/clockgen.vhd
new file mode 100644 (file)
index 0000000..84f36be
--- /dev/null
@@ -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 (file)
index 0000000..d11fb4d
--- /dev/null
@@ -0,0 +1,119 @@
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use ieee.numeric_std.all;\r
+use work.util_pkg.all;\r
+use work.lx_dad_pkg.all;\r
+\r
+entity lx_adc_if is \r
+generic\r
+(\r
+       adc_res         : positive := 18;\r
+       conv_cycles     : integer := 85\r
+);\r
+port\r
+(\r
+       clk_i   : in std_logic;\r
+       rst_i   : in std_logic;\r
+       conv_start      : in std_logic;\r
+       \r
+       sck_o   : out std_logic;\r
+       cnv_o   : out std_logic;\r
+       data_o  : out std_logic_vector((adc_res-1) downto 0);\r
+       drdy_o  : out std_logic;\r
+       \r
+       sck_i   : in std_logic;\r
+       SDI             : in std_logic\r
+);\r
+end lx_adc_if;\r
+\r
+architecture rtl of lx_adc_if is\r
+       signal received         : std_logic_vector((adc_res-1) downto 0);\r
+       signal ckout            : std_logic;\r
+       --signal active_bit_t   integer range 0 to (adc_res-1);\r
+       signal active_bit_r     : integer range 0 to (adc_res-1);\r
+       \r
+       signal conv_cnter       : integer range 0 to conv_cycles;\r
+       \r
+       type    states_i        is (conv, reading, iddle);\r
+       signal  state_i         : states_i;\r
+       signal  convert         : std_logic;\r
+\r
+       signal drdy_i           : std_logic;\r
+       signal drdy_i_last      : std_logic;\r
+       \r
+begin\r
+\r
+       data_sync: process\r
+       begin\r
+               wait until clk_i'event and clk_i = '1';\r
+               drdy_i_last <= drdy_i;\r
+               drdy_o <= '0';\r
+               if drdy_i = '1' and drdy_i_last = '0' then\r
+                       data_o <= received;\r
+                       drdy_o <= '1';\r
+               end if;\r
+       end process;\r
+\r
+       adc_readout: process(sck_i, rst_i)\r
+       begin\r
+               if rst_i = '1' then\r
+                       received <= (others => '0');\r
+                       active_bit_r <= 17;\r
+                       drdy_i <= '0';\r
+               elsif falling_edge(sck_i) then\r
+                       if convert = '1' and active_bit_r = 17 then\r
+                               received(active_bit_r) <= SDI;\r
+                               active_bit_r <= 16;\r
+                               drdy_i <= '0';\r
+                       elsif active_bit_r /= 17 then\r
+                               if active_bit_r = 0 then\r
+                                       drdy_i <= '1';\r
+                                       active_bit_r <= 17;\r
+                               end if;\r
+                               received(active_bit_r) <= SDI;\r
+                       end if;\r
+               end if;\r
+       end process;\r
+\r
+       sck_o <= ckout;\r
+       adc_control: process(clk_i, rst_i)\r
+       begin   \r
+               if rst_i = '1' then\r
+                       ckout <= '0';\r
+                       conv_cnter <= 0;\r
+               elsif rising_edge(clk_i) then\r
+                       case state_i is\r
+                       when iddle =>\r
+                               if conv_start = '1' then\r
+                                       state_i <= conv;\r
+                                       cnv_o <= '1';\r
+                                       convert <= '1';\r
+                               end if;\r
+                       when conv =>\r
+                               if conv_cnter = (conv_cycles - 1) then\r
+                                       conv_cnter <= 0;\r
+                                       state_i <= reading;\r
+                               else\r
+                                       conv_cnter <= conv_cnter + 1;\r
+                               end if;\r
+                       when reading =>\r
+                               if conv_cnter < (adc_res-1) then\r
+                                       if ckout = '1' then\r
+                                               conv_cnter <= conv_cnter + 1;\r
+                                       end if;\r
+                                       ckout <= not ckout;\r
+                               else\r
+                                       state_i <= iddle;\r
+                                       conv_cnter <= 0;\r
+                                       cnv_o <= '0';\r
+                                       convert <= '0';\r
+                               end if;\r
+                       end case;\r
+               end if;\r
+       end process;\r
+end architecture;\r
+       \r
+               \r
+               \r
+               \r
+       \r