1 |
9 |
jefflieu |
//
|
2 |
|
|
// Reset controller for Stratix IV transceivers with RX CDR in auto-lock mode.
|
3 |
|
|
//
|
4 |
|
|
// Uses altera_tse_reset_ctrl_lego to handle each reset stage, with 3 required for the overall sequence.
|
5 |
|
|
// Parameter defaults for pll-powerdown and lock-to-data-auto timers assume 50 MHz system clock
|
6 |
|
|
//
|
7 |
|
|
// $Header$
|
8 |
|
|
//
|
9 |
|
|
|
10 |
|
|
`timescale 1 ns / 1 ns
|
11 |
|
|
|
12 |
|
|
module altera_tse_reset_sequencer
|
13 |
|
|
#(
|
14 |
|
|
parameter sys_clk_in_mhz = 50 // needed for 1us and 4us delay timers
|
15 |
|
|
)
|
16 |
|
|
(
|
17 |
|
|
// User inputs and outputs
|
18 |
|
|
input wire clock,
|
19 |
|
|
input wire reset_all,
|
20 |
|
|
input tri0 reset_tx_digital,
|
21 |
|
|
input tri0 reset_rx_digital,
|
22 |
|
|
input wire powerdown_all,
|
23 |
|
|
output wire tx_ready,
|
24 |
|
|
output wire rx_ready,
|
25 |
|
|
|
26 |
|
|
// I/O to Stratix IV transceiver control & status
|
27 |
|
|
output wire pll_powerdown, // reset TX PLL
|
28 |
|
|
output wire tx_digitalreset, // reset TX PCS
|
29 |
|
|
output wire rx_analogreset, // reset RX PMA
|
30 |
|
|
output wire rx_digitalreset, // reset RX PCS
|
31 |
|
|
output wire gxb_powerdown, // powerdown whole quad
|
32 |
|
|
input wire pll_is_locked, // TX PLL is locked status
|
33 |
|
|
input tri0 rx_oc_busy, // RX channel offset cancellation status
|
34 |
|
|
input tri1 rx_is_lockedtodata, // RX CDR PLL is locked to data status
|
35 |
|
|
input tri0 manual_mode // 0=Automatically reset RX after loss of rx_is_lockedtodata
|
36 |
|
|
);
|
37 |
|
|
|
38 |
|
|
localparam clk_in_mhz =
|
39 |
|
|
`ifdef QUARTUS__SIMGEN
|
40 |
|
|
2; // simulation-only value
|
41 |
|
|
`elsif ALTERA_RESERVED_QIS
|
42 |
|
|
sys_clk_in_mhz; // use real counter lengths for normal Quartus synthesis
|
43 |
|
|
`else
|
44 |
|
|
2; // simulation-only value
|
45 |
|
|
`endif
|
46 |
|
|
localparam t_pll_powerdown = clk_in_mhz; // 1 us minimum
|
47 |
|
|
localparam t_ltd_auto = clk_in_mhz*4; // 4 us minimum
|
48 |
|
|
|
49 |
|
|
|
50 |
|
|
wire pll_is_locked_r; // pll_is_locked resynchronized
|
51 |
|
|
wire rx_oc_busy_r; // rx_oc_busy resynchronized
|
52 |
|
|
wire rx_is_lockedtodata_r; // rx_is_lockedtodata resynchronized
|
53 |
|
|
wire manual_mode_r; // manual_mode resynchonized
|
54 |
|
|
|
55 |
|
|
wire sdone_lego_pll_powerdown; // 'sequence done' output of pll_powerdown lego
|
56 |
|
|
wire sdone_lego_tx_digitalreset;// 'sequence done' output of tx_digitalreset lego
|
57 |
|
|
wire sdone_lego_rx_digitalreset;// 'sequence done' output of rx_digitalreset lego
|
58 |
|
|
wire sdone_lego_rx_analogreset; // 'sequence done' output of rx_analogreset lego
|
59 |
|
|
wire wire_tx_digital_only_reset;// reset output for TX digital-only
|
60 |
|
|
wire wire_rx_digital_only_reset;// reset output for RX digital-only
|
61 |
|
|
wire wire_tx_digitalreset; // TX digital full-reset source
|
62 |
|
|
wire wire_rx_digitalreset; // RX digital full-reset source
|
63 |
20 |
jefflieu |
wire wire_rx_digital_retrigger; // Trigger new RX digital sequence after main sequence completes, and lose lock-to-data
|
64 |
9 |
jefflieu |
|
65 |
|
|
|
66 |
|
|
// Resynchronize input signals
|
67 |
|
|
altera_tse_xcvr_resync #(
|
68 |
|
|
.WIDTH(4)
|
69 |
|
|
) altera_tse_xcvr_resync_inst (
|
70 |
|
|
.clk (clock),
|
71 |
|
|
.d ({pll_is_locked ,rx_oc_busy ,rx_is_lockedtodata ,manual_mode }),
|
72 |
|
|
.q ({pll_is_locked_r,rx_oc_busy_r,rx_is_lockedtodata_r,manual_mode_r})
|
73 |
|
|
);
|
74 |
|
|
|
75 |
20 |
jefflieu |
|
76 |
9 |
jefflieu |
// First reset ctrl sequencer lego is for pll_powerdown generation
|
77 |
|
|
altera_tse_reset_ctrl_lego #(
|
78 |
|
|
.reset_hold_cycles(t_pll_powerdown) // hold pll_powerdown for 1us
|
79 |
|
|
) lego_pll_powerdown ( .clock(clock),
|
80 |
|
|
.start(reset_all), // Do not use resynched version of reset_all here
|
81 |
|
|
.aclr(powerdown_all),
|
82 |
|
|
.reset(pll_powerdown),
|
83 |
|
|
.rdone(pll_is_locked_r),
|
84 |
|
|
.sdone(sdone_lego_pll_powerdown));
|
85 |
|
|
|
86 |
|
|
// next reset ctrl sequencer lego is for tx_digitalreset generation
|
87 |
|
|
altera_tse_reset_ctrl_lego #(
|
88 |
|
|
.reset_hold_til_rdone(1) // hold until rdone arrives for this test case
|
89 |
|
|
) lego_tx_digitalreset ( .clock(clock),
|
90 |
|
|
.start(reset_all),
|
91 |
|
|
.aclr(powerdown_all),
|
92 |
|
|
.reset(wire_tx_digitalreset),
|
93 |
|
|
.rdone(sdone_lego_pll_powerdown),
|
94 |
|
|
.sdone(sdone_lego_tx_digitalreset));
|
95 |
|
|
|
96 |
|
|
// next reset ctrl sequencer lego is for rx_analogreset generation
|
97 |
|
|
altera_tse_reset_ctrl_lego #(
|
98 |
|
|
.reset_hold_til_rdone(1), // hold until rdone arrives for this test case
|
99 |
|
|
.sdone_delay_cycles(2) // hold rx_analogreset 2 parallel_clock cycles after offset cancellation done
|
100 |
|
|
) lego_rx_analogreset ( .clock(clock),
|
101 |
|
|
.start(reset_all),
|
102 |
|
|
.aclr(powerdown_all),
|
103 |
|
|
.reset(rx_analogreset),
|
104 |
|
|
.rdone(sdone_lego_tx_digitalreset & ~rx_oc_busy_r),
|
105 |
|
|
.sdone(sdone_lego_rx_analogreset));
|
106 |
|
|
|
107 |
|
|
// last reset ctrl sequencer lego is for rx_digitalreset generation
|
108 |
|
|
altera_tse_reset_ctrl_lego #(
|
109 |
|
|
.reset_hold_til_rdone(1), // hold until rdone arrives for this test case
|
110 |
|
|
.sdone_delay_cycles(t_ltd_auto) // hold rx_digitalreset for 4us
|
111 |
|
|
) lego_rx_digitalreset ( .clock(clock),
|
112 |
20 |
jefflieu |
.start(~manual_mode & reset_all | wire_rx_digital_retrigger),
|
113 |
9 |
jefflieu |
.aclr(powerdown_all),
|
114 |
|
|
.reset(wire_rx_digitalreset),
|
115 |
|
|
.rdone(sdone_lego_rx_analogreset & rx_is_lockedtodata_r),
|
116 |
|
|
.sdone(sdone_lego_rx_digitalreset));
|
117 |
|
|
|
118 |
|
|
//////////// digital-only reset ////////////
|
119 |
|
|
// separate reset ctrl sequencer lego for digital-only reset generation
|
120 |
|
|
altera_tse_reset_ctrl_lego #(
|
121 |
|
|
.reset_hold_cycles(3) // hold 2 parallel clock cycles (assumes sysclk slower or same freq as parallel clock)
|
122 |
|
|
) lego_tx_digitalonly ( .clock(clock),
|
123 |
|
|
.start(reset_tx_digital | reset_all),
|
124 |
|
|
.aclr(powerdown_all),
|
125 |
|
|
.reset(wire_tx_digital_only_reset),
|
126 |
|
|
.rdone(sdone_lego_tx_digitalreset),
|
127 |
|
|
.sdone(tx_ready)); // TX status indicator for user
|
128 |
|
|
|
129 |
|
|
altera_tse_reset_ctrl_lego #(
|
130 |
|
|
.reset_hold_cycles(3) // hold 2 parallel clock cycles (assumes sysclk slower or same freq as parallel clock)
|
131 |
|
|
) lego_rx_digitalonly ( .clock(clock),
|
132 |
20 |
jefflieu |
.start(reset_rx_digital | (reset_all & ~manual_mode) | wire_rx_digital_retrigger),
|
133 |
9 |
jefflieu |
.aclr(powerdown_all),
|
134 |
|
|
.reset(wire_rx_digital_only_reset),
|
135 |
|
|
.rdone(sdone_lego_rx_digitalreset),
|
136 |
|
|
.sdone(rx_ready)); // RX status indicator for user
|
137 |
|
|
|
138 |
|
|
// digital resets have 2 possible sources: full-reset or digital-only
|
139 |
|
|
assign tx_digitalreset = wire_tx_digitalreset | wire_tx_digital_only_reset;
|
140 |
|
|
assign rx_digitalreset = wire_rx_digitalreset | wire_rx_digital_only_reset;
|
141 |
|
|
|
142 |
20 |
jefflieu |
// re-trigger RX digital sequence when main sequence is complete (indicated by sdone_lego_rx_digitalreset)
|
143 |
|
|
// not manual mode, and lose lock-to-data
|
144 |
|
|
assign wire_rx_digital_retrigger = ~manual_mode & sdone_lego_rx_digitalreset & ~rx_is_lockedtodata_r;
|
145 |
|
|
|
146 |
9 |
jefflieu |
// Quad power-down
|
147 |
|
|
assign gxb_powerdown = powerdown_all;
|
148 |
|
|
|
149 |
|
|
|
150 |
|
|
////////////////////////
|
151 |
|
|
// general assertions
|
152 |
|
|
//synopsys translate_off
|
153 |
|
|
// vlog/vcs/ncverilog: +define+ALTERA_XCVR_ASSERTIONS
|
154 |
|
|
`ifdef ALTERA_XCVR_ASSERTIONS
|
155 |
|
|
always @(posedge clock) begin
|
156 |
|
|
// reset_all starts by triggering CMU PLL powerdown
|
157 |
|
|
assert property ($rose(reset_all) |=> $rose(pll_powerdown));
|
158 |
|
|
// While CMU PLL powerdown is asserted, all other resets must be asserted
|
159 |
|
|
assert property (pll_powerdown |-> (tx_digitalreset & rx_analogreset & rx_digitalreset));
|
160 |
|
|
// While rx_analogreset is asserted, rx_digitalreset must be asserted
|
161 |
|
|
assert property (rx_analogreset |-> rx_digitalreset);
|
162 |
|
|
// When pll_is_locked is asserted, tx_digitalreset must be deasserted
|
163 |
|
|
assert property ($rose(pll_is_locked_r) |-> ##[0:2] !tx_digitalreset);
|
164 |
|
|
// During a reset, rx_digitalreset should remain high for t_ltd_auto after rx_is_lockedtodata rising edge
|
165 |
|
|
assert property ($rose(rx_is_lockedtodata_r) |-> rx_digitalreset [*(t_ltd_auto+1)] ##1 !rx_digitalreset);
|
166 |
|
|
// reset_tx_digital results in only a brief pulse on tx_digitalreset
|
167 |
|
|
assert property ($rose(reset_tx_digital) |=> tx_digitalreset [*3] );
|
168 |
|
|
assert property ($rose(reset_tx_digital) & tx_ready |=> tx_digitalreset [*3] ##1 ~tx_digitalreset ##1 $rose(tx_ready) );
|
169 |
|
|
// reset_rx_digital results in only a brief pulse on rx_digitalreset
|
170 |
|
|
assert property ($rose(reset_rx_digital) |=> rx_digitalreset [*3] );
|
171 |
|
|
assert property ($rose(reset_rx_digital) & rx_ready |=> rx_digitalreset [*3] ##1 ~rx_digitalreset ##1 $rose(rx_ready) );
|
172 |
|
|
end
|
173 |
|
|
`endif
|
174 |
|
|
//synopsys translate_on
|
175 |
|
|
|
176 |
|
|
endmodule
|