]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-dad.git/commitdiff
Re-implemented ADC start logic to enable multiple samples per pixel mode.
authorPavel Pisa <pisa@cmp.felk.cvut.cz>
Tue, 3 Nov 2015 19:59:45 +0000 (20:59 +0100)
committerPavel Pisa <pisa@cmp.felk.cvut.cz>
Tue, 3 Nov 2015 19:59:45 +0000 (20:59 +0100)
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
hw/clockgen.vhd
hw/lx_adc_if.vhd
hw/lx_dad_top.vhd

index e7fbf69bb7212b787a044a45d07b9730da29fa81..18373d2172720603d7d866719e11f6d2606c3258 100644 (file)
@@ -4,7 +4,7 @@ use ieee.numeric_std.all;
 
 use work.lx_dad_pkg.all;
 
-entity clockgen is 
+entity clockgen is
        port
        (
                -- inputs
@@ -20,10 +20,10 @@ entity clockgen is
        --      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);
@@ -36,22 +36,25 @@ entity clockgen is
                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 CLK_MASTER_FREQ: unsigned := 50000000;
+
+       constant pixel_max: integer := 2047;
+
        signal cntra    : unsigned(31 downto 0) := (others => '0');
-       signal pixel            : integer range 0 to 8191;
+       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);
@@ -62,10 +65,10 @@ architecture rtl of clockgen is
        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, ispd, ispdb);
+
+       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;
 
@@ -76,15 +79,20 @@ architecture rtl of clockgen is
        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  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
        (
@@ -103,7 +111,7 @@ begin
                sck_i           => sck_i,
                SDI                     => sdi
        );
-       
+
        -- adc_read : process(reset_i,clk_i)
        -- begin
                -- if reset_i = '1' then
@@ -117,11 +125,11 @@ begin
                        -- end if;
                -- end if;
        -- end process;
-       
+
        interf : process(reset_i,clk_i)
        begin
                if reset_i = '1' then                   -- set default timing
-                       t1 <= "00000000000000000000000000000110";       --6 
+                       t1 <= "00000000000000000000000000000110";       --6
                        t2 <= "00000000000000000000001111101000";       --9
                        t3 <= "00000000000000000000010001111101";       --1149
                        t4 <= "00000000000000000000001111101000";       --14
@@ -130,12 +138,13 @@ begin
                        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 
+                       if finished = '1' then
                                run_readout <= '0';
                                finished_i <= '1';
                        end if;
@@ -144,12 +153,14 @@ begin
                                        run_readout <= data_i(0);       --start/stop the readout
                                        if data_i(1) = '1'  then
                                                run_readout <= '1';
-                                               run_single <= '1'; 
+                                               run_single <= '1';
                                        end if;
                                        if data_i(3) = '1' then
                                                state_meas <= normal;
-                                       elsif data_i(4) = '1' then 
+                                       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);
@@ -157,7 +168,7 @@ begin
                                        t2 <= unsigned(data_i);
                                elsif addr_i = "0011" then
                                        t3 <= unsigned(data_i);
-                               elsif addr_i = "0100" then      
+                               elsif addr_i = "0100" then
                                        t4 <= unsigned(data_i);
                                elsif addr_i = "0101" then
                                        t5 <= unsigned(data_i);
@@ -169,6 +180,8 @@ begin
                                        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
@@ -203,7 +216,11 @@ begin
                                        data_o <= std_logic_vector(t8);
                                elsif addr_i = "1001" then
                                        data_o <= std_logic_vector(t9);
-                               end if; 
+                               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;
@@ -211,8 +228,8 @@ begin
 
        proc : process(clk_i, reset_i)
        begin
-               if reset_i='1' then 
-                       state_i <= i0;
+               if reset_i='1' then
+                       state_i <= iddle;
                        cntra <= (others => '0');
                        pixel <= 0;
                        phi_st <= '0';
@@ -220,10 +237,16 @@ begin
                        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';
@@ -233,21 +256,37 @@ begin
                        else
                                cntrb <= (others => '0');
                        end if;
-               --      if start_readout = '1' then
-               --              pixel <= 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 > 0 then
-                                                       mem_o <= "00000000000000"&adc_data_i;
-                                                       --mem_o <= std_logic_vector(to_unsigned((pixel-1),32));
-                                                       addr_o <= bank & std_logic_vector(to_unsigned((pixel-1),10));
-                                                       bls_o <= "1111";
-                                                       ce_o <= '1';
-                                               end if;
                                                if pixel > 1023 then
                                                        bank <= not bank;
                                                        state_i <= iddle;
@@ -259,6 +298,8 @@ begin
                                                                run_single_last <= '0';
                                                                finished <= '1';
                                                        end if;
+                                                       pixel_addr <= 0;
+                                                       store_samples_s <= '1';
                                                end if;
                                                pixel <= pixel +1;
                                                conv_start <= '1';
@@ -277,15 +318,6 @@ begin
                                when normal | multi_per_pixel =>
                                        case state_i is
                                        when i0 =>
-                                               if state_meas = normal then
-                                                       if pixel > 0 and pixel < 1025 then
-                                                               mem_o <= "00000000000000"&adc_data_i;
-                                                               --mem_o <= std_logic_vector(to_unsigned((pixel-1),32));
-                                                               addr_o <= bank & std_logic_vector(to_unsigned((pixel-1),10));
-                                                               bls_o <= "1111";
-                                                               ce_o <= '1';
-                                                       end if;
-                                               end if;
                                                state_i <= i1;
                                                cntra<=t1;
                                                phi_2 <= '0';
@@ -304,79 +336,42 @@ begin
                                                cntra<=t4;
                                        when i4 =>
                                                phi_1 <= '0';
-                                               if state_meas = normal then
-                                                       if pixel = 1026 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
-                                                               state_i <= i5;
-                                                               cntra<=t5;
+                                               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;
-                                               else
-                                                       if pixel > 4095 then
-                                                               state_i <= iddle;
-                                                               bank <= '1';
-                                                               cntra <= (others => '0');
-                                                               if run_readout = '1' and run_single_last = '0' then
-                                                                       run_single_last <= '1';
-                                                               end if;
-                                                               if run_readout = '1' and run_single_last = '1' then
-                                                                       run_single_i <= '0';
-                                                                       run_single_last <= '0';
-                                                                       finished <= '1';
-                                                               end if;
-                                                       else
-                                                               state_i <= i5;
-                                                               cntra<=t5;
+                                                       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';
-                                               if state_meas = normal then
-                                                       state_i <= i6;
-                                                       cntra <= t6;
-                                               else
-                                                       state_i <= ispd;
-                                               end if;
-                                       when ispd =>
-                                               conv_start <= '1';
-                                               cntra <= t9 - to_unsigned(75,cntra'length);
-                                               state_i <= ispdb;
-                                       when ispdb =>
-                                               if pixel < 2049 then
-                                                       conv_start <= '0';
-                                                       cntra <= to_unsigned(74,cntra'length);
-                                                       mem_o <= "00000000000000"&adc_data_i;
-                                                       addr_o <= std_logic_vector(to_unsigned((pixel-1),11));
-                                                       bls_o <= "1111";
-                                                       ce_o <= '1';
-                                               end if;
-                                               pixel <= pixel +1;
-                                               if spd_cntr = 0 then
-                                                       spd_cntr <= 3;
-                                                       state_i <= i0;
-                                               else
-                                                       spd_cntr <= spd_cntr - 1;
-                                                       state_i <= ispd;
-                                               end if;
+                                               state_i <= i6;
+                                               cntra <= t6;
                                        when i6 =>
-                                               state_i <= i0;  
+                                               state_i <= i0;
                                                -- start the readout from adc
                                                cntra <= t7;
                                                if run_readout = '1' then
                                                        if pixel > 0 then
-                                                               conv_start <= '1';
+                                                               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;
@@ -391,14 +386,16 @@ begin
                                                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 if;
-       end process;    
+       end process;
 
        alive : process(clk_i,reset_i)
        begin
@@ -415,4 +412,4 @@ begin
                        end if;
                end if;
        end process;
-end architecture;              
+end architecture;
index 1983ca29b5b009ded6e4a44d695cdd0bdf6d9d63..e9d9fd02e2e6ac54d000f9c6a82db63260e8d416 100644 (file)
@@ -22,7 +22,7 @@ port
        drdy_o  : out std_logic;\r
                \r
        sck_i   : in std_logic;\r
-       SDI             : in std_logic\r
+       SDI     : in std_logic\r
 );\r
 end lx_adc_if;\r
 \r
@@ -37,6 +37,9 @@ architecture rtl of lx_adc_if is
        type    states_i        is (conv, reading, iddle);\r
        signal  state_i         : states_i;\r
        signal  convert         : std_logic;\r
+       signal  odd_even        : std_logic;\r
+       signal  odd_even_r      : std_logic;\r
+       signal  odd_even_last   : std_logic;\r
 \r
        signal drdy_i           : std_logic;\r
        signal drdy_i_last      : std_logic;\r
@@ -47,6 +50,8 @@ architecture rtl of lx_adc_if is
        attribute REGISTER_DUPLICATION of drdy_i : signal is "NO";\r
        attribute REGISTER_DUPLICATION of drdy_i_last : signal is "NO";\r
        attribute REGISTER_DUPLICATION of drdy_i_last_last : signal is "NO";\r
+       attribute REGISTER_DUPLICATION of odd_even : signal is "NO";\r
+       attribute REGISTER_DUPLICATION of odd_even_r : signal is "NO";\r
        \r
 begin\r
 \r
@@ -57,6 +62,7 @@ begin
                        drdy_i_last <= '0';\r
                        drdy_i_last_last <= '0';\r
                        data_o <= (others => '0');\r
+                       odd_even_r <= '0';\r
                elsif rising_edge(clk_i) then\r
                        drdy_i_last_last <= drdy_i_last;\r
                        drdy_i_last <= drdy_i;\r
@@ -65,6 +71,7 @@ begin
                                data_o <= received;\r
                                drdy_o <= '1';\r
                        end if;\r
+                       odd_even_r <= odd_even;\r
                end if;\r
        end process;\r
 \r
@@ -74,19 +81,22 @@ begin
                        active_bit_r <= 17;\r
                        drdy_i <= '0';\r
                        received <= (others => '0');\r
+                       odd_even_last <= '0';\r
                elsif rising_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
+                       if convert = '1' and ((active_bit_r = adc_res - 1) or\r
+                          (odd_even_last /= odd_even_r)) then\r
+                               received(adc_res - 1) <= SDI;\r
+                               active_bit_r <= adc_res - 2;\r
                                drdy_i <= '0';\r
+                               odd_even_last <= odd_even_r;\r
                        elsif active_bit_r /= 17 then\r
+                               received(active_bit_r) <= SDI;\r
                                if active_bit_r = 0 then\r
                                        drdy_i <= '1';\r
-                                       active_bit_r <= 17;\r
+                                       active_bit_r <= adc_res - 1;\r
                                else\r
                                        active_bit_r <= active_bit_r - 1;\r
                                end if;\r
-                               received(active_bit_r) <= SDI;\r
                        end if;\r
                end if;\r
        end process;\r
@@ -97,6 +107,7 @@ begin
                if rst_i = '1' then\r
                        ckout <= '0';\r
                        conv_cnter <= 0;\r
+                       odd_even <= '0';\r
                elsif rising_edge(clk_i) then\r
                        case state_i is\r
                        when iddle =>\r
@@ -104,6 +115,7 @@ begin
                                        state_i <= conv;\r
                                        cnv_o <= '1';\r
                                        convert <= '1';\r
+                                       odd_even <= not odd_even;\r
                                end if;\r
                        when conv =>\r
                                if conv_cnter = (conv_cycles - 1) then\r
index 7db18c547634aa3c232327d24f3df22f47962c9d..f2f0ebc3ca8be21b503828d0b06700f74e4dc101 100644 (file)
@@ -152,7 +152,7 @@ memory_bus_example: bus_example
 
 
 --Sensor clock generator
-mytest: clockgen
+sensor_if: clockgen
        port map
        (
                clk_i   => clk_50m,