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

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

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

聊聊例化寄存器型的RTL編碼設(shè)計(jì)

jf_GctfwYN7 ? 來(lái)源:IC修真院 ? 2023-11-10 17:28 ? 次閱讀

這篇文章來(lái)整體的聊一下個(gè)人理解的例化寄存器型的RTL編碼風(fēng)格。在脫離實(shí)驗(yàn)室氛圍開(kāi)始在公司寫(xiě)芯片設(shè)計(jì)代碼的時(shí)候,就發(fā)現(xiàn)公司里代碼規(guī)范里明確表明:

1.避免always @*語(yǔ)句;

2.避免always時(shí)序語(yǔ)句;

這讓我幼小的心靈備受打擊,不用always怎么怎么寫(xiě)RTL呢?當(dāng)然了寫(xiě)著寫(xiě)著也就習(xí)慣了。避免always @*這個(gè)咱們已經(jīng)理解用意了,主要是避免X態(tài)問(wèn)題被掩蓋。那么避免always時(shí)序語(yǔ)句是為什么?又應(yīng)該如何實(shí)操呢? 要避免always時(shí)序語(yǔ)句其實(shí)也很簡(jiǎn)單,自然就是例化dff了呀,根據(jù)接口和特性可以劃分歸類一下有哪幾種dff我們可能會(huì)用得到:

1.是否需要復(fù)位

2.是否需要使能

3.是否需要校驗(yàn)

暫時(shí)排除第三種校驗(yàn)情況稍后再聊,根據(jù)前兩個(gè)分類我們會(huì)得到以下的dff模塊:

1.moon_dffre

2.moon_dffr

3.moon_dffe

4.moon_dff

這個(gè)前綴就是做一下標(biāo)志隨便加就可以。dff例化的風(fēng)格怎么取代always時(shí)序呢,以下面這段代碼為例:



reg [7:0]power; always @(posedge clk or negedge rst_n)begin if(!rst_n) power <= 8'b0; else if(case0) power <= case0_data; else if(case1) power <= case1_data; else if(case2) power <= power + 1'b1; end 以dff風(fēng)格寫(xiě)的話就是下面這樣:


//信號(hào)聲明 wire [7:0]power_d; wire [7:0]power_q; wire power_en; //組合邏輯 assign power_en = case0 || case1 || case2; assign power_d = case0 ? case0_data : case1 ? case1_data : power_q + 1'b1; //時(shí)序邏輯 moon_dffre #(.WD(8)) u_power_dff(.clk(clk), .rst_n(rst_n), .d(power_d), .en(power_en), .q(power_q)); 這兩種代碼風(fēng)格哪種好呢?對(duì)于優(yōu)秀的編碼者這兩種是沒(méi)有優(yōu)劣之分的。不過(guò)對(duì)于我這種入門級(jí)選手以及交付來(lái)說(shuō),選用dff例化風(fēng)格的代碼還是有收益的:

1.能夠規(guī)避不合理的代碼習(xí)慣。最典型的就是時(shí)序邏輯中的clk_gating問(wèn)題。想要綜合工具自動(dòng)插入門控的話,那么always塊中就盡量不要有else分支(或者else分支是非阻塞賦值給自身),如果else中對(duì)信號(hào)賦常值了那么門控就插不進(jìn)去,影響整個(gè)芯片的功耗。那么如果自己來(lái)寫(xiě)always塊粗心大意了的話就可能出問(wèn)題,且這個(gè)事完全靠個(gè)人意識(shí)了(當(dāng)然工具可以查gating比例)。如果采用例化dff的方式,寄存器的實(shí)現(xiàn)方式就是統(tǒng)一的,只要dff模塊寫(xiě)的合理那么無(wú)論如何調(diào)用都不會(huì)出這個(gè)問(wèn)題。

2.便于X態(tài)檢查。如同之前文章中所述的,if-else會(huì)掩蓋X態(tài)問(wèn)題,而如果我們希望對(duì)X態(tài)進(jìn)行檢查那么就可以統(tǒng)一在dff模塊內(nèi)來(lái)完成。

3.便于集中操作。假如某天突然有一個(gè)需求,要求所有的寄存器都加入校驗(yàn)邏輯,那么如果是always塊怎么處理比較快速呢?需要把所有寄存器的值送入一個(gè)模塊,然后連出一根error線。dff模塊呢可以在模塊內(nèi)加入邏輯,例化時(shí)把error接出來(lái)||在一起。還是那句話,這兩種方式難說(shuō)好壞,dff例化型編碼倒是可以從底層保證所有例化的寄存器都加入了校驗(yàn)邏輯(引出的工作還是得自己來(lái)的)。

4.便于全局替換。還是剛剛那個(gè)例子,加入校驗(yàn)邏輯,只需要全局把moon_dffre替換為moon_dffre_chk就可以了。

5.邏輯和互聯(lián)更加清晰,更接近于底層電路實(shí)現(xiàn)對(duì)工具友好。同時(shí)我的習(xí)慣是用xx_d、xx_q、xx_en來(lái)命名信號(hào),那么在寫(xiě)邏輯時(shí),代碼中用到了xx_q我就會(huì)非常放心因?yàn)檫@意味著該信號(hào)的時(shí)序極好,寫(xiě)習(xí)慣了對(duì)于時(shí)序路徑的把握也有所提升。

6.有利于降低復(fù)位比例,利于功耗控制。dff例化風(fēng)格編碼時(shí),組合邏輯和時(shí)序邏輯是分開(kāi)寫(xiě)的,在每一個(gè)時(shí)序邏輯處都面臨一個(gè)模塊選型的問(wèn)題,這個(gè)時(shí)候就需要分析這個(gè)寄存器是不是需要復(fù)位,如果不需要就選用moon_dffe型好了。而always塊寫(xiě)法組合邏輯和時(shí)序邏輯是在一處寫(xiě),精力很容易投在if-else的邏輯上,復(fù)位很多時(shí)候就順手寫(xiě)了,后面還得艱難的降復(fù)位比例。

7.便于腳本工具集中處理,對(duì),說(shuō)的就是auto_dff哈哈。 最后一點(diǎn),dff例化風(fēng)格的代碼天然的會(huì)分成信號(hào)聲明、組合邏輯、時(shí)序邏輯三個(gè)部分,因此你可以選擇這樣組織代碼:

//寄存器1 ...聲明... ...邏輯... ...例化... //寄存器2 ...聲明... ...邏輯... ...例化... 也可以很輕易的把三個(gè)區(qū)域分開(kāi):



...聲明所有信號(hào)... ... ...例化所有寄存器... ... ...完成所有邏輯... ... 那么這個(gè)收益是什么呢?這樣編碼形式和風(fēng)格容易寫(xiě)出美感,畢竟好看才是編碼第一要?jiǎng)?wù)! 好的,dff編碼風(fēng)格的收益部分就寫(xiě)完了,接下來(lái)進(jìn)行實(shí)操部分,各種dff模塊應(yīng)該怎么寫(xiě)呢?從最典型的moon_dffre寫(xiě)起吧。dffre顧名思義就是有復(fù)位有使能,內(nèi)部根據(jù)使能進(jìn)行賦值:


odulemodule moon_dffre #( parameter WD = 1, parameter VE = {WD{1'b0}}) ( input clk, input rst_n, input [DW -1:0]d, input en, output reg[DW -1:0]q ); always @(posedge clk or negedge rst_n)begin if(!rst_n) q <= VE; else if(en) q <= d; end endmodule 兩個(gè)參數(shù)分別是寄存器的位寬和復(fù)位值。那么如果在模塊內(nèi)加入關(guān)于X態(tài)的校驗(yàn),可以增加如下的代碼(示意):


`ifdef ASSERT_ON property chk_en_xz(); @(posedge clk) disable iff(~rst_n) ~$isunknown(en); endproperty property chk_d_xz(); @(posedge clk) disable iff(~rst_n) en |-> ~$isunknown(d); endproperty assert_chk_en_xz: assert property(chk_en_xz()) else $assertoff(0, assert_chk_en_xz); assert_chk_d_xz: assert property(chk_d_xz()) else $assertoff(0, assert_chk_d_xz); `endif 這樣一來(lái),X態(tài)檢查的問(wèn)題就融在底層模塊中了。順著這個(gè)思路,另外幾種dff的編碼也很簡(jiǎn)單,moon_dffe:


module moon_dffe #( parameter WD = 1) ( input clk, input [DW -1:0]d, input en, output reg[DW -1:0]q ); always @(posedge clk)begin if(en) q <= d; end `ifdef ASSERT_ON property chk_en_xz(); @(posedge clk) disable iff(~rst_n) ~$isunknown(en); endproperty property chk_d_xz(); @(posedge clk) disable iff(~rst_n) en |-> ~$isunknown(d); endproperty assert_chk_en_xz: assert property(chk_en_xz()) else $assertoff(0, assert_chk_en_xz); assert_chk_d_xz: assert property(chk_d_xz()) else $assertoff(0, assert_chk_d_xz); `endif endmodule moon_dffr沒(méi)有使能其實(shí)就沒(méi)有必要檢查什么X態(tài)的事了:


module moon_dffr #( parameter WD = 1, parameter VE = {WD{1'b0}}) ( input clk, input rst_n, input [DW -1:0]d, output reg[DW -1:0]q ); always @(posedge clk or negedge rst_n)begin q <= d; end endmodule 最最古樸的自然還是moon_dff:


module moon_dffr #( parameter WD = 1, parameter VE = {WD{1'b0}}) ( input clk, input rst_n, input [DW -1:0]d, output reg[DW -1:0]q ); always @(posedge clk)begin q <= d; end endmodule 基礎(chǔ)版本的寄存器這四種就完全夠用了。那么如果有需求在寄存器中加入校驗(yàn),比如說(shuō)加入奇偶校驗(yàn),又該如何編碼呢?這就需要一個(gè)單獨(dú)的寄存器,當(dāng)數(shù)據(jù)寫(xiě)入時(shí)同步寫(xiě)入校驗(yàn)位,之后每拍檢查是否發(fā)生數(shù)據(jù)篡改:


module moon_dffre_chk #( parameter WD = 1, parameter VE = {WD{1'b0}}) ( input clk, input rst_n, input [DW -1:0]d, input en, output reg[DW -1:0]q, output e ); always @(posedge clk or negedge rst_n)begin if(!rst_n) q <= VE; else if(en) q <= d; end reg err_q; wire err_d = ^d; always @(posedge clk or negedge rst_n)begin if(!rst_n) err_q <= ^VE; else if(en) err_q <= err_d; end assign e = (err_q != ^q); `ifdef ASSERT_ON property chk_en_xz(); @(posedge clk) disable iff(~rst_n) ~$isunknown(en); endproperty property chk_d_xz(); @(posedge clk) disable iff(~rst_n) en |-> ~$isunknown(d); endproperty assert_chk_en_xz: assert property(chk_en_xz()) else $assertoff(0, assert_chk_en_xz); assert_chk_d_xz: assert property(chk_d_xz()) else $assertoff(0, assert_chk_d_xz); `endif endmodule 差不多啦,收工。

編輯:黃飛

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

    關(guān)注

    31

    文章

    5343

    瀏覽量

    120385
  • 芯片設(shè)計(jì)
    +關(guān)注

    關(guān)注

    15

    文章

    1019

    瀏覽量

    54899
  • RTL
    RTL
    +關(guān)注

    關(guān)注

    1

    文章

    385

    瀏覽量

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

    關(guān)注

    30

    文章

    4788

    瀏覽量

    68625
  • 時(shí)序邏輯
    +關(guān)注

    關(guān)注

    0

    文章

    39

    瀏覽量

    9163

原文標(biāo)題:IC設(shè)計(jì)筆記 | 論RTL中always語(yǔ)法的消失術(shù)

文章出處:【微信號(hào):IC修真院,微信公眾號(hào):IC修真院】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    ARM開(kāi)發(fā)中幾個(gè)常見(jiàn)的寄存器詳解

    筆者今天來(lái)聊聊對(duì)于ARM幾個(gè)特殊寄存器的理解,F(xiàn)P、SP和LR。
    發(fā)表于 11-22 09:02 ?4172次閱讀

    聊聊寄存器被優(yōu)化的2種情況

    在項(xiàng)目初期,在使用FPGA工具quartus或者vivado生成版本燒入開(kāi)發(fā)板進(jìn)行調(diào)試時(shí)(DC開(kāi)啟優(yōu)化選項(xiàng)后同樣會(huì)優(yōu)化掉寄存器),我們有時(shí)會(huì)發(fā)現(xiàn)部分寄存器被優(yōu)化掉了,今天簡(jiǎn)單聊聊被優(yōu)化的幾種情況。
    的頭像 發(fā)表于 09-08 15:09 ?2263次閱讀
    <b class='flag-5'>聊聊</b><b class='flag-5'>寄存器</b>被優(yōu)化的2種情況

    有償求助:RTL8365MB/RTL8363SB 寄存器問(wèn)題

    內(nèi)容:RTL8365MB/RTL8363SBdatasheet上寫(xiě)到可以通過(guò)寄存器配置GMAC的工作模式為GMII/RGMII/MII,但是datasheet中并沒(méi)有相關(guān)的寄存器描述。
    發(fā)表于 08-30 09:53

    寄存器與移位寄存器

    寄存器與移位寄存器 寄存器是用來(lái)寄存數(shù)碼的邏輯部件,所以必須具備接收和寄存數(shù)碼的功能。任何一種觸發(fā)
    發(fā)表于 03-12 15:19 ?59次下載

    寄存器,寄存器是什么意思

    寄存器,寄存器是什么意思 寄存器定義  寄存器是中央處理內(nèi)的組成部分。寄存器是有限存貯容量
    發(fā)表于 03-08 14:26 ?2.2w次閱讀

    數(shù)據(jù)寄存器,數(shù)據(jù)寄存器是什么意思

    數(shù)據(jù)寄存器,數(shù)據(jù)寄存器是什么意思 數(shù)據(jù)寄存器數(shù)據(jù)寄存器包括累加AX、基址寄存器BX、計(jì)數(shù)
    發(fā)表于 03-08 14:38 ?1.3w次閱讀

    移位寄存器,移位寄存器是什么意思

    移位寄存器,移位寄存器是什么意思 移位寄存器_
    發(fā)表于 03-08 14:50 ?1.8w次閱讀

    寄存器與移位寄存器

    寄存器與移位寄存器:介紹寄存器原理和移位寄存器的原理及實(shí)現(xiàn)。
    發(fā)表于 05-20 11:47 ?0次下載

    AD轉(zhuǎn)換寄存器設(shè)置

    AD轉(zhuǎn)換寄存器設(shè)置AD轉(zhuǎn)換寄存器設(shè)置AD轉(zhuǎn)換寄存器設(shè)置
    發(fā)表于 11-10 17:36 ?16次下載
    AD轉(zhuǎn)換<b class='flag-5'>寄存器</b>設(shè)置

    五個(gè)廣泛使用的特殊寄存器

      下一步是學(xué)習(xí)如何在 IP-XACT 或 SystemRDL 中定義這些特殊寄存器。還需要學(xué)習(xí)如何在 RTL 中對(duì)其進(jìn)行編碼,并創(chuàng)建 UVM 寄存器模型并完成 UVM 測(cè)試平臺(tái)以進(jìn)行
    的頭像 發(fā)表于 06-08 09:55 ?4581次閱讀
    五個(gè)廣泛使用的特殊<b class='flag-5'>寄存器</b>

    ARM通用寄存器及狀態(tài)寄存器詳解

    筆者來(lái)聊聊ARM通用寄存器以及狀態(tài)寄存器的認(rèn)識(shí)與理解。
    的頭像 發(fā)表于 01-06 14:58 ?7209次閱讀

    RAL寄存器模型操作圖鑒

    寄存器模型操作,指的是通過(guò)寄存器模型對(duì)RTL寄存器進(jìn)行讀寫(xiě)訪問(wèn),或者同步寄存器模型與RTL
    的頭像 發(fā)表于 05-17 09:01 ?942次閱讀
    RAL<b class='flag-5'>寄存器</b>模型操作圖鑒

    RAL寄存器模型操作指南

    寄存器模型操作,指的是通過(guò)寄存器模型對(duì)RTL寄存器進(jìn)行讀寫(xiě)訪問(wèn),或者同步寄存器模型與RTL
    的頭像 發(fā)表于 07-12 09:37 ?1091次閱讀
    RAL<b class='flag-5'>寄存器</b>模型操作指南

    寄存器是什么 掌握使用寄存器做設(shè)計(jì)需要注意的事項(xiàng)

    既然RTL是以寄存器行為為基礎(chǔ),那么就必須先了解寄存器是什么,并且掌握使用寄存器做設(shè)計(jì)需要注意的事項(xiàng)。
    的頭像 發(fā)表于 07-13 15:38 ?1566次閱讀
    <b class='flag-5'>寄存器</b>是什么 掌握使用<b class='flag-5'>寄存器</b>做設(shè)計(jì)需要注意的事項(xiàng)

    寄存器分為基本寄存器和什么兩種

    寄存器是計(jì)算機(jī)中用于存儲(chǔ)數(shù)據(jù)的高速存儲(chǔ)單元,它們是CPU內(nèi)部的重要組成部分。寄存器可以分為基本寄存器和擴(kuò)展寄存器兩種類型。 一、基本寄存器
    的頭像 發(fā)表于 07-12 10:31 ?1381次閱讀