From 78da3183e06a1d5b32a3796977e6649ac1c5de36 Mon Sep 17 00:00:00 2001 From: Andrey Filippov Date: Sat, 13 Feb 2016 02:14:17 -0700 Subject: [PATCH] modifying RX input settings --- .project | 34 ++-- ahci/ahci_sata_layers.v | 31 +++- ahci/ahci_top.v | 21 ++- ahci/axi_ahci_regs.v | 37 ++++- ahci/sata_ahci_top.v | 33 +++- ahci_timing.xdc | 4 +- host/gtx_wrap.v | 80 ++++++++- host/link.v | 47 +++++- host/sata_phy.v | 46 +++++- py393sata/x393sata.py | 357 ++++++++++++++++++++++++++++++++++++++-- tb_ahci_01.sav | 61 ++++--- 11 files changed, 679 insertions(+), 72 deletions(-) diff --git a/.project b/.project index 63b8a1c..d184876 100644 --- a/.project +++ b/.project @@ -52,87 +52,87 @@ vivado_logs/VivadoBitstream.log 1 - /home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160211193930680.log + /home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160213012011614.log vivado_logs/VivadoOpt.log 1 - /home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160211193930680.log + /home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160213012011614.log vivado_logs/VivadoOptPhys.log 1 - /home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160211193930680.log + /home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160213012011614.log vivado_logs/VivadoOptPower.log 1 - /home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160211193930680.log + /home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160213012011614.log vivado_logs/VivadoPlace.log 1 - /home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160211193930680.log + /home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160213012011614.log vivado_logs/VivadoRoute.log 1 - /home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160211193930680.log + /home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160213012011614.log vivado_logs/VivadoSynthesis.log 1 - /home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160211193930680.log + /home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160213012011614.log vivado_logs/VivadoTimimgSummaryReportImplemented.log 1 - /home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160211193930680.log + /home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160213012011614.log vivado_logs/VivadoTimimgSummaryReportSynthesis.log 1 - /home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160211193930680.log + /home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160213012011614.log vivado_logs/VivadoTimingReportImplemented.log 1 - /home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160211193930680.log + /home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160213012011614.log vivado_logs/VivadoTimingReportSynthesis.log 1 - /home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160211193930680.log + /home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160213012011614.log vivado_state/x393_sata-opt-phys.dcp 1 - /home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-20160211193930680.dcp + /home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-20160213012011614.dcp vivado_state/x393_sata-opt-power.dcp 1 - /home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-20160211193930680.dcp + /home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-20160213012011614.dcp vivado_state/x393_sata-opt.dcp 1 - /home/andrey/git/x393_sata/vivado_state/x393_sata-opt-20160211193930680.dcp + /home/andrey/git/x393_sata/vivado_state/x393_sata-opt-20160213012011614.dcp vivado_state/x393_sata-place.dcp 1 - /home/andrey/git/x393_sata/vivado_state/x393_sata-place-20160211193930680.dcp + /home/andrey/git/x393_sata/vivado_state/x393_sata-place-20160213012011614.dcp vivado_state/x393_sata-route.dcp 1 - /home/andrey/git/x393_sata/vivado_state/x393_sata-route-20160211193930680.dcp + /home/andrey/git/x393_sata/vivado_state/x393_sata-route-20160213012011614.dcp vivado_state/x393_sata-synth.dcp 1 - /home/andrey/git/x393_sata/vivado_state/x393_sata-synth-20160211193930680.dcp + /home/andrey/git/x393_sata/vivado_state/x393_sata-synth-20160213012011614.dcp diff --git a/ahci/ahci_sata_layers.v b/ahci/ahci_sata_layers.v index 1259a52..78dbaa3 100644 --- a/ahci/ahci_sata_layers.v +++ b/ahci/ahci_sata_layers.v @@ -21,8 +21,13 @@ `timescale 1ns/1ps module ahci_sata_layers #( - parameter BITS_TO_START_XMIT = 6, // wait H2D FIFO to have 1 << BITS_TO_START_XMIT to start FIS transmission (or all FIS fits) - parameter DATA_BYTE_WIDTH = 4 +`ifdef USE_DATASCOPE + parameter ADDRESS_BITS = 10, //for datascope + parameter DATASCOPE_START_BIT = 14, // bit of DRP "other_control" to start recording after 0->1 (needs DRP) + parameter DATASCOPE_POST_MEAS = 16, // number of measurements to perform after event +`endif + parameter BITS_TO_START_XMIT = 6, // wait H2D FIFO to have 1 << BITS_TO_START_XMIT to start FIS transmission (or all FIS fits) + parameter DATA_BYTE_WIDTH = 4 )( input exrst, // master reset that resets PLL and GTX input reliable_clk, // use aclk that runs independently of the GTX @@ -91,6 +96,14 @@ module ahci_sata_layers #( output wire txn_out, input wire rxp_in, input wire rxn_in, +`ifdef USE_DATASCOPE +// Datascope interface (write to memory that can be software-read) + output datascope_clk, + output [ADDRESS_BITS-1:0] datascope_waddr, + output datascope_we, + output [31:0] datascope_di, +`endif + `ifdef USE_DRP input drp_rst, input drp_clk, @@ -320,6 +333,11 @@ module ahci_sata_layers #( sata_phy #( +`ifdef USE_DATASCOPE + .ADDRESS_BITS (ADDRESS_BITS), // for datascope + .DATASCOPE_START_BIT (DATASCOPE_START_BIT), + .DATASCOPE_POST_MEAS (DATASCOPE_POST_MEAS), +`endif .DATA_BYTE_WIDTH(4) ) phy ( .extrst (exrst), // input wire @@ -350,7 +368,14 @@ module ahci_sata_layers #( .cplllock_debug (), .usrpll_locked_debug(), .re_aligned (serr_DS), // output reg - + +`ifdef USE_DATASCOPE + .datascope_clk (datascope_clk), // output + .datascope_waddr (datascope_waddr), // output[9:0] + .datascope_we (datascope_we), // output + .datascope_di (datascope_di), // output[31:0] + .datascope_trig (ll_frame_ackn), // input datascope external trigger +`endif `ifdef USE_DRP .drp_rst (drp_rst), // input diff --git a/ahci/ahci_top.v b/ahci/ahci_top.v index 5e1b462..19ea859 100644 --- a/ahci/ahci_top.v +++ b/ahci/ahci_top.v @@ -182,6 +182,16 @@ module ahci_top#( output irq, // CPU interrupt request + +`ifdef USE_DATASCOPE +// Datascope interface (write to memory that can be software-read) + input datascope1_clk, + input [ADDRESS_BITS-1:0] datascope1_waddr, + input datascope1_we, + input [31:0] datascope1_di, +`endif + + `ifdef USE_DRP output drp_en, // @aclk strobes drp_ad output drp_we, @@ -715,7 +725,9 @@ module ahci_top#( .debug_in0 (debug_dma), // input[31:0] .debug_in1 (debug_dma1), // debug_in_link), // input[31:0] .debug_in2 (debug_in_phy), // input[31:0] // debug from phy/link - .debug_in3 ({22'b0, last_jump_addr[9:0]}) // input[31:0]// Last jump address in the AHDCI sequencer +// .debug_in3 ({22'b0, last_jump_addr[9:0]}) // input[31:0]// Last jump address in the AHDCI sequencer + .debug_in3 ({3'b0, debug_in_link[4:0], 14'b0,last_jump_addr[9:0]}) // input[31:0]// Last jump address in the AHDCI sequencer + `ifdef USE_DRP ,.drp_en (drp_en), // output reg .drp_we (drp_we), // output reg @@ -730,7 +742,12 @@ module ahci_top#( ,.datascope_clk (datascope_clk), // input .datascope_waddr (datascope_waddr), // input[9:0] .datascope_we (datascope_we), // input - .datascope_di (datascope_di) // input[31:0] + .datascope_di (datascope_di), // input[31:0] + + .datascope1_clk (datascope1_clk), // input + .datascope1_waddr (datascope1_waddr),// input[9:0] + .datascope1_we (datascope1_we), // input + .datascope1_di (datascope1_di) // input[31:0] `endif /// .debug_in (debug_in[31:0]) ); diff --git a/ahci/axi_ahci_regs.v b/ahci/axi_ahci_regs.v index 0c5ef4b..7ba6206 100644 --- a/ahci/axi_ahci_regs.v +++ b/ahci/axi_ahci_regs.v @@ -132,7 +132,12 @@ module axi_ahci_regs#( ,input datascope_clk, input [ADDRESS_BITS-1:0] datascope_waddr, input datascope_we, - input [31:0] datascope_di + input [31:0] datascope_di, + + input datascope1_clk, + input [ADDRESS_BITS-1:0] datascope1_waddr, + input datascope1_we, + input [31:0] datascope1_di `endif ); `ifdef USE_DRP @@ -142,11 +147,15 @@ module axi_ahci_regs#( reg drp_ready_r; `endif `ifdef USE_DATASCOPE - localparam AXIBRAM_BITS = ADDRESS_BITS + 1; // number of axi address outputs (one more than ADDRESS_BITS when using datascope) +// localparam AXIBRAM_BITS = ADDRESS_BITS + 1; // number of axi address outputs (one more than ADDRESS_BITS when using datascope) + localparam AXIBRAM_BITS = ADDRESS_BITS + 2; // number of axi address outputs (one more than ADDRESS_BITS when using datascope) wire [31:0] datascope_rdata; reg [1:0] datascope_sel; // read datascope memory instead of the registers + wire [31:0] datascope1_rdata; + reg [1:0] datascope1_sel; // read datascope memory instead of the registers always @ (posedge aclk) begin - datascope_sel <= {datascope_sel[0], bram_raddr[ADDRESS_BITS]}; + datascope_sel <= {datascope_sel[0], ~bram_raddr[ADDRESS_BITS+1] & bram_raddr[ADDRESS_BITS]}; + datascope1_sel <= {datascope1_sel[0], bram_raddr[ADDRESS_BITS+1] & ~bram_raddr[ADDRESS_BITS]}; end `else localparam AXIBRAM_BITS = ADDRESS_BITS; // number of axi address outputs (one more than ADDRESS_BITS when using datascope) @@ -433,7 +442,9 @@ sata_phy_rst_out will be released after the sata clock is stable .bram_ren (bram_ren[0]), // output .bram_regen (bram_ren[1]), // output `ifdef USE_DATASCOPE - .bram_rdata (datascope_sel[1] ? datascope_rdata : bram_rdata_r) // input[31:0] + .bram_rdata ((datascope_sel[1] | datascope1_sel[1]) ? + (datascope1_sel[1]? datascope1_rdata : datascope_rdata) : + bram_rdata_r) // input[31:0] `else .bram_rdata (bram_rdata_r) // input[31:0] `endif @@ -510,6 +521,24 @@ sata_phy_rst_out will be released after the sata clock is stable .web (8'hff), // input[7:0] .data_in (datascope_di) // input[31:0] ); + + ram_var_w_var_r #( + .REGISTERS (0), + .LOG2WIDTH_WR (5), + .LOG2WIDTH_RD (5), + .DUMMY(0) + ) datascope1_mem_i ( + .rclk (aclk), // input + .raddr (bram_raddr[9:0]), // input[9:0] + .ren (bram_ren[0]), // input + .regen (bram_ren[1]), // input + .data_out (datascope1_rdata), // output[31:0] + .wclk (datascope1_clk), // input + .waddr (datascope1_waddr), // input[9:0] + .we (datascope1_we), // input + .web (8'hff), // input[7:0] + .data_in (datascope1_di) // input[31:0] + ); `endif fifo_cross_clocks #( diff --git a/ahci/sata_ahci_top.v b/ahci/sata_ahci_top.v index 6df2132..58765a4 100644 --- a/ahci/sata_ahci_top.v +++ b/ahci/sata_ahci_top.v @@ -40,6 +40,11 @@ // 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) +`ifdef USE_DATASCOPE + parameter DATASCOPE_START_BIT = 14, // bit of DRP "other_control" to start recording after 0->1 (needs DRP) + parameter DATASCOPE_POST_MEAS = 256, // 16, // number of measurements to perform after event +`endif + parameter HBA_RESET_BITS = 9, // duration of HBA reset in aclk periods (9: ~10usec) parameter RESET_TO_FIRST_ACCESS = 1 // keep port reset until first R/W any register by software )( @@ -223,6 +228,13 @@ reg [2:0] nhrst_r; wire hrst = !nhrst_r[2]; +`ifdef USE_DATASCOPE +// Datascope interface (write to memory that can be software-read) + wire datascope_clk; + wire [ADDRESS_BITS-1:0] datascope_waddr; + wire datascope_we; + wire [31:0] datascope_di; +`endif `ifdef USE_DRP wire drp_en; @@ -376,6 +388,14 @@ .sctl_ipm (sctl_ipm), // output[3:0] .sctl_spd (sctl_spd), // output[3:0] .irq (irq), // output + +`ifdef USE_DATASCOPE + .datascope1_clk (datascope_clk), // input + .datascope1_waddr (datascope_waddr), // input[9:0] + .datascope1_we (datascope_we), // input + .datascope1_di (datascope_di), // input[31:0] +`endif + `ifdef USE_DRP .drp_en (drp_en), // output reg .drp_we (drp_we), // output reg @@ -389,7 +409,12 @@ ); ahci_sata_layers #( - .BITS_TO_START_XMIT(6), +`ifdef USE_DATASCOPE + .ADDRESS_BITS (ADDRESS_BITS), // for datascope + .DATASCOPE_START_BIT (DATASCOPE_START_BIT), // bit of DRP "other_control" to start recording after 0->1 (needs DRP) + .DATASCOPE_POST_MEAS (DATASCOPE_POST_MEAS), // number of measurements to perform after event +`endif + .BITS_TO_START_XMIT (6), .DATA_BYTE_WIDTH(4) ) ahci_sata_layers_i ( .exrst (exrst), // input @@ -444,6 +469,12 @@ .txn_out (TXN), // output wire .rxp_in (RXP), // input wire .rxn_in (RXN), // input wire +`ifdef USE_DATASCOPE + .datascope_clk (datascope_clk), // output + .datascope_waddr (datascope_waddr), // output[9:0] + .datascope_we (datascope_we), // output + .datascope_di (datascope_di), // output[31:0] +`endif `ifdef USE_DRP .drp_rst (arst), // input .drp_clk (ACLK), // input diff --git a/ahci_timing.xdc b/ahci_timing.xdc index 936792c..1f02cd8 100644 --- a/ahci_timing.xdc +++ b/ahci_timing.xdc @@ -9,7 +9,9 @@ create_clock -name gtrefclk -period 6.666 -waveform {0.000 3.333} [get_nets sata create_clock -name txoutclk -period 6.666 -waveform {0.000 3.333} [get_nets sata_top/ahci_sata_layers_i/phy/txoutclk] # recovered sata parallel clock -create_clock -name xclk -period 6.666 -waveform {0.000 3.333} [get_nets sata_top/ahci_sata_layers_i/phy/gtx_wrap/xclk] +##create_clock -name xclk -period 6.666 -waveform {0.000 3.333} [get_nets sata_top/ahci_sata_layers_i/phy/gtx_wrap/xclk] +create_clock -name xclk -period 6.666 -waveform {0.000 3.333} [get_nets sata_top/ahci_sata_layers_i/phy/gtx_wrap/xclk_gtx] +###sata_top/ahci_sata_layers_i/phy/gtx_wrap/xclk_gtx sata_top/ahci_sata_layers_i/phy/gtx_wrap/gtxe2_channel_wrapper/xclk_gtx # txoutclk -> userpll, which gives us 2 clocks: userclk (150MHz) and userclk2 (75MHz) . The second one is sata host clk ###create_generated_clock -name usrclk [get_nets sata_top/ahci_sata_layers_i/phy/CLK] diff --git a/host/gtx_wrap.v b/host/gtx_wrap.v index 3560155..9bb1bf9 100644 --- a/host/gtx_wrap.v +++ b/host/gtx_wrap.v @@ -38,6 +38,11 @@ // All computations have been done in assumption of GTX interface being 20 bits wide! //`include "system_defines.v" module gtx_wrap #( +`ifdef USE_DATASCOPE + parameter ADDRESS_BITS = 10, // for datascope + parameter DATASCOPE_START_BIT = 14, // bit of DRP "other_control" to start recording after 0->1 (needs DRP) + parameter DATASCOPE_POST_MEAS = 16, // number of measurements to perform after event +`endif parameter DATA_BYTE_WIDTH = 4, parameter TXPMARESET_TIME = 5'h1, parameter RXPMARESET_TIME = 5'h11, @@ -100,6 +105,15 @@ module gtx_wrap #( output wire dbg_rxdlysresetdone, output wire [1:0] txbufstatus +`ifdef USE_DATASCOPE +// Datascope interface (write to memory that can be software-read) + ,output datascope_clk, + output [ADDRESS_BITS-1:0] datascope_waddr, + output datascope_we, + output reg [31:0] datascope_di, + input datascope_trig // external trigger event for the datascope +`endif + `ifdef USE_DRP ,input drp_rst, input drp_clk, @@ -110,9 +124,12 @@ module gtx_wrap #( output drp_rdy, output [15:0] drp_do `endif + + ); + wire rxresetdone_gtx; wire txresetdone_gtx; reg wrap_rxreset_; @@ -389,8 +406,8 @@ wire RXDLYSRESET; // 6 (rxdlysreset), wire RXDLYBYPASS; // 7 (1'b0), // Andrey: p.243: "0: Uses the RX delay alignment circuit." wire RXDLYEN; // 8 (1'b0), wire RXDLYOVRDEN; // 9 (1'b0), -wire RXDDIEN; // 10 (1'b1), // Andrey: p.243: "Set high in RX buffer bypass mode" - +wire RXDDIEN; // 10 (1'b1), // Andrey: p.243: "Set high in RX buffer bypass mode" +wire RXLPMEN; // 11 (1'b0) 1 - enable LP, 0 - DXE `ifdef USE_DRP sipo_to_xclk_measure #( @@ -427,7 +444,7 @@ wire RXDDIEN; // 10 (1'b1), // Andrey: p.243: "Set high in RX assign RXDLYEN = other_control[ 8]; // 8 (1'b0), assign RXDLYOVRDEN = other_control[ 9]; // 9 (1'b0), assign RXDDIEN = other_control[10]; // 10 (1'b1), // Andrey: p.243: "Set high in RX buffer bypass mode" - + assign RXLPMEN = other_control[11]; // 11 (1'b0) 1 - enable LP, 0 - DXE `else reg [19:0] rxdata_comma_in_r; assign rxdata_comma_in = rxdata_comma_in_r; @@ -474,6 +491,7 @@ wire RXDDIEN; // 10 (1'b1), // Andrey: p.243: "Set high in RX `else assign RXDDIEN = 1'b0; // 10 (1'b1), // Andrey: p.243: "Set high in RX buffer bypass mode" `endif + assign RXLPMEN = 1'b0; // 11 (1'b0) 1 - enable LP, 0 - DXE `endif // aligner status generation // if we detected comma & there was 1st realign after non-aligned state -> triggered, we wait until the next comma @@ -866,7 +884,8 @@ gtxe2_channel_wrapper #( .PMA_RSV4 (32'h00000000), .RX_BIAS_CFG (12'b000000000100), .DMONITOR_CFG (24'h000A00), - .RX_CM_SEL (2'b11), +// .RX_CM_SEL (2'b11), + .RX_CM_SEL (2'b00), // Andrey .RX_CM_TRIM (3'b010), .RX_DEBUG_CFG (12'b000000000000), .RX_OS_CFG (13'b0000010000000), @@ -1162,7 +1181,7 @@ gtxe2_channel_wrapper( .RXOOBRESET (1'b0), .RXPCSRESET (1'b0), .RXPMARESET (1'b0),//rxreset), // p78 - .RXLPMEN (1'b0), + .RXLPMEN (RXLPMEN), // 1'b0), .RXCOMSASDET (), .RXCOMWAKEDET (rxcomwakedet_gtx), .RXCOMINITDET (rxcominitdet_gtx), @@ -1252,6 +1271,57 @@ gtxe2_channel_wrapper( .TXQPISENP () ); + +`ifdef USE_DATASCOPE + reg [ADDRESS_BITS - 1:0 ] datascope_post_cntr; + reg [ADDRESS_BITS - 1:0 ] datascope_waddr_r; + reg [2:0] datascope_start_r; + wire datascope_event; + reg datascope_event_r; + reg datascope_run; + reg datascope_post_run; + wire datascope_start_w = other_control[DATASCOPE_START_BIT]; // datascope requires USE_DRP to be defined + wire datascope_stop = (DATASCOPE_POST_MEAS == 0) ? datascope_event: (datascope_post_cntr == 0); + reg [2:0] datascope_trig_r; + assign datascope_waddr = datascope_waddr_r; + assign datascope_we = datascope_run; + assign datascope_clk = xclk; + assign datascope_event = (|rxnotintable_dec_out) || (|rxdisperr_dec_out) || realign || (datascope_trig_r[1] && !datascope_trig_r[2]) ; + + + always @ (posedge xclk) begin + datascope_trig_r <= {datascope_trig_r[1:0], datascope_trig}; + + datascope_start_r <= {datascope_start_r[1:0],datascope_start_w}; + + datascope_event_r <=datascope_event; + + if (!datascope_start_r[1]) datascope_run <= 0; + else if (!datascope_start_r[2]) datascope_run <= 1; + else if (datascope_stop) datascope_run <= 0; + + if (!datascope_run) datascope_post_run <= 0; + else if (datascope_event_r) datascope_post_run <= 1; + + if (!datascope_post_run) datascope_post_cntr <= DATASCOPE_POST_MEAS; + else datascope_post_cntr <= datascope_post_cntr - 1; + + if (!datascope_start_r[1] && datascope_start_r[0]) datascope_waddr_r <= 0; // for simulator + else if (datascope_run) datascope_waddr_r <= datascope_waddr_r + 1; + + if (datascope_start_r[1]) datascope_di <= { + 6'b0, + realign, // 25 + comma, // 24 + 1'b0, // 23 + state_aligned, // 22 + rxnotintable_dec_out[1:0], // 21:20 + rxdisperr_dec_out[1:0], // 19:18 + rxcharisk_dec_out[1:0], // 17:16 + rxdata_dec_out[15:0]}; // 15: 0 + end +`endif + always @ (posedge gtrefclk) debug <= ~rxelecidle | debug; diff --git a/host/link.v b/host/link.v index 86fc607..73fb06a 100644 --- a/host/link.v +++ b/host/link.v @@ -728,7 +728,7 @@ assign rcvd_dword0[CODE_OKP] = phy_isk_in_r0[0] && !(|phy_isk_in_r0[DATA_BYT assign rcvd_dword0[CODE_ERRP] = phy_isk_in_r0[0] && !(|phy_isk_in_r0[DATA_BYTE_WIDTH-1:1]) && (prim_data[CODE_ERRP ] == phy_data_in_r0); assign rcvd_dword0[CODE_CONTP] = phy_isk_in_r0[0] && !(|phy_isk_in_r0[DATA_BYTE_WIDTH-1:1]) && (prim_data[CODE_CONTP ] == phy_data_in_r0); -reg [PRIM_NUM - 1:0] debug_rcvd_dword; // at least oce received after reset +reg [PRIM_NUM - 1:0] debug_rcvd_dword; // at least once received after reset //reg [7:0] debug_alignp_cntr; ///reg [7:0] debug_unknown_primitives; ///reg [7:0] debug_notaligned_primitives; @@ -751,7 +751,6 @@ reg [15:0] debug_num_other; // other primitives - not aligh, sync or cont reg [31:0] debug_unknown_dword; wire debug_is_sync_p_w = phy_isk_in_r0[0] && !(|phy_isk_in_r[DATA_BYTE_WIDTH-1:1]) && (prim_data[CODE_SYNCP ] == phy_data_in_r0); - wire [STATES_COUNT - 1:0] debug_states_concat = { state_idle , state_sync_esc @@ -777,6 +776,8 @@ wire [STATES_COUNT - 1:0] debug_states_concat = { , state_rcvr_goodend , state_rcvr_badend }; +reg [4:0] debug_states_encoded; + reg [STATES_COUNT - 1:0] debug_states_visited; always @ (posedge clk) begin @@ -825,6 +826,16 @@ always @ (posedge clk) begin if (rst) debug_states_visited <= 0; else debug_states_visited <= debug_states_visited | debug_states_concat; + + debug_states_encoded <= { |debug_states_concat[22:16], + |debug_states_concat[15: 8], + (|debug_states_concat[22:20]) | (|debug_states_concat[15:12]) | (|debug_states_concat[7:4]), + debug_states_concat[22] | (|debug_states_concat[19:18]) | (|debug_states_concat[15:14]) | + (|debug_states_concat[11:10]) | (|debug_states_concat[7:6]) | (|debug_states_concat[3:2]), + debug_states_concat[21] | debug_states_concat[19] | debug_states_concat[17] | debug_states_concat[15] | + debug_states_concat[13] | debug_states_concat[11] | debug_states_concat[ 9] | debug_states_concat[7] | + debug_states_concat[ 5] | debug_states_concat[ 3] | debug_states_concat[ 1]}; + /* if (rst) debug_rcvd_dword <= 0; debug_alignp_r <= rcvd_dword[CODE_ALIGNP]; @@ -851,6 +862,35 @@ always @ (posedge clk) begin else if (debug_state_reset_r == 1) debug_notaligned_primitives <= debug_notaligned_primitives + 1; */ end + +/*wire state_idle; +reg state_sync_esc; // SyncEscape +reg state_nocommerr; // NoComErr +reg state_nocomm; // NoComm +reg state_align; // SendAlign - not used, handled by OOB +reg state_reset; // RESET +// tranmitter branch +reg state_send_rdy; // SendChkRdy +reg state_send_sof; // SendSOF +reg state_send_data; // SendData +reg state_send_rhold; // RcvrHold - hold initiated by current data reciever +reg state_send_shold; // SendHold - hold initiated by current data sender +reg state_send_crc; // SendCVC +reg state_send_eof; // SendEOF +reg state_wait; // Wait +// receiver branch +reg state_rcvr_wait; // RcvWaitFifo +reg state_rcvr_rdy; // RcvChkRdy +reg state_rcvr_data; // RcvData +reg state_rcvr_rhold; // Hold - hold initiated by current data reciever +reg state_rcvr_shold; // RcvHold - hold initiated by current data sender +reg state_rcvr_eof; // RcvEOF +reg state_rcvr_goodcrc; // GoodCRC +reg state_rcvr_goodend; // GoodEnd +reg state_rcvr_badend; // BadEnd +*/ + + ///assign debug_out[19: 0] = debug_to_first_err; //assign debug_out[23:16] = debug_num_aligns; //assign debug_out[31:20] = debug_num_syncs[11:0]; @@ -858,7 +898,8 @@ end ///assign debug_out[31:20] = debug_num_other[11:0]; ///assign debug_out = debug_unknown_dword; // first unknown dword -assign debug_out[15: 0] = debug_to_first_err[19:4]; +assign debug_out[ 4: 0] = debug_states_encoded; +assign debug_out[15: 5] = debug_to_first_err[14:4]; assign debug_out[31:16] = debug_rcvd_dword; diff --git a/host/sata_phy.v b/host/sata_phy.v index c845735..7a760e3 100644 --- a/host/sata_phy.v +++ b/host/sata_phy.v @@ -34,6 +34,11 @@ //`include "oob_ctrl.v" //`include "gtx_wrap.v" module sata_phy #( +`ifdef USE_DATASCOPE + parameter ADDRESS_BITS = 10, //for datascope + parameter DATASCOPE_START_BIT = 14, // bit of DRP "other_control" to start recording after 0->1 (needs DRP) + parameter DATASCOPE_POST_MEAS = 16, // number of measurements to perform after event +`endif parameter DATA_BYTE_WIDTH = 4 ) ( @@ -84,6 +89,16 @@ module sata_phy #( output usrpll_locked_debug, output re_aligned, // re-aligned after alignment loss +`ifdef USE_DATASCOPE +// Datascope interface (write to memory that can be software-read) + output datascope_clk, + output [ADDRESS_BITS-1:0] datascope_waddr, + output datascope_we, + output [31:0] datascope_di, + input datascope_trig, // external trigger event for the datascope + +`endif + `ifdef USE_DRP input drp_rst, input drp_clk, @@ -462,6 +477,11 @@ ext_clock_buf( ); gtx_wrap #( +`ifdef USE_DATASCOPE + .ADDRESS_BITS (ADDRESS_BITS), // for datascope + .DATASCOPE_START_BIT (DATASCOPE_START_BIT), + .DATASCOPE_POST_MEAS (DATASCOPE_POST_MEAS), +`endif .DATA_BYTE_WIDTH (DATA_BYTE_WIDTH), .TXPMARESET_TIME (TXPMARESET_TIME), .RXPMARESET_TIME (RXPMARESET_TIME), @@ -518,6 +538,14 @@ gtx_wrap .dbg_rxcdrlock (dbg_rxcdrlock) , .dbg_rxdlysresetdone(dbg_rxdlysresetdone), .txbufstatus (txbufstatus[1:0]) +`ifdef USE_DATASCOPE + ,.datascope_clk (datascope_clk), // output + .datascope_waddr (datascope_waddr), // output[9:0] + .datascope_we (datascope_we), // output + .datascope_di (datascope_di), // output[31:0] + .datascope_trig (datascope_trig) // inpuit // external trigger event for the datascope +`endif + `ifdef USE_DRP ,.drp_rst (drp_rst), // input .drp_clk (drp_clk), // input @@ -594,8 +622,13 @@ reg dbg_clk_align_wait; //reg dbg_rxphaligndone_down; //reg dbg_rxphaligndone_second; - +reg [11:0] error_count; always @ (posedge clk) begin +// if (!phy_ready) error_count <= 0; + if (rxelecidle) error_count <= 0; + else if (phy_ready && (|ll_err_out)) error_count <= error_count + 1; + + if (rxelecidle || clk_phase_align_ack) dbg_clk_align_wait <= 0; else if (clk_phase_align_req) dbg_clk_align_wait <= 1; @@ -636,9 +669,14 @@ assign debug_sata[23:20] = debug_cntr4; //assign phy_ready = link_state & gtx_ready & rxbyteisaligned; //assign debug_sata = {debug_cntr6,debug_cntr5}; //assign debug_sata = {8'b0, dbg_clk_align_cntr, 1'b0, dbg_rxdlysresetdone, rxelecidle, dbg_rxcdrlock, rxelsfull, rxelsempty, dbg_rxphaligndone, dbg_rx_clocks_aligned}; -assign debug_sata = {8'b0, dbg_clk_align_cntr, txbufstatus[1:0], rxelecidle, dbg_rxcdrlock, rxelsfull, rxelsempty, dbg_rxphaligndone, dbg_rx_clocks_aligned}; - - +`ifdef USE_DATASCOPE + assign debug_sata = {txbufstatus[1:0], rxelecidle, dbg_rxcdrlock, rxelsfull, rxelsempty, dbg_rxphaligndone, dbg_rx_clocks_aligned, + error_count, + 2'b0, + datascope_waddr}; +`else + assign debug_sata = {8'b0, dbg_clk_align_cntr, txbufstatus[1:0], rxelecidle, dbg_rxcdrlock, rxelsfull, rxelsempty, dbg_rxphaligndone, dbg_rx_clocks_aligned}; +`endif endmodule diff --git a/py393sata/x393sata.py b/py393sata/x393sata.py index ee305af..c041848 100644 --- a/py393sata/x393sata.py +++ b/py393sata/x393sata.py @@ -63,6 +63,7 @@ COMMAND_BUFFER_SIZE = 0x100 # 256 bytes - 128 before PRDT, 128+ - PRDTs (16 PRD_OFFSET = 0x80 # Start of the PRD table FB_OFFS = 0xc00 # Needs 0x100 bytes DRP_OFFS = 0xfec # Read/Write DRP data [31] - write/ready, [30:16] - address/0, [15:0] - data to/data from +DBG_OFFS = 0xff0 # and 3 next DWORDS DATAIN_BUFFER_OFFSET = 0x10000 DATAIN_BUFFER_SIZE = 0x10000 IDENTIFY_BUF = 0 # Identify receive buffer offset in DATAIN_BUFFER, in bytes @@ -85,6 +86,13 @@ DRP_TIMER_ADDR = 0x208 # write timer value (how long to count early/late) DRP_EARLY_ADDR = 0x209 # write timer value (how long to count early/late) DRP_LATE_ADDR = 0x20a # write timer value (how long to count early/late) DRP_OTHERCTRL_ADDR = 0x20b # Now bit 0 - disable wait for phase align +DRP_RXDLY_CFG = 0x55 +DRP_LOGGER_BIT = 14 # bit number (in DRP_OTHERCTRL_ADDR) to control last-before-error data logger + +DATASCOPE0_OFFS = 0x1000 # start of the datascope0 relative to MAXI1_ADDR +DATASCOPE0_SIZE = 0x1000 # datascope0 size in bytes +DATASCOPE1_OFFS = 0x2000 # start of the datascope1 relative to MAXI1_ADDR +DATASCOPE1_SIZE = 0x1000 # datascope0 size in bytes #FIS types @@ -457,6 +465,8 @@ class x393sata(object): @param do_not_start - do not actually launch the command by writing 1 to command_issue (CI) bit in PxCI register @param prd_irqs - None or a tuple/list with per-PRD interrupts """ + # Clear interrupt register + self.x393_mem.write_mem(self.get_reg_address('HBA_PORT__PxIS'), 0xffffffff) # clear system memory for the command for a in range(64): self.x393_mem.write_mem(COMMAND_ADDRESS + 4*a, 0) @@ -513,7 +523,22 @@ class x393sata(object): self.x393_mem.write_mem(self.get_reg_address('HBA_PORT__PxCI'), 1) print("Command table data:") print("_=mem.mem_dump (0x%x, 0x10,4)"%(COMMAND_ADDRESS)) - self.x393_mem.mem_dump (COMMAND_ADDRESS, 0x20,4) + self.x393_mem.mem_dump (COMMAND_ADDRESS, 0x20,4) + #Wait interrupt + for r in range(10): + istat = self.x393_mem.read_mem(self.get_reg_address('HBA_PORT__PxIS')) + if istat: + self.parse_register(group_range = ['HBA_PORT__PxIS'], + skip0 = True, + dword = None) + break + sleep(0.1) + else: + print ("Failed to get interrupt") + self.reg_status() + print("_=mem.mem_dump (0x%x, 0x4,4)"%(MAXI1_ADDR + DBG_OFFS)) + self.x393_mem.mem_dump (MAXI1_ADDR + DBG_OFFS, 0x4,4) + raise Exception("Failed to get interrupt") print("Datascope (debug) data:") print("_=mem.mem_dump (0x%x, 0x20,4)"%(DATASCOPE_ADDR)) self.x393_mem.mem_dump (DATASCOPE_ADDR, 0x20,4) @@ -533,6 +558,8 @@ class x393sata(object): raise ValueError ("This program supports only 24-bit LBA") if count > 256: raise ValueError ("This program supports only 8 bit count") + # Clear interrupt register + self.x393_mem.write_mem(self.get_reg_address('HBA_PORT__PxIS'), 0xffffffff) # clear system memory for the command for a in range(64): self.x393_mem.write_mem(COMMAND_ADDRESS + 4*a, 0) @@ -579,16 +606,30 @@ class x393sata(object): print("mem.write_mem(sata.get_reg_address('HBA_PORT__PxCI'), 1)") else: self.x393_mem.write_mem(self.get_reg_address('HBA_PORT__PxCI'), 1) - print("Command table data:") + print("Command table data:") print("_=mem.mem_dump (0x%x, 0x10,4)"%(COMMAND_ADDRESS)) self.x393_mem.mem_dump (COMMAND_ADDRESS, 0x20,4) + #Wait interrupt + for r in range(10): + istat = self.x393_mem.read_mem(self.get_reg_address('HBA_PORT__PxIS')) + if istat: + self.parse_register(group_range = ['HBA_PORT__PxIS'], + skip0 = True, + dword = None) + break + sleep(0.1) + else: + print ("Failed to get interrupt") + self.reg_status() + print("_=mem.mem_dump (0x%x, 0x4,4)"%(MAXI1_ADDR + DBG_OFFS)) + self.x393_mem.mem_dump (MAXI1_ADDR + DBG_OFFS, 0x4,4) + raise Exception("Failed to get interrupt") print("Datascope (debug) data:") print("_=mem.mem_dump (0x%x, 0x20,4)"%(DATASCOPE_ADDR)) - self.x393_mem.mem_dump (DATASCOPE_ADDR, 0x20,4) + self.x393_mem.mem_dump (DATASCOPE_ADDR, 0xa0,4) print("Memory read data:") print("_=mem.mem_dump (0x%x, 0x%x, 1)"%(DATAIN_ADDRESS, count * 0x200)) self.x393_mem.mem_dump (DATAIN_ADDRESS, count * 0x200, 1) - def dd_write_dma(self, skip, count = 1, use_read_buffer = False, do_not_start = False, prd_irqs = None): #TODO: Add multi-PRD testing """ Write device from memory, use single PRD table @@ -598,6 +639,8 @@ class x393sata(object): @param do_not_start - do not actually launch the command by writing 1 to command_issue (CI) bit in PxCI register @param prd_irqs - None or a tuple/list with per-PRD interrupts """ + # Clear interrupt register + self.x393_mem.write_mem(self.get_reg_address('HBA_PORT__PxIS'), 0xffffffff) if skip > (1 << 24): raise ValueError ("This program supports only 24-bit LBA") if count > 256: @@ -651,7 +694,23 @@ class x393sata(object): self.x393_mem.write_mem(self.get_reg_address('HBA_PORT__PxCI'), 1) print("Command table data:") print("_=mem.mem_dump (0x%x, 0x10,4)"%(COMMAND_ADDRESS)) - self.x393_mem.mem_dump (COMMAND_ADDRESS, 0x20,4) + self.x393_mem.mem_dump (COMMAND_ADDRESS, 0x20,4) + #Wait interrupt + for r in range(10): + istat = self.x393_mem.read_mem(self.get_reg_address('HBA_PORT__PxIS')) + if istat: + self.parse_register(group_range = ['HBA_PORT__PxIS'], + skip0 = True, + dword = None) + break + sleep(0.1) + else: + print ("Failed to get interrupt") + self.reg_status() + print("_=mem.mem_dump (0x%x, 0x4,4)"%(MAXI1_ADDR + DBG_OFFS)) + self.x393_mem.mem_dump (MAXI1_ADDR + DBG_OFFS, 0x4,4) + raise Exception("Failed to get interrupt") + print("Datascope (debug) data:") print("_=mem.mem_dump (0x%x, 0x20,4)"%(DATASCOPE_ADDR)) self.x393_mem.mem_dump (DATASCOPE_ADDR, 0x20,4) @@ -697,7 +756,216 @@ class x393sata(object): new_val = 0 self.drp_write (DRP_OTHERCTRL_ADDR, ((old_val ^ new_val) & mask) ^ old_val) + def err_count (self): + return (self.x393_mem.read_mem(MAXI1_ADDR + DBG_OFFS + (2 << 2)) >> 12) & 0xfff + + def err_rate(self, dly = 0.1): + ec0 = self.err_count() + sleep(dly) + ec1 = self.err_count() + if ec1 < ec0: + ec1 += 1 << 12 + return 1.0 * (ec1 - ec0) /dly + def set_rxdly (self,rxdly): + self.drp (DRP_RXDLY_CFG, (rxdly << 6) | 0x1f) # 0x1f - default value in other bits + + def scan_rxdly(self, dly = 0.1, low = 0, high = 511, verbose = None): + if verbose is None: + verbose = self.DEBUG_MODE + rslt = [] + for rxdly in range (low, high+1): + self.set_rxdly(rxdly) + er = self.err_rate(dly) + if verbose: + print ("dly = 0x%x -> %f err/s"%(rxdly, er)) + rslt.append(er) + return rslt + + def arm_logger(self): + d = self.drp(DRP_OTHERCTRL_ADDR); + d &= ~(1 << DRP_LOGGER_BIT) + self.drp(DRP_OTHERCTRL_ADDR, d & (~(1 << DRP_LOGGER_BIT))) + self.drp(DRP_OTHERCTRL_ADDR, d | ( 1 << DRP_LOGGER_BIT)) + + def stop_logger(self): # stop at will (w/o error), address pointer will be valid + d = self.drp(DRP_OTHERCTRL_ADDR); + d &= ~(1 << DRP_LOGGER_BIT) + self.drp(DRP_OTHERCTRL_ADDR, d & (~(1 << DRP_LOGGER_BIT))) + + def get_datascope1_poiner(self): + return (self.x393_mem.read_mem(MAXI1_ADDR + DBG_OFFS + (2 << 2)) >> 0) & ((DATASCOPE1_SIZE >> 2)-1) + + def read_datascope1(self): + offs = self.get_datascope1_poiner() + rslt = [] + for i in range (DATASCOPE1_SIZE >> 2): # in dwords + a = (offs + i) & ((DATASCOPE1_SIZE >> 2)-1) + rslt.append(self.x393_mem.read_mem(MAXI1_ADDR + DATASCOPE1_OFFS + (a << 2))) + return rslt + + def replace_p(self,dword,prev_dword, next_dword = None): + primitives = ((" ALIGNp ",0x7b4a4abc), + (" CONTp ",0x9999aa7c), + (" DMATp ",0x3636b57c), + (" EOFp ",0xd5d5b57c), + (" HOLDp ",0xd5d5aa7c), + (" HOLDAp ",0x9595aa7c), + (" PMACKp ",0x9595957c), + (" PMNAKp ",0xf5f5957c), + ("PMREQ_Pp",0x1717b57c), + ("PMREQ_Sp",0x7575957c), + (" R_ERRp ",0x5656b57c), + (" R_IPp ",0x5555b57c), + (" R_OKp ",0x3535b57c), + (" R_RDYp ",0x4a4a957c), + (" SOFp ",0x3131b57c), + (" SYNCp ",0xb5b5957c), + (" WTRMp ",0x5858b57c), + (" X_RDYp ",0x5757b57c)) + k2 = (dword >> 16) & 0x3 + d = dword & 0xffff + try: + k2_next = (next_dword >> 16) & 0x3 + d_next = next_dword & 0xffff + except: + k2_next = 3 + if k2 == 1: + for pair in primitives: + if d == (pair[1] & 0xffff): + print ("d = 0x%x, d_next = 0x%x, k2 = %d, k2_next = %d"%(d,d_next,k2,k2_next)) + if (k2_next == 3) or ((d_next == ((pair[1] >> 16) & 0xffff))): + return pair[0].replace('p','l') + elif k2==0: + if prev_dword: # None - OK + k2_prev = (prev_dword >> 16) & 0x3 + d_prev = prev_dword & 0xffff + print ("d = 0x%x, d_prev = 0x%x, k2 = %d, k2_prev = %d"%(d,d_prev,k2,k2_prev)) + if k2_prev == 1: + for pair in primitives: + print ("%s: %x<->%x %x<->%x"%(pair[0],d_prev,(pair[1] & 0xffff), d, (pair[1] >> 16) & 0xffff)) + if (d_prev == (pair[1] & 0xffff)) and ((d == ((pair[1] >> 16) & 0xffff))): + return pair[0].replace('p','h') + return None + + + def interpret_datascope1_dword(self, dword, prev_dword = None, next_dword = None): + + def replace_p(dword,prev_dword, next_dword = None): + primitives = ((" ALIGNp ",0x7b4a4abc), + (" CONTp ",0x9999aa7c), + (" DMATp ",0x3636b57c), + (" EOFp ",0xd5d5b57c), + (" HOLDp ",0xd5d5aa7c), + (" HOLDAp ",0x9595aa7c), + (" PMACKp ",0x9595957c), + (" PMNAKp ",0xf5f5957c), + ("PMREQ_Pp",0x1717b57c), + ("PMREQ_Sp",0x7575957c), + (" R_ERRp ",0x5656b57c), + (" R_IPp ",0x5555b57c), + (" R_OKp ",0x3535b57c), + (" R_RDYp ",0x4a4a957c), + (" SOFp ",0x3131b57c), + (" SYNCp ",0xb5b5957c), + (" WTRMp ",0x5858b57c), + (" X_RDYp ",0x5757b57c)) + k2 = (dword >> 16) & 0x3 + d = dword & 0xffff + try: + k2_next = (next_dword >> 16) & 0x3 + d_next = next_dword & 0xffff + except: + k2_next = 3 + d_next = -1 + if k2 == 1: + for pair in primitives: + if d == (pair[1] & 0xffff): + if (k2_next == 3) or ((d_next == ((pair[1] >> 16) & 0xffff))): + return pair[0].replace('p','l') + elif k2==0: + if prev_dword: # None - OK + k2_prev = (prev_dword >> 16) & 0x3 + d_prev = prev_dword & 0xffff + if k2_prev == 1: + for pair in primitives: + if (d_prev == (pair[1] & 0xffff)) and ((d == ((pair[1] >> 16) & 0xffff))): + return pair[0].replace('p','h') + return None + + b = ((dword >> 0) & 0xff, (dword >> 8) & 0xff) + k = ((dword >> 16) & 0x1, (dword >> 17) & 0x1) + d = ((dword >> 18) & 0x1, (dword >> 19) & 0x1) + t = ((dword >> 18) & 0x1, (dword >> 19) & 0x1) + aligned = (dword >> 22) & 0x1 + comma = (dword >> 24) & 0x1 + realign = (dword >> 25) & 0x1 + decor = [] + for nb in range(2): + if k[nb]: + if d[nb]: + if t[nb]: + decor.append("==") + else: + decor.append("**") + else: + if t[nb]: + decor.append("{}") + else: + decor.append("[]") + else: + if d[nb]: + if t[nb]: + decor.append("!!") + else: + decor.append("++") + else: + if t[nb]: + decor.append("()") + else: + decor.append("__") + rslt = " R"[realign]+" C"[comma]+"N "[aligned] + p = replace_p(dword, prev_dword, next_dword) + if p: + return rslt+"%8s"%(p) + else: + return rslt+decor[1][0]+"%02x"%(b[1])+decor[1][1]+decor[0][0]+"%02x"%(b[0])+decor[0][1] + + def datascope1(self, n = 0x400): + data = self.read_datascope1() + prev_dword = None + n >>= 3 + if not n: + n = 1 + for i in range(-n,0): + ha = (8 *i) & ((DATASCOPE1_SIZE >> 2)-1) + print("0x%03x:"%(ha),end="") + for j in range(8): + dword = data[8 * i + j] +# if (8 * i + j) < 0: + next_dword = data[8 * i + j +1] +# else: +# next_dword = None + print(" %s"%(self.interpret_datascope1_dword(dword,prev_dword,next_dword)),end="") + prev_dword = dword + print() + + """ + +sata.drp (0x20b,0x221), sata.drp (0x20b,0x4221) + +DRP_RXDLY_CFG +for i in range(0,0x4000,0x40): + sata.drp (0x55,i+0x1f) +# sata.drp (0x20b,0x1) +# sata.drp (0x20b,0x221) + print("0x%x: "%(i),end="") +# _=mem.mem_dump (0x80000ff0, 4,4) + _=mem.mem_dump (0x80000ff0, 4,4) + +(mem.read_mem(MAXI1_ADDR + DBG_OFFS + (2 << 2)) >> 12) & 0xfff +(mem.read_mem(0x80000ff8) >> 12) & 0xfff + ATA_IDFY = 0xec # Identify command ATA_WDMA = 0xca # Write to device in DMA mode ATA_WBUF_PIO = 0xe8 # Write 512 bytes to device buffer in PIO mode @@ -732,6 +1000,14 @@ sata.read_sipo_meas(0xfffff,0x7ffe) _=mem.mem_dump (0x80000ff0, 4,4) hex(sata.drp_read(0x55)) +_=sata.scan_rxdly(0.1,0x00,0x00) # set good +_=sata.scan_rxdly(0.1,0x80,0x80) # set bad +_=sata.scan_rxdly() # scan all with measurement time 0.1 +_=sata.scan_rxdly(0.1, 0, 255) # scan half (full range is 2 periods) with measurement time 0.1 + + +reload (x393sata) +sata = x393sata.x393sata() cd /mnt/mmc/local/bin python @@ -744,20 +1020,47 @@ sata = x393sata.x393sata() sata.bitstream() #sata.drp_write (0x20b,0x401) # bypass, clock align -sata.drp (0x20b,0x81) # bypass, clock align +sata.drp (0x20b,0x221) # bypass, clock align + + +hex(sata.drp (0x20b)) #sata.drp (0x20b,0x400) # bypass, clock align sata.drp (0x59,0x8) # Use RXREC #sata.drp (0x59,0x48) sata.reg_status() sata.reg_status() _=mem.mem_dump (0x80000ff0, 4,4) +sata.reg_status(),sata.reset_ie(),sata.err_count() + +sata.arm_logger() +sata.setup_pio_read_identify_command() + +sata.datascope1() + -sata.reg_status(),sata.reset_ie() sata.dd_read_dma(0x5ff, 1) _=mem.mem_dump (0x80000ff0, 4,4) _=mem.mem_dump (0x80001000, 0x100,4) -sata.reg_status(),sata.reset_ie() +sata.reg_status(),sata.reset_ie(),sata.err_count() + +/// .RXCDR_CFG (72'h03_0000_23ff_1020_0020),// 1.6G - 6.25G, No SS, RXOUT_DIV=2 + .RXCDR_CFG (72'h03_8800_8BFF_4020_0008),// http://www.xilinx.com/support/answers/53364.html - SATA-2, div=2 + + +>>> sata.drp(0xa9) +16416 +>>> hex(sata.drp(0xa8)) +'0x8' +>>> hex(sata.drp(0xa9)) +'0x4020' +>>> hex(sata.drp(0xaa)) +'0x8bff' +>>> hex(sata.drp(0xab)) +'0x8800' +>>> hex(sata.drp(0xac)) +'0x3' + for block in range (1,255): @@ -766,10 +1069,27 @@ for block in range (1,255): _=mem.mem_dump (0x80001000, 0x100,4) sata.reg_status(),sata.reset_ie() +for block in range (1,255): + sata.dd_read_dma(block, 1) + _=mem.mem_dump (0x80000ff0, 4,4) + _=mem.mem_dump (0x80001000, 0x100,4) + sata.reg_status(),sata.reset_ie(),sata.err_count() + + + +#sata.drp (0x20b,0x81), sata.drp (0x20b,0x4081) +sata.drp (0x20b,0x221), sata.drp (0x20b,0x4221) + +_=mem.mem_dump (0x80000ff0, 4,4) +_=mem.mem_dump (0x80002000, 0x400,4) + mem.write_mem(0x80000118,0x10) + + + 06b: 00104 # CFIS:Xmit: do SET_BSY 06c: 30060 # do CFIS_XMIT, WAIT DONE 06d: 19039 # if X_RDY_COLLISION goto P:Idle @@ -777,9 +1097,24 @@ mem.write_mem(0x80000118,0x10) 06f: 0a471 # if FIS_OK goto CFIS:Success 070: 00102 # always goto ERR:Non-Fatal - - - +0x201 - OK, 0x021 - out of sync +0xa1 does not seem to change anything + +for i in range(0,0x800,0x40): + sata.drp (0xa1,i) + sata.drp (0x20b,0x1) + sata.drp (0x20b,0x221) + print("0x%x: "%(i),end="") + _=mem.mem_dump (0x80000ff0, 4,4) + _=mem.mem_dump (0x80000ff0, 4,4) + +for i in range(0,0x4000,0x40): + sata.drp (0x55,i+0x1f) +# sata.drp (0x20b,0x1) +# sata.drp (0x20b,0x221) + print("0x%x: "%(i),end="") +# _=mem.mem_dump (0x80000ff0, 4,4) + _=mem.mem_dump (0x80000ff0, 4,4) diff --git a/tb_ahci_01.sav b/tb_ahci_01.sav index fcd9bc5..74dbdea 100644 --- a/tb_ahci_01.sav +++ b/tb_ahci_01.sav @@ -1,15 +1,15 @@ [*] [*] GTKWave Analyzer v3.3.66 (w)1999-2015 BSI -[*] Fri Feb 12 00:55:27 2016 +[*] Sat Feb 13 07:29:00 2016 [*] -[dumpfile] "/home/andrey/git/x393_sata/simulation/tb_ahci-20160211173556344.fst" -[dumpfile_mtime] "Fri Feb 12 00:37:07 2016" -[dumpfile_size] 6893125 +[dumpfile] "/home/andrey/git/x393_sata/simulation/tb_ahci-20160211141748402.fst" +[dumpfile_mtime] "Thu Feb 11 21:19:18 2016" +[dumpfile_size] 10518459 [savefile] "/home/andrey/git/x393_sata/tb_ahci_01.sav" -[timestart] 852330 +[timestart] 51557500 [size] 1823 1180 [pos] 0 0 -*-12.814444 869500 29549854 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +*-16.563877 51888300 29549854 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 [treeopen] tb_ahci. [treeopen] tb_ahci.axi_read_addr. [treeopen] tb_ahci.dev.linkMonitorFIS. @@ -31,7 +31,6 @@ [treeopen] tb_ahci.dut.sata_top.ahci_sata_layers_i.phy. [treeopen] tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap. [treeopen] tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.genblk1. -[treeopen] tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtxe2_channel_wrapper. [treeopen] tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtxe2_channel_wrapper.gtx_gpl. [treeopen] tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtxe2_channel_wrapper.gtx_gpl.channel. [treeopen] tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtxe2_channel_wrapper.gtx_gpl.channel.rx. @@ -60,8 +59,8 @@ [treeopen] tb_ahci.simul_axi_hp_wr_i.waddr_i. [treeopen] tb_ahci.simul_axi_hp_wr_i.wdata_i. [treeopen] tb_ahci.simul_axi_read_i. -[sst_width] 417 -[signals_width] 409 +[sst_width] 296 +[signals_width] 313 [sst_expanded] 1 [sst_vpaned_height] 573 @820 @@ -966,7 +965,7 @@ tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtxe2_channel_wrapper.gtx_g -drp @1401200 -axi_ahci_regs -@c00200 +@c00201 -ahci_fsm @28 tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.dma_abort_done @@ -1233,7 +1232,7 @@ tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.async_pend_r[1:0] @28 tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.async_ackn tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.async_from_st -@1401200 +@1401201 -ahci_fsm @c00200 -ahci_fis_receive @@ -3449,6 +3448,7 @@ tb_ahci.elastic1632_slow_i.add_rclk tb_ahci.elastic1632_slow_i.skip_rclk @8022 tb_ahci.elastic1632_slow_i.waddr[4:0] +tb_ahci.elastic1632_slow_i.raddr_r[4:0] tb_ahci.elastic1632_slow_i.dbg_diff[4:0] @1401200 -elastic_slow @@ -3506,10 +3506,38 @@ tb_ahci.elastic1632_fast_i.correct_r[2:0] -group_end @8022 tb_ahci.elastic1632_fast_i.waddr[4:0] +tb_ahci.elastic1632_fast_i.raddr_r[4:0] tb_ahci.elastic1632_fast_i.dbg_diff[4:0] @1401200 -elastic_fast @c00200 +-comma_align +@200 +- +@22 +tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtx_comma_align.aligned_data[19:0] +@28 +tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtx_comma_align.clk +tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtx_comma_align.comma +tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtx_comma_align.comma_detected +@22 +tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtx_comma_align.comma_match[19:0] +tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtx_comma_align.comma_match_p[19:0] +tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtx_comma_align.comma_match_prev[19:0] +tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtx_comma_align.comma_n[19:0] +tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtx_comma_align.comma_p[19:0] +tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtx_comma_align.indata[19:0] +tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtx_comma_align.indata_r[19:0] +tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtx_comma_align.outdata[19:0] +@28 +tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtx_comma_align.realign +tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtx_comma_align.rst +@22 +tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtx_comma_align.shifted_window[19:0] +tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtx_comma_align.window[38:0] +@1401200 +-comma_align +@c00200 -oob_ctrl @28 tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.oob_ctrl.gtx_ready @@ -3644,7 +3672,7 @@ tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.txreset tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.rxreset @1401200 -sipo_meas -@800200 +@c00200 -gtx @28 tb_ahci.dut.sata_top.ahci_top_i.axi_ahci_regs_i.drp_we @@ -3671,14 +3699,6 @@ tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.rxphaligndone2_r tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.rxphaligndone tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.rxdlysreset tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.rxdlysresetdone -tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.xclk_gtx_g -tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.xclk_gtx -@22 -tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.other_control[15:0] -@28 -tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.xclk -@29 -tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.rxreset @800200 -ttxdata_resynchro @28 @@ -3766,7 +3786,6 @@ tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.txdata_enc_out[19:0] - @1401200 -gtx8x10enc -@1000200 -gtx @c00200 -device -- 2.18.1