1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
package firrtl.passes
import com.typesafe.scalalogging.LazyLogging
import firrtl._
import firrtl.ir._
import Annotations._
import java.io.Writer
import AnalysisUtils._
sealed trait PassOption
case object InputConfigFileName extends PassOption
case object OutputConfigFileName extends PassOption
case object PassCircuitName extends PassOption
object PassConfigUtil {
def getPassOptions(t: String, usage: String = "") = {
type PassOptionMap = Map[PassOption, String]
// can't use space to delimit sub arguments (otherwise, Driver.scala will throw error)
val passArgList = t.split(":").toList
def nextPassOption(map: PassOptionMap, list: List[String]): PassOptionMap = {
list match {
case Nil => map
case "-i" :: value :: tail =>
nextPassOption(map + (InputConfigFileName -> value), tail)
case "-o" :: value :: tail =>
nextPassOption(map + (OutputConfigFileName -> value), tail)
case "-c" :: value :: tail =>
nextPassOption(map + (PassCircuitName -> value), tail)
case option :: tail =>
throw new Exception("Unknown option " + option + usage)
}
}
nextPassOption(Map[PassOption, String](), passArgList)
}
}
class ConfWriter(filename: String) {
val outputBuffer = new java.io.CharArrayWriter
def append(m: DefMemory) = {
// legacy
val maskGran = getInfo(m.info,"maskGran")
val writers = m.writers map (x => if (maskGran == None) "write" else "mwrite")
val readers = List.fill(m.readers.length)("read")
val readwriters = m.readwriters map (x => if (maskGran == None) "rw" else "mrw")
val ports = (writers ++ readers ++ readwriters).mkString(",")
val maskGranConf = if (maskGran == None) "" else s"mask_gran ${maskGran.get}"
val width = bitWidth(m.dataType)
val conf = s"name ${m.name}_ext depth ${m.depth} width ${width} ports ${ports} ${maskGranConf} \n"
outputBuffer.append(conf)
}
def serialize = {
val outputFile = new java.io.PrintWriter(filename)
outputFile.write(outputBuffer.toString)
outputFile.close()
}
}
case class ReplSeqMemAnnotation(t: String, tID: TransID)
extends Annotation with Loose with Unstable {
val usage = """
[Optional] ReplSeqMem
Pass to replace sequential memories with blackboxes + configuration file
Usage:
--replSeqMem -c:<circuit>:-i<filename>:-o<filename>
*** Note: sub-arguments to --replSeqMem should be delimited by : and not white space!
Required Arguments:
-o<filename> Specify the output configuration file
-c<compiler> Specify the target circuit
Optional Arguments:
-i<filename> Specify the input configuration file (for additional optimizations)
"""
val passOptions = PassConfigUtil.getPassOptions(t,usage)
val outputConfig = passOptions.getOrElse(
OutputConfigFileName,
throw new Exception("No output config file provided for ReplSeqMem!" + usage)
)
val passCircuit = passOptions.getOrElse(
PassCircuitName,
throw new Exception("No circuit name specified for ReplSeqMem!" + usage)
)
val target = CircuitName(passCircuit)
def duplicate(n: Named) = this.copy(t=t.replace("-c:"+passCircuit,"-c:"+n.name))
}
class ReplSeqMem(transID: TransID) extends Transform with LazyLogging {
def execute(circuit:Circuit, map: AnnotationMap) =
map get transID match {
case Some(p) => p get CircuitName(circuit.main) match {
case Some(ReplSeqMemAnnotation(t, _)) => {
val outConfigFile = new ConfWriter(PassConfigUtil.getPassOptions(t).get(OutputConfigFileName).get)
TransformResult(
(
Seq(
Legalize,
AnnotateMemMacros,
UpdateDuplicateMemMacros,
new ReplaceMemMacros(outConfigFile),
RemoveEmpty,
CheckInitialization,
ResolveKinds, // Must be run for the transform to work!
InferTypes,
ResolveGenders
) foldLeft circuit
){
(c, pass) =>
val x = Utils.time(pass.name)(pass run c)
logger debug x.serialize
x
},
None,
Some(map)
)
}
case _ => TransformResult(circuit, None, Some(map))
}
case _ => TransformResult(circuit, None, Some(map))
}
}
|