任意整数分频,50%占空比!module PWMDIV(clk_in,clk_out,clk_div,clk_dutycycle,rst);
input clk_in; // 输入时钟频率
output clk_out; // 分频后的时钟输出
input [15:0] clk_div;
input [15:0] clk_dutycycle;
input rst; // 异步复位信号
reg [23:0] cnt_p; // 上升沿脉冲计数
reg clk_p;
reg [23:0] cnt_n; // 下降沿脉冲计数
reg [23:0] cnt;
reg clk_n;
reg clk_even;
wire clk_odd;
reg [15:0] clk_div_r;
reg [15:0] clk_dutycycle_r;
reg [15:0] pulse_num_r;
reg [15:0] cnt_pulse;
always @(posedge clk_in or negedge rst)
begin
if(!rst)
cnt_p <= 0;
else if((clk_div[15:0]%2 == 0) || (clk_div[15:0] == 0))
cnt_p <= 0;
else if(cnt_p == clk_div[15:0] -1)
cnt_p <= 0;
else
cnt_p <= cnt_p+1;
end
always @(posedge clk_in or negedge rst)
begin
if(!rst)
clk_p <= 0;
else if( (clk_div[15:0]%2 == 0) || (clk_div[15:0] == 0))
clk_p <= 0;
else if(cnt_p < (clk_div[15:0]-1)/2)
clk_p <= 0;
else if(cnt_p == (clk_div[15:0]-1)/2)
clk_p <= ~clk_p;
else if(cnt_p == clk_div[15:0] -1)
clk_p <= ~clk_p;
end
always @(negedge clk_in or negedge rst)
begin
if(!rst)
cnt_n <= 0;
else if((clk_div[15:0]%2 == 0) || (clk_div[15:0] == 0))
cnt_n <= 0;
else if(cnt_n == clk_div[15:0] -1)
cnt_n <= 0;
else
cnt_n <= cnt_n+1;
end
always @(negedge clk_in or negedge rst)
begin
if( !rst )
clk_n <= 0;
else if( (clk_div[15:0]%2 == 0)|| (clk_div[15:0] == 0) )
clk_n <= 0;
else if(cnt_n < (clk_div[15:0]-1)/2)
clk_n <= 0;
else if(cnt_n == (clk_div[15:0]-1)/2)
clk_n <= ~clk_n;
else if(cnt_n == clk_div[15:0]-1)
clk_n <= ~clk_n;
end
// 偶数分频
always @(posedge clk_in or negedge rst)
begin
if(!rst)
cnt <= 0;
else if( (clk_div[15:0]%2 == 1) || (clk_div[15:0] == 0) )
cnt <= 0;
else if(cnt == clk_div[15:0] -1)
cnt <= 0;
else
cnt <= cnt+1;
end
always @(posedge clk_in or negedge rst)
begin
if(!rst)
clk_even <= 0;
else if( (clk_div[15:0]%2 == 1) || (clk_div[15:0] == 0) )
clk_even <= 0;
else if(cnt < clk_div[15:0]/2-1)
clk_even <= 0;
else if( cnt == clk_div[15:0]/2-1 )
clk_even <= ~clk_even;
else if(cnt == clk_div[15:0] -1)
clk_even <= ~clk_even;
end
assign clk_odd = clk_p | clk_n; //分频系数为奇数时的脉冲输出信号
assign clk_out = (clk_div[15:0]%2) ? clk_odd : clk_even; // 当分频系数为偶数时,输出clk_even,否则输出clk_odd
endmodule
|