本人刚开始接触Verilog,如何用比较简单的Verilog代码实现电子时钟设计,只要能复位和调节小时和分针就可以
本人刚开始接触Verilog,如何用比较简单的Verilog代码实现电子时钟设计,只要能复位和调节小时和分针就可以了,请附上详细的代码讲解。谢谢!!!...
本人刚开始接触Verilog,如何用比较简单的Verilog代码实现电子时钟设计,只要能复位和调节小时和分针就可以了,请附上详细的代码讲解。谢谢!!!
展开
2个回答
展开全部
这是王金明书中的一个例子,应该能帮助你解决该问题。
代码如下:
/*信号定义
clk : 标准时钟信号,本例中,其频率为4Hz;
clk_lk: 产生闹铃声、报时音的时钟信号,本例中其频率为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_lk,mode,change,turn,alert,hour,min,sec,
LD_alert,LD_hour,LD_min);
input clk;
input clk_lk;
input mode; //mode信号控制系统在三种功能间转换;
input change;
input turn;
output [7:0] hour;
output [7:0] min;
output [7:0] sec;
output alert;
output LD_alert;
output LD_hour;
output LD_min;
reg [7:0] hour;
reg [7:0] min;
reg [7:0] sec;
reg [7:0] hour1;
reg [7:0] min1;
reg [7:0] sec1;
reg [7:0] ahour;
reg [7:0] amin;
reg [1:0] m;
reg [1:0] fm;
reg [1:0] num1;
reg [1:0] num2;
reg [1:0] num3;
reg [1:0] num4;
reg [1:0] loop1;
reg [1:0] loop2;
reg [1:0] loop3;
reg [1:0] loop4;
reg [1:0] sound;
reg LD_hour;
reg LD_min;
reg clk_1Hz; //由4Hz的输入时钟产生1Hz的时基
reg clk_2Hz;
reg minclk;
reg hclk;
reg alert1;
reg alert2;
reg ear; //ear信号用于产生或屏蔽声音
reg count1;
reg count2;
reg counta;
reg countb;
wire ct1;
wire ct2;
wire cta;
wire ctb;
wire m_clk;
wire h_clk;
always @ (posedge clk)
begin
clk_2Hz <= ~clk_2Hz;
if(sound==3) begin sound <=0; ear<=1; end
else begin sound <=sound+1; ear<=0; end
end
always @ (posedge clk_2Hz)
clk_1Hz <= ~clk_1Hz;
always //该进程产生count1,count2,counta,countb四个信号;
begin
case(m)
2: begin if(fm)
begin
count1<=change;
{LD_min,LD_hour}<=2;
end
else
begin
counta<=change;
{LD_min,LD_hour}<=1;
end
{count2,countb}<=0;
end
1: begin if(fm)
begin
count2<=change;
{LD_min,LD_hour}<=2;
end
else
begin
countb<=change;
{LD_min,LD_hour}<=1;
end
{count1,counta}<=2'b0;
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+1;
num1<=0;
end
end
else begin loop1<=0;num1<=0; end
always @ (negedge clk) //产生num2信号
if(countb) begin
if(loop2==3) num2<=1;
else begin
loop2<=loop2+1;
num2<=0;
end
end
else begin loop2<=0; num2<=0; end
always @ (negedge clk)
if(count1) begin
if(loop3==3) num3<=1;
else begin
loop3<=loop3+1;
num3<=0;
end
end
else begin loop3<=0; num3<=0; end
always @ (negedge clk)
if(counta) begin
if(loop4==3) num4<=1;
else begin
loop4<=loop4+1;
num4<=0;
end
end
else begin loop4<=0; num4<=0; end
assign ct1=(num3&clk)|(!num3&m_clk); //ct1用于计时、校时中的分钟计数
assign ct2=(num1&clk)|(!num1&count2); //ct2用于定时状态下调整分钟信号
assign ct1=(num4&clk)|(!num4&h_clk); //cta用于计时、校时中的小时计数
assign ct1=(num2&clk)|(!num3&countb); //ctb用于定时状态下调整小时信号
always @ (posedge clk_1Hz) //秒计时和秒调整进程
if(!(sec1^8'h59)|trun&(!m))
begin
sec1<=0;
if(!(turn&(!m)))
minclk<=1;
end //按住turn键一段时间,秒信号可以清零,该功能用于手动精确调时
else begin
if(sec1[3:0]==4'b1111)
begin
sec1[3:0]<=4'b0;
sec1[7:4]<=sec1[7:4]+1;
end
end
assign m_clk=minclk|count1;
always @ (posedge ct1) //分计时和分调整进程
begin
if(min1==8'h59) begin
min1<=0;
hclk<=1;
end
else begin
if(min1[3:0]==4'hf) begin
min1[3:0]<=0;
min1[7:4]<=min1[7:4]+1;
end
else
min1[3:0]<=min1[3:0]+1;
hclk<=0;
end
end
always @ (posedge cta) //小时计时和小时调整进程
if(hour1==8'h23)
hour1<=0;
else if(hour1[3:0]<=4'hf)
begin
hour1[7:4]<=hour1[7:4]+1;
hour1[3:0]<=0;
end
else
hour1[3:0]<=hour1[3:0]+1;
always @ (posedge ct2) //闹钟定时功能中的分钟调节进程
if(amin==8'h59) amin<=0;
else if(amin[3:0]==4'hf)
begin
amin[3:0]<=0;
amin[7:4]<=amin[7:4]+1;
end
else
amin[3:0]<=amin[3:0]+1;
always @ (posedge ctb) //闹钟定时功能中的小时调节进程
if(ahour==8'h23)
ahour<=0;
else if(ahour[3:0]==4'hf)
begin
ahour[3:0]<=0;
ahour[7:4]<=ahour[7:4]+1;
end
else
ahour[3:0]<=ahour[3:0]+1;
always //闹铃功能
if((min1==amin)&&(hour1==ahour)&&(amin|ahour)&&(!change))
if(sec1<8'h20) //若按住“change"键不放,可屏蔽闹铃声
alert<=1; //控制闹铃的时间长短
else
alert<=0;
always //时、分、秒的显示控制
case(m)
3'b00: begin hour<=hour1;min<=min1;sec<=sec1; end
//计时状态下的时、分、秒显示
3'b01: begin hour<=ahour;min<=amin;sec<=8'hzz; end
//定时状态下的时、分、秒显示
3'b10: begin hour<=hour1;min<=min1;sec<=8'hzz; end
//校时状态下的时、分、秒显示
endcase
assign LD_alert=(ahour|amin)?1:0; //指示是否进行了闹铃的定时
assign alert =((alert)?clk_lk&clk:0)|alert2; //产生闹铃音或整点报时音
always //产生整点报时信号alert2
begin
if((min1==8'h59)&&(sec1>8'h54)||(!(min1|sec1)))
if(sec1>8'h54)
alert2<=ear&clk_lk; //产生短音
else
alert2<=!ear&clk_lk;//产生长音
else
alert2<=0;
endmodule
代码如下:
/*信号定义
clk : 标准时钟信号,本例中,其频率为4Hz;
clk_lk: 产生闹铃声、报时音的时钟信号,本例中其频率为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_lk,mode,change,turn,alert,hour,min,sec,
LD_alert,LD_hour,LD_min);
input clk;
input clk_lk;
input mode; //mode信号控制系统在三种功能间转换;
input change;
input turn;
output [7:0] hour;
output [7:0] min;
output [7:0] sec;
output alert;
output LD_alert;
output LD_hour;
output LD_min;
reg [7:0] hour;
reg [7:0] min;
reg [7:0] sec;
reg [7:0] hour1;
reg [7:0] min1;
reg [7:0] sec1;
reg [7:0] ahour;
reg [7:0] amin;
reg [1:0] m;
reg [1:0] fm;
reg [1:0] num1;
reg [1:0] num2;
reg [1:0] num3;
reg [1:0] num4;
reg [1:0] loop1;
reg [1:0] loop2;
reg [1:0] loop3;
reg [1:0] loop4;
reg [1:0] sound;
reg LD_hour;
reg LD_min;
reg clk_1Hz; //由4Hz的输入时钟产生1Hz的时基
reg clk_2Hz;
reg minclk;
reg hclk;
reg alert1;
reg alert2;
reg ear; //ear信号用于产生或屏蔽声音
reg count1;
reg count2;
reg counta;
reg countb;
wire ct1;
wire ct2;
wire cta;
wire ctb;
wire m_clk;
wire h_clk;
always @ (posedge clk)
begin
clk_2Hz <= ~clk_2Hz;
if(sound==3) begin sound <=0; ear<=1; end
else begin sound <=sound+1; ear<=0; end
end
always @ (posedge clk_2Hz)
clk_1Hz <= ~clk_1Hz;
always //该进程产生count1,count2,counta,countb四个信号;
begin
case(m)
2: begin if(fm)
begin
count1<=change;
{LD_min,LD_hour}<=2;
end
else
begin
counta<=change;
{LD_min,LD_hour}<=1;
end
{count2,countb}<=0;
end
1: begin if(fm)
begin
count2<=change;
{LD_min,LD_hour}<=2;
end
else
begin
countb<=change;
{LD_min,LD_hour}<=1;
end
{count1,counta}<=2'b0;
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+1;
num1<=0;
end
end
else begin loop1<=0;num1<=0; end
always @ (negedge clk) //产生num2信号
if(countb) begin
if(loop2==3) num2<=1;
else begin
loop2<=loop2+1;
num2<=0;
end
end
else begin loop2<=0; num2<=0; end
always @ (negedge clk)
if(count1) begin
if(loop3==3) num3<=1;
else begin
loop3<=loop3+1;
num3<=0;
end
end
else begin loop3<=0; num3<=0; end
always @ (negedge clk)
if(counta) begin
if(loop4==3) num4<=1;
else begin
loop4<=loop4+1;
num4<=0;
end
end
else begin loop4<=0; num4<=0; end
assign ct1=(num3&clk)|(!num3&m_clk); //ct1用于计时、校时中的分钟计数
assign ct2=(num1&clk)|(!num1&count2); //ct2用于定时状态下调整分钟信号
assign ct1=(num4&clk)|(!num4&h_clk); //cta用于计时、校时中的小时计数
assign ct1=(num2&clk)|(!num3&countb); //ctb用于定时状态下调整小时信号
always @ (posedge clk_1Hz) //秒计时和秒调整进程
if(!(sec1^8'h59)|trun&(!m))
begin
sec1<=0;
if(!(turn&(!m)))
minclk<=1;
end //按住turn键一段时间,秒信号可以清零,该功能用于手动精确调时
else begin
if(sec1[3:0]==4'b1111)
begin
sec1[3:0]<=4'b0;
sec1[7:4]<=sec1[7:4]+1;
end
end
assign m_clk=minclk|count1;
always @ (posedge ct1) //分计时和分调整进程
begin
if(min1==8'h59) begin
min1<=0;
hclk<=1;
end
else begin
if(min1[3:0]==4'hf) begin
min1[3:0]<=0;
min1[7:4]<=min1[7:4]+1;
end
else
min1[3:0]<=min1[3:0]+1;
hclk<=0;
end
end
always @ (posedge cta) //小时计时和小时调整进程
if(hour1==8'h23)
hour1<=0;
else if(hour1[3:0]<=4'hf)
begin
hour1[7:4]<=hour1[7:4]+1;
hour1[3:0]<=0;
end
else
hour1[3:0]<=hour1[3:0]+1;
always @ (posedge ct2) //闹钟定时功能中的分钟调节进程
if(amin==8'h59) amin<=0;
else if(amin[3:0]==4'hf)
begin
amin[3:0]<=0;
amin[7:4]<=amin[7:4]+1;
end
else
amin[3:0]<=amin[3:0]+1;
always @ (posedge ctb) //闹钟定时功能中的小时调节进程
if(ahour==8'h23)
ahour<=0;
else if(ahour[3:0]==4'hf)
begin
ahour[3:0]<=0;
ahour[7:4]<=ahour[7:4]+1;
end
else
ahour[3:0]<=ahour[3:0]+1;
always //闹铃功能
if((min1==amin)&&(hour1==ahour)&&(amin|ahour)&&(!change))
if(sec1<8'h20) //若按住“change"键不放,可屏蔽闹铃声
alert<=1; //控制闹铃的时间长短
else
alert<=0;
always //时、分、秒的显示控制
case(m)
3'b00: begin hour<=hour1;min<=min1;sec<=sec1; end
//计时状态下的时、分、秒显示
3'b01: begin hour<=ahour;min<=amin;sec<=8'hzz; end
//定时状态下的时、分、秒显示
3'b10: begin hour<=hour1;min<=min1;sec<=8'hzz; end
//校时状态下的时、分、秒显示
endcase
assign LD_alert=(ahour|amin)?1:0; //指示是否进行了闹铃的定时
assign alert =((alert)?clk_lk&clk:0)|alert2; //产生闹铃音或整点报时音
always //产生整点报时信号alert2
begin
if((min1==8'h59)&&(sec1>8'h54)||(!(min1|sec1)))
if(sec1>8'h54)
alert2<=ear&clk_lk; //产生短音
else
alert2<=!ear&clk_lk;//产生长音
else
alert2<=0;
endmodule
参考资料: 王金明:《Verilog HDL 程序设计教程》
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询