Commit 0c64eabc authored by Andrey Filippov's avatar Andrey Filippov

testing hardware, found elastic buffer problems

parent f8f4013f
...@@ -52,87 +52,87 @@ ...@@ -52,87 +52,87 @@
<link> <link>
<name>vivado_logs/VivadoBitstream.log</name> <name>vivado_logs/VivadoBitstream.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160202194431938.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160203212454764.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoOpt.log</name> <name>vivado_logs/VivadoOpt.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160202194431938.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160203212454764.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoOptPhys.log</name> <name>vivado_logs/VivadoOptPhys.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160202194431938.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160203212454764.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoOptPower.log</name> <name>vivado_logs/VivadoOptPower.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160202194431938.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160203212454764.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoPlace.log</name> <name>vivado_logs/VivadoPlace.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160202194431938.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160203212454764.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoRoute.log</name> <name>vivado_logs/VivadoRoute.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160202194431938.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160203212454764.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoSynthesis.log</name> <name>vivado_logs/VivadoSynthesis.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160202194431938.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160203212221686.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name> <name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160202194431938.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160203212454764.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name> <name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160202194431938.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160203212221686.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoTimingReportImplemented.log</name> <name>vivado_logs/VivadoTimingReportImplemented.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160202194431938.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160203212454764.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoTimingReportSynthesis.log</name> <name>vivado_logs/VivadoTimingReportSynthesis.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160202194431938.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160203212221686.log</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-opt-phys.dcp</name> <name>vivado_state/x393_sata-opt-phys.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-20160202194431938.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-20160203212454764.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-opt-power.dcp</name> <name>vivado_state/x393_sata-opt-power.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-20160202194431938.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-20160203212454764.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-opt.dcp</name> <name>vivado_state/x393_sata-opt.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-20160202194431938.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-20160203212454764.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-place.dcp</name> <name>vivado_state/x393_sata-place.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-place-20160202194431938.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-place-20160203212454764.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-route.dcp</name> <name>vivado_state/x393_sata-route.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-route-20160202194431938.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-route-20160203212454764.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-synth.dcp</name> <name>vivado_state/x393_sata-synth.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-synth-20160202194431938.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-synth-20160203212221686.dcp</location>
</link> </link>
</linkedResources> </linkedResources>
</projectDescription> </projectDescription>
...@@ -168,13 +168,18 @@ module ahci_ctrl_stat #( ...@@ -168,13 +168,18 @@ module ahci_ctrl_stat #(
reg [31:0] PxCMD_r; reg [31:0] PxCMD_r;
reg pxci0_r; reg pxci0_r;
reg cirq_PRC; // clear PRC bit when clearing PxSERR.DIAG.N
reg cirq_PC; // clear PC bit when clearing PxSERR.DIAG.X
wire [31:0] cirq ={32{cirq_PRC}} & HBA_PORT__PxIS__PRCS__MASK | // 'h400000;
{32{cirq_PC}} & HBA_PORT__PxIS__PCS__MASK; // 'h40;;};
wire [31:0] sirq = {32{sirq_TFE}} & HBA_PORT__PxIS__TFES__MASK | // 'h40000000; wire [31:0] sirq = {32{sirq_TFE}} & HBA_PORT__PxIS__TFES__MASK | // 'h40000000;
{32{sirq_IF }} & HBA_PORT__PxIS__IFS__MASK | // 'h8000000; {32{sirq_IF }} & HBA_PORT__PxIS__IFS__MASK | // 'h8000000;
{32{sirq_INF}} & HBA_PORT__PxIS__INFS__MASK | // 'h4000000; {32{sirq_INF}} & HBA_PORT__PxIS__INFS__MASK | // 'h4000000;
{32{sirq_OF }} & HBA_PORT__PxIS__OFS__MASK | // 'h1000000; {32{sirq_OF }} & HBA_PORT__PxIS__OFS__MASK | // 'h1000000;
{32{sirq_PRC}} & HBA_PORT__PxIS__PRCS__MASK | // 'h400000; {32{sirq_PRC}} & HBA_PORT__PxIS__PRCS__MASK | // 'h400000;
{32{sirq_PC}} & HBA_PORT__PxIS__PCS__MASK | // 'h40;; {32{sirq_PC}} & HBA_PORT__PxIS__PCS__MASK | // 'h40;
{32{sirq_DP}} & HBA_PORT__PxIS__DPS__MASK | // 'h20; {32{sirq_DP}} & HBA_PORT__PxIS__DPS__MASK | // 'h20;
{32{sirq_UF }} & HBA_PORT__PxIS__UFS__MASK | // 'h10; {32{sirq_UF }} & HBA_PORT__PxIS__UFS__MASK | // 'h10;
{32{sirq_SDB}} & HBA_PORT__PxIS__SDBS__MASK | // 'h8; {32{sirq_SDB}} & HBA_PORT__PxIS__SDBS__MASK | // 'h8;
...@@ -257,7 +262,11 @@ module ahci_ctrl_stat #( ...@@ -257,7 +262,11 @@ module ahci_ctrl_stat #(
assign update_pending = | regs_changed; assign update_pending = | regs_changed;
assign pcmd_fre = |(HBA_PORT__PxCMD__FRE__MASK & PxCMD_r); assign pcmd_fre = |(HBA_PORT__PxCMD__FRE__MASK & PxCMD_r);
assign serr_diag_X = |(HBA_PORT__PxSERR__DIAG__X__MASK & PxSERR_r); assign serr_diag_X = |(HBA_PORT__PxSERR__DIAG__X__MASK & PxSERR_r);
assign ssts_det = PxSSTS_r[3:0]; assign ssts_det = PxSSTS_r[3:0];
// assign cirq_PRC = swr_HBA_PORT__PxSERR && |(soft_write_data & HBA_PORT__PxSERR__DIAG__N__MASK);
// assign cirq_PC = swr_HBA_PORT__PxSERR && |(soft_write_data & HBA_PORT__PxSERR__DIAG__X__MASK);
localparam PxIE_MASK = HBA_PORT__PxIE__TFEE__MASK | // 'h40000000; localparam PxIE_MASK = HBA_PORT__PxIE__TFEE__MASK | // 'h40000000;
HBA_PORT__PxIE__IFE__MASK | // 'h8000000; HBA_PORT__PxIE__IFE__MASK | // 'h8000000;
...@@ -355,6 +364,11 @@ localparam PxCMD_MASK = HBA_PORT__PxCMD__ICC__MASK | // 'hf0000000; ...@@ -355,6 +364,11 @@ localparam PxCMD_MASK = HBA_PORT__PxCMD__ICC__MASK | // 'hf0000000;
assign pcmd_clo = PxCMD_r[3]; // causes ahci_fis_receive:clear_bsy_drq, that in turn resets this bit assign pcmd_clo = PxCMD_r[3]; // causes ahci_fis_receive:clear_bsy_drq, that in turn resets this bit
assign pcmd_st = PxCMD_r[0]; // current value assign pcmd_st = PxCMD_r[0]; // current value
always @(posedge mclk) begin // Here we do not have data written by soft, only the result (cleared). If bit is 0, it is
// either cleared, or was 0. If it was 0, then IS bit was also 0, so clearing will not hurt.
cirq_PRC <= swr_HBA_PORT__PxSERR && |(~soft_write_data & HBA_PORT__PxSERR__DIAG__N__MASK);
cirq_PC <= swr_HBA_PORT__PxSERR && |(~soft_write_data & HBA_PORT__PxSERR__DIAG__X__MASK);
end
always @(posedge mclk) begin always @(posedge mclk) begin
if (mrst) irq <= 0; if (mrst) irq <= 0;
...@@ -392,7 +406,7 @@ localparam PxCMD_MASK = HBA_PORT__PxCMD__ICC__MASK | // 'hf0000000; ...@@ -392,7 +406,7 @@ localparam PxCMD_MASK = HBA_PORT__PxCMD__ICC__MASK | // 'hf0000000;
// HBA_PORT__PxIS register // HBA_PORT__PxIS register
always @(posedge mclk) begin always @(posedge mclk) begin
if (rst_por) PxIS_r <= 0; if (rst_por) PxIS_r <= 0;
else PxIS_r <= PxIS_MASK & ((swr_HBA_PORT__PxIS ? soft_write_data : PxIS_r) | sirq); else PxIS_r <= PxIS_MASK & ((swr_HBA_PORT__PxIS ? soft_write_data : (PxIS_r & ~cirq)) | sirq);
end end
// HBA_PORT__PxIE register // HBA_PORT__PxIE register
...@@ -485,11 +499,11 @@ localparam PxCMD_MASK = HBA_PORT__PxCMD__ICC__MASK | // 'hf0000000; ...@@ -485,11 +499,11 @@ localparam PxCMD_MASK = HBA_PORT__PxCMD__ICC__MASK | // 'hf0000000;
else if (update_HBA_PORT__PxSSTS) ssts_changed <= 0; else if (update_HBA_PORT__PxSSTS) ssts_changed <= 0;
if (mrst) serr_changed <= 1; //0; if (mrst) serr_changed <= 1; //0;
else if (serr) serr_changed <= 1; else if (|serr) serr_changed <= 1;
else if (update_HBA_PORT__PxSERR) serr_changed <= 0; else if (update_HBA_PORT__PxSERR) serr_changed <= 0;
if (mrst) sirq_changed <= 1; //0; if (mrst) sirq_changed <= 1; //0;
else if (sirq) sirq_changed <= 1; else if ((|sirq) || (|cirq)) sirq_changed <= 1;
else if (update_HBA_PORT__PxIS) sirq_changed <= 0; else if (update_HBA_PORT__PxIS) sirq_changed <= 0;
if (mrst) pxcmd_changed <= 1; //0; if (mrst) pxcmd_changed <= 1; //0;
......
...@@ -171,14 +171,19 @@ module ahci_sata_layers #( ...@@ -171,14 +171,19 @@ module ahci_sata_layers #(
wire [31:0] debug_phy; wire [31:0] debug_phy;
wire [31:0] debug_link; wire [31:0] debug_link;
wire rxelsfull;
wire rxelsempty;
wire debug_detected_alignp; // oob detects ALIGNp, but not the link layer wire debug_detected_alignp; // oob detects ALIGNp, but not the link layer
// assign debug_sata = {link_established, phy_ready, debug_phy[29:16],debug_link[15:0]}; // // assign debug_sata = {link_established, phy_ready, debug_phy[29:16],debug_link[15:0]}; //
assign debug_sata = debug_link[31:0]; // // assign debug_sata = debug_link[31:0]; //
/// assign debug_sata = debug_phy; /// assign debug_sata = debug_phy;
// assign debug_sata = {debug_link[31:4],debug_phy[3:0]} ; //
assign debug_sata = {debug_link[31:8],debug_phy[7:0]} ; //
assign ll_h2d_last = (h2d_type_out == H2D_TYPE_FIS_LAST); assign ll_h2d_last = (h2d_type_out == H2D_TYPE_FIS_LAST);
assign d2h_valid = d2h_nempty; assign d2h_valid = d2h_nempty;
...@@ -206,8 +211,8 @@ module ahci_sata_layers #( ...@@ -206,8 +211,8 @@ module ahci_sata_layers #(
assign serr_DS = phy_ready && (0); // RWC: Link sequence error assign serr_DS = phy_ready && (0); // RWC: Link sequence error
assign serr_DC = phy_ready && (0); // RWC: CRC error in Link layer assign serr_DC = phy_ready && (0); // RWC: CRC error in Link layer
// assign serr_DB = phy_ready && (0); // RWC: 10B to 8B decode error // assign serr_DB = phy_ready && (0); // RWC: 10B to 8B decode error
assign serr_DI = phy_ready && (0); // RWC: PHY Internal Error assign serr_DI = phy_ready && (rxelsfull); // RWC: PHY Internal Error // just debugging
assign serr_EP = phy_ready && (0); // RWC: Protocol Error - a violation of SATA protocol detected assign serr_EP = phy_ready && (rxelsempty); // RWC: Protocol Error - a violation of SATA protocol detected // just debugging
assign serr_EC = phy_ready && (0); // RWC: Persistent Communication or Data Integrity Error assign serr_EC = phy_ready && (0); // RWC: Persistent Communication or Data Integrity Error
assign serr_ET = phy_ready && (0); // RWC: Transient Data Integrity Error (error not recovered by the interface) assign serr_ET = phy_ready && (0); // RWC: Transient Data Integrity Error (error not recovered by the interface)
assign serr_EM = phy_ready && (0); // RWC: Communication between the device and host was lost but re-established assign serr_EM = phy_ready && (0); // RWC: Communication between the device and host was lost but re-established
...@@ -319,9 +324,13 @@ module ahci_sata_layers #( ...@@ -319,9 +324,13 @@ module ahci_sata_layers #(
.set_offline (set_offline), // input .set_offline (set_offline), // input
.comreset_send (comreset_send), // input .comreset_send (comreset_send), // input
.cominit_got (cominit_got), // output wire .cominit_got (cominit_got), // output wire
.comwake_got (serr_DW), // output wire .comwake_got (serr_DW), // output wire
.rxelsfull (rxelsfull), // output wire
.rxelsempty (rxelsempty), // output wire
.cplllock_debug (), .cplllock_debug (),
.usrpll_locked_debug(), .usrpll_locked_debug(),
.debug_sata (debug_phy) .debug_sata (debug_phy)
,.debug_detected_alignp(debug_detected_alignp) ,.debug_detected_alignp(debug_detected_alignp)
); );
......
...@@ -690,8 +690,8 @@ module ahci_top#( ...@@ -690,8 +690,8 @@ module ahci_top#(
.afi_cache_set (set_axi_cache_mode), // output .afi_cache_set (set_axi_cache_mode), // output
.was_hba_rst (was_hba_rst), // output .was_hba_rst (was_hba_rst), // output
.was_port_rst (was_port_rst), // output .was_port_rst (was_port_rst), // output
// .debug_in ({2'b0, last_jump_addr[9:0], debug_in[19:0]}) .debug_in ({2'b0, last_jump_addr[9:0], debug_in[19:0]})
.debug_in (debug_in[31:0]) /// .debug_in (debug_in[31:0])
); );
ahci_ctrl_stat #( ahci_ctrl_stat #(
.ADDRESS_BITS (ADDRESS_BITS) .ADDRESS_BITS (ADDRESS_BITS)
......
...@@ -32,8 +32,8 @@ ...@@ -32,8 +32,8 @@
* with at least one of the Free Software programs. * with at least one of the Free Software programs.
*******************************************************************************/ *******************************************************************************/
module gtx_elastic #( module gtx_elastic #(
parameter DEPTH_LOG2 = 3, // => 8 total rows parameter DEPTH_LOG2 = 4, // 3, // => 8 total rows
parameter OFFSET = 4 // distance between read and write pointers, = wr_ptr - rd_ptr parameter OFFSET = 8 // 4 // distance between read and write pointers, = wr_ptr - rd_ptr
) )
( (
input wire rst, input wire rst,
......
...@@ -84,7 +84,12 @@ module gtx_wrap #( ...@@ -84,7 +84,12 @@ module gtx_wrap #(
output wire [DATA_BYTE_WIDTH * 8 - 1:0] rxdata, output wire [DATA_BYTE_WIDTH * 8 - 1:0] rxdata,
output wire [DATA_BYTE_WIDTH - 1:0] rxcharisk, output wire [DATA_BYTE_WIDTH - 1:0] rxcharisk,
output wire [DATA_BYTE_WIDTH - 1:0] rxnotintable, output wire [DATA_BYTE_WIDTH - 1:0] rxnotintable,
output wire [DATA_BYTE_WIDTH - 1:0] rxdisperr output wire [DATA_BYTE_WIDTH - 1:0] rxdisperr,
output wire dbg_rxphaligndone,
output wire dbg_rx_clocks_aligned,
output wire dbg_rxcdrlock,
output wire dbg_rxdlysresetdone
); );
wire rxresetdone_gtx; wire rxresetdone_gtx;
...@@ -293,6 +298,39 @@ gtx_8x10enc gtx_8x10enc( ...@@ -293,6 +298,39 @@ gtx_8x10enc gtx_8x10enc(
.outdata (txdata_enc_out) .outdata (txdata_enc_out)
); );
// Adjust RXOUTCLK so RXUSRCLK (==xclk) matches SIPO output data
wire rxcdrlock; // Marked as "reserved" - maybe not use it, only rxelecidle?
reg rxdlysreset = 0;
wire rxphaligndone;
wire rxdlysresetdone;
reg rx_clocks_aligned = 0;
reg [2:0] rxdlysreset_cntr = 7;
reg rxdlysresetdone_r;
assign dbg_rxphaligndone = rxphaligndone; // never gets up?
assign dbg_rx_clocks_aligned = rx_clocks_aligned;
assign dbg_rxcdrlock = rxcdrlock; //goes in/out (because of the SS ?
assign dbg_rxdlysresetdone = rxdlysresetdone_r;
always @ (posedge xclk) begin
// if (rxelecidle || !rxcdrlock) rxdlysreset_cntr <= 5;
if (rxelecidle) rxdlysreset_cntr <= 5;
else if (|rxdlysreset_cntr) rxdlysreset_cntr <= rxdlysreset_cntr - 1;
// if (rxelecidle || !rxcdrlock) rxdlysreset <= 0;
if (rxelecidle) rxdlysreset <= 0;
else rxdlysreset <= |rxdlysreset_cntr;
// if (rxelecidle || !rxcdrlock || rxdlysreset || |rxdlysreset_cntr) rx_clocks_aligned <= 0;
// if (rxelecidle || rxdlysreset || |rxdlysreset_cntr) rx_clocks_aligned <= 0;
if (rxelecidle) rx_clocks_aligned <= 0;
// else if (rxphaligndone) rx_clocks_aligned <= 1;
else if (rxphaligndone) rx_clocks_aligned <= 1;
if (rxelecidle || rxdlysreset || |rxdlysreset_cntr) rxdlysresetdone_r <= 0;
else if (rxdlysresetdone) rxdlysresetdone_r <= 1;
end
/* /*
* RX PCS part: comma detect + align module, 10/8 decoder, elastic buffer, interface resynchronisation * RX PCS part: comma detect + align module, 10/8 decoder, elastic buffer, interface resynchronisation
* all modules before elastic buffer shall work on a restored clock - xclk * all modules before elastic buffer shall work on a restored clock - xclk
...@@ -331,7 +369,9 @@ begin ...@@ -331,7 +369,9 @@ begin
end end
gtx_comma_align gtx_comma_align( gtx_comma_align gtx_comma_align(
// .rst (~rx_clocks_aligned), // ~wrap_rxreset_),
.rst (~wrap_rxreset_), .rst (~wrap_rxreset_),
.clk (xclk), .clk (xclk),
.indata (rxdata_comma_in), .indata (rxdata_comma_in),
.outdata (rxdata_comma_out), .outdata (rxdata_comma_out),
...@@ -348,6 +388,7 @@ wire [1:0] rxnotintable_dec_out; ...@@ -348,6 +388,7 @@ wire [1:0] rxnotintable_dec_out;
wire [1:0] rxdisperr_dec_out; wire [1:0] rxdisperr_dec_out;
gtx_10x8dec gtx_10x8dec( gtx_10x8dec gtx_10x8dec(
// .rst (~rx_clocks_aligned), // ~wrap_rxreset_),
.rst (~wrap_rxreset_), .rst (~wrap_rxreset_),
.clk (xclk), .clk (xclk),
.indata (rxdata_comma_out), .indata (rxdata_comma_out),
...@@ -372,11 +413,13 @@ gtx_elastic #( ...@@ -372,11 +413,13 @@ gtx_elastic #(
.OFFSET (4) .OFFSET (4)
) )
gtx_elastic( gtx_elastic(
// .rst (~rx_clocks_aligned), // ~wrap_rxreset_),
.rst (~wrap_rxreset_), .rst (~wrap_rxreset_),
.wclk (xclk), .wclk (xclk),
.rclk (rxusrclk), .rclk (rxusrclk),
.isaligned_in (state_aligned), /// .isaligned_in (state_aligned),
.isaligned_in (state_aligned && rxdlysresetdone_r), // rx_clocks_aligned), //Allow to align early, but do not tell it is aligned until xclk is aligned to SIPO par. clock
.charisk_in (rxcharisk_dec_out), .charisk_in (rxcharisk_dec_out),
.notintable_in (rxnotintable_dec_out), .notintable_in (rxnotintable_dec_out),
.disperror_in (rxdisperr_dec_out), .disperror_in (rxdisperr_dec_out),
...@@ -623,7 +666,7 @@ gtxe2_channel_wrapper #( ...@@ -623,7 +666,7 @@ gtxe2_channel_wrapper #(
.RXPH_CFG (24'h000000), .RXPH_CFG (24'h000000),
.RXPHDLY_CFG (24'h084020), .RXPHDLY_CFG (24'h084020),
.RXPH_MONITOR_SEL (5'b00000), .RXPH_MONITOR_SEL (5'b00000),
.RX_XCLK_SEL ("RXREC"), .RX_XCLK_SEL ("RXUSR"), // ("RXREC"), // Andrey: Now they are the same, just using p.247 "Using RX Buffer Bypass..."
.RX_DDI_SEL (6'b000000), .RX_DDI_SEL (6'b000000),
.RX_DEFER_RESET_BUF_EN ("TRUE"), .RX_DEFER_RESET_BUF_EN ("TRUE"),
/// .RXCDR_CFG (72'h03000023ff10200020),// 1.6G - 6.25G, No SS, RXOUT_DIV=2 /// .RXCDR_CFG (72'h03000023ff10200020),// 1.6G - 6.25G, No SS, RXOUT_DIV=2
...@@ -773,7 +816,7 @@ gtxe2_channel_wrapper( ...@@ -773,7 +816,7 @@ gtxe2_channel_wrapper(
.EYESCANTRIGGER (1'b0), .EYESCANTRIGGER (1'b0),
.RXCDRFREQRESET (1'b0), .RXCDRFREQRESET (1'b0),
.RXCDRHOLD (1'b0), .RXCDRHOLD (1'b0),
.RXCDRLOCK (), .RXCDRLOCK (rxcdrlock),
.RXCDROVRDEN (1'b0), .RXCDROVRDEN (1'b0),
.RXCDRRESET (1'b0), .RXCDRRESET (1'b0),
.RXCDRRESETRSV (1'b0), .RXCDRRESETRSV (1'b0),
...@@ -799,14 +842,16 @@ gtxe2_channel_wrapper( ...@@ -799,14 +842,16 @@ gtxe2_channel_wrapper(
.GTXRXN (rxn), .GTXRXN (rxn),
.RXBUFRESET (1'b0), .RXBUFRESET (1'b0),
.RXBUFSTATUS (), .RXBUFSTATUS (),
.RXDDIEN (1'b0), // .RXDDIEN (1'b0),
.RXDLYBYPASS (1'b1), .RXDDIEN (1'b1), // Andrey: p.243: "Set high in RX buffer bypass mode"
// .RXDLYBYPASS (1'b1),
.RXDLYBYPASS (1'b0), // Andrey: p.243: "0: Uses the RX delay alignment circuit."
.RXDLYEN (1'b0), .RXDLYEN (1'b0),
.RXDLYOVRDEN (1'b0), .RXDLYOVRDEN (1'b0),
.RXDLYSRESET (1'b0), .RXDLYSRESET (rxdlysreset),
.RXDLYSRESETDONE (), .RXDLYSRESETDONE (rxdlysresetdone),
.RXPHALIGN (1'b0), .RXPHALIGN (1'b0),
.RXPHALIGNDONE (), .RXPHALIGNDONE (rxphaligndone),
.RXPHALIGNEN (1'b0), .RXPHALIGNEN (1'b0),
.RXPHDLYPD (1'b0), .RXPHDLYPD (1'b0),
.RXPHDLYRESET (1'b0), .RXPHDLYRESET (1'b0),
......
...@@ -874,6 +874,7 @@ always @ (posedge clk) ...@@ -874,6 +874,7 @@ always @ (posedge clk)
if (~|rcvd_dword & phy_ready) if (~|rcvd_dword & phy_ready)
begin begin
$display("%m: invalid primitive received : %h, conrol : %h, err : %h", phy_data_in_r, phy_isk_in_r, phy_err_in_r); $display("%m: invalid primitive received : %h, conrol : %h, err : %h", phy_data_in_r, phy_isk_in_r, phy_err_in_r);
#500;
$finish; $finish;
end end
// States checker // States checker
......
...@@ -154,9 +154,11 @@ reg [DATA_BYTE_WIDTH - 1:0] rxcharisk; ...@@ -154,9 +154,11 @@ reg [DATA_BYTE_WIDTH - 1:0] rxcharisk;
// primitives detection // primitives detection
wire detected_alignp; wire detected_alignp;
localparam NUM_CON_ALIGNS = 1024; localparam NUM_CON_ALIGNS = 2; // just for debugging 1024;
reg [1:0] detected_alignp_cntr; // count detected ALIGNp - do not respond yet
///localparam NUM_CON_ALIGNS = 1024; // just for debugging 1024;
///reg [12:0] detected_alignp_cntr; // count detected ALIGNp - do not respond yet
reg detected_alignp_r; // debugging - N-th ALIGNp primitive reg detected_alignp_r; // debugging - N-th ALIGNp primitive
reg [12:0] detected_alignp_cntr; // count detected ALIGNp - do not respond yet
wire detected_syncp; wire detected_syncp;
// wait until device's cominit is done // wait until device's cominit is done
......
...@@ -75,6 +75,11 @@ module sata_phy #( ...@@ -75,6 +75,11 @@ module sata_phy #(
input comreset_send, // Not possible yet? input comreset_send, // Not possible yet?
output wire cominit_got, output wire cominit_got,
output wire comwake_got, output wire comwake_got,
// elastic buffer status
output wire rxelsfull,
output wire rxelsempty,
output cplllock_debug, output cplllock_debug,
output usrpll_locked_debug, output usrpll_locked_debug,
output [31:0] debug_sata output [31:0] debug_sata
...@@ -116,8 +121,13 @@ wire rxreset_req; ...@@ -116,8 +121,13 @@ wire rxreset_req;
wire rxreset_ack; wire rxreset_ack;
wire rxreset_oob; wire rxreset_oob;
// elastic buffer status signals TODO // elastic buffer status signals TODO
wire rxelsfull; //wire rxelsfull;
wire rxelsempty; //wire rxelsempty;
wire dbg_rxphaligndone;
wire dbg_rx_clocks_aligned;
wire dbg_rxcdrlock;
wire dbg_rxdlysresetdone;
//wire gtx_ready; //wire gtx_ready;
assign cominit_got = rxcominitdet; // For AHCI assign cominit_got = rxcominitdet; // For AHCI
...@@ -467,7 +477,11 @@ gtx_wrap ...@@ -467,7 +477,11 @@ gtx_wrap
.rxdata (rxdata), // output[31:0] wire .rxdata (rxdata), // output[31:0] wire
.rxcharisk (rxcharisk), // output[3:0] wire .rxcharisk (rxcharisk), // output[3:0] wire
.rxdisperr (rxdisperr), // output[3:0] wire .rxdisperr (rxdisperr), // output[3:0] wire
.rxnotintable (rxnotintable) // output[3:0] wire .rxnotintable (rxnotintable), // output[3:0] wire
.dbg_rxphaligndone (dbg_rxphaligndone),
.dbg_rx_clocks_aligned(dbg_rx_clocks_aligned),
.dbg_rxcdrlock (dbg_rxcdrlock) ,
.dbg_rxdlysresetdone(dbg_rxdlysresetdone)
); );
...@@ -543,6 +557,7 @@ assign debug_sata[19] = txelecidle; ...@@ -543,6 +557,7 @@ assign debug_sata[19] = txelecidle;
assign debug_sata[23:20] = debug_cntr4; assign debug_sata[23:20] = debug_cntr4;
*/ */
//assign phy_ready = link_state & gtx_ready & rxbyteisaligned; //assign phy_ready = link_state & gtx_ready & rxbyteisaligned;
assign debug_sata = {debug_cntr6,debug_cntr5}; //assign debug_sata = {debug_cntr6,debug_cntr5};
assign debug_sata = {25'b0, dbg_rxdlysresetdone, rxelecidle, dbg_rxcdrlock, rxelsfull, rxelsempty, dbg_rxphaligndone, dbg_rx_clocks_aligned};
endmodule endmodule
...@@ -402,7 +402,7 @@ ...@@ -402,7 +402,7 @@
localparam HBA_PORT__PxIS__PRCS__ADDR = 'h44; localparam HBA_PORT__PxIS__PRCS__ADDR = 'h44;
localparam HBA_PORT__PxIS__PRCS__MASK = 'h400000; localparam HBA_PORT__PxIS__PRCS__MASK = 'h400000;
localparam HBA_PORT__PxIS__PRCS__DFLT = 'h0; localparam HBA_PORT__PxIS__PRCS__DFLT = 'h0;
// RO: Device Mechanical Presence Status // RWC: Device Mechanical Presence Status
localparam HBA_PORT__PxIS__DMPS__ADDR = 'h44; localparam HBA_PORT__PxIS__DMPS__ADDR = 'h44;
localparam HBA_PORT__PxIS__DMPS__MASK = 'h80; localparam HBA_PORT__PxIS__DMPS__MASK = 'h80;
localparam HBA_PORT__PxIS__DMPS__DFLT = 'h0; localparam HBA_PORT__PxIS__DMPS__DFLT = 'h0;
......
, .INIT_00 (256'h0000000000000000AAAAAAAAAAAAAAAA00000000000000070000000000000000) , .INIT_00 (256'h0000000000000000AAAAAAAAAAAAAAAA00000000000000070000000000000000)
, .INIT_10 (256'h0000000000000000555555555555000000000000000000005555555555500000) , .INIT_10 (256'h0000000000000000555555555555000000000000000000005555555555500000)
, .INIT_11 (256'h000000000000000055054004000001C15551500000001555AAA28000000008AA) , .INIT_11 (256'h000000000000000055054004000001C15551500000001555AAA28000000088AA)
, .INIT_12 (256'h0000000000555555000000000000000000000000000000000000000000000000) , .INIT_12 (256'h0000000000555555000000000000000000000000000000000000000000000000)
, .INIT_13 (256'h00000000AAAAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF002AAAAA00AA000A) , .INIT_13 (256'h00000000AAAAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF002AAAAA00AA000A)
, .INIT_14 (256'h000000000000000000000000000000000001555555555550000000000055000D) , .INIT_14 (256'h000000000000000000000000000000000001555555555550000000000055000D)
......
...@@ -228,14 +228,17 @@ ...@@ -228,14 +228,17 @@
input [ 3:0] len; input [ 3:0] len;
input [ 1:0] burst; input [ 1:0] burst;
begin begin
wait (!CLK && AR_READY); @ (negedge CLK);
while (!AR_READY) @ (negedge CLK);
// wait (!CLK && AR_READY);
ARID_IN_r <= id; ARID_IN_r <= id;
ARADDR_IN_r <= addr; ARADDR_IN_r <= addr;
ARLEN_IN_r <= len; ARLEN_IN_r <= len;
ARSIZE_IN_r <= 3'b010; ARSIZE_IN_r <= 3'b010;
ARBURST_IN_r <= burst; ARBURST_IN_r <= burst;
AR_SET_CMD_r <= 1'b1; AR_SET_CMD_r <= 1'b1;
wait (CLK); @(posedge CLK);
// wait (CLK);
ARID_IN_r <= 12'hz; ARID_IN_r <= 12'hz;
ARADDR_IN_r <= 'hz; ARADDR_IN_r <= 'hz;
ARLEN_IN_r <= 4'hz; ARLEN_IN_r <= 4'hz;
......
This diff is collapsed.
...@@ -63,6 +63,10 @@ module tb_ahci #( ...@@ -63,6 +63,10 @@ module tb_ahci #(
`endif // CVC `endif // CVC
`endif // IVERILOG `endif // IVERILOG
parameter HOST_CLK_PERIOD = 6.666; //nsec
//parameter DEVICE_CLK_PERIOD = 6.653; //nsec
parameter DEVICE_CLK_PERIOD = 6.666; //nsec TODO: Implement actual CDR
reg [639:0] TESTBENCH_TITLE = 'bz; // to show human-readable state in the GTKWave reg [639:0] TESTBENCH_TITLE = 'bz; // to show human-readable state in the GTKWave
reg [31:0] TESTBENCH_DATA; reg [31:0] TESTBENCH_DATA;
reg [11:0] TESTBENCH_ID; reg [11:0] TESTBENCH_ID;
...@@ -81,6 +85,8 @@ end ...@@ -81,6 +85,8 @@ end
reg EXTCLK_P = 1'b1; reg EXTCLK_P = 1'b1;
reg EXTCLK_N = 1'b0; reg EXTCLK_N = 1'b0;
reg DEV_EXTCLK_P = 1'b1;
reg DEV_EXTCLK_N = 1'b0;
//reg serial_clk = 1'b1; //reg serial_clk = 1'b1;
reg [11:0] ARID_IN_r; reg [11:0] ARID_IN_r;
...@@ -335,8 +341,8 @@ sata_device dev( ...@@ -335,8 +341,8 @@ sata_device dev(
.RXP (txp), .RXP (txp),
.TXN (rxn), .TXN (rxn),
.TXP (rxp), .TXP (rxp),
.EXTCLK_P (EXTCLK_P), .EXTCLK_P (DEV_EXTCLK_P),
.EXTCLK_N (EXTCLK_N) .EXTCLK_N (DEV_EXTCLK_N)
); );
// SAXI HP interface // SAXI HP interface
...@@ -603,11 +609,16 @@ initial forever @ (posedge CLK) begin ...@@ -603,11 +609,16 @@ initial forever @ (posedge CLK) begin
end end
end end
always #3.333 begin //always #3.333 begin
always #(DEVICE_CLK_PERIOD/2) begin
EXTCLK_P = ~EXTCLK_P; EXTCLK_P = ~EXTCLK_P;
EXTCLK_N = ~EXTCLK_N; EXTCLK_N = ~EXTCLK_N;
end end
always #(HOST_CLK_PERIOD/2) begin
DEV_EXTCLK_P = ~DEV_EXTCLK_P;
DEV_EXTCLK_N = ~DEV_EXTCLK_N;
end
/* /*
// MAXI clock // MAXI clock
always #10 always #10
...@@ -889,6 +900,7 @@ localparam ATA_WDMA = 'hca; // Identify command ...@@ -889,6 +900,7 @@ localparam ATA_WDMA = 'hca; // Identify command
initial begin //Host initial begin //Host
NUM_WORDS_EXPECTED =0;
wait (!RST); wait (!RST);
//reg [639:0] TESTBENCH_TITLE = "RESET"; // to show human-readable state in the GTKWave //reg [639:0] TESTBENCH_TITLE = "RESET"; // to show human-readable state in the GTKWave
TESTBENCH_TITLE = "NO_RESET"; TESTBENCH_TITLE = "NO_RESET";
...@@ -936,8 +948,18 @@ initial begin //Host ...@@ -936,8 +948,18 @@ initial begin //Host
maxigp1_print (GHC__IS__IPS__ADDR << 2,"GHC__IS__IPS__ADDR"); // Now it should be 0 maxigp1_print (GHC__IS__IPS__ADDR << 2,"GHC__IS__IPS__ADDR"); // Now it should be 0
maxigp1_print (HBA_PORT__PxIS__DHRS__ADDR << 2,"HBA_PORT__PxIS__DHRS__ADDR"); // It should be 400041 - DHR inerrupt (and others) maxigp1_print (HBA_PORT__PxIS__DHRS__ADDR << 2,"HBA_PORT__PxIS__DHRS__ADDR"); // It should be 400041 - DHR inerrupt (and others)
maxigp1_writep (HBA_PORT__PxIS__DHRS__ADDR << 2, HBA_PORT__PxIS__DHRS__MASK); // clear that interrupt // maxigp1_writep (HBA_PORT__PxIS__DHRS__ADDR << 2, HBA_PORT__PxIS__DHRS__MASK); // clear that interrupt
maxigp1_writep (HBA_PORT__PxIS__DHRS__ADDR << 2, ~0); // clear all interrupt
maxigp1_print (HBA_PORT__PxIS__DHRS__ADDR << 2,"HBA_PORT__PxIS__DHRS__ADDR"); // Now it should be 0400040 (DHR cleared) maxigp1_print (HBA_PORT__PxIS__DHRS__ADDR << 2,"HBA_PORT__PxIS__DHRS__ADDR"); // Now it should be 0400040 (DHR cleared)
maxigp1_print (HBA_PORT__PxSERR__DIAG__X__ADDR << 2,"HBA_PORT__PxSERR"); //
maxigp1_writep (HBA_PORT__PxSERR__DIAG__X__ADDR << 2, ~0); // clear all errors
maxigp1_print (HBA_PORT__PxIS__DHRS__ADDR << 2, "cleared all i/e: HBA_PORT__PxIS__DHRS__ADDR"); //
maxigp1_print (HBA_PORT__PxSERR__DIAG__X__ADDR << 2,"cleared all i/e: HBA_PORT__PxSERR"); //
maxigp1_print (HBA_PORT__PxIS__DHRS__ADDR << 2, "re-read: HBA_PORT__PxIS__DHRS__ADDR"); //
maxigp1_print (HBA_PORT__PxSERR__DIAG__X__ADDR << 2,"re-read: HBA_PORT__PxSERR"); //
maxigp1_print (HBA_PORT__PxIS__DHRS__ADDR << 2, "re-read: HBA_PORT__PxIS__DHRS__ADDR"); //
maxigp1_print (HBA_PORT__PxSERR__DIAG__X__ADDR << 2,"re-read: HBA_PORT__PxSERR"); //
//HBA_PORT__PxIS__DHRS__ADDR //HBA_PORT__PxIS__DHRS__ADDR
maxigp1_print (PXSIG_OFFS32 << 2,"PXSIG_OFFS32"); maxigp1_print (PXSIG_OFFS32 << 2,"PXSIG_OFFS32");
......
This diff is collapsed.
...@@ -2961,7 +2961,8 @@ parameter RX_CLK25_DIV = 6; ...@@ -2961,7 +2961,8 @@ parameter RX_CLK25_DIV = 6;
parameter TX_CLK25_DIV = 6; parameter TX_CLK25_DIV = 6;
// clocking reset ( + TX PMA) // clocking reset ( + TX PMA)
wire clk_reset = EYESCANRESET | RXCDRFREQRESET | RXCDRRESET | RXCDRRESETRSV | RXPRBSCNTRESET | RXBUFRESET | RXDLYSRESET | RXPHDLYRESET | RXDFELPMRESET | GTRXRESET | RXOOBRESET | RXPCSRESET | RXPMARESET | CFGRESET | GTTXRESET | GTRESETSEL | RESETOVRD | TXDLYSRESET | TXPHDLYRESET | TXPCSRESET | TXPMARESET; //wire clk_reset = EYESCANRESET | RXCDRFREQRESET | RXCDRRESET | RXCDRRESETRSV | RXPRBSCNTRESET | RXBUFRESET | RXDLYSRESET | RXPHDLYRESET | RXDFELPMRESET | GTRXRESET | RXOOBRESET | RXPCSRESET | RXPMARESET | CFGRESET | GTTXRESET | GTRESETSEL | RESETOVRD | TXDLYSRESET | TXPHDLYRESET | TXPCSRESET | TXPMARESET;
wire clk_reset = EYESCANRESET | RXCDRFREQRESET | RXCDRRESET | RXCDRRESETRSV | RXPRBSCNTRESET | RXBUFRESET | RXPHDLYRESET | RXDFELPMRESET | GTRXRESET | RXOOBRESET | RXPCSRESET | RXPMARESET | CFGRESET | GTTXRESET | GTRESETSEL | RESETOVRD | TXDLYSRESET | TXPHDLYRESET | TXPCSRESET | TXPMARESET;
// have to wait before an external pll (mmcm) locks with usrclk, after that PCS can be resetted. Actually, we reset PMA also, because why not // have to wait before an external pll (mmcm) locks with usrclk, after that PCS can be resetted. Actually, we reset PMA also, because why not
reg reset; reg reset;
reg [31:0] reset_timer = 0; reg [31:0] reset_timer = 0;
...@@ -2974,8 +2975,17 @@ always @ (posedge TXUSRCLK) ...@@ -2974,8 +2975,17 @@ always @ (posedge TXUSRCLK)
reg rx_rst_done = 1'b0; reg rx_rst_done = 1'b0;
reg tx_rst_done = 1'b0; reg tx_rst_done = 1'b0;
reg rxcdrlock = 1'b0;
reg rxdlysresetdone = 1'b0;
reg rxphaligndone = 1'b0;
assign RXRESETDONE = rx_rst_done; assign RXRESETDONE = rx_rst_done;
assign TXRESETDONE = tx_rst_done; assign TXRESETDONE = tx_rst_done;
assign RXCDRLOCK = rxcdrlock;
assign RXDLYSRESETDONE = rxdlysresetdone;
assign RXPHALIGNDONE = rxphaligndone;
initial initial
forever @ (posedge reset) forever @ (posedge reset)
begin begin
...@@ -2994,7 +3004,46 @@ begin ...@@ -2994,7 +3004,46 @@ begin
@ (posedge GTREFCLK0); @ (posedge GTREFCLK0);
rx_rst_done <= 1'b1; rx_rst_done <= 1'b1;
end end
localparam RXCDRLOCK_DELAY = 10; // Refclk periods
localparam RXDLYSRESET_MIN_DURATION = 50; // ns
localparam RXDLYSRESETDONE_DELAY = 10;
localparam RXDLYSRESETDONE_DURATION = 7; // 100ns
localparam RXPHALIGNDONE_DELAY1 = 15;
localparam RXPHALIGNDONE_DURATION1 = 7;
localparam RXPHALIGNDONE_DELAY2 = 10;
initial forever @ (posedge (reset || RXELECIDLE)) begin
rxcdrlock <= 1'b0;
@ (negedge (reset || RXELECIDLE));
repeat (RXCDRLOCK_DELAY) @ (posedge GTREFCLK0);
rxcdrlock <= 1'b1;
end
initial forever @ (posedge RXDLYSRESET) begin
rxdlysresetdone <= 1'b0;
rxphaligndone <= 1'b0;
# (RXDLYSRESET_MIN_DURATION);
if (!RXDLYSRESET) begin
$display ("%m: RXDLYSRESET is too short - minimal duration is 50 nsec");
end else begin
@ (negedge RXDLYSRESET);
// if (!RXELECIDLE && rxcdrlock) begin
if (!RXELECIDLE) begin // removed that condition - rxcdrlock seems to go up/down (SS?)
repeat (RXDLYSRESETDONE_DELAY) @ (posedge GTREFCLK0);
rxdlysresetdone <= 1'b1;
repeat (RXDLYSRESETDONE_DURATION) @ (posedge GTREFCLK0);
rxdlysresetdone <= 1'b0;
repeat (RXPHALIGNDONE_DELAY1) @ (posedge GTREFCLK0);
rxphaligndone <= 1'b1;
repeat (RXPHALIGNDONE_DURATION1) @ (posedge GTREFCLK0);
rxphaligndone <= 1'b0;
repeat (RXPHALIGNDONE_DELAY2) @ (posedge GTREFCLK0);
rxphaligndone <= 1'b1;
end else $display ("%m: RXELECIDLE in active or rxcdrlock is inactive when applying RXDLYSRESET");
end
end
//RXELECIDLE
gtxe2_chnl #( gtxe2_chnl #(
.CPLL_CFG (CPLL_CFG), .CPLL_CFG (CPLL_CFG),
.CPLL_FBDIV (CPLL_FBDIV), .CPLL_FBDIV (CPLL_FBDIV),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment