You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将TileLink节点导出为LazyModule输出并生成对应Verilog文件

如何正确导出TileLink客户端节点并解决Diplomacy报错?

我尝试创建一个带有TileLink客户端并连接到模块输出的简单模块,耗时20小时仍无法实现,以下是我的代码:

class ArmleoCoreTop extends Module {
  implicit val p = Parameters.empty
  val acore = LazyModule(new ArmleoCore())
  val macore = Module(acore.module)
  val io = IO(acore.io_node.cloneType)
  acore.io_node <> io 
}

class ArmleoCore()(implicit p: Parameters) extends LazyModule {
  val client = TLClientNode(Seq(TLMasterPortParameters.v1(Seq(TLMasterParameters.v1(
    name = "ArmleoCore",
    sourceId = IdRange(0, 4),
    requestFifo = true,
    visibility = Seq(AddressSet(0x0000_0000, (BigInt(1) << 64) - 1)))
  ))))

  val io_node = InModuleBody { client.makeIOs() }
  lazy val module = new ArmleoCoreImpl(this)
}

class ArmleoCoreImpl(outer: ArmleoCore) extends LazyModuleImp(outer) {
  val (tl, edge) = outer.client.out(0)

  val (legal, a) = edge.Get(0.U, "h1000".U, 0x4.U)
  tl.a.bits := a
  val io = IO(new Bundle() {
    val legal = Output(Bool())
  })
  io.legal := legal
}

object ArmleoCoreDriver extends App {
  (new chisel3.stage.ChiselStage).emitVerilog(new ArmleoCoreTop(), args)
}

运行后出现如下报错:

(run-main-29) java.lang.IllegalArgumentException: requirement failed: Diplomacy has detected a problem with your graph:
[error] At the following node, the number of outward ports should equal the number of produced outward parameters.
[error] source acore.client node:
[error] parents: acore
[error] locator:  (src/main/scala/armleocpu/ArmleoCore.scala:11:25)
[error] 
[error] 0 outward ports connected: []
[error] 0 inward ports connected: []
[error] 
[error] Downstreamed inward parameters: []
[error] Produced outward parameters: [TLMasterPortParameters(List(TLMasterParameters(ArmleoCore, IdRange(0,4), List(), List(AddressSet(0x0, 0xffffffffffffffff)), Set(), false, true, , TBALGFPH, false)), TLChannelBeatBytes(None,None,None,None), 0, List(), List(), List())]

问题原因

报错核心是TLClientNode声明了对外提供的Master参数,但既没有连接到下游节点,也没有正确导出为顶层IO,Diplomacy的图检查机制发现参数与实际连接端口数量不匹配,因此抛出错误。同时原代码的层级结构不符合LazyModule的使用规范(普通Module嵌套LazyModule)。

修正方案

以下是调整后的完整代码,关键修改点已标注:

import chisel3._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._

// 顶层改为LazyModule,适配内部嵌套的LazyModule实例
class ArmleoCoreTop(implicit p: Parameters) extends LazyModule {
  val acore = LazyModule(new ArmleoCore())
  // 将client节点转换为可导出的Sink端口
  val tlSink = acore.client.makeSink()
  
  lazy val module = new Impl(this)
  class Impl(outer: ArmleoCoreTop) extends LazyModuleImp(outer) {
    // 导出顶层TileLink IO端口
    val io = IO(new Bundle {
      val tl = Flipped(TLClientPort(tlSink.params))
    })
    // 连接Sink端口与顶层IO
    io.tl <> tlSink.node.io
  }
}

class ArmleoCore()(implicit p: Parameters) extends LazyModule {
  val client = TLClientNode(Seq(TLMasterPortParameters.v1(Seq(TLMasterParameters.v1(
    name = "ArmleoCore",
    sourceId = IdRange(0, 4),
    requestFifo = true,
    visibility = Seq(AddressSet(0x0000_0000, (BigInt(1) << 64) - 1)))
  ))))

  lazy val module = new ArmleoCoreImpl(this)
}

class ArmleoCoreImpl(outer: ArmleoCore) extends LazyModuleImp(outer) {
  val (tl, edge) = outer.client.out(0)

  // 生成Get请求示例
  val (legal, a) = edge.Get(0.U, "h1000".U, 0x4.U)
  tl.a.bits := a
  tl.a.valid := legal // 仅当请求合法时置位valid

  // 必须处理响应通道,避免未连接信号报错
  tl.d.ready := true.B
}

object ArmleoCoreDriver extends App {
  implicit val p = Parameters.empty
  // 正确生成LazyModule对应的硬件模块
  (new chisel3.stage.ChiselStage).emitVerilog(LazyModule(new ArmleoCoreTop()).module, args)
}

关键修改说明

  • 层级结构修正:ArmleoCoreTop改为LazyModule,因为它内部包含LazyModule类型的acore,Diplomacy要求LazyModule必须嵌套在LazyModule中。
  • 节点导出方式:使用client.makeSink()将TLClientNode转换为可导出的端口节点,解决参数与端口数量不匹配的问题。
  • 信号完整性:在ArmleoCoreImpl中必须处理tl.d通道(设置ready),否则会出现未连接的硬件信号错误。
  • 顶层生成规范:生成Verilog时需调用LazyModule(...).module,获取LazyModule对应的实际硬件模块实例。

内容的提问来源于stack exchange,提问作者armleo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 11:49:59