Verilog HDL程序设计——基本要素
Verilog基本上熟悉了,繼續(xù)整理一下Verilog的學習筆記吧。前面記載了Verilog的結(jié)構(gòu),寫Verilog的結(jié)構(gòu)有了,但是該怎么寫呢?在寫之前就得了解一下Verilog的一些基本要素了,也就是Verilog是怎么一點一點寫出來的。
?
一、標識符與注釋前面已經(jīng)說到,模塊名的定義要符合標識符的定義,那么什么是標識符呢?它的語法是什么呢?
①標識符是賦給對象的唯一名稱,通過標識符可以提及相應的對象,Verilog語法將對轉(zhuǎn)義標識符中的字符逐個處理。
②標識符可以是字母、數(shù)字、下劃線和美元符$的組合,并且標識符的第一個字母必須是字母或者是下劃線。此外,在Verilog的標識符中,是區(qū)分大小寫的。
③Verilog中有一些關(guān)鍵字,簡單地了解就是,預定義好了的,用來說明語言節(jié)后的標識符,都是小寫的。標識符不能和關(guān)鍵字重復。
④Verilog中還有一種叫做轉(zhuǎn)義標識符的東西,定義為以\(反斜杠)符號開頭,以空白結(jié)尾(如一個空格)的字符。如\initial就是一個轉(zhuǎn)義字符。轉(zhuǎn)義標識符和關(guān)鍵字是不一樣的,比如\initial是非關(guān)鍵字,而initial是關(guān)鍵字。
語言中總需要一些注釋的,Verilog中兩種注釋方法:
①以/*開始注釋,*/結(jié)束注釋,即/* 注釋內(nèi)容*/,可以多行注釋。
②以//開頭,這種注釋只能注釋一行
二、常量對于一門語言,我們總可言考慮它的常量有哪些,變量有哪些,現(xiàn)在就讓我們看看Verilog中的常量有哪些吧。
(1)數(shù)值邏輯
數(shù)字邏輯就是一種狀態(tài),可言說說一種常量了,有下面的知識點/注意點:
①Verilog中有四種羅家數(shù)值:邏輯0,邏輯1,x:未知態(tài),Z高阻態(tài);其中x、z是不區(qū)分大小寫的;在verilog中,表達式和邏輯門輸入的z通常解釋為x,也就是不定態(tài),不能確定這個邏輯值是1還是0。
②實際電路中只有0或者1,沒有x和z,當你給電路中設置為x或z時,由編譯軟件或者綜合軟件等EDA軟件決定電路最終是0或者1.
(2)數(shù)值
一個數(shù)也是一種常量。
①Verilog中主要可以這么對數(shù)值進行組合,整數(shù)和實數(shù),有符號數(shù)和無符號數(shù)。在Verilog中,下劃線’_’可以隨意用在整數(shù)和實數(shù)中,沒有實際意義,只是提高了可讀性。
②對于Verilog中的整數(shù),可以分為簡單的十進制數(shù)和基數(shù)表示的整數(shù)。
One:簡單的十進制格式的整數(shù)定義為帶有“+”或者“-”操作符的數(shù)字序列,你如45表示十進制數(shù)45,-45表示十進制數(shù)-45。
注意,簡單的十進制數(shù)格式的整數(shù)代表一個有符號的數(shù),其中負數(shù)可使用兩種補碼形式表示。下面舉例子進行說明:
對于簡單的十進制32,它是一個有符號的數(shù),由于二進制中才對有無符號進行區(qū)分,因此它在二進制中,用6位表示就是100000或者用7位表示就是0100000(最高位是符號位);對于簡單的十進制數(shù)-15,在二進制中,用5位表示就是10001,用6位表示就是110001(最高位是符號擴展位)。
Two:基數(shù)格式的整數(shù)格式是:[位寬]’基數(shù) 數(shù)值,位寬是一個數(shù)值,表示數(shù)值位長,基數(shù)可以是二進制(b)、八進制(o)、十進制(d)、十六進制(h),字母不區(qū)分大小寫,不然7’d100表示7位的十進制數(shù)100。
③實數(shù)有十進制計數(shù)法(如2.0)和科學計數(shù)法,但是根據(jù)Verilog的定義,實數(shù)都通過四舍五入隱式的轉(zhuǎn)換為最相近的整數(shù)。
(3)字符串
字符串是雙引號內(nèi)的字符序列,不能分成多行寫。此外,字符串是8位ASCII值的序列,比如“char”這個字符串,就要8x4=32bit寄存器存儲它。一些綜合器是不支持字符串的。
(4)參數(shù)
通過parameter 、localparam等定義的參數(shù),也可以看成是常量,它們的格式記錄在前面一篇的博文里面了。
?
三、變量--數(shù)據(jù)類型?
在Verilog中,它的變量可以用另外的名稱代替:數(shù)據(jù)類型。Verilog的數(shù)據(jù)類型是一種“變量”,用來表示數(shù)字電路硬件中的數(shù)據(jù)存儲和傳送元素。Verilog中主要有兩大數(shù)據(jù)類型(變量):線網(wǎng)類型和寄存器類型。
(1)線網(wǎng)類型
①線網(wǎng)類型主要表示表示Verilog中的結(jié)構(gòu)化元件之間的物理連線,其數(shù)值由驅(qū)動單元決定;如果沒有驅(qū)動元件連接到網(wǎng)線上,則其默認值為高阻z。此外線網(wǎng)類型的變量只能用assign進行賦值驅(qū)動,不能在always中進行賦值。
(可綜合的線網(wǎng)類型:)
②線網(wǎng)類型中的wire變量是最常用的,它可以最為任何表達式的輸入,也可以用做assign語句和模塊例化的輸出。Wire的取值是0、1、x、z。此外雖然Verilog語法允許wire類型的數(shù)據(jù)變量允許多個驅(qū)動源,但是僅用于仿真當中,綜合中任何變量連接多個驅(qū)動源都是錯誤的。
③tri線網(wǎng)類型,這個類型與wire類型功能幾乎一樣,但是當總線上需要描述高阻態(tài)的特性時,用它來描述以跟wire進行區(qū)分。
④supply1和supply0線網(wǎng)類型:supply1用來對電源建模,即高電平1,;supply0用來對低電平進行建模,即低電平0。
(不可綜合,進用于仿真的線網(wǎng)類型:)
⑤wor(線或)、trior(三態(tài)或):專門用于單信號多驅(qū)動;
Wand(線與)、triand(三態(tài)與):專門用于多驅(qū)動源;
Trireg:具有電荷保持特性的連線;
Tri1:上拉電阻;tri0:下拉電阻。
(2)寄存器類型
①寄存器型變量,都有“寄存特性”,即在接受下一個賦值之前,將保持原值不變。寄存器變量沒有強度之分,且所以的寄存器類型變量都必須明確給出類型說明(無默認狀態(tài))。
(可綜合的寄存器類型:)
②最常用的是reg類型的寄存器變量。寄存器變量可以取任意長度,默認值未知,reg類型的數(shù)據(jù)可以是正值或者負值。但當一個reg類型的數(shù)據(jù)是一個表達式的操作數(shù)時,它的值被當做無符號數(shù),即正值(比如,你定義了reg ?[3:0] a;...a = -2;那么由于-2的補碼是1110,a中存儲的值是1110,也就是值其實是14)。
③integer類型,這種類型是整數(shù)寄存器類型,可以作為32位的普通寄存器使用,但是不能直接取這個變量的某一位,而是通過把這個變量賦予給一個32位的reg變量,對reg變量進行操作。
④賦值注意:賦值總是從最右端的位向最左端的位進行;任何多余的位將被截斷。此外由于整數(shù)的負數(shù)形式實質(zhì)上是以補碼向量表示的,因此需要注意賦值的位寬。
⑤reg的擴展類型——memory類型:reg ? [n-1:0] ? 存儲器名 ? [m-1:0] ;(表示深度是m,字寬是n的存儲器,可以存儲mxn個bit)。此外不能直接對memory進行讀寫,而是先定義一個地址寄存器,通過這個地址寄存器進行索引,再取值。
(不可綜合,僅用于仿真的寄存器變量有:)
⑥time類型:用于存儲和處理時間,只存儲無符號數(shù);
Real類型:實數(shù)類型;realtime類型;
由于這種電路設計中不常用,所以不過多記載。
?
四、運算符?
在Verilog中,所謂的運算符就是用來進行運算的,根據(jù)運算符所帶的操作數(shù)的個數(shù),可以分為單目、雙目、三目。然后我們還是喜歡根據(jù)功能進行劃分,大概有9種功能類型的運算符。
(1)賦值運算符
①賦值運算分為連續(xù)賦值和過程賦值。
②連續(xù)賦值語句,也成為數(shù)據(jù)流描述方式,用assign關(guān)鍵字表示,賦值符號是“=”,只能對線網(wǎng)賦值。
一個線網(wǎng)型變量一旦被連續(xù)賦值語句賦值之后,賦值語句右端賦值表達式的值將連續(xù)對被賦值變量產(chǎn)生連續(xù)驅(qū)動。只要右端表達式任一個操作數(shù)的值發(fā)生變化,就會立即出發(fā)對被賦值變量的更新操作。
③過程賦值,主要用于initial模塊和always模塊中的賦值語句。
在過程塊中,只能使用過程賦值語句,同時過程賦值語句也只能用在過程賦值模塊中。
過程賦值的賦值符號是“=”“<=”,分別表示阻塞賦值和非阻塞賦值。這兩種賦值在后面的章節(jié)中會有講解,前面寫的博文也有一些介紹:
http://www.cnblogs.com/IClearner/p/7188875.html 。
?
(2)算術(shù)運算符
①算術(shù)運算符又稱為二進制運算符,有+(加)、-(減)、*(乘)、/(除)、%(取余)。
②+、-、*是可以綜合的,/和%只有在除數(shù)或者模值是2的整數(shù)次(2、4、8...)的時候才是可以綜合。
③在進行乘除運算時,結(jié)果值會略去小數(shù)部分;在取余操作中,結(jié)果的符號位和取余運算第一位操作數(shù)的符號位保持一致(-12/(6/4),符號位與-12一致)。
④在進行基本算術(shù)運算時,如果某一操作數(shù)有不確定的值x,則運算結(jié)果也是不確定值x。
⑤算術(shù)表達式結(jié)果的位寬由位寬最大的操作數(shù)決定;在賦值賦值語句中(無論是連續(xù)還是過程賦值),算術(shù)操作的結(jié)果的位寬由操作符左端目標位寬決定;在較長的表達式中,中間結(jié)果的位寬應取最大操作數(shù)的位寬;此外由于位寬的關(guān)系,在運算是要進行位寬保留,也就是結(jié)果位寬取大一點,防止溢出。
⑥有無符號的算術(shù)運算討論:在設計中,所有的算術(shù)運算都是按照無符號數(shù)進行的;如果要完成有符號數(shù)的計算,對于加減操作,通過補碼處理即可用無符號加法完成;對于乘法操作,無符號數(shù)直接采用“*”操作,有符號數(shù),通過定義輸入輸出和中間變量的符號類型為signed來處理。
?
(3)邏輯運算符
①邏輯運算符有:邏輯與&&、邏輯或||和邏輯非!;其中&&和||是雙目運算符,運算結(jié)果是一位;!是單目運算符,結(jié)果是一位。
?
(4)關(guān)系運算符
①關(guān)系運算符有8種:大于(>)、大于等于(>=)、小于(<)、小于等于(<=)、邏輯相等(==)、邏輯不相等(!=)、全等(===)、全不等(!==)。
②關(guān)系運算符的結(jié)果是1位(包括1、0、x、z)。
③“===”和“!==”可以比較含有x和z的操作數(shù),但是由于實際硬件中不存在x態(tài)和z態(tài),在綜合時將按照“==”和“!=”來進行;其實際的功能僅用在仿真中。
?
(5)條件運算符
①條件運算符,三目運算符:(條件表達式)?():();
?
(6)位運算符
①位運算符有:按位與(&)、按位或(|)、按位反(~)、按位異或(^)、按位同或(^~或者~^)。除~外,都是雙目運算符。
②運算結(jié)果可能是多位(每一個操作數(shù)的對應位進行運算,得出的結(jié)果也是各個位運算“拼”起來的結(jié)果),不僅僅是1為,注意與邏輯運算符的區(qū)別!,此外如果兩個操作數(shù)的長度不相等,將會對較短的數(shù)進行高位補0,然后進行相應的位運算,使輸出結(jié)果的長度與位寬的操作數(shù)保持一致。
?
(7)拼接運算符
①拼接運算符可以將兩個或者更多信號的某些位拼接起來進行運算操作,{a1,b1,c1...}這樣子拼接,拼接運算也可以復制一個常量或者變量。
?
(8)移位運算符
①移位運算符有兩個:左移(<<)、右移(>>),移位過程中都用0來填補移出的空位,左移會引起位數(shù)擴大,而右移則不會(如4’b1101<<2 = 6’b110100);因此要注意移位后變量的位數(shù),以及存儲移位后結(jié)果的存儲器/線網(wǎng)位寬。
②左移相當于乘2,而右移相當于除2,在實際運算中,經(jīng)常通過不同移位數(shù)的組合來計算簡單的乘法和除法,比如result=data*19中,因為20=16 + 2 + 1=2^4+2^1+2^0,所以result = data<<4 + data<<1+data;(當然實際代碼中不是這樣的,而是在always塊中進行不同的移位,中間寄存器進行存儲移位結(jié)果,然后用assign語句進行加起來)
?
?
(9)一元簡約/歸約運算符
①一元歸約運算符是單目運算符,操作數(shù)放在右邊,操作符有歸約與(&)、歸約或(|)、歸約與非(~&)、歸約或非(~|)、歸約異或(^)、歸約同或(~^),運算形式是(?):首先將操作數(shù)的第一位和第二位進行相應的與、或等操作,然后再講運算結(jié)果和第三位進行操作,依次類推直至最后一位。
轉(zhuǎn)載于:https://www.cnblogs.com/IClearner/p/7252929.html
總結(jié)
以上是生活随笔為你收集整理的Verilog HDL程序设计——基本要素的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 滑动的TAB
- 下一篇: [JAVA #183; 0基础]:11.