Skip to content

Commit

Permalink
For verilog backend Chisel will trace all outputs and
Browse files Browse the repository at this point in the history
not just the ones that wired to the outside. As a result, there are more verilog warnings about unconnected nets but fewer
redundant modules. Also had to change how memory names are generated and uniquified. It is still possible to
write chisel code that generates redundant verilog modules if you use nondeterministic scala functions
  • Loading branch information
huytbvo committed Oct 16, 2012
1 parent b2151f9 commit c4a063a
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 19 deletions.
3 changes: 1 addition & 2 deletions src/main/scala/Bundle.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ object sort {
}
a
}

}

class Bundle(view_arg: Seq[String] = null) extends Data{
Expand Down Expand Up @@ -145,7 +144,7 @@ class Bundle(view_arg: Seq[String] = null) extends Data{
override def traceableNodes = elements.map(tup => tup._2).toArray;

override def traceNode(c: Component, stack: Stack[() => Any]) = {
for((n, i) <- elements) {
for((n, i) <- flatten) {
stack.push(() => i.traceNode(c, stack))
}
}
Expand Down
18 changes: 13 additions & 5 deletions src/main/scala/Component.scala
Original file line number Diff line number Diff line change
Expand Up @@ -412,14 +412,13 @@ abstract class Component(resetSignal: Bool = null) {
def initializeBFS: ScalaQueue[Node] = {
val res = new ScalaQueue[Node]

// initialize bfsQueue
for((n, elm) <- io.flatten)
if(elm.isInstanceOf[Bits] && elm.asInstanceOf[Bits].dir == OUTPUT)
res.enqueue(elm)
for(a <- asserts)
res.enqueue(a)
for(b <- blackboxes)
res.enqueue(b.io)
for(c <- components)
for((n, io) <- c.io.flatten)
res.enqueue(io)

for(r <- resetList)
res.enqueue(r)
Expand Down Expand Up @@ -501,6 +500,7 @@ abstract class Component(resetSignal: Bool = null) {

var count = 0
bfs {x =>
scala.Predef.assert(!x.isTypeNode)
x.fixName
count += 1
for (i <- 0 until x.inputs.length)
Expand Down Expand Up @@ -758,7 +758,15 @@ abstract class Component(resetSignal: Bool = null) {

def traceNodes() = {
val queue = Stack[() => Any]();
queue.push(() => io.traceNode(this, queue));

if (!backend.isInstanceOf[VerilogBackend]) {
queue.push(() => io.traceNode(this, queue));
} else {
for (c <- components) {
queue.push(() => c.reset.traceNode(c, queue))
queue.push(() => c.io.traceNode(c, queue))
}
}
for (a <- asserts)
queue.push(() => a.traceNode(this, queue));
for (b <- blackboxes)
Expand Down
5 changes: 3 additions & 2 deletions src/main/scala/Node.scala
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ abstract class Node extends nameable{
}

def traceNode(c: Component, stack: Stack[() => Any]): Any = {
if(this.isTypeNode) println("found")
if(this.isTypeNode) println("found " + this)
// determine whether or not the component needs a clock input
if ((isReg || isClkInput) && !(component == null))
component.containsReg = true
Expand Down Expand Up @@ -278,7 +278,8 @@ abstract class Node extends nameable{
//tmp fix, what happens if multiple componenets reference static nodes?
if (node.component == null || !components.contains(node.component))
node.component = nextComp;
stack.push(() => node.traceNode(nextComp, stack));
if (!backend.isInstanceOf[VerilogBackend] || !node.isIo)
stack.push(() => node.traceNode(nextComp, stack));
val j = i;
val n = node;
stack.push(() => {
Expand Down
9 changes: 3 additions & 6 deletions src/main/scala/Vec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -218,12 +218,9 @@ class Vec[T <: Data](val gen: () => T) extends Data with Cloneable with BufferPr
}

override def flatten: Array[(String, Bits)] = {
val res = new ArrayBuffer[(String, Bits)];
val res = new ArrayBuffer[(String, Bits)]
for (elm <- self)
elm match {
case bundle: Bundle => res ++= bundle.flatten;
case io: Bits => res += ((io.name, io));
}
res ++= elm.flatten
res.toArray
}

Expand Down Expand Up @@ -299,7 +296,7 @@ class Vec[T <: Data](val gen: () => T) extends Data with Cloneable with BufferPr
override def traceableNodes = self.toArray

override def traceNode(c: Component, stack: Stack[() => Any]) = {
for(i <- this) {
for((n, i) <- flatten) {
stack.push(() => i.traceNode(c, stack))
}
}
Expand Down
48 changes: 44 additions & 4 deletions src/main/scala/Verilog.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Reg._
import ChiselError._
import Component._
import scala.collection.mutable.HashSet
import scala.collection.mutable.HashMap

object VerilogBackend {

Expand All @@ -27,12 +28,16 @@ object VerilogBackend {
"tranif0", "tranif1", "tri", "tri0", "tri1", "triand", "trior", "trireg", "unsigned",
"vectored", "wait", "wand", "weak0", "weak1", "while", "wire", "wor", "xnor", "xor"
)

}

class VerilogBackend extends Backend {
isEmittingComponents = true
isCoercingArgs = false

val memConfigs = new HashSet[String]()
val memPaths = new HashMap[String, HashMap[String, Int]]()

def emitWidth(node: Node): String =
if (node.width == 1) "" else "[" + (node.width-1) + ":0]"

Expand Down Expand Up @@ -137,7 +142,36 @@ class VerilogBackend extends Backend {
}

override def emitDef(node: Node): String = {
def getPathName[T <: Data](m: Mem[T]) = m.component.getPathName + "_" + emitRef(m)
def getPathName[T <: Data](m: Mem[T], configStr: String): String = {
var c = m.component
var res = ""
while (c != null) {
res = c.name + "_" + res
c = c.parent
}
return uniquify(res + "_" + emitRef(m), configStr)
}

def uniquify(path: String, configStr: String): String = {
if (memPaths.contains(path)) {
val configs = memPaths(path)
if (configs.contains(configStr)) {
val count = configs(configStr)
if (count == 0) return path else return path + "_" + count
} else {
val count = configs.size
configs += (configStr -> count)
scala.Predef.assert(count != 0)
return path + "_" + count
}
} else {
val configs = new HashMap[String, Int]
configs += (configStr -> 0)
memPaths += (path -> configs)
return path
}
}

node match {
case x: Bits =>
if (x.dir == INPUT)
Expand Down Expand Up @@ -256,15 +290,21 @@ class VerilogBackend extends Backend {
val usedports = m.ports.filter(_.used)
val portdefs = usedports.zipWithIndex.map { case (p, i) => emitPortDef(p, i) }

Component.configStr +=
"name " + moduleNamePrefix+getPathName(m) +
var configStr =
" depth " + m.n +
" width " + m.width +
" ports " + usedports.map(_.getPortType).reduceLeft(_ + "," + _) +
"\n"

val fullConfigStr = "name " + moduleNamePrefix+getPathName(m, configStr) + configStr

if (!memConfigs.contains(fullConfigStr)) {
Component.configStr += fullConfigStr
memConfigs += fullConfigStr
}

val clkrst = Array(" .CLK(clk)", " .RST(reset)")
" " + moduleNamePrefix+getPathName(m) + " " + emitRef(m) + " (\n" +
" " + moduleNamePrefix+getPathName(m, configStr) + " " + emitRef(m) + " (\n" +
(clkrst ++ portdefs).reduceLeft(_ + ",\n" + _) + "\n" +
" );\n"

Expand Down

0 comments on commit c4a063a

Please sign in to comment.