用Verilog实现七段管可调计时器
【摘要】 七段管可调计时器
设计思路
在3.2的基础上,将时分秒计时器,变成可调的计时器。可以分别对小时、分、秒设定初始值。
设定的方法可以采用,从外部输入一个值,比如小时可以从5开始;也可以通过按键把小时当前的值增加或者减少来实现值的调整。
功能模块代码:
module Ktcllo(clk50,key,clk1,out5,out4,out3,out2,out1,out0,flagclk,up,down);
input clk50,key,flagclk,up,down; // clk50:输入50MHz信号;key:异步复位信号
output clk1; // clk1:新产生的1Hz信号
output reg [6:0] out5; // 输出,时_十位
output reg [6:0] out4; // 输出,时_个位
output reg [6:0] out3; // 输出,分_十位
output reg [6:0] out2; // 输出,分_个位
output reg [6:0] out1; // 输出,秒_十位
output reg [6:0] out0; // 输出,秒_个位
reg [6:0] hour=0; // 计数器_时(0-23)
reg [6:0] minutes=0; // 计数器_分(0-59)
reg [6:0] seconds=0; // 计数器_秒(0-59)
reg [3:0] flag=0;
div_clk dc(clk50,clk1); // 模块调用,50MHz -> 1Hz
// clk1,上升沿触发;key,异步信号,高电平有效
always@(posedge clk1,posedge key,posedge flagclk,posedge up,posedge down)
begin
// 异步复位
if(key)
begin
hour=0;
minutes=0;
seconds=0;
// 直接输出,方便观察检验结果
// 若连接7段管,输出信号用任务 dec_out 转换即可
// dec_out(输入:十进制数 , 输出:7位二进制数值,对应7段管显示)
// 例:dec_out(hour/10,out5);
out5=hour/10;
out4=hour%10;
out3=minutes/10;
out2=minutes%10;
out1=seconds/10;
out0=seconds%10;
end
else if(flagclk)//设置
begin
flag=(flag+1)%4;
end
else if(up)
begin
if(flag==1)
begin
if(hour<23) hour=hour+1;
else hour=0;
end
if(flag==2)
begin
if(minutes<59) minutes=minutes+1;
else minutes=0;
end
if(flag==3)
begin
if(seconds<59) seconds=seconds+1;
else seconds=0;
end
out5=hour/10;
out4=hour%10;
out3=minutes/10;
out2=minutes%10;
out1=seconds/10;
out0=seconds%10;
end
else if(down)
begin
if(flag==1)
begin
if(hour>0) hour=hour-1;
else hour=23;
end
if(flag==2)
begin
if(minutes>0) minutes=minutes-1;
else minutes=59;
end
if(flag==3)
begin
if(seconds>0) seconds=seconds-1;
else seconds=59;
end
out5=hour/10;
out4=hour%10;
out3=minutes/10;
out2=minutes%10;
out1=seconds/10;
out0=seconds%10;
end
// 计数
else
begin
if(seconds<59) seconds=seconds+1;
else
begin
if(seconds==59)
begin
seconds=0;
if(minutes<59) minutes=minutes+1;
else
begin
if(minutes==59)
begin
minutes=0;
if(hour<23) hour=hour+1;
else
begin
if(hour==23) hour=0;
end
end
end
end
end
// 直接输出,方便观察检验结果
// 若连接7段管,输出信号用任务 dec_out 转换即可
// dec_out(输入:十进制数 , 输出:7位二进制数值,对应7段管显示)
// 例:dec_out(hour/10,out5);
out5=hour/10;
out4=hour%10;
out3=minutes/10;
out2=minutes%10;
out1=seconds/10;
out0=seconds%10;
end
end
// 七段管十进制数显示:将十进制数转换为七段管显示所对应的电平信号
task dec_out;
input integer decc; // 输入,十进制数
output reg[6:0] outt; // 输出,7位二进制数值
if(decc==0) outt=7'b1000000; // 七段管显示0
else if(decc==1) outt=7'b1111001; // 七段管显示1
else if(decc==2) outt=7'b0100100; // 七段管显示2
else if(decc==3) outt=7'b0110000; // 七段管显示3
else if(decc==4) outt=7'b0011001; // 七段管显示4
else if(decc==5) outt=7'b0010010; // 七段管显示5
else if(decc==6) outt=7'b0000010; // 七段管显示6
else if(decc==7) outt=7'b1111000; // 七段管显示7
else if(decc==8) outt=7'b0000000; // 七段管显示8
else if(decc==9) outt=7'b0011000; // 七段管显示9
else outt=7'b1111111; // 七段管不显示
endtask
endmodule
// **分频电路模块 50MHz -> 1Hz**
// 50MHz = 2*10^-8 s = 20ns
// 1Hz = 1s
// 1s/20ns = 5*10^7,即1Hz信号的一个周期包含50MHz信号的5*10^7个周期
// (5*10^7)/2 = 25000000,产生1Hz信号时,每过25000000个周期翻转一次
module div_clk(clk50,clk1);
input clk50; // clk50:输入的50MHz信号
output reg clk1=1; // clk1: 产生的1Hz信号,赋初始值为1
integer i=0; // 50MHz频率下,周期计数器
always@(posedge clk50) // clk50上升沿触发
begin
if(i==250) // 每过25000000个周期
begin
i=0;
clk1=~clk1; // clk1翻转
end
else i=i+1;
end
endmodule
测试模块代码:
// Copyright (C) 2017 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions
// and other software and tools, and its AMPP partner logic
// functions, and any output files from any of the foregoing
// (including device programming or simulation files), and any
// associated documentation or information are expressly subject
// to the terms and conditions of the Intel Program License
// Subscription Agreement, the Intel Quartus Prime License Agreement,
// the Intel FPGA IP License Agreement, or other applicable license
// agreement, including, without limitation, that your use is for
// the sole purpose of programming logic devices manufactured by
// Intel and sold by Intel or its authorized distributors. Please
// refer to the applicable agreement for further details.
// *****************************************************************************
// This file contains a Verilog test bench template that is freely editable to
// suit user's needs .Comments are provided in each section to help the user
// fill out necessary details.
// *****************************************************************************
// Generated on "04/07/2022 11:09:36"
// Verilog Test Bench template for design : Ktcllo
//
// Simulation tool : ModelSim-Altera (Verilog)
//
`timescale 1 ps/ 1 ps
module Ktcllo_vlg_tst();
// constants
// general purpose registers
reg eachvec;
// test vector input registers
reg clk50;
reg down;
reg flagclk;
reg key;
reg up;
// wires
wire clk1;
wire [6:0] out0;
wire [6:0] out1;
wire [6:0] out2;
wire [6:0] out3;
wire [6:0] out4;
wire [6:0] out5;
// assign statements (if any)
Ktcllo i1 (
// port map - connection between master ports and signals/registers
.clk1(clk1),
.clk50(clk50),
.down(down),
.flagclk(flagclk),
.key(key),
.out0(out0),
.out1(out1),
.out2(out2),
.out3(out3),
.out4(out4),
.out5(out5),
.up(up)
);
parameter DELAY=20;
// 半个周期翻转一次
always #(DELAY/2) clk50=~clk50;
initial
begin
// code that executes only once
// insert code here --> begin
// --> end
up=0;down=0;
key=0;
clk50=0;
flagclk=0;
$display("Running testbench");
end
always
// optional sensitivity list
// @(event1 or event2 or .... eventn)
begin
// code executes for every event on sensitivity list
// insert code here --> begin
$monitor($realtime,,,"%d %d : %d %d : %d %d",out5,out4,out3,out2,out1,out0);
@eachvec;
// --> end
end
endmodule
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)