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

Fixed link FSM error mishandling sender hold

parent fcb4bd93
......@@ -52,87 +52,87 @@
<link>
<name>vivado_logs/VivadoBitstream.log</name>
<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>
<name>vivado_logs/VivadoOpt.log</name>
<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>
<name>vivado_logs/VivadoOptPhys.log</name>
<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>
<name>vivado_logs/VivadoOptPower.log</name>
<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>
<name>vivado_logs/VivadoPlace.log</name>
<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>
<name>vivado_logs/VivadoRoute.log</name>
<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>
<name>vivado_logs/VivadoSynthesis.log</name>
<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>
<name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name>
<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>
<name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name>
<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>
<name>vivado_logs/VivadoTimingReportImplemented.log</name>
<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>
<name>vivado_logs/VivadoTimingReportSynthesis.log</name>
<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>
<name>vivado_state/x393_sata-opt-phys.dcp</name>
<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>
<name>vivado_state/x393_sata-opt-power.dcp</name>
<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>
<name>vivado_state/x393_sata-opt.dcp</name>
<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>
<name>vivado_state/x393_sata-place.dcp</name>
<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>
<name>vivado_state/x393_sata-route.dcp</name>
<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>
<name>vivado_state/x393_sata-synth.dcp</name>
<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>
</linkedResources>
</projectDescription>
......@@ -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_pio, // update PxTFD.STS and PxTFD.ERR from pio_* (entry PIO:Update)
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_set_drq, // clear PxTFD.STS.BSY and sets PxTFD.STS.DRQ, update
input set_bsy, // set PxTFD.STS.BSY, update
......@@ -76,7 +77,12 @@ module ahci_fis_receive#(
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 [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
......@@ -126,9 +132,10 @@ CLB_OFFS = 0x800 # In the second half of the register space (0x800..0xbff - 1KB)
FB_OFFS = 0xc00 # Needs 0x100 bytes
#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 HBA_OFFS32 = 0;
localparam HBA_PORT0_OFFS32 = 'h40;
......@@ -387,8 +394,18 @@ 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]} -
{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;
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]};
// 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]};
xfer_cntr_zero_r <= xfer_cntr_r[31:2] == 0;
......
......@@ -291,7 +291,7 @@ module ahci_fsm
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 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_en) || pcmd_st_cleared;
// OK to wait for some time fsm_act_busy is supposed to never hang up
......@@ -396,8 +396,9 @@ module ahci_fsm
else if (fsm_pre_act_w) fsm_act_busy <= fsm_wait_act_w;
else if (fsm_act_done) fsm_act_busy <= 0;
if (pcmd_st_cleared) async_from_st <= 1;
else if (asynq_rq) async_from_st <= 0;
if (hba_rst) async_from_st <= 0;
else if (pcmd_st_cleared) async_from_st <= 1;
else if (asynq_rq) async_from_st <= 0;
if (hba_rst) async_pend_r <= 0;
/// else async_pend_r <= {async_pend_r[0], asynq_rq | (async_pend_r[0] & ~async_ackn)};
......
......@@ -212,6 +212,9 @@ module ahci_sata_layers #(
wire debug_detected_alignp; // oob detects ALIGNp, but not the link layer
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 = debug_link[31:0]; //
/// assign debug_sata = debug_phy;
......@@ -261,6 +264,7 @@ module ahci_sata_layers #(
if (d2h_fifo_wr) debug_last_d2h_type_in<= d2h_type_in;
if (d2h_fifo_rd) debug_last_d2h_type<= d2h_type;
end
/*
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],
......@@ -272,6 +276,22 @@ module ahci_sata_layers #(
d2h_waddr[1:0],
d2h_raddr[1: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[19:0]};
......@@ -289,7 +309,7 @@ module ahci_sata_layers #(
// .comwake_got (serr_DW), // output wire
assign datascope_di = {5'b0,debug_link[5],datascope0_di[25:0]};// aligns_pair tx
link #(
.DATA_BYTE_WIDTH(4)
) link (
......@@ -412,10 +432,10 @@ module ahci_sata_layers #(
.datascope_clk (datascope_clk), // output
.datascope_waddr (datascope_waddr), // output[9:0]
.datascope_we (datascope_we), // output
.datascope_di (datascope_di), // output[31:0]
// .datascope_trig (ll_incom_invalidate ), // ll_frame_ackn), // input datascope external trigger
.datascope_di (datascope0_di), // output[31:0]
.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] == 'h02), // state_rcvr_goodcrc // input datascope external trigger
/// .datascope_trig (debug_link[4:0] == 'h02), // state_rcvr_goodcrc // input datascope external trigger
//debug_link
`endif
......
......@@ -684,8 +684,30 @@ module ahci_top#(
wire debug_data_in_ready; // output
wire debug_fis_end_w; // output
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 #(
.ADDRESS_BITS (ADDRESS_BITS),
......@@ -745,12 +767,29 @@ wire[1:0] debug_get_fis_busy_r; // output[1:0]
.afi_cache_set (set_axi_cache_mode), // output
.was_hba_rst (was_hba_rst), // output
.was_port_rst (was_port_rst), // output
/*
.debug_in0 ({ debug_data_in_ready, // output
debug_fis_end_w, // output
xfer_cntr_zero,
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_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_dma1[23:0]}), // debug_in_link), // input[31:0]
.debug_in1 ({debug_in_link[15:8],
......@@ -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_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_set_drq (frcv_clear_bsy_set_drq), // input
......
......@@ -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
integer i;
begin
clear_transmit_pause(0);
// $readmemh("input_data/identify.dat",identify_data);
$readmemh("input_data/test512.dat",identify_data);
transmit_data[0] = FIS_DATA;
......@@ -856,6 +857,7 @@ task send_incrementing_data; // @SuppressThisWarning VEditor - Used in testbench
output integer status;
integer i;
begin
clear_transmit_pause(0);
transmit_data[0] = FIS_DATA;
for (i=0;i<len;i=i+1) begin
transmit_data[i+1] = i;
......@@ -864,6 +866,23 @@ task send_incrementing_data; // @SuppressThisWarning VEditor - Used in testbench
end
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
input integer size; // dwords count
input integer transmit_custom_crc;
output integer status;
integer pause;
integer xpause;
integer cnt;
integer crc;
reg [111:0] rprim;
......@@ -958,17 +977,21 @@ task linkTransmitFIS; // @SuppressThisWarning VEditor - Used in testbench
end
// L_SendData + L_RcvrHold + L_SendHold
cnt = 0;
pause = transmit_data_pause[0];
xpause = transmit_data_pause[0];
while (cnt < size) begin
// scrambler_value = scrambleFunc(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);
crc = calculateCRC(crc, transmit_data[cnt]);
// $display("[Device] LINK: Sent data = %h", transmit_data[cnt]);
DEV_TITLE = "Sent data";
DEV_DATA = transmit_data[cnt];
$display("[Device] LINK: %s = %h (#%d) @%t", DEV_TITLE, DEV_DATA, cnt, $time);
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]});
linkSendData(transmit_data[cnt] ^ scrambler_value);
crc = calculateCRC(crc, transmit_data[cnt]);
DEV_TITLE = "Sent data";
DEV_DATA = transmit_data[cnt];
$display("[Device] LINK: %s = %h (#%d) @%t", DEV_TITLE, DEV_DATA, cnt, $time);
end
@ (posedge clk)
rprim = linkGetPrim(0);
if (rprim == "SYNC") begin
......@@ -978,43 +1001,33 @@ task linkTransmitFIS; // @SuppressThisWarning VEditor - Used in testbench
$display("[Device] LINK: %s, transmission id = %d @%t", DEV_TITLE, DEV_DATA, $time);
#100;
$finish;
end
if ((rprim == "SCRAP") || (rprim == "DATA")) begin
end else 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);
DEV_TITLE = "Bad primitives from the host #6";
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);
#100;
$finish;
end
else
if (rprim == "DMAT") begin
end else if (rprim == "DMAT") begin
// $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;
$display("[Device] LINK: %s, transmission id = %d @%t", DEV_TITLE, DEV_DATA, $time);
#100;
$finish;
end
else
if (pause > 0) begin
// $display("[Device] LINK: Transmission is paused");
DEV_TITLE = "Transmission is paused";
$display("[Device] LINK: %s @%t", DEV_TITLE, $time);
linkSendPrim("HOLD");
pause = pause - 1;
end
else
if (rprim == "HOLD") begin
// $display("[Device] LINK: The host asked for a pause, acknowledging");
end else if (xpause > 0) begin
// DEV_TITLE = "Transmission is paused";
// $display("[Device] LINK: %s @%t", DEV_TITLE, $time);
// linkSendPrim("HOLD");
xpause = xpause - 1;
end else if (rprim == "HOLD") begin
DEV_TITLE = "The host asked for a pause, acknowledging transmission paused";
$display("[Device] LINK: %s @%t", DEV_TITLE, $time);
linkSendPrim("HOLDA");
end
else begin
end else begin
cnt = cnt + 1;
if (cnt < size)
pause = transmit_data_pause[cnt];
xpause = transmit_data_pause[cnt];
end
end
// L_SendCRC
......
......@@ -37,6 +37,7 @@
//`include "gtx_elastic.v"
// All computations have been done in assumption of GTX interface being 20 bits wide!
//`include "system_defines.v"
`define DEBUG_ELASTIC
module gtx_wrap #(
`ifdef USE_DATASCOPE
parameter ADDRESS_BITS = 10, // for datascope
......@@ -128,6 +129,10 @@ module gtx_wrap #(
output drp_rdy,
output [15:0] drp_do
`endif
`ifdef DEBUG_ELASTIC
,output reg [15:0] dbg_data_cntr // 4 MSB - got other primitives during data receive
`endif
......@@ -727,6 +732,87 @@ wire rxcominitdet_gtx;
.full (rxelsfull), // 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 txresetdone_r;
......
......@@ -176,8 +176,8 @@ always @ (posedge clk) begin
phy_err_in_r <= phy_err_in_r0;
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
wire data_txing = data_txing_r & ~state_send_crc;
......@@ -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_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_shold & dword_val_na & ~rcvd_dword[CODE_HOLDP] & ~rcvd_dword[CODE_EOFP] & ~rcvd_dword[CODE_SYNCP];
// | state_rcvr_rhold & dword_val_na & ~rcvd_dword[CODE_HOLDP] & ~rcvd_dword[CODE_EOFP] & ~rcvd_dword[CODE_SYNCP] & ~data_busy_in
| 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_shold = state_rcvr_data & dword_val & rcvd_dword[CODE_HOLDP]
......@@ -1246,7 +1248,7 @@ always @ (posedge clk)
, state_rcvr_badend
};
$display("%m: invalid states: %b", sim_states_concat);
$finish;
// $finish;
end
`endif
......
......@@ -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] rxnotintable;
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;
// once gtx_ready -> 1, gtx_configured latches
......@@ -551,7 +553,7 @@ gtx_wrap
.datascope_waddr (datascope_waddr), // output[9:0]
.datascope_we (datascope_we), // output
.datascope_di (datascope_di), // output[31:0]
.datascope_trig (datascope_trig) // inpuit // external trigger event for the datascope
.datascope_trig (datascope_trig) // input // external trigger event for the datascope
`endif
`ifdef USE_DRP
......@@ -564,6 +566,9 @@ gtx_wrap
.drp_rdy (drp_rdy), // output
.drp_do (drp_do) // output[15:0]
`endif
`ifdef DEBUG_ELASTIC
,.dbg_data_cntr (dbg_data_cntr) // output[11:0] reg
`endif
);
......@@ -656,6 +661,12 @@ always @ (posedge clk) begin
else if (dbg_rxphaligndone_down && dbg_rxphaligndone) dbg_rxphaligndone_second <= 1;
*/
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[ 7: 4] = debug_cntr2;
......@@ -678,10 +689,17 @@ assign debug_sata[23:20] = debug_cntr4;
//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};
`ifdef USE_DATASCOPE
assign debug_sata = {txbufstatus[1:0], rxelecidle, dbg_rxcdrlock, rxelsfull, rxelsempty, dbg_rxphaligndone, dbg_rx_clocks_aligned,
error_count[11:0],
/// assign debug_sata = {txbufstatus[1:0], rxelecidle, dbg_rxcdrlock, rxelsfull, rxelsempty, dbg_rxphaligndone, dbg_rx_clocks_aligned,
/// 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,
datascope_waddr[9:0]};
//dbg_data_cntr
`else
assign debug_sata = {8'b0, dbg_clk_align_cntr, txbufstatus[1:0], rxelecidle, dbg_rxcdrlock, rxelsfull, rxelsempty, dbg_rxphaligndone, dbg_rx_clocks_aligned};
`endif
......
......@@ -40,6 +40,11 @@ class x393_vsc3304(object):
DRY_MODE= True # True
DEBUG_MODE=1
x393_mem=None
OUTPUT_LEVELS = {
"ESATA_A": 3,
"ESATA_B": 3,
"SSD_B": 2,
"ZYNQ_A": 2}
PCB_CONNECTIONS = {
"10389": {
"INVERTED_PORTS": ("D","E","G","H"),
......@@ -164,6 +169,8 @@ class x393_vsc3304(object):
self.echo("1", "input_state_invert/"+self.in_port(port_letter))
self.echo("10","output_mode/"+self.out_port(port_letter))
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"
def connect(self, mode):
......
......@@ -379,24 +379,35 @@ class x393sata(object):
if quiet < 4 :
print ("Reset OFF")
self.reset(0xa)
self.set_zynq()
self.set_zynq_ssd()
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()
if self.DEBUG_MODE:
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()
if self.DEBUG_MODE:
self.vsc3304.connection_status()
def set_debug(self):
def set_debug_oscilloscope(self):
self.vsc3304.connect_debug()
if self.DEBUG_MODE:
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):
c0 = self.x393_mem.read_mem(0x80000ff0)
......@@ -1200,6 +1211,7 @@ class x393sata(object):
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) & 0x3f #temporarily reduced as same bits are used for other data
def err_rate(self, dly = 0.1):
ec0 = self.err_count()
......@@ -1334,13 +1346,14 @@ class x393sata(object):
return pair[0].replace('p','h')
return None
b = ((dword >> 0) & 0xff, (dword >> 8) & 0xff)
k = ((dword >> 16) & 0x1, (dword >> 17) & 0x1)
d = ((dword >> 18) & 0x1, (dword >> 19) & 0x1)
t = ((dword >> 18) & 0x1, (dword >> 19) & 0x1)
aligned = (dword >> 22) & 0x1
comma = (dword >> 24) & 0x1
realign = (dword >> 25) & 0x1
b = ((dword >> 0) & 0xff, (dword >> 8) & 0xff)
k = ((dword >> 16) & 0x1, (dword >> 17) & 0x1)
d = ((dword >> 18) & 0x1, (dword >> 19) & 0x1)
t = ((dword >> 18) & 0x1, (dword >> 19) & 0x1)
aligned = (dword >> 22) & 0x1
comma = (dword >> 24) & 0x1