【Verilog闯关第2天】数字秒表的设计

一、设计要求

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分别对应秒表的分、秒的十位、秒的个位;结果显示正确成立。

你可能感兴趣的:(Verilog个人实践,fpga开发)