【從零開始走進(jìn)FPGA】對立統(tǒng)一——異步時鐘同步化
一、什么是對立統(tǒng)一
本文引用地址:http://butianyuan.cn/article/269614.htm什么是CEO,就是首席執(zhí)行官,是在一個企業(yè)中負(fù)責(zé)日常經(jīng)營管理的最高級管理人員,又稱作行政總裁,或最高執(zhí)行長或大班。
那么,在FPGA系統(tǒng),需不需要一個最高級別的執(zhí)行官,來管理所有進(jìn)程呢?為了系統(tǒng)的有序性,不至于凌亂、崩潰,答案必然是肯定的。
誰都知道,FPGA內(nèi)部時序邏輯的工作,是通過時鐘的配合來完成任務(wù)的。那么當(dāng)系統(tǒng)中有異步時鐘的時候,怎么辦?每一個系統(tǒng)必須有一個最高級別的時鐘,執(zhí)行力最強;同時它擔(dān)任著管理異步時鐘的任務(wù),其它異步時鐘想讓手下執(zhí)行任務(wù),必須告訴執(zhí)行官,然后執(zhí)行官去分配任務(wù)。所以,一切行動,都必須通過首席執(zhí)行官的允許,才能進(jìn)行;不然,沒門。首席執(zhí)行官具有最高支配權(quán)。它們之間的關(guān)系如下圖所示:
因此,對于工程中出現(xiàn)的異步時鐘,與最高時鐘是對立關(guān)系,但這個CEO的地位決定了只有他說了算,不然就會“叛亂”,因此要把那些異步時鐘統(tǒng)一管理,這就是所謂的“對立統(tǒng)一”。
二、異步時鐘同步化
1. 異步時鐘種類
異步時鐘有很種類,如下是幾種項目中常常出現(xiàn)的情況
(1)系統(tǒng)異步復(fù)位信號
(2)由其它處理器輸入的時鐘
(3)內(nèi)部組合邏輯產(chǎn)生的時鐘
當(dāng)然也并非所有異步時鐘都要同步化,必須高速ADC,DAC芯片往往有個時鐘輸入端,這時保證該芯片與該部分邏輯電路同步,可以專門供給一個晶振,來達(dá)到更好的效果;同時也不是最高時鐘以外的時鐘都要同步化,由PLL產(chǎn)生的不同的時鐘,本身就是同步的,可以不處理。
當(dāng)然在可靠性要求不高的時候,異步復(fù)位這些信號也可以不處理,只是,養(yǎng)成良好的習(xí)慣,永遠(yuǎn)不會錯。
2. 異步時鐘解決方案
對于時鐘的同步,采用的方法都差不多。Bingo在特權(quán)的《深入淺出玩轉(zhuǎn)FPGA》中得到啟發(fā),相應(yīng)的簡單的描述一下幾種關(guān)于異步復(fù)位信號的同步化。
(1)異步復(fù)位信號的同步化
此部分其實很簡單,應(yīng)用了上述邊沿檢測的部分思維,用最高時鐘打慢幾拍,便實現(xiàn)了與最高時鐘的同步。此處不再用Block來累贅的描述,verilog設(shè)計代碼如下所示:
/*****************************************************
* Module Name : synchronism_design.v
* Engineer : Crazy Bingo
* Target Device : EP2C8Q208C8
* Tool versions : Quartus II 11.0
* Create Date : 2011-6-25
* Revision : v1.0
* Description :
*****************************************************/
module synchronism_design
(
input clk,
input rst_n,
output sys_rst_n
);
//------------------------------------------
//rst_n synchronism, is controlled by the input clk
reg rst_nr1, rst_nr2;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
rst_nr1 <= 1'b0;
rst_nr2 <= 1'b0;
end
else
begin
rst_nr1 <= 1'b1;
rst_nr2 <= rst_nr1;
end
end
assign sys_rst_n = rst_nr2; //active low
endmodule
Quartus II RTL圖如下:
(2)PLL協(xié)作時異步復(fù)位信號同步化
相對于上述異步復(fù)位信號同步化方法的擴展,分析存在PLL環(huán)情況下的對信號的處理。如下verilog代碼所示,先用晶振輸入時鐘對異步復(fù)位信號進(jìn)行同步化,最后通過與PLL輸出信號locked與前面產(chǎn)生的同步復(fù)位信號與操作,得到最后的系統(tǒng)復(fù)位信號。
具體Verilog代碼如下所示:
/*****************************************************
* Module Name : synchronism_pll_design.v
* Engineer : Crazy Bingo
* Target Device : EP2C8Q208C8
* Tool versions : Quartus II 11.0
* Create Date : 2011-6-25
* Revision : v1.0
* Description :
*****************************************************/
module synchronism_pll_design
(
input clk, //50MHz
input rst_n, //global reset
output sys_rst_n, //system reset
output clk_c0 //50MHz
);
//----------------------------------------------
//rst_n synchronism, is controlled by the input clk
wire pll_rst;
reg rst_nr1,rst_nr2;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
rst_nr1 <= 1'b0;
rst_nr2 <= 1'b0;
end
else
begin
rst_nr1 <= 1'b1;
rst_nr2 <= rst_nr1;
end
end
assign pll_rst = ~rst_nr2; //active High
//----------------------------------------------
//sys_rst_n synchronism, is control by the highest output clk
wire locked;
wire sysrst_nr0 = rst_nr2 & locked;
reg sysrst_nr1, sysrst_nr2;
always @(posedge clk_c0 or negedge sysrst_nr0)
begin
if(!sysrst_nr0)
begin
sysrst_nr1 <= 1'b0;
sysrst_nr2 <= 1'b0;
end
else
begin
sysrst_nr1 <= 1'b1;
sysrst_nr2 <= sysrst_nr1;
end
end
assign sys_rst_n = sysrst_nr2; //active Low
//----------------------------------------------
//Component instantiation
pll pll
(
.areset (pll_rst),
.inclk0 (clk),
.c0 (clk_c0),
.locked (locked)
);
endmodule
Quartus II RTL圖如下所示:
(3)外輸入異步信號同步化
當(dāng)外面輸入異步時鐘或者異步信號的時鐘,一律轉(zhuǎn)換為使能時鐘。此方法與前一張接關(guān)于邊沿檢測的講述一樣,此處不做累贅講解。
(4)系統(tǒng)同步信號最優(yōu)化設(shè)計方案
當(dāng)FPGA剛上電的短暫時間內(nèi),所有邏輯塊上電,多多少少需要一定的時間(盡管非常短暫)。在一般時序要求不高的項目中,似乎可以忽略不計。但對于是需要求非常嚴(yán)格的操作,這幾十ns或者ms上電時,F(xiàn)PGA內(nèi)部是相當(dāng)不穩(wěn)定的。因此,在同步異步信號的同時,先將整個系統(tǒng)工作延時一定時間,將會在一定程度上得到更穩(wěn)定的運行結(jié)果。同時,處理后FPGA內(nèi)部真正開始工作實在系統(tǒng)上電穩(wěn)定后進(jìn)行的,因此相應(yīng)邏輯時序等,更穩(wěn)定準(zhǔn)確。
以下是Bingo在實際項目中遇到的問題的解決方案。經(jīng)過對系統(tǒng)進(jìn)行100ms延時的處理后,本來容易出錯的系統(tǒng),在沒出現(xiàn)過異常。
具體verilog代碼如下所示:
/***************************************************
* Module Name : synchronism_pll_delay_design.v
* Engineer : Crazy Bingo
* Target Device : EP2C8Q208C8
* Tool versions : Quartus II 11.0
* Create Date : 2011-6-25
* Revision : v1.0
* Description :
****************************************************/
module synchronism_pll_delay_design
(
input clk, //50MHz
input rst_n, //global reset
output sys_rst_n, //system reset
output clk_c0 //50MHz
);
//----------------------------------------------
//rst_n synchronism, is controlled by the input clk
reg rst_nr1,rst_nr2;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
rst_nr1 <= 1'b0;
rst_nr2 <= 1'b0;
end
else
begin
rst_nr1 <= 1'b1;
rst_nr2 <= rst_nr1;
end
end
//----------------------------------
//component instantiation for system_delay
wire delay_ok;
system_delay system_delay_inst
(
.clk (clk),
.delay_ok (delay_ok)
);
wire pll_rst = ~rst_nr2 & ~delay_ok; //active High
//----------------------------------------------
//Component instantiation
pll pll
(
.areset (pll_rst),
.inclk0 (clk),
.c0 (clk_c0),
.locked (locked)
);
//----------------------------------------------
//sys_rst_n synchronism, is control by the highest output clk
wire locked;
wire sysrst_nr0 = rst_nr2 & locked & delay_ok;
reg sysrst_nr1, sysrst_nr2;
always @(posedge clk_c0 or negedge sysrst_nr0)
begin
if(!sysrst_nr0)
begin
sysrst_nr1 <= 1'b0;
sysrst_nr2 <= 1'b0;
end
else
begin
sysrst_nr1 <= 1'b1;
sysrst_nr2 <= sysrst_nr1;
end
end
assign sys_rst_n = sysrst_nr2; //active Low
endmodule
//################################################//
//################################################//
module system_delay
(
input clk, //50MHz
output delay_ok
);
//------------------------------------------
// Delay 100ms for steady state
reg [22:0] cnt;
always@(posedge clk)
begin
if(cnt < 23'd50_00000) //100ms
cnt <= cnt + 1'b1;
else
cnt <= cnt;
end
//------------------------------------------
//sys_rst_n synchronism
assign delay_ok = (cnt == 23'd50_00000)? 1'b1 : 1'b0;
endmodule
Quartus II RTL圖如下所示:
fpga相關(guān)文章:fpga是什么
晶振相關(guān)文章:晶振原理
評論