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

Subversion Repositories eco32

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

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

powered by: WebSVN 2.1.0

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