jesd204_rx/jesd204_rx_ctrl: Fix de-glitch mechanism
The previous implementation of the de-glitch only delayed the assertion of the SYNC phase by 64 clock cycles with the DEGLITCH state but if meanwhile one of the lanes got into a bad state cgs_ready de-asserted the state machine continued to go SYNCHRONIZED (DATA) state. This change extends the required number of consecutive cycles while all lanes must stay in data phase before moving the link to SYNCHRONIZED state from 8 to 256; This increases the reliability of link bring-up without needing extra link restarts from software side.main
parent
5edc798b6b
commit
ee143d80d6
|
@ -68,19 +68,13 @@ module jesd204_rx_ctrl #(
|
||||||
output [NUM_LINKS-1:0] sync,
|
output [NUM_LINKS-1:0] sync,
|
||||||
output reg latency_monitor_reset,
|
output reg latency_monitor_reset,
|
||||||
|
|
||||||
output reg [1:0] status_state
|
output [1:0] status_state
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam STATUS_STATE_RESET = 2'h1;
|
|
||||||
localparam STATUS_STATE_WAIT_FOR_PHY = 2'h1;
|
|
||||||
localparam STATUS_STATE_CGS = 2'h2;
|
|
||||||
localparam STATUS_STATE_SYNCHRONIZED = 2'h3;
|
|
||||||
|
|
||||||
localparam STATE_RESET = 0;
|
localparam STATE_RESET = 0;
|
||||||
localparam STATE_WAIT_FOR_PHY = 1;
|
localparam STATE_WAIT_FOR_PHY = 1;
|
||||||
localparam STATE_CGS = 2;
|
localparam STATE_CGS = 2;
|
||||||
localparam STATE_DEGLITCH = 3;
|
localparam STATE_SYNCHRONIZED = 3;
|
||||||
localparam STATE_SYNCHRONIZED = 4;
|
|
||||||
|
|
||||||
reg [2:0] state = STATE_RESET;
|
reg [2:0] state = STATE_RESET;
|
||||||
reg [2:0] next_state = STATE_RESET;
|
reg [2:0] next_state = STATE_RESET;
|
||||||
|
@ -91,24 +85,17 @@ reg [NUM_LINKS-1:0] sync_n = {NUM_LINKS{1'b1}};
|
||||||
reg en_align = 1'b0;
|
reg en_align = 1'b0;
|
||||||
reg state_good = 1'b0;
|
reg state_good = 1'b0;
|
||||||
|
|
||||||
reg [2:0] good_counter = 'h00;
|
reg [7:0] good_counter = 'h00;
|
||||||
reg [9:0] deglitch_counter = 'h3ff;
|
|
||||||
|
wire [7:0] good_cnt_limit_s;
|
||||||
|
wire good_cnt_limit_reached_s;
|
||||||
|
|
||||||
assign cgs_reset = cgs_rst;
|
assign cgs_reset = cgs_rst;
|
||||||
assign ifs_reset = ifs_rst;
|
assign ifs_reset = ifs_rst;
|
||||||
assign sync = sync_n;
|
assign sync = sync_n;
|
||||||
assign phy_en_char_align = en_align;
|
assign phy_en_char_align = en_align;
|
||||||
|
|
||||||
always @(posedge clk) begin
|
assign status_state = state;
|
||||||
case (state)
|
|
||||||
STATE_RESET: status_state <= STATUS_STATE_RESET;
|
|
||||||
STATE_WAIT_FOR_PHY: status_state <= STATUS_STATE_WAIT_FOR_PHY;
|
|
||||||
STATE_CGS: status_state <= STATUS_STATE_CGS;
|
|
||||||
STATE_DEGLITCH: status_state <= STATUS_STATE_CGS;
|
|
||||||
STATE_SYNCHRONIZED: status_state <= STATUS_STATE_SYNCHRONIZED;
|
|
||||||
default: status_state <= STATUS_STATE_RESET;
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
case (state)
|
case (state)
|
||||||
|
@ -132,33 +119,28 @@ always @(posedge clk) begin
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
always @(posedge clk) begin
|
|
||||||
case (state)
|
|
||||||
STATE_DEGLITCH: begin
|
|
||||||
if (deglitch_counter != 'h00) begin
|
|
||||||
deglitch_counter <= deglitch_counter - 1'b1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
default: begin
|
|
||||||
deglitch_counter <= 'h3f;
|
|
||||||
end
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
|
|
||||||
always @(*) begin
|
always @(*) begin
|
||||||
case (state)
|
case (state)
|
||||||
STATE_RESET: state_good <= 1'b1;
|
STATE_RESET: state_good <= 1'b1;
|
||||||
STATE_WAIT_FOR_PHY: state_good <= phy_ready;
|
STATE_WAIT_FOR_PHY: state_good <= phy_ready;
|
||||||
STATE_CGS: state_good <= &(cgs_ready | cfg_lanes_disable);
|
STATE_CGS: state_good <= &(cgs_ready | cfg_lanes_disable);
|
||||||
STATE_DEGLITCH: state_good <= deglitch_counter == 'h00;
|
|
||||||
STATE_SYNCHRONIZED: state_good <= 1'b1;
|
STATE_SYNCHRONIZED: state_good <= 1'b1;
|
||||||
default: state_good <= 1'b0;
|
default: state_good <= 1'b0;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
|
assign good_cnt_limit_s = (state == STATE_CGS) ? 'hff : 'h7;
|
||||||
|
assign good_cnt_limit_reached_s = good_counter == good_cnt_limit_s;
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (state_good == 1'b1) begin
|
if (reset) begin
|
||||||
|
good_counter <= 'h00;
|
||||||
|
end else if (state_good == 1'b1) begin
|
||||||
|
if (good_cnt_limit_reached_s) begin
|
||||||
|
good_counter <= 'h00;
|
||||||
|
end else begin
|
||||||
good_counter <= good_counter + 1'b1;
|
good_counter <= good_counter + 1'b1;
|
||||||
|
end
|
||||||
end else begin
|
end else begin
|
||||||
good_counter <= 'h00;
|
good_counter <= 'h00;
|
||||||
end
|
end
|
||||||
|
@ -175,8 +157,7 @@ always @(*) begin
|
||||||
case (state)
|
case (state)
|
||||||
STATE_RESET: next_state <= STATE_WAIT_FOR_PHY;
|
STATE_RESET: next_state <= STATE_WAIT_FOR_PHY;
|
||||||
STATE_WAIT_FOR_PHY: next_state <= STATE_CGS;
|
STATE_WAIT_FOR_PHY: next_state <= STATE_CGS;
|
||||||
STATE_CGS: next_state <= STATE_DEGLITCH;
|
STATE_CGS: next_state <= STATE_SYNCHRONIZED;
|
||||||
STATE_DEGLITCH: next_state <= STATE_SYNCHRONIZED;
|
|
||||||
default: next_state <= state_good ? state : STATE_RESET;
|
default: next_state <= state_good ? state : STATE_RESET;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
@ -185,7 +166,7 @@ always @(posedge clk) begin
|
||||||
if (reset == 1'b1) begin
|
if (reset == 1'b1) begin
|
||||||
state <= STATE_RESET;
|
state <= STATE_RESET;
|
||||||
end else begin
|
end else begin
|
||||||
if (good_counter == 'h7) begin
|
if (good_cnt_limit_reached_s) begin
|
||||||
state <= next_state;
|
state <= next_state;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue