Wolf-LITE/FPGA/vcxo_controller.v

115 wiersze
2.0 KiB
Verilog

module vcxo_controller(
vcxo_clk_in,
tcxo_clk_in,
VCXO_correction,
freq_error,
pump,
PWM
);
parameter VCXO_freq_khz = 1228800; //x100hz
parameter TCXO_freq_khz = 122880; //x100hz
input vcxo_clk_in;
input tcxo_clk_in;
input signed [7:0] VCXO_correction;
output reg signed [23:0] freq_error = 0;
output reg pump = 0;
output reg signed [23:0] PWM = 500;
reg [23:0] PWM_max = 1000;
reg signed [23:0] freq_error_now = 0;
reg signed [23:0] freq_error_prev = 0;
reg signed [23:0] freq_error_diff = 0;
reg signed [31:0] VCXO_counter = 0;
reg signed [31:0] TCXO_counter = 0;
reg [31:0] PWM_counter = 0;
reg counter_reset = 0;
reg counter_resetted = 0;
reg [7:0] state = 0;
always @ (posedge vcxo_clk_in)
begin
if(state != 2 && state != 3)
begin
if(counter_reset)
begin
VCXO_counter <= 0;
counter_resetted <= 1;
end
else
begin
VCXO_counter <= VCXO_counter + 1;
counter_resetted <= 0;
end
end
end
always @ (posedge tcxo_clk_in)
begin
//do PWM
PWM_counter = PWM_counter + 1;
if(PWM_counter >= PWM_max)
PWM_counter = 0;
if(PWM > PWM_counter)
pump = 1;
else
pump = 0;
if(counter_reset && !counter_resetted)
begin
//wait VCXO reset
end
else
begin
if(state == 0)
begin
TCXO_counter = 0;
counter_reset = 0;
state = 1;
end
else if(state == 1)
begin
TCXO_counter = TCXO_counter + 1;
if(TCXO_counter >= TCXO_freq_khz)
state = 2;
end
else if(state == 2)
begin
freq_error_now = VCXO_counter - VCXO_freq_khz + VCXO_correction;
freq_error_diff = freq_error_prev - freq_error_now;
if(freq_error_diff > -50 && freq_error_diff < 50) //measure errors
if(freq_error_now > -1000 && freq_error_now < 1000) //measure errors
begin
//save
freq_error = freq_error_now;
//tune
if(freq_error_now < 0)
PWM = PWM + 1;
else if(freq_error_now > 0)
PWM = PWM - 1;
end
state = 3;
end
else if(state == 3)
begin
freq_error_prev = freq_error_now;
if(PWM > PWM_max)
PWM = PWM_max;
if(PWM < 0)
PWM = 0;
counter_reset = 1;
state = 0;
end
end
end
endmodule