FPGA單位元訊號跨時鐘域處理

2021-10-08 04:00:38 字數 4139 閱讀 2695

詳細的原理解釋:

單位元訊號跨時鐘域問題詳解

輸入:singal_in,來自10mhz慢速時鐘域的單位元訊號

輸出:singal_out,輸出100mhz快速時鐘域的單位元訊號

10mhz =

100ns

100mhz =

10ns

因為慢速時鐘域的最簡訊號長度為1個時鐘時鐘週期即:100ns,大於快速時鐘域的時鐘週期10ns,所以只需要打3拍即可:

/* 從慢速時鐘域同步到快速時鐘域 */

module top

(//inputs

input clk,

//快速時鐘,時鐘100mhz

input rst_n,

input signal_in,

//來自慢速時鐘域,時鐘10mhz

//outputs

output signal_out //同步到快速時鐘域之後的訊號);

reg signal_in_reg1;

reg signal_in_reg2;

reg signal_in_reg3;

assign signal_out = signal_in_reg3;

always @ (posedge clk)

begin

if(!rst_n)

begin

signal_in_reg1 <=0;

signal_in_reg2 <=0;

signal_in_reg3 <=0;

endelse

begin

signal_in_reg1 <= signal_in;

signal_in_reg2 <= signal_in_reg1;

signal_in_reg3 <= signal_in_reg2;

endendendmodule

**tb檔案:

`timescale 1ns/

1psmodule top_tb;

reg clk_100m;

//period=10ns;

reg rst_n;

reg signal_in;

wire signal_out;

initial

begin

clk_100m =1;

rst_n =0;

signal_in =0;

#50rst_n =1;

#100

signal_in =1;

#100

signal_in =0;

#100

$stop;

endalways #(10/

2) clk_100m <=

!clk_100m;

top top_ut

(//inputs

.clk

(clk_100m),.

rst_n

(rst_n),.

signal_in

(signal_in)

,//outputs

.signal_out

(signal_out));

endmodule

輸入:singal_a,來自100mhz快速時鐘域的單位元訊號

輸出:singal_b,輸出10mhz慢速時鐘域的單位元訊號

10mhz =

100ns

100mhz =

10ns

這裡僅僅針對輸入訊號的脈衝寬度僅有1個快速時鐘週期寬度的訊號,即singal_a的訊號寬度僅有10ns寬,且兩個脈衝間隔時間大於兩個慢速時鐘週期,即2*100ns=200ns。

先在快速時鐘域下把邊沿訊號轉換為電平訊號,再在慢速時鐘域下把電平訊號打3拍,再在慢速時鐘域下把電平訊號轉換為邊沿訊號:

/* 快速時鐘域同步到慢速時鐘域,針對脈衝寬度只有1個clk的訊號 */

module fast_to_low

(//inputs

input clk_a,

//快速時鐘100mhz

input rst_n_a,

//復位訊號

input signal_a,

//快速時鐘訊號,單位元,1個clk寬度脈衝

input clk_b,

//慢速時鐘20mhz

input rst_n_b,

//outputs

output signal_b //同步之後的慢速時鐘域的訊號);

reg tmp;

reg tmp_reg1;

reg tmp_reg2;

reg tmp_reg3;

assign signal_b = tmp_reg2 ^ tmp_reg3;

//電平訊號轉換為邊沿

/* 在快速時鐘域下,把單clk脈衝訊號,轉換為邊沿訊號,在高電平時翻轉,要求兩個脈衝間隔時間不能太短 */

always @ (posedge clk_a)

begin

if(!rst_n_a)

tmp <=0;

else

if(signal_a)

tmp <=

~tmp;

end/* 在慢速時鐘域下對 */

always @ (posedge clk_b)

begin

if(!rst_n_b)

begin

tmp_reg1 <=0;

tmp_reg2 <=0;

tmp_reg3 <=0;

endelse

begin

tmp_reg1 <= tmp;

tmp_reg2 <= tmp_reg1;

tmp_reg3 <= tmp_reg2;

endendendmodule;

**tb檔案:

`timescale 1ns/

1psmodule top_tb;

reg clk_a;

//100mhz = 10ns;

reg clk_b;

//10mhz = 100ns;

reg rst_n_a;

reg rst_n_b;

reg signal_a;

//快速時鐘域訊號

wire signal_b;

//慢速時鐘域訊號

initial

begin

clk_a =1;

clk_b =1;

rst_n_a =0;

rst_n_b =0;

signal_a =0;

#300

rst_n_a =1;

rst_n_b =1;

#500

signal_a =1;

#10signal_a =0;

#500

//兩次脈衝時間間隔應該大於2*100ns=200ns,否則不能還原

signal_a =1;

#10signal_a =0;

#1000

$stop;

endalways #(10/

2) clk_a <=

!clk_a;

//100mhz = 10ns

always #(

100/

2) clk_b <=

!clk_b;

//10mhz = 100ns

fast_to_low fast_to_low_ut

(//inputs

.clk_a

(clk_a),.

rst_n_a

(rst_n_a),.

signal_a

(signal_a),.

clk_b

(clk_b),.

rst_n_b

(rst_n_b)

,//outputs

.signal_b

(signal_b));

endmodule

**波形:

跨時鐘域分析 單位元訊號同步

處理跨時鐘域的資料有單bit和多bit之分,而打兩拍的方式常見於處理單bit資料的跨時鐘域問題。打兩拍本質就是定義兩級暫存器對資料進行延拍。流程如下圖所示 兩級暫存器的原理 兩級寄存是一級寄存的平方,兩級並不能完全消除亞穩態危害,但是提高了可靠性減少其發生概率。總的來講,就是一級概率很大,改善不大。...

「單位元訊號同步」 學習筆記(跨時鐘域問題)

文章 1.概述 訊號同步的目的是防止新時鐘域中第一級觸發器 的亞穩態訊號對下一級邏輯造成影響。簡單的同步器由兩個觸發器串聯而成,中間沒有其它組合電路。這種設計可以保證後面的觸發器獲得前乙個觸發器輸出時 前乙個觸發器已退出了亞穩態,並且輸出已穩定。2.訊號同步的要求 為了使同步工作能正常進行 從某個時...

跨時鐘域訊號處理

一 場景描述 某訊號signal需要在不同的時鐘域進行處理,需要同步到的不同的時鐘域繼續使用。舉例說明 某定時器timer包含兩個時鐘域bus clk和tmr clk。狀態暫存器sts和控制暫存器ctrl定義如下。暫存器讀寫訪問採用bus clk時鐘,timer功能採用tmr clk時鐘,當發生溢位...