EDA-Verilog简易闹钟

自用。

一. 功能

(时间显示为24小时制。)
基础功能:正常时间显示,闹钟时间显示,闹钟触发。
进阶功能:清零正常时间,编辑闹钟时间,闹钟触发灯效。
清零,编辑操作均使用开关控制。灯效使用所有的LED-R
Switch0: 选择闹钟目前的状态。开:显示正常时间。关:编辑闹钟时间。
Switch4: 向左移动要编辑的时间位。
Switch3: 向右移动要编辑的时间位。
Switch2: 增加时间位对应的时间。
Switch1: 减少时间位对应的时间。
Switch5: 闹钟正常时间清零。
LED-R0~17: 触发闹钟则全亮5s。

二. 结构图

在这里插入图片描述

三. 代码

module Example(Clk,Hex7,Hex6,Hex5,Hex4,Hex3,Hex2,Hex0,Switch0,Switch4,Switch3,Switch2,Switch1,Led,Clr);
reg[31:0] CounterClk=0;
reg[31:0] CounterClock=0;
reg[31:0] ClockCustom=60;
reg ClkPer=0;
reg[3:0] H2=0,H1=0,M2=0,M1=0,S2=0,S1=0;
reg [31:0]TempH=0,TempM=0,TempS=0;
reg [3:0]Pos=1;
reg [31:0]TimeShow=0;
reg [31:0]LedCounter=0;
reg EnableLed=0; 
(*chip_pin="AG15"*)input Clk; 
(*chip_pin="AA14,AG18,AF17,AH17,AG17,AE17,AD17"*)output reg [6:0]Hex7;
(*chip_pin="AC17,AA15,AB15,AB17,AA16,AB16,AA17"*)output reg [6:0]Hex6;
(*chip_pin="AH18,AF18,AG19,AH19,AB18,AC18,AD18"*)output reg [6:0]Hex5;
(*chip_pin="AE18,AF19,AE19,AH21,AG21,AA19,AB19"*)output reg [6:0]Hex4;
(*chip_pin="Y19,AF23,AD24,AA21,AB20,U21,V21"*)output reg [6:0]Hex3;
(*chip_pin="W28,W27,Y26,W26,Y25,AA26,AA25"*)output reg [6:0]Hex2;
(*chip_pin="H22,J22,L25,L26,E17,F22,G18"*)output reg [6:0]Hex0;
(*chip_pin="AB28"*)input Switch0;
(*chip_pin="AB27"*)input Switch4;
(*chip_pin="AD27"*)input Switch3;
(*chip_pin="AC27"*)input Switch2;
(*chip_pin="AC28"*)input Switch1;
(*chip_pin="H15,G16,G15,F15,H17,J16,H16,J15,G17,J17,H19,J19,E18,F18,F21,E19,F19,G19"*)output reg [17:0] Led;
(*chip_pin="AC26"*)input Clr;

task ShowNumber;
input[3:0]Number;
output[6:0]Hex;
begin
	case(Number)
	4'b0000:Hex=7'b1000_000;
	4'b0001:Hex=7'b1111_001;
	4'b0010:Hex=7'b0100_100;
	4'b0011:Hex=7'b0110_000;
	
	4'b0100:Hex=7'b0011_001;
	4'b0101:Hex=7'b0010_010;
	4'b0110:Hex=7'b0000_010;
	4'b0111:Hex=7'b1111_000;
	
	4'b1000:Hex=7'b0000_000;
	4'b1001:Hex=7'b0010_000;
	
	default:Hex=7'b1111_111;
	endcase
end 
endtask

task TimeCovert;
input [31:0]Time;
input [31:0]TTempH,TTempM,TTempS;
output [3:0]TH2,TH1,TM2,TM1,TS2,TS1;
begin
	TTempH=Time/3600;
	TTempM=(Time%3600)/60;
	TTempS=(Time%3600)%60;
	TH2=TTempH/10;
	TH1=TTempH%10;
	TM2=TTempM/10;
	TM1=TTempM%10;
	TS2=TTempS/10;
	TS1=TTempS%10;
end
endtask

function [31:0]TimeValue;
input[3:0]TPos;
begin
	case(TPos)
	4'b0001:TimeValue=1;
	4'b0010:TimeValue=10;
	4'b0011:TimeValue=60;
	4'b0100:TimeValue=600;
	4'b0101:TimeValue=3600;
	4'b0110:TimeValue=36000;
	default:TimeValue=1;
	endcase
end
endfunction

always@(posedge Clk)
begin
	CounterClk=CounterClk+1;
	if (CounterClk==6250000)//normal 25000000 debug 6250000
	begin
		CounterClk=0;
		ClkPer=~ClkPer;
	end
end 

always@(posedge ClkPer)
begin
	if (Clr)CounterClock=0;
	else CounterClock=CounterClock+1;
	
	if (Switch4)
	begin 
		if (Pos==6)Pos=1;
		else Pos=Pos+1;
	end 
	else if (Switch3)
	begin 
		if (Pos==1)Pos=6;
		else Pos=Pos-1;
	end 
	else if (Switch2)
	begin 
		ClockCustom=ClockCustom+TimeValue(Pos);
	end 
	else if (Switch1)
	begin
		if (ClockCustom>=TimeValue(Pos))ClockCustom=ClockCustom-TimeValue(Pos);
		else ClockCustom=0;
	end
end 

always@(CounterClock)
begin
	if (Switch0) TimeShow=CounterClock;
	else TimeShow=ClockCustom;
	
	TimeCovert(TimeShow,TempH,TempM,TempS,H2,H1,M2,M1,S2,S1);
	ShowNumber(H2,Hex7);
	ShowNumber(H1,Hex6);
	ShowNumber(M2,Hex5);
	ShowNumber(M1,Hex4);
	ShowNumber(S2,Hex3);
	ShowNumber(S1,Hex2);
	ShowNumber(Pos,Hex0);
	
	if (CounterClock==ClockCustom)EnableLed=1;
	else EnableLed=0;
	
	if (EnableLed||LedCounter>0)
	begin 
		LedCounter=LedCounter+1;
		if (LedCounter==5)
		begin 
			EnableLed=0;
			LedCounter=0;
		end 
	end 
	
	if (EnableLed)Led=17'b1111_1111_1111_1111_1;
	else Led=17'b0000_0000_0000_0000_0;
end 
endmodule 



 

四. 问题分析和总结

  • 整体代码较为简单,但是在设计过程中也遇到了很多问题。
  • 在设计闹钟时间时,考虑到要对时间进行编辑,如何存储是一个问题,后来考虑到类似时间戳和单独时间位等方法。最终结合使用了这两种方式。存储时使用时间戳,显示时使用单独时间位。实际证明效果不错。
  • 闹钟正常显示时间功能正常后,切换到编辑闹钟时间的模式,因为不知名的bug,误以为Key系列按钮不能使用,后改用Switch系列的器件,结果依旧。最终,Switch系列的操作仍不能独立写时序逻辑,只能和时钟刷新同步,1s处理1次操作,有点迟钝,这是不理想的。
  • 对于闹钟的编辑,一开始想到分别对不同的时间位操作,结果发现很麻烦。最终考虑到简便性,对时间戳进行更改,时间戳更改完成再由转换函数变为显示所需的单独时间位。当然,因为时位,分位,秒位所占权值不同,且为两位数,这也需要写位置权值转换函数。
  • 触发闹钟的逻辑,写在输出的时序逻辑中。一开始没注意if语句接else,导致控制LED灯的信号锁存。而这也是在设计中犯的比较多的一个问题。
  • 总结,这是一门神奇的课程,它使我理解了很多硬件层次的知识。比如屏幕能显示0,下一秒显示1不是魔法,不是无中生有,是有规则的,是可以学习的。一个的崭新的世界已经向我打开(然后我亲手关上~)。最后,感谢在课程实验设计中,以及在以往实验中,帮助过我的老师和同学们,是他们鼓励着我:虽然bug不断,但一定是可以解决的吧!!!
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值