2014年2月23日 星期日

gray code encode and decode(上)

今天就不說太硬的概念。說一些比較實際的做法。
binary to gray code的verilog做法。
gray code是許多人遇過,而且很多人都會做,這裏有一個小小做法,簡單,而且不複雜,可以提供大家參考。

module bin2gray(
 bini
,grayo
);
input [4:0] bini;
output [4:0]grayo;

assign grayo = bin ^ {1'b0, bin[4:1]};

endmodule

以下是3-bit binary 和gray code的對照。
000  <-> 000
001  <-> 001
010  <-> 011
011  <-> 010
100  <-> 110
101  <-> 111
110  <-> 101
111  <-> 100

下一回,我再把gray code to binary寫出來,跟大家分享。

2014年2月16日 星期日

如何規劃power management的流程


以前設計過power managementFSM。想把它總結出來,但是,每個chip的情形都不相同,要總結出它所有的規則是困難的。但我還是想把自己的經驗提供出來給大家參考,請大家多多指教! 如果有任何更好的方法或是觀念,歡迎留言給我,讓我也能學習到更好的方法。

我的想法裏,認為power management有一個大的觀念可以去思考,在此提出來。不見得每個都適用,主要還是要看你自己的系統真實的情形 。

Fist-In-Last-Out(FILO), 最先關的,最後醒。為什麼要這麼說,以下舉幾個例子來說明。

1. 降頻節省power : 
    如果你想降頻節省某一塊的power,你會怎麼做? 1). 降低頻率.  2). power domain由1.8V切換到1.3V。如果你想要恢復到原來的速度時,又應該怎麼做? 1). 1.3V切回到1.8V.   2). 恢復原來的頻率。 這不就是FILO嗎?很多地方幾乎都是用這個方法,這樣子做比較保守,但也相對的安全。FILO是個大規則,所有的行為都是按照這個原則下去規劃。

2. 不重要的比重要的先關: 
    在規劃power management時,不重要的永遠是第一個被關掉,這是因為如果發生錯誤時,也不會影響到整個系統。而醒過來時,則是按照FILO原則,重要的先醒,然後才是不重要的。(FILO規則)

3. 先關遠的,再關近的: 
    醒過來的順序則是相反,近的先醒,然後才是遠的。(還是FILO規則)

4. 四肢(interfacebus)先關,然後才是腦(CPU),醒過來時則是腦先醒、然後才是四肢。(FILO規則)

5. 有些人會把關powerreset一起處理。所以如果你確定要關power,那你就先reset,然後關power。醒來時,就先開power,然後再放開reset

以上的例子,都是用FILO的觀念去規劃省電的機制。FILO並不能適用在所有的架構下,找出會讓系統穩定的方法,並確保glitch free,您就是找到一個適合的方法。


以上的觀念,希望能對你有所幫助。

2014年2月10日 星期一

關於跨clock domain處理的觀念

做為一個數位設計的工程師,最常遇到的情形就是訊號需要跨clock domain的處理。能使用的解決方法有很多,每個需要處理的情況也不儘相同,所以我並不就實作方法著眼,只想談談處理它的概念。
為什麼要處理跨clock domain的訊號?
使用來自其它clock domain的訊號時,容易會遇到metastable的情形,而致使產生錯誤結果。為了避免錯誤的發生,此時就需要同步來自其他clock domain的訊號。但是要怎麼做,才能做好同步處理?如果可以謹記下面的觀念,相信您一定就可以做出自已的同步訊號處理。
1. 遵守two-flip-flop的方法。
處理metastable的最基本的步驟就是用本身的clock來做two-flip-flop的同步。(這是每位數位工程師都要謹記,不可忽略的步驟)

QB就是經過兩個Flip-Flop後的訊號。用QB的訊號做為控制訊號,相信就可以避免metastable產生。
2. 分類同步訊號是哪一種?
是長脈衝訊號(long pulse),還是單脈衝訊號(one-pulse) ? 如果是長脈衝訊號,利用第一點的方法,相信就可以解決。如果是單脈衝訊號,想辦法轉成長脈衝訊號後,再利用第一點的方法即可以解決。


3.是連續單脈衝訊號還是不連續單脈衝訊號?
如果是不連續單脈衝訊號,而且每個單脈衝訊號之間的同步並不會互相影響的話,相信用第二點的方法就可以解決。但是如果是連續單脈衝訊號,想辦法變成不連續單脈衝訊號,然後再用第二點的方法就可以解決。坊間有很多種的方法,網路搜尋一下就可以找到了,在此就不赘敘。
4. 上面所說的,都是單一訊號的同步處理,切記,addressdata都是不可能拿來同步處理。
5. 所有同步處理,最終都是回到第一點的情形去處理。

如果你抓住這些基本觀念,相信你也一定可以設計出你自己的同步處理裝置。

以上的觀念,希望能對你有所幫助。

好的coding習慣

做為一個數位IC設計初學者,好的coding習慣是很重要的。它能讓你的程式被別人讀懂,而且程式的穩定度也比較高。那什麼是好的coding習慣。
1. 只使用positive edge (negative edge) clock來做為取樣的時間點(sampling data time).
   coding時,堅持只使用clock的一邊(edge)來做為你取樣的時間點(sampling data time)。這樣子可以增加程式的易讀外,也能讓你的程式行為(behavior)單純,在synthesis時比較好處理。且在做ATPG時,也比較容易處理。
只用單一邊做為你的時間點,它的穩定度比較高。這就像是你在高速公路上開車,在單一車道上快速行駛安全? 還是一直變換車道超車來加快速度安全? 建議初學者還是要堅持只使用一邊的clock edge來做為你取樣的時間點。
2. 儘量使用單純的語法,少用for, while, function等複雜語法。
十年前的工具沒有那麼的強大,無法解譯複雜語法;但現在因為synthesis工具已經愈來愈完善且強大,所以看得懂複雜語法,所以大家都在使用。但是身為數位IC工程師,你的流程是一貫的,你知道這些複雜語法所產生的netlist是什麼情形嗎?如果你不知道,當你要ECO時,該怎麼做?如果工具錯譯程式的時候,你知道要怎麼處理嗎?你會發現問題的點在哪嗎?如果你不知道怎麼樣從front-endback-end的流程中去貫徹複雜語法的使用,建議你還是只用簡單的語法。
3. 語法的使用一定要完整.
舉例來說,如果使用if,那一定要記得把else之後的語法補齊。如果使用case,那default就一定要加。這是方便你知道你自己是否有寫combinational loop的程式在裏頭。
4. 有規則的命名
如果是input port宣告,就一定會在最後面加上i。如果是output port宣告,就一定會在最後面加上o 。例如data_i, data_o,這樣子我們馬上就可以知道這是輸入訊號還是輸出訊號。
5. 一個程式裏面,只有一個module.
    我常看到初學者,把很多module放在同一個.v檔中。在閱讀時,真的滿容易造成混淆。建議初學者要習慣一個module就一個.v檔。
6.少用include
很多人都會做一些檔頭(.vh),來節省程式上重複使用的問題。這是好事,使用include常常會造成在simulationsynthesis時要做很多的設定。其實.vh檔你也可以寫在filelist上,只要檔頭比程式先被編譯即可。在synthesis時也是同樣的道理。這樣子別人在閱讀你的程式時,一目了然你到底有多少程式檔案需要被閱讀。


以上只是個人的意見,謹提供參考!