FPGA奇数分频的实现
作者:互联网
在FPGA开发中,我们往往需要对时钟进行分频,得到满足我们需求的时钟频率。尽管这些分频的工作完全可以由PLL等ip核完成,但通过verilog语言同样也可以实现。在本博客中,我们仅讨论整数倍分频。
偶数倍分频
偶数倍分频的实现较为简单,一般是设置一个计数器,从0开始计数,达到N-1后又重新归零,分频的时钟信号在(N/2-1)时翻转。
奇数倍分频
三分频
分别设置两个模3计数器cnt1,cnt2,以及两个中间信号clk1,clk2,clk1信号在clk信号的上升沿且cnt1=0或2的时候翻转,而clk2信号在clk信号的下降沿且cnt2=0或2的时候翻转,最后clk1和clk2信号相或,得到最终的结果clk_div3,即实现了三分频的效果。
以下是实现的Verilog代码:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/02/07 12:32:58
// Design Name:
// Module Name: odd_clkdiv
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module odd_clkdiv(
input wire rst,
input wire clk,
output wire clk_div3
);
reg [3:0] cnt1;
reg [3:0] cnt2;
reg clk1;
reg clk2;
assign clk_div3=clk1 | clk2;
//cnt1
always@(posedge clk,posedge rst)
if(rst)
cnt1<=0;
else if(cnt1==2)
cnt1<=0;
else
cnt1<=cnt1+1;
//cnt2
always@(negedge clk,posedge rst)
if(rst)
cnt2<=0;
else if(cnt2==3-1)
cnt2<=0;
else
cnt2<=cnt2+1;
//clk1
always@(posedge clk,posedge rst)
if(rst)
clk1<=1;
else if(cnt1==0||cnt1==2)
clk1<=~clk1;
//clk2
always@(negedge clk,posedge rst)
if(rst)
clk2<=1;
else if(cnt2==0||cnt2==2)
clk2<=~clk2;
endmodule
仿真波形:
该三分频信号的占空比为50%。
任意倍奇数倍分频
算法如下:
a.设置一个计数长度为N的上升沿计数器,和一个信号寄存器;信号寄存器在上升沿计数器为(N-1)/2的时候进行翻转,然后再在计数到N-1的时候进行翻转。
b.设置一个计数长度为N的下降沿计数器,和另一个信号寄存器;信号寄存器在下降沿计数器为(N-1)/2的时候进行翻转,然后再在计数到N-1的时候进行翻转。
c.将A和B相或就可以得到奇数分频信号。Verilog代码如下:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/02/07 12:32:58
// Design Name:
// Module Name: odd_clkdiv
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module odd_clkdiv
#(parameter N = 5)
(
input wire rst,
input wire clk,
output wire clk_div
);
reg [31:0] cnt1;
reg [31:0] cnt2;
reg clk1;
reg clk2;
assign clk_div=clk1 | clk2;
//cnt1
always@(posedge clk,posedge rst)
if(rst)
cnt1<=0;
else if(cnt1==N-1)
cnt1<=0;
else
cnt1<=cnt1+1;
//cnt2
always@(negedge clk,posedge rst)
if(rst)
cnt2<=0;
else if(cnt2==N-1)
cnt2<=0;
else
cnt2<=cnt2+1;
//clk1
always@(posedge clk,posedge rst)
if(rst)
clk1<=1;
else if(cnt1==(N-1)/2||cnt1==(N-1))
clk1<=~clk1;
//clk2
always@(negedge clk,posedge rst)
if(rst)
clk2<=1;
else if(cnt2==(N-1)/2||cnt2==(N-1))
clk2<=~clk2;
endmodule
11分频仿真波形展示:
标签:分频,FPGA,clk,奇数,cnt1,clk1,clk2,reg 来源: https://blog.csdn.net/qq_40268672/article/details/122807283