Skip to content

Commit 0b4a873

Browse files
committed
Create OneHotChiselEnum where elements have one-hot encoding IDs
1 parent f26f855 commit 0b4a873

File tree

3 files changed

+32
-6
lines changed

3 files changed

+32
-6
lines changed

core/src/main/scala/chisel3/StrongEnum.scala

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,9 @@ abstract class EnumType(private val factory: EnumFactory, selfAnnotating: Boolea
232232
def toPrintable: Printable = FullName(this) // TODO: Find a better pretty printer
233233
}
234234

235+
trait OneHotEnumFactory extends EnumFactory{
236+
override val oneHot: Boolean = true
237+
}
235238

236239
abstract class EnumFactory {
237240
class Type extends EnumType(this)
@@ -241,6 +244,7 @@ abstract class EnumFactory {
241244

242245
private var id: BigInt = 0
243246
private[chisel3] var width: Width = 0.W
247+
val oneHot: Boolean = false
244248

245249
private case class EnumRecord(inst: Type, name: String)
246250
private val enumRecords = mutable.ArrayBuffer.empty[EnumRecord]
@@ -274,13 +278,13 @@ abstract class EnumFactory {
274278
protected def do_Value(name: String): Type = {
275279
val result = new Type
276280

277-
// We have to use UnknownWidth here, because we don't actually know what the final width will be
278-
result.bindToLiteral(id, UnknownWidth())
279-
280-
enumRecords.append(EnumRecord(result, name))
281+
val resId = if (!oneHot) id else BigInt(1 << id.toInt)
281282

282-
width = (1 max id.bitLength).W
283+
// We have to use UnknownWidth here, because we don't actually know what the final width will be
284+
result.bindToLiteral(resId, UnknownWidth())
285+
width = (1 max resId.bitLength).W
283286
id += 1
287+
enumRecords.append(EnumRecord(result, name))
284288

285289
result
286290
}
@@ -343,7 +347,6 @@ abstract class EnumFactory {
343347
}
344348
}
345349

346-
347350
private[chisel3] object EnumMacros {
348351
def ValImpl(c: Context) : c.Tree = {
349352
import c.universe._

core/src/main/scala/chisel3/experimental/package.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ package object experimental {
2323

2424
type ChiselEnum = EnumFactory
2525

26+
/**
27+
* OneHotChiselEnum extends the ChiselEnum type for creating enums with
28+
* one-hot encoding IDs.
29+
* This enum type pairs well with [[Mux1H]] for parallel mux processing.
30+
*/
31+
type OneHotChiselEnum = OneHotEnumFactory
32+
2633
// Rocket Chip-style clonemodule
2734

2835
/** A record containing the results of CloneModuleAsRecord

src/main/scala/chisel3/util/Mux.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import chisel3._
99

1010
/** Builds a Mux tree out of the input signal vector using a one hot encoded
1111
* select signal. Returns the output of the Mux tree.
12+
* Pairs well with [[OneHotChiselEnum]] to create a one hot encoded select signal.
1213
*
1314
* @example {{{
1415
* val hotValue = chisel3.util.Mux1H(Seq(
@@ -17,6 +18,21 @@ import chisel3._
1718
* io.selector(2) -> 8.U,
1819
* io.selector(4) -> 11.U,
1920
* ))
21+
*
22+
* // or using OneHotChiselEnum
23+
*
24+
* object selector extends chisel3.experimental.OneHotChiselEnum {
25+
* val s0, s1, s2, s3 = Value
26+
* }
27+
* val selectorVal = Wire(UInt(selector.getWidth.W))
28+
* selectorVal := selector.s1.asUInt
29+
* val hotValue = chisel3.util.Mux1H(selectorVal.asUInt,
30+
Seq(
31+
* 2.U,
32+
* 4.U,
33+
* 8.U,
34+
* 11.U,
35+
* ))
2036
* }}}
2137
*
2238
* @note results unspecified unless exactly one select signal is high

0 commit comments

Comments
 (0)