前言
學(xué)習(xí)說明此文檔為本人的學(xué)習(xí)筆記,對一下資料進(jìn)行總結(jié),并添加了自己的理解。
一、基本概念
????????如果拿到了數(shù)字電路技術(shù)基礎(chǔ)的書,翻開書本的目錄你會發(fā)現(xiàn),關(guān)于鎖存器的章節(jié)與內(nèi)容非常少,也就是在觸發(fā)器前面有一小節(jié)進(jìn)行了簡單說明。但是真的就這么簡單么?
答案是否定的。
????????在組合邏輯電路與時序邏輯電路中間夾了一章觸發(fā)器,而觸發(fā)器作為了時序邏輯電路的基本構(gòu)成單元,而鎖存器是構(gòu)成觸發(fā)器的基本結(jié)構(gòu)(卻不是時序邏輯電路的構(gòu)成單元),但是鎖存器又是通過組合電路得來的(鎖存器嚴(yán)格來說屬于組合邏輯電路)。
上面那個問題的答案解釋呼之欲出,鎖存器不就是組合邏輯電路與時序電路的橋梁么?人們發(fā)現(xiàn)了鎖存器才進(jìn)一步有了觸發(fā)器(由于鎖存器有觸發(fā)器的儲存特性,有的教材也將其歸為觸發(fā)器,我認(rèn)為這樣是不合理的),進(jìn)而才有了時序邏輯電路。
1、組合邏輯電路與時序邏輯電路
數(shù)字電子技術(shù)基礎(chǔ)主要分為組合邏輯電路與時序邏輯電路
組合邏輯電路:由門電路組成,其某一時刻的輸出狀態(tài)只與該時刻的輸入狀態(tài)有關(guān),而與電路原來的狀態(tài)無關(guān),并沒有記憶功能。
時序邏輯電路:由鎖存器、觸發(fā)器和寄存器等單元組成,其某一時刻的輸出狀態(tài)不僅與該時刻的輸入狀態(tài)有關(guān),而且與電路原來的狀態(tài)有關(guān),具有記憶功能。
2、基本邏輯儲存單元
(1)鎖存器(latch)
????????鎖存器(latch)是一種在異步電路系統(tǒng)中,對輸入信號電平敏感的單元,用來存儲信息。鎖存器在數(shù)據(jù)未鎖存時,輸出端的信號隨輸入信號變化,此時信號通過鎖存器就相當(dāng)于通過了一個緩存器,一旦鎖存信號有效,則數(shù)據(jù)被鎖存,輸入信號不起作用。因此鎖存器也被稱為透明鎖存器,指的是不鎖存時輸出對于輸入是透明的。
《數(shù)字電子技術(shù)基礎(chǔ)》上的SR鎖存器的定義:
SR鎖存器實際上是一個組合邏輯電路,在時序分析時模型就等效為兩個各組合電路互為反饋的反饋系統(tǒng),因此,系統(tǒng)有可能會因為瞬態(tài)特性不穩(wěn)定而產(chǎn)生振蕩現(xiàn)象。
(2)觸發(fā)器(flip-flop)
????????觸發(fā)器分為電平觸發(fā)、脈沖觸發(fā)、邊沿觸發(fā)。觸發(fā)器是構(gòu)成時序邏輯電路的基本單元,能夠存儲1位二值信號的基本單元電路統(tǒng)稱觸發(fā)器(Flip-Flop)。為實現(xiàn)記憶1位二值信號功能,觸發(fā)器具備以下兩個基本特點:具有兩個能自行保持的穩(wěn)定狀態(tài),用來表示邏輯狀態(tài)0和1。在觸發(fā)信號的操作下,根據(jù)輸入信號可以將觸發(fā)器置為0或1。
可以清楚的看到相對于SR鎖存器,SR觸發(fā)器增加了CLK觸發(fā)端,這樣就能夠在時序電路中通過控制CLK端來控制SR觸發(fā)器,而在時序電路中SR鎖存器只有在時鐘平穩(wěn)時才可以控制。?
?(3)寄存器(register)
????????寄存器(register)用來暫時存放參與運算的數(shù)據(jù)和運算結(jié)果。在實際的數(shù)字系統(tǒng)中,通常把能夠用來存儲一組二進(jìn)制代碼的同步時序邏輯電路稱為寄存器。
區(qū)別與聯(lián)系:由于觸發(fā)器內(nèi)有記憶功能,因此利用觸發(fā)器可以方便地構(gòu)成寄存器。由于一個觸發(fā)器能夠存儲一位二進(jìn)制碼,所以把 n 個觸發(fā)器的時鐘端口連接起來就能構(gòu)成一個存儲 n 位二進(jìn)制碼的寄存器。
????????從寄存數(shù)據(jù)的角度來講,寄存器和鎖存器的功能是相同的;它們的區(qū)別在于寄存器是同步時鐘控制,而鎖存器是電位信號控制。 一般的設(shè)計規(guī)則是:在絕大多數(shù)設(shè)計中避免產(chǎn)生鎖存器。它會讓您設(shè)計的時序完蛋,并且它的隱蔽性很強,非老手不能查出。
3、異步電路與同步電路
異步電路:異步電路主要是組合邏輯電路,用于產(chǎn)生FIFO或RAM的讀寫控制信號脈沖,但它同時也用在時序電路中,此時它沒有統(tǒng)一的時鐘,狀態(tài)變化的時刻是不穩(wěn)定的,通常輸入信號只在電路處于穩(wěn)定狀態(tài)時才發(fā)生變化。
同步電路:同步電路是由時序電路(寄存器和各種觸發(fā)器)和組合邏輯電路構(gòu)成的電路,其所有操作都是在嚴(yán)格的時鐘控制下完成的。這些時序電路共享同一個CLK,而所有的狀態(tài)變化都是在時鐘的上升沿(或下降沿)完成的。
二、鎖存器(Latch)
1、Latch??
????????在進(jìn)行FPGA開發(fā)的過程中,經(jīng)常會在編譯程序時發(fā)現(xiàn)有一些warning提示生成了一些latch,而且一般FPGA的設(shè)計規(guī)則也不建議有l(wèi)atch生成。在Verilog對FPGA開發(fā)時,有時語法正確的代碼不一定電路就是合理的。
? ? ? ? 當(dāng)你在FPGA開發(fā)時想組合出純組合邏輯電路(沒有時鐘控制端),但有時候你的代碼最后綜合出的結(jié)果卻是“組合邏輯電路+鎖存器(觸發(fā)器)”。這說明在你的Verilog代碼中有保持不變的情況,這種“保持輸出不變”的行為意味著需要記住當(dāng)前的狀態(tài),由于組合邏輯中的門電路是無法儲存狀態(tài)的,此時代碼綜合后就會產(chǎn)生鎖存器(Latch),來儲存產(chǎn)生的狀態(tài)。這就是組合邏輯中產(chǎn)生Latch的主要原因。
? ? ? ? 在組合邏輯電路中產(chǎn)生的Latch,在同步電路中盡量避免,但并不表示沒用或者是錯誤的,Latch在異步電路中是非常有用的,只是我們設(shè)計的是同步電路,要盡量避免。
2、Latch的特點及危害
(1)對毛刺敏感
使能信號有效時,輸出狀態(tài)可能隨輸入多次變化,產(chǎn)生空翻,對下一級電路很危險,不能異步復(fù)位,因此在上電后處于不確定的狀態(tài)。并且其隱蔽性很強,不易查出。因此,在設(shè)計中,應(yīng)盡量避免latch的使用。
(2)不能異步復(fù)位
由于其能夠儲存上次狀態(tài)的原因,上電后Latch處于不定態(tài)。
(3)復(fù)雜的靜態(tài)時序電路分析
首先,鎖存器沒有時鐘信號參與信號傳遞,無法做STA;其次,綜合工具會將 latch 優(yōu)化掉,造成前后仿真結(jié)果不一致。
(4)占用更多資源
在FPGA中基本的單元是由查找表和觸發(fā)器組成的,大部分器件沒有鎖存器這個東西,若生成鎖存器反而需要更多的資源。(不同的觀點:當(dāng)然,目前網(wǎng)上還有一種說法是FPGA中只有LUT和FF的資源,沒有現(xiàn)成的Latch,所以如果要用Latch,需要更多的資源來搭出來。但這一觀點,是錯誤的??!——因為每一個slice包含F(xiàn)F和latch通用的資源。)
(5)額外的延時
在ASIC設(shè)計中,鎖存器也會帶來額外的延時和DFT,并不利于提高系統(tǒng)的工作頻率。
(6)鎖存器的優(yōu)點
?如果鎖存器和觸發(fā)器兩者都由與非門搭建的話,鎖存器耗用的邏輯資源要比D觸發(fā)器少(D觸發(fā)器需要12個MOS管,鎖存器只需6個MOS管),鎖存器的集成度更高,所以在ASIC設(shè)計中會用到鎖存器,且只有在CPU高速電路或者RAM這種面積很敏感的電路才使用鎖存器。
綜上所述
根據(jù)鎖存器的特點可以看出,在電路設(shè)計中,要對鎖存器特別謹(jǐn)慎,如果設(shè)計經(jīng)過綜合后產(chǎn)生出和設(shè)計意圖不一致的鎖存器,則將導(dǎo)致設(shè)計錯誤,包括仿真和綜合。因此,在設(shè)計中需要避免產(chǎn)生意想不到的鎖存器。如果組合邏輯的語句完全不使用 always 語句塊,就可以保證綜合器不會綜合出鎖存器。雖然在的ASIC設(shè)計中會用到鎖存器。但鎖存器對毛刺敏感,無異步復(fù)位端,不能讓芯片在上電時 處在確定的狀態(tài);另外,鎖存器會使靜態(tài)時序分析變得很復(fù)雜,不利于設(shè)計的可重用。
3、Latch的產(chǎn)生情況及避免
Latch一般產(chǎn)生在組合邏輯電路的always中,主要有三種情況:
(1)組合邏輯中if語句中沒有else
module decoder3_8(
input wire in_1,
input wire in_2,
input wire in_3,
output reg [7:0] out
);
//情況一:組合邏輯中if語句中沒有else
always@(*)
if( {in_1, in_2, in_3} == 3'b000 )
out = 8'b0000_0001;
else if({in_1, in_2, in_3} == 3'b001)
out = 8'b0000_0010;
else if({in_1, in_2, in_3} == 3'b010)
out = 8'b0000_0100;
else if({in_1, in_2, in_3} == 3'b011)
out = 8'b0000_1000;
else if({in_1, in_2, in_3} == 3'b100)
out = 8'b0001_0000;
else if({in_1, in_2, in_3} == 3'b101)
out = 8'b0010_0000;
else if({in_1, in_2, in_3} == 3'b110)
out = 8'b0100_0000;
else if({in_1, in_2, in_3} == 3'b111)
out = 8'b1000_0000;
// else //去除esle產(chǎn)生latch(鎖存器)
// out = 8'b0000_0001;
endmodule
?如圖進(jìn)行RTL代碼邏輯綜合后出現(xiàn)了latch
(2)組合邏輯中case的條件不能夠完全列舉且沒有default
module decoder3_8(
input wire in_1,
input wire in_2,
input wire in_3,
output reg [7:0] out
);
always@(*)
case ({in_1, in_2, in_3})
3'b000 : out = 8'b0000_0001;
3'b001 : out = 8'b0000_0010;
3'b010 : out = 8'b0000_0100;
3'b011 : out = 8'b0000_1000;
3'b100 : out = 8'b0001_0000;
3'b101 : out = 8'b0010_0000;
3'b110 : out = 8'b0100_0000;
// 3'b111 : out = 8'b1000_0000;
// default : out = 8'b0000_0001; //latch的產(chǎn)生
endcase
endmodule
RTL代碼邏輯綜合后產(chǎn)生latch?
?(3)組合邏輯中輸出變量賦值給自己
module decoder3_8(
input wire in_1,
input wire in_2,
input wire in_3,
output reg [7:0] out
);
//情況三:組合邏輯中輸出變量賦值給自己(一)
always@(*)
if( {in_1, in_2, in_3} == 3'b000 )
out = 8'b0000_0001;
else if({in_1, in_2, in_3} == 3'b001)
out = 8'b0000_0010;
else if({in_1, in_2, in_3} == 3'b010)
out = 8'b0000_0100;
else if({in_1, in_2, in_3} == 3'b011)
out = 8'b0000_1000;
else if({in_1, in_2, in_3} == 3'b100)
out = 8'b0001_0000;
else if({in_1, in_2, in_3} == 3'b101)
out = 8'b0010_0000;
else if({in_1, in_2, in_3} == 3'b110)
out = 8'b0100_0000;
else if({in_1, in_2, in_3} == 3'b111)
out = 8'b1000_0000;
else
out = out; //產(chǎn)生latch(鎖存器)
endmodule
module decoder3_8(
input wire in_1,
input wire in_2,
input wire in_3,
output reg [7:0] out
);
//情況三:組合邏輯中輸出變量賦值給自己(二)
always@(*)
case ({in_1, in_2, in_3})
3'b000 : out = 8'b0000_0001;
3'b001 : out = 8'b0000_0010;
3'b010 : out = 8'b0000_0100;
3'b011 : out = 8'b0000_1000;
3'b100 : out = 8'b0001_0000;
3'b101 : out = 8'b0010_0000;
3'b110 : out = 8'b0100_0000;
3'b111 : out = out; //latch的產(chǎn)生
default : out = 8'b0000_0001;
endcase
endmodule
?綜上所述:
在組合邏輯電路的always中,if-else語句中不能缺少else;case語句中條件不能夠完全列舉或缺少default;在if-else和case中均不能出現(xiàn)變量自己將值賦給自己。
本文檔參考資料
?學(xué)習(xí)視頻:是根據(jù)野火FPGA視頻教程——第十講
https://www.bilibili.com/video/BV1nQ4y1Z7zN?p=3
學(xué)習(xí)資料:《數(shù)字電子技術(shù)基礎(chǔ)》清華大學(xué)出版社,請參考本人的學(xué)習(xí)筆記專欄:
https://blog.csdn.net/arm_qiao/category_11744079.htmlhttps://blog.csdn.net/arm_qiao/category_11744079.html《Verilog HDL數(shù)字設(shè)計與綜合》第二版
參考文章:文章來源:http://www.zghlxwxcb.cn/news/detail-792605.html
http://t.csdn.cn/jyTNF、http://t.csdn.cn/MBORd、http://t.csdn.cn/k6HTQ文章來源地址http://www.zghlxwxcb.cn/news/detail-792605.html
到了這里,關(guān)于二、8【FPGA】Verilog中鎖存器(Latch)原理、危害及避免的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!