summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Waterman2016-01-17 17:20:49 -0800
committerAndrew Waterman2016-01-23 21:14:19 -0800
commit34a1abcd81bd3b2d7d264468345572009edfad27 (patch)
tree0dbaa05d8142d370d4df35d6999416325e1c0c99 /src
parent86a6c6bcdc349f40dcc31bce1931dc7c427da674 (diff)
Implement first draft of new FIRRTL changes
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/Chisel/Aggregate.scala2
-rw-r--r--src/main/scala/Chisel/Mem.scala32
-rw-r--r--src/main/scala/Chisel/Reg.scala8
-rw-r--r--src/main/scala/Chisel/internal/Builder.scala5
-rw-r--r--src/main/scala/Chisel/internal/firrtl/Emitter.scala17
-rw-r--r--src/main/scala/Chisel/internal/firrtl/IR.scala22
6 files changed, 53 insertions, 33 deletions
diff --git a/src/main/scala/Chisel/Aggregate.scala b/src/main/scala/Chisel/Aggregate.scala
index 63df8135..f510a913 100644
--- a/src/main/scala/Chisel/Aggregate.scala
+++ b/src/main/scala/Chisel/Aggregate.scala
@@ -141,7 +141,7 @@ sealed class Vec[T <: Data] private (gen: => T, val length: Int)
*/
def apply(idx: UInt): T = {
val x = gen
- pushCommand(DefAccessor(x, Node(this), NO_DIR, idx.ref))
+ x.setRef(this, idx)
x
}
diff --git a/src/main/scala/Chisel/Mem.scala b/src/main/scala/Chisel/Mem.scala
index c24e368c..3bbb1151 100644
--- a/src/main/scala/Chisel/Mem.scala
+++ b/src/main/scala/Chisel/Mem.scala
@@ -18,7 +18,7 @@ object Mem {
def apply[T <: Data](size: Int, t: T): Mem[T] = {
val mt = t.cloneType
val mem = new Mem(mt, size)
- pushCommand(DefMemory(mem, mt, size, Node(mt._parent.get.clock))) // TODO multi-clock
+ pushCommand(DefMemory(mem, mt, size)) // TODO multi-clock
mem
}
}
@@ -31,20 +31,24 @@ sealed abstract class MemBase[T <: Data](t: T, val length: Int) extends HasId wi
*/
def apply(idx: Int): T = apply(UInt(idx))
+ /** Creates a read/write accessor into the memory with dynamic addressing.
+ * See the class documentation of the memory for more detailed information.
+ */
+ def apply(idx: UInt): T = makePort(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 apply(idx: UInt): T =
- pushCommand(DefAccessor(t.cloneType, Node(this), NO_DIR, idx.ref)).id
-
- def read(idx: UInt): T = apply(idx)
+ def read(idx: UInt): T = makePort(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): Unit = apply(idx) := data
+ def write(idx: UInt, data: T): Unit = {
+ makePort(idx, MemPortDirection.WRITE) := data
+ }
/** Creates a masked write accessor into the memory.
*
@@ -56,12 +60,18 @@ sealed abstract class MemBase[T <: Data](t: T, val length: Int) extends HasId wi
* @note this is only allowed if the memory's element data type is a Vec
*/
def write(idx: UInt, data: T, mask: Vec[Bool]) (implicit evidence: T <:< Vec[_]): Unit = {
- // REVIEW TODO: error checking to detect zip length mismatch?
-
- val accessor = apply(idx).asInstanceOf[Vec[Data]]
- for (((cond, port), datum) <- mask zip accessor zip data.asInstanceOf[Vec[Data]])
+ val accessor = makePort(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(idx: UInt, dir: MemPortDirection): T =
+ pushCommand(DefMemPort(t.cloneType, Node(this), dir, idx.ref, Node(idx._parent.get.clock))).id
}
/** A combinational-read, sequential-write memory.
@@ -87,7 +97,7 @@ object SeqMem {
def apply[T <: Data](size: Int, t: T): SeqMem[T] = {
val mt = t.cloneType
val mem = new SeqMem(mt, size)
- pushCommand(DefSeqMemory(mem, mt, size, Node(mt._parent.get.clock))) // TODO multi-clock
+ pushCommand(DefSeqMemory(mem, mt, size)) // TODO multi-clock
mem
}
}
diff --git a/src/main/scala/Chisel/Reg.scala b/src/main/scala/Chisel/Reg.scala
index 4ebb6c68..f166c84b 100644
--- a/src/main/scala/Chisel/Reg.scala
+++ b/src/main/scala/Chisel/Reg.scala
@@ -45,10 +45,10 @@ object Reg {
// to resolve all use cases. If the type inferencer / implicit resolution
// system improves, this may be changed.
val x = makeType(t, next, init)
- pushCommand(DefRegister(x, Node(x._parent.get.clock), Node(x._parent.get.reset))) // TODO multi-clock
- if (init != null) {
- pushCommand(ConnectInit(x.lref, init.ref))
- }
+ val (resetEn, resetVal) =
+ if (init != null) (Node(x._parent.get.reset), init)
+ else (ULit(0, Width(1)), x)
+ pushCommand(DefRegister(x, Node(x._parent.get.clock), resetEn, resetVal.ref)) // TODO multi-clock
if (next != null) {
x := next
}
diff --git a/src/main/scala/Chisel/internal/Builder.scala b/src/main/scala/Chisel/internal/Builder.scala
index 991a442f..7e72b5e1 100644
--- a/src/main/scala/Chisel/internal/Builder.scala
+++ b/src/main/scala/Chisel/internal/Builder.scala
@@ -50,7 +50,8 @@ private[Chisel] trait HasId {
private[Chisel] def setRef(imm: Arg) = _refMap.setRef(this, imm)
private[Chisel] def setRef(name: String) = _refMap.setRef(this, name)
private[Chisel] def setRef(parent: HasId, name: String) = _refMap.setField(parent, this, name)
- private[Chisel] def setRef(parent: HasId, index: Int) = _refMap.setIndex(parent, this, index)
+ private[Chisel] def setRef(parent: HasId, index: Int) = _refMap.setIndex(parent, this, ILit(index))
+ private[Chisel] def setRef(parent: HasId, index: UInt) = _refMap.setIndex(parent, this, index.ref)
private[Chisel] def getRef = _refMap(this)
}
@@ -66,7 +67,7 @@ class RefMap {
private[Chisel] def setField(parentid: HasId, id: HasId, name: String): Unit =
_refmap(id._id) = Slot(Node(parentid), name)
- private[Chisel] def setIndex(parentid: HasId, id: HasId, index: Int): Unit =
+ private[Chisel] def setIndex(parentid: HasId, id: HasId, index: Arg): Unit =
_refmap(id._id) = Index(Node(parentid), index)
def apply(id: HasId): Arg = _refmap(id._id)
diff --git a/src/main/scala/Chisel/internal/firrtl/Emitter.scala b/src/main/scala/Chisel/internal/firrtl/Emitter.scala
index c46f14ca..8597454a 100644
--- a/src/main/scala/Chisel/internal/firrtl/Emitter.scala
+++ b/src/main/scala/Chisel/internal/firrtl/Emitter.scala
@@ -12,15 +12,14 @@ private class Emitter(circuit: Circuit) {
case e: DefPrim[_] => s"node ${e.name} = ${e.op.name}(${e.args.map(_.fullName(ctx)).reduce(_ + ", " + _)})"
case e: DefWire => s"wire ${e.name} : ${e.id.toType}"
case e: DefPoison[_] => s"poison ${e.name} : ${e.id.toType}"
- case e: DefRegister => s"reg ${e.name} : ${e.id.toType}, ${e.clock.fullName(ctx)}, ${e.reset.fullName(ctx)}"
- case e: DefMemory => s"cmem ${e.name} : ${e.t.toType}[${e.size}], ${e.clock.fullName(ctx)}"
- case e: DefSeqMemory => s"smem ${e.name} : ${e.t.toType}[${e.size}], ${e.clock.fullName(ctx)}"
- case e: DefAccessor[_] => s"infer accessor ${e.name} = ${e.source.fullName(ctx)}[${e.index.fullName(ctx)}]"
- case e: Connect => s"${e.loc.fullName(ctx)} := ${e.exp.fullName(ctx)}"
- case e: BulkConnect => s"${e.loc1.fullName(ctx)} <> ${e.loc2.fullName(ctx)}"
- case e: ConnectInit => s"onreset ${e.loc.fullName(ctx)} := ${e.exp.fullName(ctx)}"
- case e: Stop => s"stop(${e.clk.fullName(ctx)}, ${e.ret})"
- case e: Printf => s"""printf(${e.clk.fullName(ctx)}, "${e.format}"${e.ids.map(_.fullName(ctx)).fold(""){_ + ", " + _}})"""
+ case e: DefRegister => s"reg ${e.name} : ${e.id.toType}, ${e.clock.fullName(ctx)}, ${e.reset.fullName(ctx)}, ${e.init.fullName(ctx)}"
+ case e: DefMemory => s"cmem ${e.name} : ${e.t.toType}[${e.size}]"
+ case e: DefSeqMemory => s"smem ${e.name} : ${e.t.toType}[${e.size}]"
+ case e: DefMemPort[_] => s"${e.dir} mport ${e.name} = ${e.source.fullName(ctx)}[${e.index.fullName(ctx)}], ${e.clock.fullName(ctx)}"
+ case e: Connect => s"${e.loc.fullName(ctx)} <= ${e.exp.fullName(ctx)}"
+ case e: BulkConnect => s"${e.loc1.fullName(ctx)} <- ${e.loc2.fullName(ctx)}"
+ case e: Stop => s"stop(${e.clk.fullName(ctx)}, UInt<1>(1), ${e.ret})"
+ case e: Printf => s"""printf(${e.clk.fullName(ctx)}, UInt<1>(1), "${e.format}"${e.ids.map(_.fullName(ctx)).fold(""){_ + ", " + _}})"""
case e: DefInstance => {
val modName = moduleMap.getOrElse(e.id.name, e.id.name)
s"inst ${e.name} of $modName"
diff --git a/src/main/scala/Chisel/internal/firrtl/IR.scala b/src/main/scala/Chisel/internal/firrtl/IR.scala
index be61d67b..5612f1af 100644
--- a/src/main/scala/Chisel/internal/firrtl/IR.scala
+++ b/src/main/scala/Chisel/internal/firrtl/IR.scala
@@ -90,9 +90,9 @@ case class Slot(imm: Node, name: String) extends Arg {
override def fullName(ctx: Component): String =
if (imm.fullName(ctx).isEmpty) name else s"${imm.fullName(ctx)}.${name}"
}
-case class Index(imm: Arg, value: Int) extends Arg {
+case class Index(imm: Arg, value: Arg) extends Arg {
def name: String = s"[$value]"
- override def fullName(ctx: Component): String = s"${imm.fullName(ctx)}[$value]"
+ override def fullName(ctx: Component): String = s"${imm.fullName(ctx)}[${value.fullName(ctx)}]"
}
object Width {
@@ -132,6 +132,16 @@ sealed case class KnownWidth(value: Int) extends Width {
override def toString: String = value.toString
}
+sealed abstract class MemPortDirection(name: String) {
+ override def toString: String = name
+}
+object MemPortDirection {
+ object READ extends MemPortDirection("read")
+ object WRITE extends MemPortDirection("write")
+ object RDWR extends MemPortDirection("rdwr")
+ object INFER extends MemPortDirection("infer")
+}
+
abstract class Command
abstract class Definition extends Command {
def id: HasId
@@ -139,10 +149,10 @@ abstract class Definition extends Command {
}
case class DefPrim[T <: Data](id: T, op: PrimOp, args: Arg*) extends Definition
case class DefWire(id: Data) extends Definition
-case class DefRegister(id: Data, clock: Arg, reset: Arg) extends Definition
-case class DefMemory(id: HasId, t: Data, size: Int, clock: Arg) extends Definition
-case class DefSeqMemory(id: HasId, t: Data, size: Int, clock: Arg) extends Definition
-case class DefAccessor[T <: Data](id: T, source: Node, direction: Direction, index: Arg) extends Definition
+case class DefRegister(id: Data, clock: Arg, reset: Arg, init: Arg) extends Definition
+case class DefMemory(id: HasId, t: Data, size: Int) extends Definition
+case class DefSeqMemory(id: HasId, t: Data, size: Int) extends Definition
+case class DefMemPort[T <: Data](id: T, source: Node, dir: MemPortDirection, index: Arg, clock: Arg) extends Definition
case class DefInstance(id: Module, ports: Seq[Port]) extends Definition
case class DefPoison[T <: Data](id: T) extends Definition
case class WhenBegin(pred: Arg) extends Command