Some ideas are collected from various materials, and there are also some optimizations. I may modify the code in the future, such as using modular arithmetic for optimization. Hours are LED lights
The source files are as follows:
`timescale 1ns / 1ps // //Company: // Engineer: // // Create Date: 2023/10/24 10:57:00 // Design Name: // Module Name: digit_clock // Project Name: // Target Devices: //Tool Versions: // Description: // //Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // // module digit_clock(clk, rst,segs, en,dot,led,add_sec,add_min,add_hour); input clk; //clk is connected to the system default clock signal, the frequency is 100MHz input rst; //reset key input add_sec; input add_min; input add_hour; output reg [6:0]segs; output reg [3:0]en; //enable signal output reg dot; //decimal point output reg [4:0] led;//hour wire [1:0] s; //Select variables, used to determine enable and which digital tubes need to be refreshed each time the digital tube is refreshed reg [3:0] digit; //Used to pass the signal generated by timing reg [26:0] clk_cnt=0; //Counting variable, records the number of clk times, and returns to zero when it reaches 1s reg [6:0] second; //Second, [6:4] records the tens digit of the second, [3:0] records the units digit of the second reg [6:0] minute; //minute, same as second reg [4:0] hour=0; //When, due to the number of digital tubes, no display is performed assign s=clk_cnt[19:18]; always@(*) //Enable, decide which ports to enable based on the s signal begin en=4'b1111; en[s]=0;//Whenever clk_cnt=10000_0000, the corresponding s=0(2'b00) end always@(posedge clk or posedge rst or posedge add_sec or posedge add_min or posedge add_hour ) begin if(rst) begin//Reset signal, variable when 0, immutable when 1 clk_cnt=0; second=0; minute=0; hour=0; end else if(clk_cnt==10000_0000) begin//Here is the clock signal. Since a cycle of clk is 10 nanoseconds, which corresponds to 10^(-8) seconds, you need to reach 10^8 before you can operate it. clk_cnt=0;//Reset to zero if(add_sec & amp; & amp; second[3:0]<9) second[3:0]=second[3:0] + 1; if(add_min & amp; & amp; minute[3:0]<9) minute[3:0]=minute[3:0] + 1; if(add_hour ) hour=hour + 1; if(hour>=24) hour=0; if(second[3:0]!=9) begin second[3:0]=second[3:0] + 1; end//Since second[3:0] records the units digit of the second, and the maximum value is 9, it is automatically incremented when it is less than 9, and it needs to be carried out and reset to zero when it is equal to 9. else begin if(second[6:4]!=5) second[6:4]=second[6:4] + 1;//The tens digit of second also requires carry (carrying into 1 every 6), so it is the same as the above operation similar else begin if(minute[3:0]!=9) minute[3:0]=minute[3:0] + 1; //Same as above else begin if(minute[6:4]!=5) minute[6:4]=minute[6:4] + 1; else begin hour=hour + 1; minute[6:4]=0; end minute[3:0]=0; end second[6:4]=0; end second[3:0]=0; end end else clk_cnt=clk_cnt + 1; //Continue counting end always@(*) //Determine the position case(s) 2'b00: begin digit=second[3:0]; dot=1; led=hour; end //The units digit of seconds 2'b01: begin digit=second[6:4]; dot=1; led=hour; end //The tenth digit of the second 2'b10: begin digit=minute[3:0]; dot=0; led=hour; end //The units digit of the minute. Note here that if dot is always 1, there will be some problems, that is, dot cannot be displayed. , guess the reason (if the points need to be modified, en corresponds to 4'b1011 at this time, this position is also the position of dot, modification will cause dot to become invalid) 2'b11: begin digit=minute[6:4]; dot=1; led=hour; end //The tens digit of minute default: begin digit=second[3:0]; led=hour; end endcase always@(*) case(digit)//According to the digital tube schematic diagram 4'h0:segs=7'b0000001; 4'h1:segs=7'b1001111; 4'h2:segs=7'b0010010; 4'h3:segs=7'b0000110; 4'h4:segs=7'b1001100; 4'h5:segs=7'b0100100; 4'h6:segs=7'b0100000; 4'h7:segs=7'b0001111; 4'h8:segs=7'b0000000; 4'h9:segs=7'b0000100; default:segs=7'b0000001; endcase endmodule
constraint file
set_property SEVERITY {Warning} [get_drc_checks UCIO-1] set_property IOSTANDARD LVCMOS33 [get_ports clk] set_property IOSTANDARD LVCMOS33 [get_ports dot] set_property IOSTANDARD LVCMOS33 [get_ports rst] #set_property IOSTANDARD LVCMOS33 [get_ports {led[]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[4]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {en[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {en[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {en[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {en[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {segs[6]}] set_property IOSTANDARD LVCMOS33 [get_ports {segs[5]}] set_property IOSTANDARD LVCMOS33 [get_ports {segs[4]}] set_property IOSTANDARD LVCMOS33 [get_ports {segs[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {segs[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {segs[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {segs[0]}] set_property IOSTANDARD LVCMOS33 [get_ports add_sec] set_property IOSTANDARD LVCMOS33 [get_ports add_min] set_property IOSTANDARD LVCMOS33 [get_ports add_hour] set_property PACKAGE_PIN W5 [get_ports clk] set_property PACKAGE_PIN V7 [get_ports dot] set_property PACKAGE_PIN V17 [get_ports rst] set_property PACKAGE_PIN R2 [get_ports add_sec] set_property PACKAGE_PIN T1 [get_ports add_min] set_property PACKAGE_PIN U1 [get_ports add_hour] set_property PACKAGE_PIN U3 [get_ports {led[0]}] set_property PACKAGE_PIN P3 [get_ports {led[1]}] set_property PACKAGE_PIN N3 [get_ports {led[2]}] set_property PACKAGE_PIN P1 [get_ports {led[3]}] set_property PACKAGE_PIN L1 [get_ports {led[4]}] set_property PACKAGE_PIN U2 [get_ports {en[0]}] set_property PACKAGE_PIN U4 [get_ports {en[1]}] set_property PACKAGE_PIN V4 [get_ports {en[2]}] set_property PACKAGE_PIN W4 [get_ports {en[3]}] set_property PACKAGE_PIN W7 [get_ports {segs[6]}] set_property PACKAGE_PIN W6 [get_ports {segs[5]}] set_property PACKAGE_PIN U8 [get_ports {segs[4]}] set_property PACKAGE_PIN V8 [get_ports {segs[3]}] set_property PACKAGE_PIN U5 [get_ports {segs[2]}] set_property PACKAGE_PIN V5 [get_ports {segs[1]}] set_property PACKAGE_PIN U7 [get_ports {segs[0]}]
Demonstration is as follows