0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

什么樣的Verilog代碼風(fēng)格是好的風(fēng)格?

ruikundianzi ? 來源:硅農(nóng) ? 作者:硅農(nóng) ? 2022-10-24 15:23 ? 次閱讀

寫代碼是給別人和多年后的自己看的。 關(guān)于Verilog代碼設(shè)計的一些風(fēng)格和方法之前也寫過一些Verilog有什么奇技淫巧?

模塊化設(shè)計

把所有的代碼都寫到一個模塊里,也不是一個好的風(fēng)格。 積累自己的小IP,在芯片設(shè)計階段,就將功能模塊劃分仔細(xì),劃分清楚,可復(fù)用的功能做成一個可參數(shù)化IP。搭建起你的數(shù)字積木。

對齊

把編輯器設(shè)置成tap自動替換成2/4個空格。 用空格對齊代碼,提高代碼觀賞性。

 //case0
 input                   clk;
 input                   rst_n;
 inout                   in;
 output       [6:0]      out;
 //case1
 input                   clk     ;
 input                   rst_n   ;
 inout                   in      ;
 output       [6:0]      out     ;
連分號也要對齊的對齊狂魔,大可不必,徒增功耗。 關(guān)于提高Verilog代碼編寫效率的Gvim插件本訂閱號之前也分享過,I/O端口按如上所示風(fēng)格編寫好后,直接可以生成端口列表。直接寫assign和always塊語句,也可以直接生成定義。省去手動定義的麻煩。

括號

用括號將表達(dá)式的條件括起來,讓層次關(guān)系更清晰,一些情況不括起來功能上也沒有問題,但是會引起閱讀者的歧義和可讀性差。善用括號,避免閱讀歧義和工具理解歧義。

assign flag = cnt == 2'd1 && (mode != 2'd1 && (|v_shift) || cnt2 < 8'd15);


assign flag = (cnt == 2'd1) && ((mode != 2'd1) && (|v_shift) || (cnt2 < 8'd15));

能少寫則少寫

always @(posedge clk or negedge rst_n) 
begin
    if(!rst_n) begin
        out <= 0;
    end 
    else if(en)begin
        out <= in;
    end
    else begin
        out <= out;
    end
end


always @(posedge clk or negedge rst_n) begin
    if(!rst_n) 
        out <= 0;
    else if(en)
        out <= in;
end
只有單行語句可以省略去begin-end,一個always塊只對一個變量操作。else分支如果是保持的話,可以省略。還有begin的位置...,能少寫一行算一行。 注意,在組合邏輯中else分支不寫會產(chǎn)生鎖存器,寫成了保持就是組合邏輯環(huán),這一點要和時序邏輯分開。時序邏輯中else分支不寫代表保持。
 always @(*)begin
     case(in[1:0])
         2'd0 : data[1:0] = 2'd0;
         2'd1 : data[1:0] = 2'd1;
         2'd2 : data[1:0] = 2'd2;
         default : data[1:0] = 2'd3;
     endcase
 end
case語句也一樣,不寫default分支會產(chǎn)生鎖存器,如果case中的所有情況都達(dá)到,就可以不用寫default分支,但在ASIC設(shè)計中可能工具會報lint,所以這樣的寫法是最完美的。

FSM

狀態(tài)機采用三段式

591fe3be-5352-11ed-a3b6-dac502259ad0.png

Tips,在寫狀態(tài)機時,將第二段需要保持狀態(tài)循環(huán)的狀態(tài)寫法,寫成這樣的寫法,可以省去很多else的分支。 萬物基于狀態(tài)機——狀態(tài)機大法好

assign語句慎用

assign語句+三目運算符/與或門邏輯慎用

 assign data_out[5:0] = data_vld0 ? data0[5:0] :
     data_vld1 ? data1[5:0] :
     data_vld2 ? data2[5:0] :
     data_vld3 ? data3[5:0] : 6'b0;
 
 assign data_out[5:0] = ({6{data_vld0}} & data0[5:0])
     | ({6{data_vld1}} & data1[5:0])
     | ({6{data_vld2}} & data2[5:0])
     | ({6{data_vld0}} & data3[5:0]);
這兩種寫法一個帶有優(yōu)先級另一個不帶優(yōu)先級,本身沒什么問題。不過覆蓋率的expression中會將這個表達(dá)式中的所有條件滿足與否列出來。 其實很多情況是不可能出現(xiàn)的,比如這幾個vld同時1,data為0的情況組合,但是這就需要designer一個個去waive掉,然后寫出原因,選擇的語句少了還好,但是如果非常多,waive起來工作量還是很大的,徒增功耗。 這樣的問題可在開發(fā)階段就避免。
 always @(*)begin
     if(data_vld0) 
         data_out[5:0] = data0[5:0];
     else if(data_vld1)
         data_out[5:0] = data1[5:0];
     else if(data_vld2)
         data_out[5:0] = data2[5:0];
     else if(data_vld3)
         data_out[5:0] = data3[5:0];
     else 
         data_out[5:0] = 6'd0;
 end
寫成這樣,所有條件跑到就可以了。并行的語句用case。用與門和或門做的表達(dá)可能會省一些cell,但是比起后來waive時漫長的體力活,省這一毛兩毛的干啥。 看過一本書上的寫法,將所有的組合邏輯都用assign做,把D觸發(fā)器都做成IP,直接需要打拍的時候再調(diào)用。這樣的思想很好,準(zhǔn)確的將組合邏輯和時序邏輯分開,從代碼到電路。 作者提到另一個原因是由于if-else和case不能傳播不定態(tài),有的EDA工具有X態(tài)傳播選項,可以強行傳播,一般也需要license,但并不是所有的EDA工具都有這個功能。 但是我個人(淺薄的)認(rèn)為這樣的風(fēng)格不適合所有人。比如上面提到的覆蓋率問題,還有代碼的可讀性問題,assign式的寫法可讀性會變差。 直接在聲明wire時就給變量賦值這樣的寫法,連spyglass都過不了。還是先聲明再用吧。 關(guān)于工具的license問題,看看公司怎么給解決。

乘法器分時復(fù)用

一個設(shè)計要考慮PPA最優(yōu),就要考慮乘法器的數(shù)量多少以及復(fù)用能不能最大化,追求最好的設(shè)計是整個數(shù)據(jù)通路中乘法器空閑不下來。 乘法器調(diào)用方法,一般是在乘法器的輸入保證寄存器輸入,結(jié)果輸出到各個復(fù)用模塊時打一拍再使用??梢宰龀稍谶M行完乘法運算后,就打拍,這樣消耗的寄存器會少很多。畫個圖意思一下(單bit)。
593d20dc-5352-11ed-a3b6-dac502259ad0.png
修改前
595af0d0-5352-11ed-a3b6-dac502259ad0.png

修改后

修改完后的寄存器省了很多,但是乘法器的輸出寄存器負(fù)載會變大,不過后端綜合時約束了max_fan_out工具會自動插buffer和復(fù)制寄存器,經(jīng)過實測還是會節(jié)省很多面積,把一些優(yōu)化工作可以交給工具去做,了解它,信任它,使用它。

數(shù)據(jù)位寬寫全

 assign dout = din;
 
 always @(posedge clk or negedge rst_n)begin
     if(!rst_n)
         dout[255:0] <= 'd0;
     else 
         dout[255:0] <= din;
 end
寫成這樣
 assign dout[3:0] = din[3:0];
 
 always @(posedge clk or negedge rst_n)begin
     if(!rst_n)
         dout[255:0] <= 256'd0;
     else 
         dout[255:0] <= din;
 end
寫代碼時將數(shù)據(jù)位寬寫全,方便編輯器插件自動生成定義,而且寫上位寬再后續(xù)閱讀代碼時能一眼看變量的位寬,提高閱讀效率。 寄存器賦初始值 'd0 'h0等等,功能應(yīng)該沒有問題,這樣寫工具會默認(rèn)是最大32bit??lint檢查工具可能會報出來,最后還是得修改,不如一次到位。

良好的代碼風(fēng)格

寫了這么多,總結(jié)一起,其實關(guān)于代碼風(fēng)格的問題,通過多看書,多看一些代碼風(fēng)格的寫法,很多書上都有關(guān)于一些常見的風(fēng)格闡述,多寫代碼多積累,最后形成自己的代碼風(fēng)格習(xí)慣,另外一般公司都會有代碼規(guī)范的文檔,到時候參加工作以后,一定要記得多讀幾遍。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • Verilog
    +關(guān)注

    關(guān)注

    28

    文章

    1343

    瀏覽量

    109924
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4722

    瀏覽量

    68229
  • 編輯器
    +關(guān)注

    關(guān)注

    1

    文章

    800

    瀏覽量

    31054

原文標(biāo)題:什么樣的Verilog代碼風(fēng)格是好的風(fēng)格?

文章出處:【微信號:IP與SoC設(shè)計,微信公眾號:IP與SoC設(shè)計】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    FPGA實戰(zhàn)演練邏輯篇39:代碼風(fēng)格與書寫規(guī)范

    實現(xiàn)的書寫方式,它更多的是強調(diào)代碼的設(shè)計。要想做好一個FPGA設(shè)計,代碼風(fēng)格能夠起到事半功倍的效果。(特權(quán)同學(xué),版權(quán)所有)下面我們將就這兩個方面做一些深入的探討,也許沒有絕對意義上
    發(fā)表于 06-19 10:38

    FPGA實戰(zhàn)演練邏輯篇41:代碼風(fēng)格

    只有一個辦法,便是要求設(shè)計者寫出的HDL代碼盡可能最優(yōu)化。那么,我們又回到了老議題上——設(shè)計者的代碼風(fēng)格。而到底如何書寫HDL代碼才算是最優(yōu)化,什么
    發(fā)表于 06-25 09:41

    勇敢的芯伴你玩轉(zhuǎn)Altera FPGA連載35:Verilog代碼風(fēng)格概述

    設(shè)計者的用心良苦,也只有一個辦法,便是要求設(shè)計者寫出的HDL代碼盡可能最優(yōu)化。那么,我們又回到了老議題上——設(shè)計者的代碼風(fēng)格。而到底如何書寫HDL代碼才算是最優(yōu)化,
    發(fā)表于 12-27 10:07

    Linux內(nèi)核編碼風(fēng)格(編程代碼風(fēng)格推薦)

    這是翻譯版本,英文原版是linux源碼Documentation文件夾下的CodingStyle一個良好風(fēng)格的程序看起來直觀、美觀,便于閱讀,還能有助于對程序的理解,特別在代碼量比較大情況下更顯
    發(fā)表于 08-24 09:45

    C語言代碼風(fēng)格有哪些

    C語言代碼的命名風(fēng)格是怎樣的?C語言代碼的程序風(fēng)格是怎樣的?
    發(fā)表于 02-25 07:21

    什么是良好的Verilog代碼風(fēng)格?

    推薦的代碼風(fēng)格。3、代碼風(fēng)格1、規(guī)則總覽在設(shè)計這個模塊的時候,我主要遵從了以下幾條規(guī)則:Verilog2001標(biāo)準(zhǔn)的端口定義DUMMY模塊邏
    發(fā)表于 06-02 14:48

    Altera代碼風(fēng)格講義--作者:駿龍小馬

    一個講解Altera代碼風(fēng)格的講義,適合初學(xué)者看看,verilog代碼風(fēng)格
    發(fā)表于 11-17 18:07 ?0次下載

    山東分公司的風(fēng)格山東分公司的風(fēng)格山東分公司的風(fēng)格山東分公司的風(fēng)格

    東分公司的風(fēng)格東分公司的風(fēng)格東分公司的風(fēng)格東分公司的風(fēng)格東分公司的風(fēng)格東分公司的風(fēng)格東分公司的
    的頭像 發(fā)表于 09-07 14:57 ?1267次閱讀

    你想iPhone變成什么樣,iPhone 4中框風(fēng)格最完美

    你心中的理想iPhone長什么樣?日前,爆料達(dá)人Ben Geskin給出了自己心中完美iPhone的模樣,劉海消失,中框重回iPhone 4風(fēng)格,先來感受一下:
    的頭像 發(fā)表于 11-22 09:11 ?2739次閱讀

    Linux內(nèi)核的首選代碼風(fēng)格應(yīng)該如何設(shè)置

    這是一個簡短的文檔,描述了Linux內(nèi)核的首選代碼風(fēng)格代碼風(fēng)格是因人而異的,而且我不愿意把我的觀點強加給任何人,不過這里所講述的是我必須要維護的
    發(fā)表于 11-04 17:17 ?6次下載
    Linux內(nèi)核的首選<b class='flag-5'>代碼</b><b class='flag-5'>風(fēng)格</b>應(yīng)該如何設(shè)置

    Verilog HIDL的RTL設(shè)計風(fēng)格指南資源下載

    Verilog HIDL的RTL設(shè)計風(fēng)格指南資源下載
    發(fā)表于 04-13 10:09 ?9次下載

    關(guān)于Linux的內(nèi)核代碼風(fēng)格

    從而導(dǎo)致的問題。因為當(dāng)時代碼量不大,所以解決問題的時間相對較少。在代碼量增大的情況下可以借助工具進行自動修改。 快速修改編碼風(fēng)格的工具 scripts/checkpatch.pl 這是一個檢查patch是否符合內(nèi)核編碼規(guī)范的腳本
    的頭像 發(fā)表于 04-25 14:50 ?1773次閱讀

    C語言代碼風(fēng)格

    個人代碼風(fēng)格記錄此文將看到的一些代碼風(fēng)格規(guī)范總結(jié)起來,作為自己以后寫代碼時的參考。命名業(yè)界流
    發(fā)表于 01-13 13:13 ?1次下載
    C語言<b class='flag-5'>代碼</b><b class='flag-5'>風(fēng)格</b>

    Verilog編碼風(fēng)格的建議

    良好的編碼風(fēng)格,有助于代碼的閱讀、調(diào)試和修改。雖然 Verilog 代碼可以在保證語法正確的前提下任意編寫,但是潦草的編碼風(fēng)格往往是一錘子買
    的頭像 發(fā)表于 06-01 16:27 ?674次閱讀
    <b class='flag-5'>Verilog</b>編碼<b class='flag-5'>風(fēng)格</b>的建議

    淺談Verilog HDL代碼編寫風(fēng)格

    深層次的問題,對于這個行業(yè)來說可能我才是一直腳踩在門外面。所以這篇文章是寫給一些剛開始學(xué)習(xí)FPGA、Verilog HDL的同學(xué),我看過一些大神寫的代碼,然后盡量模仿大神寫法,經(jīng)過好幾個大神的影響和自己
    的頭像 發(fā)表于 11-20 10:04 ?698次閱讀
    淺談<b class='flag-5'>Verilog</b> HDL<b class='flag-5'>代碼</b>編寫<b class='flag-5'>風(fēng)格</b>