---
# System prepended metadata

title: '延伸報告二 : 以AD9361接收訊號探討專題結論'
tags: [Xilinix zedboard, AD9361, NCU CE, Result Analysis]

---

# 延伸報告二 : 以AD9361接收訊號探討專題結論
### 主旨:
本篇基於以下專題以及延伸報告進行更深入分析及討論
專題:==**以GPS規格及Zedboard實現通訊發射機**==
延伸報告:==**[延伸報告1:以頻譜分析儀探討專題結論](https://hackmd.io/@ajO9iAiKQw-VU35zjKDr1g/r1PKDeEVh)**==

內容-運用MATLAB分析發射資料的特性(頻譜與星座圖)
目標-客觀評鑑專題之成果(發射訊號特性)


---

## 引言:前述專題及延伸報告之結論
基於"以GPS規格及Zedboard實現通訊發射機之模擬"專題，其最後結論呈現以zedboard實際產生訊號並透過AD9361射頻板發射之訊號頻譜:

>![](https://hackmd.io/_uploads/BJYKV2lH2.jpg)
> *圖1-1與1-2、頻譜分析儀不同span下之螢幕截圖*
> "此頻譜的中心頻率在2.5GHz，頻寬為300kHz，且波形看起來失真。此結果與理論模擬的不同，發生了我們預期外的問題。"

以上述專題結論繼續延伸，在[延伸報告1:以頻譜分析儀探討專題結論](https://hackmd.io/@ajO9iAiKQw-VU35zjKDr1g/r1PKDeEVh)一文中，我們找到了原本未發現的程式碼問題，進一步修正後，結果有改善，卻還是沒有達到期望中的特性。

本篇將以不同的方法及觀點重新**分析**專題最後產生的**發射訊號**(由zedboard實體電路產生經AD9361射頻板發射之訊號)。

## 一、新的方法與電路架構
### 方法流程
在延伸報告1中，我們直接以頻譜分析儀觀察發射訊號頻譜，接下來我們將採用的檢測方式為：**直接將發射的訊號接收回來，透過matlab分析每一個發射出去的訊號。**

### 具體實現方式
```mermaid
graph LR;
1.以AD9361發射並接收訊號-->2.存入python介面中的陣列變數;
2.存入python介面中的陣列變數-->3.matlab分析資料;
```
1. 以AD9361的ADC模組 接收 AD9361的DAC模組發射的訊號
2. DAC收到發射訊號後，搭配zedboard內建模組DMA將實體訊號以陣列型式存回python介面中，將python中的陣列值寫入txt檔
3. 最後由matlab讀入txt檔，對資料做進一步的分析。

接下來將分為三部分概述:
`1.以AD9361發射並接收訊號`
`2.存入python介面中的陣列變數`
`3.matlab分析資料`

### 1.以AD9361發射並接收訊號
#### 電路架構

![](https://hackmd.io/_uploads/Hy4TRWYrn.jpg)
*圖2、vivado中的block design diagram*
:::danger
紅框內的模組為自設計之模組，主要負責產生除頻後的時脈並以此時脈生成goldcode，將goldcode與設定資料加密後做qpsk調變，產生欲發射之訊號
:::
:::success
綠框內的模組接手"自設計模組"產生的訊號後，再做16倍上採樣，接續再做pulse shaping
:::
:::info
藍框內的模組是AD9361的DAC，它可以將綠框內處理完的訊號經由射頻板的TX端發射出去
:::
:::warning
黃框內的模組包含了AD9361的ADC，它可以將訊號經由射頻板的RX端接收回來。同時還有Counter_AXIS_last模組協調資料及控制訊號，以輔助控制zedboard內建IP DMA(Direct Memory Access)
:::
```
剩餘沒有框到的模組主要是 系統(zynq)的模組 及 控制功能的模組。
 -系統(zynq)的模組:呼叫主要核心PS後，透過autoconnection的功能，vivado會自動呼叫出配合運行的模組。
 -控制功能的模組:包含一些gpio module(從python介面設定電路的參數)及射頻板的SPI(對AD9361做配置，傳遞參數設定)
```
### 2.存入python介面中的陣列變數
#### 簡述python操作
由vivado產生完描述檔後，在python執行，我們透過以下操作可以得到的發射訊號：
:::warning
 ```python=
 output_buffer = xlnk.cma_array(shape=(1023,), dtype=np.uint32)
 dma_recv.transfer(output_buffer)
 ```
 上面是操控dma模組的兩個核心指令:
1. output_buffer是一個自訂大小(此時為1023)的一維陣列，其數據類型為32 位元的unsigned integer，這個陣列會儲存dma收到的訊號。
2. 這行程式碼表示使用 DMA 來從外部設備(AD9361的ADC)接收資料，並將其傳輸到 output_buffer 中。
 
 更細部去說，xlnk.cma_array() 是一個用在 Xilinx 系統上進行內部記憶體管理的函式。其功能為創建一個連續的物理內存區域，output_buffer 即可存取和操作這個區域。
:::
#### 操作結果
> ![](https://hackmd.io/_uploads/S1ZkIRor3.jpg)
> *圖3、output_buffer儲存的資料(操作畫面截圖)*
> 
> 如圖，6553700是32位元的值；圖中使用len()函式可以看到output_buffer的大小(1023筆)，此時output_buffer儲存著1023筆32位元的資料。
> 
> 因為在設計上，由於我們做qpsk調變，訊號會兩兩一組做mapping，因此調變完的訊號可以分為**實部訊號**及**虛部訊號**，各為16bits，故傳送訊號的一個symbol即帶有兩個sample(實部與虛部)共為32bits，因此ouput_buffer儲存的是32bits unsigned integer。
:::warning
**進一步處理output_buffer接收的資料:**
```python=
r=output_buffer//2**16
r=np.int16(r)
i=output_buffer%2**16
i=np.int16(i)
```
為了方便後續的處理，先在python介面中將訊號的實部與虛部分離(32bits中，前16bits為實部 r ，後16bits為虛部 i )並且轉換實部與虛部資料為signed integer。

```python=
file = open('ztxrx_0508.txt', 'w')
for k in range(sz):
    if r[k]<0:
        file.write("  %s" % r[k])
    else:
        file.write("   %s" % r[k])
    if i[k]<0:
        file.write("  %s\n" % i[k])
    else:
        file.write("   %s\n" % i[k])
file.close()
```
透過上面的小迴圈，可以將實部訊號 r 與虛部訊號 i 寫進ztxrx_0508這個文字檔中，以**特定格式排列**。
:::
### 3.matlab分析資料
#### 簡述matlab操作
![](https://hackmd.io/_uploads/rJzFUJ2B2.jpg)

*圖4、在matlab中開啟txt檢視*

上面提到的**特定格式排列**就是指將實部寫在第一欄；虛部寫在第二欄，這麼做的原因是可以配合以下程式；

:::warning
```m
function [S_out_A, S_out_B]=MATLAB_FILE_OUT_AB_Decimal(file_name)
if length(file_name) == 0
   [out] = textread('TB_OUT.txt','%n');
else
   [out] = textread(file_name,'%n');    
end
S_out_A=out(1:2:end);  S_out_B=out(2:2:end); 
```
這段程式將文字檔中的數值讀出存進陣列中，具體使用如圖五，在command window叫出這個function，命名陣列名稱同時設定來源文字檔後，即可成功將資料讀入matlab中，供後續分析用。
:::

#### 操作結果
> ![](https://hackmd.io/_uploads/Skuh_1hS2.jpg)
> *圖5、將txt的文字轉到matlab以陣列儲存為數值*
> 比對圖4與圖5，可以發現在數列相同位置的值有對應，讀入成功。

#### 小結:
至此，我們幾乎完成了前述的流程，共三個步驟:
* 步驟1.以AD9361發射並接收訊號
* 步驟2.存入python介面中的陣列變數
* 步驟3.matlab分析資料

其中，步驟1與2已經確實完成，但在 **步驟3.matlab分析資料** 只做到了資料的匯入，分析資料在下一段接續講解。

## 二、MATLAB進一步分析
### 資料處理概念
在這個階段會處理從txt檔讀入的資料，分別為 **z_real**，代表訊號的實部 ; **z_imag** 代表訊號的虛部，共兩個長度為2的15次方的一維陣列，也就是兩個陣列都儲存著2的15次方筆數值。
#### 轉換
資料被分為實部與虛部儲存在matlab的變數中，而原本傳送的訊號是兩兩一組的，是複數資料型態。因此透過以下操作還原傳送訊號:
```m
z_complex = z_real + 1j*z_imag;
```
z_complex即為一複數型態的資料，在這裡也代表著傳送的訊號。有了z_complex後，對其進行一系列的運算就可以分析出其中數值的強度趨勢以及資料點的分布特性。目標是畫出**頻譜**與**分布圖**。

#### 頻譜
接下來將講解運用matlab函式畫出頻譜的過程及意涵
:::info
**取得信號的頻譜能量分佈:**
```m
z_spectrum = abs(fftshift(fft(z_complex,8192)));
```
**fft(z_complex, 8192)** 
代表對輸入的複數陣列 **z_complex** 進行 **8192** 點的快速傅立葉轉換 (FFT)。FFT將時域信號轉換為頻域信號，得到信號的頻譜資訊。

**fftshift(...)**
這個函數對括弧中的數列進行中心化。中心化是將頻譜中的直流分量移到頻譜的中心，以便於觀察頻域信號。此操作是將頻譜的低頻部分移到中心。

**abs(...)**
此函數計算括弧中數列的絕對值。作用為去除頻譜中的相位資訊，只保留頻譜的振幅。運算的結果表示頻域信號的強度或能量。

整個運算後，得到 **z_spectrum**。它是一個實數陣列，包含了 **z_complex** 輸入信號的頻譜能量分佈。
:::
:::info
**Normalize:**
```m
L = length(z_spectrum);
x = [-L/2+1:L/2]/L;
```
**L** 計算 **z_spectrum** 陣列的長度；
**x** 為一陣列，其範圍從 **-L/2+1** 到 **L/2**，並將其除以 **L**。這樣可以將 x 軸範圍限制在 [-0.5, 0.5] 之間，使總長度為1。
這兩個指令作用在正規化尺度，為繪製頻譜圖做準備。
:::
:::info
**繪製normailized頻譜:**
```m
plot(x, 10*log10(z_spectrum));
```
使用 **plot** 函數繪製頻譜圖。橫軸是 **x** 陣列(範圍在 -0.5~0.5之間)，表示頻率的相對位置；縱軸是 **10*log10(z_spectrum)**，表示以dB為單位的頻譜能量。
:::
**透過以上步驟，我們可以畫出並分析信號在頻域上的特性**
![](https://hackmd.io/_uploads/r14nni1Ih.jpg)
*圖六、由matlab繪製的發射訊號頻譜*

此處頻譜在-0.3~0.3有較強的能量，原本以為是訊號，驗證後是被抬升的雜訊。

![](https://hackmd.io/_uploads/ryQb94UL3.png)
*圖七、由matlab繪製的雜訊頻譜*

圖七頻譜是zedboard板空接的狀態，理論上頻譜應該為平的，而非有圖七中抬升的狀況，推測應該是ADC與DMA模組有出問題，詳細有待進一步釐清。
#### 星座圖
:::info
**星座圖**可以用於視覺化資料的離散點分佈和觀察其中的模式或趨勢
```m
plot(z_complex(1:4:end),'+');
plot(z_complex(2:4:end),'+');
plot(z_complex(3:4:end),'+');
plot(z_complex(4:4:end),'+');
```
運用 **plot** 函數，繪製四個不同索引範圍的 **z_complex** 陣列的星座圖。

**plot(z_complex(1:4:end),'+')** 代表將 **z_complex** 陣列中，索引為 1、5、9、... 的元素以 + 符號繪製在圖上。**1:4:end** 表示從索引 1 開始，每隔 4 個元素取一個，直到陣列結尾。

**(2:4:end)** 則是取陣列中索引為 2、6、10、... 的元素，以此類推。

目的是將 **z_complex** 向量中，特定索引範圍的元素以星座圖形式呈現。顯示了陣列中特定索引位置上，複數值的分佈情況。這邊會有四個組合的原因是由於使用pulse shaping模組，其消去ISI效應，還上採樣了4倍，之所以會需要上採樣4倍是因為要使原本輸入模組的0、1的訊號連續，因此做上採樣插值。而上採樣的倍數則會影響接收機好不好實現，插入越多值對於接收機來說會更好處理收到的波形。

:::
![](https://hackmd.io/_uploads/SkQxVhJ8n.jpg)
*圖八、不同索引範圍畫出的示意圖*

![](https://hackmd.io/_uploads/H1jPShkUn.png)
*圖九、由matlab繪製的發射訊號星座圖*
其中，不同的索引範圍畫出來，都是相同結果，幾乎無異。`P.S.星座圖理論上要接收機 down sampling 和通過 match filter 再分析會具代表性，此處直接看發射訊號不經任何處理的星座圖，只能粗略的判斷發射訊號特性。`

#### 小結:
以上，我們成功以matlab對資料處理，完成**頻譜**及**星座圖**的繪製。

## 三、結果分析
這個階段將會回顧延伸結報1的結論，以頻譜及星座圖分析差異。
### 頻譜比較
比較<font color="#A30404">**模擬頻譜**</font>、<font color="#27A304">**分析儀頻譜**</font>、<font color="#0469A3">**接收訊號繪製的頻譜**</font>
> ![](https://hackmd.io/_uploads/B1sHwxZI3.png)
> *圖十、不同階段或方法的發射頻譜比較*
> 
> <font color="#A30404">左: 資料由硬體產生，由硬體完成升採樣，沒有發射，以matlab繪圖(紅色部分模擬發射訊號之頻譜)。</font>
> 
> <font color="#27A304">中: 資料由硬體產生，由硬體完成升採樣，實際發射訊號後，以頻譜分析儀觀察。</font>
> 
> <font color="#0469A3">右: 資料由硬體產生，由硬體完成升採樣，實際發射訊號後，以射頻板收回訊號，以matlab分析並繪圖。</font>
> 
> **都由實體FPGA產生訊號，差別在 有無實際發射 和 測量方式**

細節陳述:
* 左圖，此頻譜其實是**不符合預期**的，可以發現在中心頻率左右兩側存在很多image，仔細檢查電路後，發現我們的polyphase上採樣電路模組做反了。filter模組與P2S模組的順序錯了，filter沒有在P2S後面，做濾除image的動作，而這注定會導致image干擾到主要訊號，而這也在訊號的星座圖應證了。
* polyphase上採樣的架構在 vivado 確定出現問題，詳細待結論討論。同時，上採樣的設計與AD9361的DAC可能沒有配合好，導致在模擬階段，頻譜特性就已不佳。
* 中圖與右圖，在中心頻率附近特性較一致，但可以發現matlab資料繪製的頻譜，在正負0.3附近有段差，這是在頻譜儀上沒有看到的現象。問題高機率出在射頻板的ADC與DMA模組，使接收到的訊號以matlab繪製都會被抬升；而頻譜分析儀不會使用到ADC與DMA模組故沒有被抬升。中圖與右圖作為發射訊號的頻譜，頻譜理想上應該要接近模擬的頻譜(左圖)。

### 星座圖比較
> **理論上最佳的星座圖:**
> ![](https://hackmd.io/_uploads/rkzyfLzIh.jpg)
> *圖十一、matlab繪製自設計模組產生的訊號星座圖(沒有發射)*
> 
> 因為qpsk調變的緣故，訊號因為分成實部與虛部，分別代表訊號空間中的兩軸，形成四個訊號點(symbol)，分別在四個象限。

**實際星座圖:**
![](https://hackmd.io/_uploads/S1BHmLG8n.png)
*圖十二、左為雜訊的星座圖，右為發射訊號星座圖*

可以發現雜訊的分布與發射訊號的分布有顯著的差異。其中，右圖的黑色線代表歪掉的x軸與y軸，訊號點沒有鎖定在四個訊號點上，且整個分布的趨勢都旋轉了45度左右，分布特性不理想。發射機的設計需要再調整。

## 四、結論
**在這份延伸報告中，經由測試與分析所獲得的資訊及重點**
:::info
* 成功使用AD9361及cable達成，發射、經過通道、再接收
* 成功以dma抓取接收的訊號，以matlab分析收到的訊號
* 發現頻譜分析儀的結果與matlab運算後的頻譜相近，以不同方式得到了相同的頻譜特徵，即使結果並不理想
* 觀察星座圖，發射訊號在訊號空間分布的表現並不好，訊號點的分布很亂，對於接收機來說，這樣的發射訊號可能導致解碼的錯誤率很高。
:::

至此，我們透過回收發射訊號，直接分析訊號內每個數值。透過比對不同階段的資料特徵，發現**問題**如下
:::danger
* **16倍上採樣模組架構有問題**
做完qpsk後的訊號經過pulse shaping後還符合預期(訊號點分布完美)。訊號再做16倍的上採樣模組後由AD9361的DAC發射出來的訊號(頻譜、訊號點分布)就不理想，檢查電路後發現架構有誤，因此沒有達到濾除image的功能，使訊號的分布相當雜亂。
* **星座圖的觀察有瑕疵**
星座圖應該是在接收機做相對接收機的配置做降採樣與通過matched filter後才做觀察，直接對發射訊號做星座圖分析的意義並不大。
* **AD9361的ADC與DMA有問題**
以結果來看，由射頻板ADC接收回來的訊號經過DMA取出，送到matlab分析繪製的頻譜都會凸起來而頻譜分析儀的結果都沒有。目前不知道導致這個錯誤的原因為何，有待進一步排查。
:::

### 可改進的流程


我認為，**要先熟悉Zedboard使用方法以及模組的操作**。
專題進行期間，我們邊設計模組邊熟悉zedboard的基本模組使用，這種模式在一開始能夠更快的啟動計畫看到結果，但在後期遇到問題時就得回頭改已經完成的配置。如果能在一開始先了解整個電路的運作模式及基本模組，應該能避開不必要的麻煩。也就是先看到了後面的問題，前面的設計就可以想辦法避開。
Zedboard使用指南: [Zedboard + AD9361 Tutorial](https://hackmd.io/@YXsR-gCtSTWSCuI7AaUHEA/r1pZn3z4c)

## Reference
+ NCU-CE, SDR LAB
+ [PieappleJ大神學長的Tutorial](https://hackmd.io/@Pieapplej/H1XwekrHc)
+ 以GPS規格及zedboard實現通訊發射機模擬
+ [延伸報告一:以頻譜分析儀探討專題結論](https://hackmd.io/@ajO9iAiKQw-VU35zjKDr1g/r1PKDeEVh)

在這一學年的專題實作中，我們跌跌撞撞，遇到了很多問題也經歷了很多挫敗，但我們努力不懈。不斷嘗試、追著問題、釐清細節是組員間共同的信念並鼓勵著彼此繼續向前。雖然最後沒有做出顯著的成果，但一路走來我們也收穫滿滿，將問題說清楚並順利解決，以此形式記錄。
**特別感謝SDR LAB的學長姐，與我們一起想辦法並協助我們**:100: 

###### tags:`Xilinix zedboard` `AD9361` `Result Analysis` `NCU CE`
>Department Communication Engineering
National Central University, Taiwan
主編:[name=Dylan傅詮恩]協助編輯:[name=張榮軒、陳泓宇、冼義佑]