Loading ahci/ahci_fis_receive.v +22 −22 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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}}} ; Loading @@ -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; Loading ahci/ahci_fis_transmit.v +8 −8 Original line number Diff line number Diff line Loading @@ -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) )( Loading Loading @@ -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 Loading @@ -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 Loading Loading @@ -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; Loading @@ -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); Loading Loading @@ -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 Loading ahci/ahci_top.v +197 −138 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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: Loading @@ -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 ( Loading Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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 Loading @@ -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 ); Loading Loading
ahci/ahci_fis_receive.v +22 −22 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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}}} ; Loading @@ -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; Loading
ahci/ahci_fis_transmit.v +8 −8 Original line number Diff line number Diff line Loading @@ -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) )( Loading Loading @@ -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 Loading @@ -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 Loading Loading @@ -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; Loading @@ -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); Loading Loading @@ -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 Loading
ahci/ahci_top.v +197 −138 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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: Loading @@ -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 ( Loading Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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 Loading @@ -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 ); Loading