Professional Documents
Culture Documents
Samuel Magana
CPE 133 - 01
Final Project
This guide will show how to implement an Alarm Clock using only a FPGA board. This project
was designed by Samuel Magana and Nicholas Alcazar for the CPE 133 course at Cal Poly San
Luis Obispo headed by Hummel. This alarm clock has functionality for: setting the current time,
setting the alarm time, arming or disarming the alarm, and snoozing the alarm. When the alarm
is activated, a game activates in order to stop the alarm. The goal of the game is the flip the
switches which correspond to the pattern of LEDs that light up. Pressing snooze will add 10
minutes to the alarm time and cancel the game.
Materials:
All the logic for the Alarm Clock takes place on the FPGA board. The Top level box diagram for
the alarm clock has 8 inputs and 6 outputs. The board uses 2 switches to set either the time or
the alarm and another switch to arm the alarm. The board also used 8 switches for the alarm
game. The board uses three of the buttons. Two of these buttons are used when setting the
time and the other button is used as the snooze. 11 of the LEDs on the board were used. 3 of
the LEDs were used to show what mode the alarm clock was in and the other 8 LEDs were
used for the alarm game. Lastly, there are a 4 bit bus and a 7 bit bus used to power the 4 digit 7
segment display on the board.
Step 3: Submodules
outputs: D[3:0] (4 bit bus to determine which digit on the LED display is active), and O[6:0] (7 bit
but to light up the corresponding LEDs on one digit). Its important to note that the driver module
takes into account the special coding used in the first digit, bits 15 to 12.
Source Code:
-------------------------------------------------- DISPLAY_CLOCK MAIN MODULE
------------------------------------------------entity Digital_CLock is
Port ( CLK : in STD_LOGIC;
BHR :in STD_LOGIC;
BMIN :in STD_LOGIC;
SWITCH : in STD_LOGIC;
LEDSET : out STD_LOGIC;
LEDBUS :out STD_LOGIC_VECTOR (7 downto 0);
selector : in STD_LOGIC;
toDisp : out STD_LOGIC_VECTOR (15 downto 0));
end component;
-- Display Driver
component Display port(
CLK : in STD_LOGIC;
I : in STD_LOGIC_VECTOR (15 downto 0);
O : out STD_LOGIC_VECTOR (6 downto 0);
D : out STD_LOGIC_VECTOR (3 downto 0));
end component;
-------------------------------------------------- SIGNALS BETWEEM MODULES
------------------------------------------------signal DCLK : STD_LOGIC_VECTOR( 15 downto 0);
signal SETS: STD_LOGIC_VECTOR( 15 downto 0);
signal ALARMO : STD_LOGIC_VECTOR( 15 downto 0);
signal DisplayIN : STD_LOGIC_VECTOR( 15 downto 0);
begin
-------------------------------------------------- PORTMAPS
------------------------------------------------clock: time_mod port map( LEDSET=> LEDSET, O=>DCLK, CLK => CLK, SWITCH =>
SWITCH,BHR=>BHR,BMIN=>BMIN);
Driver: Display port map( CLK => CLK,I => DISPLAYIN , O => O, D=>D);
ALARMFUNC: ALARM port map(LEDBUS =>LEDBUS, SETTIME => SWITCH, LEDGAME =>
LEDGAME, BHR=>BHR,BMIN=>BMIN, SETA => SETA ,SNOOZEBUTTON => snoozebutton,
ARM => ARM, CURRTIME => DCLK,O=>ALARMO,
LEDALARMSET => LEDALARMSET, LEDALARMON => LEDALARMON,
CLK =>CLK);
todisplay: MUXO port map( TIMEO => DCLK, ALARM => ALARMO, selector => SETA, toDisp
=> DisplayIN);
end Behavioral;
-------------------------------------------------- SUNMODULE: CLOCK (hold, increment, and set the current time)
------------------------------------------------entity Time_mod is
Port ( CLK : in STD_LOGIC;
BHR: in STD_LOGIC;
BMIN : in STD_LOGIC;
LEDSET : out STD_LOGIC;
O : out STD_LOGIC_VECTOR (15 downto 0);
switch : in STD_LOGIC);
end Time_mod;
mins_10 := "0000";
hours_1 := hours_1 + 1;
--AM/PM toggle?
if ( (hours_1 = 2) AND (hours_10 = 1) ) THEN
am := not am;
end if;
if ( hours_10 > 0 ) THEN
if ( hours_1 > 2) THEN
hours_1 := "0001";
hours_10 := "000";
end if;
else
if ( hours_1 > 9 ) THEN
hours_10 := "001";
hours_1 := "0000";
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end process time_proc;
output_sel: process (tmp) is
variable d4 : STD_LOGIC_VECTOR(3 downto 0);
begin
d4 := tmp (15 downto 12);
-- Output for right 3 digits
O(3 downto 0) <= tmp(3 downto 0);
O(7 downto 4) <= tmp(7 downto 4);
O(11 downto 8) <= tmp(11 downto 8);
-- Output for first digit (AM/PM included)
if (d4 = "0000") THEN
O(15 downto 12) <= "1100";
elsif ( d4 = "0001" ) THEN
O(15 downto 12) <= "1101";
elsif (d4 = "1000") THEN
O(15 downto 12) <= "1110";
elsif (d4 = "1001") THEN
process (CLK) is
-- counter variable
variable count : unsigned (19 downto 0) := "00000000000000000000";
begin
if (rising_edge(CLK)) THEN
if (count = 833333) THEN
count := "00000000000000000000";
else
count := count + 1;
end if;
end if;
-- Select which digit to power
if (count < 208333) THEN
D <= "0111";
tmp <= d3;
end Behavioral;
-------------------------------------------------- SUNMODULE: ALARM( SET ALARM TIME, SNOOZE, LED GAME,DISARM AND ARM
ALARM)
------------------------------------------------entity ALARM is
Port ( SETA : in STD_LOGIC;
BMIN : in STD_LOGIC;
BHR : in STD_LOGIC;
O <= ALARMTIME;
-------------------------------------------------- BUTTONS USE CLOCK RISING EDGE TO SLOW DOWN CLOCK INCREMENT BASED ON
BUTTON PRESS
------------------------------------------------IF(rising_edge(clock_one_hz)) THEN
if ((SETA = '1') AND SETTIME = '1') THEN
LEDALARMSET <= '1';
-------------------------------------------------- SET BUTTON BASED ON BUTTONS PRESS
------------------------------------------------if (bmin = '1') THEN
mins_1 := mins_1 +1;
if ( mins_1 > 9 ) THEN
mins_1 := "0000";
mins_10 := mins_10 + 1;
if ( mins_10 > 5 ) THEN
mins_10 := "0000";
end if;
end if;
end if;
if(bhr = '1') THEN
hours_1 := hours_1 + 1;
if ( (hours_1 = 2) AND (hours_10 = 1) ) THEN
am := not am;
end if;
if ( hours_10 > 0 ) THEN
if (hours_1 > 2) THEN
hours_1 := "0001";
hours_10 := "000";
end if;
else
if ( hours_1 > 9 ) THEN
hours_10 := "001";
hours_1 := "0000";
end if;
end if;
end if;
else
LEDALARMSET <= '0';
end if;
if(rising_edge(clock_one_hz)) THEN
if(arm = '1') THEN
LEDALARMON <='1';
if(count = 0 and (alarmtime = currtime)) THEN
LEDBUS(0) <= '1';
LEDBUS(2) <= '1';
LEDBUS(6) <= '1';
LEDBUS(7) <= '1';
if((LEDGAME(0) = '1' and LEDGAME(2) = '1' and LEDGAME(6) = '1' and LEDGAME(7)=
'1' ) or SNOOZEBUTTON = '1' ) THEN
LEDBUS(0) <= '0';
LEDBUS(2) <= '0';
LEDBUS(6) <= '0';
LEDBUS(7) <= '0';
end if;
elsif(count = 1 and (alarmtime = currtime) ) THEN
LEDBUS(1) <= '1';
LEDBUS(3) <= '1';
LEDBUS(4) <= '1';
LEDBUS(6) <= '1';
if((LEDGAME(1) = '1' and LEDGAME(3) = '1' and LEDGAME(4) = '1' and LEDGAME(6)=
'1') or SNOOZEBUTTON = '1') THEN
LEDBUS(1) <= '0';
LEDBUS(3) <= '0';
LEDBUS(4) <= '0';
LEDBUS(6) <= '0';
end if;
elsif(count = 2 and (alarmtime = currtime)) THEN
LEDBUS(0) <= '1';
LEDBUS(1) <= '1';
LEDBUS(3) <= '1';
LEDBUS(4) <= '1';
if((LEDGAME(0) = '1' and LEDGAME(1) = '1' and LEDGAME(3) = '1' and
LEDGAME(4)= '1') or SNOOZEBUTTON = '1') THEN
LEDBUS(0) <= '0';
LEDBUS(1) <= '0';
LEDBUS(3) <= '0';
LEDBUS(4) <= '0';
end if;
elsif(count = 3 and (alarmtime = currtime)) THEN
LEDBUS(2) <= '1';
LEDBUS(5) <= '1';
LEDBUS(6) <= '1';
begin
if (rising_edge(CLK)) THEN
count := count + 1;
--countB := countB +1;
if (count > 50000000) THEN
--50000000 (5 is used for simulation
purposes)
clockw <= not clockw;
count := "0000000000000000000000000";
end if;
end if;
end process clockd;
end Behavioral;
----------------------------------------------- DISPLAY SELECTOR(BETWEEN ,SET TIME, SET ALARM TIME AND CURRENT TIME)
--------------------------------------------entity MUXO is
Port ( ALARM : in STD_LOGIC_VECTOR (15 downto 0);
TIMEO : in STD_LOGIC_VECTOR (15 downto 0);
selector : in STD_LOGIC;
toDisp : out STD_LOGIC_VECTOR (15 downto 0));
end MUXO;
architecture Behavioral of MUXO is
-- selects output of cuRrent time and clock set and SET ALARM TIME
begin
display: process(selector) is
begin
if(selector = '1') THEN
toDisp <= alarm;
else
todisp <= timeO;
end if;
end process display;
end Behavioral;