打印

奇数倍分频(Verilog)

[复制链接]
1844|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
AutoESL|  楼主 | 2011-7-18 21:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
奇数倍分频的方法:(5分频为例)


(n=N-1)
,图中,COUNT0采用上沿计数,COUNT1采用下沿计数,DIV0DIV1是分别是上沿触发器和下沿触发器的输出,计数为0~n/2-1)时DIV0DIV1<='1' 此处为0~1,计数为n/2~n-1)时DIV0DIV1<='0'此处为2~4DIV5_CLKDIV0DIV1的或门输出。
在使用该电路时,需要注意:
1DIV0DIV1DIV5_CLK的约束要严,越快越好。不然,无法保证1:1的占空比。
2MCLK频率要求较高,尽量不要出现窄脉冲,尤其是在高频电路里。
3COUNT1可有可无,视时钟频率高低而定。频率越高,COUNT1越需要。



奇数倍分频(5分频)的方法:

`timescale 1ns / 1ps


module div(MCLK,DIV5_CLK,DIV0,DIV1,COUNT0);


input
MCLK;
//
时钟输入



output DIV5_CLK;
//5
分频输出

output DIV0,DIV1;
//(N-1)/2
分频输出

reg DIV0;
reg DIV1;


parameter N = 5;


//
设置分频数N(奇数)

parameter M = 2;



// (N-1)/2



output [2:0]COUNT0;


//
计数器计数寄存器

reg[2:0] COUNT0;
reg[2:0] COUNT1;


always@(posedge MCLK)
//MCLK
上升沿分频


begin



if(COUNT0==2)


begin


DIV0=0;


end


else if(COUNT0==5)


begin



COUNT0=0;


DIV0=1;


end


COUNT0=COUNT0+1;


end



always@(negedge MCLK)
//MCLK
下降沿分频


begin



if(COUNT1==2)


begin


DIV1=0;


end


else if(COUNT1==5)


begin



DIV1=1;


COUNT1=0;


end


COUNT1=COUNT1+1;


end



assign DIV5_CLK=DIV0|DIV1;
//
两路(N-1)/2分频输出相或



endmodule




Post-Route Simulation仿真输出:









当要去其他奇数分频数时,可以改变NM的值

parameter N = 5;


//
设置分频数N(奇数)

parameter M = 2;



// (N-1)/2



为了方便观察,增加DIV0DIV1两个输出信号,波形仿真如下:








我在编写程序的时候,开始的时候always里写成了非阻塞赋值了,仿真结果错误,错误程序如下:



always@(posedge MCLK)
//MCLK
上升沿分频


begin



if(COUNT0==M)


begin


DIV0<=0;


end


else if(COUNT0==N)


begin



COUNT0<=0;



DIV0<=1;


end


COUNT0<=COUNT0+1;


end



仿真波形如下:








可以看到计数器COUNT0根本没有在COUNT0==5的时候归零,这是为什么呢?这是由于我没有很好理解非阻塞和阻塞赋值的区别,这里用到非阻塞,导致if里面的幅值与COUNT0<=COUNT0+1是同时进行的,也就是说当COUNT==5时,理应COUNT归零,当这时COUNT0<=COUNT0+1COUNT0==6if也就无效了。所以要注意非阻塞与阻塞赋值的差别:(可参考我转载的另两篇博文)

Verilog 非阻塞赋值的仿真/综合问题(一)
Verilog 非阻塞赋值的仿真/综合问题(二)


也可以改成



always@(posedge MCLK)

begin



if(COUNT0==1)


begin



DIV0<=0;


COUNT0<=COUNT0+1;


end


else if(COUNT0==4)


begin



COUNT0<=0;


DIV0<=1;


end



else COUNT0<=COUNT0+1;



end



always@(negedge MCLK)

begin



if(COUNT1==1)


begin



DIV1<=0;


COUNT1<=COUNT1+1;


end


else if(COUNT1==4)


begin



COUNT1<=0;


DIV1<=1;


end



else COUNT1<=COUNT1+1;



end



assign DIV5_CLK=DIV0|DIV1;


Post-Route Simulation仿真输出:









通常的计数器都是用非阻塞赋值的,基本上的代码如上,if……else……


本文工程文件:


参考资料:

1)
N倍奇数分频器.(Verilog) -- 小時不識月

http://blog.**/2006tx_yafeng/146438/message.aspx
2(原創) 如何設計除頻器? (SOC) (Verilog) (MegaCore) - OO无双博客园

http://www.cnblogs.com/oomusou/archive/2008/07/31/verilog_clock_divider.html
3)
奇数分频(5分频器为例)--shuhuai
http://old.blog.edu.cn/user2/52459/archives/2008/2166031.shtml
4)
任意数分频(包括奇偶数和小数)的各种设计方法[综合电子]_老古开发网**

http://www.laogu.com/wz_1260.htm

相关帖子

沙发
dan_xb| | 2011-7-19 11:26 | 只看该作者
呵呵,经典考题,要找工作的同学仔细看看。
做实际开发的就不用了,还是用PLL/DCM比较靠谱

使用特权

评论回复
板凳
hihu| | 2011-7-19 14:13 | 只看该作者
好哟感触呀

使用特权

评论回复
地板
hihu| | 2011-7-19 14:13 | 只看该作者
谢谢版主分享

使用特权

评论回复
5
GoldSunMonkey| | 2011-7-19 15:40 | 只看该作者
还是用DCM吧:)哈哈

使用特权

评论回复
6
AutoESL|  楼主 | 2011-7-19 16:32 | 只看该作者
实际设计中很少有人这么做吧?

使用特权

评论回复
7
GoldSunMonkey| | 2011-7-19 20:55 | 只看该作者
6# AutoESL
不会有人这么做的,兄弟:)

使用特权

评论回复
8
rulu| | 2011-7-20 20:59 | 只看该作者
呵呵

使用特权

评论回复
9
hjjnet| | 2011-7-20 22:26 | 只看该作者
的确是经典的HW考试题,呵呵

使用特权

评论回复
10
lelee007| | 2011-7-21 00:24 | 只看该作者
奇数分频俺有RTL实现的电路,用移位寄存器来实现

https://bbs.21ic.com/icview-231413-1-1.html

使用特权

评论回复
11
xwj| | 2011-7-21 08:26 | 只看该作者
路过,顺便说下LZ的几个问题:
1、转帖请注明出处,这是网络的基本礼节,也是对自己和作者的尊重;
2、现在的网站都有防盗链机制,转帖别的网站的图片应该上传到发帖论坛的服务器,否则别人看不到;
3、不管是复制粘贴的贴还是自己原创的帖,都应该经常点开看看,看下别人的反应。发完贴后最好刷新看看有没有显示、排版问题,有没有错别字。
4、技术上,你贴的方法就是对上升沿、下降沿分别计数后合并,这个对输入信号的占空比是有要求的,输入信号必须要接近50%的占空比  输出才能得到接近50%的占空比。
   其实,直接对输入信号的上升沿、下降沿同时计数,然后分频即可。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:天使宝贝 博客IT人生 From C/C++/SystemC to Xilinx FPGA

0

主题

2517

帖子

3

粉丝