基于Verilog的偶数、奇数、半整数分频以及任意分频器设计
在FPGA的学习过程中,最简单最基本的实验应该就是分频器了。由于FPGA的晶振频率都是固定值,只能产生固定频率的时序信号,但是实际工程中我们需要各种各样不同频率的信号,这时候就需要对晶振产生的频率进行分频。比如如果FPGA芯片晶振的频率为50MHz,而我们希望得到1MHz的方波信号,那么就需要对晶振产生的信号进行50分频。
分频器的设计虽然是FPGA学习过程中最简单的实验,但是真正想要把分频器的来龙去脉弄清楚,还是需要花费一番功夫的。下面先介绍一下最常见的几种分频器写法:
1.偶数分频器
相信大多数朋友在学习FPGA过程中接触到的第一个实验应该就是偶数分频器了,偶数分频器的设计较为简单,用一个简单的计数器就可以实现。比如要实现一个N分频(N为偶数)的分频器,可以先写一个计数器,当计数到(N/2-1)时,让输出状态翻转,并将计数器清零,这样输出的信号就是输入时钟的N分频了。具体代码如下:
偶数分频器示例,20分频即N=20,占空比50%
module clk_div(clk_out, clk, rst_n); input clk, rst_n;
output clk_out; reg clk_out;
reg [4:0] cnt; always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
cnt <= 5'b0;
clk_out <= 1'b0;
end
else if(cnt == 4'd9)
begin
cnt <= 5'b0;
clk_out <= ~clk_out;
end
else cnt <= cnt + 1'b1; endmodule
2.奇数分频器
奇数分频器的设计比偶数分频器复杂一些,特别是占空比为50%的奇数分频器。如果对占空比没有明确的要求,则可以直接对上升沿计数,计数到(N-1)/2 时让输出翻转,计数到(N-1)时让输出状态再次翻转,并将计数器清零,这样就可以得到一个占空比为2:3的N分频(N为奇数)的分频器。而如果要实现50%的占空比,可以通过“错位相或”的方法实现。具体方法是用刚才的方法先通过对上升沿计数产生一个占空比为不是50%的N分频器,再用同样的方法对下降沿计数产生一个占空比也不是50%的N分频器,最后将这两个分频器的输出进行“或”运算,就可以得到占空比为50%的奇数N分频器,具体实现代码如下:
奇数分频器示例,5分频,占空比50%
module div_odd
(
input clk,
input rst_n,
output clk_out
); //----------count the posedge---------------------
reg [2:0] cnt_p;
reg clk_p; always @ (posedge clk or negedge rst_n)
if(!rst_n)
cnt_p <= 3'd0;
else if(cnt_p == 3'd4)
cnt_p <= 3'd0;
else
cnt_p <= cnt_p + 1'b1; always @ (posedge clk or negedge rst_n)
if(!rst_n)
clk_p <= 1'b0;
else if((cnt_p == 3'd2) || (cnt_p == 3'd4))
clk_p <= ~ clk_p;
//--------------------------------------------- //----------count the negedge------------------
reg [2:0] cnt_n;
reg clk_n; always @ (negedge clk or negedge rst_n)
if(!rst_n)
cnt_n <= 3'd0;
else if(cnt_n == 3'd4)
cnt_n <= 3'd0;
else
cnt_n <= cnt_n + 1'b1; always @ (negedge clk or negedge rst_n)
if(!rst_n)
clk_n <= 1'b0;
else if((cnt_n == 3'd2) || (cnt_n == 3'd4))
clk_n <= ~clk_n;
//---------------------------------------------- assign clk_out = clk_p | clk_n; endmodule
here is the old version :
module div_odd(clk_out, clk, rst_n); input clk, rst_n;
oput clk_out; reg clk_p, clk_n;
reg [4:0] cnt1, cnt2; //注意根据实际需要调整位宽 parameter N = 5; //此处N可以设为任意奇数 //用上升沿产生非50%占空比的分频信号clk_p
always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
cnt1 <= 0;
clk_p <= 0;
end
else if(cnt1 == 5'b10) //cnt_p == (N-1)/2,翻转
begin
cnt1 <= cnt1 + 1'b1;
clk_p <= ~clk_p;
end
else if(cnt1 == 5'b100) //cnt_p == N-1,翻转
begin
cnt1 <= 1'b0;
clk_p <= ~clk_p;
end
else cnt1 <= cnt1 +1'b1; //用下降沿产生非50%占空比的分频信号clk_n
always @(negedge clk or negedge rst_n)
if(!rst_n)
begin
cnt2 <= 0;
clk_n <= 0;
end
else if(cnt2 == 5'b10) //cnt_n == (N-1)/2,翻转
begin
cnt2 <= cnt2 + 1'b1;
clk_n <= ~clk_n;
end
else if(cnt2 == 5'b100) //cnt_n == N-1,翻转
begin
cnt2 <= 1'b0;
clk_n <= ~clk_n;
end
else cnt2 <= cnt2 +1'b1; //相与运算,得到50%占空比的分频信号
assign clk_out = clk_p | clk_n; endmodule
3.半分频器(N+0.5分频)
在实际工程中,我们还经常会遇到半分频器。比如要得到2MHz的时钟信号,而系统晶振频率为25MHz,这时候就需要对系统时钟作12.5分频。那么这种半分频器又该如何实现呢?最直接的办法当然还是用计数器了,由于半整数分频无法实现50%的占空比(因为50%占空比就要求一个周期内高低电平都是6.25个系统时钟周期,这个0.25是不可能实现的),我们只能让占空比尽可能接近50%。以12.5分频为例,可以对系统时钟计数,在前6.5个周期输出低电平,后6个周期输出高电平,依次循环,就可以实现12.5分频,占空比为(6.5/12.5),接近50%。在计数时涉及到0.5个周期,因此对上升沿和下降沿都要计数。具体代码如下:
半分频器,以12.5分频为例,占空比(6.5/12.5)
module clk_half(clk_out, clk1, clk, rst_n); input clk,rst_n;
output clk_out,clk1; parameter N = 13; //以12.5分频为例,N=13 wire clk1;
reg clk_out;
reg[4:0] cnt;
reg flag = 1'b0; //系统时钟clk计数器
always @(negedge clk or negedge rst_n)
if(!rst_n) flag <= 1'b0;
else if(cnt == 5'd6) flag <= ~flag; //在第五个时钟结束后立即将 clk1 状态翻转
assign clk1 = (flag)? ~clk:clk; //时钟 clk1 计数器,模为N
always @(posedge clk1 or negedge rst_n)
if(!rst_n) cnt <= 5'b0;
else if(cnt == 5'd12) cnt <= 5'b0;
else cnt <= cnt + 1'b1; //前6.5个周期为低电平,后6个周期为高电平,
//即为12.5分频
always @(posedge clk1 or negedge rst_n)
if(!rst_n) clk_out <= 1'b0;
else if(cnt == 5'd0) clk_out <= 1'b0;
else if(cnt == 5'd7) clk_out <= 1'b1;
else clk_out <= clk_out; endmodule
网上还有许多其他大神写的半分频程序,比如:
http://www.cnblogs.com/yuzeren48/p/3965003.html
4.任意分频——基于相位累加原理
相位累加器主要用在直接数字频率合成器(DDS)中,其中的几个主要的参数为输入频率fc,输出频率fo,计数器位宽N,频率控制字K(即计数器递增步长)。它们之间的关系为:fo=(fc*K)/(2^N)。假设输入频率fc为50MHz,计数器位宽N为32,要产生1kHz的信号,则K=(fo*2^N)/fc=85.9*fo=85900。当计数值小于等于((2^N)/2)时,输出低电平,当计数值大于((2^N)/2)时,输出高电平,依次循环,就可以产生占空比为50%的1kHz信号了。据此可以设计如下程序:
任意分频示例,输出1kHz,占空比50%
/***************************************
晶振频率 fc = 50MHz
输出频率 fo = 1kHz(根据需要可以设为任意值)
控制参数 K = (fo*2^N)/fc
参数 N = 2^32,(32为计数器的位宽) ****************************************/
module div_free(clk_out, clk, rst_n); input clk, rst_n;
output clk_out; reg clk_out;
reg [31:0] cnt; always @(posedge clk or negedge rst_n)
if(!rst_n)
cnt <= 0;
else cnt <= cnt + 32'd85900; //计数器步长 K always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
clk_out <= 1'b0;
end
else if(cnt < 32'h7FFF_FFFF)
clk_out <= 1'b0;
else clk_out <= 1'b1; endmodule
基于Verilog的偶数、奇数、半整数分频以及任意分频器设计的更多相关文章
- FPGA等占空比奇偶分频和半整数分频
1. 偶数分频比较简单,如果分频系数是N(如果N是偶数,那么N/2是整数),那么在输入时钟的每隔N/2个周期时(计数器从0到N/2-1),改变输出时钟的电平即可得到50%固定占空比的时钟.需要的代码如 ...
- 基于verilog的分频器设计(半整数分频,小数分频:下)
第二种方法:对进行奇数倍n分频时钟,首先进行n/2分频(带小数,即等于(n-1)/2+0.5),然后再进行二分频得到.得到占空比为50%的奇数倍分频.下面讲讲进行小数分频的设计方法. 小数分频:首先讲 ...
- 基于verilog的分频器设计(奇偶分频原理及其电路实现:上)
在一个数字系统中往往需要多种频率的时钟脉冲作为驱动源,这样就需要对FPGA的系统时钟(频率太高)进行分频.分频器主要分为奇数分频,偶数分频,半整数分频和小数分频,在对时钟要求不是很严格的FPGA系统中 ...
- 基于Verilog的奇数偶数小数分频器设计
今天呢,由泡泡鱼工作室发布的微信公共号“硬件为王”(微信号:king_hardware)正式上线啦,关注有惊喜哦.在这个普天同庆的美好日子里,小编脑洞大开,决定写一首诗赞美一下我们背后伟大的团队,虽然 ...
- 基于Verilog HDL整数乘法器设计与仿真验证
基于Verilog HDL整数乘法器设计与仿真验证 1.预备知识 整数分为短整数,中整数,长整数,本文只涉及到短整数.短整数:占用一个字节空间,8位,其中最高位为符号位(最高位为1表示为负数,最高位为 ...
- 基于Verilog HDL 各种实验
菜鸟做的的小实验链接汇总: 1.基于Verilog HDL 的数字时钟设计 2.乘法器 3.触发器(基本的SR触发器.同步触发器.D触发器) 4.基于Verilog HDL的ADC ...
- 基于Verilog HDL 的数字电压表设计
本次实验是在“基于Verilog HDL的ADC0809CCN数据采样”实验上进一步改进,利用ADC0809采集到的8位数据,进行BCD编码,以供查表方式相加进行显示,本次实验用三位数码管. ADC0 ...
- 基于Verilog HDL 的数字时钟设计
基于Verilog HDL的数字时钟设计 一.实验内容: 利用FPGA实现数字时钟设计,附带秒表功能及时间设置功能.时间设置由开关S1和S2控制,分别是增和减.开关S3是模式选择:0是正常时钟 ...
- 基于Verilog的带FIFO输出缓冲的串口接收接口封装
一.模块框图及基本思路 rx_module:串口接收的核心模块,详细介绍请见“基于Verilog的串口接收实验” rx2fifo_module:rx_module与rx_fifo之间的控制模块,其功能 ...
随机推荐
- 第二十六天- C/S架构 通信流程 socket
1.C/S架构 C/S架构:Client与Server ,中文意思:客户端与服务器端架构,这种架构也是从用户层面(也可是物理层面)来划分的.这里客户端一般指需先安装再执行的应用程序,对操作系统依赖性较 ...
- 网件路由器wps无法设置
问题:网件路由器WPS设置项全为灰色,无没设置 原因:因为设置WIFI时,将ssid广播隐藏了,导致WPS功能失效,所以WPS设置项为灰色.要想设置WPS,将SSID广播恢复即可
- ArcGIS for JavaScript继承TiledMapServiceLayer来实现“动态切图”
这种方式可以提高出图速度于效果,算法见http://blog.newnaw.com/?p=633,我用ArcGIS for JavaScript API来实现.具体代码为: function init ...
- Dialog中更新Activity的数据显示
假设有一个activity,activity中有一个Button和一个TextView,点击按钮,弹出Dialog,对话框中有一个ListView,选中ListView中的某一项,关闭对话框,更新ac ...
- PSP软件开发过程
1. 引言 这是为了编写psp系统的软件需求分析,主要按照提供的相关需求和功能. 1.1 项目风险 风险承担者包括: 任务提出者:承担任务不能完全按照想象的做出,投入等: 软件开发者:可能不能按时交付 ...
- leetCode题解之求二叉树最大深度
1.题目描述 Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along t ...
- armel和armhf区别
出于低功耗.封装限制等种种原因,之前的一些ARM架构处理器因为内部资源宝贵,加入浮点运算单元是十分奢侈的,因为需要额外的软件实现.之前的ARM处理器架构是什么样的?(http://www.cnblog ...
- JS弹出div简单样式
<div id="dialog" style="display:none;z-index:9999;position: absolute;border:1px so ...
- mysql-5.7 持久化统计信息详解
一.持久化统计信息的意义: 统计信息用于指导mysql生成执行计划,执行计划的准确与否直接影响到SQL的执行效率:如果mysql一重启 之前的统计信息就没有了,那么当SQL语句来临时,那么mysql就 ...
- Elasticsearch安装记录
一 安装部分 1.新建用户 elasticsearch不能使用root身份执行 adduser esuser passwd esuser 2.赋予权限 切换到root chown -R esuser ...