Alarm Clock Report 2014-05-01 author: Aditya Hendra course: Digital Electronics Design with VHDL, 10c 1
Alarm Clock Report
2014-05-01
author: Aditya Hendra
course: Digital Electronics Design with VHDL, 10c
1
Abstract
The project task is to design an alarm clock using an FPGA of Altera Cyclone II.The final design contains an alarm clock using LED-Mux as the clock display, and one green LED asthe indicator of alarm. Three pins from the Altera will also be used to change mode of clock setting,alarm setting and turning alarm on/off. One button will be used as an input by pressed.
Table of Contents1.Introduction.............................................................................................................................................42.Project Description..................................................................................................................................4
2.1.Tools & Software.............................................................................................................................42.2.Design..............................................................................................................................................4
3.Theory.....................................................................................................................................................83.1.Initial Design...................................................................................................................................83.2.Live Testing.....................................................................................................................................8
4.Implementation.......................................................................................................................................84.1.freq_div...........................................................................................................................................84.2.freq_div_alarm..............................................................................................................................104.3.clock_time.....................................................................................................................................124.4.snooze............................................................................................................................................134.5.display_rotator...............................................................................................................................154.6.dot_pointer.....................................................................................................................................154.7.SevenSegment...............................................................................................................................164.8.alarm_clock...................................................................................................................................16
5.Tests & Result.......................................................................................................................................195.1.Simulations....................................................................................................................................195.2.freq_div test and simulation..........................................................................................................19
5.2.1.freq_div.vht............................................................................................................................195.2.2.freq_div ModelSim Waves 1.................................................................................................215.2.3.freq_div ModelSim Waves 2.................................................................................................22
5.3. Clock_time and Snooze tests and simulations.............................................................................235.3.1.clock_time_bdf.vht................................................................................................................245.3.2.clock_time ModelSim Waves 1.............................................................................................285.3.3.clock_time ModelSim Waves 2.............................................................................................295.3.4.clock_time ModelSim Waves 3.............................................................................................305.3.5.clock_time ModelSim Waves 4.............................................................................................31
6.Conclusions and evaluation..................................................................................................................327. Appendix A. Source Code....................................................................................................................32
7.1.freq_div.vhd...................................................................................................................................327.2.freq_div_alarm.vhd.......................................................................................................................347.3.clock_time.vhd..............................................................................................................................357.4.snooze.vhd.....................................................................................................................................417.5.display_rotator.vhd........................................................................................................................427.6.dot_pointer.vhd..............................................................................................................................447.7.sevenSegment.vhd.........................................................................................................................45
8.References.............................................................................................................................................47
2
Illustration IndexIllustration 2.1: Principle Drawing 1..........................................................................................................5Illustration 2.2: Principle Drawing 2..........................................................................................................6Illustration 4.1: freq_div's symbol.............................................................................................................8Illustration 4.2: freq_div's RTL..................................................................................................................9Illustration 4.3: freq_div_alarm's symbol................................................................................................10Illustration 4.4: freq_div_alarm's RTL.....................................................................................................11Illustration 4.5: clock_time's symbol.......................................................................................................12Illustration 4.6: snooze's symbol..............................................................................................................13Illustration 4.7: snooze's RTL..................................................................................................................14Illustration 4.8: display_rotator's symbol.................................................................................................15Illustration 4.9: dot_pointer's symbol.......................................................................................................15Illustration 4.10: RTL of dot_pointer's symbol........................................................................................16Illustration 4.11: sevenSegment's symbol................................................................................................16Illustration 4.12: the project's BDF part 1................................................................................................17Illustration 4.13: the project's BDF part 2................................................................................................18Illustration 5.1: Test of the normal clock generator.................................................................................21Illustration 5.2: Test of the fast clock generator.......................................................................................22Illustration 5.3: Clock_time and snooze BDF..........................................................................................23Illustration 5.4: Testing alarm function....................................................................................................28Illustration 5.5: Testing snooze function..................................................................................................29Illustration 5.6: Testing to turn off and resetting the alarm timer............................................................30Illustration 5.7: Testing the clock reset feature........................................................................................31
3
1. Introduction
This project gives the possibility of learning more about VHDL programming ,simulating andtesting with real hardware implementation to real FPGA hardware.
2. Project Description
2.1. Tools & SoftwareThe project task is to design a simple alarm clock using internal Cyclone II 50Mhz clock generator.
The software IDE used is Quartus II 64-bit version 13.0.1 build 232 06/12/2013 SJ Web Edition.
The hardware tool used is an FPGA – Altera Cyclone II.
2.2. DesignThe design is using several symbols each with their own VHD file. These files are:
● freq_div.vhd
● freq_div_alarm.vhd
● snooze.vhd
● clock_time.vhd
● display_rotator.vhd
● dot_pointer.vhd
● sevenSegment.vhd
These symbols combined will make an alarm clock with LED-Mux display and snooze featurewith a dot led light representing the alarm ring. Below is the RTL design of it separated as twopictures.
4
5
Illustration 2.1: Principle Drawing 1
6
Illustration 2.2: Principle Drawing 2
Table of inputs:
Clock signal is an Internally generated 50Mhzby the Altera
Reset Mode(Clocksetting)
Mode2(alarmSetting)
Alarm_on
SetClock
Functions
1 1 1 1 1 1 Set Up both the Clock and Alarm and activatethe alarm
2 1 1 1 1 0 activate the alarm
3 1 1 1 0 1 Set Up both the Clock and Alarm anddeactivate the alarm
4 1 1 1 0 0 deactivate the alarm
5 1 1 0 1 1 Set Up the Clock and activate the alarm
6 1 1 0 1 0 activate the alarm
7 1 1 0 0 1 Set Up the Clock and deactivate the alarm
8 1 1 0 0 0 deactivate the alarm
9 1 0 1 1 1 Set Up the alarm and activate the alarm
10 1 0 1 1 0 activate the alarm
11 1 0 1 0 1 Set Up the alarm and deactivate the alarm
12 1 0 1 0 0 deactivate the alarm
13 1 0 0 1 1 activate the alarm and snooze if it's ringing
14 1 0 0 1 0 activate the alarm
15 1 0 0 0 1 Do nothing
16 1 0 0 0 0 Do nothing
17 0 X X X X Reset all to set up value
7
3. Theory
3.1. Initial DesignThe project is done with creating each symbols' VHD file separately and test the core symbolssuch as clock_time, snooze and freq_div. The freq_div_alarm is not tested because of similaritywith freq_div symbols. sevenSegment is also not tested since this symbol is using the same codefrom Lab5 report. dot_pointer and display_rotator are tested directly using the FPGA and Muxdisplayer.
3.2. Live TestingThe resulting alarm_clock.sof file is downloaded to the Altera Cyclone II FPGA for live testing anddemonstration.
4. Implementation In this part, the symbols composing the alarm clock will be further explained.
4.1. freq_div
The freq_div symbol purpose is to convert the input (clk) of internal 50Mhz clock into output(clock_seconds) of 1hz clock or 1 second ticks that could be used as internal clock ticking.
The symbol could produces two type of output of clock_seconds. The first is the normal 1 secondstick and the other one is the faster clock of 500 ticking in one second to accelerate setting whenthe mode is given value of '1' ( setting changed ) and the set_clock is given value '0' ( buttonpressed ). The second output is used to make the clock ticks faster when there is a need toset the clock's time.
8
Illustration 4.1: freq_div's symbol
9
Illustration 4.2: freq_div's RTL
4.2. freq_div_alarm
The freq_div_alarm symbol purpose is to convert the input (clk) of internal 50Mhz clock intooutput (alarm_seconds) of 500hz clock or 500 ticks in one second that is used when settingalarm clock.
Unlike the freq_div, this symbol only produce one type of output which is produced when mode isgiven value of '1' ( setting changed ) and the set_clock is given value '0' ( button pressed ). Thebutton for freq_div_alarm's mode is different with freq_div's.
10
Illustration 4.3: freq_div_alarm's symbol
11
Illustration 4.4: freq_div_alarm's RTL
4.3. clock_time
The clock_time's symbol is the main engine of the alarm_clock, where almost all of the importantprocessing are done. Here, the output from freq_div and freq_div_alarm symbols are used asinputs of clock_second and alarm_second.
Here, the inputs of clock second and alarm_second are converted into their decimal clock digit.Minute is represented by two vectors of min_digit_X0 ( for the tens of minutes ) andmin_digit_0X ( for the units of minutes ).
Hour is also represented by two vectors of hour_digit_X0 ( for the tens of hours ) andhour_digit_0X ( for the units of hours ).
Mode signal is used to switch which input will be displayed to the LED-Mux. This signal is usingthe same signal with freq_div_alarm's mode signal, so when it is time to set the alarm time, theone which will be displayed is the alarm's time, else it is the clock's time which will be displayed.
Every high edge signals from clock_second and alarm_second will be treated as one second tickfor their respective time and will increment their own respective time. Sixty seconds will equal to1 minute while 60 minutes will equal to 1 hour and 24 hour will reset the value back to zero.
Both clock and alarm time of hour and minute will be saved internally using the 24h format withminimum value of 00:00 and max value 23:59.
Since freq_div_alarm will only give input when the mode='1' and set_clock='0' ( from 4.2explanation ) then the alarm time will only increment at that specific requisite, the last valuebefore incrementation stop will be kept as the alarm time.
freq_div will always give input of clock_second representing the clock that always ticking everysecond. So when the alarm is being set, the clock's time actually is still running in the background.
The input signal of alarm_on is used to set the alarm feature on or off with alarm_on='1' meansit's on and alarm_on='0' means it's off.
The output signal alarm_ring will give the output of '1' (ringing) when alarm feature is set onand snooze_in signal is '0' meaning no snoozing and hour's time of clock and alarm is the sameand minute's time of clock and alarm is also the same indicating the clock's time is currentlyequal the alarm's time. The alarm will keep ringing for 30 minutes unless it is turned off orsnoozed.
12
Illustration 4.5: clock_time's symbol
4.4. snooze
The snooze's function is used to manage the duration of the snooze_out signal with value of '1',which will be interpreted by the clock_time's symbol to stop ringing alarm.
This function will produce snooze_out signal with value of '1' only and if only not in alarm settingmode ( alarm_mode = '0' ) and not in clock setting mode ( clock_mode = '0' ) and alarm iscurrently ringing ( alarm_ring = '1' ) and the snooze button is pressed ( set_snooze = '0' ).
The reason why it needs the alarm_mode = '0' and clock_mode = '0' is because the button pressedwhen setting alarm time and setting clock time and activate snooze is the same single button, tosimplify the button design.
If even one of the requirements is not fulfilled then the snooze_out signal will give value of '0',which will be interpreted by the clock_time's symbol to keep ringing alarm.
After the requirements are fulfilled, the function will give the snooze_out signal with value of '1'for 6 consecutive high edge clock of clock_seconds signal, which should match 6 seconds in time.In this project, 6 seconds is used just as a simple snooze example, it could be change from theinternal code.
13
Illustration 4.6: snooze's symbol
14
Illustration 4.7: snooze's RTL
4.5. display_rotator
This component is used to arrange the output to be displayed to the multiplexed LED-display.Since the Mux could only activate one array of seven-segment at one time, it is required toactivate each of the four seven-segment LED one at a time looping forever with a high refresh rateso that the eye would not recognize it blinks.
The input signals are the minutes and hours signals ( min_digit_0X, min_digit_X0, hour_digit_0X,hour_digit_X0 ) in 4bit vector from the clock_time's component and the selected signals todisplay will be sent to out_display.
The clk input signal is from the 50Mhz internal clock generator that would be used to count therefresh rate of out_display signal. The digit_selector signal is used to tell the LED-Mux, whichseven-segment LED that will receive the out_display value and need to be turn on at thismoment.
4.6. dot_pointer
This component is to manage the blinking dot between the hour and minute digit on the LED-Mux. Since there are four dot in the LED-Mux, it is necessary to arrange that only the dot betweenthe hour and minute digit that should turn on. And it should blink accordingly to 1Hz as a markerfor second.
15
Illustration 4.8: display_rotator's symbol
Illustration 4.9: dot_pointer's symbol
The clk signal is from the freq_div symbol output of 1Hz signal. The digit_selector is from thedisplay_rotator symbol, so that when the appropriate seven-segment LED-mux is selected, thenthe dot_point will be given the value from clk to represent the blinking of a ticking clock. Otherseven-segment LED-mux selected would have the dot part to be turned off.
4.7. SevenSegment
Before the data could be displayed by the seven-segment LED-Mux, the data need to be convertedfrom decimal form in 4bit binary into the appropriate seven-segment 7 bit display arrangementin order to put up the correct and readable display.
The component accepts input from the display_rotator component and convert it into the seven-segment LED-Mux display arrangement.
4.8. alarm_clock
This is the whole symbols combined within one bdf file, displayed as two separated pictures.
16
Illustration 4.11: sevenSegment's symbol
Illustration 4.10: RTL of dot_pointer's symbol
17
Illustration 4.12: the project's BDF part 1
18
Illustration 4.13: the project's BDF part 2
5. Tests & Result
5.1. SimulationsTest and simulations are done using the ModelSim altera for several important symbols which arefreq_div, clock_time and snooze. The tests for clock_time and snooze are done together at the same time using the same VHT to test the core features of the alarm_clock.
5.2. freq_div test and simulation
5.2.1. freq_div.vhtLIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY freq_div_vhd_tst IS
END freq_div_vhd_tst;
ARCHITECTURE freq_div_arch OF freq_div_vhd_tst IS
SIGNAL clk : STD_LOGIC;
SIGNAL clock_seconds : STD_LOGIC;
SIGNAL mode : STD_LOGIC;
SIGNAL set_clock : STD_LOGIC;
COMPONENT freq_div
PORT (
clk : IN STD_LOGIC;
clock_seconds : OUT STD_LOGIC;
mode : IN STD_LOGIC;
set_clock : IN STD_LOGIC
);
END COMPONENT;
BEGIN
i1 : freq_div
PORT MAP (-- list connections between master ports and signals
clk => clk,
clock_seconds => clock_seconds,
mode => mode,
set_clock => set_clock
);
init : PROCESS -- variable declarations
BEGIN -- code that executes only once
19
WAIT;
END PROCESS init;
always : PROCESS
variable internal_clck : std_logic; -- seconds ticking for clock
variable set_clock_mode : std_logic;
-- 1 <- setting alarm ; 0 <- not setting alarm
variable set_clock_pressed : std_logic;
-- 1 <- snooze pressed ; 0 <- snooze not pressed
BEGIN
for i in 0 to 1100000 loop
– mechanism to imitate a 500Khz clock
if ( i mod 2 ) = 0 then
internal_clck := '1';
else
internal_clck := '0';
end if;
– mechanism to test the fast speed generator
if ( i > 1000000 ) then
set_clock_mode := '1';
set_clock_pressed := '0';
else
set_clock_mode := '0';
set_clock_pressed := '1';
end if;
– since we need two loops to generate a full cycle clock, 1000000 loops will simulate a 500Khz clock and after that we change the clock mode to test the fast speed generator. Further explanation §5.2.2 and §5.2.3
clk <= internal_clck; mode <= set_clock_mode; set_clock <= set_clock_pressed; wait for 5 ps;
end loop;
wait;
END PROCESS always;
END freq_div_arch;
20
5.2.2. freq_div ModelSim Waves 1
In this test we use a simulation of 500Khz instead of 50Mhz to simplify the test and lessen the burden of the Altera ModelSim application. From the VHT file, we can see that each high and low edge clock cycle takes 5 ps, so one full clock will take 10ps. A repetition of 500,000 of this cycle will take 5000ns which will be used as a simulation from a 500Khz clock generator.
In this simulation we could see that the freq_div succeeds in converting the 500Khz into one clock cycle hence the 500Khz clock divider is functioning appropriately.
21
Illustration 5.1: Test of the normal clock generator
5.2.3. freq_div ModelSim Waves 2
In this test we need to see that when the mode's value is change to '0' and set_clock also change to '0' the clock divider is changed to lower counter which means producing more clock cycle in one second hence the fast clock generator.
Here we could see that the resulting clock cycle needs 10ns for each cycle, hence a 1Khz clock divider from input of 10ps per clock cycle, which also means the number the clock-cyles are produced as output is 500 times more than the normal clock divider from §5.2.2.
This mode will be used when setting up clock's time, so that we could fast forward the clock and reduce the duration in setting it.
This similar mechanism will also be used when setting up alarm's time, therefore there is no test for that feature.
22
Illustration 5.2: Test of the fast clock generator
5.3. Clock_time and Snooze tests and simulationsFor this simulation the clock_time symbol and snooze are put together into one BDF and converted into VHDL file before being simulated. These two components provide core functions for the project.
23
Illustration 5.3: Clock_time and snooze BDF
5.3.1. clock_time_bdf.vhtLIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY clock_time_bdf_vhd_tst IS
END clock_time_bdf_vhd_tst;
ARCHITECTURE clock_time_bdf_arch OF clock_time_bdf_vhd_tst IS
-- constants
-- signals
SIGNAL alarm_mode : STD_LOGIC;
SIGNAL alarm_on : STD_LOGIC;
SIGNAL alarm_ring : STD_LOGIC;
SIGNAL alarm_seconds : STD_LOGIC;
SIGNAL clock_mode : STD_LOGIC;
SIGNAL clock_seconds : STD_LOGIC;
SIGNAL hour_digit_tens : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL hour_digit_unit : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL min_digit_tens : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL min_digit_unit : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL reset : STD_LOGIC;
SIGNAL set_snooze : STD_LOGIC;
COMPONENT clock_time_bdf
PORT (
alarm_mode : IN STD_LOGIC;
alarm_on : IN STD_LOGIC;
alarm_ring : OUT STD_LOGIC;
alarm_seconds : IN STD_LOGIC;
clock_mode : IN STD_LOGIC;
clock_seconds : IN STD_LOGIC;
hour_digit_tens : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
hour_digit_unit : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
min_digit_tens : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
min_digit_unit : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
reset : IN STD_LOGIC;
set_snooze : IN STD_LOGIC
);
END COMPONENT;
BEGIN
24
i1 : clock_time_bdf
PORT MAP (
-- list connections between master ports and signals
alarm_mode => alarm_mode,
alarm_on => alarm_on,
alarm_ring => alarm_ring,
alarm_seconds => alarm_seconds,
clock_mode => clock_mode,
clock_seconds => clock_seconds,
hour_digit_tens => hour_digit_tens,
hour_digit_unit => hour_digit_unit,
min_digit_tens => min_digit_tens,
min_digit_unit => min_digit_unit,
reset => reset,
set_snooze => set_snooze
);
init : PROCESS
BEGIN
WAIT;
END PROCESS init;
always : PROCESS
variable clck_second : std_logic; -- seconds ticking for clock
variable alrm_second : std_logic; -- seconds ticking for alarm
variable set_alarm : std_logic;
-- 1 <- setting alarm ; 0 <- not setting alarm
variable alarm_on_off : std_logic;
-- 1 <- alarm turn on ; 0 <- alarm turn off
variable snooze_pressed : std_logic;
-- 1 <- snooze pressed ; 0 <- snooze not pressed
BEGIN
for i in 0000 to 400000 loop
– this is to generate clock for alarm and clock time
– the clock for alarm time will only be accepted if set_alarm = '1'
25
if ( i mod 2 ) = 0 then
clck_second := '1';
else
clck_second := '0';
end if;
– this is to activate snooze during alarm rings
if i = 12000 then
snooze_pressed := '0';
else
snooze_pressed := '1';
end if;
– the duration of setting alarm
if (( i < 10000 ) or (( i > 30000 ) and ( i < 195000 )))then
set_alarm := '1';
alarm_on_off:= '0';
else
set_alarm:='0';
alarm_on_off:= '1';
end if ;
if ( set_alarm = '1' ) then
if ( i mod 2 ) = 0 then
alrm_second := '1';
else
alrm_second := '0';
end if;
else
alrm_second := '0';
end if;
– the duration when alarm is turned off
if ( (i>350000) and (i<360000) ) then
alarm_on_off:= '0';
end if;
26
– testing the reset function
if i = 380000 then
reset <= '0';
else
reset <= '1';
end if;
– give the input the designated value and loop them to simulate clocks signals
clock_seconds <= clck_second; alarm_seconds <= alrm_second; alarm_mode <= set_alarm; alarm_on <= alarm_on_off; set_snooze <= snooze_pressed; clock_mode <= '0'; wait for 50 ps;
end loop;
wait;
END PROCESS always;
END clock_time_bdf_arch;
27
5.3.2. clock_time ModelSim Waves 1
In this wave, we could see that the alarm starts ringing (top left red circle) when the alarm's and clock's time are equal (left black boxes). In this test the alarm is set to 23:36, and the alarm stops ringing after 30 minutes or 1800 seconds as seen by the top right red circle. Since there is no intervention from snooze and the alarm is still turned on, the timer_alarm keeps counting for 1800 seconds as seen on the right low red circle, so even though the clock reset to 00:00 (middle red circle), the alarm could still rings.
28
Illustration 5.4: Testing alarm function
5.3.3. clock_time ModelSim Waves 2
In this test, we test the function of snooze. As we can see, that when we click the snooze button the set_snooze will give the signal of '0' as seen at both of the red circle, and then the alarm_ring will stop for 6 consecutive seconds as seen at the black circle. The delayed response is because it is related to the internal clock cycle.
29
Illustration 5.5: Testing snooze function
5.3.4. clock_time ModelSim Waves 3
In this test, the alarm is turned off after ringing for several minutes as seen at the upper left red circle, the alarm timer immediately reset to its original maximum value of 1800 as seen at the low left red circle. After several minutes, the alarm is turn on again, but it does not keep ringing or continuing the 1800 seconds timer as seen at the upper right red circle, meaning the alarm's ring is resetted and waiting for the next occasion when alarm's time and clock's time are equal again.
30
Illustration 5.6: Testing to turn off and resetting the alarm timer
5.3.5. clock_time ModelSim Waves 4
At this test, we could see that when the reset is on (red circles), it successfully reverts the value back to its internally predetermined (red box).
31
Illustration 5.7: Testing the clock reset feature
6. Conclusions and evaluationThe clock, alarm and snooze are working with good accuracy, perhaps there is a need to put a realsound module as the ringing alarm.
7. Appendix A. Source Code
7.1. freq_div.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity freq_div is
port
(
reset : in std_logic;
clk, mode : in std_logic; -- input signals
set_clock : in std_logic;
clock_seconds : out std_logic -- output signal
);
end entity;
architecture rtl of freq_div is
signal Q :std_logic:='0';
begin
– clock divider used a counter of 25,000,000 divided into two counter of 25,000 and 1,000 to count the high edge of 50Mhz internal clock in order to produce 1Hz clock.– the 50,000 counter is used to produce 500Hz clock (high speed clock) to be used when setting the clock time
one_hertz: process (clk,mode,reset,Q)
variable counter1 : integer range 0 to 24999 := 0;
variable counter2 : integer range 0 to 1000 := 0;
32
variable divider : integer range 0 to 24999 := 0;
begin
if reset='0' then
counter1 := 0;
counter2 := 0;
divider := 0;
Q <= '0';
elsif clk'event and clk='1' then
if (mode='1' and set_clock='0')then
divider := 49;
else
divider :=24999;
end if;
if (counter1 = divider) then
counter2 := counter2 + 1;
counter1 := 0;
else
counter1 := counter1 + 1;
end if;
if (counter2 = 1000) then
Q <= NOT(Q);
counter2:=0;
end if;
end if;
clock_seconds <= Q;
end process one_hertz;
end rtl;
33
7.2. freq_div_alarm.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity freq_div_alarm is
port
(
reset : in std_logic;
clk, mode : in std_logic; -- input signals
set_clock : in std_logic;
alarm_seconds : out std_logic -- output signal
);
end entity;
architecture rtl of freq_div_alarm is
signal Q :std_logic:='0';
begin
one_hertz: process (clk,mode,reset,Q)
variable counter1 : integer range 0 to 24999 := 0;
variable counter2 : integer range 0 to 1000 := 0;
begin
– when alarm setting mode is on ( value '1') the 50,000 counter is used to produce 500Hz clock (high speed clock) to be used to set the alarm time
if reset='0' then
counter1 := 0;
counter2 := 0;
Q <= '0';
34
elsif (clk'event and clk='1') then
if ((set_clock='0') and (mode='1')) then
if (counter1 = 49) then
counter2 := counter2 + 1;
counter1 := 0;
else
counter1 := counter1 + 1;
end if;
if (counter2 = 1000) then
Q <= NOT(Q);
counter2:=0;
end if;
end if;
end if;
alarm_seconds <= Q;
end process one_hertz;
end rtl;
7.3. clock_time.vhd
– decimal time counter converter package
library ieee;
use ieee.std_logic_1164.all;
package DecimalBinaryConversion is
function convert_Decimal(i: in integer range 0 to 9) return std_logic_vector;
end package DecimalBinaryConversion;
package body DecimalBinaryConversion is
function convert_Decimal(i: in integer range 0 to 9) return std_logic_vector is
variable result : std_logic_vector (3 downto 0);
35
begin
case i is
when 0 => result :="0000";
when 1 => result :="0001";
when 2 => result :="0010";
when 3 => result :="0011";
when 4 => result :="0100";
when 5 => result :="0101";
when 6 => result :="0110";
when 7 => result :="0111";
when 8 => result :="1000";
when 9 => result :="1001";
when others => result :="0000";
end case;
return result;
end convert_Decimal;
end DecimalBinaryConversion;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use work.DecimalBinaryConversion.all; – use the package
entity clock_time is
port
(
reset : in std_logic;
snooze_in : in std_logic;
clock_second : in std_logic; -- input signals
alarm_second : in std_logic; -- input signals
mode : in std_logic; -- input signals
alarm_on : in std_logic;
alarm_ring : out std_logic;
36
min_digit_unit: out std_logic_vector (3 downto 0); -- minute 00:0X signal
min_digit_tens: out std_logic_vector (3 downto 0); -- minute 00:X0 signal
hour_digit_unit: out std_logic_vector (3 downto 0); -- hour 0X:00 signal
hour_digit_tens : out std_logic_vector (3 downto 0) -- hour X0:00 signal
);
end entity;
architecture rtl of clock_time is
signal cntr_sec_clock : integer range 0 to 60 := 0;
signal cntr_sec_alarm : integer range 0 to 60 := 0;
signal cntr_unit_min_clock : integer range 0 to 9 := 0;
signal cntr_tens_min_clock : integer range 0 to 6 := 0;
signal cntr_unit_hour_clock : integer range 0 to 9 := 0;
signal cntr_tens_hour_clock : integer range 0 to 2 := 0;
signal cntr_unit_min_alarm : integer range 0 to 9 := 0;
signal cntr_tens_min_alarm : integer range 0 to 6 := 0;
signal cntr_unit_hour_alarm : integer range 0 to 9 := 0;
signal cntr_tens_hour_alarm : integer range 0 to 2 := 0;
signal timer_alarm : integer range 0 to 1801 := 1801;
begin
alarm_clock: process (reset, clock_second, alarm_second,mode, alarm_on,snooze_in, cntr_tens_hour_alarm, cntr_unit_hour_alarm, cntr_tens_min_alarm, cntr_unit_min_alarm, cntr_tens_hour_clock, cntr_unit_hour_clock, cntr_tens_min_clock, cntr_unit_min_clock, timer_alarm)
begin
– minutes and hour counter for alarm's time from alarm_second input
if reset='0' then
– to reset to predetermined internal value
cntr_sec_alarm <= 0;
cntr_unit_min_alarm <= 0;
cntr_tens_min_alarm <= 0;
cntr_unit_hour_alarm <= 0;
cntr_tens_hour_alarm <= 0;
37
elsif alarm_second'event and alarm_second='1' then
if mode='1' then
if ((cntr_unit_min_alarm = 9) and (cntr_sec_alarm = 59)) then
cntr_sec_alarm <= 0;
cntr_unit_min_alarm <= 0;
cntr_tens_min_alarm <= cntr_tens_min_alarm + 1;
elsif (cntr_sec_alarm = 59) then
cntr_sec_alarm <= 0;
cntr_unit_min_alarm <= cntr_unit_min_alarm + 1;
else
cntr_sec_alarm <= cntr_sec_alarm + 1;
end if;
– counter to change from seconds to minutes and hours for alarm
if ((cntr_unit_hour_alarm = 9) and ( cntr_tens_min_alarm = 5 ) and ( cntr_unit_min_alarm= 9 ) and (cntr_sec_alarm = 59))then
cntr_tens_min_alarm <= 0;
cntr_unit_hour_alarm <= 0;
cntr_tens_hour_alarm <= cntr_tens_hour_alarm +1;
elsif(( cntr_tens_min_alarm = 5 ) and ( cntr_unit_min_alarm = 9 )and (cntr_sec_alarm =59))then
cntr_tens_min_alarm <= 0;
cntr_unit_hour_alarm <= cntr_unit_hour_alarm +1;
end if;
if ((cntr_tens_hour_alarm = 2) and (cntr_unit_hour_alarm = 3) and ( cntr_tens_min_alarm = 5 ) and ( cntr_unit_min_alarm = 9 ) and (cntr_sec_alarm = 59)) then
cntr_tens_hour_alarm <= 0;
cntr_unit_hour_alarm <= 0;
38
end if;
end if;
end if;
– minutes and hour counter for clock's time from clock_second input
if reset='0' then
– to reset to predetermined internal value
cntr_sec_clock <= 0;
cntr_unit_min_clock <= 0;
cntr_tens_min_clock <= 0;
cntr_unit_hour_clock <= 0;
cntr_tens_hour_clock <= 0;
timer_alarm <= 1801;
elsif clock_second'event and clock_second='1' then
– counter to change from seconds to minutes and hours for clock
if ((cntr_unit_min_clock = 9) and (cntr_sec_clock = 59)) then
cntr_sec_clock <= 0;
cntr_unit_min_clock <= 0;
cntr_tens_min_clock <= cntr_tens_min_clock + 1;
elsif(cntr_sec_clock = 59) then
cntr_sec_clock <= 0;
cntr_unit_min_clock <= cntr_unit_min_clock + 1;
else
cntr_sec_clock <= cntr_sec_clock + 1;
end if;
if ((cntr_unit_hour_clock = 9) and ( cntr_tens_min_clock = 5 ) and ( cntr_unit_min_clock = 9 ) and (cntr_sec_clock = 59))then
cntr_tens_min_clock <= 0;
cntr_unit_hour_clock <= 0;
cntr_tens_hour_clock <= cntr_tens_hour_clock +1;
39
elsif (( cntr_tens_min_clock = 5 ) and ( cntr_unit_min_clock = 9 ) and (cntr_sec_clock = 59))then
cntr_tens_min_clock <= 0;
cntr_unit_hour_clock <= cntr_unit_hour_clock +1;
end if;
if ((cntr_tens_hour_clock = 2) and (cntr_unit_hour_clock = 3) and ( cntr_tens_min_clock = 5 )and ( cntr_unit_min_clock = 9 ) and (cntr_sec_clock = 59)) then
cntr_tens_hour_clock <= 0;
cntr_unit_hour_clock <= 0;
end if;
– mechanism for handling snooze and alarm duration of 1800 seconds
if ( ( alarm_on ='1') and ( timer_alarm < 1800 ) and ( snooze_in ='0' ) ) then
alarm_ring <='1';
timer_alarm <= timer_alarm +1;
else
alarm_ring <='0';
end if;
– mechanism for starting ringing the alarm
if ( alarm_on = '1') then
if(( cntr_unit_min_alarm = cntr_unit_min_clock) and ( cntr_tens_min_alarm = cntr_tens_min_clock ))then
if (( cntr_unit_hour_alarm = cntr_unit_hour_clock ) and ( cntr_tens_hour_alarm = cntr_tens_hour_clock )) then
timer_alarm <= 0;
end if;
end if;
else – mechanism to turn off and reset alarm
timer_alarm <= 1800;
end if;
end if;
end process alarm_clock;
40
– mechanism to send whether clock or alarm time to the output display
min_digit_unit <= convert_Decimal(cntr_unit_min_clock) when mode ='0' else
convert_Decimal(cntr_unit_min_alarm);
min_digit_tens <= convert_Decimal(cntr_tens_min_clock) when mode ='0' else
convert_Decimal(cntr_tens_min_alarm);
hour_digit_unit<= convert_Decimal(cntr_unit_hour_clock) when mode ='0' else
convert_Decimal(cntr_unit_hour_alarm);
hour_digit_tens<= convert_Decimal(cntr_tens_hour_clock) when mode ='0' else
convert_Decimal(cntr_tens_hour_alarm);
end rtl;
7.4. snooze.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity snooze is
port
(
reset : in std_logic;
clock_mode : in std_logic; -- input signals
clock_seconds : in std_logic;
set_snooze : in std_logic;
alarm_mode : in std_logic; -- input signals
alarm_ring : in std_logic; -- active high
snooze_out : out std_logic
);
end entity;
architecture rtl of snooze is
signal snooze_timer : integer range 0 to 60:= 60 ;
41
begin
snoozer: process (reset, alarm_ring, set_snooze, clock_seconds, clock_mode, alarm_mode, snooze_timer)
begin
– to reset to predetermined internal value
if reset='0' then
snooze_timer <= 60;
elsif clock_seconds'event and clock_seconds='0' then
– mechanism for starting snoozing
if ( ( alarm_mode = '0' ) and ( clock_mode = '0' ) and ( alarm_ring = '1' ) and ( set_snooze ='0' ) ) then
snooze_timer <= 0;
end if;
– mechanism for handling snooze duration of 6 seconds
if ( ( snooze_timer < 6 ) )then
snooze_out <= '1' ;
snooze_timer <= snooze_timer + 1;
else
snooze_out <= '0' ;
end if;
end if;
end process snoozer;
end rtl;
7.5. display_rotator.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
42
entity display_rotator is
port
(
reset : in std_logic;
clk : in std_logic; -- input signals
min_digit_unit : in std_logic_vector (3 downto 0); -- minute 00:0X signal
min_digit_tens : in std_logic_vector (3 downto 0); -- minute 00:X0 signal
hour_digit_unit : in std_logic_vector (3 downto 0); -- hour 0X:00 signal
hour_digit_tens : in std_logic_vector (3 downto 0); -- hour X0:00 signal
digit_selector : out std_logic_vector (3 downto 0);-- active high
out_display : out std_logic_vector (3 downto 0)
);
end entity;
architecture rtl of display_rotator is
begin
rotation: process (clk,reset)
variable counter1 : integer range 0 to 12499 := 0;
variable selector : integer range 0 to 4 := 0;
begin
– mechanism for handling the refresh rate of LED-Mux Display
if reset='0' then
counter1 := 0;
selector := 0;
elsif (clk'event and clk='1') then
if (counter1 = 12499) then
selector := selector + 1;
counter1 := 0;
43
else
counter1 := counter1 + 1;
end if;
if (selector = 4) then
selector :=0 ;
end if;
– mechanism for handling the LED-Mux Display rotation
case selector is
when 0 => out_display <= min_digit_unit;
digit_selector <="0001";
when 1 => out_display <= min_digit_tens;
digit_selector <="0010";
when 2 => out_display <= hour_digit_unit;
digit_selector <="0100";
when others => out_display <= hour_digit_tens;
digit_selector <="1000";
end case;
end if;
end process rotation;
end rtl;
7.6. dot_pointer.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity dot_pointer is
44
port
(
clk : in std_logic; -- input signals
digit_selector : in std_logic_vector (3 downto 0); -- active high
dot_point : out std_logic
);
end entity;
architecture rtl of dot_pointer is
begin
dot_pointer: process (digit_selector,clk)
– mechanism to turn on the dot at the appropriate spot
begin
case digit_selector is
when "0100" => dot_point <=clk;
when others => dot_point <='0';
end case;
end process dot_pointer;
end rtl;
7.7. sevenSegment.vhd
library ieee;
use ieee.std_logic_1164.all;
package SevenSegmentDecoding is
function convert_SevenSegment(i: in std_logic_vector(3 downto 0)) return std_logic_vector;
end package SevenSegmentDecoding;
package body SevenSegmentDecoding is
45
function convert_SevenSegment(i: in std_logic_vector(3 downto 0)) return std_logic_vector is
variable result : std_logic_vector (6 downto 0);
begin
– mechanism for arranging the seven-segment display
case i is
when "0000" => result :="0111111";
when "0001" => result :="0000110";
when "0010" => result :="1011011";
when "0011" => result :="1001111";
when "0100" => result :="1100110";
when "0101" => result :="1101101";
when "0110" => result :="1111101";
when "0111" => result :="0000111";
when "1000" => result :="1111111";
when "1001" => result :="1101111";
when "1010" => result :="1110111";
when "1011" => result :="1111100";
when "1100" => result :="0111001";
when "1101" => result :="1011110";
when "1110" => result :="1111001";
when others => result :="1110001";
end case;
return result;
end convert_SevenSegment;
end SevenSegmentDecoding;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use work.SevenSegmentDecoding.all;
entity sevenSegment is
46
port
(
data_in : in std_logic_vector(3 downto 0);
data_out : out std_logic_vector(6 downto 0)
);
end entity;
architecture rtl of sevenSegment is
begin
data_out <= convert_SevenSegment(data_in);
end rtl;
8. References
Lab5 SevenSegment report
http://www.codeproject.com/Tips/444385/Frequency-Divider-with-VHDL
47