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

Subversion Repositories eco32

[/] [eco32/] [trunk/] [fpga/] [mc/] [src/] [dsk/] [atactrl.v] - Blame information for rev 121

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

Line No. Rev Author Line
1 121 hellwig
//
2
// atactrl.v -- parallel ATA controller
3
//
4 27 hellwig
 
5 121 hellwig
 
6
`define ADDR_ALTERNATE_STATUS   4'b0110
7
`define ADDR_DEVICE_CONTROL     4'b0110
8
`define ADDR_DEVICE_ADDRESS     4'b0111
9
`define ADDR_DATA               4'b1000
10
`define ADDR_ERROR              4'b1001
11
`define ADDR_FEATURES           4'b1001
12
`define ADDR_SECTOR_COUNT       4'b1010
13
`define ADDR_LBA0               4'b1011
14
`define ADDR_LBA1               4'b1100
15
`define ADDR_LBA2               4'b1101
16
`define ADDR_LBA3_DRV           4'b1110
17
`define ADDR_STATUS             4'b1111
18
`define ADDR_COMMAND            4'b1111
19
 
20
 
21 27 hellwig
module ata_ctrl (
22
        input clk, reset,
23
 
24
        input bus_en, bus_wr,
25
        input [19:2] bus_addr,
26
        input [31:0] bus_din,
27
        output [31:0] bus_dout,
28
        output bus_wait,
29
        output bus_irq,
30
 
31
        inout [15:0] ata_d,
32
        output [2:0] ata_a,
33
        output ata_cs0_n, ata_cs1_n,
34
        output ata_dior_n, ata_diow_n,
35
        input ata_intrq,
36
        input ata_dmarq,
37
        output ata_dmack_n,
38
        input ata_iordy
39
);
40
 
41
// --- ATA IRQ line debouncing
42
reg debounced_ata_intrq, prev_ata_intrq;
43
reg [3:0] ata_intrq_debounce_counter;
44
 
45
// --- disk buffer
46
 
47
// interface to the bus
48
wire buffer_bus_wait;
49
wire [31:0] buffer_bus_dout;
50
 
51
// interface to the state machine
52
wire buffer_ata_write;
53
wire [11:1] buffer_ata_addr;
54
wire [15:0] buffer_ata_din;
55
wire [15:0] buffer_ata_dout;
56
wire buffer_bus_addressed;
57
wire buffer_bus_write;
58
reg buffer_bus_second_cycle;
59
 
60
ata_buffer buffer1 (
61
    .clk (clk),
62
    .bus_write (buffer_bus_write),
63
    .bus_addr (bus_addr [11:2]),
64
    .bus_din (bus_din),
65
    .bus_dout (buffer_bus_dout),
66
    .ata_write (buffer_ata_write),
67
    .ata_addr (buffer_ata_addr),
68
    .ata_din (buffer_ata_din),
69
    .ata_dout (buffer_ata_dout)
70
);
71
 
72
assign buffer_bus_addressed = bus_addr [19];
73
assign buffer_bus_wait = bus_en & !buffer_bus_second_cycle;
74
assign buffer_bus_write = bus_en & bus_wr &
75
    buffer_bus_addressed & !buffer_bus_second_cycle;
76
 
77
// --- control registers
78
 
79
// interface to the bus
80
wire control_bus_wait;
81
wire [31:0] control_bus_dout;
82
 
83
// interface to the state machine
84
reg [31:0] capacity;
85
reg [27:0] requestedSectorAddress;
86
reg [3:0] requestedSectorCount;
87
wire commandUnlocked;
88
reg enableInterrupts, requestedWrite, errorOutput;
89
reg operationFinished, diskInitialized;
90
wire control_bus_addressed;
91
 
92
assign control_bus_addressed = !bus_addr[19];
93
assign control_bus_wait = 0;
94
assign control_bus_dout =
95
        (bus_addr [3:2] == 2'b00) ? {ata_dmarq, 25'd0,
96
                diskInitialized, operationFinished,
97
                errorOutput, requestedWrite,
98
                enableInterrupts, 1'b0} :
99
        (bus_addr [3:2] == 2'b01) ? { 28'd0, requestedSectorCount } :
100
        (bus_addr [3:2] == 2'b10) ? { 4'd0, requestedSectorAddress } :
101
        capacity;
102
 
103
// --- ATA IO component
104
 
105
reg io_en, io_write;
106
wire io_wait;
107
reg [3:0] io_addr;
108
reg [15:0] io_data_out;
109
wire [15:0] io_data_in;
110
 
111
assign ata_dmack_n = 1'b1;
112
ata_io io (
113
        .clk(clk),
114
        .reset(reset),
115
        .bus_en(io_en),
116
        .bus_wr(io_write),
117
        .bus_addr(io_addr),
118
        .bus_din(io_data_out),
119
        .bus_dout(io_data_in),
120
        .bus_wait(io_wait),
121
        .ata_d(ata_d),
122
        .ata_a(ata_a),
123
        .ata_cs0_n(ata_cs0_n),
124
        .ata_cs1_n(ata_cs1_n),
125
        .ata_dior_n(ata_dior_n),
126
        .ata_diow_n(ata_diow_n),
127
        .ata_iordy(ata_iordy)
128
);
129
 
130
// --- bus interface
131
 
132
assign bus_dout = bus_addr [19] ? buffer_bus_dout : control_bus_dout;
133
assign bus_wait = bus_addr [19] ? buffer_bus_wait : control_bus_wait;
134
assign bus_irq = enableInterrupts & operationFinished;
135
 
136
// --- state machine
137
 
138
reg [4:0] state;
139
reg [7:0] aux_counter;
140
reg [2:0] sector_counter;
141
/*
142
    STARTUP DEBUG LOGGING
143
reg [15:0] debugTimer;
144
*/
145
 
146
wire startBit;
147
assign commandUnlocked = (state == 5'd8);
148
assign startBit = bus_en & bus_wr &
149
    (!bus_addr [19]) & (bus_addr [3:2] == 2'b00) &
150
    bus_din [0];
151
 
152
assign buffer_ata_write = (state == 5'd16) & (!io_wait);
153
assign buffer_ata_addr = {sector_counter, aux_counter [7:0]};
154
assign buffer_ata_din = io_data_in;
155
 
156
always @(posedge clk) begin
157
    if (reset) begin
158
 
159
        prev_ata_intrq <= 1'b0;
160
        debounced_ata_intrq <= 1'b0;
161
        ata_intrq_debounce_counter <= 4'b0;
162
 
163
        buffer_bus_second_cycle <= 1'b0;
164
 
165
        capacity <= 32'd0;
166
        requestedSectorAddress <= 32'd0;
167
        requestedSectorCount <= 4'b0000;
168
 
169
        enableInterrupts <= 1'b0;
170
        requestedWrite <= 1'b0;
171
        errorOutput <= 1'b0;
172
        operationFinished <= 1'b0;
173
        diskInitialized <= 1'b0;
174
 
175
        io_en <= 1'b0;
176
        io_write <= 1'b0;
177
        io_addr <= 32'd0;
178
        io_data_out <= 16'd0;
179
 
180
        state <= 5'd0;
181
        aux_counter <= 8'd0;
182
        sector_counter <= 3'd0;
183
 
184
/*
185
    STARTUP DEBUG LOGGING
186
        debugTimer <= 16'd0;
187
*/
188
 
189
    end else begin
190
 
191
        if (ata_intrq == prev_ata_intrq) begin
192
            if (ata_intrq_debounce_counter == 4'd0) begin
193
                debounced_ata_intrq <= ata_intrq;
194
            end else begin
195
                ata_intrq_debounce_counter <= ata_intrq_debounce_counter - 1;
196
            end
197
        end else begin
198
            ata_intrq_debounce_counter <= 4'd10;
199
        end
200
        prev_ata_intrq <= ata_intrq;
201
 
202
/*
203
    STARTUP DEBUG LOGGING
204
        debugTimer <= debugTimer + 1;
205
*/
206
 
207
        if (bus_en)
208
            buffer_bus_second_cycle <= !buffer_bus_second_cycle;
209
        else
210
            buffer_bus_second_cycle <= 1'b0;
211
 
212
        if (bus_en & bus_wr & control_bus_addressed) begin
213
                if (bus_addr [3:2] == 2'b00) begin
214
                            operationFinished <= bus_din [4];
215
                        if (commandUnlocked)
216
                                    requestedWrite <= bus_din [2];
217
                            enableInterrupts <= bus_din [1];
218
                    end
219
                    else if (bus_addr [3:2] == 2'b01 & commandUnlocked) begin
220
                        requestedSectorCount <= bus_din [3:0];
221
                    end
222
                    else if (bus_addr [3:2] == 2'b10 & commandUnlocked) begin
223
                        requestedSectorAddress <= bus_din [27:0];
224
                    end
225
            end
226
 
227
        if (!io_wait) begin
228
/*
229
    STARTUP DEBUG LOGGING
230
            buffer_ata_write <= 1;
231
            if (buffer_ata_addr < 2000)
232
                buffer_ata_addr <= buffer_ata_addr + 2;
233
            buffer_ata_din <= io_data_in;
234
*/
235
            case (state)
236
 
237
                // startup sequence: ask for access to command regs
238
                    // and drive
239
                    5'd0: begin
240
                        io_en <= 1'b1;
241
                            io_write <= 1'b0;
242
                            io_addr <= `ADDR_ALTERNATE_STATUS;
243
                state <= 5'd1;
244
                    end
245
 
246
                // startup sequence: wait for command regs and
247
                    // drive, or select drive 0 if ready
248
                    5'd1: begin
249
                        if (io_data_in [7:6] == 2'b01) begin
250
                                    // ready, so select drive 0
251
                                    io_write <= 1'b1;
252
                                    io_addr <= `ADDR_LBA3_DRV;
253
                                    io_data_out <= 8'b11100000;
254
                                    state <= 5'd2;
255
                            end else begin
256
                                // busy, so keep asking
257
                            end
258
                end
259
 
260
                    // startup sequence: send "identify drive" command
261
                    5'd2: begin
262
                        io_write <= 1'b1;
263
                            io_addr <= `ADDR_COMMAND;
264
                            io_data_out <= 16'h00ec;
265
                            state <= 5'd3;
266
                    end
267
 
268
            // wait for the ATA to send an IRQ, then read the status register
269
                    5'd3: begin
270
                if (debounced_ata_intrq) begin
271
                    io_en <= 1'b1;
272
                    io_write <= 1'b0;
273
                    io_addr <= `ADDR_STATUS;
274
                            aux_counter <= 8'd60;
275
                    state <= 5'd4;
276
                end else begin
277
                    io_en <= 1'b0;
278
                    io_write <= 1'b0;
279
                end
280
                    end
281
 
282
 
283
                    // skip 60 words from the data buffer, then read
284
                    // the high 16 bits of the capacity
285
            5'd4: begin
286
                        io_write <= 1'b0;
287
                            io_addr <= `ADDR_DATA;
288
                            if (aux_counter == 0) state <= 5'd5;
289
                            else aux_counter <= aux_counter - 1;
290
            end
291
 
292
                // store the high 16 bits of the capacity just
293
                    // read and read the low 16 bits
294
                    5'd5: begin
295
                        io_write <= 1'b0;
296
                            io_addr <= `ADDR_DATA;
297
                            capacity [15:0] <= io_data_in;
298
                            state <= 5'd6;
299
                    end
300
 
301
                // store the low 16 bits of the capacity,
302
            // then read another 194 words to finish the
303
            // "identify drive" buffer
304
                    5'd6: begin
305
                            capacity [31:16] <= io_data_in;
306
                            state <= 5'd7;
307
                        io_write <= 1'b0;
308
                            io_addr <= `ADDR_DATA;
309
                aux_counter <= 8'd193; // one is read now
310
                    end
311
 
312
            // skip another 193 words from the buffer
313
                    5'd7: begin
314
                if (aux_counter == 0) begin
315
                    io_en <= 1'b0;
316
                    io_write <= 1'b0;
317
                    state <= 5'd8;
318
                    diskInitialized <= 1'b1;
319
                        end else begin
320
                    aux_counter <= aux_counter - 1;
321
                end
322
            end
323
 
324
    //----------------------------------------------------------
325
 
326
            // ready and waiting for commands. Only on this
327
            // state is write access from the on-chip bus
328
            // allowed. When a request arrives, write the
329
            // drive/head/lba3 register and goto state 9.
330
            5'd8: begin
331
                if (startBit) begin
332
                    state <= 5'd19;
333
                    io_en <= 1'b1;
334
                    io_write <= 1'b0;
335
                    io_addr <= `ADDR_STATUS;
336
                end else begin
337
                    io_en <= 1'b0;
338
                end
339
            end
340
 
341
            5'd19: begin
342
              if (io_data_in[7] == 0) begin
343
                    state <= 5'd9;
344
                    io_en <= 1'b1;
345
                    io_write <= 1'b1;
346
                    io_addr <= `ADDR_LBA3_DRV;
347
                    io_data_out <=
348
                        { 8'd0, 4'b1110, requestedSectorAddress [27:24] };
349
                    sector_counter <= 3'd0;
350
              end else begin
351
                // read status again
352
              end
353
            end
354
 
355
            // next, write the lba2 register
356
            5'd9: begin
357
                io_addr <= `ADDR_LBA2;
358
                io_data_out <= { 8'd0, requestedSectorAddress [23:16] };
359
                state <= 5'd10;
360
            end
361
 
362
            // next, write the lba1 register
363
            5'd10: begin
364
                io_addr <= `ADDR_LBA1;
365
                io_data_out <= { 8'd0, requestedSectorAddress [15:8] };
366
                state <= 5'd11;
367
            end
368
 
369
            // next, write the lba0 register
370
            5'd11: begin
371
                io_addr <= `ADDR_LBA0;
372
                io_data_out <= { 8'd0, requestedSectorAddress [7:0] };
373
                state <= 5'd12;
374
            end
375
 
376
            // next, write the sector count register
377
            5'd12: begin
378
                io_addr <= `ADDR_SECTOR_COUNT;
379
                io_data_out <= { 8'd0, 4'd0, requestedSectorCount };
380
                state <= 5'd13;
381
            end
382
 
383
            // finally, write the command register
384
            5'd13: begin
385
                io_addr <= `ADDR_COMMAND;
386
                io_data_out <= requestedWrite ? 16'h30 : 16'h20;
387
                state <= 5'd14;
388
            end
389
 
390
            // now branch whether reading or writing.
391
            // for reading, wait for IRQ, then read status
392
            // for writing, wait for DRQ and simultaneously
393
            // fetch the first word from the buffer
394
            5'd14: begin
395
                if (requestedWrite) begin
396
                    io_en <= 1'b1;
397
                    io_write <= 1'b0;
398
                    io_addr <= `ADDR_STATUS;
399
                    state <= 5'd17;
400
                    aux_counter <= 8'd0;
401
                end else begin
402
                    if (debounced_ata_intrq) begin
403
                        io_en <= 1'b1;
404
                        io_write <= 1'b0;
405
                        io_addr <= `ADDR_STATUS;
406
                        state <= 5'd15;
407
                    end else begin
408
                        io_en <= 1'b0;
409
                    end
410
                end
411
            end
412
 
413
            // read 256 words of data
414
            5'd15: begin
415
                io_en <= 1'b1;
416
                io_write <= 1'b0;
417
                io_addr <= `ADDR_DATA;
418
                aux_counter <= 8'd0;
419
                state <= 5'd16;
420
            end
421
 
422
            // sample data in, and read next if needed. Data sampling is
423
            // done directly by the blockRAM, and the necessary wiring is
424
            // defined above.
425
            5'd16: begin
426
                if (aux_counter == 8'd255) begin
427
                    if (requestedSectorCount == 4'b0001) begin
428
                        io_en <= 1'b0;
429
                        state <= 5'd8;
430
                        errorOutput <= 1'b0;
431
                        operationFinished <= 1'b1;
432
                    end else begin
433
                        if (debounced_ata_intrq) begin
434
                            requestedSectorCount <= requestedSectorCount - 1;
435
                            sector_counter <= sector_counter + 1;
436
                            io_en <= 1'b1;
437
                            io_write <= 1'b0;
438
                            io_addr <= `ADDR_STATUS;
439
                            state <= 5'd15;
440
                        end else begin
441
                            io_en <= 1'b0;
442
                            // last word of finished sector is sampled
443
                            // repeatedly here (harmless)
444
                        end
445
                    end
446
                end else begin
447
                    aux_counter <= aux_counter + 1;
448
                end
449
            end
450
 
451
            // if DRQ is not yet set, wait for it. Otherwise send the
452
            // first data word to the ATA and fetch the next one
453
            5'd17: begin
454
                if (io_data_in[7] == 0 && io_data_in[3] == 1) begin
455
                    io_en <= 1'b1;
456
                    io_write <= 1'b1;
457
                    io_addr <= `ADDR_DATA;
458
                    io_data_out <= buffer_ata_dout;
459
                    aux_counter <= aux_counter + 1;
460
                    state <= 5'd18;
461
                end else begin
462
                    // read status again
463
                end
464
            end
465
 
466
            // write words to the buffer until finished. Note that since
467
            // an ATA transfer cycle takes at least two clock cycles, the
468
            // buffer is always read to buffer_ata_dout before that register
469
            // is used. After the transfer is finished, wait for IRQ, then
470
            // read the status register and select the correct next state
471
            // depending on whether more sectors must follow.
472
            5'd18: begin
473
                // loop until done. All addressing is done automatically.
474
                if (aux_counter == 8'd0) begin
475
                    if (debounced_ata_intrq) begin
476
                        io_en <= 1'b1;
477
                        io_write <= 1'b0;
478
                        io_addr <= `ADDR_STATUS;
479
                        if (requestedSectorCount == 4'b0001) begin
480
                            state <= 5'd8;
481
                            errorOutput <= 1'b0;
482
                            operationFinished <= 1'b1;
483
                        end else begin
484
                            requestedSectorCount <= requestedSectorCount - 1;
485
                            sector_counter <= sector_counter + 1;
486
                            state <= 5'd17;
487
                        end
488
                    end else begin
489
                        io_en <= 1'b0;
490
                    end
491
                end else begin
492
                    io_data_out <= buffer_ata_dout;
493
                    aux_counter <= aux_counter + 1;
494
                end
495
            end
496
 
497
            endcase
498
        end else begin
499
/*
500
    STARTUP DEBUG LOGGING
501
            buffer_ata_write <= 0;
502
*/
503
        end
504
    end
505
end
506
 
507
endmodule

powered by: WebSVN 2.1.0

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