scala 凿形铸件:将UInt转换为Int

q3qa4bjr  于 2023-08-05  发布在  Scala
关注(0)|答案(1)|浏览(156)

我正在做一个Chisel项目,遇到了一个与将UInt转换为Int相关的问题。我尝试过使用litValue方法,但在执行代码时,它给了我一个None.get错误。我需要关于如何正确执行从UInt到Int的转换并避免None.get错误的指导

val uintValue: UInt = // Some UInt value
val intValue: Int = uintValue.litValue() // This line gives None.get error

字符串
我尝试使用.litValue()方法将UInt值转换为Int
我希望这段代码能成功地将UInt值转换为Int,并将其存储在intValue变量中。然而,当执行代码时,它导致了None.get错误,我无法获得所需的整数值。
我需要关于如何正确执行从UInt到Int的转换并避免None.get错误的指导。

ufj5ltwl

ufj5ltwl1#

不知道你到底想做什么。UIntchisel data type,意思是Int是scala数据类型。
Chisel数据类型用于指定状态元素中保存的值的类型或在线路上流动的值的类型。虽然硬件设计最终是在二进制数字的向量上操作,但其他更抽象的值表示允许更清晰的规范,并帮助工具生成更优化的电路。
根据讨论How to convert Chisel.UInt to scala Int?,您尝试做的事情似乎没有意义
一般来说,这是不可能的。UInt指定运行时信号的类型,该信号在电路仿真期间可能仅具有特定值。如果要在模拟过程中将UInt值转换为Scala Int,请使用peek()方法。
它还提供了一些代码,但我猜它有点过时,因为这个问题是在2015年5月21日完成的。所以,我将添加另一个来自repo schoeberl - chisel-examples的示例

scalaVersion := "2.12.13"

// Chisel 3.5
addCompilerPlugin("edu.berkeley.cs" % "chisel3-plugin" % "3.5.3" cross CrossVersion.full)
libraryDependencies += "edu.berkeley.cs" %% "chisel3" % "3.5.3"
libraryDependencies += "edu.berkeley.cs" %% "chiseltest" % "0.5.3"

字符串

import chisel3._

/**
 * The blinking LED component.
 */

class Hello extends Module {
  val io = IO(new Bundle {
    val led = Output(UInt(1.W))
  })
  val CNT_MAX = (50000000 / 2 - 1).U

  val cntReg = RegInit(0.U(32.W))
  val blkReg = RegInit(0.U(1.W))

  cntReg := cntReg + 1.U
  when(cntReg === CNT_MAX) {
    cntReg := 0.U
    blkReg := ~blkReg
  }
  io.led := blkReg
}

/**
 * An object extending App to generate the Verilog code.
 */
object Hello extends App {
  (new chisel3.stage.ChiselStage).emitVerilog(new Hello())
}

  • test Hello(如何使用chiseltest编写测试)
import chiseltest._
import org.scalatest.flatspec.AnyFlatSpec

class HelloTest extends AnyFlatSpec with ChiselScalatestTester {
  behavior of "Hello"
  it should "pass" in {
    test(new Hello) { c => // 
      c.clock.setTimeout(0)
      var ledStatus = BigInt(-1)
      println("Start the blinking LED")
      for (_ <- 0 until 100) {
        c.clock.step(10000)
        val ledNow = c.io.led.peek().litValue
        val s = if (ledNow == 0) "o" else "*"
        if (ledStatus != ledNow) {
          System.out.println(s)
          ledStatus = ledNow
        }
      }
      println("\nEnd the blinking LED")
    }
  }
}


你得到的错误来自scala。这里有一些文章谈到了这一点

原因

一些OptionNone,并通过抛出异常来处理它们:

None.get
// java.util.NoSuchElementException: None.get
//    at scala.None$.get(Option.scala:366)
//    at repl.Session$App$$anonfun$1.apply(option_get.md:9)
//    at repl.Session$App$$anonfun$1.apply(option_get.md:9)


如果你有一个默认值来提供None的情况,使用getOrElse:

None.getOrElse(-1)
// res0: Int = -1

Scala方式的Scala解决方案:

使用OptionSomeNone。😎
但它是什么???
Option的行为有点像一个引用的容器,如果一个引用不是空的,即它指向某个内存位置,则返回Some,否则返回None
如果查看抽象类Data中的函数litValue的代码

/**
    * Returns the literal value if this is a literal that is representable as bits, otherwise crashes.
    */
  def litValue: BigInt = litOption.get


正如在前面的文章中所详细介绍的那样,直接调用Option.get并不是一个好的做法。也可以使用方法litOption

/**
    * If this is a literal that is representable as bits, returns the value as a BigInt.
    * If not a literal, or not representable as bits (for example, is or contains Analog), returns None.
    */
  def litOption: Option[BigInt]


这个函数返回一个Option[BigInt],这意味着你可以使用Pattern Matching来执行一些操作,或者使用getOrElse返回一个默认值。

相关问题