CQU digital logic experiment 2 – verilog digital clock source code and constraint files

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