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 程式碼背後的邏輯。
數位時鐘模組
測試平台