1 | library IEEE;
|
2 | use IEEE.STD_LOGIC_1164.ALL;
|
3 | use STD.textio.all;
|
4 | use IEEE.std_logic_textio.all;
|
5 |
|
6 | -- Uncomment the following library declaration if using
|
7 | -- arithmetic functions with Signed or Unsigned values
|
8 | use IEEE.NUMERIC_STD.ALL;
|
9 |
|
10 | -- Uncomment the following library declaration if instantiating
|
11 | -- any Xilinx primitives in this code.
|
12 | --library UNISIM;
|
13 | --use UNISIM.VComponents.all;
|
14 |
|
15 | entity ADCModule is
|
16 | Generic(BarSteps : Integer := 8; regBits : Integer := 14);
|
17 | Port ( ad_conv : OUT STD_LOGIC;
|
18 | SPI_SCK : OUT STD_LOGIC;
|
19 | AD_DOUT : IN STD_LOGIC;
|
20 | BarOut : OUT STD_LOGIC_VECTOR(BarSteps-1 downto 0);
|
21 | CLK : IN STD_LOGIC
|
22 | );
|
23 | end ADCModule;
|
24 |
|
25 | architecture Behavioral of ADCModule is
|
26 | CONSTANT AD_CONV_PULSE_LENGTH : INTEGER := 0; --constants defining number of pulsess for each state
|
27 | CONSTANT AD_CONV_WAIT_LENGTH : INTEGER := 0;
|
28 | CONSTANT SPI_CLK_EN_LENGTH : INTEGER := 0;
|
29 | CONSTANT DATA_AC1_LENGTH : INTEGER := 14;
|
30 | CONSTANT DATA_AC_WAIT_LENGTH : INTEGER := 0;
|
31 | CONSTANT DATA_AC2_LENGTH : INTEGER := 14;
|
32 | CONSTANT SPI_CLK_END_LENGTH : INTEGER := 0;
|
33 | CONSTANT SPI_END_WAIT_LENGTH : INTEGER := 3;
|
34 |
|
35 |
|
36 | TYPE states is (ad_conv_pulse_state, ad_conv_wait_state, spi_clk_en_state, data_ac1_state, data_ac_wait_state, data_ac2_state, spi_clk_end_state, spi_end_wait_state);
|
37 | SIGNAL pr_state : states := ad_conv_pulse_state;
|
38 | SIGNAL nx_state: states;
|
39 | SIGNAL spi_clk_en, ad_conv_en : STD_LOGIC; --bits defining the state of SPI_CLK and ad_conv being enabled or disabled. Usage is defined in StateControl process.
|
40 | SIGNAL dataBuffer1, dataBuffer2 : STD_LOGIC_VECTOR(regBits-1 downto 0) := (others => '0');
|
41 | SIGNAL temp : INTEGER := 0;
|
42 |
|
43 |
|
44 |
|
45 | -- states description:
|
46 |
|
47 | -- I defined here a Zero state as the state where both SPI_SCK and ad_conv = 0.
|
48 |
|
49 | -- ad_conv_pulse_state: State defined in Fig. 9-6 by the pulse, whose length is minimum equals 4 ns.
|
50 | -- ad_conv_wait_state: State defined in Fig. 9-6, by the Zero state between the pulse of ad_conv and the first pulse of SPI_SCK.
|
51 | -- spi_clk_en_state: Stated that has SPI_SCK enabled till the beginning of data reception.
|
52 | -- data_ac1_state: State that receives the first bunch of data.
|
53 | -- data_ac_wait_state: Stated defined in Fig. 9-6 by the Zero state between the reception of the two bunches of data.
|
54 | -- data_ac2_state: State that receives the second bunch of data.
|
55 | -- spi_clk_end_state: State that keeps the remenant of SPI_CLK pulses there.
|
56 | -- spi_end_wait_state: A Zero state till the repetition of the whole operation.
|
57 | begin
|
58 | ad_conv <= ad_conv_en;
|
59 | SPI_SCK <= clk AND spi_clk_en;
|
60 | StateContol:
|
61 | process(clk)
|
62 | VARIABLE dataBuffer1_VAR, dataBuffer2_VAR : STD_LOGIC_VECTOR(regBits-1 downto 0) := (others => '0');
|
63 | VARIABLE ad_conv_en_var, spi_clk_en_var : STD_LOGIC := '0';
|
64 | VARIABLE conv_pulse_counter_var : INTEGER := 0; -- counter for every state for timing
|
65 | VARIABLE ad_conv_wait_counter_var : INTEGER := 0;
|
66 | VARIABLE spi_clk_en_counter_var : INTEGER := 0;
|
67 | VARIABLE data_ac1_counter_var : INTEGER := 0;
|
68 | VARIABLE data_ac_wait_counter_var : INTEGER := 0;
|
69 | VARIABLE data_ac2_counter_var : INTEGER := 0;
|
70 | VARIABLE spi_clk_end_counter_var : INTEGER := 0;
|
71 | VARIABLE spi_end_wait_counter_var : INTEGER := 0;
|
72 |
|
73 | variable my_line : line;
|
74 | begin
|
75 |
|
76 | if (rising_edge(clk)) then
|
77 |
|
78 | pr_state <= nx_state;
|
79 |
|
80 |
|
81 | case pr_state is -- in every state, all counters are reset to avoid having latches, but not the one getting counted over in the current state
|
82 | when ad_conv_pulse_state =>
|
83 | ad_conv_wait_counter_var := 0;
|
84 | spi_clk_en_counter_var := 0;
|
85 | data_ac1_counter_var := 0;
|
86 | data_ac_wait_counter_var := 0;
|
87 | data_ac2_counter_var := 0;
|
88 | spi_clk_end_counter_var := 0;
|
89 | spi_end_wait_counter_var := 0;
|
90 |
|
91 | ad_conv_en_var := '1';
|
92 | spi_clk_en_var := '0';
|
93 | if (conv_pulse_counter_var < AD_CONV_PULSE_LENGTH) then
|
94 | --write(my_line, conv_pulse_counter_var);
|
95 | --writeline(output, my_line);
|
96 | conv_pulse_counter_var := conv_pulse_counter_var + 1;
|
97 | --write(my_line, conv_pulse_counter_var);
|
98 | --writeline(output, my_line);
|
99 | else
|
100 | nx_state <= ad_conv_wait_state;
|
101 | end if;
|
102 |
|
103 |
|
104 | when ad_conv_wait_state =>
|
105 | conv_pulse_counter_var := 0;
|
106 | spi_clk_en_counter_var := 0;
|
107 | data_ac1_counter_var := 0;
|
108 | data_ac_wait_counter_var := 0;
|
109 | data_ac2_counter_var := 0;
|
110 | spi_clk_end_counter_var := 0;
|
111 | spi_end_wait_counter_var := 0;
|
112 |
|
113 | ad_conv_en_var := '0';
|
114 | spi_clk_en_var := '0';
|
115 | if (ad_conv_wait_counter_var < AD_CONV_WAIT_LENGTH) then
|
116 | --write(my_line, ad_conv_wait_counter_var);
|
117 | --writeline(output, my_line);
|
118 | ad_conv_wait_counter_var := ad_conv_wait_counter_var + 1;
|
119 | else
|
120 | nx_state <= spi_clk_en_state;
|
121 | end if;
|
122 |
|
123 | --write(my_line, string'("Hello"));
|
124 | --writeline(output, my_line);
|
125 |
|
126 |
|
127 | when spi_clk_en_state =>
|
128 | conv_pulse_counter_var := 0;
|
129 | ad_conv_wait_counter_var := 0;
|
130 | data_ac1_counter_var := 0;
|
131 | data_ac_wait_counter_var := 0;
|
132 | data_ac2_counter_var := 0;
|
133 | spi_clk_end_counter_var := 0;
|
134 | spi_end_wait_counter_var := 0;
|
135 |
|
136 | ad_conv_en_var := '0';
|
137 | spi_clk_en_var := '1';
|
138 | if (spi_clk_en_counter_var < SPI_CLK_EN_LENGTH) then
|
139 | spi_clk_en_counter_var := spi_clk_en_counter_var + 1;
|
140 | else
|
141 | nx_state <= data_ac1_state;
|
142 | end if;
|
143 |
|
144 |
|
145 | when data_ac1_state =>
|
146 | conv_pulse_counter_var := 0;
|
147 | ad_conv_wait_counter_var := 0;
|
148 | spi_clk_en_counter_var := 0;
|
149 | data_ac_wait_counter_var := 0;
|
150 | data_ac2_counter_var := 0;
|
151 | spi_clk_end_counter_var := 0;
|
152 | spi_end_wait_counter_var := 0;
|
153 |
|
154 | ad_conv_en_var := '0';
|
155 | spi_clk_en_var := '1';
|
156 | if (data_ac1_counter_var < DATA_AC1_LENGTH) then
|
157 | --if (data_ac1_counter_var < regBits) then
|
158 | -- write(my_line, data_ac1_counter_var);
|
159 | -- writeline(output, my_line);
|
160 | -- write(my_line, DATA_AC1_LENGTH);
|
161 | -- writeline(output, my_line);
|
162 | -- write(my_line, DATA_AC1_LENGTH);
|
163 | -- writeline(output, my_line);
|
164 | --
|
165 | dataBuffer1_VAR(regBits - data_ac1_counter_var - 1) := AD_DOUT;
|
166 | --end if;
|
167 | data_ac1_counter_var := data_ac1_counter_var + 1;
|
168 | else
|
169 | nx_state <= data_ac_wait_state;
|
170 | end if;
|
171 |
|
172 |
|
173 | when data_ac_wait_state =>
|
174 | conv_pulse_counter_var := 0;
|
175 | ad_conv_wait_counter_var := 0;
|
176 | spi_clk_en_counter_var := 0;
|
177 | data_ac1_counter_var := 0;
|
178 | data_ac2_counter_var := 0;
|
179 | spi_clk_end_counter_var := 0;
|
180 | spi_end_wait_counter_var := 0;
|
181 |
|
182 | ad_conv_en_var := '0';
|
183 | spi_clk_en_var := '1'; --here switch back to 1 during tests
|
184 | if (data_ac_wait_counter_var < DATA_AC_WAIT_LENGTH) then
|
185 | data_ac_wait_counter_var := data_ac_wait_counter_var + 1;
|
186 | else
|
187 | nx_state <= data_ac2_state;
|
188 | end if;
|
189 |
|
190 |
|
191 | when data_ac2_state =>
|
192 | conv_pulse_counter_var := 0;
|
193 | ad_conv_wait_counter_var := 0;
|
194 | spi_clk_en_counter_var := 0;
|
195 | data_ac1_counter_var := 0;
|
196 | data_ac_wait_counter_var := 0;
|
197 | spi_clk_end_counter_var := 0;
|
198 | spi_end_wait_counter_var := 0;
|
199 |
|
200 | ad_conv_en_var := '0';
|
201 | spi_clk_en_var := '1';
|
202 | if (data_ac2_counter_var < DATA_AC2_LENGTH) then
|
203 | --if (data_ac2_counter_var < regBits) then
|
204 | dataBuffer2_VAR(regBits - data_ac2_counter_var - 1) := AD_DOUT;
|
205 | --end if;
|
206 | data_ac2_counter_var := data_ac2_counter_var + 1;
|
207 | else
|
208 | nx_state <= spi_clk_end_state;
|
209 | end if;
|
210 |
|
211 |
|
212 | when spi_clk_end_state =>
|
213 | conv_pulse_counter_var := 0;
|
214 | ad_conv_wait_counter_var := 0;
|
215 | spi_clk_en_counter_var := 0;
|
216 | data_ac1_counter_var := 0;
|
217 | data_ac_wait_counter_var := 0;
|
218 | data_ac2_counter_var := 0;
|
219 | spi_end_wait_counter_var := 0;
|
220 |
|
221 | ad_conv_en_var := '0';
|
222 | spi_clk_en_var := '1';
|
223 | if (spi_clk_end_counter_var < SPI_CLK_END_LENGTH) then
|
224 | spi_clk_end_counter_var := spi_clk_end_counter_var + 1;
|
225 | else
|
226 | nx_state <= spi_end_wait_state;
|
227 | end if;
|
228 |
|
229 | when spi_end_wait_state =>
|
230 | conv_pulse_counter_var := 0;
|
231 | ad_conv_wait_counter_var := 0;
|
232 | spi_clk_en_counter_var := 0;
|
233 | data_ac1_counter_var := 0;
|
234 | data_ac_wait_counter_var := 0;
|
235 | data_ac2_counter_var := 0;
|
236 | spi_clk_end_counter_var := 0;
|
237 |
|
238 | ad_conv_en_var := '0';
|
239 | spi_clk_en_var := '0';
|
240 | if (spi_end_wait_counter_var < SPI_END_WAIT_LENGTH) then
|
241 | spi_end_wait_counter_var := spi_end_wait_counter_var + 1;
|
242 | else
|
243 | nx_state <= ad_conv_pulse_state;
|
244 | end if;
|
245 | end case;
|
246 | temp <= conv_pulse_counter_var;
|
247 | ad_conv_en <= ad_conv_en_var;
|
248 | spi_clk_en <= spi_clk_en_var;
|
249 | if(pr_state = spi_end_wait_state) then
|
250 | dataBuffer1 <= dataBuffer1_VAR;
|
251 | dataBuffer2 <= dataBuffer2_VAR;
|
252 | end if;
|
253 | end if;
|
254 | end process;
|
255 | process(ad_conv_en)
|
256 | VARIABLE barVec : STD_LOGIC_VECTOR(barSteps-1 downto 0) := (others => '0');
|
257 | VARIABLE count : INTEGER := 0;
|
258 | begin
|
259 | if (rising_edge(ad_conv_en)) then
|
260 | For count in 0 to barSteps - 1 loop
|
261 | if (unsigned(dataBuffer1) < (2048*count)) then
|
262 | barVec(count) := '1';
|
263 | else
|
264 | barVec(count) := '0';
|
265 | end if;
|
266 | end loop;
|
267 | BarOut <= barVec;
|
268 | end if;
|
269 | end process;
|
270 | end Behavioral;
|