Commit 44c2590f authored by Andrey Filippov's avatar Andrey Filippov

fixing ifdef for debug features

parent 7de9f2a3
......@@ -52,87 +52,87 @@
<link>
<name>vivado_logs/VivadoBitstream.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160312231527798.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160313145236495.log</location>
</link>
<link>
<name>vivado_logs/VivadoOpt.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160312231527798.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160313145236495.log</location>
</link>
<link>
<name>vivado_logs/VivadoOptPhys.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160312231527798.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160313145236495.log</location>
</link>
<link>
<name>vivado_logs/VivadoOptPower.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160312231527798.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160313145236495.log</location>
</link>
<link>
<name>vivado_logs/VivadoPlace.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160312231527798.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160313145236495.log</location>
</link>
<link>
<name>vivado_logs/VivadoRoute.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160312231527798.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160313145236495.log</location>
</link>
<link>
<name>vivado_logs/VivadoSynthesis.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160312231356578.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160313145052718.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160312231527798.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160313145236495.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160312231356578.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160313145052718.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimingReportImplemented.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160312231527798.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160313145236495.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimingReportSynthesis.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160312231356578.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160313145052718.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-20160312231527798.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-20160313145236495.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-20160312231527798.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-20160313145236495.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-20160312231527798.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-20160313145236495.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-20160312231527798.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-place-20160313145236495.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-20160312231527798.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-route-20160313145236495.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-20160312231356578.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-synth-20160313145052718.dcp</location>
</link>
</linkedResources>
</projectDescription>
......@@ -149,19 +149,11 @@ module ahci_sata_layers #(
wire [ 1:0] ll_d2h_mask_out;
wire ll_d2h_valid;
wire ll_d2h_almost_full;
// wire ll_d2h_last; // may loose ll timing and send 'last' after data. Now assuming no data comes next xyxle after last
// wire [1:0] d2h_type_in;
reg [1:0] d2h_type_in;
reg fis_over_r; // push 1 more DWORD (ignore) + type (ERR/OK) when received FIS is done/error
// wire ll_frame_req_w; // pre ll_frame_req
reg ll_frame_req; // -> link // request for a new frame transition
wire ll_frame_ackn; // acknowledge for ll_frame_req
// wire ll_frame_busy; // link -> // a little bit of overkill with the cound of response signals, think of throwing out 1 of them // LL tells back if it cant handle the request for now
// wire ll_frame_ack; // link -> // LL tells if the request is transmitting not used
// wire ll_frame_rej; // link -> // or if it was cancelled because of simultanious incoming transmission
// wire ll_frame_done_good; // link -> // TL tell if the outcoming transaction is done and how it was done
// wire ll_frame_done_bad; // link ->
wire ll_incom_start; // link -> // if started an incoming transaction assuming this and next 2 are single-cycle
wire ll_incom_done; // link -> // if incoming transition was completed
......@@ -169,13 +161,8 @@ module ahci_sata_layers #(
reg ll_incom_invalidate_r; // error delayed by 1 clock - if eof was incorrect (because of earlier data error)
// let last data dword to pass through
// wire incom_ack_good = send_R_OK; // -> link // transport layer responds on a completion of a FIS
// wire incom_ack_bad = send_R_ERR; // -> link // oob sequence is reinitiated and link now is not established or rxelecidle
wire ll_link_reset = ~phy_ready; // -> link // oob sequence is reinitiated and link now is not established or rxelecidle //TODO Alexey:mb it shall be independent
// wire ll_incom_stop_req; // -> link // TL demands to stop current recieving session (use !PxCMD.ST)?
wire [DATA_BYTE_WIDTH*8 - 1:0] ph2ll_data_out;
wire [DATA_BYTE_WIDTH - 1:0] ph2ll_charisk_out; // charisk
wire [DATA_BYTE_WIDTH - 1:0] ph2ll_err_out; // disperr | notintable
......@@ -187,14 +174,12 @@ module ahci_sata_layers #(
wire [FIFO_ADDR_WIDTH-1:0] h2d_waddr;
wire [FIFO_ADDR_WIDTH:0] h2d_fill;
wire h2d_nempty;
// wire h2d_under;
wire [FIFO_ADDR_WIDTH-1:0] d2h_raddr;
wire [1:0] d2h_fifo_re_regen;
wire [FIFO_ADDR_WIDTH-1:0] d2h_waddr;
wire [FIFO_ADDR_WIDTH:0] d2h_fill;
wire d2h_nempty;
// wire d2h_over;
wire h2d_fifo_rd = h2d_nempty && ll_strobe_out; // TODO: check latency in link.v
wire h2d_fifo_wr = h2d_valid;
......@@ -202,112 +187,59 @@ module ahci_sata_layers #(
wire d2h_fifo_wr = ll_d2h_valid || fis_over_r; // fis_over_r will push FIS end to FIFO
reg h2d_pending; // HBA started sending FIS to fifo
// wire [31:0] debug_phy;
// wire [31:0] debug_link;
wire rxelsfull;
wire rxelsempty;
wire xclk; // output receive clock, just to measure frequency
// wire [FREQ_METER_WIDTH - 1:0] xclk_period; // relative (to 2*clk) xclk period
wire debug_detected_alignp; // oob detects ALIGNp, but not the link layer
wire [31:0] debug_phy0;
`ifdef USE_DATASCOPE
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;
// 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[27:20],debug_phy[23:0]} ; //
assign ll_h2d_last = (h2d_type_out == H2D_TYPE_FIS_LAST);
assign d2h_valid = d2h_nempty;
assign d2h_many = |d2h_fill[FIFO_ADDR_WIDTH:3]; //
assign h2d_ready = !h2d_fill[FIFO_ADDR_WIDTH] && !(&h2d_fill[FIFO_ADDR_WIDTH:3]);
assign ll_d2h_almost_full = d2h_fill[FIFO_ADDR_WIDTH] || &d2h_fill[FIFO_ADDR_WIDTH-1:6]; // 63 dwords (maybe use :5?) - time to tell device to stop
`endif
assign ll_h2d_last = (h2d_type_out == H2D_TYPE_FIS_LAST);
assign d2h_valid = d2h_nempty;
assign d2h_many = |d2h_fill[FIFO_ADDR_WIDTH:3]; //
assign h2d_ready = !h2d_fill[FIFO_ADDR_WIDTH] && !(&h2d_fill[FIFO_ADDR_WIDTH:3]);
assign ll_d2h_almost_full = d2h_fill[FIFO_ADDR_WIDTH] || &d2h_fill[FIFO_ADDR_WIDTH-1:6]; // 63 dwords (maybe use :5?) - time to tell device to stop
// assign ll_frame_req_w = !ll_frame_busy && h2d_pending && (((h2d_type == H2D_TYPE_FIS_LAST) && h2d_fifo_wr ) || (|h2d_fill[FIFO_ADDR_WIDTH : BITS_TO_START_XMIT]));
// Separating different types of errors, sync_escape from other problems. TODO: route individual errors to set SERR bits
//assign incom_invalidate = state_rcvr_eof & crc_bad & ~alignes_pair | state_rcvr_data & dword_val & rcvd_dword[CODE_WTRMP];
// assign phy_speed = phy_ready ? PHY_SPEED:0;
// assign serr_DB = phy_ready && (|ph2ll_err_out);
// assign serr_DH = phy_ready && (xmit_err);
assign phy_speed = link_established ? PHY_SPEED:0;
assign serr_DB = link_established && (|ph2ll_err_out);
assign serr_DH = link_established && (xmit_err);
//
assign phy_speed = link_established ? PHY_SPEED:0;
assign serr_DB = link_established && (|ph2ll_err_out);
assign serr_DH = link_established && (xmit_err);
//
// not yet assigned errors
/// assign serr_DT = phy_ready && (comreset_send); // RWC: Transport state transition error
/// assign serr_DS = phy_ready && (cominit_got); // RWC: Link sequence error
/// assign serr_DC = phy_ready && (serr_DW); // RWC: CRC error in Link layer
assign serr_DT = phy_ready && (0); // RWC: Transport state transition error
assign serr_DT = phy_ready && (0); // RWC: Transport state transition error
// assign serr_DS = phy_ready && (0); // RWC: Link sequence error
// assign serr_DC = phy_ready && (0); // RWC: CRC error in Link layer
// assign serr_DB = phy_ready && (0); // RWC: 10B to 8B decode error
assign serr_EE = phy_ready && (rxelsfull || rxelsempty);
assign serr_DI = phy_ready && (0); // rxelsfull); // RWC: PHY Internal Error // just debugging
assign serr_EP = phy_ready && (0); // rxelsempty); // RWC: Protocol Error - a violation of SATA protocol detected // just debugging
assign serr_EC = phy_ready && (0); // RWC: Persistent Communication or Data Integrity Error
assign serr_ET = phy_ready && (0); // RWC: Transient Data Integrity Error (error not recovered by the interface)
assign serr_EM = phy_ready && (0); // RWC: Communication between the device and host was lost but re-established
assign serr_EI = phy_ready && (0); // RWC: Recovered Data integrity Error
reg [1:0] debug_last_d2h_type_in;
reg [1:0] debug_last_d2h_type;
always @ (posedge clk) begin
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],
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[ 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;
assign serr_EE = phy_ready && (rxelsfull || rxelsempty);
assign serr_DI = phy_ready && (0); // rxelsfull); // RWC: PHY Internal Error // just debugging
assign serr_EP = phy_ready && (0); // rxelsempty); // RWC: Protocol Error - a violation of SATA protocol detected // just debugging
assign serr_EC = phy_ready && (0); // RWC: Persistent Communication or Data Integrity Error
assign serr_ET = phy_ready && (0); // RWC: Transient Data Integrity Error (error not recovered by the interface)
assign serr_EM = phy_ready && (0); // RWC: Communication between the device and host was lost but re-established
assign serr_EI = phy_ready && (0); // RWC: Recovered Data integrity Error
// debug_phy0[15:0]};
// debug_phy0[19:0]};
/*
// Data/type FIFO, device -> host
output [31:0] d2h_data, // FIFO input data
output [ 1:0] d2h_mask, // set to 2'b11
output [ 1:0] d2h_type, // 0 - data, 1 - FIS head, 2 - R_OK, 3 - R_ERR (last two - after data, so ignore data with R_OK/R_ERR)
output d2h_valid, // Data available from the transport layer in FIFO
output d2h_many, // Multiple DWORDs available from the transport layer in FIFO
input d2h_ready, // This module or DMA consumes DWORD
*/
// .comreset_send (comreset_send), // input
// .cominit_got (cominit_got), // output wire
// .comwake_got (serr_DW), // output wire
reg [1:0] debug_last_d2h_type_in;
reg [1:0] debug_last_d2h_type;
always @ (posedge clk) begin
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 = debug_phy0;
`ifdef USE_DATASCOPE
`ifdef DATASCOPE_INCOMING_RAW
assign datascope_di = {5'b0,debug_link[5],datascope0_di[25:0]};// aligns_pair tx
`else
......@@ -332,8 +264,8 @@ assign debug_phy = debug_phy0;
);
assign datascope_di = {dbg_was_link5,datascope0_di[30:0]};// aligns_pair tx
`endif
`endif
link #(
.DATA_BYTE_WIDTH(4)
) link (
......
......@@ -767,14 +767,6 @@ end
.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],
......@@ -783,13 +775,6 @@ end
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],
......@@ -798,10 +783,13 @@ reg was_good_bad_prev;
// .debug_in3 ({22'b0, last_jump_addr[9:0]}) // input[31:0]// Last jump address in the AHDCI sequencer
.debug_in3 ({debug_in_link[7:0],
frcv_busy,frcv_ok, // 2'b0,
`ifdef USE_DATASCOPE
datascope_waddr[9:0],
`else
10'b0,
`endif
frcv_err,frcv_ferr, // 2'b0,
last_jump_addr[9:0]}) // input[31:0]// Last jump address in the AHDCI sequencer
`ifdef USE_DRP
,.drp_en (drp_en), // output reg
.drp_we (drp_we), // output reg
......
......@@ -213,7 +213,7 @@ module axi_ahci_regs#(
reg [2:0] arst_r = ~0; // previous state of arst
reg wait_first_access = RESET_TO_FIRST_ACCESS; // keep port reset until first access
wire any_access = bram_wen_r || bram_ren[0];
reg debug_rd_r;
reg debug_rd_r = 0;
reg [31:0] debug_r;
......@@ -258,15 +258,16 @@ module axi_ahci_regs#(
bram_wen_r <= bram_wen;
if (bram_wen) bram_waddr_r <= bram_waddr[ADDRESS_BITS-1:0];
`ifdef USE_DATASCOPE
if (bram_ren[0]) debug_rd_r <= (&bram_raddr[ADDRESS_BITS-1:4]) &&
// (bram_raddr[3:2] == 0) &&
!bram_raddr[ADDRESS_BITS]; //
`else
if (bram_ren[0]) debug_rd_r <= (&bram_raddr[ADDRESS_BITS-1:4]); // &&
// (bram_raddr[3:2] == 0); //
`endif
`ifndef NO_DEBUG_OUT
`ifdef USE_DATASCOPE
if (bram_ren[0]) debug_rd_r <= (&bram_raddr[ADDRESS_BITS-1:4]) &&
// (bram_raddr[3:2] == 0) &&
!bram_raddr[ADDRESS_BITS]; //
`else
if (bram_ren[0]) debug_rd_r <= (&bram_raddr[ADDRESS_BITS-1:4]); // &&
// (bram_raddr[3:2] == 0); //
`endif
`endif // `else `ifdef NO_DEBUG_OUT
if (bram_ren[0]) debug_r <= bram_raddr[1]? (bram_raddr[0] ? debug_in3: debug_in2):
(bram_raddr[0] ? debug_in1: debug_in0);
......
......@@ -6,12 +6,15 @@ create_clock -name axi_aclk0 -period 20.000 -waveform {0.000 10.000} [get_nets a
create_clock -name gtrefclk -period 6.666 -waveform {0.000 3.333} [get_nets sata_top/ahci_sata_layers_i/phy/gtrefclk]
# after plls inside of GTX:
create_clock -name txoutclk -period 6.666 -waveform {0.000 3.333} [get_nets sata_top/ahci_sata_layers_i/phy/txoutclk]
#create_clock -name txoutclk -period 6.666 -waveform {0.000 3.333} [get_nets sata_top/ahci_sata_layers_i/phy/txoutclk]
#create_clock -name txoutclk -period 6.666 -waveform {0.000 3.333} [get_nets sata_top/ahci_sata_layers_i/phy/gtx_wrap/bufg_txoutclk/valid_reg]
###create_clock -name txoutclk -period 6.666 -waveform {0.000 3.333} [get_nets sata_top/ahci_sata_layers_i/phy/gtx_wrap/bufg_txoutclk/txoutclk_gtx]
# recovered sata parallel clock
##create_clock -name xclk -period 6.666 -waveform {0.000 3.333} [get_nets sata_top/ahci_sata_layers_i/phy/gtx_wrap/xclk]
create_clock -name xclk -period 6.666 -waveform {0.000 3.333} [get_nets sata_top/ahci_sata_layers_i/phy/gtx_wrap/xclk_gtx]
###sata_top/ahci_sata_layers_i/phy/gtx_wrap/xclk_gtx sata_top/ahci_sata_layers_i/phy/gtx_wrap/gtxe2_channel_wrapper/xclk_gtx
create_clock -name txoutclk -period 6.666 -waveform {0.000 3.333} [get_nets sata_top/ahci_sata_layers_i/phy/gtx_wrap/txoutclk_gtx]
# txoutclk -> userpll, which gives us 2 clocks: userclk (150MHz) and userclk2 (75MHz) . The second one is sata host clk
###create_generated_clock -name usrclk [get_nets sata_top/ahci_sata_layers_i/phy/CLK]
......@@ -21,14 +24,29 @@ create_clock -name xclk -period 6.666 -waveform {0.000 3.333} [get_nets sata_top
###These clocks are already automatically extracted
#create_generated_clock -name usrclk [get_nets sata_top/ahci_sata_layers_i/phy/usrclk]
#create_generated_clock -name usrclk2 [get_nets sata_top/ahci_sata_layers_i/phy/usrclk2]
#create_clock -name usrclk2 -period 15.333 -waveform {0.000 6.666} [get_nets sata_top/ahci_sata_layers_i/phy/bufg_sclk/usrclk2_r]
#create_clock -name usrclk2 -period 15.333 -waveform {0.000 6.666} [get_nets sata_top/ahci_sata_layers_i/phy/bufg_sclk/rclk]
create_clock -name usrclk2 -period 13.333 -waveform {0.000 6.666} [get_nets sata_top/ahci_sata_layers_i/phy/usrclk2_r]
#
#create_generated_clock -name usrclk2 [get_nets sata_top/ahci_sata_layers_i/phy/usrclk2_r]
#puts [get_nets sata_top/ahci_sata_layers_i/phy/usrclk2_r]
#set_clock_groups -name async_clocks -asynchronous \
#-group {gtrefclk} \
#-group {axi_aclk0} \
#-group {xclk} \
#-group {usrclk} \
#-group {usrclk2} \
#-group {clk_axihp_pre} \
#-group {txoutclk}
set_clock_groups -name async_clocks -asynchronous \
-group {gtrefclk} \
-group {axi_aclk0} \
-group {xclk} \
-group {usrclk} \
-group {usrclk2} \
-group {clk_axihp_pre} \
-group {txoutclk}
###-group {sclk} \
/*******************************************************************************
* Module: drp_other_registers
* Date:2016-03-13
* Author: andrey
* Description: Additional registers controlled/read back over DRP
*
* Copyright (c) 2016 Elphel, Inc .
* drp_other_registers.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* drp_other_registers.v is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
`timescale 1ns/1ps
module drp_other_registers#(
parameter DRP_ABITS = 8,
parameter DRP_REG0 = 8,
parameter DRP_REG1 = 9,
parameter DRP_REG2 = 10,
parameter DRP_REG3 = 11
)(
input drp_rst,
input drp_clk,
input drp_en, // @aclk strobes drp_ad
input drp_we,
input [DRP_ABITS-1:0] drp_addr,
input [15:0] drp_di,
output reg drp_rdy,
output reg [15:0] drp_do,
output [15:0] drp_register0,
output [15:0] drp_register1,
output [15:0] drp_register2,
output [15:0] drp_register3
);
reg [DRP_ABITS-1:0] drp_addr_r;
reg drp_wr_r;
reg [ 1:0] drp_rd_r;
reg [15:0] drp_di_r;
reg drp_reg0_set;
reg drp_reg1_set;
reg drp_reg2_set;
reg drp_reg3_set;
reg drp_reg0_get;
reg drp_reg1_get;
reg drp_reg2_get;
reg drp_reg3_get;
reg [15:0] drp_register0_r;
reg [15:0] drp_register1_r;
reg [15:0] drp_register2_r;
reg [15:0] drp_register3_r;
assign drp_register0 = drp_register0_r;
assign drp_register1 = drp_register1_r;
assign drp_register2 = drp_register2_r;
assign drp_register3 = drp_register3_r;
// DRP interface
always @ (posedge drp_clk) begin
drp_addr_r <= drp_addr;
drp_wr_r <= drp_we && drp_en;
drp_rd_r <= {drp_rd_r[0],~drp_we & drp_en};
drp_di_r <= drp_di;
drp_reg0_set <= drp_wr_r && (drp_addr_r == DRP_REG0);
drp_reg1_set <= drp_wr_r && (drp_addr_r == DRP_REG1);
drp_reg2_set <= drp_wr_r && (drp_addr_r == DRP_REG2);
drp_reg3_set <= drp_wr_r && (drp_addr_r == DRP_REG3);
drp_reg0_get <= drp_rd_r[0] && (drp_addr_r == DRP_REG0);
drp_reg1_get <= drp_rd_r[0] && (drp_addr_r == DRP_REG1);
drp_reg2_get <= drp_rd_r[0] && (drp_addr_r == DRP_REG2);
drp_reg3_get <= drp_rd_r[0] && (drp_addr_r == DRP_REG3);
drp_rdy <= drp_wr_r || drp_rd_r[1];
drp_do <= ({16{drp_reg0_get}} & drp_register0_r) |
({16{drp_reg1_get}} & drp_register1_r) |
({16{drp_reg2_get}} & drp_register2_r) |
({16{drp_reg3_get}} & drp_register3_r);
if (drp_rst) drp_register0_r <= 0;
else if (drp_reg0_set) drp_register0_r <= drp_di_r;
if (drp_rst) drp_register1_r <= 0;
else if (drp_reg1_set) drp_register1_r <= drp_di_r;
if (drp_rst) drp_register2_r <= 0;
else if (drp_reg2_set) drp_register2_r <= drp_di_r;
if (drp_rst) drp_register3_r <= 0;
else if (drp_reg3_set) drp_register3_r <= drp_di_r;
end
endmodule
......@@ -37,7 +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
//`define DEBUG_ELASTIC
module gtx_wrap #(
`ifdef USE_DATASCOPE
parameter ADDRESS_BITS = 10, // for datascope
......@@ -61,10 +61,9 @@ module gtx_wrap #(
input wire cplllockdetclk,
input wire cpllreset,
input wire gtrefclk,
input wire drpclk,
input wire rxuserrdy,
input wire txuserrdy,
input wire rxusrclk,
// input wire rxusrclk,
input wire rxusrclk2,
input wire rxp,
input wire rxn,
......@@ -175,9 +174,9 @@ wire txcomwake_gtx;
wire txelecidle_gtx;
`ifdef USE_DRP
wire [1:0] drp_en_w; // [0] - select GTX, [1] - select sipo_to_xclk_measure
wire [1:0] drp_we_w; // [0] - select GTX, [1] - select sipo_to_xclk_measure
reg [1:0] drp_sel; // [0] - select GTX, [1] - select sipo_to_xclk_measure
wire [1:0] drp_en_w; // [0] - select GTX, [1] - select drp_other_registers
wire [1:0] drp_we_w; // [0] - select GTX, [1] - select drp_other_registers
reg [1:0] drp_sel; // [0] - select GTX, [1] - select drp_other_registers
wire [15:0] drp_do_gtx;
wire [15:0] drp_do_meas;
wire drp_rdy_gtx;
......@@ -411,21 +410,20 @@ wire RXDLYOVRDEN; // 9 (1'b0),
wire RXDDIEN; // 10 (1'b1), // Andrey: p.243: "Set high in RX buffer bypass mode"
wire RXLPMEN; // 11 (1'b0) 1 - enable LP, 0 - DXE
reg [19:0] rxdata_comma_in_r;
assign rxdata_comma_in = rxdata_comma_in_r;
always @ (posedge xclk)
rxdata_comma_in_r <= gtx_rx_data20;
`ifdef USE_DRP
sipo_to_xclk_measure #(
.DATA_WIDTH (20),
.DRP_ABITS (8),
.DRP_MASK_ADDR (0),
.DRP_MASK_BITS (3),
.DRP_TIMER_ADDR (8),
.DRP_EARLY_ADDR (9),
.DRP_LATE_ADDR (10),
.DRP_OTHERCTRL_ADDR (11)
) sipo_to_xclk_measure_i (
.xclk (xclk), // input
.drp_rst (drp_rst), //
.sipo_di (gtx_rx_data20), // input[19:0]
.sipo_do (rxdata_comma_in), // output[19:0] //sipo_di registered @ (posedge xclk)
drp_other_registers #(
.DRP_ABITS(8),
.DRP_REG0(8),
.DRP_REG1(9),
.DRP_REG2(10),
.DRP_REG3(11)
) drp_other_registers_i (
.drp_rst (drp_rst), // input
.drp_clk (drp_clk), // input
.drp_en (drp_en_w[1]), // input
.drp_we (drp_we_w[1]), // input
......@@ -433,7 +431,10 @@ wire RXLPMEN; // 11 (1'b0) 1 - enable LP, 0 - DXE
.drp_di (drp_di), // input[15:0]
.drp_rdy (drp_rdy_meas), // output reg
.drp_do (drp_do_meas), // output[15:0] reg
.other_control (other_control) // output[15:0] reg
.drp_register0 (), // output[15:0] // reserved for future use
.drp_register1 (), // output[15:0] // reserved for future use
.drp_register2 (), // output[15:0] // reserved for future use
.drp_register3 (other_control) // output[15:0] // reserved for future use
);
assign RXPHDLYRESET = other_control[ 1]; // 1 (1'b0),
......@@ -448,32 +449,26 @@ wire RXLPMEN; // 11 (1'b0) 1 - enable LP, 0 - DXE
assign RXDDIEN = other_control[10]; // 10 (1'b1), // Andrey: p.243: "Set high in RX buffer bypass mode"
assign RXLPMEN = other_control[11]; // 11 (1'b0) 1 - enable LP, 0 - DXE
`else
reg [19:0] rxdata_comma_in_r;
assign rxdata_comma_in = rxdata_comma_in_r;
always @ (posedge xclk)
rxdata_comma_in_r <= gtx_rx_data20;
// VDT bug - considered USE_DRP undefined during closure, temporary including unconnected module
sipo_to_xclk_measure #(
.DATA_WIDTH (20),
.DRP_ABITS (8),
.DRP_MASK_ADDR (0),
.DRP_MASK_BITS (3),
.DRP_TIMER_ADDR (8),
.DRP_EARLY_ADDR (9),
.DRP_LATE_ADDR (10),
.DRP_OTHERCTRL_ADDR (11)
) sipo_to_xclk_measure_i (
.xclk (), // input
.sipo_di (), // input[19:0]
.sipo_do (), // output[19:0] //sipo_di registered @ (posedge xclk)
.drp_clk (), // input
.drp_en (), // input
.drp_we (), // input
.drp_addr (), // input[7:0]
.drp_di (), // input[15:0]
.drp_rdy (), // output reg
drp_other_registers #(
.DRP_ABITS (8),
.DRP_REG0 (8),
.DRP_REG1 (9),
.DRP_REG2 (10),
.DRP_REG3 (11)
) drp_other_registers_i (
.drp_rst (1'b0), // input
.drp_clk (1'b0), // input
.drp_en (1'b0), // input
.drp_we (1'b0), // input
.drp_addr (8'b0), // input[7:0]
.drp_di (16'b0),// input[15:0]
.drp_rdy (), // output reg
.drp_do (), // output[15:0] reg
.other_control () // output[15:0] reg
.drp_register0 (), // output[15:0] // reserved for future use
.drp_register1 (), // output[15:0] // reserved for future use
.drp_register2 (), // output[15:0] // reserved for future use
.drp_register3 () // output[15:0] // reserved for future use
);
assign RXPHDLYRESET = 1'b0;; // 1 (1'b0),
assign RXPHALIGN = 1'b0;; // 2 (1'b0),
......@@ -560,7 +555,6 @@ elastic1632 #(
) elastic1632_i (
.wclk (xclk), // input 150MHz, recovered
.rclk (rxusrclk2), // input 75 MHz, system
// .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]
......@@ -587,15 +581,11 @@ elastic1632 #(
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;
......@@ -616,10 +606,7 @@ elastic1632 #(
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;
......@@ -633,22 +620,13 @@ elastic1632 #(
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
......@@ -945,7 +923,7 @@ gtxe2_channel_wrapper(
.DRPWE (drp_we_w[0]),
`else
.DRPADDR (9'b0),
.DRPCLK (drpclk),
.DRPCLK (1'b0),
.DRPDI (16'b0),
.DRPDO (),
.DRPEN (1'b0),
......@@ -1206,55 +1184,6 @@ gtxe2_channel_wrapper(
);
`endif // not DATASCOPE_INCOMING_RAW
/*
reg [ADDRESS_BITS - 1:0 ] datascope_post_cntr;
reg [ADDRESS_BITS - 1:0 ] datascope_waddr_r;
reg [2:0] datascope_start_r;
wire datascope_event;
reg datascope_event_r;
reg datascope_run;
reg datascope_post_run;
wire datascope_start_w = other_control[DATASCOPE_START_BIT]; // datascope requires USE_DRP to be defined
wire datascope_stop = (DATASCOPE_POST_MEAS == 0) ? datascope_event: (datascope_post_cntr == 0);
reg [2:0] datascope_trig_r;
assign datascope_waddr = datascope_waddr_r;
assign datascope_we = datascope_run;
assign datascope_clk = xclk;
assign datascope_event = (|rxnotintable_dec_out) || (|rxdisperr_dec_out) || realign || (datascope_trig_r[1] && !datascope_trig_r[2]) ;
always @ (posedge xclk) begin
datascope_trig_r <= {datascope_trig_r[1:0], datascope_trig};
datascope_start_r <= {datascope_start_r[1:0],datascope_start_w};
datascope_event_r <=datascope_event;
if (!datascope_start_r[1]) datascope_run <= 0;
else if (!datascope_start_r[2]) datascope_run <= 1;
else if (datascope_stop) datascope_run <= 0;
if (!datascope_run) datascope_post_run <= 0;
else if (datascope_event_r) datascope_post_run <= 1;
if (!datascope_post_run) datascope_post_cntr <= DATASCOPE_POST_MEAS;
else datascope_post_cntr <= datascope_post_cntr - 1;
if (!datascope_start_r[1] && datascope_start_r[0]) datascope_waddr_r <= 0; // for simulator
else if (datascope_run) datascope_waddr_r <= datascope_waddr_r + 1;
if (datascope_start_r[1]) datascope_di <= {
6'b0,
realign, // 25
comma, // 24
1'b0, // 23
state_aligned, // 22
rxnotintable_dec_out[1:0], // 21:20
rxdisperr_dec_out[1:0], // 19:18
rxcharisk_dec_out[1:0], // 17:16
rxdata_dec_out[15:0]}; // 15: 0
end
*/
`endif
always @ (posedge gtrefclk)
......
......@@ -119,7 +119,6 @@ wire is_align_p_w; // got ALIGNp prim
//CONTp should pass ALIGNp
wire frame_done;
// scrambled data
wire [DATA_BYTE_WIDTH*8 - 1:0] scrambler_out;
......@@ -183,30 +182,14 @@ wire next_will_be_data = !(is_cont_p_w || (rcv_junk && !(is_
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;
// does not work with ALIGNp pair
/*
always @ (posedge clk) begin
/// data_txing <= rst | (data_last_in & data_strobe_out | dword_val_na & rcvd_dword[CODE_DMATP]) ? 1'b0 : frame_req ? 1'b1 : data_txing;
if (rst ||
(data_last_in && data_strobe_out) ||
(dword_val_na && rcvd_dword[CODE_DMATP])) data_txing <= 0;
else if (frame_req) data_txing <= 1;
end
*/
// Trying alternative, as SM sometimes got stuck in state_send_data, last was set
// Make it safe
always @ (posedge clk) begin
/// data_txing <= rst | (data_last_in & data_strobe_out | dword_val_na & rcvd_dword[CODE_DMATP]) ? 1'b0 : frame_req ? 1'b1 : data_txing;
if (rst) data_txing_r <= 0;
else if (frame_req) data_txing_r <= 1;
else if (state_send_crc) data_txing_r <= 0;
end
// fsm
// states and transitions are taken from the doc, "Link Layer State Machine" chapter
// power mode states are not implemented. TODO insert them as an additional branch of fsm
......@@ -317,73 +300,44 @@ assign state_idle = ~state_sync_esc
// got an escaping primitive = request to cancel the transmission
// may be 1 cycle, need to extend over alignes_pair
//wire got_escape_w;
//reg got_escape_pend;
//wire got_escape = got_escape_w || got_escape_pend;
//assign got_escape_w = dword_val & rcvd_dword[CODE_SYNCP];
wire got_escape = dword_val & rcvd_dword[CODE_SYNCP]; // can wait over alignes pair
reg sync_escape_req_r; // ahci sends 1 single-clock pulse, it may hit alignes_pair
always @ (posedge clk) begin
// got_escape_pend <= alignes_pair && (got_escape_w || got_escape_pend);
sync_escape_req_r <= alignes_pair && (sync_escape_req || sync_escape_req_r);
end
//sync_escape_req
// escaping is done
assign sync_escape_ack = state_sync_esc;
reg alignes_pair; // pauses every state go give a chance to insert 2 align primitives on a line at least every 256 dwords due to spec
//wire alignes_pair_0; // time for 1st align primitive
//wire alignes_pair_1; // time for 2nd align primitive
reg [8:0] alignes_timer;
///assign alignes_pair_0 = alignes_timer == 9'd252;
///assign alignes_pair_1 = alignes_timer == 9'd253;
///assign alignes_pair_0 = alignes_timer == 9'd254;
///assign alignes_pair_1 = alignes_timer == 9'd255;
///always @ (posedge clk)
/// alignes_timer <= rst | alignes_pair_1 | state_reset ? 9'h0 : alignes_timer + 1'b1;
//select_prim[CODE_ALIGNP]
//ALIGNES_PERIOD
reg alignes_pair_0; // time for 1st align primitive
//reg alignes_pair_1; // time for 2nd align primitive
always @ (posedge clk) begin
/// if (!link_established_r || select_prim[CODE_ALIGNP]) alignes_timer <= ALIGNES_PERIOD;
if (!phy_ready || select_prim[CODE_ALIGNP]) alignes_timer <= ALIGNES_PERIOD;
else alignes_timer <= alignes_timer -1;
alignes_pair_0 <= alignes_timer == 0;
// alignes_pair_1 <= alignes_pair_0;
alignes_pair <= phy_ready && ((alignes_timer == 0) || alignes_pair_0);
end
///assign alignes_pair = link_established_r && (alignes_pair_0 | alignes_pair_1);
// assign alignes_pair = phy_ready && (alignes_pair_0 | alignes_pair_1);
always @ (posedge clk) begin
link_bad_crc <= state_rcvr_eof & crc_bad;
if (incom_ack_good) incom_ack_good_pend <= 1;
// else if (!state_rcvr_goodend && !state_rcvr_goodcrc) incom_ack_good_pend <= 0;
else if (!state_rcvr_goodcrc) incom_ack_good_pend <= 0;
if (incom_ack_bad) incom_ack_bad_pend <= 1;
// else if (!state_rcvr_badend && !state_rcvr_goodcrc) incom_ack_bad_pend <= 0; // didn't like it even with good crc
else if (!state_rcvr_goodcrc) incom_ack_bad_pend <= 0; // didn't like it even with good crc
end
// Whole transitions table, literally from doc pages 311-328
// Whole transitions table, literally from doc pages 311-328 (Andrey: now modified, may be not true)
assign set_sync_esc = sync_escape_req || sync_escape_req_r; // extended over alignes_pair
assign set_nocommerr = ~phy_ready & ~state_nocomm & ~state_reset;
assign set_nocomm = state_nocommerr;
///assign set_align = state_reset & ~link_reset;
///assign set_align = state_reset & ~link_reset & rcvd_dword[CODE_ALIGNP];
assign set_align = 0; // never, as this state is handled by OOB
assign set_align = 0; // never, as this state is handled by OOB
assign set_reset = link_reset;
assign set_send_rdy = state_idle & frame_req;
......@@ -391,8 +345,6 @@ assign set_send_rdy = state_idle & frame_req;
assign set_send_sof = state_send_rdy & phy_ready & dword_val & rcvd_dword[CODE_RRDYP];
assign set_send_data = state_send_sof & phy_ready
// | state_send_rhold & data_txing & ~dec_err & dword_val_na & ~rcvd_dword[CODE_HOLDP] & ~rcvd_dword[CODE_SYNCP] & ~rcvd_dword[CODE_DMATP]
// | state_send_shold & data_txing & data_val_in & dword_val_na & ~rcvd_dword[CODE_HOLDP] & ~rcvd_dword[CODE_SYNCP];
| state_send_rhold & data_txing & ~dec_err & dword_val_na & ~rcvd_dword[CODE_HOLDP] & ~rcvd_dword[CODE_SYNCP] & ~rcvd_dword[CODE_DMATP]
| state_send_shold & data_txing & data_val_in & dword_val_na & ~rcvd_dword[CODE_HOLDP] & ~rcvd_dword[CODE_SYNCP];
......@@ -415,9 +367,7 @@ 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_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
| state_rcvr_data & next_will_be_data; // to skip over single-cycle CODE_HOLDP
//next_will_be_data
......@@ -454,15 +404,7 @@ assign clr_send_shold = set_nocommerr | set_reset | set_sync_esc | set_sen
assign clr_send_crc = set_nocommerr | set_reset | set_sync_esc | set_send_eof; // | got_escape;
assign clr_send_eof = set_nocommerr | set_reset | set_sync_esc | set_wait; // | got_escape;
assign clr_wait = set_nocommerr | set_reset | set_sync_esc | frame_done; // | got_escape;
/*
assign clr_rcvr_wait = set_nocommerr | set_reset | set_sync_esc | set_rcvr_rdy | dword_val_na & ~rcvd_dword[CODE_XRDYP];
assign clr_rcvr_rdy = set_nocommerr | set_reset | set_sync_esc | set_rcvr_data | dword_val_na & ~rcvd_dword[CODE_XRDYP] & ~rcvd_dword[CODE_SOFP];
assign clr_rcvr_data = set_nocommerr | set_reset | set_sync_esc | set_rcvr_rhold | set_rcvr_shold | set_rcvr_eof | set_rcvr_badend | got_escape;
assign clr_rcvr_rhold = set_nocommerr | set_reset | set_sync_esc | set_rcvr_data | set_rcvr_eof | set_rcvr_shold | got_escape;
assign clr_rcvr_shold = set_nocommerr | set_reset | set_sync_esc | set_rcvr_data | set_rcvr_eof | got_escape;
assign clr_rcvr_eof = set_nocommerr | set_reset | set_sync_esc | set_rcvr_goodcrc | set_rcvr_badend;
assign clr_rcvr_goodcrc = set_nocommerr | set_reset | set_sync_esc | set_rcvr_goodend | set_rcvr_badend | got_escape;
*/
assign clr_rcvr_wait = set_nocommerr | set_reset | set_sync_esc /*| set_rcvr_rdy */ | (dword_val_na & ~rcvd_dword[CODE_XRDYP]);
assign clr_rcvr_rdy = set_nocommerr | set_reset | set_sync_esc /*| set_rcvr_data */ | (dword_val_na & ~rcvd_dword[CODE_XRDYP] & ~rcvd_dword[CODE_SOFP]);
assign clr_rcvr_data = set_nocommerr | set_reset | set_sync_esc /*| set_rcvr_rhold | set_rcvr_shold | set_rcvr_eof */ | set_rcvr_badend; // | got_escape;
......@@ -528,19 +470,6 @@ begin
state_rcvr_badend <= (state_rcvr_badend | set_rcvr_badend ) & ~(got_escape | (clr_rcvr_badend & ~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
......@@ -727,15 +656,6 @@ reg data_val_out_r;
reg [31:0] data_out_rr;
reg data_val_out_rr;
// if current == EOF => _r == CRC and _rr == last data piece
/*
always @ (posedge clk)
begin
data_out_r <= scrambler_out;
data_out_rr <= data_out_r;
data_val_out_r <= inc_is_data;
data_val_out_rr <= data_val_out_r & ~set_rcvr_eof; // means that @ previous clock cycle the delivered data was crc
end
*/
reg data_held; // some data is held in data_out_r over primitives - to be restored if not EOF
// no need to check for set_rcvr_eof - last dword will be always lost
always @ (posedge clk) begin
......@@ -757,8 +677,6 @@ assign data_mask_out = 2'b11;//{DATA_BYTE_WIDTH/2{1'b1}};
assign data_val_out = data_val_out_rr;
assign data_last_out = set_rcvr_eof;
// from TL data
// gives a strobe everytime data is present and we're at a corresponding state.
assign data_strobe_out = select_prim[CODE_DATA];
......@@ -799,11 +717,7 @@ assign incom_start_w = set_rcvr_wait; // & ~alignes_pair;
// ... and processed
assign incom_done_w = set_rcvr_goodcrc; // & ~alignes_pair;
// or the FIS had errors
//assign incom_invalidate = state_rcvr_eof & crc_bad & ~alignes_pair | state_rcvr_data & dword_val_na & rcvd_dword[CODE_WTRMP]
// | (state_rcvr_wait | state_rcvr_rdy | state_rcvr_data | state_rcvr_rhold | state_rcvr_shold | state_rcvr_eof | state_rcvr_goodcrc) & got_escape;
// Separating different types of errors, sync_escape from other problems. TODO: route individual errors to set SERR bits
//assign incom_invalidate = (state_rcvr_eof & crc_bad & ~alignes_pair) | // CRC mismatch
// (state_rcvr_data & dword_val_na & rcvd_dword[CODE_WTRMP]);
assign incom_invalidate_w = (state_rcvr_eof & crc_bad) | // CRC mismatch
(state_rcvr_data & dword_val & rcvd_dword[CODE_WTRMP]); // missed EOF?
assign incom_sync_escape = (state_rcvr_wait | state_rcvr_rdy | state_rcvr_data | state_rcvr_rhold |
......@@ -814,27 +728,6 @@ assign incom_sync_escape = (state_rcvr_wait | state_rcvr_rdy | state_rcvr_dat
assign dword_val = |rcvd_dword & phy_ready; // any valid primitive/data
assign dword_val_na = |rcvd_dword & phy_ready & ~rcvd_dword[CODE_ALIGNP]; // any valid primitive/data but ALIGNp
// determine imcoming primitive type
/*
// determine imcoming primitive type
assign rcvd_dword[CODE_DATA] = ~|phy_isk_in_r;
assign rcvd_dword[CODE_CRC] = 1'b0;
assign rcvd_dword[CODE_SYNCP] = phy_isk_in_r[0] == 1'b1 & ~|phy_isk_in_r[DATA_BYTE_WIDTH-1:1] & prim_data[CODE_SYNCP ] == phy_data_in_r;
assign rcvd_dword[CODE_ALIGNP] = phy_isk_in_r[0] == 1'b1 & ~|phy_isk_in_r[DATA_BYTE_WIDTH-1:1] & prim_data[CODE_ALIGNP] == phy_data_in_r;
assign rcvd_dword[CODE_XRDYP] = phy_isk_in_r[0] == 1'b1 & ~|phy_isk_in_r[DATA_BYTE_WIDTH-1:1] & prim_data[CODE_XRDYP ] == phy_data_in_r;
assign rcvd_dword[CODE_SOFP] = phy_isk_in_r[0] == 1'b1 & ~|phy_isk_in_r[DATA_BYTE_WIDTH-1:1] & prim_data[CODE_SOFP ] == phy_data_in_r;
assign rcvd_dword[CODE_HOLDAP] = phy_isk_in_r[0] == 1'b1 & ~|phy_isk_in_r[DATA_BYTE_WIDTH-1:1] & prim_data[CODE_HOLDAP] == phy_data_in_r;
assign rcvd_dword[CODE_HOLDP] = phy_isk_in_r[0] == 1'b1 & ~|phy_isk_in_r[DATA_BYTE_WIDTH-1:1] & prim_data[CODE_HOLDP ] == phy_data_in_r;
assign rcvd_dword[CODE_EOFP] = phy_isk_in_r[0] == 1'b1 & ~|phy_isk_in_r[DATA_BYTE_WIDTH-1:1] & prim_data[CODE_EOFP ] == phy_data_in_r;
assign rcvd_dword[CODE_WTRMP] = phy_isk_in_r[0] == 1'b1 & ~|phy_isk_in_r[DATA_BYTE_WIDTH-1:1] & prim_data[CODE_WTRMP ] == phy_data_in_r;
assign rcvd_dword[CODE_RRDYP] = phy_isk_in_r[0] == 1'b1 & ~|phy_isk_in_r[DATA_BYTE_WIDTH-1:1] & prim_data[CODE_RRDYP ] == phy_data_in_r;
assign rcvd_dword[CODE_IPP] = phy_isk_in_r[0] == 1'b1 & ~|phy_isk_in_r[DATA_BYTE_WIDTH-1:1] & prim_data[CODE_IPP ] == phy_data_in_r;
assign rcvd_dword[CODE_DMATP] = phy_isk_in_r[0] == 1'b1 & ~|phy_isk_in_r[DATA_BYTE_WIDTH-1:1] & prim_data[CODE_DMATP ] == phy_data_in_r;
assign rcvd_dword[CODE_OKP] = phy_isk_in_r[0] == 1'b1 & ~|phy_isk_in_r[DATA_BYTE_WIDTH-1:1] & prim_data[CODE_OKP ] == phy_data_in_r;
assign rcvd_dword[CODE_ERRP] = phy_isk_in_r[0] == 1'b1 & ~|phy_isk_in_r[DATA_BYTE_WIDTH-1:1] & prim_data[CODE_ERRP ] == phy_data_in_r;
// was missing
assign rcvd_dword[CODE_CONTP] = phy_isk_in_r[0] == 1'b1 & ~|phy_isk_in_r[DATA_BYTE_WIDTH-1:1] & prim_data[CODE_CONTP ] == phy_data_in_r;
*/
assign rcvd_dword[CODE_DATA] = ~|phy_isk_in_r;
assign rcvd_dword[CODE_CRC] = 1'b0;
assign rcvd_dword[CODE_SYNCP] = phy_isk_in_r[0] && !(|phy_isk_in_r[DATA_BYTE_WIDTH-1:1]) && (prim_data[CODE_SYNCP ] == phy_data_in_r);
......@@ -854,14 +747,6 @@ assign rcvd_dword[CODE_ERRP] = phy_isk_in_r[0] && !(|phy_isk_in_r[DATA_BYTE_WID
assign rcvd_dword[CODE_CONTP] = phy_isk_in_r[0] && ~(|phy_isk_in_r[DATA_BYTE_WIDTH-1:1]) && (prim_data[CODE_CONTP ] == phy_data_in_r);
// CONTp (*_r0 is one cycle ahead of *_r)
//assign is_cont_p_w = phy_isk_in_r0[0] == 1'b1 & ~|phy_isk_in_r[DATA_BYTE_WIDTH-1:1] & prim_data[CODE_CONTP ] == phy_data_in_r0;
//assign is_non_cont_non_align_p_w = phy_isk_in_r0[0] == 1'b1 & ~|phy_isk_in_r[DATA_BYTE_WIDTH-1:1] & prim_data[CODE_CONTP ] != phy_data_in_r0;
/*
assign is_cont_p_w = phy_isk_in_r0[0] && !(|phy_isk_in_r[DATA_BYTE_WIDTH-1:1]) && (prim_data[CODE_CONTP ] == phy_data_in_r0);
assign is_align_p_w = phy_isk_in_r0[0] && !(|phy_isk_in_r[DATA_BYTE_WIDTH-1:1]) && (prim_data[CODE_ALIGNP ] == phy_data_in_r0);
assign is_non_cont_non_align_p_w = phy_isk_in_r0[0] && !(|phy_isk_in_r[DATA_BYTE_WIDTH-1:1]) && (prim_data[CODE_CONTP ] != phy_data_in_r0)
&& (prim_data[CODE_ALIGNP ] != phy_data_in_r0);
*/
// Following is processed one cycle ahead of the others to replace CONTp junk with the replaced repeated primitives
assign is_cont_p_w = phy_isk_in_r0[0] && !(|phy_isk_in_r0[DATA_BYTE_WIDTH-1:1]) && (prim_data[CODE_CONTP ] == phy_data_in_r0);
assign is_align_p_w = phy_isk_in_r0[0] && !(|phy_isk_in_r0[DATA_BYTE_WIDTH-1:1]) && (prim_data[CODE_ALIGNP ] == phy_data_in_r0);
......@@ -878,16 +763,6 @@ assign frame_done_good = state_wait & dword_val & rcvd_dword[CODE_OKP];
assign frame_done_bad = state_wait & dword_val & rcvd_dword[CODE_ERRP];
// Handling 3 non-align primitives - removed, this is (should be) done by OOB
/*
always @ (posedge clk) begin
if (!phy_ready || link_reset) link_established_r <= 0;
else if (state_align && !(|non_align_cntr)) link_established_r <= 1;
if (!state_align || rcvd_dword[CODE_ALIGNP]) non_align_cntr <= 3;
else non_align_cntr <= non_align_cntr - 1;
end
*/
// =========== Debug code ===================
wire [PRIM_NUM - 1:0] rcvd_dword0; // at least oce received after reset
......@@ -910,14 +785,6 @@ assign rcvd_dword0[CODE_ERRP] = phy_isk_in_r0[0] && !(|phy_isk_in_r0[DATA_BYT
assign rcvd_dword0[CODE_CONTP] = phy_isk_in_r0[0] && !(|phy_isk_in_r0[DATA_BYTE_WIDTH-1:1]) && (prim_data[CODE_CONTP ] == phy_data_in_r0);
reg [PRIM_NUM - 1:0] debug_rcvd_dword; // at least once received after reset
//reg [7:0] debug_alignp_cntr;
///reg [7:0] debug_unknown_primitives;
///reg [7:0] debug_notaligned_primitives;
///reg [7:0] debug_data_primitives;
///reg [7:0] debug_alignes;
///reg [1:0] debug_state_reset_r;
///reg debug_alignp_r;
///reg debug_syncp_r;
reg debug_first_error;
reg debug_first_alignp;
reg debug_first_syncp;
......@@ -995,7 +862,6 @@ always @ (posedge clk) begin
else if (debug_first_nonsyncp && !debug_first_error && is_align_p_w) debug_num_later_aligns <= debug_num_later_aligns + 1;
if (rst) debug_num_other <= 0;
// else if (debug_first_nonsyncp && !debug_first_error && other_prim_r) debug_num_later_aligns <= debug_num_later_aligns + 1;
else if (debug_first_nonsyncp && !debug_first_error && other_prim_r) debug_num_other <= debug_num_other + 1;
if (rst) debug_unknown_dword <= 0;
......@@ -1017,68 +883,9 @@ always @ (posedge clk) begin
debug_states_concat[13] | debug_states_concat[11] | debug_states_concat[ 9] | debug_states_concat[7] |
debug_states_concat[ 5] | debug_states_concat[ 3] | debug_states_concat[ 1]};
/*
if (rst) debug_rcvd_dword <= 0;
debug_alignp_r <= rcvd_dword[CODE_ALIGNP];
debug_syncp_r <= rcvd_dword[CODE_SYNCP];
debug_state_reset_r <= {debug_state_reset_r[0], state_reset};
if (rst) debug_rcvd_dword <= 0;
// if (rst) debug_rcvd_dword <= 0;
else if (debug_state_reset_r[0]) debug_rcvd_dword <= debug_rcvd_dword | rcvd_dword;
if (state_reset) debug_unknown_primitives <= 0;
else if ((phy_isk_in_r == 1) && !(|rcvd_dword)) debug_unknown_primitives <= debug_unknown_primitives + 1;
if (rst) debug_data_primitives <= 0;
else if ((debug_state_reset_r[0] && debug_syncp_r)) debug_data_primitives <= debug_data_primitives + 1;
if (rst) debug_alignes <= 0;
else if (debug_state_reset_r[0] && debug_alignp_r) debug_alignes <= debug_alignes + 1;
if (rst) debug_notaligned_primitives <= 0;
// else if (phy_isk_in_r[3:1] != 0) debug_notaligned_primitives <= debug_notaligned_primitives + 1;
else if (debug_state_reset_r == 1) debug_notaligned_primitives <= debug_notaligned_primitives + 1;
*/
end
/*wire state_idle;
reg state_sync_esc; // SyncEscape
reg state_nocommerr; // NoComErr
reg state_nocomm; // NoComm
reg state_align; // SendAlign - not used, handled by OOB
reg state_reset; // RESET
// tranmitter branch
reg state_send_rdy; // SendChkRdy
reg state_send_sof; // SendSOF
reg state_send_data; // SendData
reg state_send_rhold; // RcvrHold - hold initiated by current data reciever
reg state_send_shold; // SendHold - hold initiated by current data sender
reg state_send_crc; // SendCVC
reg state_send_eof; // SendEOF
reg state_wait; // Wait
// receiver branch
reg state_rcvr_wait; // RcvWaitFifo
reg state_rcvr_rdy; // RcvChkRdy
reg state_rcvr_data; // RcvData
reg state_rcvr_rhold; // Hold - hold initiated by current data reciever
reg state_rcvr_shold; // RcvHold - hold initiated by current data sender
reg state_rcvr_eof; // RcvEOF
reg state_rcvr_goodcrc; // GoodCRC
reg state_rcvr_goodend; // GoodEnd
reg state_rcvr_badend; // BadEnd
*/
///assign debug_out[19: 0] = debug_to_first_err;
//assign debug_out[23:16] = debug_num_aligns;
//assign debug_out[31:20] = debug_num_syncs[11:0];
//assign debug_out[31:20] = debug_num_later_aligns[11:0];
///assign debug_out[31:20] = debug_num_other[11:0];
///assign debug_out = debug_unknown_dword; // first unknown dword
reg [1:0] debug_data_last_in_r;
reg [1:0] debug_alignes_pair_r;
reg [1:0] debug_state_send_data_r;
......
......@@ -210,7 +210,6 @@ oob_ctrl oob_ctrl(
);
wire cplllockdetclk; // TODO
wire drpclk; // TODO
wire cpllreset;
wire gtrefclk;
wire rxresetdone;
......@@ -221,7 +220,7 @@ wire txuserrdy;
wire rxuserrdy;
wire txusrclk;
wire txusrclk2;
wire rxusrclk;
//wire rxusrclk;
wire rxusrclk2;
wire txp;
wire txn;
......@@ -277,39 +276,18 @@ assign sata_reset_done = sata_reset_done_r[1];
assign cplllock_debug = cplllock;
assign usrpll_locked_debug = usrpll_locked;
// generate internal reset after a clock is established
// !!!ATTENTION!!!
// async rst block
//localparam [7:0] RST_TIMER_LIMIT = 8'b1000;
/*
always @ (posedge clk or posedge extrst)
// rst_timer <= extrst | ~cplllock | ~usrpll_locked ? 8'h0 : sata_reset_done ? rst_timer : rst_timer + 1'b1;
if (extrst) rst_timer <= 0;
else if (~cplllock | ~usrpll_locked) rst_timer <= 0;
else if (!sata_reset_done) rst_timer <= rst_timer + 1;
// else rst_timer <= ~cplllock | ~usrpll_locked ? 8'h0 : sata_reset_done ? rst_timer : rst_timer + 1'b1;
always @ (posedge clk or posedge extrst)
if (extrst) rst_r <= 1;
else if (~|rst_timer) rst_r <= 0;
else rst_r <= !sata_reset_done;
// else rst_r <= ~|rst_timer ? 1'b0 : sata_reset_done ? 1'b0 : 1'b1;
///assign sata_reset_done = rst_timer == RST_TIMER_LIMIT;
*/
always @ (posedge clk or posedge sata_areset) begin
if (sata_areset) sata_reset_done_r <= 0;
else sata_reset_done_r <= {sata_reset_done_r[1:0], 1'b1};
end
reg cplllock_r;
always @ (posedge gtrefclk) begin
cplllock_r <= cplllock;
rxreset_f <= ~cplllock_r | ~cplllock | cpllreset | rxreset_oob & gtx_configured;
txreset_f <= ~cplllock_r | ~cplllock | cpllreset;
/// rxreset_f <= ~cplllock | cpllreset | ~usrpll_locked | ~sata_reset_done | rxreset_oob & gtx_configured;
/// txreset_f <= ~cplllock | cpllreset | ~usrpll_locked;
txreset_f_r <= txreset_f;
rxreset_f_r <= rxreset_f;
txreset_f_rr <= txreset_f_r;
......@@ -331,7 +309,6 @@ assign gtx_ready = rxuserrdy & txuserrdy & rxresetdone & txresetdone;
// assert gtx_configured. Once gtx_ready -> 1, gtx_configured latches
always @ (posedge clk or posedge extrst)
// gtx_configured <= extrst ? 1'b0 : gtx_ready | gtx_configured;
if (extrst) gtx_configured <= 0;
else gtx_configured <= gtx_ready | gtx_configured;
......@@ -342,39 +319,23 @@ always @ (posedge clk or posedge extrst)
// 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;
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;
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
if (rst) txpcsreset_cntr <= 0;
else if (txpcsreset_req) txpcsreset_cntr <= TXPCSRESET_CYCLES;
else if (txpcsreset_cntr != 0) txpcsreset_cntr <= txpcsreset_cntr - 1;
`endif // OLD_TXPCSRESET
if (rst || txelecidle || txpcsreset_r) recal_tx_done_r <= 0;
else if (txresetdone) recal_tx_done_r <= 1;
end
// issue rx reset to restore functionality after oob sequence. Let it last 8 clock cycles
......@@ -386,7 +347,6 @@ assign rxreset_oob = rxreset_req & ~rxreset_oob_stop;
assign rxreset_ack = rxreset_oob_stop & gtx_ready;
always @ (posedge clk or posedge extrst)
// rxreset_oob_cnt <= extrst | rst | ~rxreset_req ? 4'h0 : rxreset_oob_stop ? rxreset_oob_cnt : rxreset_oob_cnt + 1'b1;
if (extrst) rxreset_oob_cnt <= 1;
else rxreset_oob_cnt <= rst | ~rxreset_req ? 4'h0 : rxreset_oob_stop ? rxreset_oob_cnt : rxreset_oob_cnt + 1'b1;
......@@ -398,79 +358,21 @@ always @ (posedge clk or posedge extrst)
wire usrclk_global;
wire usrclk2;
//`define GTX_USE_PLL
`ifdef GTX_USE_PLL
wire usrpll_fb_clk;
wire usrclk;
select_clk_buf #(
.BUFFER_TYPE("BUFG")
) bufg_usrclk (
.o (usrclk_global), // output
.i (usrclk), // input
.clr (1'b0) // input
);
PLLE2_ADV #(
.BANDWIDTH ("OPTIMIZED"),
.CLKFBOUT_MULT (8),
.CLKFBOUT_PHASE (0.000),
.CLKIN1_PERIOD (6.666),
.CLKIN2_PERIOD (0.000),
.CLKOUT0_DIVIDE (8),
.CLKOUT0_DUTY_CYCLE (0.500),
.CLKOUT0_PHASE (0.000),
.CLKOUT1_DIVIDE (16),
.CLKOUT1_DUTY_CYCLE (0.500),
.CLKOUT1_PHASE (0.000),
.COMPENSATION ("ZHOLD"),
.DIVCLK_DIVIDE (1),
.IS_CLKINSEL_INVERTED (1'b0),
.IS_PWRDWN_INVERTED (1'b0),
.IS_RST_INVERTED (1'b0),
.REF_JITTER1 (0.010),
.REF_JITTER2 (0.010),
.STARTUP_WAIT ("FALSE")
)
usrclk_pll(
.CLKFBOUT (usrpll_fb_clk),
.CLKOUT0 (usrclk), //150Mhz
.CLKOUT1 (usrclk2), // 75MHz
.CLKOUT2 (),
.CLKOUT3 (),
.CLKOUT4 (),
.CLKOUT5 (),
.DO (),
.DRDY (),
.LOCKED (usrpll_locked),
.CLKFBIN (usrpll_fb_clk),
.CLKIN1 (txoutclk),
.CLKIN2 (1'b0),
.CLKINSEL (1'b1),
.DADDR (7'h0),
.DCLK (drpclk),
.DEN (1'b0),
.DI (16'h0),
.DWE (1'b0),
.PWRDWN (1'b0),
.RST (~cplllock)
);
`else // GTX_USE_PLL
// divide txoutclk (global) by 2, then make global. Does not need to be phase-aligned - will use FIFO
reg usrclk2_r;
always @ (posedge txoutclk) begin
if (~cplllock) usrclk2_r <= 0;
else usrclk2_r <= ~usrclk2;
end
assign txusrclk = txoutclk; // 150MHz, was already global
assign usrclk_global = txoutclk; // 150MHz, was already global
assign usrclk2 = usrclk2_r;
assign usrpll_locked = cplllock;
`endif // else // GTX_USE_PLL
assign txusrclk = usrclk_global; // 150MHz
assign txusrclk2 = clk; // usrclk2;
assign rxusrclk = usrclk_global; // 150MHz
assign rxusrclk2 = clk; // usrclk2;
// divide txoutclk (global) by 2, then make global. Does not need to be phase-aligned - will use FIFO
reg usrclk2_r;
always @ (posedge txoutclk) begin
if (~cplllock) usrclk2_r <= 0;
else usrclk2_r <= ~usrclk2;
end
assign txusrclk = txoutclk; // 150MHz, was already global
assign usrclk_global = txoutclk; // 150MHz, was already global
assign usrclk2 = usrclk2_r;
assign usrpll_locked = cplllock;
assign txusrclk = usrclk_global; // 150MHz
assign txusrclk2 = clk; // usrclk2;
//assign rxusrclk = usrclk_global; // 150MHz
assign rxusrclk2 = clk; // usrclk2;
select_clk_buf #(
.BUFFER_TYPE("BUFG")
......@@ -483,7 +385,9 @@ select_clk_buf #(
/*
* Padding for an external input clock @ 150 MHz
*/
localparam [1:0] CLKSWING_CFG = 2'b11;
IBUFDS_GTE2 #(
.CLKRCV_TRST ("TRUE"),
.CLKCM_CFG ("TRUE"),
......@@ -521,10 +425,9 @@ gtx_wrap
.cplllockdetclk (cplllockdetclk), // input wire
.cpllreset (cpllreset), // input wire
.gtrefclk (gtrefclk), // input wire
.drpclk (drpclk), // input wire
.rxuserrdy (rxuserrdy), // input wire
.txuserrdy (txuserrdy), // input wire
.rxusrclk (rxusrclk), // input wire
// .rxusrclk (rxusrclk), // input wire
.rxusrclk2 (rxusrclk2), // input wire
.rxp (rxp), // input wire
.rxn (rxn), // input wire
......@@ -558,12 +461,12 @@ gtx_wrap
.rxcharisk (rxcharisk), // output[3:0] wire
.rxdisperr (rxdisperr), // output[3:0] wire
.rxnotintable (rxnotintable), // output[3:0] wire
.dbg_rxphaligndone (dbg_rxphaligndone),
.dbg_rx_clocks_aligned(dbg_rx_clocks_aligned),
.dbg_rxcdrlock (dbg_rxcdrlock) ,
.dbg_rxdlysresetdone(dbg_rxdlysresetdone),
.txbufstatus (txbufstatus[1:0]),
.xclk (xclk) // output receive clock, just to measure frequency // global
.dbg_rxphaligndone (dbg_rxphaligndone),
.dbg_rx_clocks_aligned (dbg_rx_clocks_aligned),
.dbg_rxcdrlock (dbg_rxcdrlock) ,
.dbg_rxdlysresetdone (dbg_rxdlysresetdone),
.txbufstatus (txbufstatus[1:0]),
.xclk (xclk) // output receive clock, just to measure frequency // global
`ifdef USE_DATASCOPE
,.datascope_clk (datascope_clk), // output
.datascope_waddr (datascope_waddr), // output[9:0]
......@@ -594,7 +497,6 @@ gtx_wrap
* Interfaces
*/
assign cplllockdetclk = reliable_clk; //gtrefclk;
assign drpclk = reliable_clk; //gtrefclk;
assign rxn = rxn_in;
assign rxp = rxp_in;
......@@ -646,12 +548,9 @@ end
reg [15:0] dbg_clk_align_cntr;
reg dbg_clk_align_wait;
//reg dbg_rxphaligndone_down;
//reg dbg_rxphaligndone_second;
reg [11:0] error_count;
always @ (posedge clk) begin
// if (!phy_ready) error_count <= 0;
if (rxelecidle) error_count <= 0;
else if (phy_ready && (|ll_err_out)) error_count <= error_count + 1;
......@@ -662,56 +561,21 @@ always @ (posedge clk) begin
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
//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;
assign debug_sata[11: 8] = debug_cntr3;
assign debug_sata[12] = debug_cnt[11];
assign debug_sata[13] = cplllock;
assign debug_sata[14] = cpllreset;
assign debug_sata[15] = rxelecidle;
assign debug_sata[16] = usrpll_locked;
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 = {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],
/// 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]};
`ifdef DEBUG_ELASTIC
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]};
`else //DEBUG_ELASTIC
assign debug_sata = {8'b0,
error_count[11:0],
2'b0,
datascope_waddr[9:0]};
`endif //`else DEBUG_ELASTIC
//dbg_data_cntr
`else
......
/*******************************************************************************
* Module: sipo_to_xclk_measure
* Date:2016-02-09
* Author: andrey
* Description: Measuring phase of the SIPO data output relative to (global) xclk
* This module allow select all/some of the input data lines and see if the data
* sampled at negedge of the xclk differs from sampled at the previous or next
* posedge on any of the selected bits. Mismatch with previous posedge means that
* data comes while xclk == 0 (input data too late), mismatch with next posedge
* means that data changes while xclk == 1 (too early).
* Input selection for low 16 bits is written at address DRP_MASK_ADDR (0), next
* 16 bits - at DRP_MASK_ADDR + 1.
* Measurement starts by writing duration to DRP_TIMER_ADDR (8).
* Results (number of mismatches) are available as 15-bit numbers at
* DRP_EARLY_ADDR (9) and DRP_LATE_ADDR (10), MSB indicates that measurement is
* still in progress (wait it clears, small latency for 0 -> 1 should not be
* a problem).
*
* Copyright (c) 2016 Elphel, Inc .
* sipo_to_xclk_measure.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sipo_to_xclk_measure.v is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
`timescale 1ns/1ps
module sipo_to_xclk_measure#(
parameter DATA_WIDTH = 20, // Number of data bits to measure
parameter DRP_ABITS = 8,
parameter DRP_MASK_ADDR = 0,
parameter DRP_MASK_BITS = 3,
parameter DRP_TIMER_ADDR = 8, // write timer value (how long to count early/late)
parameter DRP_EARLY_ADDR = 9, // write timer value (how long to count early/late)
parameter DRP_LATE_ADDR = 10, // write timer value (how long to count early/late)
parameter DRP_OTHERCTRL_ADDR = 11
)(
input xclk,
input drp_rst, // for other_control
input [DATA_WIDTH-1:0] sipo_di,
output [DATA_WIDTH-1:0] sipo_do, // input data registered @ posedge xclk (to be used by other modules)
input drp_clk,
input drp_en, // @aclk strobes drp_ad
input drp_we,
input [DRP_ABITS-1:0] drp_addr,
input [15:0] drp_di,
output reg drp_rdy,
output reg [15:0] drp_do,
output reg [15:0] other_control // set/reset some control bits not related to this module
);
localparam MASK_WORDS = (DATA_WIDTH + 15) >> 4;
reg [DATA_WIDTH-1:0] sipo_p; // input data registered @ posedge xclk
reg [DATA_WIDTH-1:0] sipo_n; // input data registered @ negedge xclk
reg [DATA_WIDTH-1:0] sipo_pp; // input data registered twice @ posedge xclk
reg [DATA_WIDTH-1:0] sipo_np; // input data registered @ negedge xclk, then @ posedge xclk
reg [(16 * MASK_WORDS) - 1:0] dmask; // bits to consider (or)
reg input_early_r; // SIPO data is intended to be registered @ posedge xclk
reg input_late_r;
reg [15:0] timer_cntr;
reg [14:0] early_cntr;
reg [14:0] late_cntr;
wire timer_start;
reg timer_run;
reg [DRP_ABITS-1:0] drp_addr_r;
reg drp_wr_r;
reg [ 1:0] drp_rd_r;
reg [15:0] drp_di_r;
reg drp_mask_wr;
reg drp_timer_wr;
reg drp_read_early;
reg drp_read_late;
reg drp_other_ctrl;
reg drp_read_other_ctrl;
localparam DRP_MASK_MASK = (1 << DRP_MASK_BITS) -1;
assign sipo_do = sipo_p;
always @ (negedge xclk) sipo_n <= sipo_di; // only data registered @negedge
always @ (posedge xclk) begin
sipo_p <= sipo_di;
sipo_np <= sipo_n;
sipo_pp <= sipo_p;
input_early_r <= |(dmask[DATA_WIDTH-1:0] & (sipo_np ^ sipo_pp));
input_late_r <= |(dmask[DATA_WIDTH-1:0] & (sipo_np ^ sipo_p));
if (timer_start) timer_cntr <= drp_di_r;
else if (timer_run) timer_cntr <= timer_cntr - 1;
if (timer_start) timer_run <= 1;
else if (!(|timer_cntr[15:1])) timer_run <= 0;
if (timer_start) early_cntr <= 0;
else if (timer_run && input_early_r) early_cntr <= early_cntr + 1;
if (timer_start) late_cntr <= 0;
else if (timer_run && input_late_r) late_cntr <= late_cntr + 1;
end
// DRP interface
always @ (posedge drp_clk) begin
drp_addr_r <= drp_addr;
drp_wr_r <= drp_we && drp_en;
drp_rd_r <= {drp_rd_r[0],~drp_we & drp_en};
drp_di_r <= drp_di;
drp_mask_wr <= drp_wr_r && ((drp_addr_r & ~DRP_MASK_MASK) == DRP_MASK_ADDR);
drp_timer_wr <= drp_wr_r && (drp_addr_r == DRP_TIMER_ADDR);
drp_read_early <= drp_rd_r[0] && (drp_addr_r == DRP_EARLY_ADDR);
drp_read_late <= drp_rd_r[0] && (drp_addr_r == DRP_LATE_ADDR);
drp_other_ctrl <= drp_wr_r && (drp_addr_r == DRP_OTHERCTRL_ADDR);
drp_read_other_ctrl <= drp_rd_r[0] && (drp_addr_r == DRP_OTHERCTRL_ADDR);
drp_rdy <= drp_wr_r || drp_rd_r[1];
drp_do <= ({16{drp_read_early}} & {timer_run,early_cntr}) |
({16{drp_read_late}} & {timer_run,late_cntr}) |
({16{drp_read_other_ctrl}} & {other_control}) ;
if (drp_rst) other_control <= 0;
else if (drp_other_ctrl) other_control <= drp_di_r;
end
// 0..7 - data mask
genvar i1;
generate
for (i1 = 0; i1 < MASK_WORDS; i1 = i1 + 1) begin: gen_drp_mask
always @ (posedge drp_clk)
if (drp_mask_wr && ((drp_addr_r & DRP_MASK_MASK) ==i1)) dmask[16*i1 +: 16] <= drp_di_r;
end
endgenerate
pulse_cross_clock #(
.EXTRA_DLY(0)
) timer_set_i (
.rst (drp_mask_wr), // input
.src_clk (drp_clk), // input
.dst_clk (xclk), // input
.in_pulse (drp_timer_wr), // input
.out_pulse (timer_start), // output
.busy() // output
);
endmodule
......@@ -320,6 +320,7 @@ class x393sata(object):
'''
def bitstream(self,
bitfile=None,
ss_off=True,
quiet=1):
"""
Turn FPGA clock OFF, reset ON, load bitfile, turn clock ON and reset OFF
......@@ -335,11 +336,14 @@ class x393sata(object):
print("vcc_sens01 vp33sens01 vcc_sens23 vp33sens23", file = f)
"""
#Spread Spectrum off on channel 3
if quiet < 2:
print ("Spread Spectrum off on channel 3")
with open (SI5338_PATH+"/spread_spectrum/ss3_values","w") as f:
print ("0",file=f)
if ss_off:
if quiet < 2:
print ("Spread Spectrum off on channel 3")
with open (SI5338_PATH+"/spread_spectrum/ss3_values","w") as f:
print ("0",file=f)
else:
if quiet < 2:
print ("Keeping Spread Spectrum on on channel 3")
if quiet < 2:
print ("FPGA clock OFF")
self.x393_mem.write_mem(FPGA0_THR_CTRL,1)
......@@ -1545,7 +1549,7 @@ sata = x393sata.x393sata() # 1,0,"10389B")
sata.reinit_mux()
sata.bitstream()
sata.bitstream(None, False) # False - keep SS on
#sata.drp_write (0x20b,0x401) # bypass, clock align
sata.drp (0x20b,0x221) # bypass, clock align
......
......@@ -8,7 +8,7 @@
// `define DATASCOPE_INCOMING_RAW
`define PRELOAD_BRAMS
// `define AHCI_SATA 1
`define DEBUG_ELASTIC
// `define DEBUG_ELASTIC
// Enviroment-dependent options
`ifdef IVERILOG
`define SIMULATION
......
No preview for this file type
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