Commit c50815d1 authored by Andrey Filippov's avatar Andrey Filippov

combining everything in sata_ahci_top.v

parent 09386747
...@@ -25,6 +25,7 @@ module ahci_sata_layers #( ...@@ -25,6 +25,7 @@ module ahci_sata_layers #(
parameter DATA_BYTE_WIDTH = 4 parameter DATA_BYTE_WIDTH = 4
)( )(
input exrst, // master reset that resets PLL and GTX input exrst, // master reset that resets PLL and GTX
input reliable_clk, // use aclk that runs independently of the GTX
output rst, // PHY-generated reset after PLL lock output rst, // PHY-generated reset after PLL lock
output clk, // PHY-generated clock, 75MHz for SATA2 output clk, // PHY-generated clock, 75MHz for SATA2
// Data/type FIFO, host -> device // Data/type FIFO, host -> device
...@@ -44,12 +45,14 @@ module ahci_sata_layers #( ...@@ -44,12 +45,14 @@ module ahci_sata_layers #(
input d2h_ready, // This module or DMA consumes DWORD input d2h_ready, // This module or DMA consumes DWORD
// communication with link/phys layers // communication with link/phys layers
output [ 1:0] phy_ready, // 0 - not ready, 1..3 - negotiated speed output [ 1:0] phy_speed, // 0 - not ready, 1..3 - negotiated speed (Now 0/2)
output gtx_ready, // How to use it?
output xmit_ok, // received R_OK after transmission output xmit_ok, // received R_OK after transmission
output xmit_err, // Error during/after sending of a FIS (got R_ERR) output xmit_err, // Error during/after sending of a FIS (got R_ERR)
output x_rdy_collision, // X_RDY/X_RDY collision on interface output x_rdy_collision, // X_RDY/X_RDY collision on interface
output syncesc_recv, // Where to get it? output syncesc_recv, // Where to get it?
input pcmd_cleared, // PxCMD.ST 1->0 transition by software
input syncesc_send, // Send sync escape input syncesc_send, // Send sync escape
output syncesc_send_done, // "SYNC escape until the interface is quiescent..." output syncesc_send_done, // "SYNC escape until the interface is quiescent..."
input comreset_send, // Not possible yet? input comreset_send, // Not possible yet?
...@@ -60,6 +63,7 @@ module ahci_sata_layers #( ...@@ -60,6 +63,7 @@ module ahci_sata_layers #(
input send_R_ERR, input send_R_ERR,
// additional errors from SATA layers (single-clock pulses): // additional errors from SATA layers (single-clock pulses):
output serr_DT, // RWC: Transport state transition error output serr_DT, // RWC: Transport state transition error
output serr_DS, // RWC: Link sequence error output serr_DS, // RWC: Link sequence error
output serr_DH, // RWC: Handshake Error (i.e. Device got CRC error) output serr_DH, // RWC: Handshake Error (i.e. Device got CRC error)
...@@ -75,8 +79,8 @@ module ahci_sata_layers #( ...@@ -75,8 +79,8 @@ module ahci_sata_layers #(
output serr_EM, // RWC: Communication between the device and host was lost but re-established output serr_EM, // RWC: Communication between the device and host was lost but re-established
output serr_EI, // RWC: Recovered Data integrity Error output serr_EI, // RWC: Recovered Data integrity Error
// additional control signals for SATA layers // additional control signals for SATA layers
input [3:0] sctl_ipm, // Interface power management transitions allowed input [3:0] sctl_ipm, // Interface power management transitions allowed // @SuppressThisWarning Veditor Unused (yet)
input [3:0] sctl_spd, // Interface maximal speed input [3:0] sctl_spd, // Interface maximal speed // @SuppressThisWarning Veditor Unused (yet)
// Device high speed pads and clock inputs // Device high speed pads and clock inputs
// ref clk from an external source, shall be connected to pads // ref clk from an external source, shall be connected to pads
...@@ -88,6 +92,7 @@ module ahci_sata_layers #( ...@@ -88,6 +92,7 @@ module ahci_sata_layers #(
input wire rxp_in, input wire rxp_in,
input wire rxn_in input wire rxn_in
); );
localparam PHY_SPEED = 2; // SATA2
localparam FIFO_ADDR_WIDTH = 9; localparam FIFO_ADDR_WIDTH = 9;
localparam D2H_TYPE_DMA = 0; localparam D2H_TYPE_DMA = 0;
...@@ -99,6 +104,7 @@ module ahci_sata_layers #( ...@@ -99,6 +104,7 @@ module ahci_sata_layers #(
localparam H2D_TYPE_FIS_HEAD = 1; localparam H2D_TYPE_FIS_HEAD = 1;
localparam H2D_TYPE_FIS_LAST = 2; localparam H2D_TYPE_FIS_LAST = 2;
wire phy_ready;
wire [31:0] ll_h2d_data_in; wire [31:0] ll_h2d_data_in;
wire [1:0] ll_h2d_mask_in; wire [1:0] ll_h2d_mask_in;
wire ll_strobe_out; wire ll_strobe_out;
...@@ -128,8 +134,9 @@ module ahci_sata_layers #( ...@@ -128,8 +134,9 @@ module ahci_sata_layers #(
// wire incom_ack_good = send_R_OK; // -> link // transport layer responds on a completion of a FIS // wire incom_ack_good = send_R_OK; // -> link // transport layer responds on a completion of a FIS
// wire incom_ack_bad = send_R_ERR; // -> link // oob sequence is reinitiated and link now is not established or rxelecidle // wire incom_ack_bad = send_R_ERR; // -> link // oob sequence is reinitiated and link now is not established or rxelecidle
wire ll_link_reset; // -> link // oob sequence is reinitiated and link now is not established or rxelecidle wire ll_link_reset = ~phy_ready; // -> link // oob sequence is reinitiated and link now is not established or rxelecidle //TODO Alexey:mb it shall be independent
wire ll_incom_stop_req; // -> link // TL demands to stop current recieving session (use !PxCMD.ST)?
// wire ll_incom_stop_req; // -> link // TL demands to stop current recieving session (use !PxCMD.ST)?
wire [DATA_BYTE_WIDTH*8 - 1:0] ph2ll_data_out; wire [DATA_BYTE_WIDTH*8 - 1:0] ph2ll_data_out;
wire [DATA_BYTE_WIDTH - 1:0] ph2ll_charisk_out; // charisk wire [DATA_BYTE_WIDTH - 1:0] ph2ll_charisk_out; // charisk
...@@ -142,14 +149,14 @@ module ahci_sata_layers #( ...@@ -142,14 +149,14 @@ module ahci_sata_layers #(
wire [FIFO_ADDR_WIDTH-1:0] h2d_waddr; wire [FIFO_ADDR_WIDTH-1:0] h2d_waddr;
wire [FIFO_ADDR_WIDTH:0] h2d_fill; wire [FIFO_ADDR_WIDTH:0] h2d_fill;
wire h2d_nempty; wire h2d_nempty;
wire h2d_under; // wire h2d_under;
wire [FIFO_ADDR_WIDTH-1:0] d2h_raddr; wire [FIFO_ADDR_WIDTH-1:0] d2h_raddr;
wire [1:0] d2h_fifo_re_regen; wire [1:0] d2h_fifo_re_regen;
wire [FIFO_ADDR_WIDTH-1:0] d2h_waddr; wire [FIFO_ADDR_WIDTH-1:0] d2h_waddr;
wire [FIFO_ADDR_WIDTH:0] d2h_fill; wire [FIFO_ADDR_WIDTH:0] d2h_fill;
wire d2h_nempty; wire d2h_nempty;
wire d2h_over; // wire d2h_over;
wire h2d_fifo_rd = h2d_nempty && ll_strobe_out; // TODO: check latency in link.v wire h2d_fifo_rd = h2d_nempty && ll_strobe_out; // TODO: check latency in link.v
wire h2d_fifo_wr = h2d_valid; wire h2d_fifo_wr = h2d_valid;
...@@ -169,6 +176,25 @@ module ahci_sata_layers #( ...@@ -169,6 +176,25 @@ module ahci_sata_layers #(
assign ll_frame_req_w = !ll_frame_busy && h2d_pending && (((h2d_type == H2D_TYPE_FIS_LAST) && h2d_fifo_wr ) || (|h2d_fill[FIFO_ADDR_WIDTH : BITS_TO_START_XMIT])); assign ll_frame_req_w = !ll_frame_busy && h2d_pending && (((h2d_type == H2D_TYPE_FIS_LAST) && h2d_fifo_wr ) || (|h2d_fill[FIFO_ADDR_WIDTH : BITS_TO_START_XMIT]));
// Separating different types of errors, sync_escape from other problems. TODO: route individual errors to set SERR bits // Separating different types of errors, sync_escape from other problems. TODO: route individual errors to set SERR bits
//assign incom_invalidate = state_rcvr_eof & crc_bad & ~alignes_pair | state_rcvr_data & dword_val & rcvd_dword[CODE_WTRMP]; //assign incom_invalidate = state_rcvr_eof & crc_bad & ~alignes_pair | state_rcvr_data & dword_val & rcvd_dword[CODE_WTRMP];
assign phy_speed = phy_ready ? PHY_SPEED:0;
assign serr_DB = |ph2ll_err_out;
assign serr_DH = xmit_err;
// not yet assigned errors
assign serr_DT = 0; // RWC: Transport state transition error
assign serr_DS = 0; // RWC: Link sequence error
assign serr_DC = 0; // RWC: CRC error in Link layer
assign serr_DB = 0; // RWC: 10B to 8B decode error
assign serr_DI = 0; // RWC: PHY Internal Error
assign serr_EP = 0; // RWC: Protocol Error - a violation of SATA protocol detected
assign serr_EC = 0; // RWC: Persistent Communication or Data Integrity Error
assign serr_ET = 0; // RWC: Transient Data Integrity Error (error not recovered by the interface)
assign serr_EM = 0; // RWC: Communication between the device and host was lost but re-established
assign serr_EI = 0; // RWC: Recovered Data integrity Error
link #( link #(
.DATA_BYTE_WIDTH(4) .DATA_BYTE_WIDTH(4)
...@@ -205,9 +231,9 @@ module ahci_sata_layers #( ...@@ -205,9 +231,9 @@ module ahci_sata_layers #(
.link_reset (ll_link_reset), // input wire // oob sequence is reinitiated and link now is not established or rxelecidle .link_reset (ll_link_reset), // input wire // oob sequence is reinitiated and link now is not established or rxelecidle
.sync_escape_req (syncesc_send), // input wire // TL demands to brutally cancel current transaction .sync_escape_req (syncesc_send), // input wire // TL demands to brutally cancel current transaction
.sync_escape_ack (syncesc_send_done), // output wire // acknowlegement of a successful reception? .sync_escape_ack (syncesc_send_done), // output wire // acknowlegement of a successful reception?
.incom_stop_req (ll_incom_stop_req), // input wire // TL demands to stop current recieving session .incom_stop_req (pcmd_cleared), // input wire // TL demands to stop current recieving session
// inputs from phy // inputs from phy
.phy_ready (), // input wire // phy is ready - link is established .phy_ready (phy_ready), // input wire // phy is ready - link is established
// data-primitives stream from phy // data-primitives stream from phy
.phy_data_in (ph2ll_data_out), // input[31:0] wire // phy_data_in .phy_data_in (ph2ll_data_out), // input[31:0] wire // phy_data_in
.phy_isk_in (ph2ll_charisk_out), // input[3:0] wire // charisk .phy_isk_in (ph2ll_charisk_out), // input[3:0] wire // charisk
...@@ -246,9 +272,9 @@ module ahci_sata_layers #( ...@@ -246,9 +272,9 @@ module ahci_sata_layers #(
.extrst (exrst), // input wire .extrst (exrst), // input wire
.clk (clk), // output wire .clk (clk), // output wire
.rst (rst), // output wire .rst (rst), // output wire
.reliable_clk (), // input wire .reliable_clk (reliable_clk), // input wire
.phy_ready (), // output wire .phy_ready (phy_ready), // output wire
.gtx_ready (), // output wire .gtx_ready (gtx_ready), // output wire
.debug_cnt (), // output[11:0] wire .debug_cnt (), // output[11:0] wire
.extclk_p (extclk_p), // input wire .extclk_p (extclk_p), // input wire
.extclk_n (extclk_n), // input wire .extclk_n (extclk_n), // input wire
...@@ -260,7 +286,12 @@ module ahci_sata_layers #( ...@@ -260,7 +286,12 @@ module ahci_sata_layers #(
.ll_charisk_out (ph2ll_charisk_out), // output[3:0] wire .ll_charisk_out (ph2ll_charisk_out), // output[3:0] wire
.ll_err_out (ph2ll_err_out), // output[3:0] wire .ll_err_out (ph2ll_err_out), // output[3:0] wire
.ll_data_in (ll2ph_data_in), // input[31:0] wire .ll_data_in (ll2ph_data_in), // input[31:0] wire
.ll_charisk_in (ll2ph_charisk_in) // input[3:0] wire .ll_charisk_in (ll2ph_charisk_in), // input[3:0] wire
.set_offline (set_offline), // input
.comreset_send (comreset_send), // input
.cominit_got (cominit_got), // output wire
.comwake_got (serr_DW) // output wire
); );
fifo_sameclock_control #( fifo_sameclock_control #(
...@@ -277,7 +308,7 @@ module ahci_sata_layers #( ...@@ -277,7 +308,7 @@ module ahci_sata_layers #(
.mem_re (h2d_fifo_re_regen[0]), // output .mem_re (h2d_fifo_re_regen[0]), // output
.mem_regen(h2d_fifo_re_regen[1]), // output .mem_regen(h2d_fifo_re_regen[1]), // output
.over (), // output reg .over (), // output reg
.under (h2d_under) // output reg .under () //h2d_under) // output reg
); );
ram18p_var_w_var_r #( ram18p_var_w_var_r #(
...@@ -310,7 +341,7 @@ module ahci_sata_layers #( ...@@ -310,7 +341,7 @@ module ahci_sata_layers #(
.mem_ra (d2h_raddr), // output[8:0] reg .mem_ra (d2h_raddr), // output[8:0] reg
.mem_re (d2h_fifo_re_regen[0]), // output .mem_re (d2h_fifo_re_regen[0]), // output
.mem_regen(d2h_fifo_re_regen[1]), // output .mem_regen(d2h_fifo_re_regen[1]), // output
.over (d2h_over), // output reg .over (), //d2h_over), // output reg
.under () // output reg .under () // output reg
); );
......
...@@ -146,6 +146,7 @@ module ahci_top#( ...@@ -146,6 +146,7 @@ module ahci_top#(
input xmit_ok, // FIS transmission acknowledged OK input xmit_ok, // FIS transmission acknowledged OK
input xmit_err, // Error during sending of a FIS input xmit_err, // Error during sending of a FIS
input syncesc_recv, // These two inputs interrupt transmit input syncesc_recv, // These two inputs interrupt transmit
output pcmd_st_cleared, // bit was cleared by software
output syncesc_send, // Send sync escape output syncesc_send, // Send sync escape
input syncesc_send_done, // "SYNC escape until the interface is quiescent..." input syncesc_send_done, // "SYNC escape until the interface is quiescent..."
output comreset_send, // Not possible yet? output comreset_send, // Not possible yet?
...@@ -373,7 +374,6 @@ module ahci_top#( ...@@ -373,7 +374,6 @@ module ahci_top#(
// wire pcmd_clear_st; // RW clear ST (start) bit // wire pcmd_clear_st; // RW clear ST (start) bit
wire pcmd_st; // current value wire pcmd_st; // current value
wire pfsm_started; // H: FSM done, P: FSM started (enable sensing pcmd_st_cleared) wire pfsm_started; // H: FSM done, P: FSM started (enable sensing pcmd_st_cleared)
wire pcmd_st_cleared; // bit was cleared by software
//clear_bsy_drq //clear_bsy_drq
// Interrupt inputs // Interrupt inputs
wire sirq_TFE; // RWC: Task File Error Status wire sirq_TFE; // RWC: Task File Error Status
......
This diff is collapsed.
...@@ -76,7 +76,10 @@ module oob_ctrl #( ...@@ -76,7 +76,10 @@ module oob_ctrl #(
input wire rxbyteisaligned, input wire rxbyteisaligned,
// shows if channel is ready // shows if channel is ready
output wire phy_ready output wire phy_ready,
// From
input set_offline, // electrically idle
input comreset_send // Not possible yet?
); );
// oob sequence needs to be issued // oob sequence needs to be issued
...@@ -108,20 +111,30 @@ reg link_state; ...@@ -108,20 +111,30 @@ reg link_state;
// 1 - connection is being established OR already established, 0 - is not // 1 - connection is being established OR already established, 0 - is not
reg oob_state; reg oob_state;
// Force offline from AHCI
reg force_offline_r; // AHCI conrol need setting offline/sending comreset
always @ (posedge clk) begin
if (rst || comreset_send) force_offline_r <= 0;
else if (set_offline) force_offline_r <= 1;
end
assign phy_ready = link_state & gtx_ready & rxbyteisaligned; assign phy_ready = link_state & gtx_ready & rxbyteisaligned;
always @ (posedge clk) always @ (posedge clk)
link_state <= (link_state | link_up) & ~link_down & ~rst; link_state <= (link_state | link_up) & ~link_down & ~rst & ~force_offline_r;
always @ (posedge clk) always @ (posedge clk)
oob_state <= (oob_state | oob_start | cominit_req & cominit_allow) & ~oob_error & ~oob_silence & ~(link_down & ~oob_busy & ~oob_start) & ~rst; oob_state <= (oob_state | oob_start | cominit_req & cominit_allow) & ~oob_error & ~oob_silence & ~(link_down & ~oob_busy & ~oob_start) & ~rst;
// decide when to issue oob: always when gtx is ready // decide when to issue oob: always when gtx is ready
assign oob_start = gtx_ready & ~oob_state & ~oob_busy; //assign oob_start = gtx_ready & ~oob_state & ~oob_busy;
assign oob_start = gtx_ready & ~oob_state & ~oob_busy & ~force_offline_r;
// set line to idle state before if we're waiting for a device to answer AND while oob sequence // set line to idle state before if we're waiting for a device to answer AND while oob sequence
wire txelecidle_inner; wire txelecidle_inner;
assign txelecidle = /*~oob_state |*/ txelecidle_inner; //assign txelecidle = /*~oob_state |*/ txelecidle_inner ;
assign txelecidle = /*~oob_state |*/ txelecidle_inner || force_offline_r;
// let devices always begin oob sequence, if only it's not a glitch // let devices always begin oob sequence, if only it's not a glitch
assign cominit_allow = cominit_req & link_state; assign cominit_allow = cominit_req & link_state;
......
...@@ -710,7 +710,13 @@ sata_phy phy( ...@@ -710,7 +710,13 @@ sata_phy phy(
// from link layer // from link layer
.ll_data_in (ll2phy_data), .ll_data_in (ll2phy_data),
.ll_charisk_in (ll2phy_isk) .ll_charisk_in (ll2phy_isk),
// added for AHCI
.set_offline (1'b0), // input
.comreset_send (1'b0), // input
.cominit_got (), // output wire
.comwake_got () // output wire
); );
endmodule endmodule
...@@ -69,7 +69,13 @@ module sata_phy #( ...@@ -69,7 +69,13 @@ module sata_phy #(
// from link layer // from link layer
input wire [DATA_BYTE_WIDTH * 8 - 1:0] ll_data_in, input wire [DATA_BYTE_WIDTH * 8 - 1:0] ll_data_in,
input wire [DATA_BYTE_WIDTH - 1:0] ll_charisk_in input wire [DATA_BYTE_WIDTH - 1:0] ll_charisk_in,
input set_offline, // electrically idle
input comreset_send, // Not possible yet?
output wire cominit_got,
output wire comwake_got
); );
wire [DATA_BYTE_WIDTH * 8 - 1:0] txdata; wire [DATA_BYTE_WIDTH * 8 - 1:0] txdata;
...@@ -110,7 +116,8 @@ wire rxelsfull; ...@@ -110,7 +116,8 @@ wire rxelsfull;
wire rxelsempty; wire rxelsempty;
//wire gtx_ready; //wire gtx_ready;
assign cominit_got = rxcominitdet; // For AHCI
assign comwake_got = rxcomwakedet; // For AHCI
wire dummy; wire dummy;
oob_ctrl oob_ctrl( oob_ctrl oob_ctrl(
// sata clk = usrclk2 // sata clk = usrclk2
...@@ -152,7 +159,11 @@ oob_ctrl oob_ctrl( ...@@ -152,7 +159,11 @@ oob_ctrl oob_ctrl(
.rxbyteisaligned (rxbyteisaligned), .rxbyteisaligned (rxbyteisaligned),
// shows if channel is ready // shows if channel is ready
.phy_ready (phy_ready) .phy_ready (phy_ready),
// To/from AHCI
.set_offline (set_offline), // input
.comreset_send (comreset_send) // input
); );
wire cplllockdetclk; // TODO wire cplllockdetclk; // TODO
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment