3 // ===========================================================================
4 // >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
5 // ---------------------------------------------------------------------------
6 // Copyright (c) 2016 by Lattice Semiconductor Corporation
8 // ------------------------------------------------------------------
12 // Lattice SG Pte. Ltd. grants permission to use this code
13 // pursuant to the terms of the Lattice Reference Design License Agreement.
18 // This VHDL or Verilog source code is intended as a design reference
19 // which illustrates how these types of functions can be implemented.
20 // It is the user's responsibility to verify their design for
21 // consistency and functionality through the use of formal
22 // verification methods. Lattice provides no warranty
23 // regarding the use or functionality of this code.
25 // ---------------------------------------------------------------------------
27 // Lattice SG Pte. Ltd.
28 // 101 Thomson Road, United Square #07-02
32 // TEL: 1-800-Lattice (USA and Canada)
33 // +65-6631-2000 (Singapore)
34 // +1-503-268-8001 (other locations)
36 // web: http://www.latticesemi.com/
37 // email: techsupport@latticesemi.com
39 // ---------------------------------------------------------------------------
41 // =============================================================================
43 // Project : RSL- Reset Sequence Logic
45 // Title : Top-level file for RSL
49 // =============================================================================
53 // Mod. Date : October 28, 2013
54 // Changes Made : Initial Creation
55 // -----------------------------------------------------------------------------
58 // Mod. Date : November 06, 2013
59 // Changes Made : Tx/Rx separation, ready port code exclusion
60 // -----------------------------------------------------------------------------
63 // Mod. Date : June 13, 2014
64 // Changes Made : Updated Rx PCS reset method
65 // -----------------------------------------------------------------------------
66 // -----------------------------------------------------------------------------
69 // Mod. Date : Dec 19, 2014
70 // Changes Made : Added new parameter fro PCIE
71 // -----------------------------------------------------------------------------
74 // Mod. Date : Feb 23, 2016
75 // Changes Made : Behavior of rx_rdy output modified. The output rx_rdy
76 // and the rx_rdy wait counter are reset to zero on
77 // LOL or LOS. Reverted back the counter value change for PCIE.
78 // -----------------------------------------------------------------------------
81 // Mod. Date: : March 21, 2017
83 // -----------------------------------------------------------------------------
86 // Mod. Date: : May 8, 2017
87 // Changes Made : Implemented common RSL behaviour as proposed by BM.
88 // =============================================================================
92 module sgmii_channel_smi_pcsrsl_core (
93 // ------------ Inputs
95 rui_rst, // Active high reset for the RSL module
96 rui_serdes_rst_dual_c, // SERDES macro reset user command
97 rui_rst_dual_c, // PCS dual reset user command
98 rui_rsl_disable, // Active high signal that disables all reset outputs of RSL
100 rui_tx_ref_clk, // Tx reference clock
101 rui_tx_serdes_rst_c, // Tx SERDES reset user command
102 rui_tx_pcs_rst_c, // Tx lane reset user command
103 rdi_pll_lol, // Tx PLL Loss of Lock status input from the SERDES
105 rui_rx_ref_clk, // Rx reference clock
106 rui_rx_serdes_rst_c, // SERDES Receive channel reset user command
107 rui_rx_pcs_rst_c, // Rx lane reset user command
108 rdi_rx_los_low_s, // Receive loss of signal status input from SERDES
109 rdi_rx_cdr_lol_s, // Receive CDR loss of lock status input from SERDES
111 // ------------ Outputs
113 rdo_serdes_rst_dual_c, // SERDES macro reset command output
114 rdo_rst_dual_c, // PCS dual reset command output
116 ruo_tx_rdy, // Tx lane ready status output
117 rdo_tx_serdes_rst_c, // SERDES Tx reset command output
118 rdo_tx_pcs_rst_c, // PCS Tx lane reset command output
120 ruo_rx_rdy, // Rx lane ready status output
121 rdo_rx_serdes_rst_c, // SERDES Rx channel reset command output
122 rdo_rx_pcs_rst_c // PCS Rx lane reset command output
125 // ------------ Module parameters
127 parameter pnum_channels = `NUM_CHANNELS; // 1,2,4
129 parameter pnum_channels = 1;
133 parameter pprotocol = "PCIE";
135 parameter pprotocol = "";
139 parameter pserdes_mode = "RX ONLY";
142 parameter pserdes_mode = "TX ONLY";
144 parameter pserdes_mode = "RX AND TX";
149 parameter pport_tx_rdy = "ENABLED";
151 parameter pport_tx_rdy = "DISABLED";
155 parameter pwait_tx_rdy = `WAIT_TX_RDY;
157 parameter pwait_tx_rdy = 3000;
161 parameter pport_rx_rdy = "ENABLED";
163 parameter pport_rx_rdy = "DISABLED";
167 parameter pwait_rx_rdy = `WAIT_RX_RDY;
169 parameter pwait_rx_rdy = 3000;
172 // ------------ Local parameters
173 localparam wa_num_cycles = 1024;
174 localparam dac_num_cycles = 3;
175 localparam lreset_pwidth = 3; // reset pulse width-1, default=4-1=3
176 localparam lwait_b4_trst = 781250; // 5ms wait with worst-case Fmax=156 MHz
177 localparam lwait_b4_trst_s = 781; // for simulation
178 localparam lplol_cnt_width = 20; // width for lwait_b4_trst
179 localparam lwait_after_plol0 = 4;
180 localparam lwait_b4_rrst = 180224; // total calibration time
181 localparam lrrst_wait_width = 20;
182 localparam lwait_after_rrst = 800000; // For CPRI- unused
183 localparam lwait_b4_rrst_s = 460; // wait cycles provided by design team
184 localparam lrlol_cnt_width = 19; // width for lwait_b4_rrst
185 localparam lwait_after_lols = (16384 * dac_num_cycles) + wa_num_cycles; // 16384 cycles * dac_num_cycles + 1024 cycles
186 localparam lwait_after_lols_s = 150; // wait cycles provided by design team
187 localparam llols_cnt_width = 18; // lols count width
188 localparam lrdb_max = 15; // maximum debounce count
189 localparam ltxr_wait_width = 12; // width of tx ready wait counter
190 localparam lrxr_wait_width = 12; // width of tx ready wait counter
192 // ------------ input ports
194 input rui_serdes_rst_dual_c;
195 input rui_rst_dual_c;
196 input rui_rsl_disable;
198 input rui_tx_ref_clk;
199 input rui_tx_serdes_rst_c;
200 input [3:0] rui_tx_pcs_rst_c;
203 input rui_rx_ref_clk;
204 input [3:0] rui_rx_serdes_rst_c;
205 input [3:0] rui_rx_pcs_rst_c;
206 input [3:0] rdi_rx_los_low_s;
207 input [3:0] rdi_rx_cdr_lol_s;
209 // ------------ output ports
210 output rdo_serdes_rst_dual_c;
211 output rdo_rst_dual_c;
214 output rdo_tx_serdes_rst_c;
215 output [3:0] rdo_tx_pcs_rst_c;
218 output [3:0] rdo_rx_serdes_rst_c;
219 output [3:0] rdo_rx_pcs_rst_c;
221 // ------------ Internal registers and wires
224 wire rui_serdes_rst_dual_c;
226 wire rui_rsl_disable;
228 wire rui_tx_serdes_rst_c;
229 wire [3:0] rui_tx_pcs_rst_c;
232 wire [3:0] rui_rx_serdes_rst_c;
233 wire [3:0] rui_rx_pcs_rst_c;
234 wire [3:0] rdi_rx_los_low_s;
235 wire [3:0] rdi_rx_cdr_lol_s;
238 wire rdo_serdes_rst_dual_c;
241 wire rdo_tx_serdes_rst_c;
242 wire [3:0] rdo_tx_pcs_rst_c;
244 wire [3:0] rdo_rx_serdes_rst_c;
245 wire [3:0] rdo_rx_pcs_rst_c;
250 wire [lplol_cnt_width-1:0] wait_b4_trst;
251 wire [lrlol_cnt_width-1:0] wait_b4_rrst;
252 wire [llols_cnt_width-1:0] wait_after_lols;
257 // rdo_tx_serdes_rst_c
258 reg [lplol_cnt_width-1:0] plol_cnt;
274 wire dual_or_serd_rst;
277 reg txsr_appd /* synthesis syn_keep=1 */;
279 reg [pnum_channels-1:0] txpr_appd;
281 reg [ltxr_wait_width-1:0] txr_wt_cnt;
308 reg [3:0] rlol_db_cnt;
309 wire rlol_db_cnt_max;
310 wire rlol_db_cnt_zero;
314 reg [3:0] rlos_db_cnt;
315 wire rlos_db_cnt_max;
316 wire rlos_db_cnt_zero;
320 // rdo_rx_serdes_rst_c
321 reg [lrlol_cnt_width-1:0] rlol1_cnt;
326 reg [lrrst_wait_width-1:0] rrst_cnt;
339 reg [llols_cnt_width-1:0] rlols0_cnt;
345 wire rx_any_serd_rst;
346 reg [llols_cnt_width-1:0] rlolsz_cnt;
351 reg [15:0] data_loop_b_cnt;
356 reg [pnum_channels-1:0] rxsr_appd;
357 reg [pnum_channels-1:0] rxpr_appd;
358 reg rxsdr_appd /* synthesis syn_keep=1 */;
360 wire rxsdr_or_sr_appd;
361 wire dual_or_rserd_rst;
365 reg [lrxr_wait_width-1:0] rxr_wt_cnt;
369 // ==================================================================
371 // ==================================================================
372 assign rsl_enable = ~rui_rsl_disable;
374 // ------------ rdo_serdes_rst_dual_c
375 assign rdo_serdes_rst_dual_c = (rui_rst&rsl_enable) | rui_serdes_rst_dual_c;
377 // ------------ rdo_rst_dual_c
378 assign rdo_rst_dual_c = rui_rst_dual_c;
380 // ------------ Setting counter values for RSL_SIM_MODE
382 assign wait_b4_trst = lwait_b4_trst_s;
383 assign wait_b4_rrst = lwait_b4_rrst_s;
384 assign wait_after_lols = lwait_after_lols_s;
386 assign wait_b4_trst = lwait_b4_trst;
387 assign wait_b4_rrst = lwait_b4_rrst;
388 assign wait_after_lols = lwait_after_lols;
391 // ==================================================================
393 // ==================================================================
395 if((pserdes_mode=="RX AND TX")||(pserdes_mode=="TX ONLY")) begin
397 // ------------ Synchronizing pll_lol to the tx clock
398 always @(posedge rui_tx_ref_clk or posedge rui_rst) begin
399 if(rui_rst==1'b1) begin
405 pll_lol_p1 <= rdi_pll_lol;
406 pll_lol_p2 <= pll_lol_p1;
407 pll_lol_p3 <= pll_lol_p2;
411 // ------------ rdo_tx_serdes_rst_c
412 always @(posedge rui_tx_ref_clk or posedge rui_rst) begin
415 else if((pll_lol_p2==0)||(plol_cnt_tc==1)||(rdo_tx_serdes_rst_c==1))
418 plol_cnt <= plol_cnt+1;
420 assign plol_cnt_tc = (plol_cnt==wait_b4_trst)?1'b1:1'b0;
422 always @(posedge rui_tx_ref_clk or posedge rui_rst) begin
423 if(rui_rst==1'b1) begin
424 txs_cnt <= 'd0; // tx serdes reset pulse count
425 txs_rst <= 1'b0; // tx serdes reset
427 else if(plol_cnt_tc==1)
429 else if(txs_cnt_tc==1) begin
434 txs_cnt <= txs_cnt+1;
436 assign txs_cnt_tc = (txs_cnt==lreset_pwidth)?1'b1:1'b0;
438 assign rdo_tx_serdes_rst_c = (rsl_enable&txs_rst)| rui_tx_serdes_rst_c;
440 // ------------ rdo_tx_pcs_rst_c
441 assign plol_fedge = ~pll_lol_p2 & pll_lol_p3;
442 assign plol_redge = pll_lol_p2 & ~pll_lol_p3;
443 always @(posedge rui_tx_ref_clk or posedge rui_rst) begin
446 else if(plol_fedge==1'b1)
448 else if((plol0_cnt_tc==1)||(plol_redge==1))
451 always @(posedge rui_tx_ref_clk or posedge rui_rst) begin
454 else if((pll_lol_p2==1)||(plol0_cnt_tc==1))
456 else if(waita_plol0==1'b1)
457 plol0_cnt <= plol0_cnt+1;
459 assign plol0_cnt_tc = (plol0_cnt==lwait_after_plol0)?1'b1:1'b0;
461 always @(posedge rui_tx_ref_clk or posedge rui_rst) begin
462 if(rui_rst==1'b1) begin
463 txp_cnt <= 'd0; // tx serdes reset pulse count
464 txp_rst <= 1'b0; // tx serdes reset
466 else if(plol0_cnt_tc==1)
468 else if(txp_cnt_tc==1) begin
473 txp_cnt <= txp_cnt+1;
475 assign txp_cnt_tc = (txp_cnt==lreset_pwidth)?1'b1:1'b0;
478 for(i=0;i<pnum_channels;i=i+1) begin : ifor
479 assign rdo_tx_pcs_rst_c[i] = (rsl_enable&txp_rst)| rui_tx_pcs_rst_c[i];
482 assign rdo_tx_pcs_rst_c[3:1] = 3'b000;
483 else if(pnum_channels==2)
484 assign rdo_tx_pcs_rst_c[3:2] = 2'b00;
486 // ------------ ruo_tx_rdy
487 if(pport_tx_rdy=="ENABLED") begin
488 assign dual_or_serd_rst = rdo_serdes_rst_dual_c|rdo_tx_serdes_rst_c;
489 assign tx_any_pcs_rst = rdo_rst_dual_c|(|rdo_tx_pcs_rst_c[pnum_channels-1:0]);
490 assign tx_any_rst = dual_or_serd_rst | tx_any_pcs_rst;
492 always @(posedge rui_tx_ref_clk or posedge rui_rst) begin
494 txsr_appd <= 1'b1; // tx serdes reset applied
495 else if(dual_or_serd_rst==1)
498 always @(posedge rui_tx_ref_clk or posedge rui_rst) begin
500 txdpr_appd <= 1'b0; // tx dual (pcs) reset applied
501 else if(pll_lol_p2|rdo_serdes_rst_dual_c|rdo_tx_serdes_rst_c)
503 else if(rdo_rst_dual_c==1)
508 for(m=0;m<pnum_channels;m=m+1) begin :mfor
509 always @(posedge rui_tx_ref_clk or posedge rui_rst) begin
511 txpr_appd[m] <= 1'b0; // tx pcs reset applied
512 else if(pll_lol_p2|rdo_serdes_rst_dual_c|rdo_tx_serdes_rst_c)
513 txpr_appd[m] <= 1'b0;
514 else if(txsr_appd&(rdo_tx_pcs_rst_c[m]|txdpr_appd))
515 txpr_appd[m] <= 1'b1;
519 always @(posedge rui_tx_ref_clk or posedge rui_rst) begin
521 txr_wt_en <= 0; // tx ready wait counter enable
522 else if((txr_wt_tc==1)||(dual_or_serd_rst==1))
524 else if((~ruo_tx_rdyr)&(~pll_lol_p2)&(&txpr_appd))
527 always @(posedge rui_tx_ref_clk or posedge rui_rst) begin
529 txr_wt_cnt <= 'd0; // tx ready wait count
530 else if((txr_wt_tc==1)||(tx_any_rst==1))
532 else if(txr_wt_en==1)
533 txr_wt_cnt <= txr_wt_cnt+1;
535 assign txr_wt_tc = (txr_wt_cnt==pwait_tx_rdy)?1'b1:1'b0;
537 always @(posedge rui_tx_ref_clk or posedge rui_rst) begin
539 ruo_tx_rdyr <= 1'b0; // tx serdes reset applied
540 else if((tx_any_rst==1)||(pll_lol_p2==1))
542 else if(txr_wt_tc==1)
545 assign ruo_tx_rdy = ruo_tx_rdyr;
546 end // if pport_tx_rdy
548 assign ruo_tx_rdy = 1'b0;
549 end // generate if(Rx and Tx) or (Tx only)
550 else begin // generate else (Rx only)
551 assign rdo_tx_serdes_rst_c = 1'b0;
552 assign rdo_tx_pcs_rst_c = 4'd0;
553 assign ruo_tx_rdy = 1'b0;
557 // ==================================================================
559 // ==================================================================
561 if((pserdes_mode=="RX AND TX")||(pserdes_mode=="RX ONLY")) begin
562 assign comb_rlos = |rdi_rx_los_low_s[pnum_channels-1:0];
563 assign comb_rlol = |rdi_rx_cdr_lol_s[pnum_channels-1:0];
564 //assign rlols = comb_rlos|comb_rlol;
566 // ------------ Synchronizing rlols to the rx ref clock
567 always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
568 if(rui_rst==1'b1) begin
572 //rlols_db_p1 <= 1'd1;
586 //rlols_p2 <= rlols_p1;
587 //rlols_p3 <= rlols_p2;
588 //rlols_db_p1 <= rlols_db;
590 rlol_p1 <= comb_rlol;
593 rlol_db_p1 <= rlol_db;
595 rlos_p1 <= comb_rlos;
598 rlos_db_p1 <= rlos_db;
601 assign rx_all_well = ~rlol_db && ~rlos_db;
603 //******************************************************************************
604 // [ES:05.03.17] Unused registers for clean-up
605 //------------------------------------------------------------------------------
606 // ------------ Debouncing rlols
607 // always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
608 // if(rui_rst==1'b1) rdb_cnt <= lrdb_max;
609 // else if(rlols_p2==1) begin
610 // if(!rdb_cnt_max) rdb_cnt <= rdb_cnt+1;
612 // else if(!rdb_cnt_zero) rdb_cnt <= rdb_cnt-1;
614 // assign rdb_cnt_max = (rdb_cnt==lrdb_max);
615 // assign rdb_cnt_zero = (rdb_cnt==0);
616 // always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
617 // if(rui_rst==1'b1) rlols_db <= 1;
618 // else if(rdb_cnt_max) rlols_db <= 1;
619 // else if(rdb_cnt_zero) rlols_db <= 0;
621 //******************************************************************************
623 // ------------ Debouncing rlol
624 always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
625 if(rui_rst==1'b1) rlol_db_cnt <= lrdb_max;
626 else if(rlol_p2==1) begin
627 if(!rlol_db_cnt_max) rlol_db_cnt <= rlol_db_cnt+1;
629 else if(!rlol_db_cnt_zero) rlol_db_cnt <= rlol_db_cnt-1;
631 assign rlol_db_cnt_max = (rlol_db_cnt==lrdb_max);
632 assign rlol_db_cnt_zero = (rlol_db_cnt==0);
633 always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
634 if(rui_rst==1'b1) rlol_db <= 1;
635 else if(rlol_db_cnt_max) rlol_db <= 1;
636 else if(rlol_db_cnt_zero) rlol_db <= 0;
639 // ------------ Debouncing rlos
640 always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
641 if(rui_rst==1'b1) rlos_db_cnt <= lrdb_max;
642 else if(rlos_p2==1) begin
643 if(!rlos_db_cnt_max) rlos_db_cnt <= rlos_db_cnt+1;
645 else if(!rlos_db_cnt_zero) rlos_db_cnt <= rlos_db_cnt-1;
647 assign rlos_db_cnt_max = (rlos_db_cnt==lrdb_max);
648 assign rlos_db_cnt_zero = (rlos_db_cnt==0);
649 always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
650 if(rui_rst==1'b1) rlos_db <= 1;
651 else if(rlos_db_cnt_max) rlos_db <= 1;
652 else if(rlos_db_cnt_zero) rlos_db <= 0;
655 // ------------ Calib time trigger
656 always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
657 if (rui_rst==1'b1) begin
661 if (rlol1_cnt_tc) begin
669 else if (rlos_fedge) begin
675 //***************************************************************************
676 // Total calibration time counter
677 // - this covers the band calibration time (256 cycles * 64) and
678 // DAC calibration time (16384 cycles * 10 bits)
679 //---------------------------------------------------------------------------
680 always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
681 if (rui_rst==1'b1) begin
682 rlol1_cnt <= 'd0; // Counting when Rx LOL is 1 and Rx LOS is 0
685 if(rxs_rst || rlol1_cnt_tc || rlos_redge)
688 rlol1_cnt <= rlol1_cnt+1;
691 assign rlol1_cnt_tc = (rlol1_cnt==wait_b4_rrst);
693 // ------------ rdo_rx_serdes_rst_c
694 always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
695 if (rui_rst==1'b1) begin
696 rxs_cnt <= 'd0; // rx serdes reset pulse count
697 rxs_rst <= 1'b0; // rx serdes reset
702 else if (rlol1_cnt_tc && rlol_db)
704 else if (rxs_cnt_tc==1) begin
712 rxs_cnt <= rxs_cnt+1;
715 assign rxs_cnt_tc = (rxs_cnt==lreset_pwidth)?1'b1:1'b0;
717 //***************************************************************************
718 // [ES:05.03.17] Unused logic from CPRI rrst_wait
719 //---------------------------------------------------------------------------
720 // always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
723 // else if(rlol1_cnt_tc)
725 // else if(rrst_wait)
726 // rrst_cnt <= rrst_cnt+1;
728 // assign rrst_cnt_tc = (rrst_cnt==lwait_after_rrst) ? 1'b1 : 1'b0;
729 // always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
732 // else if(pprotocol != "CPRI")
734 // else if(rlol1_cnt_tc)
736 // else if(rrst_cnt_tc==1)
739 //***************************************************************************
742 for(j=0;j<pnum_channels;j=j+1) begin :jfor
743 assign rdo_rx_serdes_rst_c[j] = (rsl_enable&rxs_rst)| rui_rx_serdes_rst_c[j];
746 assign rdo_rx_serdes_rst_c[3:1] = 3'b000;
747 else if(pnum_channels==2)
748 assign rdo_rx_serdes_rst_c[3:2] = 2'b00;
750 // ------------ rdo_rx_pcs_rst_c
751 //assign rlols_fedge = ~rlols_db & rlols_db_p1;
752 //assign rlols_redge = rlols_db & ~rlols_db_p1;
754 assign rlol_fedge = ~rlol_db & rlol_db_p1;
755 assign rlol_redge = rlol_db & ~rlol_db_p1;
756 assign rlos_fedge = ~rlos_db & rlos_db_p1;
757 assign rlos_redge = rlos_db & ~rlos_db_p1;
759 always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
760 if (rui_rst==1'b1) begin
761 waita_rlols0 <= 1'd0;
764 if ((rlos_fedge && ~rlol_db) || (rlol_fedge && ~rlos_db))
765 waita_rlols0 <= 1'b1;
766 else if (rlos_redge || rlol_redge)
767 waita_rlols0 <= 1'd0;
768 else if (rlols0_cnt_tc==1)
769 waita_rlols0 <= 1'd0;
773 //***************************************************************************
774 // Post RLOL check before pcs_rst deassertion
775 // - allowance of 2-4 DAC calibration cycles + 1024 cycles for WA module
777 //---------------------------------------------------------------------------
778 always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
779 if (rui_rst==1'b1) begin
783 if (rlol_redge || rlos_redge || rlols0_cnt_tc)
785 else if (waita_rlols0==1)
786 rlols0_cnt <= rlols0_cnt+1;
789 assign rlols0_cnt_tc = (rlols0_cnt == wait_after_lols);
790 assign rx_any_serd_rst = rdo_serdes_rst_dual_c|(|rdo_rx_serdes_rst_c);
792 //***************************************************************************
793 // [ES:05.03.17] Unused registers for clean-up
794 //---------------------------------------------------------------------------
795 // always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
797 // rlolsz_cnt <= 'd0; // Counting when both Rx LOL is 0 and Rx LOS is 0
798 // else if((rlol_db|rx_any_serd_rst)||(rlolsz_cnt_tc==1))
799 // rlolsz_cnt <= 'd0;
800 // else if((rlolsz_cnt_tc==0)&&(rlol_db==0))
801 // rlolsz_cnt <= rlolsz_cnt+1;
803 // assign rlolsz_cnt_tc = (rlolsz_cnt==wait_after_lols);
804 //***************************************************************************
806 always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
807 if (rui_rst==1'b1) begin
808 rxp_cnt2 <= 'd0; // pcs serdes reset pulse count
809 rxp_rst2 <= 1'b1; // rx pcs reset
812 if (rx_any_serd_rst || rlos_redge) begin
815 else if (rlols0_cnt_tc) begin
818 //***********************************************************************
819 // [ES:05.03.17] No need for pulse width
820 //-----------------------------------------------------------------------
821 // else if(rxp_cnt2_tc==1) begin
825 //***********************************************************************
826 // [ES:05.03.17] No need for pulse width
827 //-----------------------------------------------------------------------
828 // else if (rxp_rst2==1)
829 // rxp_cnt2 <= rxp_cnt2+1;
830 //***********************************************************************
831 end // else: !if(rui_rst==1'b1)
832 end // always @ (posedge rui_rx_ref_clk or posedge rui_rst)
833 //assign rxp_cnt2_tc = (rxp_cnt2==lreset_pwidth)?1'b1:1'b0;
835 //***************************************************************************
836 // [ES:05.03.17] No need for pulse width
837 //---------------------------------------------------------------------------
839 // always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
841 // rxp_rst2 <= 1'b1; // rx pcs reset
842 // else if(rx_any_serd_rst)
844 // else if(rlolsz_cnt_tc==1)
848 //***************************************************************************
851 for(k=0;k<pnum_channels;k=k+1) begin: kfor
852 assign rdo_rx_pcs_rst_c[k] = (rsl_enable&rxp_rst2)| rui_rx_pcs_rst_c[k];
855 assign rdo_rx_pcs_rst_c[3:1] = 3'b000;
856 else if(pnum_channels==2)
857 assign rdo_rx_pcs_rst_c[3:2] = 2'b00;
859 // ------------ ruo_rx_rdy
860 if(pport_rx_rdy=="ENABLED") begin
861 assign dual_or_rserd_rst = rdo_serdes_rst_dual_c|(|rdo_rx_serdes_rst_c[pnum_channels-1:0]);
862 assign rx_any_pcs_rst = rdo_rst_dual_c|(|rdo_rx_pcs_rst_c[pnum_channels-1:0]);
863 assign rx_any_rst = dual_or_rserd_rst | rx_any_pcs_rst;
865 always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
867 rxsdr_appd <= 1'b1; // Serdes dual reset (macro reset) applied
868 else if(rdo_serdes_rst_dual_c==1)
871 always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
873 rxdpr_appd <= 1'b0; // Rx dual PCS reset (dual reset) applied
874 else if(~rx_all_well|dual_or_rserd_rst)
876 else if(rdo_rst_dual_c==1)
881 for(l=0;l<pnum_channels;l=l+1) begin : lfor
882 always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
884 rxsr_appd[l] <= 1'b0; // rx serdes reset applied
885 else if(rdo_rx_serdes_rst_c[l]==1)
886 rxsr_appd[l] <= 1'b1;
888 always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
890 rxpr_appd[l] <= 1'b0; // rx pcs reset applied
891 else if(rdi_rx_los_low_s[l]|rdi_rx_cdr_lol_s[l]|rdo_serdes_rst_dual_c|rdo_rx_serdes_rst_c[l])
892 rxpr_appd[l] <= 1'b0;
893 else if(rxsdr_or_sr_appd&(~rx_all_well)&rdo_rx_pcs_rst_c[l])
894 rxpr_appd[l] <= 1'b1;
898 assign rxsdr_or_sr_appd = rxsdr_appd|(&rxsr_appd);
900 always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
902 rxr_wt_en <= 0; // rx ready wait counter enable
903 //else if((rxr_wt_tc==1)||(dual_or_rserd_rst==1))
904 else if((rxr_wt_tc==1)||(dual_or_rserd_rst==1)||(rx_all_well==0)) // BM, 2/4/16
906 else if(~ruo_rx_rdyr&rx_all_well&((&rxpr_appd)|rxdpr_appd))
909 always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
911 rxr_wt_cnt <= 'd0; // rx ready wait count
912 //else if((rxr_wt_tc==1)||(rx_any_rst==1))
913 else if((rxr_wt_tc==1)||(rx_any_rst==1)||(rx_all_well==0)) // BM, 2/4/16
915 else if(rxr_wt_en==1)
916 rxr_wt_cnt <= rxr_wt_cnt+1;
918 assign rxr_wt_tc = (rxr_wt_cnt==pwait_rx_rdy)?1'b1:1'b0;
920 always @(posedge rui_rx_ref_clk or posedge rui_rst) begin
922 ruo_rx_rdyr <= 1'b0; // rx serdes reset applied
923 else if((rx_any_rst==1)||(rx_all_well==0))
925 else if(rxr_wt_tc==1)
928 assign ruo_rx_rdy = ruo_rx_rdyr;
929 end // if pport_rx_rdy
931 assign ruo_rx_rdy = 1'b0;
932 end // if ((pserdes_mode=="RX AND TX")||(pserdes_mode=="RX ONLY"))
934 else begin // generate else (Tx only)
935 assign rdo_rx_serdes_rst_c = 4'd0;
936 assign rdo_rx_pcs_rst_c = 4'd0;
937 assign ruo_rx_rdy = 1'b0;
938 end // else: !if((pserdes_mode=="RX AND TX")||(pserdes_mode=="RX ONLY"))
945 // ===========================================================================
946 // >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
947 // ---------------------------------------------------------------------------
948 // Copyright (c) 2015 by Lattice Semiconductor Corporation
949 // ALL RIGHTS RESERVED
950 // ------------------------------------------------------------------
954 // Lattice SG Pte. Ltd. grants permission to use this code
955 // pursuant to the terms of the Lattice Reference Design License Agreement.
960 // This VHDL or Verilog source code is intended as a design reference
961 // which illustrates how these types of functions can be implemented.
962 // It is the user's responsibility to verify their design for
963 // consistency and functionality through the use of formal
964 // verification methods. Lattice provides no warranty
965 // regarding the use or functionality of this code.
967 // ---------------------------------------------------------------------------
969 // Lattice SG Pte. Ltd.
970 // 101 Thomson Road, United Square #07-02
974 // TEL: 1-800-Lattice (USA and Canada)
975 // +65-6631-2000 (Singapore)
976 // +1-503-268-8001 (other locations)
978 // web: http://www.latticesemi.com/
979 // email: techsupport@latticesemi.com
981 // ---------------------------------------------------------------------------
983 // =============================================================================
985 // Project : SLL - Soft Loss Of Lock(LOL) Logic
987 // Title : Top-level file for SLL
991 // =============================================================================
995 // Mod. Date : March 2, 2015
996 // Changes Made : Initial Creation
997 // =============================================================================
1001 // Mod. Date : June 8, 2015
1002 // Changes Made : Following updates were made
1003 // : 1. Changed all the PLOL status logic and FSM to run
1005 // : 2. Added the HB logic for presence of tx_pclk
1006 // : 3. Changed the lparam assignment scheme for
1007 // : simulation purposes.
1008 // =============================================================================
1012 // Mod. Date : June 24, 2015
1013 // Changes Made : Updated the gearing logic for SDI dynamic rate change
1014 // =============================================================================
1018 // Mod. Date : July 14, 2015
1019 // Changes Made : Added the logic for dynamic rate change in CPRI
1020 // =============================================================================
1024 // Mod. Date : August 21, 2015
1025 // Changes Made : Added the logic for dynamic rate change of 5G CPRI &
1027 // =============================================================================
1030 // Author(s) : ES/EB
1031 // Mod. Date : March 21, 2017
1032 // Changes Made : 1. Added pdiff_sync signal to syncrhonize pcount_diff
1034 // : 2. Updated terminal count logic for PCIe 5G
1035 // : 3. Modified checking of pcount_diff in SLL state
1036 // : machine to cover actual count
1037 // : (from 16-bits to 22-bits)
1038 // =============================================================================
1042 // Mod. Date : April 19, 2017
1043 // Changes Made : 1. Added registered lock and unlock signal from
1044 // pdiff_sync to totally decouple pcount_diff from
1045 // SLL state machine.
1046 // : 2. Modified LPCLK_TC_4 to 1:1 clock ratio when CPRI
1047 // is operating @ 4.9125Gbps data rate.
1048 // =============================================================================
1051 module sgmii_channel_smi_pcssll_core (
1052 //Reset and Clock inputs
1053 sli_rst, //Active high asynchronous reset input
1054 sli_refclk, //Refclk input to the Tx PLL
1055 sli_pclk, //Tx pclk output from the PCS
1058 sli_div2_rate, //Divide by 2 control; 0 - Full rate; 1 - Half rate
1059 sli_div11_rate, //Divide by 11 control; 0 - Full rate; 1 - Div by 11
1060 sli_gear_mode, //Gear mode control for PCS; 0 - 8/10; 1- 16/20
1061 sli_cpri_mode, //Mode of operation specific to CPRI protocol
1062 sli_pcie_mode, //Mode of operation specific to PCIe mode (2.5G or 5G)
1065 slo_plol //Tx PLL Loss of Lock output to the user logic
1072 input sli_div2_rate;
1073 input sli_div11_rate;
1074 input sli_gear_mode;
1075 input [2:0] sli_cpri_mode;
1076 input sli_pcie_mode;
1083 parameter PPROTOCOL = "PCIE"; //Protocol selected by the User
1084 parameter PLOL_SETTING = 0; //PLL LOL setting. Possible values are 0,1,2,3
1085 parameter PDYN_RATE_CTRL = "DISABLED"; //PCS Dynamic Rate control
1086 parameter PPCIE_MAX_RATE = "2.5"; //PCIe max data rate
1087 parameter PDIFF_VAL_LOCK = 20; //Differential count value for Lock
1088 parameter PDIFF_VAL_UNLOCK = 39; //Differential count value for Unlock
1089 parameter PPCLK_TC = 65535; //Terminal count value for counter running on sli_pclk
1090 parameter PDIFF_DIV11_VAL_LOCK = 3; //Differential count value for Lock for SDI Div11
1091 parameter PDIFF_DIV11_VAL_UNLOCK = 3; //Differential count value for Unlock for SDI Div11
1092 parameter PPCLK_DIV11_TC = 2383; //Terminal count value (SDI Div11) for counter running on sli_pclk
1096 localparam [1:0] LPLL_LOSS_ST = 2'b00; //PLL Loss state
1097 localparam [1:0] LPLL_PRELOSS_ST = 2'b01; //PLL Pre-Loss state
1098 localparam [1:0] LPLL_PRELOCK_ST = 2'b10; //PLL Pre-Lock state
1099 localparam [1:0] LPLL_LOCK_ST = 2'b11; //PLL Lock state
1101 localparam [15:0] LRCLK_TC = 16'd63; //Terminal count value for counter running on sli_refclk
1103 localparam [15:0] LRCLK_TC = 16'd65535; //Terminal count value for counter running on sli_refclk
1105 localparam [15:0] LRCLK_TC_PUL_WIDTH = 16'd50; //Pulse width for the Refclk terminal count pulse
1106 localparam [7:0] LHB_WAIT_CNT = 8'd255; //Wait count for the Heartbeat signal
1108 // Local Parameters related to the CPRI dynamic modes
1109 // Terminal count values for the four CPRI modes
1110 localparam LPCLK_TC_0 = 32768;
1111 localparam LPCLK_TC_1 = 65536;
1112 localparam LPCLK_TC_2 = 131072;
1113 localparam LPCLK_TC_3 = 163840;
1114 localparam LPCLK_TC_4 = 65536;
1116 // Lock values count values for the four CPRI modes and four PLOL settings (4x5)
1117 // CPRI rate mode 0 CPRI rate mode 1 CPRI rate mode 2 CPRI rate mode 3 CPRI rate mode 4
1118 localparam LPDIFF_LOCK_00 = 9; localparam LPDIFF_LOCK_10 = 19; localparam LPDIFF_LOCK_20 = 39; localparam LPDIFF_LOCK_30 = 49; localparam LPDIFF_LOCK_40 = 19;
1119 localparam LPDIFF_LOCK_01 = 9; localparam LPDIFF_LOCK_11 = 19; localparam LPDIFF_LOCK_21 = 39; localparam LPDIFF_LOCK_31 = 49; localparam LPDIFF_LOCK_41 = 19;
1120 localparam LPDIFF_LOCK_02 = 49; localparam LPDIFF_LOCK_12 = 98; localparam LPDIFF_LOCK_22 = 196; localparam LPDIFF_LOCK_32 = 245; localparam LPDIFF_LOCK_42 = 98;
1121 localparam LPDIFF_LOCK_03 = 131; localparam LPDIFF_LOCK_13 = 262; localparam LPDIFF_LOCK_23 = 524; localparam LPDIFF_LOCK_33 = 655; localparam LPDIFF_LOCK_43 = 262;
1123 // Unlock values count values for the four CPRI modes and four PLOL settings (4x5)
1124 // CPRI rate mode 0 CPRI rate mode 1 CPRI rate mode 2 CPRI rate mode 3 CPRI rate mode 4
1125 localparam LPDIFF_UNLOCK_00 = 19; localparam LPDIFF_UNLOCK_10 = 39; localparam LPDIFF_UNLOCK_20 = 78; localparam LPDIFF_UNLOCK_30 = 98; localparam LPDIFF_UNLOCK_40 = 39;
1126 localparam LPDIFF_UNLOCK_01 = 65; localparam LPDIFF_UNLOCK_11 = 131; localparam LPDIFF_UNLOCK_21 = 262; localparam LPDIFF_UNLOCK_31 = 327; localparam LPDIFF_UNLOCK_41 = 131;
1127 localparam LPDIFF_UNLOCK_02 = 72; localparam LPDIFF_UNLOCK_12 = 144; localparam LPDIFF_UNLOCK_22 = 288; localparam LPDIFF_UNLOCK_32 = 360; localparam LPDIFF_UNLOCK_42 = 144;
1128 localparam LPDIFF_UNLOCK_03 = 196; localparam LPDIFF_UNLOCK_13 = 393; localparam LPDIFF_UNLOCK_23 = 786; localparam LPDIFF_UNLOCK_33 = 983; localparam LPDIFF_UNLOCK_43 = 393;
1130 // Input and Output reg and wire declarations
1135 wire sli_div11_rate;
1137 wire [2:0] sli_cpri_mode;
1141 //-------------- Internal signals reg and wire declarations --------------------
1143 //Signals running on sli_refclk
1144 reg [15:0] rcount; //16-bit Counter
1145 reg rtc_pul; //Terminal count pulse
1146 reg rtc_pul_p1; //Terminal count pulse pipeline
1147 reg rtc_ctrl; //Terminal count pulse control
1149 reg [7:0] rhb_wait_cnt; //Heartbeat wait counter
1151 //Heatbeat synchronization and pipeline registers
1156 //Pipeling registers for dynamic control mode
1164 reg rstat_pclk; //Pclk presence/absence status
1166 reg [21:0] rcount_tc; //Tx_pclk terminal count register
1167 reg [15:0] rdiff_comp_lock; //Differential comparison value for Lock
1168 reg [15:0] rdiff_comp_unlock; //Differential compariosn value for Unlock
1170 wire rpcie_mode; //PCIe mode signal synchronized to refclk
1171 reg rpcie_mode_p1; //PCIe mode pipeline register
1173 wire rcpri_mod_ch_sync; //CPRI mode change synchronized to refclk
1174 reg rcpri_mod_ch_p1; //CPRI mode change pipeline register
1175 reg rcpri_mod_ch_p2; //CPRI mode change pipeline register
1176 reg rcpri_mod_ch_st; //CPRI mode change status
1178 reg [1:0] sll_state; //Current-state register for LOL FSM
1180 reg pll_lock; //PLL Lock signal
1182 //Signals running on sli_pclk
1183 //Synchronization and pipeline registers
1192 reg [21:0] pcount; //22-bit counter
1193 reg [21:0] pcount_diff; //Differential value between Tx_pclk counter and theoritical value
1195 //Heartbeat counter and heartbeat signal running on pclk
1199 //CPRI dynamic mode releated signals
1200 reg [2:0] pcpri_mode;
1203 //Assignment scheme changed mainly for simulation purpose
1204 wire [15:0] LRCLK_TC_w;
1205 assign LRCLK_TC_w = LRCLK_TC;
1210 //Heartbeat synchronization
1211 sync # (.PDATA_RST_VAL(0)) phb_sync_inst (
1219 //Terminal count pulse synchronization
1220 sync # (.PDATA_RST_VAL(0)) rtc_sync_inst (
1224 .data_out(ppul_sync)
1227 //Differential value logic update synchronization
1228 sync # (.PDATA_RST_VAL(0)) pdiff_sync_inst (
1231 .data_in (ppul_sync),
1232 .data_out(pdiff_sync)
1235 //Gear mode synchronization
1236 sync # (.PDATA_RST_VAL(0)) gear_sync_inst (
1239 .data_in (sli_gear_mode),
1243 //Div2 synchronization
1244 sync # (.PDATA_RST_VAL(0)) div2_sync_inst (
1247 .data_in (sli_div2_rate),
1251 //Div11 synchronization
1252 sync # (.PDATA_RST_VAL(0)) div11_sync_inst (
1255 .data_in (sli_div11_rate),
1259 //CPRI mode change synchronization
1260 sync # (.PDATA_RST_VAL(0)) cpri_mod_sync_inst (
1263 .data_in (pcpri_mod_ch),
1264 .data_out(rcpri_mod_ch_sync)
1267 //PCIe mode change synchronization
1268 sync # (.PDATA_RST_VAL(0)) pcie_mod_sync_inst (
1271 .data_in (sli_pcie_mode),
1272 .data_out(rpcie_mode)
1275 // =============================================================================
1276 // Synchronized Lock/Unlock signals
1277 // =============================================================================
1278 always @(posedge sli_refclk or posedge sli_rst) begin
1279 if (sli_rst == 1'b1) begin
1282 pdiff_sync_p1 <= 1'b0;
1285 pdiff_sync_p1 <= pdiff_sync;
1287 unlock <= ~pdiff_sync && pdiff_sync_p1 ? 1'b0 : unlock;
1290 unlock <= pdiff_sync ? (pcount_diff[21:0] > {6'd0, rdiff_comp_unlock}) : 1'b0;
1293 lock <= ~pdiff_sync && pdiff_sync_p1 ? 1'b0 : lock;
1296 lock <= pdiff_sync ? (pcount_diff[21:0] <= {6'd0, rdiff_comp_lock}) : 1'b0;
1301 // =============================================================================
1302 // Refclk Counter, pulse generation logic and Heartbeat monitor logic
1303 // =============================================================================
1304 always @(posedge sli_refclk or posedge sli_rst) begin
1305 if (sli_rst == 1'b1) begin
1313 if ((rgear_p1^rgear == 1'b1) || (rdiv2_p1^rdiv2 == 1'b1) || (rdiv11_p1^rdiv11 == 1'b1) || (rcpri_mod_ch_p1^rcpri_mod_ch_p2 == 1'b1) || (rpcie_mode_p1^rpcie_mode == 1'b1)) begin
1314 if (rtc_ctrl == 1'b1) begin
1315 rcount <= LRCLK_TC_PUL_WIDTH;
1319 if (rcount != LRCLK_TC_w) begin
1320 rcount <= rcount + 1;
1327 //Pulse control logic
1328 if (rcount == LRCLK_TC_w - 1) begin
1332 //Pulse Generation logic
1333 if (rtc_ctrl == 1'b1) begin
1334 if ((rcount == LRCLK_TC_w) || (rcount < LRCLK_TC_PUL_WIDTH)) begin
1342 rtc_pul_p1 <= rtc_pul;
1347 // =============================================================================
1348 // Heartbeat synchronization & monitor logic and Dynamic mode pipeline logic
1349 // =============================================================================
1350 always @(posedge sli_refclk or posedge sli_rst) begin
1351 if (sli_rst == 1'b1) begin
1352 rhb_sync_p1 <= 1'b0;
1353 rhb_sync_p2 <= 1'b0;
1354 rhb_wait_cnt <= 8'd0;
1359 rcpri_mod_ch_p1 <= 1'b0;
1360 rcpri_mod_ch_p2 <= 1'b0;
1361 rcpri_mod_ch_st <= 1'b0;
1362 rpcie_mode_p1 <= 1'b0;
1366 //Pipeline stages for the Heartbeat
1367 rhb_sync_p1 <= rhb_sync;
1368 rhb_sync_p2 <= rhb_sync_p1;
1370 //Pipeline stages of the Dynamic rate control signals
1373 rdiv11_p1 <= rdiv11;
1375 //Pipeline stage for PCIe mode
1376 rpcie_mode_p1 <= rpcie_mode;
1378 //Pipeline stage for CPRI mode change
1379 rcpri_mod_ch_p1 <= rcpri_mod_ch_sync;
1380 rcpri_mod_ch_p2 <= rcpri_mod_ch_p1;
1382 //CPRI mode change status logic
1383 if (rcpri_mod_ch_p1^rcpri_mod_ch_sync == 1'b1) begin
1384 rcpri_mod_ch_st <= 1'b1;
1387 //Heartbeat wait counter and monitor logic
1388 if (rtc_ctrl == 1'b1) begin
1389 if (rhb_sync_p1 == 1'b1 && rhb_sync_p2 == 1'b0) begin
1390 rhb_wait_cnt <= 8'd0;
1393 else if (rhb_wait_cnt == LHB_WAIT_CNT) begin
1394 rhb_wait_cnt <= 8'd0;
1398 rhb_wait_cnt <= rhb_wait_cnt + 1;
1405 // =============================================================================
1406 // Pipleline registers for the TC pulse and CPRI mode change logic
1407 // =============================================================================
1408 always @(posedge sli_pclk or posedge sli_rst) begin
1409 if (sli_rst == 1'b1) begin
1410 ppul_sync_p1 <= 1'b0;
1411 ppul_sync_p2 <= 1'b0;
1412 ppul_sync_p3 <= 1'b0;
1414 pcpri_mod_ch <= 1'b0;
1417 ppul_sync_p1 <= ppul_sync;
1418 ppul_sync_p2 <= ppul_sync_p1;
1419 ppul_sync_p3 <= ppul_sync_p2;
1421 //CPRI mode change logic
1422 pcpri_mode <= sli_cpri_mode;
1424 if (pcpri_mode != sli_cpri_mode) begin
1425 pcpri_mod_ch <= ~pcpri_mod_ch;
1431 // =============================================================================
1432 // Terminal count logic
1433 // =============================================================================
1435 //For SDI protocol with Dynamic rate control enabled
1437 if ((PDYN_RATE_CTRL == "ENABLED") && (PPROTOCOL == "SDI")) begin
1438 always @(posedge sli_refclk or posedge sli_rst) begin
1439 if (sli_rst == 1'b1) begin
1441 rdiff_comp_lock <= 16'd0;
1442 rdiff_comp_unlock <= 16'd0;
1445 //Terminal count logic
1446 //Div by 11 is enabled
1447 if (rdiv11 == 1'b1) begin
1448 //Gear mode is 16/20
1449 if (rgear == 1'b1) begin
1450 rcount_tc <= PPCLK_DIV11_TC;
1451 rdiff_comp_lock <= PDIFF_DIV11_VAL_LOCK;
1452 rdiff_comp_unlock <= PDIFF_DIV11_VAL_UNLOCK;
1455 rcount_tc <= {PPCLK_DIV11_TC[20:0], 1'b0};
1456 rdiff_comp_lock <= {PDIFF_DIV11_VAL_LOCK[14:0], 1'b0};
1457 rdiff_comp_unlock <= {PDIFF_DIV11_VAL_UNLOCK[14:0], 1'b0};
1460 //Div by 2 is enabled
1461 else if (rdiv2 == 1'b1) begin
1462 //Gear mode is 16/20
1463 if (rgear == 1'b1) begin
1464 rcount_tc <= {1'b0,PPCLK_TC[21:1]};
1465 rdiff_comp_lock <= {1'b0,PDIFF_VAL_LOCK[15:1]};
1466 rdiff_comp_unlock <= {1'b0,PDIFF_VAL_UNLOCK[15:1]};
1469 rcount_tc <= PPCLK_TC;
1470 rdiff_comp_lock <= PDIFF_VAL_LOCK;
1471 rdiff_comp_unlock <= PDIFF_VAL_UNLOCK;
1474 //Both div by 11 and div by 2 are disabled
1476 //Gear mode is 16/20
1477 if (rgear == 1'b1) begin
1478 rcount_tc <= PPCLK_TC;
1479 rdiff_comp_lock <= PDIFF_VAL_LOCK;
1480 rdiff_comp_unlock <= PDIFF_VAL_UNLOCK;
1483 rcount_tc <= {PPCLK_TC[20:0],1'b0};
1484 rdiff_comp_lock <= {PDIFF_VAL_LOCK[14:0],1'b0};
1485 rdiff_comp_unlock <= {PDIFF_VAL_UNLOCK[14:0],1'b0};
1493 //For G8B10B protocol with Dynamic rate control enabled
1495 if ((PDYN_RATE_CTRL == "ENABLED") && (PPROTOCOL == "G8B10B")) begin
1496 always @(posedge sli_refclk or posedge sli_rst) begin
1497 if (sli_rst == 1'b1) begin
1499 rdiff_comp_lock <= 16'd0;
1500 rdiff_comp_unlock <= 16'd0;
1503 //Terminal count logic
1504 //Div by 2 is enabled
1505 if (rdiv2 == 1'b1) begin
1506 rcount_tc <= {1'b0,PPCLK_TC[21:1]};
1507 rdiff_comp_lock <= {1'b0,PDIFF_VAL_LOCK[15:1]};
1508 rdiff_comp_unlock <= {1'b0,PDIFF_VAL_UNLOCK[15:1]};
1511 rcount_tc <= PPCLK_TC;
1512 rdiff_comp_lock <= PDIFF_VAL_LOCK;
1513 rdiff_comp_unlock <= PDIFF_VAL_UNLOCK;
1521 //For CPRI protocol with Dynamic rate control is disabled
1523 if ((PDYN_RATE_CTRL == "DISABLED") && (PPROTOCOL == "CPRI")) begin
1524 always @(posedge sli_refclk or posedge sli_rst) begin
1525 if (sli_rst == 1'b1) begin
1527 rdiff_comp_lock <= 16'd0;
1528 rdiff_comp_unlock <= 16'd0;
1531 //Terminal count logic for CPRI protocol
1532 //Only if there is a change in the rate mode from the default
1533 if (rcpri_mod_ch_st == 1'b1) begin
1534 if (rcpri_mod_ch_p1^rcpri_mod_ch_p2 == 1'b1) begin
1536 3'd0 : begin //For 0.6Gbps
1537 rcount_tc <= LPCLK_TC_0;
1540 rdiff_comp_lock <= LPDIFF_LOCK_00;
1541 rdiff_comp_unlock <= LPDIFF_UNLOCK_00;
1545 rdiff_comp_lock <= LPDIFF_LOCK_01;
1546 rdiff_comp_unlock <= LPDIFF_UNLOCK_01;
1550 rdiff_comp_lock <= LPDIFF_LOCK_02;
1551 rdiff_comp_unlock <= LPDIFF_UNLOCK_02;
1555 rdiff_comp_lock <= LPDIFF_LOCK_03;
1556 rdiff_comp_unlock <= LPDIFF_UNLOCK_03;
1560 rdiff_comp_lock <= LPDIFF_LOCK_00;
1561 rdiff_comp_unlock <= LPDIFF_UNLOCK_00;
1566 3'd1 : begin //For 1.2Gbps
1567 rcount_tc <= LPCLK_TC_1;
1570 rdiff_comp_lock <= LPDIFF_LOCK_10;
1571 rdiff_comp_unlock <= LPDIFF_UNLOCK_10;
1575 rdiff_comp_lock <= LPDIFF_LOCK_11;
1576 rdiff_comp_unlock <= LPDIFF_UNLOCK_11;
1580 rdiff_comp_lock <= LPDIFF_LOCK_12;
1581 rdiff_comp_unlock <= LPDIFF_UNLOCK_12;
1585 rdiff_comp_lock <= LPDIFF_LOCK_13;
1586 rdiff_comp_unlock <= LPDIFF_UNLOCK_13;
1590 rdiff_comp_lock <= LPDIFF_LOCK_10;
1591 rdiff_comp_unlock <= LPDIFF_UNLOCK_10;
1596 3'd2 : begin //For 2.4Gbps
1597 rcount_tc <= LPCLK_TC_2;
1600 rdiff_comp_lock <= LPDIFF_LOCK_20;
1601 rdiff_comp_unlock <= LPDIFF_UNLOCK_20;
1605 rdiff_comp_lock <= LPDIFF_LOCK_21;
1606 rdiff_comp_unlock <= LPDIFF_UNLOCK_21;
1610 rdiff_comp_lock <= LPDIFF_LOCK_22;
1611 rdiff_comp_unlock <= LPDIFF_UNLOCK_22;
1615 rdiff_comp_lock <= LPDIFF_LOCK_23;
1616 rdiff_comp_unlock <= LPDIFF_UNLOCK_23;
1620 rdiff_comp_lock <= LPDIFF_LOCK_20;
1621 rdiff_comp_unlock <= LPDIFF_UNLOCK_20;
1626 3'd3 : begin //For 3.07Gbps
1627 rcount_tc <= LPCLK_TC_3;
1630 rdiff_comp_lock <= LPDIFF_LOCK_30;
1631 rdiff_comp_unlock <= LPDIFF_UNLOCK_30;
1635 rdiff_comp_lock <= LPDIFF_LOCK_31;
1636 rdiff_comp_unlock <= LPDIFF_UNLOCK_31;
1640 rdiff_comp_lock <= LPDIFF_LOCK_32;
1641 rdiff_comp_unlock <= LPDIFF_UNLOCK_32;
1645 rdiff_comp_lock <= LPDIFF_LOCK_33;
1646 rdiff_comp_unlock <= LPDIFF_UNLOCK_33;
1651 3'd4 : begin //For 4.9125bps
1652 rcount_tc <= LPCLK_TC_4;
1655 rdiff_comp_lock <= LPDIFF_LOCK_40;
1656 rdiff_comp_unlock <= LPDIFF_UNLOCK_40;
1660 rdiff_comp_lock <= LPDIFF_LOCK_41;
1661 rdiff_comp_unlock <= LPDIFF_UNLOCK_41;
1665 rdiff_comp_lock <= LPDIFF_LOCK_42;
1666 rdiff_comp_unlock <= LPDIFF_UNLOCK_42;
1670 rdiff_comp_lock <= LPDIFF_LOCK_43;
1671 rdiff_comp_unlock <= LPDIFF_UNLOCK_43;
1675 rdiff_comp_lock <= LPDIFF_LOCK_40;
1676 rdiff_comp_unlock <= LPDIFF_UNLOCK_40;
1682 rcount_tc <= LPCLK_TC_0;
1683 rdiff_comp_lock <= LPDIFF_LOCK_00;
1684 rdiff_comp_unlock <= LPDIFF_UNLOCK_00;
1690 //If there is no change in the CPRI rate mode from default
1691 rcount_tc <= PPCLK_TC;
1692 rdiff_comp_lock <= PDIFF_VAL_LOCK;
1693 rdiff_comp_unlock <= PDIFF_VAL_UNLOCK;
1700 //For PCIe protocol with Dynamic rate control disabled
1702 if ((PDYN_RATE_CTRL == "DISABLED") && (PPROTOCOL == "PCIE")) begin
1703 always @(posedge sli_refclk or posedge sli_rst) begin
1704 if (sli_rst == 1'b1) begin
1706 rdiff_comp_lock <= 16'd0;
1707 rdiff_comp_unlock <= 16'd0;
1710 //Terminal count logic
1711 if (PPCIE_MAX_RATE == "2.5") begin
1712 //2.5G mode is enabled
1713 rcount_tc <= PPCLK_TC;
1714 rdiff_comp_lock <= PDIFF_VAL_LOCK;
1715 rdiff_comp_unlock <= PDIFF_VAL_UNLOCK;
1718 //5G mode is enabled
1719 if (rpcie_mode == 1'b1) begin
1720 rcount_tc <= PPCLK_TC;
1721 rdiff_comp_lock <= PDIFF_VAL_LOCK;
1722 rdiff_comp_unlock <= PDIFF_VAL_UNLOCK;
1725 //2.5G mode is enabled
1726 rcount_tc <= {1'b0,PPCLK_TC[21:1]};
1727 rdiff_comp_lock <= {1'b0,PDIFF_VAL_LOCK[15:1]};
1728 rdiff_comp_unlock <= {1'b0,PDIFF_VAL_UNLOCK[15:1]};
1736 //For all protocols other than CPRI & PCIe
1738 if ((PDYN_RATE_CTRL == "DISABLED") && ((PPROTOCOL != "CPRI") && (PPROTOCOL != "PCIE"))) begin
1739 always @(posedge sli_refclk or posedge sli_rst) begin
1740 if (sli_rst == 1'b1) begin
1742 rdiff_comp_lock <= 16'd0;
1743 rdiff_comp_unlock <= 16'd0;
1746 //Terminal count logic for all protocols other than CPRI & PCIe
1747 rcount_tc <= PPCLK_TC;
1748 rdiff_comp_lock <= PDIFF_VAL_LOCK;
1749 rdiff_comp_unlock <= PDIFF_VAL_UNLOCK;
1756 // =============================================================================
1757 // Tx_pclk counter, Heartbeat and Differential value logic
1758 // =============================================================================
1759 always @(posedge sli_pclk or posedge sli_rst) begin
1760 if (sli_rst == 1'b1) begin
1762 pcount_diff <= 22'd65535;
1768 if (ppul_sync_p1 == 1'b1 && ppul_sync_p2 == 1'b0) begin
1772 pcount <= pcount + 1;
1776 phb_cnt <= phb_cnt + 1;
1778 if ((phb_cnt < 3'd4) && (phb_cnt >= 3'd0)) begin
1785 //Differential value logic
1786 if (ppul_sync_p1 == 1'b1 && ppul_sync_p2 == 1'b0) begin
1787 pcount_diff <= rcount_tc + ~(pcount) + 1;
1789 else if (ppul_sync_p2 == 1'b1 && ppul_sync_p3 == 1'b0) begin
1790 if (pcount_diff[21] == 1'b1) begin
1791 pcount_diff <= ~(pcount_diff) + 1;
1798 // =============================================================================
1799 // State transition logic for SLL FSM
1800 // =============================================================================
1801 always @(posedge sli_refclk or posedge sli_rst) begin
1802 if (sli_rst == 1'b1) begin
1803 sll_state <= LPLL_LOSS_ST;
1806 //Reasons to declare an immediate loss - Absence of Tx_pclk, Dynamic rate change for SDI or CPRI
1807 if ((rstat_pclk == 1'b0) || (rgear_p1^rgear == 1'b1) || (rdiv2_p1^rdiv2 == 1'b1) ||
1808 (rdiv11_p1^rdiv11 == 1'b1) || (rcpri_mod_ch_p1^rcpri_mod_ch_p2 == 1'b1) || (rpcie_mode_p1^rpcie_mode == 1'b1)) begin
1809 sll_state <= LPLL_LOSS_ST;
1813 LPLL_LOSS_ST : begin
1814 if (rtc_pul_p1 == 1'b1 && rtc_pul == 1'b0) begin
1816 sll_state <= LPLL_LOSS_ST;
1818 else if (lock) begin
1819 if (PLOL_SETTING == 2'd0) begin
1820 sll_state <= LPLL_PRELOCK_ST;
1823 sll_state <= LPLL_LOCK_ST;
1829 LPLL_LOCK_ST : begin
1830 if (rtc_pul_p1 == 1'b1 && rtc_pul == 1'b0) begin
1832 sll_state <= LPLL_LOCK_ST;
1835 if (PLOL_SETTING == 2'd0) begin
1836 sll_state <= LPLL_LOSS_ST;
1839 sll_state <= LPLL_PRELOSS_ST;
1845 LPLL_PRELOCK_ST : begin
1846 if (rtc_pul_p1 == 1'b1 && rtc_pul == 1'b0) begin
1848 sll_state <= LPLL_LOCK_ST;
1851 sll_state <= LPLL_PRELOSS_ST;
1856 LPLL_PRELOSS_ST : begin
1857 if (rtc_pul_p1 == 1'b1 && rtc_pul == 1'b0) begin
1859 sll_state <= LPLL_PRELOSS_ST;
1861 else if (lock) begin
1862 sll_state <= LPLL_LOCK_ST;
1868 sll_state <= LPLL_LOSS_ST;
1876 // =============================================================================
1877 // Logic for Tx PLL Lock
1878 // =============================================================================
1879 always @(posedge sli_refclk or posedge sli_rst) begin
1880 if (sli_rst == 1'b1) begin
1885 LPLL_LOSS_ST : begin
1889 LPLL_LOCK_ST : begin
1893 LPLL_PRELOSS_ST : begin
1904 assign slo_plol = ~(pll_lock);
1909 // ===========================================================================
1910 // >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1911 // ---------------------------------------------------------------------------
1912 // Copyright (c) 2015 by Lattice Semiconductor Corporation
1913 // ALL RIGHTS RESERVED
1914 // ------------------------------------------------------------------
1918 // Lattice SG Pte. Ltd. grants permission to use this code
1919 // pursuant to the terms of the Lattice Reference Design License Agreement.
1924 // This VHDL or Verilog source code is intended as a design reference
1925 // which illustrates how these types of functions can be implemented.
1926 // It is the user's responsibility to verify their design for
1927 // consistency and functionality through the use of formal
1928 // verification methods. Lattice provides no warranty
1929 // regarding the use or functionality of this code.
1931 // ---------------------------------------------------------------------------
1933 // Lattice SG Pte. Ltd.
1934 // 101 Thomson Road, United Square #07-02
1938 // TEL: 1-800-Lattice (USA and Canada)
1939 // +65-6631-2000 (Singapore)
1940 // +1-503-268-8001 (other locations)
1942 // web: http://www.latticesemi.com/
1943 // email: techsupport@latticesemi.com
1945 // ---------------------------------------------------------------------------
1947 // =============================================================================
1949 // Project : Synchronizer Logic
1951 // Title : Synchronizer module
1953 // =============================================================================
1957 // Mod. Date : July 7, 2015
1958 // Changes Made : Initial Creation
1959 // -----------------------------------------------------------------------------
1962 // Mod. Date : March 21, 2017
1964 // =============================================================================
1966 `ifndef PCS_SYNC_MODULE
1967 `define PCS_SYNC_MODULE
1975 input clk; //Clock in which the async data needs to be synchronized to
1976 input rst; //Active high reset
1977 input data_in; //Asynchronous data
1978 output data_out; //Synchronized data
1980 parameter PDATA_RST_VAL = 0; //Reset value for the registers
1985 // =============================================================================
1986 // Synchronization logic
1987 // =============================================================================
1988 always @(posedge clk or posedge rst) begin
1989 if (rst == 1'b1) begin
1990 data_p1 <= PDATA_RST_VAL;
1991 data_p2 <= PDATA_RST_VAL;
1999 assign data_out = data_p2;