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
......
/*******************************************************************************
* Module: sata_ahci_top
* Date: 2015-07-11
* Author: Alexey
* Description: sata for z7nq top-level module
*
* Copyright (c) 2015 Elphel, Inc.
* sata_ahci_top.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sata_ahci_top.v file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*
* Additional permission under GNU GPL version 3 section 7:
* If you modify this Program, or any covered work, by linking or combining it
* with independent modules provided by the FPGA vendor only (this permission
* does not extend to any 3-rd party modules, "soft cores" or macros) under
* different license terms solely for the purpose of generating binary "bitstream"
* files and/or simulating the code, the copyright holders of this Program give
* you the right to distribute the covered work without those independent modules
* as long as the source code for them is available from the FPGA vendor free of
* charge, and there is no dependence on any encrypted modules for simulating of
* the combined code. This permission applies to you if the distributed code
* contains all the components and scripts required to completely simulate it
* with at least one of the Free Software programs.
*******************************************************************************/
`timescale 1ns/1ps
/*
* Takes commands from axi iface as a slave, transfers data with another axi iface as a master
*/
module sata_ahci_top(
output wire sata_clk,
output wire sata_rst,
input wire arst, // extrst,
// reliable clock to source drp and cpll lock det circuits
input wire reliable_clk,
input wire hclk,
/*
* Commands interface
*/
input wire ACLK, // AXI PS Master GP1 Clock , input
input wire ARESETN, // AXI PS Master GP1 Reset, output
// AXI PS Master GP1: Read Address
input wire [31:0] ARADDR, // AXI PS Master GP1 ARADDR[31:0], output
input wire ARVALID, // AXI PS Master GP1 ARVALID, output
output wire ARREADY, // AXI PS Master GP1 ARREADY, input
input wire [11:0] ARID, // AXI PS Master GP1 ARID[11:0], output
input wire [3:0] ARLEN, // AXI PS Master GP1 ARLEN[3:0], output
input wire [1:0] ARSIZE, // AXI PS Master GP1 ARSIZE[1:0], output
input wire [1:0] ARBURST, // AXI PS Master GP1 ARBURST[1:0], output
// AXI PS Master GP1: Read Data
output wire [31:0] RDATA, // AXI PS Master GP1 RDATA[31:0], input
output wire RVALID, // AXI PS Master GP1 RVALID, input
input wire RREADY, // AXI PS Master GP1 RREADY, output
output wire [11:0] RID, // AXI PS Master GP1 RID[11:0], input
output wire RLAST, // AXI PS Master GP1 RLAST, input
output wire [1:0] RRESP, // AXI PS Master GP1 RRESP[1:0], input
// AXI PS Master GP1: Write Address
input wire [31:0] AWADDR, // AXI PS Master GP1 AWADDR[31:0], output
input wire AWVALID, // AXI PS Master GP1 AWVALID, output
output wire AWREADY, // AXI PS Master GP1 AWREADY, input
input wire [11:0] AWID, // AXI PS Master GP1 AWID[11:0], output
input wire [3:0] AWLEN, // AXI PS Master GP1 AWLEN[3:0], outpu:t
input wire [1:0] AWSIZE, // AXI PS Master GP1 AWSIZE[1:0], output
input wire [1:0] AWBURST, // AXI PS Master GP1 AWBURST[1:0], output
// AXI PS Master GP1: Write Data
input wire [31:0] WDATA, // AXI PS Master GP1 WDATA[31:0], output
input wire WVALID, // AXI PS Master GP1 WVALID, output
output wire WREADY, // AXI PS Master GP1 WREADY, input
input wire [11:0] WID, // AXI PS Master GP1 WID[11:0], output
input wire WLAST, // AXI PS Master GP1 WLAST, output
input wire [3:0] WSTRB, // AXI PS Master GP1 WSTRB[3:0], output
// AXI PS Master GP1: Write response
output wire BVALID, // AXI PS Master GP1 BVALID, input
input wire BREADY, // AXI PS Master GP1 BREADY, output
output wire [11:0] BID, // AXI PS Master GP1 BID[11:0], input
output wire [1:0] BRESP, // AXI PS Master GP1 BRESP[1:0], input
/*
* Data interface
*/
output wire [31:0] afi_awaddr,
output wire afi_awvalid,
input wire afi_awready,
output wire [5:0] afi_awid,
output wire [1:0] afi_awlock,
output wire [3:0] afi_awcache,
output wire [2:0] afi_awprot,
output wire [3:0] afi_awlen,
output wire [1:0] afi_awsize,
output wire [1:0] afi_awburst,
output wire [3:0] afi_awqos,
// write data
output wire [63:0] afi_wdata,
output wire afi_wvalid,
input wire afi_wready,
output wire [5:0] afi_wid,
output wire afi_wlast,
output wire [7:0] afi_wstrb,
// write response
input wire afi_bvalid,
output wire afi_bready,
input wire [5:0] afi_bid,
input wire [1:0] afi_bresp,
// PL extra (non-AXI) signals
input wire [7:0] afi_wcount,
input wire [5:0] afi_wacount,
output wire afi_wrissuecap1en,
// AXI_HP signals - read channel
// read address
output wire [31:0] afi_araddr,
output wire afi_arvalid,
input wire afi_arready,
output wire [5:0] afi_arid,
output wire [1:0] afi_arlock,
output wire [3:0] afi_arcache,
output wire [2:0] afi_arprot,
output wire [3:0] afi_arlen,
output wire [1:0] afi_arsize,
output wire [1:0] afi_arburst,
output wire [3:0] afi_arqos,
// read data
input wire [63:0] afi_rdata,
input wire afi_rvalid,
output wire afi_rready,
input wire [5:0] afi_rid,
input wire afi_rlast,
input wire [1:0] afi_rresp,
// PL extra (non-AXI) signals
input wire [7:0] afi_rcount,
input wire [2:0] afi_racount,
output wire afi_rdissuecap1en,
/*
* PHY
*/
output wire TXN,
output wire TXP,
input wire RXN,
input wire RXP,
input wire EXTCLK_P,
input wire EXTCLK_N
);
wire sata_clk;
wire sata_rst;
wire exrst;
// Data/type FIFO, host -> device
// Data System memory or FIS -> device
wire [31:0] h2d_data; // 32-bit data from the system memory to HBA (dma data)
wire [ 1:0] h2d_type; // 0 - data, 1 - FIS head, 2 - FIS END (make FIS_Last?)
wire h2d_valid; // output register full
wire h2d_ready; // send FIFO has room for data (>= 8? dwords)
// Data/type FIFO, device -> host
wire [31:0] d2h_data; // FIFO output data
wire [ 1:0] d2h_type; // 0 - data, 1 - FIS head, 2 - R_OK, 3 - R_ERR
wire d2h_valid; // Data available from the transport layer in FIFO
wire d2h_many; // Multiple DWORDs available from the transport layer in FIFO
wire d2h_ready; // This module or DMA consumes DWORD
// communication with transport/link/phys layers
// wire phy_rst; // frome phy, as a response to hba_arst || port_arst. It is deasserted when clock is stable
wire [ 1:0] phy_ready; // 0 - not ready, 1..3 - negotiated speed
wire xmit_ok; // FIS transmission acknowledged OK
wire xmit_err; // Error during sending of a FIS
wire syncesc_recv; // These two inputs interrupt transmit
wire pcmd_st_cleared; // bit was cleared by software
wire syncesc_send; // Send sync escape
wire syncesc_send_done; // "SYNC escape until the interface is quiescent..."
wire comreset_send; // Not possible yet?
wire cominit_got;
wire set_offline; // electrically idle
wire x_rdy_collision; // X_RDY/X_RDY collision on interface
wire send_R_OK; // Should it be originated in this layer SM?
wire send_R_ERR;
// additional errors from SATA layers (single-clock pulses):
wire serr_DT; // RWC: Transport state transition error
wire serr_DS; // RWC: Link sequence error
wire serr_DH; // RWC: Handshake Error (i.e. Device got CRC error)
wire serr_DC; // RWC: CRC error in Link layer
wire serr_DB; // RWC: 10B to 8B decode error
wire serr_DW; // RWC: COMMWAKE signal was detected
wire serr_DI; // RWC: PHY Internal Error
// sirq_PRC,
// sirq_IF || // sirq_INF
wire serr_EP; // RWC: Protocol Error - a violation of SATA protocol detected
wire serr_EC; // RWC: Persistent Communication or Data Integrity Error
wire serr_ET; // RWC: Transient Data Integrity Error (error not recovered by the interface)
wire serr_EM; // RWC: Communication between the device and host was lost but re-established
wire serr_EI; // RWC: Recovered Data integrity Error
// additional control signals for SATA layers
wire [3:0] sctl_ipm; // Interface power management transitions allowed
wire [3:0] sctl_spd; // Interface maximal speed
wire irq; // CPU interrupt request
ahci_top #(
.PREFETCH_ALWAYS(0),
.READ_REG_LATENCY(2),
.READ_CT_LATENCY(1),
.ADDRESS_BITS(10)
) ahci_top_i (
.aclk (ACLK), // input
.arst (arst), // input
.mclk (sata_clk), // input
.mrst (sata_rst), // input
.hba_arst (exrst), // output
.port_arst (), // output
.hclk (hclk), // input
.hrst (), // input
.awaddr(AWADDR), // input[31:0]
.awvalid(AWVALID), // input
.awready(AWREADY), // output
.awid(AWID), // input[11:0]
.awlen(AWLEN), // input[3:0]
.awsize(AWSIZE), // input[1:0]
.awburst(AWBURST), // input[1:0]
.wdata(WDATA), // input[31:0]
.wvalid(WVALID), // input
.wready(WREADY), // output
.wid(WID), // input[11:0]
.wlast(WLAST), // input
.wstb(WSTRB), // input[3:0]
.bvalid(BVALID), // output
.bready(BREADY), // input
.bid(BID), // output[11:0]
.bresp(BRESP), // output[1:0]
.araddr(ARADDR), // input[31:0]
.arvalid(ARVALID), // input
.arready(ARREADY), // output
.arid(ARID), // input[11:0]
.arlen(ARLEN), // input[3:0]
.arsize(ARSIZE), // input[1:0]
.arburst(ARBURST), // input[1:0]
.rdata(RDATA), // output[31:0]
.rvalid(RVALID), // output
.rready(RREADY), // input
.rid(RID), // output[11:0]
.rlast(RLAST), // output
.rresp(RRESP), // output[1:0]
.afi_awaddr(afi_awaddr), // output[31:0]
.afi_awvalid(afi_awvalid), // output
.afi_awready(afi_awready), // input
.afi_awid(afi_awid), // output[5:0]
.afi_awlock(afi_awlock), // output[1:0]
.afi_awcache(afi_awcache), // output[3:0]
.afi_awprot(afi_awprot), // output[2:0]
.afi_awlen(afi_awlen), // output[3:0]
.afi_awsize(afi_awsize), // output[1:0]
.afi_awburst(afi_awburst), // output[1:0]
.afi_awqos(afi_awqos), // output[3:0]
.afi_wdata(afi_wdata), // output[63:0]
.afi_wvalid(afi_wvalid), // output
.afi_wready(afi_wready), // input
.afi_wid(afi_wid), // output[5:0]
.afi_wlast(afi_wlast), // output
.afi_wstrb(afi_wstrb), // output[7:0]
.afi_bvalid(afi_bvalid), // input
.afi_bready(afi_bready), // output
.afi_bid(afi_bid), // input[5:0]
.afi_bresp(afi_bresp), // input[1:0]
.afi_wcount(afi_wcount), // input[7:0]
.afi_wacount(afi_wacount), // input[5:0]
.afi_wrissuecap1en (afi_wrissuecap1en), // output
.afi_araddr(afi_araddr), // output[31:0]
.afi_arvalid(afi_arvalid), // output
.afi_arready(afi_arready), // input
.afi_arid(afi_arid), // output[5:0]
.afi_arlock(afi_arlock), // output[1:0]
.afi_arcache(afi_arcache), // output[3:0]
.afi_arprot(afi_arprot), // output[2:0]
.afi_arlen(afi_arlen), // output[3:0]
.afi_arsize(afi_arsize), // output[1:0]
.afi_arburst(afi_arburst), // output[1:0]
.afi_arqos(afi_arqos), // output[3:0]
.afi_rdata(afi_rdata), // input[63:0]
.afi_rvalid(afi_rvalid), // input
.afi_rready(afi_rready), // output
.afi_rid(afi_rid), // input[5:0]
.afi_rlast(afi_rlast), // input
.afi_rresp(afi_rresp), // input[1:0]
.afi_rcount(afi_rcount), // input[7:0]
.afi_racount(afi_racount), // input[2:0]
.afi_rdissuecap1en(afi_rdissuecap1en), // output
.h2d_data(h2d_data), // output[31:0]
.h2d_type(h2d_type), // output[1:0]
.h2d_valid(h2d_valid), // output
.h2d_ready(h2d_ready), // input
.d2h_data(d2h_data), // input[31:0]
.d2h_type(d2h_type), // input[1:0]
.d2h_valid(d2h_valid), // input
.d2h_many(), // input
.d2h_ready(), // output
.phy_ready(), // input[1:0]
.xmit_ok(), // input
.xmit_err(), // input
.syncesc_recv(), // input
.pcmd_st_cleared(), // output
.syncesc_send(), // output
.syncesc_send_done(), // input
.comreset_send(), // output
.cominit_got(), // input
.set_offline(), // output
.x_rdy_collision(), // input
.send_R_OK(), // output
.send_R_ERR(), // output
.serr_DT(), // input
.serr_DS(), // input
.serr_DH(), // input
.serr_DC(), // input
.serr_DB(), // input
.serr_DW(), // input
.serr_DI(), // input
.serr_EP(), // input
.serr_EC(), // input
.serr_ET(), // input
.serr_EM(), // input
.serr_EI(), // input
.sctl_ipm(), // output[3:0]
.sctl_spd(), // output[3:0]
.irq() // output
);
ahci_sata_layers #(
.BITS_TO_START_XMIT(6),
.DATA_BYTE_WIDTH(4)
) ahci_sata_layers_i (
.exrst (exrst), // input
.reliable_clk (ACLK), // input
.rst (sata_rst), // output
.clk (sata_clk), // output
.h2d_data(), // input[31:0]
.h2d_mask(), // input[1:0]
.h2d_type(), // input[1:0]
.h2d_valid(), // input
.h2d_ready(), // output
.d2h_data(), // output[31:0]
.d2h_mask(), // output[1:0]
.d2h_type(), // output[1:0]
.d2h_valid(), // output
.d2h_many(), // output
.d2h_ready(), // input
.phy_speed(), // output[1:0]
.gtx_ready(), // output
.xmit_ok(), // output
.xmit_err(), // output
.x_rdy_collision(), // output
.syncesc_recv(), // output
.pcmd_cleared(), // input
.syncesc_send(), // input
.syncesc_send_done(), // output
.comreset_send(), // input
.cominit_got(), // output
.set_offline(), // input
.send_R_OK(), // input
.send_R_ERR(), // input
.serr_DT(), // output
.serr_DS(), // output
.serr_DH(), // output
.serr_DC(), // output
.serr_DB(), // output
.serr_DW(), // output
.serr_DI(), // output
.serr_EP(), // output
.serr_EC(), // output
.serr_ET(), // output
.serr_EM(), // output
.serr_EI(), // output
.sctl_ipm(), // input[3:0]
.sctl_spd(), // input[3:0]
.extclk_p(), // input wire
.extclk_n(), // input wire
.txp_out(), // output wire
.txn_out(), // output wire
.rxp_in(), // input wire
.rxn_in() // input wire
);
endmodule
...@@ -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