Line 29... |
Line 29... |
input rst, //reset
|
input rst, //reset
|
input clk,
|
input clk,
|
|
|
//Data Interface
|
//Data Interface
|
output reg [31:0] tx_dout,
|
output reg [31:0] tx_dout,
|
output reg tx_isk,
|
output reg tx_is_k,
|
output reg tx_set_elec_idle,
|
output reg tx_set_elec_idle,
|
output reg rx_byte_is_aligned,
|
output reg rx_byte_is_aligned,
|
|
|
input [31:0] rx_din,
|
input [31:0] rx_din,
|
input [3:0] rx_isk,
|
input [3:0] rx_is_k,
|
input rx_is_elec_idle,
|
input rx_is_elec_idle,
|
|
|
input comm_reset_detect,
|
input comm_reset_detect,
|
input comm_wake_detect,
|
input comm_wake_detect,
|
|
|
Line 85... |
Line 85... |
|
|
|
|
//Asynchronous Logic
|
//Asynchronous Logic
|
|
|
assign lax_state = state;
|
assign lax_state = state;
|
assign align_detected = ((rx_isk > 0) && (rx_din == `PRIM_ALIGN));
|
assign align_detected = ((rx_is_k > 0) && (rx_din == `PRIM_ALIGN));
|
assign dialtone_detected = ((rx_isk == 0) && (rx_din == `DIALTONE));
|
assign dialtone_detected = ((rx_is_k == 0) && (rx_din == `DIALTONE));
|
assign timeout = (timer == 0);
|
assign timeout = (timer == 0);
|
assign phy_ready = (state == READY);
|
assign phy_ready = (state == READY);
|
|
|
//Synchronous Logic
|
//Synchronous Logic
|
always @ (posedge clk) begin
|
always @ (posedge clk) begin
|
if (rst) begin
|
if (rst) begin
|
state <= IDLE;
|
state <= IDLE;
|
tx_dout <= 0;
|
tx_dout <= 0;
|
tx_isk <= 0;
|
tx_is_k <= 0;
|
tx_set_elec_idle <= 1;
|
tx_set_elec_idle <= 1;
|
timer <= 0;
|
timer <= 0;
|
hd_ready <= 0;
|
hd_ready <= 0;
|
rx_byte_is_aligned <= 0;
|
rx_byte_is_aligned <= 0;
|
align_count <= 0;
|
align_count <= 0;
|
Line 116... |
Line 116... |
timer <= timer - 1;
|
timer <= timer - 1;
|
end
|
end
|
|
|
if ((comm_reset_detect) && (state > WAIT_FOR_NO_RESET)) begin
|
if ((comm_reset_detect) && (state > WAIT_FOR_NO_RESET)) begin
|
$display("faux_sata_hd: Asynchronous RESET detected");
|
$display("faux_sata_hd: Asynchronous RESET detected");
|
state <= IDLE;
|
align_count <= 0;
|
|
hd_ready <= 0;
|
|
state <= WAIT_FOR_NO_RESET;
|
end
|
end
|
|
|
case (state)
|
case (state)
|
IDLE: begin
|
IDLE: begin
|
align_count <= 0;
|
align_count <= 0;
|
Line 135... |
Line 137... |
WAIT_FOR_NO_RESET: begin
|
WAIT_FOR_NO_RESET: begin
|
if (!comm_reset_detect) begin
|
if (!comm_reset_detect) begin
|
//host stopped sending reset
|
//host stopped sending reset
|
$display("faux_sata_hd: RESET deasserted");
|
$display("faux_sata_hd: RESET deasserted");
|
hd_ready <= 0;
|
hd_ready <= 0;
|
tx_set_elec_idle <= 1;
|
|
state <= SEND_INIT;
|
state <= SEND_INIT;
|
end
|
end
|
end
|
end
|
SEND_INIT: begin
|
SEND_INIT: begin
|
//XXX: I may need to send more than one of these
|
//XXX: I may need to send more than one of these
|
Line 168... |
Line 169... |
$display ("faux_sata_hd: stop sending WAKE");
|
$display ("faux_sata_hd: stop sending WAKE");
|
state <= WAIT_FOR_DIALTONE;
|
state <= WAIT_FOR_DIALTONE;
|
end
|
end
|
WAIT_FOR_DIALTONE: begin
|
WAIT_FOR_DIALTONE: begin
|
if (dialtone_detected) begin
|
if (dialtone_detected) begin
|
$display ("faul_sata_hd: detected dialtone");
|
$display ("faux_sata_hd: detected dialtone");
|
state <= SEND_ALIGN;
|
state <= SEND_ALIGN;
|
end
|
end
|
end
|
end
|
SEND_ALIGN: begin
|
SEND_ALIGN: begin
|
$display ("faul_sata_hd: send aligns");
|
$display ("faux_sata_hd: send aligns");
|
tx_set_elec_idle <= 0;
|
tx_set_elec_idle <= 0;
|
tx_dout <= `PRIM_ALIGN;
|
tx_dout <= `PRIM_ALIGN;
|
tx_isk <= 1;
|
tx_is_k <= 1;
|
state <= WAIT_FOR_ALIGN;
|
state <= WAIT_FOR_ALIGN;
|
timer <= 32'h`INITIALIZE_TIMEOUT;
|
timer <= 32'h`INITIALIZE_TIMEOUT;
|
rx_byte_is_aligned <= 1;
|
rx_byte_is_aligned <= 1;
|
end
|
end
|
WAIT_FOR_ALIGN: begin
|
WAIT_FOR_ALIGN: begin
|
|
tx_is_k <= 1;
|
|
tx_dout <= `PRIM_ALIGN;
|
rx_byte_is_aligned <= 1;
|
rx_byte_is_aligned <= 1;
|
|
//$display ("faux_sata_hd: waiting for aligns...");
|
|
//$display ("rx din: %h, k: %h", rx_din, rx_is_k);
|
if (align_detected) begin
|
if (align_detected) begin
|
$display ("faux_sata_hd: detected ALIGN primitive from host");
|
$display ("faux_sata_hd: detected ALIGN primitive from host");
|
$display ("faux_sata_hd: Ready");
|
$display ("faux_sata_hd: Ready");
|
tx_dout <= `PRIM_ALIGN;
|
tx_dout <= `PRIM_ALIGN;
|
tx_isk <= 1;
|
tx_is_k <= 1;
|
timer <= 0;
|
timer <= 0;
|
state <= READY;
|
state <= READY;
|
end
|
end
|
else if (timeout) begin
|
else if (timeout) begin
|
$display ("faux_sata_hd: Timeout while waiting for an alignment from the host");
|
$display ("faux_sata_hd: Timeout while waiting for an alignment from the host");
|
Line 199... |
Line 204... |
end
|
end
|
end
|
end
|
READY: begin
|
READY: begin
|
hd_ready <= 1;
|
hd_ready <= 1;
|
rx_byte_is_aligned <= 1;
|
rx_byte_is_aligned <= 1;
|
tx_isk <= 1;
|
tx_is_k <= 1;
|
tx_dout <= `PRIM_SYNC;
|
tx_dout <= `PRIM_SYNC;
|
if (align_count == 255) begin
|
if (align_count == 255) begin
|
tx_dout <= `PRIM_ALIGN;
|
tx_dout <= `PRIM_ALIGN;
|
state <= SEND_FIRST_ALIGNMENT;
|
state <= SEND_FIRST_ALIGNMENT;
|
end
|
end
|
end
|
end
|
SEND_FIRST_ALIGNMENT: begin
|
SEND_FIRST_ALIGNMENT: begin
|
rx_byte_is_aligned <= 1;
|
rx_byte_is_aligned <= 1;
|
tx_isk <= 1;
|
tx_is_k <= 1;
|
tx_dout <= `PRIM_ALIGN;
|
tx_dout <= `PRIM_ALIGN;
|
state <= SEND_SECOND_ALIGNMENT;
|
state <= SEND_SECOND_ALIGNMENT;
|
end
|
end
|
SEND_SECOND_ALIGNMENT: begin
|
SEND_SECOND_ALIGNMENT: begin
|
rx_byte_is_aligned <= 1;
|
rx_byte_is_aligned <= 1;
|
tx_isk <= 1;
|
tx_is_k <= 1;
|
tx_dout <= `PRIM_ALIGN;
|
tx_dout <= `PRIM_ALIGN;
|
state <= READY;
|
state <= READY;
|
end
|
end
|
default: begin
|
default: begin
|
$display ("faux_sata_hd: In undefined state!");
|
$display ("faux_sata_hd: In undefined state!");
|