FPGA等占空比奇偶分频和半整数分频

2023-05-15,,

1. 偶数分频比较简单,如果分频系数是N(如果N是偶数,那么N/2是整数),那么在输入时钟的每隔N/2个周期时(计数器从0到N/2-1),改变输出时钟的电平即可得到50%固定占空比的时钟。需要的代码如下

module even(clk_in,clk_out,rst_n);
input clk_in;
input rst_n;
output clk_out; parameter N=; reg [:] cnt;
reg clk_out; always @(posedge clk_in or negedge rst_n) begin
if(!rst_n) begin
cnt<='b0000;
clk_out<=;
end
else if(cnt==(N/-)) begin
clk_out<=~clk_out;
cnt<='b0000;
end else cnt<=cnt+;
end
endmodule

2. 如果N是奇数,那么N/2非整数,使用2个寄存器,分别用上升沿寄存器计数到(N-1)/2-1电平翻转信号A,再计数到N-1电平翻转信号A,再用下降沿寄存器计数到(N-1)/2-1电平翻转信号B,再计数到N-1电平翻转信号B,,得到两个波形A和B,然后A和B相或即可,代码如下:

module div3(clk,clk_out,rst_n);
input clk,rst_n;
output clk_out; reg [:] cnt_p,cnt_n;
reg clk_p,clk_n;
parameter N=; always @(posedge clk or negedge rst_n) begin
if(!rst_n)
cnt_p<='h0;
else if(cnt_p==N-)
cnt_p<=;
else cnt_p<=cnt_p+;
end always @(negedge clk or negedge rst_n) begin
if(!rst_n)
cnt_n<='h0;
else if(cnt_n==N-)
cnt_n<=;
else cnt_n<=cnt_n+;
end always @(posedge clk or negedge rst_n) begin
if(!rst_n)
clk_p<=;
else if(cnt_p==(N-)/-)
clk_p<=~clk_p;
else if(cnt_p==(N-))
clk_p<=~clk_p;
end always @(negedge clk or negedge rst_n) begin
if(!rst_n)
clk_n<=;
else if(cnt_n==(N-)/-)
clk_n<=~clk_n;
else if(cnt_n==(N-))
clk_n<=~clk_n;
end
assign clk_out=clk_n|clk_p;
endmodule

仿真截图如下

3. 半整数分频,本次以2.5分频为例子

//===========================================================
// Author: seuchenrui@126.com
//
// Description:
// This is a simple verilog code for clock frequency division
// this code can be used to get
// 1. divided by 2.5
//===========================================================
module iCLK_div_shift_register_25
(
input iCLK,
input iRESET,
output oCLK
); wire [:] tmp_shift; reg tmp_0_;
reg tmp_2_;
reg tmp_3_; reg [:] tmp;
assign tmp_shift = 'b0_0001; always@(posedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp<=tmp_shift;
else
tmp<={tmp[:], tmp[]};
end always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_0_<='b0;
else
tmp_0_<=tmp[];
end always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_2_<='b0;
else
tmp_2_<=tmp[];
end always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_3_<='b0;
else
tmp_3_<=tmp[];
end assign oCLK = tmp[]|tmp[]|tmp_0_|tmp_2_|tmp_3_|tmp[]; endmodule

3. 半整数分频,这个主要是利用时钟的上升沿和下降沿进行计数。不过分出来的占空比不是50%。问题在于如果被分的时钟不是50%占空比,那么按照下面出来的时钟频率还对吗?不对。

//2.5分频

module div_5(clk,clk_div, rst, temp_out1, temp_out2);//N+0.5
input clk;
input rst;
output clk_div;
reg [:] cnt1,cnt2;
//output reg temp1,temp2;
reg temp1,temp2;
output temp_out1, temp_out2;
parameter N = ; //设定分频系数为N+0.5
reg start_negedge;
//inital语句不可被综合
//initial
//begin
// temp1=0;temp2=1;
//end //首先进行初始化,temp1=0;temp2=1 //所有的判断信号都要写入 always @(posedge clk or negedge rst) //temp1上升沿跳变
begin if(!rst)
begin
cnt1<='b0;
temp1<=;
start_negedge <= ;
end else begin if(cnt1 == *N)
begin cnt1<='b0;end else begin cnt1 <= cnt1 + 'b1;end if(cnt1=='b0) begin temp1<=1; start_negedge <= 1;end //高电平时间为N+1;
else if(cnt1==N+) begin temp1<=;end //低电平时间为N;
end end always@(negedge clk or negedge rst) //temp2下降沿跳变
begin
if(!rst)
begin
cnt2<='b0;
temp2<=; end
else if(start_negedge == )
begin
cnt2<='b0;
temp2<=; end
else begin if(cnt2==*N) //2*N
begin cnt2<='d0;end
else begin cnt2<=cnt2+'d1;end
if(cnt2=='d0) begin temp2<=0;end //低电平时间为N;
else if(cnt2==N) begin temp2<=;end //高电平时间为N+1;
end end assign clk_div=temp1&temp2; //逻辑与
assign temp_out1 = temp1;
assign temp_out2 = temp2;
endmodule

仿真截图如下

FPGA等占空比奇偶分频和半整数分频的相关教程结束。

《FPGA等占空比奇偶分频和半整数分频.doc》

下载本文的Word格式文档,以方便收藏与打印。