2024 Hardware Description Language: Final Report


硬體描述語言期末

期末專案 (使用 MAX 10 10M50DAF484C7G 板子)

Clock

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity Clock is
    Port (
        clk    : in  STD_LOGIC;
        reset  : in  STD_LOGIC;
        hour   : out STD_LOGIC_VECTOR(5 downto 0);  -- 6 bits for 24-hour format
        minute : out STD_LOGIC_VECTOR(5 downto 0);
        second : out STD_LOGIC_VECTOR(5 downto 0)
    );
end Clock;

architecture Behavioral of Clock is

    signal sec     : unsigned(5 downto 0) := (others => '0');
    signal min     : unsigned(5 downto 0) := (others => '0');
    signal hr      : unsigned(5 downto 0) := (others => '0');
    signal counter : unsigned(25 downto 0) := (others => '0');  -- 50 MHz clock -> 1 second divider

begin

    process(clk, reset)
    begin
        if reset = '1' then
            counter <= (others => '0');
            sec <= (others => '0');
            min <= (others => '0');
            hr <= (others => '0');
        elsif rising_edge(clk) then
            if counter = 50_000_000 - 1 then  -- 50MHz clock for 1-second divider
                counter <= (others => '0');
                -- Second increment
                if sec = 59 then
                    sec <= (others => '0');
                    -- Minute increment
                    if min = 59 then
                        min <= (others => '0');
                        -- Hour increment
                        if hr = 23 then
                            hr <= (others => '0');
                        else
                            hr <= hr + 1;
                        end if;
                    else
                        min <= min + 1;
                    end if;
                else
                    sec <= sec + 1;
                end if;
            else
                counter <= counter + 1;
            end if;
        end if;
    end process;

    -- Output assignments
    hour <= std_logic_vector(hr);
    minute <= std_logic_vector(min);
    second <= std_logic_vector(sec);

end Behavioral;

VHDL coding tips and tricks: Digital Clock (With ability to Set time) And Testbench in VHDL

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
library std;
use std.textio.all;

ENTITY tb_digitalClock IS
END tb_digitalClock;

ARCHITECTURE behavior OF tb_digitalClock IS 

    -- Component Declaration for the Unit Under Test (UUT)
    COMPONENT digital_clock
        generic( CLOCK_FREQ : integer := 50000000 ); 
        PORT(
            Clock : IN  std_logic;
            reset : IN  std_logic;
            inc_secs : IN  std_logic;
            inc_mins : IN  std_logic;
            inc_hrs : IN  std_logic;
            seconds : OUT  unsigned(5 downto 0);
            minutes : OUT  unsigned(5 downto 0);
            hours : OUT  unsigned(4 downto 0)
        );
    END COMPONENT;

    -- Inputs
    signal Clock : std_logic := '0';
    signal reset : std_logic := '0';
    signal inc_secs : std_logic := '0';
    signal inc_mins : std_logic := '0';
    signal inc_hrs : std_logic := '0';

    -- Outputs
    signal seconds : unsigned(5 downto 0);
    signal minutes : unsigned(5 downto 0);
    signal hours : unsigned(4 downto 0);

    -- Clock period definitions
    constant Clock_period : time := 10 ns;
    constant CLOCK_FREQ : integer := 10; -- For testbench purposes

BEGIN

    -- Instantiate the Unit Under Test (UUT)
    uut: digital_clock 
        GENERIC MAP(CLOCK_FREQ => CLOCK_FREQ)
        PORT MAP (
            Clock => Clock,
            reset => reset,
            inc_secs => inc_secs,
            inc_mins => inc_mins,
            inc_hrs => inc_hrs,
            seconds => seconds,
            minutes => minutes,
            hours => hours
        );

    -- Clock process definitions
    ClockGeneration :process
    begin
        Clock <= '0';
        wait for Clock_period / 2;
        Clock <= '1';
        wait for Clock_period / 2;
    end process;

    -- Stimulus process
    stim_proc: process
    begin
        reset <= '1';
        wait for 100 ns;    
        reset <= '0';
        wait for Clock_period * CLOCK_FREQ * 60 * 60 * 25;  -- run the clock for 25 hours
        
        -- Increment seconds
        inc_secs <= '1';    
        wait for Clock_period;
        inc_secs <= '0';    
        wait for Clock_period * CLOCK_FREQ * 5;    -- wait for 5 secs after incrementing seconds once.
        
        -- Increment seconds 60 times
        inc_secs <= '1';    
        wait for Clock_period * 60;
        inc_secs <= '0';    
        wait for Clock_period * CLOCK_FREQ * 5;    -- wait for 5 secs after incrementing seconds.
        
        -- Increment minutes
        inc_mins <= '1';    
        wait for Clock_period;
        inc_mins <= '0';    
        wait for Clock_period * CLOCK_FREQ * 5;    -- wait for 5 secs after incrementing minutes once.
        
        -- Increment minutes 60 times
        inc_mins <= '1';    
        wait for Clock_period * 60;
        inc_mins <= '0';    
        wait for Clock_period * CLOCK_FREQ * 5;    -- wait for 5 secs after incrementing minutes.
        
        -- Increment hours
        inc_hrs <= '1';    
        wait for Clock_period;
        inc_hrs <= '0';    
        wait for Clock_period * CLOCK_FREQ * 5;    -- wait for 5 secs after incrementing hours once.
        
        -- Increment hours 25 times
        inc_hrs <= '1';    
        wait for Clock_period * 25;
        inc_hrs <= '0';    
        wait for Clock_period * CLOCK_FREQ * 5;    -- wait for 5 secs after incrementing hours.
        
        -- Apply reset
        reset <= '1';
        
        -- Wait for 100 Clock cycles and then finish the simulation
        wait for Clock_period * 100;
        assert false report "Simulation finished" severity failure;
    end process;

END;

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity digital_clock is
    generic(CLOCK_FREQ : integer := 50000000); 
    port(
        Clock : in std_logic;  
        reset : in std_logic;  
        inc_secs : in std_logic;  
        inc_mins : in std_logic;  
        inc_hrs : in std_logic;  
        seconds : out unsigned(5 downto 0);  
        minutes : out unsigned(5 downto 0);  
        hours : out unsigned(4 downto 0)  
    );
end digital_clock;

architecture Behavioral of digital_clock is
    signal secs, mins, hrs : integer := 0;  
    signal counter : integer := 0;  
begin

process(Clock, reset)
begin
    if reset = '1' then
        secs <= 0;
        mins <= 0;
        hrs <= 0;
        counter <= 0;
    elsif rising_edge(Clock) then
        if inc_secs = '1' then
            if secs = 59 then
                secs <= 0;
                if mins = 59 then
                    mins <= 0;
                    if hrs = 23 then
                        hrs <= 0;
                    else
                        hrs <= hrs + 1;
                    end if;
                else
                    mins <= mins + 1;
                end if;
            else
                secs <= secs + 1;
            end if;
        elsif inc_mins = '1' then
            if mins = 59 then
                mins <= 0;
                if hrs = 23 then
                    hrs <= 0;
                else
                    hrs <= hrs + 1;
                end if;
            else
                mins <= mins + 1;
            end if;
        elsif inc_hrs = '1' then
            if hrs = 23 then
                hrs <= 0;
            else
                hrs <= hrs + 1;
            end if;
        end if;

        if counter = CLOCK_FREQ - 1 then
            counter <= 0;
            if secs = 59 then
                secs <= 0;
                if mins = 59 then
                    mins <= 0;
                    if hrs = 23 then
                        hrs <= 0;
                    else
                        hrs <= hrs + 1;
                    end if;
                else
                    mins <= mins + 1;
                end if;
            else
                secs <= secs + 1;
            end if;
        else
            counter <= counter + 1;
        end if;
    end if;
end process;

seconds <= to_unsigned(secs, 6);
minutes <= to_unsigned(mins, 6);
hours <= to_unsigned(hrs, 5);

end Behavioral;

講解了數位時鐘 VHDL 程式碼背後的邏輯。

數位時鐘模組

測試平台