# Coding Style ###### tags: `Digital IC Design` [回到主頁面](https://hackmd.io/@derek8955/BkK2Nb5Jo/https%3A%2F%2Fhackmd.io%2FdpcBlBL8TlShpQ-wSi9Quw) - Follow公司內部的naming rule,像是counter訊號就可以定義cnt訊號角 - RTL code 必須是 synthesizable 的 code - 設計組合邏輯時,sensitivity list直接打* - 組合邏輯用Blocking assignment; 循序邏輯用Non-Blocking assignment - 避免 Latch 產生( 因為 latch 沒辦法做 [STA](https://hackmd.io/BOMX17vmRBumB39IhTR3Eg) ),產生的原因如下 : | ![](https://i.imgur.com/pWEzpfr.png) | |:-:| | <font color="gree">Condition 1 : </font> if/case statement 條件沒寫滿| | 以上方右圖為例,沒有標示 en 等於 0 的情形,代表電路必須在 en 等於 0 的時候 hold 住訊號 out 的數值。design compiler 在合成的時候就會自動添加 latch(下方所示),儲存 out 的數值以確保不會改變。 | | ![](https://i.imgur.com/MxGIOt7.png)| | ![](https://i.imgur.com/x6hD5Yl.png)| |:-:| | <font color="gree"> Codition 2 :</font> Combinational Feedback | | 如果有 feedback 產生就得有儲存裝置 FF 或 latch( net 沒有記憶功能,沒辦法回授 ) 幫你記住上個狀態的 value。例如上方左圖會合成出什麼電路? | | ![](https://i.imgur.com/ynQjzkr.png) | :::danger Latch 是 level sensitive 元件,沒有跟著 clk 的 edge trigger,所以會產生 latch 的情況只有在 combinational 電路中。所以下面的範例不會產生 latch ::: ```verilog= always @( posedge clk ) begin if( flag ) a <= 3; end ``` ![](https://i.imgur.com/wXxi3G1.png)| |:---:| |產生 DFF | [Related Paper: "full_case parallel_case", the Evil Twins of Verilog Synthesis](http://www.sunburst-design.com/papers/CummingsSNUG1999Boston_FullParallelCase.pdf) - Avoid combinational loop : 同Combinational Feedback,這樣會導致tool沒辦法做STA |![](https://i.imgur.com/ARaIK71.png)| |:---:| | Ref : http://vlsi-soc.blogspot.com/2013/05/combinational-loops.html | | a = b,b = c,c = a| - 可以用Spyglass lint檢查 - 可以用dc檢查,Command: report_timing -loop option - 所有訊號都必須 reset - 不要使用 conditional resets,所有的register應該要在同個時間下reset ```verilog= always @( posedge clk or negedge rst_n or a ) begin if( !rst_n || a ) b <= 0; else b <= c; end ``` - 不要把所有變數都擠在同一個 always block 中 : 可以把一個 always block 想像成一個黑盒子,如果這個黑盒子太複雜,design compiler 有可能會看不懂,導致最後合成出來的 netlist 可能會跟我們所設想的結果不同。所以除非變數中相似性很高才會寫在同一個 always block,其他的情形就最好是把所有變數分散開來,拆成多個 always block 來寫,不僅 debug 的時候也比較輕鬆,合成後的電路也比較能接近預期的結果。 > 也就是說 FSM cuurent state, FSM next state, counter, ...等最好都獨立出來, 寫在不同的 always block 中( 見 [FSM](https://hackmd.io/@derek8955/BkK2Nb5Jo/https%3A%2F%2Fhackmd.io%2FyUf-cb3tSsqa746uNIzXlg) ) - hierarchical design,不要把所有東西擠在一塊,多使用 module instantiation,增加可讀性、方便 debug - 不要直接拿 input data 做計算,先用個 FF 存下來 : Input data 會有 unknown propogation(在[ 02—data type ](https://hackmd.io/PUFV4TJWR46sFqgljeOOJA)有說到 4 種 logic value), 不要讓內部的 circuit 直接跟外面的世界串接起來 - Ouput 訊號同理,先用個FF存下來再送出外部電路 - 如果 input data 是序列的話,使用 shift register 儲存( 在 [looping statement](https://hackmd.io/VGQckbNDQxCmie7gIxWDIA) 有說明原因 ) - 使用 [Finite State Machine](https://hackmd.io/yUf-cb3tSsqa746uNIzXlg) 來控制整個電路運作 - 使用parameter in your design(More Portable,假如其他計畫也要使用這顆IP,就可以直接拿來用) ```verilog= //Poor Coding reg [7:0] a; wire [7:0] b; //Good Coding `define BUS_WIDTH 8 reg [BUS_WIDTH-1:0] a; wire [BUS_WIDTH-1:0] b; ``` - 避免在design內部使用負緣觸發的FF和正緣觸發的FF,STA的margin會變窄