Commit f4dc8593 authored by Andrey Filippov's avatar Andrey Filippov

Connected generated decoder+multiplexer to AHCI state machine

parent 3e169400
...@@ -45,6 +45,7 @@ module ahci_fsm ...@@ -45,6 +45,7 @@ module ahci_fsm
input phy_ready, // goes up after comreset,cominit, align, ... input phy_ready, // goes up after comreset,cominit, align, ...
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?
input cominit_got, // asynchronously jumps to P:Cominit state input cominit_got, // asynchronously jumps to P:Cominit state
output set_offline, // electrically idle output set_offline, // electrically idle
input x_rdy_collision, // X_RDY/X_RDY collision on interface input x_rdy_collision, // X_RDY/X_RDY collision on interface
...@@ -57,6 +58,7 @@ module ahci_fsm ...@@ -57,6 +58,7 @@ module ahci_fsm
// update register inputs (will write to register memory current value of the corresponding register) // update register inputs (will write to register memory current value of the corresponding register)
output pfsm_started, // H: FSM doene, P: FSM started (enable sensing pcmd_st_cleared) output pfsm_started, // H: FSM doene, P: FSM started (enable sensing pcmd_st_cleared)
// update register inputs (will write to register memory current value of the corresponding register) // update register inputs (will write to register memory current value of the corresponding register)
// Removing - such updates are always done when startimng new state
input update_pending, input update_pending,
output update_all, output update_all,
input update_busy, // valid same cycle as update_all input update_busy, // valid same cycle as update_all
...@@ -137,8 +139,8 @@ module ahci_fsm ...@@ -137,8 +139,8 @@ module ahci_fsm
input [3:0] ssts_det, // current value of PxSSTS.DET input [3:0] ssts_det, // current value of PxSSTS.DET
// SCR2:SControl (written by software only) // SCR2:SControl (written by software only)
input [3:0] sctl_ipm, // Interface power management transitions allowed /// input [3:0] sctl_ipm, // Interface power management transitions allowed
input [3:0] sctl_spd, // Interface maximal speed /// input [3:0] sctl_spd, // Interface maximal speed
input [3:0] sctl_det, // Device detection initialization requested input [3:0] sctl_det, // Device detection initialization requested
input sctl_det_changed, // Software had written new value to sctl_det input sctl_det_changed, // Software had written new value to sctl_det
output sctl_det_reset, // clear sctl_det_changed output sctl_det_reset, // clear sctl_det_changed
...@@ -147,11 +149,13 @@ module ahci_fsm ...@@ -147,11 +149,13 @@ module ahci_fsm
input pxci0, // pxCI current value input pxci0, // pxCI current value
// inputs from the DMA engine // inputs from the DMA engine
input dma_prd_done, // output (finished next prd) /// input dma_prd_done, // output (finished next prd)
output dma_prd_irq_clear, // reset pending prd_irq output dma_prd_irq_clear, // reset pending prd_irq
input dma_prd_irq_pend, // prd interrupt pending. This is just a condition for irq - actual will be generated after FIS OK input dma_prd_irq_pend, // prd interrupt pending. This is just a condition for irq - actual will be generated after FIS OK
input dma_cmd_busy, // output reg (DMA engine is processing PRDs) /// input dma_cmd_busy, // output reg (DMA engine is processing PRDs)
input dma_cmd_done, // output (last PRD is over) /// input dma_cmd_done, // output (last PRD is over)
output dma_cmd_abort, // try to abort a command
// Communication with ahci_fis_receive (some are unused) // Communication with ahci_fis_receive (some are unused)
// Debug features // Debug features
...@@ -170,7 +174,7 @@ module ahci_fsm ...@@ -170,7 +174,7 @@ module ahci_fsm
output get_ufis, output get_ufis,
output get_data_fis, output get_data_fis,
output get_ignore, // ignore whatever FIS (use for DMA activate too?) output get_ignore, // ignore whatever FIS (use for DMA activate too?)
input get_fis_busy, // busy processing FIS // input get_fis_busy, // busy processing FIS
input get_fis_done, // done processing FIS (see fis_ok, fis_err, fis_ferr) input get_fis_done, // done processing FIS (see fis_ok, fis_err, fis_ferr)
input fis_ok, // FIS done, checksum OK reset by starting a new get FIS input fis_ok, // FIS done, checksum OK reset by starting a new get FIS
input fis_err, // FIS done, checksum ERROR reset by starting a new get FIS input fis_err, // FIS done, checksum ERROR reset by starting a new get FIS
...@@ -178,8 +182,8 @@ module ahci_fsm ...@@ -178,8 +182,8 @@ module ahci_fsm
input fis_extra, // more data got from FIS than DMA can accept. Does not deny fis_ok. May have latency input fis_extra, // more data got from FIS than DMA can accept. Does not deny fis_ok. May have latency
output set_update_sig, // when set, enables get_sig (and resets itself) output set_update_sig, // when set, enables get_sig (and resets itself)
input pUpdateSig, // state variable /// input pUpdateSig, // state variable
input sig_available, // device signature available /// input sig_available, // device signature available
output update_sig, // update signature output update_sig, // update signature
...@@ -202,17 +206,17 @@ module ahci_fsm ...@@ -202,17 +206,17 @@ module ahci_fsm
input pPioXfer, // state variable input pPioXfer, // state variable
input [7:0] tfd_sts, // Current PxTFD status field (updated after regFIS and SDB - certain fields) input [7:0] tfd_sts, // Current PxTFD status field (updated after regFIS and SDB - certain fields)
// tfd_sts[7] - BSY, tfd_sts[4] - DRQ, tfd_sts[0] - ERR // tfd_sts[7] - BSY, tfd_sts[4] - DRQ, tfd_sts[0] - ERR
input [7:0] tfd_err, // Current PxTFD error field (updated after regFIS and SDB) /// input [7:0] tfd_err, // Current PxTFD error field (updated after regFIS and SDB)
input fis_i, // value of "I" field in received regsD2H or SDB FIS input fis_i, // value of "I" field in received regsD2H or SDB FIS
input sdb_n, // value of "N" field in received SDB FIS /// input sdb_n, // value of "N" field in received SDB FIS
input dma_a, // value of "A" field in received DMA Setup FIS input dma_a, // value of "A" field in received DMA Setup FIS
input dma_d, // value of "D" field in received DMA Setup FIS /// input dma_d, // value of "D" field in received DMA Setup FIS
input pio_i, // value of "I" field in received PIO Setup FIS input pio_i, // value of "I" field in received PIO Setup FIS
input pio_d, // value of "D" field in received PIO Setup FIS input pio_d, // value of "D" field in received PIO Setup FIS
input [7:0] pio_es, // value of PIO E_Status /// input [7:0] pio_es, // value of PIO E_Status
input sactive0, // bit 0 of sActive DWORD received in SDB FIS /// input sactive0, // bit 0 of sActive DWORD received in SDB FIS
// Using even word count (will be rounded up), partial DWORD (last) will be handled by PRD length if needed // Using even word count (will be rounded up), partial DWORD (last) will be handled by PRD length if needed
input [31:2] xfer_cntr, // transfer counter in words for both DMA (31 bit) and PIO (lower 15 bits), updated after decr_dwc /// input [31:2] xfer_cntr, // transfer counter in words for both DMA (31 bit) and PIO (lower 15 bits), updated after decr_dwc
input xfer_cntr_zero,// valid next cycle input xfer_cntr_zero,// valid next cycle
// Communication with ahci_fis_transmit // Communication with ahci_fis_transmit
...@@ -224,7 +228,7 @@ module ahci_fsm ...@@ -224,7 +228,7 @@ module ahci_fsm
// transmit until error, 2048DWords or pDmaXferCnt // transmit until error, 2048DWords or pDmaXferCnt
output atapi_xmit, // tarsmit ATAPI command FIS output atapi_xmit, // tarsmit ATAPI command FIS
input xmit_done, input xmit_done,
input xmit_busy, // input xmit_busy,
output clearCmdToIssue, // From CFIS:SUCCESS output clearCmdToIssue, // From CFIS:SUCCESS
input pCmdToIssue, // AHCI port variable input pCmdToIssue, // AHCI port variable
...@@ -233,19 +237,24 @@ module ahci_fsm ...@@ -233,19 +237,24 @@ module ahci_fsm
// input xmit_err, // // input xmit_err, //
input [ 1:0] dx_err, // bit 0 - syncesc_recv, 1 - xmit_err (valid @ xmit_err and later, reset by new command) input [ 1:0] dx_err, // bit 0 - syncesc_recv, 1 - xmit_err (valid @ xmit_err and later, reset by new command)
input [15:0] ch_prdtl, // Physical region descriptor table length (in entries, 0 is 0) /// input [15:0] ch_prdtl, // Physical region descriptor table length (in entries, 0 is 0)
input ch_c, // Clear busy upon R_OK for this FIS input ch_c, // Clear busy upon R_OK for this FIS
input ch_b, // Built-in self test command input ch_b, // Built-in self test command
input ch_r, // reset - may need to send SYNC escape before this command input ch_r, // reset - may need to send SYNC escape before this command
input ch_p, // prefetchable - only used with non-zero PRDTL or ATAPI bit set input ch_p, // prefetchable - only used with non-zero PRDTL or ATAPI bit set
input ch_w, // Write: system memory -> device input ch_w, // Write: system memory -> device
input ch_a, // ATAPI: 1 means device should send PIO setup FIS for ATAPI command input ch_a // ATAPI: 1 means device should send PIO setup FIS for ATAPI command
input [4:0] ch_cfl, // length of the command FIS in DW, 0 means none. 0 and 1 - illegal, /// input [4:0] ch_cfl, // length of the command FIS in DW, 0 means none. 0 and 1 - illegal,
// maximal is 16 (0x10) // maximal is 16 (0x10)
input [11:0] dwords_sent // number of DWORDs transmitted (up to 2048) /// input [11:0] dwords_sent // number of DWORDs transmitted (up to 2048)
); );
`include "includes/ahci_localparams.vh" // @SuppressThisWarning VEditor : Unused localparams `include "includes/ahci_localparams.vh" // @SuppressThisWarning VEditor : Unused localparams
`include "includes/fis_types.vh" // @SuppressThisWarning VEditor : Some localparams unused
wire tfd_bsy = tfd_sts[7];
wire tfd_drq = tfd_sts[4];
wire tfd_sts_err = tfd_sts[0];
reg [ 9:0] pgm_waddr; reg [ 9:0] pgm_waddr;
// wire pgm_ren; // wire pgm_ren;
// wire pgm_regen; // wire pgm_regen;
...@@ -261,8 +270,8 @@ module ahci_fsm ...@@ -261,8 +270,8 @@ module ahci_fsm
reg fsm_act_busy; reg fsm_act_busy;
reg [1:0] fsm_transitions; // processing transitions reg [1:0] fsm_transitions; // processing transitions
reg fsm_preload; // read first sequence data (2 cycles for regen) reg fsm_preload; // read first sequence data (2 cycles for regen)
wire [7:0] precond_w = pgm_data[17:10]; // select what to use - cond_met_w valis after precond_w, same time as conditions // wire [7:0] precond_w = pgm_data[17:10]; // select what to use - cond_met_w valis after precond_w, same time as conditions
reg [7:0] conditions; // reg [7:0] conditions;
wire pre_jump_w = (|async_pend_r) ? async_ackn : (cond_met_w & fsm_transitions[1]); wire pre_jump_w = (|async_pend_r) ? async_ackn : (cond_met_w & fsm_transitions[1]);
wire fsm_act_done = get_fis_done || xmit_done; wire fsm_act_done = get_fis_done || xmit_done;
wire fsm_wait_act_w = pgm_data[16]; // this action requires waiting for done wire fsm_wait_act_w = pgm_data[16]; // this action requires waiting for done
...@@ -304,8 +313,8 @@ module ahci_fsm ...@@ -304,8 +313,8 @@ module ahci_fsm
if (fsm_jump[0]) pgm_addr <= pgm_jump_addr; if (fsm_jump[0]) pgm_addr <= pgm_jump_addr;
else if (fsm_next) pgm_addr <= pgm_addr + 1; else if (fsm_next) pgm_addr <= pgm_addr + 1;
if (hba_rst) conditions <= 0; // if (hba_rst) conditions <= 0;
if (fsm_transitions[0]) conditions <= precond_w; // if (fsm_transitions[0]) conditions <= precond_w;
if (hba_rst) fsm_actions <= 0; if (hba_rst) fsm_actions <= 0;
else if (fsm_jump[2]) fsm_actions <= 1; else if (fsm_jump[2]) fsm_actions <= 1;
...@@ -357,108 +366,124 @@ module ahci_fsm ...@@ -357,108 +366,124 @@ module ahci_fsm
action_decoder action_decoder_i ( action_decoder action_decoder_i (
.clk (mclk), // input .clk (mclk), // input
.enable (), // input .enable (fsm_pre_act_w), // input
.data (), // input[10:0] .data (pgm_data[10:0]), // input[10:0]
.PXSERR_DIAG_X (), // output reg // CTRL_STAT
.SIRQ_DHR (), // output reg .PXSERR_DIAG_X (sirq_PC), // output reg
.SIRQ_DP (), // output reg .SIRQ_DHR (sirq_DHR), // output reg
.SIRQ_DS (), // output reg .SIRQ_DP (sirq_DP), // output reg
.SIRQ_IF (), // output reg .SIRQ_DS (sirq_DS), // output reg
.SIRQ_PS (), // output reg .SIRQ_IF (sirq_IF), // output reg
.SIRQ_SDB (), // output reg .SIRQ_PS (sirq_PS), // output reg
.SIRQ_TFE (), // output reg .SIRQ_SDB (sirq_SDB), // output reg
.SIRQ_UF (), // output reg .SIRQ_TFE (sirq_TFE), // output reg
.PFSM_STARTED (), // output reg .SIRQ_UF (sirq_UF), // output reg
.PCMD_CR_CLEAR (), // output reg .PFSM_STARTED (pfsm_started), // output reg
.PCMD_CR_SET (), // output reg .PCMD_CR_CLEAR (pcmd_cr_reset), // output reg
.PXCI0_CLEAR (), // output reg .PCMD_CR_SET (pcmd_cr_set), // output reg
.PXSSTS_DET_1 (), // output reg .PXCI0_CLEAR (pxci0_clear), // output reg
.SSTS_DET_OFFLINE (), // output reg .PXSSTS_DET_1 (ssts_det_dnp), // output reg
.SET_UPDATE_SIG (), // output reg .SSTS_DET_OFFLINE (ssts_det_offline), // output reg
.UPDATE_SIG (), // output reg .SCTL_DET_CLEAR (sctl_det_reset), // output reg
.UPDATE_ERR_STS (), // output reg // FIS RECEIVE
.UPDATE_PIO (), // output reg .SET_UPDATE_SIG (set_update_sig), // output reg
.UPDATE_PRDBC (), // output reg .UPDATE_SIG (update_sig), // output reg
.CLEAR_BSY_DRQ (), // output reg .UPDATE_ERR_STS (update_err_sts), // output reg
.CLEAR_BSY_SET_DRQ (), // output reg .UPDATE_PIO (update_pio), // output reg
.SET_BSY (), // output reg .UPDATE_PRDBC (update_prdbc), // output reg
.SET_STS_7F (), // output reg .CLEAR_BSY_DRQ (clear_bsy_drq), // output reg
.SET_STS_80 (), // output reg .CLEAR_BSY_SET_DRQ (clear_bsy_set_drq), // output reg
.XFER_CNTR_CLEAR (), // output reg .SET_BSY (set_bsy), // output reg
.DECR_DWC (), // output reg .SET_STS_7F (set_sts_7f), // output reg
.FIS_FIRST_FLUSH (), // output reg .SET_STS_80 (set_sts_80), // output reg
.CLEAR_CMD_TO_ISSUE (), // output reg .XFER_CNTR_CLEAR (clear_xfer_cntr), // output reg
.DMA_ABORT (), // output reg .DECR_DWC (decr_dwc), // output reg
.DMA_PRD_IRQ_CLEAR (), // output reg .FIS_FIRST_FLUSH (fis_first_flush), // output reg
.XMIT_COMRESET (), // output reg // FIS_TRANSMIT
.SEND_SYNC_ESC (), // output reg .CLEAR_CMD_TO_ISSUE (clearCmdToIssue), // output reg
.SET_OFFLINE (), // output reg // DMA
.R_OK (), // output reg .DMA_ABORT (dma_cmd_abort), // output reg
.R_ERR (), // output reg .DMA_PRD_IRQ_CLEAR (dma_prd_irq_clear), // output reg
.FETCH_CMD (), // output reg // SATA TRANSPORT/LINK/PHY
.ATAPI_XMIT (), // output reg .XMIT_COMRESET (comreset_send), // output reg
.CFIS_XMIT (), // output reg .SEND_SYNC_ESC (syncesc_send), // output reg
.DX_XMIT (), // output reg .SET_OFFLINE (set_offline), // output reg
.GET_DATA_FIS (), // output reg .R_OK (send_R_OK), // output reg
.GET_DSFIS (), // output reg .R_ERR (send_R_ERR), // output reg
.GET_IGNORE (), // output reg // FIS TRANSMIT/WAIT DONE
.GET_PSFIS (), // output reg .FETCH_CMD (fetch_cmd), // output reg
.GET_RFIS (), // output reg .ATAPI_XMIT (atapi_xmit), // output reg
.GET_SDBFIS (), // output reg .CFIS_XMIT (cfis_xmit), // output reg
.GET_UFIS () // output reg .DX_XMIT (dx_transmit), // output reg
//FIS RECEIVE/WAIT DONE
.GET_DATA_FIS (get_data_fis), // output reg
.GET_DSFIS (get_dsfis), // output reg
.GET_IGNORE (get_ignore), // output reg
.GET_PSFIS (get_psfis), // output reg
.GET_RFIS (get_rfis), // output reg
.GET_SDBFIS (get_sdbfis), // output reg
.GET_UFIS (get_ufis) // output reg
); );
// Condition inputs may be registered if needed
condition_mux condition_mux_i ( condition_mux condition_mux_i (
.clk (mclk), // input .clk (mclk), // input
.sel (), // input[7:0] .sel (pgm_data[17:10]), // input[7:0]
.condition (), // output .condition (cond_met_w), // output
.ST_NB_ND (), // input //COMPOSITE
.PXCI0_NOT_CMDTOISSUE (), // input .ST_NB_ND (pcmd_st && !tfd_bsy &&!tfd_drq), // input PxCMD.ST & !PxTFD.STS.BSY & !PxTFD.STS.DRQ
.PCTI_CTBAR_XCZ (), // input .PXCI0_NOT_CMDTOISSUE (pxci0 && !pCmdToIssue), // input pxci0 && !pCmdToIssue was pIssueSlot==32, -> p:SelectCmd
.PCTI_XCZ (), // input .PCTI_CTBAR_XCZ (pCmdToIssue && xfer_cntr_zero && ch_r ), // input pCmdToIssue && ch_r && xfer_cntr_zero
.NST_D2HR (), // input .PCTI_XCZ (pCmdToIssue && xfer_cntr_zero), // input pCmdToIssue && xfer_cntr_zero
.NPD_NCA (), // input .NST_D2HR (!pcmd_st && (fis_type == FIS_D2HR)), // input !ST && (FIS == FIS_D2HR) TODO: does it mean either BSY or DRQ are 1?
.CHW_DMAA (), // input .NPD_NCA (!pio_d && !ch_a), // input pio_d = 0 && ch_a == 0
.SCTL_DET_CHANGED_TO_4 (), // input .CHW_DMAA (ch_w && dma_a), // input ch_w && dma_a
.SCTL_DET_CHANGED_TO_1 (), // input // CTRL_STAT
.PXSSTS_DET_NE_3 (), // input .SCTL_DET_CHANGED_TO_4 (sctl_det_changed && (sctl_det == 4)), // input (requires sctl_det_reset after)
.PXSSTS_DET_EQ_1 (), // input .SCTL_DET_CHANGED_TO_1 (sctl_det_changed && (sctl_det == 1)), // input (requires sctl_det_reset after)
.NPCMD_FRE (), // input .PXSSTS_DET_NE_3 (ssts_det != 3), // input ssts_det!=3, // device detected, phy communication not established
.FIS_OK (), // input .PXSSTS_DET_EQ_1 (ssts_det == 1), // input
.FIS_ERR (), // input .NPCMD_FRE (!pxcmd_fre), // input !pcmd_fre (docs: goto P:NotRunning, but we need to clear FIFO)
.FIS_FERR (), // input // FIS RECEIVE
.FIS_EXTRA (), // input .FIS_OK (fis_ok), // input
.FIS_FIRST_INVALID (), // input .FIS_ERR (fis_err), // input
.FR_D2HR (), // input .FIS_FERR (fis_ferr), // input
.FIS_DATA (), // input .FIS_EXTRA (fis_extra), // input
.FIS_ANY (), // input .FIS_FIRST_INVALID (fis_first_invalid), // input
.NB_ND_D2HR_PIO (), // input .FR_D2HR (fis_first_vld && (fis_type == FIS_D2HR)), // input fis_first_vld & fis_type == 0x34 (D2H Register)
.D2HR (), // input .FIS_DATA (fis_first_vld && (fis_type == FIS_DATA)), // input fis_first_vld && (fis_type == 'h46)
.SDB (), // input .FIS_ANY (fis_first_vld), // input
.DMA_ACT (), // input .NB_ND_D2HR_PIO (((fis_type == FIS_D2HR) || (fis_type == FIS_PIOS)) && !tfd_bsy && !tfd_drq), // input ((FIS == FIS_D2HR) || (FIS == FIS_PIOS)) && !PxTFD.STS.BSY & !PxTFD.STS.DRQ
.DMA_SETUP (), // input .D2HR ( fis_type == FIS_D2HR), // input FIS == FIS_D2HR
.BIST_ACT_FE (), // input .SDB ( fis_type == FIS_SDB), // input
.BIST_ACT (), // input .DMA_ACT ( fis_type == FIS_DMAA), // input
.PIO_SETUP (), // input .DMA_SETUP ( fis_type == FIS_DMAS), // input
.NB_ND (), // input .BIST_ACT_FE (( fis_type == FIS_BIST) && (|bist_bits)), // input FIS == FIS_BIST && |bist_bits
.TFD_STS_ERR (), // input .BIST_ACT (( fis_type == FIS_BIST)), // input FIS == FIS_BIST# && !(|bist_bits)
.FIS_I (), // input .PIO_SETUP ( fis_type == FIS_PIOS), // input
.PIO_I (), // input .NB_ND (!tfd_bsy &&!tfd_drq), // input PxTFD.STS.BSY =’0’ and PxTFD.STS.DRQ =’0’
.NPD (), // input .TFD_STS_ERR ( tfd_sts_err), // input tfd_sts[0]
.PIOX (), // input .FIS_I (fis_i), // input
.XFER0 (), // input .PIO_I (pio_i), // input
.PIOX_XFER0 (), // input .NPD (!pio_d), // input pio_d = 0 , "ch_a == 1" is not needed
.CTBAA_CTBAP (), // input .PIOX (pPioXfer), // input
.CTBAP (), // input .XFER0 (xfer_cntr_zero), // input xfer_cntr_zero
.CTBA_B (), // input .PIOX_XFER0 (pPioXfer && xfer_cntr_zero), // input pPioXfer && xfer_cntr_zero
.CTBA_C (), // input // FIS_TRANSMIT
.TX_ERR (), // input .CTBAA_CTBAP (ch_a && ch_p), // input
.SYNCESC_ERR (), // input .CTBAP (ch_p), // input
.DMA_PRD_IRQ_PEND (), // input .CTBA_B (ch_b), // input
.X_RDY_COLLISION () // input .CTBA_C (ch_c), // input
.TX_ERR (dx_err[1]), // input dx_err[1] (reset by new command)
.SYNCESC_ERR (dx_err[0]), // input
// DMA
.DMA_PRD_IRQ_PEND (dma_prd_irq_pend), // input
// SATA TRANSPORT/LINK/PHY
.X_RDY_COLLISION (x_rdy_collision_pend) // input
); );
/* /*
output update_all, output update_all,
input update_busy, // valid same cycle as update_all input update_busy, // valid same cycle as update_all
......
...@@ -147,6 +147,7 @@ module ahci_top#( ...@@ -147,6 +147,7 @@ module ahci_top#(
input xmit_err, // Error during sending of a FIS input xmit_err, // Error during sending of a FIS
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?
input cominit_got, input cominit_got,
output set_offline, // electrically idle output set_offline, // electrically idle
input x_rdy_collision, // X_RDY/X_RDY collision on interface input x_rdy_collision, // X_RDY/X_RDY collision on interface
...@@ -197,7 +198,9 @@ module ahci_top#( ...@@ -197,7 +198,9 @@ module ahci_top#(
wire dev_wr; // input wire dev_wr; // input
wire dma_cmd_start; // input wire dma_cmd_start; // input
wire dma_prd_start; // input wire dma_prd_start; // input
wire dma_cmd_abort; // input wire dma_cmd_abort_xmit; // input
wire dma_cmd_abort_fsm; // abort from FSM (also from ahci_fis_transmit)
// Use some of the custom registers in the address space? // Use some of the custom registers in the address space?
wire [17:0] fsm_pgm_ad; // @aclk, address/data to program the AHCI FSM wire [17:0] fsm_pgm_ad; // @aclk, address/data to program the AHCI FSM
wire fsm_pgm_wa; // @aclk, address strobe to program the AHCI FSM wire fsm_pgm_wa; // @aclk, address strobe to program the AHCI FSM
...@@ -432,6 +435,7 @@ module ahci_top#( ...@@ -432,6 +435,7 @@ module ahci_top#(
.phy_ready (phy_ready), // input .phy_ready (phy_ready), // input
.syncesc_send (syncesc_send), // output .syncesc_send (syncesc_send), // output
.comreset_send (comreset_send), // output
.syncesc_send_done (syncesc_send_done), // input .syncesc_send_done (syncesc_send_done), // input
.cominit_got (cominit_got), // input .cominit_got (cominit_got), // input
.set_offline (set_offline), // output .set_offline (set_offline), // output
...@@ -517,6 +521,7 @@ module ahci_top#( ...@@ -517,6 +521,7 @@ module ahci_top#(
.dma_cmd_busy (dma_cmd_busy), // input .dma_cmd_busy (dma_cmd_busy), // input
.dma_cmd_done (dma_cmd_done), // input .dma_cmd_done (dma_cmd_done), // input
.dma_cmd_abort (dma_cmd_abort_fsm), // output
.fis_first_invalid (frcv_first_invalid),// input .fis_first_invalid (frcv_first_invalid),// input
.fis_first_flush (frcv_first_flush), // output .fis_first_flush (frcv_first_flush), // output
...@@ -752,7 +757,7 @@ module ahci_top#( ...@@ -752,7 +757,7 @@ module ahci_top#(
.dev_wr (dev_wr), // input .dev_wr (dev_wr), // input
.cmd_start (dma_cmd_start), // input .cmd_start (dma_cmd_start), // input
.prd_start (dma_prd_start), // input .prd_start (dma_prd_start), // input
.cmd_abort (dma_cmd_abort), // input .cmd_abort (dma_cmd_abort_xmit || dma_cmd_abort_fsm), // input
.axi_wr_cache_mode (axi_wr_cache_mode), // input[3:0] .axi_wr_cache_mode (axi_wr_cache_mode), // input[3:0]
.axi_rd_cache_mode (axi_rd_cache_mode), // input[3:0] .axi_rd_cache_mode (axi_rd_cache_mode), // input[3:0]
.set_axi_wr_cache_mode (set_axi_cache_mode), // input .set_axi_wr_cache_mode (set_axi_cache_mode), // input
...@@ -936,7 +941,7 @@ module ahci_top#( ...@@ -936,7 +941,7 @@ module ahci_top#(
.dma_dev_wr (dev_wr), // output .dma_dev_wr (dev_wr), // output
.dma_ct_busy (dma_ct_busy), // input .dma_ct_busy (dma_ct_busy), // input
.dma_prd_start (dma_prd_start), // output reg .dma_prd_start (dma_prd_start), // output reg
.dma_cmd_abort (dma_cmd_abort), // output reg .dma_cmd_abort (dma_cmd_abort_xmit), // output reg
.ct_addr (dma_ct_addr), // output[4:0] reg .ct_addr (dma_ct_addr), // output[4:0] reg
.ct_re (dma_ct_re), // output[1:0] .ct_re (dma_ct_re), // output[1:0]
.ct_data (dma_ct_data), // input[31:0] .ct_data (dma_ct_data), // input[31:0]
......
...@@ -26,6 +26,7 @@ module action_decoder ( ...@@ -26,6 +26,7 @@ module action_decoder (
output reg PXCI0_CLEAR, output reg PXCI0_CLEAR,
output reg PXSSTS_DET_1, output reg PXSSTS_DET_1,
output reg SSTS_DET_OFFLINE, output reg SSTS_DET_OFFLINE,
output reg SCTL_DET_CLEAR,
output reg SET_UPDATE_SIG, output reg SET_UPDATE_SIG,
output reg UPDATE_SIG, output reg UPDATE_SIG,
output reg UPDATE_ERR_STS, output reg UPDATE_ERR_STS,
...@@ -75,37 +76,38 @@ module action_decoder ( ...@@ -75,37 +76,38 @@ module action_decoder (
PXCI0_CLEAR <= enable && data[ 4] && data[ 1]; PXCI0_CLEAR <= enable && data[ 4] && data[ 1];
PXSSTS_DET_1 <= enable && data[ 5] && data[ 1]; PXSSTS_DET_1 <= enable && data[ 5] && data[ 1];
SSTS_DET_OFFLINE <= enable && data[ 6] && data[ 1]; SSTS_DET_OFFLINE <= enable && data[ 6] && data[ 1];
SET_UPDATE_SIG <= enable && data[ 7] && data[ 1]; SCTL_DET_CLEAR <= enable && data[ 7] && data[ 1];
UPDATE_SIG <= enable && data[ 8] && data[ 1]; SET_UPDATE_SIG <= enable && data[ 8] && data[ 1];
UPDATE_ERR_STS <= enable && data[ 9] && data[ 1]; UPDATE_SIG <= enable && data[ 9] && data[ 1];
UPDATE_PIO <= enable && data[10] && data[ 1]; UPDATE_ERR_STS <= enable && data[10] && data[ 1];
UPDATE_PRDBC <= enable && data[ 3] && data[ 2]; UPDATE_PIO <= enable && data[ 3] && data[ 2];
CLEAR_BSY_DRQ <= enable && data[ 4] && data[ 2]; UPDATE_PRDBC <= enable && data[ 4] && data[ 2];
CLEAR_BSY_SET_DRQ <= enable && data[ 5] && data[ 2]; CLEAR_BSY_DRQ <= enable && data[ 5] && data[ 2];
SET_BSY <= enable && data[ 6] && data[ 2]; CLEAR_BSY_SET_DRQ <= enable && data[ 6] && data[ 2];
SET_STS_7F <= enable && data[ 7] && data[ 2]; SET_BSY <= enable && data[ 7] && data[ 2];
SET_STS_80 <= enable && data[ 8] && data[ 2]; SET_STS_7F <= enable && data[ 8] && data[ 2];
XFER_CNTR_CLEAR <= enable && data[ 9] && data[ 2]; SET_STS_80 <= enable && data[ 9] && data[ 2];
DECR_DWC <= enable && data[10] && data[ 2]; XFER_CNTR_CLEAR <= enable && data[10] && data[ 2];
FIS_FIRST_FLUSH <= enable && data[ 4] && data[ 3]; DECR_DWC <= enable && data[ 4] && data[ 3];
CLEAR_CMD_TO_ISSUE <= enable && data[ 5] && data[ 3]; FIS_FIRST_FLUSH <= enable && data[ 5] && data[ 3];
DMA_ABORT <= enable && data[ 6] && data[ 3]; CLEAR_CMD_TO_ISSUE <= enable && data[ 6] && data[ 3];
DMA_PRD_IRQ_CLEAR <= enable && data[ 7] && data[ 3]; DMA_ABORT <= enable && data[ 7] && data[ 3];
XMIT_COMRESET <= enable && data[ 8] && data[ 3]; DMA_PRD_IRQ_CLEAR <= enable && data[ 8] && data[ 3];
SEND_SYNC_ESC <= enable && data[ 9] && data[ 3]; XMIT_COMRESET <= enable && data[ 9] && data[ 3];
SET_OFFLINE <= enable && data[10] && data[ 3]; SEND_SYNC_ESC <= enable && data[10] && data[ 3];
R_OK <= enable && data[ 5] && data[ 4]; SET_OFFLINE <= enable && data[ 5] && data[ 4];
R_ERR <= enable && data[ 6] && data[ 4]; R_OK <= enable && data[ 6] && data[ 4];
FETCH_CMD <= enable && data[ 7] && data[ 4]; R_ERR <= enable && data[ 7] && data[ 4];
ATAPI_XMIT <= enable && data[ 8] && data[ 4]; FETCH_CMD <= enable && data[ 8] && data[ 4];
CFIS_XMIT <= enable && data[ 9] && data[ 4]; ATAPI_XMIT <= enable && data[ 9] && data[ 4];
DX_XMIT <= enable && data[10] && data[ 4]; CFIS_XMIT <= enable && data[10] && data[ 4];
GET_DATA_FIS <= enable && data[ 6] && data[ 5]; DX_XMIT <= enable && data[ 6] && data[ 5];
GET_DSFIS <= enable && data[ 7] && data[ 5]; GET_DATA_FIS <= enable && data[ 7] && data[ 5];
GET_IGNORE <= enable && data[ 8] && data[ 5]; GET_DSFIS <= enable && data[ 8] && data[ 5];
GET_PSFIS <= enable && data[ 9] && data[ 5]; GET_IGNORE <= enable && data[ 9] && data[ 5];
GET_RFIS <= enable && data[10] && data[ 5]; GET_PSFIS <= enable && data[10] && data[ 5];
GET_SDBFIS <= enable && data[ 7] && data[ 6]; GET_RFIS <= enable && data[ 7] && data[ 6];
GET_UFIS <= enable && data[ 8] && data[ 6]; GET_SDBFIS <= enable && data[ 8] && data[ 6];
GET_UFIS <= enable && data[ 9] && data[ 6];
end end
endmodule endmodule
...@@ -46,7 +46,7 @@ code_rom_path= '../includes/ahxi_fsm_code.vh' ...@@ -46,7 +46,7 @@ code_rom_path= '../includes/ahxi_fsm_code.vh'
actions = ['NOP', actions = ['NOP',
# CTRL_STAT # CTRL_STAT
'PXSERR_DIAG_X', 'SIRQ_DHR', 'SIRQ_DP', 'SIRQ_DS', 'SIRQ_IF', 'SIRQ_PS', 'SIRQ_SDB', 'SIRQ_TFE', 'SIRQ_UF', 'PXSERR_DIAG_X', 'SIRQ_DHR', 'SIRQ_DP', 'SIRQ_DS', 'SIRQ_IF', 'SIRQ_PS', 'SIRQ_SDB', 'SIRQ_TFE', 'SIRQ_UF',
'PFSM_STARTED', 'PCMD_CR_CLEAR', 'PCMD_CR_SET', 'PXCI0_CLEAR', 'PXSSTS_DET_1', 'SSTS_DET_OFFLINE', 'PFSM_STARTED', 'PCMD_CR_CLEAR', 'PCMD_CR_SET', 'PXCI0_CLEAR', 'PXSSTS_DET_1', 'SSTS_DET_OFFLINE', 'SCTL_DET_CLEAR',
# FIS RECEIVE # FIS RECEIVE
'SET_UPDATE_SIG', 'UPDATE_SIG', 'UPDATE_ERR_STS', 'UPDATE_PIO', 'UPDATE_PRDBC', 'CLEAR_BSY_DRQ', 'SET_UPDATE_SIG', 'UPDATE_SIG', 'UPDATE_ERR_STS', 'UPDATE_PIO', 'UPDATE_PRDBC', 'CLEAR_BSY_DRQ',
'CLEAR_BSY_SET_DRQ', 'SET_BSY', 'SET_STS_7F', 'SET_STS_80', 'XFER_CNTR_CLEAR', 'DECR_DWC', 'FIS_FIRST_FLUSH', 'CLEAR_BSY_SET_DRQ', 'SET_BSY', 'SET_STS_7F', 'SET_STS_80', 'XFER_CNTR_CLEAR', 'DECR_DWC', 'FIS_FIRST_FLUSH',
...@@ -109,7 +109,7 @@ sequence = [{LBL:'POR', ADDR: 0x0, ACT: NOP}, ...@@ -109,7 +109,7 @@ sequence = [{LBL:'POR', ADDR: 0x0, ACT: NOP},
{ ACT: 'CLEAR_BSY_SET_DRQ'}, # clear_bsy_set_drq { ACT: 'CLEAR_BSY_SET_DRQ'}, # clear_bsy_set_drq
{ ACT: 'SET_STS_7F'}, # set_sts_7f { ACT: 'SET_STS_7F'}, # set_sts_7f
{ ACT: 'SET_UPDATE_SIG'}, # set_update_sig { ACT: 'SET_UPDATE_SIG'}, # set_update_sig
{ ACT: 'XMIT_COMRESET'}, # Now does it on reset. See if it is possible to transmit COMRESET w/o reset { ACT: 'XMIT_COMRESET'}, # comreset_send (not yet implemented) Now does it on reset. See if it is possible to transmit COMRESET w/o reset
{ GOTO:'P:NotRunning'}, { GOTO:'P:NotRunning'},
{LBL:'P:NotRunningGarbage', ACT: 'FIS_FIRST_FLUSH'}, # fis_first_flush (FIFO output has data, but not FIS head {LBL:'P:NotRunningGarbage', ACT: 'FIS_FIRST_FLUSH'}, # fis_first_flush (FIFO output has data, but not FIS head
...@@ -123,12 +123,12 @@ sequence = [{LBL:'POR', ADDR: 0x0, ACT: NOP}, ...@@ -123,12 +123,12 @@ sequence = [{LBL:'POR', ADDR: 0x0, ACT: NOP},
# Transition 8. PxCMD.FRE written to ‘1’ from a ‘0’ and previously processed Register FIS is in receive FIFO and PxSERR.DIAG.X = ‘0’ # Transition 8. PxCMD.FRE written to ‘1’ from a ‘0’ and previously processed Register FIS is in receive FIFO and PxSERR.DIAG.X = ‘0’
# can not be implemented - it is too late, FIS is already gone. So as we do not move FIS receive area, there is no sense to disable FIS, # can not be implemented - it is too late, FIS is already gone. So as we do not move FIS receive area, there is no sense to disable FIS,
# and for the signature we'll always assume FRE is on # and for the signature we'll always assume FRE is on
{IF:'ST_NB_ND', GOTO:'P:Idle'}, #12 : PxCMD.ST & !PxTBD.STS.BSY & !PxTBD.STS.DRQ {IF:'ST_NB_ND', GOTO:'P:Idle'}, #12 : PxCMD.ST & !PxTFD.STS.BSY & !PxTFD.STS.DRQ
{IF:'FR_D2HR', GOTO:'NDR:Entry'}, #13 fis_first_vld & fis_type == 0x34 (D2H Register) {IF:'FR_D2HR', GOTO:'NDR:Entry'}, #13 fis_first_vld & fis_type == 0x34 (D2H Register)
{ GOTO:'P:NotRunning'}, #14 { GOTO:'P:NotRunning'}, #14
{LBL:'P:Cominit', ACT: 'NOP'}, # got here asynchronously from COMINIT label {LBL:'P:Cominit', ACT: 'NOP'}, # got here asynchronously from COMINIT label
{ ACT: 'SET_STS_80'}, # frcv_set_sts_80 (Not clear 0xff or 0x80 should be here?) { ACT: 'SET_STS_80'}, # set_sts_80 (Not clear 0xff or 0x80 should be here?)
{ ACT: 'PXSSTS_DET_1'}, # ssts_det_dnp, // device detected, but phy communication not established { ACT: 'PXSSTS_DET_1'}, # ssts_det_dnp, // device detected, but phy communication not established
{ ACT: 'PXSERR_DIAG_X'}, # sirq_PC, // RO: Port Connect Change Status (pulse to set) { ACT: 'PXSERR_DIAG_X'}, # sirq_PC, // RO: Port Connect Change Status (pulse to set)
# {IF:'PXIE_PCE', GOTO:'P:CominitSetIS'}, # Not needed, interrupt # {IF:'PXIE_PCE', GOTO:'P:CominitSetIS'}, # Not needed, interrupt
...@@ -144,12 +144,13 @@ sequence = [{LBL:'POR', ADDR: 0x0, ACT: NOP}, ...@@ -144,12 +144,13 @@ sequence = [{LBL:'POR', ADDR: 0x0, ACT: NOP},
{ ACT: 'UPDATE_ERR_STS'}, # update_err_sts { ACT: 'UPDATE_ERR_STS'}, # update_err_sts
{ GOTO:'P:NotRunning'}, { GOTO:'P:NotRunning'},
# {IF: 'PCMD_FRE', GOTO:'P:RegFisPostToMem'}, # pcmd_fre hardware always copies signature FIS to 'memory' if expected # {IF: 'PCMD_FRE', GOTO:'P:RegFisPostToMem'}, # pxcmd_fre hardware always copies signature FIS to 'memory' if expected
# {LBL:'P:RegFisPostToMem', ACT: 'NOP'}, # Probably not needed, handled at lower level # {LBL:'P:RegFisPostToMem', ACT: 'NOP'}, # Probably not needed, handled at lower level
# { GOTO:'P:NotRunning'}, # { GOTO:'P:NotRunning'},
{LBL:'P:Offline', ACT: 'SET_OFFLINE'}, # set_offline {LBL:'P:Offline', ACT: 'SET_OFFLINE'}, # set_offline
{ ACT: 'SCTL_DET_CLEAR'}, # sctl_det_reset
{ GOTO:'P:NotRunning'}, { GOTO:'P:NotRunning'},
{LBL:'P:StartBitCleared', ACT: 'PXCI0_CLEAR'}, # pxci0_clear {LBL:'P:StartBitCleared', ACT: 'PXCI0_CLEAR'}, # pxci0_clear
...@@ -180,6 +181,7 @@ sequence = [{LBL:'POR', ADDR: 0x0, ACT: NOP}, ...@@ -180,6 +181,7 @@ sequence = [{LBL:'POR', ADDR: 0x0, ACT: NOP},
{LBL:'P:StartComm', ACT: 'SET_STS_7F'}, # frcv_set_sts_7f {LBL:'P:StartComm', ACT: 'SET_STS_7F'}, # frcv_set_sts_7f
{ ACT: 'SET_UPDATE_SIG'}, # #frcv_set_update_sig { ACT: 'SET_UPDATE_SIG'}, # #frcv_set_update_sig
{ ACT: 'XMIT_COMRESET'}, # Now does it on reset. See if it is possible to transmit COMRESET w/o reset { ACT: 'XMIT_COMRESET'}, # Now does it on reset. See if it is possible to transmit COMRESET w/o reset
{ ACT: 'SCTL_DET_CLEAR'}, # sctl_det_reset
{IF: 'PXSSTS_DET_EQ_1', GOTO:'P:StartComm'}, {IF: 'PXSSTS_DET_EQ_1', GOTO:'P:StartComm'},
{ GOTO:'P:NotRunning'}, { GOTO:'P:NotRunning'},
#New states, because FIS needs to be read in befor R_OK #New states, because FIS needs to be read in befor R_OK
...@@ -213,15 +215,15 @@ sequence = [{LBL:'POR', ADDR: 0x0, ACT: NOP}, ...@@ -213,15 +215,15 @@ sequence = [{LBL:'POR', ADDR: 0x0, ACT: NOP},
{LBL:'NDR:Accept', ACT: 'NOP'}, # ******** # send R_OK after reading in FIS: ACT: 'R_OK'}, # send_R_OK to device {LBL:'NDR:Accept', ACT: 'NOP'}, # ******** # send R_OK after reading in FIS: ACT: 'R_OK'}, # send_R_OK to device
{IF:'NB_ND_D2HR_PIO', GOTO:'NDR:IgnoreIdle'}, # 2 :((FIS == FIS_D2HR) || (FIS == FIS_PIO)) && !PxTBD.STS.BSY & !PxTBD.STS.DRQ {IF:'NB_ND_D2HR_PIO', GOTO:'NDR:IgnoreIdle'}, # 2 :((FIS == FIS_D2HR) || (FIS == FIS_PIO)) && !PxTFD.STS.BSY & !PxTFD.STS.DRQ
{IF:'NST_D2HR', GOTO:'P:RegFisUpdate'}, # 3 :!ST && (FIS == FIS_D2HR) TODO: does it mean either BSY or DRQ are 1? {IF:'NST_D2HR', GOTO:'P:RegFisUpdate'}, # 3 :!ST && (FIS == FIS_D2HR) TODO: does it mean either BSY or DRQ are 1?
{IF:'NPCMD_FRE', GOTO:'NDR:IgnoreNR' }, # 4 !pcmd_fre (docs: goto P:NotRunning, but we need to clear FIFO) {IF:'NPCMD_FRE', GOTO:'NDR:IgnoreNR' }, # 4 !pxcmd_fre (docs: goto P:NotRunning, but we need to clear FIFO)
{IF:'D2HR', GOTO:'RegFIS:Entry' }, # 5 FIS == FIS_D2HR {IF:'D2HR', GOTO:'RegFIS:Entry' }, # 5 FIS == FIS_D2HR
{IF:'SDB', GOTO:'SDB:Entry' }, # 7 (# 6 skipped) {IF:'SDB', GOTO:'SDB:Entry' }, # 7 (# 6 skipped)
{IF:'DMA_ACT', GOTO:'DX:EntryIgnore' }, # 8 FIS == FIS_DMA_ACT {IF:'DMA_ACT', GOTO:'DX:EntryIgnore' }, # 8 FIS == FIS_DMA_ACT
{IF:'DMA_SETUP', GOTO:'DmaSet:Entry' }, # 9 FIS == FIS_DMA_SETUP {IF:'DMA_SETUP', GOTO:'DmaSet:Entry' }, # 9 FIS == FIS_DMA_SETUP
{IF:'BIST_ACT_FE', GOTO:'BIST:FarEndLoopback'}, #10 FIS == FIS_BIST_ACT && |bist_bits TODO:get_ignore to read in FIS {IF:'BIST_ACT_FE', GOTO:'BIST:FarEndLoopback'}, # 10 FIS == FIS_BIST_ACT && |bist_bits
{IF:'BIST_ACT', GOTO:'BIST:TestOngoing'}, # 11 FIS == FIS_BIST_ACT && |bist_bits TODO:get_ignore to read in FIS {IF:'BIST_ACT', GOTO:'BIST:TestOngoing'}, # 11 FIS == FIS_BIST_ACT # && !(|bist_bits)
{IF:'PIO_SETUP', GOTO:'PIO:Entry' }, # 12 FIS == FIS_PIO_SETUP {IF:'PIO_SETUP', GOTO:'PIO:Entry' }, # 12 FIS == FIS_PIO_SETUP
{ GOTO:'UFIS:Entry' }, # 13 Unknown FIS (else) { GOTO:'UFIS:Entry' }, # 13 Unknown FIS (else)
#5.3.6. Command Transfer State #5.3.6. Command Transfer State
......
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