Loading ahci/ahci_fis_receive.v +14 −10 Original line number Original line Diff line number Diff line Loading @@ -59,7 +59,7 @@ module ahci_fis_receive#( input set_sts_80, // set PxTFD.STS = 0x80 (may be combined with set_sts_7f), update input set_sts_80, // set PxTFD.STS = 0x80 (may be combined with set_sts_7f), update input decr_dwc, // decrement DMA Xfer counter // need pulse to 'update_prdbc' to write to registers input decr_dwc, // decrement DMA Xfer counter // need pulse to 'update_prdbc' to write to registers input [11:2] decr_DXC_dw, // decrement value (in DWORDs) input [11:0] decr_DXC_dw, // decrement value (in DWORDs) // TODO: Add writing PRDBC here? // TODO: Add writing PRDBC here? Loading @@ -76,6 +76,9 @@ module ahci_fis_receive#( // 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 output [31:2] xfer_cntr, // transfer counter in words for both DMA (31 bit) and PIO (lower 15 bits), updated after decr_dwc output [31:2] xfer_cntr, // transfer counter in words for both DMA (31 bit) and PIO (lower 15 bits), updated after decr_dwc output reg xfer_cntr_zero,// valid next cycle output reg xfer_cntr_zero,// valid next cycle output [11:0] data_in_dwords, // number of data dwords received (valid with 'done') // FSM will send this pulse // output reg data_in_words_apply, // apply data_in_words // Registers interface // Registers interface // 2. HBA R/W registers, may be added external register layer // 2. HBA R/W registers, may be added external register layer Loading Loading @@ -135,7 +138,7 @@ localparam DATA_TYPE_ERR = 3; wire dma_in_stop; wire dma_in_stop; reg dma_in; reg dma_in; reg [1:0] was_data_in; reg [1:0] was_data_in; reg [12:0] data_in_words; reg [11:0] data_in_dwords_r; reg dwords_over; reg dwords_over; reg too_long_err; reg too_long_err; Loading Loading @@ -189,6 +192,7 @@ localparam DATA_TYPE_ERR = 3; assign xfer_cntr = xfer_cntr_r[31:2]; assign xfer_cntr = xfer_cntr_r[31:2]; assign get_fis_busy = get_fis_busy_r; assign get_fis_busy = get_fis_busy_r; assign data_in_dwords = data_out_dwords_r; always @ (posedge mclk) begin always @ (posedge mclk) begin if (hba_rst || dma_in_stop) dma_in <= 0; if (hba_rst || dma_in_stop) dma_in <= 0; Loading @@ -197,11 +201,11 @@ localparam DATA_TYPE_ERR = 3; if (hba_rst) was_data_in <= 0; if (hba_rst) was_data_in <= 0; else was_data_in <= {was_data_in[0], hba_data_in_ready}; else was_data_in <= {was_data_in[0], hba_data_in_ready}; if (dma_in_start) data_in_words <= 0; if (dma_in_start) data_in_dwords_r <= 0; else if (dma_in_valid) data_in_words <= data_in_words + 1; else if (dma_in_valid) data_in_dwords_r <= data_in_dwords_r + 1; if (hba_rst) too_long_err <= 0; // it is a fatal error, only reset if (hba_rst) too_long_err <= 0; // it is a fatal error, only reset else if ((dma_in_valid && data_in_words[12]) || else if ((dma_in_valid && data_in_dwords_r[11]) || (wreg_we_r && dwords_over)) too_long_err <= 1; (wreg_we_r && dwords_over)) too_long_err <= 1; if (get_fis) begin if (get_fis) begin Loading Loading @@ -296,18 +300,18 @@ localparam DATA_TYPE_ERR = 3; if (hba_rst || reg_sdb) xfer_cntr_r[31:2] <= 0; if (hba_rst || reg_sdb) xfer_cntr_r[31:2] <= 0; else if (reg_ps[4] || reg_ds[5]) xfer_cntr_r[31:2] <= {reg_ds[5]?hba_data_in[31:16]:16'b0, hba_data_in[15:2]} + hba_data_in[1]; // round up else if (reg_ps[4] || reg_ds[5]) xfer_cntr_r[31:2] <= {reg_ds[5]?hba_data_in[31:16]:16'b0, hba_data_in[15:2]} + hba_data_in[1]; // round up else if (decr_dwc) xfer_cntr_r[31:2] <= {xfer_cntr_r[31:2]} - {20'b0, decr_DXC_dw[11:2]}; else if (decr_dwc) xfer_cntr_r[31:2] <= {xfer_cntr_r[31:2]} - {18'b0, decr_DXC_dw[11:0]}; if (hba_rst || reg_sdb || reg_ps[4] || reg_ds[5]) prdbc_r[31:2] <= 0; if (hba_rst || reg_sdb || reg_ps[4] || reg_ds[5]) prdbc_r[31:2] <= 0; else if (decr_dwc) prdbc_r[31:2] <= {prdbc_r[31:2]} + {20'b0, decr_DXC_dw[11:2]}; else if (decr_dwc) prdbc_r[31:2] <= {prdbc_r[31:2]} + {18'b0, decr_DXC_dw[11:0]}; xfer_cntr_zero <= xfer_cntr_r[31:2] == 0; xfer_cntr_zero <= xfer_cntr_r[31:2] == 0; update_err_sts_r <= update_err_sts || clear_bsy_drq || set_bsy || set_sts_7f || set_sts_80; update_err_sts_r <= update_err_sts || clear_bsy_drq || set_bsy || set_sts_7f || set_sts_80; update_prdbc_r <= update_prdbc; // same latency as update_err_sts update_prdbc_r <= update_prdbc; // same latency as update_err_sts // 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); end end endmodule endmodule ahci/ahci_fis_transmit.v +12 −8 Original line number Original line Diff line number Diff line Loading @@ -36,13 +36,15 @@ module ahci_fis_transmit #( input dx_transmit, // send FIS header DWORD, (just 0x46), then forward DMA data input dx_transmit, // send FIS header DWORD, (just 0x46), then forward DMA data // transmit until error, 2048DWords or pDmaXferCnt // transmit until error, 2048DWords or pDmaXferCnt input atapi_xmit, // tarsmit ATAPI command FIS input atapi_xmit, // tarsmit ATAPI command FIS output reg done, output reg done, output reg busy, output reg busy, input clearCmdToIssue, // From CFIS:SUCCESS input clearCmdToIssue, // From CFIS:SUCCESS output pCmdToIssue, // AHCI port variable 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 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 // output reg fetch_cmd_busy, // does not include prefetching CT - now just use busy/done input syncesc_recv, // These two inputs interrupt transmit input syncesc_recv, // These two inputs interrupt transmit input xmit_err, // input xmit_err, // output [ 1:0] dx_err, // bit 0 - syncesc_recv, 1 - xmit_err (valid @ xmit_err and later, reset by new command) output [ 1:0] dx_err, // bit 0 - syncesc_recv, 1 - xmit_err (valid @ xmit_err and later, reset by new command) Loading @@ -56,7 +58,7 @@ module ahci_fis_transmit #( output ch_a, // ATAPI: 1 means device should send PIO setup FIS for ATAPI command output ch_a, // ATAPI: 1 means device should send PIO setup FIS for ATAPI command output [4:0] ch_cfl, // length of the command FIS in DW, 0 means none. 0 and 1 - illegal, output [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) output reg [11:2] dwords_sent, // number of DWORDs transmitted (up to 2048) output reg [11:0] dwords_sent, // number of DWORDs transmitted (up to 2048) // register memory interface // register memory interface output reg [ADDRESS_BITS-1:0] reg_addr, output reg [ADDRESS_BITS-1:0] reg_addr, Loading Loading @@ -136,7 +138,7 @@ module ahci_fis_transmit #( reg acfis_xmit_busy_r; // reg acfis_xmit_busy_r; // // reg anc_fis_r; // This is ATAPI FIS, not Command FIS // reg anc_fis_r; // This is ATAPI FIS, not Command FIS wire acfis_xmit_start_w = (cfis_xmit || atapi_xmit || acfis_xmit_pend_r) && !dma_ct_busy && !fetch_cmd_busy; // dma_ct_busy no gaps with fetch_cmd_busy wire acfis_xmit_start_w = (cfis_xmit || atapi_xmit || acfis_xmit_pend_r) && !dma_ct_busy && !fetch_cmd_busy_r; // dma_ct_busy no gaps with fetch_cmd_busy wire acfis_xmit_end = ct_stb && fis_dw_last; wire acfis_xmit_end = ct_stb && fis_dw_last; wire ct_re_w; // next cycle will be ct_re; wire ct_re_w; // next cycle will be ct_re; Loading @@ -152,8 +154,10 @@ module ahci_fis_transmit #( reg dx_busy_r; reg dx_busy_r; reg [ 1:0] dx_err_r; reg [ 1:0] dx_err_r; wire any_cmd_start = fetch_cmd || cfis_xmit || dx_transmit || atapi_xmit; 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; // done on last transmit or error 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' reg fetch_cmd_busy_r; assign todev_valid = todev_full_r; assign todev_valid = todev_full_r; assign dma_re = dma_re_w; assign dma_re = dma_re_w; Loading Loading @@ -237,9 +241,9 @@ module ahci_fis_transmit #( else if (chead_done_w) pCmdToIssue_r <= 1; else if (chead_done_w) pCmdToIssue_r <= 1; else if (clearCmdToIssue) pCmdToIssue_r <= 0; else if (clearCmdToIssue) pCmdToIssue_r <= 0; if (hba_rst) fetch_cmd_busy <= 0; if (hba_rst) fetch_cmd_busy_r <= 0; else if (fetch_cmd) fetch_cmd_busy <= 1; else if (fetch_cmd) fetch_cmd_busy_r <= 1; else if (dma_start) fetch_cmd_busy <= 0; else if (dma_start) fetch_cmd_busy_r <= 0; //CFIS/ATAPI common //CFIS/ATAPI common Loading Loading @@ -280,7 +284,7 @@ module ahci_fis_transmit #( else if (dma_re_w) dx_dwords_left[11:2] <= dx_dwords_left[11:2] - 1; else if (dma_re_w) dx_dwords_left[11:2] <= dx_dwords_left[11:2] - 1; if (dx_transmit) dwords_sent <= 0; if (dx_transmit) dwords_sent <= 0; else if (dma_re_w) dwords_sent[11:2] <= dwords_sent[11:2] + 1; else if (dma_re_w) dwords_sent <= dwords_sent + 1; // send FIS header // send FIS header if (hba_rst || write_or_w) dx_fis_pend_r <= 0; if (hba_rst || write_or_w) dx_fis_pend_r <= 0; Loading ahci/ahci_fsm.v +14 −7 Original line number Original line Diff line number Diff line Loading @@ -43,11 +43,19 @@ module ahci_fsm #( // direct communication with transposrt, link and phy layers // direct communication with transposrt, link and phy layers input phy_ready, // goes up after comreset,cominit, align, ... input phy_ready, // goes up after comreset,cominit, align, ... output syncesc_send, // Send sync escape // Other signals.... // Other signals.... // inputs from the DMA engine input dma_prd_done, // output (finished next prd) input dma_prd_irq, // output (finished next prd and prd irq is enabled) input dma_cmd_busy, // output reg (DMA engine is processing PRDs) input dma_cmd_done, // output (last PRD is over) // Communication with ahci_fis_receive (some are unused // Communication with ahci_fis_receive (some are unused input fis_first_vld, // fis_first contains valid FIS header, reset by get_* 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 // Receiving FIS output get_sig, // update signature output get_sig, // update signature output get_dsfis, output get_dsfis, Loading @@ -70,7 +78,7 @@ module ahci_fsm #( output set_sts_7f, // set PxTFD.STS = 0x7f, update output set_sts_7f, // set PxTFD.STS = 0x7f, update output set_sts_80, // set PxTFD.STS = 0x80 (may be combined with set_sts_7f), update output set_sts_80, // set PxTFD.STS = 0x80 (may be combined with set_sts_7f), update output decr_dwc, // decrement DMA Xfer counter // need pulse to 'update_prdbc' to write to registers output decr_dwc, // decrement DMA Xfer counter // need pulse to 'update_prdbc' to write to registers output [11:2] decr_DXC_dw, // decrement value (in DWORDs) output [11:0] decr_DXC_dw, // decrement value (in DWORDs) 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) Loading Loading @@ -99,9 +107,8 @@ module ahci_fsm #( output clearCmdToIssue, // From CFIS:SUCCESS output clearCmdToIssue, // From CFIS:SUCCESS input pCmdToIssue, // AHCI port variable input 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 dmaCntrZero, // DMA counter is zero - would be a duplicate to the one in receive module and dwords_sent output input fetch_cmd_busy, // does not include prefetching CT // input syncesc_recv, // These two inputs interrupt transmit output syncesc_recv, // These two inputs interrupt transmit // input xmit_err, // output 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) Loading @@ -113,7 +120,7 @@ module ahci_fsm #( 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:2] 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 Loading Loading
ahci/ahci_fis_receive.v +14 −10 Original line number Original line Diff line number Diff line Loading @@ -59,7 +59,7 @@ module ahci_fis_receive#( input set_sts_80, // set PxTFD.STS = 0x80 (may be combined with set_sts_7f), update input set_sts_80, // set PxTFD.STS = 0x80 (may be combined with set_sts_7f), update input decr_dwc, // decrement DMA Xfer counter // need pulse to 'update_prdbc' to write to registers input decr_dwc, // decrement DMA Xfer counter // need pulse to 'update_prdbc' to write to registers input [11:2] decr_DXC_dw, // decrement value (in DWORDs) input [11:0] decr_DXC_dw, // decrement value (in DWORDs) // TODO: Add writing PRDBC here? // TODO: Add writing PRDBC here? Loading @@ -76,6 +76,9 @@ module ahci_fis_receive#( // 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 output [31:2] xfer_cntr, // transfer counter in words for both DMA (31 bit) and PIO (lower 15 bits), updated after decr_dwc output [31:2] xfer_cntr, // transfer counter in words for both DMA (31 bit) and PIO (lower 15 bits), updated after decr_dwc output reg xfer_cntr_zero,// valid next cycle output reg xfer_cntr_zero,// valid next cycle output [11:0] data_in_dwords, // number of data dwords received (valid with 'done') // FSM will send this pulse // output reg data_in_words_apply, // apply data_in_words // Registers interface // Registers interface // 2. HBA R/W registers, may be added external register layer // 2. HBA R/W registers, may be added external register layer Loading Loading @@ -135,7 +138,7 @@ localparam DATA_TYPE_ERR = 3; wire dma_in_stop; wire dma_in_stop; reg dma_in; reg dma_in; reg [1:0] was_data_in; reg [1:0] was_data_in; reg [12:0] data_in_words; reg [11:0] data_in_dwords_r; reg dwords_over; reg dwords_over; reg too_long_err; reg too_long_err; Loading Loading @@ -189,6 +192,7 @@ localparam DATA_TYPE_ERR = 3; assign xfer_cntr = xfer_cntr_r[31:2]; assign xfer_cntr = xfer_cntr_r[31:2]; assign get_fis_busy = get_fis_busy_r; assign get_fis_busy = get_fis_busy_r; assign data_in_dwords = data_out_dwords_r; always @ (posedge mclk) begin always @ (posedge mclk) begin if (hba_rst || dma_in_stop) dma_in <= 0; if (hba_rst || dma_in_stop) dma_in <= 0; Loading @@ -197,11 +201,11 @@ localparam DATA_TYPE_ERR = 3; if (hba_rst) was_data_in <= 0; if (hba_rst) was_data_in <= 0; else was_data_in <= {was_data_in[0], hba_data_in_ready}; else was_data_in <= {was_data_in[0], hba_data_in_ready}; if (dma_in_start) data_in_words <= 0; if (dma_in_start) data_in_dwords_r <= 0; else if (dma_in_valid) data_in_words <= data_in_words + 1; else if (dma_in_valid) data_in_dwords_r <= data_in_dwords_r + 1; if (hba_rst) too_long_err <= 0; // it is a fatal error, only reset if (hba_rst) too_long_err <= 0; // it is a fatal error, only reset else if ((dma_in_valid && data_in_words[12]) || else if ((dma_in_valid && data_in_dwords_r[11]) || (wreg_we_r && dwords_over)) too_long_err <= 1; (wreg_we_r && dwords_over)) too_long_err <= 1; if (get_fis) begin if (get_fis) begin Loading Loading @@ -296,18 +300,18 @@ localparam DATA_TYPE_ERR = 3; if (hba_rst || reg_sdb) xfer_cntr_r[31:2] <= 0; if (hba_rst || reg_sdb) xfer_cntr_r[31:2] <= 0; else if (reg_ps[4] || reg_ds[5]) xfer_cntr_r[31:2] <= {reg_ds[5]?hba_data_in[31:16]:16'b0, hba_data_in[15:2]} + hba_data_in[1]; // round up else if (reg_ps[4] || reg_ds[5]) xfer_cntr_r[31:2] <= {reg_ds[5]?hba_data_in[31:16]:16'b0, hba_data_in[15:2]} + hba_data_in[1]; // round up else if (decr_dwc) xfer_cntr_r[31:2] <= {xfer_cntr_r[31:2]} - {20'b0, decr_DXC_dw[11:2]}; else if (decr_dwc) xfer_cntr_r[31:2] <= {xfer_cntr_r[31:2]} - {18'b0, decr_DXC_dw[11:0]}; if (hba_rst || reg_sdb || reg_ps[4] || reg_ds[5]) prdbc_r[31:2] <= 0; if (hba_rst || reg_sdb || reg_ps[4] || reg_ds[5]) prdbc_r[31:2] <= 0; else if (decr_dwc) prdbc_r[31:2] <= {prdbc_r[31:2]} + {20'b0, decr_DXC_dw[11:2]}; else if (decr_dwc) prdbc_r[31:2] <= {prdbc_r[31:2]} + {18'b0, decr_DXC_dw[11:0]}; xfer_cntr_zero <= xfer_cntr_r[31:2] == 0; xfer_cntr_zero <= xfer_cntr_r[31:2] == 0; update_err_sts_r <= update_err_sts || clear_bsy_drq || set_bsy || set_sts_7f || set_sts_80; update_err_sts_r <= update_err_sts || clear_bsy_drq || set_bsy || set_sts_7f || set_sts_80; update_prdbc_r <= update_prdbc; // same latency as update_err_sts update_prdbc_r <= update_prdbc; // same latency as update_err_sts // 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); end end endmodule endmodule
ahci/ahci_fis_transmit.v +12 −8 Original line number Original line Diff line number Diff line Loading @@ -36,13 +36,15 @@ module ahci_fis_transmit #( input dx_transmit, // send FIS header DWORD, (just 0x46), then forward DMA data input dx_transmit, // send FIS header DWORD, (just 0x46), then forward DMA data // transmit until error, 2048DWords or pDmaXferCnt // transmit until error, 2048DWords or pDmaXferCnt input atapi_xmit, // tarsmit ATAPI command FIS input atapi_xmit, // tarsmit ATAPI command FIS output reg done, output reg done, output reg busy, output reg busy, input clearCmdToIssue, // From CFIS:SUCCESS input clearCmdToIssue, // From CFIS:SUCCESS output pCmdToIssue, // AHCI port variable 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 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 // output reg fetch_cmd_busy, // does not include prefetching CT - now just use busy/done input syncesc_recv, // These two inputs interrupt transmit input syncesc_recv, // These two inputs interrupt transmit input xmit_err, // input xmit_err, // output [ 1:0] dx_err, // bit 0 - syncesc_recv, 1 - xmit_err (valid @ xmit_err and later, reset by new command) output [ 1:0] dx_err, // bit 0 - syncesc_recv, 1 - xmit_err (valid @ xmit_err and later, reset by new command) Loading @@ -56,7 +58,7 @@ module ahci_fis_transmit #( output ch_a, // ATAPI: 1 means device should send PIO setup FIS for ATAPI command output ch_a, // ATAPI: 1 means device should send PIO setup FIS for ATAPI command output [4:0] ch_cfl, // length of the command FIS in DW, 0 means none. 0 and 1 - illegal, output [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) output reg [11:2] dwords_sent, // number of DWORDs transmitted (up to 2048) output reg [11:0] dwords_sent, // number of DWORDs transmitted (up to 2048) // register memory interface // register memory interface output reg [ADDRESS_BITS-1:0] reg_addr, output reg [ADDRESS_BITS-1:0] reg_addr, Loading Loading @@ -136,7 +138,7 @@ module ahci_fis_transmit #( reg acfis_xmit_busy_r; // reg acfis_xmit_busy_r; // // reg anc_fis_r; // This is ATAPI FIS, not Command FIS // reg anc_fis_r; // This is ATAPI FIS, not Command FIS wire acfis_xmit_start_w = (cfis_xmit || atapi_xmit || acfis_xmit_pend_r) && !dma_ct_busy && !fetch_cmd_busy; // dma_ct_busy no gaps with fetch_cmd_busy wire acfis_xmit_start_w = (cfis_xmit || atapi_xmit || acfis_xmit_pend_r) && !dma_ct_busy && !fetch_cmd_busy_r; // dma_ct_busy no gaps with fetch_cmd_busy wire acfis_xmit_end = ct_stb && fis_dw_last; wire acfis_xmit_end = ct_stb && fis_dw_last; wire ct_re_w; // next cycle will be ct_re; wire ct_re_w; // next cycle will be ct_re; Loading @@ -152,8 +154,10 @@ module ahci_fis_transmit #( reg dx_busy_r; reg dx_busy_r; reg [ 1:0] dx_err_r; reg [ 1:0] dx_err_r; wire any_cmd_start = fetch_cmd || cfis_xmit || dx_transmit || atapi_xmit; 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; // done on last transmit or error 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' reg fetch_cmd_busy_r; assign todev_valid = todev_full_r; assign todev_valid = todev_full_r; assign dma_re = dma_re_w; assign dma_re = dma_re_w; Loading Loading @@ -237,9 +241,9 @@ module ahci_fis_transmit #( else if (chead_done_w) pCmdToIssue_r <= 1; else if (chead_done_w) pCmdToIssue_r <= 1; else if (clearCmdToIssue) pCmdToIssue_r <= 0; else if (clearCmdToIssue) pCmdToIssue_r <= 0; if (hba_rst) fetch_cmd_busy <= 0; if (hba_rst) fetch_cmd_busy_r <= 0; else if (fetch_cmd) fetch_cmd_busy <= 1; else if (fetch_cmd) fetch_cmd_busy_r <= 1; else if (dma_start) fetch_cmd_busy <= 0; else if (dma_start) fetch_cmd_busy_r <= 0; //CFIS/ATAPI common //CFIS/ATAPI common Loading Loading @@ -280,7 +284,7 @@ module ahci_fis_transmit #( else if (dma_re_w) dx_dwords_left[11:2] <= dx_dwords_left[11:2] - 1; else if (dma_re_w) dx_dwords_left[11:2] <= dx_dwords_left[11:2] - 1; if (dx_transmit) dwords_sent <= 0; if (dx_transmit) dwords_sent <= 0; else if (dma_re_w) dwords_sent[11:2] <= dwords_sent[11:2] + 1; else if (dma_re_w) dwords_sent <= dwords_sent + 1; // send FIS header // send FIS header if (hba_rst || write_or_w) dx_fis_pend_r <= 0; if (hba_rst || write_or_w) dx_fis_pend_r <= 0; Loading
ahci/ahci_fsm.v +14 −7 Original line number Original line Diff line number Diff line Loading @@ -43,11 +43,19 @@ module ahci_fsm #( // direct communication with transposrt, link and phy layers // direct communication with transposrt, link and phy layers input phy_ready, // goes up after comreset,cominit, align, ... input phy_ready, // goes up after comreset,cominit, align, ... output syncesc_send, // Send sync escape // Other signals.... // Other signals.... // inputs from the DMA engine input dma_prd_done, // output (finished next prd) input dma_prd_irq, // output (finished next prd and prd irq is enabled) input dma_cmd_busy, // output reg (DMA engine is processing PRDs) input dma_cmd_done, // output (last PRD is over) // Communication with ahci_fis_receive (some are unused // Communication with ahci_fis_receive (some are unused input fis_first_vld, // fis_first contains valid FIS header, reset by get_* 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 // Receiving FIS output get_sig, // update signature output get_sig, // update signature output get_dsfis, output get_dsfis, Loading @@ -70,7 +78,7 @@ module ahci_fsm #( output set_sts_7f, // set PxTFD.STS = 0x7f, update output set_sts_7f, // set PxTFD.STS = 0x7f, update output set_sts_80, // set PxTFD.STS = 0x80 (may be combined with set_sts_7f), update output set_sts_80, // set PxTFD.STS = 0x80 (may be combined with set_sts_7f), update output decr_dwc, // decrement DMA Xfer counter // need pulse to 'update_prdbc' to write to registers output decr_dwc, // decrement DMA Xfer counter // need pulse to 'update_prdbc' to write to registers output [11:2] decr_DXC_dw, // decrement value (in DWORDs) output [11:0] decr_DXC_dw, // decrement value (in DWORDs) 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) Loading Loading @@ -99,9 +107,8 @@ module ahci_fsm #( output clearCmdToIssue, // From CFIS:SUCCESS output clearCmdToIssue, // From CFIS:SUCCESS input pCmdToIssue, // AHCI port variable input 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 dmaCntrZero, // DMA counter is zero - would be a duplicate to the one in receive module and dwords_sent output input fetch_cmd_busy, // does not include prefetching CT // input syncesc_recv, // These two inputs interrupt transmit output syncesc_recv, // These two inputs interrupt transmit // input xmit_err, // output 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) Loading @@ -113,7 +120,7 @@ module ahci_fsm #( 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:2] 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 Loading