Scala 期权影响
Scala Option Impact
我在使用 scala .getorElse
命令时遇到问题。我想一直生成 AVec
,但我只希望在 elemA >= 50
时生成 AVec
和 BVec
,最后,我希望在 [=16] 时生成所有这些=].我试过 .get
但没有成功,下面你可以看到 .getorElse
.
的实现
任何关于如何正确实施的建议将不胜感激。谢谢!
val AVec = Reg(Vec(10, Valid(Vec(10, UInt(8.W)))))
val BVec = if(elemA >= 50){
Some(Reg(Vec(11, Valid(Vec(11, UInt(8.W))))))
} else {
None
}
val CVec = if(elemA >= 100){
Some(Reg(Vec(12, Valid(Vec(12, UInt(8.W))))))
} else {
None
}
when(io.elemB.fire()){
when(io.elemC === 0.U){
AVec.map{_.valid := false.B}
}.elsewhen(io.elemC === 1.U){
AVec.map{_.valid := false.B}
BVec.getOrElse(AVec).map{_.valid := false.B}
}.otherwise{
AVec.map{_.valid := false.B}
BVec.getOrElse(AVec).map{_.valid := false.B}
CVec.getOrElse(CVec).map{_.valid := false.B} //<------Issues coming here
}
}
考虑到您的写作风格,为什么不呢?
CVec.getOrElse(AVec).map{_.valid := false.B}
话虽如此,Option
有更多惯用的方法。我建议在 Scala 中查看一些关于 Option
的教程,例如。 https://www.baeldung.com/scala/option-type
特别是,您并不总是需要“获取”Option
。将 Option
视为具有零个或一个元素的 List
或 Array
。就像您可以 map
或 foreach
a List
(或您在这里做的 chisel3 Vec
)一样,您可以 map
或 foreach
一个 Option
。考虑以下因素:
when(io.elemB.fire()){
when(io.elemC === 0.U){
// Note that I used () instead of {}, this is a stylistic choice
// Generally you use {} only when there are multiple Statements in the anonymous function
// If this doesn't make sense to you yet, just ignore it, it's fine to use {} :)
AVec.map(_.valid := false.B)
}.elsewhen(io.elemC === 1.U){
AVec.map(_.valid := false.B)
BVec.foreach(_.map(_.valid := false.B))
}.otherwise{
AVec.map(_.valid := false.B)
BVec.foreach(_.map(_.valid := false.B))
CVec.foreach(_.map(_.valid := false.B))
}
就像 AVec.map(f)
将 f
应用于 Vec
的每个元素一样,BVec.foreach(g)
将 g
应用于 BVec
的内容,如果它是 Some
,否则什么都不做。这是 2 层函数嵌套深度,当您不熟悉 Chisel/Scala 时可能看起来有点陌生,但这是表达它的常用方式。
或者,您可以测试选项并使用 .get
,这对于函数式编程的新手(即大多数 Chisel 新手)来说通常更熟悉:
when(io.elemB.fire()){
when(io.elemC === 0.U){
AVec.map(_.valid := false.B)
}.elsewhen(io.elemC === 1.U){
AVec.map(_.valid := false.B)
if (BVec.isDefined) {
BVec.get.map(_.valid := false.B)
}
}.otherwise{
AVec.map(_.valid := false.B)
if (BVec.isDefined) {
BVec.get.map(_.valid := false.B)
}
if (CVec.isDefined) {
CVec.get.map(_.valid := false.B)
}
}
如果这看起来有点冗长(你必须写两次 CVec
),那就是 foreach
的目的。这个“如果定义,做 .get
并做某事”字面意思是 Option.foreach
的 implementation。
我在使用 scala .getorElse
命令时遇到问题。我想一直生成 AVec
,但我只希望在 elemA >= 50
时生成 AVec
和 BVec
,最后,我希望在 [=16] 时生成所有这些=].我试过 .get
但没有成功,下面你可以看到 .getorElse
.
任何关于如何正确实施的建议将不胜感激。谢谢!
val AVec = Reg(Vec(10, Valid(Vec(10, UInt(8.W)))))
val BVec = if(elemA >= 50){
Some(Reg(Vec(11, Valid(Vec(11, UInt(8.W))))))
} else {
None
}
val CVec = if(elemA >= 100){
Some(Reg(Vec(12, Valid(Vec(12, UInt(8.W))))))
} else {
None
}
when(io.elemB.fire()){
when(io.elemC === 0.U){
AVec.map{_.valid := false.B}
}.elsewhen(io.elemC === 1.U){
AVec.map{_.valid := false.B}
BVec.getOrElse(AVec).map{_.valid := false.B}
}.otherwise{
AVec.map{_.valid := false.B}
BVec.getOrElse(AVec).map{_.valid := false.B}
CVec.getOrElse(CVec).map{_.valid := false.B} //<------Issues coming here
}
}
考虑到您的写作风格,为什么不呢?
CVec.getOrElse(AVec).map{_.valid := false.B}
话虽如此,Option
有更多惯用的方法。我建议在 Scala 中查看一些关于 Option
的教程,例如。 https://www.baeldung.com/scala/option-type
特别是,您并不总是需要“获取”Option
。将 Option
视为具有零个或一个元素的 List
或 Array
。就像您可以 map
或 foreach
a List
(或您在这里做的 chisel3 Vec
)一样,您可以 map
或 foreach
一个 Option
。考虑以下因素:
when(io.elemB.fire()){
when(io.elemC === 0.U){
// Note that I used () instead of {}, this is a stylistic choice
// Generally you use {} only when there are multiple Statements in the anonymous function
// If this doesn't make sense to you yet, just ignore it, it's fine to use {} :)
AVec.map(_.valid := false.B)
}.elsewhen(io.elemC === 1.U){
AVec.map(_.valid := false.B)
BVec.foreach(_.map(_.valid := false.B))
}.otherwise{
AVec.map(_.valid := false.B)
BVec.foreach(_.map(_.valid := false.B))
CVec.foreach(_.map(_.valid := false.B))
}
就像 AVec.map(f)
将 f
应用于 Vec
的每个元素一样,BVec.foreach(g)
将 g
应用于 BVec
的内容,如果它是 Some
,否则什么都不做。这是 2 层函数嵌套深度,当您不熟悉 Chisel/Scala 时可能看起来有点陌生,但这是表达它的常用方式。
或者,您可以测试选项并使用 .get
,这对于函数式编程的新手(即大多数 Chisel 新手)来说通常更熟悉:
when(io.elemB.fire()){
when(io.elemC === 0.U){
AVec.map(_.valid := false.B)
}.elsewhen(io.elemC === 1.U){
AVec.map(_.valid := false.B)
if (BVec.isDefined) {
BVec.get.map(_.valid := false.B)
}
}.otherwise{
AVec.map(_.valid := false.B)
if (BVec.isDefined) {
BVec.get.map(_.valid := false.B)
}
if (CVec.isDefined) {
CVec.get.map(_.valid := false.B)
}
}
如果这看起来有点冗长(你必须写两次 CVec
),那就是 foreach
的目的。这个“如果定义,做 .get
并做某事”字面意思是 Option.foreach
的 implementation。