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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [rtl/] [soc/] [hdd/] [hdd.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * Copyright (c) 2014, Aleksander Osman
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * * Redistributions of source code must retain the above copyright notice, this
9
 *   list of conditions and the following disclaimer.
10
 *
11
 * * Redistributions in binary form must reproduce the above copyright notice,
12
 *   this list of conditions and the following disclaimer in the documentation
13
 *   and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
 
27
module hdd(
28
    input               clk,
29
    input               rst_n,
30
 
31
    //irq
32
    output reg          irq,
33
 
34
    //avalon slave
35
    input               io_address,
36
    input       [3:0]   io_byteenable,
37
    input               io_read,
38
    output reg  [31:0]  io_readdata,
39
    input               io_write,
40
    input       [31:0]  io_writedata,
41
 
42
    //ide shared port 0x3F6
43
    input               ide_3f6_read,
44
    output reg  [7:0]   ide_3f6_readdata,
45
    input               ide_3f6_write,
46
    input       [7:0]   ide_3f6_writedata,
47
 
48
    //master to control sd
49
    output      [31:0]  sd_master_address,
50
    input               sd_master_waitrequest,
51
    output              sd_master_read,
52
    input               sd_master_readdatavalid,
53
    input       [31:0]  sd_master_readdata,
54
    output              sd_master_write,
55
    output      [31:0]  sd_master_writedata,
56
 
57
    //slave with data from/to sd
58
    input       [8:0]   sd_slave_address,
59
    input               sd_slave_read,
60
    output reg  [31:0]  sd_slave_readdata,
61
    input               sd_slave_write,
62
    input       [31:0]  sd_slave_writedata,
63
 
64
    //management slave
65
    /*
66
    0x00.[31:0]:    identify write
67
    0x01.[16:0]:    media cylinders
68
    0x02.[4:0]:     media heads
69
    0x03.[8:0]:     media spt
70
    0x04.[13:0]:    media sectors per cylinder = spt * heads
71
    0x05.[31:0]:    media sectors total
72
    0x06.[31:0]:    media sd base
73
    */
74
    input       [2:0]   mgmt_address,
75
    input               mgmt_write,
76
    input       [31:0]  mgmt_writedata
77
);
78
 
79
//------------------------------------------------------------------------------
80
 
81
`define SD_AVALON_BASE_ADDRESS_FOR_HDD 32'h00000000
82
 
83
//------------------------------------------------------------------------------
84
 
85
reg io_read_last;
86
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) io_read_last <= 1'b0; else if(io_read_last) io_read_last <= 1'b0; else io_read_last <= io_read; end
87
wire io_read_valid = io_read && io_read_last == 1'b0;
88
 
89
reg sd_slave_read_last;
90
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) sd_slave_read_last <= 1'b0; else if(sd_slave_read_last) sd_slave_read_last <= 1'b0; else sd_slave_read_last <= sd_slave_read; end
91
wire sd_slave_read_valid = sd_slave_read && sd_slave_read_last == 1'b0;
92
 
93
//------------------------------------------------------------------------------
94
 
95
wire write_data_io =
96
    io_write && io_address == 1'b0 && io_byteenable[0] &&
97
    cmd_write_in_progress;
98
 
99
wire read_data_io =
100
    io_read_valid && io_address == 1'b0 && io_byteenable[0] && status_drq &&
101
    (cmd_read_in_progress || cmd_identify_in_progress);
102
 
103
wire [2:0] data_io_size =
104
    (io_byteenable[3:0] == 4'b1111)?    3'd4 :
105
    (io_byteenable[1:0] == 2'b11)?      3'd2 :
106
    (io_byteenable[0])?                 3'd1 :
107
                                        3'd0;
108
 
109
wire [7:0] status_value =
110
    (drive_select)?     8'h00 :
111
                        { status_busy,
112
                          status_drive_ready,
113
                          1'b0, //status write fault
114
                          1'b1, //status seek complete
115
                          status_drq,
116
                          1'b0, //status data corrected
117
                          status_index_pulse_counter == 4'd0 && status_index_pulse_first,
118
                          status_err
119
                        };
120
 
121
wire [15:0] cylinder_final = (drive_select)? 16'hFFFF : cylinder;
122
 
123
wire [31:0] io_readdata_next =
124
    (read_data_io)?                                                             from_hdd_result[31:0] :
125
    (io_read_valid && io_address == 1'b0 && io_byteenable[1:0] == 2'b10)?       { 16'd0, error_register, 8'd0 } :
126
    (io_read_valid && io_address == 1'b0 && io_byteenable[2:0] == 3'b100)?      { 8'd0,  sector_count,   16'd0 } :
127
    (io_read_valid && io_address == 1'b0 && io_byteenable[3:0] == 4'b1000)?     { sector, 24'd0 } :
128
    (io_read_valid && io_address == 1'b1 && io_byteenable[0] == 1'b1)?          { 24'd0, cylinder_final[7:0] } :
129
    (io_read_valid && io_address == 1'b1 && io_byteenable[1:0] == 2'b10)?       { 16'd0, cylinder_final[15:8], 8'd0 } :
130
    (io_read_valid && io_address == 1'b1 && io_byteenable[2:0] == 3'b100)?      { 8'd0, 8'h80 | ((lba_mode)? 8'h40 : 8'h00) | 8'h20 | ((drive_select)? 8'h10 : 8'h00) | ((drive_select)? 8'h00 : { 4'd0, head }), 16'd0 } :
131
    (io_read_valid && io_address == 1'b1 && io_byteenable[3:0] == 4'b1000)?     { status_value, 24'd0 } :
132
                                                                                32'd0; //used
133
 
134
always @(posedge clk or negedge rst_n) begin
135
    if(rst_n == 1'b0)   io_readdata <= 32'b0;
136
    else                io_readdata <= io_readdata_next;
137
end
138
 
139
always @(posedge clk or negedge rst_n) begin
140
    if(rst_n == 1'b0)   ide_3f6_readdata <= 8'b0;
141
    else                ide_3f6_readdata <= status_value;
142
end
143
 
144
//------------------------------------------------------------------------------ media management
145
 
146
reg [16:0] media_cylinders;
147
always @(posedge clk or negedge rst_n) begin
148
    if(rst_n == 1'b0)                           media_cylinders <= 17'd0;
149
    else if(mgmt_address == 3'd1 && mgmt_write) media_cylinders <= mgmt_writedata[16:0];
150
end
151
 
152
reg [4:0] media_heads;
153
always @(posedge clk or negedge rst_n) begin
154
    if(rst_n == 1'b0)                           media_heads <= 5'd0;
155
    else if(mgmt_address == 3'd2 && mgmt_write) media_heads <= mgmt_writedata[4:0];
156
end
157
 
158
reg [8:0] media_spt;
159
always @(posedge clk or negedge rst_n) begin
160
    if(rst_n == 1'b0)                           media_spt <= 9'd0;
161
    else if(mgmt_address == 3'd3 && mgmt_write) media_spt <= mgmt_writedata[8:0];
162
end
163
 
164
reg [13:0] media_spc; //sectors per cylinder = spt * heads
165
always @(posedge clk or negedge rst_n) begin
166
    if(rst_n == 1'b0)                           media_spc <= 14'd0; //14'd1008;
167
    else if(mgmt_address == 3'd4 && mgmt_write) media_spc <= mgmt_writedata[13:0];
168
end
169
 
170
reg [31:0] media_sectors;
171
always @(posedge clk or negedge rst_n) begin
172
    if(rst_n == 1'b0)                           media_sectors <= 32'd0; //32'd1032192;
173
    else if(mgmt_address == 3'd5 && mgmt_write) media_sectors <= mgmt_writedata;
174
end
175
 
176
reg [31:0] media_sd_base;
177
always @(posedge clk or negedge rst_n) begin
178
    if(rst_n == 1'b0)                           media_sd_base <= 32'd0;
179
    else if(mgmt_address == 3'd6 && mgmt_write) media_sd_base <= mgmt_writedata;
180
end
181
 
182
//------------------------------------------------------------------------------
183
 
184
reg status_drq;
185
always @(posedge clk or negedge rst_n) begin
186
    if(rst_n == 1'b0)                                                   status_drq <= 1'b0;
187
    else if(sw_reset_start)                                             status_drq <= 1'b0;
188
    else if(cmd_read_start || cmd_identify_start || cmd_seek_start)     status_drq <= 1'b0;
189
    else if(cmd_execute_drive_diag)                                     status_drq <= 1'b0;
190
    else if(cmd_initialize_start)                                       status_drq <= 1'b0;
191
    else if(cmd_verify_start)                                           status_drq <= 1'b0;
192
    else if(command_requires_drq)                                       status_drq <= 1'b1;
193
    else if(command_finished)                                           status_drq <= 1'b0;
194
    else if(drq_zero)                                                   status_drq <= 1'b0;
195
    else if(command_abort)                                              status_drq <= 1'b0;
196
end
197
 
198
reg status_busy;
199
always @(posedge clk or negedge rst_n) begin
200
    if(rst_n == 1'b0)                                                   status_busy <= 1'b0;
201
    else if(sw_reset_start)                                             status_busy <= 1'b1;
202
    else if(sw_reset_end)                                               status_busy <= 1'b0;
203
    else if(cmd_read_start || cmd_identify_start || cmd_seek_start)     status_busy <= 1'b1;
204
    else if(cmd_initialize_start)                                       status_busy <= 1'b0;
205
    else if(cmd_verify_start)                                           status_busy <= 1'b0;
206
    else if(command_requires_drq)                                       status_busy <= 1'b0;
207
    else if(command_finished)                                           status_busy <= 1'b0;
208
    else if(drq_zero)                                                   status_busy <= 1'b1;
209
    else if(command_abort)                                              status_busy <= 1'b0;
210
end
211
 
212
reg status_drive_ready;
213
always @(posedge clk or negedge rst_n) begin
214
    if(rst_n == 1'b0)               status_drive_ready <= 1'b1;
215
    else if(sw_reset_start)         status_drive_ready <= 1'b0;
216
    else if(sw_reset_end)           status_drive_ready <= 1'b1;
217
    else if(cmd_initialize_start)   status_drive_ready <= 1'b1;
218
    else if(cmd_features_start)     status_drive_ready <= 1'b1;
219
    else if(cmd_verify_start)       status_drive_ready <= 1'b1;
220
    else if(cmd_max_start)          status_drive_ready <= 1'b1;
221
    else if(command_requires_drq)   status_drive_ready <= 1'b1;
222
    else if(command_finished)       status_drive_ready <= 1'b1;
223
    else if(command_abort)          status_drive_ready <= 1'b1;
224
end
225
 
226
reg status_err;
227
always @(posedge clk or negedge rst_n) begin
228
    if(rst_n == 1'b0)               status_err <= 1'b0;
229
    else if(sw_reset_start)         status_err <= 1'b0;
230
    else if(command_requires_drq)   status_err <= 1'b0;
231
    else if(command_abort)          status_err <= 1'b1;
232
    else if(command_finished)       status_err <= 1'b0;
233
    else if(cmd_start)              status_err <= 1'b0;
234
end
235
 
236
reg [7:0] error_register;
237
always @(posedge clk or negedge rst_n) begin
238
    if(rst_n == 1'b0)                                                   error_register <= 8'h01;
239
    else if(sw_reset_start)                                             error_register <= 8'h01;
240
    else if(cmd_execute_drive_diag)                                     error_register <= 8'h01;
241
    else if(cmd_read_start || cmd_identify_start || cmd_seek_start)     error_register <= 8'h00;
242
    else if(command_requires_drq)                                       error_register <= 8'h00;
243
    else if(command_finished)                                           error_register <= 8'h00;
244
    else if(command_abort)                                              error_register <= 8'h04;
245
end
246
 
247
wire [3:0] status_index_pulse_counter_next = (status_index_pulse_counter == 4'd9)? 4'd0 : status_index_pulse_counter + 4'd1;
248
 
249
reg status_index_pulse_first;
250
always @(posedge clk or negedge rst_n) begin
251
    if(rst_n == 1'b0)                           status_index_pulse_first <= 1'b0;
252
    else if(status_index_pulse_counter != 4'd0) status_index_pulse_first <= 1'b1;
253
end
254
 
255
reg [3:0] status_index_pulse_counter;
256
always @(posedge clk or negedge rst_n) begin
257
    if(rst_n == 1'b0)                                                                                                       status_index_pulse_counter <= 4'd0;
258
    else if(~(drive_select) && (ide_3f6_read || (io_read_valid && io_address == 1'b1 && io_byteenable[3:0] == 4'b1000)))    status_index_pulse_counter <= status_index_pulse_counter_next;
259
end
260
 
261
reg [7:0] features;
262
always @(posedge clk or negedge rst_n) begin
263
    if(rst_n == 1'b0)                                                       features <= 8'h00;
264
    else if(io_write && io_address == 1'b0 && io_byteenable[1:0] == 2'b10)  features <= io_writedata[15:8];
265
end
266
 
267
reg [16:0] num_sectors;
268
always @(posedge clk or negedge rst_n) begin
269
    if(rst_n == 1'b0)                   num_sectors <= 17'd0;
270
    else if(lba48_transform_active)     num_sectors <= (sector_count == 8'd0 && hob_nsector == 8'd0)? 17'd65536 : { 1'b0, hob_nsector, sector_count };
271
    else if(lba48_transform_inactive)   num_sectors <= (sector_count == 8'd0)? 17'd256 : { 9'd0, sector_count };
272
    else if(update_location_by_one)     num_sectors <= num_sectors - 17'd1;
273
end
274
 
275
reg [7:0] sector_count;
276
always @(posedge clk or negedge rst_n) begin
277
    if(rst_n == 1'b0)                                                           sector_count <= 8'd1;
278
    else if(set_signature)                                                      sector_count <= 8'd1;
279
    else if(cmd_checkpower_start)                                               sector_count <= 8'hFF;
280
    else if(io_write && io_address == 1'b0 && io_byteenable[2:0] == 3'b100)     sector_count <= io_writedata[23:16];
281
    else if(update_location_by_one)                                             sector_count <= sector_count - 8'd1;
282
end
283
 
284
reg [7:0] hob_nsector;
285
always @(posedge clk or negedge rst_n) begin
286
    if(rst_n == 1'b0)                                                       hob_nsector <= 8'd0;
287
    else if(io_write && io_address == 1'b0 && io_byteenable[2:0] == 3'b100) hob_nsector <= sector_count;
288
end
289
 
290
reg drive_select;
291
always @(posedge clk or negedge rst_n) begin
292
    if(rst_n == 1'b0)                                                       drive_select <= 1'b0;
293
    else if(set_signature)                                                  drive_select <= 1'b0;
294
    else if(io_write && io_address == 1'b1 && io_byteenable[2:0] == 3'b100) drive_select <= io_writedata[20];
295
end
296
 
297
reg disable_irq;
298
always @(posedge clk or negedge rst_n) begin
299
    if(rst_n == 1'b0)       disable_irq <= 1'b0;
300
    else if(sw_reset_start) disable_irq <= 1'b0;
301
    else if(ide_3f6_write)  disable_irq <= ide_3f6_writedata[1];
302
end
303
 
304
wire sw_reset_start = ide_3f6_write && ide_3f6_writedata[2];
305
wire sw_reset_end   = ide_3f6_write && ~(ide_3f6_writedata[2]) && reset_in_progress;
306
 
307
reg reset_in_progress;
308
always @(posedge clk or negedge rst_n) begin
309
    if(rst_n == 1'b0)       reset_in_progress <= 1'b0;
310
    else if(ide_3f6_write)  reset_in_progress <= ide_3f6_writedata[2];
311
end
312
 
313
always @(posedge clk or negedge rst_n) begin
314
    if(rst_n == 1'b0)                           irq <= 1'b0;
315
    else if(sw_reset_start)                     irq <= 1'b0;
316
    else if(raise_interrupt && ~(disable_irq))  irq <= 1'b1; //raise more important than lower
317
    else if(lower_interrupt)                    irq <= 1'b0;
318
end
319
 
320
reg [7:0] current_command;
321
always @(posedge clk or negedge rst_n) begin
322
    if(rst_n == 1'b0)                                                                   current_command <= 8'b0;
323
    else if(sw_reset_start)                                                             current_command <= 8'b0;
324
    else if(cmd_read_start || cmd_write_start || cmd_identify_start || cmd_seek_start)  current_command <= io_writedata[31:24];
325
    else if(state == S_IDLE)                                                            current_command <= 8'd0;
326
end
327
 
328
reg lba_mode;
329
always @(posedge clk or negedge rst_n) begin
330
    if(rst_n == 1'b0)                                                       lba_mode <= 1'b0;
331
    else if(sw_reset_start)                                                 lba_mode <= 1'b0;
332
    else if(io_write && io_address == 1'b1 && io_byteenable[2:0] == 3'b100) lba_mode <= io_writedata[22];
333
end
334
 
335
reg [4:0] multiple_sectors;
336
always @(posedge clk or negedge rst_n) begin
337
    if(rst_n == 1'b0)           multiple_sectors <= 5'd0;
338
    else if(sw_reset_start)     multiple_sectors <= 5'd0;
339
    else if(cmd_multiple_start) multiple_sectors <= sector_count[4:0];
340
end
341
 
342
//------------------------------------------------------------------------------
343
 
344
wire [16:0] media_cylinders_minus_1 = media_cylinders - 17'd1;
345
 
346
reg [15:0] cylinder;
347
always @(posedge clk or negedge rst_n) begin
348
    if(rst_n == 1'b0)                                                                           cylinder <= 16'd0;
349
    else if(set_signature)                                                                      cylinder <= 16'd0;
350
    else if(io_write && io_address == 1'b1 && io_byteenable[0] == 1'b1)                         cylinder <= { cylinder[15:8], io_writedata[7:0] };
351
    else if(io_write && io_address == 1'b1 && io_byteenable[1:0] == 2'b10)                      cylinder <= { io_writedata[15:8], cylinder[7:0] };
352
    else if(update_location_to_overflow)                                                        cylinder <= media_sectors[23:8];
353
    else if(update_location_by_one && lba_mode && current_command_lba48)                        cylinder <= location_lba48_plus_1[23:8];
354
    else if(update_location_by_one && lba_mode)                                                 cylinder <= location_lba28_plus_1[23:8];
355
 
356
    else if(update_location_to_max && lba_mode && current_command_lba48)                        cylinder <= location_lba48_max[23:8];
357
    else if(update_location_to_max && lba_mode)                                                 cylinder <= location_lba28_max[23:8];
358
 
359
    else if(update_location_chs_cylinder_only && { 1'b0, cylinder } < media_cylinders - 17'd1)  cylinder <= cylinder + 16'd1;
360
    else if(update_location_chs_cylinder_only)                                                  cylinder <= media_cylinders_minus_1[15:0];
361
    else if(cmd_calibrate_start)                                                                cylinder <= 16'd0;
362
end
363
 
364
reg [3:0] head;
365
always @(posedge clk or negedge rst_n) begin
366
    if(rst_n == 1'b0)   head <= 4'd0;
367
    else if(set_signature)                                                      head <= 4'd0;
368
    else if(io_write && io_address == 1'b1 && io_byteenable[2:0] == 3'b100)     head <= io_writedata[19:16];
369
    else if(update_location_to_overflow && ~(current_command_read_lba48))       head <= media_sectors[27:24];
370
    else if(update_location_by_one && lba_mode && ~(current_command_lba48))     head <= location_lba28_plus_1[27:24];
371
    else if(update_location_to_max && lba_mode && ~(current_command_lba48))     head <= location_lba28_max[27:24];
372
    else if(update_location_chs_head_only)                                      head <= head + 4'd1;
373
    else if(update_location_chs_cylinder_only)                                  head <= 4'd0;
374
end
375
 
376
reg [7:0] sector;
377
always @(posedge clk or negedge rst_n) begin
378
    if(rst_n == 1'b0)                                                           sector <= 8'd1;
379
    else if(set_signature)                                                      sector <= 8'd1;
380
    else if(io_write && io_address == 1'b0 && io_byteenable[3:0] == 4'b1000)    sector <= io_writedata[31:24];
381
    else if(update_location_to_overflow)                                        sector <= media_sectors[7:0];
382
    else if(update_location_by_one && lba_mode && current_command_lba48)        sector <= location_lba48_plus_1[7:0];
383
    else if(update_location_by_one && lba_mode)                                 sector <= location_lba28_plus_1[7:0];
384
    else if(update_location_to_max && lba_mode && current_command_lba48)        sector <= location_lba48_max[7:0];
385
    else if(update_location_to_max && lba_mode)                                 sector <= location_lba28_max[7:0];
386
    else if(update_location_chs_sector_only)                                    sector <= sector + 8'd1;
387
    else if(update_location_chs_head_only || update_location_chs_cylinder_only) sector <= 8'd1;
388
end
389
 
390
reg [7:0] hob_hcyl;
391
always @(posedge clk or negedge rst_n) begin
392
    if(rst_n == 1'b0)   hob_hcyl <= 8'd0;
393
    else if(io_write && io_address == 1'b1 && io_byteenable[1:0] == 2'b10)      hob_hcyl <= cylinder[15:8];
394
    else if(update_location_to_overflow && current_command_read_lba48)          hob_hcyl <= 8'd0;
395
    else if(update_location_by_one && lba_mode && current_command_lba48)        hob_hcyl <= location_lba48_plus_1[47:40];
396
    else if(update_location_to_max && lba_mode && current_command_lba48)        hob_hcyl <= location_lba48_max[47:40];
397
end
398
 
399
reg [7:0] hob_lcyl;
400
always @(posedge clk or negedge rst_n) begin
401
    if(rst_n == 1'b0)   hob_lcyl <= 8'd0;
402
    else if(io_write && io_address == 1'b1 && io_byteenable[0] == 1'b1)         hob_lcyl <= cylinder[7:0];
403
    else if(update_location_to_overflow && current_command_read_lba48)          hob_lcyl <= 8'd0;
404
    else if(update_location_by_one && lba_mode && current_command_lba48)        hob_lcyl <= location_lba48_plus_1[39:32];
405
    else if(update_location_to_max && lba_mode && current_command_lba48)        hob_lcyl <= location_lba48_max[39:32];
406
end
407
 
408
reg [7:0] hob_sector;
409
always @(posedge clk or negedge rst_n) begin
410
    if(rst_n == 1'b0)   hob_sector <= 8'd0;
411
    else if(io_write && io_address == 1'b0 && io_byteenable[3:0] == 4'b1000)    hob_sector <= sector;
412
    else if(update_location_to_overflow && current_command_read_lba48)          hob_sector <= media_sectors[31:24];
413
    else if(update_location_by_one && lba_mode && current_command_lba48)        hob_sector <= location_lba48_plus_1[31:24];
414
    else if(update_location_to_max && lba_mode && current_command_lba48)        hob_sector <= location_lba48_max[31:24];
415
end
416
 
417
wire [27:0] location_lba28_plus_1 = { head, cylinder, sector } + 28'd1;
418
wire [47:0] location_lba48_plus_1 = { hob_hcyl, hob_lcyl, hob_sector, cylinder, sector } + 48'd1;
419
 
420
wire [27:0] location_lba28_max = (media_sectors[31:28] != 4'd0)? 28'hFFFFFFF : media_sectors[27:0] - 28'd1;
421
wire [47:0] location_lba48_max = { 16'd0, media_sectors - 32'd1 };
422
 
423
//------------------------------------------------------------------------------ update location
424
 
425
wire update_location_to_overflow =
426
    state == S_COUNT_DECISION && logical_sector[47:32] == 16'd0 && logical_sector[31:0] < media_sectors &&
427
    current_command_read_multiple && lba_mode && (current_command_read_lba48 || media_sectors[31:28] == 4'd0) &&
428
    (logical_sector[31:0] + { 27'd0, multiple_final_read }) > media_sectors;
429
 
430
wire update_location_to_max = cmd_max_start;
431
 
432
wire update_location_by_one =
433
    (state == S_SD_READ_WAIT_FOR_DATA && sd_slave_write && sd_counter == 7'd127) ||
434
    (state == S_SD_WRITE_WAIT_FOR_DATA && sd_slave_read_valid && sd_counter == 7'd127);
435
 
436
wire update_location_chs_sector_only = update_location_by_one && ~(lba_mode) &&
437
    { 1'b0, sector } < media_spt;
438
 
439
wire update_location_chs_head_only = update_location_by_one && ~(lba_mode) &&
440
    { 1'b0, sector } == media_spt && { 1'b0, head } < media_heads - 5'd1;
441
 
442
wire update_location_chs_cylinder_only = update_location_by_one && ~(lba_mode) &&
443
    { 1'b0, sector } == media_spt && { 1'b0, head } == media_heads - 5'd1;
444
 
445
//------------------------------------------------------------------------------ current command
446
 
447
wire current_command_lba48 = current_command_read_lba48 || current_command_write_lba48 ||
448
    (cmd_max_start && io_writedata[31:24] == 8'h27);
449
 
450
wire cmd_read_in_progress          = current_command == 8'h24 || current_command == 8'h29 || current_command == 8'h20 || current_command == 8'h21 || current_command == 8'hC4;
451
wire current_command_read_multiple = current_command == 8'hC4 || current_command == 8'h29;
452
wire current_command_read_lba48    = current_command == 8'h24 || current_command == 8'h29;
453
 
454
wire cmd_identify_in_progress = current_command == 8'hEC || current_command == 8'hA1;
455
 
456
wire cmd_write_in_progress          = current_command == 8'h30 || current_command == 8'hC5 || current_command == 8'h34 || current_command == 8'h39;
457
wire current_command_write_multiple = current_command == 8'hC5 || current_command == 8'h39;
458
wire current_command_write_lba48    = current_command == 8'h34 || current_command == 8'h39;
459
 
460
//------------------------------------------------------------------------------ command
461
 
462
wire cmd_start =
463
    io_write && io_address == 1'b1 && io_byteenable[3:0] == 4'b1000 && ~(drive_select) && ~(status_busy);
464
 
465
//calibrate
466
wire cmd_calibrate_start = cmd_start && io_writedata[31:24] >= 8'h10 && io_writedata[31:24] <= 8'h1F;
467
 
468
//read
469
wire cmd_read_prepare = cmd_start && (io_writedata[31:24] == 8'h24 || io_writedata[31:24] == 8'h29 || io_writedata[31:24] == 8'h20 || io_writedata[31:24] == 8'h21 || io_writedata[31:24] == 8'hC4);
470
 
471
wire cmd_read_abort_at_start = cmd_read_prepare && (
472
    (~(lba_mode) && head == 4'd0 && cylinder == 16'd0 && sector == 8'd0) ||
473
    ((io_writedata[31:24] == 8'hC4 || io_writedata[31:24] == 8'h29) && multiple_sectors == 5'd0)
474
);
475
 
476
wire cmd_read_start = cmd_read_prepare && ~(cmd_read_abort_at_start);
477
 
478
//write
479
wire cmd_write_prepare = cmd_start && (io_writedata[31:24] == 8'h30 || io_writedata[31:24] == 8'hC5 || io_writedata[31:24] == 8'h34 || io_writedata[31:24] == 8'h39);
480
 
481
wire cmd_write_abort_at_start = cmd_write_prepare && (
482
    ((io_writedata[31:24] == 8'hC5 || io_writedata[31:24] == 8'h39) && multiple_sectors == 5'd0)
483
);
484
 
485
wire cmd_write_start = cmd_write_prepare && ~(cmd_write_abort_at_start);
486
 
487
wire write_data_ready =
488
    (current_command_write_multiple    && to_hdd_count >= { multiple_final_read, 7'd0 }) ||
489
    (~(current_command_write_multiple) && to_hdd_count >= 12'd128);
490
 
491
//diag
492
wire cmd_execute_drive_diag = cmd_start && io_writedata[31:24] == 8'h90;
493
 
494
//initialize
495
wire cmd_initialize_prepare = cmd_start && io_writedata[31:24] == 8'h91;
496
 
497
wire cmd_initialize_abort_at_start = cmd_initialize_prepare && (
498
    ({ 1'b0, sector_count } != media_spt) ||
499
    (head != 4'd0 && { 1'b0, head } != media_heads - 5'd1)
500
);
501
 
502
wire cmd_initialize_start = cmd_initialize_prepare && ~(cmd_initialize_abort_at_start);
503
 
504
//identify
505
wire cmd_identify_start = cmd_start && io_writedata[31:24] == 8'hEC;
506
 
507
//set features
508
wire cmd_features_prepare = cmd_start && io_writedata[31:24] == 8'hEF;
509
 
510
wire cmd_features_abort_at_start = cmd_features_prepare && (
511
    (features == 8'h03 && (sector_count[7:3] != 5'd0 && sector_count[7:3] != 5'd1 && sector_count[7:3] != 5'd4 && sector_count[7:3] != 5'd8)) ||
512
    (features != 8'h03 && features != 8'h02 && features != 8'h82 && features != 8'hAA && features != 8'h55 && features != 8'hCC && features != 8'h66)
513
);
514
 
515
wire cmd_features_start = cmd_features_prepare && ~(cmd_features_abort_at_start);
516
 
517
//read verify sectors
518
wire cmd_verify_start = cmd_start && (io_writedata[31:24] == 8'h40 || io_writedata[31:24] == 8'h41 || io_writedata[31:24] == 8'h42);
519
 
520
//set multiple
521
 
522
//if changed - fix cmd_multiple_abort_at_start
523
`define MAX_MULTIPLE_SECTORS 16
524
 
525
wire cmd_multiple_prepare = cmd_start && io_writedata[31:24] == 8'hC6;
526
 
527
wire cmd_multiple_abort_at_start = cmd_multiple_prepare && (
528
    (sector_count > `MAX_MULTIPLE_SECTORS) ||
529
    (sector_count != 8'd1 && sector_count != 8'd2 && sector_count != 8'd4 && sector_count != 8'd8 && sector_count != 8'd16) ||
530
    (sector_count == 8'd0)
531
);
532
 
533
wire cmd_multiple_start = cmd_multiple_prepare && ~(cmd_multiple_abort_at_start);
534
 
535
//power
536
wire cmd_power_start = cmd_start && (io_writedata[31:24] == 8'hE0 || io_writedata[31:24] == 8'hE1 || io_writedata[31:24] == 8'hE7 || io_writedata[31:24] == 8'hEA);
537
 
538
//check power
539
wire cmd_checkpower_start = cmd_start && io_writedata[31:24] == 8'hE5;
540
 
541
//seek
542
wire cmd_seek_start = cmd_start && io_writedata[31:24] == 8'h70;
543
 
544
wire cmd_seek_in_progress = current_command == 8'h70;
545
 
546
//max address
547
wire cmd_max_prepare = cmd_start && (io_writedata[31:24] == 8'h27 || io_writedata[31:24] == 8'hF8);
548
 
549
wire cmd_max_abort_at_start = cmd_max_prepare && (
550
    ~(lba_mode)
551
);
552
 
553
wire cmd_max_start = cmd_max_prepare && ~(cmd_max_abort_at_start);
554
 
555
//unknown
556
wire cmd_unknown_start = cmd_start &&
557
    ~(cmd_calibrate_start) &&
558
    ~(cmd_read_prepare) &&
559
    ~(cmd_write_prepare) &&
560
    ~(cmd_execute_drive_diag) &&
561
    ~(cmd_initialize_prepare) &&
562
    ~(cmd_identify_start) &&
563
    ~(cmd_features_prepare) &&
564
    ~(cmd_verify_start) &&
565
    ~(cmd_multiple_prepare) &&
566
    ~(cmd_power_start) &&
567
    ~(cmd_checkpower_start) &&
568
    ~(cmd_seek_start) &&
569
    ~(cmd_max_prepare);
570
 
571
//location
572
wire lba48_transform_active =
573
    (cmd_read_start   && (io_writedata[31:24] == 8'h24 || io_writedata[31:24] == 8'h29)) ||
574
    (cmd_write_start  && (io_writedata[31:24] == 8'h34 || io_writedata[31:24] == 8'h39)) ||
575
    (cmd_verify_start &&  io_writedata[31:24] == 8'h42) ||
576
    (cmd_max_start    &&  io_writedata[31:24] == 8'h27);
577
 
578
wire lba48_transform_inactive = ~(lba48_transform_active) && (cmd_read_start || cmd_write_start || cmd_verify_start || cmd_max_start);
579
 
580
wire set_signature =
581
    cmd_execute_drive_diag ||
582
    sw_reset_end;
583
 
584
//------------------------------------------------------------------------------
585
 
586
localparam [3:0] S_IDLE                     = 4'd0;
587
 
588
localparam [3:0] S_PREPARE_COUNT            = 4'd1;
589
localparam [3:0] S_COUNT_LOGICAL            = 4'd2;
590
localparam [3:0] S_COUNT_FINAL              = 4'd3;
591
localparam [3:0] S_COUNT_DECISION           = 4'd4;
592
 
593
localparam [3:0] S_SD_MUTEX                 = 4'd5;
594
localparam [3:0] S_SD_AVALON_BASE           = 4'd6;
595
localparam [3:0] S_SD_ADDRESS               = 4'd7;
596
localparam [3:0] S_SD_BLOCK_COUNT           = 4'd8;
597
 
598
localparam [3:0] S_SD_CONTROL               = 4'd9;
599
localparam [3:0] S_SD_READ_WAIT_FOR_DATA    = 4'd10;
600
 
601
localparam [3:0] S_WAIT_FOR_EMPTY_READ_FIFO = 4'd11;
602
 
603
localparam [3:0] S_IDENTIFY_COPY            = 4'd12;
604
 
605
localparam [3:0] S_WAIT_FOR_FULL_WRITE_FIFO = 4'd13;
606
localparam [3:0] S_SD_WRITE_WAIT_FOR_DATA   = 4'd14;
607
 
608
localparam [3:0] S_IDENTIFY_FILL            = 4'd15;
609
 
610
reg [3:0] state;
611
always @(posedge clk or negedge rst_n) begin
612
    if(rst_n == 1'b0)                                                                                                       state <= S_IDLE;
613
 
614
    //read
615
    else if(state == S_IDLE && cmd_read_start)                                                                              state <= S_PREPARE_COUNT;
616
        //count
617
    else if(state == S_COUNT_DECISION && ~(count_decision_immediate_error) && cmd_read_in_progress)                         state <= S_SD_MUTEX;
618
        //sd
619
    else if(state == S_SD_CONTROL && sd_master_waitrequest == 1'b0 && cmd_read_in_progress)                                 state <= S_SD_READ_WAIT_FOR_DATA;
620
    else if(state == S_SD_READ_WAIT_FOR_DATA && logical_sector_count == 5'd0)                                               state <= S_WAIT_FOR_EMPTY_READ_FIFO;
621
    else if(state == S_WAIT_FOR_EMPTY_READ_FIFO && from_hdd_empty_valid && num_sectors == 17'd0 && cmd_read_in_progress)    state <= S_IDLE;
622
    else if(state == S_WAIT_FOR_EMPTY_READ_FIFO && from_hdd_empty_valid && cmd_read_in_progress)                            state <= S_PREPARE_COUNT;
623
 
624
    //seek
625
    else if(state == S_IDLE && cmd_seek_start)                                                                      state <= S_PREPARE_COUNT;
626
        //count
627
    else if(state == S_COUNT_DECISION && ~(count_decision_immediate_error) && cmd_seek_in_progress)                 state <= S_IDLE;
628
 
629
    //identify
630
    else if(state == S_IDLE && cmd_identify_start)                                                                  state <= S_IDENTIFY_FILL;
631
    else if(state == S_IDENTIFY_FILL && identify_counter == 7'd127)                                                 state <= S_WAIT_FOR_EMPTY_READ_FIFO;
632
    else if(state == S_WAIT_FOR_EMPTY_READ_FIFO && from_hdd_empty_valid && cmd_identify_in_progress)                state <= S_IDLE;
633
 
634
    //write
635
    else if(state == S_IDLE && cmd_write_start)                                                                     state <= S_WAIT_FOR_FULL_WRITE_FIFO;
636
    else if(state == S_WAIT_FOR_FULL_WRITE_FIFO && write_data_ready)                                                state <= S_PREPARE_COUNT;
637
        //count
638
    else if(state == S_COUNT_DECISION && ~(count_decision_immediate_error) && cmd_write_in_progress)                state <= S_SD_MUTEX;
639
        //sd
640
    else if(state == S_SD_CONTROL && sd_master_waitrequest == 1'b0 && cmd_write_in_progress)                        state <= S_SD_WRITE_WAIT_FOR_DATA;
641
    else if(state == S_SD_WRITE_WAIT_FOR_DATA && logical_sector_count == 5'd0 && num_sectors == 17'd0)              state <= S_IDLE;
642
    else if(state == S_SD_WRITE_WAIT_FOR_DATA && logical_sector_count == 5'd0)                                      state <= S_WAIT_FOR_FULL_WRITE_FIFO;
643
 
644
    //count
645
    else if(state == S_PREPARE_COUNT)                                                                               state <= S_COUNT_LOGICAL;
646
    else if(state == S_COUNT_LOGICAL && mult1_b == 14'd0 && mult2_b == 9'd0)                                        state <= S_COUNT_FINAL;
647
    else if(state == S_COUNT_FINAL)                                                                                 state <= S_COUNT_DECISION;
648
    else if(state == S_COUNT_DECISION && count_decision_immediate_error)                                            state <= S_IDLE;
649
 
650
    //sd read/write
651
    else if(state == S_SD_MUTEX && sd_master_readdatavalid && sd_master_readdata[2:0] == 3'd2)                      state <= S_SD_AVALON_BASE;
652
    else if(state == S_SD_AVALON_BASE && sd_master_waitrequest == 1'b0)                                             state <= S_SD_ADDRESS;
653
    else if(state == S_SD_ADDRESS     && sd_master_waitrequest == 1'b0)                                             state <= S_SD_BLOCK_COUNT;
654
    else if(state == S_SD_BLOCK_COUNT && sd_master_waitrequest == 1'b0)                                             state <= S_SD_CONTROL;
655
end
656
 
657
//------------------------------------------------------------------------------
658
 
659
wire drq_zero =
660
    (state == S_WAIT_FOR_EMPTY_READ_FIFO && from_hdd_empty_valid && cmd_read_in_progress) ||
661
    (state == S_WAIT_FOR_FULL_WRITE_FIFO && write_data_ready);
662
 
663
wire command_finished =
664
    (state == S_WAIT_FOR_EMPTY_READ_FIFO && from_hdd_empty_valid && cmd_read_in_progress && num_sectors == 17'd0) ||
665
    (state == S_WAIT_FOR_EMPTY_READ_FIFO && from_hdd_empty_valid && cmd_identify_in_progress) ||
666
    (state == S_SD_WRITE_WAIT_FOR_DATA && logical_sector_count == 5'd0 && num_sectors == 17'd0) ||
667
    cmd_calibrate_start ||
668
    cmd_multiple_start ||
669
    cmd_power_start ||
670
    cmd_checkpower_start ||
671
    (state == S_COUNT_DECISION && ~(count_decision_immediate_error) && cmd_seek_in_progress);
672
 
673
wire command_requires_drq =
674
    (state == S_SD_READ_WAIT_FOR_DATA && logical_sector_count == 5'd0) ||
675
    (state == S_IDENTIFY_FILL && identify_counter == 7'd127) ||
676
    (state == S_SD_WRITE_WAIT_FOR_DATA && logical_sector_count == 5'd0 && num_sectors > 17'd0) ||
677
    (state == S_IDLE && cmd_write_start);
678
 
679
wire raise_interrupt =
680
    command_requires_drq ||
681
    command_abort ||
682
    (state == S_SD_WRITE_WAIT_FOR_DATA && logical_sector_count == 5'd0 && num_sectors == 17'd0) ||
683
    cmd_calibrate_start ||
684
    cmd_execute_drive_diag ||
685
    cmd_initialize_start ||
686
    cmd_features_start ||
687
    cmd_verify_start ||
688
    cmd_multiple_start ||
689
    cmd_power_start ||
690
    cmd_checkpower_start ||
691
    (state == S_COUNT_DECISION && ~(count_decision_immediate_error) && cmd_seek_in_progress) ||
692
    cmd_max_start;
693
 
694
wire lower_interrupt =
695
    (io_read_valid  && io_address == 1'b1 && io_byteenable[3:0] == 4'b1000) ||
696
    (io_write && io_address == 1'b1 && io_byteenable[3:0] == 4'b1000 && ~(drive_select));
697
 
698
wire command_abort =
699
    (state == S_COUNT_DECISION && count_decision_immediate_error) ||
700
    cmd_read_abort_at_start ||
701
    cmd_write_abort_at_start ||
702
    cmd_initialize_abort_at_start ||
703
    cmd_features_abort_at_start ||
704
    cmd_multiple_abort_at_start ||
705
    cmd_max_abort_at_start ||
706
    cmd_unknown_start;
707
 
708
//------------------------------------------------------------------------------ count logical sector count
709
 
710
wire [31:0] sectors_left = media_sectors - logical_sector[31:0] - 32'd1;
711
 
712
wire [4:0] multiple_final_write =
713
    (current_command_write_multiple && lba_mode && (current_command_write_lba48 || media_sectors[31:28] == 4'd0) && sectors_left < { 27'd0, multiple_final_read })? sectors_left[4:0] : multiple_final_read;
714
 
715
wire [4:0] multiple_final_read =
716
    (num_sectors >= { 12'd0, multiple_sectors })? multiple_sectors : num_sectors[4:0];
717
 
718
reg [4:0] logical_sector_count;
719
always @(posedge clk or negedge rst_n) begin
720
    if(rst_n == 1'b0)                                                                                                           logical_sector_count <= 5'd0;
721
    else if(state == S_SD_AVALON_BASE && current_command_read_multiple)                                                         logical_sector_count <= multiple_final_read;
722
    else if(state == S_SD_AVALON_BASE && current_command_write_multiple)                                                        logical_sector_count <= multiple_final_write;
723
    else if(state == S_SD_AVALON_BASE)                                                                                          logical_sector_count <= 5'd1;
724
 
725
    else if(state == S_SD_READ_WAIT_FOR_DATA  && sd_slave_write       && sd_counter == 7'd127 && logical_sector_count > 5'd0)   logical_sector_count <= logical_sector_count - 5'd1;
726
    else if(state == S_SD_WRITE_WAIT_FOR_DATA && sd_slave_read_valid  && sd_counter == 7'd127 && logical_sector_count > 5'd0)   logical_sector_count <= logical_sector_count - 5'd1;
727
end
728
 
729
wire count_decision_immediate_error =
730
    logical_sector[47:32] != 16'd0 ||
731
    logical_sector[31:0] >= media_sectors ||
732
    (current_command_read_multiple && lba_mode && (current_command_read_lba48 || media_sectors[31:28] == 4'd0) && (logical_sector[31:0] + { 27'd0, multiple_final_read }) > media_sectors);
733
 
734
//------------------------------------------------------------------------------ count logical sector
735
 
736
reg [29:0] mult1_a; //cylinder
737
always @(posedge clk or negedge rst_n) begin
738
    if(rst_n == 1'b0)                   mult1_a <= 30'd0;
739
    else if(state == S_PREPARE_COUNT)   mult1_a <= { 14'd0, cylinder };
740
    else if(state == S_COUNT_LOGICAL)   mult1_a <= { mult1_a[28:0], 1'b0 };
741
end
742
 
743
reg [13:0] mult1_b; //media_spc
744
always @(posedge clk or negedge rst_n) begin
745
    if(rst_n == 1'b0)                   mult1_b <= 14'd0;
746
    else if(state == S_PREPARE_COUNT)   mult1_b <= media_spc;
747
    else if(state == S_COUNT_LOGICAL)   mult1_b <= { 1'b0, mult1_b[13:1] };
748
end
749
 
750
reg [29:0] logical_sector1; //cylinder * media_spc
751
always @(posedge clk or negedge rst_n) begin
752
    if(rst_n == 1'b0)                               logical_sector1 <= 30'd0;
753
    else if(state == S_PREPARE_COUNT)               logical_sector1 <= { 22'd0, sector } - 30'd1;
754
    else if(state == S_COUNT_LOGICAL && mult1_b[0]) logical_sector1 <= logical_sector1 + mult1_a;
755
end
756
 
757
reg [12:0] mult2_a; //head
758
always @(posedge clk or negedge rst_n) begin
759
    if(rst_n == 1'b0)                   mult2_a <= 13'd0;
760
    else if(state == S_PREPARE_COUNT)   mult2_a <= { 9'd0, head };
761
    else if(state == S_COUNT_LOGICAL)   mult2_a <= { mult2_a[11:0], 1'b0 };
762
end
763
 
764
reg [8:0] mult2_b; //media_spt
765
always @(posedge clk or negedge rst_n) begin
766
    if(rst_n == 1'b0)                   mult2_b <= 9'd0;
767
    else if(state == S_PREPARE_COUNT)   mult2_b <= media_spt;
768
    else if(state == S_COUNT_LOGICAL)   mult2_b <= { 1'b0, mult2_b[8:1] };
769
end
770
 
771
reg [12:0] logical_sector2; //head * media_spt
772
always @(posedge clk or negedge rst_n) begin
773
    if(rst_n == 1'b0)                               logical_sector2 <= 13'd0;
774
    else if(state == S_PREPARE_COUNT)               logical_sector2 <= 13'd0;
775
    else if(state == S_COUNT_LOGICAL && mult2_b[0]) logical_sector2 <= logical_sector2 + mult2_a;
776
end
777
 
778
reg [47:0] logical_sector;
779
always @(posedge clk or negedge rst_n) begin
780
    if(rst_n == 1'b0)                                                       logical_sector <= 48'd0;
781
    else if(state == S_COUNT_FINAL && lba_mode && current_command_lba48)    logical_sector <= { hob_hcyl, hob_lcyl, hob_sector, cylinder, sector };
782
    else if(state == S_COUNT_FINAL && lba_mode)                             logical_sector <= { 20'd0, head, cylinder, sector };
783
    else if(state == S_COUNT_FINAL)                                         logical_sector <= { 18'b0, logical_sector1 } + { 35'd0, logical_sector2 };
784
end
785
 
786
//------------------------------------------------------------------------------ sd
787
 
788
reg [6:0] sd_counter;
789
always @(posedge clk or negedge rst_n) begin
790
    if(rst_n == 1'b0)                                                               sd_counter <= 7'd0;
791
    else if(state != S_SD_READ_WAIT_FOR_DATA && state != S_SD_WRITE_WAIT_FOR_DATA)  sd_counter <= 7'd0;
792
    else if(sd_slave_write || sd_slave_read_valid)                                  sd_counter <= sd_counter + 7'd1;
793
end
794
 
795
reg [31:0] sd_sector;
796
always @(posedge clk or negedge rst_n) begin
797
    if(rst_n == 1'b0)                   sd_sector <= 32'd0;
798
    else if(state == S_SD_AVALON_BASE)  sd_sector <= (logical_sector >= { 16'd0, media_sectors })? media_sd_base + media_sectors - 32'd1 : media_sd_base + logical_sector[31:0];
799
end
800
 
801
assign sd_master_address =
802
    (state == S_SD_MUTEX)?          32'd8 :
803
    (state == S_SD_AVALON_BASE)?    32'd0 :
804
    (state == S_SD_ADDRESS)?        32'd4 :
805
    (state == S_SD_BLOCK_COUNT)?    32'd8 :
806
    (state == S_SD_CONTROL)?        32'd12 :
807
                                    32'd0;
808
 
809
reg sd_read_done;
810
always @(posedge clk or negedge rst_n) begin
811
    if(rst_n == 1'b0)                                           sd_read_done <= 1'b0;
812
    else if(sd_master_read && sd_master_waitrequest == 1'b0)    sd_read_done <= 1'b1;
813
    else if(sd_master_readdatavalid)                            sd_read_done <= 1'b0;
814
end
815
 
816
reg [3:0] sd_mutex_wait;
817
always @(posedge clk or negedge rst_n) begin
818
    if(rst_n == 1'b0)                                       sd_mutex_wait <= 4'd0;
819
    else if(state == S_SD_MUTEX && sd_master_read == 1'b0)  sd_mutex_wait <= sd_mutex_wait + 4'd1;
820
end
821
 
822
assign sd_master_read = state == S_SD_MUTEX && sd_mutex_wait == 4'd9 && ~(sd_read_done);
823
 
824
assign sd_master_write = state == S_SD_AVALON_BASE || state == S_SD_ADDRESS || state == S_SD_BLOCK_COUNT || state == S_SD_CONTROL;
825
 
826
assign sd_master_writedata =
827
    (state == S_SD_AVALON_BASE)?                        `SD_AVALON_BASE_ADDRESS_FOR_HDD :
828
    (state == S_SD_ADDRESS)?                            sd_sector :
829
    (state == S_SD_BLOCK_COUNT)?                        { 27'd0, logical_sector_count } :
830
    (state == S_SD_CONTROL && cmd_read_in_progress)?    32'd2 : //CONTROL_READ
831
    (state == S_SD_CONTROL && cmd_write_in_progress)?   32'd3 : //CONTROL_WRITE
832
                                                        32'd0;
833
 
834
//------------------------------------------------------------------------------ fifo for identify
835
 
836
reg [6:0] identify_counter;
837
always @(posedge clk or negedge rst_n) begin
838
    if(rst_n == 1'b0)                   identify_counter <= 7'd0;
839
    else if(state != S_IDENTIFY_FILL)   identify_counter <= 7'd0;
840
    else                                identify_counter <= identify_counter + 7'd1;
841
end
842
 
843
wire [31:0] identify_q;
844
wire [31:0] identify_q_final =
845
    (identify_counter == 7'd29)?    { (multiple_sectors > 5'd0)? (16'h0100 | { 11'd0, multiple_sectors }) : 16'h0000,  identify_q[15:0] } :
846
                                    identify_q;
847
 
848
simple_fifo #(
849
    .width      (32),
850
    .widthu     (7)
851
)
852
fifo_identify_inst(
853
    .clk        (clk),
854
    .rst_n      (rst_n),
855
 
856
    .sclr       (1'b0),                                                                 //input
857
 
858
    .data       ((mgmt_write)? mgmt_writedata : identify_q),                            //input [31:0]
859
    .wrreq      ((mgmt_address == 3'd0 && mgmt_write) || state == S_IDENTIFY_FILL),     //input
860
 
861
    .rdreq      (state == S_IDENTIFY_FILL),                                             //input
862
    .q          (identify_q),                                                           //output [31:0]
863
 
864
    /* verilator lint_off PINNOCONNECT */
865
    .full       (),                                                                     //output
866
    .empty      (),                                                                     //output
867
    .usedw      ()                                                                      //output [6:0]
868
    /* verilator lint_on PINNOCONNECT */
869
);
870
 
871
//------------------------------------------------------------------------------ fifo from hdd
872
 
873
wire [2:0] from_hdd_stored_index_next = 3'd4 + { 1'b0, from_hdd_stored_index } - data_io_size;
874
 
875
reg [1:0] from_hdd_stored_index;
876
always @(posedge clk or negedge rst_n) begin
877
    if(rst_n == 1'b0)                                                           from_hdd_stored_index <= 2'd0;
878
    else if(state == S_IDLE)                                                    from_hdd_stored_index <= 2'd0;
879
    else if(read_data_io && { 1'b0, from_hdd_stored_index } >= data_io_size)    from_hdd_stored_index <= from_hdd_stored_index - data_io_size[1:0];
880
    else if(read_data_io && from_hdd_empty)                                     from_hdd_stored_index <= 2'd0;
881
    else if(read_data_io)                                                       from_hdd_stored_index <= from_hdd_stored_index_next[1:0];
882
end
883
 
884
wire [55:0] from_hdd_result =
885
    (from_hdd_stored_index == 2'd0)?        { 24'd0, from_hdd_q } :
886
    (from_hdd_stored_index == 2'd1)?        { 16'd0, from_hdd_q, from_hdd_stored[7:0] } :
887
    (from_hdd_stored_index == 2'd2)?        { 8'd0,  from_hdd_q, from_hdd_stored[15:0] } :
888
                                            {        from_hdd_q, from_hdd_stored[23:0] };
889
 
890
reg [23:0] from_hdd_stored;
891
always @(posedge clk or negedge rst_n) begin
892
    if(rst_n == 1'b0)                               from_hdd_stored <= 24'd0;
893
    else if(read_data_io && data_io_size == 3'd1)   from_hdd_stored <= from_hdd_result[31:8];
894
    else if(read_data_io && data_io_size == 3'd2)   from_hdd_stored <= from_hdd_result[39:16];
895
    else if(read_data_io && data_io_size == 3'd4)   from_hdd_stored <= from_hdd_result[55:32];
896
end
897
 
898
wire from_hdd_empty_valid = from_hdd_empty && from_hdd_stored_index == 2'd0;
899
 
900
wire        from_hdd_empty;
901
wire [31:0] from_hdd_q;
902
 
903
simple_fifo #(
904
    .width      (32),
905
    .widthu     (11)
906
)
907
fifo_from_hdd_inst(
908
    .clk        (clk),
909
    .rst_n      (rst_n),
910
 
911
    .sclr       (sw_reset_start),                                                                   //input
912
 
913
    .data       ((state == S_IDENTIFY_FILL)? identify_q_final : sd_slave_writedata),                //input [31:0]
914
    .wrreq      ((state == S_SD_READ_WAIT_FOR_DATA && sd_slave_write) || state == S_IDENTIFY_FILL), //input
915
 
916
    .rdreq      (read_data_io && { 1'b0, from_hdd_stored_index } < data_io_size),                   //input
917
    .empty      (from_hdd_empty),                                                                   //output
918
    .q          (from_hdd_q),                                                                       //output [31:0]
919
 
920
    /* verilator lint_off PINNOCONNECT */
921
    .full       (),                                                                                 //output
922
    .usedw      ()                                                                                  //output [10:0]
923
    /* verilator lint_on PINNOCONNECT */
924
);
925
 
926
 
927
//------------------------------------------------------------------------------ fifo to hdd
928
 
929
reg [1:0] to_hdd_stored_index;
930
always @(posedge clk or negedge rst_n) begin
931
    if(rst_n == 1'b0)       to_hdd_stored_index <= 2'd0;
932
    else if(write_data_io)  to_hdd_stored_index <= to_hdd_sum[1:0];
933
end
934
 
935
wire [55:0] to_hdd_result =
936
    (to_hdd_stored_index == 2'd0)?        { 24'd0, io_writedata } :
937
    (to_hdd_stored_index == 2'd1)?        { 16'd0, io_writedata, to_hdd_stored[7:0] } :
938
    (to_hdd_stored_index == 2'd2)?        { 8'd0,  io_writedata, to_hdd_stored[15:0] } :
939
                                          {        io_writedata, to_hdd_stored[23:0] };
940
 
941
wire [2:0] to_hdd_sum = data_io_size + { 1'b0, to_hdd_stored_index };
942
 
943
reg [23:0] to_hdd_stored;
944
always @(posedge clk or negedge rst_n) begin
945
    if(rst_n == 1'b0)                               to_hdd_stored <= 24'd0;
946
    else if(write_data_io && to_hdd_sum == 3'd1)    to_hdd_stored <= { 16'd0, to_hdd_result[7:0] };
947
    else if(write_data_io && to_hdd_sum == 3'd2)    to_hdd_stored <= { 8'd0,  to_hdd_result[15:0] };
948
    else if(write_data_io && to_hdd_sum == 3'd3)    to_hdd_stored <= {        to_hdd_result[23:0] };
949
    else if(write_data_io && to_hdd_sum == 3'd5)    to_hdd_stored <= { 16'd0, to_hdd_result[39:32] };
950
    else if(write_data_io && to_hdd_sum == 3'd6)    to_hdd_stored <= { 8'd0,  to_hdd_result[47:32] };
951
    else if(write_data_io && to_hdd_sum == 3'd7)    to_hdd_stored <= {        to_hdd_result[55:32] };
952
end
953
 
954
always @(posedge clk or negedge rst_n) begin
955
    if(rst_n == 1'b0)   sd_slave_readdata <= 32'b0;
956
    else                sd_slave_readdata <= to_hdd_q;
957
end
958
 
959
wire [11:0] to_hdd_count = { to_hdd_full, to_hdd_usedw };
960
wire [10:0] to_hdd_usedw;
961
wire        to_hdd_full;
962
wire [31:0] to_hdd_q;
963
 
964
simple_fifo #(
965
    .width      (32),
966
    .widthu     (11)
967
)
968
fifo_to_hdd_inst(
969
    .clk        (clk),
970
    .rst_n      (rst_n),
971
 
972
    .sclr       (sw_reset_start),                                               //input
973
 
974
    .data       (to_hdd_result[31:0]),                                          //input [31:0]
975
    .wrreq      (write_data_io && to_hdd_sum >= 3'd4 && ~(write_data_ready)),   //input
976
    .full       (to_hdd_full),                                                  //output
977
 
978
    .rdreq      (state == S_SD_WRITE_WAIT_FOR_DATA && sd_slave_read_valid),     //input
979
    .q          (to_hdd_q),                                                     //output [31:0]
980
 
981
    .usedw      (to_hdd_usedw),                                                 //output [10:0]
982
 
983
    /* verilator lint_off PINNOCONNECT */
984
    .empty      ()                                                             //output
985
    /* verilator lint_on PINNOCONNECT */
986
);
987
 
988
//------------------------------------------------------------------------------
989
 
990
// synthesis translate_off
991
wire _unused_ok = &{ 1'b0, ide_3f6_writedata[7:3], ide_3f6_writedata[0],
992
                           sd_master_readdata[31:3], sd_slave_address[8:0],
993
                           media_cylinders_minus_1[16], from_hdd_stored_index_next[2], 1'b0 };
994
// synthesis translate_on
995
 
996
//------------------------------------------------------------------------------
997
 
998
endmodule

powered by: WebSVN 2.1.0

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