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.
 
 
 

149 lines
4.4 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
);
//
//
//insignal
// ----->
// insignal_trigger_sig
// ------->
// insignal_division
// -------->
// insignal_multiplication
wire insignal_rising_edge; //! 输入信号上升沿
wire insignal_falling_edge; //! 输入信号下降沿
wire 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)
);
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;
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;
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;
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;
gen_pluse_cnt <= gen_pluse_cnt + 1;
end
else begin
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