在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 12446|回复: 26

[求助] 用Verilog如何实现一个边沿启动计数器模块

[复制链接]
发表于 2010-11-30 13:37:36 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
请各位帮忙:我想要设计这样的一个计数器模块,计数器在正常工作时,每一个clk上升沿加1。带一个启动/停止控制信号en,en的上升沿启动计数器计数。
类似于一个脉冲启动电脑那种。应该怎么设计呢?
发表于 2010-11-30 15:19:25 | 显示全部楼层
en高电平启动,en低电平停止不行么
发表于 2010-11-30 20:01:02 | 显示全部楼层
本帖最后由 liqz 于 2010-11-30 20:02 编辑

用寄存器en_reg把en打一拍,然后在en&(~en_reg)的时候开始计数器启动,你没讲什么时候停止计数,是在en下降沿吗?是的话en_reg&(~en)的时候停止计数。
module (clk,rst,en,counter);
input clk,rst,en;
output [9:0]counter;
reg  [9:0]counter;
reg en_reg;
reg state;
always @ (posedge clk )
begin
if(rst)
    begin
        counter<=10'd0;
        en_reg<=1'd0;
       state<=1'd0;
    end
else
begin
    en_reg<=en;
    case(state)
          1'd0:
          begin
                 if(en&(~en_reg))
                 begin
                        state<=1'd1;
                        counter<=counter+1'd1;
                 end
           end
           1'd1:
           begin
                  if(en_reg&(~en))
                  begin
                          state<=1'd0;
                          counter <=10'd0;
                  end
                  else
                        counter<=counter+1'd1;
          end
     endcase
end
end
endmodule
发表于 2010-12-1 00:57:11 | 显示全部楼层
这个可以吗
 楼主| 发表于 2010-12-1 11:18:25 | 显示全部楼层
本帖最后由 bh3715 于 2010-12-1 12:48 编辑

感谢liqz 的解答~
没有把问题说清楚真是很抱歉,要求是这样的:设计一个计数器,计数器在接收到启动信号后,在每个时钟的上升沿计数。计数结束后停止工作,直到启动信号再次有效。计数器在计数时,若收到启动信号,则重新开始计数。
对于这个要求,启动信号应该是是异步的。liqz的电路中,en(启动信号)是同步的,而且对en时序的要求也是很严格的。有一点不是很明白,还请liqz解答,en的建立和保持时间怎么保证呢?
模块大致这样定义:
module counter(clk, start, set_count, alarm);
      input clk, start;     //start是异步启动信号
      input[9:0] set_count;    //用于设置计数器的计数值
      output alarm;     //计数完成后置位一个时钟周期

.....
endmodule
发表于 2010-12-1 14:20:45 | 显示全部楼层
感觉楼主描述的启动信号,其实就是一个置位信号,每一次该信号有效,就从某个计数值开始计数。另外你说的设置计数器的计数值,是开始值还是结束值?建立保持时间的话,应该是通过约束来控制,代码上根据你的设计来看,没有什么能影响到布局布线的东西,感觉上,也要看你的计数时钟频率有多快了。小于10M的话,应该没什么问题,不用考虑建立保持时间的。
发表于 2010-12-1 15:14:21 | 显示全部楼层
本帖最后由 liqz 于 2010-12-1 15:18 编辑

如果是异步信号的话可以打两拍来处理
加了一个rst输入信号
module counter(clk, rst,start, set_count, alarm);
      input clk, rst,start;     //start是异步启动信号
    input[9:0] set_count;    //用于设置计数器的计数值
    output alarm;     //计数完成后置位一个时钟周期
    reg alarm;
    reg  [9:0]counter;
      reg start1,start2,start3;
      reg state;
always @ (posedge clk )
begin
if(rst)
    begin
        counter<=10'd0;
        start1<=1'd0;
        start2<=1'd0;
        start3<=1'd0;
        state<=1'd0;
        alarm<=1'd0;
    end
else
begin
    start1<=start;
    start2<=start1;
    start3<=start2;
    case(state)
          1'd0:
          begin
                 alarm<=1'd0;
                 if(start2&(~start3))//start2是打两拍后的start信号,做了个亚稳态处理,抓的是start2的上升沿
                 begin
                        state<=1'd1;
                        counter<=counter+1'd1;
                 end
           end
           1'd1:
           begin
                  if(counter==set_count)//计数到需要的值以后,alarm置为有效,回到状态0
                  begin
                          state<=1'd0;
                          counter <=10'd0;
                          alarm<=1'd1;
                  end
                  else if(start2&(~start3))//如果在计数过程中又来了启动信号,重新计数
                  begin
                          counter<=10'd0;
                  end
                  else
                        counter<=counter+1'd1;
          end
     endcase
end
end
endmodule
发表于 2010-12-1 15:31:26 | 显示全部楼层
学到不少东西不错
发表于 2010-12-1 18:21:44 | 显示全部楼层
kankan~~~~~
发表于 2010-12-1 22:42:15 | 显示全部楼层
这种设计有一个前提,就是start在高电平的时间必须大于一个时钟周期,否则有可能抓不到它的上升沿。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条

×

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-3-29 00:05 , Processed in 0.032500 second(s), 9 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表