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

continue to populate ahci_top

parent bec76787
Loading
Loading
Loading
Loading
+22 −22
Original line number Diff line number Diff line
@@ -82,9 +82,9 @@ module ahci_fis_receive#(
    output reg                    reg_we,
    output reg             [31:0] reg_data,        
    
    input                  [31:0] hda_data_in,         // FIFO output data
    input                  [ 1:0] hda_data_in_type,    // 0 - data, 1 - FIS head, 2 - R_OK, 3 - R_ERR
    input                         hba_data_in_avalid,  // Data available from the transport layer in FIFO                
    input                  [31:0] hba_data_in,         // FIFO output data
    input                  [ 1:0] hba_data_in_type,    // 0 - data, 1 - FIS head, 2 - R_OK, 3 - R_ERR
    input                         hba_data_in_valid,  // Data available from the transport layer in FIFO                
    input                         hba_data_in_many,    // Multiple DWORDs available from the transport layer in FIFO           
    output                        hba_data_in_ready,   // This module or DMA consumes DWORD

@@ -141,16 +141,16 @@ localparam DATA_TYPE_ERR = 3;
    reg [ADDRESS_BITS-1:0] reg_addr_r;
    reg           [3:0] fis_dcount; // number of DWORDS left to be written to the "memory"
    reg                 fis_save;   // save FIS data
    wire                fis_end = (hda_data_in_type == DATA_TYPE_OK) || (hda_data_in_type == DATA_TYPE_ERR);
    wire                fis_end = (hba_data_in_type == DATA_TYPE_OK) || (hba_data_in_type == DATA_TYPE_ERR);
    wire                fis_end_w = data_in_ready && fis_end & ~(|fis_end_r);
    reg           [1:0] fis_end_r;
     
    reg                 fis_rec_run; // running received FIS
    reg                 is_data_fis;
    
    wire                is_FIS_HEAD = data_in_ready && (hda_data_in_type == DATA_TYPE_FIS_HEAD);
    wire                is_FIS_HEAD = data_in_ready && (hba_data_in_type == DATA_TYPE_FIS_HEAD);
    
    wire                data_in_ready =  hba_data_in_avalid && (hba_data_in_many || !(|was_data_in || hba_data_in_ready) );
    wire                data_in_ready =  hba_data_in_valid && (hba_data_in_many || !(|was_data_in || hba_data_in_ready) );
    
    wire                get_fis = get_dsfis || get_psfis || get_rfis || get_sdbfis || get_ufis || get_data_fis ||  get_ignore;
    reg                 wreg_we_r; 
@@ -171,8 +171,8 @@ localparam DATA_TYPE_ERR = 3;
    reg                 update_prdbc_r;
    
    // Forward data to DMA (dev->mem) engine
    assign              dma_in_valid = dma_in_ready && (hda_data_in_type == DATA_TYPE_DMA) && data_in_ready && !too_long_err;
    assign              dma_in_stop = dma_in && data_in_ready && (hda_data_in_type != DATA_TYPE_DMA); // ||
    assign              dma_in_valid = dma_in_ready && (hba_data_in_type == DATA_TYPE_DMA) && data_in_ready && !too_long_err;
    assign              dma_in_stop = dma_in && data_in_ready && (hba_data_in_type != DATA_TYPE_DMA); // ||
    
    
    assign reg_we_w = wreg_we_r && !dwords_over && fis_save;
@@ -255,23 +255,23 @@ localparam DATA_TYPE_ERR = 3;
        else if (is_FIS_HEAD)                 fis_first_vld <= 1;
        
        if      (hba_rst || get_fis)          fis_ok <= 0;
        else if (fis_end_w)                   fis_ok <= hda_data_in_type == DATA_TYPE_OK;
        else if (fis_end_w)                   fis_ok <= hba_data_in_type == DATA_TYPE_OK;
        
        if      (hba_rst || get_fis)          fis_err <= 0;
        else if (fis_end_w)                   fis_err <= hda_data_in_type != DATA_TYPE_OK;
        else if (fis_end_w)                   fis_err <= hba_data_in_type != DATA_TYPE_OK;
        
        if (reg_we_w)                         reg_data[31:8] <= hda_data_in[31:8];
        else if (update_sig[1])               reg_data[31:8] <= hda_data_in[23:0];
        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_prdbc_r)              reg_data[31:8] <= {xfer_cntr_r[31:8]};

        if (reg_we_w)                         reg_data[ 7:0] <=  hda_data_in[ 7:0];
        else if (update_sig[3])               reg_data[ 7:0] <=  hda_data_in[ 7:0];
        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_prdbc_r)              reg_data[ 7:0] <=  {xfer_cntr_r[ 7:2],2'b0};
        
        if (reg_d2h || update_sig[0])         tf_err_sts  <= hda_data_in[15:0];
        else if (reg_sdb)                     tf_err_sts  <= {hda_data_in[15:8], tf_err_sts[7], hda_data_in[6:4], tf_err_sts[3],hda_data_in[2:0]};
        if (reg_d2h || update_sig[0])         tf_err_sts  <= hba_data_in[15:0];
        else if (reg_sdb)                     tf_err_sts  <= {hba_data_in[15:8], tf_err_sts[7], hba_data_in[6:4], tf_err_sts[3],hba_data_in[2:0]};
        else if (clear_bsy_drq || set_bsy)    tf_err_sts  <= tf_err_sts & {8'hff,clear_bsy_drq,3'h7,clear_bsy_drq,3'h7} | {8'h0,set_bsy,7'h0};
        else if (set_sts_7f || set_sts_80)    tf_err_sts  <= {tf_err_sts[15:8],set_sts_80,{7{set_sts_7f}}} ;
        
@@ -281,17 +281,17 @@ localparam DATA_TYPE_ERR = 3;
        else if (update_err_sts_r)            reg_addr <=  PXTFD_OFFS32;
        else if (update_prdbc_r)              reg_addr <=  CLB_OFFS32 + 1; // location of PRDBC

        if (reg_d2h || reg_sdb || reg_ds[0])  fis_i <=           hda_data_in[14];
        if (reg_sdb)                          sdb_n <=           hda_data_in[15];
        if (reg_ds[0])                        {dma_a,dma_d}  <=  {hda_data_in[15],hda_data_in[13]};
        if (reg_d2h || reg_sdb || reg_ds[0])  fis_i <=           hba_data_in[14];
        if (reg_sdb)                          sdb_n <=           hba_data_in[15];
        if (reg_ds[0])                        {dma_a,dma_d}  <=  {hba_data_in[15],hba_data_in[13]};

        if (reg_ps[0])                        {pio_i,pio_d}  <=  {hda_data_in[14],hda_data_in[13]};
        if (reg_ps[0])                        {pio_i,pio_d}  <=  {hba_data_in[14],hba_data_in[13]};
        
        if (hba_rst)                          pio_es  <=         0;
        else if (reg_ps[3])                   pio_es  <=         hda_data_in[31:24];
        else if (reg_ps[3])                   pio_es  <=         hba_data_in[31:24];
        
        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]?hda_data_in[31:16]:16'b0, hda_data_in[15:2]} + hda_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]};
        
        if (hba_rst || reg_sdb || reg_ps[4] || reg_ds[5])  prdbc_r[31:2] <= 0;
+8 −8
Original line number Diff line number Diff line
@@ -22,8 +22,8 @@

module  ahci_fis_transmit #(
    parameter PREFETCH_ALWAYS =   0,
    parameter READ_REG_LATENCY =  2, // 0 if  reg_rdata is available with reg_re/reg_addr
    parameter READ_CT_LATENCY =   2, // 0 if  reg_rdata is available with reg_re/reg_addr
    parameter READ_REG_LATENCY =  2, // 0 if  reg_rdata is available with reg_re/reg_addr, 2 with re/regen
    parameter READ_CT_LATENCY =   1, // 0 if  reg_rdata is available with reg_re/reg_addr, 2 with re/regen
    parameter ADDRESS_BITS =     10 // number of memory address bits - now fixed. Low half - RO/RW/RWC,RW1 (2-cycle write), 2-nd just RW (single-cycle)

)(
@@ -60,7 +60,7 @@ module ahci_fis_transmit #(
    
    // register memory interface
    output reg [ADDRESS_BITS-1:0] reg_addr,      
    output                        reg_re,
    output                 [ 1:0] reg_re,
    input                  [31:0] reg_rdata,

    // ahci_fis_receive interface
@@ -73,11 +73,11 @@ module ahci_fis_transmit #(
    input                         dma_ct_busy,   // dma module is busy reading command table from the system memory
    // issue dma_prd_start same time as dma_start if prefetch enabled, otherwise with cfis_xmit
    output reg                    dma_prd_start, // at or after cmd_start - enable reading PRD/data (if any) ch_prdtl should be valid, twice - OK
    output reg                    cmd_abort,   // try to abort a command TODO: Implement
    output reg                    dma_cmd_abort,   // try to abort a command TODO: Implement
    
    // reading out command table data from DMA module
    output reg             [ 4:0] ct_addr,     // DWORD address
    output                        ct_re,       //  
    output                 [ 1:0] ct_re,       // [0] - re, [1] - regen 
    input                  [31:0] ct_data,     // 
    
    // DMA (memory -> device) interface
@@ -157,7 +157,7 @@ module ahci_fis_transmit #(
    
    assign todev_valid = todev_full_r;
    assign dma_re =   dma_re_w;
    assign reg_re =   reg_re_r[0]; 
    assign reg_re =   reg_re_r[1:0]; 
    
    assign ch_prdtl = ch_prdtl_r;
    assign ch_c =     ch_c_r;
@@ -172,7 +172,7 @@ module ahci_fis_transmit #(
    assign dma_start =   fetch_chead_stb_r[3]; // next cycle after dma_ctba_ld 
    assign pCmdToIssue = pCmdToIssue_r;
//    assign dmaCntrZero = dmaCntrZero_r;
    assign ct_re =       ct_re_r[0];
    assign ct_re =       ct_re_r[1:0];
    assign fis_data_valid = ct_stb; // no wait write to output register 'todev_data', ct_re_r[0] is throttled according to FIFO room availability
    assign ct_re_w = todev_ready && ((cfis_acmd_left_r[4:1] != 0) || (cfis_acmd_left_r[0] && !ct_re_r[0]));  // Later add more sources
    assign fis_dw_last = (cfis_acmd_left_out_r == 1);
@@ -310,7 +310,7 @@ module ahci_fis_transmit #(
       else if (any_cmd_start)                busy <= 1;
       else if (done_w)                       busy <= 0;

       cmd_abort <= done_w && (|dx_err_r);
       dma_cmd_abort <= done_w && (|dx_err_r);


    end 
+197 −138
Original line number Diff line number Diff line
@@ -21,10 +21,17 @@
`timescale 1ns/1ps

module  ahci_top#(
    parameter PREFETCH_ALWAYS =   0,
    parameter READ_REG_LATENCY =  2, // 0 if  reg_rdata is available with reg_re/reg_addr, 2 with re/regen
    parameter READ_CT_LATENCY =   1, // 0 if  ct_rdata is available with reg_re/reg_addr, 2 with re/regen
    parameter ADDRESS_BITS =     10 // number of memory address bits - now fixed. Low half - RO/RW/RWC,RW1 (2-cycle write), 2-nd just RW (single-cycle)
)(
    input             aclk,    // clock - should be buffered
    input             arst,    // @aclk sync reset, active high
    input             mclk,    // SATA system clock (current 75MHz for SATA2)
    input             mrst,    // reset in mclk clock domain
    input             hclk,    // AXI HP interface clock for 64-bit DMA (current - 150MHz
    input             hrst,    // reset in hclk clock domain
// MAXIGP1   
// AXI Write Address
    input      [31:0] awaddr,  // AWADDR[31:0], input
@@ -114,7 +121,21 @@ module ahci_top#(
    // PL extra (non-AXI) signals
    input      [ 7:0] afi_rcount,
    input      [ 2:0] afi_racount,
    output            afi_rdissuecap1en
    output            afi_rdissuecap1en,
// Data/type FIFO, host -> device   
    // Data System memory or FIS -> device
    output      [31:0] h2d_data,     // 32-bit data from the system memory to HBA (dma data)
    output      [ 1:0] h2d_type,     // 0 - data, 1 - FIS head, 2 - FIS END (make FIS_Last?)
    output             h2d_valid,    // output register full
    input              h2d_ready,     // send FIFO has room for data (>= 8? dwords)
 
// Data/type FIFO, device -> host
    input       [31:0] d2h_data,         // FIFO output data
    input       [ 1:0] d2h_type,    // 0 - data, 1 - FIS head, 2 - R_OK, 3 - R_ERR
    input              d2h_valid,  // Data available from the transport layer in FIFO                
    input              d2h_many,    // Multiple DWORDs available from the transport layer in FIFO           
    output             d2h_ready   // This module or DMA consumes DWORD

    
);
// axi_ahci_regs signals:
@@ -125,16 +146,45 @@ module ahci_top#(
    wire                    soft_arst;        // reset SATA PHY not relying on SATA clock
                                                // TODO: Decode from {bram_addr, ahci_regs_di}, bram_wen_d
// 2. HBA R/W registers, use hba clock
    wire                    hba_clk;
    wire                    hba_rst;
    wire [ADDRESS_BITS-1:0] hba_addr;
    wire                    hba_we;
    wire              [1:0] hba_re; // [0] - re, [1] - regen
    wire             [31:0] hba_din;
    wire             [31:0] hba_dout;
    wire                    regs_we;
    wire              [1:0] regs_re; // [0] - re, [1] - regen
    wire [ADDRESS_BITS-1:0] regs_waddr;
    wire [ADDRESS_BITS-1:0] regs_raddr;
    wire             [31:0] regs_din;
    wire             [31:0] regs_dout;
    wire [ADDRESS_BITS-1:0] regs_addr = ({ADDRESS_BITS{regs_we}} & regs_waddr) | ({ADDRESS_BITS{regs_re[0]}} & regs_raddr);
    
//---------------------    

//    wire             [31:7] ctba; // input[31:7] 
    wire                    ctba_ld; // input
    wire             [15:0] prdtl; // input[15:0] 
    wire                    dev_wr; // input
    wire                    dma_cmd_start; // input
    wire                    dma_prd_start; // input
    wire                    dma_cmd_abort; // input
    wire             [ 3:0] axi_wr_cache_mode; // input[3:0] 
    wire             [ 3:0] axi_rd_cache_mode; // input[3:0] 
    wire                    set_axi_wr_cache_mode; // input
    wire                    set_axi_rd_cache_mode; // input
    wire                    dma_ct_busy; // output reg 
    wire             [ 4:0] dma_ct_addr; // input[4:0] 
    wire             [ 1:0] dma_ct_re; // input
    wire             [31:0] dma_ct_data; // output[31:0] reg 
    wire                    dma_prd_done; // output
    wire                    dma_prd_irq; // output
    wire                    dma_cmd_busy; // output reg 
    wire                    dma_cmd_done; // output
    wire             [31:0] dma_dout;    // output[31:0] 
    wire                    dma_dav; // output
    wire                    dma_re;      // input
    wire             [31:0] d2h_data;// input[31:0] 
    wire                    dma_in_ready; // output
    wire                    dma_we;      // input



    axi_ahci_regs #(
        .ADDRESS_BITS(10)
    ) axi_ahci_regs_i (
@@ -174,48 +224,57 @@ module ahci_top#(
        .soft_write_data  (soft_write_data), // output[31:0] 
        .soft_write_en    (soft_write_en),   // output
        .soft_arst        (soft_arst),       // output
        .hba_clk          (hba_clk),         // input
        .hba_clk          (mclk),         // input
        .hba_rst          (hba_rst),         // input
        .hba_addr         (hba_addr),        // input[9:0] 
        .hba_we           (hba_we),          // input
        .hba_re           (hba_re),          // input[1:0] 
        .hba_din          (hba_din),         // input[31:0] 
        .hba_dout         (hba_dout)         // output[31:0] 
        .hba_addr         (regs_addr),        // input[9:0] 
        .hba_we           (regs_we),          // input
        .hba_re           (regs_re),          // input[1:0] 
        .hba_din          (regs_din),         // input[31:0] 
        .hba_dout         (regs_dout)         // output[31:0] 
    );


    /* Instance template for module ahci_dma */
    ahci_dma ahci_dma_i (
        .mrst(), // input
        .hrst(), // input
        .mclk(), // input
        .hclk(), // input
        .ctba(), // input[31:7] 
        .ctba_ld(), // input
        .prdtl(), // input[15:0] 
        .dev_wr(), // input
        .cmd_start(), // input
        .prd_start(), // input
        .cmd_abort(), // input
        .axi_wr_cache_mode(), // input[3:0] 
        .axi_rd_cache_mode(), // input[3:0] 
        .set_axi_wr_cache_mode(), // input
        .set_axi_rd_cache_mode(), // input
        .ct_busy(), // output reg 
        .ct_addr(), // input[4:0] 
        .ct_re(), // input
        .ct_data(), // output[31:0] reg 
        .prd_done(), // output
        .prd_irq(), // output
        .cmd_busy(), // output reg 
        .cmd_done(), // output
        .sys_out(), // output[31:0] 
        .sys_dav(), // output
        .sys_re(), // input
        .sys_in(), // input[31:0] 
        .sys_nfull(), // output
        .sys_we(), // input
        .mrst                  (mrst), // input
        .hrst                  (hrst), // input
        .mclk                  (mclk), // input
        .hclk                  (hclk), // input
        .ctba                  (regs_dout[31:7]), // input[31:7] 
        .ctba_ld               (ctba_ld), // input
        .prdtl                 (prdtl), // input[15:0] 
        .dev_wr                (dev_wr), // input
        .cmd_start             (dma_cmd_start), // input
        .prd_start             (dma_prd_start), // input
        .cmd_abort             (dma_cmd_abort), // input
        .axi_wr_cache_mode     (axi_wr_cache_mode), // input[3:0] 
        .axi_rd_cache_mode     (axi_rd_cache_mode), // input[3:0] 
        .set_axi_wr_cache_mode (set_axi_wr_cache_mode), // input
        .set_axi_rd_cache_mode (set_axi_rd_cache_mode), // input
        .ct_busy               (dma_ct_busy), // output reg 
        .ct_addr               (dma_ct_addr), // input[4:0] 
        .ct_re                 (dma_ct_re[0]), // input
        .ct_data               (dma_ct_data), // output[31:0] reg 
        .prd_done              (dma_prd_done), // output
        .prd_irq               (dma_prd_irq), // output
        .cmd_busy              (dma_cmd_busy), // output reg 
        .cmd_done              (dma_cmd_done), // output
        .sys_out               (dma_dout),    // output[31:0] 
        .sys_dav               (dma_dav), // output
        .sys_re                (dma_re),      // input
        .sys_in                (d2h_data), // input[31:0] 
        .sys_nfull             (dma_in_ready), // output
        .sys_we                (dma_we),      // input
/*
    // xmit: DMA (memory -> device) interface
    input                  [31:0] dma_out,      // 32-bit data from the DMA module, HBA -> device port
    input                         dma_dav,      // at least one dword is ready to be read from DMA module
    output                        dma_re,       // read dword from DMA module to the output register
    // rcv: Forwarding data to the DMA engine
    input                         dma_in_ready,        // DMA engine ready to accept data
    output                        dma_in_valid         // Write data to DMA dev->memory channel


*/        
        .afi_awaddr        (afi_awaddr),        // output[31:0] 
        .afi_awvalid       (afi_awvalid),       // output
        .afi_awready       (afi_awready),       // input
@@ -263,10 +322,10 @@ module ahci_top#(
    );

    ahci_fis_receive #(
        .ADDRESS_BITS(10)
        .ADDRESS_BITS      (ADDRESS_BITS)
    ) ahci_fis_receive_i (
        .hba_rst(), // input
        .mclk(), // input
        .hba_rst           (hba_rst), // input
        .mclk              (mclk), // input
        .get_sig           (), // input
        .get_dsfis         (), // input
        .get_psfis         (), // input
@@ -299,26 +358,26 @@ module ahci_top#(
        .pio_es            (), // output[7:0] reg 
        .xfer_cntr         (), // output[31:2] 
        .xfer_cntr_zero    (), // output reg 
        .reg_addr(), // output[9:0] reg 
        .reg_we(), // output reg 
        .reg_data(), // output[31:0] reg 
        .hda_data_in(), // input[31:0] 
        .hda_data_in_type(), // input[1:0] 
        .hba_data_in_avalid(), // input
        .hba_data_in_many(), // input
        .hba_data_in_ready(), // output
        .reg_addr          (regs_waddr), // output[9:0] reg 
        .reg_we            (regs_we),    // output reg 
        .reg_data          (regs_din),   // output[31:0] reg 
        .hba_data_in       (d2h_data),   // input[31:0] 
        .hba_data_in_type  (d2h_type),   // input[1:0] 
        .hba_data_in_valid (d2h_valid),  // input
        .hba_data_in_many  (d2h_many),   // input
        .hba_data_in_ready (d2h_ready),  // output
        .dma_in_ready      (), // input
        .dma_in_valid      () // output
    );

    ahci_fis_transmit #(
        .PREFETCH_ALWAYS(0),
        .READ_REG_LATENCY(2),
        .READ_CT_LATENCY(2),
        .ADDRESS_BITS(10)
        .PREFETCH_ALWAYS  (PREFETCH_ALWAYS),
        .READ_REG_LATENCY (READ_REG_LATENCY),
        .READ_CT_LATENCY  (READ_CT_LATENCY),
        .ADDRESS_BITS     (ADDRESS_BITS)
    ) ahci_fis_transmit_i (
        .hba_rst(), // input
        .mclk(), // input
        .hba_rst           (hba_rst), // input
        .mclk              (mclk), // input
        .fetch_cmd         (), // input
        .cfis_xmit         (), // input
        .dx_transmit       (), // input
@@ -340,26 +399,26 @@ module ahci_top#(
        .ch_a              (), // output
        .ch_cfl            (), // output[4:0] 
        .dwords_sent       (), // output[11:2] reg 
        .reg_addr(), // output[9:0] reg 
        .reg_re(), // output
        .reg_rdata(), // input[31:0] 
        .reg_addr          (regs_raddr), // output[9:0] reg 
        .reg_re            (regs_re),    // output[1:0]
        .reg_rdata         (regs_dout),  // input[31:0] 
        .xfer_cntr         (), // input[31:2] 
        .dma_ctba_ld(), // output
        .dma_start(), // output
        .dma_ctba_ld       (ctba_ld), // output
        .dma_start         (dma_cmd_start), // output
        .dma_dev_wr        (), // output
        .dma_ct_busy       (), // input
        .dma_prd_start(), // output reg 
        .cmd_abort(), // output reg 
        .ct_addr(), // output[4:0] reg 
        .ct_re(), // output
        .dma_prd_start     (dma_prd_start), // output reg 
        .dma_cmd_abort     (dma_cmd_abort), // output reg 
        .ct_addr           (dma_ct_addr), // output[4:0] reg 
        .ct_re             (dma_ct_re), // output[1:0]
        .ct_data           (), // input[31:0] 
        .dma_out           (), // input[31:0] 
        .dma_dav           (), // input
        .dma_re            (), // output
        .todev_data(), // output[31:0] reg 
        .todev_type(), // output[1:0] reg 
        .todev_valid(), // output
        .todev_ready() // input
        .todev_data        (h2d_data),   // output[31:0] reg 
        .todev_type        (h2d_type),   // output[1:0] reg 
        .todev_valid       (h2d_valid),  // output
        .todev_ready       (h2d_ready)   // input
    );