รายการอุปกรณ์
1. บอร์ด Altera FPGA (WARRIOR CYCLONE3 DEV) ชิปหมายเลข EP3C10E144C8 1 บอร์ด
2. สายดาวน์โหลด ByteBlaster II Cable หรือ สายดาวน์โหลดUSB Blaster Cable 1 ชุด
3. เครื่องคอมพิวเตอร์ 1 ชุด
4. ออสซิลโลสโคป 1 เครื่อง
5. สายวัด Logic Analyzer 1 เส้น
วิธีการทดลอง
ออกแบบวงจรดิจิลัทโดยใช้ภาษา VHDL สำหรับนำไปสร้างเป็นวงจรในชิป FPGA โดยวงจรดิจิทัลมี I/O ดังนี้
- CLK (input) มีความถี่ 50MHz ใช้สำหรับกำหนดจังหวะการทำงานของวงจรทั้งหมด (เป็นการออกแบบวงจรดิจิทัลแบบ Synchronous Design)
- RST_B (input) เป็นอินพุตสำหรับใช้รีเซตแบบ Asynchronous สำหรับการทำงานของวงจรโดยรวม (ทำงานแบบ Active-Low) ซึ่งได้จากวงจรปุ่มกด (Push Button)
- PB[2:0] (input) เป็นอินพุตจากปุ่มกด 3 ปุ่ม ทำงานแบบ Active-low เพื่อใช้ในการเปลี่ยนค่า Duty Cycle โดยเพิ่มทีละ 10 ในช่วง 0 ถึง 100 สำหรับสัญญาณ PWM(2:0) ที่มี 3 ช่องสัญญาณ
- PWM[2:0] (output) เป็นเอาต์พุตสำหรับนำไปควบคุมการทำงานของ RGB LED จำนวน 1 ดวง
วงจรดิจิทัลพฤติกรรมการทำงานเป็นดังนี้
- เมื่อเริ่มต้นหรือกดปุ่มรีเซต RST_B ค่า PWM[2:0] จะเป็นลอจิก 0 ทั้ง 3 ช่องสัญญาณ และมีค่า Duty Cycle สำหรับสัญญาณ PWM[i], i=0,1,2 เป็น 0
- เมื่อกดปุ่มใดๆ PB[i], i=0,1,2, แล้วปล่อยในแต่ละครั้ง จะเพิ่มค่า Duty Cycle ของสัญญาณ PWM สำหรับช่องสัญญาณ i ทีละ 10 แต่ถ้าถึง 100 จะกลับไปเริ่มต้นที 0 ใหม่
- สัญญาณ PWM แต่ละช่อง ต้องมีความถี่เท่ากันและคงที่ และสามารถเลือกใช้ความถี่ได้ในช่วง 500Hz ถึง 1kHz
แนวทางการออกแบบและทดสอบ
- ออกแบบวงจรโดยใช้ภาษา VHDL
- เขียน VHDL Testbench เพื่อทดสอบการทำงาน และจำลองการทำงาน
- ทดสอบการทำงานในบอร์ด FPGA แล้ววัดสัญญาณโดยใช้ออสซิลโลสโคป
- บันทึกผลและเขียนรายงานการทดลอง
รูปแผนภาพ Block Diagram การทำงานของวงจร
โค้ดวงจรดิจิทัลภาษา VHDL
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity DutyCycle is
generic (
PERIOD : integer := 100; -- count period for PWM
STEP : integer := 10 -- increment step for duty cycle
);
port(
CLK : in std_logic;
RST_B : in std_logic;
PB : in std_logic_vector (2 downto 0);
PWM : out std_logic_vector (2 downto 0));
end DutyCycle;
architecture behave of DutyCycle is
signal check_0 : std_logic:= '0';
signal check_1 : std_logic:= '0';
signal check_2 : std_logic:= '0';
signal duty_cycle_0 :integer :=0;
signal duty_cycle_1 :integer :=0;
signal duty_cycle_2 :integer :=0;
signal count :integer :=0;
signal ti : integer := 0;
begin
process (CLK,RST_B) begin
if rising_edge(CLK) then
if RST_B ='0' then
duty_cycle_0 <= 0;
duty_cycle_1 <= 0;
duty_cycle_2 <= 0;
end if;
if PB(0) = '1' and check_0 = '1' then
check_0 <= '0';
duty_cycle_0 <= duty_cycle_0+STEP;
if duty_cycle_0 > (PERIOD-1) then
duty_cycle_0 <= 0;
end if;
elsif PB(0) ='0' then
if ti < 50000 then
ti <= ti+1;
else
check_0 <= '1';
ti <= 0;
end if;
end if;
-----------------------------------------------
if PB(1) = '1' and check_1 = '1' then
check_1 <= '0';
duty_cycle_1 <= duty_cycle_1+STEP;
if duty_cycle_1 > (PERIOD-1) then
duty_cycle_1 <= 0;
end if;
elsif PB(1) ='0' then
if ti < 50000 then
ti <= ti+1;
else
check_1 <= '1';
ti <= 0;
end if;
end if;
-----------------------------------------
if PB(2) = '1' and check_2 = '1' then
check_2 <= '0';
duty_cycle_2 <= duty_cycle_2+STEP;
if duty_cycle_2 > (PERIOD-1) then
duty_cycle_2 <= 0;
end if;
elsif PB(2) ='0' then
if ti < 50000 then
ti <= ti+1;
else
check_2 <= '1';
ti <= 0;
end if;
end if;
end if;
end process;
process (CLK) begin
if rising_edge(CLK) then
if count >99999 then
count <= 0;
else
count <= count+1;
end if;
end if;
end process;
PWM(0) <= '1' when (count < duty_cycle_0*1000) else '0';
PWM(1) <= '1' when (count < duty_cycle_1*1000) else '0';
PWM(2) <= '1' when (count < duty_cycle_2*1000) else '0';
end behave;
|
ผลการทดลอง
ผลการสังเคราะห์ VHDL เป็นวงจรในชิปและการใช้ทรัพยากรของบอร์ด FPGA
ผลการจำลองการทำงานด้วย Modelsim
ทดลองบนบอร์ด FPGA
ผลลัพธ์ที่ได้
การเปลี่ยนแปลงลักษณะสัญญาณเมื่อกดปุ่ม PB ช่องสัญญาณ D0:5 ครั้ง D1:9 ครั้ง D2:1 ครั้ง
การเปลี่ยนแปลงลักษณะสัญญาณเมื่อกดปุ่ม PB ช่องสัญญาณ D0:8 ครั้ง D1:4 ครั้ง D2:1 ครั้ง
การเปลี่ยนแปลงลักษณะสัญญาณเมื่อกดปุ่ม PB ช่องสัญญาณ D0:1 ครั้ง D1:5 ครั้ง D2:8 ครั้ง

ไม่มีความคิดเห็น:
แสดงความคิดเห็น