表达式 _GEN_7 用作 FEMALE 但只能用作 MALE
Expression _GEN_7 is used as a FEMALE but can only be used as a MALE
我正在尝试为 firrtl 编写一个 Scala 转换,在某些时候,我有一堆电线应该连接到输入端口。因为电线的数量可能很多,我不想将每根电线都连接到一个端口,而是将所有电线连接在一起并使用一个宽度更大的端口。
我正在使用 seqCat 函数:
val seq_cat = seqCat(wires.map(x=>WRef(x.name,port.tpe,WireKind,BIGENDER)))
然后我接上猫的输出,就是几只猫组成的表达式:
val connect_pin = Connect(NoInfo, seq_cat, WRef(port.name, port.tpe, PortKind, BIGENDER))
因为connect_pin的表达式比较复杂:
Connect(,DoPrim(cat,List(WRef(_GEN_0,UIntType(IntWidth(3)),WireKind,BIGENDER), DoPrim(cat,ArrayBuffer(WRef(_GEN_1,UIntType(IntWidth(3)),WireKind,BIGENDER), WRef(_GEN_2,UIntType(IntWidth(3)),WireKind,BIGENDER)),List(),UIntType(UnknownWidth))),List(),UIntType(UnknownWidth)),WRef(faultPin,UIntType(IntWidth(3)),PortKind,BIGENDER))
我尝试使用 Chisel Bootcamp 上提供的 Splitter 函数将其拆分为更简单的节点,splitter 的输出是预期的:
Block(ArrayBuffer(DefNode(,_GEN_6,DoPrim(cat,ArrayBuffer(WRef(_GEN_1,UIntType(IntWidth(3)),WireKind,BIGENDER), WRef(_GEN_2,UIntType(IntWidth(3)),WireKind,BIGENDER)),List(),UIntType(UnknownWidth))), DefNode(,_GEN_7,DoPrim(cat,List(WRef(_GEN_0,UIntType(IntWidth(3)),WireKind,BIGENDER), WRef(_GEN_6,UIntType(UnknownWidth),ExpKind,UNKNOWNGENDER)),List(),UIntType(UnknownWidth))), Connect(,WRef(_GEN_7,UIntType(UnknownWidth),ExpKind,UNKNOWNGENDER),WRef(faultPin,UIntType(IntWidth(3)),PortKind,BIGENDER))))
当我 运行 转换时,出现 运行 时间错误:
======== Starting Transform CheckGenders$ ========
[error] (run-main-0) firrtl.passes.CheckGenders$WrongGender: @[:Top_adder_muxed.fir@22.2]: [module Top_adder] Expression _GEN_7 is used as a FEMALE but can only be used as a MALE.
[error] firrtl.passes.CheckGenders$WrongGender: @[:Top_adder_muxed.fir@22.2]: [module Top_adder] Expression _GEN_7 is used as a FEMALE but can only be used as a MALE.
[error] at firrtl.passes.CheckGenders$.firrtl$passes$CheckGenders$$check_gender(Checks.scala:511)
[error] at firrtl.passes.CheckGenders$.firrtl$passes$CheckGenders$$check_genders_s(Checks.scala:542)
[error] at firrtl.passes.CheckGenders$$anonfun$firrtl$passes$CheckGenders$$check_genders_s.apply(Checks.scala:558)
[error] at firrtl.passes.CheckGenders$$anonfun$firrtl$passes$CheckGenders$$check_genders_s.apply(Checks.scala:558) ``` ```
我不明白为什么会出现这个错误,它只是一根线,应该连接到输入端口。事实上,这根电线是猫的输出,它并不能使它成为 MALE,因为只是将一些电线放在一起,猫操作员不会合成任何驱动电线的驱动程序。
如果你对此有任何提示,我在这个错误上被困了几天。
问题是原始操作(DoPrims)的输出是MALE(新术语中的SourceFlow,基本上是只读值)。虽然概念上将连线连接在一起并不一定意味着它是只读的,但在 FIRRTL 的语义中确实如此。这在 FIRRTL Spec 的第 8 节中有描述:"The flow of all other expressions are source"。
所以这给我们留下了一个问题,即如何完成将单个端口连接到多条线。您可以使用多个连接来执行此操作。这是代码的草图,当然,这取决于您的具体类型:
// Assuming 3-bit wires and UInt port as suggested by the code in the question
val portRef = WRef(port) // same as val portRef = WRef(port.name, port.tpe, PortKind, UNKNOWNGENDER)
val cons = wires.zipWithIndex.map { case (wire, idx) =>
val msb = (idx * 3) - 1
val lsb = msb - 2
val rhs = DoPrim(PrimOps.Bits, Seq(portRef), Seq(msb, lsb), UIntType(IntWidth(3)))
val lhs = WRef(wire) // same as WRef(wire.name, wire.tpe, WireKind, UNKNOWNGENDER)
Connect(NoInfo, lhs, rhs)
}
所有这些逻辑都可以包含在一个可重用的实用程序函数中,这可能非常有用,当然这样的实用程序需要适用于其他类型(不仅仅是 UInts)。
我正在尝试为 firrtl 编写一个 Scala 转换,在某些时候,我有一堆电线应该连接到输入端口。因为电线的数量可能很多,我不想将每根电线都连接到一个端口,而是将所有电线连接在一起并使用一个宽度更大的端口。
我正在使用 seqCat 函数:
val seq_cat = seqCat(wires.map(x=>WRef(x.name,port.tpe,WireKind,BIGENDER)))
然后我接上猫的输出,就是几只猫组成的表达式:
val connect_pin = Connect(NoInfo, seq_cat, WRef(port.name, port.tpe, PortKind, BIGENDER))
因为connect_pin的表达式比较复杂:
Connect(,DoPrim(cat,List(WRef(_GEN_0,UIntType(IntWidth(3)),WireKind,BIGENDER), DoPrim(cat,ArrayBuffer(WRef(_GEN_1,UIntType(IntWidth(3)),WireKind,BIGENDER), WRef(_GEN_2,UIntType(IntWidth(3)),WireKind,BIGENDER)),List(),UIntType(UnknownWidth))),List(),UIntType(UnknownWidth)),WRef(faultPin,UIntType(IntWidth(3)),PortKind,BIGENDER))
我尝试使用 Chisel Bootcamp 上提供的 Splitter 函数将其拆分为更简单的节点,splitter 的输出是预期的:
Block(ArrayBuffer(DefNode(,_GEN_6,DoPrim(cat,ArrayBuffer(WRef(_GEN_1,UIntType(IntWidth(3)),WireKind,BIGENDER), WRef(_GEN_2,UIntType(IntWidth(3)),WireKind,BIGENDER)),List(),UIntType(UnknownWidth))), DefNode(,_GEN_7,DoPrim(cat,List(WRef(_GEN_0,UIntType(IntWidth(3)),WireKind,BIGENDER), WRef(_GEN_6,UIntType(UnknownWidth),ExpKind,UNKNOWNGENDER)),List(),UIntType(UnknownWidth))), Connect(,WRef(_GEN_7,UIntType(UnknownWidth),ExpKind,UNKNOWNGENDER),WRef(faultPin,UIntType(IntWidth(3)),PortKind,BIGENDER))))
当我 运行 转换时,出现 运行 时间错误:
======== Starting Transform CheckGenders$ ========
[error] (run-main-0) firrtl.passes.CheckGenders$WrongGender: @[:Top_adder_muxed.fir@22.2]: [module Top_adder] Expression _GEN_7 is used as a FEMALE but can only be used as a MALE.
[error] firrtl.passes.CheckGenders$WrongGender: @[:Top_adder_muxed.fir@22.2]: [module Top_adder] Expression _GEN_7 is used as a FEMALE but can only be used as a MALE.
[error] at firrtl.passes.CheckGenders$.firrtl$passes$CheckGenders$$check_gender(Checks.scala:511)
[error] at firrtl.passes.CheckGenders$.firrtl$passes$CheckGenders$$check_genders_s(Checks.scala:542)
[error] at firrtl.passes.CheckGenders$$anonfun$firrtl$passes$CheckGenders$$check_genders_s.apply(Checks.scala:558)
[error] at firrtl.passes.CheckGenders$$anonfun$firrtl$passes$CheckGenders$$check_genders_s.apply(Checks.scala:558) ``` ```
我不明白为什么会出现这个错误,它只是一根线,应该连接到输入端口。事实上,这根电线是猫的输出,它并不能使它成为 MALE,因为只是将一些电线放在一起,猫操作员不会合成任何驱动电线的驱动程序。
如果你对此有任何提示,我在这个错误上被困了几天。
问题是原始操作(DoPrims)的输出是MALE(新术语中的SourceFlow,基本上是只读值)。虽然概念上将连线连接在一起并不一定意味着它是只读的,但在 FIRRTL 的语义中确实如此。这在 FIRRTL Spec 的第 8 节中有描述:"The flow of all other expressions are source"。
所以这给我们留下了一个问题,即如何完成将单个端口连接到多条线。您可以使用多个连接来执行此操作。这是代码的草图,当然,这取决于您的具体类型:
// Assuming 3-bit wires and UInt port as suggested by the code in the question
val portRef = WRef(port) // same as val portRef = WRef(port.name, port.tpe, PortKind, UNKNOWNGENDER)
val cons = wires.zipWithIndex.map { case (wire, idx) =>
val msb = (idx * 3) - 1
val lsb = msb - 2
val rhs = DoPrim(PrimOps.Bits, Seq(portRef), Seq(msb, lsb), UIntType(IntWidth(3)))
val lhs = WRef(wire) // same as WRef(wire.name, wire.tpe, WireKind, UNKNOWNGENDER)
Connect(NoInfo, lhs, rhs)
}
所有这些逻辑都可以包含在一个可重用的实用程序函数中,这可能非常有用,当然这样的实用程序需要适用于其他类型(不仅仅是 UInts)。