如果按照计数器中的触发器是否同时翻转分类,可将计数器分为同步计数器和异步计数器两种。
1.基本概念:每个不同的计数器,在设计之初,被设计者设定为感应固定的波形的某一部分(一般为瞬态感应),比如方波的下降沿(或上升沿);
2.同步计数:当你所购得的计数器为同步计数器,所谓同步,就是该计数器只有当输入信号的下降沿(或上升沿)来临时,计数器才会开始处理,其他时间无论高低电平,计数器都会无视;
3.异步计数:所谓异步,就是你随时达到所设定的值,它立刻就跳转,并不等待下一个下降沿(或上升沿)的到来;
综上可以看出,同步,异步说的都是相对于输入信号,计数器在达到最大计数值时的响应是同步于该输入信号,还是异步于它;
下面我们先分别看一下同步计数器和异步计数器的实现
同步计数器:
module counter(rst_n,clk,out_cnt);input clk;
input rst_n;
output reg out_cnt;
reg [7:0]cnt;
always @(posedge clk or negedge rst_n)
if(!rst_n)
cnt <= 8'd0;
else if(cnt == 8'd125)
cnt <= 8'd0;
else
cnt <= cnt + 1'b1;
always @(posedge clk or negedge rst_n)
if(!rst_n)
out_cnt <= 1'b1;
else if(cnt == 8'd125)
out_cnt <= ~out_cnt;
else
out_cnt <= out_cnt;
endmodule
///////////////////`tb
`timescale 1ns/1ns
`define clock_period 20
module counter_tb;
reg clk;
reg rst_n;
wire out_cnt;
counter counter(.rst_n(rst_n),.clk(clk),.out_cnt(out_cnt));
initial clk = 1;
always #(`clock_period/2) clk = ~clk;
initial begin
rst_n = 1'b0;
#(`clock_period *20);
rst_n = 1'b1;
#(`clock_period *2000);
$stop;
end
endmodule
仿真波形图:
异步计数:
moduleasyn_counter(rst_n,clk,out_cnt,asyn_out);inputclk;inputrst_n;outputregout_cnt;outputregasyn_out;reg[7:0]cnt;always@(posedgeclkornegedgerst_n)if(!rst_n)cnt<=8'd0;elseif(cnt==8'd125)cnt<=8'd0;elsecnt<=cnt+1'b1;always@(posedgeclkornegedgerst_n)if(!rst_n)out_cnt<=1'b1;elseif(cnt==8'd125)out_cnt<=~out_cnt;elseout_cnt<=out_cnt;//always@(clkorrst_n)always@(cnt)if(!rst_n)asyn_out<=1'b1;elseif(cnt==8'd125)asyn_out<=~asyn_out;elseasyn_out<=asyn_out;endmodule//////`tb更改一下例化就行了asyn_countercounter(.rst_n(rst_n),.clk(clk),.out_cnt(out_cnt),.asyn_out(asyn_out));
IP 核的计数器
ip核设置如下(Quartus 15.0):
计数到100清零,此程序中 carry_in /out 可以不选
如上图打开 可以找到例化模块 counter(.........)
设置ip/counter.qip为顶层文件
仿真代码:
`timescale1ns/1ns`defineclock_period20modulecounter_tb;regcin;//进位输入regclk;//计数基准时钟wirecout;//进位输出wire[7:0]q;countercounter0(.cin(cin),.clock(clk),.cout(cout),.q(q));initialclk=1;always#(`clock_period/2)clk=~clk;initialbeginrepeat(300)begin//cin=0;#(`clock_period*5)cin=1;#(`clock_period)cin=0;end#(`clock_period*200);$stop;endendmodule
波形图:
上图箭头所产生的时间极短的尖峰,在此可以不考虑,等后续笔记会做"竞争冒险"讲述