The Smart Alarm Clock: (Wing Yiu) Calvin Chan (9819484), Computer Engineering Student, Mcmaster University
The Smart Alarm Clock: (Wing Yiu) Calvin Chan (9819484), Computer Engineering Student, Mcmaster University
I. INTRODUCTION The smart alarm clock provides a new move away functionality concept over the conventional alarm clock design. In addition to the conventional basic alarm clock functionalities, the alarm clock finds a random path and move away from its original position during alarm time. The basic function of modern alarm clock design includes a timing device, a buzzer, a snooze control (the temporary disable button) and main buzzer switch snooze control provides a safe re-buzz function in case the user turns off the alarm because of fatigue and buzz again in a preset time interval. This design is useful while the user is not yet adapted to the function of the alarm clock, normally after a certain a period of usage, this function is no longer useful due to the fact that the user subconsciously realized the position of the main buzzer switch and turn off the alarm clock. This design overcomes this problem by introducing a mo ving mechanism. The idea is the have the user to find the clock after it was first switched off and then the user can regain consciousness by looking for the device. Prototype implementation with VHDL allows additional interfaces to be added easily for future expansion, including other movable mechanism and alarm sounds setting. This results a multi-functional base for any advance alarm clock design. II. HARDWARE INTERFACE DESIGN The smart alarm clock design contains two major parts: Hardware Interface Design and VHDL Design. The Altera UP2 Board (FLEX 10K: EPF10K70RC2402 Chip onboard) was used with the Altera MAX+PlusII CAD as the prototyping core. The UP2 Board is connected to an external display and alarm panel with five red LEDs, two yellow LEDs, six 330Ohms pull-up resistors, one 4 -12V 3.6KHz piezo alarm buzzer, two Futaba FP-S148 Indirect drive servo motors and four 7segment LED digit display (Fig. 1).
Fig. 2 Hardware interface connection
The LED display front panel uses 5V low true logic. The control signaling LEDs, 7S-LEDM0a -g, 7S-LEDM1ag, 7S-LEDH0a-g and 7S-LEDH1a-g are connected a number of separate 330Ohms pull-up resistor respectively . The interfacing between the UP1 Board and the display panel are connected with a 40 pins ribbon cable. The panel is connected to the UP1 Board by separate 22 AWG wires glued into the ribbon connector to provide a strong connectivity during experiment (Fig. 2).
On the control panel, there are 5 control signaling LEDs (alarm_on_off, confirm_led and mode indicator leds). The control signaling LEDs connectivity is shown in TABLE I for reference. The alarm_on_off LED provides the user the alarm on/off control information. The alarm_on_off LED illuminate when the alarm function is turned ON. The alarm_on_off signal itself is low true. The confirm_led LED display the confirmation status during time setup and
alarm time setup. The new time value is confirmed when the LED is ON. The confirm_led signal itself is low true. The set_st, alarm_st and disp_st LEDs are use for debugging purpose; they turned ON according to the current main state of the smart alarm clock. Hence, only one of these three LEDs should illuminate at any instance of time.
TABLE I CONTROL SIGNALING LED CONNECTIVITY Control Signal Programming Expansion Slot Pin Name Pin Slot Number alarm_on_off 222 C 48 confirm_led 223 C 49 set_st 225 C 50 alarm_st 226 C 51 disp_st 227 C 52 (NOTE : Programming Pin number used for Max+PlusII pin assignment only, the Slot Pin number is respect to the physical pin location)
Fig. 4 Control signaling LEDs (alarm_on_off, confirm_led, set_st, alarm_st and disp_st)
III. VHDL STRUCTURE A ND BUILDING BLOCKS The smart alarm clock design contains 11 functional modules in total. They are listed as follow: smart_alarm, control_fsm, time_count, buzz_mod, rand_gen, motor_count, MOTOR_CONTROL, CLK_DIV, DEBOUNCE, DEC_7SEG and ONEPULSE.
A. Main Module: smart_alarm.vhd
The 7-segments LED digit display each provides 8 inputs (7 for digit and 1 for decimal point). In this design, only the 7 digits are used and the decimal point is used for experimental and debugging purposes. Two additional LEDs are connected to the same output dummy_led1 for double dots flashing display. The connectivity assignments are shown in TABLE II.
TABLE II 7-SEMENTS LED CONNECTIVITY Control Signal Name Expansion Slot Pin Slot Number min0_seg_a-g C 15-21 min0_seg_dot C 22 min1_seg_a-g C 23-29 min1_seg_dot C 30 hr0_seg_a-g C 31-37 hr0_seg_dot C 38 hr1_seg_a-g C 39-45 hr1_seg_dot C 46 Dummy_led1 C 47 (NOTE : Programming Pin number is not shown here, please refer to [1])
330 O h ms B1 set_st U P2 Connector al a r m_ On_Off conf irm L ED 7 S-L ED M0a 7S- LED M0b 7S- LE D M0f 7S- LE D M0g ala _st disp_st 330 Ohms
The smart_alarm module is the top hierarchy of the smart alarm clock design; it provides the inter-connectivity of all modules. All the expansion and current hardware output are done in this module. B. FSM Control Module: control_fsm.vhd The sequential controlling algorithm of the smart alarm clock is implemented in this module. It mainly provides the following functions: I/O state control, display panel control functions, current time setting, alarm-timer setting/checking and snooze-timer setting/checking. The I/O state control allows the alarm clock to perform the correction function according to its state and change state under certain conditions. A multi-level state machine approach is used. A multi-level state machine is one that contains sub-states. Each of the many sub-states used to improve the readability of the VHDL code and simplifies the hardware description complexity. The state description is giving in TABLE III.
TABLE III STATE DESCRIPTION AND HIERARCHY State Type States Description Global_state SetTime General state of the alarm SetAlarm clock. Display ST_state ModHr Substate of SetTime state. ModMin It indicates the current Confirm position of the modification take place. SA_state ModHr Substate of SetAlarm state. ModMin It indicates the current AlarmOnOff position of the modificaConfirm tion take place. User can turn On/Off the alarm in the AlarmOnOff state. STL_state NewEntry This state signal used for Modified loading the current time into the SetTime register during the first entrance of SetTime state.
switching assignment defect is defined as the combinational comparison error during a sequential bit change on the comparing time. This problem can eliminate by using the Inertial Delay function (AFTER <time>) in VHDL, which outputs changes after the input stabilized for a certain time interval as illustrated below.
snooze_trig <= (CompareBCD(cur_min0, int_snz_min0) AND CompareBCD(cur_min1, int_snz_min1) AND CompareBCD(cur_hr0, int_snz_hr0) AND CompareBCD(cur_hr1, int_snz_hr1) AND modify_mask) AFTER 500 ns;
During the snooze mode the buzzer output is masked away by a snooze mask signal. The mask is contained in a sequential logic block, which detects the strobe from the snooze time comparison output. This mask is reset after the alarm is turned off. C. Timing Logic Module: time_count.vhd The timing logic module performs the time counting by using the 1Hz clock input from the CLK_DIV module. Inside the time_count module, there are three sets of BCD counters that provide the counting to hours, minutes and seconds respectively. The loading inputs of the counters are connected to the control_fsm for setup time, which strobe into the counter after confirmation. The input of the strobe line is connected to the ONE_PULSE module to ensure that the strobe last for maximum of one clock pulse to avoid continuous time reset. Each set of BCD counter requires a carry out to the next digit (except hour counting) like a full-adder. Also, the counting differs from normal counter due to the 24hrs and 60 min/sec carry counting. These constrains were satisfied by using the conditional checking within a process block (see VHDL code for detail). D. Buzzer Sound Controlling Module: buzz_mod.vhd The buzzer sound controlling module allows the buzzer to produce various alarm sounds. On the current prototype version, the sound selection is being hard-coded in VHDL. It is possible to expand this feature further by including an extra interface in the FSM control module to allow user to select the buzzer sound. E. Random Number Generator Module: rand_gen.vhd This module provides a true random number generation by using of current time as seed in the pseudo-number generator algorithm to control the random m otion of the smart alarm clock. The random number generator module generates an 8-bits number for forw_back (forward -backward direction selector), left_right (left-right direction selector), step_fb (forward-backward steps) and step_lr (left-right steps). (For the pseudo-number generator algorithm, please refer to [2]-p235,236 for detail)
The alarm clock uses the 1Hz clock signal from the CLK_DIV module to produce blinking function on the display for modification indication and double dot display. Various time values are required to display in different mode of operation. They are, current time (cur_min, cur_hr), temporary setting time (set_min, set_hr) and alarm time (ala_min, ala_hr). The selection amount different timing registers are controlled by a multiplexer with the global_state signal as control to display the correct time on the panel. The smart alarm clock provides a sequential access for current time setup and alarm time setup. As soon as button 1 is pressed in display mode, the state machine switches to SetTime state and allow user to modify the blinking digit with button 2 and confirm the digit with button 1. In the end of each time setup, a confirmation is required from user. The confirmation mode can observe by the confirm_led that toggle by using button 2 during the confirm sub-state. After confirmation is made in current time setup, a strobe is sent to the time_count module to update the time counter described in the next section. As in many programming language, VHDL provides syntax of a procedure call to reduce the amount of code redundancy. Although, VHDL is a hardware description language, which code size is not a concern, but the procedural code still useful for debugging purposes. The time comparing function and minute/hour increment function are implemented in procedural code. By using the procedural code, the function itself can be tested separately and easily by timing simulation to reduce the development time. The alarm timer and snooze timer both implemented by using a time register and a comparison combinational logic to achieve accurate timing. With the use of combinational logic, the problem of multiple bit switching assignment defects take place. The multiple bits
F. Moving Algorithm Module: motor_count.vhd The moving algorithm module provides the motion sequence according to different state. During the alarm time, the moving algorithm module commands the motor_control module to maintain a circular motion, while in snooze mode it commands the motor_control module to move according to the value provided by the rand_gen module. More advance algorithm like obstacle-sensing algorithm can be integrated with this module for future expansion. G. Other Modules The CLK_DIV, DEBOUNCE, DEC_7SEG and ONEPULSE modules are modified/taken from external source, TABLE IV provides a general summer for each module. (Please refer to [2] for m ore detail functional description.)
TABLE IV EXTERNAL FUNCTIONAL MODULE DESCRIPTION Module Descriptions MOTOR_CONTROL Pulse Width Modulation (PWM) control for servo motor. (For more information about PWM please refer to reference [2], [6].) CLK_DIV Clock divider module. Produces various rate clock signals. DEBOUNCE Button input debouncing. DEC_7SEG 7-Segments LED digit display decoder. Provides BCD decoding from 0-9 and blank output for blinking purpose. ONEPULSE Produce a single pulse signal for one clock cycle.
Note that the above information is not listed explicitly in the Max+PlusII user manual. The results are obtained after numerous trial and error experiments during the smart alarm clock implementation. B. Complex multiple input sequential state machine In this smart alarm clock design, the operation mode contains multiple sub-states. The initial idea of having all the state control within one process block was found to be impossible due to constrains mentioned above. The change of state of the original design required the alarm clock to enter into various modes trigger by input button, alarm timer, snooze mode timer, and clock. Due to the fact that a process block does not allow assignment of signal or variable to independently assigns in multiply edge triggering IF clause, therefore, wipe out the original structure of the design described above. The design had modified, each input control device had broken down into individual process block. With this modification, communication link between process blocks must establish with respect to each other for various actions to take place. The complexity of the design increase significantly due to the handshaking issues and various timing problem, which is the major problem to face in the current stage. C. Debugging features missing The timing simulator provided a basis to debug the VHDL design with various complex signals. After numbers of experiments, an uncertainty delay issue was found while debugging a sparking edge issue on the snooze mode alarm triggering issue. In VHDL, the inertial delay is assigned to solve the sparking edge problem. Trials had been made to correct the sparking edge of a comparator output during number assignment stage of the alarm register. According to the information in reference [3] with various sources from the Internet, the inertial delay is the only way to eliminate this problem. The attempt was unsuccessful. Therefore, a suspicion to the simulator accuracy or unsupported feature arose. V. EXPERIMENTAL RESULTS The smart alarm clock prototype v1 does not contain any timing critical components except the time counting. It results very little timing problem in the implementation, as compare to the state machine implementation. The final code had been tested with various compilation settings. TABLE V provides a summary of this experiment.
IV. IMPPLEMENTATION DETAILS During the implementation of the smart alarm clock various technical difficulties had encountered on the implementation of the control module. These problems can generally divided into 3 areas. A. Limitation in Max+PlusII VHDL synthesizer Due to the complex sequential implementation the smart alarm clock requires various advance VHDL hardware description syntax to support the original layout of the design. In Max+PlusII, various advance features are not supported. These features included: transport delay, inertial delay; wait on, wait for; combined use of procedure call and loop; stable attribute; multiple triggering/reset condition not allowed for process statement. (Please refer to [3] for VHDL information.)
TABLE IV
Control Logic Top Level Schematic
COMPILATION Compile Mode Fast Logic Synthesis (Optimization Level 5) Normal Logic Synthesis (Optimization Level 5) WYSIWYG Logic Synthesis (Optimization Level 5)
DETAILS OF T HE SMART ALARM CLOCK Information Details I/O pins used Logic cells used EAB used Avg. Fan-in Tot. Fan-in Synthesized LC I/O pins used Logic cells used EAB used Avg. Fan-in Tot. Fan-in Synthesized LC I/O pins used Logic cells used EAB used Avg. Fan-in Tot. Fan-in Synthesized LC 31/53 (58%) 45/576 (7%) 0/3 (0%) 2.8/4 (70%) 126/2304 (5%) 20/576 (3%) 31/53 (58%) 25/576 (4%) 0/3 (0%) 3.4/4 (85%) 126/2304 (5%) 85/576 (3%) 31/53 (58%) 72/576 (12%) 0/3 (0%) 3.08/4 (77%) 126/2304 (5%) 222/576 (9%)
Current Time
Setup Time
VI. CONCLUSION The smart alarm clock prototype v1 was successfully implemented. It is desirable to combine all the hardware together with LEGO as planned, however, with the time frame limitation, the focus was given to the design functionalities and structure instead of the m echanics. Providing enough time, further improvement can possibly be made on the smart alarm clock. It is logical to provide an obstacle detection function on the clock to allow the alarm clock to find a obstacle free path to move away. VII. A PPENDIX A. VHDL Modules Design Schematics
Accurate Timing Logic (CLK_DIV)
Clock
Wake-up Flag
Front / Back
Left / Right
Mode
Buzzer
Motion Wake-up Flag (Output Pin)
Random Instruction
Motion Instructio n
Servomotor
On/Off Control
On Initialize [Power key pressed] / Initialize
Power off
Power on
entry set time mode
[1] University Program Design Laboratory Package User Guide, Version 2, Altera Corporation, October 2001. [2] J.O. Hamblen and M.D. Furman, Rapid Prototyping of Digital Systems, 2nd Edition, KAP, 2001. [3] D.L. Perry, VHDL Programming by Example, 4th Edition, McGraw-Hill, 2002. [4] S. Brown and Z. Vranesic, Fundamentals of Digital Logic with VHDL design, McGraw-Hill, 2000. [5] P.J. Ashenden, The VHDL Cookbook, 1st Edition, 1990. [6] G.McComb, The Robot Builders Bonanza, 2nd Edition, McGraw-Hill, 2000.
Overall Model
Set Time Mode
Confirmed
Display Mode
Alarm Mode
Snooze Mode
Button 2 Pressed
Button 2 Pressed
Button 2 Pressed
Button 2 Pressed
Confirmation
Button 1 Pressed
Alarm On/Off
Button 2 Pressed
Confirmation
Button 1 Pressed
Alarm Mode
Automatic Extra Function Function Complete Mode 1 (Robotic Mechanism Add-on) Snooze Mode
Button 1 Pressed
Buzzing Mode
Automatic Function Complete DisplayMode
Button 2 Pressed
Snooze Mode
Time out
5 Minutes Timer
ala_st : OUT STD_LOGIC; disp_st : OUT STD_LOGIC; dummy : OUT STD_LOGIC; snooze_mask_port : OUT STD_LOGIC; snooze_trig_port: OUT STD_LOGIC; alarm_now_port : OUT STD_LOGIC); alarm_trig_port : OUT STD_LOGIC; alarm_onoff_port: OUT STD_LOGIC; mask_cond_port : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); time0 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); time1 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); time2 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); time3 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END COMPONENT; COMPONENT time_count PORT( clock : IN STD_LOGIC; load : IN STD_LOGIC; enable : IN STD_LOGIC; -- Loading Inputs set_sec0 : IN STD_LOGIC_VECTOR(3 DOWNTO 0); set_sec1 : IN STD_LOGIC_VECTOR(3 DOWNTO 0); set_min0 : IN STD_LOGIC_VECTOR(3 DOWNTO 0); set_min1 : IN STD_LOGIC_VECTOR(3 DOWNTO 0); set_hr0 : IN STD_LOGIC_VECTOR(3 DOWNTO 0); set_hr1 : IN STD_LOGIC_VECTOR(3 DOWNTO 0); -- Display Outpus bcd_sec_out0 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0); bcd_sec_out1 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0); bcd_min_out0 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0); bcd_min_out1 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0); bcd_hr_out0 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0); bcd_hr_out1 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0)); END COMPONENT; COMPONENT motor_count PORT( clock : IN STD_LOGIC; motion_trigger : IN STD_LOGIC; rotate : IN STD_LOGIC; -- Direction of Motion forw_back : IN STD_LOGIC; left_right : IN STD_LOGIC; -- Number of Steps for Movement (0 -7 Possible Steps) steps_fb : IN STD_LOGIC_VECTOR(2 DOWNTO 0); steps_lr : IN STD_LOGIC_VECTOR(2 DOWNTO 0); -- To Control Driver lmotor_dir : OUT STD_LOGIC; rmotor_dir : OUT STD_LOGIC; lmotor_speed : OUT STD_LOGIC; rmotor_speed : OUT STD_LOGIC); END COMPONENT; COMPONENT rand_gen PORT( clock : IN STD_LOGIC; -- Direction of Motion forw_back : OUT STD_LOGIC; left_right : OUT STD_LOGIC; -- Number of Steps for Movement (0 -7 Possible Steps) steps_fb: OUT STD_LOGIC_VECTOR(2 DOWNTO 0); steps_lr : OUT STD_LOGIC_VECTOR(2 DOWNTO 0)); END COMPONENT; COMPONENT buzz_mod PORT( buzz_mode : IN INTEGER; buzz_on : IN STD_LOGIC; clock_10Hz: IN STD_LOGIC; clock_1Hz : IN STD_LOGIC; buzzer : OUT STD_LOGIC); END COMPONENT; COMPONENT MOTOR_CONTROL PORT( clock_1khz : IN STD_LOGIC; lmotor_dir, rmotor_dir : IN STD_LOGIC; lmotor_speed, rmotor_speed : IN STD_LOGIC; lmotor, rmotor : OUT STD_LOGIC); END COMPONENT; COMPONENT ONEPULSE PORT( PB_debounced, clock : IN STD_LOGIC; PB_single_pulse : OUT STD_LOGIC); END COMPONENT; COMPONENT CLK_DIV PORT ( clock_25Mhz : IN STD_LOGIC; clock_1MHz : OUT STD_LOGIC; clock_100KHz : OUT STD_LOGIC; clock_10KHz : OUT STD_LOGIC; clock_1KHz : OUT STD_LOGIC; clock_100Hz : OUT STD_LOGIC; clock_10Hz : OUT STD_LOGIC; clock_1Hz : OUT STD_LOGIC); END COMPONENT; COMPONENT DEBOUNCE PORT( pb, clock_100Hz : INSTD_LOGIC; pb_debounced : OUT STD_LOGIC); END COMPONENT; COMPONENT DEC_7SEG PORT( hex_digit : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
segment_a, segment_b, segment_c, segment_d, segment_e, segment_f, segment_g : OUT STD_LOGIC); END COMPONENT; SIGNAL int_load : SIGNAL int_button1 SIGNAL int_button2 SIGNAL load : SIGNAL cur_sec0 : SIGNAL cur_sec1 : SIGNAL cur_min0 SIGNAL cur_min1 SIGNAL cur_hr0 SIGNAL cur_hr1 SIGNAL set_min0 SIGNAL set_min1 SIGNAL set_hr0 SIGNAL set_hr1 SIGNAL clock_1MHz SIGNAL clock_100KHz SIGNAL clock_10KHz SIGNAL clock_1KHz SIGNAL clock_100Hz SIGNAL clock_10Hz SIGNAL clock_1Hz SIGNAL deb_button1 SIGNAL deb_button2 SIGNAL motion SIGNAL buzzer_on_off SIGNAL mux_select SIGNAL enable SIGNAL null_time SIGNAL buzz_mode -- Motion Related SIGNAL forw_back SIGNAL left_right SIGNAL steps_fb : SIGNAL steps_lr : SIGNAL lmotor_dir SIGNAL rmotor_dir SIGNAL lmotor_speed SIGNAL rmotor_speed BEGIN ctrl_logic : control_fsm PORT MAP( clock_25Mhz,clock_1Hz, cur_min0,cur_min1,cur_hr0,cur_hr1, set_min0,set_min1,set_hr0,set_hr1, disp_min0,disp_min1,disp_hr0,disp_hr1, int_load,buzzer_on_off,motion, deb_button1,deb_button2, mux_select, confirm_led,alarm_on_off, -- Test purpose state identifier set_st,ala_st,disp_st,alarm_now ); STD_LOGIC; : STD_LOGIC; : STD_LOGIC; STD_LOGIC; STD_LOGIC_VECTOR(3 DOWNTO 0); STD_LOGIC_VECTOR(3 DOWNTO 0); : STD_LOGIC_VECTOR(3 DOWNTO 0); : STD_LOGIC_VECTOR(3 DOWNTO 0); : STD_LOGIC_VECTOR(3 DOWNTO 0); : STD_LOGIC_VECTOR(3 DOWNTO 0); : STD_LOGIC_VECTOR(3 DOWNTO 0); : STD_LOGIC_VECTOR(3 DOWNTO 0); : STD_LOGIC_VECTOR(3 DOWNTO 0); : STD_LOGIC_VECTOR(3 DOWNTO 0); : STD_LOGIC; : STD_LOGIC; : STD_LOGIC; : STD_LOGIC; : STD_LOGIC; : STD_LOGIC; : STD_LOGIC; : STD_LOGIC; : STD_LOGIC; : STD_LOGIC; : STD_LOGIC; : STD_LOGIC_VECTOR(1 DOWNTO 0); : STD_LOGIC; : STD_LOGIC_VECTOR(3 DOWNTO 0); : INTEGER; : STD_LOGIC; : STD_LOGIC; STD_LOGIC_VECTOR(2 DOWNTO 0); STD_LOGIC_VECTOR(2 DOWNTO 0); : STD_LOGIC; : STD_LOGIC; : STD_LOGIC; : STD_LOGIC;
min0_seg_e,min0_seg_f,min0_seg_g ); min1_7seg : DEC_7SEG PORT MAP ( disp_min1, min1_seg_a,min1_seg_b,min1_seg_c,min1_seg_d, min1_seg_e,min1_seg_f,min1_seg_g ); hr0_7seg : DEC_7SEG PORT MAP ( disp_hr0, hr0_seg_a,hr0_seg_b,hr0_seg_c,hr0_seg_d, hr0_seg_e,hr0_seg_f,hr0_seg_g ); : DEC _7SEG PORT MAP ( disp_hr1, hr1_seg_a,hr1_seg_b,hr1_seg_c,hr1_seg_d, hr1_seg_e,hr1_seg_f,hr1_seg_g );
hr1_7seg
-- Null Time, Enable (Default), Dummy Flashing LEDs null_time <= "0000"; enable <= '1'; dummy_led1<= clock_1Hz WHEN mux_select = "00" ELSE '0' WHEN mux_select = "10" ELSE '1'; dummy_led2<= clock_1Hz WHEN mux_select = "00" ELSE '0' WHEN mux_select = "10" ELSE '1'; buzz_mode <= 1; -- Testing Purpose LEDs (Low True) min0_dot <= '1'; min1_dot <= '1'; hr0_dot <= '1'; hr1_dot <= '1'; END alarm_behavior;
time_counter: time_count PORT MAP (clock_1Hz, load,enable, null_time,null_time, set_min0,set_min1,set_hr0,set_hr1, cur_sec0,cur_sec1,cur_min0,cur_min1,cur_hr0,cur_hr1 ); motor_ctrl: motor_count PORT MAP (clock_1Hz, motion,buzzer_on_off, forw_back,left_right, steps_fb,steps_lr, lmotor_dir,rmotor_dir, lmotor_speed,rmotor_speed ); step_gen: rand_gen PORT MAP ( clock_100Hz, forw_back,left_right, steps_fb,steps_lr);
buzzer_mod: buzz_mod PORT MAP( buzz_mode,buzzer_on_off, clock_1Hz,clock_10Hz, buzzer ); m_drive: MOTOR_CONTROL PORT MAP (clock_1KHz, lmotor_dir,rmotor_dir, lmotor_speed,rmotor_speed, lmotor, rmotor ); clk_divider : CLK_DIV PORT MAP ( clock_25Mhz, clock_1MHz,clock_100KHz,clock_10KHz,clock_1KHz, clock_100Hz,clock_10Hz,clock_1Hz); deb_but1 : DEBOUNCE PORT MAP (button1, clock_100Hz, int_button1); : DEBOUNCE PORT MAP (button2, clock_100Hz, int_button2);
deb_but2
one_pulse0 : ONEPULSE PORT MAP ( int_load, clock_1Hz, load); one_pulse1 : ONEPULSE PORT MAP ( int_button1, clock_10Khz, deb_button1); one_pulse2 : ONEPULSE PORT MAP ( int_button2, clock_10Khz, deb_button2); min0_7seg : DEC_7SEG PORT MAP ( disp_min0, min0_seg_a,min0_seg_b,min0_seg_c,min0_seg_d,
B. control_fsm.vhd
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.all; USE IEEE.STD_LOGIC_ARITH.all; USE IEEE.STD_LOGIC_UNSIGNED.all; ENTITY control_fsm IS PORT( clock : IN STD_LOGIC; clock1Hz : IN STD_LOGIC; -- Current Time (from time_count) cur_min0 : IN STD_LOGIC_VECTOR(3 DOWNTO 0); cur_min1 : IN STD_LOGIC_VECTOR(3 DOWNTO 0); cur_hr0 : IN STD_LOGIC_VECTOR(3 DOWNTO 0); cur_hr1 : IN STD_LOGIC_VECTOR(3 DOWNTO 0); -- Temporary Setup Display Time set_min0 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0); set_min1 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0); set_hr0 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0); set_hr1 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0); -- Display Time bcd_min0 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); bcd_min1 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); bcd_hr0 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); bcd_hr1 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); -- Control Output internal_load : OUT STD_LOGIC; buzzer : OUT STD_LOGIC; motion : OUT STD_LOGIC; -- Button Latch button1 : IN STD_LOGIC; button2 : IN STD_LOGIC; -- Display MUX Select mux_select : BUFFER STD_LOGIC_VECTOR(1 DOWNTO 0); -- LED Output confirm_led : OUT STD_LOGIC; ala_on_off : BUFFER STD_LOGIC; -- Testing Purposes Port set_st : OUT STD_LOGIC; ala_st : OUT STD_LOGIC; disp_st : OUT STD_LOGIC; -snooze_mask_port : OUT STD_LOGIC; -snooze_trig_port: OUT STD_LOGIC; alarm_now_port : OUT STD_LOGIC -alarm_trig_port : OUT STD_LOGIC; -alarm_onoff_port: OUT STD_LOGIC; -mask_cond_port : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); -time0 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); -time1 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); -time2 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); -time3 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0) ); END control_fsm; ARCHITECTURE fsm_behavior OF control_fsm IS TYPE GLOBAL_STATE IS( SetTime, SetAlarm, Display ); TYPE ST_STATE IS( ModHr, ModMin, Confirm); ModHr, ModMin, AlarmOnOff, Confirm); SnoozeOn, SnoozeOff ); ( NewEntry, Modified );
-- Internal Snooze Wakeup SIGNAL int_snz_min0 SIGNAL int_snz_min1 SIGNAL int_snz_hr0 SIGNAL int_snz_hr1
Time : STD_LOGIC_VECTOR(3 DOWNTO 0); : STD_LOGIC_VECTOR(3 DOWNTO 0); : STD_LOGIC_VEC TOR(3 DOWNTO 0); : STD_LOGIC_VECTOR(3 DOWNTO 0);
-- Initial Setup Time (Obtained from current time when entering SetTime state) SIGNAL init_set_min0 : STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL init_set_min1 : STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL init_set_hr0 : STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL init_set_hr1 : STD_LOGIC_VECTOR(3 DOWNTO 0); -- Blinking Mask SIGNAL blink : STD_LOGIC_VECTOR(3 DOWNTO 0);
-- Comparator Function FUNCTION CompareBCD(a : STD_LOGIC_VECTOR; b : STD_LOGIC_VECTOR) RETURN STD_LOGIC IS VARIABLE c : STD_LOGIC; BEGIN IF (a = b) THEN c := '1'; ELSE c := '0'; END IF; return c; END CompareBCD; -- Increment Hour Procedure PROCEDURE IncrementHr( hr0 : INOUT STD_LOGIC_VECTOR(3 DOWNTO 0); hr1 : INOUT STD_LOGIC_VECTOR(3 DOWNTO 0)) IS BEGIN IF ( (hr0 = "0011") AND (hr1 = "0010") ) THEN hr0 := "0000"; hr1 := "0000"; ELSIF (hr0 = "1001") THEN hr0 := "0000"; hr1 := hr1 + '1'; ELSE hr0 := hr0 + '1'; END IF; END In crementHr; -- Increment Minute Procedure PROCEDURE IncrementMin(min0 : INOUT STD_LOGIC_VECTOR(3 DOWNTO 0); min1 : INOUT STD_LOGIC_VECTOR(3 DOWNTO 0); hr0 : INOUT STD_LOGIC_VECTOR(3 DOWNTO 0); hr1 : INOUT STD_LOGIC_VECTOR(3 DOWNTO 0)) IS BEGIN IF (min0 = "1001") THEN -- MINUTES digit 0 count up to 9 min0 := "0000"; IF (min1 = "0101") THEN-- MINUTES digit 1 count up to 5 min1 := "0000"; IF ( (hr0 = "0011") AND (hr1 = "0010") ) THEN hr0 := "0000"; hr1 := "0000"; ELSIF (hr0 = "1001") THEN hr0 := "0000"; hr1 := hr1 + '1'; ELSE hr0 := hr0 + '1'; END IF; ELSE min1 := min1 + '1'; END IF; ELSE min0 := min0 + '1'; END IF; END IncrementMin; ------------------------- Architecture Begin ------------------------BEGIN -------------------------- Combinational Logic --------------------------- Alarm Triggering Hardware alarm_trig <= ( CompareBCD(cur_min0, int_ala_min0)AND CompareBCD(cur_min1, int_ala_min1)AND CompareBCD(cur_hr0, int_ala_hr0) AND CompareBCD(cur_hr1, int_ala_hr1))AFTER 500 ns WHEN (current_state = Display) ELSE '0'; -- Snooze Mode Alarm Triggering Hardware snooze_trig <= (CompareBCD(cur_min0, int_snz_min0)AND CompareBCD(cur_min1, int_snz_min1)AND CompareBCD(cur_hr0, int_snz_hr0)AND CompareBCD(cur_hr1, int_snz_hr1)AND modify_mask) AFTER 500 ns; mux_select <= mux_select1 & mux_select0; buzzer <= (alarm_now AND (NOT snooze_mask)); -- MINUTES digit 1 increment -- MINUTES digit 0 increment
-- Add Later to Improve... -- TYPE SN_STATE IS( -TYPE STL_STATE IS SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL
--
current_state: GLOBAL_STATE; set_time_mode : ST_STATE; set_alarm_mode: SA_STATE; snooze_mode : SN_STATE; set_load_mode : STL_STATE; confirm_ST confirm_SA alarm_reset alarm_trig alarm_now int_ala_on_off snooze_mask snooze_reset: snooze_trig modify_mask mask_cond mux_select1 mux_select0 : : : : : : STD_LOGIC; STD_LOGIC; STD_LOGIC; STD_LOGIC; STD_LOGIC; STD_LOGIC;
-- Internal Alarm Time SIGNAL int_ala_min0: SIGNAL int_ala_min1: SIGNAL int_ala_hr0 SIGNAL int_ala_hr1
STD_LOGIC_VECTOR(3 DOWNTO 0); STD_LOGIC_VECTOR(3 DOWNTO 0); : STD_LOGIC_VECTOR(3 DOWNTO 0); : STD_LOGIC_VECTOR(3 DOWNTO 0);
motion <= (button2 AND Alarm_now); blink <= (clock1Hz & clock1Hz & clock1Hz & clock1Hz);
-- Temporary Setup Display Time SIGNAL int_set_min0: STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL int_set_min1: STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL int_set_hr0 : STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL int_set_hr1 : STD_LOGIC_VECTOR(3 DOWNTO 0);
-- Time Display Output & Blinking Effect bcd_min0 <=cur_min0 WHEN (current_state = Display) ELSE -- Blink when modifying set_min0 AND blink WHEN ((current_state = SetTime) AND (set_time_mode = ModMin)) ELSE set_min0 WHEN (current_state = SetTime) ELSE
10
int_ala_min0 AND blink WHEN ((current_state = SetAlarm) AND (set_alarm_mode = ModMin)) ELSE int_ala_min0; bcd_min1 <=cur_min1 WHEN (current_state = Display) ELSE -- Blink when modifying set_min1 AND blink WHEN ((current_state = SetTime) AND (set_time_mode = ModMin)) ELSE set_min1 WHEN (current_state = SetTime) ELSE int_ala_min1 AND blink WHEN ((current_state = SetAlarm) AND (set_alarm_mode = ModMin)) ELSE int_ala_min1; bcd_hr0 <= cur_hr0 WHEN (current_state = Display) ELSE -- Blink when modifying set_hr0 AND blink WHEN ((current_state = SetTime) AND (set_time_mode = ModHr)) ELSE set_hr0 WHEN (current_state = SetTime) ELSE int_ala_hr0 AND blink WHEN ((current_state = SetAlarm) AND (set_alarm_mode = ModHr)) ELSE int_ala_hr0; bcd_hr1 <= cur_hr1 WHEN (current_state = Display) ELSE -- Blink when modifying set_hr1 AND blink WHEN ((current_state = SetTime) AND (set_time_mode = ModHr)) ELSE set_hr1 WHEN (current_state = SetTime) ELSE int_ala_hr1 AND blink WHEN ((current_state = SetAlarm) AND (set_alarm_mode = ModHr)) ELSE int_ala_hr1; -- Low True LED ala_on_off <= (NOT int_ala_on_off); confirm_led <= (NOT confirm_ST) WHEN (current_state = SetTime) ELSE (NOT confirm_SA) WHEN (current_state = SetAlarm) ELSE '1'; -- Assign the Setup Time -- (Use initialized value at entry point, when modification -- made by button2 switch to user defined setup time.) set_min0 <= int_set_min0 WHEN (set_load_mode = Modified) ELSE init_set_min0; set_min1 <= int_set_min1 WHEN (set_load_mode = Modified) ELSE init_set_min1; set_hr0 <= int_set_hr0 WHEN (set_load_mode = Modified) ELSE init_set_hr0; set_hr1 <= int_set_hr1 WHEN (set_load_mode = Modified) ELSE init_set_hr1; --------------------------- Test Purpose Setting ---------------------------- dummy <= clock; -- motion <= '0'; alarm_now_port <= NOT alarm_now; -- alarm_trig_port <= alarm_trig; -- alarm_onoff_port <= alarm_on_off; -- snooze_mask_port <= snooze_mask; -- snooze_trig_port <= snooze_trig AFTER 500 ns; -- time0 <= bcd_snz_min0; -- time1 <= bcd_snz_min1; -- time2 <= bcd_snz_hr0; -- time3 <= bcd_snz_hr1; -- Test: show the current state set_st <= '0' WHEN (current_state = SetTime) ELSE '1' WHEN (current_state = SetAlarm) ELSE '1'; ala_st <= '1' WHEN (current_state = SetTime) ELSE '0' WHEN (current_state = SetAlarm) ELSE '1'; disp_st <= '1' WHEN (current_state = SetTime) ELSE '1' WHEN (current_state = SetAlarm) ELSE '0'; ------------------------ Alarm Time Action -----------------------Alarm_Check: PROCESS( alarm_trig, button1 ) BEGIN IF (button1 = '1') THEN alarm_now <= '0'; ELSIF (alarm_trig'EVENT AND alarm_trig = '1') THEN IF (int_ala_on_off = '1') THEN alarm_now <= '1'; END IF; END IF; END PROCESS Alarm_Check;
BEGIN IF (button2'EVENT AND button2 = '1') THEN temp_snz_min0 := cur_min0; temp_snz_min1 := cur_min1; temp_snz_hr0 := cur_hr0; temp_snz_hr1 := cur_hr1; -- Increment 3 Minutes for the next Snooze Alarm Time IncrementMin( temp_snz_min0,temp_snz_min1,temp_snz_hr0,temp_snz_hr1 ); -- TEST MODE Increment only 1 Minute. -IncrementMin( temp_snz_min0,temp_snz_min1,temp_snz_hr0,temp_snz_hr1 ); -IncrementMin( temp_snz_min0,temp_snz_min1,temp_snz_hr0,temp_snz_hr1 ); END IF; int_snz_min0 <= temp_snz_min0; int_snz_min1 <= temp_snz_min1; int_snz_hr0 <= temp_snz_hr0; int_snz_hr1 <= temp_snz_hr1; END PROCESS Snooze_Ctrl1; -- Setup the snooze alarm mask Snooze_Ctrl2: PROCESS( snooze_trig,button2,button1 ) VARIABLE mask_cond0: STD_LOGIC; VARIABLE mask_cond1: STD_LOGIC; BEGIN IF (snooze_trig = '1') THEN mask_cond0 := '1'; ELSIF (button2'EVENT AND button2 = '1') THEN mask_cond0 := '0'; END IF; -- Alarm_now must exist in the condition -- (mask_cond1 should not be reset when the clock is not in snooze state) IF ((button2 AND Alarm_now) = '1') THEN mask_cond1 := '0'; ELSIF (button1'EVENT AND button1 = '1') THEN mask_cond1 := '1'; END IF; -mask_cond <= mask_cond1 & mask_cond0; mask_cond_port <= mask_cond; END PROCESS Snooze_Ctrl2; Snooze_Ctrl3: PROCESS( clock ) VARIABLE temp_mask : STD_LOGIC; BEGIN IF (clock'EVENT AND clock = '1') THEN IF (mask_cond = "00") THEN temp_mask := '1'; ELSE temp_mask := '0'; END IF; snooze_mask <= temp_mask; END IF; END PROCESS Snooze_Ctrl3; ------------------------- Expansion Features ------------------------Clock_On: PROCESS( clock ) BEGIN END PROCESS Clock_On;
-------------------------------------- State Change Trigger by button1 -------------------------------------Global_FSM: PROCESS( button1 ) -- Intermediate Variable VARIABLE min0_buff : STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE min1_buff : STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE hr0_buff : STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE hr1_buff : STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE temp_load : STD_LOGIC;
BEGIN IF (button1'EVENT AND button1 = '1') THEN -- Reset Internal Load -- (Notice that the load signal would automatically reset when it enters the SetAlarm state) temp_load := '0'; CASE current_state IS WHEN SetTime => IF (set_time_mode = ModHr) THEN set_time_mode <= ModMin; ELSIF (set_time_mode = ModMin) THEN set_time_mode <= Confirm; ELSE set_time_mode <= ModHr; -- Return to SetTime again if 'Not Confirm' IF (confirm_ST = '1') THEN current_state <= SetAlarm; -- Set the load signal temp_load := '1'; -- Display the alarm time mux_select0 <= '1'; END IF; END IF; WHEN SetAlarm => IF (set_alarm_mode = ModHr) THEN set_alarm_mode <= ModMin; ELSIF (set_alarm_mode = ModMin) THEN set_alarm_mode <= AlarmOnOff; ELSIF (set_alarm_mode = AlarmOnOff) THENset_alarm_mode <= Confirm; ELSE set_alarm_mode <= ModHr; -- Return to SetAlarm again if 'Not Confirm' IF (confirm_SA = '1') THEN
-------------------------- Snooze Time Control --------------------------- Stablize the trigger signal Snooze_Ctrl0: PROCESS( button2, snooze_mask ) BEGIN IF (snooze_mask = '0') THEN modify_mask <= '1'; ELSIF (button2'EVENT AND button2 = '1') THEN modify_mask <= '0'; END IF; END PROCESS Snooze_Ctrl0; -- Reset the snooze time Snooze_Ctrl1: PROCESS( button2 ) VARIABLE temp_snz_min0 : STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE temp_snz_min1 : STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE temp_snz_ hr0 : STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE temp_snz_hr1 : STD_LOGIC_VECTOR(3 DOWNTO 0);
11
current_state <= Display; -- Display the actual time mux_select0 <= '0'; END IF; END IF; WHEN Display => IF (alarm_now = '0') THEN -- Not in Alarm Mode, Change to SetTime state current_state <= SetTime; -- Initialize the Setup Time min0_buff := cur_min0; min1_buff := cur_min1; hr0_buff:= cur_hr0; hr1_buff:= cur_hr1; END IF; END CASE; -- Assign the initial setup time init_set_min0 <= min0_buff; init_set_min1 <= min1_buff; init_set_hr0 <= hr0_buff; init_set_hr1 <= hr1_buff; -- Internal Load signal (Trigger the External Pulse Generator for resetting time) internal_load <= temp_load; END IF; END PROCESS Global_FSM;
WHEN SetAlarm => IF (set_alarm_mode = ModHr) THEN IncrementHr( temp_ala_hr0,temp_ala_hr1 ); ELSIF (set_alarm_mode = ModMin) THEN Incremen tMin( temp_ala_min0,temp_ala_min1,temp_ala_hr0,temp_ala_hr1 ); ELSIF (set_alarm_mode = AlarmOnOff) THENtemp_on_off := ( NOT temp_on_off ); ELSE temp_conf2 := ( NOT temp_conf2 ); END IF; WHEN Display => NULL; WHEN OTHERS =>NULL; END CASE; -- Load the procedure output back into the registers int_set_hr0 <= temp_set_hr0; int_set_hr1 <= temp_set_hr1; int_set_min0<= temp _set_min0; int_set_min1<= temp_set_min1; int_ala_hr0 int_ala_hr1 int_ala_min0<= int_ala_min1<= <= temp_ala_hr0; <= temp_ala_hr1; temp_ala_min0; temp_ala_min1;
-- Load the temporary variable into signal [This procedure avoid warning for signal assignment in process] -- (LED Connect to confirm signals) confirm_ST <= temp_conf1; confirm_SA <= temp_conf2; mux_select1 <= temp_mux_sel; int_ala_on_off <= temp_on_off; END IF; END PROCESS Value_Adj;
-------------------------------------- Value Change Trigger by button2 -------------------------------------Value_Adj: PROCESS( button2 ) -- Temporary Setup Display Time VARIABLE temp_set_min0 : STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE temp_set_min1 : STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE temp_set_hr0 : STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE temp_set_hr1 : STD_LOGIC_VECTOR(3 DOWNTO 0); -- Temporary Alarm Display Time VARIABLE temp_ala_min0 : STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE temp_ala_min1 : STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE temp_ala_hr0 : STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE temp_ala_hr1 : STD_LOGIC_VECTOR(3 DOWNTO 0); -- Temporary Control Variables VARIABLE temp_mux_sel : STD_LOGIC; VARIABLE temp_on_off : STD_LOGIC; VARIABLE temp_conf1 : STD_LOGIC; VARIABLE temp_conf2 : STD_LOGIC; -- SetTime Initialization Flag [Low Tru e] -- (Initialization indicator for setup time) VARIABLE set_init : STD_LOGIC; BEGIN IF ((button1 AND temp_conf1) = '1') THEN -- Reset of the mux_sel -- (Selection of the correct output display) temp_mux_sel := '0'; -- Reset the SetTime Initialization State for next entry set_load_mode <= NewEntry; ELSIF (button2'EVENT AND button2 = '1') THEN -- Initialize the temporary variable for procedure input -- (Since procedure requires parameters as variable) temp_set_min0 := set_mi n0; temp_set_min1 := set_min1; temp_set_hr0 := set_hr0; temp_set_hr1 := set_hr1; temp_ala_min0 temp_ala_min1 temp_ala_hr0 temp_ala_hr1 := := := := int_ala_min0; int_ala_min1; int_ala_hr0; int_ala_hr1;
END fsm_behavior;
CASE current_state IS WHEN SetTime => IF (set_time_mode = ModHr) THEN (set_load_mode = NewEntry) THEN temp_set_min0 := init_set_min0; temp_set_min1 := init_set_min1; temp_set_hr0 := init_set_hr0; temp_set_hr1 := init_set_hr1; -- Reset the SetTime Confirmation temp_conf1 := '0'; temp_conf2 := '0'; -- Set the SetTime Initialization Flage -- (Value not require to initialize when the next time a button is pressed again) set_load_mode <= Modified; temp_mux_sel := '1'; END IF; IncrementHr( temp_set_hr0,temp_set_hr1 ); ELSIF (set_time_mode = ModMin) THEN Incremen tMin( temp_set_min0,temp_set_min1,temp_set_hr0,temp_set_hr1 ); ELSE temp_conf1 := ( NOT temp_conf1 ); END IF; IF
12
C. time_count.vhd
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.all; USE IEEE.STD_LOGIC_ARITH.all; USE IEEE.STD_LOGIC_UNSIGNED.all; ENTITY time_count IS PORT( clock : IN STD_LOGIC; load : IN STD_LOGIC; enable : IN STD_LOGIC; -- Loading Inputs set_sec0 : IN STD_LOGIC_VECTOR(3 DOWNTO 0); set_sec1 : IN STD_LOGIC_VECTOR(3 DOWNTO 0); set_min0 : IN STD_LOGIC_VECTOR(3 DOWNTO 0); set_min1 : IN STD_LOGIC_VECTOR(3 DOWNTO 0); set_hr0 : IN STD_LOGIC_VECTOR(3 DOWNTO 0); set_hr1 : IN STD_LOGIC_VECTOR(3 DOWNTO 0); -- Display Outpus bcd_sec_out0 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0); bcd_sec_out1 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0); bcd_min_out0 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0); bcd_min_out1 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0); bcd_hr_out0 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0); bcd_hr_out1 : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0) ); END time_count; ARCHITECTURE Time_count_behavior OF time_count IS BEGIN Process_1: PROCESS( load, clock ) BEGIN -- Load External Value IF (load = '1') THEN bcd_sec_out0 <= set_sec0; bcd_sec_out1 <= set_sec1; bcd_min_out0 <= set_min0; bcd_min_out1 <= set_min1; bcd_hr_out0 <= set_hr0; bcd_hr_out1 <= set_hr1; -- Counting with the Clock ELSIF (clock'EVENT AND clock = '1') THEN IF (enable = '1') THEN IF (bcd_sec_out0 = "1001") THEN -- SECONDS digit 0 count up to 9 bcd_sec_out0 <= "0000"; IF (bcd_sec_out1 = "0101") THEN-- SECONDS digit 1 count up to 5 bcd_sec_out1 <= "0000"; IF (bcd_min_out0 = "1001") THEN -- MINUTES digit 0 count up to 9 bcd_min_out0 <= "0000"; IF (bcd_min_out1 = "0101") THEN-- MINUTES digit 1 count up to 5 bcd_min_out1 <= "0000"; -- HOURS at 24:00 reset IF ( (bcd_hr_out0 = "0011") AND (bcd_hr_out1 = "0010") ) THEN bcd_hr_out0 <= "0000"; bcd_hr_out1 <= "0000"; ELSIF (bcd_hr_out0 = "1001") THEN bcd_hr_out0 <= "0000"; bcd_hr_out1 <= bcd_hr_out1 + '1'; ELSE bcd_hr_out0 <= bcd_hr_out0 + '1'; END IF; ELSE -- MINUTES digit 1 increment bcd_min_out1 <= bcd_min_out1 + '1'; END IF; ELSE -- MINUTES digit 0 increment bcd_min_out0 <= bcd_min_out0 + '1'; END IF; ELSE -- SECONDS digit 1 increment bcd_sec_out1 <= bcd_sec_out1 + '1'; END IF; ELSE -- SECONDS digit 0 increment bcd_sec_out0 <= bcd_sec_out0 + '1'; END IF; END IF; END IF; END PROCESS Process_1; END Time_count_behavior;
D. rand_gen.vhd
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.all; USE IEEE.STD_LOGIC_ARITH.all; USE IEEE.STD_LOGIC_UNSIGNED.all; ENTITY rand_gen IS PORT( clock : IN STD_LOGIC; -- Direction of Motion forw_back : OUT STD_LOGIC; left_right : OUT STD_LOGIC; -- Number of Steps for Movement (0 -7 Possible Steps) steps_fb: OUT STD_LOGIC_VECTOR(2 DOWNTO 0); steps_lr : OUT STD_LOGIC_VECTOR(2 DOWNTO 0) ); END rand_gen; ARCHITECTURE rand_gen_behaviour OF rand_gen IS SIGNAL SIGNAL BEGIN -- Pseudo Random Binary Number Generator shifter: PROCESS( clock ) BEGIN IF(rand_num = "00000000") THEN rand_num <= "10101010"; ELSIF(clock'EVENT AND clock='1') THEN rand_num <= rand_num(6 DOWNTO 0) & (rand_num(7) XOR rand_num(5) XOR rand_num(4) XOR rand_num(3)); END IF; END PROCESS shifter; forw_back <= rand_num(0); left_right <= rand_num(1); steps_fb <= rand_num(4 DOWNTO 2); steps_lr <= rand_num(7 DOWNTO 5); END rand_gen_behaviour; rand_seed : rand_num : STD_LOGIC_VECTOR(7 DOWNTO 0); STD_LOGIC_VECTOR(7 DOWNTO 0);
13
E. buzz_mod.vhd
-- Buzzer Modulator LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.all; USE IEEE.STD_LOGIC_ARITH.all; USE IEEE.STD_LOGIC_UNSIGNED.all; ENTITY buzz_mod IS PORT( buzz_mode : IN INTEGER; buzz_on : IN STD_LOGIC; clock_10Hz: IN STD_LOGIC; clock_1Hz : IN STD_LOGIC; clock_5Hz : OUT STD_LOGIC; buzzer : OUT STD_LOGIC ); END buzz_mod; ARCHITECTURE modulation_behavior OF buzz_mod IS SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL BEGIN buzzer <= buzz_on WHEN (buzz_mode = 0) ELSE buzz1 WHEN (buzz_mode = 1) ELSE buzz2 WHEN (buzz_mode = 2) ELSE buzz3 WHEN (buzz_mode = 3) ELSE buzz4; set_clock_5Hz: PROCESS( clock_10Hz ) VARIABLE count : STD_LOGIC; BEGIN IF (clock_10Hz'EVENT AND clock_10Hz = '1') THEN IF (count /= '1') THEN count := '1'; ELSE count := '0'; END IF; int_clock_5Hz <= count; END IF; END PROCESS set_clock_5Hz; modulation1: PROCESS( int_clock_5Hz ) VARIABLE count1 : STD_LOGIC_VECTOR(4 DOWNTO 0); BEGIN IF (int_clock_5Hz'EVENT AND int_clock_5Hz = '1') THEN IF (count1 <= "00111") THEN count1 := count1 + "00001"; ELSE count1 := "00000"; END IF; IF (count1 <= "00101") THEN buzz1 <= int_clock_5Hz; ELSE buzz1 <= '0'; END IF; END IF; END PROCESS modulation1; modulation2: PROCESS( int_clock_5Hz ) VARIABLE count2 : STD_LOGIC_VECTOR(4 DOWNTO 0); BEGIN IF (int_clock_5Hz'EVENT AND int_clock_5Hz = '1') THEN IF (count2 <= "00101") THEN count2 := count2 + "00001"; ELSE count2 := "00000"; END IF; IF (count2 <= "00011") THEN buzz2 <= int_clock_5Hz; ELSE buzz2 <= '0'; END IF; END IF; END PROCESS modulation2; buzz3 <= int_clock_5Hz; buzz4 <= clock_1Hz; clock_5Hz <= int_clock_5Hz; END modulation_behavior; buzz1 buzz2 buzz3 buzz4 : : : : STD_LOGIC; STD_LOGIC; STD_LOGIC; STD_LOGIC; STD_LOGIC;
int_clock_5Hz :