針對SpinalHDL中的兩大類型Reg、Wire,來梳理下在SpinalHDL中的對應關系及聲明形式。
Wire
在編寫Verilog時,reg、wire是我們經常用到的變量聲明類型。wire類型變量常用于描述組合邏輯。而Reg則用于描述時序邏輯。在SpinalHDL中,其定義了Bool、Bits、UInt、SInt、Vec等數據類型。當我們聲明一個數據類型變量時其默認均為線網類型:
在上面的代碼中,我們聲明了端口dataIn、dataOut、其默認均對應著RTL中的Wire類型:
Reg
Reg類型變量常用于時序邏輯,在SpinalHDL中,將數據類型聲明為Reg類型的方式有:
SpinalHDL提供了四種類型聲明寄存器的方式,根據不同的場景需求,我們可以四選一選擇最合適的(都是基于Reg一步步封裝的)。 除此之外,由于SpinalHDL中默認為Wire類型,而SpinalHDL為其都提供了setAsReg()方法來標注為寄存器類型,同時提供Init(resetValue)方法來做初始化。因此想上面的那個例子我們想寄存器打一拍我們可以這么來寫:
case class regDemo() extends Component{ val io=new Bundle{ val dataIn=in UInt(8 bits) val dataOut=out UInt(8 bits) } val regTemp=Reg(UInt(8 bits)) init(0) regTemp:=io.dataIn io.dataOut:=regTemp}也可以這么來寫:
case class regDemo() extends Component{ val io=new Bundle{ val dataIn=in UInt(8 bits) val dataOut=out UInt(8 bits) } val regTemp=RegInit(U(0,8 bits)) regTemp:=io.dataIn io.dataOut:=regTemp}還可以這么寫:
case class regDemo() extends Component{ val io=new Bundle{ val dataIn=in UInt(8 bits) val dataOut=out UInt(8 bits) } io.dataOut:=RegNext(io.dataIn).init(0)}甚至可以這么寫:
case class regDemo() extends Component{ val io=new Bundle{ val dataIn=in UInt(8 bits) val dataOut=out UInt(8 bits) setAsReg() init(0) } io.dataOut:=io.dataIn}
時序調整很容易
在我們編寫RTL代碼時,當時序存在問題時需要我們調整時序時是很痛苦的,因為無論是Verilog還是SystemVerilog代碼,在較長組合邏輯之間添加一級寄存器往往需要改動較多的點,還需要仔細的評估。稍不注意就是時序沒調整好,功能先出問題了(主要在于代碼太長,更改需慎之又慎)。 而在SpinalHDL里,時序調整可以做到簡潔而優雅。 在我們之前用SpinalHDL做Sobel圖像處理算法時有這么一段代碼:
在卷積核計算處理時這里存在較多的組合邏輯延遲,會成為系統時序瓶頸點。當我們想向更高的頻率去跑時這里便需要插入寄存器。想想看這里如果是用Verilog來寫時我們插入寄存器不僅要計算清楚中間寄存器的位寬,同時也需要改多行代碼,還要小心翼翼的改寫。 而在SpinalHDL里,我們這里插入寄存器調整時序很容易!我們可以通過調用regNext很容易地插入一級寄存器:
如此我們便可以輕松地優化時序,誰還說時序調整是個體力活兒呢??? 而針對帶握手信號的時序打拍優化,SpinalHDL也有相關的Lib供調用可以快捷地優化處理。
原文標題:SpinalHDL—Reg&Wire
文章出處:【微信公眾號:FPGA之家】歡迎添加關注!文章轉載請注明出處。
-
寄存器
+關注
關注
31文章
5325瀏覽量
120052 -
Reg
+關注
關注
0文章
20瀏覽量
11465 -
代碼
+關注
關注
30文章
4753瀏覽量
68368 -
時序邏輯
+關注
關注
0文章
39瀏覽量
9150
原文標題:SpinalHDL—Reg&Wire
文章出處:【微信號:zhuyandz,微信公眾號:FPGA之家】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論