เจาะลึก RFSoC: สร้างสัญญาณคลื่นวิทยุระดับกิกะเฮิรตซ์ด้วย ZCU111

ข้อดีอย่างหนึ่งของบอร์ด FPGA คือความเป็น "คู่ขนาน (Parallel)" อย่างแท้จริง ทำให้มันกลายเป็นฮีโร่ในงานสายเรดาร์ (RADAR), โทรคมนาคม, วิทยุ, การถ่ายภาพทางการแพทย์, คอมพิวเตอร์ควอนตัม และสงครามอิเล็กทรอนิกส์ (Electronic Warfare)

แต่งานโหดๆ พวกนี้ต้องพึ่งพาชิปแปลงสัญญาณความเร็วสูงมากๆ อย่าง ADC (อนาล็อกเป็นดิจิทัล) และ DAC (ดิจิทัลเป็นอนาล็อก) ระดับ "กิกะแซมเปิลต่อวินาที (GSPS)" ทาง AMD เลยแก้ปัญหานี้ด้วยการเปิดตัว RFSoC ในปี 2019 โดยจับเอา ADC/DAC ความเร็วแสงมายัดรวมไว้ในซิลิคอนเดียวกับฝั่ง Programmable logic ซะเลย! โปรเจกต์นี้เราจะมาเจาะลึกโครงสร้างและลองสร้างสัญญาณเสียง (Tone) ง่ายๆ ด้วยบอร์ดพัฒนารุ่น ZCU111 (RFSoC GEN1) กันครับ

RFSoC ZCU111 Overview

สถาปัตยกรรมภายใน (Architecture)

RFSoC คือชิปที่ทำงานแบบผสมผสาน (Heterogeneous SoC) โครงสร้างฝั่งประมวลผลแทบจะเหมือนกับรุ่น MPSoC ทุกประการ (แค่ไม่มีชิปการ์ดจอ Mali GPU) ส่วนฝั่ง Logic จะอิงพื้นฐานจาก UltraScale+ fabric

จุดที่แตกต่างคือ RFSoC จะมี "RF Data Convertors" ฝังอยู่ข้างใน ซึ่งภายในนั้นมีทั้ง ADC และ DAC แบบ GSPS เชื่อมต่อกับฝั่ง User Logic ผ่านพอร์ต AXI Streams โดยภายใน RF DAC จะมีฟีเจอร์เด็ดๆ อย่าง:

  • รองรับเอาต์พุตแบบ Real หรือ I/Q
  • ระบบ FIFO Gear Box สำหรับแมตช์ความเร็ว
  • I/Q RF Mixer และตัวคูณเพิ่มความละเอียด (Interpolation)
  • ระบบกระจายสัญญาณนาฬิกา RF (RF Clock distribution)

ระบบทั้งหมดจะถูกจัดเรียงเป็น "แผ่น (Tiles)" ซึ่งแต่ละ Tile จะมีสัญญาณนาฬิกา (RF Reference Clock) ของตัวเองบนพินแยกต่างหาก เพื่อให้สามารถเลือกปรับความถี่อ้างอิงได้แบบไดนามิก

การออกแบบฮาร์ดแวร์ผ่าน Vivado

เราจะใช้บอร์ด ZCU111 ร่วมกับแผงวงจร XM500 RF break out board เพื่อให้มีพอร์ต SMA สำหรับดึงสัญญาณออก โดยเริ่มจากการเปิดโปรแกรม Vivado 2025.2 สร้างโปรเจกต์ใหม่และเลือก Target ไปที่บอร์ด ZCU111

จากนั้นให้เพิ่มบล็อก Zynq UltraScale+ MPSoC และ RF Data Convertor ลงใน Block Diagram แล้วจัดการรัน Block Automation เพื่อเชื่อมต่อสัญญาณนาฬิกาต่างๆ เราจะตั้งค่า DAC One บน Tile 229 ให้เป็นแบบ Real Output, ตั้ง Interpolation เป็น 8x และตั้ง Sampling rate ที่ 2.456 GSPS (โดยมี Clock อ้างอิงที่ 122.8 MHz)

Vivado Block Diagram
คลิกเพื่อดูรูปขั้นตอนการตั้งค่า Vivado ทั้งหมด (View More)
Vivado 1
Vivado 2
Vivado 3
Vivado 4
Vivado 5
Vivado 6
Vivado 7
Vivado 8
Vivado 9
Vivado 10

การเขียนซอฟต์แวร์ควบคุม (Software Development)

ในส่วนของ Software ไม่ได้มีความซับซ้อนมากนัก โค้ดหลักๆ จะใช้สำหรับมอนิเตอร์ดูสถานะของ PLL (Phase-Locked Loops) และ RF DAC ระบบส่งสัญญาณ RF จะเริ่มทำงานทันทีที่โปรแกรมบอร์ดสำเร็จและมีสัญญาณนาฬิกา RF ป้อนเข้ามาครบถ้วน

คลิกเพื่อดูและคัดลอกซอร์สโค้ด C (View More)
#include "xil_printf.h"
#include "xil_io.h"
#include "sleep.h"
#include "xil_cache.h"
#include "xrfdc.h"
#include <metal/sys.h>
#include <metal/io.h>

#define RFDC_BASEADDR      (0xB0000000U)
#define RFDC_REGION_SIZE   (0x40000U)
#define DAC_TILE_ID        1
#define DAC_BLOCK_ID       0

/* Units are MHz */
#define DAC_REFCLK_MHZ     (250.0)     /* e.g. 250.0, 245.76, etc */
#define DAC_FS_MHZ         (2500.0)    /* e.g. 2500.0 for 2.5 GSPS */

static inline u32 Peek32(u32 a) { return Xil_In32(a); }

static int MetalInitCompat(void) {
#ifdef METAL_INIT_DEFAULTS
  struct metal_init_params mip = METAL_INIT_DEFAULTS;
  return metal_init(&mip);
#else
  return metal_init(NULL);
#endif
}

static void MetalIoInitCompat(struct metal_io_region *io, void *virt, metal_phys_addr_t *physmap, size_t size) {
  metal_io_init(io, virt, physmap, size, (unsigned int)(-1), 0, NULL);
}

// ... [ฟังก์ชันอื่นๆ ถูกเรียกใช้งานภายใน Main] ...

int main(void) {
  XRFdc RFdcInst;
  XRFdc_Config *CfgPtr;
  int mst;
  u32 Status;

  xil_printf("\r\n--- RFDC DAC bring-up / full dump ---\r\n");
  Xil_DCacheDisable();
  Xil_ICacheDisable();
  
  CfgPtr = XRFdc_LookupConfig((metal_phys_addr_t)RFDC_BASEADDR);
  if (!CfgPtr) {
    xil_printf("ERROR: XRFdc_LookupConfig returned NULL\r\n");
    while (1) {}
  }
  
  // Initialization process...
  mst = MetalInitCompat();
  if (mst != 0) {
    xil_printf("ERROR: metal_init failed\r\n");
    while (1) {}
  }
  
  xil_printf("\r\nStarting DAC tile %d...\r\n", DAC_TILE_ID);
  Status = XRFdc_StartUp(&RFdcInst, XRFDC_DAC_TILE, DAC_TILE_ID);
  xil_printf("StartUp(tile %d) = %lu\r\n", DAC_TILE_ID, (unsigned long)Status);
  
  xil_printf("\r\nDone.\r\n");
  while (1) { usleep(1000000); }
}

การทดสอบและดูผลลัพธ์ (Testing)

ในการทดสอบเราจะใช้เครื่อง Spectrum Analyser (ในโปรเจกต์ใช้ Tiny SA Ultra) ต่อสายเข้าที่พอร์ต SMA ของ DAC 229 Channel 0 บนบอร์ดแยก XM500

ก่อนจะเห็นผลลัพธ์ เราต้องใช้บอร์ด ZCU111 Board User Interface เพื่อตั้งค่าสัญญาณนาฬิกา RF Clocks ไปที่ 122.8 MHz เสียก่อน เมื่อโปรแกรมเสร็จแล้ว ไฟ LED สถานะ RF Clock บนบอร์ดจะสว่างขึ้น และคุณจะเห็นคลื่นสัญญาณโผล่ขึ้นมาบนหน้าจอ Spectrum Analyser (ประมาณ 75MHz) ครับ

คลิกเพื่อดูรูปภาพผลการทดสอบ (View More)
Spectrum Analyzer Setup
UI Config
UI Config Success
LED Off
LED On
Spectrum Analyzer Result

สรุป: นี่เป็นการแนะนำให้รู้จักพลังของบอร์ดตระกูล RFSoC เบื้องต้นเกี่ยวกับการสร้างคลื่นเสียง (Tones) ด้วย DAC ไว้รอบหน้าเราจะมาเจาะลึกฝั่งของ ADC และฟีเจอร์ระดับสูงอื่นๆ กันต่อครับ!


คำเตือน: เนื้อหานี้เป็นการสรุปและเรียบเรียงจากบทความต้นฉบับภาษาอังกฤษ ข้อมูลฉบับภาษาไทยอาจมีความคลาดเคลื่อนบางประการจากการตีความหรือย่อเนื้อหา

อ้างอิงและเรียบเรียงโดย: Globalbyteshop Blog

แหล่งที่มาต้นฉบับ:
- Understanding RFSoC by Adam Taylor (Hackster.io)

แท็ก


Blog posts

© 2026 บริษัท โกลบอลโทรนิค อินเตอร์เทรด จํากัด, ขับเคลื่อนโดย Shopify

    • PayPal

    เข้าสู่ระบบ

    ลืมรหัสผ่านใช่ไหม?

    ยังไม่มีบัญชีใช่ไหม?
    สร้างบัญชี