FPGA |
Altera Cyclon EP1C6 |
Logic Elements |
5980 |
Logic Gate |
120000 Logic Gate |
RAM Bit |
92160 Bit |
외부 CPU |
PXA255 |
외부 인터페이스 |
32 Bit Address/Data Bus |
입력 I/O |
Push SW, Dip SW, ADC, Image Sensor |
출력 I/O |
Text LCD, LED, 7 Segment, Buzzer, DotMatrix,
VGA |
기타 I/O |
EEPROM |
use ieee.std_logic_1164.all;
entity clk_div is
generic(count : integer range 0 to 30000 := 2);
port(CLK_IN : in std_logic;
SM_CLK : out std_logic );
end clk_div;
architecture sample of clk_div is
begin
process(CLK_IN)
variable tmp : integer range 0 to 30000 := 0;
begin
if(CLK_IN'event and CLK_IN = '1') then
if(tmp = count-1) then
tmp := 0;
SM_CLK <= '1';
else
tmp := tmp + 1;
SM_CLK <= '0';
end if;
end if;
end process;
end sample;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity DigitalTimer is
port( CLK : in std_logic;
rset : in std_logic;
ih_key : in std_logic;
im_key : in std_logic;
is_key : in std_logic;
FDATA_SM : out std_logic_vector(7 downto 0) := "00111111";
FCOM : out std_logic_vector(5 downto 0) := "001111" );
end DigitalTimer;
architecture rt1 of DigitalTimer is
function fnd_disnum(cnt : integer range 0 to 9) return std_logic_vector is
variable seg_decode : std_logic_vector(7 downto 0);
begin
case cnt is
when 0 => seg_decode := "00111111";
when 1 => seg_decode := "00000110";
when 2 => seg_decode := "01011011";
when 3 => seg_decode := "01001111";
when 4 => seg_decode := "01100110";
when 5 => seg_decode := "01101101";
when 6 => seg_decode := "01111101";
when 7 => seg_decode := "00100111";
when 8 => seg_decode := "01111111";
when 9 => seg_decode := "01100111";
when others => seg_decode := "00000000";
end case;
return (seg_decode);
end fnd_disnum;
-- clock division
component clk_div
generic(count : integer range 0 to 30000);
port( CLK_IN : in std_logic;
SM_CLK : out std_logic );
end component;
-- used signal
signal temp : integer range 0 to 5;
signal cnt_sec1 : integer range 0 to 10 := 0;
signal cnt_min : integer range 0 to 10 := 0;
signal cnt_min1 : integer range 0 to 10 := 0;
signal seg0 : std_logic_vector(7 downto 0) := "00111111";
signal seg1 : std_logic_vector(7 downto 0) := "00111111";
signal seg2 : std_logic_vector(7 downto 0) := "00111111";
signal seg3 : std_logic_vector(7 downto 0) := "00111111";
signal seg4 : std_logic_vector(7 downto 0) := "00111111";
signal seg5 : std_logic_vector(7 downto 0) := "00111111";
signal sclk0, sclk1, sclk2, sclk3 : std_logic := '0';
signal temp_clk : std_logic;
signal fnd_clk : std_logic;
signal sec_clk : std_logic;
begin
LED_CLK_DIV : clk_div generic map(330) port map(CLK, fnd_clk); -- fnd_clk : 100Khz
TEMP_CLK_DIV : clk_div generic map(3300) port map(CLK, temp_clk); -- temp_clk : 10Khz
SEC_CLK_DIV : clk_div generic map(10000) port map(temp_clk, sec_clk); -- sec_clk : 1hz
-- FND Output Process
process(fnd_clk)
begin
if(fnd_clk'event and fnd_clk = '1') then
case temp is
when 0 => temp <=1; FCOM <= "111110"; FDATA_SM <= seg5;
when 1 => temp <=2; FCOM <= "111101"; FDATA_SM <= seg4;
when 2 => temp <=3; FCOM <= "111011"; FDATA_SM <= seg3;
when 3 => temp <=4; FCOM <= "110111"; FDATA_SM <= seg2;
when 4 => temp <=5; FCOM <= "101111"; FDATA_SM <= seg1;
when 5 => temp <=0; FCOM <= "011111"; FDATA_SM <= seg0;
when others => FCOM <= "111111"; FDATA_SM <= "00111111";
end case;
end if;
end process;
-- 1 second Process
process(sec_clk, rset, is_key)
variable cnt : integer range 0 to 10 := 0;
begin
if(rset = '1' or is_key = '1') then
cnt := 0;
sclk0 <= '0';
seg0 <= fnd_disnum(0);
elsif(sec_clk'event and sec_clk = '1') then
if(cnt = 9) then
cnt := 0;
sclk0 <= '0';
elsif(cnt = 8) then
sclk0 <= '1';
cnt := cnt + 1;
else
cnt := cnt + 1;
sclk0 <= '0';
end if;
seg0 <= fnd_disnum(cnt);
end if;
end process;
-- 10 second process
process(sec_clk, rset, is_key)
begin
if(rset = '1' or is_key = '1') then
cnt_sec1 <= 0;
elsif(sec_clk'event and sec_clk = '1') then
if(sclk0 = '1') then
if(cnt_sec1 = 5) then
cnt_sec1 <= 0;
else
cnt_sec1 <= cnt_sec1 + 1;
end if;
end if;
end if;
seg1 <= fnd_disnum(cnt_sec1);
end process;
sclk1 <= '1' when(cnt_sec1 = 5 and sclk0 = '1') else '0';
-- 1 miniute process
process(sec_clk, rset, im_key)
begin
if(rset = '1') then
cnt_min <= 0;
elsif(sec_clk'event and sec_clk = '1') then
if(im_key = '1') then
if(cnt_min = 9) then
cnt_min <= 0;
else
cnt_min <= cnt_min + 1;
end if;
elsif(sclk1 = '1') then
if(cnt_min = 9) then
cnt_min <= 0;
else
cnt_min <= cnt_min + 1;
end if;
end if;
end if;
seg2 <= fnd_disnum(cnt_min);
end process;
sclk2 <= '1' when(cnt_min = 9 and sclk1 = '1') else
'1' when(cnt_min = 9 and im_key = '1') else '0';
-- 10 miniute process
process(sec_clk, rset)
begin
if(rset = '1') then
cnt_min1 <= 0;
elsif(sec_clk'event and sec_clk = '1') then
if(sclk2 = '1') then
if(cnt_min1 = 5) then
cnt_min1 <= 0;
else
cnt_min1 <= cnt_min1 + 1;
end if;
end if;
end if;
seg3 <= fnd_disnum(cnt_min1);
end process;
sclk3 <= '1' when(cnt_min1 = 5 and sclk2 = '1') else '0';
-- hour process
process(sec_clk, rset, ih_key)
variable cnt : integer range 0 to 24 := 0;
variable a, b : integer range 0 to 50 := 0;
begin
if(rset = '1') then
cnt := 0;
elsif(sec_clk'event and sec_clk = '1') then
if(ih_key = '1') then
if(cnt = 23) then
cnt := 0;
else
cnt := cnt + 1;
end if;
elsif(sclk3 = '1') then
if(cnt = 23) then
cnt := 0;
else
cnt := cnt + 1;
end if;
end if;
end if;
a := cnt / 10;
b := cnt mod 10;
seg4 <= fnd_disnum(b);
seg5 <= fnd_disnum(a);
end process;
end rt1;
이번 프로젝트에서는 디지털시계를 HDL언어인 VHDL를 사용하여 설계하여 실습 보드인 PXA255 FPGA에 직접 올려보았다.
디지털시계를 구현하기 위해서 33Mhz의 메인 클럭에서 1hz의 클럭을 얻기 위한 묘듈이 필요했다. 이 묘듈은 카운터를 이용하여 원하는 수만큼 카운트 한 후 신호를 내보내는 원리로 동작한다.
디지털시계는 1초, 10초, 1분, 10분, 시간을 각각 처리하는 프로세스 문으로 작성되며, 모든 동작은 1hz인 second clock에 동기 되어 동작하게 된다. 그 외 sclk0, sclk1, sclk2, sclk3 의 클럭들이 내부에서 발생 된다. sclk0은 9초에서 10초로 넘어 갈 때, sclk1은 59초에서 1분으로 넘어 갈 때, sclk2는 9분에서 10분으로 넘어 갈 때, sclk3는 59분에서 1시간으로 넘어 갈 때 사용 되는 신호이다.
이번 프로젝트를 통해서 타이밍에 대한 이해와 VHDL의 활용능력 및 쿼터스 같은 툴 사용에 대해 익숙해 진 것 같다. 또한 자신이 작성한 디지털시계를 직접 FPGA에 올려 보고 제대로 동작을 하는지 확인해봄으로써, 평소 시뮬레이션만 해보는 것과 다르게 회로설계에 대한 자신감을 가질 수 있었다.