级联BCD计数器
设计三级bcd计数器,可以计数到999
BCD码是用四位二进制数表示十进制中的0-9这10个数字,最常见的是8421码,各个位的权值分别为8、4、2、1,同样还有5421码等,例如将321转化为BCD码为0011_0010_0001。详细请参考百度。
3 | 2 | 1 | |||||||||
0 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 |
BCD码的主要应用之一就是数码管,假设在数码管上要显示256,一般是将个十百位进行拆分,然后查出对应数码管显示的段码再送给IO口,这个过程是比较消耗时间的,但是如果先将其转换为BCA码,可以大幅度减少运算时间。
注意如果只是一个BCD计数器,cin可以是没有的,笔者在网上看到有的说是不能少,但是如果单个BCD计数器与普通计数器相差不大,在时钟上升沿进行计数,没有多大影响。
顶层模块设计
module bcd_top(
input clk,
input rst_n,
input cin,
output cout,
output [11:0]q
);
wire [3:0] q0,q1,q2;
assign q={q2,q1,q0};
wire cin2;
wire cin3;
bcd_counter bcd_counter1(
.clk(clk),
.rst_n(rst_n),
.cin(cin),
.cout(cin2),
.q(q0)
);
bcd_counter bcd_counter2(
.clk(clk),
.rst_n(rst_n),
.cin(cin2),
.cout(cin3),
.q(q1)
);
bcd_counter bcd_counter3(
.clk(clk),
.rst_n(rst_n),
.cin(cin3),
.cout(cout),
.q(q2)
);
endmodule
计数模块
module bcd_counter(
input clk,
input rst_n,
input cin,
output cout,
output [3:0]q
);
reg [3:0] cnt;
always@(posedge clk or negedge rst_n)
if(!rst_n)
cnt<=0;
else if(cin)begin
if(cnt==4'd9)
cnt<=0;
else
cnt<=cnt+1;
end
else
cnt<=cnt;
assign cout=(cnt==4'd9 && cin==1)?1:0;
assign q=cnt;
endmodule
`timescale 1ns/1ns
module bcd_counter_tb;
reg clk;
reg rst_n;
reg cin;
wire cout;
wire [11:0] q;
bcd_top bcd_top(
.clk(clk),
.rst_n(rst_n),
.cin(cin),
.cout(cout),
.q(q)
);
initial clk=0;
always #10 clk=~clk;
initial begin
rst_n=0;
cin=0;
#210;
rst_n=1;
#100;
cin=1;
end
endmodule