Loading ahci/ahci_sata_layers.v +34 −4 Original line number Diff line number Diff line Loading @@ -24,7 +24,12 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> . */ `timescale 1ns/1ps //`define CHECK_LOW_H2D_FIFO // reduce actual h2d fifo size during simulation, to test h2d_ready /** TODO: 1. Check nothing is left in H2D FIFO after data is sent - it will happen after DPATp received. 2. Make DPATp an error? It is not easy to insert 0x00000046" data FIS header before remaining data (already in FIS) - it may also hold fis_transmit, as maximal data fis is 4x of the FIFO size. */ module ahci_sata_layers #( `ifdef USE_DATASCOPE parameter ADDRESS_BITS = 10, //for datascope Loading Loading @@ -105,6 +110,9 @@ module ahci_sata_layers #( output wire txn_out, input wire rxp_in, input wire rxn_in, output debug_is_data, // @clk (sata clk) - last symbol was data output output debug_dmatp, // @clk (sata clk) - received CODE_DMATP `ifdef USE_DATASCOPE // Datascope interface (write to memory that can be software-read) output datascope_clk, Loading Loading @@ -142,6 +150,13 @@ module ahci_sata_layers #( localparam H2D_TYPE_FIS_HEAD = 1; localparam H2D_TYPE_FIS_LAST = 2; `ifdef SIMULATION `ifdef CHECK_LOW_H2D_FIFO localparam H2D_FIFO_THRESHOLD = 4; // to test h2d_ready - will turn off frequently, much earlier than fifo almost full `endif `endif wire phy_ready; // active when GTX gets aligned output wire link_established; // Received 3 back-to-back non-ALIGNp wire [31:0] ll_h2d_data_in; Loading Loading @@ -186,7 +201,9 @@ module ahci_sata_layers #( wire [FIFO_ADDR_WIDTH:0] d2h_fill; wire d2h_nempty; wire h2d_fifo_rd = h2d_nempty && ll_strobe_out; // TODO: check latency in link.v wire h2d_fifo_wr = h2d_valid; // wire h2d_fifo_wr = h2d_valid; //2016.12.10 wire h2d_fifo_wr = h2d_valid && h2d_ready; // or should valid depend on ready in the fis_transmit? wire d2h_fifo_rd = d2h_valid && d2h_ready; wire d2h_fifo_wr = ll_d2h_valid || fis_over_r; // fis_over_r will push FIS end to FIFO Loading @@ -205,7 +222,18 @@ assign ll_h2d_last = (h2d_type_out == H2D_TYPE_FIS_LAST); assign d2h_valid = d2h_nempty; assign d2h_many = |d2h_fill[FIFO_ADDR_WIDTH:3]; // assign h2d_ready = !h2d_fill[FIFO_ADDR_WIDTH] && !(&h2d_fill[FIFO_ADDR_WIDTH:3]); // assign h2d_ready = !h2d_fill[FIFO_ADDR_WIDTH] && !(&h2d_fill[FIFO_ADDR_WIDTH:3]); // 2016:12:10 sometimes overflow happened because of a BUG `ifdef SIMULATION `ifdef CHECK_LOW_H2D_FIFO assign h2d_ready = !h2d_fill[FIFO_ADDR_WIDTH] && (h2d_fill < ((1 << BITS_TO_START_XMIT) + H2D_FIFO_THRESHOLD )); `else assign h2d_ready = !h2d_fill[FIFO_ADDR_WIDTH] && !(&h2d_fill[FIFO_ADDR_WIDTH-1:3]); // same as with synthesis `endif `else assign h2d_ready = !h2d_fill[FIFO_ADDR_WIDTH] && !(&h2d_fill[FIFO_ADDR_WIDTH-1:3]); `endif assign ll_d2h_almost_full = d2h_fill[FIFO_ADDR_WIDTH] || &d2h_fill[FIFO_ADDR_WIDTH-1:6]; // 63 dwords (maybe use :5?) - time to tell device to stop // assign ll_frame_req_w = !ll_frame_busy && h2d_pending && (((h2d_type == H2D_TYPE_FIS_LAST) && h2d_fifo_wr ) || (|h2d_fill[FIFO_ADDR_WIDTH : BITS_TO_START_XMIT])); Loading Loading @@ -318,6 +346,8 @@ assign debug_phy = debug_phy0; // to phy .phy_data_out (ll2ph_data_in), // output[31:0] wire .phy_isk_out (ll2ph_charisk_in), // output[3:0] wire // charisk .debug_is_data (debug_is_data), // output reg @clk (sata clk) - last symbol was data output .debug_dmatp (debug_dmatp), // output reg @clk (sata clk) - received CODE_DMATP .debug_out (debug_link) ); Loading ahci/ahci_top.v +103 −7 Original line number Diff line number Diff line Loading @@ -190,6 +190,8 @@ module ahci_top#( output irq, // CPU interrupt request input debug_link_send_data, // @posedge sata_clk - last symbol was data output (to count sent out) input debug_link_dmatp, // link received DMATp from device `ifdef USE_DATASCOPE // Datascope interface (write to memory that can be software-read) Loading Loading @@ -1204,6 +1206,7 @@ wire [9:0] xmit_dbg_01; .soft_write_addr (soft_write_addr), // input[9:0] .soft_write_data (soft_write_data), // input[31:0] .soft_write_en (soft_write_en), // input .cfis (fsnd_cfis_xmit), // input command FIS - to reset dword counter .h2d_data (h2d_data), // input[31:0] .h2d_type (h2d_type), // input[1:0] .h2d_valid (h2d_valid), // input Loading @@ -1212,6 +1215,8 @@ wire [9:0] xmit_dbg_01; .d2h_type (d2h_type), // input[1:0] .d2h_valid (d2h_valid), // input .d2h_ready (d2h_ready), // input .debug_link_send_data(debug_link_send_data), // input .debug_link_dmatp (debug_link_dmatp), // link received DMATp from device .datascope_clk (datascope_clk), // output .datascope_waddr (datascope_waddr), // output[9:0] reg .datascope_we (datascope_we), // output Loading Loading @@ -1327,6 +1332,8 @@ module datascope_timing #( input [31:0] soft_write_data, input soft_write_en, input cfis, // to reset send counter // outgoing FISes input [31:0] h2d_data, // 32-bit data from the system memory to HBA (dma data) input [ 1:0] h2d_type, // 0 - data, 1 - FIS head, 2 - FIS END (make FIS_Last?) Loading @@ -1341,6 +1348,8 @@ module datascope_timing #( input d2h_valid, // Data available from the transport layer in FIFO input d2h_ready, // This module or DMA consumes DWORD input debug_link_send_data, // @posedge mclk (sata_clk, 75MHz) - last symbol was data output (to count sent out) input debug_link_dmatp, // link received DMATp from device output datascope_clk, output reg [ADDRESS_BITS-1:0] datascope_waddr, output datascope_we, Loading @@ -1360,6 +1369,9 @@ module datascope_timing #( reg [31:0] fis_data; reg [27:0] cur_time; reg was_h2d_last; reg h2d_ready_d; // delayed h2d_ready to count 1->0 transitions reg [ 7:0] h2d_nready_cntr; // count (infrequent) events when h2d FIFO turns off ready // reg wire fis_start = (h2d_valid && h2d_ready && (h2d_type == 1)) || (d2h_valid && d2h_ready && (d2h_type == 1)); Loading @@ -1367,11 +1379,44 @@ module datascope_timing #( // wire fis_end_we = (fis_left == 0) || fis_end; wire pre_we_w = fis_run && (d2h_valid?(d2h_valid && d2h_ready):(h2d_valid && h2d_ready)); reg fis_run_d2; reg fis_run_d3; reg fis_run_d4; // to read non 0x39 d2h fis reg fis_run_d5; // number of dwords sent by link a s data symbols // reg fis_first; reg data_fis; reg pre_we_r; reg we_r; wire inc_dw_cntr = fis_run && (d2h_valid?(d2h_ready && (d2h_type == 0)):(h2d_valid && h2d_ready)); wire is_cfis_w = h2d_valid && (h2d_data[ 7: 0] == 8'h27) && // valid @ fis_start ((h2d_data[23:16] == 8'h25) || // Read DMA Extended (h2d_data[23:16] == 8'h35) || // Write DMA Extended (h2d_data[23:16] == 8'hC8) || // Read DMA (h2d_data[23:16] == 8'hCA)); // Write DMA reg is_cfis_r; reg [23:0] last_dma_cmd; reg set_dma_count; reg [21:0] dw_count; wire [7:0] fis_data_w = d2h_valid ? d2h_data[7:0] : h2d_data[7:0]; reg [31:0] non_dma_act; // last D2H FIS that was not DMA activate, received after DMA/IO command reg set_non_dma_act; reg [21:0] link_count; reg [21:0] link_count_latched; reg reset_link_count; // data FIS from dma command until reg was_link_dmatp; // // input debug_link_dmatp, // link received DMATp from device assign datascope_we = we_r; assign datascope_clk = clk; always @ (posedge clk) begin was_h2d_last <= h2d_type[1] && h2d_valid && h2d_ready; Loading @@ -1387,14 +1432,26 @@ module datascope_timing #( if (write_punch_time || fis_start) datascope_di <= {write_punch_time?{1'b1,punch_tag}:{3'b0,d2h_valid},cur_time}; else if (fis_we) datascope_di <= fis_data; else if (!fis_run && fis_run_d) datascope_di <= {19'h7fff8, fis_len}; else if (!fis_run_d && fis_run_d2) datascope_di <= {10'h2a8, dw_count}; else if (!fis_run_d2 && fis_run_d3) datascope_di <= {8'h55, last_dma_cmd}; else if (!fis_run_d3 && fis_run_d4) datascope_di <= non_dma_act; else if (!fis_run_d4 && fis_run_d5) datascope_di <= {h2d_nready_cntr[7:0], was_link_dmatp, 1'b0, link_count_latched}; pre_we_r <= pre_we_w || fis_start ; we_r <= write_punch_time || fis_start || (fis_we ? pre_we_r : (!fis_run && fis_run_d)); // we_r <= write_punch_time || fis_start || (fis_we ? pre_we_r : (!fis_run && fis_run_d)); we_r <= write_punch_time || fis_start || (fis_we ? pre_we_r : (!fis_run && (fis_run_d || fis_run_d2 || fis_run_d3 || fis_run_d4 || fis_run_d5))); // 3 after if (fis_start) fis_left <= FIS_LEN - 1; else if (pre_we_w) fis_left <= fis_left - 1; // if (fis_start) fis_first <= 1; // else if (pre_we_w) fis_first <= 0; if (fis_end) data_fis <= 0; // else if (pre_we_w && fis_start) data_fis <= fis_data_w == 8'h46; else if (fis_start) data_fis <= fis_data_w == 8'h46; if (rst) fis_we <= 0; else if (fis_start) fis_we <= 1; else if ((fis_left == 0) || fis_end) fis_we <= 0; Loading @@ -1404,6 +1461,45 @@ module datascope_timing #( else if (fis_end) fis_run <= 0; fis_run_d <= fis_run; fis_run_d2 <= fis_run_d; fis_run_d3 <= fis_run_d2; fis_run_d4 <= fis_run_d3; fis_run_d5 <= fis_run_d4; if (cfis) dw_count <= 0; else if (inc_dw_cntr && data_fis) dw_count <= dw_count + 1; if (rst) reset_link_count <= 0; else if (cfis) reset_link_count <= 1; else if (fis_start && (fis_data_w == 8'h46)) reset_link_count <= 0; if (reset_link_count) link_count <= 0; else if (debug_link_send_data) link_count <= link_count + 1; // will only be valid later, latch at next fis start if (fis_start) link_count_latched <= link_count; if (reset_link_count) was_link_dmatp <= 0; else if (debug_link_dmatp) was_link_dmatp <= 1; h2d_ready_d <= h2d_ready; if (rst) h2d_nready_cntr <= 0; else if (!h2d_ready && h2d_ready_d) h2d_nready_cntr <= h2d_nready_cntr+1; if (fis_start) is_cfis_r <= is_cfis_w; if (fis_start && is_cfis_w) last_dma_cmd[23:16] <= h2d_data[23:16]; // command code set_dma_count <= (fis_len == 3) && h2d_valid && h2d_ready && is_cfis_r; if (set_dma_count) last_dma_cmd[15:0] <= fis_data[15:0]; set_non_dma_act <= fis_start && d2h_valid && (fis_data_w != 8'h39); if (set_dma_count) non_dma_act <= 32'h33333333; else if (set_non_dma_act) non_dma_act <= fis_data; if (fis_start) fis_len <= d2h_valid? 0 : 1; else if (pre_we_w) fis_len <= fis_len + 1; Loading ahci/sata_ahci_top.v +8 −1 Original line number Diff line number Diff line Loading @@ -239,6 +239,8 @@ reg [2:0] nhrst_r; wire hrst = !nhrst_r[2]; wire debug_link_send_data; // @sata clk - last symbol was data output wire debug_link_dmatp; // @clk (sata clk) - received CODE_DMATP wire [FREQ_METER_WIDTH-1:0] xclk_period; `ifdef USE_DATASCOPE Loading Loading @@ -403,7 +405,8 @@ .sctl_ipm (sctl_ipm), // output[3:0] .sctl_spd (sctl_spd), // output[3:0] .irq (irq), // output .debug_link_send_data (debug_link_send_data), // input @posedge sata_clk - last symbol was data output (to count sent out) .debug_link_dmatp (debug_link_dmatp), // link received DMATp from device `ifdef USE_DATASCOPE .datascope1_clk (datascope_clk), // input .datascope1_waddr (datascope_waddr), // input[9:0] Loading Loading @@ -489,6 +492,10 @@ .txn_out (TXN), // output wire .rxp_in (RXP), // input wire .rxn_in (RXN), // input wire .debug_is_data (debug_link_send_data), //output @clk (sata clk) - last symbol was data output .debug_dmatp (debug_link_dmatp), // @clk (sata clk) - received CODE_DMATP `ifdef USE_DATASCOPE .datascope_clk (datascope_clk), // output .datascope_waddr (datascope_waddr), // output[9:0] Loading device/sata_device.v +6 −1 Original line number Diff line number Diff line Loading @@ -47,7 +47,8 @@ module sata_device( // reg [31:0] DEV_DATA; integer DEV_DATA; //`endif //`define TERMINATE_DMA_H2D //`undef TERMINATE_DMA_H2D wire phy_ready; wire [31:0] phy2dev_data; Loading Loading @@ -569,6 +570,10 @@ task linkMonitorFIS; cnt = cnt + 1; if (cnt <= 2048) pause = pause + receive_data_pause[cnt]; `ifdef TERMINATE_DMA_H2D linkSendPrim("DMAT"); `endif end end @ (posedge clk) Loading host/link.v +10 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,8 @@ module link #( // to phy output wire [DATA_BYTE_WIDTH*8 - 1:0] phy_data_out, output wire [DATA_BYTE_WIDTH - 1:0] phy_isk_out, // charisk output reg debug_is_data, // @clk (sata clk) - last symbol was data output output reg debug_dmatp, // @clk (sata clk) - received CODE_DMATP // debug output [31:0] debug_out // ); Loading Loading @@ -580,6 +582,10 @@ begin end endgenerate always @ (posedge clk) begin debug_dmatp <= rcvd_dword[CODE_DMATP]; end // select which primitive shall be sent wire [PRIM_NUM - 1:0] select_prim; assign select_prim[CODE_SYNCP] = ~alignes_pair & (state_idle | state_sync_esc | state_rcvr_wait | state_reset); Loading Loading @@ -618,6 +624,10 @@ always @ (posedge clk) {DATA_BYTE_WIDTH*8{select_prim[CODE_CRC]}} & prim_data[CODE_CRC] | {DATA_BYTE_WIDTH*8{select_prim[CODE_DATA]}} & prim_data[CODE_DATA]; always @ (posedge clk) debug_is_data <= select_prim[CODE_DATA]; always @ (posedge clk) to_phy_isk <= rst | ~select_prim[CODE_DATA] & ~select_prim[CODE_CRC] ? {{(DATA_BYTE_WIDTH - 1){1'b0}}, 1'b1} : {DATA_BYTE_WIDTH{1'b0}} ; Loading Loading
ahci/ahci_sata_layers.v +34 −4 Original line number Diff line number Diff line Loading @@ -24,7 +24,12 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> . */ `timescale 1ns/1ps //`define CHECK_LOW_H2D_FIFO // reduce actual h2d fifo size during simulation, to test h2d_ready /** TODO: 1. Check nothing is left in H2D FIFO after data is sent - it will happen after DPATp received. 2. Make DPATp an error? It is not easy to insert 0x00000046" data FIS header before remaining data (already in FIS) - it may also hold fis_transmit, as maximal data fis is 4x of the FIFO size. */ module ahci_sata_layers #( `ifdef USE_DATASCOPE parameter ADDRESS_BITS = 10, //for datascope Loading Loading @@ -105,6 +110,9 @@ module ahci_sata_layers #( output wire txn_out, input wire rxp_in, input wire rxn_in, output debug_is_data, // @clk (sata clk) - last symbol was data output output debug_dmatp, // @clk (sata clk) - received CODE_DMATP `ifdef USE_DATASCOPE // Datascope interface (write to memory that can be software-read) output datascope_clk, Loading Loading @@ -142,6 +150,13 @@ module ahci_sata_layers #( localparam H2D_TYPE_FIS_HEAD = 1; localparam H2D_TYPE_FIS_LAST = 2; `ifdef SIMULATION `ifdef CHECK_LOW_H2D_FIFO localparam H2D_FIFO_THRESHOLD = 4; // to test h2d_ready - will turn off frequently, much earlier than fifo almost full `endif `endif wire phy_ready; // active when GTX gets aligned output wire link_established; // Received 3 back-to-back non-ALIGNp wire [31:0] ll_h2d_data_in; Loading Loading @@ -186,7 +201,9 @@ module ahci_sata_layers #( wire [FIFO_ADDR_WIDTH:0] d2h_fill; wire d2h_nempty; wire h2d_fifo_rd = h2d_nempty && ll_strobe_out; // TODO: check latency in link.v wire h2d_fifo_wr = h2d_valid; // wire h2d_fifo_wr = h2d_valid; //2016.12.10 wire h2d_fifo_wr = h2d_valid && h2d_ready; // or should valid depend on ready in the fis_transmit? wire d2h_fifo_rd = d2h_valid && d2h_ready; wire d2h_fifo_wr = ll_d2h_valid || fis_over_r; // fis_over_r will push FIS end to FIFO Loading @@ -205,7 +222,18 @@ assign ll_h2d_last = (h2d_type_out == H2D_TYPE_FIS_LAST); assign d2h_valid = d2h_nempty; assign d2h_many = |d2h_fill[FIFO_ADDR_WIDTH:3]; // assign h2d_ready = !h2d_fill[FIFO_ADDR_WIDTH] && !(&h2d_fill[FIFO_ADDR_WIDTH:3]); // assign h2d_ready = !h2d_fill[FIFO_ADDR_WIDTH] && !(&h2d_fill[FIFO_ADDR_WIDTH:3]); // 2016:12:10 sometimes overflow happened because of a BUG `ifdef SIMULATION `ifdef CHECK_LOW_H2D_FIFO assign h2d_ready = !h2d_fill[FIFO_ADDR_WIDTH] && (h2d_fill < ((1 << BITS_TO_START_XMIT) + H2D_FIFO_THRESHOLD )); `else assign h2d_ready = !h2d_fill[FIFO_ADDR_WIDTH] && !(&h2d_fill[FIFO_ADDR_WIDTH-1:3]); // same as with synthesis `endif `else assign h2d_ready = !h2d_fill[FIFO_ADDR_WIDTH] && !(&h2d_fill[FIFO_ADDR_WIDTH-1:3]); `endif assign ll_d2h_almost_full = d2h_fill[FIFO_ADDR_WIDTH] || &d2h_fill[FIFO_ADDR_WIDTH-1:6]; // 63 dwords (maybe use :5?) - time to tell device to stop // assign ll_frame_req_w = !ll_frame_busy && h2d_pending && (((h2d_type == H2D_TYPE_FIS_LAST) && h2d_fifo_wr ) || (|h2d_fill[FIFO_ADDR_WIDTH : BITS_TO_START_XMIT])); Loading Loading @@ -318,6 +346,8 @@ assign debug_phy = debug_phy0; // to phy .phy_data_out (ll2ph_data_in), // output[31:0] wire .phy_isk_out (ll2ph_charisk_in), // output[3:0] wire // charisk .debug_is_data (debug_is_data), // output reg @clk (sata clk) - last symbol was data output .debug_dmatp (debug_dmatp), // output reg @clk (sata clk) - received CODE_DMATP .debug_out (debug_link) ); Loading
ahci/ahci_top.v +103 −7 Original line number Diff line number Diff line Loading @@ -190,6 +190,8 @@ module ahci_top#( output irq, // CPU interrupt request input debug_link_send_data, // @posedge sata_clk - last symbol was data output (to count sent out) input debug_link_dmatp, // link received DMATp from device `ifdef USE_DATASCOPE // Datascope interface (write to memory that can be software-read) Loading Loading @@ -1204,6 +1206,7 @@ wire [9:0] xmit_dbg_01; .soft_write_addr (soft_write_addr), // input[9:0] .soft_write_data (soft_write_data), // input[31:0] .soft_write_en (soft_write_en), // input .cfis (fsnd_cfis_xmit), // input command FIS - to reset dword counter .h2d_data (h2d_data), // input[31:0] .h2d_type (h2d_type), // input[1:0] .h2d_valid (h2d_valid), // input Loading @@ -1212,6 +1215,8 @@ wire [9:0] xmit_dbg_01; .d2h_type (d2h_type), // input[1:0] .d2h_valid (d2h_valid), // input .d2h_ready (d2h_ready), // input .debug_link_send_data(debug_link_send_data), // input .debug_link_dmatp (debug_link_dmatp), // link received DMATp from device .datascope_clk (datascope_clk), // output .datascope_waddr (datascope_waddr), // output[9:0] reg .datascope_we (datascope_we), // output Loading Loading @@ -1327,6 +1332,8 @@ module datascope_timing #( input [31:0] soft_write_data, input soft_write_en, input cfis, // to reset send counter // outgoing FISes input [31:0] h2d_data, // 32-bit data from the system memory to HBA (dma data) input [ 1:0] h2d_type, // 0 - data, 1 - FIS head, 2 - FIS END (make FIS_Last?) Loading @@ -1341,6 +1348,8 @@ module datascope_timing #( input d2h_valid, // Data available from the transport layer in FIFO input d2h_ready, // This module or DMA consumes DWORD input debug_link_send_data, // @posedge mclk (sata_clk, 75MHz) - last symbol was data output (to count sent out) input debug_link_dmatp, // link received DMATp from device output datascope_clk, output reg [ADDRESS_BITS-1:0] datascope_waddr, output datascope_we, Loading @@ -1360,6 +1369,9 @@ module datascope_timing #( reg [31:0] fis_data; reg [27:0] cur_time; reg was_h2d_last; reg h2d_ready_d; // delayed h2d_ready to count 1->0 transitions reg [ 7:0] h2d_nready_cntr; // count (infrequent) events when h2d FIFO turns off ready // reg wire fis_start = (h2d_valid && h2d_ready && (h2d_type == 1)) || (d2h_valid && d2h_ready && (d2h_type == 1)); Loading @@ -1367,11 +1379,44 @@ module datascope_timing #( // wire fis_end_we = (fis_left == 0) || fis_end; wire pre_we_w = fis_run && (d2h_valid?(d2h_valid && d2h_ready):(h2d_valid && h2d_ready)); reg fis_run_d2; reg fis_run_d3; reg fis_run_d4; // to read non 0x39 d2h fis reg fis_run_d5; // number of dwords sent by link a s data symbols // reg fis_first; reg data_fis; reg pre_we_r; reg we_r; wire inc_dw_cntr = fis_run && (d2h_valid?(d2h_ready && (d2h_type == 0)):(h2d_valid && h2d_ready)); wire is_cfis_w = h2d_valid && (h2d_data[ 7: 0] == 8'h27) && // valid @ fis_start ((h2d_data[23:16] == 8'h25) || // Read DMA Extended (h2d_data[23:16] == 8'h35) || // Write DMA Extended (h2d_data[23:16] == 8'hC8) || // Read DMA (h2d_data[23:16] == 8'hCA)); // Write DMA reg is_cfis_r; reg [23:0] last_dma_cmd; reg set_dma_count; reg [21:0] dw_count; wire [7:0] fis_data_w = d2h_valid ? d2h_data[7:0] : h2d_data[7:0]; reg [31:0] non_dma_act; // last D2H FIS that was not DMA activate, received after DMA/IO command reg set_non_dma_act; reg [21:0] link_count; reg [21:0] link_count_latched; reg reset_link_count; // data FIS from dma command until reg was_link_dmatp; // // input debug_link_dmatp, // link received DMATp from device assign datascope_we = we_r; assign datascope_clk = clk; always @ (posedge clk) begin was_h2d_last <= h2d_type[1] && h2d_valid && h2d_ready; Loading @@ -1387,14 +1432,26 @@ module datascope_timing #( if (write_punch_time || fis_start) datascope_di <= {write_punch_time?{1'b1,punch_tag}:{3'b0,d2h_valid},cur_time}; else if (fis_we) datascope_di <= fis_data; else if (!fis_run && fis_run_d) datascope_di <= {19'h7fff8, fis_len}; else if (!fis_run_d && fis_run_d2) datascope_di <= {10'h2a8, dw_count}; else if (!fis_run_d2 && fis_run_d3) datascope_di <= {8'h55, last_dma_cmd}; else if (!fis_run_d3 && fis_run_d4) datascope_di <= non_dma_act; else if (!fis_run_d4 && fis_run_d5) datascope_di <= {h2d_nready_cntr[7:0], was_link_dmatp, 1'b0, link_count_latched}; pre_we_r <= pre_we_w || fis_start ; we_r <= write_punch_time || fis_start || (fis_we ? pre_we_r : (!fis_run && fis_run_d)); // we_r <= write_punch_time || fis_start || (fis_we ? pre_we_r : (!fis_run && fis_run_d)); we_r <= write_punch_time || fis_start || (fis_we ? pre_we_r : (!fis_run && (fis_run_d || fis_run_d2 || fis_run_d3 || fis_run_d4 || fis_run_d5))); // 3 after if (fis_start) fis_left <= FIS_LEN - 1; else if (pre_we_w) fis_left <= fis_left - 1; // if (fis_start) fis_first <= 1; // else if (pre_we_w) fis_first <= 0; if (fis_end) data_fis <= 0; // else if (pre_we_w && fis_start) data_fis <= fis_data_w == 8'h46; else if (fis_start) data_fis <= fis_data_w == 8'h46; if (rst) fis_we <= 0; else if (fis_start) fis_we <= 1; else if ((fis_left == 0) || fis_end) fis_we <= 0; Loading @@ -1404,6 +1461,45 @@ module datascope_timing #( else if (fis_end) fis_run <= 0; fis_run_d <= fis_run; fis_run_d2 <= fis_run_d; fis_run_d3 <= fis_run_d2; fis_run_d4 <= fis_run_d3; fis_run_d5 <= fis_run_d4; if (cfis) dw_count <= 0; else if (inc_dw_cntr && data_fis) dw_count <= dw_count + 1; if (rst) reset_link_count <= 0; else if (cfis) reset_link_count <= 1; else if (fis_start && (fis_data_w == 8'h46)) reset_link_count <= 0; if (reset_link_count) link_count <= 0; else if (debug_link_send_data) link_count <= link_count + 1; // will only be valid later, latch at next fis start if (fis_start) link_count_latched <= link_count; if (reset_link_count) was_link_dmatp <= 0; else if (debug_link_dmatp) was_link_dmatp <= 1; h2d_ready_d <= h2d_ready; if (rst) h2d_nready_cntr <= 0; else if (!h2d_ready && h2d_ready_d) h2d_nready_cntr <= h2d_nready_cntr+1; if (fis_start) is_cfis_r <= is_cfis_w; if (fis_start && is_cfis_w) last_dma_cmd[23:16] <= h2d_data[23:16]; // command code set_dma_count <= (fis_len == 3) && h2d_valid && h2d_ready && is_cfis_r; if (set_dma_count) last_dma_cmd[15:0] <= fis_data[15:0]; set_non_dma_act <= fis_start && d2h_valid && (fis_data_w != 8'h39); if (set_dma_count) non_dma_act <= 32'h33333333; else if (set_non_dma_act) non_dma_act <= fis_data; if (fis_start) fis_len <= d2h_valid? 0 : 1; else if (pre_we_w) fis_len <= fis_len + 1; Loading
ahci/sata_ahci_top.v +8 −1 Original line number Diff line number Diff line Loading @@ -239,6 +239,8 @@ reg [2:0] nhrst_r; wire hrst = !nhrst_r[2]; wire debug_link_send_data; // @sata clk - last symbol was data output wire debug_link_dmatp; // @clk (sata clk) - received CODE_DMATP wire [FREQ_METER_WIDTH-1:0] xclk_period; `ifdef USE_DATASCOPE Loading Loading @@ -403,7 +405,8 @@ .sctl_ipm (sctl_ipm), // output[3:0] .sctl_spd (sctl_spd), // output[3:0] .irq (irq), // output .debug_link_send_data (debug_link_send_data), // input @posedge sata_clk - last symbol was data output (to count sent out) .debug_link_dmatp (debug_link_dmatp), // link received DMATp from device `ifdef USE_DATASCOPE .datascope1_clk (datascope_clk), // input .datascope1_waddr (datascope_waddr), // input[9:0] Loading Loading @@ -489,6 +492,10 @@ .txn_out (TXN), // output wire .rxp_in (RXP), // input wire .rxn_in (RXN), // input wire .debug_is_data (debug_link_send_data), //output @clk (sata clk) - last symbol was data output .debug_dmatp (debug_link_dmatp), // @clk (sata clk) - received CODE_DMATP `ifdef USE_DATASCOPE .datascope_clk (datascope_clk), // output .datascope_waddr (datascope_waddr), // output[9:0] Loading
device/sata_device.v +6 −1 Original line number Diff line number Diff line Loading @@ -47,7 +47,8 @@ module sata_device( // reg [31:0] DEV_DATA; integer DEV_DATA; //`endif //`define TERMINATE_DMA_H2D //`undef TERMINATE_DMA_H2D wire phy_ready; wire [31:0] phy2dev_data; Loading Loading @@ -569,6 +570,10 @@ task linkMonitorFIS; cnt = cnt + 1; if (cnt <= 2048) pause = pause + receive_data_pause[cnt]; `ifdef TERMINATE_DMA_H2D linkSendPrim("DMAT"); `endif end end @ (posedge clk) Loading
host/link.v +10 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,8 @@ module link #( // to phy output wire [DATA_BYTE_WIDTH*8 - 1:0] phy_data_out, output wire [DATA_BYTE_WIDTH - 1:0] phy_isk_out, // charisk output reg debug_is_data, // @clk (sata clk) - last symbol was data output output reg debug_dmatp, // @clk (sata clk) - received CODE_DMATP // debug output [31:0] debug_out // ); Loading Loading @@ -580,6 +582,10 @@ begin end endgenerate always @ (posedge clk) begin debug_dmatp <= rcvd_dword[CODE_DMATP]; end // select which primitive shall be sent wire [PRIM_NUM - 1:0] select_prim; assign select_prim[CODE_SYNCP] = ~alignes_pair & (state_idle | state_sync_esc | state_rcvr_wait | state_reset); Loading Loading @@ -618,6 +624,10 @@ always @ (posedge clk) {DATA_BYTE_WIDTH*8{select_prim[CODE_CRC]}} & prim_data[CODE_CRC] | {DATA_BYTE_WIDTH*8{select_prim[CODE_DATA]}} & prim_data[CODE_DATA]; always @ (posedge clk) debug_is_data <= select_prim[CODE_DATA]; always @ (posedge clk) to_phy_isk <= rst | ~select_prim[CODE_DATA] & ~select_prim[CODE_CRC] ? {{(DATA_BYTE_WIDTH - 1){1'b0}}, 1'b1} : {DATA_BYTE_WIDTH{1'b0}} ; Loading