OpenCores
URL https://opencores.org/ocsvn/ata/ata/trunk

Subversion Repositories ata

[/] [ata/] [trunk/] [rtl/] [vhdl/] [ocidec3/] [atahost_pio_controller.vhd] - Blame information for rev 35

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 rherveille
---------------------------------------------------------------------
2
----                                                             ----
3
----  OpenCores IDE Controller                                   ----
4
----  ATA/ATAPI-5 PIO controller with write PingPong             ----
5
----                                                             ----
6
----  Author: Richard Herveille                                  ----
7
----          richard@asics.ws                                   ----
8
----          www.asics.ws                                       ----
9
----                                                             ----
10
---------------------------------------------------------------------
11
----                                                             ----
12
---- Copyright (C) 2001, 2002 Richard Herveille                  ----
13
----                          richard@asics.ws                   ----
14
----                                                             ----
15
---- This source file may be used and distributed without        ----
16
---- restriction provided that this copyright statement is not   ----
17
---- removed from the file and that any derivative work contains ----
18
---- the original copyright notice and the associated disclaimer.----
19
----                                                             ----
20
----     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ----
21
---- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ----
22
---- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ----
23
---- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ----
24
---- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ----
25
---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ----
26
---- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ----
27
---- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ----
28
---- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ----
29
---- LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ----
30
---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ----
31
---- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ----
32
---- POSSIBILITY OF SUCH DAMAGE.                                 ----
33
----                                                             ----
34
---------------------------------------------------------------------
35
 
36
-- rev.: 1.0 march 8th, 2001. Initial release
37
--
38
--  CVS Log
39
--
40
--  $Id: atahost_pio_controller.vhd,v 1.1 2002-02-18 14:32:12 rherveille Exp $
41
--
42
--  $Date: 2002-02-18 14:32:12 $
43
--  $Revision: 1.1 $
44
--  $Author: rherveille $
45
--  $Locker:  $
46
--  $State: Exp $
47
--
48
-- Change History:
49
--               $Log: not supported by cvs2svn $
50
--
51
 
52
library ieee;
53
use ieee.std_logic_1164.all;
54
use ieee.std_logic_arith.all;
55
 
56
entity atahost_pio_controller is
57
        generic(
58
                TWIDTH : natural := 8;                        -- counter width
59
 
60
                -- PIO mode 0 settings (@100MHz clock)
61
                PIO_mode0_T1 : natural := 6;                  -- 70ns
62
                PIO_mode0_T2 : natural := 28;                 -- 290ns
63
                PIO_mode0_T4 : natural := 2;                  -- 30ns
64
                PIO_mode0_Teoc : natural := 23                -- 240ns ==> T0 - T1 - T2 = 600 - 70 - 290 = 240
65
        );
66
        port(
67
                clk    : in std_logic;                                            -- master clock in
68
                nReset  : in std_logic := '1';                 -- asynchronous active low reset
69
                rst    : in std_logic := '0';                 -- synchronous active high reset
70
 
71
                -- control / registers
72
                IDEctrl_IDEen,
73
                IDEctrl_ppen,
74
                IDEctrl_FATR0,
75
                IDEctrl_FATR1 : in std_logic;
76
 
77
                -- PIO registers
78
                cmdport_T1,
79
                cmdport_T2,
80
                cmdport_T4,
81
                cmdport_Teoc : in unsigned(7 downto 0);
82
                cmdport_IORDYen : in std_logic;               -- PIO command port / non-fast timing
83
 
84
                dport0_T1,
85
                dport0_T2,
86
                dport0_T4,
87
                dport0_Teoc : in unsigned(7 downto 0);
88
                dport0_IORDYen : in std_logic;                -- PIO mode data-port / fast timing device 0
89
 
90
                dport1_T1,
91
                dport1_T2,
92
                dport1_T4,
93
                dport1_Teoc : in unsigned(7 downto 0);
94
                dport1_IORDYen : in std_logic;                -- PIO mode data-port / fast timing device 1
95
 
96
                sel : in  std_logic;                          -- PIO controller selected
97
                ack : out std_logic;                          -- PIO controller acknowledge
98
                a   : in  unsigned(3 downto 0);               -- lower address bits
99
                we  : in  std_logic;                          -- write enable input
100
                d   : in  std_logic_vector(15 downto 0);
101
                q   : out std_logic_vector(15 downto 0);
102
 
103
                PIOreq : out std_logic;                       -- PIO transfer request
104
                PPFull : out std_logic;                       -- PIO Write PingPong Full
105
                go     : in std_logic;                        -- start PIO transfer
106
                done   : buffer std_logic;                    -- done with PIO transfer
107
 
108
                PIOa : out unsigned(3 downto 0);              -- PIO address, address lines towards ATA devices
109
                PIOd : out std_logic_vector(15 downto 0);     -- PIO data, data towards ATA devices
110
 
111
                SelDev : buffer std_logic;                    -- Selected Device, Dev-bit in ATA Device/Head register
112
 
113
                DDi      : in std_logic_vector(15 downto 0);
114
                DDoe : buffer std_logic;
115
 
116
                DIOR     : buffer std_logic;
117
                DIOW     : buffer std_logic;
118
                IORDY   : in std_logic
119
        );
120
end entity atahost_pio_controller;
121
 
122
architecture structural of atahost_pio_controller is
123
        --
124
        -- component declarations
125
        --
126
        component atahost_pio_actrl is
127
        generic(
128
                TWIDTH : natural := 8;                     -- counter width
129
 
130
                -- PIO mode 0 settings (@100MHz clock)
131
                PIO_mode0_T1 : natural := 6;               -- 70ns
132
                PIO_mode0_T2 : natural := 28;              -- 290ns
133
                PIO_mode0_T4 : natural := 2;               -- 30ns
134
                PIO_mode0_Teoc : natural := 23             -- 240ns ==> T0 - T1 - T2 = 600 - 70 - 290 = 240
135
        );
136
        port(
137
                clk    : in std_logic;                     -- master clock
138
                nReset : in std_logic;                     -- asynchronous active low reset
139
                rst    : in std_logic;                     -- synchronous active high reset
140
 
141
                IDEctrl_FATR0,
142
                IDEctrl_FATR1 : in std_logic;
143
 
144
                cmdport_T1,
145
                cmdport_T2,
146
                cmdport_T4,
147
                cmdport_Teoc : in unsigned(7 downto 0);
148
                cmdport_IORDYen : in std_logic;            -- PIO command port / non-fast timing
149
 
150
                dport0_T1,
151
                dport0_T2,
152
                dport0_T4,
153
                dport0_Teoc : in unsigned(7 downto 0);
154
                dport0_IORDYen : in std_logic;             -- PIO mode data-port / fast timing device 0
155
 
156
                dport1_T1,
157
                dport1_T2,
158
                dport1_T4,
159
                dport1_Teoc : in unsigned(7 downto 0);
160
                dport1_IORDYen : in std_logic;             -- PIO mode data-port / fast timing device 1
161
 
162
                SelDev : in std_logic;                     -- Selected device   
163
 
164
                go   : in  std_logic;                      -- Start transfer sequence
165
                done : out std_logic;                      -- Transfer sequence done
166
                dir  : in  std_logic;                      -- Transfer direction '1'=write, '0'=read
167
                a    : in  unsigned(3 downto 0);           -- PIO transfer address
168
                q    : out std_logic_vector(15 downto 0);  -- Data read from ATA devices
169
 
170
                DDi : in std_logic_vector(15 downto 0);    -- Data from ATA DD bus
171
                oe  : buffer std_logic;                    -- DDbus output-enable signal
172
 
173
                DIOR,
174
                DIOW  : buffer std_logic;
175
                IORDY : in std_logic
176
        );
177
        end component atahost_pio_actrl;
178
 
179
        --
180
        -- signals
181
        --
182
 
183
        -- PIO pingpong signals
184
        signal pp_d : std_logic_vector(15 downto 0);
185
        signal pp_a : unsigned(3 downto 0);
186
        signal pp_we : std_logic;
187
        signal idone : std_logic;
188
 
189
begin
190
        --
191
        -- generate selected device
192
        --
193
        gen_seldev: process(clk, pp_a)
194
                variable Asel : std_logic; -- address selected
195
        begin
196
                Asel := not pp_a(3) and pp_a(2) and pp_a(1) and not pp_a(0); -- header/device register
197
 
198
                if (clk'event and clk = '1') then
199
                        if ( (idone = '1') and (Asel = '1') and (pp_we = '1') ) then
200
                                SelDev <= pp_d(4);
201
                        end if;
202
                end if;
203
        end process gen_seldev;
204
 
205
        --
206
        -- generate PIO write pingpong system
207
        --
208
        gen_pingpong: block
209
                signal ping_d, pong_d : std_logic_vector(15 downto 0);
210
                signal ping_a, pong_a : unsigned(3 downto 0);
211
                signal ping_we, pong_we : std_logic;
212
                signal ping_valid, pong_valid : std_logic;
213
                signal dping_valid, dpong_valid : std_logic;
214
                signal wpp, rpp : std_logic;
215
 
216
                signal dsel, sel_strb : std_logic;
217
 
218
                signal iack : std_logic;
219
        begin
220
                -- generate PIO acknowledge
221
                gen_ack: process(clk, ping_valid, dping_valid, pong_valid, dpong_valid, we)
222
                        variable ping_re, ping_fe, pong_re, pong_fe : std_logic;
223
                begin
224
                        -- detect rising edge of ping_valid and pong_valid
225
                        ping_re := ping_valid and not dping_valid and we;
226
                        pong_re := pong_valid and not dpong_valid and we;
227
 
228
                        -- detect falling edge of ping_valid and pong_valid
229
                        ping_fe := not ping_valid and dping_valid;
230
                        pong_fe := not pong_valid and dpong_valid;
231
 
232
                        if (clk'event and clk = '1') then
233
                                if ((pp_we = '1') and (IDEctrl_ppen = '1')) then -- write sequence
234
                                        if (wpp = '1') then
235
                                                iack <= ping_re;
236
                                        else
237
                                                iack <= pong_re;
238
                                        end if;
239
                                else                                           -- read sequence
240
                                        if (rpp = '1') then
241
                                                iack <= ping_fe;
242
                                        else
243
                                                iack <= pong_fe;
244
                                        end if;
245
                                end if;
246
                        end if;
247
                end process gen_ack;
248
                ack <= (iack or not IDEctrl_IDEen) and sel; -- acknowledge access when not enabled (discard access)
249
 
250
                -- generate select-strobe, hold sel_strb until pingpong system ready for new data
251
                gen_sel_strb: process(clk, nReset)
252
                begin
253
                        if (nReset = '0') then
254
                                dsel <= '0';
255
                        elsif (clk'event and clk = '1') then
256
                                if (rst = '1') then
257
                                        dsel <= '0';
258
                                else
259
                                        dsel <= sel_strb or (dsel and sel);
260
                                end if;
261
                        end if;
262
                end process gen_sel_strb;
263
                sel_strb <= sel and not dsel and IDEctrl_IDEen and ((wpp and not ping_valid) or (not wpp and not pong_valid));
264
 
265
                -- generate pingpong control
266
                gen_pp : process(clk, nReset)
267
                begin
268
                        if (nReset = '0') then
269
                                wpp <= '0';
270
                                rpp <= '0';
271
                                ping_valid <= '0';
272
                                pong_valid <= '0';
273
                                dping_valid <= '0';
274
                                dpong_valid <= '0';
275
                        elsif (clk'event and clk = '1') then
276
                                if (rst = '1') then
277
                                        wpp <= '0';
278
                                        rpp <= '0';
279
                                        ping_valid <= '0';
280
                                        pong_valid <= '0';
281
                                        dping_valid <= '0';
282
                                        dpong_valid <= '0';
283
                                else
284
                                        wpp <= (wpp xor (iack and we)) and IDEctrl_ppen;
285
                                        rpp <= (rpp xor (idone and pp_we)) and IDEctrl_ppen;
286
                                        ping_valid <= ((    wpp and sel_strb) or ping_valid) and not (    rpp and idone);
287
                                        pong_valid <= ((not wpp and sel_strb) or pong_valid) and not (not rpp and idone);
288
                                        dping_valid <= ping_valid;
289
                                        dpong_valid <= pong_valid;
290
                                end if;
291
                        end if;
292
                end process gen_pp;
293
 
294
                -- generate pingpong full signal
295
                PPFull <= (ping_valid and pong_valid) when (IDEctrl_ppen = '1') else pong_valid;
296
 
297
                -- fill ping/pong registers
298
                fill_pp: process(clk)
299
                begin
300
                        if (clk'event and clk = '1') then
301
                                if (sel = '1') then
302
                                        if (wpp = '1') then
303
                                                if (ping_valid = '0') then
304
                                                        ping_d <= d;
305
                                                        ping_a <= a;
306
                                                        ping_we <= we;
307
                                                end if;
308
                                        else
309
                                                if (pong_valid = '0') then
310
                                                        pong_d <= d;
311
                                                        pong_a <= a;
312
                                                        pong_we <= we;
313
                                                end if;
314
                                        end if;
315
                                end if;
316
                        end if;
317
                end process fill_pp;
318
 
319
                -- multiplex pingpong data to pp_d, pp_a, pp_we
320
                pp_d <= ping_d when (rpp = '1') else pong_d;
321
                pp_a <= ping_a when (rpp = '1') else pong_a;
322
                pp_we <= ping_we when (rpp = '1') else pong_we;
323
 
324
                -- generate PIOreq
325
                PIOreq <= (ping_valid and not idone) when (rpp = '1') else (pong_valid and not idone);
326
        end block gen_pingpong;
327
 
328
        --
329
        -- Hookup PIO access controller
330
        --
331
        PIO_access_control: atahost_pio_actrl
332
                generic map(
333
                        TWIDTH => TWIDTH,
334
                        PIO_mode0_T1 => PIO_mode0_T1,
335
                        PIO_mode0_T2 => PIO_mode0_T2,
336
                        PIO_mode0_T4 => PIO_mode0_T4,
337
                        PIO_mode0_Teoc => PIO_mode0_Teoc
338
                )
339
                port map(
340
                        clk    => clk,
341
                        nReset => nReset,
342
                        rst    => rst,
343
                        IDEctrl_FATR0 => IDEctrl_FATR0,
344
                        IDEctrl_FATR1 => IDEctrl_FATR1,
345
                        cmdport_T1   => cmdport_T1,
346
                        cmdport_T2   => cmdport_T2,
347
                        cmdport_T4   => cmdport_T4,
348
                        cmdport_Teoc => cmdport_Teoc,
349
                        cmdport_IORDYen => cmdport_IORDYen,
350
                        dport0_T1   => dport0_T1,
351
                        dport0_T2   => dport0_T2,
352
                        dport0_T4   => dport0_T4,
353
                        dport0_Teoc => dport0_Teoc,
354
                        dport0_IORDYen => dport0_IORDYen,
355
                        dport1_T1   => dport1_T1,
356
                        dport1_T2   => dport1_T2,
357
                        dport1_T4   => dport1_T4,
358
                        dport1_Teoc => dport1_Teoc,
359
                        dport1_IORDYen => dport1_IORDYen,
360
                        SelDev => SelDev,
361
                        go     => go,
362
                        done   => idone,
363
                        dir    => pp_we,
364
                        a      => pp_a,
365
                        q      => Q,
366
                        DDi    => DDi,
367
                        oe     => DDoe,
368
                        DIOR   => dior,
369
                        DIOW   => diow,
370
                        IORDY  => IORDY
371
                );
372
 
373
        --
374
        -- assign outputs
375
        --
376
        PIOa <= pp_a;
377
        PIOd <= pp_d;
378
        Done <= idone;
379
end architecture structural;
380
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.