diff options
Diffstat (limited to 'src/main')
| -rw-r--r-- | src/main/scala/firrtl/Emitter.scala | 25 | ||||
| -rw-r--r-- | src/main/scala/firrtl/Serialize.scala | 30 | ||||
| -rw-r--r-- | src/main/scala/firrtl/passes/Checks.scala | 8 |
3 files changed, 41 insertions, 22 deletions
diff --git a/src/main/scala/firrtl/Emitter.scala b/src/main/scala/firrtl/Emitter.scala index 17cb9d50..eb4cd9b8 100644 --- a/src/main/scala/firrtl/Emitter.scala +++ b/src/main/scala/firrtl/Emitter.scala @@ -55,10 +55,11 @@ object FIRRTLEmitter extends Emitter { } case class VIndent() -case class VRandom() +case object VRandom extends Expression { + def tpe = UIntType(UnknownWidth()) +} class VerilogEmitter extends Emitter { val tab = " " - val ran = VRandom() var w:Option[Writer] = None var mname = "" def wref (n:String,t:Type) = WRef(n,t,ExpKind(),UNKNOWNGENDER) @@ -72,7 +73,7 @@ class VerilogEmitter extends Emitter { def emit (x:Any) = emit2(x,0) def emit2 (x:Any, top:Int) : Unit = { def cast (e:Expression) : Any = { - (tpe(e)) match { + e.tpe match { case (t:UIntType) => e case (t:SIntType) => Seq("$signed(",e,")") case (t:ClockType) => e @@ -89,6 +90,8 @@ class VerilogEmitter extends Emitter { case (e:WSubAccess) => w.get.write(LowerTypes.loweredName(e.exp) + "[" + LowerTypes.loweredName(e.index) + "]") case (e:WSubIndex) => w.get.write(e.serialize) case (_:UIntValue|_:SIntValue) => v_print(e) + case VRandom => w.get.write("$random") + } } case (t:Type) => { @@ -113,7 +116,6 @@ class VerilogEmitter extends Emitter { case (i:Int) => w.get.write(i.toString) case (i:Long) => w.get.write(i.toString) case (t:VIndent) => w.get.write(" ") - case (r:VRandom) => w.get.write("$random") case (s:Seq[Any]) => { s.foreach((x:Any) => emit2(x.as[Any].get, top + 1)) if (top == 0) w.get.write("\n") @@ -308,6 +310,14 @@ class VerilogEmitter extends Emitter { } def assign (e:Expression,value:Expression) = assigns += Seq("assign ",e," = ",value,";") + // Like assign but with different versions for synthesis and simulation + def synSimAssign(e: Expression, syn: Expression, sim: Expression) = { + assigns += Seq("`ifdef SYNTHESIS") + assigns += Seq("assign ", e, " = ", syn, ";") + assigns += Seq("`else") + assigns += Seq("assign ", e, " = ", sim, ";") + assigns += Seq("`endif") + } def update_and_reset(r: Expression, clk: Expression, reset: Expression, init: Expression) = { def addUpdate(e: Expression, tabs: String): Seq[Seq[Any]] = { e match { @@ -349,7 +359,7 @@ class VerilogEmitter extends Emitter { val nx = namespace.newTemp val wx = ((long_BANG(t) + 31) / 32).toInt val tx = SIntType(IntWidth(wx * 32)) - val rand = Seq("{",wx.toString,"{",ran,"}}") + val rand = Seq("{",wx.toString,"{",VRandom,"}}") declare("reg",nx,tx) initials += Seq(wref(nx,tx)," = ",rand,";") Seq(nx,"[",long_BANG(t) - 1,":0]") @@ -486,7 +496,10 @@ class VerilogEmitter extends Emitter { val addrx = delay(addr,s.read_latency,clk) val enx = delay(en,s.read_latency,clk) val mem_port = WSubAccess(mem,addrx,s.data_type,UNKNOWNGENDER) - assign(data,mem_port) + val depthValue = UIntValue(s.depth, IntWidth(BigInt(s.depth).bitLength)) + val garbageGuard = DoPrim(GREATER_EQ_OP, Seq(addrx, depthValue), Seq(), UnknownType()) + val garbageMux = Mux(garbageGuard, VRandom, mem_port, UnknownType()) + synSimAssign(data, mem_port, garbageMux) } for (w <- s.writers ) { diff --git a/src/main/scala/firrtl/Serialize.scala b/src/main/scala/firrtl/Serialize.scala index 0229bb57..1735c270 100644 --- a/src/main/scala/firrtl/Serialize.scala +++ b/src/main/scala/firrtl/Serialize.scala @@ -31,25 +31,29 @@ import firrtl.PrimOps._ import firrtl.Utils._ private object Serialize { - def serialize(root: AST): String = { + lazy val ser = new Serialize root match { - case r: PrimOp => serialize(r) - case r: Expression => serialize(r) - case r: Stmt => serialize(r) - case r: Width => serialize(r) - case r: Flip => serialize(r) - case r: Field => serialize(r) - case r: Type => serialize(r) - case r: Direction => serialize(r) - case r: Port => serialize(r) - case r: Module => serialize(r) - case r: Circuit => serialize(r) - case r: StringLit => serialize(r) + case r: PrimOp => ser.serialize(r) + case r: Expression => ser.serialize(r) + case r: Stmt => ser.serialize(r) + case r: Width => ser.serialize(r) + case r: Flip => ser.serialize(r) + case r: Field => ser.serialize(r) + case r: Type => ser.serialize(r) + case r: Direction => ser.serialize(r) + case r: Port => ser.serialize(r) + case r: Module => ser.serialize(r) + case r: Circuit => ser.serialize(r) + case r: StringLit => ser.serialize(r) case _ => throw new Exception("serialize called on unknown AST node!") } } + /** Creates new instance of Serialize */ + def apply() = new Serialize +} +class Serialize { def serialize(bi: BigInt): String = if (bi < BigInt(0)) "\"h" + bi.toString(16).substring(1) + "\"" else "\"h" + bi.toString(16) + "\"" diff --git a/src/main/scala/firrtl/passes/Checks.scala b/src/main/scala/firrtl/passes/Checks.scala index 49effc75..23613e65 100644 --- a/src/main/scala/firrtl/passes/Checks.scala +++ b/src/main/scala/firrtl/passes/Checks.scala @@ -648,7 +648,9 @@ object CheckWidths extends Pass { def name = "Width Check" var mname = "" class UninferredWidth (info:Info) extends PassException(s"${info} : [module ${mname}] Uninferred width.") - class WidthTooSmall (info:Info,v:String) extends PassException(s"${info} : [module ${mname} Width too small for constant ${v}.") + class WidthTooSmall(info: Info, b: BigInt) extends PassException( + s"$info : [module $mname] Width too small for constant " + + Serialize().serialize(b) + ".") class NegWidthException(info:Info) extends PassException(s"${info}: [module ${mname}] Width cannot be negative or zero.") def run (c:Circuit): Circuit = { val errors = new Errors() @@ -666,7 +668,7 @@ object CheckWidths extends Pass { (e.width) match { case (w:IntWidth) => if (scala.math.max(1,e.value.bitLength) > w.width) { - errors.append(new WidthTooSmall(info, serialize(e.value))) + errors.append(new WidthTooSmall(info, e.value)) } case (w) => errors.append(new UninferredWidth(info)) } @@ -675,7 +677,7 @@ object CheckWidths extends Pass { case (e:SIntValue) => { (e.width) match { case (w:IntWidth) => - if (e.value.bitLength + 1 > w.width) errors.append(new WidthTooSmall(info, serialize(e.value))) + if (e.value.bitLength + 1 > w.width) errors.append(new WidthTooSmall(info, e.value)) case (w) => errors.append(new UninferredWidth(info)) } check_width_w(info)(e.width) |
