Loading ahci/ahci_fis_transmit.v +31 −14 Original line number Diff line number Diff line Loading @@ -33,21 +33,25 @@ module ahci_fis_transmit #( input fetch_cmd, // Enter p:FetchCmd, fetch command header (from the register memory, prefetch command FIS) // wait for either fetch_cmd_busy == 0 or pCmdToIssue ==1 after fetch_cmd input cfis_xmit, // transmit command (wait for dma_ct_busy == 0) input dx_transmit, // send FIS header DWORD, (just 0x46), then forward DMA data input dx_xmit, // send FIS header DWORD, (just 0x46), then forward DMA data // transmit until error, 2048DWords or pDmaXferCnt input atapi_xmit, // trasmit ATAPI command FIS output reg done, output reg done, // for fetch_cmd - dma_start, for *_xmit - xmit_ok, xmit_err, syncesc_recv or xrdy_collision output reg busy, input clearCmdToIssue, // From CFIS:SUCCESS output pCmdToIssue, // AHCI port variable // output dmaCntrZero, // DMA counter is zero - would be a duplicate to the one in receive module and dwords_sent output // output reg fetch_cmd_busy, // does not include prefetching CT - now just use busy/done input syncesc_recv, // These two inputs interrupt transmit // Should wait for xmit_ok? Timeout? Timeout will be handled by software, so just wait for OK or some error input xmit_ok, // FIS transmission acknowledged OK input xmit_err, // output [ 1:0] dx_err, // bit 0 - syncesc_recv, 1 - xmit_err (valid @ xmit_err and later, reset by new command) input syncesc_recv, // These two inputs interrupt transmit input xrdy_collision, output [ 2:0] dx_err, // bit 0 - syncesc_recv, 1 - xmit_err, 2 - collision (valid @ xmit_err and later, reset by new command) output [15:0] ch_prdtl, // Physical region descriptor table length (in entries, 0 is 0) output ch_c, // Clear busy upon R_OK for this FIS Loading Loading @@ -89,7 +93,7 @@ module ahci_fis_transmit #( // Data System memory or FIS -> device output reg [31:0] todev_data, // 32-bit data from the system memory to HBA (dma data) output reg [ 1:0] todev_type, // 0 - data, 1 - FIS head, 2 - FIS END (make FIS_Last?) output reg [ 1:0] todev_type, // 0 - data, 1 - FIS head, 2 - FIS LAST) output todev_valid, // output register full input todev_ready // send FIFO has room for data (>= 8? dwords) Loading Loading @@ -152,13 +156,16 @@ module ahci_fis_transmit #( reg dx_fis_pend_r; // waiting to send first DWORD of the H2D data transfer wire dx_dma_last_w; // sending last adat word reg dx_busy_r; reg [ 1:0] dx_err_r; wire any_cmd_start = fetch_cmd || cfis_xmit || dx_transmit || atapi_xmit; wire done_w = dx_dma_last_w || ((|dx_err_r) && dx_busy_r) || chead_done_w || acfis_xmit_end || dma_start; // done on last transmit or error reg [ 2:0] dx_err_r; reg xmit_ok_r; wire any_cmd_start = fetch_cmd || cfis_xmit || dx_xmit || atapi_xmit; // wire done_w = dx_dma_last_w || ((|dx_err_r) && dx_busy_r) || chead_done_w || acfis_xmit_end || dma_start; // done on last transmit or error // dma_start ends 'fetch_cmd' wire done_w = xmit_ok_r || ((|dx_err_r) && dx_busy_r) || dma_start; // done on last transmit or error reg fetch_cmd_busy_r; assign todev_valid = todev_full_r; assign dma_re = dma_re_w; assign reg_re = reg_re_r[1:0]; Loading Loading @@ -283,15 +290,15 @@ module ahci_fis_transmit #( //TODO: update xfer length, prdtl (only after R_OK) - yes, do it outside if (dx_transmit) dx_dwords_left[11:2] <= (|xfer_cntr[31:11])?10'h200:{1'b0,xfer_cntr[10:2]}; if (dx_xmit) dx_dwords_left[11:2] <= (|xfer_cntr[31:11])?10'h200:{1'b0,xfer_cntr[10:2]}; else if (dma_re_w) dx_dwords_left[11:2] <= dx_dwords_left[11:2] - 1; if (dx_transmit) dwords_sent <= 0; if (dx_xmit) dwords_sent <= 0; else if (dma_re_w) dwords_sent <= dwords_sent + 1; // send FIS header if (hba_rst || write_or_w) dx_fis_pend_r <= 0; else if (dx_transmit) dx_fis_pend_r <= 1; else if (dx_xmit) dx_fis_pend_r <= 1; if (hba_rst || dx_dma_last_w || (|dx_err_r)) dma_en_r <= 0; else if (dx_fis_pend_r && write_or_w) dma_en_r <= 1; Loading @@ -303,9 +310,14 @@ module ahci_fis_transmit #( if (hba_rst || any_cmd_start) dx_err_r[1] <= 0; else if (xmit_err) dx_err_r[1] <= 1; if (hba_rst) dx_busy_r <= 0; else if (dx_transmit) dx_busy_r <= 1; else if (dx_dma_last_w || (|dx_err_r)) dx_busy_r <= 0; if (hba_rst || any_cmd_start) dx_err_r[2] <= 0; else if (xrdy_collision) dx_err_r[2] <= 1; if (hba_rst) dx_busy_r <= 0; // sending CFIS, AFIS or data FIS (until error or R_OK) // else if (dx_xmit) dx_busy_r <= 1; // else if (dx_dma_last_w || (|dx_err_r)) dx_busy_r <= 0; else if (dx_xmit || acfis_xmit_start_r) dx_busy_r <= 1; else if (xmit_ok || (|dx_err_r)) dx_busy_r <= 0; dma_prd_start <= (dma_start && (PREFETCH_ALWAYS || ch_p_r || !ch_w_r)) || // device read may prefetch just prd addresses (dx_fis_pend_r && write_or_w); // enable PRD read now (if it was not already done) Loading @@ -317,6 +329,11 @@ module ahci_fis_transmit #( else if (any_cmd_start) busy <= 1; else if (done_w) busy <= 0; if (hba_rst) xmit_ok_r <= 0; else xmit_ok_r <= dx_busy_r && !(|dx_err_r) && xmit_ok; dma_cmd_abort <= done_w && (|dx_err_r); Loading ahci/ahci_fsm.v +10 −10 Original line number Diff line number Diff line Loading @@ -48,7 +48,7 @@ module ahci_fsm output comreset_send, // Not possible yet? 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 // 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 @@ -213,7 +213,7 @@ module ahci_fsm output fetch_cmd, // Enter p:FetchCmd, fetch command header (from the register memory, prefetch command FIS) // wait for either fetch_cmd_busy == 0 or pCmdToIssue ==1 after fetch_cmd output cfis_xmit, // transmit command (wait for dma_ct_busy == 0) output dx_transmit, // send FIS header DWORD, (just 0x46), then forward DMA data output dx_xmit, // send FIS header DWORD, (just 0x46), then forward DMA data // transmit until error, 2048DWords or pDmaXferCnt output atapi_xmit, // tarsmit ATAPI command FIS input xmit_done, Loading @@ -224,7 +224,7 @@ module ahci_fsm // output dmaCntrZero, // DMA counter is zero - would be a duplicate to the one in receive module and dwords_sent output // input syncesc_recv, // These two inputs interrupt transmit // 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 [ 2:0] dx_err, // bit 0 - syncesc_recv, 1 - xmit_err, 2 - X_RDY/X_RDY collision (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 ch_c, // Clear busy upon R_OK for this FIS Loading Loading @@ -272,7 +272,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; // reg x_rdy_collision_pend; reg syncesc_send_pend; // waiting for 'syncesc_send' confiramtion 'syncesc_send_done' reg [1:0] phy_ready_prev; // previous state of phy_ready / speed reg phy_ready_chng_r; // pulse when phy_ready changes Loading Loading @@ -353,8 +353,8 @@ module ahci_fsm 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; // if (hba_rst || pcmd_cr_set) x_rdy_collision_pend <= 0; // else if (x_rdy_collision) x_rdy_collision_pend <= 1; if (hba_rst || syncesc_send_done) syncesc_send_pend <= 0; else if (syncesc_send) syncesc_send_pend <= 1; Loading Loading @@ -435,7 +435,7 @@ module ahci_fsm .FETCH_CMD (fetch_cmd), // output reg .ATAPI_XMIT (atapi_xmit), // output reg .CFIS_XMIT (cfis_xmit), // output reg .DX_XMIT (dx_transmit), // output reg .DX_XMIT (dx_xmit), // output reg //FIS RECEIVE/WAIT DONE .GET_DATA_FIS (get_data_fis), // output reg .GET_DSFIS (get_dsfis), // output reg Loading Loading @@ -500,7 +500,7 @@ module ahci_fsm // DMA .DMA_PRD_IRQ_PEND (dma_prd_irq_pend), // input // SATA TRANSPORT/LINK/PHY .X_RDY_COLLISION (x_rdy_collision_pend) // input .X_RDY_COLLISION (dx_err[2]) //x_rdy_collision_pend) // input ); Loading Loading
ahci/ahci_fis_transmit.v +31 −14 Original line number Diff line number Diff line Loading @@ -33,21 +33,25 @@ module ahci_fis_transmit #( input fetch_cmd, // Enter p:FetchCmd, fetch command header (from the register memory, prefetch command FIS) // wait for either fetch_cmd_busy == 0 or pCmdToIssue ==1 after fetch_cmd input cfis_xmit, // transmit command (wait for dma_ct_busy == 0) input dx_transmit, // send FIS header DWORD, (just 0x46), then forward DMA data input dx_xmit, // send FIS header DWORD, (just 0x46), then forward DMA data // transmit until error, 2048DWords or pDmaXferCnt input atapi_xmit, // trasmit ATAPI command FIS output reg done, output reg done, // for fetch_cmd - dma_start, for *_xmit - xmit_ok, xmit_err, syncesc_recv or xrdy_collision output reg busy, input clearCmdToIssue, // From CFIS:SUCCESS output pCmdToIssue, // AHCI port variable // output dmaCntrZero, // DMA counter is zero - would be a duplicate to the one in receive module and dwords_sent output // output reg fetch_cmd_busy, // does not include prefetching CT - now just use busy/done input syncesc_recv, // These two inputs interrupt transmit // Should wait for xmit_ok? Timeout? Timeout will be handled by software, so just wait for OK or some error input xmit_ok, // FIS transmission acknowledged OK input xmit_err, // output [ 1:0] dx_err, // bit 0 - syncesc_recv, 1 - xmit_err (valid @ xmit_err and later, reset by new command) input syncesc_recv, // These two inputs interrupt transmit input xrdy_collision, output [ 2:0] dx_err, // bit 0 - syncesc_recv, 1 - xmit_err, 2 - collision (valid @ xmit_err and later, reset by new command) output [15:0] ch_prdtl, // Physical region descriptor table length (in entries, 0 is 0) output ch_c, // Clear busy upon R_OK for this FIS Loading Loading @@ -89,7 +93,7 @@ module ahci_fis_transmit #( // Data System memory or FIS -> device output reg [31:0] todev_data, // 32-bit data from the system memory to HBA (dma data) output reg [ 1:0] todev_type, // 0 - data, 1 - FIS head, 2 - FIS END (make FIS_Last?) output reg [ 1:0] todev_type, // 0 - data, 1 - FIS head, 2 - FIS LAST) output todev_valid, // output register full input todev_ready // send FIFO has room for data (>= 8? dwords) Loading Loading @@ -152,13 +156,16 @@ module ahci_fis_transmit #( reg dx_fis_pend_r; // waiting to send first DWORD of the H2D data transfer wire dx_dma_last_w; // sending last adat word reg dx_busy_r; reg [ 1:0] dx_err_r; wire any_cmd_start = fetch_cmd || cfis_xmit || dx_transmit || atapi_xmit; wire done_w = dx_dma_last_w || ((|dx_err_r) && dx_busy_r) || chead_done_w || acfis_xmit_end || dma_start; // done on last transmit or error reg [ 2:0] dx_err_r; reg xmit_ok_r; wire any_cmd_start = fetch_cmd || cfis_xmit || dx_xmit || atapi_xmit; // wire done_w = dx_dma_last_w || ((|dx_err_r) && dx_busy_r) || chead_done_w || acfis_xmit_end || dma_start; // done on last transmit or error // dma_start ends 'fetch_cmd' wire done_w = xmit_ok_r || ((|dx_err_r) && dx_busy_r) || dma_start; // done on last transmit or error reg fetch_cmd_busy_r; assign todev_valid = todev_full_r; assign dma_re = dma_re_w; assign reg_re = reg_re_r[1:0]; Loading Loading @@ -283,15 +290,15 @@ module ahci_fis_transmit #( //TODO: update xfer length, prdtl (only after R_OK) - yes, do it outside if (dx_transmit) dx_dwords_left[11:2] <= (|xfer_cntr[31:11])?10'h200:{1'b0,xfer_cntr[10:2]}; if (dx_xmit) dx_dwords_left[11:2] <= (|xfer_cntr[31:11])?10'h200:{1'b0,xfer_cntr[10:2]}; else if (dma_re_w) dx_dwords_left[11:2] <= dx_dwords_left[11:2] - 1; if (dx_transmit) dwords_sent <= 0; if (dx_xmit) dwords_sent <= 0; else if (dma_re_w) dwords_sent <= dwords_sent + 1; // send FIS header if (hba_rst || write_or_w) dx_fis_pend_r <= 0; else if (dx_transmit) dx_fis_pend_r <= 1; else if (dx_xmit) dx_fis_pend_r <= 1; if (hba_rst || dx_dma_last_w || (|dx_err_r)) dma_en_r <= 0; else if (dx_fis_pend_r && write_or_w) dma_en_r <= 1; Loading @@ -303,9 +310,14 @@ module ahci_fis_transmit #( if (hba_rst || any_cmd_start) dx_err_r[1] <= 0; else if (xmit_err) dx_err_r[1] <= 1; if (hba_rst) dx_busy_r <= 0; else if (dx_transmit) dx_busy_r <= 1; else if (dx_dma_last_w || (|dx_err_r)) dx_busy_r <= 0; if (hba_rst || any_cmd_start) dx_err_r[2] <= 0; else if (xrdy_collision) dx_err_r[2] <= 1; if (hba_rst) dx_busy_r <= 0; // sending CFIS, AFIS or data FIS (until error or R_OK) // else if (dx_xmit) dx_busy_r <= 1; // else if (dx_dma_last_w || (|dx_err_r)) dx_busy_r <= 0; else if (dx_xmit || acfis_xmit_start_r) dx_busy_r <= 1; else if (xmit_ok || (|dx_err_r)) dx_busy_r <= 0; dma_prd_start <= (dma_start && (PREFETCH_ALWAYS || ch_p_r || !ch_w_r)) || // device read may prefetch just prd addresses (dx_fis_pend_r && write_or_w); // enable PRD read now (if it was not already done) Loading @@ -317,6 +329,11 @@ module ahci_fis_transmit #( else if (any_cmd_start) busy <= 1; else if (done_w) busy <= 0; if (hba_rst) xmit_ok_r <= 0; else xmit_ok_r <= dx_busy_r && !(|dx_err_r) && xmit_ok; dma_cmd_abort <= done_w && (|dx_err_r); Loading
ahci/ahci_fsm.v +10 −10 Original line number Diff line number Diff line Loading @@ -48,7 +48,7 @@ module ahci_fsm output comreset_send, // Not possible yet? 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 // 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 @@ -213,7 +213,7 @@ module ahci_fsm output fetch_cmd, // Enter p:FetchCmd, fetch command header (from the register memory, prefetch command FIS) // wait for either fetch_cmd_busy == 0 or pCmdToIssue ==1 after fetch_cmd output cfis_xmit, // transmit command (wait for dma_ct_busy == 0) output dx_transmit, // send FIS header DWORD, (just 0x46), then forward DMA data output dx_xmit, // send FIS header DWORD, (just 0x46), then forward DMA data // transmit until error, 2048DWords or pDmaXferCnt output atapi_xmit, // tarsmit ATAPI command FIS input xmit_done, Loading @@ -224,7 +224,7 @@ module ahci_fsm // output dmaCntrZero, // DMA counter is zero - would be a duplicate to the one in receive module and dwords_sent output // input syncesc_recv, // These two inputs interrupt transmit // 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 [ 2:0] dx_err, // bit 0 - syncesc_recv, 1 - xmit_err, 2 - X_RDY/X_RDY collision (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 ch_c, // Clear busy upon R_OK for this FIS Loading Loading @@ -272,7 +272,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; // reg x_rdy_collision_pend; reg syncesc_send_pend; // waiting for 'syncesc_send' confiramtion 'syncesc_send_done' reg [1:0] phy_ready_prev; // previous state of phy_ready / speed reg phy_ready_chng_r; // pulse when phy_ready changes Loading Loading @@ -353,8 +353,8 @@ module ahci_fsm 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; // if (hba_rst || pcmd_cr_set) x_rdy_collision_pend <= 0; // else if (x_rdy_collision) x_rdy_collision_pend <= 1; if (hba_rst || syncesc_send_done) syncesc_send_pend <= 0; else if (syncesc_send) syncesc_send_pend <= 1; Loading Loading @@ -435,7 +435,7 @@ module ahci_fsm .FETCH_CMD (fetch_cmd), // output reg .ATAPI_XMIT (atapi_xmit), // output reg .CFIS_XMIT (cfis_xmit), // output reg .DX_XMIT (dx_transmit), // output reg .DX_XMIT (dx_xmit), // output reg //FIS RECEIVE/WAIT DONE .GET_DATA_FIS (get_data_fis), // output reg .GET_DSFIS (get_dsfis), // output reg Loading Loading @@ -500,7 +500,7 @@ module ahci_fsm // DMA .DMA_PRD_IRQ_PEND (dma_prd_irq_pend), // input // SATA TRANSPORT/LINK/PHY .X_RDY_COLLISION (x_rdy_collision_pend) // input .X_RDY_COLLISION (dx_err[2]) //x_rdy_collision_pend) // input ); Loading