Commit effd0f51 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

working on ahci_top.v, preparing for top fsm implementation

parent 3cbb9c90
Loading
Loading
Loading
Loading
+14 −10
Original line number Original line Diff line number Diff line
@@ -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?
    
    
@@ -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
@@ -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;
    
    
@@ -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;
@@ -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
@@ -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
+12 −8
Original line number Original line Diff line number Diff line
@@ -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)
@@ -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,      
@@ -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;
@@ -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;
@@ -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
       
       
@@ -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;
+14 −7
Original line number Original line Diff line number Diff line
@@ -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,
@@ -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)
@@ -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)
@@ -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