Aktuální adresář: FITkit /
trunk /
fpga /
ctrls /
ide /
ide_pio_ctrl.vhd
1 -- ide_ctrl.vhd : IDE Controler
2 -- Copyright (C) 2009 Brno University of Technology,
3 -- Faculty of Information Technology
4 -- Author(s): Stanislav Sigmund <xsigmu02 AT stud.fit.vutbr.cz>
5 --
6 -- LICENSE TERMS
7 --
8 -- Redistribution and use in source and binary forms, with or without
9 -- modification, are permitted provided that the following conditions
10 -- are met:
11 -- 1. Redistributions of source code must retain the above copyright
12 -- notice, this list of conditions and the following disclaimer.
13 -- 2. Redistributions in binary form must reproduce the above copyright
14 -- notice, this list of conditions and the following disclaimer in
15 -- the documentation and/or other materials provided with the
16 -- distribution.
17 -- 3. All advertising materials mentioning features or use of this software
18 -- or firmware must display the following acknowledgement:
19 --
20 -- This product includes software developed by the University of
21 -- Technology, Faculty of Information Technology, Brno and its
22 -- contributors.
23 --
24 -- 4. Neither the name of the Company nor the names of its contributors
25 -- may be used to endorse or promote products derived from this
26 -- software without specific prior written permission.
27 --
28 -- This software or firmware is provided ``as is'', and any express or implied
29 -- warranties, including, but not limited to, the implied warranties of
30 -- merchantability and fitness for a particular purpose are disclaimed.
31 -- In no event shall the company or contributors be liable for any
32 -- direct, indirect, incidental, special, exemplary, or consequential
33 -- damages (including, but not limited to, procurement of substitute
34 -- goods or services; loss of use, data, or profits; or business
35 -- interruption) however caused and on any theory of liability, whether
36 -- in contract, strict liability, or tort (including negligence or
37 -- otherwise) arising in any way out of the use of this software, even
38 -- if advised of the possibility of such damage.
39 --
40 -- $Id$
41 --
42 --
43
44 library ieee;
45 use ieee.std_logic_1164.all;
46 use ieee.std_logic_arith.all;
47 use ieee.std_logic_unsigned.all;
48
49 entity IDE_ctrl is
50 generic (
51 CLK_PERIOD : integer := 20
52 );
53 port (
54 -- Reset a synchronizace
55 IDE : inout std_logic_vector(45 downto 1) := (others => 'Z');
56 CLK : in std_logic; -- Hodiny radice (min. 4x vetsi, nez hodiny SPI)
57 RST : in std_logic; -- RESET radice
58 INTRQ : out std_logic; -- Zadost o preruseni
59
60 -- Interni rozhrani
61 DI : out std_logic; -- Serial data out (MOSI)
62 DI_REQ : in std_logic; -- DI request
63 DO : in std_logic; -- Serial data in (MISO)
64 DO_VLD : in std_logic; -- DO valid
65 CS : in std_logic -- internal SPI active
66 );
67 end IDE_ctrl;
68
69 architecture basic of IDE_ctrl is
70 -- system casovani, zatim se pocita s PIO 0
71 -- ior/iow ma byt nahozen az za 70 ns po platne adrese
72 constant IORW_VALID : integer := 70 / CLK_PERIOD + 1; -- 4
73 -- ior/iow ma drzet nejmene 290 ns (pro 8-bitovy rezim...)
74 constant IORW_HOLD : integer := 290 / CLK_PERIOD; -- 14
75 -- po shozeni iow maji byt data pritomna jeste min. 30 ns
76 constant IOW_HOLD : integer := 30 / CLK_PERIOD + 1; -- 2
77 -- po shozeni ior jsou data pritomna jeste 5ns - shodime ior pozdeji
78 constant IOR_HOLD : integer := 5 / CLK_PERIOD + 1; -- 1
79
80 constant IO_DELAY : integer := (IORW_HOLD + IORW_VALID + IOW_HOLD + 2);
81 subtype tcntr is integer range 0 to (IORW_HOLD + 1);
82 signal delcntr : tcntr := 0; -- pocitadlo casovani
83 signal delcntr_rst : std_logic := '1'; -- povoleni pocitadla
84 -- datove vodice d15 - d0:
85 type RWstate is (SIdle,SRAVld,SWAVld,SIowHold,SIorHold,SWHold,SRHold);
86 signal pstate : RWstate := SIdle; -- actual state
87 signal nstate : RWstate := SIdle; -- next state
88 signal cmp_avld : std_logic;
89 signal cmp_rwhold : std_logic;
90 signal cmp_rhold : std_logic;
91 signal cmp_whold : std_logic;
92 -- signal cmp_state_ch : std_logic;
93 signal state_ch : std_logic;
94
95
96 signal data : std_logic_vector(15 downto 0) := (others => 'Z');
97 signal data_in : std_logic_vector(16 downto 0);
98 signal data_in_valid : std_logic := '0';
99 signal data_out_buff : std_logic_vector(15 downto 0);
100 signal data_out : std_logic_vector(16 downto 0);
101 signal data_out_ready : std_logic := '0';
102 signal iow : std_logic := '1'; -- zapis na disk
103 signal ior : std_logic := '1'; -- cteni z disku
104 signal read_data : std_logic; -- chceme cist data
105 signal write_data : std_logic; -- chceme zapsat data
106 signal ctrl_out : std_logic_vector(8 downto 0) := (others => '0');
107 signal ctrl_in : std_logic_vector(8 downto 0) := (others => '0');
108 signal ctrl_adc_out : std_logic_vector(8 downto 0) := (others => 'Z');
109 signal ctrl_write : std_logic; -- chceme zapsat ridici bity
110 -- adresace registru v disku, vyvody CS1, CS0, DA2, DA1, DA0
111 signal reg_addr: std_logic_vector(4 downto 0);
112 signal buff_addr: std_logic_vector(4 downto 0);
113 signal reg_adc_addr: std_logic_vector(4 downto 0);
114 signal reg_addr_ready : std_logic := '0';
115
116 component SPI_adc
117 generic (
118 ADDR_WIDTH : integer;
119 DATA_WIDTH : integer;
120 ADDR_OUT_WIDTH : integer;
121 BASE_ADDR : integer;
122 DELAY : integer
123 );
124 port (
125 CLK : in std_logic;
126
127 CS : in std_logic;
128 DO : in std_logic;
129 DO_VLD : in std_logic;
130 DI : out std_logic;
131 DI_REQ : in std_logic;
132
133 ADDR : out std_logic_vector(ADDR_OUT_WIDTH-1 downto 0);
134 DATA_OUT : out std_logic_vector(DATA_WIDTH-1 downto 0);
135 DATA_IN : in std_logic_vector(DATA_WIDTH-1 downto 0);
136
137 WRITE_EN : out std_logic;
138 READ_EN : out std_logic
139 );
140 end component;
141
142 begin
143 -- datove vodice
144
145 idec: for i in 0 to 7 generate
146 IDE(23+2*i) <= data(i);
147 IDE(36-2*i) <= data(i+8);
148 end generate;
149
150 data <= data_out_buff when data_out_ready = '1' else (others => 'Z');
151
152 -- IDE(13) = IORDY
153 INTRQ <= IDE(9);
154
155 IDE(39) <= ctrl_out(0); -- RESET-
156 ctrl_in <= (others => '0');
157 -- zemnici vodice
158 IDE(38) <= '0';IDE(21) <= '0';IDE(18) <= '0';IDE(16) <= '0';
159 IDE(14) <= '0';IDE(10) <= '0';-- IDE(0) <= '0';
160
161 cmp_avld <= '1' when (delcntr = IORW_VALID) else '0';
162 cmp_rwhold <= '1' when (delcntr = IORW_HOLD) else '0';
163 cmp_rhold <= '1' when (delcntr = IOR_HOLD) else '0';
164 cmp_whold <= '1' when (delcntr = IOW_HOLD) else '0';
165 -- cmp_state_ch <= '0' when (pstate = nstate) else '1';
166
167 IDE(2) <= reg_addr(4);IDE(3) <= reg_addr(3);
168 IDE(4) <= reg_addr(2);IDE(7) <= reg_addr(1);
169 IDE(5) <= reg_addr(0); -- cs1, cs0, da2, da1, da0
170 reg_addr <= buff_addr when reg_addr_ready = '1' else "11000";
171
172 IDE(17) <= iow;
173 IDE(15) <= ior;
174
175 -- nezapojene vyvody
176 -- DASP- DIAG- IOCS16- DMACK- CSEL
177 IDE(1) <= 'Z';IDE(6) <= 'Z';IDE(8) <= 'Z';IDE(11) <= 'Z';IDE(12) <= 'Z';
178 -- IORDY DMARQ keypin_20, nic
179 IDE(13) <= 'Z';IDE(19) <= 'Z';IDE(20) <= 'Z';IDE(40) <= 'Z';IDE(41) <= 'Z';
180 -- nic nic nic nic
181 IDE(42) <= 'Z';IDE(43) <= 'Z';IDE(44) <= 'Z';IDE(45) <= 'Z';
182
183 SPI_adc_data: SPI_adc
184 generic map(
185 ADDR_WIDTH => 7,
186 DATA_WIDTH => 17,
187 ADDR_OUT_WIDTH => 5,
188 BASE_ADDR => 16#00#,
189 DELAY => IO_DELAY
190 )
191 port map(
192 CLK => CLK,
193
194 CS => CS,
195 DO => DO,
196 DO_VLD => DO_VLD,
197 DI => DI,
198 DI_REQ => DI_REQ,
199
200 ADDR => reg_adc_addr,
201 DATA_IN => data_in,
202 READ_EN => read_data,
203
204 DATA_OUT => data_out,
205 WRITE_EN => write_data
206 );
207
208 SPI_adc_ctrl: SPI_adc
209 generic map(
210 ADDR_WIDTH => 7,
211 DATA_WIDTH => 9,
212 ADDR_OUT_WIDTH => 1,
213 BASE_ADDR => 16#20#,
214 DELAY => 0
215 )
216 port map(
217 CLK => CLK,
218
219 CS => CS,
220 DO => DO,
221 DO_VLD => DO_VLD,
222 DI => DI,
223 DI_REQ => DI_REQ,
224
225 ADDR => open,
226 DATA_IN => ctrl_in,
227 READ_EN => open,
228
229 DATA_OUT => ctrl_adc_out,
230 WRITE_EN => ctrl_write
231 );
232 data_store: process(CLK)
233 begin
234 if CLK'event and CLK = '1' then
235 if write_data = '1' then
236 data_out_buff <= data_out(15 downto 0);
237 end if;
238 end if;
239 end process;
240
241 data_in_store: process(CLK)
242 begin
243 if CLK'event and CLK = '1' then
244 if data_in_valid = '1' then
245 data_in <= '0' & data;
246 end if;
247 end if;
248 end process;
249
250 addr_store: process(CLK)
251 begin
252 if CLK'event and CLK = '1' then
253 if (read_data = '1') or (write_data = '1') then
254 buff_addr <= reg_adc_addr;
255 end if;
256 end if;
257 end process;
258
259 ctrl_set: process(CLK,RST)
260 begin
261 if RST = '1' then
262 ctrl_out <= (others => '0');
263 elsif CLK'event and CLK = '1' then
264 if ctrl_write = '1' then
265 ctrl_out <= ctrl_adc_out;
266 end if;
267 end if;
268 end process;
269
270 rw_tick: process(CLK,RST)
271 begin
272 if RST = '1' then
273 pstate <= SIdle;
274 elsif CLK'event and CLK = '1' then
275 pstate <= nstate;
276 end if;
277 end process;
278
279 del_tick: process(CLK,delcntr_rst)
280 begin
281 if delcntr_rst = '1' then
282 delcntr <= 0;
283 elsif CLK'event and CLK = '1' then
284 if state_ch = '1' then
285 delcntr <= 0;
286 else
287 delcntr <= delcntr + 1;
288 end if;
289 end if;
290 end process;
291
292 rw_FSA: process(pstate,cmp_avld,cmp_rwhold,cmp_rhold,cmp_whold,read_data,write_data)
293 begin
294 state_ch <= '0';
295 case pstate is
296 --RW Idle
297 when SIdle =>
298 nstate <= SIdle;
299 if read_data = '1' then
300 nstate <= SRAVld;
301 state_ch <= '1';
302 elsif write_data = '1' then
303 nstate <= SWAVld;
304 state_ch <= '1';
305 end if;
306 when SRAVld =>
307 nstate <= SRAVld;
308 if (cmp_avld = '1') then
309 nstate <= SIorHold;
310 state_ch <= '1';
311 end if;
312 when SWAVld =>
313 nstate <= SWAVld;
314 if (cmp_avld = '1') then
315 nstate <= SIowHold;
316 state_ch <= '1';
317 end if;
318 when SIorHold =>
319 nstate <= SIorHold;
320 if (cmp_rwhold = '1') then
321 nstate <= SRHold;
322 state_ch <= '1';
323 end if;
324 when SIowHold =>
325 nstate <= SIowHold;
326 if (cmp_rwhold = '1') then
327 nstate <= SWHold;
328 state_ch <= '1';
329 end if;
330 when SRHold =>
331 nstate <= SRHold;
332 if (cmp_rhold = '1') then
333 nstate <= SIdle;
334 state_ch <= '1';
335 end if;
336 when SWHold =>
337 nstate <= SWHold;
338 if (cmp_whold = '1') then
339 nstate <= SIdle;
340 state_ch <= '1';
341 end if;
342 end case;
343 end process;
344
345 rw_logic: process(pstate)
346 begin
347 data_out_ready <= '0';
348 ior <= '1';
349 iow <= '1';
350 data_in_valid <= '0';
351 reg_addr_ready <= '1';
352 delcntr_rst <= '0';
353 case pstate is
354 --RW Idle
355 when SIdle =>
356 delcntr_rst <= '1';
357 reg_addr_ready <= '0';
358 when SRAVld =>
359 when SWAVld =>
360 when SIorHold =>
361 ior <= '0';
362 data_in_valid <= '1';
363 when SIowHold =>
364 iow <= '0';
365 data_out_ready <= '1';
366 when SRHold =>
367 when SWHold =>
368 data_out_ready <= '1';
369 end case;
370 end process;
371
372 end basic;
373