]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-dad.git/blob - hw/lx_adc_if.vhd
fixed FPGA buggs, added support for single shot measurement (fpga does 2 measurements...
[fpga/lx-cpu1/lx-dad.git] / hw / lx_adc_if.vhd
1 library ieee;\r
2 use ieee.std_logic_1164.all;\r
3 use ieee.numeric_std.all;\r
4 use work.util_pkg.all;\r
5 use work.lx_dad_pkg.all;\r
6 \r
7 entity lx_adc_if is \r
8 generic\r
9 (\r
10         adc_res         : positive := 18;\r
11         conv_cycles     : integer := 85\r
12 );\r
13 port\r
14 (\r
15         clk_i   : in std_logic;\r
16         rst_i   : in std_logic;\r
17         conv_start      : in std_logic;\r
18         \r
19         sck_o   : out std_logic;\r
20         cnv_o   : out std_logic;\r
21         data_o  : out std_logic_vector((adc_res-1) downto 0);\r
22         drdy_o  : out std_logic;\r
23                 \r
24         sck_i   : in std_logic;\r
25         SDI             : in std_logic\r
26 );\r
27 end lx_adc_if;\r
28 \r
29 architecture rtl of lx_adc_if is\r
30         signal received         : std_logic_vector((adc_res-1) downto 0);\r
31         signal ckout            : std_logic;\r
32         --signal active_bit_t   integer range 0 to (adc_res-1);\r
33         signal active_bit_r     : integer range 0 to (adc_res-1);\r
34          \r
35         signal conv_cnter       : integer range 0 to conv_cycles;\r
36         \r
37         type    states_i        is (conv, reading, iddle);\r
38         signal  state_i         : states_i;\r
39         signal  convert         : std_logic;\r
40 \r
41         signal drdy_i           : std_logic;\r
42         signal drdy_i_last      : std_logic;\r
43         signal drdy_i_last_last : std_logic;\r
44         \r
45         attribute REGISTER_DUPLICATION : string;\r
46         attribute REGISTER_DUPLICATION of received : signal is "NO";\r
47         attribute REGISTER_DUPLICATION of drdy_i : signal is "NO";\r
48         attribute REGISTER_DUPLICATION of drdy_i_last : signal is "NO";\r
49         attribute REGISTER_DUPLICATION of drdy_i_last_last : signal is "NO";\r
50         \r
51 begin\r
52 \r
53         data_sync: process(clk_i,rst_i)\r
54         begin\r
55                 if rst_i = '1' then\r
56                         drdy_o <= '0';\r
57                         drdy_i_last <= '0';\r
58                         drdy_i_last_last <= '0';\r
59                         data_o <= (others => '0');\r
60                 elsif rising_edge(clk_i) then\r
61                         drdy_i_last_last <= drdy_i_last;\r
62                         drdy_i_last <= drdy_i;\r
63                         drdy_o <= '0';\r
64                         if drdy_i = '1' and drdy_i_last = '1' and drdy_i_last_last = '0' then\r
65                                 data_o <= received;\r
66                                 drdy_o <= '1';\r
67                         end if;\r
68                 end if;\r
69         end process;\r
70 \r
71         adc_readout: process(sck_i,rst_i)\r
72         begin\r
73                 if rst_i= '1' then\r
74                         active_bit_r <= 17;\r
75                         drdy_i <= '0';\r
76                         received <= (others => '0');\r
77                 elsif rising_edge(sck_i) then\r
78                         if convert = '1' and active_bit_r = 17 then\r
79                                 received(active_bit_r) <= SDI;\r
80                                 active_bit_r <= 16;\r
81                                 drdy_i <= '0';\r
82                         elsif active_bit_r /= 17 then\r
83                                 if active_bit_r = 0 then\r
84                                         drdy_i <= '1';\r
85                                         active_bit_r <= 17;\r
86                                 else\r
87                                         active_bit_r <= active_bit_r - 1;\r
88                                 end if;\r
89                                 received(active_bit_r) <= SDI;\r
90                         end if;\r
91                 end if;\r
92         end process;\r
93 \r
94         sck_o <= ckout;\r
95         adc_control: process(clk_i, rst_i)\r
96         begin   \r
97                 if rst_i = '1' then\r
98                         ckout <= '0';\r
99                         conv_cnter <= 0;\r
100                 elsif rising_edge(clk_i) then\r
101                         case state_i is\r
102                         when iddle =>\r
103                                 if conv_start = '1' then\r
104                                         state_i <= conv;\r
105                                         cnv_o <= '1';\r
106                                         convert <= '1';\r
107                                 end if;\r
108                         when conv =>\r
109                                 if conv_cnter = (conv_cycles - 1) then\r
110                                         conv_cnter <= 0;\r
111                                         state_i <= reading;\r
112                                 else\r
113                                         conv_cnter <= conv_cnter + 1;\r
114                                 end if;\r
115                         when reading =>\r
116                                 if conv_cnter < (adc_res) then\r
117                                         if ckout = '1' then\r
118                                                 conv_cnter <= conv_cnter + 1;\r
119                                         end if;\r
120                                         ckout <= not ckout;\r
121                                 else\r
122                                         state_i <= iddle;\r
123                                         conv_cnter <= 0;\r
124                                         cnv_o <= '0';\r
125                                         convert <= '0';\r
126                                 end if;\r
127                         end case;\r
128                 end if;\r
129         end process;\r
130 end architecture;\r
131         \r
132                 \r
133                 \r
134                 \r
135         \r