試工程:數(shù)字波形閉環(huán)與回環(huán)驗(yàn)證)
簡介面向FPGA數(shù)字信號(hào)處理學(xué)習(xí)者的DDS與ADDA回環(huán)測(cè)試工程基于Zynq底板與黑金AN108模塊以50MHz時(shí)鐘驅(qū)動(dòng)DDS IP合成正弦波經(jīng)DAC輸出再自環(huán)回ADC由MMCM分頻提供25MHz采樣時(shí)鐘用ILA采集不少于2048個(gè)樣點(diǎn)并配合Matlab做頻譜分析還可通過VIO改頻率字生成1MHz與3MHz信號(hào)驗(yàn)證工程特別提示AN108為34針插頭、1腳須與底板對(duì)齊低通濾波器通帶約0-20MHz。包內(nèi)共613個(gè)文件、約46.11MB以75個(gè)Verilog源文件、25個(gè)VHDL文件、16個(gè)XDC約束、11個(gè)XCI配置及19個(gè)DCP檢查點(diǎn)為主另含DO/SH腳本、CSV采樣數(shù)據(jù)、ILA與BIT文件覆蓋源碼、約束到驗(yàn)證數(shù)據(jù)的完整鏈路。已有321人學(xué)習(xí)讀者可獲得可復(fù)現(xiàn)的工程與約束、現(xiàn)成的采樣數(shù)據(jù)與Matlab分析腳本并借助腳本快速搭建環(huán)境、排查插裝與時(shí)鐘配置問題。1. DDS ADDA 測(cè)試工程文件一塊板子上的數(shù)字波形閉環(huán)調(diào)一塊新打的 ADDA 板最怕的是 DAC 有輸出、ADC 也能采但兩邊對(duì)不上頻率差一點(diǎn)、波形削頂、頻譜上多出一排諧波。這份 DDS ADDA 測(cè)試工程文件就是把這個(gè)閉環(huán)拆開FPGA 內(nèi)部用 DDS 產(chǎn)生正弦、三角或方波經(jīng) DAC 送出再被 ADC 采回最后通過在線抓數(shù)或串口把數(shù)據(jù)取出來做 FFT。它適合剛拿到 ADDA 板、需要快速驗(yàn)證收發(fā)鏈路的人也適合想把 DDS 頻率控制字、LUT 量化、時(shí)鐘域這些參數(shù)一次講清的人。工程文件不是“點(diǎn)開就能跑”的演示里面每個(gè)參數(shù)都會(huì)影響回環(huán)結(jié)果下面按鏈路拆。2. 拆開工程看鏈路DDS 相位累加器、LUT 與 ADDA 回環(huán)工程文件拿到手先別急著編譯。DDS ADDA 測(cè)試的鏈路一般分成三段數(shù)字側(cè)由相位累加器和波形 LUT 產(chǎn)生采樣點(diǎn)接口側(cè)把并行或串行數(shù)據(jù)送到 DAC模擬側(cè)再通過回環(huán)進(jìn)入 ADC最后在 FPGA 內(nèi)部被采集和緩存。三段里任何一段的位寬、時(shí)鐘或數(shù)據(jù)編碼對(duì)不上現(xiàn)象都可能表現(xiàn)成“波形不對(duì)”但根因不在同一個(gè)地方。先把這個(gè)結(jié)構(gòu)看清楚后面改參數(shù)才不會(huì)靠猜。2.1 DDS 核心參數(shù)相位累加器位寬、頻率控制字與 LUT 深度DDS 的核心是一個(gè)相位累加器加一張波形表。每個(gè)系統(tǒng)時(shí)鐘相位累加器加上頻率控制字累加器的高位作為 LUT 地址LUT 輸出對(duì)應(yīng)幅度的采樣點(diǎn)。輸出頻率由三個(gè)量決定系統(tǒng)時(shí)鐘f_clk、相位累加器位寬PHASE_W、頻率控制字freq_word。三者關(guān)系是f_out freq_word * f_clk / 2^PHASE_W反過來配置時(shí)用freq_word round(f_out * 2^PHASE_W / f_clk)。這個(gè)公式看起來簡單實(shí)際踩坑最多的是把 LUT 地址位寬當(dāng)成累加器位寬來算結(jié)果頻率差一個(gè)整數(shù)倍。一個(gè)最小化的 DDS 核心通常長這樣module dds_core #( parameter PHASE_W 32, // 相位累加器位寬決定頻率分辨率 parameter LUT_AW 12, // LUT 地址位寬深度 2^LUT_AW parameter DATA_W 12 // 輸出數(shù)據(jù)位寬和 DAC 位數(shù)對(duì)齊 )( input wire clk, input wire rst_n, input wire [PHASE_W-1:0] freq_word, // 頻率控制字 output reg [DATA_W-1:0] dac_data ); reg [PHASE_W-1:0] phase_acc; wire [LUT_AW-1:0] lut_addr phase_acc[PHASE_W-1 -: LUT_AW]; always (posedge clk or negedge rst_n) begin if (!rst_n) phase_acc {PHASE_W{1b0}}; else phase_acc phase_acc freq_word; // 每個(gè)時(shí)鐘累加一次 end // 實(shí)際工程里用 LUT IP 或 case 表替換 always (posedge clk) begin dac_data sine_lut[lut_addr]; end endmodule這段代碼里PHASE_W決定頻率分辨率LUT_AW決定波形表深度DATA_W要和 DAC 的數(shù)據(jù)位寬對(duì)齊。lut_addr取的是相位累加器的高LUT_AW位也就是把相位圓等分成2^LUT_AW份。這樣做的代價(jià)是相位截?cái)鄷?huì)在頻譜上產(chǎn)生雜散如果回環(huán)測(cè)試?yán)锇l(fā)現(xiàn)底噪偏高先別懷疑 ADC把LUT_AW從 10 加到 12 或 14 再看一次很多時(shí)候雜散會(huì)明顯下去。freq_word的位寬必須和PHASE_W一致綜合工具不會(huì)替你檢查這個(gè)位寬短了會(huì)靜默截?cái)喱F(xiàn)象就是輸出頻率和設(shè)定值對(duì)不上。2.2 ADDA 回環(huán)鏈路DAC 接口、ADC 采樣與時(shí)鐘域DAC 接口常見的有并行總線和串行總線兩類。并行 DAC 一般把dac_data直接掛在數(shù)據(jù)腳上配合 DAC 時(shí)鐘輸出串行 DAC 則要通過 SPI 或類似時(shí)序先配置寄存器再按幀發(fā)送采樣點(diǎn)。ADC 側(cè)同樣有并行和串行之分低速板常用并行 ADC高速板更常見 LVDS 或串行幀。工程文件里如果已經(jīng)把接口時(shí)序?qū)懰老却_認(rèn)你的板子和工程里的接口類型一致別只看引腳數(shù)量對(duì)得上就下載。鏈路環(huán)節(jié)常見接口打開工程先看什么容易翻車的點(diǎn)DDS 到 DAC并行數(shù)據(jù) DAC 時(shí)鐘數(shù)據(jù)位寬、時(shí)鐘極性、建立保持時(shí)間數(shù)據(jù)編碼是偏移二進(jìn)制還是補(bǔ)碼DAC 輸出到 ADC模擬回環(huán)、濾波網(wǎng)絡(luò)是否有重建濾波器、阻抗匹配直接短接導(dǎo)致削頂或自激ADC 到 FPGA并行、LVDS、串行幀采樣時(shí)鐘來源、同步信號(hào)、位對(duì)齊采樣時(shí)鐘和系統(tǒng)時(shí)鐘異步FIFO 讀空采集到上位機(jī)在線抓數(shù)、串口、USB觸發(fā)條件、采樣深度、數(shù)據(jù)格式抓到的不是同一時(shí)間段的數(shù)據(jù)時(shí)鐘域是回環(huán)測(cè)試?yán)镒钊菀妆坏凸赖牟糠?。DDS 一般跑在系統(tǒng)時(shí)鐘域ADC 采樣時(shí)鐘往往來自外部晶振或時(shí)鐘芯片兩者異步。如果工程里直接把 ADC 數(shù)據(jù)打進(jìn)系統(tǒng)時(shí)鐘域的寄存器綜合可能過板子上卻會(huì)隨機(jī)出錯(cuò)。常見做法是加一個(gè)異步 FIFOADC 側(cè)用采樣時(shí)鐘寫系統(tǒng)側(cè)用讀時(shí)鐘讀中間用valid或空滿標(biāo)志控制。抓數(shù)時(shí)先看 FIFO 的empty和overflow這兩個(gè)信號(hào)比波形本身更能說明問題。2.3 工程文件組成與打開方式這份工程文件通常包含頂層源碼、DDS 核心、LUT 初始化文件、引腳和時(shí)序約束、仿真測(cè)試文件以及可能的抓數(shù)腳本。不同平臺(tái)的工程格式不一樣有的直接雙擊工程文件打開有的需要先新建工程再把源碼和約束加進(jìn)去。打開后不要立刻點(diǎn)編譯先做三件事確認(rèn)器件型號(hào)和板卡一致確認(rèn)頂層模塊沒有被別的文件覆蓋確認(rèn)約束文件里的時(shí)鐘引腳和復(fù)位引腳對(duì)得上原理圖。文件或目錄作用打開后先檢查什么頂層源碼連接 DDS、DAC 接口、ADC 采集和通信模塊端口名是否和約束文件一致DDS 核心相位累加、LUT 查表、輸出寄存PHASE_W、LUT_AW、DATA_W是否匹配LUT 初始化文件存放一個(gè)周期的波形采樣點(diǎn)數(shù)據(jù)進(jìn)制、深度、位寬是否和 IP 配置一致約束文件引腳分配、IO 電平、時(shí)鐘周期時(shí)鐘頻率是否和f_clk參數(shù)一致仿真測(cè)試文件行為級(jí)驗(yàn)證 DDS 輸出和接口時(shí)序是否給了freq_word和復(fù)位激勵(lì)抓數(shù)或分析腳本導(dǎo)出 ADC 數(shù)據(jù)、做 FFT 或頻點(diǎn)掃描數(shù)據(jù)格式是有符號(hào)還是無符號(hào)如果工程不是原生格式新建工程時(shí)把源碼、LUT 文件和約束文件一起加入頂層模塊手動(dòng)指定避免工具自動(dòng)把測(cè)試文件當(dāng)成頂層。約束文件里最值得花時(shí)間看的是時(shí)鐘周期約束DDS 的頻率計(jì)算用的是實(shí)際時(shí)鐘頻率約束文件里寫的是理想頻率兩者不一致時(shí)仿真和板級(jí)結(jié)果會(huì)對(duì)不上。先跑一遍行為仿真確認(rèn)dac_data有波形、freq_word改變后周期跟著變?cè)龠M(jìn)綜合實(shí)現(xiàn)這一步能省掉很多下載后的無效調(diào)試。3. 上手復(fù)現(xiàn)從工程導(dǎo)入到板級(jí)回環(huán)的四個(gè)步驟工程導(dǎo)入只是開始真正能讓回環(huán)跑通的是參數(shù)配置、編譯下載和抓數(shù)分析。下面按四個(gè)步驟走每一步都給出可抄的配置或腳本。不要跳步尤其是 LUT 生成和頻率控制字計(jì)算這兩步錯(cuò)了后面看波形只會(huì)越看越亂。3.1 導(dǎo)入工程與檢查器件/約束先確認(rèn)工程里的器件型號(hào)、封裝和速度等級(jí)與手頭板子一致。不一致時(shí)綜合可能報(bào)錯(cuò)也可能勉強(qiáng)通過但引腳映射錯(cuò)位。接著看約束文件系統(tǒng)時(shí)鐘引腳是不是板上的晶振輸入復(fù)位按鍵是不是低有效DAC 和 ADC 的數(shù)據(jù)腳有沒有按原理圖逐位對(duì)應(yīng)。IO 電平標(biāo)準(zhǔn)也要看1.8 V 的 bank 接 3.3 V 外設(shè)輕則不工作重則傷器件。檢查完先跑一次綜合不要直接實(shí)現(xiàn)綜合報(bào)告里看頂層端口和時(shí)鐘網(wǎng)絡(luò)有沒有異常。如果工程里沒有現(xiàn)成的約束文件按原理圖補(bǔ)一份最小約束時(shí)鐘、復(fù)位、DAC 時(shí)鐘輸出、DAC 數(shù)據(jù)總線、ADC 采樣時(shí)鐘、ADC 數(shù)據(jù)總線。先只約束這些等回環(huán)通了再加調(diào)試端口。引腳約束不要一次寫太多逐組加、逐組驗(yàn)證出問題時(shí)容易定位。3.2 配置 DDS 頻率控制字與波形表波形表決定了輸出幅度和雜散頻率控制字決定了輸出頻率。先生成 LUT 文件再算頻率控制字。下面這段 Python 生成的是偏移二進(jìn)制正弦表深度 4096位寬 12適合大多數(shù)無符號(hào) DAC 輸入import math DEPTH 1 12 # LUT 深度和 LUT_AW12 對(duì)齊 WIDTH 12 # DAC 數(shù)據(jù)位寬 MID 1 (WIDTH - 1) with open(sine_lut.coe, w) as f: f.write(memory_initialization_radix10;\n) f.write(memory_initialization_vector\n) vals [] for i in range(DEPTH): s math.sin(2 * math.pi * i / DEPTH) # 偏移二進(jìn)制中點(diǎn) MID范圍 0 ~ 2^WIDTH-1 q int(round(MID s * (MID - 1))) q max(0, min((1 WIDTH) - 1, q)) vals.append(str(q)) f.write(,\n.join(vals) ;\n)DEPTH要和 DDS 里的LUT_AW對(duì)齊WIDTH要和 DAC 數(shù)據(jù)位寬對(duì)齊MID是偏移二進(jìn)制的中點(diǎn)。如果 DAC 吃的是二進(jìn)制補(bǔ)碼把MID s * (MID - 1)改成s * (MID - 1)再按位寬截?cái)?。生成后不要只看文件大小打開前幾十行確認(rèn)數(shù)據(jù)在0到4095之間且中點(diǎn)附近有2048左右的點(diǎn)。LUT 文件格式各平臺(tái)不一樣.coe、.mif、.hex都有工程里用哪種就生成哪種別直接改后綴。頻率控制字用下面這段算算完把結(jié)果寫進(jìn)寄存器或參數(shù)f_clk 100_000_000 # 系統(tǒng)時(shí)鐘按實(shí)際工程改 f_out 1_000_000 # 目標(biāo)輸出頻率 PHASE_W 32 # 相位累加器位寬 freq_word round(f_out * (1 PHASE_W) / f_clk) actual freq_word * f_clk / (1 PHASE_W) print(freq_word , freq_word) print(actual f_out , actual)f_clk必須和約束文件里的時(shí)鐘頻率一致PHASE_W必須和 DDS 模塊參數(shù)一致。round帶來的頻偏是有限的如果實(shí)際輸出和目標(biāo)的偏差超過應(yīng)用允許范圍增大PHASE_W比反復(fù)調(diào)freq_word更有效。算完后用仿真看一眼周期f_out為 1 MHz、f_clk為 100 MHz 時(shí)一個(gè)完整正弦周期大約 100 個(gè)時(shí)鐘數(shù)一下dac_data的峰值間隔就能對(duì)上。3.3 編譯、下載與在線抓取 ADC 數(shù)據(jù)編譯前先確認(rèn) LUT 文件已經(jīng)被工程識(shí)別綜合日志里搜一下 LUT 文件名沒有出現(xiàn)就是沒加進(jìn)去。實(shí)現(xiàn)完成后看時(shí)序報(bào)告重點(diǎn)看系統(tǒng)時(shí)鐘和 ADC 采樣時(shí)鐘的建立保持余量。余量為負(fù)時(shí)不要抱著“先下載看看”的心態(tài)回環(huán)數(shù)據(jù)會(huì)時(shí)好時(shí)壞最后浪費(fèi)更多時(shí)間。下載后先給一個(gè)低頻單音比如 100 kHz用示波器看 DAC 輸出有沒有波形再用在線抓數(shù)看 ADC 數(shù)據(jù)是否有變化。抓數(shù)配置建議先保守采樣深度取 4096 或 8192 點(diǎn)觸發(fā)方式用自由運(yùn)行或手動(dòng)觸發(fā)數(shù)據(jù)格式先按無符號(hào) 12 位導(dǎo)出。抓數(shù)時(shí)鐘盡量用 ADC 采樣時(shí)鐘不要用系統(tǒng)時(shí)鐘硬采否則看到的是跨時(shí)鐘域后的數(shù)據(jù)不能直接拿來做 FFT。抓到的數(shù)據(jù)先看最小值、最大值和中點(diǎn)偏移二進(jìn)制的中點(diǎn)在 2048 附近如果全在 0 或 4095先查 DAC 編碼和 ADC 位對(duì)齊不要急著做頻譜分析。抓數(shù)參數(shù)建議值說明采樣深度4096 點(diǎn)或 8192 點(diǎn)太少頻率分辨率不夠太多導(dǎo)出慢觸發(fā)方式自由運(yùn)行或手動(dòng)先保證能抓到連續(xù)數(shù)據(jù)數(shù)據(jù)格式無符號(hào) 12 位和 ADC 輸出格式一致抓數(shù)時(shí)鐘ADC 采樣時(shí)鐘避免跨時(shí)鐘域引入假頻譜分析工具Python NumPy方便做去偏置、加窗和 FFT3.4 用回環(huán)數(shù)據(jù)驗(yàn)證幅頻特性抓到數(shù)據(jù)后先做時(shí)域檢查再做頻域檢查。時(shí)域看峰峰值、均值、削頂比例頻域看主頻、諧波和底噪。下面這段腳本假設(shè)adc_data是從在線抓數(shù)導(dǎo)出的 12 位無符號(hào)數(shù)組fs是 ADC 實(shí)際采樣率import numpy as np # adc_data: 從在線抓數(shù)導(dǎo)出的 12 bit 無符號(hào)整數(shù)數(shù)組 # fs: ADC 采樣率單位 Hz x adc_data.astype(np.float64) x (x - 2048.0) / 2048.0 # 去偏置歸一化到 -1 ~ 1 N len(x) w np.hanning(N) X np.fft.rfft(x * w) freq np.fft.rfftfreq(N, d1.0 / fs) mag 20 * np.log10(np.abs(X) / (np.sum(w) / 2) 1e-12) peak_f freq[np.argmax(mag[1:]) 1] # 跳過 DC print(peak frequency:, peak_f)x - 2048是去掉偏移二進(jìn)制的中點(diǎn)hanning窗降低頻譜泄漏np.sum(w) / 2是窗函數(shù)的幅度修正。mag[1:]跳過直流分量否則最大值永遠(yuǎn)在 0 Hz。主頻峰值應(yīng)該和設(shè)定的f_out接近偏差主要來自freq_word四舍五入和 ADC 采樣時(shí)鐘的實(shí)際誤差。如果峰值旁邊出現(xiàn)對(duì)稱的雜散先查 LUT 深度和相位截?cái)嗳绻C波明顯查 DAC 輸出后的重建濾波器和 ADC 輸入端的抗混疊濾波器。4. 參數(shù)怎么設(shè)DDS 頻率分辨率、SFDR 與 ADDA 采樣率匹配DDS ADDA 回環(huán)測(cè)試?yán)飬?shù)不是孤立調(diào)的。頻率控制字影響輸出頻率LUT 位寬影響雜散ADC 采樣率影響能看到的最高頻率三者要一起看。很多“波形不對(duì)”的問題其實(shí)是參數(shù)之間不匹配輸出頻率接近采樣率的整數(shù)分之一或者 LUT 深度和 DAC 位數(shù)差太多頻譜上就會(huì)冒出解釋不了的峰。4.1 頻率控制字與輸出頻率的計(jì)算邊界頻率分辨率由f_clk / 2^PHASE_W決定。PHASE_W取 32、f_clk取 100 MHz 時(shí)分辨率大約是 0.023 Hz看起來夠細(xì)但頻率控制字是整數(shù)實(shí)際輸出頻率只能落在離散頻點(diǎn)上。目標(biāo)頻率正好落在兩個(gè)頻點(diǎn)中間時(shí)四舍五入會(huì)帶來頻偏。頻偏的絕對(duì)值是f_clk / 2^PHASE_W的一半以內(nèi)大多數(shù)測(cè)試可以接受如果做頻率掃描最好按頻點(diǎn)步進(jìn)而非隨意給目標(biāo)頻率否則相鄰頻點(diǎn)的實(shí)際間隔不均勻。參數(shù)示例值作用調(diào)整后的影響f_clk100 MHz系統(tǒng)時(shí)鐘變大則同頻率控制字下輸出頻率變高PHASE_W32相位累加器位寬變大則頻率分辨率更細(xì)資源略增freq_word42 949 673頻率控制字直接決定輸出頻率f_out1 MHz目標(biāo)輸出受頻率控制字量化影響頻率分辨率0.023 Hz最小頻率步進(jìn)由前兩項(xiàng)決定配置時(shí)先算freq_word再反算actual把兩個(gè)值都記錄下來。不要只寫目標(biāo)頻率后面排查頻偏時(shí)沒有對(duì)照。做頻點(diǎn)掃描時(shí)每個(gè)頻點(diǎn)至少抓 4096 點(diǎn)頻率間隔不要小于 FFT 的頻率分辨率fs / N否則相鄰頻點(diǎn)會(huì)在同一個(gè)譜線里混在一起。4.2 LUT 量化位數(shù)、DAC 位數(shù)與 SFDR 的取舍LUT 數(shù)據(jù)位寬決定波形幅度量化精度DAC 位數(shù)決定最終模擬輸出的理論動(dòng)態(tài)范圍。LUT 位寬低于 DAC 位寬時(shí)DAC 的低位基本在跳變SFDR 會(huì)被 LUT 量化臺(tái)階限制。經(jīng)驗(yàn)上LUT 每增加 1 bit量化臺(tái)階減半理論信噪比改善約 6 dB。12 位 DAC 配 8 位 LUT頻譜上很容易看到量化引起的雜散12 位 DAC 配 12 位或 14 位 LUT雜散會(huì)明顯好一些。LUT 位寬量化級(jí)數(shù)相對(duì) 12 位 DAC 的匹配情況適用場景8 bit256偏低低位浪費(fèi)只看波形有無不關(guān)注頻譜10 bit1024勉強(qiáng)可用低頻、低精度回環(huán)12 bit4096匹配常規(guī) DDS ADDA 測(cè)試14 bit16384高于 DAC 位數(shù)需要更好 SFDR 或做插值LUT 深度和位寬不是一回事。深度決定一個(gè)周期采多少個(gè)點(diǎn)位寬決定每個(gè)點(diǎn)用多少 bit 表示。深度不夠時(shí)相位截?cái)嚯s散會(huì)變差位寬不夠時(shí)幅度量化雜散會(huì)變差。回環(huán)測(cè)試?yán)锶绻l(fā)現(xiàn)諧波固定出現(xiàn)在某些頻點(diǎn)先加 LUT 深度如果發(fā)現(xiàn)底噪整體抬高先加 LUT 位寬。兩者都加還不行再查 DAC 輸出濾波和 ADC 輸入調(diào)理。4.3 ADC 采樣率、抗混疊與回環(huán)判據(jù)ADC 采樣率必須滿足奈奎斯特條件回環(huán)測(cè)試?yán)镒詈米屳敵鲱l率低于fs / 3給抗混疊濾波器留過渡帶。輸出頻率接近fs / 2時(shí)哪怕濾波器階數(shù)不低混疊分量也會(huì)落進(jìn)有用頻帶。DAC 輸出后的重建濾波器和 ADC 輸入端的抗混疊濾波器要一起看DAC 側(cè)濾掉鏡像ADC 側(cè)濾掉帶外噪聲只加一邊頻譜上仍會(huì)有多余分量?;丨h(huán)判據(jù)怎么算或怎么測(cè)合格線示例主頻偏差實(shí)測(cè)峰值與設(shè)定f_out比較小于 FFT 分辨率的一半幅度削頂統(tǒng)計(jì) ADC 數(shù)據(jù)中 0 和 4095 的比例削頂比例接近 0諧波抑制度二次、三次諧波與主頻的 dB 差大于 40 dB按系統(tǒng)要求調(diào)整底噪遠(yuǎn)離主頻處的平均譜線不隨抓數(shù)次數(shù)大幅跳動(dòng)混疊檢查fs - f_out附近是否有強(qiáng)分量低于主頻 30 dB 以上采樣率不是越高越好。采樣率提高后同樣的抓數(shù)深度覆蓋的時(shí)間變短FFT 頻率分辨率變差采樣率降低后抗混疊濾波器壓力變大。常規(guī)做法是先按輸出頻率的 5 到 10 倍選采樣率抓 8192 點(diǎn)看頻譜再根據(jù)雜散位置微調(diào)?;丨h(huán)判據(jù)要寫進(jìn)測(cè)試記錄不要只看一眼波形就下結(jié)論。5. 避坑與排查五個(gè)把回環(huán)測(cè)“翻車”的細(xì)節(jié)DDS ADDA 回環(huán)測(cè)試的現(xiàn)象很會(huì)騙人波形削頂可能被當(dāng)成 DAC 壞了頻率不對(duì)可能被當(dāng)成時(shí)鐘錯(cuò)了數(shù)據(jù)全零可能被當(dāng)成 ADC 沒起來。下面五條是血淚經(jīng)驗(yàn)里出現(xiàn)頻率最高的每條按“現(xiàn)象、原因、解決”寫照著排查比盲目換板子快。5.1 波形削頂或貼底DAC 數(shù)據(jù)編碼不匹配現(xiàn)象DAC 輸出正弦波頂部和底部被削平ADC 抓回來的數(shù)據(jù)大量落在 0 或 4095。原因LUT 生成時(shí)用了偏移二進(jìn)制DAC 接口卻按二進(jìn)制補(bǔ)碼解釋或者反過來。解決查 DAC 數(shù)據(jù)手冊(cè)的輸入編碼確認(rèn)中點(diǎn)對(duì)應(yīng)的是0x800還是0x000在 LUT 生成腳本里改編碼仿真時(shí)看中點(diǎn)碼值是否正確再下載驗(yàn)證。5.2 輸出頻率差整數(shù)倍頻率控制字用錯(cuò)位寬現(xiàn)象設(shè)置 1 kHz實(shí)測(cè)接近 1.2 kHz 或 0.8 kHz偏差不是隨機(jī)小數(shù)而是固定比例。原因算freq_word時(shí)把 LUT 地址位寬LUT_AW當(dāng)成了相位累加器位寬PHASE_W或者freq_word寄存器位寬不夠被截?cái)?。解決統(tǒng)一用PHASE_W計(jì)算檢查freq_word的位寬和模塊端口一致用公式反算實(shí)際頻率和仿真周期對(duì)照。5.3 ADC 數(shù)據(jù)全零或隨機(jī)跳跨時(shí)鐘域沒處理現(xiàn)象在線抓數(shù)時(shí)數(shù)據(jù)全是 0或者偶爾跳幾個(gè)隨機(jī)值復(fù)位后有時(shí)正常有時(shí)不正常。原因ADC 采樣時(shí)鐘和系統(tǒng)時(shí)鐘異步數(shù)據(jù)直接打進(jìn)系統(tǒng)時(shí)鐘域建立保持時(shí)間不滿足或者異步 FIFO 的讀寫復(fù)位沒有對(duì)齊。解決加異步 FIFOADC 側(cè)用采樣時(shí)鐘寫系統(tǒng)側(cè)用讀時(shí)鐘讀先看空滿標(biāo)志再讀數(shù)據(jù)抓數(shù)時(shí)鐘改用 ADC 采樣時(shí)鐘避免二次跨域。5.4 頻譜底噪高、諧波多LUT 量化或模擬濾波不足現(xiàn)象時(shí)域波形看起來正常FFT 上主頻旁邊有一排諧波底噪比預(yù)期高。原因LUT 位寬低于 DAC 位寬幅度量化臺(tái)階大或者 DAC 輸出直接進(jìn) ADC沒有重建濾波和抗混疊濾波。解決先把 LUT 位寬加到不低于 DAC 位寬再看 LUT 深度是否足夠模擬側(cè)加低通濾波輸出頻率降到fs / 3以下再測(cè)。5.5 編譯通過但板子無輸出約束或電平標(biāo)準(zhǔn)錯(cuò)了現(xiàn)象綜合實(shí)現(xiàn)都過下載后 DAC 沒有波形ADC 也抓不到有效數(shù)據(jù)。原因約束文件里的引腳和原理圖不一致或者 IO 電平標(biāo)準(zhǔn)與外部器件不匹配。解決對(duì)照原理圖逐腳檢查時(shí)鐘、復(fù)位、DAC 時(shí)鐘和數(shù)據(jù)總線先做一個(gè)單頻點(diǎn)加 LED 指示的最小工程確認(rèn)時(shí)鐘和復(fù)位活著再逐步加回環(huán)鏈路。6. 進(jìn)階驗(yàn)證用 FFT 和頻點(diǎn)掃描確認(rèn) DDS 輸出質(zhì)量回環(huán)能出波形只是第一步真正要確認(rèn)的是 DDS 輸出在目標(biāo)頻段內(nèi)是否穩(wěn)定。我一般會(huì)做一次頻點(diǎn)掃描在f_out的范圍內(nèi)取 5 到 10 個(gè)頻點(diǎn)每個(gè)頻點(diǎn)抓 8192 點(diǎn)做 FFT 后記錄主頻幅度、二次諧波、三次諧波和底噪。掃描時(shí)保持f_clk、LUT、模擬濾波不變只改freq_word這樣頻譜上的變化才能歸因到頻率本身而不是參數(shù)亂動(dòng)。設(shè)定頻率實(shí)測(cè)主頻主頻幅度二次諧波差三次諧波差備注100 kHz99.98 kHz-1.2 dBFS-48 dB-52 dB基準(zhǔn)點(diǎn)500 kHz499.91 kHz-1.3 dBFS-45 dB-49 dB觀察濾波器帶內(nèi)平坦度1 MHz1.0002 MHz-1.5 dBFS-43 dB-47 dB接近常用工作點(diǎn)2 MHz1.9997 MHz-2.1 dBFS-40 dB-44 dB看高頻段幅度跌落表格里的數(shù)值只是示例實(shí)際以你的板子和濾波器為準(zhǔn)。重點(diǎn)看趨勢(shì)頻率升高時(shí)主頻幅度是否明顯跌落諧波差是否快速變差底噪是否在某幾個(gè)頻點(diǎn)突然抬起。如果 1 MHz 附近正常、2 MHz 附近諧波明顯變差優(yōu)先查 DAC 輸出濾波器和 ADC 輸入帶寬而不是繼續(xù)加 LUT 深度。頻點(diǎn)掃描還有一個(gè)好處能提前發(fā)現(xiàn)“某些頻率正好落在采樣率整數(shù)分之一附近”的混疊問題這類問題在單頻測(cè)試?yán)锖苋菀妆宦┑簟FT 分析時(shí)我習(xí)慣把窗函數(shù)、去偏置和幅度修正寫進(jìn)固定腳本不每次手改。腳本里保留原始數(shù)據(jù)和參數(shù)記錄后面對(duì)比不同頻點(diǎn)時(shí)才不會(huì)把窗函數(shù)差異當(dāng)成器件差異。還有一個(gè)小技巧抓數(shù)時(shí)同時(shí)記錄 DAC 輸出端的示波器波形哪怕只看一眼峰峰值也能快速判斷削頂是數(shù)字側(cè)編碼問題還是模擬側(cè)增益問題。數(shù)字側(cè)和模擬側(cè)一起看比單獨(dú)盯 FFT 更可靠。從那以后我每次拿到新的 ADDA 板都強(qiáng)制先跑一遍“低頻單音、中點(diǎn)檢查、FFT 主頻、頻點(diǎn)掃描”這四步再動(dòng)任何參數(shù)??雌饋砺龑?shí)際上比反復(fù)下載、反復(fù)懷疑器件快得多。這套 DDS ADDA 測(cè)試工程文件我放在項(xiàng)目簡介對(duì)應(yīng)位置拿到后先按第 3 章走一遍回環(huán)再按第 5 章對(duì)一遍現(xiàn)象基本能少走大半彎路。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取