在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~
審核編輯:彭菁
-
HDL
+關(guān)注
關(guān)注
8文章
324瀏覽量
47229 -
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)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論