From 23eb5ae24c3390a0752507b8eab35533e0c6b57e Mon Sep 17 00:00:00 2001 From: filipriec skolsky PC Date: Mon, 13 Apr 2026 17:29:48 +0200 Subject: [PATCH] its now working perfectly well with HH:MM and MM:SS to switch between them via button --- .../imports/Downloads/Basys-3-Master.xdc | 2 +- .../sources_1/new/clock_logic.vhd | 178 +++++++++++++++ .../project_5.srcs/sources_1/new/counter.vhd | 13 +- .../sources_1/new/display_drive.vhd | 72 ++++++ .../sources_1/new/top_modul.vhd | 213 ++++-------------- project_7/project_5.xpr | 12 + 6 files changed, 315 insertions(+), 175 deletions(-) create mode 100644 project_7/project_5.srcs/sources_1/new/clock_logic.vhd create mode 100644 project_7/project_5.srcs/sources_1/new/display_drive.vhd diff --git a/project_7/project_5.srcs/constrs_1/imports/Downloads/Basys-3-Master.xdc b/project_7/project_5.srcs/constrs_1/imports/Downloads/Basys-3-Master.xdc index ff3d123..6e71daf 100644 --- a/project_7/project_5.srcs/constrs_1/imports/Downloads/Basys-3-Master.xdc +++ b/project_7/project_5.srcs/constrs_1/imports/Downloads/Basys-3-Master.xdc @@ -12,7 +12,7 @@ create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports CLK set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports {RST}] set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports {START}] -#set_property -dict { PACKAGE_PIN W16 IOSTANDARD LVCMOS33 } [get_ports {sw[2]}] +set_property -dict { PACKAGE_PIN W16 IOSTANDARD LVCMOS33 } [get_ports {SW_MODE}] #set_property -dict { PACKAGE_PIN W17 IOSTANDARD LVCMOS33 } [get_ports {sw[3]}] #set_property -dict { PACKAGE_PIN W15 IOSTANDARD LVCMOS33 } [get_ports {sw[4]}] #set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports {sw[5]}] diff --git a/project_7/project_5.srcs/sources_1/new/clock_logic.vhd b/project_7/project_5.srcs/sources_1/new/clock_logic.vhd new file mode 100644 index 0000000..8c047e6 --- /dev/null +++ b/project_7/project_5.srcs/sources_1/new/clock_logic.vhd @@ -0,0 +1,178 @@ +-- clock_logic.vhd + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +--use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity clock_logic is + Port ( + CLK : in STD_LOGIC; + RST : in STD_LOGIC; + CE_1HZ : in STD_LOGIC; -- Enable signal from the divider + SW_DIN : in STD_LOGIC_VECTOR (3 downto 0); + BTN_LOAD : in STD_LOGIC_VECTOR (3 downto 0); + -- Outputs to the top module/display + S_UNITS : out STD_LOGIC_VECTOR (3 downto 0); + S_TENS : out STD_LOGIC_VECTOR (3 downto 0); + M_UNITS : out STD_LOGIC_VECTOR (3 downto 0); + M_TENS : out STD_LOGIC_VECTOR (3 downto 0); + H_UNITS : out STD_LOGIC_VECTOR (3 downto 0); + H_TENS : out STD_LOGIC_VECTOR (3 downto 0) + ); +end clock_logic; + + +architecture Behavioral of clock_logic is + component counter is + Generic ( MAX_LIMIT : STD_LOGIC_VECTOR(3 downto 0) := "1001" ); -- Default to 9 + Port ( CLK : in STD_LOGIC; + CE : in STD_LOGIC; + PE : in STD_LOGIC; + DIN : in STD_LOGIC_VECTOR(3 downto 0); + RST : in STD_LOGIC; + TC : out STD_LOGIC; + COUNT_OUT : out STD_LOGIC_VECTOR (3 downto 0)); + end component; + + -- Internal signals to connect the counters + signal sig_s_units, sig_s_tens : std_logic_vector(3 downto 0); + signal sig_m_units, sig_m_tens : std_logic_vector(3 downto 0); + signal sig_h_units, sig_h_tens : std_logic_vector(3 downto 0); + -- Carry signals (TC) + signal tc_su, tc_st, tc_mu, tc_mt, tc_hu : std_logic; + -- Reset for hours (to handle the 24 reset) + signal hour_reset : std_logic; + + -- Specific load enable signals that check for boundaries + signal load_h_tens, load_h_units : std_logic; + signal load_m_tens, load_m_units : std_logic; + + -- Internal signals for the "Safe" load triggers + signal safe_load_su, safe_load_st : std_logic; + signal safe_load_mu, safe_load_mt : std_logic; + signal safe_load_hu, safe_load_ht : std_logic; +begin + -- MINUTES CONSTRAINTS (Max 59) + load_m_units <= BTN_LOAD(0) when (SW_DIN <= "1001") else '0'; -- 0-9 + load_m_tens <= BTN_LOAD(1) when (SW_DIN <= "0101") else '0'; -- 0-5 + -- HOURS CONSTRAINTS (Max 23) + -- Rule A: Cannot load Tens > 2. + -- Rule B: If Tens is 2, cannot load Units > 3. + -- Rule C: If Units is > 3, cannot load Tens into 2. + load_h_tens <= BTN_LOAD(3) when ( + SW_DIN < "0010" or + (SW_DIN = "0010" and sig_h_units <= "0011") + ) else '0'; + + load_h_units <= BTN_LOAD(2) when ( + (sig_h_tens < "0010" and SW_DIN <= "1001") or + (sig_h_tens = "0010" and SW_DIN <= "0011") + ) else '0'; + + ------------------------------------------------------- + -- SECONDS SECTION + -- SECONDS UNITS (0-9) - Triggered by the 1Hz pulse + U_CNT_SEC_UNITS : counter + generic map ( MAX_LIMIT => "1001" ) -- do 9 + port map ( + CLK => CLK, RST => RST, CE => CE_1HZ, + PE => '0', DIN => "0000", -- Seconds usually don't need manual load + TC => tc_su, COUNT_OUT => sig_s_units + ); + + -- SECONDS TENS (0-5) - Triggered when Sec Units reach 9 + U_CNT_SEC_TENS : counter + generic map ( MAX_LIMIT => "0101" ) -- do 5 + port map ( + CLK => CLK, RST => RST, CE => tc_su, + PE => '0', DIN => "0000", + TC => tc_st, COUNT_OUT => sig_s_tens + ); + + ------------------------------------------------------- + -- MINUTES SECTION + + -- MINUTES UNITS (0-9) - When Seconds reach 59 + U_CNT_MIN_UNITS : counter + generic map ( MAX_LIMIT => "1001" ) -- do 9 + port map ( + CLK => CLK, + RST => RST, + CE => tc_st, + PE => load_m_units, + DIN => SW_DIN, + TC => tc_mu, + COUNT_OUT => sig_m_units + ); + + -- MINUTES TENS (0-5) + U_CNT_MIN_TENS : counter + generic map ( MAX_LIMIT => "0101" ) -- do 5 + port map ( + CLK => CLK, + RST => RST, + CE => tc_mu, + PE => load_m_tens, + DIN => SW_DIN, + TC => tc_mt, + COUNT_OUT => sig_m_tens + ); + + ------------------------------------------------------- + -- HOURS SECTION + -- If we are at 23:59:59, the next tick should reset hours + process(sig_h_tens, sig_h_units, tc_mt, RST) + begin + if RST = '1' then + hour_reset <= '1'; + elsif (sig_h_tens = "0010" and sig_h_units = "0011" and tc_mt = '1') then + hour_reset <= '1'; + else + hour_reset <= '0'; + end if; + end process; + + -- HOURS UNITS (0-9) + U_CNT_HOR_UNITS : counter + generic map ( MAX_LIMIT => "1001" ) -- To 9 + port map ( + CLK => CLK, + RST => hour_reset, + CE => tc_mt, + PE => load_h_units, + DIN => SW_DIN, + TC => tc_hu, + COUNT_OUT => sig_h_units + ); + + -- HOURS TENS (0-2) + U_CNT_HOR_TENS : counter + generic map ( MAX_LIMIT => "0010" ) -- To 2 + port map ( + CLK => CLK, + RST => hour_reset, + CE => tc_hu, + PE => load_h_tens, + DIN => SW_DIN, + TC => open, + COUNT_OUT => sig_h_tens + ); + + + -- Drive output ports + S_UNITS <= sig_s_units; + S_TENS <= sig_s_tens; + M_UNITS <= sig_m_units; + M_TENS <= sig_m_tens; + H_UNITS <= sig_h_units; + H_TENS <= sig_h_tens; +end Behavioral; diff --git a/project_7/project_5.srcs/sources_1/new/counter.vhd b/project_7/project_5.srcs/sources_1/new/counter.vhd index af82596..d39b0db 100644 --- a/project_7/project_5.srcs/sources_1/new/counter.vhd +++ b/project_7/project_5.srcs/sources_1/new/counter.vhd @@ -45,7 +45,9 @@ end counter; architecture Behavioral of counter is -- Internal signal to keep track of the current number - signal s_cnt : STD_LOGIC_VECTOR(3 downto 0) := "0000"; + signal s_cnt : STD_LOGIC_VECTOR(3 downto 0) := (others => '0'); + -- (others => '0') je to iste ako "0000" pre 4 bity. Ale narozdiel od hardcode + -- robi nuly cez vsetky bity, takze zalezi na pocte bitov rodica begin -- Main counting logic @@ -54,23 +56,18 @@ begin if rising_edge(CLK) then if RST = '1' then s_cnt <= "0000"; - TC <= '0'; -- Reset TC elsif PE = '1' then s_cnt <= DIN; - TC <= '0'; elsif CE = '1' then if s_cnt = MAX_LIMIT then - s_cnt <= "0000"; -- Reset to 0 when limit is hit - TC <= '1'; + s_cnt <= (others => '0'); -- Reset to 0 when limit is hit else s_cnt <= s_cnt + 1; -- Otherwise increment - TC <= '0'; end if; - else - TC <= '0'; end if; end if; end process; + TC <= '1' when (s_cnt = MAX_LIMIT and CE = '1') else '0'; COUNT_OUT <= s_cnt; diff --git a/project_7/project_5.srcs/sources_1/new/display_drive.vhd b/project_7/project_5.srcs/sources_1/new/display_drive.vhd new file mode 100644 index 0000000..9b11bc1 --- /dev/null +++ b/project_7/project_5.srcs/sources_1/new/display_drive.vhd @@ -0,0 +1,72 @@ +-- display_drive.vhd + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +--use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity display_driver is + Port ( + CLK : in STD_LOGIC; -- Connect to 400Hz signal + RST : in STD_LOGIC; + -- The four BCD digits from your counters + DIGIT_0 : in STD_LOGIC_VECTOR (3 downto 0); + DIGIT_1 : in STD_LOGIC_VECTOR (3 downto 0); + DIGIT_2 : in STD_LOGIC_VECTOR (3 downto 0); + DIGIT_3 : in STD_LOGIC_VECTOR (3 downto 0); + -- Physical outputs to the FPGA pins + SEGMENTS : out STD_LOGIC_VECTOR (7 downto 0); + ANODES : out STD_LOGIC_VECTOR (3 downto 0) + ); +end display_driver; + +architecture Behavioral of display_driver is + + component counter_2bit is + Port ( CLK : in STD_LOGIC; RST : in STD_LOGIC; + COUNT_OUT : out STD_LOGIC_VECTOR (1 downto 0)); + end component; + + component decoder_an is + Port ( SEL : in STD_LOGIC_VECTOR (1 downto 0); + ANODES : out STD_LOGIC_VECTOR (3 downto 0)); + end component; + + component mux is + Port ( I0, I1, I2, I3 : in STD_LOGIC_VECTOR (3 downto 0); + S : in STD_LOGIC_VECTOR (1 downto 0); + Y : out STD_LOGIC_VECTOR (3 downto 0)); + end component; + + component dec_seg is + Port ( bcd : in STD_LOGIC_VECTOR (3 downto 0); + seg : out STD_LOGIC_VECTOR (7 downto 0)); + end component; + + -- Internal signals stay here now + signal s_cnt_2bit : std_logic_vector(1 downto 0); + signal s_mux_out : std_logic_vector(3 downto 0); + +begin + U_CNT_2BIT : counter_2bit + port map (CLK => CLK, RST => RST, COUNT_OUT => s_cnt_2bit); + + U_DEC_ANODES : decoder_an + port map (SEL => s_cnt_2bit, ANODES => ANODES); + + U_MUX : mux + port map (I0 => DIGIT_0, I1 => DIGIT_1, I2 => DIGIT_2, I3 => DIGIT_3, + S => s_cnt_2bit, Y => s_mux_out); + + U_DEC_SEG : dec_seg + port map (BCD => s_mux_out, SEG => SEGMENTS); + +end Behavioral; diff --git a/project_7/project_5.srcs/sources_1/new/top_modul.vhd b/project_7/project_5.srcs/sources_1/new/top_modul.vhd index 4874f0a..087b3f8 100644 --- a/project_7/project_5.srcs/sources_1/new/top_modul.vhd +++ b/project_7/project_5.srcs/sources_1/new/top_modul.vhd @@ -1,213 +1,94 @@ ----------------------------------------------------------------------------------- --- Company: --- Engineer: --- --- Create Date: 09.03.2026 14:40:14 --- Design Name: --- Module Name: top_modul - Behavioral --- Project Name: --- Target Devices: --- Tool Versions: --- Description: --- --- Dependencies: --- --- Revision: --- Revision 0.01 - File Created --- Additional Comments: --- ----------------------------------------------------------------------------------- - +-- top_modul.vhd library IEEE; use IEEE.STD_LOGIC_1164.ALL; --- Uncomment the following library declaration if using --- arithmetic functions with Signed or Unsigned values ---use IEEE.NUMERIC_STD.ALL; - --- Uncomment the following library declaration if instantiating --- any Xilinx leaf cells in this code. ---library UNISIM; ---use UNISIM.VComponents.all; - entity top_modul is Port ( CLK : in STD_LOGIC; RST : in STD_LOGIC; START : in STD_LOGIC; - SW_DIN : in STD_LOGIC_VECTOR (3 downto 0); -- The value to set + SW_MODE : in STD_LOGIC; -- '0' = HH:MM, '1' = MM:SS + SW_DIN : in STD_LOGIC_VECTOR (3 downto 0); -- Value to set BTN_LOAD : in STD_LOGIC_VECTOR (3 downto 0); -- Which digit to set SEGMENTS : out STD_LOGIC_VECTOR (7 downto 0); ANODS : out STD_LOGIC_VECTOR (3 downto 0)); end top_modul; architecture Behavioral of top_modul is - component divider is Port ( CLK : in STD_LOGIC; RST : in STD_LOGIC; - CLK_1_Hz : out STD_LOGIC); -- This will be our enable pulse + CLK_1_Hz : out STD_LOGIC); -- Enable pulse end component; component divider_400Hz is Port ( CLK : in STD_LOGIC; RST : in STD_LOGIC; - CLK_400_Hz : out STD_LOGIC); -- This will be our enable pulse + CLK_400_Hz : out STD_LOGIC); -- Enable pulse end component; - component counter is - Generic ( MAX_LIMIT : STD_LOGIC_VECTOR(3 downto 0) := "1001" ); -- Default to 9 - Port ( CLK : in STD_LOGIC; - CE : in STD_LOGIC; - PE : in STD_LOGIC; - DIN : in STD_LOGIC_VECTOR(3 downto 0); - RST : in STD_LOGIC; - TC : out STD_LOGIC; - COUNT_OUT : out STD_LOGIC_VECTOR (3 downto 0)); - end component; - - component counter_2bit is - Port ( CLK : in STD_LOGIC; - RST : in STD_LOGIC; - COUNT_OUT : out STD_LOGIC_VECTOR (1 downto 0)); - end component; - - component decoder_an is - Port ( SEL : in STD_LOGIC_VECTOR (1 downto 0); - ANODES : out STD_LOGIC_VECTOR (3 downto 0)); - end component; - - component mux is - Port ( I0 : in STD_LOGIC_VECTOR (3 downto 0); - I1 : in STD_LOGIC_VECTOR (3 downto 0); - I2 : in STD_LOGIC_VECTOR (3 downto 0); - I3 : in STD_LOGIC_VECTOR (3 downto 0); - S : in STD_LOGIC_VECTOR (1 downto 0); - Y : out STD_LOGIC_VECTOR (3 downto 0)); - end component; - - component dec_seg is - Port ( bcd : in STD_LOGIC_VECTOR (3 downto 0); - seg : out STD_LOGIC_VECTOR (7 downto 0)); - end component; - signal clk_1_Hz : std_logic; signal clk_400_Hz : std_logic; - signal s_ce_units : std_logic; - -- Internal signals to connect the counters - signal sig_m_units : std_logic_vector(3 downto 0); - signal sig_m_tens : std_logic_vector(3 downto 0); - signal sig_h_units : std_logic_vector(3 downto 0); - signal sig_h_tens : std_logic_vector(3 downto 0); - -- Carry signals (TC) - signal tc_mu, tc_mt, tc_hu : std_logic; - -- Reset for hours (to handle the 24 reset) - signal hour_reset : std_logic; - signal s_cnt_2bit : std_logic_vector(1 downto 0); - signal s_mux_out : std_logic_vector(3 downto 0); + -- You MUST declare these signals so top_modul can carry data between the two submodules + signal sig_s_units, sig_s_tens : std_logic_vector(3 downto 0); + signal sig_m_units, sig_m_tens : std_logic_vector(3 downto 0); + signal sig_h_units, sig_h_tens : std_logic_vector(3 downto 0); + + -- Signals to send to the display + signal d0, d1, d2, d3 : std_logic_vector(3 downto 0); begin - U_DIV : divider + U_DIV_1HZ : divider port map ( CLK => CLK, RST => RST, CLK_1_Hz => clk_1_Hz ); - - U_DIV_400Hz : divider_400Hz + U_DIV_REFRESH : divider_400Hz port map ( - CLK => CLK, - RST => RST, + CLK => CLK, + RST => RST, CLK_400_Hz => clk_400_Hz ); - + s_ce_units <= clk_1_Hz and START; - -- MINUTES UNITS (0-9) - U_CNT_MIN_UNITS : counter - generic map ( MAX_LIMIT => "1001" ) -- To 9 + + -- Clock Engine submodule + U_CLOCK_CORE : entity work.clock_logic port map ( - CLK => CLK, - RST => RST, - CE => s_ce_units, - PE => BTN_LOAD(0), - DIN => SW_DIN, - TC => tc_mu, - COUNT_OUT => sig_m_units + CLK => CLK, + RST => RST, + CE_1HZ => s_ce_units, + SW_DIN => SW_DIN, + BTN_LOAD => BTN_LOAD, + S_UNITS => sig_s_units, + S_TENS => sig_s_tens, + M_UNITS => sig_m_units, + M_TENS => sig_m_tens, + H_UNITS => sig_h_units, + H_TENS => sig_h_tens ); - -- MINUTES TENS (0-5) - U_CNT_MIN_TENS : counter - generic map ( MAX_LIMIT => "0101" ) -- To 5 - port map ( - CLK => CLK, - RST => RST, - CE => tc_mu, - PE => BTN_LOAD(1), - DIN => SW_DIN, - TC => tc_mt, - COUNT_OUT => sig_m_tens - ); - - -- Logic to reset hours at 24:00 - hour_reset <= '1' when (RST = '1' or (sig_h_tens = "0010" and sig_h_units = "0011" and tc_mt = '1')) else '0'; + -- Mode Multiplexing + -- If SW_MODE = '1', show MM:SS. If '0', show HH:MM. + d0 <= sig_s_units when SW_MODE = '1' else sig_m_units; + d1 <= sig_s_tens when SW_MODE = '1' else sig_m_tens; + d2 <= sig_m_units when SW_MODE = '1' else sig_h_units; + d3 <= sig_m_tens when SW_MODE = '1' else sig_h_tens; - -- HOURS UNITS (0-9) - U_CNT_HOR_UNITS : counter - generic map ( MAX_LIMIT => "1001" ) -- To 9 + U_DISPLAY : entity work.display_driver port map ( - CLK => CLK, - RST => hour_reset, - CE => tc_mt, - PE => BTN_LOAD(2), - DIN => SW_DIN, - TC => tc_hu, - COUNT_OUT => sig_h_units - ); - - -- HOURS TENS (0-2) - U_CNT_HOR_TENS : counter - generic map ( MAX_LIMIT => "0010" ) -- To 2 - port map ( - CLK => CLK, - RST => hour_reset, - CE => tc_hu, - PE => BTN_LOAD(3), - DIN => SW_DIN, - TC => open, - COUNT_OUT => sig_h_tens - ); - - U_CNT_2BIT : counter_2bit - port map ( - CLK => clk_400_Hz, - RST => RST, - COUNT_OUT => s_cnt_2bit - ); - - U_DEC_ANODES : decoder_an - port map ( - SEL => s_cnt_2bit, - ANODES => ANODS - ); - - U_MUX : mux - port map ( - I0 => sig_m_units, - I1 => sig_m_tens, - I2 => sig_h_units, - I3 => sig_h_tens, - S => s_cnt_2bit, - Y => s_mux_out - ); - - U_DEC_SEG : dec_seg - port map ( - BCD => s_mux_out, - SEG => SEGMENTS - ); - + CLK => clk_400_Hz, + RST => RST, + DIGIT_0 => d0, + DIGIT_1 => d1, + DIGIT_2 => d2, + DIGIT_3 => d3, + SEGMENTS => SEGMENTS, + ANODES => ANODS + ); end Behavioral; diff --git a/project_7/project_5.xpr b/project_7/project_5.xpr index 424c18a..8bcad32 100644 --- a/project_7/project_5.xpr +++ b/project_7/project_5.xpr @@ -92,6 +92,12 @@ + + + + + + @@ -116,6 +122,12 @@ + + + + + +