简介:
计数器设计是数字IC设计 的核心,也是最常用的代码片段,通过记录时钟周期个数,可以控制电路的时序,通过计数器可以实现测量,计数,状态控制,分频,计数器有触发器和逻辑门共同构成。
计数器设计要素:
1 初始值是多少?
这里要考虑的是复位信号和其他标志信号,一般复位是计数器清0,其他标志信号看情况。
2 结束值是多少?
结束值同样重要,默认在计数满的时候自动清0,
3 往哪个方向计数
加计数,还是减计数,在同一个设计里面,计数的方向要保持一致。
4计数步长是多少
每次计数的步长是多少,默认是1
5计数条件是啥
一般条件是时钟沿跳变,还有可能是使能信号,标志信号等
计数器示例(Verilog实现)
1 加法计数器
一个指令周期或外部脉冲时将计数器内容加1
module up_counter(
input clk ,
input rst_n,
output reg [7:0] cnt ,
)
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
begin
cnt<= 8'b0;
end
else
begin
cnt <= cnt+1'b1;
end
end
endmodule
2减计数器
一个指令周期或外部脉冲时将计数器内容减1
module down_counter(
input clk ,
input rst_n,
output reg [7:0] cnt ,
)
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
begin
cnt<= 8'hff;
end
else
begin
cnt <= cnt-1'b1;
end
end
endmodule
3带使能标志计数器
使能信号有效是计数
module ena_counter(
input clk ,
input rst_n,
input ena ,
output reg [7:0] cnt ,
)
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
begin
cnt<= 8'b0;
end
else if(ena ==1)
begin
cnt <= cnt+1'b1;
end
else begin
cnt <= cnt ;
end
end
endmodule
4 格雷码计数
格雷码计数器是为了在异步时钟域之间传递计数结果而用到的计数器
module gray_counter(
input clk ,
input rst_n,
output [7:0] gray_out ,
)
reg [7:0] cnt ;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
begin
cnt<= 8'b0;
end
else
begin
cnt <= cnt+1'b1;
end
end
always@(*)begin
if(!rst_n)
gray_out = 8'b0;
else
gray_out = cnt[8:1] ^ (cnt[8:1] >> 1) ;
end
endmodule
5 环形计数器
最简单的移位寄存器,对应n位环形计数器有n个状态
module ring_counter(
input clk ,
input rst_n,
input ena ,
output reg [7:0] cnt ,
)
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
begin
cnt<= 8'b0000_0001;
end
else if(ena == 1'b1)
begin
cnt <= {cnt[0],cnt[7:1]};
end
else
begin
cnt <= cnt ;
end
end
endmodule
6 Johnson计数器
约翰逊(Johnson)计数器又称扭环计数器,是一种n位触发器来表示2n个状态的计数器,约翰逊计数器相邻两组数只有一位不同,避免竞争冒险
module johnson_counter(
input clk ,
input rst_n,
input ena ,
output reg [7:0] cnt ,
)
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
begin
cnt<= 8'd0;
end
else if(ena == 1'b1)
begin
cnt <= {~cnt[0],cnt[7:1]};
end
else
begin
cnt <= cnt ;
end
end
endmodule
7 Ripple计数器(低功耗计数器的一种)
行波计数器一般指异步计数器,使用触发器输出作为下一级触发器时钟的输入。
缺点:
信号延迟偏移
sta和综合麻烦,验证工作量大
优点
module ripple_counter(
input clk ,
input rst ,
output [3:0] cnt ,
);
T_FF tff0(cnt[0], clk , rst);
T_FF tff1(cnt[1], cnt[0] , rst);
T_FF tff2(cnt[2], cnt[1] , rst);
T_FF tff3(cnt[3], cnt[2] , rst);
endmodule
module T_FF(
output t_out,
input clk ,
input rst ,
);
wire d_in;
D_FF dff0(t_out,d_in,clk,rst);
not n1 (d_in,t_out);
endmodule
module D_FF(
input reg d_out,
input d_in ,
input clk ,
input rst ,
);
always @(posedge clk or negedge rst) begin
if(rst)
d_out <= 1'b0 ;
else
d_out <= d_in;
end
endmodule
8 BCD 计数器
用4 位二进制,来表示一位十进制数,十进制计数,计满进位
module bcd_counter(
input clk ,
input rst_n ,
input cin , //carry input
output reg cout , //carry output
output reg [3:0] cnt
);
//count
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
cnt <= 1'b0;
else if(cin==1'b1)begin
if(cnt==4'd9)
cnt <= 1'b0;
end
else
cnt <= cnt+4'b1 ;
else
cnt <= cnt ;
end
//carry out
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
cout <= 1'b0 ;
else if(cin==1'b1 && cnt = 4'd9)begin
cout <= 1'b1 ;
end
else
cout <= 1'b0;
end
endmodule
其他的计数器就不一一列举了,有兴趣可以再研究一下。