From 9fbbb5b56808a9d1cd0c3fb47a3127bc795eabf2 Mon Sep 17 00:00:00 2001 From: klin02 Date: Wed, 1 Apr 2026 15:58:04 +0800 Subject: [PATCH] feat(query): add batch tables to query db Add BatchInfo and BatchStep tables to persist batch entry records and per-step bundle count summaries in the query database. Also add the BundleNames table to provide a readable mapping from bundle ids to bundle names. --- src/main/scala/DPIC.scala | 15 +++++++- src/main/scala/util/Query.scala | 66 ++++++++++++++++++++++++++++++++- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/src/main/scala/DPIC.scala b/src/main/scala/DPIC.scala index 1c1ad0d4c..68c070205 100644 --- a/src/main/scala/DPIC.scala +++ b/src/main/scala/DPIC.scala @@ -311,16 +311,29 @@ class DPICBatch(template: Seq[DifftestBundle], batchIO: BatchIO, config: Gateway | ${bundleEnum.mkString(",\n ")} | }; | static int dut_index = 0; + |#ifdef CONFIG_DIFFTEST_QUERY + | static int batch_query_nums[${bundleEnum.length}] = {0}; + |#endif // CONFIG_DIFFTEST_QUERY | $batchDecl | for (int i = 0; i < $infoLen; i++) { | if (!diffstate_buffer) return; | uint8_t id = info[i].id; | uint8_t num = info[i].num; | uint32_t coreid, index, address; + |#ifdef CONFIG_DIFFTEST_QUERY + | if (qStats) { + | qStats->BatchInfo_write(id, num); + | batch_query_nums[id] = num; + | } + |#endif // CONFIG_DIFFTEST_QUERY | if (id == BatchFinish) { | break; | } | else if (id == BatchStep) { + |#ifdef CONFIG_DIFFTEST_QUERY + | if (qStats) qStats->BatchStep_write(batch_query_nums); + | memset(batch_query_nums, 0, sizeof(batch_query_nums)); + |#endif // CONFIG_DIFFTEST_QUERY | $stepPending | dut_index = (dut_index + 1) % CONFIG_DIFFTEST_BATCH_SIZE; |#ifdef CONFIG_DIFFTEST_INTERNAL_STEP @@ -391,7 +404,7 @@ object DPIC { } def batch(template: Seq[DifftestBundle], control: GatewaySinkControl, io: BatchIO, config: GatewayConfig): Unit = { - Query.register(template, "", "0") + Query.registerBatch(template, "", "0") val module = Module(new DummyDPICBatchWrapper(template, chiselTypeOf(io), config)) module.control := control module.io := io diff --git a/src/main/scala/util/Query.scala b/src/main/scala/util/Query.scala index 5f0ff8b7f..e6c310dbc 100644 --- a/src/main/scala/util/Query.scala +++ b/src/main/scala/util/Query.scala @@ -23,11 +23,13 @@ import scala.collection.mutable.ListBuffer object Query { private val tables = ListBuffer.empty[QueryTable] + private var batchTable: Option[BatchQueryTable] = None def register(gen: DifftestBundle, locPrefix: String, dutZone: String) = { tables += new QueryTable(gen, locPrefix, dutZone) } - def register(gens: Seq[DifftestBundle], locPrefix: String, dutZone: String) = { + def registerBatch(gens: Seq[DifftestBundle], locPrefix: String, dutZone: String) = { gens.foreach { gen => tables += new QueryTable(gen, locPrefix, dutZone) } + batchTable = Some(new BatchQueryTable(gens)) } def writeInvoke(gen: DifftestBundle): String = { tables.find(_.gen == gen).get.writeInvoke @@ -51,11 +53,15 @@ object Query { |class QueryStats: public QueryStatsBase { |public: | ${tables.map { t => s"Query* ${t.instName};" }.mkString("\n ")} + | ${batchTable.map(_.members).getOrElse("")} | QueryStats(char *path): QueryStatsBase(path) { | ${tables.map(_.initInvoke).mkString("\n ")} + | ${batchTable.map(_.initInvoke).getOrElse("")} | } | ${tables.map(_.initDecl).mkString("")} | ${tables.map(_.writeDecl).mkString("")} + | ${batchTable.map(_.initDecl).getOrElse("")} + | ${batchTable.map(_.writeDecl).getOrElse("")} |}; |#endif // CONFIG_DIFFTEST_QUERY |#endif // __DIFFTEST_QUERY_H__ @@ -121,3 +127,61 @@ class QueryTable(val gen: DifftestBundle, locPrefix: String, dutZone: String) { } val writeInvoke = s"qStats->${tableName}_write($dutZone, ${locArgs.map(locPrefix + _._2).mkString(", ")}, packet);" } + +class BatchQueryTable(template: Seq[DifftestBundle]) { + private val bundleNames: Seq[String] = + template.map(_.desiredModuleName.replace("Difftest", "")) ++ Seq("BatchStep", "BatchFinish") + + val members: String = + s"""Query* query_BatchInfo; + | Query* query_BatchStep;""".stripMargin + + val initInvoke: String = "BatchTable_init();" + + val initDecl: String = { + val bundleNameInserts = bundleNames.zipWithIndex.map { case (name, id) => + s"INSERT INTO BundleNames VALUES($id, '$name');" + }.mkString("") + + s""" + | void BatchTable_init() { + | const char* createBatchInfoSql = "CREATE TABLE BatchInfo(" + | "ID INTEGER PRIMARY KEY AUTOINCREMENT," + | "STEP INTEGER NOT NULL," + | "BUNDLE_ID INTEGER NOT NULL," + | "NUM INTEGER NOT NULL);"; + | const char* insertBatchInfoSql = "INSERT INTO BatchInfo (STEP,BUNDLE_ID,NUM)" + | " VALUES (?,?,?);"; + | query_BatchInfo = new Query(mem_db, createBatchInfoSql, insertBatchInfoSql); + | + | const char* createBundleNamesSql = "CREATE TABLE BundleNames(" + | "BUNDLE_ID INTEGER PRIMARY KEY," + | "NAME TEXT NOT NULL);"; + | char* errMsg; + | sqlite3_exec(mem_db, createBundleNamesSql, 0, 0, &errMsg); + | sqlite3_exec(mem_db, "$bundleNameInserts", 0, 0, &errMsg); + | + | const char* createBatchStepSql = "CREATE TABLE BatchStep(" + | "ID INTEGER PRIMARY KEY AUTOINCREMENT," + | "STEP INTEGER NOT NULL," + | "${bundleNames.map(n => s"$n INTEGER NOT NULL").mkString(",")});"; + | const char* insertBatchStepSql = "INSERT INTO BatchStep (STEP,${bundleNames.mkString(",")}) " + | "VALUES (${Seq.fill(bundleNames.length + 1)("?").mkString(",")});"; + | query_BatchStep = new Query(mem_db, createBatchStepSql, insertBatchStepSql); + | } + |""".stripMargin + } + + val writeDecl: String = { + val numArgs = bundleNames.indices.map(i => s"nums[$i]").mkString(", ") + val writeArgCount = bundleNames.length + 1 // STEP + bundleNames + s""" + | void BatchInfo_write(int bundle_id, int num) { + | query_BatchInfo->write(3, (int)query_step, bundle_id, num); + | } + | void BatchStep_write(int* nums) { + | query_BatchStep->write($writeArgCount, (int)query_step, $numArgs); + | } + |""".stripMargin + } +}