搜索
bottom↓
回复: 21

如何实现这样的占空比?

[复制链接]

出0入0汤圆

发表于 2011-6-16 18:06:53 | 显示全部楼层 |阅读模式
我的FPGA时钟是50MHZ,想得到1MHZ,占空比1:4的时钟,我写的代码如下:
module dps(clk,clkout);
input clk;
output clkout;
reg [8:0] cnt;

always @(posedge clk) //50分频
if(cnt==49)
cnt<=0;
else
cnt<=cnt+1;

always @(posedge clk) //占空比1:4
if(cnt<=12)
clkout<=0;
esle
clkout<=1;

endmodule

我的想法是先50分频,然后调整占空比,50*1/4=12.5 于是当cnt计数在12以内时,给予clkout低电平,其他时间给予高电平,但是由于12.5是个小数,而FPGA不支持小数处理。
后来对这个程序做了个时序仿真,得到的是1MHZ的时钟,但是占空比为6/25=1:4.16666...
问哈大家,如何得到1:4的占空比???谢谢了

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2011-6-16 18:14:59 | 显示全部楼层
不懂的只能帮顶,为什么你不能换个数分频呢?一定要1M吗,稍微偏差点行不行。。。或者最简单的,频率能否提高到100M

出0入0汤圆

发表于 2011-6-16 18:16:24 | 显示全部楼层
啥叫占空比1:4 好好想想吧。。。

出0入0汤圆

发表于 2011-6-16 19:34:29 | 显示全部楼层
module dps(rst,clk,clkout);
input clk;
input rst;

output clkout;

reg [8:0] cnt;

always @(negedge rst or posedge clk)  begin //25分频
    if(!rst = 1)
        cnt [8:0] <= 0;
    else if(cnt==24)
        cnt<=0;
    else
        cnt<=cnt+1;
end

always @(posedge clk) begin //占空比1:4
    if(!rst=1)
        clkout <= 0;
    else if(cnt<=25)
        clkout<=1;
    else
        clkout<=0;
end

endmodule

出0入0汤圆

 楼主| 发表于 2011-6-17 17:56:23 | 显示全部楼层
谢谢大家 问题已经解决,贴出代码如下:

module div5(clk,clkout1,clkout2,clkout);
input clk;
output clkout1;
output clkout2;
output clkout;  //5分频得到的时钟

reg [5:0] cnt;
reg rg_clkout1,rg_clkout2;

always @(posedge clk)
if(cnt==4)
cnt<=0;
else
cnt<=cnt+1;

always @(posedge clk)
if(cnt<=2)
rg_clkout1<=1;
else
rg_clkout1<=0;

always @(negedge clk)
if(cnt<=2)
rg_clkout2<=1;
else
rg_clkout2<=0;

assign clkout=rg_clkout1&&rg_clkout2;  //两时钟做与运算得到clkout
assign clkout1=rg_clkout1;
assign clkout2=rg_clkout2;

endmodule

出0入0汤圆

发表于 2011-6-18 14:59:42 | 显示全部楼层
你写的代码用到两种CLK边缘,在FPGA设计中不提倡,在设计复杂系统时候很容易出问题,主要是编译器支持不好。

另外输出的产生使用应该用主CLK同步至少一拍。

作为另一个简洁的实现方式可以用移位寄存器。
module func(input clki,rstn,output reg clko);
reg [3:0] cntr;
reg [4:0] sftr;
wrie cntr_over =(cntr==9);

always @ (posedge clki )
cntr<=(cntr_over)?0:(cntr+1);

always @ (posedge clki)
if (~rstn) sftr<=5'b00001 ; //一定要有rstn信号,否则5位都是0
if (cntr_over)
sftr[4:0]<={sftr[3:0],sftr[4]}; //循环左移一位。//右移也可以 只要是循环就行

always @ (posedge clki)
clko<=sftr[0] ;// 取sftr的任何一位都可以

endmodule


以上代码第一个always 实现分频,将50M 的输入始终产生一个5M的脉冲。用来做控制触发信号cntr_over
第2个always 是移位置寄存器,5位其中4个0一个1,以5M的速度移5位,也就是说以1M速度循环,这样就得到了占空比为1:4的1M信号。


FPGA逻辑设计里面有些比较专门的思考方式,和串行代码不一样。用数字电路方式考虑,尽量不要停留在纸面的代码层面。

出0入0汤圆

发表于 2011-6-18 15:20:22 | 显示全部楼层
回复【楼主位】xuzhengan123  

if(cnt<=12)
clkout<=0;
esle
clkout<=1;

......
-----------------------------------------------------------------------

为什么要用cnt<=12, 而不用cnt==12

<= 比 ==更占用资源

出0入0汤圆

发表于 2011-6-19 13:35:50 | 显示全部楼层
回复【5楼】mcupro  李伟
-----------------------------------------------------------------------

【5位其中4个0一个1】
这个效果和第一个代码是一样的啊,楼主想要的波形应该是有四位里面有一个1三个0


(原文件名:QQ截图未命名.png)

出0入0汤圆

发表于 2011-6-19 15:05:09 | 显示全部楼层
回复【4楼】xuzhengan123  
-----------------------------------------------------------------------

这个仿真出来clkout既不是1M占空比也不是25%,能解释一下它的原理吗?

(原文件名:QQ截图未命名.png)

出0入0汤圆

发表于 2011-6-19 18:41:51 | 显示全部楼层
mark!

出0入0汤圆

发表于 2011-6-19 18:49:26 | 显示全部楼层
mark

出0入0汤圆

 楼主| 发表于 2011-6-19 19:04:37 | 显示全部楼层
回复【4楼】xuzhengan123
-----------------------------------------------------------------------

哥们,你的代码是不是有问题?我用你的做时序仿真,占空比是:9/49

(原文件名:func.jpg)

出0入0汤圆

 楼主| 发表于 2011-6-19 19:06:19 | 显示全部楼层
回复【5楼】mcupro 李伟
-----------------------------------------------------------------------

我的意思是当计数器记到12(包括12)以内时,clkout为0,当大于12时,clkout为1

出0入0汤圆

 楼主| 发表于 2011-6-19 19:07:31 | 显示全部楼层
回复【7楼】night_0309
-----------------------------------------------------------------------

不好意思哈,我贴错了程序,问题其实还没解决,自己还在想怎么写

出0入0汤圆

 楼主| 发表于 2011-6-19 19:14:40 | 显示全部楼层
回复【2楼】cwfboy
-----------------------------------------------------------------------

哥们,你的代码有问题哦

出0入0汤圆

 楼主| 发表于 2011-6-19 19:21:38 | 显示全部楼层
回复【4楼】xuzhengan123
-----------------------------------------------------------------------

不好意思哈,本人看错了,代码没有任何问题,谢谢了!!

出0入0汤圆

发表于 2011-6-19 19:34:28 | 显示全部楼层
利用上升沿 和 下降沿 是否能解决问题

出0入0汤圆

发表于 2011-6-19 20:18:15 | 显示全部楼层
回复【16楼】avr-qq  高级工程叁
-----------------------------------------------------------------------

利用posedge和negedge就等于有每秒100M次的触发了啊,结合最早的那个代码应该就可以解决啦

出0入0汤圆

发表于 2011-6-19 20:21:15 | 显示全部楼层
回复【11楼】xuzhengan123  
-----------------------------------------------------------------------

咦~你仿真的怎么和我不一样结果,我仿的是4楼的代码,你呢?引用图片【8楼】night_0309  
-----------------------------------------------------------------------

(原文件名:QQ截图未命名.png)

出0入0汤圆

 楼主| 发表于 2011-6-19 21:42:36 | 显示全部楼层
回复【17楼】night_0309
-----------------------------------------------------------------------

四楼的代码有问题吧,正确的代码如下,你可以试试:
//实现功能:对clk进行5分频,同时占空比为1:4
module func(clki,rstn,clko,cntr_over,sftr);
input clki;
input rstn;
output reg clko;
output cntr_over;
output sftr;

reg [3:0] cntr;
reg [3:0] sftr;
wire cntr_over =(cntr==9);  

always @ (posedge clki )
cntr<=(cntr_over)?0:(cntr+1);

always @ (posedge clki)
if (~rstn) sftr<=4'b0001 ; //一定要有rstn信号,否则5位都是0
else if (cntr_over)
sftr[3:0]<={sftr[2:0],sftr[3]}; //循环左移一位。//右移也可以 只要是循环就行  

always @ (posedge clki)
clko<=sftr[0] ;// 取sftr的任何一位都可以  

endmodule

出0入0汤圆

发表于 2011-6-19 21:52:05 | 显示全部楼层
回复【19楼】xuzhengan123  
-----------------------------------------------------------------------

这也太简单了吧,这个占空比是1:5,20%不是1:4,modelsim仿真波形在7楼
难就难在他要求占空比25%
看看占空比的定义吧


(原文件名:9f1011b3e418a5b4d9335af5.jpg)

方波的占空比是50%也就是1:2,不是1:!

出0入0汤圆

 楼主| 发表于 2011-6-19 22:36:09 | 显示全部楼层
回复【19楼】xuzhengan123
-----------------------------------------------------------------------

哥们,我说的1:4不就是指25%吗?此1:4非高电平和低电平的时间比,而是高电平和周期比,我没有说错啊
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 13:23

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表