1
0
mirror of synced 2026-01-13 15:27:17 +00:00
2010-04-13 16:38:40 +00:00

100 lines
2.1 KiB
Verilog

//
// ide.v
// simple state machine to do proper read & write cycles to ATA IDE device
//
module ide(clk, reset, ata_rd, ata_wr, ata_addr, ata_in, ata_out, ata_done,
ide_data_bus, ide_dior, ide_diow, ide_cs, ide_da);
input clk;
input reset;
input ata_rd;
input ata_wr;
input [4:0] ata_addr;
input [15:0] ata_in;
output [15:0] ata_out;
reg [15:0] ata_out;
output ata_done;
inout [15:0] ide_data_bus;
output ide_dior;
output ide_diow;
output [1:0] ide_cs;
output [2:0] ide_da;
reg [2:0] ata_state;
parameter [2:0]
idle = 3'd0,
s0 = 3'd1,
s1 = 3'd2,
s2 = 3'd3,
s3 = 3'd4,
s4 = 3'd5;
wire assert_cs;
wire assert_rw;
reg [2:0] ata_state_next;
// if write, drive ide_bus
assign ide_data_bus = (ata_wr && (ata_state == s0 ||
ata_state == s1 ||
ata_state == s2 ||
ata_state == s3)) ? ata_in : 16'bz;
// assert cs & da during r/w cycle
assign assert_cs = (ata_rd || ata_wr) && ata_state != s4;
assign ide_cs = assert_cs ? ata_addr[4:3] : 2'b11;
assign ide_da = assert_cs ? ata_addr[2:0] : 3'b111;
// assert r/w one cycle sort
assign assert_rw = ata_state == s0 ||
ata_state == s1 ||
ata_state == s2;
assign ide_dior = (assert_rw && ata_rd) ? 1'b0 : 1'b1;
assign ide_diow = (assert_rw && ata_wr) ? 1'b0 : 1'b1;
// send back done pulse at end
assign ata_done = ata_state == s3;
always @(posedge clk)
if (reset)
ata_state <= idle;
else
ata_state <= ata_state_next;
always @(clk or ata_state or ata_rd or ata_wr or ata_addr or ide_data_bus)
begin
case (ata_state)
idle:
begin
if (ata_rd || ata_wr)
ata_state_next = s0;
else
ata_state_next = idle;
end
s0: ata_state_next = s1;
s1: ata_state_next = s2;
s2: ata_state_next = s3;
s3: ata_state_next = s4;
s4: ata_state_next = idle;
default: ata_state_next = idle;
endcase
end
always @(posedge clk)
if (reset)
ata_out <= 0;
else
if (ata_state == s2 && ata_rd)
ata_out <= ide_data_bus;
endmodule // ide