Build a 4-digit BCD (binary-coded decimal) counter. Each decimal digit is encoded using 4 bits: q[3:0] is the ones digit, q[7:4] is the tens digit, etc. For digits [3:1], also output an enable signal indicating when each of the upper three digits should be incremented.
You may want to instantiate or modify some one-digit decade counters.
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:1] ena,
output [15:0] q);
always @(posedge clk) begin
if (reset)
ena <= 3'b0;
else begin
if (q[3:0]==4'd8)
ena[1] <= 1'b1;
else
ena[1] <= 1'b0;
if (q[3:0]==4'd8 && q[7:4]==4'd9)
ena[2] <= 1'b1;
else
ena[2] <= 1'b0;
if (q[3:0]==4'd8 && q[7:4]==4'd9 &&q[11:8]==4'd9)
ena[3] <= 1'b1;
else
ena[3] <= 1'b0;
end
end
count cnt0(clk,reset,1'b1,q[3:0]);
count cnt1(clk,reset,ena[1],q[7:4]);
count cnt2(clk,reset,ena[2],q[11:8]);
count cnt3(clk,reset,ena[3],q[15:12]);
endmodule
module count(
input clk,
input reset,
input ena,
output [3:0]q
);
always @(posedge clk)begin
if(reset)
q<=0;
else if(ena)begin
if(q==9)
q=0;
else
q = q+1;
end
else
q = q;
end
endmodule
为什么q [3:0] 要等于8呢?
因为always 有延一拍的效果,所以在q[3:0]==9的时候,十位计数器使能位置1。那么q[7:4]为什么是在==9的时候呢?在q[11:8] ==0,此时百位使能位置1。以此类推
q[3:0]==9的时候ena[1]使能,所以下一个时钟沿 十位计数器开始累加,
module top_module (
input logic clk,
input logic reset, // Synchronous active-high reset
output logic [3:1] ena,
output logic [15:0] q);
reg [3:0] ones;
reg [3:0] tens;
reg [3:0] hundreds;
reg [3:0] thousands;
always@(posedge clk)begin
if(reset) ones <= 4'd0;
else if(ones == 4'd9) ones <= 4'd0;
else ones <= ones + 4'd1 ;
end
always@(posedge clk)begin
if(reset) tens <= 4'd0;
else if(tens == 4'd9 && ones == 4'd9)
tens <= 4'd0;
else if(ones == 4'd9) tens <= tens + 4'd1;
end
always@(posedge clk)begin
if(reset) hundreds <= 4'd0;
else if(hundreds == 4'd9 && tens == 4'd9 && ones == 4'd9)
hundreds <= 4'd0;
else if(tens == 4'd9 && ones == 4'd9)
hundreds <= hundreds + 4'd1;
end
always@(posedge clk)begin
if(reset) thousands <= 4'd0;
else if(thousands == 4'd9 && hundreds == 4'd9 && tens == 4'd9 && ones == 4'd9)
thousands <= 4'd0;
else if(hundreds == 4'd9 && tens == 4'd9 && ones == 4'd9)
thousands <= thousands + 4'd1;
end
assign q = {thousands, hundreds, tens, ones};
assign ena[1] = (ones == 4'd9) ? 1'b1 : 1'b0;
assign ena[2] = (tens == 4'd9 && ones == 4'd9) ? 1'b1 : 1'b0;
assign ena[3] = (hundreds == 4'd9 && tens == 4'd9 && ones == 4'd9) ? 1'b1 : 1'b0;
endmodule
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:1] ena,
output [15:0] q);
wire en1, en2, en3, en4;
assign en1 = 1;
assign en2 = (q[3:0] == 4'd9);
assign en3 = (q[7:4] == 4'd9 && q[3:0] == 4'd9);
assign en4 = (q[11:8] == 4'd9 && q[7:4] == 4'd9 && q[3:0] == 4'd9);
//one
count4 inst1_count4
(
.clk(clk),
.reset(reset),
.ena(en1),
.q(q[3:0])
);
//ten
count4 inst2_count4
(
.clk(clk),
.reset(reset),
.ena(en2),
.q(q[7:4])
);
//hundred
count4 inst3_count4
(
.clk(clk),
.reset(reset),
.ena(en3),
.q(q[11:8])
);
//thousand
count4 inst4_count4
(
.clk(clk),
.reset(reset),
.ena(en4),
.q(q[15:12])
);
//用来表示进位
assign ena = {q[11:8] == 4'd9 && q[7:4] == 4'd9 && q[3:0] == 4'd9, q[7:4] == 4'd9 && q[3:0] == 4'd9, q[3:0] == 4'd9};
endmodule
module count4
(
input clk,
input reset,
input ena,
output reg[3:0] q
);
always @ (posedge clk)
begin
if(reset)
q <= 4'b0;
else if (ena)
begin
if(q == 4'd9)
q <= 4'd0;
else
q <= q + 1'b1;
end
else
q<=q;
end
endmodule