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
|
// See LICENSE for license details.
package firrtl.passes
import firrtl._
import firrtl.ir._
import Annotations._
import AnalysisUtils._
import Utils.error
import java.io.{File, CharArrayWriter, PrintWriter}
sealed trait PassOption
case object InputConfigFileName extends PassOption
case object OutputConfigFileName extends PassOption
case object PassCircuitName extends PassOption
object PassConfigUtil {
type PassOptionMap = Map[PassOption, String]
def getPassOptions(t: String, usage: 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 =>
error("Unknown option " + option + usage)
}
}
nextPassOption(Map[PassOption, String](), passArgList)
}
}
class ConfWriter(filename: String) {
val outputBuffer = new CharArrayWriter
def append(m: DefMemory) = {
// legacy
val maskGran = getInfo(m.info, "maskGran")
val readers = List.fill(m.readers.length)("read")
val writers = List.fill(m.writers.length)(if (maskGran.isEmpty) "write" else "mwrite")
val readwriters = List.fill(m.readwriters.length)(if (maskGran.isEmpty) "rw" else "mrw")
val ports = (writers ++ readers ++ readwriters) mkString ","
val maskGranConf = maskGran match { case None => "" case Some(p) => s"mask_gran $p" }
val width = bitWidth(m.dataType)
val conf = s"name ${m.name} depth ${m.depth} width $width ports $ports $maskGranConf \n"
outputBuffer.append(conf)
}
def serialize() = {
val outputFile = new 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,
error("No output config file provided for ReplSeqMem!" + usage)
)
val passCircuit = passOptions.getOrElse(
PassCircuitName,
error("No circuit name specified for ReplSeqMem!" + usage)
)
val target = CircuitName(passCircuit)
def duplicate(n: Named) = this copy (t = t.replace(s"-c:$passCircuit", s"-c:${n.name}"))
}
class ReplSeqMem(transID: TransID) extends Transform with SimpleRun {
def passSeq(inConfigFile: Option[YamlFileReader], outConfigFile: ConfWriter) =
Seq(Legalize,
AnnotateMemMacros,
UpdateDuplicateMemMacros,
new AnnotateValidMemConfigs(inConfigFile),
new ReplaceMemMacros(outConfigFile),
RemoveEmpty,
CheckInitialization,
InferTypes,
ResolveKinds, // Must be run for the transform to work!
ResolveGenders)
def execute(c: Circuit, map: AnnotationMap) = map get transID match {
case Some(p) => p get CircuitName(c.main) match {
case Some(ReplSeqMemAnnotation(t, _)) =>
val inputFileName = PassConfigUtil.getPassOptions(t).getOrElse(InputConfigFileName, "")
val inConfigFile = {
if (inputFileName.isEmpty) None
else if (new File(inputFileName).exists) Some(new YamlFileReader(inputFileName))
else error("Input configuration file does not exist!")
}
val outConfigFile = new ConfWriter(PassConfigUtil.getPassOptions(t)(OutputConfigFileName))
run(c, passSeq(inConfigFile, outConfigFile))
case _ => error("Unexpected transform annotation")
}
case _ => TransformResult(c)
}
}
|