Chisel3:如何在Bundle定义中移除Input和Output修饰符?
解决方案:无需复制粘贴生成无方向Bundle
现有带方向修饰的Bundle定义:
class ios extends Bundle{ val wen = Input(Bool()) val wdata = Input(UInt(8.W)) val rdata = Output(UInt(8.W)) }
以及翻转方向后的版本:
class flipped_ios extends Bundle{ val wen = Output(Bool()) val wdata = Output(UInt(8.W)) val rdata = Input(UInt(8.W)) }
要生成不带Input/Output修饰的plain_ios,完全不需要复制粘贴修改代码,有几种实用的Chisel实现方式:
1. 先定义无方向基础Bundle(推荐)
从设计根源避免重复代码,先写无方向的核心结构,再基于它扩展带方向的版本:
// 无方向的基础Bundle class plain_ios extends Bundle{ val wen = Bool() val wdata = UInt(8.W) val rdata = UInt(8.W) } // 带输入输出方向的Bundle复用基础结构 class ios extends plain_ios { override val wen = Input(Bool()) override val wdata = Input(UInt(8.W)) override val rdata = Output(UInt(8.W)) } // 翻转方向的Bundle同理 class flipped_ios extends plain_ios { override val wen = Output(Bool()) override val wdata = Output(UInt(8.W)) override val rdata = Input(UInt(8.W)) }
后续修改字段结构时,只需要改动plain_ios,所有依赖它的带方向Bundle会自动同步,维护成本极低。
2. 从已有带方向Bundle动态提取类型
如果已经存在ios类,不想重新定义基础结构,可以通过Chisel的API遍历字段,提取无方向的基础类型来构建plain_ios:
class plain_ios extends Bundle { val iosInst = new ios // 遍历原Bundle的所有字段,提取底层无方向类型 iosInst.getElements.zip(iosInst.names).foreach { case (elem, name) => val baseType = elem match { case in: Input[_] => in._underlyingType.cloneType case out: Output[_] => out._underlyingType.cloneType case _ => elem.cloneType } addElement(name, baseType) } }
这种方式完全不需要手动复制字段,自动同步原Bundle的字段结构和类型。
3. 使用类型别名统一管理
通过Scala的类型别名,把字段类型统一抽离,再分别用于带方向和无方向的Bundle:
object IOTypeDefs { type WenType = Bool type WdataType = UInt type RdataType = UInt } import IOTypeDefs._ class ios extends Bundle { val wen = Input(WenType()) val wdata = Input(WdataType(8.W)) val rdata = Output(RdataType(8.W)) } class plain_ios extends Bundle { val wen = WenType() val wdata = WdataType(8.W) val rdata = RdataType(8.W) }
这种方式适合需要统一管理字段类型的场景,修改类型时只需改动别名定义。
内容的提问来源于stack exchange,提问作者Kera
相关产品推荐
相关产品推荐

