| |
`timescale 1ns/1ns
module alt_gxb_clk_ctrl
(
input rst,
input clk,
input rx_pll_locked,
input rx_freq_locked,
output reg lock_to_data,
output reg lock_to_refclk
);
parameter START = 3'b001;
parameter MANUAL_SEL = 3'b010;
parameter AUTO_SEL = 3'b100;
reg [2:0] cur_stat;
reg [2:0] next_stat;
reg cnt_reset;
reg [7:0] cnt_dly;
reg time_dly_flag0;
reg time_dly_flag1;
always @ (posedge clk or posedge rst)
begin
if (rst == 1'b1)
cur_stat <= START;
else
cur_stat <= next_stat;
end
always @ (*)
begin
case (cur_stat)
START :
begin
if ((rx_pll_locked == 1'b1) && (time_dly_flag0 == 1'b1))
next_stat = MANUAL_SEL;
else
next_stat = START;
end
MANUAL_SEL :
begin
if ((rx_freq_locked == 1'b1) && (time_dly_flag1 == 1'b1))
next_stat = AUTO_SEL;
else
next_stat = START;
end
AUTO_SEL :
begin
if (rx_freq_locked == 1'b1)
next_stat = AUTO_SEL;
else
next_stat = START;
end
default : next_stat = START;
endcase
end
always @ (posedge clk or posedge rst)
begin
if (rst == 1'b1)
cnt_reset <= 1'b1;
else
begin
case (cur_stat)
START :
begin
if (time_dly_flag0 == 1'b1)
cnt_reset <= 1'b1;
else
cnt_reset <= 1'b0;
end
MANUAL_SEL :
begin
if (time_dly_flag1 == 1'b1)
cnt_reset <= 1'b1;
else
cnt_reset <= 1'b0;
end
AUTO_SEL : cnt_reset <= 1'b1;
default : cnt_reset <= 1'b1;
endcase
end
end
always @ (posedge clk or posedge rst)
begin
if (rst == 1'b1)
cnt_dly <= 8'd0;
else if (cnt_reset == 1'b1)
cnt_dly <= 8'd0;
else if (cur_stat == START)
begin
if (cnt_dly <= 8'd31)
cnt_dly <= cnt_dly + 8'd1;
else ;
end
else if (cur_stat == MANUAL_SEL)
begin
if (cnt_dly <= 8'hff)
cnt_dly <= cnt_dly + 8'd1;
else ;
end
else
cnt_dly <= 8'd0;
end
always @ (posedge clk or posedge rst)
begin
if (rst == 1'b1)
time_dly_flag0 <= 1'b0;
else if ((cur_stat == START) && (cnt_dly == 8'd31))
time_dly_flag0 <= 1'b1;
else
time_dly_flag0 <= 1'b0;
end
always @ (posedge clk or posedge rst)
begin
if (rst == 1'b1)
time_dly_flag1 <= 1'b0;
else if ((cur_stat == MANUAL_SEL) && (cnt_dly == 8'hff))
time_dly_flag1 <= 1'b1;
else
time_dly_flag1 <= 1'b0;
end
always @ (posedge clk or posedge rst)
begin
if (rst == 1'b1)
begin
lock_to_data <= 1'b0;
lock_to_refclk <= 1'b0;
end
else
begin
case (cur_stat)
START :
begin
lock_to_data <= 1'b0;
lock_to_refclk <= 1'b1;
end
MANUAL_SEL :
begin
lock_to_data <= 1'b1;
lock_to_refclk <= 1'b0;
end
AUTO_SEL :
begin
lock_to_data <= 1'b0;
lock_to_refclk <= 1'b0;
end
default :
begin
lock_to_data <= 1'b0;
lock_to_refclk <= 1'b0;
end
endcase
end
end
endmodule