Loading ahci/ahci_fis_receive.v +31 −30 Original line number Diff line number Diff line Loading @@ -37,9 +37,6 @@ module ahci_fis_receive#( // Control Interface output reg fis_first_vld, // fis_first contains valid FIS header, reset by get_* // Receiving FIS input set_update_sig, // when set, enables get_sig (and resets itself) output pUpdateSig, // state variable input get_sig, // update signature input get_dsfis, input get_psfis, input get_rfis, Loading @@ -52,7 +49,11 @@ module ahci_fis_receive#( output reg fis_ok, // FIS done, checksum OK reset by starting a new get FIS output reg fis_err, // FIS done, checksum ERROR reset by starting a new get FIS output fis_ferr, // FIS done, fatal error - FIS too long input set_update_sig,// when set, enables update_sig (and resets itself) output pUpdateSig, // state variable output reg sig_available, // device signature a ailable // next commands use register address/data/we for 1 clock cycle - after next to command (commnd - t0, we - t2) input update_sig, // update signature - now after get_rfis, after FIS is already received input update_err_sts,// update PxTFD.STS and PxTFD.ERR from the last received regs d2h input update_pio, // update PxTFD.STS and PxTFD.ERR from pio_* (entry PIO:Update) input update_prdbc, // update PRDBC in registers Loading Loading @@ -168,7 +169,7 @@ localparam DATA_TYPE_ERR = 3; wire reg_we_w; reg [3:0] update_sig; reg [3:0] store_sig; reg [5:0] reg_ds; reg [4:0] reg_ps; reg reg_d2h; Loading @@ -179,6 +180,7 @@ localparam DATA_TYPE_ERR = 3; reg [15:0] tf_err_sts; reg update_err_sts_r; reg update_sig_r; // reg update_pio_r; reg update_prdbc_r; reg get_fis_busy_r; Loading @@ -188,6 +190,7 @@ localparam DATA_TYPE_ERR = 3; reg [7:0] pio_err_r; reg pUpdateSig_r = 1; // state variable reg [31:0] sig_r; // signature register, save at // Forward data to DMA (dev->mem) engine assign dma_in_valid = dma_in_ready && (hba_data_in_type == DATA_TYPE_DMA) && data_in_ready && !too_long_err; Loading Loading @@ -226,27 +229,24 @@ localparam DATA_TYPE_ERR = 3; (wreg_we_r && dwords_over)) too_long_err <= 1; if (get_fis) begin reg_addr_r <= ({ADDRESS_BITS{get_sig}} & (PXSIG_OFFS32)) | ({ADDRESS_BITS{get_dsfis}} & (FB_OFFS32 + DSFIS32)) | reg_addr_r <= ({ADDRESS_BITS{get_dsfis}} & (FB_OFFS32 + DSFIS32)) | ({ADDRESS_BITS{get_psfis}} & (FB_OFFS32 + PSFIS32)) | ({ADDRESS_BITS{get_rfis}} & (FB_OFFS32 + RFIS32)) | ({ADDRESS_BITS{get_sdbfis}} & (FB_OFFS32 + SDBFIS32)) | ({ADDRESS_BITS{get_ufis}} & (FB_OFFS32 + UFIS32)); fis_dcount <= ({4{get_sig}} & RFIS32_LENM1) | ({4{get_dsfis}} & DSFIS32_LENM1) | fis_dcount <= ({4{get_dsfis}} & DSFIS32_LENM1) | ({4{get_psfis}} & PSFIS32_LENM1) | ({4{get_rfis}} & RFIS32_LENM1) | ({4{get_sdbfis}} & SDBFIS32_LENM1) | ({4{get_ufis}} & UFIS32_LENM1 ) | ({4{get_data_fis}} & DMAH_LENM1) | ({4{get_ignore}} & IGNORE_LENM1 ); // fis_save <= pcmd_fre && !get_data_fis && !get_ignore && !get_sig; // save signature FIS to memory if waiting (if not - ignore FIS) // for non-signature /non-data - obey pcmd_fre fis_save <= get_sig? pUpdateSig_r : (pcmd_fre && !get_data_fis && !get_ignore); fis_save <= (pUpdateSig_r || get_rfis) || (pcmd_fre && !get_data_fis && !get_ignore); is_data_fis <= get_data_fis; update_sig <= ((get_sig && pUpdateSig_r)? 1 : 0); store_sig <= (get_rfis)? 1 : 0; reg_ds <= get_dsfis ? 1 : 0; reg_ps <= get_psfis ? 1 : 0; reg_d2h <= get_rfis ? 1 : 0; Loading @@ -254,7 +254,7 @@ localparam DATA_TYPE_ERR = 3; end else if (wreg_we_r && !dwords_over) begin fis_dcount <= fis_dcount - 1; // update even if not writing to registers if (fis_save) reg_addr_r <= reg_addr_r + 1; // update only when writing to registers update_sig <= update_sig << 1; store_sig <= store_sig << 1; reg_ds <= reg_ds << 1; reg_ps <= reg_ps << 1; reg_d2h <= 0; Loading Loading @@ -289,19 +289,16 @@ localparam DATA_TYPE_ERR = 3; if (hba_rst || get_fis) fis_err <= 0; else if (fis_end_w) fis_err <= hba_data_in_type != DATA_TYPE_OK; if (reg_we_w) reg_data[31:8] <= hba_data_in[31:8]; else if (update_sig[1]) reg_data[31:8] <= hba_data_in[23:0]; else if (update_err_sts_r) reg_data[31:8] <= {16'b0,tf_err_sts[15:8]}; // else if (update_pio_r) reg_data[31:8] <= {16'b0,pio_err_r[7:0]}; else if (update_prdbc_r) reg_data[31:8] <= {xfer_cntr_r[31:8]}; if (reg_we_w) reg_data[ 7:0] <= hba_data_in[ 7:0]; else if (update_sig[3]) reg_data[ 7:0] <= hba_data_in[ 7:0]; else if (update_err_sts_r) reg_data[ 7:0] <= tf_err_sts [ 7:0]; // else if (update_pio_r) reg_data[ 7:0] <= pio_es_r [ 7:0]; else if (update_prdbc_r) reg_data[ 7:0] <= {xfer_cntr_r[ 7:2],2'b0}; if (reg_we_w) reg_data <= hba_data_in; else if (update_err_sts_r) reg_data <= {16'b0,tf_err_sts}; else if (update_sig_r) reg_data <= sig_r; else if (update_prdbc_r) reg_data <= {xfer_cntr_r[31:2],2'b0}; if (store_sig[1]) sig_r[31:8] <= hba_data_in[23:0]; if (store_sig[3]) sig_r[ 7:0] <= hba_data_in[ 7:0]; if (reg_d2h || update_sig[0]) tf_err_sts <= hba_data_in[15:0]; if (reg_d2h) tf_err_sts <= hba_data_in[15:0]; // Sets pPioErr[pPmpCur] to Error field of the FIS // Updates PxTFD.STS.ERR with pPioErr[pPmpCur] ?? else if (reg_ps[0]) tf_err_sts <= {hba_data_in[31:24],hba_data_in[23:16]}; Loading @@ -311,10 +308,11 @@ localparam DATA_TYPE_ERR = 3; tf_err_sts <= tf_err_sts & {8'hff,clear_bsy_drq,3'h7,clear_bsy_drq,3'h7} | {8'h0,set_bsy,3'h0,clear_bsy_set_drq,3'h0}; else if (set_sts_7f || set_sts_80) tf_err_sts <= {tf_err_sts[15:8],set_sts_80,{7{set_sts_7f}}} ; reg_we <= reg_we_w || update_sig[3] || update_err_sts_r || update_prdbc_r; reg_we <= reg_we_w || update_sig_r || update_err_sts_r || update_prdbc_r; if (reg_we_w || update_sig[3]) reg_addr <= reg_addr_r; if (reg_we_w) reg_addr <= reg_addr_r; else if (update_err_sts_r) reg_addr <= PXTFD_OFFS32; else if (update_sig_r) reg_addr <= PXSIG_OFFS32; else if (update_prdbc_r) reg_addr <= CLB_OFFS32 + 1; // location of PRDBC if (reg_d2h || reg_sdb || reg_ds[0]) fis_i <= hba_data_in[14]; Loading @@ -341,13 +339,16 @@ localparam DATA_TYPE_ERR = 3; update_err_sts_r <= update_pio || update_err_sts || clear_bsy_drq || set_bsy || set_sts_7f || set_sts_80; // update_pio_r <= update_pio; update_prdbc_r <= update_prdbc; // same latency as update_err_sts update_sig_r <= update_sig && pUpdateSig_r; // do not update if not requested if (hba_rst || update_pio) pPioXfer <= 0; else if (reg_ps[4]) pPioXfer <= 1; if (hba_rst || set_update_sig) pUpdateSig_r <= 1; else if (update_sig[3]) pUpdateSig_r <= 0; else if (update_sig) pUpdateSig_r <= 0; if (hba_rst || update_sig) sig_available <= 0; else if (store_sig[3]) sig_available <= 1; // Maybe it is not needed if the fsm will send this pulse? // data_in_words_apply <= dma_in_stop && (hba_data_in_type == DATA_TYPE_OK); Loading ahci/ahci_fis_transmit.v +5 −2 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ module ahci_fis_transmit #( input cfis_xmit, // transmit command (wait for dma_ct_busy == 0) input dx_transmit, // send FIS header DWORD, (just 0x46), then forward DMA data // transmit until error, 2048DWords or pDmaXferCnt input atapi_xmit, // tarsmit ATAPI command FIS input atapi_xmit, // trasmit ATAPI command FIS output reg done, Loading Loading @@ -233,9 +233,12 @@ module ahci_fis_transmit #( ch_r_r <= reg_rdata[ 8]; ch_p_r <= reg_rdata[ 7]; ch_w_r <= reg_rdata[ 6]; ch_a_r <= reg_rdata[ 5]; // ch_a_r <= reg_rdata[ 5]; ch_cmd_len_r<= reg_rdata[ 4: 0]; end //ch_a if (hba_rst || atapi_xmit) ch_a_r <= 0; else if (fetch_chead_stb_r[0]) ch_a_r <= reg_rdata[ 5]; if (hba_rst) pCmdToIssue_r <= 0; else if (chead_done_w) pCmdToIssue_r <= 1; Loading ahci/ahci_fsm.v +17 −5 Original line number Diff line number Diff line Loading @@ -44,8 +44,10 @@ module ahci_fsm // direct communication with transposrt, link and phy layers input phy_ready, // goes up after comreset,cominit, align, ... output syncesc_send, // Send sync escape input syncesc_send_done, // "SYNC escape until the interface is quiescent..." input cominit_got, // asynchronously jumps to P:Cominit state output set_offline, // electrically idle input x_rdy_collision, // X_RDY/X_RDY collision on interface output send_R_OK, // Should it be originated in this layer SM? output send_R_ERR, Loading Loading @@ -153,11 +155,9 @@ module ahci_fsm // Communication with ahci_fis_receive (some are unused input fis_first_vld, // fis_first contains valid FIS header, reset by 'get_*' input [7:0] fis_type, // FIS type (low byte in the first FIS DWORD), valid with 'fis_first_vld' // Receiving FIS output set_update_sig, // when set, enables get_sig (and resets itself) input pUpdateSig, // state variable input [7:0] bist_bits, // bits that define built-in self test output get_sig, // update signature // Receiving FIS output get_dsfis, output get_psfis, output get_rfis, Loading @@ -170,6 +170,13 @@ module ahci_fsm 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_ferr, // FIS done, fatal error - FIS too long output set_update_sig, // when set, enables get_sig (and resets itself) input pUpdateSig, // state variable input sig_available, // device signature available output update_sig, // update signature // next commands use register address/data/we for 1 clock cycle - after next to command (commnd - t0, we - t2) output update_err_sts,// update PxTFD.STS and PxTFD.ERR from the last received regs d2h output update_pio, // update PxTFD.STS and PxTFD.ERR from pio_* (entry PIO:Update) Loading Loading @@ -260,7 +267,7 @@ module ahci_fsm reg async_from_st; // chnge to multi-bit if there will be more sources for async transitions wire asynq_rq = cominit_got || pcmd_st_cleared; wire async_ackn = !fsm_preload && async_pend_r[0] && ((fsm_actions && !update_busy && !fsm_act_busy) || fsm_transitions[0]); // OK to process async jump reg x_rdy_collision_pend; assign fsm_next = (fsm_preload || (fsm_actions && !update_busy && !fsm_act_busy) || fsm_transitions[0]) && !async_pend_r[0]; // quiet if received cominit is pending Loading Loading @@ -316,6 +323,11 @@ module ahci_fsm if (hba_rst) async_pend_r <= 0; else async_pend_r <= {async_pend_r[0], asynq_rq | (async_pend_r[0] & ~async_ackn)}; if (hba_rst || pcmd_cr_set) x_rdy_collision_pend <= 0; else if (x_rdy_collision) x_rdy_collision_pend <= 1; end /* Loading ahci/ahci_top.v +24 −10 Original line number Diff line number Diff line Loading @@ -146,8 +146,10 @@ module ahci_top#( input syncesc_recv, // These two inputs interrupt transmit input xmit_err, // Error during sending of a FIS output syncesc_send, // Send sync escape input syncesc_send_done, // "SYNC escape until the interface is quiescent..." input cominit_got, output set_offline, // electrically idle input x_rdy_collision, // X_RDY/X_RDY collision on interface output send_R_OK, // Should it be originated in this layer SM? output send_R_ERR, Loading Loading @@ -222,10 +224,6 @@ module ahci_top#( // fsm <-> ahc_fis_receive // fsm -> wire frcv_first_vld; wire frcv_set_update_sig; // when set, enables get_sig (and resets itself) wire frcv_pUpdateSig; // state variable wire frcv_get_sig; // update signature wire frcv_get_dsfis; wire frcv_get_psfis; wire frcv_get_rfis; Loading Loading @@ -255,6 +253,12 @@ module ahci_top#( wire frcv_err; // FIS done, checksum ERROR reset by starting a new get FIS wire frcv_ferr; // FIS done, fatal error - FIS too long wire frcv_set_update_sig; // when set, enables get_sig (and resets itself) wire frcv_pUpdateSig; // state variable wire frcv_sig_available; // signature data available wire frcv_update_sig; // update signature // fsm <- state variables that are maintained inside 'ahc_fis_receive' wire [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 Loading Loading @@ -419,11 +423,14 @@ module ahci_top#( .phy_ready (phy_ready), // input .syncesc_send (syncesc_send), // output .syncesc_send_done (syncesc_send_done), // input .cominit_got (cominit_got), // input .set_offline (set_offline), // output .x_rdy_collision (x_rdy_collision), // input .send_R_OK (send_R_OK), // output .send_R_ERR (send_R_ERR), // output .update_pending (update_regs_pending),// input .update_all (update_all_regs), // output .update_busy (update_regs_busy), // input Loading Loading @@ -502,9 +509,8 @@ module ahci_top#( .fis_first_vld (frcv_first_vld), // input .fis_type (d2h_data[7:0]), // input[7:0] FIS type (low byte in the first FIS DWORD), valid with 'fis_first_vld' .set_update_sig (frcv_set_update_sig),// output .pUpdateSig (frcv_pUpdateSig), // input .get_sig (frcv_get_sig), // output .bist_bits (d2h_data[23:16]), // bits that define built-in self test .get_dsfis (frcv_get_dsfis), // output .get_psfis (frcv_get_psfis), // output .get_rfis (frcv_get_rfis), // output Loading @@ -517,6 +523,12 @@ module ahci_top#( .fis_ok (frcv_ok), // input .fis_err (frcv_err), // input .fis_ferr (frcv_ferr), // input .set_update_sig (frcv_set_update_sig),// output .pUpdateSig (frcv_pUpdateSig), // input .sig_available (frcv_sig_available), // input .update_sig (frcv_update_sig), // output .update_err_sts (frcv_update_err_sts),// output .update_pio (frcv_update_pio), // output .update_prdbc (frcv_update_prdbc), // output Loading Loading @@ -797,10 +809,7 @@ module ahci_top#( .mclk (mclk), // input .fis_first_vld (frcv_first_vld), // output reg .set_update_sig (frcv_set_update_sig), // input .pUpdateSig (frcv_pUpdateSig), // output .get_sig (frcv_get_sig), // input .get_dsfis (frcv_get_dsfis), // input .get_psfis (frcv_get_psfis), // input .get_rfis (frcv_get_rfis), // input Loading @@ -815,6 +824,11 @@ module ahci_top#( .fis_err (frcv_err), // output reg .fis_ferr (frcv_ferr), // output .set_update_sig (frcv_set_update_sig), // input .pUpdateSig (frcv_pUpdateSig), // output .sig_available (frcv_sig_available), // output reg .update_sig (frcv_update_sig), // input .update_err_sts (frcv_update_err_sts), // input .update_pio (frcv_update_pio), // input update PxTFD.STS and PxTFD.ERR from pio_* (entry PIO:Update) Loading Loading
ahci/ahci_fis_receive.v +31 −30 Original line number Diff line number Diff line Loading @@ -37,9 +37,6 @@ module ahci_fis_receive#( // Control Interface output reg fis_first_vld, // fis_first contains valid FIS header, reset by get_* // Receiving FIS input set_update_sig, // when set, enables get_sig (and resets itself) output pUpdateSig, // state variable input get_sig, // update signature input get_dsfis, input get_psfis, input get_rfis, Loading @@ -52,7 +49,11 @@ module ahci_fis_receive#( output reg fis_ok, // FIS done, checksum OK reset by starting a new get FIS output reg fis_err, // FIS done, checksum ERROR reset by starting a new get FIS output fis_ferr, // FIS done, fatal error - FIS too long input set_update_sig,// when set, enables update_sig (and resets itself) output pUpdateSig, // state variable output reg sig_available, // device signature a ailable // next commands use register address/data/we for 1 clock cycle - after next to command (commnd - t0, we - t2) input update_sig, // update signature - now after get_rfis, after FIS is already received input update_err_sts,// update PxTFD.STS and PxTFD.ERR from the last received regs d2h input update_pio, // update PxTFD.STS and PxTFD.ERR from pio_* (entry PIO:Update) input update_prdbc, // update PRDBC in registers Loading Loading @@ -168,7 +169,7 @@ localparam DATA_TYPE_ERR = 3; wire reg_we_w; reg [3:0] update_sig; reg [3:0] store_sig; reg [5:0] reg_ds; reg [4:0] reg_ps; reg reg_d2h; Loading @@ -179,6 +180,7 @@ localparam DATA_TYPE_ERR = 3; reg [15:0] tf_err_sts; reg update_err_sts_r; reg update_sig_r; // reg update_pio_r; reg update_prdbc_r; reg get_fis_busy_r; Loading @@ -188,6 +190,7 @@ localparam DATA_TYPE_ERR = 3; reg [7:0] pio_err_r; reg pUpdateSig_r = 1; // state variable reg [31:0] sig_r; // signature register, save at // Forward data to DMA (dev->mem) engine assign dma_in_valid = dma_in_ready && (hba_data_in_type == DATA_TYPE_DMA) && data_in_ready && !too_long_err; Loading Loading @@ -226,27 +229,24 @@ localparam DATA_TYPE_ERR = 3; (wreg_we_r && dwords_over)) too_long_err <= 1; if (get_fis) begin reg_addr_r <= ({ADDRESS_BITS{get_sig}} & (PXSIG_OFFS32)) | ({ADDRESS_BITS{get_dsfis}} & (FB_OFFS32 + DSFIS32)) | reg_addr_r <= ({ADDRESS_BITS{get_dsfis}} & (FB_OFFS32 + DSFIS32)) | ({ADDRESS_BITS{get_psfis}} & (FB_OFFS32 + PSFIS32)) | ({ADDRESS_BITS{get_rfis}} & (FB_OFFS32 + RFIS32)) | ({ADDRESS_BITS{get_sdbfis}} & (FB_OFFS32 + SDBFIS32)) | ({ADDRESS_BITS{get_ufis}} & (FB_OFFS32 + UFIS32)); fis_dcount <= ({4{get_sig}} & RFIS32_LENM1) | ({4{get_dsfis}} & DSFIS32_LENM1) | fis_dcount <= ({4{get_dsfis}} & DSFIS32_LENM1) | ({4{get_psfis}} & PSFIS32_LENM1) | ({4{get_rfis}} & RFIS32_LENM1) | ({4{get_sdbfis}} & SDBFIS32_LENM1) | ({4{get_ufis}} & UFIS32_LENM1 ) | ({4{get_data_fis}} & DMAH_LENM1) | ({4{get_ignore}} & IGNORE_LENM1 ); // fis_save <= pcmd_fre && !get_data_fis && !get_ignore && !get_sig; // save signature FIS to memory if waiting (if not - ignore FIS) // for non-signature /non-data - obey pcmd_fre fis_save <= get_sig? pUpdateSig_r : (pcmd_fre && !get_data_fis && !get_ignore); fis_save <= (pUpdateSig_r || get_rfis) || (pcmd_fre && !get_data_fis && !get_ignore); is_data_fis <= get_data_fis; update_sig <= ((get_sig && pUpdateSig_r)? 1 : 0); store_sig <= (get_rfis)? 1 : 0; reg_ds <= get_dsfis ? 1 : 0; reg_ps <= get_psfis ? 1 : 0; reg_d2h <= get_rfis ? 1 : 0; Loading @@ -254,7 +254,7 @@ localparam DATA_TYPE_ERR = 3; end else if (wreg_we_r && !dwords_over) begin fis_dcount <= fis_dcount - 1; // update even if not writing to registers if (fis_save) reg_addr_r <= reg_addr_r + 1; // update only when writing to registers update_sig <= update_sig << 1; store_sig <= store_sig << 1; reg_ds <= reg_ds << 1; reg_ps <= reg_ps << 1; reg_d2h <= 0; Loading Loading @@ -289,19 +289,16 @@ localparam DATA_TYPE_ERR = 3; if (hba_rst || get_fis) fis_err <= 0; else if (fis_end_w) fis_err <= hba_data_in_type != DATA_TYPE_OK; if (reg_we_w) reg_data[31:8] <= hba_data_in[31:8]; else if (update_sig[1]) reg_data[31:8] <= hba_data_in[23:0]; else if (update_err_sts_r) reg_data[31:8] <= {16'b0,tf_err_sts[15:8]}; // else if (update_pio_r) reg_data[31:8] <= {16'b0,pio_err_r[7:0]}; else if (update_prdbc_r) reg_data[31:8] <= {xfer_cntr_r[31:8]}; if (reg_we_w) reg_data[ 7:0] <= hba_data_in[ 7:0]; else if (update_sig[3]) reg_data[ 7:0] <= hba_data_in[ 7:0]; else if (update_err_sts_r) reg_data[ 7:0] <= tf_err_sts [ 7:0]; // else if (update_pio_r) reg_data[ 7:0] <= pio_es_r [ 7:0]; else if (update_prdbc_r) reg_data[ 7:0] <= {xfer_cntr_r[ 7:2],2'b0}; if (reg_we_w) reg_data <= hba_data_in; else if (update_err_sts_r) reg_data <= {16'b0,tf_err_sts}; else if (update_sig_r) reg_data <= sig_r; else if (update_prdbc_r) reg_data <= {xfer_cntr_r[31:2],2'b0}; if (store_sig[1]) sig_r[31:8] <= hba_data_in[23:0]; if (store_sig[3]) sig_r[ 7:0] <= hba_data_in[ 7:0]; if (reg_d2h || update_sig[0]) tf_err_sts <= hba_data_in[15:0]; if (reg_d2h) tf_err_sts <= hba_data_in[15:0]; // Sets pPioErr[pPmpCur] to Error field of the FIS // Updates PxTFD.STS.ERR with pPioErr[pPmpCur] ?? else if (reg_ps[0]) tf_err_sts <= {hba_data_in[31:24],hba_data_in[23:16]}; Loading @@ -311,10 +308,11 @@ localparam DATA_TYPE_ERR = 3; tf_err_sts <= tf_err_sts & {8'hff,clear_bsy_drq,3'h7,clear_bsy_drq,3'h7} | {8'h0,set_bsy,3'h0,clear_bsy_set_drq,3'h0}; else if (set_sts_7f || set_sts_80) tf_err_sts <= {tf_err_sts[15:8],set_sts_80,{7{set_sts_7f}}} ; reg_we <= reg_we_w || update_sig[3] || update_err_sts_r || update_prdbc_r; reg_we <= reg_we_w || update_sig_r || update_err_sts_r || update_prdbc_r; if (reg_we_w || update_sig[3]) reg_addr <= reg_addr_r; if (reg_we_w) reg_addr <= reg_addr_r; else if (update_err_sts_r) reg_addr <= PXTFD_OFFS32; else if (update_sig_r) reg_addr <= PXSIG_OFFS32; else if (update_prdbc_r) reg_addr <= CLB_OFFS32 + 1; // location of PRDBC if (reg_d2h || reg_sdb || reg_ds[0]) fis_i <= hba_data_in[14]; Loading @@ -341,13 +339,16 @@ localparam DATA_TYPE_ERR = 3; update_err_sts_r <= update_pio || update_err_sts || clear_bsy_drq || set_bsy || set_sts_7f || set_sts_80; // update_pio_r <= update_pio; update_prdbc_r <= update_prdbc; // same latency as update_err_sts update_sig_r <= update_sig && pUpdateSig_r; // do not update if not requested if (hba_rst || update_pio) pPioXfer <= 0; else if (reg_ps[4]) pPioXfer <= 1; if (hba_rst || set_update_sig) pUpdateSig_r <= 1; else if (update_sig[3]) pUpdateSig_r <= 0; else if (update_sig) pUpdateSig_r <= 0; if (hba_rst || update_sig) sig_available <= 0; else if (store_sig[3]) sig_available <= 1; // Maybe it is not needed if the fsm will send this pulse? // data_in_words_apply <= dma_in_stop && (hba_data_in_type == DATA_TYPE_OK); Loading
ahci/ahci_fis_transmit.v +5 −2 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ module ahci_fis_transmit #( input cfis_xmit, // transmit command (wait for dma_ct_busy == 0) input dx_transmit, // send FIS header DWORD, (just 0x46), then forward DMA data // transmit until error, 2048DWords or pDmaXferCnt input atapi_xmit, // tarsmit ATAPI command FIS input atapi_xmit, // trasmit ATAPI command FIS output reg done, Loading Loading @@ -233,9 +233,12 @@ module ahci_fis_transmit #( ch_r_r <= reg_rdata[ 8]; ch_p_r <= reg_rdata[ 7]; ch_w_r <= reg_rdata[ 6]; ch_a_r <= reg_rdata[ 5]; // ch_a_r <= reg_rdata[ 5]; ch_cmd_len_r<= reg_rdata[ 4: 0]; end //ch_a if (hba_rst || atapi_xmit) ch_a_r <= 0; else if (fetch_chead_stb_r[0]) ch_a_r <= reg_rdata[ 5]; if (hba_rst) pCmdToIssue_r <= 0; else if (chead_done_w) pCmdToIssue_r <= 1; Loading
ahci/ahci_fsm.v +17 −5 Original line number Diff line number Diff line Loading @@ -44,8 +44,10 @@ module ahci_fsm // direct communication with transposrt, link and phy layers input phy_ready, // goes up after comreset,cominit, align, ... output syncesc_send, // Send sync escape input syncesc_send_done, // "SYNC escape until the interface is quiescent..." input cominit_got, // asynchronously jumps to P:Cominit state output set_offline, // electrically idle input x_rdy_collision, // X_RDY/X_RDY collision on interface output send_R_OK, // Should it be originated in this layer SM? output send_R_ERR, Loading Loading @@ -153,11 +155,9 @@ module ahci_fsm // Communication with ahci_fis_receive (some are unused input fis_first_vld, // fis_first contains valid FIS header, reset by 'get_*' input [7:0] fis_type, // FIS type (low byte in the first FIS DWORD), valid with 'fis_first_vld' // Receiving FIS output set_update_sig, // when set, enables get_sig (and resets itself) input pUpdateSig, // state variable input [7:0] bist_bits, // bits that define built-in self test output get_sig, // update signature // Receiving FIS output get_dsfis, output get_psfis, output get_rfis, Loading @@ -170,6 +170,13 @@ module ahci_fsm 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_ferr, // FIS done, fatal error - FIS too long output set_update_sig, // when set, enables get_sig (and resets itself) input pUpdateSig, // state variable input sig_available, // device signature available output update_sig, // update signature // next commands use register address/data/we for 1 clock cycle - after next to command (commnd - t0, we - t2) output update_err_sts,// update PxTFD.STS and PxTFD.ERR from the last received regs d2h output update_pio, // update PxTFD.STS and PxTFD.ERR from pio_* (entry PIO:Update) Loading Loading @@ -260,7 +267,7 @@ module ahci_fsm reg async_from_st; // chnge to multi-bit if there will be more sources for async transitions wire asynq_rq = cominit_got || pcmd_st_cleared; wire async_ackn = !fsm_preload && async_pend_r[0] && ((fsm_actions && !update_busy && !fsm_act_busy) || fsm_transitions[0]); // OK to process async jump reg x_rdy_collision_pend; assign fsm_next = (fsm_preload || (fsm_actions && !update_busy && !fsm_act_busy) || fsm_transitions[0]) && !async_pend_r[0]; // quiet if received cominit is pending Loading Loading @@ -316,6 +323,11 @@ module ahci_fsm if (hba_rst) async_pend_r <= 0; else async_pend_r <= {async_pend_r[0], asynq_rq | (async_pend_r[0] & ~async_ackn)}; if (hba_rst || pcmd_cr_set) x_rdy_collision_pend <= 0; else if (x_rdy_collision) x_rdy_collision_pend <= 1; end /* Loading
ahci/ahci_top.v +24 −10 Original line number Diff line number Diff line Loading @@ -146,8 +146,10 @@ module ahci_top#( input syncesc_recv, // These two inputs interrupt transmit input xmit_err, // Error during sending of a FIS output syncesc_send, // Send sync escape input syncesc_send_done, // "SYNC escape until the interface is quiescent..." input cominit_got, output set_offline, // electrically idle input x_rdy_collision, // X_RDY/X_RDY collision on interface output send_R_OK, // Should it be originated in this layer SM? output send_R_ERR, Loading Loading @@ -222,10 +224,6 @@ module ahci_top#( // fsm <-> ahc_fis_receive // fsm -> wire frcv_first_vld; wire frcv_set_update_sig; // when set, enables get_sig (and resets itself) wire frcv_pUpdateSig; // state variable wire frcv_get_sig; // update signature wire frcv_get_dsfis; wire frcv_get_psfis; wire frcv_get_rfis; Loading Loading @@ -255,6 +253,12 @@ module ahci_top#( wire frcv_err; // FIS done, checksum ERROR reset by starting a new get FIS wire frcv_ferr; // FIS done, fatal error - FIS too long wire frcv_set_update_sig; // when set, enables get_sig (and resets itself) wire frcv_pUpdateSig; // state variable wire frcv_sig_available; // signature data available wire frcv_update_sig; // update signature // fsm <- state variables that are maintained inside 'ahc_fis_receive' wire [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 Loading Loading @@ -419,11 +423,14 @@ module ahci_top#( .phy_ready (phy_ready), // input .syncesc_send (syncesc_send), // output .syncesc_send_done (syncesc_send_done), // input .cominit_got (cominit_got), // input .set_offline (set_offline), // output .x_rdy_collision (x_rdy_collision), // input .send_R_OK (send_R_OK), // output .send_R_ERR (send_R_ERR), // output .update_pending (update_regs_pending),// input .update_all (update_all_regs), // output .update_busy (update_regs_busy), // input Loading Loading @@ -502,9 +509,8 @@ module ahci_top#( .fis_first_vld (frcv_first_vld), // input .fis_type (d2h_data[7:0]), // input[7:0] FIS type (low byte in the first FIS DWORD), valid with 'fis_first_vld' .set_update_sig (frcv_set_update_sig),// output .pUpdateSig (frcv_pUpdateSig), // input .get_sig (frcv_get_sig), // output .bist_bits (d2h_data[23:16]), // bits that define built-in self test .get_dsfis (frcv_get_dsfis), // output .get_psfis (frcv_get_psfis), // output .get_rfis (frcv_get_rfis), // output Loading @@ -517,6 +523,12 @@ module ahci_top#( .fis_ok (frcv_ok), // input .fis_err (frcv_err), // input .fis_ferr (frcv_ferr), // input .set_update_sig (frcv_set_update_sig),// output .pUpdateSig (frcv_pUpdateSig), // input .sig_available (frcv_sig_available), // input .update_sig (frcv_update_sig), // output .update_err_sts (frcv_update_err_sts),// output .update_pio (frcv_update_pio), // output .update_prdbc (frcv_update_prdbc), // output Loading Loading @@ -797,10 +809,7 @@ module ahci_top#( .mclk (mclk), // input .fis_first_vld (frcv_first_vld), // output reg .set_update_sig (frcv_set_update_sig), // input .pUpdateSig (frcv_pUpdateSig), // output .get_sig (frcv_get_sig), // input .get_dsfis (frcv_get_dsfis), // input .get_psfis (frcv_get_psfis), // input .get_rfis (frcv_get_rfis), // input Loading @@ -815,6 +824,11 @@ module ahci_top#( .fis_err (frcv_err), // output reg .fis_ferr (frcv_ferr), // output .set_update_sig (frcv_set_update_sig), // input .pUpdateSig (frcv_pUpdateSig), // output .sig_available (frcv_sig_available), // output reg .update_sig (frcv_update_sig), // input .update_err_sts (frcv_update_err_sts), // input .update_pio (frcv_update_pio), // input update PxTFD.STS and PxTFD.ERR from pio_* (entry PIO:Update) Loading