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

Subversion Repositories eco32

[/] [eco32/] [tags/] [eco32-0.26/] [fpga/] [src/] [dsk/] [atactrl.v] - Blame information for rev 27

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

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

powered by: WebSVN 2.1.0

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