// SPDX-License-Identifier: Apache-2.0 /** The Chisel compatibility package allows legacy users to continue using the `Chisel` (capital C) package name * while moving to the more standard package naming convention `chisel3` (lowercase c). */ import chisel3._ // required for implicit conversions. import chisel3.util.random.FibonacciLFSR import chisel3.stage.{phases, ChiselCircuitAnnotation, ChiselOutputFileAnnotation, ChiselStage} package object Chisel { import chisel3.internal.firrtl.Width import scala.language.experimental.macros import scala.annotation.StaticAnnotation import scala.annotation.compileTimeOnly import scala.language.implicitConversions implicit val defaultCompileOptions = chisel3.ExplicitCompileOptions.NotStrict abstract class Direction case object INPUT extends Direction case object OUTPUT extends Direction case object NODIR extends Direction val Input = chisel3.Input val Output = chisel3.Output object Flipped { def apply[T <: Data](target: T): T = chisel3.Flipped[T](target) } implicit class AddDirectionToData[T <: Data](target: T) { def asInput: T = Input(target) def asOutput: T = Output(target) def flip: T = Flipped(target) @deprecated( "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5" ) def flip(dummy: Int*): T = flip } implicit class AddDirMethodToData[T <: Data](target: T) { import chisel3.ActualDirection import chisel3.experimental.DataMirror import chisel3.internal.requireIsHardware def dir: Direction = { requireIsHardware(target) // This has the side effect of calling _autoWrapPorts target match { case e: Element => DataMirror.directionOf(e) match { case ActualDirection.Output => OUTPUT case ActualDirection.Input => INPUT case _ => NODIR } case _ => NODIR } } } implicit class cloneTypeable[T <: Data](target: T) { import chisel3.experimental.DataMirror def chiselCloneType: T = { DataMirror.internal.chiselTypeClone(target).asInstanceOf[T] } } type ChiselException = chisel3.internal.ChiselException type Data = chisel3.Data object Wire extends WireFactory { import chisel3.CompileOptions def apply[T <: Data](dummy: Int = 0, init: T)(implicit compileOptions: CompileOptions): T = chisel3.WireDefault(init) def apply[T <: Data](t: T, init: T)(implicit compileOptions: CompileOptions): T = chisel3.WireDefault(t, init) } object Clock { def apply(): Clock = new Clock def apply(dir: Direction): Clock = { val result = apply() dir match { case INPUT => Input(result) case OUTPUT => Output(result) case _ => result } } } type Clock = chisel3.Clock // Implicit conversion to allow fromBits because it's being deprecated in chisel3 implicit class fromBitsable[T <: Data](data: T) { import chisel3.CompileOptions import chisel3.internal.sourceinfo.SourceInfo /** Creates an new instance of this type, unpacking the input Bits into * structured data. * * This performs the inverse operation of toBits. * * @note does NOT assign to the object this is called on, instead creates * and returns a NEW object (useful in a clone-and-assign scenario) * @note does NOT check bit widths, may drop bits during assignment * @note what fromBits assigs to must have known widths */ def fromBits(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { that.asTypeOf(data) } } type Aggregate = chisel3.Aggregate object Vec extends chisel3.VecFactory { import chisel3.CompileOptions import chisel3.internal.sourceinfo._ @deprecated("Vec argument order should be size, t; this will be removed by the official release", "chisel3") def apply[T <: Data](gen: T, n: Int)(implicit compileOptions: CompileOptions): Vec[T] = apply(n, gen) /** Creates a new [[Vec]] of length `n` composed of the result of the given * function repeatedly applied. * * @param n number of elements (and the number of times the function is * called) * @param gen function that generates the [[Data]] that becomes the output * element */ def fill[T <: Data](n: Int)(gen: => T)(implicit compileOptions: CompileOptions): Vec[T] = apply(Seq.fill(n)(gen)) def apply[T <: Data](elts: Seq[T]): Vec[T] = macro VecTransform.apply_elts /** @group SourceInfoTransformMacro */ def do_apply[T <: Data](elts: Seq[T])(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = chisel3.VecInit(elts) def apply[T <: Data](elt0: T, elts: T*): Vec[T] = macro VecTransform.apply_elt0 /** @group SourceInfoTransformMacro */ def do_apply[T <: Data]( elt0: T, elts: T* )( implicit sourceInfo: SourceInfo, compileOptions: CompileOptions ): Vec[T] = chisel3.VecInit(elt0 +: elts.toSeq) def tabulate[T <: Data](n: Int)(gen: (Int) => T): Vec[T] = macro VecTransform.tabulate /** @group SourceInfoTransformMacro */ def do_tabulate[T <: Data]( n: Int )(gen: (Int) => T )( implicit sourceInfo: SourceInfo, compileOptions: CompileOptions ): Vec[T] = chisel3.VecInit.tabulate(n)(gen) } type Vec[T <: Data] = chisel3.Vec[T] type VecLike[T <: Data] = chisel3.VecLike[T] type Record = chisel3.Record type Bundle = chisel3.Bundle val assert = chisel3.assert val stop = chisel3.stop /** This contains literal constructor factory methods that are deprecated as of Chisel3. */ trait UIntFactory extends chisel3.UIntFactory { /** Create a UInt literal with inferred width. */ def apply(n: String): UInt = n.asUInt /** Create a UInt literal with fixed width. */ def apply(n: String, width: Int): UInt = n.asUInt(width.W) /** Create a UInt literal with specified width. */ def apply(value: BigInt, width: Width): UInt = value.asUInt(width) /** Create a UInt literal with fixed width. */ def apply(value: BigInt, width: Int): UInt = value.asUInt(width.W) /** Create a UInt with a specified width - compatibility with Chisel2. */ // NOTE: This resolves UInt(width = 32) def apply(dir: Option[Direction] = None, width: Int): UInt = apply(width.W) /** Create a UInt literal with inferred width.- compatibility with Chisel2. */ def apply(value: BigInt): UInt = value.asUInt /** Create a UInt with a specified direction and width - compatibility with Chisel2. */ def apply(dir: Direction, width: Int): UInt = apply(dir, width.W) /** Create a UInt with a specified direction, but unspecified width - compatibility with Chisel2. */ def apply(dir: Direction): UInt = apply(dir, Width()) def apply(dir: Direction, width: Width): UInt = { val result = apply(width) dir match { case INPUT => Input(result) case OUTPUT => Output(result) case NODIR => result } } /** Create a UInt with a specified width */ def width(width: Int): UInt = apply(width.W) /** Create a UInt port with specified width. */ def width(width: Width): UInt = apply(width) } /** This contains literal constructor factory methods that are deprecated as of Chisel3. */ trait SIntFactory extends chisel3.SIntFactory { /** Create a SInt type or port with fixed width. */ def width(width: Int): SInt = apply(width.W) /** Create an SInt type with specified width. */ def width(width: Width): SInt = apply(width) /** Create an SInt literal with inferred width. */ def apply(value: BigInt): SInt = value.asSInt /** Create an SInt literal with fixed width. */ def apply(value: BigInt, width: Int): SInt = value.asSInt(width.W) /** Create an SInt literal with specified width. */ def apply(value: BigInt, width: Width): SInt = value.asSInt(width) def Lit(value: BigInt): SInt = value.asSInt def Lit(value: BigInt, width: Int): SInt = value.asSInt(width.W) /** Create a SInt with a specified width - compatibility with Chisel2. */ def apply(dir: Option[Direction] = None, width: Int): SInt = apply(width.W) /** Create a SInt with a specified direction and width - compatibility with Chisel2. */ def apply(dir: Direction, width: Int): SInt = apply(dir, width.W) /** Create a SInt with a specified direction, but unspecified width - compatibility with Chisel2. */ def apply(dir: Direction): SInt = apply(dir, Width()) def apply(dir: Direction, width: Width): SInt = { val result = apply(width) dir match { case INPUT => Input(result) case OUTPUT => Output(result) case NODIR => result } } } /** This contains literal constructor factory methods that are deprecated as of Chisel3. */ trait BoolFactory extends chisel3.BoolFactory { /** Creates Bool literal. */ def apply(x: Boolean): Bool = x.B /** Create a UInt with a specified direction and width - compatibility with Chisel2. */ def apply(dir: Direction): Bool = { val result = apply() dir match { case INPUT => Input(result) case OUTPUT => Output(result) case NODIR => result } } } type Element = chisel3.Element type Bits = chisel3.Bits object Bits extends UIntFactory type Num[T <: Data] = chisel3.Num[T] type UInt = chisel3.UInt object UInt extends UIntFactory type SInt = chisel3.SInt object SInt extends SIntFactory type Bool = chisel3.Bool object Bool extends BoolFactory val Mux = chisel3.Mux type Reset = chisel3.Reset implicit def resetToBool(reset: Reset): Bool = reset.asBool type BlackBox = chisel3.internal.LegacyBlackBox type MemBase[T <: Data] = chisel3.MemBase[T] val Mem = chisel3.Mem type Mem[T <: Data] = chisel3.Mem[T] implicit class MemCompatibility(a: Mem.type) { import chisel3.internal.sourceinfo.UnlocatableSourceInfo def apply[T <: Data](t: T, size: BigInt)(implicit compileOptions: CompileOptions): Mem[T] = a.do_apply(size, t)(UnlocatableSourceInfo, compileOptions) def apply[T <: Data](t: T, size: Int)(implicit compileOptions: CompileOptions): Mem[T] = a.do_apply(size, t)(UnlocatableSourceInfo, compileOptions) } val SeqMem = chisel3.SyncReadMem type SeqMem[T <: Data] = chisel3.SyncReadMem[T] implicit class SeqMemCompatibility(a: SeqMem.type) { import chisel3.internal.sourceinfo.SourceInfo def apply[T <: Data]( t: T, size: BigInt )( implicit sourceInfo: SourceInfo, compileOptions: CompileOptions ): SyncReadMem[T] = a.do_apply(size, t) def apply[T <: Data]( t: T, size: Int )( implicit sourceInfo: SourceInfo, compileOptions: CompileOptions ): SyncReadMem[T] = a.do_apply(size, t) } import chisel3.CompileOptions @deprecated("Use Chisel.Module", "Chisel 3.5") type CompatibilityModule = chisel3.internal.LegacyModule val Module = chisel3.Module type Module = chisel3.internal.LegacyModule val printf = chisel3.printf val RegNext = chisel3.RegNext val RegInit = chisel3.RegInit object Reg { import chisel3.CompileOptions import chisel3.internal.sourceinfo.SourceInfo // Passthrough for chisel3.Reg // Single-element constructor to avoid issues caused by null default args in a type // parameterized scope. def apply[T <: Data](t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = chisel3.Reg(t) /** Creates a register with optional next and initialization values. * * @param t: data type for the register * @param next: new value register is to be updated with every cycle (or * empty to not update unless assigned to using the := operator) * @param init: initialization value on reset (or empty for uninitialized, * where the register value persists across a reset) * * @note this may result in a type error if called from a type parameterized * function, since the Scala compiler isn't smart enough to know that null * is a valid value. In those cases, you can either use the outType only Reg * constructor or pass in `null.asInstanceOf[T]`. */ def apply[T <: Data]( t: T = null, next: T = null, init: T = null )( implicit sourceInfo: SourceInfo, compileOptions: CompileOptions ): T = { if (t ne null) { val reg = if (init ne null) { RegInit(t, init) } else { chisel3.Reg(t) } if (next ne null) { reg := next } reg } else if (next ne null) { if (init ne null) { RegNext(next, init) } else { RegNext(next) } } else if (init ne null) { RegInit(init) } else { throwException("cannot infer type") } } } val when = chisel3.when type WhenContext = chisel3.WhenContext implicit class fromBigIntToLiteral(x: BigInt) extends chisel3.fromBigIntToLiteral(x) implicit class fromtIntToLiteral(x: Int) extends chisel3.fromIntToLiteral(x) implicit class fromtLongToLiteral(x: Long) extends chisel3.fromLongToLiteral(x) implicit class fromStringToLiteral(x: String) extends chisel3.fromStringToLiteral(x) implicit class fromBooleanToLiteral(x: Boolean) extends chisel3.fromBooleanToLiteral(x) implicit class fromIntToWidth(x: Int) extends chisel3.fromIntToWidth(x) @deprecated("Use object firrtl.util.BackendCompilationUtilities instead", "Chisel 3.5") type BackendCompilationUtilities = chisel3.BackendCompilationUtilities val ImplicitConversions = chisel3.util.ImplicitConversions // Deprecated as of Chisel3 object chiselMain { import java.io.File private var target_dir: Option[String] = None private def parseArgs(args: Array[String]): Unit = { for (i <- args.indices) { if (args(i) == "--targetDir") { target_dir = Some(args(i + 1)) } } } def apply[T <: Module](args: Array[String], gen: () => T): Unit = Predef.assert(false, "No more chiselMain in Chisel3") def run[T <: Module](args: Array[String], gen: () => T): Unit = { val circuit = ChiselStage.elaborate(gen()) parseArgs(args) val output_file = new File(target_dir.getOrElse(new File(".").getCanonicalPath) + "/" + circuit.name + ".fir") (new phases.Emitter) .transform(Seq(ChiselCircuitAnnotation(circuit), ChiselOutputFileAnnotation(output_file.toString))) } } @deprecated("debug doesn't do anything in Chisel3 as no pruning happens in the frontend", "chisel3") object debug { def apply(arg: Data): Data = arg } // Deprecated as of Chsiel3 object throwException { @throws(classOf[Exception]) def apply(s: String, t: Throwable = null): Nothing = { val xcpt = new Exception(s, t) throw xcpt } } object testers { type BasicTester = chisel3.testers.BasicTester val TesterDriver = chisel3.testers.TesterDriver } val log2Ceil = chisel3.util.log2Ceil val log2Floor = chisel3.util.log2Floor val isPow2 = chisel3.util.isPow2 /** Compute the log2 rounded up with min value of 1 */ object log2Up { def apply(in: BigInt): Int = { require(in >= 0) 1.max((in - 1).bitLength) } def apply(in: Int): Int = apply(BigInt(in)) } /** Compute the log2 rounded down with min value of 1 */ object log2Down { def apply(in: BigInt): Int = log2Up(in) - (if (isPow2(in)) 0 else 1) def apply(in: Int): Int = apply(BigInt(in)) } val BitPat = chisel3.util.BitPat type BitPat = chisel3.util.BitPat implicit class BitsObjectCompatibility(a: BitPat.type) { def DC(width: Int): BitPat = a.dontCare(width) } type ArbiterIO[T <: Data] = chisel3.util.ArbiterIO[T] type LockingArbiterLike[T <: Data] = chisel3.util.LockingArbiterLike[T] type LockingRRArbiter[T <: Data] = chisel3.util.LockingRRArbiter[T] type LockingArbiter[T <: Data] = chisel3.util.LockingArbiter[T] type RRArbiter[T <: Data] = chisel3.util.RRArbiter[T] type Arbiter[T <: Data] = chisel3.util.Arbiter[T] val FillInterleaved = chisel3.util.FillInterleaved val PopCount = chisel3.util.PopCount val Fill = chisel3.util.Fill val Reverse = chisel3.util.Reverse val Cat = chisel3.util.Cat val Log2 = chisel3.util.Log2 type SwitchContext[T <: Bits] = chisel3.util.SwitchContext[T] val is = chisel3.util.is val switch = chisel3.util.switch type Counter = chisel3.util.Counter val Counter = chisel3.util.Counter type DecoupledIO[+T <: Data] = chisel3.util.DecoupledIO[T] val DecoupledIO = chisel3.util.Decoupled val Decoupled = chisel3.util.Decoupled type QueueIO[T <: Data] = chisel3.util.QueueIO[T] val Queue = chisel3.util.Queue type Queue[T <: Data] = QueueCompatibility[T] sealed class QueueCompatibility[T <: Data]( gen: T, entries: Int, pipe: Boolean = false, flow: Boolean = false )( implicit compileOptions: chisel3.CompileOptions) extends chisel3.util.Queue[T](gen, entries, pipe, flow)(compileOptions) { def this(gen: T, entries: Int, pipe: Boolean, flow: Boolean, override_reset: Option[Bool]) = { this(gen, entries, pipe, flow) this.override_reset = override_reset } def this(gen: T, entries: Int, pipe: Boolean, flow: Boolean, _reset: Bool) = { this(gen, entries, pipe, flow) this.override_reset = Some(_reset) } } object Enum extends chisel3.util.Enum { /** Returns n unique values of the specified type. Can be used with unpacking to define enums. * * nodeType must be of UInt type (note that Bits() creates a UInt) with unspecified width. * * @example {{{ * val state_on :: state_off :: Nil = Enum(UInt(), 2) * val current_state = UInt() * switch (current_state) { * is (state_on) { * ... * } * if (state_off) { * ... * } * } * }}} */ def apply[T <: Bits](nodeType: T, n: Int): List[T] = { require(nodeType.isInstanceOf[UInt], "Only UInt supported for enums") require(!nodeType.widthKnown, "Bit width may no longer be specified for enums") apply(n).asInstanceOf[List[T]] } /** An old Enum API that returns a map of symbols to UInts. * * Unlike the new list-based Enum, which can be unpacked into vals that the compiler * understands and can check, map accesses can't be compile-time checked and typos may not be * caught until runtime. * * Despite being deprecated, this is not to be removed from the compatibility layer API. * Deprecation is only to nag users to do something safer. */ @deprecated("Use list-based Enum", "not soon enough") def apply[T <: Bits](nodeType: T, l: Symbol*): Map[Symbol, T] = { require(nodeType.isInstanceOf[UInt], "Only UInt supported for enums") require(!nodeType.widthKnown, "Bit width may no longer be specified for enums") (l.zip(createValues(l.length))).toMap.asInstanceOf[Map[Symbol, T]] } /** An old Enum API that returns a map of symbols to UInts. * * Unlike the new list-based Enum, which can be unpacked into vals that the compiler * understands and can check, map accesses can't be compile-time checked and typos may not be * caught until runtime. * * Despite being deprecated, this is not to be removed from the compatibility layer API. * Deprecation is only to nag users to do something safer. */ @deprecated("Use list-based Enum", "not soon enough") def apply[T <: Bits](nodeType: T, l: List[Symbol]): Map[Symbol, T] = { require(nodeType.isInstanceOf[UInt], "Only UInt supported for enums") require(!nodeType.widthKnown, "Bit width may no longer be specified for enums") (l.zip(createValues(l.length))).toMap.asInstanceOf[Map[Symbol, T]] } } /** LFSR16 generates a 16-bit linear feedback shift register, returning the register contents. * This is useful for generating a pseudo-random sequence. * * The example below, taken from the unit tests, creates two 4-sided dice using `LFSR16` primitives: * @example {{{ * val bins = Reg(Vec(8, UInt(32.W))) * * // Create two 4 sided dice and roll them each cycle. * // Use tap points on each LFSR so values are more independent * val die0 = Cat(Seq.tabulate(2) { i => LFSR16()(i) }) * val die1 = Cat(Seq.tabulate(2) { i => LFSR16()(i + 2) }) * * val rollValue = die0 +& die1 // Note +& is critical because sum will need an extra bit. * * bins(rollValue) := bins(rollValue) + 1.U * * }}} */ object LFSR16 { /** Generates a 16-bit linear feedback shift register, returning the register contents. * @param increment optional control to gate when the LFSR updates. */ def apply(increment: Bool = true.B): UInt = VecInit( FibonacciLFSR .maxPeriod(16, increment, seed = Some(BigInt(1) << 15)) .asBools .reverse ).asUInt } val ListLookup = chisel3.util.ListLookup val Lookup = chisel3.util.Lookup val Mux1H = chisel3.util.Mux1H val PriorityMux = chisel3.util.PriorityMux val MuxLookup = chisel3.util.MuxLookup val MuxCase = chisel3.util.MuxCase val OHToUInt = chisel3.util.OHToUInt val PriorityEncoder = chisel3.util.PriorityEncoder val UIntToOH = chisel3.util.UIntToOH val PriorityEncoderOH = chisel3.util.PriorityEncoderOH val RegEnable = chisel3.util.RegEnable val ShiftRegister = chisel3.util.ShiftRegister type ValidIO[+T <: Data] = chisel3.util.Valid[T] val Valid = chisel3.util.Valid val Pipe = chisel3.util.Pipe type Pipe[T <: Data] = chisel3.util.Pipe[T] /** Package for experimental features, which may have their API changed, be removed, etc. * * Because its contents won't necessarily have the same level of stability and support as * non-experimental, you must explicitly import this package to use its contents. */ object experimental { import scala.annotation.compileTimeOnly class dump extends chisel3.internal.naming.dump class treedump extends chisel3.internal.naming.treedump class chiselName extends chisel3.internal.naming.chiselName } implicit class DataCompatibility(a: Data) { import chisel3.internal.sourceinfo.DeprecatedSourceInfo def toBits(implicit compileOptions: CompileOptions): UInt = a.do_asUInt(DeprecatedSourceInfo, compileOptions) } implicit class VecLikeCompatibility[T <: Data](a: VecLike[T]) { import chisel3.internal.sourceinfo.DeprecatedSourceInfo def read(idx: UInt)(implicit compileOptions: CompileOptions): T = a.do_apply(idx)(compileOptions) def write(idx: UInt, data: T)(implicit compileOptions: CompileOptions): Unit = a.do_apply(idx)(compileOptions).:=(data)(DeprecatedSourceInfo, compileOptions) } implicit class BitsCompatibility(a: Bits) { import chisel3.internal.sourceinfo.DeprecatedSourceInfo final def asBits(implicit compileOptions: CompileOptions): Bits = a.do_asUInt(DeprecatedSourceInfo, compileOptions) final def toSInt(implicit compileOptions: CompileOptions): SInt = a.do_asSInt(DeprecatedSourceInfo, compileOptions) final def toUInt(implicit compileOptions: CompileOptions): UInt = a.do_asUInt(DeprecatedSourceInfo, compileOptions) final def toBools(implicit compileOptions: CompileOptions): Seq[Bool] = a.do_asBools(DeprecatedSourceInfo, compileOptions) } }