Commit cb2fc48f authored by Andrey Filippov's avatar Andrey Filippov

eliminating use of PLL with GTX

parent 36c295d8
...@@ -52,87 +52,87 @@ ...@@ -52,87 +52,87 @@
<link> <link>
<name>vivado_logs/VivadoBitstream.log</name> <name>vivado_logs/VivadoBitstream.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160312151407716.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160312231527798.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoOpt.log</name> <name>vivado_logs/VivadoOpt.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160312151407716.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160312231527798.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoOptPhys.log</name> <name>vivado_logs/VivadoOptPhys.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160312151407716.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160312231527798.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoOptPower.log</name> <name>vivado_logs/VivadoOptPower.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160312151407716.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160312231527798.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoPlace.log</name> <name>vivado_logs/VivadoPlace.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160312151407716.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160312231527798.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoRoute.log</name> <name>vivado_logs/VivadoRoute.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160312151407716.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160312231527798.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoSynthesis.log</name> <name>vivado_logs/VivadoSynthesis.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160312151407716.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160312231356578.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name> <name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160312151407716.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160312231527798.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name> <name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160312151407716.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160312231356578.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoTimingReportImplemented.log</name> <name>vivado_logs/VivadoTimingReportImplemented.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160312151407716.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160312231527798.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoTimingReportSynthesis.log</name> <name>vivado_logs/VivadoTimingReportSynthesis.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160312151407716.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160312231356578.log</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-opt-phys.dcp</name> <name>vivado_state/x393_sata-opt-phys.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-20160312151407716.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-20160312231527798.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-opt-power.dcp</name> <name>vivado_state/x393_sata-opt-power.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-20160312151407716.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-20160312231527798.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-opt.dcp</name> <name>vivado_state/x393_sata-opt.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-20160312151407716.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-20160312231527798.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-place.dcp</name> <name>vivado_state/x393_sata-place.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-place-20160312151407716.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-place-20160312231527798.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-route.dcp</name> <name>vivado_state/x393_sata-route.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-route-20160312151407716.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-route-20160312231527798.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-synth.dcp</name> <name>vivado_state/x393_sata-synth.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-synth-20160312151407716.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-synth-20160312231356578.dcp</location>
</link> </link>
</linkedResources> </linkedResources>
</projectDescription> </projectDescription>
...@@ -84,7 +84,7 @@ module gtx_wrap #( ...@@ -84,7 +84,7 @@ module gtx_wrap #(
input wire txelecidle, input wire txelecidle,
output wire txp, output wire txp,
output wire txn, output wire txn,
output wire txoutclk, output wire txoutclk, // global clock
input wire txpcsreset, input wire txpcsreset,
output wire txresetdone, output wire txresetdone,
input wire txcominit, input wire txcominit,
...@@ -108,7 +108,7 @@ module gtx_wrap #( ...@@ -108,7 +108,7 @@ module gtx_wrap #(
output wire [1:0] txbufstatus, output wire [1:0] txbufstatus,
output xclk // just to measure frequency to set the local clock output xclk // just to measure frequency to set the local clock (global clock)
`ifdef USE_DATASCOPE `ifdef USE_DATASCOPE
// Datascope interface (write to memory that can be software-read) // Datascope interface (write to memory that can be software-read)
...@@ -144,17 +144,9 @@ wire rxresetdone_gtx; ...@@ -144,17 +144,9 @@ wire rxresetdone_gtx;
wire txresetdone_gtx; wire txresetdone_gtx;
reg wrap_rxreset_; reg wrap_rxreset_;
reg wrap_txreset_; reg wrap_txreset_;
`ifdef OLD_ELASTIC // resets while PCS resets, active low
reg rxresetdone_gtx_r; always @ (posedge rxusrclk2) wrap_rxreset_ <= rxuserrdy & rxresetdone_gtx;
reg txresetdone_gtx_r; always @ (posedge txusrclk2) wrap_txreset_ <= txuserrdy & txresetdone_gtx;
// resets while PCS resets, active low
always @ (posedge rxusrclk2) wrap_rxreset_ <= rxuserrdy & rxresetdone_gtx_r;
always @ (posedge txusrclk2) wrap_txreset_ <= txuserrdy & txresetdone_gtx_r;
`else // OLD_ELASTIC
// resets while PCS resets, active low
always @ (posedge rxusrclk2) wrap_rxreset_ <= rxuserrdy & rxresetdone_gtx;
always @ (posedge txusrclk2) wrap_txreset_ <= txuserrdy & txresetdone_gtx;
`endif // OLD_ELASTIC
wire [63:0] rxdata_gtx; wire [63:0] rxdata_gtx;
wire [7:0] rxcharisk_gtx; wire [7:0] rxcharisk_gtx;
wire [7:0] rxdisperr_gtx; wire [7:0] rxdisperr_gtx;
...@@ -561,220 +553,69 @@ gtx_10x8dec gtx_10x8dec( ...@@ -561,220 +553,69 @@ gtx_10x8dec gtx_10x8dec(
wire rxcomwakedet_gtx; wire rxcomwakedet_gtx;
wire rxcominitdet_gtx; wire rxcominitdet_gtx;
`ifdef OLD_ELASTIC
// elastic buffer: transition from xclk to rxusrclk elastic1632 #(
wire [15:0] rxdata_els_out; .DEPTH_LOG2 (ELASTIC_DEPTH), // 16 //4),
wire [1:0] rxcharisk_els_out; .OFFSET (ELASTIC_OFFSET) // 10 //5)
wire [1:0] rxnotintable_els_out; ) elastic1632_i (
wire [1:0] rxdisperr_els_out; .wclk (xclk), // input 150MHz, recovered
wire lword_strobe; .rclk (rxusrclk2), // input 75 MHz, system
wire isaligned;
wire elastic_full;
wire elastic_empty;
gtx_elastic #(
.DEPTH_LOG2 (3),
.OFFSET (4)
)
gtx_elastic(
// .rst (~rx_clocks_aligned), // ~wrap_rxreset_),
.rst (~wrap_rxreset_),
.wclk (xclk),
.rclk (rxusrclk),
/// .isaligned_in (state_aligned),
// .isaligned_in (state_aligned && rxdlysresetdone_r), // input // .isaligned_in (state_aligned && rxdlysresetdone_r), // input
.isaligned_in (state_aligned), // input Moved clock phase reset/align to OOB module to handle .isaligned_in (state_aligned), // input Moved clock phase reset/align to OOB module to handle
.charisk_in (rxcharisk_dec_out), .charisk_in (rxcharisk_dec_out), // input[1:0]
.notintable_in (rxnotintable_dec_out), .notintable_in (rxnotintable_dec_out), // input[1:0]
.disperror_in (rxdisperr_dec_out), .disperror_in (rxdisperr_dec_out), // input[1:0]
.data_in (rxdata_dec_out), .data_in (rxdata_dec_out), // input[15:0]
.isaligned_out (rxbyteisaligned), // output
.isaligned_out (isaligned), .charisk_out (rxcharisk), // output[3:0] reg
.charisk_out (rxcharisk_els_out), .notintable_out (rxnotintable), // output[3:0] reg
.notintable_out (rxnotintable_els_out), .disperror_out (rxdisperr), // output[3:0] reg
.disperror_out (rxdisperr_els_out), .data_out (rxdata), // output[31:0] reg
.data_out (rxdata_els_out), .full (rxelsfull), // output
.empty (rxelsempty) // output
.lword_strobe (lword_strobe), );
.full (elastic_full), `ifdef DEBUG_ELASTIC
.empty (elastic_empty) localparam ALIGN_PRIM = 32'h7B4A4ABC;
); localparam SOF_PRIM = 32'h3737b57c;
localparam EOF_PRIM = 32'hd5d5b57c;
// iface resync localparam CONT_PRIM = 32'h9999aa7c;
reg rxcomwakedet_gtx_r; localparam HOLD_PRIM = 32'hd5d5aa7c;
reg rxcominitdet_gtx_r; localparam HOLDA_PRIM = 32'h9595aa7c;
localparam WTRM_PRIM = 32'h5858b57c;
// insert resync if it's necessary
generate
if (DATA_BYTE_WIDTH == 4) begin
// resync to rxusrclk
// Fin = 2*Fout => 2*WIDTHin = WIDTHout
// first data word arrived = last word of a primitive, second arrived - first one
// lword_strobe indicates that second data word is arrived
wire rxdata_resync_nempty;
reg rxdata_resync_nempty_r;
wire rxdata_resync_strobe;
wire [50:0] rxdata_resync_in;
wire [50:0] rxdata_resync_out;
reg [25:0] rxdata_resync_buf;
assign rxdata_resync_strobe = lword_strobe;
assign rxdata_resync_in = { reg [15:0] dbg_data_in_r;
isaligned, // 1 reg [1:0] dbg_charisk_in_r;
rxcomwakedet_gtx_r | rxdata_resync_buf[25], // 1 // reg [1:0] dbg_notintable_in_r;
rxcominitdet_gtx_r | rxdata_resync_buf[24], // 1 // reg [1:0] dbg_disperror_in_r;
rxresetdone_gtx_r, // 1 reg dbg_aligned32_in_r; // input data is word-aligned and got ALIGNp
txresetdone_gtx_r, // 1 reg dbg_msb_in_r; // input contains MSB
elastic_full | rxdata_resync_buf[23], // 1 // reg dbg_inc_waddr;
elastic_empty | rxdata_resync_buf[22], // 1 reg [11:0] dbg_data_cntr_r;
rxdisperr_els_out, // 2 reg [3:0] got_prims_r;
rxnotintable_els_out, // 2 reg dbg_frun;
rxcharisk_els_out, // 2 reg dbg_is_alignp_r;
rxdata_els_out, // 16 reg dbg_is_sof_r;
rxdata_resync_buf[21:0]}; // 22 / 51 total reg dbg_is_eof_r;
always @ (posedge rxusrclk) begin reg dbg_is_data_r;
/// rxdata_resync_buf <= ~wrap_rxreset_ ? 26'h0 : ~rxdata_resync_strobe ? {rxcomwakedet_gtx_r, rxcominitdet_gtx_r, elastic_full, elastic_empty, rxdisperr_els_out, rxnotintable_els_out, rxcharisk_els_out, rxdata_els_out} : rxdata_resync_buf;
if (!wrap_rxreset_) rxdata_resync_buf <= 26'b0;
else if (!rxdata_resync_strobe) rxdata_resync_buf <= {rxcomwakedet_gtx_r,
rxcominitdet_gtx_r,
elastic_full,
elastic_empty,
rxdisperr_els_out,
rxnotintable_els_out,
rxcharisk_els_out,
rxdata_els_out};
end
always @ (posedge rxusrclk2)
rxdata_resync_nempty_r <= rxdata_resync_nempty;
fifo_cross_clocks #( wire dbg_is_alignp_w = ({rxdata_dec_out, dbg_data_in_r} == ALIGN_PRIM) && ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h1);
.DATA_WIDTH (51),
.DATA_DEPTH (4) wire dbg_is_sof_w = ({rxdata_dec_out, dbg_data_in_r} == SOF_PRIM) && ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h1);
) wire dbg_is_eof_w = ({rxdata_dec_out, dbg_data_in_r} == EOF_PRIM) && ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h1);
rxdata_resynchro(
// .rst (~wrap_rxreset_),
.rst (1'b0),
.rrst (~wrap_rxreset_),
.wrst (~wrap_rxreset_),
.rclk (rxusrclk2),
.wclk (rxusrclk),
.we (rxdata_resync_strobe),
.re (rxdata_resync_nempty & rxdata_resync_nempty_r),
.data_in (rxdata_resync_in),
.data_out (rxdata_resync_out),
.nempty (rxdata_resync_nempty),
.half_empty ()
);
assign rxbyteisaligned = rxdata_resync_out[50];
assign rxcomwakedet = rxdata_resync_out[49];
assign rxcominitdet = rxdata_resync_out[48];
assign rxresetdone = rxdata_resync_out[47];
assign txresetdone = rxdata_resync_out[46];
assign rxelsfull = rxdata_resync_out[45];
assign rxelsempty = rxdata_resync_out[44];
assign rxdisperr[3:0] = {rxdata_resync_out[43:42], rxdata_resync_out[21:20]};
assign rxnotintable[3:0] = {rxdata_resync_out[41:40], rxdata_resync_out[19:18]};
assign rxcharisk[3:0] = {rxdata_resync_out[39:38], rxdata_resync_out[17:16]};
assign rxdata[31:0] = {rxdata_resync_out[37:22], rxdata_resync_out[15:0] };
end else if (DATA_BYTE_WIDTH == 2) begin
// no resync is needed => straightforward assignments
assign rxbyteisaligned = isaligned;
assign rxcomwakedet = rxcomwakedet_gtx_r;
assign rxcominitdet = rxcominitdet_gtx_r;
assign rxresetdone = rxresetdone_gtx_r;
assign txresetdone = txresetdone_gtx_r;
assign rxelsfull = elastic_full;
assign rxelsempty = elastic_empty;
assign rxdisperr[1:0] = rxdisperr_els_out;
assign rxnotintable[1:0] = rxnotintable_els_out;
assign rxcharisk[1:0] = rxcharisk_els_out;
assign rxdata[15:0] = rxdata_els_out;
end
else begin
// unconsidered case
always @ (posedge txusrclk)
begin
$display("Wrong width set in %m, value is %d", DATA_BYTE_WIDTH);
end
end
endgenerate
// latching gtx outputs, synchronous to RXUSRCLK2 = rxusrclk wire dbg_is_cont_w = ({rxdata_dec_out, dbg_data_in_r} == CONT_PRIM) && ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h1);
always @ (posedge rxusrclk) wire dbg_is_hold_w = ({rxdata_dec_out, dbg_data_in_r} == HOLD_PRIM) && ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h1);
begin wire dbg_is_holda_w = ({rxdata_dec_out, dbg_data_in_r} == HOLDA_PRIM) && ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h1);
rxcomwakedet_gtx_r <= rxcomwakedet_gtx; wire dbg_is_wrtm_w = ({rxdata_dec_out, dbg_data_in_r} == WTRM_PRIM) && ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h1);
rxcominitdet_gtx_r <= rxcominitdet_gtx;
rxresetdone_gtx_r <= rxresetdone_gtx;
txresetdone_gtx_r <= txresetdone_gtx;
end
`else // OLD_ELASTIC
elastic1632 #(
.DEPTH_LOG2 (ELASTIC_DEPTH), // 16 //4),
.OFFSET (ELASTIC_OFFSET) // 10 //5)
) 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]
.disperror_in (rxdisperr_dec_out), // input[1:0]
.data_in (rxdata_dec_out), // input[15:0]
.isaligned_out (rxbyteisaligned), // output
.charisk_out (rxcharisk), // output[3:0] reg
.notintable_out (rxnotintable), // output[3:0] reg
.disperror_out (rxdisperr), // output[3:0] reg
.data_out (rxdata), // output[31:0] reg
.full (rxelsfull), // output
.empty (rxelsempty) // output
);
`ifdef DEBUG_ELASTIC wire dbg_is_data_w = ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h0);
localparam ALIGN_PRIM = 32'h7B4A4ABC;
localparam SOF_PRIM = 32'h3737b57c;
localparam EOF_PRIM = 32'hd5d5b57c;
localparam CONT_PRIM = 32'h9999aa7c;
localparam HOLD_PRIM = 32'hd5d5aa7c;
localparam HOLDA_PRIM = 32'h9595aa7c;
localparam WTRM_PRIM = 32'h5858b57c;
reg [15:0] dbg_data_in_r; always @ (posedge xclk) begin
reg [1:0] dbg_charisk_in_r; dbg_data_in_r <= rxdata_dec_out;
// reg [1:0] dbg_notintable_in_r; dbg_charisk_in_r <= rxcharisk_dec_out;
// reg [1:0] dbg_disperror_in_r;
reg dbg_aligned32_in_r; // input data is word-aligned and got ALIGNp
reg dbg_msb_in_r; // input contains MSB
// reg dbg_inc_waddr;
reg [11:0] dbg_data_cntr_r;
reg [3:0] got_prims_r;
reg dbg_frun;
reg dbg_is_alignp_r;
reg dbg_is_sof_r;
reg dbg_is_eof_r;
reg dbg_is_data_r;
wire dbg_is_alignp_w = ({rxdata_dec_out, dbg_data_in_r} == ALIGN_PRIM) && ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h1);
wire dbg_is_sof_w = ({rxdata_dec_out, dbg_data_in_r} == SOF_PRIM) && ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h1);
wire dbg_is_eof_w = ({rxdata_dec_out, dbg_data_in_r} == EOF_PRIM) && ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h1);
wire dbg_is_cont_w = ({rxdata_dec_out, dbg_data_in_r} == CONT_PRIM) && ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h1);
wire dbg_is_hold_w = ({rxdata_dec_out, dbg_data_in_r} == HOLD_PRIM) && ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h1);
wire dbg_is_holda_w = ({rxdata_dec_out, dbg_data_in_r} == HOLDA_PRIM) && ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h1);
wire dbg_is_wrtm_w = ({rxdata_dec_out, dbg_data_in_r} == WTRM_PRIM) && ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h1);
wire dbg_is_data_w = ({rxcharisk_dec_out, dbg_charisk_in_r} == 4'h0);
always @ (posedge xclk) begin
dbg_data_in_r <= rxdata_dec_out;
dbg_charisk_in_r <= rxcharisk_dec_out;
// dbg_notintable_in_r <= rxnotintable_dec_out; // dbg_notintable_in_r <= rxnotintable_dec_out;
// dbg_disperror_in_r <= rxdisperr_dec_out; // dbg_disperror_in_r <= rxdisperr_dec_out;
...@@ -794,111 +635,72 @@ wire rxcominitdet_gtx; ...@@ -794,111 +635,72 @@ wire rxcominitdet_gtx;
// dbg_inc_waddr <= !dbg_msb_in_r || (dbg_is_alignp_w && !dbg_aligned32_in_r); // 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; // if (!dbg_aligned32_in_r || dbg_is_eof_w) dbg_frun <= 0;
// else if (dbg_is_sof_w) dbg_frun <= 1; // else if (dbg_is_sof_w) dbg_frun <= 1;
if (!dbg_aligned32_in_r || dbg_is_eof_r) dbg_frun <= 0; if (!dbg_aligned32_in_r || dbg_is_eof_r) dbg_frun <= 0;
else if (dbg_is_sof_r) dbg_frun <= 1; else if (dbg_is_sof_r) dbg_frun <= 1;
// if (!dbg_aligned32_in_r || dbg_is_sof_w) dbg_data_cntr_r <= 0; // 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; // 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; 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; 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 // 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
`endif // DEBUG_ELASATIC
reg rxresetdone_r;
reg txresetdone_r;
always @ (posedge rxusrclk2) rxresetdone_r <= rxresetdone_gtx;
always @ (posedge txusrclk2) txresetdone_r <= txresetdone_gtx;
assign rxresetdone = rxresetdone_r;
assign txresetdone = txresetdone_r;
pulse_cross_clock #(
.EXTRA_DLY(0)
) pulse_cross_clock_rxcominitdet_i (
.rst (~wrap_rxreset_), // input
.src_clk (xclk), // input
.dst_clk (rxusrclk2), // input
.in_pulse (rxcominitdet_gtx), // input
.out_pulse (rxcominitdet), // output
.busy () // output
);
pulse_cross_clock #(
.EXTRA_DLY(0)
) pulse_cross_clock_rxcomwakedet_i (
.rst (~wrap_rxreset_), // input
.src_clk (xclk), // input
.dst_clk (rxusrclk2), // input
.in_pulse (rxcomwakedet_gtx), // input
.out_pulse (rxcomwakedet), // output
.busy () // output
);
end
//rxusrclk2 `endif // DEBUG_ELASATIC
reg rxresetdone_r;
reg txresetdone_r;
always @ (posedge rxusrclk2) rxresetdone_r <= rxresetdone_gtx;
always @ (posedge txusrclk2) txresetdone_r <= txresetdone_gtx;
assign rxresetdone = rxresetdone_r;
assign txresetdone = txresetdone_r;
pulse_cross_clock #(
.EXTRA_DLY(0)
) pulse_cross_clock_rxcominitdet_i (
.rst (~wrap_rxreset_), // input
.src_clk (xclk), // input
.dst_clk (rxusrclk2), // input
.in_pulse (rxcominitdet_gtx), // input
.out_pulse (rxcominitdet), // output
.busy () // output
);
`endif //OLD_ELASTIC pulse_cross_clock #(
wire txoutclk_gtx; .EXTRA_DLY(0)
) pulse_cross_clock_rxcomwakedet_i (
.rst (~wrap_rxreset_), // input
.src_clk (xclk), // input
.dst_clk (rxusrclk2), // input
.in_pulse (rxcomwakedet_gtx), // input
.out_pulse (rxcomwakedet), // output
.busy () // output
);
wire txoutclk_gtx;
wire xclk_gtx; wire xclk_gtx;
//wire xclk_mr;
BUFG bufg_txoutclk (.O(txoutclk),.I(txoutclk_gtx));
//BUFR bufr_xclk (.O(xclk),.I(xclk_mr),.CE(1'b1),.CLR(1'b0));
//BUFMR bufmr_xclk (.O(xclk_mr),.I(xclk_gtx));
`ifdef USE_DRP
wire xclk_gtx_g;
`ifdef STRAIGHT_XCLK
BUFH BUFH_i (
.O(), // output
.I() // input
);
/* Instance template for module clock_inverter */
clock_inverter clock_inverter_i (
.rst (),
.clk_in (), // input
.invert (), // input
.clk_out() // output
);
BUFG bug_xclk (.O(xclk),.I(xclk_gtx));
`else
BUFH bufr_xclk (.O (xclk_gtx_g),
.I (xclk_gtx));
clock_inverter bug_xclk (
.rst (rxreset),
.clk_in (xclk_gtx_g), // input
.invert (other_control[15]), // input other_control[15] inverts xclk phase
.clk_out (xclk)); // output
`endif
`else
// VDT bug - incorrectly processes defines when calculating closure
BUFH BUFH_i (
.O(), // output
.I() // input
);
/* Instance template for module clock_inverter */
clock_inverter clock_inverter_i (
.rst (),
.clk_in (), // input
.invert (), // input
.clk_out() // output
);
BUFG bug_xclk (.O(xclk),.I(xclk_gtx)); select_clk_buf #(
`endif .BUFFER_TYPE("BUFG")
) bufg_txoutclk (
.o (txoutclk), // output
.i (txoutclk_gtx), // input
.clr (1'b0) // input
);
select_clk_buf #(
.BUFFER_TYPE("BUFG")
) bug_xclk (
.o (xclk), // output
.i (xclk_gtx), // input
.clr (1'b0) // input
);
gtxe2_channel_wrapper #( gtxe2_channel_wrapper #(
.SIM_RECEIVER_DETECT_PASS ("TRUE"), .SIM_RECEIVER_DETECT_PASS ("TRUE"),
......
...@@ -227,7 +227,7 @@ wire txp; ...@@ -227,7 +227,7 @@ wire txp;
wire txn; wire txn;
wire rxp; wire rxp;
wire rxn; wire rxn;
wire txoutclk; wire txoutclk; // comes out global from gtx_wrap
wire txpmareset_done; wire txpmareset_done;
wire rxeyereset_done; wire rxeyereset_done;
...@@ -377,7 +377,7 @@ always @ (posedge clk or posedge extrst) ...@@ -377,7 +377,7 @@ always @ (posedge clk or posedge extrst)
`endif // OLD_TXPCSRESET `endif // OLD_TXPCSRESET
// issue rx reset to restore functionality after oob sequence. Let it lasts 8 clock lycles // issue rx reset to restore functionality after oob sequence. Let it last 8 clock cycles
reg [3:0] rxreset_oob_cnt; reg [3:0] rxreset_oob_cnt;
wire rxreset_oob_stop; wire rxreset_oob_stop;
...@@ -395,73 +395,89 @@ always @ (posedge clk or posedge extrst) ...@@ -395,73 +395,89 @@ always @ (posedge clk or posedge extrst)
* USRCLKs generation. USRCLK @ 150MHz, same as TXOUTCLK; USRCLK2 @ 75Mhz -> sata_clk === sclk * USRCLKs generation. USRCLK @ 150MHz, same as TXOUTCLK; USRCLK2 @ 75Mhz -> sata_clk === sclk
* It's recommended to use MMCM instead of PLL, whatever * It's recommended to use MMCM instead of PLL, whatever
*/ */
wire usrpll_fb_clk;
wire usrclk;
wire usrclk2;
wire usrclk_global; wire usrclk_global;
BUFG bufg_usrclk (.O(usrclk_global),.I(usrclk)); 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 txusrclk = usrclk_global; // 150MHz
assign txusrclk2 = clk; // usrclk2; // should not use non-buffered clock! assign txusrclk2 = clk; // usrclk2;
assign rxusrclk = usrclk_global; // 150MHz assign rxusrclk = usrclk_global; // 150MHz
assign rxusrclk2 = clk; // usrclk2; // should not use non-buffered clock! assign rxusrclk2 = clk; // usrclk2;
PLLE2_ADV #( select_clk_buf #(
.BANDWIDTH ("OPTIMIZED"), .BUFFER_TYPE("BUFG")
.CLKFBOUT_MULT (8), ) bufg_sclk (
.CLKFBOUT_PHASE (0.000), .o (clk), // output
.CLKIN1_PERIOD (6.666), .i (usrclk2), // input
.CLKIN2_PERIOD (0.000), .clr (1'b0) // input
.CLKOUT0_DIVIDE (8),
.CLKOUT0_DUTY_CYCLE (0.500),
.CLKOUT0_PHASE (0.000),
.CLKOUT1_DIVIDE (16),
.CLKOUT1_DUTY_CYCLE (0.500),
.CLKOUT1_PHASE (0.000),
/* .CLKOUT2_DIVIDE = 1,
.CLKOUT2_DUTY_CYCLE = 0.500,
.CLKOUT2_PHASE = 0.000,
.CLKOUT3_DIVIDE = 1,
.CLKOUT3_DUTY_CYCLE = 0.500,
.CLKOUT3_PHASE = 0.000,
.CLKOUT4_DIVIDE = 1,
.CLKOUT4_DUTY_CYCLE = 0.500,
.CLKOUT4_PHASE = 0.000,
.CLKOUT5_DIVIDE = 1,
.CLKOUT5_DUTY_CYCLE = 0.500,
.CLKOUT5_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)
); );
/* /*
...@@ -528,7 +544,7 @@ gtx_wrap ...@@ -528,7 +544,7 @@ gtx_wrap
.txelecidle (txelecidle), // input wire .txelecidle (txelecidle), // input wire
.txp (txp), // output wire .txp (txp), // output wire
.txn (txn), // output wire .txn (txn), // output wire
.txoutclk (txoutclk), // output wire .txoutclk (txoutclk), // output wire // made global inside
.txpcsreset (txpcsreset), // input wire .txpcsreset (txpcsreset), // input wire
.txresetdone (txresetdone), // output wire .txresetdone (txresetdone), // output wire
.txcominit (txcominit), // input wire .txcominit (txcominit), // input wire
...@@ -547,7 +563,7 @@ gtx_wrap ...@@ -547,7 +563,7 @@ gtx_wrap
.dbg_rxcdrlock (dbg_rxcdrlock) , .dbg_rxcdrlock (dbg_rxcdrlock) ,
.dbg_rxdlysresetdone(dbg_rxdlysresetdone), .dbg_rxdlysresetdone(dbg_rxdlysresetdone),
.txbufstatus (txbufstatus[1:0]), .txbufstatus (txbufstatus[1:0]),
.xclk (xclk) // output receive clock, just to measure frequency .xclk (xclk) // output receive clock, just to measure frequency // global
`ifdef USE_DATASCOPE `ifdef USE_DATASCOPE
,.datascope_clk (datascope_clk), // output ,.datascope_clk (datascope_clk), // output
.datascope_waddr (datascope_waddr), // output[9:0] .datascope_waddr (datascope_waddr), // output[9:0]
...@@ -580,8 +596,6 @@ gtx_wrap ...@@ -580,8 +596,6 @@ gtx_wrap
assign cplllockdetclk = reliable_clk; //gtrefclk; assign cplllockdetclk = reliable_clk; //gtrefclk;
assign drpclk = reliable_clk; //gtrefclk; assign drpclk = reliable_clk; //gtrefclk;
//assign clk = usrclk2;
BUFG bufg_sclk (.O(clk),.I(usrclk2));
assign rxn = rxn_in; assign rxn = rxn_in;
assign rxp = rxp_in; assign rxp = rxp_in;
assign txn_out = txn; assign txn_out = txn;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
`define SYSTEM_DEFINES `define SYSTEM_DEFINES
`define USE_DRP `define USE_DRP
`define ALIGN_CLOCKS `define ALIGN_CLOCKS
`define STRAIGHT_XCLK // `define STRAIGHT_XCLK
`define USE_DATASCOPE `define USE_DATASCOPE
// `define DATASCOPE_INCOMING_RAW // `define DATASCOPE_INCOMING_RAW
`define PRELOAD_BRAMS `define PRELOAD_BRAMS
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
`include "system_defines.vh" `include "system_defines.vh"
module top #( module top #(
//`include "includes/x393_parameters.vh" // SuppressThisWarning VEditor - partially used `include "includes/x393_parameters.vh" // SuppressThisWarning VEditor - partially used
) )
( (
// sata serial data iface // sata serial data iface
...@@ -149,11 +149,31 @@ always @(posedge comb_rst or posedge axi_aclk0) begin ...@@ -149,11 +149,31 @@ always @(posedge comb_rst or posedge axi_aclk0) begin
else axi_rst_pre <= 1'b0; else axi_rst_pre <= 1'b0;
end end
//BUFG bufg_axi_aclk_i (.O(axi_aclk),.I(/*fclk[0]*/ sclk)); select_clk_buf #(
//assign axi_aclk = sclk; .BUFFER_TYPE("BUFG")
BUFG bufg_axi_aclk0_i (.O(axi_aclk0),.I(fclk[0])); ) bufg_axi_aclk0_i (
BUFG bufg_axi_rst_i (.O(axi_rst),.I(axi_rst_pre)); .o (axi_aclk0), // output
BUFG bufg_extrst_i (.O(extrst),.I(axi_rst_pre)); .i (fclk[0]), // input
.clr (1'b0) // input
);
select_clk_buf #(
.BUFFER_TYPE("BUFG")
) bufg_axi_rst_i (
.o (axi_rst), // output
.i (axi_rst_pre), // input
.clr (1'b0) // input
);
select_clk_buf #(
.BUFFER_TYPE("BUFG")
) bufg_extrst_i (
.o (extrst), // output
.i (axi_rst_pre), // input
.clr (1'b0) // input
);
axi_hp_clk #( axi_hp_clk #(
.CLKIN_PERIOD(20.000), .CLKIN_PERIOD(20.000),
.CLKFBOUT_MULT_AXIHP(18), .CLKFBOUT_MULT_AXIHP(18),
...@@ -164,6 +184,7 @@ axi_hp_clk #( ...@@ -164,6 +184,7 @@ axi_hp_clk #(
.clk_axihp (hclk), // output .clk_axihp (hclk), // output
.locked_axihp () // output // not controlled? .locked_axihp () // output // not controlled?
); );
sata_ahci_top sata_top( sata_ahci_top sata_top(
.sata_clk (sclk), .sata_clk (sclk),
// reliable clock to source drp and cpll lock det circuits // reliable clock to source drp and cpll lock det circuits
......
/*******************************************************************************
* Module: select_clk_buf
* Date:2015-11-07
* Author: andrey
* Description: Select one of the clock buffers primitives by parameter
*
* Copyright (c) 2015 Elphel, Inc .
* select_clk_buf.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.
*
* select_clk_buf.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/> .
*
* Additional permission under GNU GPL version 3 section 7:
* If you modify this Program, or any covered work, by linking or combining it
* with independent modules provided by the FPGA vendor only (this permission
* does not extend to any 3-rd party modules, "soft cores" or macros) under
* different license terms solely for the purpose of generating binary "bitstream"
* files and/or simulating the code, the copyright holders of this Program give
* you the right to distribute the covered work without those independent modules
* as long as the source code for them is available from the FPGA vendor free of
* charge, and there is no dependence on any encrypted modules for simulating of
* the combined code. This permission applies to you if the distributed code
* contains all the components and scripts required to completely simulate it
* with at least one of the Free Software programs.
*******************************************************************************/
`timescale 1ns/1ps
module select_clk_buf #(
parameter BUFFER_TYPE = "BUFR" // to use clr
)(
output o,
input i,
input clr // for BUFR_only
);
generate
if (BUFFER_TYPE == "BUFG") BUFG clk1x_i (.O(o), .I(i));
else if (BUFFER_TYPE == "BUFH") BUFH clk1x_i (.O(o), .I(i));
else if (BUFFER_TYPE == "BUFR") BUFR clk1x_i (.O(o), .I(i), .CE(1'b1), .CLR(clr));
else if (BUFFER_TYPE == "BUFMR") BUFMR clk1x_i (.O(o), .I(i));
else if (BUFFER_TYPE == "BUFIO") BUFIO clk1x_i (.O(o), .I(i));
else assign o = i;
endgenerate
endmodule
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