在 Chisel 中实现外交 AXI Stream 接口 - BundleMap.cloneType 错误
Implementing a diplomatic AXI Stream interface in Chisel - BundleMap.cloneType error
我正在尝试构建一个最小示例,说明如何使用 Chisel 和外交生成 AXI4Stream 接口。我正在使用 rocket-chip (freechips.rocketchip.amba.axis) 中已有的外交界面。我对 Chisel 有一些经验,但我仍在努力学习外交。
无论如何,我已经使用此处提供的答案成功创建了一个小型 APB 示例:
之后,我尝试创建一个类似的、简单的 AXI Stream 示例,但我不断收到错误。具体来说,我收到以下错误:
[error] (Compile / run) java.lang.Exception: Unable to use BundleMap.cloneType on class freechips.rocketchip.amba.axis.AXISBundleBits, probably because class freechips.rocketchip.amba.axis.AXISBundleBits does not have a constructor accepting BundleFields. Consider overriding cloneType() on class freechips.rocketchip.amba.axis.AXISBundleBits
代码:
package chipyard.example
import chisel3._
import chisel3.internal.sourceinfo.SourceInfo
import chisel3.stage.ChiselStage
import freechips.rocketchip.config.{Config, Parameters}
import freechips.rocketchip.amba.axis._
import freechips.rocketchip.diplomacy.{SimpleNodeImp, ValName, SourceNode, NexusNode,
SinkNode, LazyModule, LazyModuleImp, TransferSizes,
SimpleDevice, AddressSet}
class MyAxisController(implicit p: Parameters) extends LazyModule {
val device = new SimpleDevice("my-device", Seq("tutorial,my-device0"))
val axisParams = AXISSlaveParameters.v1(name = "axisSlave", supportsSizes = TransferSizes(8,8))
val axisPortParams = AXISSlavePortParameters.v1(slaves = Seq(axisParams))
val node = AXISSlaveNode(portParams = Seq(axisPortParams))
lazy val module = new LazyModuleImp(this) {
val ins = node.in.unzip._1
val register = RegInit(UInt(8.W), 0.U)
register := register + ins(0).bits.data
}
}
class AXISMaster()(implicit p: Parameters) extends LazyModule {
val axisMasterParams = AXISMasterParameters.v1(
name = "axisMaster", emitsSizes = TransferSizes(8, 8)
)
val axisMasterPortParams = AXISMasterPortParameters.v1(
masters = Seq(axisMasterParams),
beatBytes = Option(8)
)
val node = AXISMasterNode(
portParams = Seq(axisMasterPortParams)
)
lazy val module = new LazyModuleImp(this) {
//The dontTouch here preserves the interface so logic is generated
dontTouch(node.out.head._1)
}
}
class MyAxisWrapper()(implicit p: Parameters) extends LazyModule {
val master = LazyModule(new AXISMaster)
val slave = LazyModule(new MyAxisController()(Parameters.empty))
slave.node := master.node
lazy val module = new LazyModuleImp(this) {
//nothing???
}
}
和Main.scala:
package chipyard.example
import chisel3._
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy._
import java.io.File
import java.io.FileWriter
/**
* An object extending App to generate the Verilog code.
*/
object Main {
def main(args: Array[String]): Unit = {
//(new chisel3.stage.ChiselStage).execute(args, Seq(ChiselGeneratorAnnotation(() => LazyModule(new MyWrapper()(Parameters.empty)).module)))
val verilog = (new chisel3.stage.ChiselStage).emitVerilog(
LazyModule(new MyAxisWrapper()(Parameters.empty)).module
)
//println(s"```verilog\n$verilog```")
val fileWriter = new FileWriter(new File("./gen/gen.v"))
fileWriter.write(verilog)
fileWriter.close()
}
}
该代码也可在 https://github.com/jurevreca12/temp_dspblock_example/tree/axistream2/scala/main 获得。
我的问题是。为什么会出现此错误?或者我一开始就做错了什么,有没有更简单的方法来创建 AXIStream 模块?
感谢任何反馈。
这似乎是 Rocket-Chip 为升级到 Chisel 3.5 所做的更改的问题。在这些更改期间,AXISBundleBits
删除了它的 cloneType,即使它扩展了 BundleMap(因此由于扩展了 Record
而需要 cloneType)。
目前我还不了解 cloneType 的所有细节,但本质上:
- 记录需要 cloneType
- Bundle 过去需要 cloneType,但自从编译器插件实现后,从 3.5 开始,它们不再需要 cloneType。
BundleMap
是一个令人困惑的情况,因为它是一个直接从 Record 扩展的自定义 Bundle 类型,而不是 Bundle 类型。因此,它不应该在 3.5 Chisel bump 期间删除其 cloneType 方法,并且需要将其添加回 RC 主分支中的 AXIS 才能再次开始工作。
编辑:cloneType 异常问题现已在主分支上针对 3.5 修复:)
我正在尝试构建一个最小示例,说明如何使用 Chisel 和外交生成 AXI4Stream 接口。我正在使用 rocket-chip (freechips.rocketchip.amba.axis) 中已有的外交界面。我对 Chisel 有一些经验,但我仍在努力学习外交。
无论如何,我已经使用此处提供的答案成功创建了一个小型 APB 示例:
之后,我尝试创建一个类似的、简单的 AXI Stream 示例,但我不断收到错误。具体来说,我收到以下错误:
[error] (Compile / run) java.lang.Exception: Unable to use BundleMap.cloneType on class freechips.rocketchip.amba.axis.AXISBundleBits, probably because class freechips.rocketchip.amba.axis.AXISBundleBits does not have a constructor accepting BundleFields. Consider overriding cloneType() on class freechips.rocketchip.amba.axis.AXISBundleBits
代码:
package chipyard.example
import chisel3._
import chisel3.internal.sourceinfo.SourceInfo
import chisel3.stage.ChiselStage
import freechips.rocketchip.config.{Config, Parameters}
import freechips.rocketchip.amba.axis._
import freechips.rocketchip.diplomacy.{SimpleNodeImp, ValName, SourceNode, NexusNode,
SinkNode, LazyModule, LazyModuleImp, TransferSizes,
SimpleDevice, AddressSet}
class MyAxisController(implicit p: Parameters) extends LazyModule {
val device = new SimpleDevice("my-device", Seq("tutorial,my-device0"))
val axisParams = AXISSlaveParameters.v1(name = "axisSlave", supportsSizes = TransferSizes(8,8))
val axisPortParams = AXISSlavePortParameters.v1(slaves = Seq(axisParams))
val node = AXISSlaveNode(portParams = Seq(axisPortParams))
lazy val module = new LazyModuleImp(this) {
val ins = node.in.unzip._1
val register = RegInit(UInt(8.W), 0.U)
register := register + ins(0).bits.data
}
}
class AXISMaster()(implicit p: Parameters) extends LazyModule {
val axisMasterParams = AXISMasterParameters.v1(
name = "axisMaster", emitsSizes = TransferSizes(8, 8)
)
val axisMasterPortParams = AXISMasterPortParameters.v1(
masters = Seq(axisMasterParams),
beatBytes = Option(8)
)
val node = AXISMasterNode(
portParams = Seq(axisMasterPortParams)
)
lazy val module = new LazyModuleImp(this) {
//The dontTouch here preserves the interface so logic is generated
dontTouch(node.out.head._1)
}
}
class MyAxisWrapper()(implicit p: Parameters) extends LazyModule {
val master = LazyModule(new AXISMaster)
val slave = LazyModule(new MyAxisController()(Parameters.empty))
slave.node := master.node
lazy val module = new LazyModuleImp(this) {
//nothing???
}
}
和Main.scala:
package chipyard.example
import chisel3._
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy._
import java.io.File
import java.io.FileWriter
/**
* An object extending App to generate the Verilog code.
*/
object Main {
def main(args: Array[String]): Unit = {
//(new chisel3.stage.ChiselStage).execute(args, Seq(ChiselGeneratorAnnotation(() => LazyModule(new MyWrapper()(Parameters.empty)).module)))
val verilog = (new chisel3.stage.ChiselStage).emitVerilog(
LazyModule(new MyAxisWrapper()(Parameters.empty)).module
)
//println(s"```verilog\n$verilog```")
val fileWriter = new FileWriter(new File("./gen/gen.v"))
fileWriter.write(verilog)
fileWriter.close()
}
}
该代码也可在 https://github.com/jurevreca12/temp_dspblock_example/tree/axistream2/scala/main 获得。
我的问题是。为什么会出现此错误?或者我一开始就做错了什么,有没有更简单的方法来创建 AXIStream 模块?
感谢任何反馈。
这似乎是 Rocket-Chip 为升级到 Chisel 3.5 所做的更改的问题。在这些更改期间,AXISBundleBits
删除了它的 cloneType,即使它扩展了 BundleMap(因此由于扩展了 Record
而需要 cloneType)。
目前我还不了解 cloneType 的所有细节,但本质上:
- 记录需要 cloneType
- Bundle 过去需要 cloneType,但自从编译器插件实现后,从 3.5 开始,它们不再需要 cloneType。
BundleMap
是一个令人困惑的情况,因为它是一个直接从 Record 扩展的自定义 Bundle 类型,而不是 Bundle 类型。因此,它不应该在 3.5 Chisel bump 期间删除其 cloneType 方法,并且需要将其添加回 RC 主分支中的 AXIS 才能再次开始工作。
编辑:cloneType 异常问题现已在主分支上针对 3.5 修复:)