摘要:本文是對實驗課上講解的面向硬件電路的設計思維的總結,結合數字邏輯課本,進行提煉和整理??梢娮枞x值描述時序電路有風險。
本文是對實驗課上講解的“面向硬件電路的設計思維”的總結,結合數字邏輯課本,進行提煉和整理。
主要來源是課件與本人整理,部分參考了網絡大佬的博客。
本文主要介紹不同于之前軟件設計思維的硬件設計思維,從非阻塞賦值、并行、面積速度轉換、同步電路設計原則、模塊劃分設計、if-case對比等方面進行整理。
內容太多,我整理了好幾天,在浩如煙海的網絡前有點無力,想想是自己的實踐不夠,有一些問題沒有親身體驗;也不能一蹴而就,得久久為功。所以這篇文章就當作一個Verilog學習與FPGA設計的總述性文章,后續繼續學習我會加深對這些知識的理解。
回憶一下課本上的相關內容。
阻塞賦值:
"="
Verilog編譯器按照這些語句在always塊中的先后順序依次執行。
如果一個變量通過阻塞賦值語句賦值,則這個新賦的值會在這個block中的后續語句中使用。
相當于串行
非阻塞賦值:
"<="
always塊中所有非阻塞賦值的語句在求值時所用的值是最初進入always時各個變量已經具有的值。
換一個角度講,"<="左側的被賦值變量,只在always結束時統一被更新。
相當于并行
先來看一看這段代碼:
1 module example5_5 (x1, x2, x3, Clock, f, g);2 input x1, x2, x3, Clock;3 output reg f, g;4 always @(posedgeClock)5 begin6 f=x1 & x2;7 g=f | x3;8end9endmodule
可以看到關鍵點是g的表達式,由于是阻塞賦值,所以相當于:
g=(x1 & x2) | x3;
綜合出的電路如圖:
1 module example5_6 (x1, x2, x3, Clock, f, g);2 input x1, x2, x3, Clock;3 output reg f, g;4 always @(posedge Clock)5 begin6 f <=x1 &x2;7 g <=f | x3;8 end9 endmodule
這個區別之處就在于這個g,是x3與前一個 f 進行"|"運算。
將阻塞賦值的示例代碼中的兩個執行語句互換位置,會發生什么情況?
可以料見影響比較大。
可見阻塞賦值描述時序電路有風險。
相反的,如果我們要實現 f=a1a0 + a2a1這樣一個函數;
1 always @(A)2 begin3 f=A[1] & A[0];4 f=f | (A[2] & A[1]);5 end
1 always @(A)2 begin3 f <=A[1] & A[0];4 f <=f | (A[2] & A[1]);5 end
可見這段代碼有兩個特征;
非阻塞賦值的結果在always結束后才可以看到
多次賦值時,后覆蓋前。
這兩個特征使得第二個f語句出現問題,因為第二個語句
f <=f | (A[2] & A[1]);
右側的f的值是不可見的。
對組合邏輯建模采用阻塞賦值
對時序邏輯建模采用非阻塞賦值
用多個always塊分別對組合和時序邏輯建模
盡量不要在一個always塊里面混合使用阻塞賦值和非阻塞賦值。如果在同一個塊即為組合邏輯又為時序邏輯,應使用“非阻塞賦值”
這里給的例子沒怎么看懂。自己查了一下。
先說結論:
各個always塊是并行執行的,
always塊和initial塊之間是并行執行的,
begin-end塊內是順序執行的,
但是非阻塞賦值(<=)是并行執行的,阻塞賦值(=)是順序執行的,這條優先。且硬件思想的集中體現就是前面提到過的非阻塞賦值帶來的并行執行語句。
再回去看例子:
1 module test ( clk, reset, a, b ); 2 input clk; 3 input reset; 4 input [3:0 ] a; 5 output [ 3:0 ] b; 6 7 reg [ 3:0] tempa1, tempa2, b; 8 9 always @ ( posedge clk ) begin10 if ( ! reset ) begin11 tempa1<=0;12tempa2<=0;13 b<=0;14 end15 elsebegin16 tempa1<=a + 1’b1;17tempa2<=tempa1 + 1’b1;18 b<=tempa2 + 1’b1;19 end20 end21 endmodule
可以料見實現的電路:
下面借鑒了這篇文章
波形圖:
可以看到強調的還是上面說過的非阻塞賦值的特點。
實驗任務里總有這么一句:“用可綜合的代碼......”
什么是可綜合性,什么又是不可綜合性呢?
下面學習了這篇文章
這篇文章講的挺多,但是我現在這個RTL級還沒搞明白的菜鳥用不到這么多,基本篩選如下:
不可綜合的Verilog語句:
initial
只能在test bench中使用,不能綜合。
assign 和deassign
不支持對reg 數據類型的assign或deassign進行綜合,支持對wire數據類型的assign或deassign進行綜合。
fork join 不可綜合,可以使用非塊語句達到同樣的效果。
這個塊是并行執行的,但是不可綜合。
敏感列表里同時帶有posedge和negedge 如:(現在也碰不到
1 always@(posedge clk or negedge clk) 2 begin3 ...4 end
這里我們說的面積:設計所占用的FPGA邏輯資源數目,一般用所消耗的觸發器和查找表(還沒學)來衡量。
速度:是指在芯片上可以穩定運行時能達到的最高頻率
兩者性能上的調配方法:
模塊復用
串并變換
可以看到這種串并轉換,用更大的面積(即多個子模塊并行),達到高頻率的效果。這一點后面還會再提到。
流水線
同步設計的優點:
可以有效避免毛刺的影響,提高設計的可靠性
可以簡化時序分析過程
可以減少工作環境對設計的影響
設計原則:
(由于應用還不多,對這些體會還不深刻,簡單記錄:
單時鐘
全局時鐘網絡的時鐘是性能最優,最便于預測的時鐘,具有最強的驅動能力
單時鐘沿
混合時鐘會使時序分析復雜、電路工作頻率降低
避免使用門控時鐘
即時鐘不要與組合邏輯再進行組合,如下:
可能引起毛刺、偏移
在模塊內部不要再產生時鐘了。
這有點像C++的封裝。
上一層模塊只負責下一層模塊的依據(即原材料),而具體行為互不相關。
這樣就保證了各個模塊的相對獨立性和內部結構的合理性,便于維護,也使得相同邏輯可以復用同一模塊。
在設計時,應盡量將模塊中的同步時序邏輯輸出信號以寄存器的形式送出,以便于綜合工具區分時序和組合邏輯;
并且時序輸出的寄存器應符合流水線設計思路,能工作在更高的頻率,以極大地提高模塊吞吐量。
流水線設計思路是什么?
就是將組合邏輯系統地分割,并在各個部分(分級)之間插入寄存器,并暫存中間數據的方法。 目的是將一個大操作分解成若干的小操作,每一步小操作的時間較小,所以能提高頻率,各小操作能并行執行,所以能提高數據吞吐率(提高處理速度)。
對于我這個初學者來說,邏輯復用和邏輯復制十分相似,了解后就知道確實不同,主要是涉及性能衡量尺度:速度和面積的統籌。
邏輯復用是通過提高工作頻率來節省面積的優化方法,經常用于存在多個資源可共享單元的設計中。
PS:相當于為了節省人力,而讓一個人干三個人的活。
10MHZ乘法器
兩個5MHZ乘法器
邏輯復制——面積換速度
邏輯復用是通過增加面積而改善設計時序的優化方法,經常用于調整信號的扇出。
舉例就類似于上面的面積換速度
鏈狀結構
樹狀結構
If語句指定了一個有優先級的編碼邏輯,
而case語句生成的邏輯是并行的,不具有優先級。
這里的if的優先級就引起一些其他問題:
1 always@(in0,in1,in2,in3) 2 begin 3 sel=2’b00 ; 4 if(in0) sel=2’b00 ; 5 else if(in1) sel=2’b01 ; 6 elseif(in2) sel=2’b10 ; 7 else if(in3) sel=2’b11 ; 8end 9//當這里in0和in1都==1時,se1=2b00而不是2b01;10 //這就是if-else的優先邏輯。
而case是并行的,沒有優先級。
if語句可以包含一系列的表達式;/有時甚至一個else就可以是一個二路選擇器。
而case語句比較的是一個公共的控制表達式。整個語句塊一起構成了一個多路選擇器。
這個很好理解。
通常if-else結構速度較慢,但占用的面積?。?/p>
case語句結構速度較快,但占用的面積較大。
嵌套的if語句如果使用不當,就會導致設計的更長延時。
如果想利用if語句來實現那些對延時要求苛刻的路徑,應將最高優先級給最遲到達的關鍵信號。(最小生成樹思想)。
有時為了兼顧面積和速度,可以將if和case語句合用。
1 //if-else實現四選一 2 module sdata_if (clk, reset, x, s, y); 3 input clk; 4 input reset; 5 input[3:0] x; 6 input [1:0] s; 7 output y; 8 9 reg y;10 always@(posedge clk)begin11 if(!reset)begin12 y<=0;13 end14 else begin15 if(s==2b00)16 y<=x[0];17 else if (s==2b01)18 y<=x[1];19 else if (s==2b10)20 y<=x[2];21 else 22 y<=x[3];23 end24 end25 endmodule
想象一下是什么電路?
就是一個四選一,需要兩位的控制信號,這個控制信號就正好是s。
1 //case語句 2module sdata_if (clk, reset, x, s, y); 3 input clk; 4 input reset; 5 input[3:0] x; 6 input [1:0] s; 7 output y; 8 9 reg y;10 always@(posedge clk)begin11 if(!reset)begin12 y<=0;13 end14 else begin15 case(s)16 2b00: y<=x[0];17 2b01: y<=x[1];18 2b10: y<=x[2];19 2b11: y<=x[3];20 end21 end22 endmodule2324
實現電路也是類似上面的電路。
鎖存器在課本里學過,是用于存儲一位數據的元件,電平觸發。
其特點是:鎖存器在不鎖存數據時,輸出隨輸入變化;但一旦數據鎖存時,輸入對輸出不產生任何影響。
而我們在設計電路時,應該避免無意之間產生這種鎖存器,否則會導致一些邏輯上的錯誤。
引起意外鎖存器的原因
翻閱了很多網上的總結。有一些規則比較復雜,考慮到我現在的水平,我只記錄對初入門水平夠用且好理解的方面。后續繼續學習可以深入了解更多。
if……else……結構中缺少else
case結構中的分支沒有包含所有情況且沒有default語句。
如果使用if語句,最好寫上else分支;
如果使用case語句,最好寫上default語句。
即使需要鎖存器,也通過else分支或default分支來顯式說明。而不要利用語言特性觸發生成(因為不可控)
內容真的好多,一時間難以完全消化...
上傳于2021年11月25日23時
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/125363.html
摘要:將經過仿真的設計下載到硬件實驗箱進行驗證。流水燈控制電路仿真如圖所示實驗引腳鎖定八個按鍵按鍵分別對應上的引腳。 一、實驗目的 (1)學習并掌握Quartus II的...
摘要:本章我們將使用高速芯片實現數模轉換,產生正弦波模擬電壓信號。實驗任務本節實驗任務是使用新起點開發板及雙路高速擴展模塊模塊實現數模轉換。下載驗證將雙路高速模塊插入新起點開發板的擴展口,連接時注意擴展口電源引腳方向和開發板電源引腳方向一致。 ...
摘要:本文就關于電子元件國產化的一些交流內容進行介紹。一些重要的工業領域的國產化要求越來越高,也會對高端的需求增加。 前幾天發表的工業控制領域電子元件全國產化替代解讀文章也有一些關注與討論,這個文章有人說是軟文,想想也像是軟文,不過里邊提到的任一個廠家都沒有給贊助,也是很無奈。文章主要目的是把我接...
摘要:為了應對計算多元化的需求,越來越多的場景開始引入等硬件進行加速,異構計算應運而生。眾所周知,意味著對計算力的超高要求,目前以為代表的異構計算已成為加速創新的新一代計算架構。目前異構計算使用最多的是利用來加速。在互聯網行業,隨著信息化的普及,數據量的暴增使得人們對存儲空間又有了新要求,同時,機器學習、人工智能、無人駕駛、工業仿真等領域的崛起,使得通用CPU在處理海量計算、海量數據/圖片時遇到越...
閱讀 730·2023-04-25 19:43
閱讀 3974·2021-11-30 14:52
閱讀 3801·2021-11-30 14:52
閱讀 3865·2021-11-29 11:00
閱讀 3796·2021-11-29 11:00
閱讀 3894·2021-11-29 11:00
閱讀 3571·2021-11-29 11:00
閱讀 6154·2021-11-29 11:00