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

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [lib/] [opencores/] [ata/] [atahost_dma_actrl.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
---------------------------------------------------------------------
2
----                                                             ----
3
----  OpenCores IDE Controller                                   ----
4
----  DMA (single- and multiword) mode access controller         ----
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 9th, 2001. Initial release
37
--
38
--  CVS Log
39
--
40
--  $Id: atahost_dma_actrl.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: atahost_dma_actrl.vhd,v $
50
--               Revision 1.1  2002/02/18 14:32:12  rherveille
51
--               renamed all files to 'atahost_***.vhd'
52
--               broke-up 'counter.vhd' into 'ud_cnt.vhd' and 'ro_cnt.vhd'
53
--               changed resD input to generic RESD in ud_cnt.vhd
54
--               changed ID input to generic ID in ro_cnt.vhd
55
--               changed core to reflect changes in ro_cnt.vhd
56
--               removed references to 'count' library
57
--               changed IO names
58
--               added disclaimer
59
--               added CVS log
60
--               moved registers and wishbone signals into 'atahost_wb_slave.vhd'
61
--
62
--
63
--
64
 
65
 
66
-- Host accesses to DMA ports are 32bit wide. Accesses are made by 2 consecutive 16bit accesses to the ATA
67
-- device's DataPort. The MSB HostData(31:16) is transfered first, then the LSB HostData(15:0) is transfered.
68
 
69
--
70
---------------------------
71
-- DMA Access Controller --
72
---------------------------
73
--
74
library ieee;
75
use ieee.std_logic_1164.all;
76
use ieee.std_logic_arith.all;
77
library grlib;
78
use grlib.stdlib.all;
79
 
80
entity atahost_dma_actrl is
81
        generic(
82
                tech   : integer := 0;                     -- fifo mem technology
83
                fdepth : integer := 8;                     -- DMA fifo depth
84
                TWIDTH : natural := 8;                     -- counter width
85
 
86
                -- DMA mode 0 settings (@100MHz clock)
87
                DMA_mode0_Tm : natural := 4;               -- 50ns
88
                DMA_mode0_Td : natural := 21;              -- 215ns
89
                DMA_mode0_Teoc : natural := 21             -- 215ns ==> T0 - Td - Tm = 480 - 50 - 215 = 215
90
        );
91
        port(
92
                clk : in std_logic;                           -- master clock
93
                nReset : in std_logic;                        -- asynchronous active low reset
94
                rst : in std_logic;                           -- synchronous active high reset
95
 
96
                IDEctrl_rst : in std_logic;                   -- IDE control register bit0, 'rst'
97
 
98
                sel : in std_logic;                           -- DMA buffers selected
99
                we : in std_logic;                            -- write enable input
100
                ack : out std_logic;                                    -- acknowledge output
101
 
102
                dev0_Tm,
103
                dev0_Td,
104
                dev0_Teoc : in std_logic_vector(7 downto 0);          -- DMA mode timing device 0
105
                dev1_Tm,
106
                dev1_Td,
107
                dev1_Teoc : in std_logic_vector(7 downto 0);          -- DMA mode timing device 1
108
 
109
                DMActrl_DMAen,
110
                DMActrl_dir,
111
                DMActrl_Bytesw, --Jagre 2006-12-04, byte swap ATA data
112
                DMActrl_BeLeC0,
113
                DMActrl_BeLeC1 : in std_logic;                -- control register settings
114
 
115
                TxD : in std_logic_vector(31 downto 0);       -- DMA transmit data
116
                TxFull : out std_logic;                    -- DMA transmit buffer full
117
                TxEmpty : out std_logic;
118
                RxQ : out std_logic_vector(31 downto 0);      -- DMA receive data
119
                RxEmpty : out std_logic;                   -- DMA receive buffer empty
120
                RxFull : out std_logic;                       -- DMA receive buffer full
121
                DMA_req : out std_logic;                      -- DMA request to external DMA engine
122
                DMA_ack : in std_logic;                       -- DMA acknowledge from external DMA engine
123
 
124
                DMARQ : in std_logic;                         -- ATA devices request DMA transfer
125
 
126
                SelDev : in std_logic;                        -- Selected device        
127
 
128
                Go : in std_logic;                            -- Start transfer sequence
129
                Done : out std_logic;                         -- Transfer sequence done
130
 
131
                DDi : in std_logic_vector(15 downto 0);       -- Data from ATA DD bus
132
                DDo : out std_logic_vector(15 downto 0);      -- Data towards ATA DD bus
133
 
134
                DIOR,
135
                DIOW : out std_logic
136
        );
137
end entity atahost_dma_actrl;
138
 
139
architecture structural of atahost_dma_actrl is
140
        --
141
        -- component declarations
142
        --
143
        component atahost_dma_tctrl is
144
        generic(
145
                TWIDTH : natural := 8;            -- counter width
146
 
147
                -- DMA mode 0 settings (@100MHz clock)
148
                DMA_mode0_Tm : natural := 6;     -- 70ns
149
                DMA_mode0_Td : natural := 28;    -- 290ns
150
                DMA_mode0_Teoc : natural := 23   -- 240ns ==> T0 - T1 - T2 = 600 - 70 - 290 = 240
151
        );
152
        port(
153
                clk : in std_logic;                      -- master clock
154
                nReset : in std_logic;                   -- asynchronous active low reset
155
                rst : in std_logic;                      -- synchronous active high reset
156
 
157
                -- timing register settings
158
                Tm : in std_logic_vector(TWIDTH -1 downto 0);    -- Tm time (in clk-ticks)
159
                Td : in std_logic_vector(TWIDTH -1 downto 0);    -- Td time (in clk-ticks)
160
                Teoc : in std_logic_vector(TWIDTH -1 downto 0);  -- end of cycle time
161
 
162
                -- control signals
163
                go : in std_logic;                       -- DMA controller selected (strobe signal)
164
                we : in std_logic;                       -- DMA direction '1' = write, '0' = read
165
 
166
                -- return signals
167
                done : out std_logic;                    -- finished cycle
168
                dstrb : out std_logic;                   -- data strobe
169
 
170
                -- ATA signals
171
                DIOR,                                    -- IOread signal, active high
172
                DIOW : out std_logic                  -- IOwrite signal, active high
173
        );
174
        end component atahost_dma_tctrl;
175
 
176
        component atahost_reg_buf is
177
        generic (
178
                WIDTH : natural := 8
179
        );
180
        port(
181
                clk : in std_logic;
182
                nReset : in std_logic;
183
                rst : in std_logic;
184
 
185
                D : in std_logic_vector(WIDTH -1 downto 0);
186
                Q : out std_logic_vector(WIDTH -1 downto 0);
187
                rd : in std_logic;
188
                wr : in std_logic;
189
                valid : out std_logic
190
        );
191
        end component atahost_reg_buf;
192
 
193
        component atahost_dma_fifo is
194
        generic(tech  : integer:=0;
195
                abits : integer:=3;
196
                dbits : integer:=32;
197
                depth : integer:=8);
198
 
199
        port( clk          : in std_logic;
200
              reset        : in std_logic;
201
 
202
              write_enable : in std_logic;
203
              read_enable  : in std_logic;
204
 
205
              data_in      : in std_logic_vector(dbits-1 downto 0);
206
              data_out     : out std_logic_vector(dbits-1 downto 0);
207
 
208
              write_error  : out std_logic:='0';
209
              read_error   : out std_logic:='0';
210
 
211
              level        : out natural range 0 to depth;
212
              empty        : out std_logic:='1';
213
              full         : out std_logic:='0'
214
        );
215
        end component atahost_dma_fifo;
216
 
217
        signal Tdone, Tfw : std_logic;
218
        signal RxWr, TxRd : std_logic;
219
        signal assync_TxRd, s_TxFull : std_logic; -----------------------Erik Jagre 2006-10-27
220
        signal dstrb, rd_dstrb, wr_dstrb : std_logic;
221
        signal TxbufQ, RxbufD : std_logic_vector(31 downto 0);
222
        signal iRxEmpty : std_logic;
223
 
224
        constant abits : integer := Log2(fdepth);
225
 
226
begin
227
 
228
        -- note: *fw = *first_word, *lw = *last_word
229
 
230
 
231
        --
232
        -- generate DDi/DDo controls
233
        --
234
        gen_DMA_sigs: block
235
                signal writeDfw, writeDlw : std_logic_vector(15 downto 0);
236
                signal readDfw, readDlw : std_logic_vector(15 downto 0);
237
                signal BeLeC : std_logic; -- BigEndian <-> LittleEndian conversion
238
        begin
239
                -- generate byte_swap signal
240
                BeLeC <=        (not SelDev and DMActrl_BeLeC0) or (SelDev and DMActrl_BeLeC1);
241
 
242
                -- generate Tfw (Transfering first word)
243
                gen_Tfw: process(clk, nReset)
244
                begin
245
                        if (nReset = '0') then
246
                                Tfw <= '0';
247
                        elsif (clk'event and clk = '1') then
248
                                if (rst = '1') then
249
                                        Tfw <= '0';
250
                                else
251
                                        Tfw <= go or (Tfw and not Tdone);
252
                                end if;
253
                        end if;
254
                end process gen_Tfw;
255
 
256
                -- transmit data part
257
                gen_writed_pipe:process(clk)
258
                begin
259
                        if (clk'event and clk = '1') then
260
                                if (TxRd = '1') then                              -- reload registers
261
                                        if (BeLeC = '1') then                           -- Do big<->little endian conversion
262
                                                writeDfw(15 downto 8) <= TxbufQ( 7 downto  0); -- TxbufQ = data from transmit buffer
263
                                                writeDfw( 7 downto 0) <= TxbufQ(15 downto  8);
264
                                                writeDlw(15 downto 8) <= TxbufQ(23 downto 16);
265
                                                writeDlw( 7 downto 0) <= TxbufQ(31 downto 24);
266
                                        else                                              -- don't do big<->little endian conversion
267
                                                writeDfw <= TxbufQ(31 downto 16);
268
                                                writeDlw <= TxbufQ(15 downto 0);
269
                                        end if;
270
                                elsif (wr_dstrb = '1') then                          -- next word to transfer
271
                                        writeDfw <= writeDlw;
272
                                end if;
273
                        end if;
274
                end process gen_writed_pipe;
275
 
276
                --Jagre 2006-12-04
277
                --swap byte orderD when MActrl_Bytesw is set to '1'
278
                DDo(15 downto 8) <= writeDfw(15 downto 8) when DMActrl_Bytesw='0' else
279
                                    writeDfw(7 downto 0);
280
 
281
                DDo(7 downto 0)  <= writeDfw(7 downto 0) when DMActrl_Bytesw='0' else
282
                                    writeDfw(15 downto 8);
283
 
284
                --DDo <= writeDfw;                                       -- assign DMA data out
285
 
286
                -- generate transmit register read request
287
                gen_Tx_rreq: process(clk, nReset)
288
                begin
289
                        if (nReset = '0') then
290
                                TxRd <= '0';
291
                        elsif (clk'event and clk = '1') then
292
                                if (rst = '1') then
293
                                        TxRd <= '0';
294
                                else
295
                                        TxRd <= go and DMActrl_dir;
296
                                end if;
297
                        end if;
298
                end process gen_Tx_rreq;
299
                assync_TxRd <= go and DMActrl_dir; --Jagre 2006-12-14
300
 
301
                -- receive
302
                gen_readd_pipe:process(clk)
303
                begin
304
                        if (clk'event and clk = '1') then
305
                                if (rd_dstrb = '1') then
306
 
307
                                        readDfw <= readDlw;                   -- shift previous read word to msb
308
                                        if (BeLeC = '1' xor DMActrl_Bytesw = '1') then -- swap bytes, DMActrl_Bytesw added 2006-12-04, Jagre
309
                                                readDlw(15 downto 8) <= DDi( 7 downto 0);
310
                                                readDlw( 7 downto 0) <= DDi(15 downto 8);
311
                                        else                                  -- don't swap bytes
312
                                                readDlw <= DDi;
313
                                        end if;
314
                                end if;
315
                        end if;
316
                end process gen_readd_pipe;
317
                -- RxD = data to receive buffer
318
                RxbufD <= (readDfw & readDlw) when (BeLeC = '0') else (readDlw & readDfw);
319
 
320
                -- generate receive register write request
321
                gen_Rx_wreq: process(clk, nReset)
322
                begin
323
                        if (nReset = '0') then
324
                                RxWr <= '0';
325
                        elsif (clk'event and clk = '1') then
326
                                if (rst = '1') then
327
                                        RxWr <= '0';
328
                                else
329
                                        RxWr <= not Tfw and rd_dstrb;
330
                                end if;
331
                        end if;
332
                end process gen_Rx_wreq;
333
        end block gen_DMA_sigs;
334
 
335
 
336
        --
337
        -- Hookup DMA read / write buffers
338
        --
339
        gen_DMAbuf: block
340
                signal DMArst : std_logic;
341
                signal RxRd, TxWr : std_logic;
342
        begin
343
                -- generate DMA reset signal
344
                DMArst <= rst or IDEctrl_rst;
345
 
346
                Txfifo: atahost_dma_fifo
347
                generic map(dbits=>32,depth=>fdepth,tech=>tech,abits=>abits)
348
                port map( clk          => clk,
349
                      reset        => DMArst,
350
                      write_enable => TxWr,
351
                      read_enable  => assync_TxRd,
352
                      data_in      => TxD,
353
                      data_out     => TxbufQ,
354
                      write_error  => open,
355
                      read_error   => open,
356
                      level        => open,
357
                      empty        => TxEmpty,
358
                      full         => s_TxFull
359
                );
360
 
361
                Rxfifo: atahost_dma_fifo
362
                generic map(dbits=>32,depth=>fdepth,tech=>tech,abits=>abits)
363
                port map( clk          => clk,
364
                      reset        => DMArst,
365
                      write_enable => RxWr,
366
                      read_enable  => RxRd,
367
                      data_in      => RxbufD,
368
                      data_out     => RxQ,
369
                      write_error  => open,
370
                      read_error   => open,
371
                      level        => open,
372
                      empty        => iRxEmpty,
373
                      full         => RxFull
374
                );
375
 
376
                RxEmpty <= iRxEmpty; -- avoid 'cannot associate OUT port with BUFFER port' error
377
 
378
                --
379
                -- generate DMA buffer access signals
380
                --
381
                RxRd <= sel and not we and not iRxEmpty;
382
                TxWr <= sel and     we and not s_TxFull;
383
 
384
                ack  <= RxRd or TxWr; -- DMA buffer access acknowledge
385
        end block gen_DMAbuf;
386
 
387
        --
388
        -- generate request signal for external DMA engine
389
        --
390
        gen_DMA_req: block
391
                signal hgo : std_logic;
392
                signal iDMA_req : std_logic;
393
                signal request : std_logic;
394
        begin
395
                -- generate hold-go
396
                gen_hgo : process(clk, nReset)
397
                begin
398
                        if (nReset = '0') then
399
                                hgo <= '0';
400
                        elsif (clk'event and clk = '1') then
401
                                if (rst = '1') then
402
                                        hgo <= '0';
403
                                else
404
                                        hgo <= go or (hgo and not (wr_dstrb and not Tfw) and DMActrl_dir);
405
                                end if;
406
                        end if;
407
                end process gen_hgo;
408
 
409
                request <= (DMActrl_dir and DMARQ and not s_TxFull and not hgo) or not iRxEmpty;
410
                process(clk, nReset)
411
                begin
412
                        if (nReset = '0') then
413
                                iDMA_req <= '0';
414
                        elsif (clk'event and clk = '1') then
415
                                if (rst = '1') then
416
                                        iDMA_req <= '0';
417
                                else
418
                                        iDMA_req <= DMActrl_DMAen and not DMA_ack and (request or iDMA_req);
419
--                              DMA_req <= (DMActrl_DMAen and DMActrl_dir and DMARQ and not TxFull and not hgo) or not iRxEmpty;
420
                                end if;
421
                        end if;
422
                end process;
423
                DMA_req <= iDMA_req;
424
        end block gen_DMA_req;
425
 
426
 
427
        --
428
        -- DMA timing controller
429
        --
430
        DMA_timing_ctrl: block
431
                signal Tm, Td, Teoc, Tdmack_ext : std_logic_vector(TWIDTH -1 downto 0);
432
                signal dTfw, igo : std_logic;
433
        begin
434
                --
435
                -- generate internal GO signal
436
                --
437
                gen_igo : process(clk, nReset)
438
                begin
439
                        if (nReset = '0') then
440
                                igo  <= '0';
441
                                dTfw <= '0';
442
                        elsif (clk'event and clk = '1') then
443
                                if (rst = '1') then
444
                                        igo  <= '0';
445
                                        dTfw <= '0';
446
                                else
447
                                        igo  <= go or (not Tfw and dTfw);
448
                                        dTfw <= Tfw;
449
                                end if;
450
                        end if;
451
                end process gen_igo;
452
 
453
                --
454
                -- select timing settings for the addressed device
455
                --
456
                sel_dev_t: process(clk)
457
                begin
458
                        if (clk'event and clk = '1') then
459
                                if (SelDev = '1') then                      -- device1 selected
460
                                        Tm   <= dev1_Tm;
461
                                        Td   <= dev1_Td;
462
                                        Teoc <= dev1_Teoc;
463
                                else                                        -- device0 selected
464
                                        Tm   <= dev0_Tm;
465
                                        Td   <= dev0_Td;
466
                                        Teoc <= dev0_Teoc;
467
                                end if;
468
                        end if;
469
                end process sel_dev_t;
470
 
471
                --
472
                -- hookup timing controller
473
                --
474
                DMA_timing_ctrl: atahost_dma_tctrl
475
                        generic map (
476
                                TWIDTH => TWIDTH,
477
                                DMA_mode0_Tm   => DMA_mode0_Tm,
478
                                DMA_mode0_Td   => DMA_mode0_Td,
479
                                DMA_mode0_Teoc => DMA_mode0_Teoc
480
                        )
481
                        port map (
482
                                clk    => clk,
483
                                nReset => nReset,
484
                                rst    => rst,
485
                                Tm     => Tm,
486
                                Td     => Td,
487
                                Teoc   => Teoc,
488
                                go     => igo,
489
                                we     => DMActrl_dir,
490
                                done   => Tdone,
491
                                dstrb  => dstrb,
492
                                DIOR   => dior,
493
                                DIOW   => diow
494
                        );
495
 
496
                done <= Tdone and not Tfw;             -- done transfering last word
497
                rd_dstrb <= dstrb and not DMActrl_dir; -- read data strobe
498
                wr_dstrb <= dstrb and     DMActrl_dir; -- write data strobe
499
                TxFull <= s_TxFull;
500
        end block DMA_timing_ctrl;
501
 
502
end architecture structural;
503
 

powered by: WebSVN 2.1.0

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