aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/scala/firrtl/Emitter.scala25
-rw-r--r--src/main/scala/firrtl/Serialize.scala30
-rw-r--r--src/main/scala/firrtl/passes/Checks.scala8
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)