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

Subversion Repositories ata

[/] [ata/] [trunk/] [rtl/] [verilog/] [ocidec-1/] [atahost_pio_tctrl.v] - Blame information for rev 15

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

Line No. Rev Author Line
1 15 rherveille
//
2
// file: pio_tctrl.v
3
//      description: PIO mode timing controller for ATA controller
4
// author : Richard Herveille
5
// Rev. 1.0 June 27th, 2001. Initial Verilog release
6
// Rev. 1.1 July  2nd, 2001. Fixed incomplete port list and some Verilog related issues.
7
// Rev. 1.2 July 11th, 2001. Changed 'igo' & 'hold_go' generation.
8
 
9
//
10
///////////////////////////
11
// PIO Timing controller //
12
///////////////////////////
13
//
14
 
15
//
16
// Timing       PIO mode transfers
17
//--------------------------------------------
18
// T0:  cycle time
19
// T1:  address valid to DIOR-/DIOW-
20
// T2:  DIOR-/DIOW- pulse width
21
// T2i: DIOR-/DIOW- recovery time
22
// T3:  DIOW- data setup
23
// T4:  DIOW- data hold
24
// T5:  DIOR- data setup
25
// T6:  DIOR- data hold
26
// T9:  address hold from DIOR-/DIOW- negated
27
// Trd: Read data valid to IORDY asserted
28
// Ta:  IORDY setup time
29
// Tb:  IORDY pulse width
30
//
31
// Transfer sequence
32
//--------------------------------
33
// 1)   set address (DA, CS0-, CS1-)
34
// 2)   wait for T1
35
// 3)   assert DIOR-/DIOW-
36
//         when write action present Data (timing spec. T3 always honored), enable output enable-signal
37
// 4)   wait for T2
38
// 5)   check IORDY
39
//         when not IORDY goto 5
40
//        when IORDY negate DIOW-/DIOR-, latch data (if read action)
41
//    when write, hold data for T4, disable output-enable signal
42
// 6)   wait end_of_cycle_time. This is T2i or T9 or (T0-T1-T2) whichever takes the longest
43
// 7)   start new cycle
44
 
45
`include "timescale.v"
46
 
47
module atahost_pio_tctrl(clk, nReset, rst, IORDY_en, T1, T2, T4, Teoc, go, we, oe, done, dstrb, DIOR, DIOW, IORDY);
48
        // parameter declarations
49
        parameter TWIDTH = 8;
50
        parameter PIO_MODE0_T1   =  6;             // 70ns
51
        parameter PIO_MODE0_T2   = 28;             // 290ns
52
        parameter PIO_MODE0_T4   =  2;             // 30ns
53
        parameter PIO_MODE0_Teoc = 23;             // 240ns
54
 
55
        // inputs & outputs
56
        input clk; // master clock
57
        input nReset; // asynchronous active low reset
58
        input rst; // synchronous active high reset
59
 
60
        // timing & control register settings
61
        input IORDY_en;          // use IORDY (or not)
62
        input [TWIDTH-1:0] T1;   // T1 time (in clk-ticks)
63
        input [TWIDTH-1:0] T2;   // T1 time (in clk-ticks)
64
        input [TWIDTH-1:0] T4;   // T1 time (in clk-ticks)
65
        input [TWIDTH-1:0] Teoc; // T1 time (in clk-ticks)
66
 
67
        // control signals
68
        input go; // PIO controller selected (strobe signal)
69
        input we; // write enable signal. 1'b0 == read, 1'b1 == write
70
 
71
        // return signals
72
        output oe; // output enable signal
73
        reg oe;
74
        output done; // finished cycle
75
        output dstrb; // data strobe, latch data (during read)
76
        reg dstrb;
77
 
78
        // ata signals
79
        output DIOR; // IOread signal, active high
80
        reg DIOR;
81
        output DIOW; // IOwrite signal, active high
82
        reg DIOW;
83
        input  IORDY; // IOrDY signal
84
 
85
 
86
        //
87
        // constant declarations
88
        //
89
        // PIO mode 0 settings (@100MHz clock)
90
        wire [TWIDTH-1:0] T1_m0   = PIO_MODE0_T1;
91
        wire [TWIDTH-1:0] T2_m0   = PIO_MODE0_T2;
92
        wire [TWIDTH-1:0] T4_m0   = PIO_MODE0_T4;
93
        wire [TWIDTH-1:0] Teoc_m0 = PIO_MODE0_Teoc;
94
 
95
        //
96
        // variable declaration
97
        //
98
        reg busy, hold_go;
99
        wire igo;
100
        wire T1done, T2done, T4done, Teoc_done, IORDY_done;
101
        reg hT2done;
102
 
103
        //
104
        // module body
105
        //
106
 
107
        // generate internal go strobe
108
        // strecht go until ready for new cycle
109
        always@(posedge clk or negedge nReset)
110
                if (~nReset)
111
                        begin
112
                                busy <= 1'b0;
113
                                hold_go <= 1'b0;
114
                        end
115
                else if (rst)
116
                        begin
117
                                busy <= 1'b0;
118
                                hold_go <= 1'b0;
119
                        end
120
                else
121
                        begin
122
                                busy <= (igo | busy) & !Teoc_done;
123
                                hold_go <= (go | (hold_go & busy)) & !igo;
124
                        end
125
 
126
        assign igo = (go | hold_go) & !busy;
127
 
128
        // 1)   hookup T1 counter
129
        ro_cnt #(TWIDTH) t1_cnt(.clk(clk), .nReset(nReset), .rst(rst), .cnt_en(1'b1), .go(igo), .d(T1), .id(T1_m0), .done(T1done), .q());
130
 
131
        // 2)   set (and reset) DIOR-/DIOW-, set output-enable when writing to device
132
        always@(posedge clk or negedge nReset)
133
                if (~nReset)
134
                        begin
135
                                DIOR <= 1'b0;
136
                                DIOW <= 1'b0;
137
                                oe   <= 1'b0;
138
                        end
139
                else if (rst)
140
                        begin
141
                                DIOR <= 1'b0;
142
                                DIOW <= 1'b0;
143
                                oe   <= 1'b0;
144
                        end
145
                else
146
                        begin
147
                                DIOR <= (!we & T1done) | (DIOR & !IORDY_done);
148
                                DIOW <= ( we & T1done) | (DIOW & !IORDY_done);
149
                                oe   <= ( (we & igo) | oe) & !T4done;           // negate oe when t4-done
150
                        end
151
 
152
        // 3)   hookup T2 counter
153
        ro_cnt #(TWIDTH) t2_cnt(.clk(clk), .nReset(nReset), .rst(rst), .cnt_en(1'b1), .go(T1done), .d(T2), .id(T2_m0), .done(T2done), .q());
154
 
155
        // 4)   check IORDY (if used), generate release_DIOR-/DIOW- signal (ie negate DIOR-/DIOW-)
156
        // hold T2done
157
        always@(posedge clk or negedge nReset)
158
                if (~nReset)
159
                        hT2done <= 1'b0;
160
                else if (rst)
161
                        hT2done <= 1'b0;
162
                else
163
                                hT2done <= (T2done | hT2done) & !IORDY_done;
164
 
165
        assign IORDY_done = (T2done | hT2done) & (IORDY | !IORDY_en);
166
 
167
        // generate datastrobe, capture data at rising DIOR- edge
168
        always@(posedge clk)
169
                dstrb <= IORDY_done;
170
 
171
        // hookup data hold counter
172
        ro_cnt #(TWIDTH) dhold_cnt(.clk(clk), .nReset(nReset), .rst(rst), .cnt_en(1'b1), .go(IORDY_done), .d(T4), .id(T4_m0), .done(T4done), .q());
173
        assign done = T4done; // placing done here provides the fastest return possible, 
174
                        // while still guaranteeing data and address hold-times
175
 
176
        // 5)   hookup end_of_cycle counter
177
        ro_cnt #(TWIDTH) eoc_cnt(.clk(clk), .nReset(nReset), .rst(rst), .cnt_en(1'b1), .go(IORDY_done), .d(Teoc), .id(Teoc_m0), .done(Teoc_done), .q());
178
 
179
endmodule

powered by: WebSVN 2.1.0

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