【问题标题】:Chisel switch statement doesn't appear to work in manner outlined in official tutorialChisel switch 语句似乎无法以官方教程中概述的方式工作
【发布时间】:2015-07-30 08:35:04
【问题描述】:

当我收到与我正在使用的 switch 语句相关的多个错误时,我正试图为 chisel 中的电路创建控制逻辑。我决定运行官方chisel tutorial第9页和第10页提供的switch语句示例代码来隔离问题。

Scala 代码:

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,并带有大写字母 I,但我尝试了两种方式都无济于事。我认为这只是一种旧类型,所以我用 UInt 替换了 UFix,但其他一切都保持不变。然后我得到以下错误:

[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 语句让他们正常工作?如果是这种情况,我该怎么做才能解决它?

【问题讨论】:

    标签: scala switch-statement chisel


    【解决方案1】:

    原因与 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 并且搞砸了

    【讨论】:

      【解决方案2】:

      如您所见,UFix 已不再使用。而是使用 UInt。

      其次,“is”必须从自己的行开始。前面不能有 {

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多