一、设计要求
1.提供给计时器内部设定的时钟频率是12Hz,计时器最长时间为10min,为此需要提供一个三位显示器,显示的最长时间为9分59秒。
2.设有复位和起/停开关
(1)复位开关用于计数器清(2)起/停开关,按一下——启动;再按一下——终止。(3)复位开关任何时间均可使用,即在计时期间,按一下复位开关即对计数器清零,终止计数过程。
二、设计说明
主要有分频器、十进制计数器(秒的个位,分的个位,共计2个十进制计数器)和一个六进制计数器。设计中还需要一个复位信号,还需要在每个计数器上设置使能端作为起/停开关。设置3个四位二进制计数器作为输出。DOUT[11:9]显示分的位数;DOUT[7:4]显示秒的十位;DOUT[3:0]显示个位数秒。
三、代码
(1)产生12Hz的时钟;
//filename:clkgen.v
// Edit by xixihahasoso on 2022/5/7
// 时钟频率12HZ
//reference:郭磊《Verilog 实战教程》
module clkgen ( Rd, CLK_IN , CLK_OUT);
parameter CLK_Freq = 12 ;//12Hz input
parameter CLK_OUT_Freq = 1;//1Hz output)
input Rd, CLK_IN;
output reg CLK_OUT ;
reg [25:0] Counter_DIV;//inner knot
always @ (posedge CLK_IN or negedge Rd) begin
if (~Rd) begin//YiBuQingLing
CLK_OUT <= 0;
Counter_DIV <= 0;
end
else begin
if (Counter_DIV <(CLK_Freq /2 * CLK_OUT_Freq))
Counter_DIV <= Counter_DIV +1'b1;//divider adder add 1
else begin
Counter_DIV <= 0;
CLK_OUT <= ~CLK_OUT;
end
end
end
endmodule
(2)六进制计数
//filename:CNT6.v
// Edit by xixihahasoso on 2022/5/7
// 六进制计数器
module CNT6 ( Rd, EN, CLK, Q, carryout);
input Rd, EN, CLK;
output [3:0] Q;
output carryout;
reg carryout;
integer cnt;
assign Q = cnt;
always @ (posedge CLK) begin
if (~Rd) begin
cnt = 1'b0;
carryout = 1'b0;
end
else if (cnt < 5) begin
carryout = 1'b0;
if(!EN)
cnt = 1'b0;
else
cnt = cnt + 1'b1;
end
else
begin
cnt = 1'b0;
carryout = 1'b1;
end
end
endmodule
(3)十进制计数
//filename:CNT10.v
// Edit by xixihahasoso on 2022/5/7
// 十进制计数器
module CNT10 ( Rd, EN, CLK, Q, carryout);
input Rd, EN, CLK;
output [3:0] Q;
output carryout;
reg carryout;
integer cnt;
assign Q = cnt;
always @ (posedge CLK) begin
if (~Rd) begin
cnt = 1'b0;
carryout = 1'b0;
end
else if (cnt < 9) begin
carryout = 1'b0;
if(!EN)
cnt = 1'b0;
else
cnt = cnt + 1'b1;
end
else
begin
cnt = 1'b0;
carryout = 1'b1;
end
end
endmodule
(4)顶层文件
//filename:top.v
// Edit by xixihahasoso on 2022/5/7
// top file
module top ( CLK_IN, CLR, EN, DOUT,Carryout);
input CLK_IN, CLR, EN;
output [11:0] DOUT;
output Carryout;
wire CLK;
//wire [3:0] D1,D2,D3,D4,D5,D6,D7;
wire [3:0] D5,D6,D7;
//wire carryout1,carryout2,carryout3,carryout4,carryout5,carryout6;
wire carryout1,carryout2,carryout3,carryout4,carryout5,carryout6;
clkgen CLKGEN ( .Rd(CLR), .CLK_IN(CLK_IN) , .CLK_OUT(CLK));
CNT10 CNT10_3 ( .Rd(CLR), .EN(EN), .CLK(carryout2), .Q(D5), .carryout(Carryout));
CNT6 CNT10_4 ( .Rd(CLR), .EN(EN), .CLK(carryout1), .Q(D6), .carryout(carryout2));
CNT10 CNT10_5 ( .Rd(CLR), .EN(EN), .CLK(CLK), .Q(D7), .carryout(carryout1));
assign DOUT = (Carryout == 1) ? {D5,D6,D7} :0 ;
endmodule
(5)测试文件
//filename:CNT6.v
// Edit by xixihahasoso on 2022/5/7
//testbench
module ShuZiMiaoBiao_tb();
reg CLK_IN, CLR, EN;
wire [11:0] DOUT;
parameter Period = 2;
top test ( CLK_IN, CLR, EN, DOUT);
always begin
#(Period/2)
CLK_IN = ~ CLK_IN;
end
initial begin
CLR = 0; EN = 0; CLK_IN = 0;
#25 CLR <= 1;
#30 EN <= 1;
#2000 CLR <= 0;
#2100 CLR <= 1;
#4000 $finish;
end
endmodule
四、测试结果
图中D5,D6,D7分别对应秒表的分、秒的十位、秒的个位;结果显示正确成立。