Заявление о переключении долот, кажется, не работает так, как описано в официальном руководстве

Я пытался создать управляющую логику для цепи в долоте, когда получил несколько ошибок, связанных с операторами переключения, которые я использовал. Я решил запустить пример кода оператора switch, представленный на страницах 9 и 10 официального руководства по долото, чтобы изолировать проблему.

Скала код:

package Testbed

import Chisel._


class Testbed extends Module {
  val io = new Bundle {
    val nickel = Bool(dir = INPUT)
    val dime = Bool(dir = INPUT)
    val rdy = Bool(dir = OUTPUT) }

  val s_idle :: s_5 :: s_10 :: s_15 :: s_ok :: Nil = Enum(UFix(), 5)
  val state = Reg(init = s_idle)

  switch (state) {
    is (s_idle) {
      when (io.nickel) { state := s_5 }
      when (io.dime) { state := s_10 }
    } is (s_5) {
      when (io.nickel) { state := s_10 }
      when (io.dime) { state := s_15 }
    } is (s_10) {
      when (io.nickel) { state := s_15 }
      when (io.dime) { state := s_ok }
    } is (s_15) {
      when (io.nickel) { state := s_ok }
      when (io.dime) { state := s_ok }
    } is (s_ok) {
      state := s_idle
    }
  }
  io.rdy := (state === s_ok)
}


class TestbedTests(c: Testbed) extends Tester(c) {
}

object Testbed {
  def main(args: Array[String]): Unit = {
    val tutArgs = args.slice(1, args.length)
    chiselMainTest(tutArgs, () => Module(new Testbed())) {
      c => new TestbedTests(c) }
  }
}

Но я получаю ошибки, связанные с UFix:

[error] /home/chisel-tutorial/test/Testbed.scala:12: not found: value UFix
[error]   val s_idle :: s_5 :: s_10 :: s_15 :: s_ok :: Nil = Enum(UFix(), 5)
[error]                                                           ^
[error] /home/chisel-tutorial/test/Testbed.scala:13: inferred type arguments [Any] do not conform to method apply's type parameter bounds [T <: Chisel.Data]
[error]   val state = Reg(init = s_idle)
[error]               ^
[error] /home/chisel-tutorial/test/Testbed.scala:16: overloaded method value apply with alternatives:
[error]   (v: Iterable[Chisel.Bits])(block: => Unit)Unit <and>
[error]   (v: Chisel.Bits,vr: Chisel.Bits*)(block: => Unit)Unit <and>
[error]   (v: Chisel.Bits)(block: => Unit)Unit
[error]  cannot be applied to (Any)
[error]     is (s_idle) {
[error]     ^
[error] three errors found
[error] (compile:compile) Compilation failed

В учебнике он был написан как UFIx с большой буквы, но я попробовал оба способа безрезультатно. Я предположил, что это просто старый тип, поэтому я заменил UFix на UInt, но остальное оставил прежним. Тогда я получаю следующие ошибки:

[error] /home/chisel-tutorial/test/Testbed.scala:19: value is is not a member of Unit
[error] possible cause: maybe a semicolon is missing before `value is'?
[error]     } is (s_5) {
[error]       ^
[error] one error found
[error] (compile:compile) Compilation failed

Прислушиваясь к сообщению об ошибке, я попытался устранить ошибку, добавляя точки с запятой перед каждым оператором "is", кроме первого:

package Testbed

import Chisel._


class Testbed extends Module {
  val io = new Bundle {
    val nickel = Bool(dir = INPUT)
    val dime = Bool(dir = INPUT)
    val rdy = Bool(dir = OUTPUT) }

  val s_idle :: s_5 :: s_10 :: s_15 :: s_ok :: Nil = Enum(UInt(), 5)
  val state = Reg(init = s_idle)

  switch (state) {
    is (s_idle) {
      when (io.nickel) { state := s_5 }
      when (io.dime) { state := s_10 }
    }; is (s_5) {
      when (io.nickel) { state := s_10 }
      when (io.dime) { state := s_15 }
    }; is (s_10) {
      when (io.nickel) { state := s_15 }
      when (io.dime) { state := s_ok }
    }; is (s_15) {
      when (io.nickel) { state := s_ok }
      when (io.dime) { state := s_ok }
    }; is (s_ok) {
      state := s_idle
    }
  }
  io.rdy := (state === s_ok)
}


class TestbedTests(c: Testbed) extends Tester(c) {
}

object Testbed {
  def main(args: Array[String]): Unit = {
    val tutArgs = args.slice(1, args.length)
    chiselMainTest(tutArgs, () => Module(new Testbed())) {
      c => new TestbedTests(c) }
  }
}

и в результате код был наконец успешным в создании verilog. Затем я также попытался удалить точку с запятой, но поставил закрывающую фигурную скобку из предыдущего оператора switch в строке выше, которая также работала:

package Testbed

import Chisel._


class Testbed extends Module {
  val io = new Bundle {
    val nickel = Bool(dir = INPUT)
    val dime = Bool(dir = INPUT)
    val rdy = Bool(dir = OUTPUT) }

  val s_idle :: s_5 :: s_10 :: s_15 :: s_ok :: Nil = Enum(UInt(), 5)
  val state = Reg(init = s_idle)

  switch (state) {
    is (s_idle) {
      when (io.nickel) { state := s_5 }
      when (io.dime) { state := s_10 }}
    is (s_5) {
      when (io.nickel) { state := s_10 }
      when (io.dime) { state := s_15 }}
    is (s_10) {
      when (io.nickel) { state := s_15 }
      when (io.dime) { state := s_ok }}
    is (s_15) {
      when (io.nickel) { state := s_ok }
      when (io.dime) { state := s_ok }}
    is (s_ok) {
      state := s_idle
    }
  }
  io.rdy := (state === s_ok)
}


class TestbedTests(c: Testbed) extends Tester(c) {
}

object Testbed {
  def main(args: Array[String]): Unit = {
    val tutArgs = args.slice(1, args.length)
    chiselMainTest(tutArgs, () => Module(new Testbed())) {
      c => new TestbedTests(c) }
  }
}

Теперь меня интересует, работает ли версия оператора switch, представленная в руководстве по долотам, для других людей, и если да, кто-нибудь знает, почему я должен быть осторожен, чтобы отформатировать свои операторы switch очень специфическим образом, чтобы они правильно работать? Если это так, что я могу сделать, чтобы это исправить?

3 ответа

Причина связана с синтаксисом scala. Важно помнить, что вы кодируете в Scala и Chisel одновременно. Ваша ошибка с 'is' похожа на следующий синтаксис scala:

hashmap getOrElse (foo, bar)

"is" определяется как объект в https://github.com/ucbbar/chisel/blob/master/src/main/scala/when.scala

по сути, scala интерпретирует это как:

is().is

который не существует, поэтому он думает, что вы хотели определить его как val и просто облажался

просто отделяйте строку после каждого } примера:

      switch(in){
  is(condition){ 
   logic}
is(condition){ 
   logic}
}

после логики закрыть } и затем начать с новой строки

Как вы заметили, UFix больше не используется. Вместо этого используйте UInt.

Во-вторых, "это" должно начинаться с отдельной строки. Этому не может предшествовать {,

Другие вопросы по тегам