Upload
others
View
1
Download
0
Embed Size (px)
Citation preview
5. LED 제어
SYS-Lab 5000의 Block Diagram
SYS-Lab 5000의 FPGA와 연결된 주변 장치
ISE의 실행
LED 출력 - 1
ISE에 새로운 프로젝트 생성, FPGA 디바이스 지정
LED 출력 - 2
디자인에 적용할 Source File 종류 선택
LED 출력 – 3(VHDL)
1) Source2) Process3) Edit
LED 출력 – 4(Verilog)
1) Source2) Process3) Edit
LED 출력 - 5
문법 오류 확인
LED 출력 - 6
Implement Constraint File 지정
LED 출력 (UCF File)
Spartan 3의 UCF파일의내용 Virtex 4의 UCF 파일의내용
LED 출력 - 7
iMPACT 실행
JTAG Cable 연결과 다운로드 파일 지정
FPGA 프로그램
카운터를 사용한 LED 값의 증가
SYS-Lab 5000에는 22.1184MHz의oscillator 사용
입력 클럭을 2^24 = 16,777,216 분주를 하여 22,118,400 / 16,777,216 ≒ 1.3184Hz의속도로(약 0.76초의 속도로) LED의 값을하나씩 증가시키도록 구성
Clock PIN 지정◦ SPARTAN3 : NET "clock" LOC = "A11" ;◦ VIRTEX4 : NET "clock" LOC = "B14" ;
HDL Code
library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity led02 isPort( clock : in STD_LOGIC;
led_out : out STD_LOGIC_VECTOR (23 downto 0));end led02;
architecture Behavioral of led02 issignal count : std_logic_vector(47 downto 0);
beginprocess(clock,count)begin
if clock'event and clock='1' thencount <= count + '1';
end if;end process;led_out <= count(47 downto 24);
end Behavioral;
module led02(clock, led_out);input clock;output [23:0] led_out;
reg [47:0] count;
assign led_out = count[47:24];
always @(posedge clock)count <= count + 1;
endmodule
1초마다 LED 값의 증가(VHDL) - 1
그림 3-9). 예제 code의 clock과 internal_clock 관계 개념도
1초마다 LED 값의 증가(VHDL) - 2
1초마다 LED 값의 증가(Verilog)
LED를 사용한 2진 표기 시계(VHDL) - 1
library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;entity led04 is
Port ( clock : in STD_LOGIC;led_out : out STD_LOGIC_VECTOR (23 downto 0));
end led04;
architecture Behavioral of led04 issignal internal_clock, m_clock, h_clock : std_logic;signal count : std_logic_vector(24 downto 0);signal sec_count : std_logic_vector(5 downto 0);
LED를 사용한 2진 표기 시계(VHDL) - 2
signal min_count : std_logic_vector(5 downto 0);signal hour_count : std_logic_vector(4 downto 0);
beginprocess(clock,count)begin
if clock'event and clock='1' thenif count="1010100010111111111111111" then
count <= (others=>'0');internal_clock <= '1';
elsif count="0101010001011111111111111" thencount <= count + '1';internal_clock <= '0';
elsecount <= count + '1';internal_clock <= internal_clock;
end if;end if;
end process;
LED를 사용한 2진 표기 시계(VHDL) - 3
led_out <= "000" & hour_count & "00" & min_count & "00" & sec_count;
process(internal_clock,sec_count)begin
if internal_clock'event and internal_clock='1' thenif sec_count="111011" then
sec_count <= (others=>'0');m_clock <= '1';
elsif sec_count="011101" thensec_count <= sec_count + '1';m_clock <= '0';
elsesec_count <= sec_count + '1';m_clock <= m_clock;
end if;end if;
end process;
LED를 사용한 2진 표기 시계(VHDL) - 4
process(m_clock,min_count)begin
if m_clock'event and m_clock='1' thenif min_count="111011" then
min_count <= (others=>'0');h_clock <= '1';
elsif min_count="011101" thenmin_count <= min_count + '1';h_clock <= '0';
elsemin_count <= min_count + '1';h_clock <= h_clock;
end if;end if;
end process;process(h_clock,hour_count)begin
LED를 사용한 2진 표기 시계(VHDL) - 5
if h_clock'event and h_clock='1' thenif hour_count="10111" then
hour_count <= (others=>'0');else
hour_count <= hour_count + '1';end if;
end if;end process;
end Behavioral;
LED를 사용한 2진 표기 시계(Verilog)- 1
module led04(clock, led_out);input clock;output [23:0] led_out;
reg [24:0] count;reg [5:0] sec_count;reg [5:0] min_count;reg [4:0] hour_count;reg internal_clock, m_clock, h_clock;
assign led_out = {3'b000,hour_count,2'b00,min_count,2'b00,sec_count};
always @(posedge clock)if (count=='b1010100010111111111111111)begin
count <= 25'h0000000;internal_clock <= 1;
endelse if (count=='b0101010001011111111111111)begin
LED를 사용한 2진 표기 시계(Verilog)- 2count <= count + 1;internal_clock <= 0;
endelsebegin
count <= count + 1;internal_clock <= internal_clock;
end
always @(posedge internal_clock)if (sec_count=='d59)begin
sec_count <= 6'h00;m_clock <= 1;
endelse if (sec_count=='d29)begin
sec_count <= sec_count + 1;m_clock <= 0;
end
LED를 사용한 2진 표기 시계(Verilog)- 3
elsebegin
sec_count <= sec_count + 1;m_clock <= m_clock;
endalways @(posedge m_clock)
if (min_count=='d59)begin
min_count <= 6'h00;h_clock <= 1;
endelse if (min_count=='d29)begin
min_count <= min_count + 1;h_clock <= 0;
end
LED를 사용한 2진 표기 시계(Verilog)- 4
elsebegin
min_count <= min_count + 1;h_clock <= h_clock;
endalways @(posedge h_clock)
if (hour_count=='d23)hour_count <= 5'h00;
elsehour_count <= hour_count + 1;
endmodule
LED의 밝기 조절 사람의 눈은 약 1/60초의 시간 간격보다 짧은시간으로 변하는 끊어진 움직임에 대해서는끊어져 움직이는 것을 느끼지 못하며 연속적인 변화로 감지
LED의 on/off 시간을 일정 주기로 제어하고 각주기 내에서 on 구간과 off 구간을 설정하여 on 구간이 길면 LED는 밝게, off 구간이 길면 LED는 어둡게 보이도록 제어
LED의 밝기 조절(VHDL) - 1library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity cnt_10 isPort ( clock : in STD_LOGIC;
led_out : out STD_LOGIC_VECTOR (23 downto 0));end cnt_10;
architecture Behavioral of cnt_10 issignal i_clk, m_clk : std_logic;signal cnt : std_logic_vector(3 downto 0);signal count, led_data : std_logic_vector(7 downto 0);signal i_cnt : std_logic_vector(17 downto 0);
begin
LED의 밝기 조절(VHDL) - 2process(clock, cnt)
begin -- 22.1184MHz의 클럭을 10분주한 i_clk 생성
if clock'event and clock='1' then
if cnt="1001" then
cnt <= (others=>'0');
i_clk <= '1';
elsif cnt="0100" then
cnt <= cnt + '1';
i_clk <= '0';
else
cnt <= cnt + '1';
i_clk <= i_clk;
end if;
end if;
end process;
LED의 밝기 조절(VHDL) - 3
process(i_clk, count, led_data)
begin -- i_clk을 사용하여 256단계의 PWM 파형 생성
if i_clk'event and i_clk='1' then
count <= count + '1';
if count="11111111" then
led_out <= (others=>'1');
elsif count=led_data then
led_out <= (others=>'0');
end if;
end if;
end process;
LED의 밝기 조절(VHDL) - 4
m_clk <= count(7);
process(m_clk, i_cnt)
begin -- System clock을 10분주하고 이를 다시 256분주하여 i_cnt증가
if m_clk'event and m_clk='1' then
i_cnt <= i_cnt + '1';
end if;
end process; -- i_cnt의 상위 8-bit를 사용하여
led_data <= i_cnt(17 downto 10); -- LED가 on 되는 구간 설정
end Behavioral;
LED의 밝기 조절(Verilog) - 1
module led04(clock, led_out);input clock;output reg [23:0] led_out;
reg [7:0] count;reg [3:0] cnt;reg [17:0] i_cnt;reg i_clk;
wire [7:0] led_data;wire m_clk;
always @(posedge clock)if (cnt=='b1001)begin
LED의 밝기 조절(Verilog) - 2
cnt <= 4'h0;i_clk <= 1;
endelse if (cnt=='b0100)begin
cnt <= cnt + 1;i_clk <= 0;
endelsebegin
cnt <= cnt + 1;i_clk <= i_clk;
end
LED의 밝기 조절(Verilog) - 3always @(posedge i_clk)begin
count <= count + 1;if (count==8'hff)
led_out <= 24'hffffff;else if (count==led_data)
led_out <= 24'h0;end
assign m_clk = count[7];
always @(posedge m_clk)i_cnt <= i_cnt + 1;
assign led_data = i_cnt[17:10];endmodule
LED 밝기 조절 동작
SYS-Lab 5000에 다운로드하여 동작◦ LED가 서서히 밝아지며 최대 밝기에 도달
◦ 이 후 가장 어두운 상태가 되며
◦ 다시 밝아지는 동작을 반복
◦ PWM 주파수
22.1184MHz의 클럭을 사용할 경우
8.64khz로 동작하며
가장 어두운 상태에서 최대 밝기까지 약 30초