/* 信号定义:
clk: 标准时钟李迅信号,本例中,其频率为4Hz;
clk_1k: 产生闹铃音、报时音的时钟信号,本例中其频率为1024Hz;
mode: 功能控制信号;为0:计时功能;
为1:闹钟功能;
为2:手动校时功能;
turn: 接按键,在手动校时功能时,选择是调整小时,还是分钟;
若长时间按住该键,还可使秒信号清零,用于精确调时;
change: 接按键,手动调整时,每按一次,计数器加1;
如果长按,则连续快速加1,用于快速调时和定时;
hour,min,sec :此三信号分别输出并显示时、分、秒信号,
皆采用BCD码计数,分别驱动6个数码管显示时间;
alert: 输出到扬声器的信号,用于产生闹铃音和报时音;
闹铃音为持续20秒的急促的"嘀嘀嘀"音,若按住"change"键,
则可屏蔽该音;整点报时音为"嘀嘀嘀嘀-嘟"四短一长音;
LD_alert: 接发光二极管,指示是否设置了闹钟功能;
LD_hour: 接发光二极管,指示当前调整的是小时信号;
LD_min: 接发光二极管,指示当前调整的是分钟信号。
*/
module clock(clk,clk_1k,mode,change,turn,alert,hour,min,sec,
LD_alert,LD_hour,LD_min)
input clk,clk_1k,mode,change,turn
output alert,LD_alert,LD_hour,LD_min
output[7:0] hour,min,sec
reg[7:0] hour,min,sec,hour1,min1,sec1,ahour,amin
reg[1:0] m,fm,num1,num2,num3,num4
reg[1:0] loop1,loop2,loop3,loop4,sound
reg LD_hour,LD_min
reg clk_1Hz,clk_2Hz,minclk,hclk
reg alert1,alert2,ear
reg count1,count2,counta,countb
wire ct1,ct2,cta,ctb,m_clk,h_clk
always @(posedge clk)
begin
clk_2Hz<=~clk_2Hz
if(sound==3) begin sound<=0ear<=1end
//ear信号用于产生或屏蔽声音
else begin sound<=sound+1ear<=0end
end
always @(posedge clk_2Hz) //由4Hz 的输入时钟产生1Hz的时基信号
clk_1Hz<=~clk_1Hz
always @(posedge mode) //mode信号控制系统在三种功能间转换
begin if(m==2) m<=0else m<=m+1end
always @(posedge turn)
fm<=~fm
always //该进程产蚂困生count1,count2,counta,countb四个信号
begin
case(m)
2:begin if(fm)
begin count1<=change{LD_min,LD_hour}<=2end
else
begin counta<=change{LD_min,LD_hour}<=1end
{count2,countb}<=0
end
1:begin if(fm)
begin count2<=change{LD_min,LD_hour}<=2end
else
begin countb<=change{LD_min,LD_hour}<=1end
{count1,counta}<=2'b00
end
default: {count1,count2,counta,countb,LD_min,LD_hour}<=0
endcase
end
always @(negedge clk)
//如果长时间按下"change"键,则生成"num1"信号用于连续快速加1
if(count2) begin
if(loop1==3) num1<=1
else
begin loop1<=loop1+1num1<=0end
end
else begin loop1<哪物此=0num1<=0end
always @(negedge clk) //产生num2信号
if(countb) begin
if(loop2==3) num2<=1
else
begin loop2<=loop2+1num2<=0end
end
else begin loop2<=0num2<=0end
always @(negedge clk)
if(count1) begin
if(loop3==3) num3<=1
else
begin loop3<=loop3+1num3<=0end
end
else begin loop3<=0num3<=0end
always @(negedge clk)
if(counta) begin
if(loop4==3) num4<=1
else
begin loop4<=loop4+1num4<=0end
end
else begin loop4<=0num4<=0end
assign ct1=(num3&clk)|(!num3&m_clk)//ct1 用于计时、校时中的分钟计数
assign ct2=(num1&clk)|(!num1&count2)//ct2 用于定时状态下调整分钟信号
assign cta=(num4&clk)|(!num4&h_clk)//cta 用于计时、校时中的小时计数
assign ctb=(num2&clk)|(!num2&countb)//ctb 用于定时状态下调整小时信号
always @(posedge clk_1Hz) //秒计时和秒调整进程
if(!(sec1^8'h59)|turn&(!m))
begin
sec1<=0if(!(turn&(!m))) minclk<=1
end
//按住"turn"按键一段时间,秒信号可清零,该功能用于手动精确调时
else begin
if(sec1[3:0]==4'b1001)
begin sec1[3:0]<=4'b0000sec1[7:4]<=sec1[7:4]+1end
else sec1[3:0]<=sec1[3:0]+1minclk<=0
end
assign m_clk=minclk||count1
always @(posedge ct1) //分计时和分调整进程
begin
if(min1==8'h59) begin min1<=0hclk<=1end
else begin
if(min1[3:0]==9)
begin min1[3:0]<=0min1[7:4]<=min1[7:4]+1end
else min1[3:0]<=min1[3:0]+1hclk<=0
end
end
assign h_clk=hclk||counta
always @(posedge cta) //小时计时和小时调整进程
if(hour1==8'h23) hour1<=0
else if(hour1[3:0]==9)
begin hour1[7:4]<=hour1[7:4]+1hour1[3:0]<=0end
else hour1[3:0]<=hour1[3:0]+1
always @(posedge ct2) //闹钟定时功能中的分钟调节进程
if(amin==8'h59) amin<=0
else if(amin[3:0]==9)
begin amin[3:0]<=0amin[7:4]<=amin[7:4]+1end
else amin[3:0]<=amin[3:0]+1
always @(posedge ctb) //闹钟定时功能中的小时调节进程
if(ahour==8'h23) ahour<=0
else if(ahour[3:0]==9)
begin ahour[3:0]<=0ahour[7:4]<=ahour[7:4]+1end
else ahour[3:0]<=ahour[3:0]+1
always //闹铃功能
if((min1==amin)&&(hour1==ahour)&&(amin|ahour)&&(!change))
//若按住"change"键不放,可屏蔽闹铃音
if(sec1<8'h20) alert1<=1//控制闹铃的时间长短
else alert1<=0
else alert1<=0
always //时、分、秒的显示控制
case(m)
3'b00: begin hour<=hour1min<=min1sec<=sec1end
//计时状态下的时、分、秒显示
3'b01: begin hour<=ahourmin<=aminsec<=8'hzzend
//定时状态下的时、分、秒显示
3'b10: begin hour<=hour1min<=min1sec<=8'hzzend
//校时状态下的时、分、秒显示
endcase
assign LD_alert=(ahour|amin)?1:0//指示是否进行了闹铃定时
assign alert=((alert1)?clk_1k&clk:0)|alert2//产生闹铃音或整点报时音
always //产生整点报时信号alert2
begin
if((min1==8'h59)&&(sec1>8'h54)||(!(min1|sec1)))
if(sec1>8'h54) alert2<=ear&clk_1k// 产生短音
else alert2<=!ear&clk_1k//产生长音
else alert2<=0
end
endmodule
输入1Hz的时钟作为秒信号,秒计数缺明满60后向分计数进1,分计数满60后做局向时计数进1。当计数到24:60:60自动回到00:00:00;library ieee
use ieee.std_logic_1164.all
entity clock is
port(clk:in std_logic--输入1Hz的时钟作为秒信号
clr:in std_logic--异步清零信号
s:out integer range 0 to 60--秒纯扮让
min:out integer range 0 to 60--分
h:out integer range 0 to 24--时
)
end clock
architecture clock of clock is
begin
process(clk,clr)
variable count1 :integer range 0 to 60--秒计数
variable count2 :integer range 0 to 60--分计数
variable count3 :integer range 0 to 24--时计数
begin
s<=count1
min<=count2
h<=count3
if(clr='1')then
count1:=0
count2:=0
count3:=0
elsif(clk'event and clk='1')then
count1:=count1+1
if (count1=60)then
count1:=0
count2:=count2+1
if(count2=60)then
count2:=0
count3:=count3+1
if(count3=24)then
count3:=0
end if
end if
end if
end if
end process
end clock
2. 微秒模块采用VHDL语言输入方式,以时钟clk,清零信号clr以及暂停信号STOP为进程敏感变量,程序如下:
library ieee
use ieee.std_logic_1164.all
use ieee.std_logic_unsigned.all
entity MINSECONDb is
port(clk,clrm,stop:in std_logic----时钟/清零信号
secm1,secm0:out std_logic_vector(3 downto 0)----秒高位/低位
co:out std_logic)-------输出/进位信号
end MINSECONDb
architecture SEC of MINSECONDb is
signal clk1,DOUT2:std_logic
begin
process(clk,clrm)
variable cnt1,cnt0:std_logic_vector(3 downto 0)---计数
VARIABLE COUNT2 :INTEGER RANGE 0 TO 10
begin
IF CLK'EVENT AND CLK='1'THEN
IF COUNT2>=0 AND COUNT2<10 THEN
COUNT2:=COUNT2+1
ELSE COUNT2:=0
DOUT2<= NOT DOUT2
END IF
END IF
if clrm='1'族磨 then----当clr为1时,高低位均塌穗锋为0
cnt1:="0000"
cnt0:="0000"
elsif clk'event and clk='1' then
if stop='1' then
cnt0:=cnt0
cnt1:=cnt1
end if
if cnt1="1001" and cnt0="1000" then----当记数为98(实际是经过59个记时脉冲)
co<='1'----进位
cnt0:="1001"----低位为9
elsif cnt0<"1001" then----小于9时
cnt0:=cnt0+1----计数
--elsif cnt0="1001" then
--clk1<=not clk1
else
cnt0:="0000"
if cnt1<"1001" then----高位小于9时
cnt1:=cnt1+1
else
cnt1:="0000"
co<='0'
end if
end if
end if
secm1<=cnt1
secm0<=cnt0
end process
end SEC
3. 秒模块程序清团晌单
library ieee
use ieee.std_logic_1164.all
use ieee.std_logic_unsigned.all
entity SECOND is
port(clk,clr:in std_logic----时钟/清零信号
sec1,sec0:out std_logic_vector(3 downto 0)----秒高位/低位
co:out std_logic)-------输出/进位信号
end SECOND
architecture SEC of SECOND is
begin
process(clk,clr)
variable cnt1,cnt0:std_logic_vector(3 downto 0)---计数
begin
if clr='1' then----当ckr为1时,高低位均为0
cnt1:="0000"
cnt0:="0000"
elsif clk'event and clk='1' then
if cnt1="0101" and cnt0="1000" then----当记数为58(实际是经过59个记时脉冲)
co<='1'----进位
cnt0:="1001"----低位为9
elsif cnt0<"1001" then----小于9时
cnt0:=cnt0+1----计数
else
cnt0:="0000"
if cnt1<"0101" then----高位小于5时
cnt1:=cnt1+1
else
cnt1:="0000"
co<='0'
end if
end if
end if
sec1<=cnt1
sec0<=cnt0
end process
end SEC
4. 分模块程序清单
library ieee
use ieee.std_logic_1164.all
use ieee.std_logic_unsigned.all
entity MINUTE is
port(clk,en:in std_logic
min1,min0:out std_logic_vector(3 downto 0)
co:out std_logic)
end MINUTE
architecture MIN of MINUTE is
begin
process(clk)
variable cnt1,cnt0:std_logic_vector(3 downto 0)
begin
if clk'event and clk='1' then
if en='1' then
if cnt1="0101" and cnt0="1000" then
co<='1'
cnt0:="1001"
elsif cnt0<"1001" then
cnt0:=cnt0+1
else
cnt0:="0000"
if cnt1<"0101" then
cnt1:=cnt1+1
else
cnt1:="0000"
co<='0'
end if
end if
end if
end if
min1<=cnt1
min0<=cnt0
end process
end MIN
5. 时模块程序清单
library ieee
use ieee.std_logic_1164.all
use ieee.std_logic_unsigned.all
entity HOUR is
port(clk,en:in std_logic----输入时钟/高电平有效的使能信号
h1,h0:out std_logic_vector(3 downto 0))----时高位/低位
end HOUR
architecture hour_arc of HOUR is
begin
process(clk)
variable cnt1,cnt0:std_logic_vector(3 downto 0)----记数
begin
if clk'event and clk='1' then---上升沿触发
if en='1' then---同时“使能”为1
if cnt1="0010" and cnt0="0011" then
cnt1:="0000"----高位/低位同时为0时
cnt0:="0000"
elsif cnt0<"1001" then----低位小于9时,低位记数累加
cnt0:=cnt0+1
else
cnt0:="0000"
cnt1:=cnt1+1-----高位记数累加
end if
end if
end if
h1<=cnt1
h0<=cnt0
end process
end hour_arc
6. 动态扫描模块
library ieee
use ieee.std_logic_1164.all
use ieee.std_logic_unsigned.all
use ieee.std_logic_arith.all
entity SELTIME is
port(
clk:in std_logic------扫描时钟
secm1,secm0,sec1,sec0,min1,min0,h1,h0:in std_logic_vector(3 downto 0)-----分别为秒个位/时位;分个位/
daout:out std_logic_vector(3 downto 0)----------------输出
sel:out std_logic_vector(2 downto 0))-----位选信号
end SELTIME
architecture fun of SELTIME is
signal count:std_logic_vector(2 downto 0)----计数信号
begin
sel<=count
process(clk)
begin
if(clk'event and clk='1') then
if(count>="111") then
count<="000"
else
count<=count+1
end if
end if
case count is
when"111"=>daout<= secm0----秒个位
when"110"=>daout<= secm1----秒十位
when"101"=>daout<= sec0----分个位
when"100"=>daout<= sec1----分十位
when"011"=>daout<=min0 ----时个位
when"010"=>daout<=min1----时十位
when"001"=>daout<=h0
when others =>daout<=h1
end case
end process
end fun
7. 报时模块
library ieee
use ieee.std_logic_1164.all
entity ALERT is
port(m1,m0,s1,s0:in std_logic_vector(3 downto 0)------输入秒、分高/低位信号
clk:in std_logic------高频声控制
q500,qlk:out std_logic)----低频声控制
end ALERT
architecture sss_arc of ALERT is
begin
process(clk)
begin
if clk'event and clk='1' then
if m1="0101" and m0="1001" and s1="0101" then----当秒高位为5,低位为9时且分高位为5
if s0="0001" or s0="0011" or s0="0101" or s0="0111" then---当分的低位为1或3或5或7时
q500<='1'----低频输出为1
else
q500<='0'----否则输出为0
end if
end if
if m1="0101" and m0="1001" and s1="0101" and s0="1001" then---当秒高位为5,低位为9时且分高位为5,----分低位为9时,也就是“59分59秒”的时候“报时”
qlk<='1'-----高频输出为1
else
qlk<='0'
end if
end if
end process
end sss_arc
8. 显示模块
library ieee
use ieee.std_logic_1164.all
entity DISPLAY is
port(d:in std_logic_vector(3 downto 0)----连接seltime扫描部分d信号
q:out std_logic_vector(6 downto 0))----输出段选信号(电平)
end DISPLAY
architecture disp_are of DISPLAY is
begin
process(d)
begin
case d is
when"0000" =>q<="0111111"--显示0
when"0001" =>q<="0000110"--显示1
when"0010" =>q<="1011011"--显示2
when"0011" =>q<="1001111"--显示3
when"0100" =>q<="1100110"--显示4
when"0101" =>q<="1101101"--显示5
when"0110" =>q<="1111101"--显示6
when"0111" =>q<="0100111"--显示7
when"1000" =>q<="1111111"--显示8
when others =>q<="1101111"--显示9
end case
end process
end disp_are
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)