Commit 50ca592a authored by Andrey Filippov's avatar Andrey Filippov

got identify PIO data from the SSD

parent 0a15e1e3
......@@ -52,87 +52,87 @@
<link>
<name>vivado_logs/VivadoBitstream.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160204125242916.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160205231700944.log</location>
</link>
<link>
<name>vivado_logs/VivadoOpt.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160204125242916.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160205231700944.log</location>
</link>
<link>
<name>vivado_logs/VivadoOptPhys.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160204125242916.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160205231700944.log</location>
</link>
<link>
<name>vivado_logs/VivadoOptPower.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160204125242916.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160205231700944.log</location>
</link>
<link>
<name>vivado_logs/VivadoPlace.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160204125242916.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160205231700944.log</location>
</link>
<link>
<name>vivado_logs/VivadoRoute.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160204125242916.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160205231700944.log</location>
</link>
<link>
<name>vivado_logs/VivadoSynthesis.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160204124820270.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160205231700944.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160204125242916.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160205231700944.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160204124820270.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160205231700944.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimingReportImplemented.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160204125242916.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160205231700944.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimingReportSynthesis.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160204124820270.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160205231700944.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-20160204125242916.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-20160205231700944.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-20160204125242916.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-20160205231700944.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-20160204125242916.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-20160205231700944.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-20160204125242916.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-place-20160205231700944.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-20160204125242916.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-route-20160205231700944.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-20160204124820270.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-synth-20160205231700944.dcp</location>
</link>
</linkedResources>
</projectDescription>
......@@ -467,7 +467,8 @@ localparam PxCMD_MASK = HBA_PORT__PxCMD__ICC__MASK | // 'hf0000000;
else if (pfsm_started) pfsm_started_r <= 1;
if (!pfsm_started_r) pcmd_st_cleared <= 0;
else if (swr_HBA_PORT__PxCMD) pcmd_st_cleared <= |(HBA_PORT__PxCMD__ST__MASK & PxCMD_r & ~soft_write_data);
// else if (swr_HBA_PORT__PxCMD) pcmd_st_cleared <= |(HBA_PORT__PxCMD__ST__MASK & PxCMD_r & ~soft_write_data);
else pcmd_st_cleared <= swr_HBA_PORT__PxCMD && (|(HBA_PORT__PxCMD__ST__MASK & PxCMD_r & ~soft_write_data));
end
......@@ -487,7 +488,7 @@ localparam PxCMD_MASK = HBA_PORT__PxCMD__ICC__MASK | // 'hf0000000;
({32{update_HBA_PORT__PxCMD}} & PxCMD_r) |
({32{update_HBA_PORT__PxCI}} & {31'b0, pxci0});
regs_we <= update_GHC__IS || update_HBA_PORT__PxIS || update_HBA_PORT__PxSSTS || update_HBA_PORT__PxSERR | update_HBA_PORT__PxCMD;
regs_we <= update_GHC__IS || update_HBA_PORT__PxIS || update_HBA_PORT__PxSSTS || update_HBA_PORT__PxSERR | update_HBA_PORT__PxCMD || update_HBA_PORT__PxCI;
// pending updates
if (mrst) pxci_changed <= 1; //0;
......
......@@ -100,6 +100,8 @@ module ahci_fis_transmit #(
output todev_valid, // output register full
input todev_ready // send FIFO has room for data (>= 8? dwords)
,output [9:0] debug_01
// Add a possiblity to flush any data to FIFO if error was detected after data went there?
);
localparam CLB_OFFS32 = 'h200; // # In the second half of the register space (0x800..0xbff - 1KB)
......@@ -152,6 +154,7 @@ module ahci_fis_transmit #(
wire ct_re_w; // next cycle will be ct_re;
reg [READ_CT_LATENCY:0] ct_re_r;
wire ct_stb = ct_re_r[READ_CT_LATENCY];
reg fis_dw_first;
......@@ -204,7 +207,9 @@ module ahci_fis_transmit #(
// What else to wait for when
assign fis_data_valid = ct_stb || (!dma_ct_busy && dx_fis_pend_r); // no wait write to output register 'todev_data', ct_re_r[0] is throttled according to FIFO room availability
assign ct_re_w = todev_ready && ((cfis_acmd_left_r[4:1] != 0) || (cfis_acmd_left_r[0] && !ct_re_r[0])); // Later add more sources
/// assign ct_re_w = todev_ready && ((cfis_acmd_left_r[4:1] != 0) || (cfis_acmd_left_r[0] && !ct_re_r[0])); // Later add more sources
assign ct_re_w = todev_ready && acfis_xmit_busy_r && ((cfis_acmd_left_r[4:1] != 0) || (cfis_acmd_left_r[0] && !ct_re_r[0])); // Later add more sources
//
assign fis_dw_last = (cfis_acmd_left_out_r == 1);
assign fis_data_type = {fis_dw_last, (write_or_w && dx_fis_pend_r) | (fis_dw_first && ct_stb)};
......@@ -219,6 +224,11 @@ module ahci_fis_transmit #(
// When watching for FIS end, do not fill/use output register in the same cycle
reg [3:0] dbg_was_ct_re_r;
reg [4:0] dbg_was_cfis_acmd_left_r;
always @ (posedge mclk) begin
// Mutliplex between DMA and FIS output to the output routed to transmit FIFO
// Count bypassing DMA dwords to generate FIS_last condition?
......@@ -308,7 +318,8 @@ module ahci_fis_transmit #(
if (acfis_xmit_start_r) cfis_acmd_left_out_r <= cfis_acmd_left_r;
else if (ct_stb) cfis_acmd_left_out_r <= cfis_acmd_left_out_r - 1;
ct_re_r <= {ct_re_r[READ_CT_LATENCY-1:0],ct_re_w};
if (hba_rst || acfis_xmit_start_w) ct_re_r <= 0;
else ct_re_r <= {ct_re_r[READ_CT_LATENCY-1:0], ct_re_w};
if (cfis_xmit) ct_addr <= 0;
else if (atapi_xmit) ct_addr <= 'h10; // start of ATAPI area
......@@ -369,8 +380,15 @@ module ahci_fis_transmit #(
dma_cmd_abort <= done_w && (|dx_err_r);
if (cfis_xmit) dbg_was_ct_re_r <= {ct_re_r, ct_re_w};
if (cfis_xmit) dbg_was_cfis_acmd_left_r <= cfis_acmd_left_r;
end
assign debug_01 = {dx_fis_pend_r, ct_re_r, ct_re_w, cfis_acmd_left_r}; // 1,2,5
// assign debug_01 = {acfis_xmit_start_w, acfis_xmit_pend_r, dma_ct_busy, fetch_cmd_busy_r, ct_re_w, dbg_was_cfis_acmd_left_r}; // 1,2,5
// wire acfis_xmit_start_w = (cfis_xmit || atapi_xmit || acfis_xmit_pend_r) && !dma_ct_busy && !fetch_cmd_busy_r; // dma_ct_busy no gaps with fetch_cmd_busy
endmodule
......@@ -274,6 +274,7 @@ module ahci_fsm
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
wire asynq_rq = cominit_got || pcmd_st_cleared;
// OK to wait for some time fsm_act_busy is supposed to never hang up
wire async_ackn = !fsm_preload && async_pend_r[0] && ((fsm_actions && !update_busy && !fsm_act_busy) || fsm_transitions[0]); // OK to process async jump
// reg x_rdy_collision_pend;
reg syncesc_send_pend; // waiting for 'syncesc_send' confiramtion 'syncesc_send_done'
......@@ -358,7 +359,8 @@ module ahci_fsm
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)};
/// else async_pend_r <= {async_pend_r[0], asynq_rq | (async_pend_r[0] & ~async_ackn)};
else async_pend_r <= {async_pend_r[0], (asynq_rq | async_pend_r[0]) & ~async_ackn};
// if (hba_rst || pcmd_cr_set) x_rdy_collision_pend <= 0;
......
......@@ -183,7 +183,8 @@ module ahci_sata_layers #(
/// assign debug_sata = debug_phy;
// assign debug_sata = {debug_link[31:4],debug_phy[3:0]} ; //
assign debug_sata = {debug_link[31:8],debug_phy[7:0]} ; //
// assign debug_sata = {debug_link[31:8],debug_phy[7:0]} ; //
assign debug_sata = {debug_link[27:20],debug_phy[23:0]} ; //
assign ll_h2d_last = (h2d_type_out == H2D_TYPE_FIS_LAST);
assign d2h_valid = d2h_nempty;
......
......@@ -187,6 +187,14 @@ module ahci_top#(
);
`ifdef USE_DATASCOPE
// Datascope interface (write to memory that can be software-read)
wire datascope_clk;
wire [ADDRESS_BITS-1:0] datascope_waddr;
wire datascope_we;
wire [31:0] datascope_di;
`endif
// axi_ahci_regs signals:
// 1. Notification of data written @ hba_clk
wire [ADDRESS_BITS-1:0] soft_write_addr; // register address written by software
......@@ -691,6 +699,12 @@ module ahci_top#(
.was_hba_rst (was_hba_rst), // output
.was_port_rst (was_port_rst), // output
.debug_in ({2'b0, last_jump_addr[9:0], debug_in[19:0]})
`ifdef USE_DATASCOPE
,.datascope_clk (datascope_clk), // input
.datascope_waddr (datascope_waddr), // input[9:0]
.datascope_we (datascope_we), // input
.datascope_di (datascope_di) // input[31:0]
`endif
/// .debug_in (debug_in[31:0])
);
ahci_ctrl_stat #(
......@@ -938,7 +952,8 @@ module ahci_top#(
.dma_in_ready (dma_in_ready), // input
.dma_in_valid (dma_we) // output
);
wire ahci_fis_transmit_busy;
wire [9:0] xmit_dbg_01;
ahci_fis_transmit #(
.PREFETCH_ALWAYS (PREFETCH_ALWAYS),
.READ_REG_LATENCY (READ_REG_LATENCY),
......@@ -955,7 +970,7 @@ module ahci_top#(
.atapi_xmit (fsnd_atapi_xmit), // input
.done (fsnd_done), // output reg
.busy (), /// fsnd_busy), // output reg
.busy (ahci_fis_transmit_busy), /// fsnd_busy), // output reg
.clearCmdToIssue (fsnd_clearCmdToIssue), // input
.pCmdToIssue (fsnd_pCmdToIssue), // output
.xmit_ok (xmit_ok), // input
......@@ -995,8 +1010,47 @@ module ahci_top#(
.todev_type (h2d_type), // output[1:0] reg
.todev_valid (h2d_valid), // output
.todev_ready (h2d_ready) // input
,.debug_01(xmit_dbg_01)
);
// Datascope code
`ifdef USE_DATASCOPE
// Datascope interface (write to memory that can be software-read)
// wire datascope_clk;
// wire [ADDRESS_BITS-1:0] datascope_waddr;
// wire datascope_we;
// wire [31:0] datascope_di;
localparam DATASCOPE_CFIS_START=0;
reg [ADDRESS_BITS-1:0] datascope_waddr_r;
reg [1:0] datascope_run;
reg [8:0] datascope_cntr;
reg datascope_was_busy;
assign datascope_clk = mclk;
// assign datascope_di = datascope_run[0]? {h2d_type, dma_dav, datascope_was_busy, xmit_dbg_01, datascope_cntr[3:0], h2d_data[15:0]} : {{32-ADDRESS_BITS{1'b0}},datascope_waddr_r};
assign datascope_di = datascope_run[0]? {h2d_type, xmit_dbg_01, datascope_cntr[3:0], h2d_data[15:0]} : {{32-ADDRESS_BITS{1'b0}},datascope_waddr_r};
assign datascope_we = (datascope_run[0] && h2d_valid && h2d_ready) || (datascope_run == 2);
assign datascope_waddr = datascope_waddr_r;
always @(posedge mclk) begin
if (mrst) datascope_run[0] <= 0;
else if (fsnd_cfis_xmit) datascope_run[0] <= 1;
else if (h2d_valid && h2d_ready && (h2d_type == 2)) datascope_run[0] <= 0;
datascope_run[1] <= datascope_run[0];
if (fsnd_cfis_xmit) datascope_waddr_r <= DATASCOPE_CFIS_START;
else if (datascope_we) datascope_waddr_r <= datascope_waddr_r + 1;
if (fsnd_cfis_xmit) datascope_cntr <= 0;
else datascope_cntr <= datascope_cntr + 1;
if (fsnd_cfis_xmit) datascope_was_busy <= ahci_fis_transmit_busy;
end
`endif
endmodule
......@@ -116,30 +116,28 @@ module axi_ahci_regs#(
output was_hba_rst, // last reset was hba reset (not counting system reset)
output was_port_rst, // last reset was port reset
input [31:0] debug_in
`ifdef USE_DATASCOPE
// Datascope interface (write to memory that can be software-read)
,input datascope_clk,
input [ADDRESS_BITS-1:0] datascope_waddr,
input datascope_we,
input [31:0] datascope_di
`endif
);
`ifdef USE_DATASCOPE
localparam AXIBRAM_BITS = ADDRESS_BITS + 1; // number of axi address outputs (one more than ADDRESS_BITS when using datascope)
wire [31:0] datascope_rdata;
reg [1:0] datascope_sel; // read datascope memory instead of the registers
always @ (posedge aclk) begin
datascope_sel <= {datascope_sel[0], bram_raddr[ADDRESS_BITS]};
end
`else
localparam AXIBRAM_BITS = ADDRESS_BITS; // number of axi address outputs (one more than ADDRESS_BITS when using datascope)
`endif
`include "includes/ahci_localparams.vh" // @SuppressThisWarning VEditor : Unused localparams
/*
localparam GHC__GHC__HR__ADDR = 'h1;
localparam GHC__GHC__HR__MASK = 'h1;
localparam GHC__GHC__HR__DFLT = 'h0;
// RO: Device Detection Initialization
localparam HBA_PORT__PxSCTL__DET__ADDR = 'h4b;
localparam HBA_PORT__PxSCTL__DET__MASK = 'hf;
localparam HBA_PORT__PxSCTL__DET__DFLT = 'h0;
// RW: SAXIHP write channel cache mode
localparam HBA_PORT__AFI_CACHE__WR_CM__ADDR = 'h5c;
localparam HBA_PORT__AFI_CACHE__WR_CM__MASK = 'hf0;
localparam HBA_PORT__AFI_CACHE__WR_CM__DFLT = 'h30;
// RW: SAXIHP read channel cache mode
localparam HBA_PORT__AFI_CACHE__RD_CM__ADDR = 'h5c;
localparam HBA_PORT__AFI_CACHE__RD_CM__MASK = 'hf;
localparam HBA_PORT__AFI_CACHE__RD_CM__DFLT = 'h3;
*/
wire [ADDRESS_BITS-1:0] bram_waddr;
wire [AXIBRAM_BITS-1:0] bram_waddr;
// wire [ADDRESS_BITS-1:0] pre_awaddr;
wire [ADDRESS_BITS-1:0] bram_raddr;
wire [AXIBRAM_BITS-1:0] bram_raddr;
wire [31:0] bram_rdata;
wire pre_bram_wen; // one cycle ahead of bram_wen, nut not masked by dev_ready
wire bram_wen;
......@@ -192,7 +190,7 @@ module axi_ahci_regs#(
reg debug_rd_r;
assign bram_addr = bram_ren[0] ? bram_raddr : (bram_wen_r ? bram_waddr_r : bram_waddr);
assign bram_addr = bram_ren[0] ? bram_raddr[ADDRESS_BITS-1:0] : (bram_wen_r ? bram_waddr_r : bram_waddr[ADDRESS_BITS-1:0]);
assign hba_arst = hba_rst_r; // hba _reset (currently does ~ the same as port reset)
assign port_arst = port_rst_r; // port _reset by software
......@@ -215,7 +213,7 @@ module axi_ahci_regs#(
bram_wen_r <= bram_wen;
if (bram_wen) bram_waddr_r <= bram_waddr;
if (bram_wen) bram_waddr_r <= bram_waddr[ADDRESS_BITS-1:0];
end
......@@ -284,7 +282,7 @@ module axi_ahci_regs#(
end
always @(posedge aclk) begin
if (bram_ren[0]) debug_rd_r <= &bram_raddr[ADDRESS_BITS-1:4]; // last 16 DWORDs
if (bram_ren[0]) debug_rd_r <= &bram_raddr[ADDRESS_BITS-1:4]; // last 16 DWORDs (With AXIBRAM_BITS will be duplicated)
end
//debug_rd_r
......@@ -325,7 +323,7 @@ sata_phy_rst_out will be released after the sata clock is stable
axibram_write #(
.ADDRESS_BITS(ADDRESS_BITS)
.ADDRESS_BITS(AXIBRAM_BITS) // in debug mode - 1 bit more than ADDERSS_BITS
) axibram_write_i (
.aclk (aclk), // input
.arst (arst), // input
......@@ -359,7 +357,7 @@ sata_phy_rst_out will be released after the sata clock is stable
);
axibram_read #(
.ADDRESS_BITS(ADDRESS_BITS)
.ADDRESS_BITS(AXIBRAM_BITS) // in debug mode - 1 bit more than ADDERSS_BITS
) axibram_read_i (
.aclk (aclk), // input
.arst (arst), // input
......@@ -383,7 +381,11 @@ sata_phy_rst_out will be released after the sata clock is stable
.bram_raddr (bram_raddr), // output[9:0]
.bram_ren (bram_ren[0]), // output
.bram_regen (bram_ren[1]), // output
`ifdef USE_DATASCOPE
.bram_rdata (datascope_sel[1] ? datascope_rdata : bram_rdata_r) // input[31:0]
`else
.bram_rdata (bram_rdata_r) // input[31:0]
`endif
);
// Register memory, lower half uses read-modify-write using bit type from ahci_regs_type_i ROM, 2 aclk cycles/per write and
......@@ -441,6 +443,26 @@ sata_phy_rst_out will be released after the sata clock is stable
.web (8'b0), // input[7:0]
.data_in (64'b0) // input[63:0]
);
`ifdef USE_DATASCOPE
ram_var_w_var_r #(
.REGISTERS (0),
.LOG2WIDTH_WR (5),
.LOG2WIDTH_RD (5),
.DUMMY(0)
) datascope_mem_i (
.rclk (aclk), // input
.raddr (bram_raddr[9:0]), // input[9:0]
.ren (bram_ren[0]), // input
.regen (bram_ren[1]), // input
.data_out (datascope_rdata), // output[31:0]
.wclk (datascope_clk), // input
.waddr (datascope_waddr), // input[9:0]
.we (datascope_we), // input
.web (8'hff), // input[7:0]
.data_in (datascope_di) // input[31:0]
);
`endif
fifo_cross_clocks #(
.DATA_WIDTH(ADDRESS_BITS+32),
......
......@@ -758,17 +758,17 @@ task send_good_status; // @SuppressThisWarning VEditor - Used in testbench
{1'b0,dev_specific_status_bits,4'b0}, // status
1, // error
0, // device
0, // lba_low
1, // lba_low
0, // lba_high
0, // count
1, // count
status); // output: result status
transmit_data[0] = FIS_D2HR | (irq? 'h4000:0) | (dev_specific_status_bits << 20) | 'h1000000;
transmit_data[1] = 1;
transmit_data[2] = 0;
transmit_data[3] = 1;
transmit_data[4] = 0;
linkTransmitFIS(id, 5, 0, status);
// transmit_data[0] = FIS_D2HR | (irq? 'h4000:0) | (dev_specific_status_bits << 20) | 'h1000000;
// transmit_data[1] = 1;
// transmit_data[2] = 0;
// transmit_data[3] = 1;
// transmit_data[4] = 0;
// linkTransmitFIS(id, 5, 0, status);
end
endtask
......
......@@ -64,6 +64,10 @@ module gtx_wrap #(
output wire rxcominitdet,
output wire rxelecidle,
output wire rxresetdone,
input wire clk_phase_align_req,
output wire clk_phase_align_ack,
input wire txreset,
input wire txusrclk,
input wire txusrclk2,
......@@ -89,7 +93,9 @@ module gtx_wrap #(
output wire dbg_rxphaligndone,
output wire dbg_rx_clocks_aligned,
output wire dbg_rxcdrlock,
output wire dbg_rxdlysresetdone
output wire dbg_rxdlysresetdone,
output wire [1:0] txbufstatus
);
wire rxresetdone_gtx;
......@@ -129,17 +135,6 @@ assign txchardispmode_gtx = {6'h0, txdata_enc_out[19], txdata_enc_out[9]};
assign txchardispval_gtx = {6'h0, txdata_enc_out[18], txdata_enc_out[8]};
// Interface part
/*
input wire cpllreset, - async
input wire wrap_rxreset_, - async
input wire wrap_txreset_, - async
input wire rxreset, - async
input wire txreset, - async
input wire txelecidle, - txusrclk2 - need to resync to gtx iface clk - txusrclk
input wire txpcsreset, - async
input wire txcominit, - txusrclk2 - need to resync to gtx iface clk - txusrclk
input wire txcomwake, - txusrclk2 - need to resync to gtx iface clk - txusrclk
*/
// @ gtx iface clk
wire txcominit_gtx;
wire txcomwake_gtx;
......@@ -178,15 +173,7 @@ if (DATA_BYTE_WIDTH == 4) begin
always @ (posedge txreset or posedge txusrclk) begin
if (txreset) txdata_resync_strobe <= 0;
else if (txdata_resync_valid) txdata_resync_strobe <= ~txdata_resync_strobe;
/*
if (txreset) begin
txdata_enc_in_r <= 0;
txcharisk_enc_in_r <= 0;
end else if (txdata_resync_valid) begin
txdata_enc_in_r <= txdata_resync_strobe? txdata_resync_out[31:16]: txdata_resync_out[15:0];
txcharisk_enc_in_r <= txdata_resync_strobe? txdata_resync_out[35:34]: txdata_resync_out[33:32];
end
*/
if (txreset) begin
txcomwake_gtx_f <= 0;
txcominit_gtx_f <= 0;
......@@ -246,37 +233,93 @@ gtx_8x10enc gtx_8x10enc(
);
// Adjust RXOUTCLK so RXUSRCLK (==xclk) matches SIPO output data
wire rxcdrlock; // Marked as "reserved" - maybe not use it, only rxelecidle?
reg rxdlysreset = 0;
wire rxphaligndone;
wire rxdlysresetdone;
reg rx_clocks_aligned = 0;
reg [2:0] rxdlysreset_cntr = 7;
reg rxdlysresetdone_r;
assign dbg_rxphaligndone = rxphaligndone; // never gets up?
assign dbg_rx_clocks_aligned = rx_clocks_aligned;
assign dbg_rxcdrlock = rxcdrlock; //goes in/out (because of the SS ?
assign dbg_rxdlysresetdone = rxdlysresetdone_r;
always @ (posedge xclk) begin
// if (rxelecidle || !rxcdrlock) rxdlysreset_cntr <= 5;
if (rxelecidle) rxdlysreset_cntr <= 5;
else if (|rxdlysreset_cntr) rxdlysreset_cntr <= rxdlysreset_cntr - 1;
`ifdef CLK_ADJUST_VARIANT_1
wire rxcdrlock; // Marked as "reserved" - maybe not use it, only rxelecidle?
reg rxdlysreset = 0;
wire rxphaligndone;
wire rxdlysresetdone;
reg rx_clocks_aligned = 0;
reg [2:0] rxdlysreset_cntr = 7;
reg rxdlysresetdone_r;
// if (rxelecidle || !rxcdrlock) rxdlysreset <= 0;
if (rxelecidle) rxdlysreset <= 0;
else rxdlysreset <= |rxdlysreset_cntr;
assign dbg_rxphaligndone = rxphaligndone; // never gets up?
assign dbg_rx_clocks_aligned = rx_clocks_aligned;
assign dbg_rxcdrlock = rxcdrlock; //goes in/out (because of the SS ?
assign dbg_rxdlysresetdone = rxdlysresetdone_r;
always @ (posedge xclk) begin
// if (rxelecidle || !rxcdrlock) rxdlysreset_cntr <= 5;
if (rxelecidle) rxdlysreset_cntr <= 5;
else if (|rxdlysreset_cntr) rxdlysreset_cntr <= rxdlysreset_cntr - 1;
// if (rxelecidle || !rxcdrlock) rxdlysreset <= 0;
if (rxelecidle) rxdlysreset <= 0;
else rxdlysreset <= |rxdlysreset_cntr;
// if (rxelecidle || !rxcdrlock || rxdlysreset || |rxdlysreset_cntr) rx_clocks_aligned <= 0;
// if (rxelecidle || rxdlysreset || |rxdlysreset_cntr) rx_clocks_aligned <= 0;
if (rxelecidle) rx_clocks_aligned <= 0;
// else if (rxphaligndone) rx_clocks_aligned <= 1;
else if (rxphaligndone) rx_clocks_aligned <= 1;
// if (rxelecidle || !rxcdrlock || rxdlysreset || |rxdlysreset_cntr) rx_clocks_aligned <= 0;
// if (rxelecidle || rxdlysreset || |rxdlysreset_cntr) rx_clocks_aligned <= 0;
if (rxelecidle) rx_clocks_aligned <= 0;
// else if (rxphaligndone) rx_clocks_aligned <= 1;
else if (rxphaligndone) rx_clocks_aligned <= 1;
if (rxelecidle || rxdlysreset || |rxdlysreset_cntr) rxdlysresetdone_r <= 0;
else if (rxdlysresetdone) rxdlysresetdone_r <= 1;
end
if (rxelecidle || rxdlysreset || |rxdlysreset_cntr) rxdlysresetdone_r <= 0;
else if (rxdlysresetdone) rxdlysresetdone_r <= 1;
end
`else
// time to first rxphaligndone ~450ns, time to second (that should stay - 4.9 usec, still much less than allowed ALIGNp response time)
wire rxdlysreset = clk_phase_align_req;
reg rxphaligndone1_r = 0; // first time rxphaligndone gets active
reg rxphaligndone2_r = 0; // rxphaligndone deasserted
reg rx_clocks_aligned = 0; // second time rxphaligndone gets active (and is supposed to stay)
reg rxdlysresetdone_r;
wire rxphaligndone;
wire rxdlysresetdone;
wire rxcdrlock; // Marked as "reserved" - maybe not use it, only rxelecidle? (seems alternating 0/1 forever- SS?)
assign clk_phase_align_ack = rx_clocks_aligned;
assign dbg_rxphaligndone = rxphaligndone; // never gets up?
assign dbg_rx_clocks_aligned = rx_clocks_aligned;
assign dbg_rxcdrlock = rxcdrlock; //goes in/out (because of the SS ?
assign dbg_rxdlysresetdone = rxdlysresetdone_r;
`ifdef ALIGN_CLOCKS
always @ (posedge xclk) begin
if (rxelecidle) rxphaligndone1_r <= 0;
else if (rxphaligndone) rxphaligndone1_r <= 1;
if (rxelecidle) rxphaligndone2_r <= 0;
else if (rxphaligndone1_r && !rxphaligndone) rxphaligndone2_r <= 1;
if (rxelecidle) rx_clocks_aligned <= 0;
else if (rxphaligndone2_r && rxphaligndone) rx_clocks_aligned <= 1;
if (rxelecidle || rxdlysreset) rxdlysresetdone_r <= 0;
else if (rxdlysresetdone) rxdlysresetdone_r <= 1;
end
`else // ALIGN_CLOCKS - just bypassing
always @ (posedge xclk) begin
if (rxelecidle) rxphaligndone1_r <= 0;
else if (clk_phase_align_req) rxphaligndone1_r <= 1;
if (rxelecidle) rxphaligndone2_r <= 0;
else if (rxphaligndone1_r && !clk_phase_align_req) rxphaligndone2_r <= 1;
if (rxelecidle) rx_clocks_aligned <= 0;
else if (rxphaligndone2_r) rx_clocks_aligned <= 1;
if (rxelecidle || rxdlysreset) rxdlysresetdone_r <= 0;
else if (rxphaligndone2_r) rxdlysresetdone_r <= 1;
end
`endif
`endif
/*
* RX PCS part: comma detect + align module, 10/8 decoder, elastic buffer, interface resynchronisation
......@@ -371,7 +414,8 @@ wire rxcominitdet_gtx;
.rclk (rxusrclk),
/// .isaligned_in (state_aligned),
.isaligned_in (state_aligned && rxdlysresetdone_r), // rx_clocks_aligned), //Allow to align early, but do not tell it is aligned until xclk is aligned to SIPO par. clock
// .isaligned_in (state_aligned && rxdlysresetdone_r), // input
.isaligned_in (state_aligned), // input Moved clock phase reset/align to OOB module to handle
.charisk_in (rxcharisk_dec_out),
.notintable_in (rxnotintable_dec_out),
.disperror_in (rxdisperr_dec_out),
......@@ -505,7 +549,8 @@ wire rxcominitdet_gtx;
) elastic1632_i (
.wclk (xclk), // input 150MHz, recovered
.rclk (rxusrclk2), // input 75 MHz, system
.isaligned_in (state_aligned && rxdlysresetdone_r), // input
// .isaligned_in (state_aligned && rxdlysresetdone_r), // input
.isaligned_in (state_aligned), // input Moved clock phase reset/align to OOB module to handle
.charisk_in (rxcharisk_dec_out), // input[1:0]
.notintable_in (rxnotintable_dec_out), // input[1:0]
.disperror_in (rxdisperr_dec_out), // input[1:0]
......@@ -518,14 +563,7 @@ wire rxcominitdet_gtx;
.full (rxelsfull), // output
.empty (rxelsempty) // output
);
/*
// What is left:
assign rxcomwakedet = rxdata_resync_out[49];
assign rxcominitdet = rxdata_resync_out[48];
assign rxresetdone = rxdata_resync_out[47];
assign txresetdone = rxdata_resync_out[46];
*/
reg rxresetdone_r;
reg txresetdone_r;
always @ (posedge rxusrclk2) rxresetdone_r <= rxresetdone_gtx;
......@@ -674,7 +712,11 @@ gtxe2_channel_wrapper #(
.RXPH_CFG (24'h000000),
.RXPHDLY_CFG (24'h084020),
.RXPH_MONITOR_SEL (5'b00000),
`ifdef ALIGN_CLOCKS
.RX_XCLK_SEL ("RXUSR"), // ("RXREC"), // Andrey: Now they are the same, just using p.247 "Using RX Buffer Bypass..."
`else
.RX_XCLK_SEL ("RXREC"), // Andrey: Does not align clocks if in this mode
`endif
.RX_DDI_SEL (6'b000000),
.RX_DEFER_RESET_BUF_EN ("TRUE"),
/// .RXCDR_CFG (72'h03000023ff10200020),// 1.6G - 6.25G, No SS, RXOUT_DIV=2
......@@ -850,10 +892,13 @@ gtxe2_channel_wrapper(
.GTXRXN (rxn),
.RXBUFRESET (1'b0),
.RXBUFSTATUS (),
// .RXDDIEN (1'b0),
`ifdef ALIGN_CLOCKS
.RXDDIEN (1'b1), // Andrey: p.243: "Set high in RX buffer bypass mode"
// .RXDLYBYPASS (1'b1),
.RXDLYBYPASS (1'b0), // Andrey: p.243: "0: Uses the RX delay alignment circuit."
`else
.RXDDIEN (1'b0),
.RXDLYBYPASS (1'b1),
`endif
.RXDLYEN (1'b0),
.RXDLYOVRDEN (1'b0),
.RXDLYSRESET (rxdlysreset),
......@@ -975,7 +1020,7 @@ gtxe2_channel_wrapper(
.TXPHINIT (1'b0),
.TXPHINITDONE (),
.TXPHOVRDEN (1'b0),
.TXBUFSTATUS (),
.TXBUFSTATUS (txbufstatus[1:0]), // Andrey
.TXBUFDIFFCTRL (3'b100),
.TXDEEMPH (1'b0),
.TXDIFFCTRL (4'b1000),
......
......@@ -391,29 +391,29 @@ assign clr_rcvr_badend = set_nocommerr | set_reset | set_sync_esc | got_esc
// Others transitions are straightforward
always @ (posedge clk)
begin
state_sync_esc <= (state_sync_esc | set_sync_esc & ~alignes_pair) & ~clr_sync_esc & ~rst;
state_nocommerr <= (state_nocommerr | set_nocommerr & ~alignes_pair) & ~clr_nocommerr & ~rst;
state_nocomm <= (state_nocomm | set_nocomm & ~alignes_pair) & ~clr_nocomm & ~rst;
state_sync_esc <= (state_sync_esc | set_sync_esc & ~alignes_pair) & ~(clr_sync_esc & ~alignes_pair) & ~rst;
state_nocommerr <= (state_nocommerr | set_nocommerr & ~alignes_pair) & ~(clr_nocommerr & ~alignes_pair) & ~rst;
state_nocomm <= (state_nocomm | set_nocomm & ~alignes_pair) & ~(clr_nocomm & ~alignes_pair) & ~rst;
// state_align is not used, it is handled by OOB
state_align <= (state_align | set_align & ~alignes_pair) & ~clr_align & ~rst;
state_reset <= (state_reset | set_reset ) & ~clr_reset & ~rst;
state_send_rdy <= (state_send_rdy | set_send_rdy & ~alignes_pair) & ~clr_send_rdy & ~rst;
state_send_sof <= (state_send_sof | set_send_sof & ~alignes_pair) & ~clr_send_sof & ~rst;
state_send_data <= (state_send_data | set_send_data & ~alignes_pair) & ~clr_send_data & ~rst;
state_send_rhold <= (state_send_rhold | set_send_rhold & ~alignes_pair) & ~clr_send_rhold & ~rst;
state_send_shold <= (state_send_shold | set_send_shold & ~alignes_pair) & ~clr_send_shold & ~rst;
state_send_crc <= (state_send_crc | set_send_crc & ~alignes_pair) & ~clr_send_crc & ~rst;