完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
|
clk_50M 为50MHz
问题如下:我的目标是count7计数到600031时,让clear置1,然后马上让count6为33,为什么count6把33计数了两次 见下图的仿真波形! 仿真波形最下面两路脉冲分别为count6、count7 initial begin count6=0;end //-----------------------------SP频率1MHz 高电平100ns 低电平 900ns ------------------------------------- output reg [19:0] count7; reg clear; always @(negedge clk_50M or negedge rst_n) begin if(!rst_n) begin count7 <= 1'b0; clear <= 1'b0; end else if(count7==20'd600031) begin clear <= 1'b1; count7 <= 1'b0; end else begin count7 <= count7 + 1'b1; clear <= 1'b0; end end output reg [9:0] count6; always @(negedge clk_50M or posedge clear) begin if(clear) //clear为1时让count6为33 begin count6 <= 33; end else if(count6>=0 && count6<33) //sp保持660ns的低电平 begin SP <= 1'b0; count6 <= count6 + 1'b1; end else if (count6>=33 && count6<38)//sp保持5个时钟(100ns)的高电平 begin SP <= 1'b1; count6 <= count6 + 1'b1; end else if(count6>=38 && count6<83) begin SP <= 1'b0; count6 <= count6 + 1'b1; end else if (count6>=83 && count6<88) begin SP <= 1'b1; count6 <= count6 + 1'b1; end else if (count6>=88 && count6<283) begin SP <= 1'b0; count6 <= count6 + 1'b1; end else if(count6>=283 && count6<288) begin SP <= 1'b1; count6 <= count6 + 1'b1; end else if(count6>=288 && count6<332) begin SP <= 1'b0; count6 <= count6 + 1'b1; end else if (count6 == 332) count6 <= 283; else count6 <= count6 + 1'b1; end
|
|
相关推荐
19个回答
|
|
|
本帖最后由 Gavin_OJL 于 2014-12-18 21:10 编辑
貌似 if(clear) //clear为1时让count6为33 有问题改为 if(count7==20'd600031) 或者 if(count7==20'd600030) 试试
最佳答案
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
还是不行哇 仿真波形如下,在count7计算到600031时,count6为283,结果count6为284时,后面才变为0 |
|
|
|
|
|
提前准备clear信号,并且去掉posedge clear!不过count6没初始复位!
else if(count7==20'd600030) clear <= 1'b1; else if(count7==20'd600031) count7 <= 1'b0; |
|
|
|
|
cutfor 发表于 2014-12-18 20:57 我来看看,先谢谢了~ |
|
|
|
|
|
|
|
|
|
|
cutfor 发表于 2014-12-18 20:57 貌似还是不对 按照你改的程序如下: always @(negedge clk_50M or negedge rst_n) begin if(!rst_n) begin count7 <= 1'b0; clear <= 1'b0; end else if(count7==20'd600030) begin clear <= 1'b1; //count7 <= 1'b0; end else if(count7==20'd600031) count7 <= 1'b0; else begin count7 <= count7 + 1'b1; clear <= 1'b0; end end always @(negedge clk_50M) begin //if(!rst_n) //count6<=1'b0; if(clear) count6 <= 33; 然后进行仿真;结果如下两个图所示 存在一下问题: count7计数到600030时 后面就没有计数了 count6计数到33时也没有继续计数了 |
|
|
|
|
cutfor 发表于 2014-12-18 20:57 错误的一个原因是clear在为1后,一直保持1;还在等待解决方法~ |
|
|
|
|
cutfor 发表于 2014-12-18 20:57 clear一直保持1的解放方法是: else if(count7==20'd600030) begin clear <= 1'b1; count7 <= count7 +1; //count7 <= 1'b0; end else if(count7==20'd600031) begin count7 <= 1'b0; //clear <= 0; end 不过仿真出来,出现了以前一样的错误,那就是count6计数33计了两次! 见仿真图:
|
|
|
|
|
|
count6把33计数两次的问题确实是解决了,不过如何让count6为33时立即执行else if(count6>=33 && count6<38) begin SP <= 1'b1; count6 <= count6 + 1'b1; end 还有待解决!除此之外,为何count6=38时,SP也是高电平 仿真波形如下图所示!
|
|
|
|
|
|
我给你解释下,为你第一个例子里,count6 会计2次33。
1、看你第一个count7和clear的always敏感列表,时钟采样是negedge,那么在clk_50m的下降沿,如果count7等于600031,将看到clear为1,我们看到确实如此,clear为1,持续一个时钟周期,而且从该下降沿持续到下一个下降沿。 2、看count6的always敏感列表,时钟采样是negedge,而一个异步信号clear却是posedge,那么,神奇的一幕就出现了,上面我们说当count7为600031的时候,clear从0变1了,此时clear就是一个posedge,触发了count6的always,那么进入always判断后执行第一条if语句,直接把count6变成33了(看清楚,count66第一次变33是在clear的上升沿,不是clk的下降沿哦!),随后,clk_50M的下降沿来了,此时也进入always,此时clear还是为1(根据count7的negedge变化,clear会在当前clk_50m时钟后,才变0),那么还是会进入第一条if,所以count66又是33了,这样,你就看到count6维持33的时间,是2个clk_50m周期。 其实是一个bug导致的巧合而已,不是clk_50M导致了count6维持了2个时钟周期,再说一遍,第一次count6变成33,是在clear为1的时候,异步触发always,导致第二次是clk_50M下降沿时候触发always,判断clear依然为1,所以count6依然保持33。 评分
|
|||
|
|
|||
|
给你的建议,如果把always当做时序电路用,请别用自己生成的信号放入always列表,最好只放统一的clk和rst信号,免得出现这些尴尬的bug。
其它信号,比如clear,当做使能信号,比如你在第一个列子里,把count7 == 600030时,让clear =1,这样clear就会在count7 == 600031时为1,然后在count6的always里,把clear作为使能,当clear为1时,count6 = 33,这样就不会出现“两次33”了。。。 |
|
|
|
|
|
always (negedge clk_50m or negedge rst_n)
begin ...... else if(count7 == 600030) clear = 1; else clear = 0; ...... end always (negedge clk_50m or negedge rst_n) begin ...... else if(clear == 1) count6 = 33; ...... end |
|
|
|
|
|
确实count6计数器为什么计数2次33不怎么明白,自己感觉对基本的语法只是大致了解了,对一些细枝末节的感觉就是不清不楚,还需要多学习学习,认真琢磨一下;先按照你说的来调试一下看看!谢谢你的建议哈! |
|
|
|
|
|
只是给了个大概意思。。。
呃,只要把你的改后的改一下,因为那样clear持续了两个周期,我们只要一个周期就够了, 就是在count7 == 60031那个周期。 而且做同步设计要每一级流水线都是对前个数据做处理,而不是一个数据变,就全部变,那是异步了。 所以SP是总会比count6慢一个时钟周期的。 你看看这样行不行! else if(count7==20'd600030) begin clear <= 1'b1; count7 <= count7 +1; end else if(count7==20'd600031) begin count7 <= 1'b0; clear <= 0; end |
|
|
|
|
|
|
|
|
|
|
|
谢谢你的答复,问题已经全部解决了~ |
|
|
|
|
|
没事,谁都是一步一步来的,FPGA其实是个被限制得比较死的硬件,你用C语言能随便写程序,但用verilog,只能写FPGA可以综合的语句,并不是大家想象中的那么自由,你做设计,按照FPGA器件本身的规则来,是最好的,如果你硬要天马行空,什么设计思路都往上放,最后设计出的东西反而不能发挥FPGA本身性能,而且容易导致bug,所以要多积累行业经验,等你看过的代码多了,自己自然知道该怎么去写。。
|
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
NVMe高速传输之摆脱XDMA设计50:主要功能测试结果与分析2 nvmePCIe高速存储
252 浏览 0 评论
NVMe高速传输之摆脱XDMA设计49:主要功能测试结果与分析1
1501 浏览 0 评论
907 浏览 0 评论
855 浏览 0 评论
658 浏览 0 评论
4427 浏览 63 评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-2 11:08 , Processed in 1.069551 second(s), Total 113, Slave 92 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
3166