From e1ec4646e8551fdbe90e0ce2e957e455f0c8733d Mon Sep 17 00:00:00 2001 From: Palmer Dabbelt Date: Mon, 11 Jan 2016 13:59:11 -0800 Subject: Add a dummy chiselMain We don't have this in Chisel3, but for compatibility with berkeley-hardfloat I want a function header. This lets me keep the test harness in upstream hardfloat so I don't have to fork it for Chisel3 testing. --- src/main/scala/Chisel/Main.scala | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/main/scala/Chisel/Main.scala (limited to 'src') diff --git a/src/main/scala/Chisel/Main.scala b/src/main/scala/Chisel/Main.scala new file mode 100644 index 00000000..23abc763 --- /dev/null +++ b/src/main/scala/Chisel/Main.scala @@ -0,0 +1,8 @@ +// See LICENSE for details + +package Chisel + +@deprecated("chiselMain doesn't exist in Chisel3", "3.0") object chiselMain { + def apply[T <: Module](args: Array[String], gen: () => T) = + Predef.assert(false) +} -- cgit v1.2.3 From eada40ac04ca5505d6c64515904f1dcccb34349a Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Tue, 12 Jan 2016 15:21:27 -0800 Subject: Catch yet another missing-cloneType case --- src/main/scala/Chisel/Aggregate.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/main/scala/Chisel/Aggregate.scala b/src/main/scala/Chisel/Aggregate.scala index 35b8b4e5..4be7095f 100644 --- a/src/main/scala/Chisel/Aggregate.scala +++ b/src/main/scala/Chisel/Aggregate.scala @@ -331,7 +331,7 @@ class Bundle extends Aggregate(NO_DIR) { try { constructor.newInstance(_parent.get).asInstanceOf[this.type] } catch { - case _: java.lang.reflect.InvocationTargetException => + case _: java.lang.reflect.InvocationTargetException | _: java.lang.IllegalArgumentException => Builder.error(s"Parameterized Bundle ${this.getClass} needs cloneType method. You are probably using " + "an anonymous Bundle object that captures external state and hence is un-cloneTypeable") this -- cgit v1.2.3 From 171dd769bebaaeff069ca6dd745d3d1725b36547 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Tue, 12 Jan 2016 16:31:10 -0800 Subject: elaboration-time asserts should call Predef.assert --- src/main/scala/Chisel/CoreUtil.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/main/scala/Chisel/CoreUtil.scala b/src/main/scala/Chisel/CoreUtil.scala index 7077c9c1..9027711b 100644 --- a/src/main/scala/Chisel/CoreUtil.scala +++ b/src/main/scala/Chisel/CoreUtil.scala @@ -43,13 +43,13 @@ object assert { /** An elaboration-time assertion, otherwise the same as the above run-time * assertion. */ def apply(cond: Boolean, message: String) { - apply(Bool(cond), message) + Predef.assert(cond, message) } /** A workaround for default-value overloading problems in Scala, just * 'assert(cond, "")' */ def apply(cond: Boolean) { - apply(cond, "") + Predef.assert(cond, "") } } -- cgit v1.2.3 From 2d7bf7a5fdb5ee722009d4816bb8aa355ead59fc Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Fri, 15 Jan 2016 14:23:28 -0800 Subject: flatten should return Seq[Bits], not Seq[UInt] Calling toBits inside of flatten makes asInput/asOutput/asDirectionless fail on SInts. Also, the abstract type Data was already defining it to return Seq[Bits], so this change didn't really change the API. --- src/main/scala/Chisel/Bits.scala | 6 +++--- src/main/scala/Chisel/Data.scala | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/main/scala/Chisel/Bits.scala b/src/main/scala/Chisel/Bits.scala index e001f864..7505c102 100644 --- a/src/main/scala/Chisel/Bits.scala +++ b/src/main/scala/Chisel/Bits.scala @@ -10,9 +10,7 @@ import firrtl.PrimOp._ /** Element is a leaf data type: it cannot contain other Data objects. Example * uses are for representing primitive data types, like integers and bits. */ -abstract class Element(dirArg: Direction, val width: Width) extends Data(dirArg) { - private[Chisel] def flatten: IndexedSeq[UInt] = IndexedSeq(toBits) -} +abstract class Element(dirArg: Direction, val width: Width) extends Data(dirArg) /** A data type for values represented by a single bitvector. Provides basic * bitwise operations. @@ -25,6 +23,8 @@ sealed abstract class Bits(dirArg: Direction, width: Width, override val litArg: private[Chisel] def fromInt(x: BigInt): this.type + private[Chisel] def flatten: IndexedSeq[Bits] = IndexedSeq(this) + def cloneType: this.type = cloneTypeWidth(width) override def <> (that: Data): Unit = this := that diff --git a/src/main/scala/Chisel/Data.scala b/src/main/scala/Chisel/Data.scala index f9b277e1..c72c7dfc 100644 --- a/src/main/scala/Chisel/Data.scala +++ b/src/main/scala/Chisel/Data.scala @@ -123,7 +123,7 @@ object Clock { // TODO: Document this. sealed class Clock(dirArg: Direction) extends Element(dirArg, Width(1)) { def cloneType: this.type = Clock(dirArg).asInstanceOf[this.type] - private[Chisel] override def flatten: IndexedSeq[UInt] = IndexedSeq() + private[Chisel] override def flatten: IndexedSeq[Bits] = IndexedSeq() private[Chisel] def cloneTypeWidth(width: Width): this.type = cloneType private[Chisel] def toType = "Clock" -- cgit v1.2.3 From ccb532af5fc9ae96c011a9efd852f5e153b12613 Mon Sep 17 00:00:00 2001 From: ducky Date: Sat, 16 Jan 2016 18:03:11 -0800 Subject: Add When test and fix when / elsewhen / otherwise behavior --- src/main/scala/Chisel/When.scala | 26 +++++++-------- src/test/scala/chiselTests/When.scala | 60 +++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 13 deletions(-) create mode 100644 src/test/scala/chiselTests/When.scala (limited to 'src') diff --git a/src/main/scala/Chisel/When.scala b/src/main/scala/Chisel/When.scala index 7b8d60c2..506661b9 100644 --- a/src/main/scala/Chisel/When.scala +++ b/src/main/scala/Chisel/When.scala @@ -25,31 +25,31 @@ object when { // scalastyle:ignore object.name * }}} */ def apply(cond: => Bool)(block: => Unit): WhenContext = { - new WhenContext(cond)(block) + new WhenContext(cond, Bool(true))(block) } } -class WhenContext(cond: => Bool)(block: => Unit) { +/** Internal mechanism for generating a when. Because of the way FIRRTL + * commands are emitted, generating a FIRRTL elsewhen or nested whens inside + * elses would be difficult. Instead, this keeps track of the negative of the + * previous conditions, so when an elsewhen or otherwise is used, it checks + * that both the condition is true and all the previous conditions have been + * false. + */ +class WhenContext(cond: => Bool, prevCond: Bool)(block: => Unit) { /** This block of logic gets executed if above conditions have been false * and this condition is true. */ - def elsewhen (cond: => Bool)(block: => Unit): WhenContext = - doOtherwise(when(cond)(block)) + def elsewhen (elseCond: => Bool)(block: => Unit): WhenContext = + new WhenContext(elseCond, prevCond && !cond)(block) /** This block of logic gets executed only if the above conditions were all * false. No additional logic blocks may be appended past the `otherwise`. */ def otherwise(block: => Unit): Unit = - doOtherwise(block) + new WhenContext(Bool(true), prevCond && !cond)(block) - pushCommand(WhenBegin(cond.ref)) + pushCommand(WhenBegin((cond && prevCond).ref)) block pushCommand(WhenEnd()) - - private def doOtherwise[T](block: => T): T = { - pushCommand(WhenElse()) - val res = block - pushCommand(WhenEnd()) - res - } } diff --git a/src/test/scala/chiselTests/When.scala b/src/test/scala/chiselTests/When.scala new file mode 100644 index 00000000..b78e1c5a --- /dev/null +++ b/src/test/scala/chiselTests/When.scala @@ -0,0 +1,60 @@ +// See LICENSE for license details. + +package chiselTests + +import org.scalatest._ +import Chisel._ +import Chisel.testers.BasicTester + +class WhenTester() extends BasicTester { + val cnt = Counter(4) + when(Bool(true)) { cnt.inc() } + + val out = Wire(UInt(width=3)) + when(cnt.value === UInt(0)) { + out := UInt(1) + } .elsewhen (cnt.value === UInt(1)) { + out := UInt(2) + } .elsewhen (cnt.value === UInt(2)) { + out := UInt(3) + } .otherwise { + out := UInt(0) + } + + assert(out === cnt.value + UInt(1)) + + when(cnt.value === UInt(3)) { + stop() + } +} + +class OverlappedWhenTester() extends BasicTester { + val cnt = Counter(4) + when(Bool(true)) { cnt.inc() } + + val out = Wire(UInt(width=3)) + when(cnt.value <= UInt(0)) { + out := UInt(1) + } .elsewhen (cnt.value <= UInt(1)) { + out := UInt(2) + } .elsewhen (cnt.value <= UInt(2)) { + out := UInt(3) + } .otherwise { + out := UInt(0) + } + + assert(out === cnt.value + UInt(1)) + + when(cnt.value === UInt(3)) { + stop() + } +} + +class WhenSpec extends ChiselFlatSpec { + "When, elsewhen, and otherwise with orthogonal conditions" should "work" in { + assert(execute{ new WhenTester }) + } + "When, elsewhen, and otherwise with overlapped conditions" should "work" in { + assert(execute{ new OverlappedWhenTester }) + } +} -- cgit v1.2.3 From e6a712b255d94e1b4d8b1c10db523100db25c721 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sat, 16 Jan 2016 18:43:17 -0800 Subject: Allow Wire() to be called from parameterized functions Accomplish this by avoiding default-null parameters on the apply methods. --- src/main/scala/Chisel/Data.scala | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/main/scala/Chisel/Data.scala b/src/main/scala/Chisel/Data.scala index c72c7dfc..7927db86 100644 --- a/src/main/scala/Chisel/Data.scala +++ b/src/main/scala/Chisel/Data.scala @@ -104,7 +104,16 @@ abstract class Data(dirArg: Direction) extends HasId { } object Wire { - def apply[T <: Data](t: T = null, init: T = null): T = { + def apply[T <: Data](t: T): T = + makeWire(t, null.asInstanceOf[T]) + + def apply[T <: Data](dummy: Int = 0, init: T): T = + makeWire(null.asInstanceOf[T], init) + + def apply[T <: Data](t: T, init: T): T = + makeWire(t, init) + + private def makeWire[T <: Data](t: T, init: T): T = { val x = Reg.makeType(t, null.asInstanceOf[T], init) pushCommand(DefWire(x)) if (init != null) { -- cgit v1.2.3 From fc3587aa24132991a50fbba1fbe4dc769953a3db Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sat, 16 Jan 2016 18:48:23 -0800 Subject: Disallow Muxing between bundles whose fields have different widths --- src/main/scala/Chisel/Bits.scala | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/main/scala/Chisel/Bits.scala b/src/main/scala/Chisel/Bits.scala index 7505c102..d6bef0d0 100644 --- a/src/main/scala/Chisel/Bits.scala +++ b/src/main/scala/Chisel/Bits.scala @@ -538,6 +538,9 @@ object Mux { // This returns an lvalue, which it most definitely should not private def doWhen[T <: Data](cond: Bool, con: T, alt: T): T = { require(con.getClass == alt.getClass, s"can't Mux between ${con.getClass} and ${alt.getClass}") + for ((c, a) <- con.flatten zip alt.flatten) + require(c.width == a.width, "can't Mux between aggregates of different width") + val res = Wire(t = alt.cloneTypeWidth(con.width max alt.width), init = alt) when (cond) { res := con } res -- cgit v1.2.3 From 215d71c20e0b3e609eb5ac0f957c475fe3d61357 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sun, 17 Jan 2016 01:47:58 -0800 Subject: Add =/= operator to BitPat --- src/main/scala/Chisel/BitPat.scala | 3 ++- src/main/scala/Chisel/Bits.scala | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/main/scala/Chisel/BitPat.scala b/src/main/scala/Chisel/BitPat.scala index b4138992..a1bf1985 100644 --- a/src/main/scala/Chisel/BitPat.scala +++ b/src/main/scala/Chisel/BitPat.scala @@ -75,5 +75,6 @@ object BitPat { sealed class BitPat(val value: BigInt, val mask: BigInt, width: Int) { def getWidth: Int = width def === (other: UInt): Bool = UInt(value) === (other & UInt(mask)) - def != (other: UInt): Bool = !(this === other) + def =/= (other: UInt): Bool = !(this === other) + def != (other: UInt): Bool = this =/= other } diff --git a/src/main/scala/Chisel/Bits.scala b/src/main/scala/Chisel/Bits.scala index d6bef0d0..57d88244 100644 --- a/src/main/scala/Chisel/Bits.scala +++ b/src/main/scala/Chisel/Bits.scala @@ -321,6 +321,7 @@ sealed class UInt private[Chisel] (dir: Direction, width: Width, lit: Option[ULi def === (that: BitPat): Bool = that === this def != (that: BitPat): Bool = that != this + def =/= (that: BitPat): Bool = that =/= this /** Returns this UInt as a [[SInt]] with an additional zero in the MSB. */ -- cgit v1.2.3 From 34ee838ebc7c9e08fc1699c9b20386fcb37a5830 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sun, 17 Jan 2016 14:21:07 -0800 Subject: Improve code generation for When The change to fix elsewhen/otherwise blew up the node count. --- src/main/scala/Chisel/When.scala | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/main/scala/Chisel/When.scala b/src/main/scala/Chisel/When.scala index 506661b9..af6b3555 100644 --- a/src/main/scala/Chisel/When.scala +++ b/src/main/scala/Chisel/When.scala @@ -24,8 +24,8 @@ object when { // scalastyle:ignore object.name * } * }}} */ - def apply(cond: => Bool)(block: => Unit): WhenContext = { - new WhenContext(cond, Bool(true))(block) + def apply(cond: Bool)(block: => Unit): WhenContext = { + new WhenContext(cond, !cond)(block) } } @@ -36,20 +36,21 @@ object when { // scalastyle:ignore object.name * that both the condition is true and all the previous conditions have been * false. */ -class WhenContext(cond: => Bool, prevCond: Bool)(block: => Unit) { +class WhenContext(cond: Bool, prevCond: => Bool)(block: => Unit) { /** This block of logic gets executed if above conditions have been false * and this condition is true. */ - def elsewhen (elseCond: => Bool)(block: => Unit): WhenContext = - new WhenContext(elseCond, prevCond && !cond)(block) + def elsewhen (elseCond: Bool)(block: => Unit): WhenContext = { + new WhenContext(prevCond && elseCond, prevCond && !elseCond)(block) + } /** This block of logic gets executed only if the above conditions were all * false. No additional logic blocks may be appended past the `otherwise`. */ def otherwise(block: => Unit): Unit = - new WhenContext(Bool(true), prevCond && !cond)(block) + new WhenContext(prevCond, null)(block) - pushCommand(WhenBegin((cond && prevCond).ref)) + pushCommand(WhenBegin(cond.ref)) block pushCommand(WhenEnd()) } -- cgit v1.2.3 From 57c1770a964c44b4211453ab6f7f41289f21cd50 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sun, 17 Jan 2016 14:53:27 -0800 Subject: Remove unused WhenElse IR node --- src/main/scala/Chisel/firrtl/Emitter.scala | 3 --- src/main/scala/Chisel/firrtl/IR.scala | 1 - 2 files changed, 4 deletions(-) (limited to 'src') diff --git a/src/main/scala/Chisel/firrtl/Emitter.scala b/src/main/scala/Chisel/firrtl/Emitter.scala index 1d0f4ddc..a6fd15aa 100644 --- a/src/main/scala/Chisel/firrtl/Emitter.scala +++ b/src/main/scala/Chisel/firrtl/Emitter.scala @@ -29,9 +29,6 @@ private class Emitter(circuit: Circuit) { case w: WhenBegin => indent() s"when ${w.pred.fullName(ctx)} :" - case _: WhenElse => - indent() - "else :" case _: WhenEnd => unindent() "skip" diff --git a/src/main/scala/Chisel/firrtl/IR.scala b/src/main/scala/Chisel/firrtl/IR.scala index 8cc31b54..6f3eb4d1 100644 --- a/src/main/scala/Chisel/firrtl/IR.scala +++ b/src/main/scala/Chisel/firrtl/IR.scala @@ -146,7 +146,6 @@ case class DefAccessor[T <: Data](id: T, source: Node, direction: Direction, ind 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 -case class WhenElse() extends Command case class WhenEnd() extends Command case class Connect(loc: Node, exp: Arg) extends Command case class BulkConnect(loc1: Node, loc2: Node) extends Command -- cgit v1.2.3 From 544afdebc4d1b441e57123bd67bc48e8c036ffbb Mon Sep 17 00:00:00 2001 From: jackkoenig Date: Sat, 23 Jan 2016 15:56:55 -0800 Subject: Move firrtl subpackage to inside internal subpackage. --- src/main/scala/Chisel/Aggregate.scala | 2 +- src/main/scala/Chisel/Bits.scala | 2 +- src/main/scala/Chisel/CoreUtil.scala | 2 +- src/main/scala/Chisel/Data.scala | 2 +- src/main/scala/Chisel/Driver.scala | 2 +- src/main/scala/Chisel/Mem.scala | 2 +- src/main/scala/Chisel/Module.scala | 2 +- src/main/scala/Chisel/Reg.scala | 2 +- src/main/scala/Chisel/When.scala | 2 +- src/main/scala/Chisel/firrtl/Emitter.scala | 73 ---------- src/main/scala/Chisel/firrtl/IR.scala | 160 --------------------- src/main/scala/Chisel/internal/Builder.scala | 2 +- .../scala/Chisel/internal/firrtl/Emitter.scala | 73 ++++++++++ src/main/scala/Chisel/internal/firrtl/IR.scala | 160 +++++++++++++++++++++ src/main/scala/Chisel/testers/BasicTester.scala | 2 +- 15 files changed, 244 insertions(+), 244 deletions(-) delete mode 100644 src/main/scala/Chisel/firrtl/Emitter.scala delete mode 100644 src/main/scala/Chisel/firrtl/IR.scala create mode 100644 src/main/scala/Chisel/internal/firrtl/Emitter.scala create mode 100644 src/main/scala/Chisel/internal/firrtl/IR.scala (limited to 'src') diff --git a/src/main/scala/Chisel/Aggregate.scala b/src/main/scala/Chisel/Aggregate.scala index 4be7095f..33b71c4e 100644 --- a/src/main/scala/Chisel/Aggregate.scala +++ b/src/main/scala/Chisel/Aggregate.scala @@ -7,7 +7,7 @@ import scala.collection.mutable.{ArrayBuffer, HashSet, LinkedHashMap} import internal._ import internal.Builder.pushCommand -import firrtl._ +import internal.firrtl._ /** An abstract class for data types that solely consist of (are an aggregate * of) other Data objects. diff --git a/src/main/scala/Chisel/Bits.scala b/src/main/scala/Chisel/Bits.scala index 57d88244..b512bb56 100644 --- a/src/main/scala/Chisel/Bits.scala +++ b/src/main/scala/Chisel/Bits.scala @@ -4,7 +4,7 @@ package Chisel import internal._ import internal.Builder.pushOp -import firrtl._ +import internal.firrtl._ import firrtl.PrimOp._ /** Element is a leaf data type: it cannot contain other Data objects. Example diff --git a/src/main/scala/Chisel/CoreUtil.scala b/src/main/scala/Chisel/CoreUtil.scala index 9027711b..eed90410 100644 --- a/src/main/scala/Chisel/CoreUtil.scala +++ b/src/main/scala/Chisel/CoreUtil.scala @@ -4,7 +4,7 @@ package Chisel import internal._ import internal.Builder.pushCommand -import firrtl._ +import internal.firrtl._ object assert { /** Checks for a condition to be valid in the circuit at all times. If the diff --git a/src/main/scala/Chisel/Data.scala b/src/main/scala/Chisel/Data.scala index 7927db86..1011fe47 100644 --- a/src/main/scala/Chisel/Data.scala +++ b/src/main/scala/Chisel/Data.scala @@ -4,7 +4,7 @@ package Chisel import internal._ import internal.Builder.pushCommand -import firrtl._ +import internal.firrtl._ sealed abstract class Direction(name: String) { override def toString: String = name diff --git a/src/main/scala/Chisel/Driver.scala b/src/main/scala/Chisel/Driver.scala index cd88c302..6a5e2095 100644 --- a/src/main/scala/Chisel/Driver.scala +++ b/src/main/scala/Chisel/Driver.scala @@ -6,7 +6,7 @@ import scala.sys.process._ import java.io._ import internal._ -import firrtl._ +import internal.firrtl._ trait BackendCompilationUtilities { /** Create a temporary directory with the prefix name. Exists here because it doesn't in Java 6. diff --git a/src/main/scala/Chisel/Mem.scala b/src/main/scala/Chisel/Mem.scala index bd27a9c7..c24e368c 100644 --- a/src/main/scala/Chisel/Mem.scala +++ b/src/main/scala/Chisel/Mem.scala @@ -4,7 +4,7 @@ package Chisel import internal._ import internal.Builder.pushCommand -import firrtl._ +import internal.firrtl._ object Mem { @deprecated("Mem argument order should be size, t; this will be removed by the official release", "chisel3") diff --git a/src/main/scala/Chisel/Module.scala b/src/main/scala/Chisel/Module.scala index 05b7dc26..1681f901 100644 --- a/src/main/scala/Chisel/Module.scala +++ b/src/main/scala/Chisel/Module.scala @@ -7,7 +7,7 @@ import scala.collection.mutable.{ArrayBuffer, HashSet} import internal._ import internal.Builder.pushCommand import internal.Builder.dynamicContext -import firrtl._ +import internal.firrtl._ object Module { /** A wrapper method that all Module instantiations must be wrapped in diff --git a/src/main/scala/Chisel/Reg.scala b/src/main/scala/Chisel/Reg.scala index 21415362..4ebb6c68 100644 --- a/src/main/scala/Chisel/Reg.scala +++ b/src/main/scala/Chisel/Reg.scala @@ -4,7 +4,7 @@ package Chisel import internal._ import internal.Builder.pushCommand -import firrtl._ +import internal.firrtl._ object Reg { private[Chisel] def makeType[T <: Data](t: T = null, next: T = null, init: T = null): T = { diff --git a/src/main/scala/Chisel/When.scala b/src/main/scala/Chisel/When.scala index af6b3555..5f6b02c5 100644 --- a/src/main/scala/Chisel/When.scala +++ b/src/main/scala/Chisel/When.scala @@ -4,7 +4,7 @@ package Chisel import internal._ import internal.Builder.pushCommand -import firrtl._ +import internal.firrtl._ object when { // scalastyle:ignore object.name /** Create a `when` condition block, where whether a block of logic is diff --git a/src/main/scala/Chisel/firrtl/Emitter.scala b/src/main/scala/Chisel/firrtl/Emitter.scala deleted file mode 100644 index a6fd15aa..00000000 --- a/src/main/scala/Chisel/firrtl/Emitter.scala +++ /dev/null @@ -1,73 +0,0 @@ -// See LICENSE for license details. - -package Chisel.firrtl -import Chisel._ - -private class Emitter(circuit: Circuit) { - override def toString: String = res.toString - - private def emitPort(e: Port): String = - s"${e.dir} ${e.id.getRef.name} : ${e.id.toType}" - private def emit(e: Command, ctx: Component): String = e match { - 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: DefInstance => { - val modName = moduleMap.getOrElse(e.id.name, e.id.name) - s"inst ${e.name} of $modName" - } - - case w: WhenBegin => - indent() - s"when ${w.pred.fullName(ctx)} :" - case _: WhenEnd => - unindent() - "skip" - } - private def emitBody(m: Component) = { - val me = new StringBuilder - withIndent { - for (p <- m.ports) - me ++= newline + emitPort(p) - me ++= newline - for (cmd <- m.commands) - me ++= newline + emit(cmd, m) - me ++= newline - } - me - } - - private val bodyMap = collection.mutable.HashMap[StringBuilder, String]() - private val moduleMap = collection.mutable.HashMap[String, String]() - - private def emit(m: Component): String = { - val body = emitBody(m) - bodyMap get body match { - case Some(name) => - moduleMap(m.name) = name - "" - case None => - bodyMap(body) = m.name - newline + s"module ${m.name} : " + body - } - } - - private var indentLevel = 0 - private def newline = "\n" + (" " * indentLevel) - private def indent(): Unit = indentLevel += 1 - private def unindent() { require(indentLevel > 0); indentLevel -= 1 } - private def withIndent(f: => Unit) { indent(); f; unindent() } - - private val res = new StringBuilder(s"circuit ${circuit.name} : ") - withIndent { circuit.components.foreach(c => res ++= emit(c)) } - res ++= newline -} diff --git a/src/main/scala/Chisel/firrtl/IR.scala b/src/main/scala/Chisel/firrtl/IR.scala deleted file mode 100644 index 6f3eb4d1..00000000 --- a/src/main/scala/Chisel/firrtl/IR.scala +++ /dev/null @@ -1,160 +0,0 @@ -// See LICENSE for license details. - -package Chisel.firrtl -import Chisel._ -import Chisel.internal._ - -case class PrimOp(val name: String) { - override def toString: String = name -} - -object PrimOp { - val AddOp = PrimOp("add") - val AddModOp = PrimOp("addw") - val SubOp = PrimOp("sub") - val SubModOp = PrimOp("subw") - val TimesOp = PrimOp("mul") - val DivideOp = PrimOp("div") - val ModOp = PrimOp("mod") - val ShiftLeftOp = PrimOp("shl") - val ShiftRightOp = PrimOp("shr") - val DynamicShiftLeftOp = PrimOp("dshl") - val DynamicShiftRightOp = PrimOp("dshr") - val BitAndOp = PrimOp("and") - val BitOrOp = PrimOp("or") - val BitXorOp = PrimOp("xor") - val BitNotOp = PrimOp("not") - val ConcatOp = PrimOp("cat") - val BitSelectOp = PrimOp("bit") - val BitsExtractOp = PrimOp("bits") - val LessOp = PrimOp("lt") - val LessEqOp = PrimOp("leq") - val GreaterOp = PrimOp("gt") - val GreaterEqOp = PrimOp("geq") - val EqualOp = PrimOp("eq") - val PadOp = PrimOp("pad") - val NotEqualOp = PrimOp("neq") - val NegOp = PrimOp("neg") - val MultiplexOp = PrimOp("mux") - val XorReduceOp = PrimOp("xorr") - val ConvertOp = PrimOp("cvt") - val AsUIntOp = PrimOp("asUInt") - val AsSIntOp = PrimOp("asSInt") -} - -abstract class Arg { - def fullName(ctx: Component): String = name - def name: String -} - -case class Node(id: HasId) extends Arg { - override def fullName(ctx: Component): String = id.getRef.fullName(ctx) - def name: String = id.getRef.name -} - -abstract class LitArg(val num: BigInt, widthArg: Width) extends Arg { - private[Chisel] def forcedWidth = widthArg.known - private[Chisel] def width: Width = if (forcedWidth) widthArg else Width(minWidth) - - protected def minWidth: Int - if (forcedWidth) { - require(widthArg.get >= minWidth) - } -} - -case class ILit(n: BigInt) extends Arg { - def name: String = n.toString -} - -case class ULit(n: BigInt, w: Width) extends LitArg(n, w) { - def name: String = "UInt<" + width + ">(\"h0" + num.toString(16) + "\")" - def minWidth: Int = 1 max n.bitLength - - require(n >= 0, s"UInt literal ${n} is negative") -} - -case class SLit(n: BigInt, w: Width) extends LitArg(n, w) { - def name: String = { - val unsigned = if (n < 0) (BigInt(1) << width.get) + n else n - s"asSInt(${ULit(unsigned, width).name})" - } - def minWidth: Int = 1 + n.bitLength -} - -case class Ref(name: String) extends Arg -case class ModuleIO(mod: Module, name: String) extends Arg { - override def fullName(ctx: Component): String = - if (mod eq ctx.id) name else s"${mod.getRef.name}.$name" -} -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 { - def name: String = s"[$value]" - override def fullName(ctx: Component): String = s"${imm.fullName(ctx)}[$value]" -} - -object Width { - def apply(x: Int): Width = KnownWidth(x) - def apply(): Width = UnknownWidth() -} - -sealed abstract class Width { - type W = Int - def max(that: Width): Width = this.op(that, _ max _) - def + (that: Width): Width = this.op(that, _ + _) - def + (that: Int): Width = this.op(this, (a, b) => a + that) - def shiftRight(that: Int): Width = this.op(this, (a, b) => 0 max (a - that)) - def dynamicShiftLeft(that: Width): Width = - this.op(that, (a, b) => a + (1 << b) - 1) - - def known: Boolean - def get: W - protected def op(that: Width, f: (W, W) => W): Width -} - -sealed case class UnknownWidth() extends Width { - def known: Boolean = false - def get: Int = None.get - def op(that: Width, f: (W, W) => W): Width = this - override def toString: String = "?" -} - -sealed case class KnownWidth(value: Int) extends Width { - require(value >= 0) - def known: Boolean = true - def get: Int = value - def op(that: Width, f: (W, W) => W): Width = that match { - case KnownWidth(x) => KnownWidth(f(value, x)) - case _ => that - } - override def toString: String = value.toString -} - -abstract class Command -abstract class Definition extends Command { - def id: HasId - def name: String = id.getRef.name -} -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 DefInstance(id: Module, ports: Seq[Port]) extends Definition -case class DefPoison[T <: Data](id: T) extends Definition -case class WhenBegin(pred: Arg) extends Command -case class WhenEnd() extends Command -case class Connect(loc: Node, exp: Arg) extends Command -case class BulkConnect(loc1: Node, loc2: Node) extends Command -case class ConnectInit(loc: Node, exp: Arg) extends Command -case class Stop(clk: Arg, ret: Int) extends Command -case class Printf(clk: Arg, format: String, ids: Seq[Arg]) extends Command -case class Component(id: Module, name: String, ports: Seq[Port], commands: Seq[Command]) extends Arg -case class Port(id: Data, dir: Direction) - -case class Circuit(name: String, components: Seq[Component], refMap: RefMap) { - def emit: String = new Emitter(this).toString -} diff --git a/src/main/scala/Chisel/internal/Builder.scala b/src/main/scala/Chisel/internal/Builder.scala index 385e25a2..991a442f 100644 --- a/src/main/scala/Chisel/internal/Builder.scala +++ b/src/main/scala/Chisel/internal/Builder.scala @@ -6,7 +6,7 @@ import scala.util.DynamicVariable import scala.collection.mutable.{ArrayBuffer, HashMap} import Chisel._ -import Chisel.firrtl._ +import Chisel.internal.firrtl._ private[Chisel] class Namespace(parent: Option[Namespace], keywords: Set[String]) { private var i = 0L diff --git a/src/main/scala/Chisel/internal/firrtl/Emitter.scala b/src/main/scala/Chisel/internal/firrtl/Emitter.scala new file mode 100644 index 00000000..c46f14ca --- /dev/null +++ b/src/main/scala/Chisel/internal/firrtl/Emitter.scala @@ -0,0 +1,73 @@ +// See LICENSE for license details. + +package Chisel.internal.firrtl +import Chisel._ + +private class Emitter(circuit: Circuit) { + override def toString: String = res.toString + + private def emitPort(e: Port): String = + s"${e.dir} ${e.id.getRef.name} : ${e.id.toType}" + private def emit(e: Command, ctx: Component): String = e match { + 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: DefInstance => { + val modName = moduleMap.getOrElse(e.id.name, e.id.name) + s"inst ${e.name} of $modName" + } + + case w: WhenBegin => + indent() + s"when ${w.pred.fullName(ctx)} :" + case _: WhenEnd => + unindent() + "skip" + } + private def emitBody(m: Component) = { + val me = new StringBuilder + withIndent { + for (p <- m.ports) + me ++= newline + emitPort(p) + me ++= newline + for (cmd <- m.commands) + me ++= newline + emit(cmd, m) + me ++= newline + } + me + } + + private val bodyMap = collection.mutable.HashMap[StringBuilder, String]() + private val moduleMap = collection.mutable.HashMap[String, String]() + + private def emit(m: Component): String = { + val body = emitBody(m) + bodyMap get body match { + case Some(name) => + moduleMap(m.name) = name + "" + case None => + bodyMap(body) = m.name + newline + s"module ${m.name} : " + body + } + } + + private var indentLevel = 0 + private def newline = "\n" + (" " * indentLevel) + private def indent(): Unit = indentLevel += 1 + private def unindent() { require(indentLevel > 0); indentLevel -= 1 } + private def withIndent(f: => Unit) { indent(); f; unindent() } + + private val res = new StringBuilder(s"circuit ${circuit.name} : ") + withIndent { circuit.components.foreach(c => res ++= emit(c)) } + res ++= newline +} diff --git a/src/main/scala/Chisel/internal/firrtl/IR.scala b/src/main/scala/Chisel/internal/firrtl/IR.scala new file mode 100644 index 00000000..be61d67b --- /dev/null +++ b/src/main/scala/Chisel/internal/firrtl/IR.scala @@ -0,0 +1,160 @@ +// See LICENSE for license details. + +package Chisel.internal.firrtl +import Chisel._ +import Chisel.internal._ + +case class PrimOp(val name: String) { + override def toString: String = name +} + +object PrimOp { + val AddOp = PrimOp("add") + val AddModOp = PrimOp("addw") + val SubOp = PrimOp("sub") + val SubModOp = PrimOp("subw") + val TimesOp = PrimOp("mul") + val DivideOp = PrimOp("div") + val ModOp = PrimOp("mod") + val ShiftLeftOp = PrimOp("shl") + val ShiftRightOp = PrimOp("shr") + val DynamicShiftLeftOp = PrimOp("dshl") + val DynamicShiftRightOp = PrimOp("dshr") + val BitAndOp = PrimOp("and") + val BitOrOp = PrimOp("or") + val BitXorOp = PrimOp("xor") + val BitNotOp = PrimOp("not") + val ConcatOp = PrimOp("cat") + val BitSelectOp = PrimOp("bit") + val BitsExtractOp = PrimOp("bits") + val LessOp = PrimOp("lt") + val LessEqOp = PrimOp("leq") + val GreaterOp = PrimOp("gt") + val GreaterEqOp = PrimOp("geq") + val EqualOp = PrimOp("eq") + val PadOp = PrimOp("pad") + val NotEqualOp = PrimOp("neq") + val NegOp = PrimOp("neg") + val MultiplexOp = PrimOp("mux") + val XorReduceOp = PrimOp("xorr") + val ConvertOp = PrimOp("cvt") + val AsUIntOp = PrimOp("asUInt") + val AsSIntOp = PrimOp("asSInt") +} + +abstract class Arg { + def fullName(ctx: Component): String = name + def name: String +} + +case class Node(id: HasId) extends Arg { + override def fullName(ctx: Component): String = id.getRef.fullName(ctx) + def name: String = id.getRef.name +} + +abstract class LitArg(val num: BigInt, widthArg: Width) extends Arg { + private[Chisel] def forcedWidth = widthArg.known + private[Chisel] def width: Width = if (forcedWidth) widthArg else Width(minWidth) + + protected def minWidth: Int + if (forcedWidth) { + require(widthArg.get >= minWidth) + } +} + +case class ILit(n: BigInt) extends Arg { + def name: String = n.toString +} + +case class ULit(n: BigInt, w: Width) extends LitArg(n, w) { + def name: String = "UInt<" + width + ">(\"h0" + num.toString(16) + "\")" + def minWidth: Int = 1 max n.bitLength + + require(n >= 0, s"UInt literal ${n} is negative") +} + +case class SLit(n: BigInt, w: Width) extends LitArg(n, w) { + def name: String = { + val unsigned = if (n < 0) (BigInt(1) << width.get) + n else n + s"asSInt(${ULit(unsigned, width).name})" + } + def minWidth: Int = 1 + n.bitLength +} + +case class Ref(name: String) extends Arg +case class ModuleIO(mod: Module, name: String) extends Arg { + override def fullName(ctx: Component): String = + if (mod eq ctx.id) name else s"${mod.getRef.name}.$name" +} +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 { + def name: String = s"[$value]" + override def fullName(ctx: Component): String = s"${imm.fullName(ctx)}[$value]" +} + +object Width { + def apply(x: Int): Width = KnownWidth(x) + def apply(): Width = UnknownWidth() +} + +sealed abstract class Width { + type W = Int + def max(that: Width): Width = this.op(that, _ max _) + def + (that: Width): Width = this.op(that, _ + _) + def + (that: Int): Width = this.op(this, (a, b) => a + that) + def shiftRight(that: Int): Width = this.op(this, (a, b) => 0 max (a - that)) + def dynamicShiftLeft(that: Width): Width = + this.op(that, (a, b) => a + (1 << b) - 1) + + def known: Boolean + def get: W + protected def op(that: Width, f: (W, W) => W): Width +} + +sealed case class UnknownWidth() extends Width { + def known: Boolean = false + def get: Int = None.get + def op(that: Width, f: (W, W) => W): Width = this + override def toString: String = "?" +} + +sealed case class KnownWidth(value: Int) extends Width { + require(value >= 0) + def known: Boolean = true + def get: Int = value + def op(that: Width, f: (W, W) => W): Width = that match { + case KnownWidth(x) => KnownWidth(f(value, x)) + case _ => that + } + override def toString: String = value.toString +} + +abstract class Command +abstract class Definition extends Command { + def id: HasId + def name: String = id.getRef.name +} +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 DefInstance(id: Module, ports: Seq[Port]) extends Definition +case class DefPoison[T <: Data](id: T) extends Definition +case class WhenBegin(pred: Arg) extends Command +case class WhenEnd() extends Command +case class Connect(loc: Node, exp: Arg) extends Command +case class BulkConnect(loc1: Node, loc2: Node) extends Command +case class ConnectInit(loc: Node, exp: Arg) extends Command +case class Stop(clk: Arg, ret: Int) extends Command +case class Printf(clk: Arg, format: String, ids: Seq[Arg]) extends Command +case class Component(id: Module, name: String, ports: Seq[Port], commands: Seq[Command]) extends Arg +case class Port(id: Data, dir: Direction) + +case class Circuit(name: String, components: Seq[Component], refMap: RefMap) { + def emit: String = new Emitter(this).toString +} diff --git a/src/main/scala/Chisel/testers/BasicTester.scala b/src/main/scala/Chisel/testers/BasicTester.scala index 1079727c..6807a30e 100644 --- a/src/main/scala/Chisel/testers/BasicTester.scala +++ b/src/main/scala/Chisel/testers/BasicTester.scala @@ -5,7 +5,7 @@ import Chisel._ import internal._ import internal.Builder.pushCommand -import firrtl._ +import internal.firrtl._ class BasicTester extends Module { // The testbench has no IOs, rather it should communicate using printf, assert, and stop. -- cgit v1.2.3 From b4517e0fb563271464bd40ddf9a46a40fd827da4 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sat, 23 Jan 2016 16:10:22 -0800 Subject: Don't use deprecated constructs --- src/main/scala/Chisel/Aggregate.scala | 2 +- src/main/scala/Chisel/Bits.scala | 2 +- src/main/scala/Chisel/util/Arbiter.scala | 2 +- src/main/scala/Chisel/util/Decoupled.scala | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/main/scala/Chisel/Aggregate.scala b/src/main/scala/Chisel/Aggregate.scala index 33b71c4e..63df8135 100644 --- a/src/main/scala/Chisel/Aggregate.scala +++ b/src/main/scala/Chisel/Aggregate.scala @@ -156,7 +156,7 @@ sealed class Vec[T <: Data] private (gen: => T, val length: Int) def write(idx: UInt, data: T): Unit = apply(idx) := data override def cloneType: this.type = - Vec(gen, length).asInstanceOf[this.type] + Vec(length, gen).asInstanceOf[this.type] private val t = gen private[Chisel] def toType: String = s"${t.toType}[$length]" diff --git a/src/main/scala/Chisel/Bits.scala b/src/main/scala/Chisel/Bits.scala index b512bb56..739e6c1b 100644 --- a/src/main/scala/Chisel/Bits.scala +++ b/src/main/scala/Chisel/Bits.scala @@ -432,7 +432,7 @@ sealed class SInt private (dir: Direction, width: Width, lit: Option[SLit] = Non def >= (other: SInt): Bool = compop(GreaterEqOp, other) def != (other: SInt): Bool = compop(NotEqualOp, other) def === (other: SInt): Bool = compop(EqualOp, other) - def abs(): UInt = Mux(this < SInt(0), (-this).toUInt, this.toUInt) + def abs(): UInt = Mux(this < SInt(0), (-this).asUInt, this.asUInt) def << (other: Int): SInt = binop(SInt(this.width + other), ShiftLeftOp, other) def << (other: BigInt): SInt = this << other.toInt diff --git a/src/main/scala/Chisel/util/Arbiter.scala b/src/main/scala/Chisel/util/Arbiter.scala index 119b9f5a..2747640f 100644 --- a/src/main/scala/Chisel/util/Arbiter.scala +++ b/src/main/scala/Chisel/util/Arbiter.scala @@ -7,7 +7,7 @@ package Chisel /** An I/O bundle for the Arbiter */ class ArbiterIO[T <: Data](gen: T, n: Int) extends Bundle { - val in = Vec(Decoupled(gen), n).flip + val in = Vec(n, Decoupled(gen)).flip val out = Decoupled(gen) val chosen = UInt(OUTPUT, log2Up(n)) } diff --git a/src/main/scala/Chisel/util/Decoupled.scala b/src/main/scala/Chisel/util/Decoupled.scala index b1505887..ca000af9 100644 --- a/src/main/scala/Chisel/util/Decoupled.scala +++ b/src/main/scala/Chisel/util/Decoupled.scala @@ -82,7 +82,7 @@ class Queue[T <: Data](gen: T, val entries: Int, { val io = new QueueIO(gen, entries) - val ram = Mem(gen, entries) + val ram = Mem(entries, gen) val enq_ptr = Counter(entries) val deq_ptr = Counter(entries) val maybe_full = Reg(init=Bool(false)) -- cgit v1.2.3 From 86a6c6bcdc349f40dcc31bce1931dc7c427da674 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sat, 23 Jan 2016 21:11:09 -0800 Subject: Change implicit clock name to clk to match Chisel2 This allows us to share Verilog test harnesses between the two. --- src/main/resources/top.cpp | 8 ++++---- src/main/scala/Chisel/Module.scala | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/main/resources/top.cpp b/src/main/resources/top.cpp index 075d7085..8bfe2a99 100644 --- a/src/main/resources/top.cpp +++ b/src/main/resources/top.cpp @@ -44,10 +44,10 @@ int main(int argc, char** argv) { top->reset = 0; // Deassert reset } if ((main_time % 10) == 1) { - top->clock = 1; // Toggle clock + top->clk = 1; // Toggle clock } if ((main_time % 10) == 6) { - top->clock = 0; + top->clk = 0; } top->eval(); // Evaluate model #if VM_TRACE @@ -69,10 +69,10 @@ int main(int argc, char** argv) { vluint64_t end_time = main_time + 100; while (main_time < end_time) { if ((main_time % 10) == 1) { - top->clock = 1; // Toggle clock + top->clk = 1; // Toggle clock } if ((main_time % 10) == 6) { - top->clock = 0; + top->clk = 0; } top->eval(); // Evaluate model #if VM_TRACE diff --git a/src/main/scala/Chisel/Module.scala b/src/main/scala/Chisel/Module.scala index 1681f901..2a0f29db 100644 --- a/src/main/scala/Chisel/Module.scala +++ b/src/main/scala/Chisel/Module.scala @@ -60,7 +60,7 @@ abstract class Module(_clock: Clock = null, _reset: Bool = null) extends HasId { private[Chisel] def ref = Builder.globalRefMap(this) private[Chisel] def lref = ref - private def ports = (clock, "clock") :: (reset, "reset") :: (io, "io") :: Nil + private def ports = (clock, "clk") :: (reset, "reset") :: (io, "io") :: Nil private[Chisel] def computePorts = ports map { case (port, name) => val bundleDir = if (port.isFlip) INPUT else OUTPUT -- cgit v1.2.3 From 34a1abcd81bd3b2d7d264468345572009edfad27 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sun, 17 Jan 2016 17:20:49 -0800 Subject: Implement first draft of new FIRRTL changes --- src/main/scala/Chisel/Aggregate.scala | 2 +- src/main/scala/Chisel/Mem.scala | 32 ++++++++++++++-------- src/main/scala/Chisel/Reg.scala | 8 +++--- src/main/scala/Chisel/internal/Builder.scala | 5 ++-- .../scala/Chisel/internal/firrtl/Emitter.scala | 17 ++++++------ src/main/scala/Chisel/internal/firrtl/IR.scala | 22 +++++++++++---- 6 files changed, 53 insertions(+), 33 deletions(-) (limited to 'src') 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 -- cgit v1.2.3 From f856d44b1f7c00ecee0b13021b4723c89debd250 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sun, 24 Jan 2016 17:09:12 -0800 Subject: Disallow weak connect for Vec --- src/main/scala/Chisel/Aggregate.scala | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/main/scala/Chisel/Aggregate.scala b/src/main/scala/Chisel/Aggregate.scala index f510a913..3df48052 100644 --- a/src/main/scala/Chisel/Aggregate.scala +++ b/src/main/scala/Chisel/Aggregate.scala @@ -103,21 +103,16 @@ sealed class Vec[T <: Data] private (gen: => T, val length: Int) private val self = IndexedSeq.fill(length)(gen) - override def <> (that: Data): Unit = that match { - case _: Vec[_] => this bulkConnect that - case _ => this badConnect that - } + override def <> (that: Data): Unit = this := that - /** Weak bulk connect, assigning elements in this Vec from elements in a Seq. + /** Strong bulk connect, assigning elements in this Vec from elements in a Seq. * - * @note length mismatches silently ignored + * @note the length of this Vec must match the length of the input Seq */ - def <> (that: Seq[T]): Unit = - for ((a, b) <- this zip that) - a <> b + def <> (that: Seq[T]): Unit = this := that // TODO: eliminate once assign(Seq) isn't ambiguous with assign(Data) since Vec extends Seq and Data - def <> (that: Vec[T]): Unit = this bulkConnect that + def <> (that: Vec[T]): Unit = this := that.asInstanceOf[Data] override def := (that: Data): Unit = that match { case _: Vec[_] => this connect that -- cgit v1.2.3 From 9017ec37d0eb7bb3bd10ed7863c0706ff1020cd9 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 25 Jan 2016 15:35:03 -0800 Subject: Emit FIRRTL muxes for aggregates --- src/main/scala/Chisel/Bits.scala | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/main/scala/Chisel/Bits.scala b/src/main/scala/Chisel/Bits.scala index 739e6c1b..fbc1586f 100644 --- a/src/main/scala/Chisel/Bits.scala +++ b/src/main/scala/Chisel/Bits.scala @@ -527,24 +527,20 @@ object Mux { case (c: UInt, a: Bool) => doMux(cond, c, a << 0).asInstanceOf[T] case (c: Bool, a: UInt) => doMux(cond, c << 0, a).asInstanceOf[T] case (c: Bits, a: Bits) => doMux(cond, c, a).asInstanceOf[T] - // FIRRTL doesn't support Mux for aggregates, so use a when instead - case _ => doWhen(cond, con, alt) + case _ => doAggregateMux(cond, con, alt) } - private def doMux[T <: Bits](cond: Bool, con: T, alt: T): T = { + private def doMux[T <: Data](cond: Bool, con: T, alt: T): T = { require(con.getClass == alt.getClass, s"can't Mux between ${con.getClass} and ${alt.getClass}") val d = alt.cloneTypeWidth(con.width max alt.width) pushOp(DefPrim(d, MultiplexOp, cond.ref, con.ref, alt.ref)) } - // This returns an lvalue, which it most definitely should not - private def doWhen[T <: Data](cond: Bool, con: T, alt: T): T = { + + private def doAggregateMux[T <: Data](cond: Bool, con: T, alt: T): T = { require(con.getClass == alt.getClass, s"can't Mux between ${con.getClass} and ${alt.getClass}") for ((c, a) <- con.flatten zip alt.flatten) require(c.width == a.width, "can't Mux between aggregates of different width") - - val res = Wire(t = alt.cloneTypeWidth(con.width max alt.width), init = alt) - when (cond) { res := con } - res + doMux(cond, con, alt) } } -- cgit v1.2.3 From 2a3b5fc59c732d85aafda78f2fb21368dc4a5660 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 27 Jan 2016 15:18:49 -0800 Subject: New FIRRTL syntax for reg --- src/main/scala/Chisel/Reg.scala | 10 ++++++---- src/main/scala/Chisel/internal/firrtl/Emitter.scala | 3 ++- src/main/scala/Chisel/internal/firrtl/IR.scala | 3 ++- 3 files changed, 10 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/main/scala/Chisel/Reg.scala b/src/main/scala/Chisel/Reg.scala index f166c84b..e69061c5 100644 --- a/src/main/scala/Chisel/Reg.scala +++ b/src/main/scala/Chisel/Reg.scala @@ -45,10 +45,12 @@ 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) - 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 + val clock = Node(x._parent.get.clock) // TODO multi-clock + if (init == null) { + pushCommand(DefReg(x, clock)) + } else { + pushCommand(DefRegInit(x, clock, Node(x._parent.get.reset), init.ref)) + } if (next != null) { x := next } diff --git a/src/main/scala/Chisel/internal/firrtl/Emitter.scala b/src/main/scala/Chisel/internal/firrtl/Emitter.scala index 8597454a..2765efa8 100644 --- a/src/main/scala/Chisel/internal/firrtl/Emitter.scala +++ b/src/main/scala/Chisel/internal/firrtl/Emitter.scala @@ -12,7 +12,8 @@ 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)}, ${e.init.fullName(ctx)}" + case e: DefReg => s"reg ${e.name} : ${e.id.toType}, ${e.clock.fullName(ctx)}" + case e: DefRegInit => s"reg ${e.name} : ${e.id.toType}, ${e.clock.fullName(ctx)} with : (reset => (${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)}" diff --git a/src/main/scala/Chisel/internal/firrtl/IR.scala b/src/main/scala/Chisel/internal/firrtl/IR.scala index 5612f1af..ec9b9e36 100644 --- a/src/main/scala/Chisel/internal/firrtl/IR.scala +++ b/src/main/scala/Chisel/internal/firrtl/IR.scala @@ -149,7 +149,8 @@ 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, init: Arg) extends Definition +case class DefReg(id: Data, clock: Arg) extends Definition +case class DefRegInit(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 -- cgit v1.2.3 From 71f45a6df99cb86ada1ad9d091a38e01b698a863 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 27 Jan 2016 15:19:23 -0800 Subject: In FIRRTL, bitwise operators return UInt --- src/main/scala/Chisel/Bits.scala | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/main/scala/Chisel/Bits.scala b/src/main/scala/Chisel/Bits.scala index fbc1586f..3974d05d 100644 --- a/src/main/scala/Chisel/Bits.scala +++ b/src/main/scala/Chisel/Bits.scala @@ -92,9 +92,6 @@ sealed abstract class Bits(dirArg: Direction, width: Width, override val litArg: private[Chisel] def redop(op: PrimOp): Bool = pushOp(DefPrim(Bool(), op, this.ref)) - /** Returns this wire bitwise-inverted. */ - def unary_~ : this.type = unop(cloneTypeWidth(width), BitNotOp) - /** Returns this wire zero padded up to the specified width. * * @note for SInts only, this does sign extension @@ -292,6 +289,9 @@ sealed class UInt private[Chisel] (dir: Direction, width: Width, lit: Option[ULi def | (other: UInt): UInt = binop(UInt(this.width max other.width), BitOrOp, other) def ^ (other: UInt): UInt = binop(UInt(this.width max other.width), BitXorOp, other) + /** Returns this wire bitwise-inverted. */ + def unary_~ : UInt = unop(UInt(width = width), BitNotOp) + // REVIEW TODO: Can this be defined on Bits? def orR: Bool = this != UInt(0) def andR: Bool = ~this === UInt(0) @@ -422,9 +422,12 @@ sealed class SInt private (dir: Direction, width: Width, lit: Option[SLit] = Non def / (other: SInt): SInt = binop(SInt(this.width), DivideOp, other) def % (other: SInt): SInt = binop(SInt(this.width), ModOp, other) - def & (other: SInt): SInt = binop(SInt(this.width max other.width), BitAndOp, other) - def | (other: SInt): SInt = binop(SInt(this.width max other.width), BitOrOp, other) - def ^ (other: SInt): SInt = binop(SInt(this.width max other.width), BitXorOp, other) + def & (other: SInt): SInt = binop(UInt(this.width max other.width), BitAndOp, other).asSInt + def | (other: SInt): SInt = binop(UInt(this.width max other.width), BitOrOp, other).asSInt + def ^ (other: SInt): SInt = binop(UInt(this.width max other.width), BitXorOp, other).asSInt + + /** Returns this wire bitwise-inverted. */ + def unary_~ : SInt = unop(UInt(width = width), BitNotOp).asSInt def < (other: SInt): Bool = compop(LessOp, other) def > (other: SInt): Bool = compop(GreaterOp, other) @@ -490,6 +493,9 @@ sealed class Bool(dir: Direction, lit: Option[ULit] = None) extends UInt(dir, Wi def | (other: Bool): Bool = binop(Bool(), BitOrOp, other) def ^ (other: Bool): Bool = binop(Bool(), BitXorOp, other) + /** Returns this wire bitwise-inverted. */ + override def unary_~ : Bool = unop(Bool(), BitNotOp) + /** Outputs the logical OR of two Bools. */ def || (that: Bool): Bool = this | that -- cgit v1.2.3 From 22d302ad066d8a073e44289ba4876a165ea56b05 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 27 Jan 2016 15:20:00 -0800 Subject: Remove unsupported FIRRTL node bit(); use bits() --- src/main/scala/Chisel/Bits.scala | 2 +- src/main/scala/Chisel/internal/firrtl/IR.scala | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/main/scala/Chisel/Bits.scala b/src/main/scala/Chisel/Bits.scala index 3974d05d..6062f2de 100644 --- a/src/main/scala/Chisel/Bits.scala +++ b/src/main/scala/Chisel/Bits.scala @@ -39,7 +39,7 @@ sealed abstract class Bits(dirArg: Direction, width: Width, override val litArg: if (isLit()) { Bool(((litValue() >> x.toInt) & 1) == 1) } else { - pushOp(DefPrim(Bool(), BitSelectOp, this.ref, ILit(x))) + pushOp(DefPrim(Bool(), BitsExtractOp, this.ref, ILit(x), ILit(x))) } } diff --git a/src/main/scala/Chisel/internal/firrtl/IR.scala b/src/main/scala/Chisel/internal/firrtl/IR.scala index ec9b9e36..1bc3ad89 100644 --- a/src/main/scala/Chisel/internal/firrtl/IR.scala +++ b/src/main/scala/Chisel/internal/firrtl/IR.scala @@ -25,7 +25,6 @@ object PrimOp { val BitXorOp = PrimOp("xor") val BitNotOp = PrimOp("not") val ConcatOp = PrimOp("cat") - val BitSelectOp = PrimOp("bit") val BitsExtractOp = PrimOp("bits") val LessOp = PrimOp("lt") val LessEqOp = PrimOp("leq") -- cgit v1.2.3 From c9dd94dd6968cba5ecd44fee6df3071cb7a25a9c Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 27 Jan 2016 15:20:44 -0800 Subject: Use FIRRTL node rem, not mod, for % --- src/main/scala/Chisel/Bits.scala | 4 ++-- src/main/scala/Chisel/internal/firrtl/IR.scala | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/main/scala/Chisel/Bits.scala b/src/main/scala/Chisel/Bits.scala index 6062f2de..4a9a6074 100644 --- a/src/main/scala/Chisel/Bits.scala +++ b/src/main/scala/Chisel/Bits.scala @@ -283,7 +283,7 @@ sealed class UInt private[Chisel] (dir: Direction, width: Width, lit: Option[ULi def * (other: UInt): UInt = binop(UInt(this.width + other.width), TimesOp, other) def * (other: SInt): SInt = other * this def / (other: UInt): UInt = binop(UInt(this.width), DivideOp, other) - def % (other: UInt): UInt = binop(UInt(this.width), ModOp, other) + def % (other: UInt): UInt = binop(UInt(this.width), RemOp, other) def & (other: UInt): UInt = binop(UInt(this.width max other.width), BitAndOp, other) def | (other: UInt): UInt = binop(UInt(this.width max other.width), BitOrOp, other) @@ -420,7 +420,7 @@ sealed class SInt private (dir: Direction, width: Width, lit: Option[SLit] = Non def * (other: SInt): SInt = binop(SInt(this.width + other.width), TimesOp, other) def * (other: UInt): SInt = binop(SInt(this.width + other.width), TimesOp, other) def / (other: SInt): SInt = binop(SInt(this.width), DivideOp, other) - def % (other: SInt): SInt = binop(SInt(this.width), ModOp, other) + def % (other: SInt): SInt = binop(SInt(this.width), RemOp, other) def & (other: SInt): SInt = binop(UInt(this.width max other.width), BitAndOp, other).asSInt def | (other: SInt): SInt = binop(UInt(this.width max other.width), BitOrOp, other).asSInt diff --git a/src/main/scala/Chisel/internal/firrtl/IR.scala b/src/main/scala/Chisel/internal/firrtl/IR.scala index 1bc3ad89..cc80e3aa 100644 --- a/src/main/scala/Chisel/internal/firrtl/IR.scala +++ b/src/main/scala/Chisel/internal/firrtl/IR.scala @@ -15,7 +15,7 @@ object PrimOp { val SubModOp = PrimOp("subw") val TimesOp = PrimOp("mul") val DivideOp = PrimOp("div") - val ModOp = PrimOp("mod") + val RemOp = PrimOp("rem") val ShiftLeftOp = PrimOp("shl") val ShiftRightOp = PrimOp("shr") val DynamicShiftLeftOp = PrimOp("dshl") -- cgit v1.2.3 From bce4a96934fe8575b71769f2e52a2b75a068d34d Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 27 Jan 2016 15:20:58 -0800 Subject: Use FIRRTL nodes add+tail instead of addw --- src/main/scala/Chisel/Bits.scala | 26 ++++++++++++++++++++++---- src/main/scala/Chisel/internal/firrtl/IR.scala | 4 ++-- 2 files changed, 24 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/main/scala/Chisel/Bits.scala b/src/main/scala/Chisel/Bits.scala index 4a9a6074..b800644d 100644 --- a/src/main/scala/Chisel/Bits.scala +++ b/src/main/scala/Chisel/Bits.scala @@ -29,6 +29,24 @@ sealed abstract class Bits(dirArg: Direction, width: Width, override val litArg: override def <> (that: Data): Unit = this := that + def tail(n: Int): UInt = { + val w = width match { + case KnownWidth(x) => + require(x >= n, s"Can't tail($n) for width $x < $n") + Width(x - n) + case UnknownWidth() => Width() + } + binop(UInt(width = w), TailOp, n) + } + + def head(n: Int): UInt = { + width match { + case KnownWidth(x) => require(x >= n, s"Can't head($n) for width $x < $n") + case UnknownWidth() => + } + binop(UInt(width = n), HeadOp, n) + } + /** Returns the specified bit on this wire as a [[Bool]], statically * addressed. */ @@ -276,10 +294,10 @@ sealed class UInt private[Chisel] (dir: Direction, width: Width, lit: Option[ULi def unary_-% : UInt = UInt(0) -% this def +& (other: UInt): UInt = binop(UInt((this.width max other.width) + 1), AddOp, other) def + (other: UInt): UInt = this +% other - def +% (other: UInt): UInt = binop(UInt(this.width max other.width), AddModOp, other) + def +% (other: UInt): UInt = (this +& other) tail 1 def -& (other: UInt): UInt = binop(UInt((this.width max other.width) + 1), SubOp, other) def - (other: UInt): UInt = this -% other - def -% (other: UInt): UInt = binop(UInt(this.width max other.width), SubModOp, other) + def -% (other: UInt): UInt = (this -& other) tail 1 def * (other: UInt): UInt = binop(UInt(this.width + other.width), TimesOp, other) def * (other: SInt): SInt = other * this def / (other: UInt): UInt = binop(UInt(this.width), DivideOp, other) @@ -410,13 +428,13 @@ sealed class SInt private (dir: Direction, width: Width, lit: Option[SLit] = Non /** add (default - no growth) operator */ def + (other: SInt): SInt = this +% other /** add (no growth) operator */ - def +% (other: SInt): SInt = binop(SInt(this.width max other.width), AddModOp, other) + def +% (other: SInt): SInt = (this +& other).tail(1).asSInt /** subtract (width +1) operator */ def -& (other: SInt): SInt = binop(SInt((this.width max other.width) + 1), SubOp, other) /** subtract (default - no growth) operator */ def - (other: SInt): SInt = this -% other /** subtract (no growth) operator */ - def -% (other: SInt): SInt = binop(SInt(this.width max other.width), SubModOp, other) + def -% (other: SInt): SInt = (this -& other).tail(1).asSInt def * (other: SInt): SInt = binop(SInt(this.width + other.width), TimesOp, other) def * (other: UInt): SInt = binop(SInt(this.width + other.width), TimesOp, other) def / (other: SInt): SInt = binop(SInt(this.width), DivideOp, other) diff --git a/src/main/scala/Chisel/internal/firrtl/IR.scala b/src/main/scala/Chisel/internal/firrtl/IR.scala index cc80e3aa..3e923366 100644 --- a/src/main/scala/Chisel/internal/firrtl/IR.scala +++ b/src/main/scala/Chisel/internal/firrtl/IR.scala @@ -10,9 +10,9 @@ case class PrimOp(val name: String) { object PrimOp { val AddOp = PrimOp("add") - val AddModOp = PrimOp("addw") val SubOp = PrimOp("sub") - val SubModOp = PrimOp("subw") + val TailOp = PrimOp("tail") + val HeadOp = PrimOp("head") val TimesOp = PrimOp("mul") val DivideOp = PrimOp("div") val RemOp = PrimOp("rem") -- cgit v1.2.3 From 41674d5e130f64d7489fdb8583b8f4ad88b64aeb Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 28 Jan 2016 12:05:03 -0800 Subject: Use FIRRTL is invalid construct --- src/main/scala/Chisel/Data.scala | 10 +--------- src/main/scala/Chisel/Mem.scala | 7 +++++-- src/main/scala/Chisel/Module.scala | 8 ++------ src/main/scala/Chisel/internal/firrtl/Emitter.scala | 2 +- src/main/scala/Chisel/internal/firrtl/IR.scala | 2 +- 5 files changed, 10 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/main/scala/Chisel/Data.scala b/src/main/scala/Chisel/Data.scala index 1011fe47..0ac3ee32 100644 --- a/src/main/scala/Chisel/Data.scala +++ b/src/main/scala/Chisel/Data.scala @@ -119,7 +119,7 @@ object Wire { if (init != null) { x := init } else { - x.flatten.foreach(e => e := e.fromInt(0)) + pushCommand(DefInvalid(x.ref)) } x } @@ -141,11 +141,3 @@ sealed class Clock(dirArg: Direction) extends Element(dirArg, Width(1)) { case _ => this badConnect that } } - -// TODO: check with FIRRTL specs, how much official implementation flexibility -// is there? -/** A source of garbage data, used to initialize Wires to a don't-care value. */ -private object Poison extends Command { - def apply[T <: Data](t: T): T = - pushCommand(DefPoison(t.cloneType)).id -} diff --git a/src/main/scala/Chisel/Mem.scala b/src/main/scala/Chisel/Mem.scala index 3bbb1151..21284607 100644 --- a/src/main/scala/Chisel/Mem.scala +++ b/src/main/scala/Chisel/Mem.scala @@ -113,6 +113,9 @@ object SeqMem { * result is undefined (unlike Vec, where the last assignment wins) */ sealed class SeqMem[T <: Data](t: T, n: Int) extends MemBase[T](t, n) { - def read(addr: UInt, enable: Bool): T = - read(Mux(enable, addr, Poison(addr))) + def read(addr: UInt, enable: Bool): T = { + val a = Wire(UInt()) + when (enable) { a := addr } + read(a) + } } diff --git a/src/main/scala/Chisel/Module.scala b/src/main/scala/Chisel/Module.scala index 2a0f29db..463c2f81 100644 --- a/src/main/scala/Chisel/Module.scala +++ b/src/main/scala/Chisel/Module.scala @@ -20,16 +20,12 @@ object Module { def apply[T <: Module](bc: => T): T = { val parent = dynamicContext.currentModule val m = bc.setRefs() - // init module outputs - m._commands prependAll (for (p <- m.io.flatten; if p.dir == OUTPUT) - yield Connect(p.lref, p.fromInt(0).ref)) + m._commands.prepend(DefInvalid(m.io.ref)) // init module outputs dynamicContext.currentModule = parent val ports = m.computePorts Builder.components += Component(m, m.name, ports, m._commands) pushCommand(DefInstance(m, ports)) - // init instance inputs - for (p <- m.io.flatten; if p.dir == INPUT) - p := p.fromInt(0) + pushCommand(DefInvalid(m.io.ref)) // init instance inputs m.connectImplicitIOs() } } diff --git a/src/main/scala/Chisel/internal/firrtl/Emitter.scala b/src/main/scala/Chisel/internal/firrtl/Emitter.scala index 2765efa8..13d9fa8f 100644 --- a/src/main/scala/Chisel/internal/firrtl/Emitter.scala +++ b/src/main/scala/Chisel/internal/firrtl/Emitter.scala @@ -11,7 +11,6 @@ private class Emitter(circuit: Circuit) { private def emit(e: Command, ctx: Component): String = e match { 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: DefReg => s"reg ${e.name} : ${e.id.toType}, ${e.clock.fullName(ctx)}" case e: DefRegInit => s"reg ${e.name} : ${e.id.toType}, ${e.clock.fullName(ctx)} with : (reset => (${e.reset.fullName(ctx)}, ${e.init.fullName(ctx)}))" case e: DefMemory => s"cmem ${e.name} : ${e.t.toType}[${e.size}]" @@ -21,6 +20,7 @@ private class Emitter(circuit: Circuit) { 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: DefInvalid => s"${e.arg.fullName(ctx)} is invalid" 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 3e923366..7bb273c0 100644 --- a/src/main/scala/Chisel/internal/firrtl/IR.scala +++ b/src/main/scala/Chisel/internal/firrtl/IR.scala @@ -147,6 +147,7 @@ abstract class Definition extends Command { def name: String = id.getRef.name } case class DefPrim[T <: Data](id: T, op: PrimOp, args: Arg*) extends Definition +case class DefInvalid(arg: Arg) extends Command case class DefWire(id: Data) extends Definition case class DefReg(id: Data, clock: Arg) extends Definition case class DefRegInit(id: Data, clock: Arg, reset: Arg, init: Arg) extends Definition @@ -154,7 +155,6 @@ 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 case class WhenEnd() extends Command case class Connect(loc: Node, exp: Arg) extends Command -- cgit v1.2.3