910 likes | 1.18k Views
Stop Watch & Digital Watch 구현. Lecture #14. Team Project - 학습목표. 지금까지의 교육을 통해 얻은 지식을 토대로 임베디드 하드웨어를 개발하는 프로젝트를 부과하며 , 이의 관리 및 지도를 통하여 최종 결과물을 발표하도록 한다 다양한 프로젝트들의 구현을 통해 VHDL 의 응용능력을 기른다 기본적인 타이밍도의 이해 및 응용능력을 실질적인 프로젝트에 적용하는 능력을 기른다 주요 입출력 장치의 특성을 이해한다
E N D
Stop Watch & Digital Watch 구현 Lecture #14
Team Project - 학습목표 • 지금까지의 교육을 통해 얻은 지식을 토대로 임베디드 하드웨어를 개발하는 프로젝트를 부과하며, 이의 관리 및 지도를 통하여 최종 결과물을 발표하도록 한다 • 다양한 프로젝트들의 구현을 통해 VHDL의 응용능력을 기른다 • 기본적인 타이밍도의 이해 및 응용능력을 실질적인 프로젝트에 적용하는 능력을 기른다 • 주요 입출력 장치의 특성을 이해한다 • Stop Watch 및 Digital Watch의 VHDL 회로에 대한 기본적인 설계 개념을 제공한다
Stop Watch – Design Specification • Stop Watch용 VHDL의 입출력 설계 사양 • 입력 : • Clock : 10KHz • Key 2개 : RESET, START_STOP • 출력 : • 공통캐소드단자 6개 : Com0, Com1, Com2, Com3, Com4, Com5 • Segment LED 출력 7개 : A, B, C, D, E, F, G
Stop Watch – Design Specification • 입력장치( Input Device ) • 2개의 푸시 버튼 스위치를 사용 • RESET, START_STOP • 각각의 스위치는 눌러질 경우에 1을 출력하고, 평상시에는 0을 출력하는 구조 RESET START_STOP
Stop Watch – Design Specification • 출력장치(Output Device) • 6개의 7 Segment LED을 사용함. • 분:2개, 초:2개, 1/100초:2개 분 초 1/100초
Stop Watch – Design Specification • Stop Watch 동작 설계 (1) 초기 POWER ON시 RESET상태 - 초기에 표시되는 값은 00 : 00 : 00임 - START_STOP KEY 가 눌러지면 시간 증가 모드로 이동함
Stop Watch – Design Specification (2) 시간 증가 모드 - 00 : 00 : 00 .. 00 : 00 : 99 00 : 01 : 00 .. 00 : 59 : 99 01 : 00 : 00 .. 59 : 59 : 99 00 : 00 : 00 의 순서로 순환됨 - 시간이 증가되는 상태에서 START_STOP KEY 가 눌러지면 시간을 정지함 - 다시 START_STOP KEY가 눌러지면 정지된 시간에서부터 시작하여 시간을 1/100초 단위의 정밀도로 증가하는 것을 반복함 - RESET KEY가 눌러지면 초기 파워 온 상태와 같은 초기 값인 00:00:00 으로 되며, 시간증가를 정지함
이 부분을 VHDL로 설계함. 6개의 7 Segments만 사용함 분 : 초 : 1/10초 A,B,C,D,E,F,G는 공통으로 사용. Stop Watch –전체 회로
10KHz 처음 부터 다시 시작 버튼 RUN/STOP조정버튼 Stop Watch – VHDL Top Diagram 6개의 FND가운데 하나를 선택함. 6개의 선택신호 중에서 1개만 0이 되고 나머지는 모두 1이 됨. ENP가 1이면 스톱워치가 증가, 0이면 정지 위에서부터 순서대로 2개씩 묶어 분, 초, 1/100초를 나타냄. 100Hz RESET신호는 Key가 눌러졌을 때 1인 신호이며, Nclr은 Active Low신호임. A,B,C,D,E,F,G는 Segment LED의 입력신호 1이면 해당 LED가 발광함.
10KHz Stop Watch의 Run/Stop 동작을 조정하는 스위치 6개의 FND가운데 하나를 선택함. 6개의 선택신호 중에서 1개만 0이 되고 나머지는 모두 1이 됨. 0이 되는 위치의 FND가 발광하게 됨. A,B,C,D,E,F,G의 값은 6개의 FND가 공통으로 연결하여 사용하므로 MUX를 이용하여 시간 정보를 하나씩 번갈아가며 선택해야 함. Stop Watch – Top Level Entity library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity stopwatch is port( clk : in std_logic; reset : in std_logic; start_stop : in std_logic; com0 : out std_logic; com1 : out std_logic; com2 : out std_logic; com3 : out std_logic; com4 : out std_logic; com5 : out std_logic; A : out std_logic; B : out std_logic; C : out std_logic; D : out std_logic; E : out std_logic; F : out std_logic; G : out std_logic ); end stopwatch;
Stop Watch – Top Level Entity architecture a of stopwatch is component Hz100ctrl port( clk,nclr : in std_logic; Hz100 : out std_logic); end component; component keyif port( start_stop : in std_logic; clk, nclr : in std_logic; enp : out std_logic); end component; component timecontrol port( clk, nclr : in std_logic; enp : in std_logic; SSL : out std_logic_vector(3 downto 0); SSH : out std_logic_vector(3 downto 0); SECL : out std_logic_vector(3 downto 0); SECH : out std_logic_vector(3 downto 0); MINL : out std_logic_vector(3 downto 0); MINH : out std_logic_vector(3 downto 0)); end component; component outputif port( clk, nclr : in std_logic; SSL : in std_logic_vector(3 downto 0); SSH : in std_logic_vector(3 downto 0); SEC : in std_logic_vector(3 downto 0); SECH : in std_logic_vector(3 downto 0); MINL : in std_logic_vector(3 downto 0); MINH : in std_logic_vector(3 downto 0); com_out : out std_logic_vector(5 downto 0); seg_out : out std_logic_vector(6 downto 0)); end component;
RESET는 키가 눌러졌을 때 1이 된다. 그러므로 Active Low로 만들기 위해 Not 처리함. 이후 모든 블록은 Nclr을 리셋신호로 사용함. Stop Watch – Top Level Entity signal nclr : std_logic; signal Hz100 : std_logic; signal enp : std_logic; signal SSL : std_logic_vector(3 downto 0); signal SSH : std_logic_vector(3 downto 0); signal SECL : std_logic_vector(3 downto 0); signal SECH : std_logic_vector(3 downto 0); signal MINL : std_logic_vector(3 downto 0); signal MINH : std_logic_vector(3 downto 0); signal com_out : std_logic_vector(5 downto 0); signal seg_out : std_logic_vector(6 downto 0); begin nclr <= not reset; U1: Hz100ctrl port map( clk,nclr,Hz100); U2: keyif port map( start_stop,clk,nclr,enp); U3: timecontrol port map( Hz100,nclr,enp,SSL,SSH,SECL,SECH,MINL,MINH); U4: outputif port map( clk,nclr,SSL,SSH,SECL,SECH,MINL,MINH,com_out,seg_out); com0<=com_out(5);com1<=com_out(4);com2<=com_out(3); com3<=com_out(2);com4<=com_out(1);com5<=com_out(0); A<=seg_out(6);B<=seg_out(5);C<=seg_out(4); D<=seg_out(3);E<=seg_out(2);F<=seg_out(1);G<=seg_out(0); end a;
Stop Watch – 100Hz Gen. • 10KHz Clock(=clk)으로부터 1/100초인 100Hz(=Hz100)을 만드는 회로 10KHz 100Hz는 1/100초이므로 Stop Watch의 1/100초를 카운트하는데 사용되는 클럭으로 사용된다. TimeControl 블록과 KeyIF의 클럭으로 사용됨 10KHz:100Hz=100:1 그러므로 10KHz가 100주기 발생할 때 100Hz는 1주기 발생하면 된다.
Stop Watch – 100Hz Gen. library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity Hz100ctrl is port( clk,nclr : in std_logic; Hz100 : out std_logic); end Hz100ctrl; architecture a of Hz100ctrl is signal cnt : std_logic_vector(5 downto 0); signal sHz100 : std_logic; begin process(nclr,clk) begin if( nclr='0') then cnt <="000000"; elsif(clk'event and clk='1') then if(cnt=49) then cnt <= "000000"; else cnt <= cnt+'1'; end if; end if; end process; process(nclr,clk) begin if( nclr='0') then sHz100 <='0'; elsif(clk'event and clk='1') then if(cnt=49) then sHz100 <= not sHz100; end if; end if; end process; Hz100 <= sHz100; end a; Clk=10KHz Hz100=100Hz Modulo 50 Counter Cnt=49일 때마다 Hz100를 Toggle함
Stop Watch – Key Interface • Start_Stop 키 입력을 받아 Stop Watch의 시작과 정지를 위해 카운터의 증가/정지를 명령하는 ENP를 생성 • ENP는 1/100초의 Hz100과의 동기가 필요하므로 Shift Register를 하나 더 사용함 Start Stop Start_Stop이 홀수번째 1이 입력되면 가 스톱워치가 증가모드, 짝수번째는 정지모드 Clk에 비동기 입력 Clk에 동기 됨 ENP가 1이면 스톱워치가 증가, 0이면 정지 100Hz
Stop Watch – Key Interface library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity keyif is port( start_stop : in std_logic; clk,nclr : in std_logic; enp : out std_logic ); end keyif; architecture a of keyif is signal q : std_logic_vector( 1 downto 0); signal RisingShotPules : std_logic; signal s_enp : std_logic; Begin process(nclr,clk) -- shift register 2bits : begin if( nclr='0') then q <="00"; elsif(clk'event and clk='1') then q(1) <= q(0); q(0) <= start_stop; end if; end process; RisingShotPules <= q(0) and (not q(1)); ENP가 1이면 스톱워치가 증가, 0이면 정지 Rising Shot Pulse 발생회로 Q(0)는 CLK에 동기를 맞추기 위한 플립플롭임.
Stop Watch – Key Interface -- enp generation process(nclr,clk) begin if( nclr='0') then s_enp <='0'; elsif(clk'event and clk='1') then if(RisingShotPules='1') then s_enp <= not s_enp; end if; end if; end process; enp <= s_enp; end a; ENP 발생회로 RisingShotPulses가 1인 경우 ENP를 Toggle시킨다.
Stop Watch – Time Control • 입력된 ENP값이 0일 때는 카운터의 값을 정지하고, 1 일 때는 00:00:00 .. 00:00:99 00:01:00 .. 00:59:99 • 01:00:00 .. 59:59:99 00:00:00 의 순서로 증가시킴 ENP가 1이면 카운터 증가, 0이면 정지 0.99초 100Hz 59초 00분 00초 00 59분
Stop Watch – Time Control 모든 Counter는 ENP=1일 때만 정상동작 함. library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity timecontrol is port( clk,nclr : in std_logic; enp : in std_logic; SSL : out std_logic_vector(3 downto 0); SSH : out std_logic_vector(3 downto 0); SECL : out std_logic_vector(3 downto 0); SECH : out std_logic_vector(3 downto 0); MINL : out std_logic_vector(3 downto 0); MINH : out std_logic_vector(3 downto 0) ); end timecontrol; architecture a of timecontrol is signal s_SSL : std_logic_vector(3 downto 0); signal s_SSH : std_logic_vector(3 downto 0); signal s_SECL : std_logic_vector(3 downto 0); signal s_SECH : std_logic_vector(2 downto 0); signal s_MINL : std_logic_vector(3 downto 0); signal s_MINH : std_logic_vector(2 downto 0); begin 1/00초 초 분
Stop Watch – Time Control s_SSL_cnt: process(nclr,clk) begin if( nclr='0') then s_SSL <="0000"; elsif(clk'event and clk='1') then if(enp='1' and s_SSL=9) then s_SSL <= "0000"; elsif(enp='1') then s_SSL <= s_SSL+'1'; end if; end if; end process; s_SSH_cnt: process(nclr,clk) begin if( nclr='0') then s_SSH <="0000"; elsif(clk'event and clk='1') then if(enp='1' and s_SSH=9 and s_SSL=9) then s_SSH <= "0000"; elsif(enp='1' and s_SSL=9) then s_SSH <= s_SSH+'1'; end if; end if; end process; 1/100 초의 1의 자리 Control : Modulo 0 Counter 1/100 초의 10의 자리 Control
Stop Watch – Time Control s_SECL_cnt: process(nclr,clk) begin if( nclr='0') then s_SECL <="0000"; elsif(clk'event and clk='1') then if(enp='1' and s_SECL=9 and s_SSH=9 and s_SSL=9) then s_SECL <= "0000"; elsif(enp='1' and s_SSH=9 and s_SSL=9) then s_SECL <= s_SECL+'1'; end if; end if; end process; s_SECH_cnt: process(nclr,clk) begin if( nclr='0') then s_SECH <="000"; elsif(clk'event and clk='1') then if(enp='1' and s_SECH=5 and s_SECL=9 and s_SSH=9 and s_SSL=9) then s_SECH <= "000"; elsif(enp='1' and s_SECL=9 and s_SSH=9 and s_SSL=9) then s_SECH <= s_SECH+'1'; end if; end if; end process; 초의 1의 자리 Control 초의 10의 자리 Control
Stop Watch – Time Control s_MINL_cnt: process(nclr,clk) begin if( nclr='0') then s_MINL <="0000"; elsif(clk'event and clk='1') then if(enp='1' and s_MINL=9 and s_SECH=5 and s_SECL=9 and s_SSH=9 and s_SSL=9) then s_MINL <= "0000"; elsif(enp='1' and s_SECH=5 and s_SECL=9 and s_SSH=9 and s_SSL=9) then s_MINL <= s_MINL+'1'; end if; end if; end process; s_MINH_cnt: process(nclr,clk) begin if( nclr='0') then s_SSH <="000"; elsif(clk'event and clk='1') then if(enp='1' and s_MINH=5 and s_MINL=9 and s_SECH=5 and s_SECL=9 and s_SSH=9 and s_SSL=9) then s_MINH <= "000"; elsif(enp='1' and s_MINL=9 and s_SECH=5 and s_SECL=9 and s_SSH=9 and s_SSL=9) then s_MINH <= s_MINH+'1'; end if; end if; end process; SSL <= s_SSL; SSH <= s_SSH; SECL <= s_SECL; SECH <= '0' & s_SECH; MINL <= s_MINL; MINH <= '0' & s_MINH; end a; 분의 1의 자리 Control 분의 10의 자리 Control
Stop Watch – Output Interface • 분, 초, 1/100초를 나타내는 카운터의 출력을 6개의 7 Segment LED에 출력하는 회로 • a,b,c,d,e,f,g를 6개의 7 Segment LED 가 공통으로 이용하므로 6입력 멀티플렉서를 이용하여 순차적으로 하나씩 선택하여 출력해야 함 • 6개의 7 Segment LED 의 인터페이스를 위해 BCD-7 Segment Decoder를 멀티플렉서 출력에 연결해야 함 12분 분 High의 FND선택 분 Low의 FND선택 6개의 출력신호 중에서 1개만 0이고 나머지는 1 34초 0.90초 BCD-7 Segment Decoder 출력 1 2 3 4 9 0 1
Stop Watch – Output Interface library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity outputif is port( clk,nclr : in std_logic; SSL : in std_logic_vector(3 downto 0); SSH : in std_logic_vector(3 downto 0); SECL : in std_logic_vector(3 downto 0); SECH : in std_logic_vector(3 downto 0); MINL : in std_logic_vector(3 downto 0); MINH : in std_logic_vector(3 downto 0); com_out : out std_logic_vector(5 downto 0); seg_out : out std_logic_vector(6 downto 0) ); end outputif; architecture a of outputif is signal muxout : std_logic_vector(3 downto 0); signal cnt : std_logic_vector(2 downto 0); begin -- modulo 6 counter process(nclr,clk) begin if( nclr='0') then cnt <="111"; elsif(clk'event and clk='1') then if(cnt=5) then cnt <="000"; else cnt <= cnt+'1'; end if; end if; end process; 6개의 FND를 공통으로 연결된 A,B,C,D,E,F,G를 이용하여 번갈아가며 Display하기위해서는 Modulo 6 Counter가 필요함.
Stop Watch – Output Interface -- com signal gen : 3X8 decoder process(cnt) begin case cnt is when "000" => com_out <= "011111"; when "001" => com_out <= "101111"; when "010" => com_out <= "110111"; when "011" => com_out <= "111011"; when "100" => com_out <= "111101"; when "101" => com_out <= "111110"; when others=> com_out <= "111111"; end case; end process; -- 6_1 mux (4bits) process(cnt) begin case cnt is when "000" => muxout <= MINH; when "001" => muxout <= MINL; when "010" => muxout <= SECH; when "011" => muxout <= SECL; when "100" => muxout <= SSH; when others=> muxout <= SSL; end case; end process; 6개의 FND가운데 하나를 선택함. 6개의 선택신호 중에서 1개만 0이 되고 나머지는 모두 1이 됨. 0이 되는 위치의 FND가 발광하게 됨. A,B,C,D,E,F,G의 값은 6개의 FND가 공통으로 연결하여 사용하므로 MUX를 이용하여 시간 정보를 하나씩 번갈아가며 선택해야 함.
Stop Watch – Output Interface -- BCD to 7 Segment gen process(muxout) begin case muxout is when "0000" => seg_out <= "1111110"; when "0001" => seg_out <= "0110000"; when "0010" => seg_out <= "1101101"; when "0011" => seg_out <= "1111001"; when "0100" => seg_out <= "0110011"; when "0101" => seg_out <= "1011011"; when "0110" => seg_out <= "1011111"; when "0111" => seg_out <= "1110000"; when "1000" => seg_out <= "1111111"; when "1001" => seg_out <= "1110011"; when others => seg_out <= "0000000"; end case; end process; end a; 멀티플렉서를 통과시킨 MUXOUT은 4비트의 BCD코드이므로 이를 7 Segment 값인 A,B,C,D,E,F,G로 변경시켜야만 함.
Digital Watch – Design Specification • VHDL의 입출력 설계 사양 • 입력 : • Clock : 10KHz • Key 3개 : RESET SW, SET SW, INC SW • 출력 : • LCD Interface : E, RS, RW, D0, D1, D2, D3, D4, D5, D6, D7
RESET SET INC Digital Watch – Design Specification • 입력장치( Input Device ) • 3개의 푸시 버튼 스위치를 사용 • RESET SW, SET SW, INC SW • 각각의 스위치는 눌러질 경우에 1을 출력하고, 평상시에는 0을 출력하는 구조
Digital Watch – Design Specification • 출력장치(Output Device) • Character LCD 20문자 2줄 D.D.RAM의 주소
Digital Watch – Design Specification • Digital Watch 동작 설계 (1) 초기 POWER ON시 RESET상태 ( = Initial_State ) - 초기에 표시되는 값은 AM 12 : 00 임 - AM 12 00 전체가 0.5초 간격으로 깜박거림 - SET KEY 가 눌러지면 시간 수정모드의 처음인 TIME AM/PM SETTING MODE 로 이동
Digital Watch – Design Specification (2) 시간 수정모드 ① TIME AM/PM SETTING MODE ( = Time_AmPm_Set_State ) - 초기상태는 AM/PM위치의 LED가 0.5초 간격으로 깜박이며 다른 부분은 DISPLAY ON됨 - INC KEY에 의해 AM/PM이 반전되어 나타남 - SET KEY를 누르면 TIME HOUR SETTING MODE로 이동 ② TIME HOUR SETTING MODE ( = Time_Hour_Set_State ) - 현재의 HOUR을 나타내는 LED가 0.5초 간격으로 깜박임 - INC KEY에 의해 1씩 증가함 12 1 2 3 4 5 6 7 8 9 10 11 12 .. - SET KEY를 누르면 TIME MIN HIGH SETTING MODE로 이동 Set Key나 Inc Key 2가지 입력 중 어느 하나의 Key라도 눌러지면 그 시점에 동기를 맞춰 켜짐부터 깜박임을 다시 시작해야 한다.=> 이런 디스플레이 방식이 시간 수정 시에 자연스럽다.
Digital Watch – Design Specification (2) 시간 수정모드 ③ TIME MIN HIGH SETTING MODE ( = Time_Min_High_Set_State ) - 현재의 분의 HIGH를 나타내는 LED가 0.5초 간격으로 깜박임 - INC KEY에 의해 1씩 증가함 0 1 2 3 4 5 0 .. - SET KEY를 누르면 TIME MIN LOW SETTING MODE로 이동 ④ TIME MIN LOW SETTING MODE ( = Time_Min_Low_Set_State ) - 현재의 분의 LOW를 나타내는 LED가 0.5초 간격으로 깜박임 - INC KEY에 의해 1씩 증가함 0 1 2 3 4 5 0 .. - SET KEY를 누르면 NORMAL TIME MODE로 이동
Digital Watch – Design Specification (3) NORMAL TIME MODE ( = Normal_Time_State ) - 현재 진행되는 시간을 나타냄 - SET KEY 가 눌러지면 시간 수정모드의 처음인 TIME AM/PM SETTING MODE 로 이동
Digital Watch –전체 회로 LCD의 밝기 조절 회로. 이 부분을 VHDL로 설계함. CharacterLCD사용.
Digital Watch – Top Level 구성 BCD -> ASCII 변환부 LCD Interface 부 이 블록을 제외하고 나머지는 Digital Watch – FND Interface와 같음.
Digital Watch – Top Level Entity (1) -- purpose : clock top block -- ver 2 : LCD interface LIBRARY IEEE; USE IEEE.std_logic_1164.all; entity clocklcd is port( clk : in std_logic; reset_sw : in std_logic; set_sw : in std_logic; inc_sw : in std_logic; --; e : out std_logic; rw : out std_logic; rs : out std_logic; data : out std_logic_vector(7 downto 0) ); end clocklcd; Architecture a of clocklcd is signal set_button, inc_button : std_logic; signal set_shot, inc_shot : std_logic; signal reset, Hz100 : std_logic; signal state : std_logic_vector(3 downto 0); signal time_set_mode : std_logic; -- time counters for 7 segment signal time_ampm : std_logic; signal time_hour_high : std_logic; signal time_hour_low : std_logic_vector(3 downto 0); signal time_min_high : std_logic_vector(2 downto 0); signal time_min_low : std_logic_vector(3 downto 0); signal time_sec_high : std_logic_vector(2 downto 0); signal time_sec_low : std_logic_vector(3 downto 0); signal led_blink : std_logic; signal buzzer_blink : std_logic; -- for 0.5 sec buzer blink
Digital Watch – Top Level Entity (2) signal initial_state : std_logic; signal time_ampm_set_state : std_logic; signal time_hour_set_state : std_logic; signal time_min_high_set_state : std_logic; signal time_min_low_set_state : std_logic; signal normal_time_state : std_logic; signal s_select_hour_high : std_logic; -- for hour_high=0 : display Off; signal LCD_time_ampm_ap : std_logic_vector(7 downto 0); signal LCD_time_ampm_m : std_logic_vector(7 downto 0); signal LCD_time_hour_high : std_logic_vector(7 downto 0); signal LCD_time_hour_low : std_logic_vector(7 downto 0); signal LCD_time_min_high : std_logic_vector(7 downto 0); signal LCD_time_min_low : std_logic_vector(7 downto 0); signal LCD_time_sec_high : std_logic_vector(7 downto 0); signal LCD_time_sec_low : std_logic_vector(7 downto 0); signal LCD_time_sec_colon : std_logic_vector(7 downto 0); component statemachine port ( clk : in std_logic; reset : in std_logic; set_shot : in std_logic; initial_state : out std_logic; time_ampm_set_state : out std_logic; time_hour_set_state : out std_logic; time_min_high_set_state : out std_logic; time_min_low_set_state : out std_logic; normal_time_state : out std_logic; time_set_mode : out std_logic ); end component;
Digital Watch – Top Level Entity (3) component timecount port( clk : in std_logic; reset : in std_logic; inc_shot : in std_logic; set_shot : in std_logic; initial_state : in std_logic; time_ampm_set_state : in std_logic; time_hour_set_state : in std_logic; time_min_high_set_state : in std_logic; time_min_low_set_state : in std_logic; normal_time_state : in std_logic; -- time counters for 7 segment time_ampm : buffer std_logic; time_hour_high : buffer std_logic; time_hour_low : buffer std_logic_vector(3 downto 0); time_min_high : buffer std_logic_vector(2 downto 0); time_min_low : buffer std_logic_vector(3 downto 0); time_sec_high : buffer std_logic_vector(2 downto 0); time_sec_low : buffer std_logic_vector(3 downto 0); buzzer_blink : buffer std_logic -- for 0.5 sec buzer blink ); end component; component ledblink port( clk : in std_logic; reset : in std_logic; set_shot : in std_logic; inc_shot : in std_logic; initial_state : in std_logic; time_set_mode : in std_logic; led_blink : buffer std_logic ); end component;
Digital Watch – Top Level Entity (4) component LCD_IF port( clk : in std_logic; -- 10KHz : 0.1msec = 100usec resetb : in std_logic; -- LCD input : time information LCD_time_ampm_ap : in std_logic_vector(7 downto 0); LCD_time_ampm_m : in std_logic_vector(7 downto 0); LCD_time_hour_high : in std_logic_vector(7 downto 0); LCD_time_hour_low : in std_logic_vector(7 downto 0); LCD_time_min_high : in std_logic_vector(7 downto 0); LCD_time_min_low : in std_logic_vector(7 downto 0); LCD_time_sec_high : in std_logic_vector(7 downto 0); LCD_time_sec_low : in std_logic_vector(7 downto 0); LCD_time_sec_colon : in std_logic_vector(7 downto 0); e : out std_logic; rw : out std_logic; rs : out std_logic; data : out std_logic_vector(7 downto 0) ); end component; component Hz100ctrl port( clk,nclr : in std_logic; Hz100 : out std_logic ); end component; component shotpulse port( clk : in std_logic; reset : in std_logic; d : in std_logic; rising_shot : out std_logic ); end component;
Digital Watch – Top Level Entity (5) component ToLCDBlink port( initial_state : in std_logic; time_ampm_set_state : in std_logic; time_hour_set_state : in std_logic; time_min_high_set_state : in std_logic; time_min_low_set_state : in std_logic; normal_time_state : in std_logic; led_blink : in std_logic; -- time clock time_ampm : in std_logic; time_hour_high : in std_logic; time_hour_low : in std_logic_vector(3 downto 0); time_min_high : in std_logic_vector(2 downto 0); time_min_low : in std_logic_vector(3 downto 0); time_sec_high : in std_logic_vector(2 downto 0); time_sec_low : in std_logic_vector(3 downto 0); -- LCD input : time information LCD_time_ampm_ap : out std_logic_vector(7 downto 0); LCD_time_ampm_m : out std_logic_vector(7 downto 0); LCD_time_hour_high : out std_logic_vector(7 downto 0); LCD_time_hour_low : out std_logic_vector(7 downto 0); LCD_time_min_high : out std_logic_vector(7 downto 0); LCD_time_min_low : out std_logic_vector(7 downto 0); LCD_time_sec_high : out std_logic_vector(7 downto 0); LCD_time_sec_low : out std_logic_vector(7 downto 0); LCD_time_sec_colon : out std_logic_vector(7 downto 0)); end component;
Digital Watch – Top Level Entity (6) begin U1: statemachine port map( Hz100, reset, set_shot, initial_state, time_ampm_set_state, time_hour_set_state, time_min_high_set_state, time_min_low_set_state, normal_time_state, time_set_mode); U2: timecount port map( Hz100, reset, inc_shot, set_shot, initial_state, time_ampm_set_state, time_hour_set_state, time_min_high_set_state, time_min_low_set_state, normal_time_state, time_ampm, time_hour_high, time_hour_low, time_min_high, time_min_low, time_sec_high, time_sec_low, buzzer_blink ); U3: ledblink port map( Hz100, reset, set_shot, inc_shot, initial_state, time_set_mode, led_blink); U4 :Hz100ctrl port map( clk,reset,Hz100); U5: shotpulse port map( Hz100, reset, set_button, set_shot ); U6: shotpulse port map( Hz100, reset, inc_button, inc_shot ); reset <= not(reset_sw); set_button <= (set_sw) and not(inc_sw); inc_button <= not(set_sw) and inc_sw; U7: ToLCDBlink port map( initial_state, time_ampm_set_state, time_hour_set_state, time_min_high_set_state, time_min_low_set_state, normal_time_state, led_blink, time_ampm, time_hour_high, time_hour_low, time_min_high, time_min_low, time_sec_high, time_sec_low, LCD_time_ampm_ap, LCD_time_ampm_m, LCD_time_hour_high, LCD_time_hour_low, LCD_time_min_high, LCD_time_min_low, LCD_time_sec_high, LCD_time_sec_low, LCD_time_sec_colon); U8: LCD_IF port map(clk, reset, LCD_time_ampm_ap, LCD_time_ampm_m, LCD_time_hour_high, LCD_time_hour_low, LCD_time_min_high, LCD_time_min_low, LCD_time_sec_high, LCD_time_sec_low, LCD_time_sec_colon, e, rw, rs, data ); end a;
Digital Watch - Shot Pulse Gen. • 외부에서 입력되는 키의 신호는 모두 클럭 100Hz에 비동기인 신호 • 실제 회로 내부에서 필요한 신호는 동기신호 이므로 동기처리 후 Shot Pulse를 만들어야 한다 100Hz Clk에 비동기 입력 Clk에 동기 됨 입력신호가 1로 들어오면 100Hz의 1주기동안 1인 신호
Digital Watch - Shot Pulse Gen. -- purpose : rising shot pulse generator LIBRARY IEEE; USE IEEE.std_logic_1164.all; entity shotpulse is port( clk : in std_logic; reset : in std_logic; d : in std_logic; rising_shot : out std_logic ); end shotpulse; architecture a of shotpulse is signal qa,qb : std_logic; begin process(clk,reset) begin if(reset='0') then qa<='0';qb<='0'; elsif(clk'event and clk='1') then qa<= d; qb<=qa; end if; end process; rising_shot <= qa and not(qb); end a;
Digital Watch - 100Hz Gen. • 10KHz Clock(=clk)으로부터 1/100초인 100Hz(=Hz100)을 만드는 회로 10KHz 100Hz는 1/100초이므로 Stop Watch의 1/100초를 카운트하는데 사용되는 클럭으로 사용된다. TimeControl 블록과 KeyIF의 클럭으로 사용됨 10KHz:100Hz=100:1 그러므로 10KHz가 100주기 발생할 때 100Hz는 1주기 발생하면 된다.
Digital Watch - 100Hz Gen. Clk=10KHz library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity Hz100ctrl is port( clk, nclr : in std_logic; Hz100 : out std_logic); end Hz100ctrl; architecture a of Hz100ctrl is signal cnt : std_logic_vector(5 downto 0); signal sHz100 : std_logic; Begin process(nclr,clk) begin if( nclr='0') then cnt <="000000"; elsif(clk'event and clk='1') then if(cnt=49) then cnt <= "000000"; else cnt <= cnt+'1'; end if; end if; end process; process(nclr,clk) begin if( nclr='0') then sHz100 <='0'; elsif(clk'event and clk='1') then if(cnt=49) then sHz100 <= not sHz100; end if; end if; end process; Hz100 <= sHz100; end a; Hz100=100Hz Modulo 50 Counter Cnt=49일 때마다 Hz100를 Toggle함
Digital Watch - Mode Control(Flow) Input : Set_Shot Set_Shot은 입력 스위치인 Set Key를 누르면 클럭의 1주기 동안만 1이 되는 Shot Pulse 임. 0 S0 1 상태는 전부 6개로 나누어짐. S0 : Initial State S1 : AM/PM Setting State S2 : Hour Setting State S3 : Minute High Setting State S4 : Minute Low Setting State S5 : Normal Time State 0 S1 1 S1, S2, S3, S4는 시간 수정 Mode임. 0 S2 1 0 S3 1 상태도 설명 : 초기에 전원이 인가되면 S0에서 부터 시작한다. Set_Shot 신호가 1이 입력될 때마다 다음 상태로 천이 되며, 0 입력이면 상태를 그대로 유지한다. 시간 수정모드의 마지막 상태인 S4에서 Set_Shot이 1로 들어오면, 상태는 정상적인 시간이 진행되는 S5로 천이 된다. S5상태에서 Set_Shot이 1로 입력되면 상태는 시간 수정모드의 시작인 S1으로 다시 천이 되고 AM/PM 값의 수정을 시작한다. 0 S4 1 1 0 S5