การเรียนรู้และใช้งาน FPGA ด้วยภาษา VHDL

เขียนโดย ดร.จักรกฤษณ์  แสงแก้ว วันที่ 1 มิถุนายน 2560

กล่าวนำ

ในการศึกษา VHDL บนบอร์ด Xilinx Spartan 3AN ซึ่งใช้ชิป FPGA เบอร์ SC700AN มีรายละเอียดจำนวนมาก ดังนั้น ผู้เขียนเห็นว่าควรรวบรวม เอาไว้ในหัวข้อเดียวจะได้เป็นหมวดหมู่ เพื่อให้จัดเก็บและค้นหาง่าย จึงตั้งหัวข้อนี้สำหรับการศึกษาเรียนรู้ VHDL เพื่อควบคุม FPGA 

ประวัติความเป็นมาของ VHDL

- VHDL : Very Hight Speed IC (Hardware Description Language)
- ปี ค.ศ. 1981 กลาโหมอเมริกา (US:DOD) ตั้งโครงการ VHSIC เพื่อสร้างโปรแกรมภาษาระดับสูงให้บรรยายพฤติกรรมของวงจรดิจิตอล เพื่อให้ออกแบบวงจรดิจิตอลได้รวดเร็ว
- กลาโหมอเมริกาว่าจ้างบริษัท IBM, Teaxas Instruments และ Intermetrics ศึกษาและพัฒนาภาษาดังกล่าวและประสบผลสำเร็จ (ไม่รู้ใช้งบประมาณไปเท่าไร)
- ค.ศ. 1985 อนุญาตให้ถ่ายทอดเทคโนโลยีให้ใช้ได้ทั่วไป ต่อมา IEEE เข้ามาศึกษาจนถึงปี 1987 ได้เผยแพร่เป็นมาตรฐาน เรียก IEEE 1976-1987 
- ในปัจจุบันพัฒนาเป็นมาตรฐาน IEEE 1076-1993 หรือ VHDL 1993

ส่วนประกอบของ VHDL 3 ส่วน

1) Library และ Package
2) Entity
3) Architecture

การทำงานเหมือนภาษาระดับสูงทั่วไป ไลบรารี่และแพคเกจเป็นฟังก์ชั่นต่าง ๆ ของตัวภาษา VHDL ส่วน Entity สำหรับบอกว่าอุปกรณ์ที่ออกแบบมี Input / Output อย่างไรบ้าง สุดท้าย Architecture อธิบายพฤติกรรมของฮาร์แวร์ที่กำลังออกแบบนี้

สถาปัตยกรรม 3 แบบภายใน VHDL

1) Behavioural คือ คำอธิบายอัลกริทึม มีคำสั่ง if-then-else, for-loop เป็นต้น เช่น
architecture behavioural of xxx is 
begin 
process(i0, i1, sel)
if(sel='0') then output <= i0; 
else output <= i1;
end if;
end process;
end behavioural;

2) Structure คือ การแสดงเป็นลำดับมีโครงสร้าง อุปกรณ์หลายตัวต่อกันไป (Cascade) เช่น
architecture structureal of xxx is
component AAA port(i1:in bit; o1: out bit); end component;
component BBB port(i1,i2:in bit; o1: out bit); end component;
component CCC port(i1,i2 :in bit; o1: out bit); end component;
signal x0, x1, x2:bit;
begin
STEP0: AAA : port map(i1=>sel, o1=>x0);
STEP1: BBB : port map(i1=>i0, i2=>x0, 01=>x1);
STEP2: CCC: port map(i1=>sel, i2=>i1, o1=>x2);
STEP3: DDD: port map(i1=>x1, i2=>x2, o1=z);
end structural;

3) Mixed - Level คือ การผสมระหว่างคำอธิบายและโครงสร้าง

มาตรฐานของชนิดข้อมูล

- Boolean : False, True
- Bit : '0' , '1'
- Bit_Vector : '0000', '1111, ..
- Character : 'a', 'b', ...
- String : "Hello World" ...
- Integer : 1, 2, ...
- Real : 1.01, -10.3 ...
- Time : 10 ns, 200 fs, ...

การ Casting กรณีเลขจำนวนเต็มให้คำสั่ง CONV_INTEGER()

Entity XXX IS
PORT (i0, i1 : IN UNSIGNED(3 downto 0);
R : OUT Integer);
END XXX;

ARCHITECTURE TEST OF XXX IS
Begin 
R <= CONV_INTEGER(i0 + i1);
End TEST;

อาร์เรย์ (Array)

Aggregation

ใช้คำว่า Others แทนบิตที่เหลือ เช่น 
bit 3 = 1
bit 1 = 0
others คือบิตที่เหลือ คือ bit 2 และ 0 ให้มีค่าเท่ากับตัวแปร B

Operators 3 ประเภท

1)่ Local Operators ได้แก่ AND, OR, NAND, NOR, XOR, NOT
2) Relational Operators ได้แก่ <, <=, >, >=, =, /= 
3) Arithmetic Operators ได้แก่ +, - , *, /, **, mod, abs, rem

คำสั่ง Concurrent และ Sequential

- Concurrent Statements ทำงานไปพร้อมกัน ได้แก่คำสั่ง when-else, with-select, signal, component, process และ procedure 
- Sequential Statement ทำงานทีละบรรทัด เช่น if then, case, for loop หากต้องการใช้แบบลำดับต้องประกาศไว้ใน process เท่านั้น

ตัวอย่าง When - Else

ตัวอย่าง With-Select

ตัวอย่าง : Process

ความต่างระหว่างสัญลักษณ์ := และ <=

ตัวอย่าง : Multiplexer

Shift Register


ตัวอย่าง RAM



การเขียนโปรแกรมภาษา VHDL แสดงข้อความบนจอ LCD ขนาด 16x2 ตัวอักษร

บอร์ดทดลอง Xilinx Spartan 3AN มีการเชื่อมต่อสัญญาณโมดูลแสดงผล LCD 16x2 (อักษร 16 ตัวสองบรรทัด) วันนี้ ทำ KM (Knowledge Management) การแสดงข้อความ is.msu.ac.th ให้ปรากฎบนจอภาพ LCD ด้วยภาษา VHDL บนชิป FPGA


การเชื่อมต่อระหว่าง FPGA Chip กับ LCD 16x2 Module
สัญญาณที่ใช้มีอยู่ 4 ชุด คือ 
- LCD_DB คือ Data มีชนิดเป็นบิตเวคเตอร์ 8 ช่องสัญญาณ
- LCD_E คือ Enable ขนาด 1 ช่องสัญญาณ
- LCD_RS คือ สัญญาณ Reset ขนาด 1 ช่องสัญญาณ
- LCD_RW คือ สัญญาณ Read / Write ขนาด 1 ช่องสัญญาณ
การกำหนดขาสัญญาณสำหรับ FPGA ประกาศใช้งาน ดังนี้
ข้อมูลอักขระภายใน CG ROM (Character Generator ROM)
ภายใน CG ROM ประกอบด้วยอักขระที่ใช้สำหรับการแสดงผลบน LCD 16x2 แสดงข้อมูล เช่น DB[7:4] = 0101 และ DB[3:0] = 0011 ซึ่งหมายถึง ตัวอักษร S เป็นต้น
คำสั่งควบคุม LCD 16x2 
ในการแสดงผลต้องออกคำสั่งเพื่อแสดงอักขระแต่ละตัว โดยชุดคำสั่งจะอยู่ในรูปแบบสัญญาณควบคุม ดังนี้
ช่วงเวลาที่สื่อสารและส่งข้อมูลไปยังโมดูล LCD 16x2
โค๊ด VHDL : สำหรับแสดงข้อความคำว่า 'is.msu.ac.th'
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity lcd_orig is
Port ( 
--Data Pins
LCD_DATA : out STD_LOGIC_VECTOR (7 downto 0);

--Control Pins	
LCD_ENABLE : out STD_LOGIC;

LCD_RS : out STD_LOGIC;

LED1 : out STD_LOGIC;
LED2 : out STD_LOGIC;

--Clock
CLK : in STD_LOGIC);
end lcd_orig;

ARCHITECTURE behavior of lcd_orig IS

type state_type is (	S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, 
S10, S11, S12, S13, S14, S15, S16, S17,
S18, S19, S20, S21, S22, S23, S24, S25,
S26, S27,S28,S29,S30,S31,S32,S33, IDLE);
signal current_state: state_type;
signal a : std_logic := '0';
signal b : std_logic := '0';

BEGIN

LED1 <= a;
LED2 <= b;

PROCESS(CLK)
VARIABLE cnt: INTEGER RANGE 0 TO 1750000;
BEGIN

if rising_edge(CLK) then

--Count Clock Ticks
IF(cnt = 1750000)THEN	
cnt := 0;
a <= '0';
b <= '1';
ELSE
cnt := cnt + 1;
END IF;

--Slowly Move Into Next States
IF(cnt = 1500000)THEN	
--Next State Logic
a <='1';
b <='0';
case current_state is

-------------------Function Set-------------------
when S0 =>
current_state <= S1;

LCD_DATA	<= x'38';

LCD_ENABLE	<= '0';

LCD_RS	<= '0';

when S1 =>
current_state <= S2;

LCD_DATA	<= x'38';

LCD_ENABLE	<= '1';

LCD_RS	<= '0';

when S2 =>
current_state <= S3;

LCD_DATA	<= x'38';

LCD_ENABLE	<= '0';

LCD_RS	<= '0';

-------------------Reset Display-------------------	
when S3 =>
current_state <= S4;

LCD_DATA	<= '00000001';

LCD_ENABLE	<= '0';

LCD_RS	<= '0';

when S4 =>
current_state <= S5;

LCD_DATA	<= '00000001';

LCD_ENABLE	<= '1';

LCD_RS	<= '0';	

when S5 =>
current_state <= S6;	

LCD_DATA	<= '00000001';

LCD_ENABLE	<= '0';

LCD_RS	<= '0';

-------------------Display On-------------------	
when S6 =>
current_state <= S7;	

LCD_DATA	<= '00001110';

LCD_ENABLE	<= '0';

LCD_RS	<= '0';

when S7 =>
current_state <= S8;

LCD_DATA	<= '00001110';

LCD_ENABLE	<= '1';

LCD_RS	<= '0';

when S8 =>
current_state <= S9;	

LCD_DATA	<= '00001110';

LCD_ENABLE	<= '0';

LCD_RS	<= '1';

-------------------Write 'i'-------------------	
when S9 =>
current_state <= S10;	

LCD_DATA	<= x'69';

LCD_ENABLE	<= '1';

LCD_RS	<= '1';	

when S10 =>
current_state <= S11;

LCD_DATA	<= x'69';

LCD_ENABLE	<= '0';

LCD_RS	<= '1';	

-------------------Write 's'-------------------	
when S11 =>
current_state <= S12;	

LCD_DATA	<= x'73';

LCD_ENABLE	<= '1';

LCD_RS	<= '1';	

when S12 =>
current_state <= S13;

LCD_DATA	<= x'73';

LCD_ENABLE	<= '0';

LCD_RS	<= '1';	
-------------------Write '.'-------------------	
when S13 =>
current_state <= S14;	

LCD_DATA	<= x'2e';

LCD_ENABLE	<= '1';

LCD_RS	<= '1';	

when S14 =>
current_state <= S15;

LCD_DATA	<= x'2e';

LCD_ENABLE	<= '0';

LCD_RS	<= '1';	
-------------------Write 'm'-------------------	
when S15 =>
current_state <= S16;	

LCD_DATA	<= x'6d';

LCD_ENABLE	<= '1';

LCD_RS	<= '1';	

when S16 =>
current_state <= S17;

LCD_DATA	<= x'6d';

LCD_ENABLE	<= '0';

LCD_RS	<= '1';	
-------------------Write 's'-------------------	
when S17 =>
current_state <= S18;	

LCD_DATA	<= x'73';

LCD_ENABLE	<= '1';

LCD_RS	<= '1';	

when S18 =>
current_state <= S19;

LCD_DATA	<= x'73';

LCD_ENABLE	<= '0';

LCD_RS	<= '1';	
-------------------Write 'u'-------------------	
when S19 =>
current_state <= S20;	

LCD_DATA	<= x'75';

LCD_ENABLE	<= '1';

LCD_RS	<= '1';	

when S20 =>
current_state <= S21;

LCD_DATA	<= x'75';

LCD_ENABLE	<= '0';

LCD_RS	<= '1';	
-------------------Write '.'-------------------	
when S21 =>
current_state <= S22;	

LCD_DATA	<= x'2e';

LCD_ENABLE	<= '1';

LCD_RS	<= '1';	

when S22 =>
current_state <= S23;

LCD_DATA	<= x'2e';

LCD_ENABLE	<= '0';

LCD_RS	<= '1';	
-------------------Write 'a'-------------------	
when S23 =>
current_state <= S24;	

LCD_DATA	<= x'61';

LCD_ENABLE	<= '1';

LCD_RS	<= '1';	

when S24 =>
current_state <= S25;

LCD_DATA	<= x'61';

LCD_ENABLE	<= '0';

LCD_RS	<= '1';
-------------------Write 'c'-------------------	
when S25 =>
current_state <= S26;	

LCD_DATA	<= x'63';

LCD_ENABLE	<= '1';

LCD_RS	<= '1';	

when S26 =>
current_state <= S27;

LCD_DATA	<= x'63';

LCD_ENABLE	<= '0';

LCD_RS	<= '1';
-------------------Write '.'-------------------	
when S27 =>
current_state <= S28;	

LCD_DATA	<= x'2e';

LCD_ENABLE	<= '1';

LCD_RS	<= '1';	

when S28 =>
current_state <= S29;

LCD_DATA	<= x'2e';

LCD_ENABLE	<= '0';

LCD_RS	<= '1';

-------------------Write 't'-------------------	
when S29 =>
current_state <= S30;	

LCD_DATA	<= x'74';

LCD_ENABLE	<= '1';

LCD_RS	<= '1';	

when S30 =>
current_state <= S31;

LCD_DATA	<= x'74';

LCD_ENABLE	<= '0';

LCD_RS	<= '1';
-------------------Write 'h'-------------------	
when S31 =>
current_state <= S32;	

LCD_DATA	<= x'68';

LCD_ENABLE	<= '1';

LCD_RS	<= '1';	

when S32 =>
current_state <= S33;

LCD_DATA	<= x'68';

LCD_ENABLE	<= '0';

LCD_RS	<= '1';

when S33=>
current_state <= IDLE;	

when IDLE	=>
current_state <= IDLE;

when others =>
current_state <= IDLE;	

end case;	

END IF;

end if;
END PROCESS;

END behavior;
กำหนด Constraint ดังนี้
NET "LCD_RS" LOC = "Y14" ;
NET "LCD_ENABLE" LOC = "AB4" ;

NET "LCD_DATA[0]" LOC = "Y13" ;
NET "LCD_DATA[1]" LOC = "AB18" ;
NET "LCD_DATA[2]" LOC = "AB17" ;
NET "LCD_DATA[3]" LOC = "AB12" ;
NET "LCD_DATA[4]" LOC = "AA12" ;
NET "LCD_DATA[5]" LOC = "Y16" ;
NET "LCD_DATA[6]" LOC = "AB16" ;
NET "LCD_DATA[7]" LOC = "Y15" ;

NET "CLK" LOC = "E12";

NET "LED1" LOC = "R20" ;
NET "LED2" LOC = "T19" ;

วงจรไฟกระพริบด้วย constant : natural

กล่าวนำ
ในการทำวงจรหารความถี่ นักพัฒนาแต่ละท่านใช้เทคนิคแตกต่างกันไป แต่สำหรับหัวข้อนี้ ผมจะใช้เทคนิคการประกาศค่าคงที่ ซึ่งทำให้การเขียนโปรแกรมมีความเป็นภาษาระดับสูงและอ่านง่ายมากขึ้น

จุดที่น่าสนใจคือ การประกาศค่าคงที่ภายใน architecture มีชนิดเป็น
constant ........ : natural := 5000000;

ซึ่งการประกาศแบบนี้ ระบุตัวเลขลงไปได้เลย ในตัวอย่างนี้ประกาศให้มีค่าเท่ากับ 50 ล้าน (50MHz) หรือ 50 ล้านรอบต่อวินาที !!
การกำหนด Constraint ทำได้ดังนี้
เมื่อตัวแปร refclk คือ ตำแหน่ง E12 ซึ่งคือ สัญญาณนาฬิกาและ
ตัวแปร led คือตำแหน่ง R20 ซึ่งต่อกับหลอด LED บนบอร์ดทดลองครับ


ซอร์สโค๊ด : VHDL และ UCF
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;

entity led is
Port ( 
refclk : in std_logic;
led : out std_logic
);
end led;

T architecture behavior of led is
constant max_count : natural := 50000000;
signal Rst : std_logic;
begin

Rst <= '0';

-- 0 to max_count counter
compteur : process(refclk, Rst)
variable count : natural range 0 to max_count;
begin
if Rst = '1' then
count := 0;
led <= '1';
elsif rising_edge(refclk) then
if count < max_count/2 then
count := count + 1;
led <= '1';
elsif count < max_count then
led <= '0';
count := count + 1;
else
led <= '1';
count := 0;
end if;
end if;
end process compteur; 
end behavior;
กำหนด Constrain ดังนี้
เมื่อตัวแปร refclk คือ ตำแหน่ง E12 ซึ่งคือ สัญญาณนาฬิกาและ ตัวแปร led คือตำแหน่ง R20 ซึ่งต่อกับหลอด LED บนบอร์ดทดลองครับ
หัวข้อ : การเปลี่ยน Output Pin จาก R20 เป็น V14 

ในตัวอย่างด้านบนกำหนด Constraint จากบอร์ด กล่าวคือ LED เป็นสัญญาณ R20 ในขณะที่ตัวอย่างนี้จะทำการเปลี่ยนผลลัพธ์ให้แสดงที่ เป็น V14 ซึ่งคือ J20 Accessory Header 

สิ่งที่ต้องดำเนินการ
1. เดินสายต่อขั้วบวกของหลอด LED เข้ากับตำแหน่ง V14
2. ต่อสาย Ground เข้ากับหลอด LED
3. เปลี่ยนตำแหน่ง UCF จาก R20 เป็น V14
4. คอมไพล์และโปรแกรมลงบอร์ด
5. เสร็จเรียบร้อย

สิ่งที่ได้ศึกษาเพิ่มเติมในหัวข้อนี้ คือ การย้ายตำแหน่งของ Output Pin ไปยังตำแหน่งอื่น ๆ ของชิป FPGA


หัวข้อ : การเปลี่ยน Output Pin จาก R20 เป็น AA3 

ในตัวอย่างด้านบนกำหนด Constraint จากบอร์ด กล่าวคือ LED เป็นสัญญาณ R20 ในขณะที่ตัวอย่างนี้จะทำการเปลี่ยนผลลัพธ์ให้แสดงที่ เป็น AA3 ซึ่งคือ J15 Accessory Header 

สิ่งที่ต้องดำเนินการ
1. เดินสายต่อขั้วบวกของหลอด LED เข้ากับตำแหน่ง AA3
2. ต่อสาย Ground เข้ากับหลอด LED
3. เปลี่ยนตำแหน่ง UCF จาก R20 เป็น AA3
4. คอมไพล์และโปรแกรมลงบอร์ด
5. เสร็จเรียบร้อย

สิ่งที่ได้ศึกษาเพิ่มเติมในหัวข้อนี้ คือ การย้ายตำแหน่งของ Output Pin ไปยังตำแหน่งอื่น ๆ ของชิป FPGA

การเขียนข้อความลง LCD 16x2 ด้วยอาร์เรย์ (V.2.0)

ในเวอร์ชั่นแรกได้ใช้การส่งตัวอักขระทีละตัวซึ่งค่อนข้างลูกทุ่งมาก สำหรับเวอร์ชั่นใหม่ ปรับมาให้อยู่ในรูปอาร์เรย์ ซอร์สโค๊ดเรียบง่ายขึ้นมากครับ :) (y)

ในตอนท้ายเขียนโค๊ดไพธอนสังเคราะห์รหัสอักษรให้เป็นเลขฐาน 16 เพื่อนำไปใช้ใน VHDL 


===================================
ซอร์สโค๊ด : VHDL
===================================
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity lcd is
port ( clk : in std_logic; --clock i/p
lcd_rw	: out std_logic; --read & write control
lcd_e : out std_logic; --enable control
lcd_rs	: out std_logic; --data or command control
data : out std_logic_vector(7 downto 0)); --data line
end lcd;

architecture Behavioral of lcd is
constant N: integer :=21; 
type arr is array (1 to N) of std_logic_vector(7 downto 0); 
constant datas : arr :=(X"38",X"0c",X"06",X"01",X"C0",x"4d",x"52",x"2e",x"4e",x"55",x"49",x"2d",x"43",x"48",x"41",x"4b",x"4b",x"52",x"49",x"54",x"20");

begin
lcd_rw <= '0'; --lcd write
process(clk)
variable i : integer := 0;
variable j : integer := 1;
begin
if clk'event and clk = '1' then
if i <= 1000000 then
i := i + 1;
lcd_e <= '1';
data <= datas(j)(7 downto 0);
elsif i > 1000000 and i < 2000000 then
i := i + 1;
lcd_e <= '0';
elsif i = 2000000 then
j := j + 1;
i := 0;
end if;
if j <= 5 then
lcd_rs <= '0'; --command signal
elsif j > 5 then
lcd_rs <= '1'; --data signal
end if;
if j = 22 then --repeated display of data
j := 5;
end if;
end if;
end process;
end Behavioral;
===================================
ซอร์สโค๊ด : UCF
===================================
NET "lcd_rs" LOC = "Y14" ;
NET "lcd_e" LOC = "AB4" ;
NET "lcd_rw" LOC = "W13";

NET "data[0]" LOC = "Y13" ;
NET "data[1]" LOC = "AB18" ;
NET "data[2]" LOC = "AB17" ;
NET "data[3]" LOC = "AB12" ;
NET "data[4]" LOC = "AA12" ;
NET "data[5]" LOC = "Y16" ;
NET "data[6]" LOC = "AB16" ;
NET "data[7]" LOC = "Y15" ;

การวาดธงชาติไทยลงจอภาพ VGA ด้วย VHDL ทำงานบน FPGA

สำหรับการพล็อตสีธงชาติลงบนจอภาพ VGA ทำได้โดยแบ่งส่วนแนวนอนเป็น 6 ส่วน และกำหนดสีให้แต่ละส่วนเป็น แดง, ขาว น้ำเงิน , น้ำเงิน, ขาว และแดง ตามลำดับ


ซอร์สโค๊ด VHDL : ส่วนการระบายสีแสดงได้ดังนี้
if vcounter < 80 then
b <= "0000";
r <= "1111";
g <= "0000";
elsif vcounter < 160 then
r <= "1111";
g <= "1111";
b <= "1111";
elsif vcounter < 240 then
r <= "0000";
g <= "0000";
b <= "1111";
elsif vcounter < 320 then
r <= "0000";
g <= "0000";
b <= "1111";
elsif vcounter < 400 then
r <= "1111";
g <= "1111";
b <= "1111";
elsif vcounter < 480 then
r <= "1111";
g <= "0000";
b <= "0000";
end if;

การเขียน VHDL ไฟกระพริบและแอนเกต ทำงานไปพร้อมกัน !!



การสร้างวงจรไฟกระพริบและให้มีแอนเกตทำงานไปพร้อม ๆ กัน ทำได้โดย
ประกาศส่วน Entity ให้มี a,b เป็น input และ q เป็น output
ในขณะที่ process ให้เพิ่ม อาร์กิวเมนต์ a และ b เข้าไปด้วยเป็น input
ภายใน process body กำหนดผลลัพธ์แอนเกตด้วย q<=a and b;


กำหนด Constraints 


ตำแหน่ง LED และ SLIDE SWITCH !!


สรุป
หัวข้อนี้เป็นการทำวงจรไฟกระพริบ โดยให้ Led สลับไปมาที่ตำแหน่ง LED0 (R20) ในขณะที่ทำงานเป็น AND Gate 2 อินพุต โดยอินพุตเป็น สไลด์สวิตช์ ที่ตำแหน่ง SW0 (V8) และ SW1(U10) ส่วนผลลัพธ์ของ AND Gate คือ LED7 (W21) 

เมื่อฮาร์ดแวร์ทำงาน จะแสดงไฟกระพริบที่ LED0 และยังสามารถใช้งาน AND Gate 2 input ในระหว่างที่ไฟกระพริบไปพร้อม ๆ กัน

ส่วนสำคัญของหัวข้อนี้คือ ใน process() ต้องกำหนด input เพิ่มลงไปอีก 2 ตัว คือ a และ b

สัญญาณการเชื่อมต่อของบอร์ด Spartan3AN (UCF Location Constraints)

#=============================
# SLIDE SWITCHES
#=============================
NET "SW<0>" LOC = "V8" | IOSTANDARD = LVCMOS33 ;
NET "SW<1>" LOC = "U10"| IOSTANDARD = LVCMOS33 ;
NET "SW<2>" LOC = "U8" | IOSTANDARD = LVCMOS33 ;
NET "SW<3>" LOC = "T9" | IOSTANDARD = LVCMOS33 ;

#=============================
# Bush Button Switches
#=============================
NET "BTN_EAST" LOC = "T16" | IOSTANDARD = LVCMOS33 | PULLDOWN ;
NET "BTN_NORTH" LOC = "T14" | IOSTANDARD = LVCMOS33 | PULLDOWN ;
NET "BTN_SOUTH" LOC = "T15" | IOSTANDARD = LVCMOS33 | PULLDOWN ;
NET "BTN_WEST" LOC = "U15" | IOSTANDARD = LVCMOS33 | PULLDOWN ;

#=============================
# Rotary Push-Button Switch
#=============================
NET "ROT_A" LOC = "T13" | IOSTANDARD = LVCMOS33 | PULLUP ;
NET "ROT_B" LOC = "R14" | IOSTANDARD = LVCMOS33 | PULLUP ;
NET "ROT_CENTER" LOC = "R13" | IOSTANDARD = LVCMOS33 | PULLDOWN ;

#=============================
# LEDs
#=============================
NET "LED<7>" LOC = "W21" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "LED<6>" LOC = "Y22" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "LED<5>" LOC = "V20" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "LED<4>" LOC = "V19" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "LED<3>" LOC = "U19" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "LED<2>" LOC = "U20" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "LED<1>" LOC = "T19" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "LED<0>" LOC = "R20" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;

#=============================
# CLOCK
#=============================
NET "CLK_50MHZ" LOC = "E12"| IOSTANDARD = LVCMOS33 ; -- 50MHz
NET "CLK_AUX" LOC = "V12"| IOSTANDARD = LVCMOS33 ; -- 133MHz
NET "CLK_SMA" LOC = "U12"| IOSTANDARD = LVCMOS33 ;

#=============================
# LCD
#=============================
NET "LCD_E" LOC = "AB4" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_RS" LOC = "Y14" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_RW" LOC = "W13" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<7>" LOC = "Y15" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<6>" LOC = "AB16" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<5>" LOC = "Y16" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<4>" LOC = "AA12" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<3>" LOC = "AB12" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<2>" LOC = "AB17" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<1>" LOC = "AB18" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<0>" LOC = "Y13" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;

#=============================
# VGA
#=============================
NET "VGA_R<3>" LOC = "C8" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "VGA_R<2>" LOC = "B8" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "VGA_R<1>" LOC = "B3" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "VGA_R<0>" LOC = "A3" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "VGA_G<3>" LOC = "D6" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "VGA_G<2>" LOC = "C6" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "VGA_G<1>" LOC = "D5" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "VGA_G<0>" LOC = "C5" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "VGA_B<3>" LOC = "C9" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "VGA_B<2>" LOC = "B9" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "VGA_B<1>" LOC = "D7" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "VGA_B<0>" LOC = "C7" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "VGA_HSYNC" LOC = "C11" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "VGA_VSYNC" LOC = "B11" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;

#=============================
# RS-232 I/II
#=============================
NET "RS232_DTE_RXD" LOC = "F16" | IOSTANDARD = LVCMOS33 ;
NET "RS232_DTE_TXD" LOC = "E15" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;

RS-232 II/II
NET "RS232_DCE_RXD" LOC = "E16" | IOSTANDARD = LVCMOS33 ;
NET "RS232_DCE_TXD" LOC = "F15" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW 

#=============================
#PS2-Ports
#=============================
# Primary connection
NET "PS2_CLK1" LOC = "W12" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "PS2_DATA1" LOC = "V11" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
# Secondary connection (requires Y-splitter cable)
NET "PS2_CLK2" LOC = "U11" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "PS2_DATA2" LOC = "Y12" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;

#=============================
# Pre-Amplifier (AMP)
#=============================
NET "SPI_MOSI" LOC = "AB14"| IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "AMP_CS" LOC = "W6" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "SPI_SCK" LOC = "AA20"| IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "AMP_SHDN" LOC = "W15" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "AMP_DOUT" LOC = "T7" | IOSTANDARD = LVCMOS33 ;

#=============================
# Analog-to-Digital Converter (ADC)
#=============================
NET "AD_CONV" LOC = "Y6" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "SPI_SCK" LOC = "AA20" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "AD_DOUT" LOC = "D16" | IOSTANDARD = LVCMOS33 ;

#=============================
# Digital-to-Analog Converter (DAC)
#=============================
NET "SPI_MOSI" LOC = "AB14" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "SPI_SCK" LOC = "AA20" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "DAC_CS" LOC = "W7" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "DAC_CLR" LOC = "AB13" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "DAC_OUT" LOC = "V7" | IOSTANDARD = LVCMOS33 ;

#=============================
# Parallel NOR Flash PROM
#=============================
NET "NF_A<24>" LOC = "A11" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<23>" LOC = "N11" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<22>" LOC = "V12" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<21>" LOC = "C21" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<20>" LOC = "C22" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<19>" LOC = "F21" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<18>" LOC = "F22" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<17>" LOC = "H20" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<16>" LOC = "H21" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<15>" LOC = "G22" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<14>" LOC = "H22" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<13>" LOC = "J20" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<12>" LOC = "J21" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<11>" LOC = "J22" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<10>" LOC = "K22" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<9>" LOC = "N17" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<8>" LOC = "N18" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<7>" LOC = "N19" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<6>" LOC = "N20" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<5>" LOC = "N21" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<4>" LOC = "N22" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<3>" LOC = "P18" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<2>" LOC = "R19" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<1>" LOC = "T18" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_A<0>" LOC = "T17" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;

#=============================
# FLASH DATA I/O Pins
#=============================
NET "NF_D<14>" LOC = "R21" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_D<13>" LOC = "T22" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_D<12>" LOC = "U22" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_D<11>" LOC = "U21" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_D<10>" LOC = "V22" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_D<9>" LOC = "W22" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_D<8>" LOC = "T20" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_D<7>" LOC = "Y9" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_D<6>" LOC = "AB9" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_D<5>" LOC = "Y11" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_D<4>" LOC = "AB11" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_D<3>" LOC = "U13" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_D<2>" LOC = "AA17" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_D<1>" LOC = "Y17" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "SPI_MISO" LOC = "AB20" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;

#=============================
# Flash Control Pins
#=============================
NET "NF_BYTE" LOC = "Y21" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_CE" LOC = "W20" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_OE" LOC = "W19" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_RP" LOC = "R22" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_STS" LOC = "P22" | IOSTANDARD = LVCMOS33 ;
NET "NF_WE" LOC = "AA22" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "NF_WP" LOC = "E14" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;

#=============================
# SPI serial Flash PROM
#=============================
# some connections shared with SPI Flash, DAC, ADC, and AMP
NET "SPI_MISO" LOC = "AB20" | IOSTANDARD = LVCMOS33 ;
NET "SPI_MOSI" LOC = "AB14" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "SPI_SCK" LOC = "AA20" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "SPI_SS_B" LOC = "Y4" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "ALT_SS_B" LOC = "Y5" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
# write-protect and reset controls for Atmel AT45DB161D PROM
NET "DATAFLASH_WP" LOC = "C14" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "DATAFLASH_RST" LOC = "C15" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
# write-protect control for ST M25P16 PROM
NET "ST_SPI_WP" LOC = "C13" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;

#=============================
# FPGA-to-DDR2 SDRAM Connections 
#=============================
NET "SD_A<15>" LOC = "W3" | IOSTANDARD = SSTL18_II ;
NET "SD_A<14>" LOC = "V4" | IOSTANDARD = SSTL18_II ;
NET "SD_A<13>" LOC = "V3" | IOSTANDARD = SSTL18_II ;
NET "SD_A<12>" LOC = "Y2" | IOSTANDARD = SSTL18_II ;
NET "SD_A<11>" LOC = "V1" | IOSTANDARD = SSTL18_II ;
NET "SD_A<10>" LOC = "T3" | IOSTANDARD = SSTL18_II ;
NET "SD_A<9>" LOC = "W2" | IOSTANDARD = SSTL18_II ;
NET "SD_A<8>" LOC = "W1" | IOSTANDARD = SSTL18_II ;
NET "SD_A<7>" LOC = "Y1" | IOSTANDARD = SSTL18_II ;
NET "SD_A<6>" LOC = "U1" | IOSTANDARD = SSTL18_II ;
NET "SD_A<5>" LOC = "U4" | IOSTANDARD = SSTL18_II ;
NET "SD_A<4>" LOC = "U2" | IOSTANDARD = SSTL18_II ;
NET "SD_A<3>" LOC = "U3" | IOSTANDARD = SSTL18_II ;
NET "SD_A<2>" LOC = "R1" | IOSTANDARD = SSTL18_II ;
NET "SD_A<1>" LOC = "T4" | IOSTANDARD = SSTL18_II ;
NET "SD_A<0>" LOC = "R2" | IOSTANDARD = SSTL18_II ;

#=============================
# DDR2 SDRAM Data I/O Pins
#=============================
NET "SD_DQ<15>" LOC = "F3" | IOSTANDARD = SSTL18_II ;
NET "SD_DQ<14>" LOC = "G3" | IOSTANDARD = SSTL18_II ;
NET "SD_DQ<13>" LOC = "F1" | IOSTANDARD = SSTL18_II ;
NET "SD_DQ<12>" LOC = "H5" | IOSTANDARD = SSTL18_II ;
NET "SD_DQ<11>" LOC = "H6" | IOSTANDARD = SSTL18_II ;
NET "SD_DQ<10>" LOC = "G1" | IOSTANDARD = SSTL18_II ;
NET "SD_DQ<9>" LOC = "G4" | IOSTANDARD = SSTL18_II ;
NET "SD_DQ<8>" LOC = "F2" | IOSTANDARD = SSTL18_II ;
NET "SD_DQ<7>" LOC = "H2" | IOSTANDARD = SSTL18_II ;
NET "SD_DQ<6>" LOC = "K4" | IOSTANDARD = SSTL18_II ;
NET "SD_DQ<5>" LOC = "L1" | IOSTANDARD = SSTL18_II ;
NET "SD_DQ<4>" LOC = "L5" | IOSTANDARD = SSTL18_II ;
NET "SD_DQ<3>" LOC = "L3" | IOSTANDARD = SSTL18_II ;
NET "SD_DQ<2>" LOC = "K1" | IOSTANDARD = SSTL18_II ;
NET "SD_DQ<1>" LOC = "K5" | IOSTANDARD = SSTL18_II ;
NET "SD_DQ<0>" LOC = "H1" | IOSTANDARD = SSTL18_II ; 

#=============================
# DDR2 SDRAM Control Pins
#=============================
NET "SD_BA<2>" LOC = "P5" | IOSTANDARD = SSTL18_II ;
NET "SD_BA<1>" LOC = "R3" | IOSTANDARD = SSTL18_II ;
NET "SD_BA<0>" LOC = "P3" | IOSTANDARD = SSTL18_II ;
NET "SD_RAS" LOC = "M3" | IOSTANDARD = SSTL18_II ;
NET "SD_CAS" LOC = "M4" | IOSTANDARD = SSTL18_II ;
NET "SD_WE" LOC = "N4" | IOSTANDARD = SSTL18_II ;
NET "SD_CK_N" LOC = "M2" | IOSTANDARD = SSTL18_II ;
NET "SD_CK_P" LOC = "M1" | IOSTANDARD = SSTL18_II ;
NET "SD_CKE" LOC = "N3" | IOSTANDARD = SSTL18_II ;
NET "SD_CS" LOC = "M5" | IOSTANDARD = SSTL18_II ;
NET "SD_UDM" LOC = "E3" | IOSTANDARD = SSTL18_II ;
NET "SD_UDQS_N" LOC = "J5" | IOSTANDARD = SSTL18_II ;
NET "SD_UDQS_P" LOC = "K6" | IOSTANDARD = SSTL18_II ;
NET "SD_LDM" LOC = "J3" | IOSTANDARD = SSTL18_II ;
NET "SD_LDQS_N" LOC = "K2" | IOSTANDARD = SSTL18_II ;
NET "SD_LDQS_P" LOC = "K3" | IOSTANDARD = SSTL18_II ;
NET "SD_ODT" LOC = "P1" | IOSTANDARD = SSTL18_II ;
NET "SD_LOOP_IN" LOC = "H4" | IOSTANDARD = SSTL18_II ;
NET "SD_LOOP_OUT" LOC = "H3" | IOSTANDARD = SSTL18_II ; 

#=============================
# 10/100 Ethernet PHY Inputs
#=============================
NET "E_COL" LOC = "G12" | IOSTANDARD = LVCMOS33 | PULLDOWN ;
NET "E_CRS" LOC = "H12" | IOSTANDARD = LVCMOS33 | PULLDOWN ;
NET "E_MDC" LOC = "D10" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8;
NET "E_MDIO" LOC = "E10" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8;
NET "E_NRST" LOC = "D15" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8;
NET "E_RX_CLK" LOC = "C12" | IOSTANDARD = LVCMOS33 ;
NET "E_RX_DV" LOC = "H10" | IOSTANDARD = LVCMOS33 ;
NET "E_RXD<0>" LOC = "G7" | IOSTANDARD = LVCMOS33 | PULLUP ;
NET "E_RXD<1>" LOC = "G8" | IOSTANDARD = LVCMOS33 | PULLUP ;
NET "E_RXD<2>" LOC = "G9" | IOSTANDARD = LVCMOS33 | PULLUP ;
NET "E_RXD<3>" LOC = "H9" | IOSTANDARD = LVCMOS33 | PULLUP ;
NET "E_RXD<4>" LOC = "G10" | IOSTANDARD = LVCMOS33 ;
NET "E_TX_CLK" LOC = "E11" | IOSTANDARD = LVCMOS33 ;
NET "E_TX_EN" LOC = "D8" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8;
NET "E_TXD<0>" LOC = "F8" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8;
NET "E_TXD<1>" LOC = "E7" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8;
NET "E_TXD<2>" LOC = "E6" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8;
NET "E_TXD<3>" LOC = "F7" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8;
NET "E_TXD<4>" LOC = "B2" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 | PULLUP;

#=============================
#100-Pin Hirose FX2 Connector
#=============================
# ==== FX2 Connector (FX2) ====
NET "FX2_CLKIN" LOC = "M22" | IOSTANDARD = LVCMOS33 ;
NET "FX2_CLKIO" LOC = "L21" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_CLKOUT" LOC = "L22" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<1>" LOC = "A13" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<2>" LOC = "B13" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<3>" LOC = "A14" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<4>" LOC = "B15" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<5>" LOC = "A15" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<6>" LOC = "A16" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<7>" LOC = "A17" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<8>" LOC = "B17" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<9>" LOC = "A18" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<10>" LOC = "C18" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<11>" LOC = "A19" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<12>" LOC = "B19" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<13>" LOC = "A20" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<14>" LOC = "B20" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<15>" LOC = "C19" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<16>" LOC = "D19" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<17>" LOC = "D18" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<18>" LOC = "E17" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<19>" LOC = "D20" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<20>" LOC = "D21" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<21>" LOC = "D22" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<22>" LOC = "E22" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<23>" LOC = "F18" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<24>" LOC = "F19" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<25>" LOC = "F20" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<26>" LOC = "E20" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<27>" LOC = "G20" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<28>" LOC = "G19" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<29>" LOC = "H19" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<30>" LOC = "J18" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<31>" LOC = "K18" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<32>" LOC = "K17" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<33>" LOC = "K19" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<34>" LOC = "K20" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<35>" LOC = "L19" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<36>" LOC = "L18" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<37>" LOC = "M20" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<38>" LOC = "M18" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<39>" LOC = "L20" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "FX2_IO<40>" LOC = "P20" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;

#=============================
# Receive and Transmit Headers
#=============================
# High-Speed LVDS “Receive” Connector (RX)
NET "RX_CLK_N" LOC = "A11" | IOSTANDARD = LVDS_33 ;
NET "RX_CLK_P" LOC = "A12" | IOSTANDARD = LVDS_33 ;
NET "RX_N<0>" LOC = "B4" | IOSTANDARD = LVDS_33 ;
NET "RX_P<0>" LOC = "A4" | IOSTANDARD = LVDS_33 ;
NET "RX_N<1>" LOC = "A5" | IOSTANDARD = LVDS_33 ;
NET "RX_P<1>" LOC = "B6" | IOSTANDARD = LVDS_33 ;
NET "RX_N<2>" LOC = "A6" | IOSTANDARD = LVDS_33 ;
NET "RX_P<2>" LOC = "A7" | IOSTANDARD = LVDS_33 ;
NET "RX_N<3>" LOC = "A8" | IOSTANDARD = LVDS_33 ;
NET "RX_P<3>" LOC = "A9" | IOSTANDARD = LVDS_33 ;
NET "RX_N<4>" LOC = "C10" | IOSTANDARD = LVDS_33 ;
NET "RX_P<4>" LOC = "A10" | IOSTANDARD = LVDS_33 ;
# High-Speed LVDS “Transmit” Connector (TX)
NET "TX_CLK_N" LOC = "AB10" | IOSTANDARD = LVDS_33 ;
NET "TX_CLK_P" LOC = "AA10" | IOSTANDARD = LVDS_33 ;
NET "TX_N<0>" LOC = "AA3" | IOSTANDARD = LVDS_33 ;
NET "TX_P<0>" LOC = "AB2" | IOSTANDARD = LVDS_33 ;
NET "TX_N<1>" LOC = "AA4" | IOSTANDARD = LVDS_33 ;
NET "TX_P<1>" LOC = "AB3" | IOSTANDARD = LVDS_33 ;
NET "TX_N<2>" LOC = "AB6" | IOSTANDARD = LVDS_33 ;
NET "TX_P<2>" LOC = "AA6" | IOSTANDARD = LVDS_33 ;
NET "TX_N<3>" LOC = "AB7" | IOSTANDARD = LVDS_33 ;
NET "TX_P<3>" LOC = "Y7" | IOSTANDARD = LVDS_33 ;
NET "TX_N<4>" LOC = "AB8" | IOSTANDARD = LVDS_33 ;
NET "TX_P<4>" LOC = "AA8" | IOSTANDARD = LVDS_33 ;

#=============================
# Six-Pin Accessory Header (J18,J19,J20)
#=============================
# ==== 6-pin header J18 ====
NET "J18_IO<1>" LOC = "AA21" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "J18_IO<2>" LOC = "AB21" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "J18_IO<3>" LOC = "AA19" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "J18_IO<4>" LOC = "AB19" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
# ==== 6-pin header J19 ====
# These four connections go to through-hole pads, not to a connector.
NET "J19_IO<1>" LOC = "Y18" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "J19_IO<2>" LOC = "W18" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "J19_IO<3>" LOC = "V17" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "J19_IO<4>" LOC = "W17" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
# ==== 6-pin header J20 ====
NET "J20_IO<1>" LOC = "V14" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "J20_IO<2>" LOC = "V15" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "J20_IO<3>" LOC = "W16" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "J20_IO<4>" LOC = "V16" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;

#=============================
# AUDIO Connector
#=============================
# Controls VCCAUX supply rail (IC19)
NET "AUD_L" LOC = "Y10" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "AUD_R" LOC = "V10" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;

#=============================
# Regulator I2C Control Signals
#=============================
# Controls VCCAUX supply rail (IC19)
NET "REG1_SCL" LOC = "E13" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "REG1_SDA" LOC = "D13" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
# Control D/A Converter reference voltage for Channels C and D (IC18)
NET "REG2_SCL" LOC = "D11" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "REG2_SDA" LOC = "F13" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;

สรุป

หัวข้อนี้เป็นการศึกษาภาษา VHDL บนบอร์ด Xilinx Spartan 3AN ซึ่งใช้ชิป FPGA เบอร์ SC700AN ทำให้มีความรู้และเข้าใจการออกแบบพฤติกรรมของไอซีชิปด้วยภาษา VHDL ได้ในระดับหนึ่ง หวังว่าจะเป็นประโยชน์ต่อท่านไม่มากก็น้อย
การเรียนรู้และใช้งาน FPGA ด้วยภาษา VHDL