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

Subversion Repositories ata

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

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

Line No. Rev Author Line
1 23 rherveille
/////////////////////////////////////////////////////////////////////
2
////                                                             ////
3
////  OCIDEC-1 ATA/ATAPI-5 Controller                            ////
4
////  Wishbone Slave interface (common for all OCIDEC cores)     ////
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
//
37
//  CVS Log
38
//
39
//  $Id: atahost_wb_slave.v,v 1.1 2002-02-18 14:25:43 rherveille Exp $
40
//
41
//  $Date: 2002-02-18 14:25:43 $
42
//  $Revision: 1.1 $
43
//  $Author: rherveille $
44
//  $Locker:  $
45
//  $State: Exp $
46
//
47
// Change History:
48
//               $Log: not supported by cvs2svn $
49
//
50
 
51
`include "timescale.v"
52
 
53
module atahost_wb_slave (
54
                clk_i, arst_i, rst_i, cyc_i, stb_i, ack_o, rty_o, err_o, adr_i, dat_i, dat_o, sel_i, we_i, inta_o,
55
                PIOsel, PIOtip, PIOack, PIOq, PIOpp_full, irq,
56
                DMAsel, DMAtip, DMAack, DMARxEmpty, DMATxFull, DMA_dmarq, DMAq,
57
                IDEctrl_rst, IDEctrl_IDEen, IDEctrl_FATR1, IDEctrl_FATR0, IDEctrl_ppen,
58
                DMActrl_DMAen, DMActrl_dir, DMActrl_BeLeC0, DMActrl_BeLeC1,
59
                PIO_cmdport_T1, PIO_cmdport_T2, PIO_cmdport_T4, PIO_cmdport_Teoc, PIO_cmdport_IORDYen,
60
                PIO_dport0_T1, PIO_dport0_T2, PIO_dport0_T4, PIO_dport0_Teoc, PIO_dport0_IORDYen,
61
                PIO_dport1_T1, PIO_dport1_T2, PIO_dport1_T4, PIO_dport1_Teoc, PIO_dport1_IORDYen,
62
                DMA_dev0_Tm, DMA_dev0_Td, DMA_dev0_Teoc, DMA_dev1_Tm, DMA_dev1_Td, DMA_dev1_Teoc
63
        );
64
 
65
        //
66
        // Parameters
67
        //
68
        parameter DeviceId   = 4'h0;
69
        parameter RevisionNo = 4'h0;
70
 
71
        // PIO mode 0 settings (@100MHz clock)
72
        parameter PIO_mode0_T1   =  6;                // 70ns
73
        parameter PIO_mode0_T2   = 28;                // 290ns
74
        parameter PIO_mode0_T4   =  2;                // 30ns
75
        parameter PIO_mode0_Teoc = 23;                // 240ns ==> T0 - T1 - T2 = 600 - 70 - 290 = 240
76
 
77
        // Multiword DMA mode 0 settings (@100MHz clock)
78
        parameter DMA_mode0_Tm   =  6;                // 50ns
79
        parameter DMA_mode0_Td   = 21;                // 215ns
80
        parameter DMA_mode0_Teoc = 21;                // 215ns ==> T0 - Td - Tm = 480 - 50 - 215 = 215
81
 
82
        //
83
        // inputs & outputs
84
        //
85
 
86
        // WISHBONE SYSCON signals
87
        input clk_i;                                // master clock in
88
        input arst_i;                               // asynchronous active low reset
89
        input rst_i;                                // synchronous active high reset
90
 
91
        // WISHBONE SLAVE signals
92
        input       cyc_i;                          // valid bus cycle input
93
        input       stb_i;                          // strobe/core select input
94
        output      ack_o;                          // strobe acknowledge output
95
        output      rty_o;                          // retry output
96
        output      err_o;                          // error output
97
        input [6:2] adr_i;                          // A6 = '1' ATA devices selected
98
                                                    //          A5 = '1' CS1- asserted, '0' CS0- asserted
99
                                                    //          A4..A2 ATA address lines
100
                                                    // A6 = '0' ATA controller selected
101
        input  [31:0] dat_i;                        // Databus in
102
        output [31:0] dat_o;                        // Databus out
103
        input  [ 3:0] sel_i;                        // Byte select signals
104
        input         we_i;                         // Write enable input
105
        output        inta_o;                       // interrupt request signal IDE0
106
 
107
        // PIO control input
108
        output        PIOsel;
109
        input         PIOtip;                       // PIO transfer in progress
110
        input         PIOack;                       // PIO acknowledge signal
111
        input  [15:0] PIOq;                         // PIO data input
112
        input         PIOpp_full;                   // PIO write-ping-pong buffers full
113
        input         irq;                          // interrupt signal input
114
 
115
        // DMA control inputs
116
        output       DMAsel;
117
        input        DMAtip;                        // DMA transfer in progress
118
        input        DMAack;                        // DMA transfer acknowledge
119
        input        DMARxEmpty;                    // DMA receive buffer empty
120
        input        DMATxFull;                     // DMA transmit buffer full
121
        input        DMA_dmarq;                     // wishbone DMA request
122
        input [31:0] DMAq;
123
 
124
        // outputs
125
        // control register outputs
126
        output IDEctrl_rst;
127
        output IDEctrl_IDEen;
128
        output IDEctrl_FATR1;
129
        output IDEctrl_FATR0;
130
        output IDEctrl_ppen;
131
        output DMActrl_DMAen;
132
        output DMActrl_dir;
133
        output DMActrl_BeLeC0;
134
        output DMActrl_BeLeC1;
135
 
136
        // CMD port timing registers
137
        output [7:0] PIO_cmdport_T1,
138
                     PIO_cmdport_T2,
139
                     PIO_cmdport_T4,
140
                     PIO_cmdport_Teoc;
141
        output       PIO_cmdport_IORDYen;
142
 
143
        reg [7:0] PIO_cmdport_T1,
144
                  PIO_cmdport_T2,
145
                  PIO_cmdport_T4,
146
                  PIO_cmdport_Teoc;
147
 
148
        // data-port0 timing registers
149
        output [7:0] PIO_dport0_T1,
150
                     PIO_dport0_T2,
151
                     PIO_dport0_T4,
152
                     PIO_dport0_Teoc;
153
        output       PIO_dport0_IORDYen;
154
 
155
        reg [7:0] PIO_dport0_T1,
156
                  PIO_dport0_T2,
157
                  PIO_dport0_T4,
158
                  PIO_dport0_Teoc;
159
 
160
        // data-port1 timing registers
161
        output [7:0] PIO_dport1_T1,
162
                     PIO_dport1_T2,
163
                     PIO_dport1_T4,
164
                     PIO_dport1_Teoc;
165
        output       PIO_dport1_IORDYen;
166
 
167
        reg [7:0] PIO_dport1_T1,
168
                  PIO_dport1_T2,
169
                  PIO_dport1_T4,
170
                  PIO_dport1_Teoc;
171
 
172
        // DMA device0 timing registers
173
        output [7:0] DMA_dev0_Tm,
174
                     DMA_dev0_Td,
175
                     DMA_dev0_Teoc;
176
 
177
        reg [7:0] DMA_dev0_Tm,
178
                  DMA_dev0_Td,
179
                  DMA_dev0_Teoc;
180
 
181
        // DMA device1 timing registers
182
        output [7:0] DMA_dev1_Tm,
183
                     DMA_dev1_Td,
184
                     DMA_dev1_Teoc;
185
 
186
        reg [7:0] DMA_dev1_Tm,
187
                  DMA_dev1_Td,
188
                  DMA_dev1_Teoc;
189
 
190
 
191
        //
192
        // constants
193
        //
194
 
195
        // addresses
196
        `define ATA_DEV_ADR adr_i[6]
197
        `define ATA_ADR     adr_i[5:2]
198
 
199
        `define ATA_CTRL_REG 4'b0000
200
        `define ATA_STAT_REG 4'b0001
201
        `define ATA_PIO_CMD  4'b0010
202
        `define ATA_PIO_DP0  4'b0011
203
        `define ATA_PIO_DP1  4'b0100
204
        `define ATA_DMA_DEV0 4'b0101
205
        `define ATA_DMA_DEV1 4'b0110
206
        // reserved //
207
        `define ATA_DMA_PORT 4'b1111
208
 
209
 
210
        //
211
        // signals
212
        //
213
 
214
        // registers
215
        reg  [31:0] CtrlReg; // control register
216
        wire [31:0] StatReg; // status register
217
 
218
        // store ping-pong-full signal
219
        reg store_pp_full;
220
 
221
 
222
        //
223
        // generate bus cycle / address decoder
224
        //
225
        wire w_acc  = &sel_i[1:0];                        // word access
226
        wire dw_acc = &sel_i;                             // double word access
227
 
228
        // bus error
229
        wire berr = `ATA_DEV_ADR ? !w_acc : !dw_acc;
230
 
231
        // PIO accesses at least 16bit wide, no PIO access during DMAtip or pingpong-full
232
        wire PIOsel = cyc_i & stb_i & `ATA_DEV_ADR & w_acc & !(DMAtip | store_pp_full);
233
 
234
        // CON accesses only 32bit wide
235
        wire CONsel = cyc_i & stb_i & !(`ATA_DEV_ADR) & dw_acc;
236
        wire DMAsel = CONsel & (`ATA_ADR == `ATA_DMA_PORT);
237
 
238
        // bus retry (OCIDEC-3 and above)
239
        // store PIOpp_full, we don't want a PPfull based retry initiated by the current bus-cycle
240
        always@(posedge clk_i)
241
                if (!PIOsel)
242
                        store_pp_full <= #1 PIOpp_full;
243
 
244
        wire brty = (`ATA_DEV_ADR & w_acc) & (DMAtip | store_pp_full);
245
 
246
        //
247
        // generate registers
248
        //
249
 
250
        // generate register select signals
251
        wire sel_ctrl        = CONsel & we_i & (`ATA_ADR == `ATA_CTRL_REG);
252
        wire sel_stat        = CONsel & we_i & (`ATA_ADR == `ATA_STAT_REG);
253
        wire sel_PIO_cmdport = CONsel & we_i & (`ATA_ADR == `ATA_PIO_CMD);
254
        wire sel_PIO_dport0  = CONsel & we_i & (`ATA_ADR == `ATA_PIO_DP0);
255
        wire sel_PIO_dport1  = CONsel & we_i & (`ATA_ADR == `ATA_PIO_DP1);
256
        wire sel_DMA_dev0    = CONsel & we_i & (`ATA_ADR == `ATA_DMA_DEV0);
257
        wire sel_DMA_dev1    = CONsel & we_i & (`ATA_ADR == `ATA_DMA_DEV1);
258
        // reserved 0x1c-0x38
259
        // reserved 0x3c : DMA-port
260
 
261
 
262
        // generate control register
263
        always@(posedge clk_i or negedge arst_i)
264
                if (~arst_i)
265
                        begin
266
                                CtrlReg[31:1] <= #1 0;
267
                                CtrlReg[0]    <= #1 1'b1; // set reset bit (ATA-RESETn line)
268
                        end
269
                else if (rst_i)
270
                        begin
271
                                CtrlReg[31:1] <= #1 0;
272
                                CtrlReg[0]    <= #1 1'b1; // set reset bit (ATA-RESETn line)
273
                        end
274
                else if (sel_ctrl)
275
                        CtrlReg <= #1 dat_i;
276
 
277
        // assign bits
278
        assign DMActrl_DMAen        = CtrlReg[15];
279
        assign DMActrl_dir          = CtrlReg[13];
280
        assign DMActrl_BeLeC1       = CtrlReg[9];
281
        assign DMActrl_BeLeC0       = CtrlReg[8];
282
        assign IDEctrl_IDEen        = CtrlReg[7];
283
        assign IDEctrl_FATR1        = CtrlReg[6];
284
        assign IDEctrl_FATR0        = CtrlReg[5];
285
        assign IDEctrl_ppen         = CtrlReg[4];
286
        assign PIO_dport1_IORDYen   = CtrlReg[3];
287
        assign PIO_dport0_IORDYen   = CtrlReg[2];
288
        assign PIO_cmdport_IORDYen  = CtrlReg[1];
289
        assign IDEctrl_rst          = CtrlReg[0];
290
 
291
 
292
        // generate status register clearable bits
293
        reg dirq, int;
294
 
295
        always@(posedge clk_i or negedge arst_i)
296
                if (~arst_i)
297
                        begin
298
                                int  <= #1 1'b0;
299
                                dirq <= #1 1'b0;
300
                        end
301
                else if (rst_i)
302
                        begin
303
                                int  <= #1 1'b0;
304
                                dirq <= #1 1'b0;
305
                        end
306
                else
307
                        begin
308
                                int  <= #1 (int | (irq & !dirq)) & !(sel_stat & !dat_i[0]);
309
                                dirq <= #1 irq;
310
                        end
311
 
312
        // assign status bits
313
        assign StatReg[31:28] = DeviceId;   // set Device ID
314
        assign StatReg[27:24] = RevisionNo; // set revision number
315
        assign StatReg[23:16] = 0;          // reserved
316
        assign StatReg[15]    = DMAtip;
317
        assign StatReg[14:11] = 0;
318
        assign StatReg[10]    = DMARxEmpty;
319
        assign StatReg[9]     = DMATxFull;
320
        assign StatReg[8]     = DMA_dmarq;
321
        assign StatReg[7]     = PIOtip;
322
        assign StatReg[6]     = PIOpp_full;
323
        assign StatReg[5:1]   = 0;          // reserved
324
        assign StatReg[0]     = int;
325
 
326
 
327
        // generate PIO compatible / command-port timing register
328
        always@(posedge clk_i or negedge arst_i)
329
                if (~arst_i)
330
                        begin
331
                                PIO_cmdport_T1   <= #1 PIO_mode0_T1;
332
                                PIO_cmdport_T2   <= #1 PIO_mode0_T2;
333
                                PIO_cmdport_T4   <= #1 PIO_mode0_T4;
334
                                PIO_cmdport_Teoc <= #1 PIO_mode0_Teoc;
335
                        end
336
                else if (rst_i)
337
                        begin
338
                                PIO_cmdport_T1   <= #1 PIO_mode0_T1;
339
                                PIO_cmdport_T2   <= #1 PIO_mode0_T2;
340
                                PIO_cmdport_T4   <= #1 PIO_mode0_T4;
341
                                PIO_cmdport_Teoc <= #1 PIO_mode0_Teoc;
342
                        end
343
                else if(sel_PIO_cmdport)
344
                        begin
345
                                PIO_cmdport_T1   <= #1 dat_i[ 7: 0];
346
                                PIO_cmdport_T2   <= #1 dat_i[15: 8];
347
                                PIO_cmdport_T4   <= #1 dat_i[23:16];
348
                                PIO_cmdport_Teoc <= #1 dat_i[31:24];
349
                        end
350
 
351
        // generate PIO device0 timing register
352
        always@(posedge clk_i or negedge arst_i)
353
                if (~arst_i)
354
                        begin
355
                                PIO_dport0_T1   <= #1 PIO_mode0_T1;
356
                                PIO_dport0_T2   <= #1 PIO_mode0_T2;
357
                                PIO_dport0_T4   <= #1 PIO_mode0_T4;
358
                                PIO_dport0_Teoc <= #1 PIO_mode0_Teoc;
359
                        end
360
                else if (rst_i)
361
                        begin
362
                                PIO_dport0_T1   <= #1 PIO_mode0_T1;
363
                                PIO_dport0_T2   <= #1 PIO_mode0_T2;
364
                                PIO_dport0_T4   <= #1 PIO_mode0_T4;
365
                                PIO_dport0_Teoc <= #1 PIO_mode0_Teoc;
366
                        end
367
                else if(sel_PIO_dport0)
368
                        begin
369
                                PIO_dport0_T1   <= #1 dat_i[ 7: 0];
370
                                PIO_dport0_T2   <= #1 dat_i[15: 8];
371
                                PIO_dport0_T4   <= #1 dat_i[23:16];
372
                                PIO_dport0_Teoc <= #1 dat_i[31:24];
373
                        end
374
 
375
        // generate PIO device1 timing register
376
        always@(posedge clk_i or negedge arst_i)
377
                if (~arst_i)
378
                        begin
379
                                PIO_dport1_T1   <= #1 PIO_mode0_T1;
380
                                PIO_dport1_T2   <= #1 PIO_mode0_T2;
381
                                PIO_dport1_T4   <= #1 PIO_mode0_T4;
382
                                PIO_dport1_Teoc <= #1 PIO_mode0_Teoc;
383
                        end
384
                else if (rst_i)
385
                        begin
386
                                PIO_dport1_T1   <= #1 PIO_mode0_T1;
387
                                PIO_dport1_T2   <= #1 PIO_mode0_T2;
388
                                PIO_dport1_T4   <= #1 PIO_mode0_T4;
389
                                PIO_dport1_Teoc <= #1 PIO_mode0_Teoc;
390
                        end
391
                else if(sel_PIO_dport1)
392
                        begin
393
                                PIO_dport1_T1   <= #1 dat_i[ 7: 0];
394
                                PIO_dport1_T2   <= #1 dat_i[15: 8];
395
                                PIO_dport1_T4   <= #1 dat_i[23:16];
396
                                PIO_dport1_Teoc <= #1 dat_i[31:24];
397
                        end
398
 
399
        // generate DMA device0 timing register
400
        always@(posedge clk_i or negedge arst_i)
401
                if (~arst_i)
402
                        begin
403
                                DMA_dev0_Tm   <= #1 DMA_mode0_Tm;
404
                                DMA_dev0_Td   <= #1 DMA_mode0_Td;
405
                                DMA_dev0_Teoc <= #1 DMA_mode0_Teoc;
406
                        end
407
                else if (rst_i)
408
                        begin
409
                                DMA_dev0_Tm   <= #1 DMA_mode0_Tm;
410
                                DMA_dev0_Td   <= #1 DMA_mode0_Td;
411
                                DMA_dev0_Teoc <= #1 DMA_mode0_Teoc;
412
                        end
413
                else if(sel_DMA_dev0)
414
                        begin
415
                                DMA_dev0_Tm   <= #1 dat_i[ 7: 0];
416
                                DMA_dev0_Td   <= #1 dat_i[15: 8];
417
                                DMA_dev0_Teoc <= #1 dat_i[31:24];
418
                        end
419
 
420
        // generate DMA device1 timing register
421
        always@(posedge clk_i or negedge arst_i)
422
                if (~arst_i)
423
                        begin
424
                                DMA_dev1_Tm   <= #1 DMA_mode0_Tm;
425
                                DMA_dev1_Td   <= #1 DMA_mode0_Td;
426
                                DMA_dev1_Teoc <= #1 DMA_mode0_Teoc;
427
                        end
428
                else if (rst_i)
429
                        begin
430
                                DMA_dev1_Tm   <= #1 DMA_mode0_Tm;
431
                                DMA_dev1_Td   <= #1 DMA_mode0_Td;
432
                                DMA_dev1_Teoc <= #1 DMA_mode0_Teoc;
433
                        end
434
                else if(sel_DMA_dev1)
435
                        begin
436
                                DMA_dev1_Tm   <= #1 dat_i[ 7: 0];
437
                                DMA_dev1_Td   <= #1 dat_i[15: 8];
438
                                DMA_dev1_Teoc <= #1 dat_i[31:24];
439
                        end
440
 
441
        //
442
        // generate WISHBONE interconnect signals
443
        //
444
        reg [31:0] Q;
445
 
446
        // generate acknowledge signal
447
        assign ack_o = PIOack | CONsel; // | DMAack; // since DMAack is derived from CONsel this is OK
448
 
449
        // generate error signal
450
        assign err_o = cyc_i & stb_i & berr;
451
 
452
        // generate retry signal (for OCIDEC-3 and above only)
453
        assign rty_o = cyc_i & stb_i & brty;
454
 
455
        // generate interrupt signal
456
        assign inta_o = StatReg[0];
457
 
458
        // generate output multiplexor
459
        always@(`ATA_ADR or CtrlReg or StatReg or
460
                        PIO_cmdport_T1 or PIO_cmdport_T2 or PIO_cmdport_T4 or PIO_cmdport_Teoc or
461
                        PIO_dport0_T1 or PIO_dport0_T2 or PIO_dport0_T4 or PIO_dport0_Teoc or
462
                        PIO_dport1_T1 or PIO_dport1_T2 or PIO_dport1_T4 or PIO_dport1_Teoc or
463
                        DMA_dev0_Tm or DMA_dev0_Td or DMA_dev0_Teoc or
464
                        DMA_dev1_Tm or DMA_dev1_Td or DMA_dev1_Teoc or
465
                        DMAq
466
                )
467
                case (`ATA_ADR) // synopsis full_case parallel_case
468
                        `ATA_CTRL_REG: Q = CtrlReg;
469
                        `ATA_STAT_REG: Q = StatReg;
470
                        `ATA_PIO_CMD : Q = {PIO_cmdport_Teoc, PIO_cmdport_T4, PIO_cmdport_T2, PIO_cmdport_T1};
471
                        `ATA_PIO_DP0 : Q = {PIO_dport0_Teoc, PIO_dport0_T4, PIO_dport0_T2, PIO_dport0_T1};
472
                        `ATA_PIO_DP1 : Q = {PIO_dport1_Teoc, PIO_dport1_T4, PIO_dport1_T2, PIO_dport1_T1};
473
                        `ATA_DMA_DEV0: Q = {DMA_dev0_Teoc, 8'h0, DMA_dev0_Td, DMA_dev0_Tm};
474
                        `ATA_DMA_DEV1: Q = {DMA_dev1_Teoc, 8'h0, DMA_dev1_Td, DMA_dev1_Tm};
475
                        `ATA_DMA_PORT: Q = DMAq;
476
                        default: Q = 0;
477
                endcase
478
 
479
        // assign DAT_O output
480
        assign dat_o = `ATA_DEV_ADR ? {16'h0, PIOq} : Q;
481
 
482
endmodule

powered by: WebSVN 2.1.0

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