能否在Chipyard中以文件夹形式添加NoC作为BlackBox?
在Chipyard中批量导入整个文件夹的SystemVerilog作为BlackBox MMIO外设
核心结论
可以批量导入整个文件夹的SystemVerilog文件,无需逐个调用addResource(),以下提供两种可行实现方式:
方法一:Scala遍历目录批量添加资源
在NoC_top.scala的BlackBox类中,通过Scala文件API遍历目标目录下所有.sv文件,自动调用addResource()添加。这种方式可控性强,能精准选择需要的文件。
示例代码:
import chisel3._ import chisel3.experimental.{BlackBox, HasBlackBoxResource} import java.io.File class NoCTopBlackBox extends BlackBox with HasBlackBoxResource { // 定义BlackBox的IO接口,需与NoC_Top.sv的接口匹配 val io = IO(new Bundle { val clk = Input(Clock()) val rst_n = Input(Bool()) // 添加MMIO相关信号,如地址、数据、读写使能等 val mmio_addr = Input(UInt(32.W)) val mmio_wdata = Input(UInt(64.W)) val mmio_rdata = Output(UInt(64.W)) val mmio_we = Input(Bool()) }) // 设置SystemVerilog模块名(若与类名不一致时需配置) setModuleName("NoC_Top") // 遍历指定目录下所有.sv文件的工具方法 private def addSvFilesFromDir(dirPath: String): Unit = { val dir = new File(getClass.getResource(dirPath).getPath) if (dir.isDirectory) { // 递归遍历所有子目录和文件 def traverse(currentDir: File): Unit = { currentDir.listFiles().foreach { file => if (file.isFile && file.getName.endsWith(".sv")) { // 构造相对于resources目录的路径,添加为资源 val relativePath = s"${dirPath}/${file.getName}" addResource(relativePath) } else if (file.isDirectory) { traverse(file) } } } traverse(dir) } } // 添加顶层文件 addResource("/vsrc/NoC_Top.sv") // 批量添加子目录下的所有.sv文件 addSvFilesFromDir("/vsrc/small_core") addSvFilesFromDir("/vsrc/another_NoC_System") }
方法二:通过sbt配置自动包含资源目录
Chipyard基于sbt构建,可在chipyard/generators/NoC/build.sbt中配置,让sbt自动将整个vsrc目录(或子目录)下的文件作为资源包含,无需在Scala代码中手动遍历。
示例build.sbt配置:
// 将vsrc目录及其子目录下的所有文件加入编译资源 unmanagedResourceDirectories in Compile += baseDirectory.value / "src" / "main" / "resources" / "vsrc" // 或仅包含特定子目录 unmanagedResourceDirectories in Compile ++= Seq( baseDirectory.value / "src" / "main" / "resources" / "vsrc" / "small_core", baseDirectory.value / "src" / "main" / "resources" / "vsrc" / "another_NoC_System" )
配置后,sbt会自动把这些目录下的文件打包到资源中,只需在BlackBox中添加顶层文件addResource("/vsrc/NoC_Top.sv"),工具链会自动找到依赖的子模块文件。
将NoC集成到Chipyard作为MMIO外设
完成BlackBox的文件导入后,需将其封装为LazyModule并连接到系统MMIO总线:
- 封装外设模块:
import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ class NoCMMIOPeripheral(implicit p: Parameters) extends LazyModule { // 定义TileLink从节点,用于连接到系统MMIO总线 val node = TLSlaveNode(Seq(TLSlavePortParameters( slaves = Seq(TLSlaveParameters( address = AddressSet(0x20000000L, 0x00FFFFFFL), // 分配MMIO地址空间 resources = new SimpleDevice("noc-mmio", Seq("chipyard,noc-1.0")).reg, regionType = RegionType.IDEMPOTENT, executable = false, supportsGet = TransferSizes(1, 8), supportsPutFull = TransferSizes(1, 8), supportsPutPartial = TransferSizes(1, 8) )), beatBytes = 8 ))) lazy val module = new LazyModuleImp(this) { val noC = Module(new NoCTopBlackBox) // 连接时钟复位 noC.io.clk := clock noC.io.rst_n := !reset.asBool // 连接TileLink信号到BlackBox的MMIO接口 val tlIn = node.in(0) noC.io.mmio_addr := tlIn.a.bits.address(31, 0) noC.io.mmio_wdata := tlIn.a.bits.data noC.io.mmio_we := tlIn.a.bits.opcode === TLPutFullData || tlIn.a.bits.opcode === TLPutPartialData // 处理读响应 tlIn.d.bits.data := noC.io.mmio_rdata tlIn.d.bits.opcode := TLAccessAckData tlIn.d.bits.param := 0.U tlIn.d.bits.size := tlIn.a.bits.size tlIn.d.bits.source := tlIn.a.bits.source tlIn.d.bits.sink := tlIn.a.bits.sink tlIn.d.bits.error := false.B // 控制TileLink握手信号 tlIn.a.ready := true.B tlIn.d.valid := tlIn.a.valid && tlIn.a.bits.opcode === TLGet } }
- 在Chipyard配置中启用该外设:
import freechips.rocketchip.config.Config import chipyard.{BuildTop, DefaultConfig} class WithNoCMMIOPeripheral extends Config((site, here, up) => { case BuildTop => (clock: Clock, reset: Bool, p: Parameters) => { val top = up(BuildTop)(clock, reset, p) val noCPeriph = LazyModule(new NoCMMIOPeripheral()(p)) // 将外设连接到系统的MMIO总线(此处假设使用系统的TLXbar) top.tlXbar.node := noCPeriph.node top } }) // 组合配置:默认配置 + NoC外设 class NoCConfig extends Config( new WithNoCMMIOPeripheral ++ new DefaultConfig )
注意事项
- 确保SystemVerilog文件中的模块名与BlackBox中
setModuleName()指定的名称一致,否则工具链会找不到模块。 - 递归遍历目录时,注意过滤非
.sv文件,避免引入无关资源。 - MMIO地址空间的分配需避免与其他外设冲突,可参考Chipyard默认外设地址布局调整。
- 使用sbt自动包含资源时,需确保目录路径配置正确,否则会出现文件找不到的错误。
内容的提问来源于stack exchange,提问作者asamorning
相关产品推荐
相关产品推荐

