cdc跨時鐘域處理 結繩握手法

2021-09-26 08:35:32 字數 4072 閱讀 8000

參考文件

前言對於訊號需要跨時鐘域處理而言,最重要的就是確保資料能穩定的傳送到取樣時鐘域。

普通的cdc處理方法需要關注時鐘域速度的異同,即分慢時鐘域到快時鐘域、快時鐘域到慢時鐘域、相位關係等問題,會讓人瞬間**。

那麼,是否有一種相對穩定,又無需關注傳送時鐘域和接收時鐘域兩者時鐘速度、相位關係的資料傳遞方式呢?

這裡**驗證握手結繩法,自己想的,不知道跟結繩法是不是一致的。。。。。。

思考方式為:要絕對的保證資料被接收,自然是握手應答機制。

流程首先考慮亞穩態說明:對於非同步訊號的採集,不可避免的會有亞穩態,但亞穩態的恢復時間一般為1個時鐘或者兩個時鐘,同樣其不會是0、1的中間值,而是乙個開發者無法確定的定值,同時你的時鐘頻率越高,亞穩態發生的概率就越大。

網上感覺都說的不明就裡,對於簡單的使用多級觸發器,然後使用最高的2bit進行邊沿檢測,目測是不行的。

可以理解為**中的x值,但數位電路的本質上是有值的,要麼0,要麼1。

所以如果是檢測乙個訊號的上公升沿,即使採到亞穩態,那就分兩種情況:

(1)邊沿比較陡峭,時鐘只採到1次亞穩態,那麼邊沿暫存器的值就可能為:00、01。檢測到00,下一次就會採到01。如果是檢測到01,就是想要的沿。

(2)邊沿一點都不陡峭,導致時鐘採到兩次甚至更多次的亞問題,那這就沒得玩了。因為你不知道當前是00\01\10\11,這就可能導致你的後續邏輯完蛋了。

當然這裡第二種情況不予考慮,fpga內部不太可能出現這麼糟糕的上公升沿,除非你的時鐘過快,在時鐘沿到來前,亞穩態還沒有恢復過來。

極端的處理方式是(本質上是濾波):用更多位的暫存器,比如8bit,當檢測到為8'b0000_1111,那就是上公升沿啦,雖然這闊以絕對可靠的檢測到邊沿,但檢測出沿的所用的時間更長,同時需要保證前級訊號的高低電平長度,否則就被濾波了。。。。。。

所以,訊號的邊沿陡峭性是很重要的,專業術語叫做:上公升時間、下降時間。

言歸正傳,那麼握手結繩法是咋樣的操作呢?

如下圖所示:有點複雜

如圖所示,則操作流程為:上述方法應該是支援多bit資料跨時鐘域的,這裡的多bit說的是fpga內部資料,pulse_clk1表示傳送資料使能,clk1檢測到使能則拉高pulse_delay_clk1開始結繩。在clk2中,檢測到clk1中的結繩訊號的上公升沿則產生pulse_clk2,clk2檢測到pulse_clk2則啟動clk2中的結繩pulse_delay_clk2,在clk1中檢測到clk2中的結繩訊號為高則解掉clk1的結繩。在clk2中檢測到clk1的結繩拉低,則解繩clk2中的結繩訊號pulse_delay_clk2,完成傳輸。

待傳送資料在clk2的結繩上公升沿被取樣。

busy訊號為clk1中的訊號,在clk1的傳送資料使能到來則拉高,在pulse_delay_clk2的下降沿則拉低。

可以看到,這種方式只適合少量的慢速的資料傳輸。

源**

`timescale 1ns/1ps

module

cdc_test (

input

i_clk1 ,

input

i_clk2 ,

//input i_rst_n ,

input

i_en_clk1 ,

input [15:0

] i_data_clk1 ,

output

o_busy_clk1 ,

output

o_valid_clk2 ,

output [15:0

] o_data_clk2

);///

/clk1

////clk1的傳送使能邊沿檢測

reg [1:0] r_en_clk1_edge = 2

'b00;

always @(posedge

i_clk1)

begin

r_en_clk1_edge

<= ;

endreg r_en_clk2 = 1

'b0;clk2的使能邊沿檢測

reg [1:0] r_en_clk2_edge = 2

'b00;

always @(posedge

i_clk1)

begin

r_en_clk2_edge

<= ;

endreg r_en_expand = 1

'b0; clk1的使能延長

always @(posedge

i_clk1)

begin

if (r_en_clk1_edge == 2

'b01)

r_en_expand <= 1

'b1;

else

if (r_en_clk2_edge == 2

'b01)

r_en_expand <= 1

'b0;

endreg r_busy_clk1 = 1

'b0; 傳輸忙碌指示,忙碌的時候clk1的資料不可發生改變

always @(posedge

i_clk1)

begin

if (r_en_clk1_edge == 2

'b01)

r_busy_clk1 <= 1

'b1;

else

if (r_en_clk2_edge == 2

'b10)

r_busy_clk1 <= 1

'b0;

end///

/clk2

reg [1:0] r_en_expand_edge = 2

'b00; clk1的擴充套件後的使能邊沿檢測

always @(posedge

i_clk2)

begin

r_en_expand_edge

<= ;

endalways @(posedge i_clk2) ///

/clk2中的使能

begin

if (r_en_expand_edge == 2

'b01)

r_en_clk2 <= 1

'b1;

else

if (r_en_expand_edge == 2

'b10)

r_en_clk2 <= 1

'b0;

endreg r_valid_clk2 = 1

'b0;

always @(posedge

i_clk2)

begin

if (r_en_expand_edge == 2

'b01) 上公升沿表示資料有效

r_valid_clk2 <= 1

'b1;

else

r_valid_clk2

<= 1

'b0;

endreg [15:0] r_data_clk2 = 16

'd0;

always @(posedge

i_clk2)

begin

if (r_en_expand_edge == 2

'b01) 上公升沿重新整理資料

r_data_clk2 <=i_data_clk1;

end///

/訊號輸出

assign o_busy_clk1 =r_busy_clk1;

assign o_valid_clk2 =r_valid_clk2;

assign o_data_clk2 =r_data_clk2;

endmodule

//end the cdc_test model

**看看。

可以看到資料正確傳輸,不管是快到慢還是慢到快。

以後再板級測試啦。

以上。

跨時鐘域處理

需要做的事情 使能訊號txe to eth由時鐘122.88m時鐘輸出 另一使能訊號vde dv由25m時鐘輸出,計算兩個使能訊號之間的時間間隔,即兩個訊號上公升沿之間的時鐘計數。由於兩個訊號屬於不同的時鐘域,因此要先進行跨時鐘域處理,這裡對vde dv進行處理 在122.88m時鐘下將vde dv...

跨時鐘域處理

討論 今天華為面試題 非同步fifo讀時鐘是寫時鐘的100倍,或者寫是讀的100倍會出現什麼問題?今天華為面試題 非同步fifo讀時鐘是寫時鐘的100倍,或者寫是讀的100倍會出現什麼問題?答得 如果是瞬態資料中間有足夠間隔,則不會出現問題。如果是連續資料,則很快輸出空滿標誌位。面試官不滿意,請教下...

跨時鐘域(CDC)技術 亞穩態簡介

1.亞穩態以及其危害 對我們使用的邊沿觸發器而言 例如上公升沿觸發 由建立時間 setup time 和保持時間 hold time 在上公升沿定義了乙個時間視窗,如果在這個視窗內觸發器的輸入資料發生變化,就會產生時序違規。這會導致觸發器在這個視窗內採集的資料處於乙個不確定的狀態,也就是亞穩態。乙個...