summaryrefslogtreecommitdiff
path: root/chiselFrontend/src/main/scala/chisel3/Mem.scala
diff options
context:
space:
mode:
authorJack Koenig2020-03-22 18:13:58 -0700
committerJack Koenig2020-03-25 19:17:15 -0700
commitfbf5e6f1a0e8bf535d465b748ad554575fe62156 (patch)
tree578858ab6d219ca6daf44cf87b73f75054989097 /chiselFrontend/src/main/scala/chisel3/Mem.scala
parentb2e004fb615a3c931d910a338b9faa99c1c975d7 (diff)
Rename subprojects to more canonical names
* Rename coreMacros to macros * Rename chiselFrontend to core Also make each subproject publish with "chisel3-" as a prefix
Diffstat (limited to 'chiselFrontend/src/main/scala/chisel3/Mem.scala')
-rw-r--r--chiselFrontend/src/main/scala/chisel3/Mem.scala216
1 files changed, 0 insertions, 216 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/Mem.scala b/chiselFrontend/src/main/scala/chisel3/Mem.scala
deleted file mode 100644
index 24ab4b8e..00000000
--- a/chiselFrontend/src/main/scala/chisel3/Mem.scala
+++ /dev/null
@@ -1,216 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3
-
-import scala.language.experimental.macros
-
-import firrtl.{ir => fir}
-
-import chisel3.internal._
-import chisel3.internal.Builder.pushCommand
-import chisel3.internal.firrtl._
-import chisel3.internal.sourceinfo.{SourceInfo, SourceInfoTransform, UnlocatableSourceInfo, MemTransform}
-
-
-object Mem {
-
- /** Creates a combinational/asynchronous-read, sequential/synchronous-write [[Mem]].
- *
- * @param size number of elements in the memory
- * @param t data type of memory element
- */
- def apply[T <: Data](size: BigInt, t: T): Mem[T] = macro MemTransform.apply[T]
-
- /** Creates a combinational/asynchronous-read, sequential/synchronous-write [[Mem]].
- *
- * @param size number of elements in the memory
- * @param t data type of memory element
- */
- def apply[T <: Data](size: Int, t: T): Mem[T] = macro MemTransform.apply[T]
-
- /** @group SourceInfoTransformMacro */
- def do_apply[T <: Data](size: BigInt, t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Mem[T] = {
- if (compileOptions.declaredTypeMustBeUnbound) {
- requireIsChiselType(t, "memory type")
- }
- val mt = t.cloneTypeFull
- val mem = new Mem(mt, size)
- pushCommand(DefMemory(sourceInfo, mem, mt, size))
- mem
- }
-
- /** @group SourceInfoTransformMacro */
- def do_apply[T <: Data](size: Int, t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Mem[T] =
- do_apply(BigInt(size), t)(sourceInfo, compileOptions)
-}
-
-sealed abstract class MemBase[T <: Data](val t: T, val length: BigInt) extends HasId with NamedComponent with SourceInfoDoc {
- // REVIEW TODO: make accessors (static/dynamic, read/write) combinations consistent.
-
- /** Creates a read accessor into the memory with static addressing. See the
- * class documentation of the memory for more detailed information.
- */
- def apply(x: BigInt): T = macro SourceInfoTransform.xArg
-
- /** Creates a read accessor into the memory with static addressing. See the
- * class documentation of the memory for more detailed information.
- */
- def apply(x: Int): T = macro SourceInfoTransform.xArg
-
- /** @group SourceInfoTransformMacro */
- def do_apply(idx: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
- require(idx >= 0 && idx < length)
- apply(idx.asUInt)
- }
-
- /** @group SourceInfoTransformMacro */
- def do_apply(idx: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T =
- do_apply(BigInt(idx))(sourceInfo, compileOptions)
-
- /** Creates a read/write accessor into the memory with dynamic addressing.
- * See the class documentation of the memory for more detailed information.
- */
- def apply(x: UInt): T = macro SourceInfoTransform.xArg
-
- /** @group SourceInfoTransformMacro */
- def do_apply(idx: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T =
- makePort(sourceInfo, idx, MemPortDirection.INFER)
-
- /** Creates a read accessor into the memory with dynamic addressing. See the
- * class documentation of the memory for more detailed information.
- */
- def read(x: UInt): T = macro SourceInfoTransform.xArg
-
- /** @group SourceInfoTransformMacro */
- def do_read(idx: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T =
- makePort(sourceInfo, idx, MemPortDirection.READ)
-
- /** Creates a write accessor into the memory.
- *
- * @param idx memory element index to write into
- * @param data new data to write
- */
- def write(idx: UInt, data: T)(implicit compileOptions: CompileOptions): Unit = {
- implicit val sourceInfo = UnlocatableSourceInfo
- makePort(UnlocatableSourceInfo, idx, MemPortDirection.WRITE) := data
- }
-
- /** Creates a masked write accessor into the memory.
- *
- * @param idx memory element index to write into
- * @param data new data to write
- * @param mask write mask as a Seq of Bool: a write to the Vec element in
- * memory is only performed if the corresponding mask index is true.
- *
- * @note this is only allowed if the memory's element data type is a Vec
- */
- def write(idx: UInt, data: T, mask: Seq[Bool]) (implicit evidence: T <:< Vec[_], compileOptions: CompileOptions): Unit = {
- implicit val sourceInfo = UnlocatableSourceInfo
- val accessor = makePort(sourceInfo, idx, MemPortDirection.WRITE).asInstanceOf[Vec[Data]]
- val dataVec = data.asInstanceOf[Vec[Data]]
- if (accessor.length != dataVec.length) {
- Builder.error(s"Mem write data must contain ${accessor.length} elements (found ${dataVec.length})")
- }
- if (accessor.length != mask.length) {
- Builder.error(s"Mem write mask must contain ${accessor.length} elements (found ${mask.length})")
- }
- for (((cond, port), datum) <- mask zip accessor zip dataVec)
- when (cond) { port := datum }
- }
-
- private def makePort(sourceInfo: SourceInfo, idx: UInt, dir: MemPortDirection)(implicit compileOptions: CompileOptions): T = {
- requireIsHardware(idx, "memory port index")
- val i = Vec.truncateIndex(idx, length)(sourceInfo, compileOptions)
-
- val port = pushCommand(
- DefMemPort(sourceInfo,
- t.cloneTypeFull, Node(this), dir, i.ref, Builder.forcedClock.ref)
- ).id
- // Bind each element of port to being a MemoryPort
- port.bind(MemoryPortBinding(Builder.forcedUserModule))
- port
- }
-}
-
-/** A combinational/asynchronous-read, sequential/synchronous-write memory.
- *
- * Writes take effect on the rising clock edge after the request. Reads are
- * combinational (requests will return data on the same cycle).
- * Read-after-write hazards are not an issue.
- *
- * @note when multiple conflicting writes are performed on a Mem element, the
- * result is undefined (unlike Vec, where the last assignment wins)
- */
-sealed class Mem[T <: Data] private (t: T, length: BigInt) extends MemBase(t, length)
-
-object SyncReadMem {
-
-
- type ReadUnderWrite = fir.ReadUnderWrite.Value
- val Undefined = fir.ReadUnderWrite.Undefined
- val ReadFirst = fir.ReadUnderWrite.Old
- val WriteFirst = fir.ReadUnderWrite.New
-
- /** Creates a sequential/synchronous-read, sequential/synchronous-write [[SyncReadMem]].
- *
- * @param size number of elements in the memory
- * @param t data type of memory element
- */
- def apply[T <: Data](size: BigInt, t: T): SyncReadMem[T] = macro MemTransform.apply[T]
- def apply[T <: Data](size: BigInt, t: T, ruw: ReadUnderWrite): SyncReadMem[T] = macro MemTransform.apply_ruw[T]
-
- /** Creates a sequential/synchronous-read, sequential/synchronous-write [[SyncReadMem]].
- *
- * @param size number of elements in the memory
- * @param t data type of memory element
- */
- def apply[T <: Data](size: Int, t: T): SyncReadMem[T] = macro MemTransform.apply[T]
- def apply[T <: Data](size: Int, t: T, ruw: ReadUnderWrite): SyncReadMem[T] = macro MemTransform.apply_ruw[T]
-
- /** @group SourceInfoTransformMacro */
- def do_apply[T <: Data](size: BigInt, t: T, ruw: ReadUnderWrite = Undefined)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SyncReadMem[T] = {
- if (compileOptions.declaredTypeMustBeUnbound) {
- requireIsChiselType(t, "memory type")
- }
- val mt = t.cloneTypeFull
- val mem = new SyncReadMem(mt, size, ruw)
- pushCommand(DefSeqMemory(sourceInfo, mem, mt, size, ruw))
- mem
- }
-
- /** @group SourceInfoTransformMacro */
- // Alternate signatures can't use default parameter values
- def do_apply[T <: Data](size: Int, t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SyncReadMem[T] =
- do_apply(BigInt(size), t)(sourceInfo, compileOptions)
-
- /** @group SourceInfoTransformMacro */
- // Alternate signatures can't use default parameter values
- def do_apply[T <: Data](size: Int, t: T, ruw: ReadUnderWrite)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SyncReadMem[T] =
- do_apply(BigInt(size), t, ruw)(sourceInfo, compileOptions)
-}
-
-/** A sequential/synchronous-read, sequential/synchronous-write memory.
- *
- * Writes take effect on the rising clock edge after the request. Reads return
- * data on the rising edge after the request. Read-after-write behavior (when
- * a read and write to the same address are requested on the same cycle) is
- * undefined.
- *
- * @note when multiple conflicting writes are performed on a Mem element, the
- * result is undefined (unlike Vec, where the last assignment wins)
- */
-sealed class SyncReadMem[T <: Data] private (t: T, n: BigInt, val readUnderWrite: SyncReadMem.ReadUnderWrite) extends MemBase[T](t, n) {
- def read(x: UInt, en: Bool): T = macro SourceInfoTransform.xEnArg
-
- /** @group SourceInfoTransformMacro */
- def do_read(addr: UInt, enable: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
- val a = Wire(UInt())
- a := DontCare
- var port: Option[T] = None
- when (enable) {
- a := addr
- port = Some(read(a))
- }
- port.get
- }
-}