การ Debug GPIO IP นั้นสามารถทำได้หลายวิธี เช่น การใช้ Testbench เพื่อ Simulation การใช้ System Console หรือ การใช้ Signal Tap อย่างไรก็ตาม ในบทความนี้จะกล่าวถึงอีกวิธีหนึ่งที่อาจเป็นประโยชน์ นั่นคือ การ Debug GPIO IP ผ่าน U-Boot
โดย U-Boot เป็น Bootloader ที่ใช้ในการบูตระบบปฏิบัติการ เช่น Linux บน Hardware นอกจากนี้ U-Boot ยังสามารถใช้ในการเข้าถึง memory ต่างๆ ได้ โดยในบทความนี้ก็จะใช้ U-Boot ในการเข้าถึง memory เพื่อ Debug GPIO IP ที่สร้างขึ้น
# ในตัวอย่างนี้จะแสดงขั้นตอนบนบอร์ด Terasic SoCKit ( Cyclone V SoC 5CSXFC6D6F31NES Device ) ซึ่งได้ทำการโหลด image file ( ประกอบด้วย U-boot, Device Tree Blob, Linux Kernel, Linux Root File system ) ลงบน SD card และ ตั้ง Config Mode ให้ HPS บูตจาก SD card ไว้เรียบร้อยแล้ว โดยจะไม่ได้แสดงวิธีการในบทความนี้ )
ขั้นตอนการ Debug GPIO IP ผ่าน U-Boot
- สร้าง Project ขึ้นมาบน Quartus

- เปิด Tools 🡪 Platform Designer

- Add module ต่างๆ เข้ามาในระบบ และเชื่อมต่อกัน ดังรูป ( หาก Address มีการซ้อนทับกันสามารถกด System 🡪 Assign Base Addresses เพื่อให้ระบบกำหนด Address ให้ใหม่ )

- Double-click ที่ hps_0 หลังจากนั้นจะปรากฏแท็บ Parameters ที่ใช้ตั้งค่า Arria V/Cyclone V Hard Processor System โดยตั้งค่าตาม Project ตัวอย่างของ Terasic ทั้งหมด ซึ่ง download ได้จาก SoCKit_v.2.0.1_SystemCD.zip

- สำหรับวิธีการเพิ่ม GPIO IP ที่สร้างขึ้นเข้ามาในระบบ สามารถดูวิธีการได้ในบทความ “Custom GPIO IP” ดังนั้นในที่นี้จึงขอไม่กล่าวถึง
- เมื่อออกแบบระบบเสร็จแล้วตรวจสอบแท็บ Messages ด้านล่างว่าไม่มี Errors จากนั้น Save ให้เรียบร้อย แล้วกด Generate HDL

- เลือก Create HDL design files for synthesis ระหว่าง Verilog หรือ VHDL จากนั้นกด Generate

- เมื่อ Generate เสร็จสามารถกด Finish เพื่อปิด Platform Designer ได้

- กลับมาที่ Quartus และเปิด Altera In-System Sources & Probes ในแท็บ IP Catalog ทางขวา

- ในหน้าต่าง New IP Variation ให้ตั้ง Entity name จากนั้นกด OK

- ในหน้าต่าง IP Parameter Editor ให้ตั้งค่าดังนี้

- Save ให้เรียบร้อย จากนั้น Generate HDL จนเสร็จแล้วกด Finish ในทำนองเดียวกันกับบน Platform Designer

- กลับมายัง Quartus บนแท็บ Project Navigator เลือก Files

- Double-Click ที่ Files จะปรากฏหน้าต่าง Settings ขึ้นมา

- กดที่ … เพื่อเพิ่มไฟล์เข้ามาใน Project โดยต้องเพิ่มไฟล์ Top Entity ( PRJ_TOP.vhd ), .qip ที่ได้จาก Platform Designer กับ Altera In-System Sources & Probes และ hps_reset.v กับ altera_edge_detector.v ซึ่งนำมาจาก Project ตัวอย่างที่ Download มาก่อนหน้า เสร็จแล้วกด Apply

- กำหนด Top-Level Entity File โดย click ขวาที่ File นั้น

- Analysis & Synthesis

- กำหนด Pin Assignment ในไฟล์ .qsf โดยดูตัวอย่างจาก soc_system.qsf ใน Project ตัวอย่างที่ Download มาก่อนหน้า

- Compile Design

- ไปที่ File 🡪 Convert Programming Files กำหนด Programming file type เป็น .jic, Configuration device เป็น EPCQ256
Flash Loader กด Add Device เลือก Cyclone V 5CSXFC6D6ES
SOF Data กด Add File เลือกไฟล์ .sof
เสร็จแล้วกด Generate

- เชื่อมต่อบอร์ดกับ computer ผ่าน JTAG จากนั้นเปิด Tools 🡪 Programmer แล้วเลือกไฟล์ .jic โปรแกรมลงบน EPCQ256
( ต้องตั้งค่าให้ FPGA boot จาก EPCQ256 โดยใช้ FPGA Configuration Mode Switch ตามที่ระบุใน User Manual )

- เชื่อมต่อบอร์ดกับ computer ผ่าน UART และเปิด Tera Term ขึ้นมาโดยตั้งค่า port และ speed ให้ถูกต้อง

- Reset HPS เพื่อให้โหลด U-boot ขึ้นมา

- เปิดใช้งาน HPS-FPGA bridges ด้วย command ดังนี้

- สำหรับ address ของ Lightweight FPGA slaves ของ Cyclone V base address จะเริ่มที่ 0xFF200000 และ offset ไปตามค่าที่ระบุใน Platform Designer โดยตัวอย่างนี้มี address ดังนี้

- ใช้ command ‘mw’ ในการเขียนข้อมูลลงบน Registers และ ‘md’ ในการอ่าน

md.l 0xFF200004 1 : อ่าน data ที่ address 0xFF200004 จำนวน 1 ชุด
mw.l 0xFF200004 0xF : เขียน data 0xF เข้าไปที่ address 0xFF200004
md.l 0xFF200004 1 : อ่าน data ที่ address 0xFF200004 จำนวน 1 ชุด
mw.l 0xFF200000 0xF : เขียน data 0xA เข้าไปที่ address 0xFF20000
หวังว่าบทความนี้จะมีประโยชน์ และ ช่วยให้เข้าใจวิธีการ Debug GPIO IP ด้วย U-Boot ไม่มากก็น้อยนะครับ หากมีข้อสงสัย หรือ ข้อเสนอแนะเพิ่มเติมสามารถติดต่อได้ที่ Facebook : Bannawich Horie ขอบคุณครับ