1 --////////////////////////////////////////////////////////////////////////////////
4 --// /___/ \ / Vendor: Xilinx
5 --// \ \ \/ Version : 2.
5
6 --// \ \ Application : 7 Series FPGAs Transceivers Wizard
7 --// / / Filename :s6link_ctle_agc_comp.vhd
13 -- Description : This module performs TX reset and initialization.
17 -- Module S6Link_ctle_agc_comp
18 -- Generated by Xilinx 7 Series FPGAs Transceivers Wizard
21 -- (c) Copyright 2010-2012 Xilinx, Inc. All rights reserved.
23 -- This file contains confidential and proprietary information
24 -- of Xilinx, Inc. and is protected under U.S. and
25 -- international copyright and other intellectual property
29 -- This disclaimer is not a license and does not grant any
30 -- rights to the materials distributed herewith. Except as
31 -- otherwise provided in a valid license issued to you by
32 -- Xilinx, and to the maximum extent permitted by applicable
33 -- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS"
AND
34 -- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
35 -- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
36 -- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
37 -- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
38 -- (2) Xilinx shall
not be liable (whether
in contract
or tort,
39 -- including negligence, or under any other theory of
40 -- liability) for any loss or damage of any kind or nature
41 -- related to, arising under or in connection with these
42 -- materials, including for any direct, or any indirect,
43 -- special, incidental, or consequential loss or damage
44 -- (including loss of data, profits, goodwill, or any type of
45 -- loss or damage suffered as a result of any action brought
46 -- by a third party) even if such damage or loss was
47 -- reasonably foreseeable or Xilinx had been advised of the
48 -- possibility of the same.
50 -- CRITICAL APPLICATIONS
51 -- Xilinx products are not designed or intended to be fail-
52 -- safe, or for use in any application requiring fail-safe
53 -- performance, such as life-support or safety devices or
54 -- systems, Class III medical devices, nuclear facilities,
55 -- applications related to the deployment of airbags, or any
56 -- other applications that could lead to death, personal
57 -- injury, or severe property or environmental damage
58 -- (individually and collectively, "Critical
59 -- Applications"). Customer assumes the sole risk and
60 -- liability of any use of Xilinx products in Critical
61 -- Applications, subject only to applicable laws and
62 -- regulations governing limitations on product liability.
64 -- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
65 -- PART OF THIS FILE AT ALL TIMES.
68 --*****************************************************************************
71 use IEEE.STD_LOGIC_1164.
ALL;
72 use IEEE.STD_LOGIC_UNSIGNED.
ALL;
73 use IEEE.STD_LOGIC_ARITH.
ALL;
74 use IEEE.NUMERIC_STD.
ALL;
77 use unisim.vcomponents.
all;
81 AGC_TIMER: range 0 to 4095 := 150
82 --DCLK FREQ (in MHZ) * 12.
5 / (Line Rate
in Gbps)
83 --Max DCLK is 150MHz. Min Line Rate is 0.5Gbps per data sheet
86 RST : in ;
--RST low starts state machine
87 DONE : out ;
--DONE asserted when complete, deasserted with RST high
89 --DRP for accessing CTLE3
90 DRDY : in ;
--Connect to Channel DRP
91 DO : in (15 downto 0);
--Connect to Channel DRP
93 DCLK : in ;
--Connect to same clk as Channel DRP DCLK
94 DADDR : out (8 downto 0);
--Connect to Channel DRP
95 DI : out (15 downto 0);
--Connect to Channel DRP
96 DEN : out ;
--Connect to Channel DRP
97 DWE : out ;
--Connect to Channel DRP
99 --RXMONITOR to observe AGC
100 RXMONITOR : in (6 downto 0);
--Connect to RXMONITOR port
101 RXMONITORSEL : out (1 downto 0);
--Connect to RXMONITORSEL port
104 curr_state : out (3 downto 0);
108 end S6Link_ctle_agc_comp;
112 constant DLY : := 1 ns;
113 constant CTLE3_ADDR : (8 downto 0) := "010000011";
--integer range 0 to 511 :=
131;
114 constant CTLE3_UPPER_LIMIT : := 7;
115 constant CTLE3_LOWER_LIMIT : := 0;
116 constant AGC_UPPER_LIMIT : := 30;
117 constant AGC_LOWER_LIMIT : := 1;
119 constant AGC_BW_ADDR : (8 downto 0) := "000011101";
120 constant AGC_BW_1X : (3 downto 0) := "0000";
121 constant AGC_BW_4X : (3 downto 0) := "0010";
122 constant AGC_BW_8X : (3 downto 0) := "0011";
124 --DCLK_FREQ is actually DCLK_FREQ * 12.5/LineRate
in Gbps
125 constant UPDATE_TIMER_LIMIT : range 0 to 16380 := AGC_TIMER*4;
--At 12.5Gbps,
wait 240us
in 8x. 12-bits multiply by
4,
14 bits
126 constant UPDATE_TIMER_LIMIT_4X : range 0 to 32760 := UPDATE_TIMER_LIMIT*2;
--14 bits multiply by 2.
15 bits.
128 constant IDLE : (3 downto 0) := "0000";
129 constant READ : (3 downto 0) := "0001";
130 constant WAIT_READ : (3 downto 0) := "0010";
131 constant DECIDE : (3 downto 0) := "0011";
132 constant INC_S : (3 downto 0) := "0100";
133 constant DEC_S : (3 downto 0) := "0101";
134 constant WRITE : (3 downto 0) := "0110";
135 constant WAIT_UPDATE : (3 downto 0) := "0111";
136 constant DONE_ST : (3 downto 0) := "1000";
137 constant READ_AGC_BW : (3 downto 0) := "1001";
138 constant WAIT_READ_AGC_BW : (3 downto 0) := "1010";
139 constant MODIFY_AGC_BW : (3 downto 0) := "1011";
140 constant WRITE_AGC_BW : (3 downto 0) := "1100";
141 constant WAIT_WRITE_AGC_BW : (3 downto 0) := "1101";
142 constant DOWNSHIFT_4X_S : (3 downto 0) := "1110";
143 constant WAIT_AGC_4X : (3 downto 0) := "1111";
144 --parameter KEEP = 4'b1111;
146 signal in_progress : ;
147 signal in_progress_b : ;
149 signal agc_reg : (4 downto 0);
150 signal agc_reg0 : (4 downto 0);
152 signal agc_bw : (3 downto 0);
154 signal ctle3_reg : (3 downto 0);
155 signal ctle3_ld : (3 downto 0);
157 signal next_state : (3 downto 0);
158 signal rxmon_sel : (1 downto 0);
160 signal update_timer : (14 downto 0);
161 signal clk_div_counter : (5 downto 0);
162 --reg [10:0] clk_div_counter;
166 signal do_reg : (15 downto 0);
168 signal di_int : (15 downto 0);
169 signal daddr_int : (8 downto 0);
172 signal incdec : (1 downto 0);
173 signal curr_state_reg : (3 downto 0);
175 signal clk_int_en : ;
176 signal clk_timer_en : ;
177 signal write_state : ;
178 signal done_state : ;
179 signal downshift_4x_state : ;
180 signal read_state : ;
181 signal wait_agc_4x_state : ;
184 signal agc_not_railed : ;
185 signal agc_not_railed_l : ;
186 signal rxmon_ok_l : ;
187 signal rxmon_ok_l_b : ;
188 signal downshift_4x : ;
189 signal downshift_1x : ;
192 signal agc_railing_int : ;
193 signal agc_interm : (3 downto 0);
196 --Assign AGC BW to 4x in beginning
then 1x after done adjusting CTLE3.
199 agc_railing <= agc_railing_int;
200 curr_state <= curr_state_reg;
201 agc_interm <= AGC_BW_4X when(downshift_4x='1') else AGC_BW_8X;
202 agc_bw <= AGC_BW_1X when(downshift_1x='1') else agc_interm;
203 --assign agc_bw = done_pre ? AGC_BW_1X : AGC_BW_4X;
206 --always@(posedge clk_int)
208 if rising_edge(DCLK) then
209 if(clk_int_en='1') then
210 if((curr_state_reg = WRITE) or (curr_state_reg = WRITE_AGC_BW)) then
211 write_state <= '1' after DLY;
213 write_state <= '0' after DLY;
215 if(curr_state_reg = DONE_ST) then
216 done_state <= '1' after DLY;
218 done_state <= '0' after DLY;
220 if(curr_state_reg = DOWNSHIFT_4X_S) then
221 downshift_4x_state <= '1' after DLY;
223 downshift_4x_state <= '0' after DLY;
225 if(curr_state_reg = WAIT_AGC_4X) then
226 wait_agc_4x_state <= '1' after DLY;
228 wait_agc_4x_state <= '0' after DLY;
230 if(curr_state_reg = READ) then
231 read_state <= '1' after DLY;
233 read_state <= '0' after DLY;
241 in_progress_b <= not(in_progress);
242 RXMONITORSEL <= rxmon_sel;
245 --DRP signals. Hard-code address for GTX CTLE3. AGC read is done thru RX_MONITOR
246 --assign DADDR = in_progress_b ? 9'd0 : CTLE3_ADDR;
247 DADDR <= (others=>'0') when(in_progress_b='1') else daddr_int;
248 DI <= (others=>'0') when(in_progress_b='1') else di_int;
250 --assign di_int[11:0] = do_reg[11:0];
251 --assign di_int[15:12] = (curr_state_reg == WRITE || curr_state_reg == WAIT_UPDATE) ? ctle3_ld[3:0] : ctle3_reg;
253 ctle3_reg <= do_reg(15 downto 12);
256 -- /*initial --For Sim
258 -- clk_div_counter <= 1'b0;
263 if rising_edge(DCLK) then
264 clk_div_counter <= clk_div_counter + '1' after DLY;
268 --State machine and most logic on divided-16 clock. Only latching of input signals and DEN are on full-rate clock. Timers are on divided 2048 clock.
269 clk_int_en <= '1' when(clk_div_counter(3 downto 0)="1111") else '0';
--div 16
270 clk_timer_en <= '1' when(clk_div_counter(5 downto 0)="111111") else '0';
--div 64 For synth
271 --assign clk_timer_en = (clk_div_counter == 11'b000_0001_1111);--div
1024 For sim
273 --den_int updated by divided down clock. Want DEN to be 1 DCLK cycle wide.
274 DEN_reg <= (den_int and not(den_int2));
278 if rising_edge(DCLK) then
279 den_int2 <= den_int after DLY;
285 if rising_edge(DCLK) then
286 if(in_progress_b='1') then
287 do_reg <= (others=>'0') after DLY;
288 done_drp <= '0' after DLY;
291 do_reg <= DO after DLY;
292 done_drp <= '1' after DLY;
293 elsif(DEN_reg='1') then
294 done_drp <= '0' after DLY;
302 if rising_edge(DCLK) then
303 agc_reg0 <= RXMONITOR(4 downto 0) after DLY;
304 agc_reg <= agc_reg0 after DLY;
308 min_agc <= '1' when(agc_reg(4 downto 0) = "00000") else '0';
309 max_agc <= '1' when(agc_reg(4 downto 0) = "11111") else '0';
310 agc_not_railed <= not(min_agc or max_agc);
313 --SR latch. CLR is dominant.
315 generic map ( INIT => '0'
325 --Determine when to clear latched AGC value
326 rxmon_ok_sr_ff : FDRE
327 generic map ( INIT => '0'
338 generic map ( INIT => '0'
341 Q => agc_not_railed_l,
344 S => agc_not_railed ,
348 downshift_4x_sr_ff : FDRE
349 generic map ( INIT => '0'
355 CE => downshift_4x_state,
359 downshift_1x_sr_ff : FDRE
360 generic map ( INIT => '0'
366 CE => wait_agc_4x_state,
370 rxmon_ok_l_b <= not(rxmon_ok_l);
371 agc_railing_int <= not(agc_not_railed_l);
377 in_progress <= '0' after DLY;
378 elsif(rising_edge(DCLK)) then
379 if(DONE_INT='1') then
380 in_progress <= '0' after DLY;
382 in_progress <= '1' after DLY;
387 process(DCLK,write_state)
389 if (write_state='1') then
390 update_timer <= (others=>'0') after DLY;
391 elsif(rising_edge(DCLK)) then
392 if(clk_timer_en='1' and ((curr_state_reg = WAIT_UPDATE) or (curr_state_reg = WAIT_AGC_4X))) then
393 update_timer <= update_timer + '1' after DLY;
401 if rising_edge(DCLK) then
402 if(clk_int_en='1') then
403 curr_state_reg <= next_state after DLY;
408 process(curr_state_reg,in_progress_b,done_drp,downshift_1x,downshift_4x,agc_reg,ctle3_reg,agc_railing_int)
410 --in_progress_b asserted by RST or DONE_ST state
411 if(in_progress_b='1') then
412 next_state <= IDLE after DLY;
414 case curr_state_reg is
416 next_state <= READ_AGC_BW after DLY;
419 next_state <= WAIT_READ_AGC_BW after DLY;
421 when WAIT_READ_AGC_BW =>
422 if(done_drp='1') then
423 next_state <= MODIFY_AGC_BW after DLY;
425 next_state <= WAIT_READ_AGC_BW after DLY;
428 when MODIFY_AGC_BW =>
429 next_state <= WRITE_AGC_BW after DLY;
432 next_state <= WAIT_WRITE_AGC_BW after DLY;
434 when WAIT_WRITE_AGC_BW =>
435 if(done_drp='1') then
436 if(downshift_1x='1') then
437 next_state <= DONE_ST after DLY;
--Done setting 1x AGC so must be done.
438 elsif(downshift_4x='1') then
439 next_state <= WAIT_AGC_4X after DLY;
--Wait for 4x AGC convergence.
441 next_state <= READ after DLY;
--Done setting 8x AGC. Start CTLE3 compensation.
444 next_state <= WAIT_WRITE_AGC_BW after DLY;
448 next_state <= WAIT_READ after DLY;
451 if(done_drp='1') then
452 next_state <= DECIDE after DLY;
454 next_state <= WAIT_READ after DLY;
458 --Update CTLE3 based on AGC value.
459 --Do not update if AGC not railing (e.g. OK if dithering between 0 &
1)
460 if((agc_reg < AGC_LOWER_LIMIT) and (ctle3_reg < CTLE3_UPPER_LIMIT) and (agc_railing_int='1')) then
461 next_state <= INC_S after DLY;
462 elsif((agc_reg > AGC_UPPER_LIMIT) and (ctle3_reg > CTLE3_LOWER_LIMIT) and (agc_railing_int='1')) then
463 next_state <= DEC_S after DLY;
464 else --Done adjusting. Go back to 4x AGC BW
465 next_state <= DOWNSHIFT_4X_S after DLY;
469 next_state <= WRITE after DLY;
472 next_state <= WRITE after DLY;
475 next_state <= WAIT_UPDATE after DLY;
478 if(update_timer = UPDATE_TIMER_LIMIT) then
479 next_state <= READ after DLY;
481 next_state <= WAIT_UPDATE after DLY;
484 when DOWNSHIFT_4X_S =>
485 next_state <= READ_AGC_BW after DLY;
488 if(update_timer = UPDATE_TIMER_LIMIT_4X) then
489 next_state <= READ_AGC_BW after DLY;
491 next_state <= WAIT_AGC_4X after DLY;
495 next_state <= DONE_ST after DLY;
498 next_state <= IDLE after DLY;
505 process(curr_state_reg,do_reg,agc_bw,ctle3_ld)
507 case curr_state_reg is
509 inc <= '0' after DLY;
510 dec <= '0' after DLY;
511 den_int <= '0' after DLY;
512 dwe_int <= '0' after DLY;
513 di_int <= (others=>'0') after DLY;
514 daddr_int <= (others=>'0') after DLY;
515 rxmon_sel <= (others=>'0') after DLY;
518 inc <= '0' after DLY;
519 dec <= '0' after DLY;
520 den_int <= '1' after DLY;
521 dwe_int <= '0' after DLY;
522 di_int <= (others=>'0') after DLY;
523 daddr_int <= AGC_BW_ADDR after DLY;
524 rxmon_sel <= (others=>'0') after DLY;
526 when WAIT_READ_AGC_BW =>
527 inc <= '0' after DLY;
528 dec <= '0' after DLY;
529 den_int <= '0' after DLY;
530 dwe_int <= '0' after DLY;
531 di_int <= do_reg after DLY;
532 daddr_int <= AGC_BW_ADDR after DLY;
533 rxmon_sel <= (others=>'0') after DLY;
536 when MODIFY_AGC_BW =>
537 inc <= '0' after DLY;
538 dec <= '0' after DLY;
539 den_int <= '0' after DLY;
540 dwe_int <= '0' after DLY;
541 di_int <= agc_bw & do_reg(11 downto 0) after DLY;
542 --di_int <= {do_reg[15:7],agc_bw,do_reg[2:0]};
543 daddr_int <= AGC_BW_ADDR after DLY;
544 rxmon_sel <= (others=>'0') after DLY;
547 inc <= '0' after DLY;
548 dec <= '0' after DLY;
549 den_int <= '1' after DLY;
550 dwe_int <= '1' after DLY;
551 di_int <= agc_bw & do_reg(11 downto 0) after DLY;
552 --di_int <= {do_reg[15:7],agc_bw,do_reg[2:0]} after DLY;
553 daddr_int <= AGC_BW_ADDR after DLY;
554 rxmon_sel <= (others=>'0') after DLY;
556 when WAIT_WRITE_AGC_BW =>
557 inc <= '0' after DLY;
558 dec <= '0' after DLY;
559 den_int <= '0' after DLY;
560 dwe_int <= '0' after DLY;
561 di_int <= agc_bw & do_reg(11 downto 0) after DLY;
562 --di_int <= {do_reg[15:7],agc_bw,do_reg[2:0]};
563 daddr_int <= AGC_BW_ADDR after DLY;
564 rxmon_sel <= (others=>'0') after DLY;
567 --Issue DRP read for addr x083 where ctle3_re is located.
568 --1st step in READ-MODIFY-WRITE
569 inc <= '0' after DLY;
570 dec <= '0' after DLY;
571 den_int <= '1' after DLY;
572 dwe_int <= '0' after DLY;
573 di_int <= do_reg after DLY;
574 daddr_int <= CTLE3_ADDR after DLY;
575 rxmon_sel <= "01" after DLY;
578 --Wait until see DONE_ST signal from DRP
579 inc <= '0' after DLY;
580 dec <= '0' after DLY;
581 den_int <= '0' after DLY;
582 dwe_int <= '0' after DLY;
583 di_int <= do_reg after DLY;
584 daddr_int <= CTLE3_ADDR after DLY;
585 rxmon_sel <= "01" after DLY;
588 --Update CTLE3 value based on AGC value
589 inc <= '0' after DLY;
590 dec <= '0' after DLY;
591 den_int <= '0' after DLY;
592 dwe_int <= '0' after DLY;
593 di_int <= do_reg after DLY;
594 daddr_int <= CTLE3_ADDR after DLY;
595 rxmon_sel <= "01" after DLY;
598 inc <= '1' after DLY;
599 dec <= '0' after DLY;
600 den_int <= '0' after DLY;
601 dwe_int <= '0' after DLY;
602 di_int <= do_reg after DLY;
603 daddr_int <= CTLE3_ADDR after DLY;
604 rxmon_sel <= "01" after DLY;
607 inc <= '0' after DLY;
608 dec <= '1' after DLY;
609 den_int <= '0' after DLY;
610 dwe_int <= '0' after DLY;
611 di_int <= do_reg after DLY;
612 daddr_int <= CTLE3_ADDR after DLY;
613 rxmon_sel <= "01" after DLY;
616 --Write new CTLE3 value
617 inc <= '0' after DLY;
618 dec <= '0' after DLY;
619 den_int <= '1' after DLY;
620 dwe_int <= '1' after DLY;
621 di_int <= ctle3_ld & do_reg(11 downto 0) after DLY;
622 daddr_int <= CTLE3_ADDR after DLY;
623 rxmon_sel <= "01" after DLY;
626 --Wait for 1024 cycles
to give
for AGC
to adapt
627 inc <= '0' after DLY;
628 dec <= '0' after DLY;
629 den_int <= '0' after DLY;
630 dwe_int <= '0' after DLY;
631 di_int <= ctle3_ld & do_reg(11 downto 0) after DLY;
632 daddr_int <= CTLE3_ADDR after DLY;
633 rxmon_sel <= "01" after DLY;
635 when DOWNSHIFT_4X_S =>
636 inc <= '0' after DLY;
637 dec <= '0' after DLY;
638 den_int <= '0' after DLY;
639 dwe_int <= '0' after DLY;
640 di_int <= (others=>'0') after DLY;
641 daddr_int <= AGC_BW_ADDR after DLY;
642 rxmon_sel <= (others=>'0') after DLY;
645 --Wait for AGC to adapt
646 inc <= '0' after DLY;
647 dec <= '0' after DLY;
648 den_int <= '0' after DLY;
649 dwe_int <= '0' after DLY;
650 di_int <= (others=>'0') after DLY;
651 daddr_int <= AGC_BW_ADDR after DLY;
652 rxmon_sel <= "01" after DLY;
656 inc <= '0' after DLY;
657 dec <= '0' after DLY;
658 den_int <= '0' after DLY;
659 dwe_int <= '0' after DLY;
660 di_int <= (others=>'0') after DLY;
661 daddr_int <= (others=>'0') after DLY;
662 rxmon_sel <= (others=>'0') after DLY;
665 inc <= '0' after DLY;
666 dec <= '0' after DLY;
667 den_int <= '0' after DLY;
668 dwe_int <= '0' after DLY;
669 di_int <= (others=>'0') after DLY;
670 daddr_int <= (others=>'0') after DLY;
671 rxmon_sel <= (others=>'0') after DLY;
677 --always @ (posedge clk_int)
679 if rising_edge(DCLK) then
680 if(clk_int_en='1') then
681 if(in_progress_b='1') then
682 --if(in_progress_b || time_reached)
683 ctle3_ld <= ctle3_reg after DLY;
687 ctle3_ld <= ctle3_reg - '1' after DLY;
689 ctle3_ld <= ctle3_reg + '1' after DLY;
691 ctle3_ld <= ctle3_ld after DLY;
700 --For synth: LDCE as SR latch
702 --- parameter INIT = 1'b0
717 --- always @ (CLR or G)