用Verilog实现七段管可调计时器

举报
nimo的小舔狗 发表于 2022/04/19 18:22:16 2022/04/19
【摘要】 七段管可调计时器

设计思路

在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

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。