diff --git a/.project b/.project
index 63b8a1c7bc8bd969186ed31dce4e747c2cf3e100..d184876554b32a7cf7e358a5e8ce0a6eb1a6e7ee 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 1259a521042787ef3b046738df5ec5335424530f..78dbaa37b52213848443fbaa973f5ae33d2f3598 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 5e1b462faed0f6b8db1ebf2c2d5a4e930f547a6e..19ea85926df2697b835d6a3b597bb0c43536960e 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 0c5ef4bd63086b0e103de42f28aee50b6d5f6400..7ba6206378b55c79917c61671e1e1af24512f10e 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 6df213270f3a6ae42c659b4a0ac130c57f03c0c8..58765a44308d9cb2591d864354d5bedd33f6bfe0 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 936792c35a9aa6eb776be110f6eb0759a7a9f5a2..1f02cd8a923382b441489f5012ddd1712821a317 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 3560155dfebfb3fe20c77b9d050d23ca557c905d..9bb1bf9819a65f2ec785429263389530c3647be3 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 86fc60747fe9c1c16af4a420daa23eaf3f23d0b5..73fb06a5473a77333ce092a2d51624b9a1c10312 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 c84573570f71e3c5440271fd437941291e0cc371..7a760e34201cb6e3ee2c65bf2b780ca9b6cb9738 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 ee305af296ccc752b130b49b3b1c03bb63fab728..c041848f41154966f526eccbd4be79f87e1d76c6 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 fcd9bc5884971dd7179016179ffb137c0c6fe517..74dbdead24d7cfd29c357ec0662f1e9ee49f251c 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