forked from p_lusterinc_xsync/xsync_fpge
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
5.1 KiB
157 lines
5.1 KiB
module zsimple_pll (
|
|
input clk, //!clock input
|
|
input rst_n, //!asynchronous reset input, low active
|
|
|
|
input insignal, //!输入信号
|
|
input trigger_eage_type,
|
|
input wire [31:0] freq_detect_bias, //! 频率偏差计数
|
|
input wire [31:0] freq_division,
|
|
input wire [31:0] freq_multiplication,
|
|
input wire polarity_ctrl,
|
|
input wire cfg_change,
|
|
output wire outsignal,
|
|
output reg output_trigger_sig
|
|
);
|
|
|
|
//
|
|
//
|
|
//insignal
|
|
// ----->
|
|
// insignal_trigger_sig
|
|
// ------->
|
|
// insignal_division
|
|
// -------->
|
|
// insignal_multiplication
|
|
|
|
|
|
|
|
wire insignal_rising_edge; //! 输入信号上升沿
|
|
wire insignal_falling_edge; //! 输入信号下降沿
|
|
reg insignal_trigger_sig; //! 触发信号
|
|
wire module_reset; //! 模块内部复位信号
|
|
|
|
reg insignal_division; //! 输入信号分频后的信号
|
|
reg insignal_multiplication; //! 输入信号倍频后的信号
|
|
reg insignal_pluse_width_modulation; //! 输入信号脉宽调制后的信号
|
|
|
|
|
|
zutils_edge_detecter edge_detecter (
|
|
.clk (clk),
|
|
.rst_n (rst_n),
|
|
.in_signal (insignal),
|
|
.in_signal_rising_edge (insignal_rising_edge),
|
|
.in_signal_falling_edge(insignal_falling_edge)
|
|
);
|
|
|
|
|
|
always @(*) begin
|
|
case (trigger_eage_type)
|
|
0: insignal_trigger_sig <= insignal_rising_edge;
|
|
1: insignal_trigger_sig <= insignal_rising_edge;
|
|
2: insignal_trigger_sig <= insignal_rising_edge;
|
|
default:
|
|
insignal_trigger_sig <= insignal_rising_edge;
|
|
endcase
|
|
end
|
|
|
|
// assign insignal_trigger_sig = trigger_eage_type ? insignal_rising_edge : insignal_falling_edge;
|
|
assign module_reset = !rst_n || cfg_change;
|
|
|
|
// 分频
|
|
reg [31:0] insignal_division_cnt;
|
|
always @(posedge clk or posedge module_reset) begin
|
|
if (module_reset) begin
|
|
insignal_division_cnt <= 0;
|
|
insignal_division <= 0;
|
|
end else begin
|
|
if (insignal_trigger_sig) begin
|
|
if (insignal_division_cnt >= freq_division) begin
|
|
insignal_division_cnt <= 0;
|
|
insignal_division <= 1;
|
|
end else begin
|
|
insignal_division_cnt <= insignal_division_cnt + 1;
|
|
end
|
|
end else begin
|
|
insignal_division <= 0;
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
wire [31:0] insignal_multiplication_freq_cnt;
|
|
wire pluse_width_cnt_lock;
|
|
|
|
zutils_freq_detector_v2 freq_detector (
|
|
.clk (clk),
|
|
.rst_n (rst_n),
|
|
.freq_detect_bias (freq_detect_bias),
|
|
.pluse_input (insignal_division),
|
|
.pluse_width_cnt (insignal_multiplication_freq_cnt),
|
|
.pluse_width_cnt_lock(pluse_width_cnt_lock)
|
|
);
|
|
|
|
|
|
reg [31:0] multiplication_cnt;
|
|
reg [31:0] multiplication_state;
|
|
reg [31:0] gen_pluse_cnt;
|
|
|
|
always @(posedge clk or posedge module_reset) begin
|
|
if (module_reset || !pluse_width_cnt_lock) begin
|
|
multiplication_cnt <= 0;
|
|
multiplication_state <= 0;
|
|
gen_pluse_cnt <= 0;
|
|
insignal_multiplication <= 0;
|
|
output_trigger_sig <= 0;
|
|
end else begin
|
|
case (multiplication_state)
|
|
0: begin
|
|
gen_pluse_cnt <= 0;
|
|
multiplication_cnt <= 0;
|
|
insignal_multiplication <= 0;
|
|
|
|
if (pluse_width_cnt_lock) begin
|
|
multiplication_state <= 1;
|
|
end
|
|
end
|
|
1: begin
|
|
if (insignal_division) begin
|
|
multiplication_state <= 2;
|
|
gen_pluse_cnt <= 0;
|
|
insignal_multiplication <= 1;
|
|
output_trigger_sig <= 1;
|
|
multiplication_cnt <= 0;
|
|
end
|
|
end
|
|
2: begin
|
|
if (multiplication_cnt < insignal_multiplication_freq_cnt >> 1) begin
|
|
multiplication_cnt <= multiplication_cnt + freq_multiplication + 1;
|
|
insignal_multiplication <= 1;
|
|
output_trigger_sig <= 0;
|
|
end else if ((multiplication_cnt + freq_multiplication + 2) >= insignal_multiplication_freq_cnt) begin
|
|
gen_pluse_cnt <= gen_pluse_cnt + 1;
|
|
multiplication_cnt <= 0;
|
|
insignal_multiplication <= 1;
|
|
output_trigger_sig <= 1;
|
|
gen_pluse_cnt <= gen_pluse_cnt + 1;
|
|
end else begin
|
|
output_trigger_sig <= 0;
|
|
if (gen_pluse_cnt >= freq_multiplication) begin
|
|
multiplication_state <= 1;
|
|
insignal_multiplication <= 0;
|
|
multiplication_cnt <= 0;
|
|
end else begin
|
|
multiplication_cnt <= multiplication_cnt + freq_multiplication + 1;
|
|
insignal_multiplication <= 0;
|
|
end
|
|
end
|
|
end
|
|
default: begin
|
|
multiplication_state <= 0;
|
|
end
|
|
endcase
|
|
end
|
|
end
|
|
|
|
|
|
assign outsignal = insignal_multiplication ^ polarity_ctrl;
|
|
endmodule
|