当前位置:   article > 正文

【veriog】正向计时器设计(FPGA,秒表,时钟,正向计时)_fpga程序如何实现计时

fpga程序如何实现计时

硬件部分

使用6位8段数码管将时间值显示出来

设计思路

将时间拆分为6个参数:

        s1  -> 秒个位
        s10 -> 秒十位
        m1  -> 分个位
        m10 -> 分十位
        h1;   -> 时个位
        h10;  -> 时十位
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在异步复位的时候为上述六个参数赋初始值。
然后对50Mhz系统时钟进行计数,计数50M次(即为1s)。然后对六个参数的当前值做出判断,并在下一个clk做出改变。

当计满1s,判断当前各h、m、s,的数值
-控制s个位:
若(s个位>=0 <9) s个位+1 
-控制s十位:
若(s个位=9 s十位>=0 <5)s个位清0 s十位+1 
-控制m个位:
若(s个位=9 s十位=5,(m个位>=0 <9)s个位清0 s十位清0 若m个位+1
-控制m十位:
若(s个位=9 s十位=5 )(m个位=9,m十位>=0 <5 )s个位清0 s十位清0 m个位归0 m十位+1
-控制h个位:
分为两种情况:
1、若(s个位=9 s十位=5 )(m个位=9,m十位=5 )(h个位>=0 <9 且 h十位 >=0 < 2 )m十位清0 			
   s个位清0 s十位清0 m个位清0  h个位+1  
2、若(s个位=9 s十位=5 )(m个位=9,m十位=5 )(h个位>=0 <3 且 h十位 = 2)
   s个位清0 s十位清0 m个位清0 m十位清0 h个位+1 
-控制h十位:
(s个位=9 s十位=5 )(m个位=9,m十位=5 )(h个位=9 且 十位>=0 <2)
 s个位清0 s十位清0 m个位清0 m十位清0 h个位清0 h十位+1
-若当前时间为: 23:59:59 
 置为00:00:00
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

代码(verilog)

顶层模块(连接计时器与数码管)

module top(
				clk,
				rst,
				dig,
                dict
				);
    input clk;
    input rst;
    output  [5:0] dig;  //六个数码管片选
    output  [7:0] dict; //动态数码管段选
    
    wire [23:0] set_data;//数码管显示的内容:4bit*6 

        clock f1(
					.clk(clk),
					.rst(rst),
					.s1(set_data[3:0]),
					.s10(set_data[7:4]),
					.m1(set_data[11:8]),
					.m10(set_data[15:12]),
					.h1(set_data[19:16]),
					.h10(set_data[23:20])
					);
                
        dig8_6 f2(
                 .clk(clk),
                 .rst(rst),
                 .set_data(set_data),
                 .dig(dig), 
                 .dict(dict)
               );
               
            
endmodule


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

计时器模块

module clock(
					clk,
					rst,
					s1,
					s10,
					m1,
					m10,
					h1,
					h10
					);

	input clk;
	input rst;
	output reg[3:0] s1;
	output reg[3:0] s10;
	output reg[3:0] m1;
	output reg[3:0] m10;
	output reg[3:0] h1;
	output reg[3:0] h10;
	
	reg [31:0] cnt; 
	
	always@(posedge clk or negedge rst)
	begin
		if(!rst)
			begin
			
				cnt <= 32'd0;
				
				s1 <= 4'd0;
				s10 <= 4'd5;
                m1 <= 4'd9;
				m10 <= 4'd5;
                h1 <= 4'd3;
                h10 <= 4'd2; //初始时间我设置为了23:59:50
			end
//s1++ : 当计满1s 且(s个位>=0 <9) s个位+1 计数器归0
		else if(cnt == 32'd50000000 && s1 >= 4'd0 && s1 < 4'd9 ) 
			begin 	
				s1 <= s1 + 1'd1;
				cnt <= 32'd0;
			end
//s10++ : 当计满1s 且(s个位=9 s十位>=0 <5)s个位清0 s十位+1 计数器归0
		else if(cnt == 32'd50000000 && s1 == 4'd9 && s10 >= 4'd0 && s10 < 4'd5) 
				begin	
					s1 <= 1'd0;
					s10 <= s10 + 1'd1;
					cnt <= 32'd0;
				end
//m1++ :当计满1s 且(s个位=9 s十位=5 )s个位清0 s十位清0 
//      若(m个位>=0 <9)m个位+1 计数器归0
		else if(cnt == 32'd50000000 && s1 == 4'd9 && s10 == 4'd5 && m1 >= 4'd0 && m1 < 4'd9) 
				begin	
					s1 <= 1'd0;
					s10 <= 1'd0;
					m1 <= m1 + 1'd1;
					cnt <= 32'd0;
				end
//m10++ : 计满1s 且(s个位=9 s十位=5 )s个位清0 s十位清0
//        若(m个位=9,m十位>=0 <5 )m个位归0 m十位+1 计数器归0
		else if(cnt == 32'd50000000 && s1 == 4'd9 && s10 == 4'd5 && m1 == 4'd9 && m10 >= 4'd0 && m10 < 4'd5) 
				begin	
					s1 <= 1'd0;
					s10 <= 1'd0;
					m1 <= 1'd0;
					m10 <= m10 + 1'd1;
					cnt <= 32'd0;
				end
//h1 ++ 分为两种情况:
//1、计满1s 且(s个位=9 s十位=5 )(m个位=9,m十位=5 )s个位清0 s十位清0 m个位清0 m十位清0 			
//   若(h个位>=0 <9 且 h十位 >=0 < 2 )h个位+1 计数器归0  
//2、计满1s 且(s个位=9 s十位=5 )(m个位=9,m十位=5 )s个位清0 s十位清0 m个位清0 m十位清0 
//   若(h个位>=0 <3 且 h十位 = 2) h个位+1 计数器归0
		else if(cnt == 32'd50000000 && s1 == 4'd9 && s10 == 4'd5 && m1 == 4'd9 && m10 == 4'd5 && h1 >= 4'd0 && h1 < 4'd9 && h10 >= 4'd0 && h10 < 4'd2) 
		begin	
			s1 <= 1'd0;
			s10 <= 1'd0;
			m1 <= 1'd0;
			m10 <= 1'd0;
			h1 <= h1 + 1'd1;
			cnt <= 32'd0;
		end
		else if(cnt == 32'd50000000 && s1 == 4'd9 && s10 == 4'd5 && m1 == 4'd9 && m10 == 4'd5 && h1 >= 4'd0 && h1 < 4'd3 && h10 == 4'd2) 
		begin	
			s1 <= 1'd0;
			s10 <= 1'd0;
			m1 <= 1'd0;
			m10 <= 1'd0;
			h1 <= h1 + 1'd1;
			cnt <= 32'd0;
		end
//h10 ++ : 计满1s 且(s个位=9 s十位=5 )(m个位=9,m十位=5 )s个位清0 s十位清0 m个位清0 m十位清0 
//         若(h个位=9 且 十位>=0 <2)h个位清0 h十位+1 计数器归0
		else if(cnt == 32'd50000000 && s1 == 4'd9 && s10 == 4'd5 && m1 == 4'd9 && m10 == 4'd5 && h1 == 4'd9 && h10 >= 4'd0 && h10 < 4'd2) 

		begin	
			s1 <= 1'd0;
			s10 <= 1'd0;
			m1 <= 1'd0;
			m10 <= 1'd0;
			h1 <= 1'd0;
			h10 <= h10 + 1'd1;
			cnt <= 32'd0;
		end
//23:59:59
//计满1s 且(s个位=9 s十位=5)(m个位=9,m十位=5)(h个位=3,十位=2)
//s个位置0 s十位清0 m个位清0 m十位清0 若h个位清0 h十位清
//计数器归0
		else if(cnt == 32'd50000000 && s1 == 4'd9 && s10 == 4'd5 && m1 == 4'd9 && m10 == 4'd5 && h1 == 4'd3 && h10 == 4'd2) 
		begin	
			s1 <= 1'd0;
			s10 <= 1'd0;
			m1 <= 1'd0;
			m10 <= 1'd0;
			h1 <= 1'd0;
			h10 <= 0;
			cnt <= 32'd0;
		end
//cnt ++ 
		else 
			cnt <= cnt + 1'b1;
	end  
	endmodule
	

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125

数码管显示模块

(数码管的驱动见:链接

testbench*(单独对计时器模块进行测试)

需要将计时器模块设为顶层,在测试时,需要将cnt计数值调低 以便观察!!!

`timescale 1ns/1ns
`define clk_period 20

module tb;

	reg clk;
	reg rst;
	
	wire [3:0] s1;
	wire [3:0] s10;
	wire [3:0] m1;
	wire [3:0] m10;
	wire [3:0] h1;
	wire [3:0] h10;
	
	clock clock1(
					.clk(clk),
					.rst(rst),
					.s1(s1),
					.s10(s10),
					.m1(m1),
					.m10(m10),
					.h1(h1),
					.h10(h10)
					);
					
	initial clk = 1'd0;
	always #10 clk = ~ clk;
	
	initial begin
		rst = 1'b0;
		#(`clk_period*20)
		rst = 1'b1;
		#(`clk_period)
		
		#20000000;
		
		$stop;
	end 
	
	endmodule 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

波形图

在这里插入图片描述
在这里插入图片描述

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号