用Verilog如何实现一个边沿启动计数器模块
类似于一个脉冲启动电脑那种。应该怎么设计呢?
en高电平启动,en低电平停止不行么
用寄存器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
这个可以吗
感谢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
感觉小编描述的启动信号,其实就是一个置位信号,每一次该信号有效,就从某个计数值开始计数。另外你说的设置计数器的计数值,是开始值还是结束值?建立保持时间的话,应该是通过约束来控制,代码上根据你的设计来看,没有什么能影响到布局布线的东西,感觉上,也要看你的计数时钟频率有多快了。小于10M的话,应该没什么问题,不用考虑建立保持时间的。
如果是异步信号的话可以打两拍来处理
加了一个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
学到不少东西不错
kankan~
这种设计有一个前提,就是start在高电平的时间必须大于一个时钟周期,否则有可能抓不到它的上升沿。
过来看看,学习一下
内部对en采样,采到由0到1后就开始计数不就好了!
不过停止计数的条件是什么呢?
学到不少东西,可以用握手解决脉冲窄的问题
再犀利点,就到犀利哥
按Iqz那位仁兄改了下
如果把en作为启动和停止计时信号呢?就是说先按一下en是启动计时功能,再次按下停止计时,计数值停留在停止计时那一刻的值。
后面有不稳定的,不知道是什么原因
可是,有问题,在START之前就开始计数了
这个应该不难哈,到处都有。
好好学习了
学习了,谢谢!
学习了,,,
这里的state有啥用?
学习学习
