在fpga設計中,我們經常會使用分頻的方法來得到乙個我們需要的時鐘頻率,而在很多開發板廠家配套的教程裡,他們常常會使用計數器分頻得到的高低電平時鐘來當做驅動時鐘,這種方法簡單易懂,但是,在工程設計中,這種方法是不被允許的。
門控時鐘就是使用計數器和邏輯門翻轉來產生的時鐘,下面是典型的門控時鐘
//生成i2c的scl的四倍頻率的驅動時鐘用於驅動i2c的操作
always @(posedge sys_clk or negedge rst_n) begin
if(rst_n == 1'b0) begin
dri_clk <= 1'b1;
clk_cnt <= 10'd0;
endelse if(clk_cnt == clk_divide - 1'd1) begin
clk_cnt <= 10'd0;
dri_clk <= ~dri_clk;
endelse
clk_cnt <= clk_cnt + 1'b1;
end//(三段式狀態機)同步時序描述狀態轉移
always @(posedge dri_clk or negedge rst_n) begin
if(rst_n == 1'b0)
cur_state <= st_idle;
else
cur_state <= next_state;
end
在上面**中,先使用sys_clk生成乙個dri_clk,然後再使用dri_clk來驅動其他的電路,這種方法是絕對不允許的,主要有以下兩點原因:
1、dri_clk是由邏輯門生成的,會有可能產生毛刺
2、dri_clk經過了邏輯門,從sys_clk觸發到dri_clk穩定輸出會有一定的延遲,這樣dri_clk和sys_clk以及其他的門控時鐘會有一定的相位差,這在大型系統或者比較嚴格的系統中是很危險的。
時鐘使能的方法就能有效的解決以上兩個缺點
時鐘使能也會用到計數器,但是不會用到反相器,生成的訊號也不會直接用於其他電路的觸發,就以上面的**為例子進行修改,時鐘使能的**如下:
//生成i2c的scl的四倍頻率的驅動時鐘用於驅動i2c的操作
always @(posedge sys_clk or negedge rst_n) begin
if(rst_n == 1'b0) begin
dri_clk <= 1'b0;
clk_cnt <= 10'd0;
endelse if(clk_cnt == clk_divide - 1'd1) begin
clk_cnt <= 10'd0;
dri_clk <= 1'b1;
endelse begin
clk_cnt <= clk_cnt + 1'b1;
dri_clk <= 1'b0;
endend//(三段式狀態機)同步時序描述狀態轉移
always @(posedge sys_clk or negedge rst_n) begin
if(rst_n == 1'b0)
cur_state <= st_idle;
else
begin
if(dri_clk == 1'b1)
cur_state <= next_state;
else
;end
end
可以看到,在上面**中,也使用到了計數器,但是僅僅是用於產生乙個時鐘使能脈衝訊號,只持續乙個sys_clk。
而dri_clk也沒有直接用於驅動其他電路,在整個系統中,所有的時鐘都是sys_clk,這樣就不會有相位不匹配的問題存在了,而且也不會出現由於毛刺帶來的影響。
門控時鐘 使能時鐘的實現
在編寫fpga的時候我們常常會遇到這樣的問題 全域性時鐘的頻率太高了,某些模組需要頻率更低的時鐘來驅動,總是呼叫pll太浪費資源了。現在說說這種時候該怎麼辦 1.門控時鐘分頻 門控時鐘就是通過計數的方式來實現對全域性時鐘的分頻,滿足你對低頻時鐘的需求。基於計數器的分頻器不說了太基礎了,現在說說非整數...
GPIO時鐘使能和串列埠時鐘使能的關係
由於stm32有很多外設,為降低功耗,每個外設都對應著乙個時鐘。在晶元剛剛上電時,這些時鐘都是被關閉的。如果想要外設工作,必須把相應的時鐘開啟。即當gpio口復用usart進行通訊時,必須要先使能gpio的時鐘,然後再使能具體外設的時鐘 usart的時鐘 1.stm32微控制器的i o埠配置步驟 1...
clock gating門控時鐘
asic設計人員主要使用正邊沿觸發的d觸發器來生成暫存器。這些觸發器在每個時鐘週期被時鐘觸發 如果需要保持以前的值,通常使用mux多路器電路。圖1顯示了這個電路。雖然這個電路在概念上很簡單,但它可以通過幾種方式進行改進。圖2顯示了門控時鐘的等效電路。這個電路的效能更高,因為它從輸入到觸發器的時序關鍵...