FPGA实现任意奇数分频
奇数分频原理分析
我们都知道用FPGA做偶数分频很简单,只需要用计数器计数到分频系数N的一半再减去1,不断去翻转分频的信号即可得到分频的信号,那么奇数奇数分频其实也是一样的,但是如果要得到占空比为50%的信号,那可能就需要处理一下才可以,下图为占空比为50%的3分频信号产生原理。
Verilog代码实现
module div_clk#(
parameter DIV_MAX = 3
)
(
input clk,
input rst_n,
output clk_div
);
reg [7:0] cnt_pos;
reg clk_div_p;
reg [7:0] cnt_neg;
reg clk_div_n;
// 利用原始信号的上升沿产生一个三分频的信号,此时占空比不是50%
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
cnt_pos <= 8'd0;
clk_div_p <= 1'd0;
end
else if(cnt_pos == DIV_MAX/2 - 1) begin
cnt_pos <= cnt_pos + 1'b1;
clk_div_p <= 1'b0;
end
else if(cnt_pos == DIV_MAX - 1) begin
cnt_pos <= 8'd0;
clk_div_p <= 1'b1;
end
else begin
cnt_pos <= cnt_pos + 1'b1;
clk_div_p <= clk_div_p;
end
end
// 利用原始信号的下降升沿产生一个三分频的信号,此时占空比不是50%
always @(negedge clk or negedge rst_n) begin
if(!rst_n) begin
cnt_neg <= 8'd0;
clk_div_n <= 1'd0;
end
else if(cnt_neg == DIV_MAX/2 - 1) begin
cnt_neg <= cnt_neg + 1'b1;
clk_div_n <= 1'b0;
end
else if(cnt_neg == DIV_MAX - 1) begin
cnt_neg <= 8'd0;
clk_div_n <= 1'b1;
end
else begin
cnt_neg <= cnt_neg + 1'b1;
clk_div_n <= clk_div_n;
end
end
assign clk_div = clk_div_n | clk_div_p;
endmodule
仿真验证
`timescale 1ns/1ps
module div_clk_tb;
reg clk;
reg rst_n;
wire clk_div1;
wire clk_div2;
div_clk#(
.DIV_MAX(3)
)
div_clk_u1
(
.clk(clk),
.rst_n(rst_n),
.clk_div(clk_div1)
);
div_clk#(
.DIV_MAX(5)
)
div_clk_u2
(
.clk(clk),
.rst_n(rst_n),
.clk_div(clk_div2)
);
initial begin
clk = 1'b0;
rst_n = 1'b1;
#100;
rst_n = 1'b0;
#100;
rst_n = 1'b1;
#100000;
$stop;
end
always #10 clk = ~clk;
endmodule
仿真结果:
本人比较菜,如果有什么地方不对,还请各位大神指正。这个方法最后用到了组合逻辑,容易产生毛刺,如果大家有更好的方法可以前来交流。
来源:CSDN
作者:来不及了,快上车
链接:https://blog.csdn.net/qq_36662353/article/details/103678378