xref: /XiangShan/src/main/scala/xiangshan/transforms/PrintControl.scala (revision e3da8bad334fc71ba0d72f0607e2e93245ddaece)
15931ace3STang Haojin/***************************************************************************************
2*e3da8badSTang Haojin* Copyright (c) 2024 Beijing Institute of Open Source Chip (BOSC)
3*e3da8badSTang Haojin* Copyright (c) 2020-2024 Institute of Computing Technology, Chinese Academy of Sciences
45931ace3STang Haojin* Copyright (c) 2020-2021 Peng Cheng Laboratory
55931ace3STang Haojin*
65931ace3STang Haojin* XiangShan is licensed under Mulan PSL v2.
75931ace3STang Haojin* You can use this software according to the terms and conditions of the Mulan PSL v2.
85931ace3STang Haojin* You may obtain a copy of Mulan PSL v2 at:
95931ace3STang Haojin*          http://license.coscl.org.cn/MulanPSL2
105931ace3STang Haojin*
115931ace3STang Haojin* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
125931ace3STang Haojin* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
135931ace3STang Haojin* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
145931ace3STang Haojin*
155931ace3STang Haojin* See the Mulan PSL v2 for more details.
165931ace3STang Haojin***************************************************************************************/
175931ace3STang Haojin
185931ace3STang Haojinpackage xiangshan.transforms
195931ace3STang Haojin
20*e3da8badSTang Haojincase class DisablePrintfAnnotation(m: String) extends firrtl.annotations.NoTargetAnnotation
21*e3da8badSTang Haojinobject DisablePrintfAnnotation extends firrtl.options.HasShellOptions{
225931ace3STang Haojin
235931ace3STang Haojin  val options = Seq(
24*e3da8badSTang Haojin    new firrtl.options.ShellOption[String](
255931ace3STang Haojin      longOption = "disable-module-print",
265931ace3STang Haojin      toAnnotationSeq = s => Seq(DisablePrintfAnnotation(s)),
275931ace3STang Haojin      helpText =
285931ace3STang Haojin        "The verilog 'printf' in the <module> and it's submodules will be removed\n",
295931ace3STang Haojin      shortOption = Some("dm"),
305931ace3STang Haojin      helpValueName = Some("<module>")
315931ace3STang Haojin    )
325931ace3STang Haojin  )
335931ace3STang Haojin
345931ace3STang Haojin}
355931ace3STang Haojin
36*e3da8badSTang Haojincase class EnablePrintfAnnotation(m: String) extends firrtl.annotations.NoTargetAnnotation
37*e3da8badSTang Haojinobject EnablePrintfAnnotation extends firrtl.options.HasShellOptions {
385931ace3STang Haojin  val options = Seq(
39*e3da8badSTang Haojin    new firrtl.options.ShellOption[String](
405931ace3STang Haojin      longOption = "enable-module-print",
415931ace3STang Haojin      toAnnotationSeq = s => Seq(EnablePrintfAnnotation(s)),
425931ace3STang Haojin      helpText =
435931ace3STang Haojin        "The verilog 'printf' except the <module> and it's submodules will be removed\n",
445931ace3STang Haojin      shortOption = Some("em"),
455931ace3STang Haojin      helpValueName = Some("<module>")
465931ace3STang Haojin    )
475931ace3STang Haojin  )
485931ace3STang Haojin
495931ace3STang Haojin}
505931ace3STang Haojin
51*e3da8badSTang Haojincase class DisableAllPrintAnnotation() extends firrtl.annotations.NoTargetAnnotation
52*e3da8badSTang Haojinobject DisableAllPrintAnnotation extends firrtl.options.HasShellOptions {
535931ace3STang Haojin  val options = Seq(
54*e3da8badSTang Haojin    new firrtl.options.ShellOption[Unit](
555931ace3STang Haojin      longOption = "disable-all",
565931ace3STang Haojin      toAnnotationSeq = _ => Seq(DisableAllPrintAnnotation()),
575931ace3STang Haojin      helpText =
585931ace3STang Haojin        "All the verilog 'printf' will be removed\n",
595931ace3STang Haojin      shortOption = Some("dall")
605931ace3STang Haojin    )
615931ace3STang Haojin  )
625931ace3STang Haojin}
635931ace3STang Haojin
64*e3da8badSTang Haojincase class RemoveAssertAnnotation() extends firrtl.annotations.NoTargetAnnotation
65*e3da8badSTang Haojinobject RemoveAssertAnnotation extends firrtl.options.HasShellOptions{
665931ace3STang Haojin  val options = Seq(
67*e3da8badSTang Haojin    new firrtl.options.ShellOption[Unit](
685931ace3STang Haojin      longOption = "remove-assert",
695931ace3STang Haojin      toAnnotationSeq = _ => Seq(RemoveAssertAnnotation()),
705931ace3STang Haojin      helpText = "All the 'assert' will be removed\n",
715931ace3STang Haojin      shortOption = None
725931ace3STang Haojin    )
735931ace3STang Haojin  )
745931ace3STang Haojin}
75*e3da8badSTang Haojin
76*e3da8badSTang Haojinimport scala.collection.mutable
77*e3da8badSTang Haojin
78*e3da8badSTang Haojinclass PrintControl extends firrtl.options.Phase {
79*e3da8badSTang Haojin
80*e3da8badSTang Haojin  override def invalidates(a: firrtl.options.Phase) = false
81*e3da8badSTang Haojin
82*e3da8badSTang Haojin  override def transform(annotations: firrtl.AnnotationSeq): firrtl.AnnotationSeq = {
83*e3da8badSTang Haojin
84*e3da8badSTang Haojin    import xiangshan.transforms.Helpers._
85*e3da8badSTang Haojin
86*e3da8badSTang Haojin    val disableList = annotations.collect {
87*e3da8badSTang Haojin      case DisablePrintfAnnotation(m) => m
88*e3da8badSTang Haojin    }
89*e3da8badSTang Haojin    val enableList = annotations.collect {
90*e3da8badSTang Haojin      case EnablePrintfAnnotation(m) => m
91*e3da8badSTang Haojin    }
92*e3da8badSTang Haojin    val disableAll = annotations.collectFirst {
93*e3da8badSTang Haojin      case DisableAllPrintAnnotation() => true
94*e3da8badSTang Haojin    }.nonEmpty
95*e3da8badSTang Haojin    val removeAssert = annotations.collectFirst{
96*e3da8badSTang Haojin      case RemoveAssertAnnotation() => true
97*e3da8badSTang Haojin    }.nonEmpty
98*e3da8badSTang Haojin
99*e3da8badSTang Haojin    assert(!(enableList.nonEmpty && (disableAll || disableList.nonEmpty)))
100*e3da8badSTang Haojin
101*e3da8badSTang Haojin    val (Seq(circuitAnno: firrtl.stage.FirrtlCircuitAnnotation), otherAnnos) = annotations.partition {
102*e3da8badSTang Haojin      case _: firrtl.stage.FirrtlCircuitAnnotation => true
103*e3da8badSTang Haojin      case _ => false
104*e3da8badSTang Haojin    }
105*e3da8badSTang Haojin    val c = circuitAnno.circuit
106*e3da8badSTang Haojin
107*e3da8badSTang Haojin    val top = c.main
108*e3da8badSTang Haojin    val queue = new mutable.Queue[String]()
109*e3da8badSTang Haojin    val ancestors = new mutable.HashMap[String, mutable.LinkedHashSet[String]]()
110*e3da8badSTang Haojin
111*e3da8badSTang Haojin    queue += top
112*e3da8badSTang Haojin    ancestors(top) = mutable.LinkedHashSet.empty
113*e3da8badSTang Haojin
114*e3da8badSTang Haojin    while (queue.nonEmpty) {
115*e3da8badSTang Haojin      val curr = queue.dequeue()
116*e3da8badSTang Haojin      c.modules.find(m => m.name==curr).foreach(m => {
117*e3da8badSTang Haojin        def viewStmt(s: firrtl.ir.Statement): firrtl.ir.Statement = s match {
118*e3da8badSTang Haojin          case firrtl.ir.DefInstance(_, _, module, _) =>
119*e3da8badSTang Haojin            ancestors(module) = ancestors(curr).union(Set(m.name))
120*e3da8badSTang Haojin            queue += module
121*e3da8badSTang Haojin            s
122*e3da8badSTang Haojin          case other =>
123*e3da8badSTang Haojin            other.mapStmt(viewStmt)
124*e3da8badSTang Haojin        }
125*e3da8badSTang Haojin        m.foreachStmt(viewStmt)
126*e3da8badSTang Haojin      })
127*e3da8badSTang Haojin    }
128*e3da8badSTang Haojin
129*e3da8badSTang Haojin    def onModule(m: firrtl.ir.DefModule): firrtl.ir.DefModule = m match {
130*e3da8badSTang Haojin      case _: firrtl.ir.ExtModule => m
131*e3da8badSTang Haojin      case _: firrtl.ir.Module =>
132*e3da8badSTang Haojin        def inRange(seq: Seq[String]): Boolean = {
133*e3da8badSTang Haojin          seq.nonEmpty && (seq.contains(m.name) || seq.map(elm => {
134*e3da8badSTang Haojin            ancestors(m.name).contains(elm)
135*e3da8badSTang Haojin          }).reduce(_||_))
136*e3da8badSTang Haojin        }
137*e3da8badSTang Haojin        val enable = enableList.isEmpty || inRange(enableList)
138*e3da8badSTang Haojin        val disable = disableAll || inRange(disableList) || !enable
139*e3da8badSTang Haojin        def onStmt(s: firrtl.ir.Statement): firrtl.ir.Statement = s match {
140*e3da8badSTang Haojin          case _: firrtl.ir.Print if disable => firrtl.ir.EmptyStmt
141*e3da8badSTang Haojin          case _: firrtl.ir.Stop if removeAssert => firrtl.ir.EmptyStmt
142*e3da8badSTang Haojin          case _: firrtl.ir.Verification if removeAssert => firrtl.ir.EmptyStmt
143*e3da8badSTang Haojin          case other => other.mapStmt(onStmt)
144*e3da8badSTang Haojin        }
145*e3da8badSTang Haojin        m.mapStmt(onStmt)
146*e3da8badSTang Haojin    }
147*e3da8badSTang Haojin
148*e3da8badSTang Haojin    firrtl.stage.FirrtlCircuitAnnotation(c.mapModule(onModule)) +: otherAnnos
149*e3da8badSTang Haojin  }
150*e3da8badSTang Haojin}
151