2011年12月31日 星期六

2011/12/19 Verilog上機考試

上機考程式碼: 

執行結果:











這次的題目化減得到了六項,
因此有六個and閘。

2011/12/26 Verilog運算元和連續指定

Verilog除了有很多從C語言照搬過來的運算子外,
也有許多為了方便設計IC而產生的運算子,
(筆者不能百分之百確定運算子的新舊,因筆者對C語言位元處理的部分並沒有多加深入)
數值運算子的部分,
舉凡加減乘除等全部都和C語言一樣,
這裡就不再多加描述。

位元運算子的部分,
有"<<"的左移運算子,
或是相反的右移運算子等等的,
種類並不多。

邏輯運算子的部分,
常見的"&&"和"||"並無任何改變,
但令人感到特別的是"?"加上":"的"if、else"簡化版也出現在Verilog之中。
還有對應not的"~"邏輯運算元,
只要變數前面加了"~"就是not的意思。

Verilog中有x的unknow信號和z的high xxx信號,
前者為短路的象徵,
後者則是開路的象徵,
對應這兩種情況,
Verilog有===、!==這兩種新的邏輯運算子來判斷是否發生這樣的情況。
若只用==和!=,碰到上述情況就會給出x的判斷結果,
進而造成錯誤。

連續指定的部分的關鍵是assign,
他也是無窮迴圈的一種,
透過這個無窮迴圈,
再加上運算子和變數設值的計算,
也可以變成一個類似的邏輯閘,
但這個部分偏理念上的設計,
若直接透過電腦佈局,
只會得到失敗的情況,
若要成功,
還是得用老實的方式把接腳的線一步步拉出來,
最近有出一顆新型的CPU,
它的效能不理想的原因據傳是因為太過仰類電腦佈局的結果,
以前數位邏輯也有將邏輯閘以最複雜的方式呈現,
那都是為了可以透過電腦來工作,
但現今人工智慧還不夠成熟,
若要有個優良的IC,
還是得靠人的智慧一步一腳印的慢慢實踐。

2011/11/21 Verilog程序指定

Verilog是由C語言寫出來的程式語言,
理所當然的,
C語言的精隨幾乎都可以在Verilog中被拿出來使用,
這次程序指定所要看的是一些C語言常見的程式用法。

之前所介紹的initial的功能是指告訴編譯器程式的執行起點在這裡,
在initial裡面,
我們可以為變數設初值,
例如:
    i = 2;
    j = 4;
當我們使用C語言時,
若要使兩個變數的值對調,
那我們必須再設一個k變數當中介者,
但Verilog裡的信號延遲"#"可以讓這件事情原封不動的只用兩個變數就完成,
範例如下:















圖中可以注意到,
若display沒有延遲那麼會印出時間為零的時候的i和j,
所以要得到變換後的i、j之值,
則必定要延遲印出的時間。
順帶一提,
begin和end就像是C語言的中括號,
同樣使用這種型式代替中括號的語言還有MATLAB。

C語言中只要對for、while、do while下個不可能達成的條件,
就可以完成無窮迴圈,
Verilog是個設計IC的程式語言,
一顆IC我們都是希望設計出來就是通著電,
然後一直照我們的設定不斷的工作,
因為這樣的重要特性,
Verilog將無窮迴圈交由always函數來處理,
always的條件寫法和while相似,
但always再條件括號前要加個"@",
而內部的條件判斷對應IC中相當重要的時脈信號,
可以有"posedge"、"negaedge"兩種正緣或負緣觸發的兩種判斷條件,
只要滿足就動作,
一直工作到記憶體使用完畢,
或是達到外部條件達成為止。
同樣的這些都不是IC佈局時該出現的東西。

if、和else的用法同C語言,
這裡就不在多加描述。

2011年12月30日 星期五

2011/11/14 Verilog之檔案輸出

Verilog本身是由C語言所寫成,
那麼C語言的功能幾乎是應有盡有,
檔案輸出當然也不在話下。

Verilog的檔案輸出和C語言極為類似,
首先得宣告一個變數用來當作檔案的指標,
並且透過指標的名稱來修改檔案的內容,
至於檔案開啟的函數則和C語言一樣是fopen,
若今天宣告一個變數叫f,
那我就對f進行fdisplay的函數,
就可以在檔案裡面寫下文字,
範例如下:














範例中的檔案被命名為testfileopen,
如果編譯器在資料夾內找不到這個檔案,
就會自動新增一個,
而檔案會建立在CAD的資料夾之中:


如果要調查內容是否正確,
可以透過輔助軟體來檢查:





內容和當初期望的一模一樣,
且裡面出現三次的0D0A正好就是ASCII CODE中的換航指令,也就是"\n"。

然而因為程式簡單所以可以少輸入一個很重要的指令,
也就是fclose,
如果沒有使用這個指令,
檔案因為沒有正常關閉很有可能出現問題。
這一點也是跟C語言一樣的。

檔案的產生可以使得程式有更高度的應用,
但他也不是IC本身該有的功能,
因此也是幫助偵錯和設計IC用的指令。

再來提到的是一個時間函數timeformat
如果我們對timeformat進行以下的宣告:
timeformat(-9, 2, "ns", 7);
其中-9表示他是ns的單位,
2表示小數位的位數,
" "內為想要顯示在數字後面的字串,
通常都是顯示單位,
7則是包括小數點的位數,
也就是這個時間是由4個整數位數加上1個小數點和2個小數位數組成,
在display的表示是以"%t"的形式來正確的輸出,
如果用"%d"也可以有正確的數值,
但卻有可能會空太多位置。

同樣的,
timeformat的函數並非IC本身的功能,
但它卻可以用來測試IC的執行效率,
Verilog中還有個realtime的函數,
可以更精準的印出真正經過的時間,
畢竟一個IC優不優質,
正是決定於同樣一件事情的處理速度。

2011/10/31 "#"之信號延遲

今天上課的內容以"display"為主。

除了字串的印出之外,
其餘變數數值印出皆和C語言相同,
唯一不同的是verilog可以直接印出變數的數值。
Verilog本身是個和時間控制息息相關的程式語言,
程式中必須要有"initial"讓程式知道哪邊是程式的起點,
否則編譯後會顯示有錯誤。
如下圖,即使有信號延遲,但編譯器並不知道起點到底是什麼時候。
(正確範例請參照之前的文章)















而且每使用一次display就要用一個initial告知開始時間,
否則會一直有階段的編譯錯誤信息。
但這麼麻煩的話早就沒有人要用了,
這裡Verilog採用和MATLAB相似的用法,
那就是"begin"和"end"來當作昔日C語言的大括號,
而且適當的搭配initial和#的信號延遲,
就可以產生出奇特的輸出順序,
以下先來個錯誤範例:
















#後面的數字代表延遲的時間,
但顯示結果明顯的和期望的不同,
這是因為程式執行只要碰到#就會停下來,
等到延遲的時間到了為止,
應此第二行句子變成延遲了7個系統時脈後才印出,
而非延遲短的先印出。
要改善這樣的問題,
當然就是要有兩個時間起點,
也就是兩組initial:
















如此一來輸出的結果就符合文法和文意了。

最後再次強調,
display本身並不是個電路上的IC功能,
但在設計電路時,
適當的信號輸出可以幫助偵錯進展的速度。

另外稍微提到的是$wirte函數,
其實C語言的printf和wirte比較相似,
只要沒有要求(\n)就不會有換行的指令,
反觀display則是和C語言的put系列函數類似,
他們本身就含有\n的指令。

2011年11月13日 星期日

2011/11/07 硬體描述語言 多bits加法器設計

這個禮拜的課題僅針對加法器的設計去處理,
為了可以像多工器那樣用模組的方式構成高bit的加法器,
首先就得先設計出可以做為基底的1-bit加法器,
其電路圖如下:











我自己本身也用真值表的關係,
加上卡諾圖的化簡,
一樣會得到相同的結果。

因此電路圖的程式碼如下:













如此一來便完成了基底的模組,之後只要向多bits多工器般累加上去即可。

2-bits加法器的關係圖如下:












其中需要注意的是低腳位的進位必須進入高腳位的進位輸入端才能使高腳位動作,
因此在程式碼的撰寫上應注意先寫低腳位的程式碼。
其程式碼如下:










如此一來便可將兩個1-bit加法器連接成2-bits加法器。
剩餘程式碼則不打出來了。

接著就可以進行測試,
當A和B為1時,cin為0,
其結果應為2,
結果圖為:
圖中結果驗證推測正確,
且cout為0(2位元加法器只要結果不超過3就沒有進位)。
由此可知64bits的加法器並不難製作,
而結果的部分以後再補上。


而這禮拜要注意的是位變數設值的部份,
原先因為設值有問題的關係一直沒有使結果正確跑出,
直到老師說最好不要將設值以C語言的方式來看待,
應該要用verilog所具有的設值方式來設值,
按照老師的指導之後,
果然順利跑出結果。

另外在課本測試程式碼的部分,
C語言和MATLAB的「不等於」皆是"!=",
而verilog則是"!==",
不過不小心打錯時,
只要照著編譯結果除錯,
都可以快速的修正問題。

2011年10月24日 星期一

2011/10/24 硬體描述語言 多工器設計 Multiplexer design

比照之前2011/10/03的多工器設計是個1-bit的多工器,

將兩個1-bit的多工器組合便可產生2-bits的多工器。
同理,
4-bits的多工器則是使用兩個2-bits組合而成。

同樣從2011/10/03的時脈圖可得知,
當SEL為0時,信號輸出為B。
當SEL為1時,信號輸出為A。
不論多少bit的多工器皆須滿足上述條件。

多工器本身的組合並不難,
只要注意將輸入線數除以二分成高腳位和低角位。

以下為1-bit組合成2-bits多工器的範例程式碼:


























以此類推便可推至64-bits的程式碼,在此則省略不多加說明。

當64-bits的多工器組合好後,
如何驗證該多工器是否正確成了今天最主要的課題。
緊接著先介紹一些會用到的Verilog語法:
※大多為網路上蒐集來的零星資料,和自己所學過的程式語言比較。

一、initial語法:
initial具對變數設出值的功能,
但它只在#0的時候動作,
也就是說透過initial設初值的動作只會被執行唯一一次,並且至於時脈設定的模組
其過程類似MATLAB的for迴圈動作,
開始與結尾分別用begin、end來囊括設初值的動作。

二、reg語法:
reg是register的縮寫,有登記的意思。
在Verilog中是指對變數設位數(也就是幾條線),
reg設的值是被動的,
必須透過initial和always設定初值才會改變。

三、wire語法:
wire起初也是對變數設位數,
之後透過assign來對變數設值,
或者是不設初值,透過輸入信號的不同而不同。

因此,一個用於測試64-bits的時脈設置如下:
















300的十六進制是12C,
100的十六進制是64,
故時脈圖當SEL=0時,輸出應是64,反之為12C。