Digital clock in VHDL
Entity block is the usual thing. Architecture defines the usual convenient signals.
ENTITY CtrDemo IS
PORT (
Clock :in std_logic;
ResetL :in std_logic; -- Low true reset to 1:00 AM
Hr1 :out std_logic_vector(3 downto 0); -- 1's place
Hr10 :out std_logic_vector(3 downto 0); -- 10's place
Min1 :out std_logic_vector(3 downto 0); -- 1's place
Min10 :out std_logic_vector(3 downto 0); -- 10's place
AMPM :out std_logic -- Toggles at 11:59 -> 12:00
);
END CtrDemo;
ARCHITECTURE CtrDemo_arch OF CtrDemo IS
signal CurrHr1, NextHr1, CurrHr10, NextHr10 :std_logic_vector(3 downto 0);
signal CurrMin1, NextMin1, CurrMin10, NextMin10 :std_logic_vector(3 downto 0);
signal ClockUpdate :std_logic; -- Internal clock signal
signal CurrAMPM, NextAMPM :std_logic;
signal Min59, Hr11, Hr12 :std_logic; -- Convenient abbreviations
begin
Digital clock in VHDL
Each digit is a separate process.
-- Internal clock process
-- ClockUpdate is a signal that “ticks” once per minute. This is not the
-- same as the master system clock, but is divided down from it.
-- MINUTES COUNTER
-- Combinational next state logic for the ones counter
MinutesOnes: process(ClockUpdate, CurrMin1, ResetL)
-- Combinational next state logic for the tens counter
MinutesTens: process(ClockUpdate, CurrMin1, CurrMin10, ResetL)
Min59 <= '1' when CurrMin10="0101" and CurrMin1="1001" else '0';
Hr12 <= '1' when CurrHr10="0001" and CurrHr1="0010" else '0';
-- HOURS COUNTER
-- Combinational next state logic for the ones counter
HoursOnes: process(ClockUpdate, Min59, CurrHr1, Hr12, ResetL)
-- Combinational next state logic for the tens counter
HoursTens: process(ClockUpdate, Min59, Hr12, CurrHr10, CurrHr1, ResetL)
-- Combinational next state logic for the AMPM indicator
AMPMtog: process(ClockUpdate, CurrAMPM, Hr11, Min59, ResetL)
Example: Tens digit of hours counter
-- Combinational next state logic for the tens counter
HoursTens: process(ClockUpdate, Min59, Hr12, CurrHr10, CurrHr1, ResetL)
begin
if(ResetL='0') then
NextHr10 <= "0000";
else
if(ClockUpdate='1' and Min59='1') then
if(Hr12='1') then
NextHr10 <= "0000";
elsif(CurrHr1="1001") then
NextHr10 <= "0001";
end if;
else
NextHr10 <= CurrHr10;
end if;
end if;
end process HoursTens;
All the digits are updated in the same clocked process
-- Update the counter bits on the clock edge
HrMinRegister: process(ResetL, Clock, NextMin1, NextMin10, NextHr1, NextHr10, NextAMPM)
begin
if rising_edge(Clock) then
CurrMin1 <= NextMin1;
CurrMin10 <= NextMin10;
CurrHr1 <= NextHr1;
CurrHr10 <= NextHr10;
CurrAMPM <= NextAMPM;
end if;
end process HrMinRegister;
--Copy internal signals to pins (combinational outputs)
Min1 <= CurrMin1;
Min10 <= CurrMin10;
Hr1 <= CurrHr1;
Hr10 <= CurrHr10;
AMPM <= CurrAMPM;
Alternative design, using 7218C for multiplexed seven-segment display
ENTITY CtrDemo IS
PORT (
Clock :in std_logic;
ResetL :in std_logic; -- Low true reset to 1:00 AM
-- Parallel time output
Hr1 :out std_logic_vector(3 downto 0); -- 1's place
Hr10 :out std_logic_vector(3 downto 0); -- 10's place
Min1 :out std_logic_vector(3 downto 0); -- 1's place
Min10 :out std_logic_vector(3 downto 0); -- 10's place
AMPM :out std_logic; -- Toggles at 12:59
-- Connections to the 7218
ID03 :out std_logic_vector(3 downto 0); -- Multiplexed output
ID7 :out std_logic; -- Decimal point (for separators)
DA :out std_logic_vector(2 downto 0); -- Digit address
Wbar :out std_logic; -- Low-true write enable
-- Diagnostic pins
CU :out std_logic
);
END CtrDemo;