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
......
This diff is collapsed.
......@@ -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;
state_send_eof <= (state_send_eof | set_send_eof & ~alignes_pair) & ~clr_send_eof & ~rst;
state_wait <= (state_wait | set_wait & ~alignes_pair) & ~clr_wait & ~rst;
state_rcvr_wait <= (state_rcvr_wait | set_rcvr_wait & ~alignes_pair) & ~clr_rcvr_wait & ~rst;
state_rcvr_rdy <= (state_rcvr_rdy | set_rcvr_rdy & ~alignes_pair) & ~clr_rcvr_rdy & ~rst;
state_rcvr_data <= (state_rcvr_data | set_rcvr_data & ~alignes_pair) & ~clr_rcvr_data & ~rst;
state_rcvr_rhold <= (state_rcvr_rhold | set_rcvr_rhold & ~alignes_pair) & ~clr_rcvr_rhold & ~rst;
state_rcvr_shold <= (state_rcvr_shold | set_rcvr_shold & ~alignes_pair) & ~clr_rcvr_shold & ~rst;
state_rcvr_eof <= (state_rcvr_eof | set_rcvr_eof & ~alignes_pair) & ~clr_rcvr_eof & ~rst;
state_rcvr_goodcrc <= (state_rcvr_goodcrc | set_rcvr_goodcrc & ~alignes_pair) & ~clr_rcvr_goodcrc & ~rst;
state_rcvr_goodend <= (state_rcvr_goodend | set_rcvr_goodend & ~alignes_pair) & ~clr_rcvr_goodend & ~rst;
state_rcvr_badend <= (state_rcvr_badend | set_rcvr_badend & ~alignes_pair) & ~clr_rcvr_badend & ~rst;
state_align <= (state_align | set_align & ~alignes_pair) & ~(clr_align & ~alignes_pair) & ~rst;
state_reset <= (state_reset | set_reset ) & ~ clr_reset & ~rst;
state_send_rdy <= (state_send_rdy | set_send_rdy & ~alignes_pair) & ~(clr_send_rdy & ~alignes_pair) & ~rst;
state_send_sof <= (state_send_sof | set_send_sof & ~alignes_pair) & ~(clr_send_sof & ~alignes_pair) & ~rst;
state_send_data <= (state_send_data | set_send_data & ~alignes_pair) & ~(clr_send_data & ~alignes_pair) & ~rst;
state_send_rhold <= (state_send_rhold | set_send_rhold & ~alignes_pair) & ~(clr_send_rhold & ~alignes_pair) & ~rst;
state_send_shold <= (state_send_shold | set_send_shold & ~alignes_pair) & ~(clr_send_shold & ~alignes_pair) & ~rst;
state_send_crc <= (state_send_crc | set_send_crc & ~alignes_pair) & ~(clr_send_crc & ~alignes_pair) & ~rst;
state_send_eof <= (state_send_eof | set_send_eof & ~alignes_pair) & ~(clr_send_eof & ~alignes_pair) & ~rst;
state_wait <= (state_wait | set_wait & ~alignes_pair) & ~(clr_wait & ~alignes_pair) & ~rst;
state_rcvr_wait <= (state_rcvr_wait | set_rcvr_wait & ~alignes_pair) & ~(clr_rcvr_wait & ~alignes_pair) & ~rst;
state_rcvr_rdy <= (state_rcvr_rdy | set_rcvr_rdy & ~alignes_pair) & ~(clr_rcvr_rdy & ~alignes_pair) & ~rst;
state_rcvr_data <= (state_rcvr_data | set_rcvr_data & ~alignes_pair) & ~(clr_rcvr_data & ~alignes_pair) & ~rst;
state_rcvr_rhold <= (state_rcvr_rhold | set_rcvr_rhold & ~alignes_pair) & ~(clr_rcvr_rhold & ~alignes_pair) & ~rst;
state_rcvr_shold <= (state_rcvr_shold | set_rcvr_shold & ~alignes_pair) & ~(clr_rcvr_shold & ~alignes_pair) & ~rst;
state_rcvr_eof <= (state_rcvr_eof | set_rcvr_eof & ~alignes_pair) & ~(clr_rcvr_eof & ~alignes_pair) & ~rst;
state_rcvr_goodcrc <= (state_rcvr_goodcrc | set_rcvr_goodcrc & ~alignes_pair) & ~(clr_rcvr_goodcrc & ~alignes_pair) & ~rst;
state_rcvr_goodend <= (state_rcvr_goodend | set_rcvr_goodend & ~alignes_pair) & ~(clr_rcvr_goodend & ~alignes_pair) & ~rst;
state_rcvr_badend <= (state_rcvr_badend | set_rcvr_badend & ~alignes_pair) & ~(clr_rcvr_badend & ~alignes_pair) & ~rst;
end
// flag if incoming request to terminate current transaction came from TL
......
This diff is collapsed.
......@@ -51,6 +51,10 @@ module oob_ctrl #(
input wire recal_tx_done, // input wire
output wire rxreset_req, // output wire // rx reset (after rxelecidle -> 0)
input wire rxreset_ack, // input wire
// Andrey: adding new signal and state - after RX is operational try re-align clock
output wire clk_phase_align_req, // Request GTX to align SIPO parallel clock and user- provided RXUSRCLK
input wire clk_phase_align_ack, // GTX aligned clock phase (DEBUG - not always clear when it works or not)
input wire [DATA_BYTE_WIDTH*8 - 1:0] txdata_in, // output[31:0] wire // input data stream (if any data during OOB setting => ignored)
input wire [DATA_BYTE_WIDTH - 1:0] txcharisk_in, // output[3:0] wire // input data stream (if any data during OOB setting => ignored)
output wire [DATA_BYTE_WIDTH*8 - 1:0] txdata_out, // output[31:0] wire // output data stream to gtx
......@@ -129,19 +133,21 @@ oob #(
)
oob
(
.debug (debug), // output [11:0] reg
.clk (clk), // input wire // sata clk = usrclk2
.rst (rst), // input wire // reset oob
.rxcominitdet_in (rxcominitdet_in), // input wire // oob responses
.rxcomwakedet_in (rxcomwakedet_in), // input wire // oob responses
.rxelecidle_in (rxelecidle_in), // input wire // oob responses
.txcominit (txcominit), // output wire // oob issues
.txcomwake (txcomwake), // output wire // oob issues
.txelecidle (txelecidle_inner), // output wire // oob issues
.txpcsreset_req (txpcsreset_req), // output wire
.recal_tx_done (recal_tx_done), // input wire
.rxreset_req (rxreset_req), // output wire
.debug (debug), // output [11:0] reg
.clk (clk), // input wire // sata clk = usrclk2
.rst (rst), // input wire // reset oob
.rxcominitdet_in (rxcominitdet_in), // input wire // oob responses
.rxcomwakedet_in (rxcomwakedet_in), // input wire // oob responses
.rxelecidle_in (rxelecidle_in), // input wire // oob responses
.txcominit (txcominit), // output wire // oob issues
.txcomwake (txcomwake), // output wire // oob issues
.txelecidle (txelecidle_inner),// output wire // oob issues
.txpcsreset_req (txpcsreset_req), // output wire
.recal_tx_done (recal_tx_done), // input wire
.rxreset_req (rxreset_req), // output wire
.rxreset_ack (rxreset_ack), // input wire
.clk_phase_align_req (clk_phase_align_req), // output wire
.clk_phase_align_ack (clk_phase_align_ack), // input wire
.txdata_in (txdata_in), // input [31:0] wire // input data stream (if any data during OOB setting => ignored)
.txcharisk_in (txcharisk_in), // input [3:0] wire // input data stream (if any data during OOB setting => ignored)
.txdata_out (txdata_out), // output [31:0] wire // output data stream to gtx
......
......@@ -97,6 +97,7 @@ wire [DATA_BYTE_WIDTH - 1:0] txcharisk_in;
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;
assign ll_err_out = rxdisperr | rxnotintable;
......@@ -119,6 +120,10 @@ wire txpcsreset_req;
wire recal_tx_done;
wire rxreset_req;
wire rxreset_ack;
wire clk_phase_align_req;
wire clk_phase_align_ack;
wire rxreset_oob;
// elastic buffer status signals TODO
//wire rxelsfull;
......@@ -138,48 +143,51 @@ wire dummy;
oob_ctrl oob_ctrl(
// sata clk = usrclk2
.clk (clk),
.clk (clk),
// reset oob
.rst (rst),
.rst (rst),
// gtx is ready = all resets are done
.gtx_ready (gtx_ready),
.debug ({dummy,debug_cnt[10:0]}),
.gtx_ready (gtx_ready),
.debug ({dummy,debug_cnt[10:0]}),
// oob responses
.rxcominitdet_in (rxcominitdet),
.rxcomwakedet_in (rxcomwakedet),
.rxelecidle_in (rxelecidle),
.rxcominitdet_in (rxcominitdet),
.rxcomwakedet_in (rxcomwakedet),
.rxelecidle_in (rxelecidle),
// oob issues
.txcominit (txcominit),
.txcomwake (txcomwake),
.txelecidle (txelecidle),
.txcominit (txcominit),
.txcomwake (txcomwake),
.txelecidle (txelecidle),
.txpcsreset_req (txpcsreset_req),
.recal_tx_done (recal_tx_done),
.txpcsreset_req (txpcsreset_req),
.recal_tx_done (recal_tx_done),
.rxreset_req (rxreset_req),
.rxreset_ack (rxreset_ack),
.rxreset_req (rxreset_req),
.rxreset_ack (rxreset_ack),
.clk_phase_align_req (clk_phase_align_req), // output wire
.clk_phase_align_ack (clk_phase_align_ack), // input wire
// input data stream (if any data during OOB setting => ignored)
.txdata_in (txdata_in),
.txcharisk_in (txcharisk_in),
.txdata_in (txdata_in),
.txcharisk_in (txcharisk_in),
// output data stream to gtx
.txdata_out (txdata),
.txcharisk_out (txcharisk),
.txdata_out (txdata),
.txcharisk_out (txcharisk),
// input data from gtx
.rxdata_in (rxdata[31:0]),
.rxcharisk_in (rxcharisk[3:0]),
.rxdata_in (rxdata[31:0]),
.rxcharisk_in (rxcharisk[3:0]),
// bypassed data from gtx
.rxdata_out (rxdata_out),
.rxcharisk_out (rxcharisk_out),
.rxdata_out (rxdata_out),
.rxcharisk_out (rxcharisk_out),
// receiving data is aligned
.rxbyteisaligned (rxbyteisaligned),
.rxbyteisaligned (rxbyteisaligned),
// shows if channel is ready
.phy_ready (phy_ready),
.phy_ready (phy_ready),
// To/from AHCI
.set_offline (set_offline), // input
.comreset_send (comreset_send) // input
.set_offline (set_offline), // input
.comreset_send (comreset_send) // input
,.debug_detected_alignp(debug_detected_alignp)
);
......@@ -313,18 +321,42 @@ always @ (posedge clk or posedge extrst)
// issue partial tx reset to restore functionality after oob sequence. Let it lasts 8 clock lycles
reg [3:0] txpcsreset_cnt;
wire txpcsreset_stop;
// issue partial tx reset to restore functionality after oob sequence. Let it lasts 8 clock cycles
// Not enough or too early (after txelctidle?) txbufstatus shows overflow
`ifdef OLD_TXPCSRESET
reg [3:0] txpcsreset_cnt;
wire txpcsreset_stop;
assign txpcsreset_stop = txpcsreset_cnt[3];
assign txpcsreset = txpcsreset_req & ~txpcsreset_stop & gtx_configured;
assign recal_tx_done = txpcsreset_stop & gtx_ready;
always @ (posedge clk or posedge extrst)
// txpcsreset_cnt <= extrst | rst | ~txpcsreset_req ? 4'h0 : txpcsreset_stop ? txpcsreset_cnt : txpcsreset_cnt + 1'b1;
if (extrst) txpcsreset_cnt <= 1;
else txpcsreset_cnt <= rst | ~txpcsreset_req ? 4'h0 : txpcsreset_stop ? txpcsreset_cnt : txpcsreset_cnt + 1'b1;
`else // OLD_TXPCSRESET
localparam TXPCSRESET_CYCLES = 100;
reg txpcsreset_r;
reg [7:0] txpcsreset_cntr;
reg recal_tx_done_r;
assign recal_tx_done = recal_tx_done_r;
assign txpcsreset = txpcsreset_r;
always @ (posedge clk) begin
if (rst || (txpcsreset_cntr == 0)) txpcsreset_r <= 0;
else if (txpcsreset_req) txpcsreset_r <= 1;
if (rst) txpcsreset_cntr <= 0;
else if (txpcsreset_req) txpcsreset_cntr <= TXPCSRESET_CYCLES;
else if (txpcsreset_cntr != 0) txpcsreset_cntr <= txpcsreset_cntr - 1;
if (rst || txelecidle || txpcsreset_r) recal_tx_done_r <= 0;
else if (txresetdone) recal_tx_done_r <= 1;
end
`endif // OLD_TXPCSRESET
assign txpcsreset_stop = txpcsreset_cnt[3];
assign txpcsreset = txpcsreset_req & ~txpcsreset_stop & gtx_configured;
assign recal_tx_done = txpcsreset_stop & gtx_ready;
always @ (posedge clk or posedge extrst)
// txpcsreset_cnt <= extrst | rst | ~txpcsreset_req ? 4'h0 : txpcsreset_stop ? txpcsreset_cnt : txpcsreset_cnt + 1'b1;
if (extrst) txpcsreset_cnt <= 1;
else txpcsreset_cnt <= rst | ~txpcsreset_req ? 4'h0 : txpcsreset_stop ? txpcsreset_cnt : txpcsreset_cnt + 1'b1;
// issue rx reset to restore functionality after oob sequence. Let it lasts 8 clock lycles
reg [3:0] rxreset_oob_cnt;
......@@ -459,7 +491,11 @@ gtx_wrap
.rxcominitdet (rxcominitdet), // output wire
.rxelecidle (rxelecidle), // output wire
.rxresetdone (rxresetdone), // output wire
.txreset (txreset), // input wire
.txreset (txreset), // input wire
.clk_phase_align_req(clk_phase_align_req), // output wire
.clk_phase_align_ack(clk_phase_align_ack), // input wire
.txusrclk (txusrclk), // input wire
.txusrclk2 (txusrclk2), // input wire
.txelecidle (txelecidle), // input wire
......@@ -481,7 +517,8 @@ gtx_wrap
.dbg_rxphaligndone (dbg_rxphaligndone),
.dbg_rx_clocks_aligned(dbg_rx_clocks_aligned),
.dbg_rxcdrlock (dbg_rxcdrlock) ,
.dbg_rxdlysresetdone(dbg_rxdlysresetdone)
.dbg_rxdlysresetdone(dbg_rxdlysresetdone),
.txbufstatus (txbufstatus[1:0])
);
......@@ -542,6 +579,32 @@ always @ (posedge clk) begin
else if (debug_error_r) debug_cntr6 <= debug_cntr6 + 1;
end
reg [15:0] dbg_clk_align_cntr;
reg dbg_clk_align_wait;
//reg dbg_rxphaligndone_down;
//reg dbg_rxphaligndone_second;
always @ (posedge clk) begin
if (rxelecidle || clk_phase_align_ack) dbg_clk_align_wait <= 0;
else if (clk_phase_align_req) dbg_clk_align_wait <= 1;
if (rxelecidle) dbg_clk_align_cntr <= 0;
else if (dbg_clk_align_wait) dbg_clk_align_cntr <= dbg_clk_align_cntr +1;
/*
if (rxelecidle || dbg_rxphaligndone_second) dbg_clk_align_wait <= 0;
else if (clk_phase_align_req) dbg_clk_align_wait <= 1;
if (rxelecidle) dbg_rxphaligndone_down <= 0;
else if (dbg_rx_clocks_aligned && !dbg_rxphaligndone) dbg_rxphaligndone_down <= 1;
if (rxelecidle) dbg_rxphaligndone_second <= 0;
else if (dbg_rxphaligndone_down && dbg_rxphaligndone) dbg_rxphaligndone_second <= 1;
*/
end
/*
assign debug_sata[ 3: 0] = debug_cntr1;
assign debug_sata[ 7: 4] = debug_cntr2;
......@@ -555,9 +618,17 @@ assign debug_sata[17] = txreset;
assign debug_sata[18] = txpcsreset;
assign debug_sata[19] = txelecidle;
assign debug_sata[23:20] = debug_cntr4;
.clk_phase_align_req(clk_phase_align_req), // output wire
.clk_phase_align_ack(clk_phase_align_ack), // input wire
*/
//assign phy_ready = link_state & gtx_ready & rxbyteisaligned;
//assign debug_sata = {debug_cntr6,debug_cntr5};
assign debug_sata = {25'b0, dbg_rxdlysresetdone, rxelecidle, dbg_rxcdrlock, rxelsfull, rxelsempty, dbg_rxphaligndone, dbg_rx_clocks_aligned};
//assign debug_sata = {8'b0, dbg_clk_align_cntr, 1'b0, dbg_rxdlysresetdone, rxelecidle, dbg_rxcdrlock, rxelsfull, rxelsempty, dbg_rxphaligndone, dbg_rx_clocks_aligned};
assign debug_sata = {8'b0, dbg_clk_align_cntr, txbufstatus[1:0], rxelecidle, dbg_rxcdrlock, rxelsfull, rxelsempty, dbg_rxphaligndone, dbg_rx_clocks_aligned};
endmodule
// This file may be used to define same pre-processor macros to be included into each parsed file
`ifndef SYSTEM_DEFINES
`define SYSTEM_DEFINES
`define ALIGN_CLOCKS
`define USE_DATASCOPE
`define PRELOAD_BRAMS
`define AHCI_SATA 1
// Enviroment-dependent options
......
......@@ -1059,6 +1059,17 @@ initial begin //Host
/// setup_pio_read_identify_command_multi4(1,27,64,83); // prdt interrupt for entry 0
setup_pio_read_identify_command_multi4(1,64,63,64); // prdt interrupt for entry 0
maxigp1_print (HBA_PORT__PxCI__CI__ADDR << 2,"HBA_PORT__PxCI__CI__ADDR");
`ifdef TEST_ABORT_COMMAND
// Abort command by clearing ST
maxigp1_writep (HBA_PORT__PxCMD__FRE__ADDR << 2, HBA_PORT__PxCMD__FRE__MASK); // Enable FR, 0-> ST
maxigp1_print (HBA_PORT__PxCI__CI__ADDR << 2,"HBA_PORT__PxCI__CI__ADDR");
repeat (300) @(posedge CLK);
// maxigp1_writep (HBA_PORT__PxCMD__FRE__ADDR << 2, HBA_PORT__PxCMD__FRE__MASK); // Enable FR, 0-> ST
maxigp1_print (HBA_PORT__PxCI__CI__ADDR << 2,"HBA_PORT__PxCI__CI__ADDR");
// maxigp1_writep (HBA_PORT__PxCMD__FRE__ADDR << 2, HBA_PORT__PxCMD__FRE__MASK); // Enable FR, 0-> ST
maxigp1_print (HBA_PORT__PxCI__CI__ADDR << 2,"HBA_PORT__PxCI__CI__ADDR");
`endif
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
......@@ -1069,6 +1080,15 @@ initial begin //Host
maxigp1_writep (HBA_PORT__PxIS__PSS__ADDR << 2, HBA_PORT__PxIS__PSS__MASK); // clear PS interrupt
maxigp1_writep (GHC__IS__IPS__ADDR << 2, 1); // clear global interrupts
wait (~IRQ);
// Print datascope - contents of the last CFIS sent
maxigp1_print ('h1000,"DATASCOPE 0"); //
maxigp1_print ('h1004,"DATASCOPE 1"); //
maxigp1_print ('h1008,"DATASCOPE 2"); //
maxigp1_print ('h100c,"DATASCOPE 3"); //
maxigp1_print ('h1010,"DATASCOPE 4"); //
maxigp1_print ('h1014,"DATASCOPE 5"); //
maxigp1_print ('h1018,"DATASCOPE 6"); //
maxigp1_print ('h101c,"DATASCOPE 7"); //
// sysmem_print ('h1e81,'h180); // for shifted
sysmem_print ('h1e80,'h180); // Compact dump of "system memory" in hex word format
......@@ -1087,6 +1107,17 @@ initial begin //Host
TESTBENCH_TITLE = "DMA transfer to device completed";
$display("[Testbench]: %s @%t", TESTBENCH_TITLE, $time);
repeat (50) @(posedge CLK);
// Print datascope - contents of the last CFIS sent
maxigp1_print ('h1000,"DATASCOPE 0"); //
maxigp1_print ('h1004,"DATASCOPE 1"); //
maxigp1_print ('h1008,"DATASCOPE 2"); //
maxigp1_print ('h100c,"DATASCOPE 3"); //
maxigp1_print ('h1010,"DATASCOPE 4"); //
maxigp1_print ('h1014,"DATASCOPE 5"); //
maxigp1_print ('h1018,"DATASCOPE 6"); //
maxigp1_print ('h101c,"DATASCOPE 7"); //
/*
// Reset port
maxigp1_print ('h3ff << 2,"DEBUG_REGISTER");
......
This diff is collapsed.
......@@ -3008,9 +3008,9 @@ localparam RXCDRLOCK_DELAY = 10; // Refclk periods
localparam RXDLYSRESET_MIN_DURATION = 50; // ns
localparam RXDLYSRESETDONE_DELAY = 10;
localparam RXDLYSRESETDONE_DURATION = 7; // 100ns
localparam RXPHALIGNDONE_DELAY1 = 15;
localparam RXPHALIGNDONE_DELAY1 = 15; // 0.45 usec from the end of reset (measured)
localparam RXPHALIGNDONE_DURATION1 = 7;
localparam RXPHALIGNDONE_DELAY2 = 10;
localparam RXPHALIGNDONE_DELAY2 = 311; // 4.9 usec from the end of reset (measured)
initial forever @ (posedge (reset || RXELECIDLE)) begin
rxcdrlock <= 1'b0;
......
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