一、概述
1、我们在日常进行FPGA的开发之中,会根据需求的不同设计不同的功能实现,这就需要不同的分频信号,而分频的思想在我们的日常开发中显得尤为重要。用通俗易懂的说法表示分频就是对计数器进行一个进一步设计从而达到不同的分频器的思想。在这篇文章中我们实现的是偶数分频器,在下一篇文中我们会对于奇数分频器进行一个讲解。
2、工作原理
偶数分频器的实现简单,用计数器在上升沿或者下降沿计数,当计数器的值等于分频系数的一半或等于分频系数时,信号翻转。 偶数分频器分频原理如下图所示:
上图的的分频系数是4,就是4分频。 电路原理是用一个上升沿计数的计数器,每次计数到2时输出信号clkout翻转一次,每次计数到4时clkout再翻转一次,一直周期重复下去。 其他的偶数分频器原理也是一样。 从波形中可以看出cnt
从00->01->10->11->00......一直循环记数,如果你够仔细,就可以看出cnt的最高位其实也是一个4分频的时钟。
二、测试文件的编写
新建divider.v文件(这里的divider就是分频器的英文,见文思意),如下:
module divider(
input clk,
input rst_n,
output reg clk_out
);
//偶数分频
parameter TIME = 4;//分频系数
reg [31:0] cnt;//定义计数器
//分频计数器的实现
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt<=0;
else if(cnt==(TIME-1))
cnt<=0;
else
cnt<=cnt+1;
end
//时钟频率占空比的设计
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
clk_out<=0;
else if(cnt<=1)
clk_out<=0;
else
clk_out<=1;
end
endmodule
三、仿真文件的编写
新建一个divider_tb.v文件,如下:
//定义时间尺度
`timescale 1ns/1ns
module divider_tb ;
//输入信号定义
reg clk;
reg rst_n;
wire clk_out;
//模块例化
divider div (
/*input */ .clk (clk ),
/*input */ .rst_n (rst_n ),
/*output*/ .clk_out (clk_out )
);
//激励信号产生
parameter CLK_CYC = 20;
//时钟
initial clk=1;
always #(CLK_CYC/2)clk=~clk;
//复位
initial begin
rst_n= 1'b0;
#(CLK_CYC*3);
#5;//复位结束避开时钟上升沿
rst_n= 1'b1;
end
endmodule
在仿真文件中就是对于模块进行一个简单的实例化,其次就是对于时钟信号和复位信号进行一个简单的设计就是最终的仿真文件。
四、仿真波形图
在仿真波形图中我们可以看到分频之后输出的计数器就是我们代码中所设置的4分频,但存在着一个奇怪的问题,我们在代码中设置的是0和1为低电平,2和3为高电平,然而在波形图中是1和2为低电平,3和0是高电平。其实这里的现象是正确的实际波形输出和代码设计的有相位偏差时因为时序电路慢一拍输出的特性,也就是慢一个周期进行输出。