diff options
| author | Andrew Waterman | 2015-08-20 16:40:42 -0700 |
|---|---|---|
| committer | Andrew Waterman | 2015-08-20 16:40:42 -0700 |
| commit | 6f3bc0551ec89e397d2972d7a664915c63e19a06 (patch) | |
| tree | 72e96b612e6e358bf8619a0bbc1bf460802e8ec1 /src | |
| parent | e7baa0a935da93aa1e9e78f7adc1f61222900c60 (diff) | |
Remove Port/Kind IR nodes, which merely wrap Data
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/scala/Chisel/Builder.scala | 10 | ||||
| -rw-r--r-- | src/main/scala/Chisel/Core.scala | 97 | ||||
| -rw-r--r-- | src/main/scala/Chisel/Emitter.scala | 34 | ||||
| -rw-r--r-- | src/main/scala/Chisel/FP.scala | 4 | ||||
| -rw-r--r-- | src/main/scala/Chisel/IR.scala | 37 |
5 files changed, 75 insertions, 107 deletions
diff --git a/src/main/scala/Chisel/Builder.scala b/src/main/scala/Chisel/Builder.scala index 41fbb3b5..66d2df84 100644 --- a/src/main/scala/Chisel/Builder.scala +++ b/src/main/scala/Chisel/Builder.scala @@ -35,11 +35,13 @@ private class IdGen { } private[Chisel] trait HasId { + private[Chisel] val _refMap = Builder.globalRefMap private[Chisel] val _id = Builder.idGen.next - private[Chisel] def setRef(imm: Immediate) = Builder.globalRefMap.setRef(this, imm) - private[Chisel] def setRef(name: String) = Builder.globalRefMap.setRef(this, name) - private[Chisel] def setRef(parent: HasId, name: String) = Builder.globalRefMap.setField(parent, this, name) - private[Chisel] def setRef(parent: HasId, index: Int) = Builder.globalRefMap.setIndex(parent, this, index) + private[Chisel] def setRef(imm: Immediate) = _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 getRef = _refMap(this) } class RefMap { diff --git a/src/main/scala/Chisel/Core.scala b/src/main/scala/Chisel/Core.scala index cd271018..56ffdbe7 100644 --- a/src/main/scala/Chisel/Core.scala +++ b/src/main/scala/Chisel/Core.scala @@ -39,7 +39,6 @@ abstract class Data(dirArg: Direction) extends HasId { if (_mod ne null) _mod.addNode(this) - def toType: Kind def dir: Direction = dirVar // Sucks this is mutable state, but cloneType doesn't take a Direction arg @@ -69,6 +68,7 @@ abstract class Data(dirArg: Direction) extends HasId { private[Chisel] def lref: Alias = Alias(this) private[Chisel] def ref: Arg = if (isLit) litArg.get else lref private[Chisel] def cloneTypeWidth(width: Width): this.type + private[Chisel] def toType: String def := (that: Data): Unit = this badConnect that def <> (that: Data): Unit = this badConnect that @@ -80,7 +80,7 @@ abstract class Data(dirArg: Direction) extends HasId { def width: Width final def getWidth = width.get - def flatten: IndexedSeq[UInt] + private[Chisel] def flatten: IndexedSeq[Bits] def fromBits(n: Bits): this.type = { var i = 0 val wire = Wire(this.cloneType) @@ -90,14 +90,13 @@ abstract class Data(dirArg: Direction) extends HasId { } wire.asInstanceOf[this.type] } - def toBits(): UInt = this.flatten.reverse.reduce(_##_) - def toPort: Port = Port(this, toType) + def toBits(): UInt = Cat(this.flatten.reverse) } object Wire { def apply[T <: Data](t: T = null, init: T = null): T = { val x = Reg.makeType(t, null.asInstanceOf[T], init) - pushCommand(DefWire(x, x.toType)) + pushCommand(DefWire(x)) if (init != null) x := init else @@ -119,7 +118,7 @@ object Reg { def apply[T <: Data](t: T = null, next: T = null, init: T = null): T = { val x = makeType(t, next, init) - pushCommand(DefRegister(x, x.toType, Alias(x._mod.clock), Alias(x._mod.reset))) // TODO multi-clock + pushCommand(DefRegister(x, Alias(x._mod.clock), Alias(x._mod.reset))) // TODO multi-clock if (init != null) pushCommand(ConnectInit(x.lref, init.ref)) if (next != null) @@ -133,7 +132,7 @@ object Mem { def apply[T <: Data](t: T, size: Int): Mem[T] = { val mt = t.cloneType val mem = new Mem(mt, size) - pushCommand(DefMemory(mem, mt.toType, size, Alias(mt._mod.clock))) // TODO multi-clock + pushCommand(DefMemory(mem, size, Alias(mt._mod.clock))) // TODO multi-clock mem } } @@ -155,8 +154,8 @@ sealed class Mem[T <: Data](t: T, val length: Int) extends Aggregate(NO_DIR) wit } def cloneType = throwException("Mem.cloneType unimplemented") - def flatten = throwException("Mem.flatten unimplemented") - def toType = throwException("Mem.toType unimplemented") + private[Chisel] def flatten = throwException("Mem.flatten unimplemented") + private[Chisel] def toType = t.toType } object SeqMem { @@ -184,7 +183,7 @@ object Vec { require(!elts.isEmpty) val width = elts.map(_.width).reduce(_ max _) val vec = new Vec(elts.head.cloneTypeWidth(width), elts.length) - pushCommand(DefWire(vec, vec.toType)) + pushCommand(DefWire(vec)) for ((v, e) <- vec zip elts) v := e vec @@ -198,7 +197,7 @@ object Vec { } sealed abstract class Aggregate(dirArg: Direction) extends Data(dirArg) { - def cloneTypeWidth(width: Width): this.type = cloneType + private[Chisel] def cloneTypeWidth(width: Width): this.type = cloneType def width: Width = flatten.map(_.width).reduce(_ + _) } @@ -206,10 +205,6 @@ sealed class Vec[T <: Data](gen: => T, val length: Int) extends Aggregate(gen.dir) with VecLike[T] { private val self = IndexedSeq.fill(length)(gen) - override def collectElts: Unit = - for ((elt, i) <- self zipWithIndex) - elt.setRef(this, i) - override def <> (that: Data): Unit = that match { case _: Vec[_] => this bulkConnect that case _ => this badConnect that @@ -241,17 +236,19 @@ sealed class Vec[T <: Data](gen: => T, val length: Int) } def apply(idx: Int): T = self(idx) - - def toType: Kind = VectorType(length, gen.toType, isFlip) + def read(idx: UInt): T = apply(idx) + def write(idx: UInt, data: T): Unit = apply(idx) := data override def cloneType: this.type = Vec(gen, length).asInstanceOf[this.type] - override lazy val flatten: IndexedSeq[UInt] = + private val t = gen + private[Chisel] def toType: String = s"${t.toType}[$length]" + private[Chisel] lazy val flatten: IndexedSeq[Bits] = (0 until length).flatMap(i => this.apply(i).flatten) - - def read(idx: UInt): T = apply(idx) - def write(idx: UInt, data: T): Unit = apply(idx) := data + private[Chisel] override def collectElts = + for ((elt, i) <- self zipWithIndex) + elt.setRef(this, i) } trait VecLike[T <: Data] extends collection.IndexedSeq[T] { @@ -310,7 +307,7 @@ sealed class BitPat(val value: BigInt, val mask: BigInt, width: Int) { } abstract class Element(dirArg: Direction, val width: Width) extends Data(dirArg) { - def flatten: IndexedSeq[UInt] = IndexedSeq(toBits) + private[Chisel] def flatten: IndexedSeq[UInt] = IndexedSeq(toBits) } object Clock { @@ -319,9 +316,9 @@ object Clock { sealed class Clock(dirArg: Direction) extends Element(dirArg, Width(1)) { def cloneType: this.type = Clock(dirArg).asInstanceOf[this.type] - def cloneTypeWidth(width: Width): this.type = cloneType - override def flatten: IndexedSeq[UInt] = IndexedSeq() - def toType: Kind = ClockType(isFlip) + private[Chisel] override def flatten: IndexedSeq[UInt] = IndexedSeq() + private[Chisel] def cloneTypeWidth(width: Width): this.type = cloneType + private[Chisel] def toType = "Clock" override def := (that: Data): Unit = that match { case _: Clock => this connect that @@ -417,10 +414,9 @@ abstract trait Num[T <: Data] { } sealed class UInt(dir: Direction, width: Width, lit: Option[ULit] = None) extends Bits(dir, width, lit) with Num[UInt] { - override def cloneTypeWidth(w: Width): this.type = + private[Chisel] override def cloneTypeWidth(w: Width): this.type = new UInt(dir, w).asInstanceOf[this.type] - - def toType: Kind = UIntType(width, isFlip) + private[Chisel] def toType = s"UInt<$width>" def fromInt(value: BigInt): this.type = UInt(value).asInstanceOf[this.type] def makeLit(value: BigInt): ULit = ULit(value, Width()) @@ -508,9 +504,9 @@ object Bits extends UIntFactory object UInt extends UIntFactory sealed class SInt(dir: Direction, width: Width, lit: Option[SLit] = None) extends Bits(dir, width, lit) with Num[SInt] { - override def cloneTypeWidth(w: Width): this.type = + private[Chisel] override def cloneTypeWidth(w: Width): this.type = new SInt(dir, w).asInstanceOf[this.type] - def toType: Kind = SIntType(width, isFlip) + private[Chisel] def toType = s"SInt<$width>" override def := (that: Data): Unit = that match { case _: SInt => this connect that @@ -572,7 +568,7 @@ object SInt { } sealed class Bool(dir: Direction, lit: Option[ULit] = None) extends UInt(dir, Width(1), lit) { - override def cloneTypeWidth(w: Width): this.type = { + private[Chisel] override def cloneTypeWidth(w: Width): this.type = { require(!w.known || w.get == 1) new Bool(dir).asInstanceOf[this.type] } @@ -656,14 +652,7 @@ class Bundle extends Aggregate(NO_DIR) { override def := (that: Data): Unit = this <> that - def toPorts: Seq[Port] = - elements.map(_._2.toPort).toSeq.reverse - def toType: BundleType = - BundleType(this.toPorts, isFlip) - - override def flatten: IndexedSeq[UInt] = allElts.flatMap(_._2.flatten) - - lazy val elements: ListMap[String, Data] = ListMap(allElts:_*) + lazy val elements: ListMap[String, Data] = ListMap(namedElts:_*) private def isBundleField(m: java.lang.reflect.Method) = m.getParameterTypes.isEmpty && @@ -671,21 +660,24 @@ class Bundle extends Aggregate(NO_DIR) { classOf[Data].isAssignableFrom(m.getReturnType) && !(Bundle.keywords contains m.getName) - private lazy val allElts = { - val elts = ArrayBuffer[(String, Data)]() - for (m <- getClass.getMethods; if isBundleField(m)) m.invoke(this) match { - case data: Data => elts += m.getName -> data - case _ => + private[Chisel] lazy val namedElts = { + val nameMap = LinkedHashMap[String, Data]() + val seen = HashSet[Data]() + for (m <- getClass.getMethods.sortWith(_.getName < _.getName); if isBundleField(m)) { + m.invoke(this) match { + case d: Data => + if (nameMap contains m.getName) require(nameMap(m.getName) eq d) + else if (!seen(d)) { nameMap(m.getName) = d; seen += d } + case _ => + } } - elts sortWith {case ((an, a), (bn, b)) => (a._id > b._id) || ((a eq b) && (an > bn))} + ArrayBuffer(nameMap.toSeq:_*) sortWith {case ((an, a), (bn, b)) => (a._id > b._id) || ((a eq b) && (an > bn))} } - - private[Chisel] lazy val namedElts = LinkedHashMap[String, Data](allElts:_*) - - private[Chisel] def addElt(name: String, elt: Data) = + private[Chisel] def toType = s"{${namedElts.reverse.map(e => (if (e._2.isFlip) "flip " else "")+e._2.getRef.name+" : "+e._2.toType).reduce(_+", "+_)}}" + private[Chisel] lazy val flatten = namedElts.flatMap(_._2.flatten) + private[Chisel] def addElt(name: String, elt: Data): Unit = namedElts += name -> elt - - override def collectElts = + private[Chisel] override def collectElts: Unit = for ((name, elt) <- namedElts) { elt.setRef(this, _namespace.name(name)) } override def cloneType : this.type = { @@ -745,8 +737,7 @@ abstract class Module(_clock: Clock = null, _reset: Bool = null) extends HasId { def addNode(d: Data) { _nodes += d } - private def computePorts = - clock.toPort +: reset.toPort +: io.toPorts + private def computePorts = io.namedElts.unzip._2 private def connectImplicitIOs(): this.type = _parent match { case Some(p) => diff --git a/src/main/scala/Chisel/Emitter.scala b/src/main/scala/Chisel/Emitter.scala index c053259d..805df74f 100644 --- a/src/main/scala/Chisel/Emitter.scala +++ b/src/main/scala/Chisel/Emitter.scala @@ -3,27 +3,17 @@ package Chisel private class Emitter(circuit: Circuit) { override def toString = res.toString - def join(parts: Seq[String], sep: String): StringBuilder = - parts.tail.foldLeft(new StringBuilder(parts.head))((s, p) => s ++= sep ++= p) - def emitDir(e: Port, isTop: Boolean): String = - if (isTop) (if (e.id.isFlip) "input " else "output ") - else (if (e.id.isFlip) "flip " else "") - def emitPort(e: Port, isTop: Boolean): String = - s"${emitDir(e, isTop)}${circuit.refMap(e.id).name} : ${emitType(e.kind)}" - private def emitType(e: Kind): String = e match { - case e: UnknownType => "?" - case e: UIntType => s"UInt<${e.width}>" - case e: SIntType => s"SInt<${e.width}>" - case e: BundleType => s"{${join(e.ports.map(x => emitPort(x, false)), ", ")}}" - case e: VectorType => s"${emitType(e.kind)}[${e.size}]" - case e: ClockType => s"Clock" - } + def emitDir(e: Data, isTop: Boolean): String = + if (isTop) (if (e.isFlip) "input " else "output ") + else (if (e.isFlip) "flip " else "") + def emitPort(e: Data, isTop: Boolean): String = + s"${emitDir(e, isTop)}${circuit.refMap(e).name} : ${e.toType}" private def emit(e: Command, ctx: Component): String = e match { - case e: DefPrim[_] => s"node ${e.name} = ${e.op.name}(${join(e.args.map(x => x.fullName(ctx)), ", ")})" - case e: DefWire => s"wire ${e.name} : ${emitType(e.kind)}" - case e: DefRegister => s"reg ${e.name} : ${emitType(e.kind)}, ${e.clock.fullName(ctx)}, ${e.reset.fullName(ctx)}" - case e: DefMemory => s"cmem ${e.name} : ${emitType(e.kind)}[${e.size}], ${e.clock.fullName(ctx)}"; - case e: DefSeqMemory => s"smem ${e.name} : ${emitType(e.kind)}[${e.size}]"; + 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: DefRegister => s"reg ${e.name} : ${e.id.toType}, ${e.clock.fullName(ctx)}, ${e.reset.fullName(ctx)}" + case e: DefMemory => s"cmem ${e.name} : ${e.id.toType}[${e.size}], ${e.clock.fullName(ctx)}"; + case e: DefSeqMemory => s"smem ${e.name} : ${e.id.toType}[${e.size}]"; 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)}" @@ -47,8 +37,8 @@ private class Emitter(circuit: Circuit) { unindent() "skip" } - private def initPort(p: Port, dir: Direction, ctx: Component) = { - for (x <- p.id.flatten; if x.dir == dir) + private def initPort(p: Data, dir: Direction, ctx: Component) = { + for (x <- p.flatten; if x.dir == dir) yield s"${circuit.refMap(x).fullName(ctx)} := ${x.makeLit(0).name}" } diff --git a/src/main/scala/Chisel/FP.scala b/src/main/scala/Chisel/FP.scala index 8dcff65b..4dd15b22 100644 --- a/src/main/scala/Chisel/FP.scala +++ b/src/main/scala/Chisel/FP.scala @@ -97,7 +97,7 @@ class Flo(dir: Direction = NO_DIR, val value:Option[FloLit] = None) extends FloB pushOp(DefPrim(cloneType, BitsToFlo, this.ref)).asInstanceOf[this.type] override def toBits: UInt = pushOp(DefPrim(UInt(width=32), FloToBits, this.ref)) - def toType: Kind = FloType(isFlip) + private[Chisel] def toType = "Flo" def cloneType: this.type = new Flo(dir).asInstanceOf[this.type] def fromInt(x: Int): Flo = @@ -177,7 +177,7 @@ class Dbl(dir: Direction, val value: Option[DblLit] = None) extends FloBase[Dbl] pushOp(DefPrim(cloneType, BitsToDbl, this.ref)).asInstanceOf[this.type] override def toBits: UInt = pushOp(DefPrim(UInt(width=64), DblToBits, this.ref)) - def toType: Kind = DblType(isFlip) + private[Chisel] def toType = "Dbl" def cloneType: this.type = new Dbl(dir).asInstanceOf[this.type] def fromInt(x: Int): this.type = diff --git a/src/main/scala/Chisel/IR.scala b/src/main/scala/Chisel/IR.scala index ad75bea2..292dc820 100644 --- a/src/main/scala/Chisel/IR.scala +++ b/src/main/scala/Chisel/IR.scala @@ -48,9 +48,8 @@ abstract class Arg extends Immediate { } case class Alias(id: HasId) extends Arg { - private val refMap = Builder.globalRefMap - override def fullName(ctx: Component) = refMap(id).fullName(ctx) - def name = refMap(id).name + override def fullName(ctx: Component) = id.getRef.fullName(ctx) + def name = id.getRef.name def emit: String = s"Alias($id)" } @@ -84,8 +83,7 @@ case class SLit(n: BigInt, w: Width) extends LitArg(n, w) { case class Ref(name: String) extends Immediate case class ModuleIO(mod: Module) extends Immediate { - private val refMap = Builder.globalRefMap - def name = refMap(mod).name + def name = mod.getRef.name override def fullName(ctx: Component) = if (mod eq ctx.id) "" else name } case class Slot(imm: Alias, name: String) extends Immediate { @@ -98,8 +96,6 @@ case class Index(imm: Immediate, value: Int) extends Immediate { override def fullName(ctx: Component) = s"${imm.fullName(ctx)}[$value]" } -case class Port(id: Data, kind: Kind) - object Width { def apply(x: Int): Width = KnownWidth(x) def apply(): Width = UnknownWidth() @@ -137,36 +133,25 @@ sealed case class KnownWidth(value: Int) extends Width { override def toString = value.toString } -abstract class Kind(val isFlip: Boolean); -case class UnknownType(flip: Boolean) extends Kind(flip); -case class UIntType(val width: Width, flip: Boolean) extends Kind(flip); -case class SIntType(val width: Width, flip: Boolean) extends Kind(flip); -case class FloType(flip: Boolean) extends Kind(flip); -case class DblType(flip: Boolean) extends Kind(flip); -case class BundleType(val ports: Seq[Port], flip: Boolean) extends Kind(flip); -case class VectorType(val size: Int, val kind: Kind, flip: Boolean) extends Kind(flip); -case class ClockType(flip: Boolean) extends Kind(flip) - -abstract class Command; +abstract class Command abstract class Definition extends Command { - private val refMap = Builder.globalRefMap def id: HasId - def name = refMap(id).name + def name = id.getRef.name } case class DefPrim[T <: Data](id: T, op: PrimOp, args: Arg*) extends Definition -case class DefWire(id: HasId, kind: Kind) extends Definition -case class DefRegister(id: HasId, kind: Kind, clock: Arg, reset: Arg) extends Definition -case class DefMemory(id: HasId, kind: Kind, size: Int, clock: Arg) extends Definition -case class DefSeqMemory(id: HasId, kind: Kind, size: Int) extends Definition +case class DefWire(id: Data) extends Definition +case class DefRegister(id: Data, clock: Arg, reset: Arg) extends Definition +case class DefMemory(id: Data, size: Int, clock: Arg) extends Definition +case class DefSeqMemory(id: Data, size: Int) extends Definition case class DefAccessor(id: HasId, source: Alias, direction: Direction, index: Arg) extends Definition -case class DefInstance(id: Module, ports: Seq[Port]) extends Definition +case class DefInstance(id: Module, ports: Seq[Data]) extends Definition case class WhenBegin(pred: Arg) extends Command case class WhenElse() extends Command case class WhenEnd() extends Command case class Connect(loc: Alias, exp: Arg) extends Command case class BulkConnect(loc1: Alias, loc2: Alias) extends Command case class ConnectInit(loc: Alias, exp: Arg) extends Command -case class Component(id: Module, name: String, ports: Seq[Port], commands: Seq[Command]) extends Immediate +case class Component(id: Module, name: String, ports: Seq[Data], commands: Seq[Command]) extends Immediate case class Circuit(name: String, components: Seq[Component], refMap: RefMap, parameterDump: ParameterDump) { def emit = new Emitter(this).toString |
