LogUtils.scala 4.2 KB
Newer Older
L
LinJiawei 已提交
1
package utils
L
LinJiawei 已提交
2 3

import chisel3._
L
LinJiawei 已提交
4
import top.Parameters
L
LinJiawei 已提交
5
import xiangshan.HasXSParameter
L
LinJiawei 已提交
6
import utils.XSLogLevel.XSLogLevel
L
LinJiawei 已提交
7 8 9 10

object XSLogLevel extends Enumeration {
  type XSLogLevel = Value

11
  val ALL   = Value(0, "ALL  ")
L
LinJiawei 已提交
12
  val DEBUG = Value("DEBUG")
Y
Yinan Xu 已提交
13
  val INFO  = Value("INFO ")
Y
Yinan Xu 已提交
14
  val PERF  = Value("PERF ")
Y
Yinan Xu 已提交
15
  val WARN  = Value("WARN ")
L
LinJiawei 已提交
16
  val ERROR = Value("ERROR")
Y
Yinan Xu 已提交
17
  val OFF   = Value("OFF  ")
L
LinJiawei 已提交
18 19
}

20
object XSLog {
21
  val MagicStr = "9527"
L
LinJiawei 已提交
22
  def apply(debugLevel: XSLogLevel)
Y
Yinan Xu 已提交
23
           (prefix: Boolean, cond: Bool, pable: Printable)
24 25
           (implicit name: String): Any =
  {
26
    val logEnable = WireInit(false.B)
L
LinJiawei 已提交
27
    val logTimestamp = WireInit(0.U(64.W))
Y
Yinan Xu 已提交
28 29 30
    val enableDebug = Parameters.get.envParameters.EnableDebug && debugLevel != XSLogLevel.PERF
    val enablePerf = Parameters.get.envParameters.EnablePerfDebug && debugLevel == XSLogLevel.PERF
    if (enableDebug || enablePerf) {
31 32
      ExcitingUtils.addSink(logEnable, "DISPLAY_LOG_ENABLE")
      ExcitingUtils.addSink(logTimestamp, "logTimestamp")
J
jinyue110 已提交
33
      when (cond && logEnable) {
34
        val commonInfo = p"[$debugLevel][time=$logTimestamp] $MagicStr: "
35
        printf((if (prefix) commonInfo else p"") + pable)
36 37 38
        if (debugLevel >= XSLogLevel.ERROR) {
          assert(false.B)
        }
39
      }
L
LinJiawei 已提交
40 41
    }
  }
42 43 44 45 46

  def displayLog: Bool = {
    val logEnable = WireInit(false.B)
    val ret = WireInit(false.B)
    if(Parameters.get.envParameters.EnableDebug) {
47
      ExcitingUtils.addSink(logEnable, "DISPLAY_LOG_ENABLE")
48
      ret := logEnable
L
LinJiawei 已提交
49
    }
50
    ret
L
LinJiawei 已提交
51 52 53
  }
}

W
William Wang 已提交
54
sealed abstract class LogHelper(val logLevel: XSLogLevel) extends HasXSParameter {
L
LinJiawei 已提交
55

56
  def apply(cond: Bool, fmt: String, data: Bits*)(implicit name: String): Any =
L
LinJiawei 已提交
57
    apply(cond, Printable.pack(fmt, data:_*))
Y
Yinan Xu 已提交
58
  def apply(cond: Bool, pable: Printable)(implicit name: String): Any = apply(true, cond, pable)
59
  def apply(fmt: String, data: Bits*)(implicit name: String): Any =
Y
Yinan Xu 已提交
60 61 62 63 64 65
    apply(Printable.pack(fmt, data:_*))
  def apply(pable: Printable)(implicit name: String): Any = apply(true.B, pable)
  def apply(prefix: Boolean, cond: Bool, fmt: String, data: Bits*)(implicit name: String): Any =
    apply(prefix, cond, Printable.pack(fmt, data:_*))
  def apply(prefix: Boolean, cond: Bool, pable: Printable)(implicit name: String): Any =
    XSLog(logLevel)(prefix, cond, pable)
A
Allen 已提交
66 67 68 69

  // trigger log or not
  // used when user what to fine-control their printf output
  def trigger: Bool = {
70
    XSLog.displayLog
A
Allen 已提交
71
  }
A
Allen 已提交
72 73

  def printPrefix()(implicit name: String): Unit = {
74
    val commonInfo = p"[$logLevel][time=${GTimer()}] ${XSLog.MagicStr}: "
A
Allen 已提交
75 76 77 78
    when (trigger) {
      printf(commonInfo)
    }
  }
79 80

  // dump under with certain prefix
81
  def exec(dump: () => Unit)(implicit name: String): Unit = {
82 83 84 85 86 87 88
    when (trigger) {
      printPrefix
      dump
    }
  }

  // dump under certain condition and with certain prefix
89
  def exec(cond: Bool, dump: () => Unit)(implicit name: String): Unit = {
90 91 92 93 94
    when (trigger && cond) {
      printPrefix
      dump
    }
  }
L
LinJiawei 已提交
95 96 97 98 99 100 101 102 103
}

object XSDebug extends LogHelper(XSLogLevel.DEBUG)

object XSInfo extends LogHelper(XSLogLevel.INFO)

object XSWarn extends LogHelper(XSLogLevel.WARN)

object XSError extends LogHelper(XSLogLevel.ERROR)
Y
Yinan Xu 已提交
104 105 106

object XSPerf {
  def apply(perfName: String, perfCnt: UInt)(implicit name: String) = {
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
    val reset = true
    val print_per_cycle = false
    val print_gap_bits = 15

    val counter = RegInit(0.U(64.W))
    val next_counter = WireInit(0.U(64.W))
    val logTimestamp = WireInit(0.U(64.W))
    val enableDebug = Parameters.get.envParameters.EnableDebug
    val logEnable = WireInit(false.B)

    if (enableDebug) {
      ExcitingUtils.addSink(logEnable, "DISPLAY_LOG_ENABLE")

      if(!print_per_cycle) {
        ExcitingUtils.addSink(logTimestamp, "logTimestamp")

        next_counter := counter + perfCnt

        when(logEnable && logTimestamp(print_gap_bits-1, 0) === 0.U) { // TODO: Need print when program exit?
          if(reset) {
            next_counter := perfCnt
            XSLog(XSLogLevel.PERF)(true, true.B, p"$perfName, $counter\n")
          }else{
            XSLog(XSLogLevel.PERF)(true, true.B, p"$perfName, $next_counter\n")
          }
        }

        counter := next_counter
      }else{
        when(logEnable) {
          XSLog(XSLogLevel.PERF)(true, true.B, p"$perfName, $perfCnt\n")
        }
      }
    }
Y
Yinan Xu 已提交
141 142
  }
}