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
+240 −148

File changed.

Preview size limit exceeded, changes collapsed.

+33 −1
Original line number Original line Diff line number Diff line
@@ -97,7 +97,14 @@ module axi_ahci_regs#(
//   input               [3:0] hba_wstb, Needed?
//   input               [3:0] hba_wstb, Needed?
    input               [1:0] hba_re, // [0] - re, [1] - regen
    input               [1:0] hba_re, // [0] - re, [1] - regen
    input              [31:0] hba_din,
    input              [31:0] hba_din,
    output             [31:0] hba_dout
    output             [31:0] hba_dout,
    
//  other control signals
    output reg         [ 3:0] afi_wcache,
    output reg         [ 3:0] afi_rcache,
    output                    afi_cache_set
    
    
);
);


`include "includes/ahci_localparams.vh" // @SuppressThisWarning VEditor : Unused localparams
`include "includes/ahci_localparams.vh" // @SuppressThisWarning VEditor : Unused localparams
@@ -109,6 +116,14 @@ module axi_ahci_regs#(
    localparam HBA_PORT__PxSCTL__DET__ADDR = 'h4b;
    localparam HBA_PORT__PxSCTL__DET__ADDR = 'h4b;
    localparam HBA_PORT__PxSCTL__DET__MASK = 'hf;
    localparam HBA_PORT__PxSCTL__DET__MASK = 'hf;
    localparam HBA_PORT__PxSCTL__DET__DFLT = 'h0;
    localparam HBA_PORT__PxSCTL__DET__DFLT = 'h0;
// RW: SAXIHP write channel cache mode 
    localparam HBA_PORT__AFI_CACHE__WR_CM__ADDR = 'h5c;
    localparam HBA_PORT__AFI_CACHE__WR_CM__MASK = 'hf0;
    localparam HBA_PORT__AFI_CACHE__WR_CM__DFLT = 'h30;
// RW: SAXIHP read channel cache mode 
    localparam HBA_PORT__AFI_CACHE__RD_CM__ADDR = 'h5c;
    localparam HBA_PORT__AFI_CACHE__RD_CM__MASK = 'hf;
    localparam HBA_PORT__AFI_CACHE__RD_CM__DFLT = 'h3;
    
    
*/
*/
    wire   [ADDRESS_BITS-1:0] bram_waddr;
    wire   [ADDRESS_BITS-1:0] bram_waddr;
@@ -143,6 +158,8 @@ module axi_ahci_regs#(
    reg                      port_nrst_r;     // port _reset by software
    reg                      port_nrst_r;     // port _reset by software
    
    
    wire                   high_sel = bram_waddr_r[ADDRESS_BITS-1]; // high addresses - use single-cycle writes without read-modify-write
    wire                   high_sel = bram_waddr_r[ADDRESS_BITS-1]; // high addresses - use single-cycle writes without read-modify-write
    wire                   afi_cache_set_w = bram_wen_r && !high_sel && (bram_addr == HBA_PORT__AFI_CACHE__WR_CM__ADDR);
    
//    assign bram_addr = bram_ren[0] ? bram_raddr : (bram_wen ? bram_waddr : pre_awaddr);
//    assign bram_addr = bram_ren[0] ? bram_raddr : (bram_wen ? bram_waddr : pre_awaddr);
    assign bram_addr = bram_ren[0] ? bram_raddr : (bram_wen_r ? bram_waddr_r : bram_waddr);
    assign bram_addr = bram_ren[0] ? bram_raddr : (bram_wen_r ? bram_waddr_r : bram_waddr);
    assign hba_arst =  !hba_nrst_r;       // hba _reset (currently does ~ the same as port reset)
    assign hba_arst =  !hba_nrst_r;       // hba _reset (currently does ~ the same as port reset)
@@ -196,6 +213,11 @@ module axi_ahci_regs#(
                     port_nrst_r <= !ahci_regs_di[0]; // write "1" - reset on, write 0 - reset off
                     port_nrst_r <= !ahci_regs_di[0]; // write "1" - reset on, write 0 - reset off
    end
    end


    always @(posedge aclk) begin
        if      (arst)             {afi_wcache,afi_rcache}  <= 8'h33;
        else if (afi_cache_set_w)  {afi_wcache,afi_rcache}  <= ahci_regs_di[7:0];
    end    

/*
/*
Will generate async reset on both HBA reset(for some time) and port reset (until released) 
Will generate async reset on both HBA reset(for some time) and port reset (until released) 
until it is more clear about GTX reset options. Such reset will be applied to both PLL and GTX,
until it is more clear about GTX reset options. Such reset will be applied to both PLL and GTX,
@@ -364,6 +386,16 @@ sata_phy_rst_out will be released after the sata clock is stable
        .half_empty ()                                   // output
        .half_empty ()                                   // output
    );
    );


    pulse_cross_clock #(
        .EXTRA_DLY(0)
    ) afi_cache_set_i (
        .rst       (arst),             // input
        .src_clk   (aclk),             // input
        .dst_clk   (hba_clk),          // input
        .in_pulse  (afi_cache_set_w),  // input
        .out_pulse (afi_cache_set),    // output
        .busy()                        // output
    );




endmodule
endmodule
Loading