diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/scala/Chisel/Core.scala | 12 | ||||
| -rw-r--r-- | src/main/scala/Chisel/utils.scala | 39 |
2 files changed, 25 insertions, 26 deletions
diff --git a/src/main/scala/Chisel/Core.scala b/src/main/scala/Chisel/Core.scala index d9d7cf38..a3483c82 100644 --- a/src/main/scala/Chisel/Core.scala +++ b/src/main/scala/Chisel/Core.scala @@ -16,14 +16,6 @@ class IdGen { object Builder { val components = new ArrayBuffer[Component]() val idGen = new IdGen - val switchKeyz = new Stack[Stack[Bits]]() - def switchKeys = switchKeyz.top - def pushScope = { - switchKeyz.push(new Stack[Bits]()) - } - def popScope = { - switchKeyz.pop() - } val modulez = new Stack[Module]() def pushModule(mod: Module) { modulez.push(mod) @@ -993,7 +985,6 @@ object Module { val m = bc m.setRefs val cmd = popCommands - popScope popModule val ports = m.computePorts val component = Component(m.name, ports, cmd) @@ -1017,7 +1008,6 @@ abstract class Module(_clock: Clock = null, _reset: Bool = null) extends Id { val name = globalNamespace.name(getClass.getName.split('.').last) pushModule(this) - pushScope pushCommands val params = Module.params @@ -1091,11 +1081,9 @@ abstract class BlackBox(_clock: Clock = null, _reset: Bool = null) extends Modul object when { private[Chisel] def execBlock(block: => Unit): Command = { - pushScope pushCommands block val cmd = popCommands - popScope cmd } def apply(cond: => Bool)(block: => Unit): when = { diff --git a/src/main/scala/Chisel/utils.scala b/src/main/scala/Chisel/utils.scala index 1e024b11..6d073e3d 100644 --- a/src/main/scala/Chisel/utils.scala +++ b/src/main/scala/Chisel/utils.scala @@ -1,6 +1,10 @@ package Chisel import Builder._ import scala.math._ +import scala.language.reflectiveCalls +import scala.language.experimental.macros +import scala.reflect.runtime.universe._ +import scala.reflect.macros.whitebox._ object log2Up { @@ -122,23 +126,30 @@ object unless { } } -object switch { - def apply(c: Bits)(block: => Unit) { - switchKeys.push(c) - block - switchKeys.pop() +class SwitchContext[T <: Bits](cond: T) { + def is(v: Iterable[T])(block: => Unit) { + if (!v.isEmpty) when (v.map(_.asUInt === cond.asUInt).reduce(_||_)) { block } } + def is(v: T)(block: => Unit) { is(Seq(v))(block) } + def is(v: T, vr: T*)(block: => Unit) { is(v :: vr.toList)(block) } +} + +object is { // Begin deprecation of non-type-parameterized is statements. + def apply(v: Iterable[Bits])(block: => Unit) { ChiselError.error("The 'is' keyword may not be used outside of a switch.") } + def apply(v: Bits)(block: => Unit) { ChiselError.error("The 'is' keyword may not be used outside of a switch.") } + def apply(v: Bits, vr: Bits*)(block: => Unit) { ChiselError.error("The 'is' keyword may not be used outside of a switch.") } } -object is { - def apply(v: Bits)(block: => Unit): Unit = - apply(Seq(v))(block) - def apply(v: Bits, vr: Bits*)(block: => Unit): Unit = - apply(v :: vr.toList)(block) - def apply(v: Iterable[Bits])(block: => Unit): Unit = { - val keys = switchKeys - if (keys.isEmpty) ChiselError.error("The 'is' keyword may not be used outside of a switch.") - else if (!v.isEmpty) when (v.map(_.toBits === keys.top.toBits).reduce(_||_)) { block } +object switch { + def apply[T <: Bits](cond: T)(x: => Unit): Unit = macro impl + def impl(c: Context)(cond: c.Tree)(x: c.Tree) = { import c.universe._ + def extractIsStatement(tree: Tree): List[c.universe.Tree] = tree match { + case q"Chisel.is.apply( ..$params )( ..$body )" => List(q"sc.is( ..$params )( ..$body )") + case b => throw new Exception(s"Cannot include blocks that do not begin with is() in switch.") + } + val q"..$body" = x + val ises = body.flatMap(extractIsStatement(_)) + q"""{ val sc = new SwitchContext($cond); ..$ises }""" } } |
