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

Subversion Repositories ata

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

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

Line No. Rev Author Line
1 15 rherveille
//
2
// Project:             AT Atachement interface
3
// ATA-3 rev7B compliant
4
// Author:              Richard Herveille
5
// rev.: 1.0   June 29th, 2001. Initial Verilog release
6
// rev.: 1.1   July  3rd, 2001. Changed 'ADR_I[5:2]' into 'ADR_I' on output multiplexor sensitivity list.
7
// rev.: 1.2   July  9th, 2001. Fixed register control; registers latched data on all edge cycles instead when selected.
8
// rev.: 1.3   July 11th, 2001. Fixed case sensitivity error (nRESET instead of nReset) in "controller" module declaration.
9
// rev.: 1.4   July 26th, 2001. Fixed non-blocking assignments.
10
// rev.: 1.5 August 15th, 2001. Changed port-names to conform to new OpenCores naming-convention.
11
 
12
// DeviceType: OCIDEC-1: OpenCores IDE Controller type1
13
// Features: PIO Compatible Timing
14
// DeviceID: 0x01
15
// RevNo : 0x00
16
 
17
//
18
// Host signals:
19
// Reset
20
// DIOR-                read strobe. The falling edge enables data from device onto DD. The rising edge latches data at the host.
21
// DIOW-                write strobe. The rising edge latches data from DD into the device.
22
// DA(2:0)              3bit binary coded adress
23
// CS0-         select command block registers
24
// CS1-         select control block registers
25
 
26
`include "timescale.v"
27
 
28
module atahost_top (wb_clk_i, rst_nreset_i, wb_rst_i, wb_cyc_i, wb_stb_i, wb_ack_o, wb_err_o,
29
                wb_adr_i, wb_dat_i, wb_dat_o, wb_sel_i, wb_we_i, wb_inta_o,
30
                ata_resetn_pad_o, ata_dd_pad_i, ata_dd_pad_o, ata_dd_pad_oe, ata_da_pad_o, ata_cs0n_pad_o,
31
                ata_cs1n_pad_o, ata_diorn_pad_o, ata_diown_pad_o, ata_iordy_pad_i, ata_intrq_pad_i);
32
        //
33
        // Parameter declarations
34
        //
35
        parameter TWIDTH = 8;                         // counter width
36
        // PIO mode 0 settings (@100MHz clock)
37
        parameter PIO_mode0_T1   =  6;                // 70ns
38
        parameter PIO_mode0_T2   = 28;                // 290ns
39
        parameter PIO_mode0_T4   =  2;                // 30ns
40
        parameter PIO_mode0_Teoc = 23;                // 240ns ==> T0 - T1 - T2 = 600 - 70 - 290 = 240
41
 
42
        //
43
        // inputs & outputs
44
        //
45
 
46
        // WISHBONE SYSCON signals
47
        input wb_clk_i;                               // master clock in
48
        input rst_nreset_i;                           // asynchronous active low reset
49
        input wb_rst_i;                               // synchronous active high reset
50
 
51
        // WISHBONE SLAVE signals
52
        input        wb_cyc_i;                        // valid bus cycle input
53
        input        wb_stb_i;                        // strobe/core select input
54
        output       wb_ack_o;                        // strobe acknowledge output
55
        output       wb_err_o;                        // error output
56
        input  [6:2] wb_adr_i;                        // A6 = '1' ATA devices selected
57
                                                      //          A5 = '1' CS1- asserted, '0' CS0- asserted
58
                                                      //          A4..A2 ATA address lines
59
                                                      // A6 = '0' ATA controller selected
60
        input  [31:0] wb_dat_i;                       // Databus in
61
        output [31:0] wb_dat_o;                       // Databus out
62
        input  [ 3:0] wb_sel_i;                       // Byte select signals
63
        input         wb_we_i;                        // Write enable input
64
        output        wb_inta_o;                      // interrupt request signal
65
 
66
        // ATA signals
67
        output        ata_resetn_pad_o;
68
        input  [15:0] ata_dd_pad_i;
69
        output [15:0] ata_dd_pad_o;
70
        output        ata_dd_pad_oe;
71
        output [ 2:0] ata_da_pad_o;
72
        output        ata_cs0n_pad_o;
73
        output        ata_cs1n_pad_o;
74
 
75
        output        ata_diorn_pad_o;
76
        output        ata_diown_pad_o;
77
        input         ata_iordy_pad_i;
78
        input         ata_intrq_pad_i;
79
 
80
        //
81
        // constant declarations
82
        //
83
        parameter [3:0] DeviceId = 4'h1;
84
        parameter [3:0] RevisionNo = 4'h0;
85
 
86
        `define ATA_ATA_ADR wb_adr_i[6]
87
        `define ATA_CTRL_REG 4'b0000
88
        `define ATA_STAT_REG 4'b0001
89
        `define ATA_PIO_CMD 4'b0010
90
 
91
        //
92
        // Variable declarations
93
        //
94
 
95
        // registers
96
        wire        IDEctrl_IDEen, IDEctrl_rst;
97
        reg  [ 7:0] PIO_cmdport_T1, PIO_cmdport_T2, PIO_cmdport_T4, PIO_cmdport_Teoc;
98
        wire        PIO_cmdport_IORDYen;
99
        reg  [31:0] CtrlReg; // control register
100
 
101
        wire        PIOack;
102
        wire [15:0] PIOq;
103
 
104
        wire [31:0] stat;
105
 
106
        wire irq; // ATA bus IRQ signal
107
 
108
        /////////////////
109
        // Module body //
110
        /////////////////
111
 
112
        // generate bus cycle / address decoder
113
        wire w_acc  = &wb_sel_i[1:0];                        // word access
114
        wire dw_acc = &wb_sel_i;                             // double word access
115
 
116
        // bus error
117
        wire berr = `ATA_ATA_ADR ? !w_acc : !dw_acc;
118
 
119
        // PIO accesses at least 16bit wide
120
        wire PIOsel = wb_cyc_i & wb_stb_i & `ATA_ATA_ADR & w_acc;
121
 
122
        // CON accesses only 32bit wide
123
        wire CONsel = wb_cyc_i & wb_stb_i & !(`ATA_ATA_ADR) & dw_acc;
124
 
125
        // generate registers
126
 
127
        // generate register select signals
128 16 rudi
        wire sel_ctrl        = CONsel & wb_we_i & (wb_adr_i[5:2] == `ATA_CTRL_REG);
129
        wire sel_stat        = CONsel & wb_we_i & (wb_adr_i[5:2] == `ATA_STAT_REG);
130
        wire sel_PIO_cmdport = CONsel & wb_we_i & (wb_adr_i[5:2] == `ATA_PIO_CMD);
131 15 rherveille
        // reserved 0x03-0x0f --
132
 
133
        // generate control register
134
        always@(posedge wb_clk_i or negedge rst_nreset_i)
135
                if (~rst_nreset_i)
136
                        begin
137
                                CtrlReg[31:1] <= 0;
138
                                CtrlReg[0] <= 1'b1; // set reset bit (ATA-RESETn line)
139
                        end
140
                else if (wb_rst_i)
141
                        begin
142
                                CtrlReg[31:1] <= 0;
143
                                CtrlReg[0] <= 1'b1; // set reset bit (ATA-RESETn line)
144
                        end
145
                else if (sel_ctrl)
146
                        CtrlReg <= wb_dat_i;
147
 
148
        // assign bits
149
        assign IDEctrl_IDEen       = CtrlReg[7];
150
        assign PIO_cmdport_IORDYen = CtrlReg[1];
151
        assign IDEctrl_rst         = CtrlReg[0];
152
 
153
 
154
        // generate status register clearable bits
155
        reg dirq, int;
156
 
157
        always@(posedge wb_clk_i or negedge rst_nreset_i)
158
                if (~rst_nreset_i)
159
                        begin
160
                                int  <= 1'b0;
161
                                dirq <= 1'b0;
162
                        end
163
                else if (wb_rst_i)
164
                        begin
165
                                int  <= 1'b0;
166
                                dirq <= 1'b0;
167
                        end
168
                else
169
                        begin
170
                                int  <= (int | (irq & !dirq)) & !(sel_stat & !wb_dat_i[0]);
171
                                dirq <= irq;
172
                        end
173
 
174
        // assign status bits
175
        assign stat[31:28] = DeviceId;   // set Device ID
176
        assign stat[27:24] = RevisionNo; // set revision number
177
        assign stat[23: 1] = 0;          // --clear unused bits-- 
178
                                   // Although stat[7]=PIOtip this bit is zero, because it is impossible 
179
                                   // to read the status register and access the PIO registers at the same time.
180
        assign stat[0]     = int;
181
 
182
 
183
        // generate PIO compatible / command-port timing register
184
        always@(posedge wb_clk_i or negedge rst_nreset_i)
185
                if (~rst_nreset_i)
186
                        begin
187
                                PIO_cmdport_T1   <= PIO_mode0_T1;
188
                                PIO_cmdport_T2   <= PIO_mode0_T2;
189
                                PIO_cmdport_T4   <= PIO_mode0_T4;
190
                                PIO_cmdport_Teoc <= PIO_mode0_Teoc;
191
                        end
192
                else if (wb_rst_i)
193
                        begin
194
                                PIO_cmdport_T1   <= PIO_mode0_T1;
195
                                PIO_cmdport_T2   <= PIO_mode0_T2;
196
                                PIO_cmdport_T4   <= PIO_mode0_T4;
197
                                PIO_cmdport_Teoc <= PIO_mode0_Teoc;
198
                        end
199
                else if(sel_PIO_cmdport)
200
                        begin
201
                                PIO_cmdport_T1   <= wb_dat_i[ 7: 0];
202
                                PIO_cmdport_T2   <= wb_dat_i[15: 8];
203
                                PIO_cmdport_T4   <= wb_dat_i[23:16];
204
                                PIO_cmdport_Teoc <= wb_dat_i[31:24];
205
                        end
206
 
207
 
208
        //
209
        // hookup controller section
210
        //
211
        atahost_controller #(TWIDTH, PIO_mode0_T1, PIO_mode0_T2, PIO_mode0_T4, PIO_mode0_Teoc)
212
                u1 (
213
                        .clk(wb_clk_i),
214
                        .nReset(rst_nreset_i),
215
                        .rst(wb_rst_i),
216
                        .irq(irq),
217
                        .IDEctrl_rst(IDEctrl_rst),
218
                        .IDEctrl_IDEen(IDEctrl_IDEen),
219
                        .PIO_cmdport_T1(PIO_cmdport_T1),
220
                        .PIO_cmdport_T2(PIO_cmdport_T2),
221
                        .PIO_cmdport_T4(PIO_cmdport_T4),
222
                        .PIO_cmdport_Teoc(PIO_cmdport_Teoc),
223
                        .PIO_cmdport_IORDYen(PIO_cmdport_IORDYen),
224
                        .PIOreq(PIOsel),
225
                        .PIOack(PIOack),
226
                        .PIOa(wb_adr_i[5:2]),
227
                        .PIOd(wb_dat_i[15:0]),
228
                        .PIOq(PIOq),
229
                        .PIOwe(wb_we_i),
230
                        .RESETn(ata_resetn_pad_o),
231
                        .DDi(ata_dd_pad_i),
232
                        .DDo(ata_dd_pad_o),
233
                        .DDoe(ata_dd_pad_oe),
234
                        .DA(ata_da_pad_o),
235
                        .CS0n(ata_cs0n_pad_o),
236
                        .CS1n(ata_cs1n_pad_o),
237
                        .DIORn(ata_diorn_pad_o),
238
                        .DIOWn(ata_diown_pad_o),
239
                        .IORDY(ata_iordy_pad_i),
240
                        .INTRQ(ata_intrq_pad_i)
241
                );
242
 
243
        //
244
        // generate WISHBONE interconnect signals
245
        //
246
        reg [31:0] Q;
247
 
248
        // generate acknowledge signal
249
        assign wb_ack_o = PIOack | CONsel;
250
 
251
        // generate error signal
252
        assign wb_err_o = wb_cyc_i & wb_stb_i & berr;
253
 
254
        // generate interrupt signal
255
        assign wb_inta_o = stat[0];
256
 
257
        // generate output multiplexor
258
        always@(wb_adr_i or CtrlReg or stat or PIO_cmdport_T1 or PIO_cmdport_T2 or PIO_cmdport_T4 or PIO_cmdport_Teoc)
259
                case (wb_adr_i[5:2]) // synopsis full_case parallel_case
260
                        4'b0000: Q = CtrlReg;
261
                        4'b0001: Q = stat;
262
                        4'b0010: Q = {PIO_cmdport_Teoc, PIO_cmdport_T4, PIO_cmdport_T2, PIO_cmdport_T1};
263
                        default: Q = 0;
264
                endcase
265
 
266
        // assign DAT_O output
267
        assign wb_dat_o = `ATA_ATA_ADR ? {16'h0000, PIOq} : Q;
268
 
269
endmodule

powered by: WebSVN 2.1.0

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