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
|