数字逻辑大作业:FPGA数字钟实验

题目

使用SystemVerilog实现一个数字钟。
要求:
(1)能够显示时分秒;
(2)能够设置开始时间;
(3)使用你自己的7段数码管显示译码电路实现;
(4)可以使用动态显示方法实现;
(5)依据实现的其他附加功能,酌情加分:秒表、倒计时、闹钟…
(6)需要在Basys3 FPGA开发板上实现

解决方案

本解决方案参考@Hellsegamosken[SystemVerilog] 基于 FPGA 的数字钟设计,并在其基础上进行修改。

clock.sv

module clock
    (
    input logic clk_pre,TU, TL, TC, TD,TR,
	input logic T1, T2, T3, T4, T15, T16,
	output logic [10:0] segments,
	output logic alarm_light, down_light,ontime_light
    );

// Control signals for different modes
logic mode1, mode2, mode3, mode4;
// Display variables for digits A and B
logic [3:0] disp_A0, disp_A1, disp_B0, disp_B1;
// Clock variables
logic [3:0] h0 = 4'b0000, h1 = 4'b0000, m0 = 4'b0000, m1 = 4'b0000, s0 = 4'b0000, s1 = 4'b0000; 
// Alarm variables
logic [3:0] ah0 = 4'b0000, ah1 = 4'b0000, am0 = 4'b0000, am1 = 4'b0000, as0 = 4'b0000, as1 = 4'b0000; 
// Countdown variables
logic [3:0] dh0 = 4'b0000, dh1 = 4'b0000, dm0 = 4'b0000, dm1 = 4'b0000, ds0 = 4'b0000, ds1 = 4'b0000;
// Stopwatch variables
logic [3:0] ch0 = 4'b0000, ch1 = 4'b0000, cm0 = 4'b0000, cm1 = 4'b0000, cs0 = 4'b0000, cs1 = 4'b0000; 
integer disp_pos = 0,set_pos = 0;
logic clk_sec = 1'b0, clk_centi = 1'b0, clk_disp = 1'b0;

// Enumeration for different modes
typedef enum integer {
   MAIN, ALARM, COUNT, DOWN,ONTIME} ModeType;
// Enumeration for display control
typedef enum logic {
   LOW, HIGH} DispType;
// Enumeration for hand control
typedef enum logic {
   OFF, ON} HandType;
ModeType mode = MAIN;
DispType DISP = LOW;
logic hand = OFF;
integer alarm_time = 0, down_time = 0,ontime_time=0;
logic down_sig = 1'b1, alarm_sig = 1'b1, ontime_sig = 1'b1, counting = 1'b0;

// Control module
// Temporary variables to handle button debouncing
logic tmpU1, tmpU2, tmpU3, UP;
logic tmpL1, tmpL2, tmpL3, LEFT;
logic tmpR1, tmpR2, tmpR3, RIGHT;
logic tmpC1, tmpC2, tmpC3, CENTER;
logic tmpD1, tmpD2, tmpD3, RESET;
// Eliminate button debounce
always_ff @ (posedge clk_centi) begin 
	tmpU3 <= tmpU2;
	tmpU2 <= tmpU1;
	tmpU1 <= TU;

	tmpL3 <= tmpL2;
	tmpL2 <= tmpL1;
	tmpL1 <= TL;

	tmpR3 <= tmpR2;
	tmpR2 <= tmpR1;
	tmpR1 <= TR;

	tmpC3 <= tmpC2;
	tmpC2 <= tmpC1;
	tmpC1 <= TC;

	tmpD3 <= tmpD2;
	tmpD2 <= tmpD1;
	tmpD1 <= TD;
end

// Decode input signals to determine current mode and other information
always_comb begin
	if (T16) hand = ON;
	else hand = OFF;
	
	if (T1) begin mode = ALARM; {
   mode1, mode2, mode3, mode4} = 4'b1000; end
	else if (T2) begin mode = COUNT; {
   mode1, mode2, mode3, mode4} = 4'b0100; end
	else if (T3) begin mode = DOWN; {
   mode1, mode2, mode3, mode4} = 4'b0010; end
	else if (T4) begin mode = ONTIME; {
   mode1, mode2, mode3, mode4} = 4'b0000; end
	else begin  mode = MAIN; {
   mode1, mode2, mode3, mode4} = 4'b0000; end

	if (T15) DISP = HIGH;
	else DISP = LOW;

	UP = tmpU1 & tmpU2 & tmpU3;
	LEFT = tmpL1 & tmpL2 & tmpL3;
	RIGHT = tmpR1 & tmpR2 & tmpR3;
	CENTER = tmpC1 & tmpC2 & tmpC3;
	RESET = tmpD1 & tmpD2 & tmpD3;
end

// Main logic to handle clock/stopwatch increment and time settings
integer cnt_sec = 0, cnt_centi = 0, cnt_disp = 0, cnt_flip = 0;
// logic clk_sec = 1'b0, clk_centi = 1'b0, clk_disp = 1'b0;
logic flip = 1'b1;
logic jw_d = 1'b0, jw_m = 1'b0, jw_y = 1'b0;
logic prehand = 1'b0, preleft = 1'b0,preright = 1'b0, preup = 1'b0, predown_sig = 1'b0, prealarm_sig = 1'b0, preontime_sig = 1'b0, precenter, prereset;

always_ff @ (posedge clk_pre) begin
	cnt_sec <= cnt_sec + 1;
	cnt_centi <= cnt_centi + 1;
	cnt_disp <= cnt_disp + 1;
	cnt_flip <= cnt_flip + 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值