Выражение _GEN_7 используется как ЖЕНЩИНА, но может использоваться только как МУЖЧИНА - PullRequest
4 голосов
/ 02 октября 2019

Я пытаюсь написать преобразование Scala для firrtl, и в какой-то момент у меня есть несколько проводов, которые должны быть подключены к входному порту. Поскольку число проводов может быть слишком большим, я не хочу соединять каждый провод с портом, но объединить все провода вместе и использовать один порт с большей шириной.

Я использую функцию seqCat:

 val seq_cat = seqCat(wires.map(x=>WRef(x.name,port.tpe,WireKind,BIGENDER))) 

, затем я подключаю выход cat, который является выражением, составленным из нескольких кошек:

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))

Я пытаюсь разбить его на более простые узлы, используя функцию Splitter , предоставленную в Chisel Bootcamp, и вывод 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$1(Checks.scala:511)
[error]     at firrtl.passes.CheckGenders$.firrtl$passes$CheckGenders$$check_genders_s$1(Checks.scala:542)
[error]     at firrtl.passes.CheckGenders$$anonfun$firrtl$passes$CheckGenders$$check_genders_s$1$4.apply(Checks.scala:558)
[error]     at firrtl.passes.CheckGenders$$anonfun$firrtl$passes$CheckGenders$$check_genders_s$1$4.apply(Checks.scala:558) ``` ``` 

Я не понимаю, почему происходит эта ошибка, это просто провод, который должен быть связан с входомпорт. Тот факт, что этот провод является выходом кошки, он не делает его МУЖЧИНОЙ, потому что просто соединяет несколько проводов, оператор кошки не синтезирует драйвер для управления проводами.

Если выесть подсказка, я застрял на несколько дней с этой ошибкой.

1 Ответ

3 голосов
/ 02 октября 2019

Проблема в том, что выходные данные примитивных операций (DoPrims) имеют значение MALE (SourceFlow в новой терминологии, в основном значение только для чтения). Хотя условная конкатенация проводов вместе не обязательно означает, что она доступна только для чтения, в семантике FIRRTL это так. Это описано в разделе 8 спецификации FIRRTL : «Поток всех других выражений является источником».

Таким образом, возникает вопрос о том, как выполнить подключение одного порта к нескольким проводам. Вы делаете это с несколькими подключениями. Вот эскиз того, как может выглядеть код, но, конечно, это зависит от ваших точных типов:

// 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).

...