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

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

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

在SpinalHDL里在頂層一鍵優(yōu)化Stream/Flow代碼生成

Spinal FPGA ? 來源:Spinal FPGA ? 2023-12-14 09:05 ? 次閱讀

在SpinalHDL里在頂層一鍵優(yōu)化代碼中Stream/Flow代碼生成的payload,fragment。

難看的代碼

來看一段代碼:

importspinal.core._
importspinal.lib._
caseclassDataPort() extendsBundle{
val data0=UInt(8bits)
val data1=UInt(8bits)
}

caseclassDemo() extendsComponent{
val io=newBundle{
val sink=slave(Stream(Fragment(DataPort())))
val source=master(Stream(Fragment(DataPort())))
}
noIoPrefix()
io.source<

很簡(jiǎn)單的功能,一個(gè)Stream接口Pipeline打拍。在生成RTL代碼時(shí)會(huì)看到下面這種有點(diǎn)兒“不太舒服”的結(jié)構(gòu)命名:

 wiresink_s2mPipe_payload_last;
wire[7:0] sink_s2mPipe_payload_fragment_data0;
wire[7:0] sink_s2mPipe_payload_fragment_data1;
regsink_rValidN;
regsink_rData_last;
reg[7:0] sink_rData_fragment_data0;
reg[7:0] sink_rData_fragment_data1;
wiresink_s2mPipe_m2sPipe_valid;
wiresink_s2mPipe_m2sPipe_ready;
wiresink_s2mPipe_m2sPipe_payload_last;
wire[7:0] sink_s2mPipe_m2sPipe_payload_fragment_data0;
wire[7:0] sink_s2mPipe_m2sPipe_payload_fragment_data1;

雖然說不怎么看生成的代碼,但有時(shí)候別人看這里信號(hào)命名中間夾雜了一堆_payload_fragment_的信號(hào)還是略覺有點(diǎn)兒?jiǎn)隆?/p>

尤其在用一些Axi/AxiLite總線時(shí),當(dāng)使用cloneOf時(shí),會(huì)發(fā)現(xiàn)大量的信號(hào)名中間夾著一些paylaod字段,略覺不雅~

雖然這是Stream類的定義所導(dǎo)致,但如果去修改設(shè)計(jì)中的每一處總歸還是比較麻煩的~

StreamRenameUtil

這里提供一個(gè)DIY的工具StreamRenameUtil,用于在設(shè)計(jì)的頂層一鍵讓這種場(chǎng)景下的代碼生成稍微優(yōu)雅一些:

object StreamRenameUtil {
def apply(topLevel:Component) = {
Rename(topLevel,true)
}

def Rename(toplevel:Component,isCurrentComponentBoolean={
//current component process
if(!isCurrentComponent){
toplevel.dslBody.foreachStatements{
casebt:BaseType ifbt.parent.isInstanceOf[Stream[_]] => streamRename( bt.parent.asInstanceOf[Stream[_]])
casebt:BaseType ifbt.parent.isInstanceOf[Flow[_]] => flowRename( bt.parent.asInstanceOf[Flow[_]])
case_ =>
}
}else{
toplevel.dslBody.foreachStatements{
casebt:BaseType ifbt.parent.isInstanceOf[Stream[_]] => toplevel.addPrePopTask(()=>{streamRename( bt.parent.asInstanceOf[Stream[_]])})
casebt:BaseType ifbt.parent.isInstanceOf[Flow[_]] => toplevel.addPrePopTask(()=>{flowRename( bt.parent.asInstanceOf[Flow[_]])})
case_ =>
}
}

for(child<-toplevel.children){
??????Rename(child,false)
????}
????true
??}

??def streamRename(streamPort:Stream[_])={
????streamPort.flatten.foreach((bt)=>{
val signalName=bt.getName()
if(signalName.contains("fragment")){
bt.setName(signalName.replace("_payload_fragment_","_"))
}else{
bt.setName(signalName.replace("_payload_","_"))
}
})
}

def flowRename(flowPort:Flow[_])={
flowPort.flatten.foreach((bt)=>{
val signalName=bt.getName()
if(signalName.contains("fragment")){
bt.setName(signalName.replace("_payload_fragment_","_"))
}else{
bt.setName(signalName.replace("_payload_","_"))
}
})
}

}

使用時(shí)僅需在頂層調(diào)用該方法,其會(huì)遍歷設(shè)計(jì)中各模塊的Stream、Flow類變量定義統(tǒng)一做修改:

caseclassDemo() extendsComponent{
val io=newBundle{
val sink=slave(Stream(Fragment(DataPort())))
val source=master(Stream(Fragment(DataPort())))
}
noIoPrefix()
io.source<

最終代碼生成會(huì)優(yōu)雅一些:

 wiresink_s2mPipe_valid;
regsink_s2mPipe_ready;
wiresink_s2mPipe_last;
wire[7:0] sink_s2mPipe_data0;
wire[7:0] sink_s2mPipe_data1;
regsink_rValidN;
regsink_rData_last;
reg[7:0] sink_rData_fragment_data0;
reg[7:0] sink_rData_fragment_data1;
wiresink_s2mPipe_m2sPipe_valid;
wiresink_s2mPipe_m2sPipe_ready;
wiresink_s2mPipe_m2sPipe_last;
wire[7:0] sink_s2mPipe_m2sPipe_data0;
wire[7:0] sink_s2mPipe_m2sPipe_data1;
regsink_s2mPipe_rValid;
regsink_s2mPipe_rData_last;
reg[7:0] sink_s2mPipe_rData_fragment_data0;
reg[7:0] sink_s2mPipe_rData_fragment_data1;
wirewhen_Stream_l369;

這里的sink_s2mPipe_rData_fragment_data0、sink_s2mPipe_rData_fragment_data1為在打拍時(shí)生命的Fragment類型,非Stream類型,如果你實(shí)在看不慣也可以依樣畫葫蘆添加一個(gè)對(duì)Fragment類型的Rename~

審核編輯:彭菁

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

    關(guān)注

    8

    文章

    324

    瀏覽量

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

    關(guān)注

    1

    文章

    384

    瀏覽量

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

    關(guān)注

    30

    文章

    4670

    瀏覽量

    67760
  • Stream
    +關(guān)注

    關(guān)注

    0

    文章

    20

    瀏覽量

    7949

原文標(biāo)題:逼死強(qiáng)迫癥—優(yōu)化Stream/Flow代碼生成

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

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    如何一鍵生成mybatisplus

    Mybatis代碼生成器相信大家用過,本篇博客我們來介紹如何一鍵生成mybatisplus 的相關(guān)Entity、Mapper、Mapper XML、Service、Controller
    的頭像 發(fā)表于 09-25 14:23 ?641次閱讀
    如何<b class='flag-5'>一鍵</b><b class='flag-5'>生成</b>mybatisplus

    SpinalHDLswitch方法有何用處呢

    ,當(dāng)我們需要根據(jù)tkeep信號(hào)來計(jì)算這拍有多少有效數(shù)據(jù)時(shí)這里的代碼會(huì)是什么樣子……這種代碼寫的手有點(diǎn)兒累(又沒啥技術(shù)含量)……SpinalHDL
    發(fā)表于 06-22 14:25

    SpinalHDL實(shí)現(xiàn)優(yōu)雅的添加待跟蹤波形信號(hào)

    SpinalHDL,我們樣可以實(shí)現(xiàn)優(yōu)雅的添加待跟蹤波形信號(hào)。姿勢(shì)一在Verilog代碼,我
    發(fā)表于 06-22 14:37

    個(gè)小的example來對(duì)比SpinalHDL Lib庫(kù)的強(qiáng)大

    SpinalHDL的世界,它基于core提供了豐富的Lib庫(kù),包含了Stream、Flow、Fragment、State Machine
    發(fā)表于 06-22 14:44

    SpinalHDL的設(shè)計(jì)中集成現(xiàn)有RTL設(shè)計(jì)(IP)的渠道——BlackBox

    我們SpinalHDL的設(shè)計(jì)中提供了集成現(xiàn)有RTL設(shè)計(jì)(IP)的渠道——BlackBox。BlackBox顧名思義,SpinalHDL將待集成的RTL設(shè)計(jì)當(dāng)作個(gè)黑盒對(duì)待,不關(guān)心內(nèi)部
    發(fā)表于 06-22 14:59

    SpinalHDL中關(guān)于casez的使用

    SpinalHDL中的switch之前的文章中曾提到過SpinalHDL中switch的使用:通常情況下,switch對(duì)應(yīng)著我們?nèi)粘erilog代碼中的case。像下面的
    發(fā)表于 07-06 10:59

    以slaveFactory庫(kù)為例看看如何一鍵生成整個(gè)設(shè)計(jì)的寄存器文檔

    在做邏輯實(shí)現(xiàn)及后期調(diào)試維護(hù),維護(hù)文檔中的寄存器列表和真實(shí)設(shè)計(jì)中的唯性往往是件令人“痛苦”的事情(個(gè)字,懶)。
    發(fā)表于 07-08 16:05

    分享個(gè)SpinalHDLapply的有趣用法

    個(gè)例子,SpinalHDL的example關(guān)于UDP設(shè)計(jì)的代碼看到了這么
    發(fā)表于 07-19 15:08

    SpinalHDL中的代碼組織結(jié)構(gòu)如何實(shí)現(xiàn)Component參數(shù)化設(shè)計(jì)呢

    方式:some.where.else.theSignal.pull()在生成RTL代碼時(shí),會(huì)講該信號(hào)聲明個(gè)端口鏈接偷穿到我們這級(jí)的Component。Component參數(shù)化設(shè)計(jì)與
    發(fā)表于 07-21 14:20

    SpinalHDL將功能封裝抽象成庫(kù)函數(shù)供Stream總線接口快速調(diào)用

    io_dataIn 做拍總線握手延遲即可但現(xiàn)在需要在輸出io_dataIn* 之前插入拍數(shù)據(jù)先輸出。insertHeaderSpinalHDL
    發(fā)表于 07-21 14:31

    如何在SpinalHDL啟動(dòng)個(gè)仿真

    前言安裝完成Verilator、GtkWave后,我們即可在IDEA通過SpinalHDL提供的仿真接口來對(duì)我們的設(shè)計(jì)進(jìn)行仿真。Spinal
    發(fā)表于 07-26 16:59

    SpinalHDL有沒有什么好的方式實(shí)現(xiàn)個(gè)接口位寬轉(zhuǎn)換呢

    下午微信群有個(gè)小伙伴問了這么道題:將個(gè)為UInt(128 bits)的Stream接口連接到個(gè)UInt(32 bits)的Strea
    發(fā)表于 07-27 14:52

    SpinalHDL中常用的Stream總線

    在于SpinalHDL中,Stream/Flow這種類型映射生成Verilog
    發(fā)表于 01-31 16:38

    SpinalHDL時(shí)鐘域中的定制與命名

    SpinalHDL時(shí)鐘域中時(shí)鐘的定制與命名。 相較于Verilog,SpinalHDL
    的頭像 發(fā)表于 03-22 10:14 ?2038次閱讀

    淺析Stream的隱式轉(zhuǎn)換

    Stream、Flow電路描述經(jīng)常用到的對(duì)象。
    的頭像 發(fā)表于 05-15 17:36 ?406次閱讀
    淺析<b class='flag-5'>Stream</b><b class='flag-5'>里</b>的隱式轉(zhuǎn)換