Stop Watch 구현 Lecture #12
Team Project - 학습목표 지금까지의 교육을 통해 얻은 지식을 토대로 임베디드 하드웨어를 개발하는 프로젝트를 부과하며, 이의 관리 및 지도를 통하여 최종 결과물을 발표하도록 한다 다양한 프로젝트들의 구현을 통해 VHDL의 응용능력을 기른다 기본적인 타이밍도의 이해 및 응용능력을 실질적인 프로젝트에 적용하는 능력을 기른다 주요 입출력 장치의 특성을 이해한다 Stop Watch의 VHDL 회로에 대한 기본적인 설계 개념을 제공한다 모바일컴퓨터특강
Stop Watch 설계 모바일컴퓨터특강
Stop Watch – Design Specification Stop Watch용 VHDL의 입출력 설계 사양 입력 : Clock : 12MHz 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 (1) 초기 POWER ON시 RESET상태 - 초기에 표시되는 값은 00 : 00 : 00임 - START_STOP KEY 가 눌러지면 시간 증가 모드로 이동함 00분 00초 0.00초 모바일컴퓨터특강
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 으로 되며, 시간증가를 정지함 최대값 = 59분 59초 0.99초 5 9 모바일컴퓨터특강
Stop Watch – 전체 회로 이 부분을 VHDL로 설계함. 6개의 7 Segments만 사용함 분 : 초 : 1/10초 A,B,C,D,E,F,G는 공통으로 사용. 모바일컴퓨터특강
Stop Watch – VHDL Top Diagram 모바일컴퓨터특강
Stop Watch – VHDL Top Diagram 6개의 FND가운데 하나를 선택함. 6개의 선택신호 중에서 1개만 0이 되고 나머지는 모두 1이 됨. ENP가 1이면 스톱워치가 증가, 0이면 정지 위에서부터 순서대로 2개씩 묶어 분, 초, 1/100초를 나타냄. 100Hz 12MHz RUN/STOP조정버튼 RESET신호는 Key가 눌러졌을 때 1인 신호이며, Nclr은 Active Low신호임. A,B,C,D,E,F,G는 Segment LED의 입력신호 1이면 해당 LED가 발광함. 처음 부터 다시 시작 버튼 모바일컴퓨터특강
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; 12MHz 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 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); 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)); component outputif 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)); 모바일컴퓨터특강
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; RESET는 키가 눌러졌을 때 1이 된다. 그러므로 Active Low로 만들기 위해 Not 처리함. 이후 모든 블록은 Nclr을 리셋신호로 사용함. 모바일컴퓨터특강
그러므로 12MHz가 120000 주기 발생할 때 100Hz는 1주기 발생하면 된다. Stop Watch – 100Hz Gen. 12MHz Clock(=clk)으로부터 1/100초인 100Hz(=Hz100)을 만드는 회로 12MHz 100Hz는 1/100초이므로 Stop Watch의 1/100초를 카운트하는데 사용되는 클럭으로 사용된다. TimeControl 블록과 KeyIF의 클럭으로 사용됨 12MHz:100Hz =120000:1 그러므로 12MHz가 120000 주기 발생할 때 100Hz는 1주기 발생하면 된다. 모바일컴퓨터특강
Stop Watch – 100Hz Gen. Clk=12MHz Hz100=100Hz 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) variable cnt : integer range 0 to 65535; variable sHz100 : std_logic; if( nclr='0') then cnt := 0; sHz100 :='0'; elsif (clk'event and clk='1') then if (cnt=62915) then sHz100 := not sHz100; else cnt := cnt + 1; end if; Hz100 <= sHz100; end process; end a; Clk=12MHz Hz100=100Hz Cnt=62915일 때마다 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 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 process; s_SSH_cnt: process(nclr,clk) s_SSH <="0000"; 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'; 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 process; s_SECH_cnt: process(nclr,clk) s_SECH <="000"; 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'; 초의 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 process; s_MINH_cnt: process(nclr,clk) if( nclr='0') then s_SSH <="000"; 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'; 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); signal dp : std_logic; signal fnd_clk : std_logic; begin 모바일컴퓨터특강
Stop Watch – Output Interface -- clock divisor process(clk) variable cnt : integer range 0 to 65535; variable clk_out : std_logic; begin if (clk'event and clk = '1') then if cnt < 3300 then cnt := cnt + 1; elsif cnt = 3300 then cnt := 0; clk_out := not clk_out; end if; fnd_clk <= clk_out; end process; -- modulo 6 counter process(nclr, fnd_clk) if( nclr='0') then cnt <="111"; elsif(clk'event and clk='1') then if(cnt=5) then cnt <="000"; else cnt <= cnt+'1'; 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) when "000" => muxout <= SSL; dp <= ‘1’; when "001" => muxout <= SSH; dp <= ‘0’; when "010" => muxout <= SECL; dp <= ‘1’; when "011" => muxout <= SECH; dp <= ‘0’; when "100" => muxout <= MINL; dp <= ‘1’; when others=> muxout <= MINH; dp <= ‘0’; 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) variable seg_decode : std_logic_vector(6 downto 0); begin case muxout is when "0000" => seg_decode <= "1111110"; when "0001" => seg_decode <= "0110000"; when "0010" => seg_decode <= "1101101"; when "0011" => seg_decode <= "1111001"; when "0100" => seg_decode <= "0110011"; when "0101" => seg_decode <= "1011011"; when "0110" => seg_decode <= "1011111"; when "0111" => seg_decode <= "1110000"; when "1000" => seg_decode <= "1111111"; when "1001" => seg_decode <= "1110011"; when others => seg_decode <= "0000000"; end case; if dp = '1' then seg_out <= '1' & seg_decode; else seg_out <= '0' & seg_decode; end if; end process; end a; 멀티플렉서를 통과시킨 MUXOUT은 4비트의 BCD코드이므로 이를 7 Segment 값인 A,B,C,D,E,F,G로 변경시켜야만 함. 모바일컴퓨터특강
FPGA – Device Setting 사용하는 FPGA의 종류를 설정한다 Assignment-device Family: Cyclon Device: EP1C12Q240C8 Device & Pin Options – configuration Configuration Scheme: Passive Serial Use Configuration Device : EPC2 모바일컴퓨터특강
FPGA – Assign Pins FPGA의 물리적인 핀과 VHDL로 작성한 코드의 PIN과 연결한다. Assignment - Pins To: VHDL에서 사용되는 입출력 핀 이름 Location: FPGA의 물리적인 핀 Assignment - Pin Planner에서 같은 작업 가능 참고자료의 FPGA-IOM.pdf 참조 FPGA 보드의 회로도를 참조하여 FND, Clock등의 입출력 핀과 어느 FPGA의 물리적인 핀이 연결되어 있는지 확인 모바일컴퓨터특강
FPGA B’d 회로도 발췌 모바일컴퓨터특강
FPGA B’d 회로도 발췌 모바일컴퓨터특강
Pin Assignment 모바일컴퓨터특강
FPGA – Programmer (1) Pin 설정 후 컴파일이 성공하면 FPGA에 프로그램해서 테스트한다. Tools-Programmer Hardware Setup Add Hardware: ButeBlasterMV or ByteBlaster II , LPT1 모바일컴퓨터특강
FPGA – Programmer (2) Tools-Programmer 하드웨어와 호스트를 ByteBlaster로 연결한다. 하드웨어의 전원이 켜져있는 상태에서 Auto Detect EPC2와 EP1C6 두 디바이스가 검색되어진다. EP1C12을 더블클릭하여 컴파일하여 생성된 sof 파일을 불러온다 EP1C12의 Program/Configure을 클릭하고 Start를 누르면 FPGA의 메모리로 프로그램된다. 모바일컴퓨터특강
FPGA – Programmer (3) 앞의 실습은 FPGA의 메모리에 프로그램한 것으로 전원이 꺼지면 저장된 내용은 지워지게 된다. FPGA에 Flash하기 위해서는 다음의 과정을 행한다. File-Convert Programming Files Configuration Device: EPC2로 설정하고 Add file을 클릭하여 이전의 sof파일을 불러온다. Generate를 클릭하여 EPC2로 변경된 pof파일을 생성한다. 모바일컴퓨터특강
FPGA – Programmer (4) Tools-Programmer 이후 하드웨어를 재부팅해도 프로그램한 내용이 동작된다. 하드웨어와 호스트를 ByteBlaster로 연결한다. 하드웨어의 전원이 켜져있는 상태에서 Auto Detect EPC2와 EP1C6 두 디바이스가 검색되어진다. EP2를 더블클릭하여 컴파일시 생성된 pof 파일을 불러온다 EP2의 Program/Configure을 클릭하고 Start를 누르면 FPGA에 플래시된다. 이후 하드웨어를 재부팅해도 프로그램한 내용이 동작된다. 모바일컴퓨터특강