N位分频器的实现
一、 目的
使用verilog实现n位的分频器,可以是偶数,也可以是奇数
二、 原理
FPGA中n位分频器的工作原理可以简要概括为:
- 分频器的作用是将输入时钟频率分频,输出低于输入时钟频率的时钟信号。
- n位分频器可以将输入时钟频率分频2^n倍。
- n位分频器主要由n个触发器级联组成。
- 第一个触发器时钟输入接入输入时钟,数据端接D=0。
- 后级触发器的时钟依次接前一级触发器的反相Q信号。
- 通过这种级联,将输入时钟周期分成2^n个阶段。
7.最后一个触发器Q输出即为分频之后的时钟信号。
- 更改计数器位数n,可以灵活改变分频比例。
- 分频器广泛应用于计数器、时序逻辑的时钟分频等场景。
所以n位分频器通过n个触发器的级联,利用反相Q输出产生2^n分频效果,是FPGA时钟管理中的重要组成部分。
三、 系统架构设计
工程模块划分及说明
四、 代码实现
1. 模块端口信号列表
module divider #(parameter N = 9)(
input wire clk,
input wire rst_n,
output wire out
);
reg[N:0] cnt1;//上升沿计数器
reg[N:0] cnt2;//下降沿计数器
wire add_cnt1;//上升沿开始条件
wire end_cnt1;//上升沿结束条件
wire add_cnt2;//下降沿开始条件
wire end_cnt2;//下降沿结束条件
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
cnt1<='d0;
end
else if(add_cnt1)begin
if(end_cnt1)begin
cnt1 <='d0;
end
else begin
cnt1 <= cnt1 + 1'b1;
end
end
else begin
cnt1<=cnt1;
end
end
always @(negedge clk or negedge rst_n) begin
if(~rst_n) begin
cnt2<='d0;
end
else if(add_cnt2)begin
if(end_cnt2)begin
cnt2 <='d0;
end
else begin
cnt2 <= cnt2 + 1'b1;
end
end
else begin
cnt2<=cnt2;
end
end
assign add_cnt1 = 1'b1;
assign end_cnt1 = add_cnt1 && cnt1 == N;
assign add_cnt2 = 1'b1;
assign end_cnt2 = add_cnt2 && cnt2 == N;
assign out = (N%2==0)?((cnt2<=(N>>1))&&(cnt1<=(N>>1))?1'b0:1'b1):((cnt1<=(N>>1)?1'b0:1'b1);
endmodule
测试文件:
module driver_n_tb();
reg clk;
reg rst_n;
wire out;
parameter SYS_CLK = 20;
parameter N = 8;
always #(SYS_CLK/2) clk = ~clk;
initial begin
clk=1'b0;
rst_n=1'b0;
#(2*SYS_CLK+10);
rst_n=1'b1;
#(100*SYS_CLK);
$stop;
end
divider #(.N(N)) inst_divider_n (
.clk(clk),
.rst_n(rst_n),
.out(out));
endmodule
五. 时序及仿真结果
偶数:
奇数:
五、 仿真波形图
偶数:
奇数: