問:實(shí)現(xiàn)穩(wěn)健的微控制器到 FPGA SPI 接口: 雙緩沖區(qū)
在介紹雙緩沖器之前,我們將簡(jiǎn)要探討Verilog 脈寬調(diào)制器 (PWM) 的工作原理。這一點(diǎn)很重要,因?yàn)殡p緩沖區(qū)最好被看作是硬件模塊 (如 PWM) 的可尋址接口。
PWM 的回顧
PWM 模塊的頂層接口在這個(gè) Verilog 代碼片段中描述。觀察該模塊使用了位寬參數(shù),并建立了最小和最大占空比限制。最后,觀察PWM模塊有一個(gè)[B - 1:0]輸入矢量來設(shè)置占空比。沒有顯示的是在每個(gè) PWM 占空比開始時(shí)讀取輸入的事實(shí)。
module PWM #(parameter
B = 12,
D_MIN_PERCENT = 0,
D_MAX_PERCENT = 95
)
(
input wire clk,
input wire enable,
input wire [B -1:0] d_in,
output reg PWM,
output reg [B -1:0] cnt
);
“
同步數(shù)據(jù)呈現(xiàn)
PWM 設(shè)計(jì)用于在更大的 uC 到 FPGA SPI 系統(tǒng)中工作?;叵胍幌拢琒PI自然地使用字節(jié)寬度的數(shù)據(jù)元素進(jìn)行操作。這與使用B定義的數(shù)據(jù)寬度操作的PWM形成鮮明對(duì)比。為了方便,我們假設(shè) PWM 以16位的位寬度(B)實(shí)例化。
當(dāng)系統(tǒng)更新與 PWM 輸入相關(guān)的寄存器時(shí),會(huì)出現(xiàn)一個(gè)問題。如果沒有適當(dāng)?shù)淖⒁?,PWM 可能會(huì)在更新過程中執(zhí)行讀取操作。其結(jié)果是驅(qū)動(dòng)器字節(jié)被分割成一個(gè)舊字節(jié)和一個(gè)新字節(jié)。這可能導(dǎo)致占空比的顯著躍升,持續(xù)一個(gè) PWM 周期。如果 PWM 用于LED 指示燈,則可能不會(huì)注意到這一點(diǎn)。在更復(fù)雜的系統(tǒng)中,故障相當(dāng)于一個(gè)強(qiáng)脈沖,并可能導(dǎo)致系統(tǒng)響鈴或變得不穩(wěn)定,具體取決于錯(cuò)誤發(fā)生的時(shí)間和頻率。
解決方案是實(shí)現(xiàn)以下三篇文章中提到的雙緩沖方案,后面將進(jìn)行深入討論。
第1 部分介紹了指導(dǎo)大型系統(tǒng)開發(fā)的 Verilog 設(shè)計(jì)理念。這是介紹寄存器傳輸電平 (RTL) 設(shè)計(jì)準(zhǔn)則的關(guān)鍵部分,如時(shí)鐘邊界、頻閃器的使用和雙緩沖區(qū)的必要性。
第2部分介紹了 SPI 協(xié)議?;叵胍幌拢x協(xié)議改編自802.3以太網(wǎng)幀,具有可變有效載荷長(zhǎng)度和循環(huán)冗余校驗(yàn) (CRC) 等概念,以提供數(shù)據(jù)完整性的度量。
第3部分介紹了 uC 到 FPGA 接口的高級(jí)視圖。那篇文章中最重要的部分是這里重復(fù)的框圖。
使用一組寄存器來捕獲單個(gè)字節(jié)。當(dāng)收集到完整的n字節(jié)數(shù)據(jù)時(shí),更新第二個(gè)更寬的寄存器。第二個(gè)寄存器-雙緩沖區(qū)-然后用于驅(qū)動(dòng)其他模塊,如代表性的 PWM。
雙緩沖模塊
雙緩沖模塊的框圖如圖1所示。在內(nèi)部,它由四個(gè)主要部分組成。最重要的是輸出寄存器。在這個(gè)例子中,它是16位寬,使其適合驅(qū)動(dòng)16位 PWM。輸出寄存器由單個(gè)8位寄存器驅(qū)動(dòng),在本例中它們被標(biāo)記為 LSB 和 MSB。注意,所有的寄存器更新都是由雙緩沖區(qū)的控制部分發(fā)起的。這是一個(gè)同步操作,其中所有元素響應(yīng)主 100mhz時(shí)鐘的滴答聲。
圖1:雙緩沖區(qū)的框圖,顯示了單個(gè)8位緩沖區(qū)與輸出緩沖區(qū)之間的關(guān)系。
重要的是要理解,每個(gè)雙緩沖區(qū)模塊都是用特定的地址和特定的字節(jié)寬度實(shí)例化的,如下面的代碼清單所示。注意,16位地址、8位數(shù)據(jù)和寫頻閃都涉及到加載緩沖區(qū)。當(dāng)16位地址輸入與實(shí)例化地址匹配時(shí),數(shù)據(jù)傳輸就開始了。
module
double_buffer #(
parameterBYTE_WIDTH = 2,
parameterBASE_ADDRESS = 16'h0200
) (
input wire clk,
input wire [7:0]data,
input wire [15:0]address,
input wirewrite_strobe,
output reg [((8 *BYTE_WIDTH) - 1): 0] double_buffer_out,
output regnew_data_strobe
);
如圖1所示,這個(gè) uC 到 FPGA 接口有一個(gè)底層的8位傳輸過程。在這文章中首先介紹的命令幀中也隱含了一個(gè)連續(xù)寫入操作。為了方便起見,這里將命令幀重復(fù)為圖2。作為一個(gè)例子,讓我們假設(shè) PWM 和相關(guān)的雙緩沖區(qū)以地址0x0200實(shí)例化。命令幀的寫地址將被設(shè)置為0x0200,負(fù)載的前兩個(gè)字節(jié)將保持所需的16位 PWM 值。
圖2:構(gòu)成uC到FPGA SPI協(xié)議基礎(chǔ)的命令和響應(yīng)幀。
當(dāng)接收并驗(yàn)證命令幀時(shí),MSG 寫塊將斷言地址0x0200,該地址指向 PWM 的雙緩沖區(qū)。它將把第一個(gè)有效載荷字節(jié)放到數(shù)據(jù)總線上。最后,它將為一個(gè)時(shí)鐘周期斷言寫頻閃。這將加載如圖1所示的 MSB (大端)。
繼續(xù)進(jìn)行連續(xù)寫入,MSG 寫入器向前推進(jìn)地址,斷言下一個(gè)數(shù)據(jù)字節(jié),然后脈沖寫入頻閃,從而將 LSB 加載到雙緩沖區(qū)中。這個(gè)過程對(duì)命令幀中的每個(gè)字節(jié)繼續(xù)進(jìn)行,由幀的字節(jié)長(zhǎng)度字段控制。
從本質(zhì)上講,消息編寫器并不了解相關(guān)的雙緩沖區(qū)的長(zhǎng)度。它只關(guān)心斷言地址、數(shù)據(jù)和寫頻閃的三步過程。這取決于雙緩沖區(qū)模塊來理解它們何時(shí)被尋址,以及何時(shí)接收到 BYTE_WIDTH 參數(shù)指定的必要字節(jié)數(shù)。
由于雙級(jí)緩沖區(qū)的基址和字節(jié)寬度在實(shí)例化時(shí)是已知的,因此很容易確定何時(shí)接收到所有字節(jié)。在這個(gè) PWM 示例中,雙緩沖器計(jì)數(shù)到2,然后發(fā)送一個(gè)頻閃來加載輸出寄存器。
技術(shù)貼士: 數(shù)據(jù)可能首先訪問最高有效字節(jié) (MSB) 或最低有效字節(jié) (LSB)。描述順序的術(shù)語(yǔ)是“端序” (endian)。如果 MSB 先出現(xiàn),則系統(tǒng)為大端序。如果 LSB 是第一個(gè),則系統(tǒng)是小端序的。本文描述的雙緩沖區(qū)和關(guān)聯(lián)幀是大端序。
雙緩沖區(qū)代碼
雙緩沖區(qū)的 Verilog 代碼附在本注釋的末尾。代碼緊跟圖2的框圖,理解它可以擴(kuò)展到n字節(jié)的寬度。這可以通過更改 BYTE_WIDTH 參數(shù)來實(shí)現(xiàn)。
這段代碼的關(guān)鍵是 Verilog 生成操作符的使用?;叵胍幌?,generate特性允許迭代地生成硬件。它的運(yùn)作方式就像一個(gè)制造小部件的工廠。
除了,在這種情況下,我們正在制作8位寄存器,其程序集的總數(shù)等于 BYTE_WIDTH 參數(shù)。我們可以在 Vivado 分層設(shè)計(jì)窗口中看到這一點(diǎn),如圖3所示。這些“制造”的塊與它們?cè)谏裳h(huán)中定義的連續(xù)命名方案一起出現(xiàn)。
圖3:在雙緩沖區(qū)實(shí)例化中可以看到生成的字節(jié)寬度寄存器。
觀察每個(gè)生成的9位寄存器都包含一個(gè)對(duì)應(yīng)的 local_write_strobe。這是一個(gè)重要的設(shè)計(jì)方面,因?yàn)?“control”部分使用它來加載相關(guān)的8位寄存器。
除了寄存器之外,生成循環(huán)還制造一個(gè)8位矢量,每個(gè)8位寄存器的輸出都連接到這個(gè)矢量上。然后將這些N × 8位的包連接起來并傳遞到n字節(jié)輸出寄存器。
代碼的最后一部分確定n字節(jié)何時(shí)被收集。然后它更新輸出寄存器并發(fā)送一個(gè)new_data_strobe。
控制部分有三個(gè)基本功能:
當(dāng)基址與實(shí)例化地址匹配時(shí)激活模塊。
維護(hù)一個(gè)計(jì)數(shù)器指向“制造的”8位寄存器。這個(gè)計(jì)數(shù)器對(duì)于連續(xù)寫入是必不可少的。
對(duì)相關(guān)的8位寄存器進(jìn)行頻閃。
當(dāng)N個(gè)8位寄存器被填滿時(shí),對(duì)輸出緩沖區(qū)進(jìn)行頻閃。
技術(shù)貼士:矢量是導(dǎo)線的一維數(shù)組。一個(gè)例子是“input wire [15:0] address”,它定義了一個(gè)16位的名為 address 的矢量。
結(jié)語(yǔ)
最后,雖然這段代碼確實(shí)很復(fù)雜,但 Verilog 生成操作符提供了很大的靈活性。它消除了為每個(gè)期望的字節(jié)寬度構(gòu)建獨(dú)立模塊的需要。
-
寄存器
+關(guān)注
關(guān)注
31文章
5253瀏覽量
119205 -
緩沖器
+關(guān)注
關(guān)注
6文章
1903瀏覽量
45327 -
LED指示燈
+關(guān)注
關(guān)注
2文章
94瀏覽量
12515 -
SPI接口
+關(guān)注
關(guān)注
0文章
258瀏覽量
34228 -
脈寬調(diào)制器
+關(guān)注
關(guān)注
1文章
48瀏覽量
16964
原文標(biāo)題:實(shí)現(xiàn)MCU到FPGA SPI接口有一個(gè)好選項(xiàng):用雙緩沖器!
文章出處:【微信號(hào):得捷電子DigiKey,微信公眾號(hào):得捷電子DigiKey】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論