Commit 271e974e authored by Andrey Filippov's avatar Andrey Filippov

Fixed link FSM error mishandling sender hold

parent fcb4bd93
...@@ -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-20160304130042850.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160306195735683.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-20160304130042850.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160306195735683.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-20160304130042850.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160306195735683.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-20160304130042850.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160306195735683.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-20160304130042850.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160306195735683.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-20160304130042850.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160306195735683.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-20160304125744608.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160306195310071.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-20160304130042850.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160306195735683.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-20160304125744608.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160306195310071.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-20160304130042850.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160306195735683.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-20160304125744608.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160306195310071.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-20160304130042850.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-20160306195735683.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-20160304130042850.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-20160306195735683.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-20160304130042850.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-20160306195735683.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-20160304130042850.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-place-20160306195735683.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-20160304130042850.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-route-20160306195735683.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-20160304125744608.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-synth-20160306195310071.dcp</location>
</link> </link>
</linkedResources> </linkedResources>
</projectDescription> </projectDescription>
...@@ -63,6 +63,7 @@ module ahci_fis_receive#( ...@@ -63,6 +63,7 @@ module ahci_fis_receive#(
input update_err_sts,// update PxTFD.STS and PxTFD.ERR from the last received regs d2h input update_err_sts,// update PxTFD.STS and PxTFD.ERR from the last received regs d2h
input update_pio, // update PxTFD.STS and PxTFD.ERR from pio_* (entry PIO:Update) input update_pio, // update PxTFD.STS and PxTFD.ERR from pio_* (entry PIO:Update)
input update_prdbc, // update PRDBC in registers input update_prdbc, // update PRDBC in registers
input clear_prdbc, // save resources - clear prdbc for every command - discard what is written there
input clear_bsy_drq, // clear PxTFD.STS.BSY and PxTFD.STS.DRQ, update input clear_bsy_drq, // clear PxTFD.STS.BSY and PxTFD.STS.DRQ, update
input clear_bsy_set_drq, // clear PxTFD.STS.BSY and sets PxTFD.STS.DRQ, update input clear_bsy_set_drq, // clear PxTFD.STS.BSY and sets PxTFD.STS.DRQ, update
input set_bsy, // set PxTFD.STS.BSY, update input set_bsy, // set PxTFD.STS.BSY, update
...@@ -76,7 +77,12 @@ module ahci_fis_receive#( ...@@ -76,7 +77,12 @@ module ahci_fis_receive#(
input pcmd_fre, // control bit enables saving FIS to memory (will be ignored for signature) input pcmd_fre, // control bit enables saving FIS to memory (will be ignored for signature)
// TODO: Add writing PRDBC here? // TODO: Add writing PRDBC here? Yes, the following. B ut data may be discarded as only 0 is supposed to be written
// input [ADDRESS_BITS-1:0] soft_write_addr, // register address written by software
// input [31:0] soft_write_data, // register data written (after applying wstb and type (RO, RW, RWC, RW1)
// input soft_write_en, // write enable for data write
output reg pPioXfer, // state variable output reg pPioXfer, // state variable
output [7:0] tfd_sts, // Current PxTFD status field (updated after regFIS and SDB - certain fields) output [7:0] tfd_sts, // Current PxTFD status field (updated after regFIS and SDB - certain fields)
// tfd_sts[7] - BSY, tfd_sts[3] - DRQ, tfd_sts[0] - ERR // tfd_sts[7] - BSY, tfd_sts[3] - DRQ, tfd_sts[0] - ERR
...@@ -126,9 +132,10 @@ CLB_OFFS = 0x800 # In the second half of the register space (0x800..0xbff - 1KB) ...@@ -126,9 +132,10 @@ CLB_OFFS = 0x800 # In the second half of the register space (0x800..0xbff - 1KB)
FB_OFFS = 0xc00 # Needs 0x100 bytes FB_OFFS = 0xc00 # Needs 0x100 bytes
#HBA_PORT0 = 0x100 Not needed, always HBA_OFFS + 0x100 #HBA_PORT0 = 0x100 Not needed, always HBA_OFFS + 0x100
*/
`include "includes/ahci_localparams.vh" // @SuppressThisWarning VEditor : Unused localparams
*/
localparam CLB_OFFS32 = 'h200; // # In the second half of the register space (0x800..0xbff - 1KB) localparam CLB_OFFS32 = 'h200; // # In the second half of the register space (0x800..0xbff - 1KB)
localparam HBA_OFFS32 = 0; localparam HBA_OFFS32 = 0;
localparam HBA_PORT0_OFFS32 = 'h40; localparam HBA_PORT0_OFFS32 = 'h40;
...@@ -387,7 +394,17 @@ localparam DATA_TYPE_ERR = 3; ...@@ -387,7 +394,17 @@ localparam DATA_TYPE_ERR = 3;
else if ((decr_dwcw || decr_dwcr) && !xfer_cntr_zero_r) xfer_cntr_r[31:2] <= {xfer_cntr_r[31:2]} - else if ((decr_dwcw || decr_dwcr) && !xfer_cntr_zero_r) xfer_cntr_r[31:2] <= {xfer_cntr_r[31:2]} -
{18'b0, decr_dwcr? data_in_dwords: decr_DXC_dw[11:0]}; {18'b0, decr_dwcr? data_in_dwords: decr_DXC_dw[11:0]};
if (hba_rst || reg_sdb[0] || reg_ps[4] || reg_ds[5]) prdbc_r[31:2] <= 0; // no - it should only be updated when written by software
//CLB_OFFS32 + 1; // location of PRDBC
/*
input [ADDRESS_BITS-1:0] soft_write_addr, // register address written by software
input [31:0] soft_write_data, // register data written (after applying wstb and type (RO, RW, RWC, RW1)
input soft_write_en, // write enable for data write
*/
// if (hba_rst || reg_sdb[0] || reg_ps[4] || reg_ds[5]) prdbc_r[31:2] <= 0;
// if (soft_write_en && (soft_write_addr == (CLB_OFFS32 + 1))) prdbc_r[31:2] <= soft_write_data[31:2];
if (clear_prdbc || hba_rst) prdbc_r[31:2] <= 0;
else if (decr_dwcw || decr_dwcr) prdbc_r[31:2] <= {prdbc_r[31:2]} + {18'b0, decr_dwcr? data_in_dwords: decr_DXC_dw[11:0]}; else if (decr_dwcw || decr_dwcr) prdbc_r[31:2] <= {prdbc_r[31:2]} + {18'b0, decr_dwcr? data_in_dwords: decr_DXC_dw[11:0]};
xfer_cntr_zero_r <= xfer_cntr_r[31:2] == 0; xfer_cntr_zero_r <= xfer_cntr_r[31:2] == 0;
......
...@@ -291,7 +291,7 @@ module ahci_fsm ...@@ -291,7 +291,7 @@ module ahci_fsm
wire fsm_pre_act_w = fsm_actions && fsm_next; // use it as CS for generated actions (registered) wire fsm_pre_act_w = fsm_actions && fsm_next; // use it as CS for generated actions (registered)
reg [1:0] async_pend_r; // waiting to process cominit_got reg [1:0] async_pend_r; // waiting to process cominit_got
reg async_from_st; // chnge to multi-bit if there will be more sources for async transitions reg async_from_st; // change to multi-bit if there will be more sources for async transitions
// wire asynq_rq = (cominit_got && unsolicited_cominit_en) || pcmd_st_cleared; // wire asynq_rq = (cominit_got && unsolicited_cominit_en) || pcmd_st_cleared;
wire asynq_rq = (cominit_got && unsolicited_en) || pcmd_st_cleared; wire asynq_rq = (cominit_got && unsolicited_en) || pcmd_st_cleared;
// OK to wait for some time fsm_act_busy is supposed to never hang up // OK to wait for some time fsm_act_busy is supposed to never hang up
...@@ -396,7 +396,8 @@ module ahci_fsm ...@@ -396,7 +396,8 @@ module ahci_fsm
else if (fsm_pre_act_w) fsm_act_busy <= fsm_wait_act_w; else if (fsm_pre_act_w) fsm_act_busy <= fsm_wait_act_w;
else if (fsm_act_done) fsm_act_busy <= 0; else if (fsm_act_done) fsm_act_busy <= 0;
if (pcmd_st_cleared) async_from_st <= 1; if (hba_rst) async_from_st <= 0;
else if (pcmd_st_cleared) async_from_st <= 1;
else if (asynq_rq) async_from_st <= 0; else if (asynq_rq) async_from_st <= 0;
if (hba_rst) async_pend_r <= 0; if (hba_rst) async_pend_r <= 0;
......
...@@ -212,6 +212,9 @@ module ahci_sata_layers #( ...@@ -212,6 +212,9 @@ module ahci_sata_layers #(
wire debug_detected_alignp; // oob detects ALIGNp, but not the link layer wire debug_detected_alignp; // oob detects ALIGNp, but not the link layer
wire [31:0] debug_phy0; wire [31:0] debug_phy0;
wire [31:0] datascope0_di;
// 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;
...@@ -261,6 +264,7 @@ module ahci_sata_layers #( ...@@ -261,6 +264,7 @@ module ahci_sata_layers #(
if (d2h_fifo_wr) debug_last_d2h_type_in<= d2h_type_in; if (d2h_fifo_wr) debug_last_d2h_type_in<= d2h_type_in;
if (d2h_fifo_rd) debug_last_d2h_type<= d2h_type; if (d2h_fifo_rd) debug_last_d2h_type<= d2h_type;
end end
/*
assign debug_phy = {h2d_type_out[1:0],h2d_type[1:0], assign debug_phy = {h2d_type_out[1:0],h2d_type[1:0],
ll_h2d_last,d2h_valid, d2h_type[1:0], ll_h2d_last,d2h_valid, d2h_type[1:0],
debug_last_d2h_type_in, d2h_type_in[1:0], debug_last_d2h_type_in, d2h_type_in[1:0],
...@@ -272,6 +276,22 @@ module ahci_sata_layers #( ...@@ -272,6 +276,22 @@ module ahci_sata_layers #(
d2h_waddr[1:0], d2h_waddr[1:0],
d2h_raddr[1:0], d2h_raddr[1:0],
debug_phy0[ 7:0]}; debug_phy0[ 7:0]};
*/
/*
assign debug_phy = {h2d_type_out[1:0],h2d_type[1:0],
ll_h2d_last,d2h_valid, d2h_type[1:0],
// debug_last_d2h_type_in, d2h_type_in[1:0],
// debug_last_d2h_type[1:0],
// d2h_fill[1:0],
// 1'b0,
// d2h_fifo_wr,
// d2h_fifo_re_regen[1:0],
// d2h_waddr[1:0],
// d2h_raddr[1:0],
debug_phy0[23:0]};
*/
assign debug_phy = debug_phy0;
// debug_phy0[15:0]}; // debug_phy0[15:0]};
// debug_phy0[19:0]}; // debug_phy0[19:0]};
...@@ -289,7 +309,7 @@ module ahci_sata_layers #( ...@@ -289,7 +309,7 @@ module ahci_sata_layers #(
// .comwake_got (serr_DW), // output wire // .comwake_got (serr_DW), // output wire
assign datascope_di = {5'b0,debug_link[5],datascope0_di[25:0]};// aligns_pair tx
link #( link #(
.DATA_BYTE_WIDTH(4) .DATA_BYTE_WIDTH(4)
) link ( ) link (
...@@ -412,10 +432,10 @@ module ahci_sata_layers #( ...@@ -412,10 +432,10 @@ module ahci_sata_layers #(
.datascope_clk (datascope_clk), // output .datascope_clk (datascope_clk), // output
.datascope_waddr (datascope_waddr), // output[9:0] .datascope_waddr (datascope_waddr), // output[9:0]
.datascope_we (datascope_we), // output .datascope_we (datascope_we), // output
.datascope_di (datascope_di), // output[31:0] .datascope_di (datascope0_di), // output[31:0]
// .datascope_trig (ll_incom_invalidate ), // ll_frame_ackn), // input datascope external trigger .datascope_trig (ll_incom_invalidate ), // ll_frame_ackn), // input datascope external trigger
// .datascope_trig (debug_link[4:0] == 'h0a), // state_send_eof // input datascope external trigger // .datascope_trig (debug_link[4:0] == 'h0a), // state_send_eof // input datascope external trigger
.datascope_trig (debug_link[4:0] == 'h02), // state_rcvr_goodcrc // input datascope external trigger /// .datascope_trig (debug_link[4:0] == 'h02), // state_rcvr_goodcrc // input datascope external trigger
//debug_link //debug_link
`endif `endif
......
...@@ -687,6 +687,28 @@ wire[1:0] debug_fis_end_r; // output[1:0] ...@@ -687,6 +687,28 @@ wire[1:0] debug_fis_end_r; // output[1:0]
wire[1:0] debug_get_fis_busy_r; // output[1:0] wire[1:0] debug_get_fis_busy_r; // output[1:0]
localparam DATA_TYPE_DMA = 0;
localparam DATA_TYPE_FIS_HEAD = 1;
localparam DATA_TYPE_OK = 2;
localparam DATA_TYPE_ERR = 3;
reg [12:0] debug_d2h_length;
reg [12:0] debug_d2h_length_prev;
reg was_good_bad;
reg was_good_bad_prev;
always @(posedge mclk) if (d2h_ready && d2h_valid) begin
if (d2h_type == DATA_TYPE_FIS_HEAD) debug_d2h_length_prev <= debug_d2h_length;
if (d2h_type == DATA_TYPE_FIS_HEAD) debug_d2h_length <= 0;
else if (d2h_type == DATA_TYPE_DMA) debug_d2h_length <= debug_d2h_length + 1;
if (d2h_type == DATA_TYPE_FIS_HEAD) was_good_bad_prev <= was_good_bad;
if ((d2h_type == DATA_TYPE_OK) || (d2h_type == DATA_TYPE_ERR)) was_good_bad <= (d2h_type == DATA_TYPE_OK);
end
axi_ahci_regs #( axi_ahci_regs #(
.ADDRESS_BITS (ADDRESS_BITS), .ADDRESS_BITS (ADDRESS_BITS),
.HBA_RESET_BITS (HBA_RESET_BITS), .HBA_RESET_BITS (HBA_RESET_BITS),
...@@ -745,12 +767,29 @@ wire[1:0] debug_get_fis_busy_r; // output[1:0] ...@@ -745,12 +767,29 @@ wire[1:0] debug_get_fis_busy_r; // output[1:0]
.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_in0 ({ debug_data_in_ready, // output .debug_in0 ({ debug_data_in_ready, // output
debug_fis_end_w, // output debug_fis_end_w, // output
xfer_cntr_zero, xfer_cntr_zero,
debug_fis_end_r[0], // debug_fis_end_r[1:0], // output[1:0] debug_fis_end_r[0], // debug_fis_end_r[1:0], // output[1:0]
debug_get_fis_busy_r[1:0], // output[1:0] debug_get_fis_busy_r[1:0], // output[1:0]
debug_dma[25:0]}), // input[31:0] debug_dma[25:0]}), // input[31:0]
*/
.debug_in0 ({ 2'b0,
was_good_bad_prev,
debug_d2h_length_prev[12:0],
2'b0,
was_good_bad,
debug_d2h_length[12:0]
}),
/*
reg [12:0] debug_d2h_length;
reg [12:0] debug_d2h_length_prev;
reg was_good_bad;
reg was_good_bad_prev;
*/
// .debug_in1 ({xclk_period[7:0], // lower 8 bits of 12-bit value. Same frequency would be 0x800 (msb opposite to 3 next bits) // .debug_in1 ({xclk_period[7:0], // lower 8 bits of 12-bit value. Same frequency would be 0x800 (msb opposite to 3 next bits)
// debug_dma1[23:0]}), // debug_in_link), // input[31:0] // debug_dma1[23:0]}), // debug_in_link), // input[31:0]
.debug_in1 ({debug_in_link[15:8], .debug_in1 ({debug_in_link[15:8],
...@@ -1003,6 +1042,8 @@ wire[1:0] debug_get_fis_busy_r; // output[1:0] ...@@ -1003,6 +1042,8 @@ wire[1:0] debug_get_fis_busy_r; // output[1:0]
.update_pio (frcv_update_pio), // input update PxTFD.STS and PxTFD.ERR from pio_* (entry PIO:Update) .update_pio (frcv_update_pio), // input update PxTFD.STS and PxTFD.ERR from pio_* (entry PIO:Update)
.update_prdbc (frcv_update_prdbc), // input .update_prdbc (frcv_update_prdbc), // input
.clear_prdbc (fsnd_fetch_cmd), // input save resources - clear prdbc for every commnad
.clear_bsy_drq (frcv_clear_bsy_drq), // input .clear_bsy_drq (frcv_clear_bsy_drq), // input
.clear_bsy_set_drq (frcv_clear_bsy_set_drq), // input .clear_bsy_set_drq (frcv_clear_bsy_set_drq), // input
......
...@@ -840,6 +840,7 @@ task send_identify_data; // @SuppressThisWarning VEditor - Used in testbench ...@@ -840,6 +840,7 @@ task send_identify_data; // @SuppressThisWarning VEditor - Used in testbench
reg [15:0] identify_data[0:255]; // SuppressThisWarning VEditor : assigned in $readmem() system task reg [15:0] identify_data[0:255]; // SuppressThisWarning VEditor : assigned in $readmem() system task
integer i; integer i;
begin begin
clear_transmit_pause(0);
// $readmemh("input_data/identify.dat",identify_data); // $readmemh("input_data/identify.dat",identify_data);
$readmemh("input_data/test512.dat",identify_data); $readmemh("input_data/test512.dat",identify_data);
transmit_data[0] = FIS_DATA; transmit_data[0] = FIS_DATA;
...@@ -856,6 +857,7 @@ task send_incrementing_data; // @SuppressThisWarning VEditor - Used in testbench ...@@ -856,6 +857,7 @@ task send_incrementing_data; // @SuppressThisWarning VEditor - Used in testbench
output integer status; output integer status;
integer i; integer i;
begin begin
clear_transmit_pause(0);
transmit_data[0] = FIS_DATA; transmit_data[0] = FIS_DATA;
for (i=0;i<len;i=i+1) begin for (i=0;i<len;i=i+1) begin
transmit_data[i+1] = i; transmit_data[i+1] = i;
...@@ -864,6 +866,23 @@ task send_incrementing_data; // @SuppressThisWarning VEditor - Used in testbench ...@@ -864,6 +866,23 @@ task send_incrementing_data; // @SuppressThisWarning VEditor - Used in testbench
end end
endtask endtask
task send_incrementing_data_pause; // @SuppressThisWarning VEditor - Used in testbench
input integer id;
input integer len;
output integer status;
integer i;
begin
clear_transmit_pause(0);
for (i=0;i<len;i=i+8) begin
transmit_data_pause[i+1] = i; // each 8-th have increainsg pause
end
transmit_data[0] = FIS_DATA;
for (i=0;i<len;i=i+1) begin
transmit_data[i+1] = i;
end
linkTransmitFIS(id, 129, 0, status);
end
endtask
/* /*
...@@ -895,7 +914,7 @@ task linkTransmitFIS; // @SuppressThisWarning VEditor - Used in testbench ...@@ -895,7 +914,7 @@ task linkTransmitFIS; // @SuppressThisWarning VEditor - Used in testbench
input integer size; // dwords count input integer size; // dwords count
input integer transmit_custom_crc; input integer transmit_custom_crc;
output integer status; output integer status;
integer pause; integer xpause;
integer cnt; integer cnt;
integer crc; integer crc;
reg [111:0] rprim; reg [111:0] rprim;
...@@ -958,17 +977,21 @@ task linkTransmitFIS; // @SuppressThisWarning VEditor - Used in testbench ...@@ -958,17 +977,21 @@ task linkTransmitFIS; // @SuppressThisWarning VEditor - Used in testbench
end end
// L_SendData + L_RcvrHold + L_SendHold // L_SendData + L_RcvrHold + L_SendHold
cnt = 0; cnt = 0;
pause = transmit_data_pause[0]; xpause = transmit_data_pause[0];
while (cnt < size) begin while (cnt < size) begin
// scrambler_value = scrambleFunc(scrambler_value[31:16]); if (xpause > 0) begin
DEV_TITLE = "Transmission is paused";
$display("[Device] LINK: %s @%t", DEV_TITLE, $time);
linkSendPrim("HOLD");
xpause = xpause - 1;
end else begin
scrambler_value = scrambleFunc({16'b0,scrambler_value[31:16]}); scrambler_value = scrambleFunc({16'b0,scrambler_value[31:16]});
// $display("[Device] LINK: Scrambler = %h", scrambler_value);
linkSendData(transmit_data[cnt] ^ scrambler_value); linkSendData(transmit_data[cnt] ^ scrambler_value);
crc = calculateCRC(crc, transmit_data[cnt]); crc = calculateCRC(crc, transmit_data[cnt]);
// $display("[Device] LINK: Sent data = %h", transmit_data[cnt]);
DEV_TITLE = "Sent data"; DEV_TITLE = "Sent data";
DEV_DATA = transmit_data[cnt]; DEV_DATA = transmit_data[cnt];
$display("[Device] LINK: %s = %h (#%d) @%t", DEV_TITLE, DEV_DATA, cnt, $time); $display("[Device] LINK: %s = %h (#%d) @%t", DEV_TITLE, DEV_DATA, cnt, $time);
end
@ (posedge clk) @ (posedge clk)
rprim = linkGetPrim(0); rprim = linkGetPrim(0);
if (rprim == "SYNC") begin if (rprim == "SYNC") begin
...@@ -978,43 +1001,33 @@ task linkTransmitFIS; // @SuppressThisWarning VEditor - Used in testbench ...@@ -978,43 +1001,33 @@ task linkTransmitFIS; // @SuppressThisWarning VEditor - Used in testbench
$display("[Device] LINK: %s, transmission id = %d @%t", DEV_TITLE, DEV_DATA, $time); $display("[Device] LINK: %s, transmission id = %d @%t", DEV_TITLE, DEV_DATA, $time);
#100; #100;
$finish; $finish;
end end else if ((rprim == "SCRAP") || (rprim == "DATA")) begin
if ((rprim == "SCRAP") || (rprim == "DATA")) begin
// $display("[Device] LINK: Bad primitives from the host, is data = %h, data = %h, transmission id = %d", linkIsData(0), linkGetData(0), id); // $display("[Device] LINK: Bad primitives from the host, is data = %h, data = %h, transmission id = %d", linkIsData(0), linkGetData(0), id);
DEV_TITLE = "Bad primitives from the host #6"; DEV_TITLE = "Bad primitives from the host #6";
DEV_DATA = id; DEV_DATA = id;
$display("[Device] LINK: %s, is data = %h, data = %h, reception id = %d @%t", DEV_TITLE, linkIsData(0), linkGetData(0), DEV_DATA, $time); $display("[Device] LINK: %s, is data = %h, data = %h, reception id = %d @%t", DEV_TITLE, linkIsData(0), linkGetData(0), DEV_DATA, $time);
#100; #100;
$finish; $finish;
end end else if (rprim == "DMAT") begin
else
if (rprim == "DMAT") begin
// $display("[Device] LINK: Transmission terminated by the host via DMAT, transmission id = %d", id); // $display("[Device] LINK: Transmission terminated by the host via DMAT, transmission id = %d", id);
DEV_TITLE = "Transmission terminated by the hostvia DMAT"; DEV_TITLE = "Transmission terminated by the host via DMAT";
DEV_DATA = id; DEV_DATA = id;
$display("[Device] LINK: %s, transmission id = %d @%t", DEV_TITLE, DEV_DATA, $time); $display("[Device] LINK: %s, transmission id = %d @%t", DEV_TITLE, DEV_DATA, $time);
#100; #100;
$finish; $finish;
end end else if (xpause > 0) begin
else // DEV_TITLE = "Transmission is paused";
if (pause > 0) begin // $display("[Device] LINK: %s @%t", DEV_TITLE, $time);
// $display("[Device] LINK: Transmission is paused"); // linkSendPrim("HOLD");
DEV_TITLE = "Transmission is paused"; xpause = xpause - 1;
$display("[Device] LINK: %s @%t", DEV_TITLE, $time); end else if (rprim == "HOLD") begin
linkSendPrim("HOLD");
pause = pause - 1;
end
else
if (rprim == "HOLD") begin
// $display("[Device] LINK: The host asked for a pause, acknowledging");
DEV_TITLE = "The host asked for a pause, acknowledging transmission paused"; DEV_TITLE = "The host asked for a pause, acknowledging transmission paused";
$display("[Device] LINK: %s @%t", DEV_TITLE, $time); $display("[Device] LINK: %s @%t", DEV_TITLE, $time);
linkSendPrim("HOLDA"); linkSendPrim("HOLDA");
end end else begin
else begin
cnt = cnt + 1; cnt = cnt + 1;
if (cnt < size) if (cnt < size)
pause = transmit_data_pause[cnt]; xpause = transmit_data_pause[cnt];
end end
end end
// L_SendCRC // L_SendCRC
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
//`include "gtx_elastic.v" //`include "gtx_elastic.v"
// All computations have been done in assumption of GTX interface being 20 bits wide! // All computations have been done in assumption of GTX interface being 20 bits wide!
//`include "system_defines.v" //`include "system_defines.v"
`define DEBUG_ELASTIC
module gtx_wrap #( module gtx_wrap #(
`ifdef USE_DATASCOPE `ifdef USE_DATASCOPE
parameter ADDRESS_BITS = 10, // for datascope parameter ADDRESS_BITS = 10, // for datascope
...@@ -128,6 +129,10 @@ module gtx_wrap #( ...@@ -128,6 +129,10 @@ module gtx_wrap #(
output drp_rdy, output drp_rdy,
output [15:0] drp_do output [15:0] drp_do
`endif `endif
`ifdef DEBUG_ELASTIC
,output reg [15:0] dbg_data_cntr // 4 MSB - got other primitives during data receive
`endif
...@@ -728,6 +733,87 @@ wire rxcominitdet_gtx; ...@@ -728,6 +733,87 @@ wire rxcominitdet_gtx;
.empty (rxelsempty) // output .empty (rxelsempty) // output
); );
`ifdef DEBUG_ELASTIC
localparam ALIGN_PRIM = 32'h7B4A4ABC;
localparam SOF_PRIM = 32'h3737b57c;
localparam EOF_PRIM = 32'hd5d5b57c;
localparam CONT_PRIM = 32'h9999aa7c;
localparam HOLD_PRIM = 32'hd5d5aa7c;
localparam HOLDA_PRIM = 32'h9595aa7c;
localparam WTRM_PRIM = 32'h5858b57c;
reg [15:0] dbg_data_in_r;
reg [1:0] dbg_charisk_in_r;
// reg [1:0] dbg_notintable_in_r;
// reg [1:0] dbg_disperror_in_r;
reg dbg_aligned32_in_r; // input data is word-aligned and got ALIGNp
reg dbg_msb_in_r; // input contains MSB
// reg dbg_inc_waddr;
reg [11:0] dbg_data_cntr_r;
reg [3:0] got_prims_r;
reg dbg_frun;
reg dbg_is_alignp_r;
reg dbg_is_sof_r;
reg dbg_is_eof_r;
reg dbg_is_data_r;
wire dbg_is_alignp_w = ({rxdata_dec_out, dbg_data_in_r} == ALIGN_PRIM) && ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h1);
wire dbg_is_sof_w = ({rxdata_dec_out, dbg_data_in_r} == SOF_PRIM) && ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h1);
wire dbg_is_eof_w = ({rxdata_dec_out, dbg_data_in_r} == EOF_PRIM) && ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h1);
wire dbg_is_cont_w = ({rxdata_dec_out, dbg_data_in_r} == CONT_PRIM) && ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h1);
wire dbg_is_hold_w = ({rxdata_dec_out, dbg_data_in_r} == HOLD_PRIM) && ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h1);
wire dbg_is_holda_w = ({rxdata_dec_out, dbg_data_in_r} == HOLDA_PRIM) && ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h1);
wire dbg_is_wrtm_w = ({rxdata_dec_out, dbg_data_in_r} == WTRM_PRIM) && ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h1);
wire dbg_is_data_w = ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h0);
always @ (posedge xclk) begin
dbg_data_in_r <= rxdata_dec_out;
dbg_charisk_in_r <= rxcharisk_dec_out;
// dbg_notintable_in_r <= rxnotintable_dec_out;
// dbg_disperror_in_r <= rxdisperr_dec_out;
dbg_is_alignp_r <=dbg_is_alignp_w;
dbg_is_sof_r <= dbg_is_sof_w;
dbg_is_eof_r <= dbg_is_eof_w;
dbg_is_data_r <=dbg_is_data_w && dbg_msb_in_r;
if (!dbg_aligned32_in_r && !dbg_is_alignp_w) dbg_msb_in_r <= 1;
else dbg_msb_in_r <= !dbg_msb_in_r;
if (!state_aligned) dbg_aligned32_in_r <= 0;
else if (dbg_is_alignp_w) dbg_aligned32_in_r <= 1;
if (!dbg_aligned32_in_r || dbg_is_sof_r) got_prims_r <= 0;
else if (dbg_frun) got_prims_r <= got_prims_r | {dbg_is_cont_w, dbg_is_hold_w, dbg_is_holda_w, dbg_is_wrtm_w};
// dbg_inc_waddr <= !dbg_msb_in_r || (dbg_is_alignp_w && !dbg_aligned32_in_r);
// if (!dbg_aligned32_in_r || dbg_is_eof_w) dbg_frun <= 0;
// else if (dbg_is_sof_w) dbg_frun <= 1;
if (!dbg_aligned32_in_r || dbg_is_eof_r) dbg_frun <= 0;
else if (dbg_is_sof_r) dbg_frun <= 1;
// if (!dbg_aligned32_in_r || dbg_is_sof_w) dbg_data_cntr_r <= 0;
// else if (dbg_frun && dbg_is_data_w &&dbg_msb_in_r) dbg_data_cntr_r <= dbg_data_cntr_r + 1;
if (!dbg_aligned32_in_r || dbg_is_sof_r) dbg_data_cntr_r <= 0;
else if (dbg_frun && dbg_is_data_r) dbg_data_cntr_r <= dbg_data_cntr_r + 1;
// if (!dbg_aligned32_in_r || dbg_is_sof_w) dbg_data_cntr <= dbg_data_cntr_r; // copy previous value
if (!dbg_aligned32_in_r || dbg_is_sof_r) dbg_data_cntr <= {got_prims_r, dbg_data_cntr_r}; // copy previous value
end
`endif // DEBUG_ELASATIC
reg rxresetdone_r; reg rxresetdone_r;
reg txresetdone_r; reg txresetdone_r;
always @ (posedge rxusrclk2) rxresetdone_r <= rxresetdone_gtx; always @ (posedge rxusrclk2) rxresetdone_r <= rxresetdone_gtx;
......
...@@ -176,8 +176,8 @@ always @ (posedge clk) begin ...@@ -176,8 +176,8 @@ always @ (posedge clk) begin
phy_err_in_r <= phy_err_in_r0; phy_err_in_r <= phy_err_in_r0;
end end
// When switching from state_rcvr_shold to state_rcvr_data we need to know that it will be data 1 cycle ahead
wire next_will_be_data = !(is_cont_p_w || (rcv_junk && !(is_non_cont_non_align_p_w || is_align_p_w))) && !(|phy_isk_in_r0);
reg data_txing_r; // if there are still some data to transmit and the transaction wasn't cancelled reg data_txing_r; // if there are still some data to transmit and the transaction wasn't cancelled
wire data_txing = data_txing_r & ~state_send_crc; wire data_txing = data_txing_r & ~state_send_crc;
...@@ -413,9 +413,11 @@ assign set_rcvr_wait = state_idle & dword_val & rcvd_dword[COD ...@@ -413,9 +413,11 @@ assign set_rcvr_wait = state_idle & dword_val & rcvd_dword[COD
assign set_rcvr_rdy = state_rcvr_wait & dword_val & rcvd_dword[CODE_XRDYP] & ~data_busy_in; assign set_rcvr_rdy = state_rcvr_wait & dword_val & rcvd_dword[CODE_XRDYP] & ~data_busy_in;
assign set_rcvr_data = state_rcvr_rdy & dword_val & rcvd_dword[CODE_SOFP] assign set_rcvr_data = state_rcvr_rdy & dword_val & rcvd_dword[CODE_SOFP]
| state_rcvr_rhold & dword_val_na & ~rcvd_dword[CODE_HOLDP] & ~rcvd_dword[CODE_EOFP] & ~rcvd_dword[CODE_SYNCP] & ~data_busy_in // | state_rcvr_rhold & dword_val_na & ~rcvd_dword[CODE_HOLDP] & ~rcvd_dword[CODE_EOFP] & ~rcvd_dword[CODE_SYNCP] & ~data_busy_in
| state_rcvr_shold & dword_val_na & ~rcvd_dword[CODE_HOLDP] & ~rcvd_dword[CODE_EOFP] & ~rcvd_dword[CODE_SYNCP]; | state_rcvr_rhold & next_will_be_data & ~data_busy_in
// | state_rcvr_shold & dword_val_na & ~rcvd_dword[CODE_HOLDP] & ~rcvd_dword[CODE_EOFP] & ~rcvd_dword[CODE_SYNCP];
| state_rcvr_shold & next_will_be_data; // So it will not be align
//next_will_be_data
assign set_rcvr_rhold = state_rcvr_data & dword_val & rcvd_dword[CODE_DATA] & data_busy_in; assign set_rcvr_rhold = state_rcvr_data & dword_val & rcvd_dword[CODE_DATA] & data_busy_in;
assign set_rcvr_shold = state_rcvr_data & dword_val & rcvd_dword[CODE_HOLDP] assign set_rcvr_shold = state_rcvr_data & dword_val & rcvd_dword[CODE_HOLDP]
...@@ -1246,7 +1248,7 @@ always @ (posedge clk) ...@@ -1246,7 +1248,7 @@ always @ (posedge clk)
, state_rcvr_badend , state_rcvr_badend
}; };
$display("%m: invalid states: %b", sim_states_concat); $display("%m: invalid states: %b", sim_states_concat);
$finish; // $finish;
end end
`endif `endif
......
...@@ -128,7 +128,9 @@ wire [DATA_BYTE_WIDTH - 1:0] rxcharisk_out; ...@@ -128,7 +128,9 @@ wire [DATA_BYTE_WIDTH - 1:0] rxcharisk_out;
wire [DATA_BYTE_WIDTH - 1:0] rxdisperr; wire [DATA_BYTE_WIDTH - 1:0] rxdisperr;
wire [DATA_BYTE_WIDTH - 1:0] rxnotintable; wire [DATA_BYTE_WIDTH - 1:0] rxnotintable;
wire [1:0] txbufstatus; wire [1:0] txbufstatus;
`ifdef DEBUG_ELASTIC
wire [15:0] dbg_data_cntr; // output[11:0] reg 4 MSBs - got primitives during data receive
`endif
assign ll_err_out = rxdisperr | rxnotintable; assign ll_err_out = rxdisperr | rxnotintable;
// once gtx_ready -> 1, gtx_configured latches // once gtx_ready -> 1, gtx_configured latches
...@@ -551,7 +553,7 @@ gtx_wrap ...@@ -551,7 +553,7 @@ gtx_wrap
.datascope_waddr (datascope_waddr), // output[9:0] .datascope_waddr (datascope_waddr), // output[9:0]
.datascope_we (datascope_we), // output .datascope_we (datascope_we), // output
.datascope_di (datascope_di), // output[31:0] .datascope_di (datascope_di), // output[31:0]
.datascope_trig (datascope_trig) // inpuit // external trigger event for the datascope .datascope_trig (datascope_trig) // input // external trigger event for the datascope
`endif `endif
`ifdef USE_DRP `ifdef USE_DRP
...@@ -564,6 +566,9 @@ gtx_wrap ...@@ -564,6 +566,9 @@ gtx_wrap
.drp_rdy (drp_rdy), // output .drp_rdy (drp_rdy), // output
.drp_do (drp_do) // output[15:0] .drp_do (drp_do) // output[15:0]
`endif `endif
`ifdef DEBUG_ELASTIC
,.dbg_data_cntr (dbg_data_cntr) // output[11:0] reg
`endif
); );
...@@ -656,6 +661,12 @@ always @ (posedge clk) begin ...@@ -656,6 +661,12 @@ always @ (posedge clk) begin
else if (dbg_rxphaligndone_down && dbg_rxphaligndone) dbg_rxphaligndone_second <= 1; else if (dbg_rxphaligndone_down && dbg_rxphaligndone) dbg_rxphaligndone_second <= 1;
*/ */
end end
//reg [11:0] dbg_data_cntr_r;
//always @ (posedge clk) begin
// if (datascope_trig) dbg_data_cntr_r <=dbg_data_cntr;
//end
/* /*
assign debug_sata[ 3: 0] = debug_cntr1; assign debug_sata[ 3: 0] = debug_cntr1;
assign debug_sata[ 7: 4] = debug_cntr2; assign debug_sata[ 7: 4] = debug_cntr2;
...@@ -678,10 +689,17 @@ assign debug_sata[23:20] = debug_cntr4; ...@@ -678,10 +689,17 @@ assign debug_sata[23:20] = debug_cntr4;
//assign debug_sata = {debug_cntr6,debug_cntr5}; //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, 1'b0, dbg_rxdlysresetdone, rxelecidle, dbg_rxcdrlock, rxelsfull, rxelsempty, dbg_rxphaligndone, dbg_rx_clocks_aligned};
`ifdef USE_DATASCOPE `ifdef USE_DATASCOPE
assign debug_sata = {txbufstatus[1:0], rxelecidle, dbg_rxcdrlock, rxelsfull, rxelsempty, dbg_rxphaligndone, dbg_rx_clocks_aligned, /// assign debug_sata = {txbufstatus[1:0], rxelecidle, dbg_rxcdrlock, rxelsfull, rxelsempty, dbg_rxphaligndone, dbg_rx_clocks_aligned,
error_count[11:0], /// error_count[11:0],
/// 2'b0,
/// datascope_waddr[9:0]};
assign debug_sata = {dbg_data_cntr[15:0], // latched at error from previous FIS (@sof) (otherwise overwritten by h2d rfis)
error_count[3:0],
2'b0, 2'b0,
datascope_waddr[9:0]}; datascope_waddr[9:0]};
//dbg_data_cntr
`else `else
assign debug_sata = {8'b0, dbg_clk_align_cntr, txbufstatus[1:0], 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};
`endif `endif
......
...@@ -40,6 +40,11 @@ class x393_vsc3304(object): ...@@ -40,6 +40,11 @@ class x393_vsc3304(object):
DRY_MODE= True # True DRY_MODE= True # True
DEBUG_MODE=1 DEBUG_MODE=1
x393_mem=None x393_mem=None
OUTPUT_LEVELS = {
"ESATA_A": 3,
"ESATA_B": 3,
"SSD_B": 2,
"ZYNQ_A": 2}
PCB_CONNECTIONS = { PCB_CONNECTIONS = {
"10389": { "10389": {
"INVERTED_PORTS": ("D","E","G","H"), "INVERTED_PORTS": ("D","E","G","H"),
...@@ -164,6 +169,8 @@ class x393_vsc3304(object): ...@@ -164,6 +169,8 @@ class x393_vsc3304(object):
self.echo("1", "input_state_invert/"+self.in_port(port_letter)) self.echo("1", "input_state_invert/"+self.in_port(port_letter))
self.echo("10","output_mode/"+self.out_port(port_letter)) self.echo("10","output_mode/"+self.out_port(port_letter))
self.echo("1", "forward_OOB/all") self.echo("1", "forward_OOB/all")
for out_pair in self.OUTPUT_LEVELS:
self.echo(str(self.OUTPUT_LEVELS[out_pair]), "output_level/"+self.out_port(self.port_name(out_pair)))
self.current_mode = "IDLE" self.current_mode = "IDLE"
def connect(self, mode): def connect(self, mode):
......
...@@ -379,25 +379,36 @@ class x393sata(object): ...@@ -379,25 +379,36 @@ class x393sata(object):
if quiet < 4 : if quiet < 4 :
print ("Reset OFF") print ("Reset OFF")
self.reset(0xa) self.reset(0xa)
self.set_zynq() self.set_zynq_ssd()
if quiet < 4 : if quiet < 4 :
print("Use 'set_zynq()', 'set_esata()' or 'set_debug() to switch SSD connection") print("Use ' sata.set_zynq_ssd()', 'sata.set_zynq_esata()' or 'sata.set_esata_ssd() to switch SSD connection")
def set_zynq(self): def set_zynq_ssd(self):
self.vsc3304.connect_zynq_ssd() self.vsc3304.connect_zynq_ssd()
if self.DEBUG_MODE: if self.DEBUG_MODE:
self.vsc3304.connection_status() self.vsc3304.connection_status()
def set_esata(self): def set_zynq_esata(self):
self.vsc3304.connect_zynq_esata()
if self.DEBUG_MODE:
self.vsc3304.connection_status()
def set_esata_ssd(self):
self.vsc3304.connect_esata_ssd() self.vsc3304.connect_esata_ssd()
if self.DEBUG_MODE: if self.DEBUG_MODE:
self.vsc3304.connection_status() self.vsc3304.connection_status()
def set_debug(self): def set_debug_oscilloscope(self):
self.vsc3304.connect_debug() self.vsc3304.connect_debug()
if self.DEBUG_MODE: if self.DEBUG_MODE:
self.vsc3304.connection_status() self.vsc3304.connection_status()
def reinit_mux(self):
"""
Set output port voltage level (possibly other port settings may be added)
"""
self.vsc3304.reinit()
def erate(self, dly = 1.0): def erate(self, dly = 1.0):
c0 = self.x393_mem.read_mem(0x80000ff0) c0 = self.x393_mem.read_mem(0x80000ff0)
sleep(dly) sleep(dly)
...@@ -1200,6 +1211,7 @@ class x393sata(object): ...@@ -1200,6 +1211,7 @@ class x393sata(object):
def err_count (self): def err_count (self):
return (self.x393_mem.read_mem(MAXI1_ADDR + DBG_OFFS + (2 << 2)) >> 12) & 0xfff return (self.x393_mem.read_mem(MAXI1_ADDR + DBG_OFFS + (2 << 2)) >> 12) & 0xfff
## return (self.x393_mem.read_mem(MAXI1_ADDR + DBG_OFFS + (2 << 2)) >> 12) & 0x3f #temporarily reduced as same bits are used for other data
def err_rate(self, dly = 0.1): def err_rate(self, dly = 0.1):
ec0 = self.err_count() ec0 = self.err_count()
...@@ -1341,6 +1353,7 @@ class x393sata(object): ...@@ -1341,6 +1353,7 @@ class x393sata(object):
aligned = (dword >> 22) & 0x1 aligned = (dword >> 22) & 0x1
comma = (dword >> 24) & 0x1 comma = (dword >> 24) & 0x1
realign = (dword >> 25) & 0x1 realign = (dword >> 25) & 0x1
snd_align = (dword >> 26) & 0x1
decor = [] decor = []
for nb in range(2): for nb in range(2):
if k[nb]: if k[nb]:
...@@ -1365,7 +1378,7 @@ class x393sata(object): ...@@ -1365,7 +1378,7 @@ class x393sata(object):
decor.append("()") decor.append("()")
else: else:
decor.append("__") decor.append("__")
rslt = " R"[realign]+" C"[comma]+"N "[aligned] rslt = " A"[snd_align]+" R"[realign]+" C"[comma]+"N "[aligned]
p = replace_p(dword, prev_dword, next_dword) p = replace_p(dword, prev_dword, next_dword)
if p: if p:
return rslt+"%8s"%(p) return rslt+"%8s"%(p)
...@@ -1429,6 +1442,7 @@ def init_sata(): ...@@ -1429,6 +1442,7 @@ def init_sata():
sata = x393sata( debug_mode = 0, # 1, sata = x393sata( debug_mode = 0, # 1,
dry_mode = 0, dry_mode = 0,
pcb_rev = None) pcb_rev = None)
sata.reinit_mux()
sata.bitstream(bitfile=None, sata.bitstream(bitfile=None,
quiet=4) # 4 will be really quiet quiet=4) # 4 will be really quiet
...@@ -1515,6 +1529,7 @@ sata.vsc3304.PCB_CONNECTIONS['10389B']['INVERTED_PORTS'] ...@@ -1515,6 +1529,7 @@ sata.vsc3304.PCB_CONNECTIONS['10389B']['INVERTED_PORTS']
('A', 'E', 'G', 'H') ('A', 'E', 'G', 'H')
sata.vsc3304.PCB_CONNECTIONS['10389B']['INVERTED_PORTS']=('E','G','H') sata.vsc3304.PCB_CONNECTIONS['10389B']['INVERTED_PORTS']=('E','G','H')
#######################################
reload (x393sata) reload (x393sata)
sata = x393sata.x393sata() sata = x393sata.x393sata()
...@@ -1526,7 +1541,7 @@ import x393sata ...@@ -1526,7 +1541,7 @@ import x393sata
import x393_mem import x393_mem
mem = x393_mem.X393Mem(1,0,1) mem = x393_mem.X393Mem(1,0,1)
sata = x393sata.x393sata() # 1,0,"10389B") sata = x393sata.x393sata() # 1,0,"10389B")
# def __init__(self, debug_mode=1,dry_mode=False, pcb_rev = "10389"): sata.reinit_mux()
sata.bitstream() sata.bitstream()
#sata.drp_write (0x20b,0x401) # bypass, clock align #sata.drp_write (0x20b,0x401) # bypass, clock align
...@@ -1539,14 +1554,65 @@ sata.drp (0x59,0x8) # Use RXREC ...@@ -1539,14 +1554,65 @@ sata.drp (0x59,0x8) # Use RXREC
#sata.drp (0x59,0x48) #sata.drp (0x59,0x48)
sata.reg_status() sata.reg_status()
sata.reg_status() sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4) sata.arm_logger()
sata.reg_status(),sata.reset_ie(),sata.err_count()
_=sata.dd_read_dma_ext(0x80,4096,0x3000),sata.reg_status(),sata.reset_ie(),sata.err_count(),mem.mem_dump (0x80000ff0, 4,4),mem.mem_dump (0x80000800, 4,4)
_=sata.reg_status(),sata.reset_ie(),sata.err_count(),mem.mem_dump (0x80000ff0, 4,4),mem.mem_dump (0x80000800, 4,4)
_=sata.err_count(),mem.mem_dump (0x80000ff0, 4,4),mem.mem_dump (0x80000800, 4,4)
_=sata.reg_status(),sata.reset_ie(),mem.mem_dump (0x80000ff0, 4,4),mem.mem_dump (0x80000800, 4,4)
_=mem.mem_dump (0x80001000, 0x400,4), sata.datascope1()
_=mem.mem_dump (0x80000ff0, 4,4) _=mem.mem_dump (0x80000ff0, 4,4)
_=mem.mem_dump (0x80000800, 4,4)
_=mem.mem_dump (0x80000ff0, 4,4),mem.mem_dump (0x80000800, 4,4)
_=mem.mem_dump (0x80001000, 0x120,4) _=mem.mem_dump (0x80001000, 0x120,4)
sata.arm_logger()
sata.dd_read_dma_ext(0x80,4096,0x3000)
_=mem.mem_dump (0x80000ff0, 4,4)
Good:
>>> _=sata.err_count(),mem.mem_dump (0x80000ff0, 4,4),mem.mem_dump (0x80000800, 4,4)
0x80000ff0:24002004 9d000000 40200378 967ff03b
0x80000800:00030005 00003000 1f800010 00000000
Bad:
>>> sata.dd_read_dma_ext(0x80,4096,0x3000)
0x80000ff0:200407ff 9d010f00 933003c7 023ff90c
0x80000800:00030005 00003000 1f800010 00000000
good:
_=mem.mem_dump (0x80000ff0, 4,4)
0x80000ff0:24002004 9d000000 40200031 967ff03b
bad:
0x80000ff0:200407ff 9d010f00 56500367 023ff90c
good:
0x80000ff0:24002004 5d000000 402001f1 167ff03b
bad:
0x80000ff0:200407ff 9d010f00 46c00308 023ff90c
good:
0x80000ff0:24002004 5d000000 040203be 967ff03b
bad
0x80000ff0:200407ff 5d010f00 c94102c3 023ff90c
{dbg_is_cont_w, dbg_is_hold_w, dbg_is_holda_w, dbg_is_wrtm_w}
sata.dd_read_dma_ext(0x80,4096,0x30000)
sata.dd_read_dma(block, 1)
hex(sata.get_reg_address('HBA_PORT__PxSCTL')) hex(sata.get_reg_address('HBA_PORT__PxSCTL'))
mem.write_mem(0x8000012c,1) mem.write_mem(0x8000012c,1)
mem.write_mem(0x8000012c,0) mem.write_mem(0x8000012c,0)
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
`define USE_DATASCOPE `define USE_DATASCOPE
`define PRELOAD_BRAMS `define PRELOAD_BRAMS
`define AHCI_SATA 1 `define AHCI_SATA 1
`define DEBUG_ELASTIC
// Enviroment-dependent options // Enviroment-dependent options
`ifdef IVERILOG `ifdef IVERILOG
`define SIMULATION `define SIMULATION
......
...@@ -354,6 +354,16 @@ wire [31:0] test_elastic_fast_data_out; ...@@ -354,6 +354,16 @@ wire [31:0] test_elastic_fast_data_out;
wire test_elastic_fast_full; wire test_elastic_fast_full;
wire test_elastic_fast_empty; wire test_elastic_fast_empty;
wire incom_start_slow ;
wire incom_done_slow ;
wire incom_invalidate_slow ;
wire incom_sync_escape_slow ;
wire incom_start_fast ;
wire incom_done_fast ;
wire incom_invalidate_fast ;
wire incom_sync_escape_fast ;
reg test_elastic_slow_rclk = 0; reg test_elastic_slow_rclk = 0;
reg test_elastic_fast_rclk = 0; reg test_elastic_fast_rclk = 0;
...@@ -381,6 +391,52 @@ always #(TEST_ELASTIC_PERIOD_FAST/2) test_elastic_fast_rclk =!test_elastic_fast_ ...@@ -381,6 +391,52 @@ always #(TEST_ELASTIC_PERIOD_FAST/2) test_elastic_fast_rclk =!test_elastic_fast_
.empty (test_elastic_slow_empty) // output .empty (test_elastic_slow_empty) // output
); );
/* Testing just receive after elastic */
/*
link #(
.DATA_BYTE_WIDTH(4),
.ALIGNES_PERIOD(10)
) link_slow_i (
.rst (dut.sata_top.ahci_sata_layers_i.rst), // input wire
.clk (test_elastic_slow_rclk), // input wire
.data_in (0), // input[31:0] wire
.data_mask_in (2'b0), // input[1:0] wire
.data_strobe_out (), // output wire
.data_last_in (1'b0), // input wire
.data_val_in (1'b0), // input wire
.data_out (), // output[31:0] wire
.data_mask_out (), // output[1:0] wire
.data_val_out (), // output wire
.data_busy_in (1'b0), // input wire
.data_last_out (), // output wire
.frame_req (1'b0), // input wire
.frame_busy (), // output wire
.frame_ack (), // output wire
.frame_rej (), // output wire
.frame_done_good (), // output wire
.frame_done_bad (), // output wire
.incom_start (incom_start_slow), // output wire
.incom_done (incom_done_slow), // output wire
.incom_invalidate (incom_invalidate_slow), // output wire
.incom_sync_escape (incom_sync_escape_slow), // output wire
.incom_ack_good (1'b0), // input wire Not needed here?
.incom_ack_bad (1'b0), // input wire Not needed here?
.link_reset (dut.sata_top.ahci_sata_layers_i.ll_link_reset), // input wire
.sync_escape_req (1'b0), // input wire
.sync_escape_ack (), // output wire
.incom_stop_req (1'b0), // input wire
.link_established (), // output
.link_bad_crc (), // output reg
.phy_ready (dut.sata_top.ahci_sata_layers_i.phy_ready), // input wire
.phy_data_in (test_elastic_slow_data_out), // input[31:0] wire
.phy_isk_in (test_elastic_slow_charisk_out), // input[3:0] wire
.phy_err_in (test_elastic_slow_notintable_out | test_elastic_slow_disperror_out), // input[3:0] wire
.phy_data_out (), // output[31:0] wire
.phy_isk_out (), // output[3:0] wire
.debug_out () // output[31:0]
);
*/
elastic1632 #( elastic1632 #(
.DEPTH_LOG2(4), .DEPTH_LOG2(4),
.OFFSET(5) .OFFSET(5)
...@@ -401,7 +457,52 @@ always #(TEST_ELASTIC_PERIOD_FAST/2) test_elastic_fast_rclk =!test_elastic_fast_ ...@@ -401,7 +457,52 @@ always #(TEST_ELASTIC_PERIOD_FAST/2) test_elastic_fast_rclk =!test_elastic_fast_
.empty (test_elastic_fast_empty) // output .empty (test_elastic_fast_empty) // output
); );
/* Testing just receive after elastic */
/*
link #(
.DATA_BYTE_WIDTH(4),
.ALIGNES_PERIOD(10)
) link_fast_i (
.rst (dut.sata_top.ahci_sata_layers_i.rst), // input wire
.clk (test_elastic_fast_rclk), // input wire
.data_in (0), // input[31:0] wire
.data_mask_in (2'b0), // input[1:0] wire
.data_strobe_out (), // output wire
.data_last_in (1'b0), // input wire
.data_val_in (1'b0), // input wire
.data_out (), // output[31:0] wire
.data_mask_out (), // output[1:0] wire
.data_val_out (), // output wire
.data_busy_in (1'b0), // input wire
.data_last_out (), // output wire
.frame_req (1'b0), // input wire
.frame_busy (), // output wire
.frame_ack (), // output wire
.frame_rej (), // output wire
.frame_done_good (), // output wire
.frame_done_bad (), // output wire
.incom_start (incom_start_fast), // output wire
.incom_done (incom_done_fast), // output wire
.incom_invalidate (incom_invalidate_fast), // output wire
.incom_sync_escape (incom_sync_escape_fast), // output wire
.incom_ack_good (1'b0), // input wire Not needed here - will it work in passive mode?
.incom_ack_bad (1'b0), // input wire Not needed here - will it work in passive mode?
.link_reset (dut.sata_top.ahci_sata_layers_i.ll_link_reset), // input wire
.sync_escape_req (1'b0), // input wire
.sync_escape_ack (), // output wire
.incom_stop_req (1'b0), // input wire
.link_established (), // output
.link_bad_crc (), // output reg
.phy_ready (dut.sata_top.ahci_sata_layers_i.phy_ready), // input wire
.phy_data_in (test_elastic_fast_data_out), // input[31:0] wire
.phy_isk_in (test_elastic_fast_charisk_out), // input[3:0] wire
.phy_err_in (test_elastic_fast_notintable_out | test_elastic_fast_disperror_out), // input[3:0] wire
.phy_data_out (), // output[31:0] wire
.phy_isk_out (), // output[3:0] wire
.debug_out () // output[31:0]
);
*/
...@@ -905,6 +1006,7 @@ localparam ATA_RDMA_EXT = 'h25; // Read DMA devices that support 48-bit Addressi ...@@ -905,6 +1006,7 @@ localparam ATA_RDMA_EXT = 'h25; // Read DMA devices that support 48-bit Addressi
(0 << 10) | // 'C' Do not clear BSY/CI after transmitting this command (0 << 10) | // 'C' Do not clear BSY/CI after transmitting this command
// (1 << 10) | // 'C' Do clear BSY/CI after transmitting this command // (1 << 10) | // 'C' Do clear BSY/CI after transmitting this command
(1 << 16)); // 'PRDTL' - number of PRDT entries (just one) (1 << 16)); // 'PRDTL' - number of PRDT entries (just one)
maxigp1_writep ((CLB_OFFS32 +1 ) << 2, 0); // clear PRDBC
// maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE) & 32'hffffffc0); // 'CTBA' - Command table base address // maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE) & 32'hffffffc0); // 'CTBA' - Command table base address
maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE)); // 'CTBA' - Command table base address maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE)); // 'CTBA' - Command table base address
// Set Command Issued // Set Command Issued
...@@ -938,6 +1040,7 @@ localparam ATA_RDMA_EXT = 'h25; // Read DMA devices that support 48-bit Addressi ...@@ -938,6 +1040,7 @@ localparam ATA_RDMA_EXT = 'h25; // Read DMA devices that support 48-bit Addressi
// (0 << 10) | // 'C' Do not clear BSY/CI after transmitting this command // (0 << 10) | // 'C' Do not clear BSY/CI after transmitting this command
(1 << 10) | // 'C' Do clear BSY/CI after transmitting this command (1 << 10) | // 'C' Do clear BSY/CI after transmitting this command
(1 << 16)); // 'PRDTL' - number of PRDT entries (just one) (1 << 16)); // 'PRDTL' - number of PRDT entries (just one)
maxigp1_writep ((CLB_OFFS32 +1 ) << 2, 0); // clear PRDBC
// maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE) & 32'hffffffc0); // 'CTBA' - Command table base address // maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE) & 32'hffffffc0); // 'CTBA' - Command table base address
maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE)); // 'CTBA' - Command table base address maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE)); // 'CTBA' - Command table base address
// Set Command Issued // Set Command Issued
...@@ -989,6 +1092,7 @@ localparam ATA_RDMA_EXT = 'h25; // Read DMA devices that support 48-bit Addressi ...@@ -989,6 +1092,7 @@ localparam ATA_RDMA_EXT = 'h25; // Read DMA devices that support 48-bit Addressi
// (0 << 10) | // 'C' Do not clear BSY/CI after transmitting this command // (0 << 10) | // 'C' Do not clear BSY/CI after transmitting this command
(1 << 10) | // 'C' Do clear BSY/CI after transmitting this command (1 << 10) | // 'C' Do clear BSY/CI after transmitting this command
(4 << 16)); // 'PRDTL' - number of PRDT entries (4) (4 << 16)); // 'PRDTL' - number of PRDT entries (4)
maxigp1_writep ((CLB_OFFS32 +1 ) << 2, 0); // clear PRDBC
/// maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE) & 32'hffffffc0); // 'CTBA' - Command table base address /// maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE) & 32'hffffffc0); // 'CTBA' - Command table base address
maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE)); // 'CTBA' - Command table base address maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE)); // 'CTBA' - Command table base address
// Set Command Issued // Set Command Issued
...@@ -1041,6 +1145,7 @@ localparam ATA_RDMA_EXT = 'h25; // Read DMA devices that support 48-bit Addressi ...@@ -1041,6 +1145,7 @@ localparam ATA_RDMA_EXT = 'h25; // Read DMA devices that support 48-bit Addressi
(0 << 10) | // 'C' Do not clear BSY/CI after transmitting this command (0 << 10) | // 'C' Do not clear BSY/CI after transmitting this command
// (1 << 10) | // 'C' Do clear BSY/CI after transmitting this command // (1 << 10) | // 'C' Do clear BSY/CI after transmitting this command
(4 << 16)); // 'PRDTL' - number of PRDT entries (4) (4 << 16)); // 'PRDTL' - number of PRDT entries (4)
maxigp1_writep ((CLB_OFFS32 +1 ) << 2, 0); // clear PRDBC
/// maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE) & 32'hffffffc0); // 'CTBA' - Command table base address /// maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE) & 32'hffffffc0); // 'CTBA' - Command table base address
maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE)); // 'CTBA' - Command table base address maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE)); // 'CTBA' - Command table base address
// Set Command Issued // Set Command Issued
...@@ -1097,6 +1202,7 @@ localparam ATA_RDMA_EXT = 'h25; // Read DMA devices that support 48-bit Addressi ...@@ -1097,6 +1202,7 @@ localparam ATA_RDMA_EXT = 'h25; // Read DMA devices that support 48-bit Addressi
// (0 << 10) | // 'C' Do not clear BSY/CI after transmitting this command // (0 << 10) | // 'C' Do not clear BSY/CI after transmitting this command
(1 << 10) | // 'C' Do clear BSY/CI after transmitting this command (1 << 10) | // 'C' Do clear BSY/CI after transmitting this command
(4 << 16)); // 'PRDTL' - number of PRDT entries (4) (4 << 16)); // 'PRDTL' - number of PRDT entries (4)
maxigp1_writep ((CLB_OFFS32 +1 ) << 2, 0); // clear PRDBC
/// maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE) & 32'hffffffc0); // 'CTBA' - Command table base address /// maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE) & 32'hffffffc0); // 'CTBA' - Command table base address
maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE)); // 'CTBA' - Command table base address maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE)); // 'CTBA' - Command table base address
// Set Command Issued // Set Command Issued
...@@ -1136,6 +1242,7 @@ localparam ATA_RDMA_EXT = 'h25; // Read DMA devices that support 48-bit Addressi ...@@ -1136,6 +1242,7 @@ localparam ATA_RDMA_EXT = 'h25; // Read DMA devices that support 48-bit Addressi
// (0 << 10) | // 'C' Do not clear BSY/CI after transmitting this command // (0 << 10) | // 'C' Do not clear BSY/CI after transmitting this command
(1 << 10) | // 'C' Do clear BSY/CI after transmitting this command (1 << 10) | // 'C' Do clear BSY/CI after transmitting this command
(1 << 16)); // 'PRDTL' - number of PRDT entries (1) (1 << 16)); // 'PRDTL' - number of PRDT entries (1)
maxigp1_writep ((CLB_OFFS32 +1 ) << 2, 0); // clear PRDBC
/// maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE) & 32'hffffffc0); // 'CTBA' - Command table base address /// maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE) & 32'hffffffc0); // 'CTBA' - Command table base address
maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE)); // 'CTBA' - Command table base address maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE)); // 'CTBA' - Command table base address
// Set Command Issued // Set Command Issued
...@@ -1281,11 +1388,17 @@ initial begin //Host ...@@ -1281,11 +1388,17 @@ initial begin //Host
maxigp1_print (HBA_PORT__PxCI__CI__ADDR << 2,"HBA_PORT__PxCI__CI__ADDR"); maxigp1_print (HBA_PORT__PxCI__CI__ADDR << 2,"HBA_PORT__PxCI__CI__ADDR");
`endif `endif
// TODO change to ifdef - this is for identify command
// maxigp1_writep (HBA_PORT__PxIE__PSE__ADDR << 2, HBA_PORT__PxIE__PSE__MASK); // allow PS only interrupts (PIO setup)
// maxigp1_writep (HBA_PORT__PxIS__PSS__ADDR << 2, HBA_PORT__PxIS__PSS__MASK); // clear that interrupt
maxigp1_writep (HBA_PORT__PxIE__PSE__ADDR << 2, HBA_PORT__PxIE__DHRE__MASK); // allow DHR only interrupts (PIO setup)
maxigp1_writep (HBA_PORT__PxIS__PSS__ADDR << 2, HBA_PORT__PxIE__DHRE__MASK); // clear that interrupt
maxigp1_writep (HBA_PORT__PxIE__PSE__ADDR << 2, HBA_PORT__PxIE__PSE__MASK); // allow PS only interrupts (PIO setup)
maxigp1_writep (HBA_PORT__PxIS__PSS__ADDR << 2, HBA_PORT__PxIS__PSS__MASK); // clear that interrupt
wait (IRQ); wait (IRQ);
TESTBENCH_TITLE = "Got Identify"; // TESTBENCH_TITLE = "Got Identify";
TESTBENCH_TITLE = "Got D2HRFIS";
$display("[Testbench]: %s @%t", TESTBENCH_TITLE, $time); $display("[Testbench]: %s @%t", TESTBENCH_TITLE, $time);
maxigp1_print (HBA_PORT__PxIS__PSS__ADDR << 2,"HBA_PORT__PxIS__PSS__ADDR"); maxigp1_print (HBA_PORT__PxIS__PSS__ADDR << 2,"HBA_PORT__PxIS__PSS__ADDR");
maxigp1_writep (HBA_PORT__PxIS__PSS__ADDR << 2, HBA_PORT__PxIS__PSS__MASK); // clear PS interrupt maxigp1_writep (HBA_PORT__PxIS__PSS__ADDR << 2, HBA_PORT__PxIS__PSS__MASK); // clear PS interrupt
...@@ -1457,10 +1570,12 @@ initial begin //Device ...@@ -1457,10 +1570,12 @@ initial begin //Device
dev.send_dma_activate (69, // input integer id; dev.send_dma_activate (69, // input integer id;
status); // output integer status; status); // output integer status;
end else if (func_is_dev_read_dma_ext(dev.receive_data[0])) begin end else if (func_is_dev_read_dma_ext(dev.receive_data[0])) begin
dev.send_incrementing_data(70, // input integer id;
// dev.send_incrementing_data(70, // input integer id;
dev.send_incrementing_data_pause(70, // input integer id;
128, // number of dwords to send, later decode count field 128, // number of dwords to send, later decode count field
status); // output integer status; status); // output integer status;
DEVICE_TITLE = "Device sent Data FIS (READ DMA EXT)"; DEVICE_TITLE = "Device sent Data FIS with pauses(READ DMA EXT)";
$display("[Dev-TB]: %s, status = 0x%x @%t", DEVICE_TITLE, status, $time); $display("[Dev-TB]: %s, status = 0x%x @%t", DEVICE_TITLE, status, $time);
// Send multiple FISes if needed, when done: // Send multiple FISes if needed, when done:
......
[*] [*]
[*] GTKWave Analyzer v3.3.66 (w)1999-2015 BSI [*] GTKWave Analyzer v3.3.66 (w)1999-2015 BSI
[*] Fri Mar 4 19:49:47 2016 [*] Mon Mar 7 02:46:09 2016
[*] [*]
[dumpfile] "/home/andrey/git/x393_sata/simulation/tb_ahci-20160304124651260.fst" [dumpfile] "/home/andrey/git/x393_sata/simulation/tb_ahci-20160306192631093.fst"
[dumpfile_mtime] "Fri Mar 4 19:48:48 2016" [dumpfile_mtime] "Mon Mar 7 02:28:25 2016"
[dumpfile_size] 13922108 [dumpfile_size] 14586310
[savefile] "/home/andrey/git/x393_sata/tb_ahci_01.sav" [savefile] "/home/andrey/git/x393_sata/tb_ahci_01.sav"
[timestart] 34498000 [timestart] 33393100
[size] 1823 1180 [size] 1823 1180
[pos] 0 42 [pos] 1920 60
*-19.415150 37229086 62346574 72998842 74025406 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 *-16.114683 33642778 32476228 47988010 32736600 -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.
[treeopen] tb_ahci.axi_read_addr. [treeopen] tb_ahci.axi_read_addr.
[treeopen] tb_ahci.dev. [treeopen] tb_ahci.dev.
[treeopen] tb_ahci.dev.linkMonitorFIS. [treeopen] tb_ahci.dev.linkMonitorFIS.
[treeopen] tb_ahci.dev.phy. [treeopen] tb_ahci.dev.linkTransmitFIS.
[treeopen] tb_ahci.dev.phy.gtx_wrapper. [treeopen] tb_ahci.dev.phy.gtx_wrapper.
[treeopen] tb_ahci.dev.phy.gtx_wrapper.gtx_gpl. [treeopen] tb_ahci.dev.phy.gtx_wrapper.gtx_gpl.
[treeopen] tb_ahci.dev.phy.gtx_wrapper.gtx_gpl.channel. [treeopen] tb_ahci.dev.phy.gtx_wrapper.gtx_gpl.channel.
...@@ -26,11 +26,13 @@ ...@@ -26,11 +26,13 @@
[treeopen] tb_ahci.dut. [treeopen] tb_ahci.dut.
[treeopen] tb_ahci.dut.axi_hp_clk_i. [treeopen] tb_ahci.dut.axi_hp_clk_i.
[treeopen] tb_ahci.dut.sata_top. [treeopen] tb_ahci.dut.sata_top.
[treeopen] tb_ahci.dut.sata_top.ahci_sata_layers_i.
[treeopen] tb_ahci.dut.sata_top.ahci_sata_layers_i.fifo_h2d_control_i. [treeopen] tb_ahci.dut.sata_top.ahci_sata_layers_i.fifo_h2d_control_i.
[treeopen] tb_ahci.dut.sata_top.ahci_sata_layers_i.link. [treeopen] tb_ahci.dut.sata_top.ahci_sata_layers_i.link.
[treeopen] tb_ahci.dut.sata_top.ahci_sata_layers_i.link.crc. [treeopen] tb_ahci.dut.sata_top.ahci_sata_layers_i.link.crc.
[treeopen] tb_ahci.dut.sata_top.ahci_sata_layers_i.link.scrambler. [treeopen] tb_ahci.dut.sata_top.ahci_sata_layers_i.link.scrambler.
[treeopen] tb_ahci.dut.sata_top.ahci_sata_layers_i.phy. [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.genblk1.
[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.
[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.
...@@ -59,10 +61,10 @@ ...@@ -59,10 +61,10 @@
[treeopen] tb_ahci.simul_axi_hp_wr_i.waddr_i. [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_hp_wr_i.wdata_i.
[treeopen] tb_ahci.simul_axi_read_i. [treeopen] tb_ahci.simul_axi_read_i.
[sst_width] 325 [sst_width] 252
[signals_width] 338 [signals_width] 349
[sst_expanded] 1 [sst_expanded] 1
[sst_vpaned_height] 573 [sst_vpaned_height] 577
@820 @820
tb_ahci.TESTBENCH_TITLE[639:0] tb_ahci.TESTBENCH_TITLE[639:0]
tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.oob_ctrl.oob.HOST_OOB_TITLE[639:0] tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.oob_ctrl.oob.HOST_OOB_TITLE[639:0]
...@@ -719,6 +721,8 @@ tb_ahci.AR_SET_CMD_r ...@@ -719,6 +721,8 @@ tb_ahci.AR_SET_CMD_r
tb_ahci.dut.TXN tb_ahci.dut.TXN
tb_ahci.dut.RXN tb_ahci.dut.RXN
tb_ahci.dut.irq tb_ahci.dut.irq
@22
tb_ahci.dut.sata_top.ahci_top_i.ahci_ctrl_stat_i.PxIS_r[31:0]
@c00200 @c00200
-axi_read -axi_read
@28 @28
...@@ -2531,15 +2535,14 @@ tb_ahci.simul_axi_hp_wr_i.wdata_i.fill[7:0] ...@@ -2531,15 +2535,14 @@ tb_ahci.simul_axi_hp_wr_i.wdata_i.fill[7:0]
-fifo_wdata -fifo_wdata
@1401200 @1401200
-simul_axi_hp_wr -simul_axi_hp_wr
@800200 @c00200
-ahci_dma -ahci_dma
@200 @200
- -
@800200 @800200
-debug_non_prefetchable -debug_non_prefetchable
@29
tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.condition_mux_i.XFER0
@28 @28
tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.condition_mux_i.XFER0
tb_ahci.dut.sata_top.ahci_top_i.dma_cmd_busy tb_ahci.dut.sata_top.ahci_top_i.dma_cmd_busy
tb_ahci.dut.sata_top.ahci_top_i.dma_cmd_done tb_ahci.dut.sata_top.ahci_top_i.dma_cmd_done
tb_ahci.dut.sata_top.ahci_top_i.ahci_fis_receive_i.dma_prds_done tb_ahci.dut.sata_top.ahci_top_i.ahci_fis_receive_i.dma_prds_done
...@@ -3846,7 +3849,7 @@ tb_ahci.simul_axi_hp_rd_i.rdata_i.out_full ...@@ -3846,7 +3849,7 @@ tb_ahci.simul_axi_hp_rd_i.rdata_i.out_full
-top -top
@200 @200
- -
@1000200 @1401200
-ahci_dma -ahci_dma
@c00200 @c00200
-datascope0 -datascope0
...@@ -3897,6 +3900,12 @@ tb_ahci.dut.sata_top.ahci_top_i.datascope_di[31:0] ...@@ -3897,6 +3900,12 @@ tb_ahci.dut.sata_top.ahci_top_i.datascope_di[31:0]
-datascope0 -datascope0
@800200 @800200
-link -link
@28
tb_ahci.dut.sata_top.ahci_sata_layers_i.link.data_val_out
tb_ahci.dut.sata_top.ahci_sata_layers_i.link.data_last_out
tb_ahci.dut.sata_top.ahci_sata_layers_i.link.set_rcvr_eof
tb_ahci.dut.sata_top.ahci_sata_layers_i.link.alignes_pair
tb_ahci.dut.sata_top.ahci_sata_layers_i.link.data_strobe_out
@22 @22
tb_ahci.dut.sata_top.ahci_sata_layers_i.link.data_in[31:0] tb_ahci.dut.sata_top.ahci_sata_layers_i.link.data_in[31:0]
@28 @28
...@@ -4022,6 +4031,46 @@ tb_ahci.dut.sata_top.ahci_sata_layers_i.link.set_nocommerr ...@@ -4022,6 +4031,46 @@ tb_ahci.dut.sata_top.ahci_sata_layers_i.link.set_nocommerr
tb_ahci.dut.sata_top.ahci_sata_layers_i.link.set_reset tb_ahci.dut.sata_top.ahci_sata_layers_i.link.set_reset
tb_ahci.dut.sata_top.ahci_sata_layers_i.link.set_sync_esc tb_ahci.dut.sata_top.ahci_sata_layers_i.link.set_sync_esc
tb_ahci.dut.sata_top.ahci_sata_layers_i.link.got_escape tb_ahci.dut.sata_top.ahci_sata_layers_i.link.got_escape
@800200
-scrambler
@28
tb_ahci.dut.sata_top.ahci_sata_layers_i.link.scrambler.val_in
@22
tb_ahci.dut.sata_top.ahci_sata_layers_i.link.scrambler.data_in[31:0]
tb_ahci.dut.sata_top.ahci_sata_layers_i.link.scrambler.data_out[31:0]
@200
-
@1000200
-scrambler
@28
tb_ahci.dut.sata_top.ahci_sata_layers_i.link.is_align_p_w
@c00022
tb_ahci.dut.sata_top.ahci_sata_layers_i.link.rcvd_dword[15:0]
@28
(0)tb_ahci.dut.sata_top.ahci_sata_layers_i.link.rcvd_dword[15:0]
(1)tb_ahci.dut.sata_top.ahci_sata_layers_i.link.rcvd_dword[15:0]
(2)tb_ahci.dut.sata_top.ahci_sata_layers_i.link.rcvd_dword[15:0]
(3)tb_ahci.dut.sata_top.ahci_sata_layers_i.link.rcvd_dword[15:0]
(4)tb_ahci.dut.sata_top.ahci_sata_layers_i.link.rcvd_dword[15:0]
(5)tb_ahci.dut.sata_top.ahci_sata_layers_i.link.rcvd_dword[15:0]
(6)tb_ahci.dut.sata_top.ahci_sata_layers_i.link.rcvd_dword[15:0]
(7)tb_ahci.dut.sata_top.ahci_sata_layers_i.link.rcvd_dword[15:0]
(8)tb_ahci.dut.sata_top.ahci_sata_layers_i.link.rcvd_dword[15:0]
(9)tb_ahci.dut.sata_top.ahci_sata_layers_i.link.rcvd_dword[15:0]
(10)tb_ahci.dut.sata_top.ahci_sata_layers_i.link.rcvd_dword[15:0]
(11)tb_ahci.dut.sata_top.ahci_sata_layers_i.link.rcvd_dword[15:0]
(12)tb_ahci.dut.sata_top.ahci_sata_layers_i.link.rcvd_dword[15:0]
(13)tb_ahci.dut.sata_top.ahci_sata_layers_i.link.rcvd_dword[15:0]
(14)tb_ahci.dut.sata_top.ahci_sata_layers_i.link.rcvd_dword[15:0]
(15)tb_ahci.dut.sata_top.ahci_sata_layers_i.link.rcvd_dword[15:0]
@1401200
-group_end
@28
tb_ahci.dut.sata_top.ahci_sata_layers_i.link.next_will_be_data
tb_ahci.dut.sata_top.ahci_sata_layers_i.link.set_rcvr_data
tb_ahci.dut.sata_top.ahci_sata_layers_i.link.state_rcvr_data
tb_ahci.dut.sata_top.ahci_sata_layers_i.link.set_rcvr_shold
tb_ahci.dut.sata_top.ahci_sata_layers_i.link.state_rcvr_shold
@200 @200
- -
@22 @22
...@@ -4593,8 +4642,64 @@ tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtx_comma_align.comma_detec ...@@ -4593,8 +4642,64 @@ tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtx_comma_align.comma_detec
- -
@1401200 @1401200
-comma -comma
@c00201
-elastic_phy
@c00022
tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
@28
(0)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(1)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(2)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(3)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(4)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(5)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(6)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(7)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(8)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(9)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(10)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(11)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(12)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(13)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(14)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(15)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(16)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(17)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(18)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(19)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(20)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(21)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(22)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(23)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(24)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(25)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(26)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(27)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(28)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(29)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(30)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
(31)tb_ahci.dut.sata_top.ahci_sata_layers_i.debug_phy0[31:0]
@1401200
-group_end
@22
tb_ahci.dut.sata_top.ahci_top_i.axi_ahci_regs_i.debug_in1[31:0]
@200
-
@28
tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.elastic1632_i.is_alignp_w
tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.elastic1632_i.isaligned_in
tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.elastic1632_i.msb_in_r
tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.elastic1632_i.inc_waddr
@22
tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.elastic1632_i.waddr[4:0]
@200
-
@1401201
-elastic_phy
@c00200 @c00200
-elastic_slow -elastic_slow
@200
-
@28 @28
tb_ahci.elastic1632_slow_i.wclk tb_ahci.elastic1632_slow_i.wclk
tb_ahci.elastic1632_slow_i.rclk tb_ahci.elastic1632_slow_i.rclk
...@@ -4698,6 +4803,8 @@ tb_ahci.elastic1632_slow_i.dbg_diff[4:0] ...@@ -4698,6 +4803,8 @@ tb_ahci.elastic1632_slow_i.dbg_diff[4:0]
-elastic_slow -elastic_slow
@c00200 @c00200
-elastic_fast -elastic_fast
@200
-
@28 @28
tb_ahci.elastic1632_fast_i.wclk tb_ahci.elastic1632_fast_i.wclk
tb_ahci.elastic1632_fast_i.rclk tb_ahci.elastic1632_fast_i.rclk
...@@ -4832,7 +4939,7 @@ tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.usrpll_locked ...@@ -4832,7 +4939,7 @@ tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.usrpll_locked
tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.rxresetdone_gtx tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.rxresetdone_gtx
@1401200 @1401200
-debug_hba_reset -debug_hba_reset
@800200 @c00200
-oob_ctrl -oob_ctrl
@28 @28
tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.oob_ctrl.gtx_ready tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.oob_ctrl.gtx_ready
...@@ -4877,6 +4984,7 @@ tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.dbg_clk_align_cntr[15:0] ...@@ -4877,6 +4984,7 @@ tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.dbg_clk_align_cntr[15:0]
- -
@1000200 @1000200
-oob -oob
@1401200
-oob_ctrl -oob_ctrl
@c00200 @c00200
-sipo_meas -sipo_meas
...@@ -5176,9 +5284,25 @@ tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.txdata_enc_out[19:0] ...@@ -5176,9 +5284,25 @@ tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.txdata_enc_out[19:0]
-gtx -gtx
@200 @200
- -
@c00200 @800200
-device -device
@820 @820
tb_ahci.dev.DEV_TITLE[639:0]
@800200
-linkTransmitFIS
@22
tb_ahci.dev.dev2phy_data[31:0]
tb_ahci.dev.linkTransmitFIS.scrambler_value[31:0]
@820
tb_ahci.dev.linkTransmitFIS.rprim[111:0]
@22
tb_ahci.dev.linkTransmitFIS.cnt
tb_ahci.dev.DEV_DATA
@1000200
-linkTransmitFIS
@200
-
@820
tb_ahci.dev.linkMonitorFIS.rprim[111:0] tb_ahci.dev.linkMonitorFIS.rprim[111:0]
tb_ahci.dev.linkSendPrim.type[111:0] tb_ahci.dev.linkSendPrim.type[111:0]
@22 @22
...@@ -5227,9 +5351,9 @@ tb_ahci.dev.phy.gtx_wrapper.gtx_gpl.channel.tx.TXN ...@@ -5227,9 +5351,9 @@ tb_ahci.dev.phy.gtx_wrapper.gtx_gpl.channel.tx.TXN
-dev_phy -dev_phy
@820 @820
tb_ahci.dev.linkSendPrim.type[111:0] tb_ahci.dev.linkSendPrim.type[111:0]
@1401200 @1000200
-device -device
@800200 @c00200
-datascope -datascope
@200 @200
- -
...@@ -5358,7 +5482,6 @@ tb_ahci.dut.sata_top.ahci_top_i.datascope_waddr[9:0] ...@@ -5358,7 +5482,6 @@ tb_ahci.dut.sata_top.ahci_top_i.datascope_waddr[9:0]
(9)tb_ahci.dut.sata_top.ahci_top_i.datascope_waddr[9:0] (9)tb_ahci.dut.sata_top.ahci_top_i.datascope_waddr[9:0]
@1401200 @1401200
-group_end -group_end
@1000200
-datascope -datascope
@c00200 @c00200
-frequency_meter -frequency_meter
......
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