09 การใช้งาน Xilinx CORE Generator
การเขียน VHDL เพื่อสร้างงานลงบนชิพ FPGA หรือ CPLD ก็คล้ายกับการเขียนโปรแกรมภาษาต่างๆเพื่อนำไปรันบนคอมพิวเตอร์ คือเราสามารถเขียนเองทั้งหมด หรือเรียกใช้สิ่งที่มีผู้อื่นสร้างใว้ให้แล้ว หรือในกรณีที่เป็นโปรแกรมที่มีความซับซ้อน มักจะมีผู้ที่ทำเก็บใว้ให้เรียกใช้ได้ในไลบรารี่ กรณีของ VHDL ก็มีเช่นเดียวกัน แต่จะไม่เรียกว่าไลบรารี่ จะเรียกว่า Core Generator หรือ IP (Intellectual Property) core การเรียกใช้นี้สามารถปรับแต่งให้เข้ากับงานเราได้ การเรียกใช้ Core Generator จึงให้ทั้งความสะดวก และรวดเร็ว แต่ IP ส่วนใหญ่ จะไม่เปิดเผยโค๊ด จึงยากที่จะใช้เป็นตัวอย่างเพื่อการศึกษาถึงเทคนิคการเขียน และในกรณีที่ต้องการนำไปใช้งานจริงๆ มักมีค่าใช้จ่าย เพราะ Core ส่วนใหญ่มีลิขสิทธิ์
ตัวอย่างนี้ใช้ Core generator สร้างวงจรนับขึ้นขนาด 8 บิต โดยขา Input มีเพียงขา clk และ reset เท่านั้น เพื่อให้ตัวอย่างไม่ซับซ้อนมากนัก
การใช้ Xilinx Core Generator เพื่อสร้างโปรเจคมีขั้นตอนดังนี้
สร้างโปรเจคใหม่
สร้างโปรเจคใหม่ (New Project) ศึกษาได้จาก ise14_7.pdf ของ รศ.ณรงค์ บวบทอง
ใช้ Core Generator สร้างโค๊ดของโมดูล
1. เมื่อสร้างโปรเจคใหม่เสร็จแล้ว ในส่วนหน้าต่าง Design ที่อยู่กรอบซ้ายบน จะยังไม่มีโมดูลใดๆอยู่ มีเพียงชื่อชิพ FPGA เท่านั้น
ให้คลิกปุ่มขวาของเมาส์ที่ชื่อชิพ แล้วเลือกเมนู New Source
2. เมื่อปรากฏหน้าต่าง New Source Wizard ให้คลิกเมนู IP(CORE Generator & Architure wizard)
ช่อง File name ใส่ชื่อไฟล์ my_counter
ช่อง Location เป็นที่เก็บ Core ให้เป็นชื่อไดเร็คตอรีของโปรเจค
กด Next
3. เมื่อปรากฏรายชื่อ IP Core ต่างให้เลือก ฺBasic Element -> Counter -> Binary Counter ด้วยการดับเบิลคลิกที่ชื่อนี้
4. เมื่อปรากฏหน้าต่างรูปแบบของ Binary Counter
Output Width = 8 กำหนดขนาดวงจรนับ เป็น 8 บิต
Count Mode = UP เลือกวิธีการนับเป็นแบบนับขึ้น
ติกเลือก Synchronous Clear ให้มีขารีเซ็ตแบบซิงค์กับสัญญาณนาฬิกา
ตอนนี้สังเกต บล็อกไดอะแกรมที่อยู่ช่องสายมือของหน้าต่างจะปรากฏขาสัญญาณต่างๆที่ กำหนด
คลิก Generate
สังเกตที่หน้าต่าง Design จะปรากฏ my_counter(my_counter.xco) เป็นโมดูลในชิพ
เขียนโค๊ด vhdl อื่นๆที่เกี่ยวข้อง
1. เขียนโค๊ดตัวหลัก top_io.vhd ที่เรียกใช้ IP Core ที่สร้างขึ้น
ก่อนอื่นต้องดูวิธีการ Interface IP Core (การชื่อมต่อ)
2. ที่หน้าต่าง Design คลิกที่ชื่อ IP Core my_Counter(my_counter.xco)
ที่หน้าต่าง Process ให้ดับเบิลคลิกที่เมนู View HDL Instantiation Template
จะปรากฏไฟล์ที่เป็นเทมเพลทของการติดต่อกับ IP Core ให้ใช้เฉพาะส่วนโค๊ด Component กับ Port map
มาเขียนไฟล์ top_io.vhd
------------------------------------------------------------------------------------------------------
------------- Begin Cut here for COMPONENT Declaration ------ COMP_TAG
COMPONENT my_counter
PORT (
clk : IN STD_LOGIC;
sclr : IN STD_LOGIC;
q : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
-- COMP_TAG_END ------ End COMPONENT Declaration ------------
-- The following code must appear in the VHDL architecture
-- body. Substitute your own instance name and net names.
------------- Begin Cut here for INSTANTIATION Template ----- INST_TAG
your_instance_name : my_counter
PORT MAP (
clk => clk,
sclr => sclr,
q => q
);
------------------------------------------------------------------------------------------------------
ไฟล์ top_io.vhd ที่เขียนขึ้นเพื่อใช้เป็นโมดูลหลักของโปรเจค
สังเกตชื่อสัญญาณที่เปลี่ยนให้ตรงกับที่ใช้จริง เช่นใช้ led ที่เป็นสัญญาณที่ต่ออยู่กับ led บนบอร์ดทดลอง
------------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
entity top_io is
port(
clk : in std_logic;
rst_n : in std_logic;
led: out std_logic_vector(7 downto 0)
);
end top_io;
architecture rtl of top_io is
component my_counter
port (
CLK: IN std_logic;
sclr: IN std_logic;
Q: OUT std_logic_VECTOR(7 downto 0));
end component;
signal clk10hz: std_logic;
signal rst: std_logic;
begin
rst <= not rst_n;
U1 : my_counter
port map (
CLK=>clk10hz,
sclr => rst,
Q => led);
DIVIDER1 : entity work.DIVIDER
generic map(fin => 50000000,
fout => 10
)
port map (CLK=>clk,
Q => clk10hz
);
end rtl;
------------------------------------------------------------------------------------------------------
เนื่องจากความถี่ที่ใช้ในชิพของบอร์ดทดลองเป็น 50 MHz เพื่อให้เห็นการนับช้าลงจะได้เห็นการนับอย่างชัดเจนจึงเพิ่มโมดูลหารความถี่ divider เข้าไป โดยให้เพิ่มไฟล์ divider.vhd ลงในโปรเจค (คลิก divider.vhd เพื่อดาวน์โหลดไฟล์)
ส่วนการเชื่อมต่อระหว่างโมดูลหลักกับ divide ก็ใช้ port map เช่นกัน (แต่เป็นการเรียกใช้อีกวิธีหนึ่ง)
สุดท้ายเพิามไฟล์ที่ใช้กำหนดสัญญาณเข้ากับขาของชิพ ชื่อ top_io.ucf โดยเขียนตามคำสั่งด้านล่างนี้
------------------------------------------------------------------------------------------------------
#Created by Constraints Editor (xc6slx9-tqg144-3) - 2012/11/05
NET "clk" TNM_NET = clk;
TIMESPEC TS_clk = PERIOD "clk" 50 MHz HIGH 50%;
# PlanAhead Generated physical constraints
NET "clk" LOC = P56;
NET "rst_n" LOC = P38;
NET "led<0>" LOC = P134;
NET "led<1>" LOC = P133;
NET "led<2>" LOC = P132;
NET "led<3>" LOC = P131;
NET "led<4>" LOC = P127;
NET "led<5>" LOC = P126;
NET "led<6>" LOC = P124;
NET "led<7>" LOC = P123;
------------------------------------------------------------------------------------------------------
แปลโค๊ต และ Config FPGA
ศึกษาได้จาก ise14_7.pdf ของ รศ.ณรงค์ บวบทอง