目录
1.课题概述
基于FPGA的电子万年历系统开发,包含各模块testbench。主要包含以下核心模块:
时钟控制模块:提供系统基准时钟和计时功能。
日历计算模块:处理年月日的计算和闰年判断。
秒表模块:实现精确到 0.01 秒的计时功能。
2.系统仿真结果
FPGA仿真测试
当输入的i_run信号为1的时候,秒表开始运行,从上面我们可以看到最高位Num6的计数结果,其余几位由于速度很快,所以被缩小了,看不清楚,当i_set为1的时候,秒表暂停。
这个模块主要是一个以秒为计数单位的计数器,秒计数满60,分累加1,分计数满60的时候,小时累加1,小时计数满24的时候,产生一个时钟信号,用来确定日期加1。
这个模块主要是一个计数器,当计数器计数到24小时的时候,年月日模块计数器会自动加1,表示日期往前累积1日。
这里我们分两个小模块来设计,一个是日月模块,一个是年模块,当计数器计数到12月31日的时候,那么年模块则进一。即年份增加一。
3.核心程序与模型
版本:vivado2022.2
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 14:45:46 04/09/2014
// Design Name:
// Module Name: tops
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module tops(
i_clk,
i_rst,
i_Function_Controller,
i_sel,
i_set,
i_run,
o_Num1,
o_Num2,
o_Num3,
o_Num4,
o_Num5,
o_Num6,
o_Num7,
o_Num8
);
input i_clk;
input i_rst;
input[1:0] i_Function_Controller;
input i_sel;
input i_set;
input i_run;
output[3:0]o_Num1;
output[3:0]o_Num2;
output[3:0]o_Num3;
output[3:0]o_Num4;
output[3:0]o_Num5;
output[3:0]o_Num6;
output[3:0]o_Num7;
output[3:0]o_Num8;
wire Clock_mb;
wire Clock;
clock_div clock_div_u(
.i_clk (i_clk),
.i_rst (i_rst),
.i_sel (1'b0),
.o_clock1 (Clock_mb),
.o_clock2 (Clock)
);
//======================================================================
wire CLK_Year;
wire[3:0]ym_Num1;
wire[3:0]ym_Num2;
wire[3:0]ym_Num3;
wire[3:0]ym_Num4;
wire[3:0]ym_Num5;
wire[3:0]ym_Num6;
wire[3:0]ym_Num7;
wire[3:0]ym_Num8;
year_month year_month_u(
.i_clk (CLK_Year),
.i_rst (i_rst),
.i_sel (i_sel),
.i_set (i_set),
.o_Num1 (ym_Num1),
.o_Num2 (ym_Num2),
.o_Num3 (ym_Num3),
.o_Num4 (ym_Num4),
.o_Num5 (ym_Num5),
.o_Num6 (ym_Num6),
.o_Num7 (ym_Num7),
.o_Num8 (ym_Num8)
);
//======================================================================
wire[3:0]tm_Num1;
wire[3:0]tm_Num2;
wire[3:0]tm_Num3;
wire[3:0]tm_Num4;
wire[3:0]tm_Num5;
wire[3:0]tm_Num6;
wire[3:0]tm_Num7;
wire[3:0]tm_Num8;
times times_u(
.i_clk (Clock),
.i_rst (i_rst),
.i_run (i_run),
.i_sel (i_sel),
.i_set (i_set),
.o_Num1 (tm_Num1),
.o_Num2 (tm_Num2),
.o_Num3 (tm_Num3),
.o_Num4 (tm_Num4),
.o_Num5 (tm_Num5),
.o_Num6 (tm_Num6),
.o_CLK_Year (CLK_Year),
.CNT ()
);
assign tm_Num7 = 4'd0;
assign tm_Num8 = 4'd0;
//======================================================================
wire[3:0]mb_Num1;
wire[3:0]mb_Num2;
wire[3:0]mb_Num3;
wire[3:0]mb_Num4;
wire[3:0]mb_Num5;
wire[3:0]mb_Num6;
wire[3:0]mb_Num7;
wire[3:0]mb_Num8;
miaobiao miaobiao_u(
.i_clk (Clock_mb),
.i_rst (i_rst),
.i_run (i_run),
.i_pause (i_set),
.i_clear (i_sel),
.o_Num1 (mb_Num1),
.o_Num2 (mb_Num2),
.o_Num3 (mb_Num3),
.o_Num4 (mb_Num4),
.o_Num5 (mb_Num5),
.o_Num6 (mb_Num6)
);
assign mb_Num7 = 4'd0;
assign mb_Num8 = 4'd0;
//=====================================================================
reg[3:0]o_Num1;
reg[3:0]o_Num2;
reg[3:0]o_Num3;
reg[3:0]o_Num4;
reg[3:0]o_Num5;
reg[3:0]o_Num6;
reg[3:0]o_Num7;
reg[3:0]o_Num8;
always @(posedge i_clk or posedge i_rst)
begin
if(i_rst)
begin
o_Num1 <= 4'd0;
o_Num2 <= 4'd0;
o_Num3 <= 4'd0;
o_Num4 <= 4'd0;
o_Num5 <= 4'd0;
o_Num6 <= 4'd0;
o_Num7 <= 4'd0;
o_Num8 <= 4'd0;
end
else begin
if(i_Function_Controller == 2'b00)
begin
o_Num1 <= ym_Num1;
o_Num2 <= ym_Num2;
o_Num3 <= ym_Num3;
o_Num4 <= ym_Num4;
o_Num5 <= ym_Num5;
o_Num6 <= ym_Num6;
o_Num7 <= ym_Num7;
o_Num8 <= ym_Num8;
end
if(i_Function_Controller == 2'b01)
begin
o_Num1 <= tm_Num1;
o_Num2 <= tm_Num2;
o_Num3 <= tm_Num3;
o_Num4 <= tm_Num4;
o_Num5 <= tm_Num5;
o_Num6 <= tm_Num6;
o_Num7 <= tm_Num7;
o_Num8 <= tm_Num8;
end
if(i_Function_Controller == 2'b11)
begin
o_Num1 <= mb_Num1;
o_Num2 <= mb_Num2;
o_Num3 <= mb_Num3;
o_Num4 <= mb_Num4;
o_Num5 <= mb_Num5;
o_Num6 <= mb_Num6;
o_Num7 <= mb_Num7;
o_Num8 <= mb_Num8;
end
end
end
endmodule
00X6_004m
4.系统原理简介
系统顶层框图如下:
1.该系统的基本功能
时钟显示:时、分(24 小时制)
日历显示:年、月、日
秒表功能:精确到 0.01 秒,支持开始 / 暂停 / 复位
2.模式切换功能
我们的控制输入有5个脚,分析功能如下所示:
i_Function_Controller=0;显示年月日
i_sel:选择需要调整的某位数字。
i_set:计数器,调整需要调整的位置的数字。
具体调整的时候,首先选择i_sel,按键按一下,需要调整的位置会移动一次,然后移动到需要调整的位置上,然后松开i_sel,然后按下i_set,调整显示的数字。
i_run:不使用
i_Function_Controller=1;显示时间,小时,分,秒
i_sel:
i_set:
i_run:
正常工作的时候,上面三个设置分别输入0,0,1
当需要调整时间的时候,设置i_run=0,然后设置i_sel,选择对应的需要调整的数字位,然后设置i_set,设置具体的值,其中秒位置,如果设置i_set。那么秒直接清零。
注意,因为时间部分计数到24小时的时候,年月日才被加1,所以在年月日这里i_run不使用,他是靠日期模块来驱动的。
i_Function_Controller=3;秒表的控制
i_sel:清零
i_set:暂停
i_run:开始秒表计时
5.完整工程文件
v