From 1d0ee72fbbe38eb63a158c22999d3088c4d110ba Mon Sep 17 00:00:00 2001 From: LinJiawei Date: Thu, 25 Jun 2020 21:58:27 +0800 Subject: [PATCH] Log System: Support user to specify log level in EMU --- Makefile | 5 +++- src/main/scala/xiangshan/XSCore.scala | 1 - src/main/scala/xiangshan/utils/LogUtils.scala | 23 +++++++++++-------- src/test/csrc/common.h | 12 ++++++++++ src/test/csrc/emu.h | 7 +++--- src/test/csrc/log.cpp | 22 ++++++++++++++++++ src/test/csrc/main.cpp | 9 +++++--- src/test/scala/top/XSSim.scala | 7 ++++-- 8 files changed, 67 insertions(+), 19 deletions(-) create mode 100644 src/test/csrc/log.cpp diff --git a/Makefile b/Makefile index a93dbc268..2a5d8367e 100644 --- a/Makefile +++ b/Makefile @@ -86,11 +86,14 @@ $(EMU): $(EMU_MK) $(EMU_DEPS) $(EMU_HEADERS) $(REF_SO) SEED = -s $(shell seq 1 10000 | shuf | head -n 1) +# log will only be printed when (B<=GTimer<=E) && (L < loglevel) +# use 'emu -h' to see more details B ?= 0 E ?= -1 +L ?= ALL emu: $(EMU) - @$(EMU) -i $(IMAGE) $(SEED) -b $(B) -e $(E) + @$(EMU) -i $(IMAGE) $(SEED) -b $(B) -e $(E) -l $(L) cache: $(MAKE) emu IMAGE=Makefile diff --git a/src/main/scala/xiangshan/XSCore.scala b/src/main/scala/xiangshan/XSCore.scala index 7237db7b9..a538fa4f9 100644 --- a/src/main/scala/xiangshan/XSCore.scala +++ b/src/main/scala/xiangshan/XSCore.scala @@ -11,7 +11,6 @@ import xiangshan.frontend.Frontend import xiangshan.utils._ trait HasXSParameter { - val LogLevel = XSLogLevel.ALL val XLEN = 64 val HasMExtension = true val HasCExtension = true diff --git a/src/main/scala/xiangshan/utils/LogUtils.scala b/src/main/scala/xiangshan/utils/LogUtils.scala index e6eab4f00..d6d0e9e62 100644 --- a/src/main/scala/xiangshan/utils/LogUtils.scala +++ b/src/main/scala/xiangshan/utils/LogUtils.scala @@ -8,7 +8,7 @@ import xiangshan.utils.XSLogLevel.XSLogLevel object XSLogLevel extends Enumeration { type XSLogLevel = Value - val ALL = Value("ALL ") + val ALL = Value(0, "ALL ") val DEBUG = Value("DEBUG") val INFO = Value("INFO ") val WARN = Value("WARN ") @@ -16,9 +16,9 @@ object XSLogLevel extends Enumeration { val OFF = Value("OFF ") } -object XSLog extends HasXSParameter { +object XSLog { - def displayLog(): Bool = { + def displayLog: Bool = { val disp_begin, disp_end = WireInit(0.U(64.W)) BoringUtils.addSink(disp_begin, "DISPALY_LOG_START") BoringUtils.addSink(disp_end, "DISPLAY_LOG_END") @@ -26,14 +26,19 @@ object XSLog extends HasXSParameter { (GTimer() >= disp_begin) && (GTimer() <= disp_end) } + def xsLogLevel: UInt = { + val log_level = WireInit(0.U(64.W)) + BoringUtils.addSink(log_level, "DISPLAY_LOG_LEVEL") + assert(log_level < XSLogLevel.maxId.U) + log_level + } + def apply(debugLevel: XSLogLevel) (cond: Bool, pable: Printable) (implicit m: Module): Any = { - if (debugLevel >= LogLevel) { - when (cond && displayLog()) { - val commonInfo = p"[$debugLevel][time=${GTimer()}] ${m.name}: " - printf(commonInfo + pable) - } + val commonInfo = p"[$debugLevel][time=${GTimer()}] ${m.name}: " + when (debugLevel.id.U >= xsLogLevel && cond && displayLog) { + printf(commonInfo + pable) } } } @@ -49,7 +54,7 @@ sealed abstract class LogHelper(val logLevel: XSLogLevel) extends HasXSParameter // Do not use that unless you have valid reasons def apply(cond: Bool = true.B)(body: => Unit): Any = - if (logLevel >= LogLevel) { when (cond && XSLog.displayLog()) { body } } + when (logLevel.id.U >= XSLog.xsLogLevel && cond && XSLog.displayLog) { body } } object XSDebug extends LogHelper(XSLogLevel.DEBUG) diff --git a/src/test/csrc/common.h b/src/test/csrc/common.h index dc744a8d6..8c4479841 100644 --- a/src/test/csrc/common.h +++ b/src/test/csrc/common.h @@ -42,6 +42,18 @@ void init_device(void); bool is_finished(void); int get_exit_code(void); +// log +enum { + LOG_ALL = 0, + LOG_DEBUG, + LOG_INFO, + LOG_WARN, + LOG_ERROR, + LOG_OFF +}; + +uint64_t getLogLevel(const char * str); + void app_error(const char *fmt, ...); int monitor(void); diff --git a/src/test/csrc/emu.h b/src/test/csrc/emu.h index a08798bb1..8b1ba0179 100644 --- a/src/test/csrc/emu.h +++ b/src/test/csrc/emu.h @@ -25,7 +25,7 @@ class Emulator { // emu control variable uint32_t seed; uint64_t max_cycles, cycles; - uint64_t log_begin, log_end; + uint64_t log_begin, log_end, log_level; std::vector parse_args(int argc, const char *argv[]); @@ -57,7 +57,7 @@ class Emulator { image(nullptr), dut_ptr(new std::remove_reference::type), seed(0), max_cycles(-1), cycles(0), - log_begin(0), log_end(-1) + log_begin(0), log_end(-1), log_level(LOG_ALL) { // init emu auto args = parse_args(argc, argv); @@ -67,9 +67,10 @@ class Emulator { srand48(seed); Verilated::randReset(2); - // set log time range + // set log time range and log level dut_ptr->io_logCtrl_log_begin = log_begin; dut_ptr->io_logCtrl_log_end = log_end; + dut_ptr->io_logCtrl_log_level = log_level; // init ram extern void init_ram(const char *img); diff --git a/src/test/csrc/log.cpp b/src/test/csrc/log.cpp new file mode 100644 index 000000000..2db2609aa --- /dev/null +++ b/src/test/csrc/log.cpp @@ -0,0 +1,22 @@ +#include +#include +#include "common.h" + +uint64_t getLogLevel(const char * str) { + if(!strcmp("ALL", str)){ + return LOG_ALL; + } else if(!strcmp("DEBUG", str)){ + return LOG_DEBUG; + } else if(!strcmp("INFO", str)){ + return LOG_INFO; + } else if(!strcmp("WARN", str)){ + return LOG_WARN; + } else if(!strcmp("ERROR", str)){ + return LOG_ERROR; + } else if(!strcmp("OFF", str)){ + return LOG_OFF; + } else { + printf("Unknow log level!\n"); + exit(-1); + } +} \ No newline at end of file diff --git a/src/test/csrc/main.cpp b/src/test/csrc/main.cpp index 189a073df..ec99cac82 100644 --- a/src/test/csrc/main.cpp +++ b/src/test/csrc/main.cpp @@ -20,8 +20,9 @@ const struct option Emulator::long_options[] = { { "seed", 1, NULL, 's' }, { "max-cycles", 1, NULL, 'C' }, { "image", 1, NULL, 'i' }, - { "log-begin", 1, NULL, 'b'}, - { "log-end", 1, NULL, 'e'}, + { "log-begin", 1, NULL, 'b' }, + { "log-end", 1, NULL, 'e' }, + { "log-level", 1, NULL, 'l' }, { "help", 0, NULL, 'h' }, { 0, 0, NULL, 0 } }; @@ -34,6 +35,7 @@ void Emulator::print_help(const char *file) { printf(" -i, --image=FILE run with this image file\n"); printf(" -b, --log-begin=NUM display log from NUM th cycle\n"); printf(" -e, --log-end=NUM stop display log at NUM th cycle\n"); + printf(" -l, --log-level=STR log level, can be one of [ALL, DEBUG, INFO, WARN, ERROR]\n"); printf(" -h, --help print program help info\n"); printf("\n"); } @@ -41,7 +43,7 @@ void Emulator::print_help(const char *file) { std::vector Emulator::parse_args(int argc, const char *argv[]) { std::vector args = { argv[0] }; int o; - while ( (o = getopt_long(argc, const_cast(argv), "-s:C:hi:m:b:e:", long_options, NULL)) != -1) { + while ( (o = getopt_long(argc, const_cast(argv), "-s:C:hi:m:b:e:l:", long_options, NULL)) != -1) { switch (o) { case 's': if(std::string(optarg) != "NO_SEED") { @@ -56,6 +58,7 @@ std::vector Emulator::parse_args(int argc, const char *argv[]) { break; case 'b': log_begin = atoll(optarg); break; case 'e': log_end = atoll(optarg); break; + case 'l': log_level = getLogLevel(optarg); break; default: print_help(argv[0]); exit(0); diff --git a/src/test/scala/top/XSSim.scala b/src/test/scala/top/XSSim.scala index 278808b1c..96da57662 100644 --- a/src/test/scala/top/XSSim.scala +++ b/src/test/scala/top/XSSim.scala @@ -28,7 +28,8 @@ class DiffTestIO extends Bundle { } class LogCtrlIO extends Bundle { - val log_begin, log_end = Input(UInt(32.W)) + val log_begin, log_end = Input(UInt(64.W)) + val log_level = Input(UInt(64.W)) // a cpp uint } class XSSimTop extends Module { @@ -72,12 +73,14 @@ class XSSimTop extends Module { BoringUtils.addSink(difftest.scause, "difftestScause") io.difftest := difftest - val log_begin, log_end = Wire(UInt(32.W)) + val log_begin, log_end, log_level = Wire(UInt(64.W)) log_begin := io.logCtrl.log_begin log_end := io.logCtrl.log_end + log_level := io.logCtrl.log_level BoringUtils.addSource(log_begin, "DISPALY_LOG_START") BoringUtils.addSource(log_end, "DISPLAY_LOG_END") + BoringUtils.addSource(log_level, "DISPLAY_LOG_LEVEL") } object TestMain extends App { -- GitLab