From e54fb610c6bf0a7fe5c9c0f0e0b3acbb3728cfd0 Mon Sep 17 00:00:00 2001 From: Adam Izraelevitz Date: Sun, 25 Sep 2016 20:35:09 -0700 Subject: Spec features added: AnalogType and Attach (#295) * Spec features added: AnalogType and Attach AnalogType(width: Width): - Concrete syntax: wire x: AnalogType<10> - New groundtype, very restricted in use cases. - Can only declare ports and wires with Analog type - Analog types are never equivalent, thus if x and y have Analog types: x <= y is never legal. Attach(info: Info, source: Expression, exprs: Seq[Expression]): - Concrete syntax: attach x to (y, z) - New statement - Source can be any groundtyped expression (UInt, SInt, Analog, Clock) - Exprs must have an Analog type reference an instance port - Source and exprs must have identical widths Included WDefInstanceConnector to enable emission of Verilog inout Should be mostly feature complete. Need to update spec if PR gets accepted. * Fixed bug where invalidated ports aren't handled * Bugfix for VerilogPrep Intermediate wires for invalidated instance ports were not invalidated * Bugfix: calling create_exp with name/tpe Returns unknown gender, which was passing through Caused temporary wire to not be declared Because Verilog is dumb, undeclared wires are assumed to be 1bit signals * Addressed donggyukim's style comments * Reworked pass to only allow analog types in attach Restrict source to be only wire or port kind Much simpler implementation, almost identical functionality Clearer semantics (i think?) * Fixup bugs from pulling in new changes from master * comments for type eqs and small style fixes --- src/main/scala/firrtl/Emitter.scala | 47 +++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 23 deletions(-) (limited to 'src/main/scala/firrtl/Emitter.scala') diff --git a/src/main/scala/firrtl/Emitter.scala b/src/main/scala/firrtl/Emitter.scala index 0269a4fc..0a3068bc 100644 --- a/src/main/scala/firrtl/Emitter.scala +++ b/src/main/scala/firrtl/Emitter.scala @@ -64,6 +64,7 @@ case class VRandom(width: BigInt) extends Expression { def mapType(f: Type => Type): Expression = this def mapWidth(f: Width => Width): Expression = this } + class VerilogEmitter extends Emitter { val tab = " " def AND(e1: WrappedExpression, e2: WrappedExpression): Expression = { @@ -87,6 +88,7 @@ class VerilogEmitter extends Emitter { case (t: UIntType) => e case (t: SIntType) => Seq("$signed(",e,")") case ClockType => e + case AnalogType(w) => e } (x) match { case (e: DoPrim) => emit(op_stream(e), top + 1) @@ -106,6 +108,9 @@ class VerilogEmitter extends Emitter { val wx = bitWidth(t) - 1 if (wx > 0) w write s"[$wx:0]" case ClockType => + case t: AnalogType => + val wx = bitWidth(t) - 1 + if (wx > 0) w write s"[$wx:0]" case (t: VectorType) => emit(t.tpe, top + 1) w write s"[${t.size - 1}:0]" @@ -371,21 +376,6 @@ class VerilogEmitter extends Emitter { initials += Seq("`endif") } - def instantiate(n: String,m: String, es: Seq[Expression]) { - instdeclares += Seq(m, " ", n, " (") - es.zipWithIndex foreach {case (e, i) => - val s = Seq(tab, ".", remove_root(e), "(", LowerTypes.loweredName(e), ")") - if (i != es.size - 1) instdeclares += Seq(s, ",") - else instdeclares += s - } - instdeclares += Seq(");") - es foreach { e => - declare("wire",LowerTypes.loweredName(e), e.tpe) - val ex = WRef(LowerTypes.loweredName(e), e.tpe, kind(e), gender(e)) - if (gender(e) == FEMALE) assign(ex,netlist(e)) - } - } - def simulate(clk: Expression, en: Expression, s: Seq[Any], cond: Option[String]) { if (!at_clock.contains(clk)) at_clock(clk) = ArrayBuffer[Seq[Any]]() at_clock(clk) += Seq("`ifndef SYNTHESIS") @@ -415,10 +405,12 @@ class VerilogEmitter extends Emitter { } def build_ports(): Unit = portdefs ++= m.ports.zipWithIndex map { - case (p, i) => p.direction match { - case Input => + case (p, i) => (p.tpe, p.direction) match { + case (AnalogType(_), _) => + Seq("inout", " ", p.tpe, " ", p.name) + case (_, Input) => Seq(p.direction, " ", p.tpe, " ", p.name) - case Output => + case (_, Output) => val ex = WRef(p.name, p.tpe, PortKind, FEMALE) assign(ex, netlist(ex)) Seq(p.direction, " ", p.tpe, " ", p.name) @@ -427,9 +419,12 @@ class VerilogEmitter extends Emitter { def build_streams(s: Statement): Statement = s map build_streams match { case (s: DefWire) => - declare("wire", s.name, s.tpe) - val e = wref(s.name, s.tpe) - assign(e,netlist(e)) + declare("wire",s.name,s.tpe) + val e = wref(s.name,s.tpe) + netlist get e match { + case Some(n) => assign(e,n) + case None => + } s case (s: DefRegister) => declare("reg", s.name, s.tpe) @@ -453,9 +448,15 @@ class VerilogEmitter extends Emitter { case (s: Print) => simulate(s.clk, s.en, printf(s.string, s.args), Some("PRINTF_COND")) s - case (s: WDefInstance) => + case (s: WDefInstanceConnector) => val es = create_exps(WRef(s.name, s.tpe, InstanceKind, MALE)) - instantiate(s.name, s.module, es) + instdeclares += Seq(s.module, " ", s.name, " (") + (es zip s.exprs).zipWithIndex foreach {case ((l, r), i) => + val s = Seq(tab, ".", remove_root(l), "(", r, ")") + if (i != es.size - 1) instdeclares += Seq(s, ",") + else instdeclares += s + } + instdeclares += Seq(");") s case (s: DefMemory) => declare("reg", s.name, VectorType(s.dataType, s.depth)) -- cgit v1.2.3