Skip to content

Commit 199cfee

Browse files
authored
feat(query): support query for difftest-dpic data (#557)
1 parent b3dabd5 commit 199cfee

File tree

10 files changed

+320
-8
lines changed

10 files changed

+320
-8
lines changed

.github/workflows/main.yml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,13 @@ jobs:
165165
./build/emu -i $WORKLOAD --diff $REF_SO
166166
make clean
167167
168+
- name: Difftest with Squash Batch GlobalEnable and Query
169+
run: |
170+
cd $NOOP_HOME
171+
make emu MILL_ARGS="--difftest-config ESB" DIFFTEST_QUERY=1 -j2
172+
./build/emu -i $WORKLOAD --diff $REF_SO
173+
make clean
174+
168175
- name: Difftest with JsonProfile and DiffTestIOTrace
169176
run: |
170177
cd $NOOP_HOME
@@ -237,10 +244,10 @@ jobs:
237244
./build/simv +workload=$WORKLOAD +diff=$REF_SO
238245
make clean
239246
240-
- name: Verilator Build with VCS Top (with DutZone PerfCnt)
247+
- name: Verilator Build with VCS Top (with DutZone PerfCnt Query)
241248
run: |
242249
cd $NOOP_HOME
243-
make simv MILL_ARGS="--difftest-config ZP" DIFFTEST_PERFCNT=1 VCS=verilator -j2
250+
make simv MILL_ARGS="--difftest-config ZP" DIFFTEST_PERFCNT=1 DIFFTEST_QUERY=1 VCS=verilator -j2
244251
./build/simv +workload=$WORKLOAD +no-diff +max-cycles=100000
245252
./build/simv +workload=$WORKLOAD +diff=$REF_SO
246253
make clean
@@ -261,10 +268,10 @@ jobs:
261268
./build/simv +workload=$WORKLOAD +diff=$REF_SO
262269
make clean
263270
264-
- name: Verilator Build with VCS Top (with GlobalEnable Squash Replay Batch InternalStep NonBlock PerfCnt)
271+
- name: Verilator Build with VCS Top (with GlobalEnable Squash Replay Batch InternalStep NonBlock PerfCnt Query)
265272
run: |
266273
cd $NOOP_HOME
267-
make simv MILL_ARGS="--difftest-config ESRBINP" DIFFTEST_PERFCNT=1 VCS=verilator -j2
274+
make simv MILL_ARGS="--difftest-config ESRBINP" DIFFTEST_PERFCNT=1 DIFFTEST_QUERY=1 VCS=verilator -j2
268275
./build/simv +workload=$WORKLOAD +no-diff +max-cycles=100000
269276
./build/simv +workload=$WORKLOAD +diff=$REF_SO
270277
make clean

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ SIM_CXXFLAGS += -I$(DIFFTEST_CSRC_DIR)
9494
ifeq ($(DIFFTEST_PERFCNT), 1)
9595
SIM_CXXFLAGS += -DCONFIG_DIFFTEST_PERFCNT
9696
endif
97+
ifeq ($(DIFFTEST_QUERY), 1)
98+
SIM_CXXFLAGS += -DCONFIG_DIFFTEST_QUERY
99+
SIM_LDFLAGS += -lsqlite3
100+
endif
97101
endif
98102

99103
# ChiselDB

libso.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ CC_OBJ_DIR = $(abspath $(BUILD_DIR)/cc_obj)
44
LIB_CSRC_DIR = $(abspath ./src/test/csrc/vcs)
55
LIB_CXXFILES = $(SIM_CXXFILES) $(shell find $(LIB_CSRC_DIR) -name "*.cpp")
66
LIB_CXXFLAGS = -m64 -c -fPIC -g -std=c++11
7-
LIB_CXXFLAGS += $(subst \\\",\", $(SIM_CXXFLAGS)) -I$(LIB_CSRC_DIR) -DNUM_CORES=$(NUM_CORES)
7+
LIB_CXXFLAGS += $(subst \\\",\", $(SIM_CXXFLAGS)) $(SIM_LDFLAGS) -I$(LIB_CSRC_DIR) -DNUM_CORES=$(NUM_CORES)
88

99
ifeq ($(WITH_DRAMSIM3),1)
1010
LD_LIB = -L $(DRAMSIM3_HOME)/ -ldramsim3 -Wl,-rpath-link=$(DRAMSIM3_HOME)/libdramsim3.so

palladium.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ DPILIB_EMU = $(PLDM_BUILD_DIR)/libdpi_emu.so
8080
PLDM_CSRC_DIR = $(abspath ./src/test/csrc/vcs)
8181
PLDM_CXXFILES = $(SIM_CXXFILES) $(shell find $(PLDM_CSRC_DIR) -name "*.cpp")
8282
PLDM_CXXFLAGS = -m64 -c -fPIC -g -std=c++11 -I$(PLDM_IXCOM) -I$(PLDM_SIMTOOL)
83-
PLDM_CXXFLAGS += $(subst \\\",\", $(SIM_CXXFLAGS)) -I$(PLDM_CSRC_DIR) -DNUM_CORES=$(NUM_CORES)
83+
PLDM_CXXFLAGS += $(subst \\\",\", $(SIM_CXXFLAGS)) $(SIM_LDFLAGS) -I$(PLDM_CSRC_DIR) -DNUM_CORES=$(NUM_CORES)
8484

8585
ifeq ($(WITH_DRAMSIM3),1)
8686
PLDM_LD_LIB = -L $(DRAMSIM3_HOME)/ -ldramsim3 -Wl,-rpath-link=$(DRAMSIM3_HOME)/libdramsim3.so

src/main/scala/DPIC.scala

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import difftest._
2323
import difftest.batch.{BatchInfo, BatchIO}
2424
import difftest.common.FileControl
2525
import difftest.gateway.{GatewayConfig, GatewayResult, GatewaySinkControl}
26+
import difftest.util.Query
2627

2728
import scala.collection.mutable.ListBuffer
2829

@@ -180,7 +181,13 @@ class DPIC[T <: DifftestBundle](gen: T, config: GatewayConfig) extends DPICBase(
180181
val body = lhs.zip(rhs.flatten).map { case (l, r) => s"packet->$l = $r;" }
181182
val packetDecl = Seq(getPacketDecl(gen, "io_", config))
182183
val validAssign = if (!gen.bits.hasValid || gen.isFlatten) Seq() else Seq("packet->valid = true;")
183-
packetDecl ++ validAssign ++ body
184+
val query =
185+
Seq(s"""
186+
|#ifdef CONFIG_DIFFTEST_QUERY
187+
| ${Query.writeInvoke(gen)}
188+
|#endif // CONFIG_DIFFTEST_QUERY
189+
|""".stripMargin)
190+
packetDecl ++ validAssign ++ body ++ query
184191
}
185192

186193
setInline(s"$desiredName.v", moduleBody)
@@ -202,6 +209,12 @@ class DPICBatch(template: Seq[DifftestBundle], batchIO: BatchIO, config: Gateway
202209
unpack += getPacketDecl(gen, "", config)
203210
unpack += s"memcpy(packet, data, sizeof(${gen.desiredModuleName}));"
204211
unpack += s"data += ${elem_bytes.sum};"
212+
unpack +=
213+
s"""
214+
|#ifdef CONFIG_DIFFTEST_QUERY
215+
| ${Query.writeInvoke(gen)}
216+
|#endif // CONFIG_DIFFTEST_QUERY
217+
|""".stripMargin
205218
unpack.toSeq.mkString("\n ")
206219
}
207220

@@ -260,6 +273,9 @@ class DPICBatch(template: Seq[DifftestBundle], batchIO: BatchIO, config: Gateway
260273
| }
261274
| else if (id == BatchInterval) {
262275
| dut_index = (dut_index + 1) % CONFIG_DIFFTEST_BATCH_SIZE;
276+
|#ifdef CONFIG_DIFFTEST_QUERY
277+
| difftest_query_step();
278+
|#endif // CONFIG_DIFFTEST_QUERY
263279
| continue;
264280
| }
265281
| $bundleAssign
@@ -298,7 +314,9 @@ object DPIC {
298314
val interfaces = ListBuffer.empty[(String, String, String)]
299315

300316
def apply(control: GatewaySinkControl, io: Valid[DifftestBundle], config: GatewayConfig): Unit = {
301-
val module = Module(new DummyDPICWrapper(chiselTypeOf(io), config))
317+
val bundleType = chiselTypeOf(io)
318+
Query.register(bundleType.bits, "io_")
319+
val module = Module(new DummyDPICWrapper(bundleType, config))
302320
module.control := control
303321
module.io := io
304322
val dpic = module.dpic
@@ -309,6 +327,7 @@ object DPIC {
309327
}
310328

311329
def batch(template: Seq[DifftestBundle], control: GatewaySinkControl, io: BatchIO, config: GatewayConfig): Unit = {
330+
Query.register(template, "")
312331
val module = Module(new DummyDPICBatchWrapper(template, chiselTypeOf(io), config))
313332
module.control := control
314333
module.io := io
@@ -320,6 +339,7 @@ object DPIC {
320339
if (interfaces.isEmpty) {
321340
return GatewayResult()
322341
}
342+
Query.collect()
323343

324344
val interfaceCpp = ListBuffer.empty[String]
325345
interfaceCpp += "#ifndef __DIFFTEST_DPIC_H__"
@@ -384,6 +404,7 @@ object DPIC {
384404
interfaceCpp += ""
385405
interfaceCpp += "#include \"difftest.h\""
386406
interfaceCpp += "#include \"difftest-dpic.h\""
407+
interfaceCpp += "#include \"difftest-query.h\""
387408
interfaceCpp += ""
388409
interfaceCpp +=
389410
s"""

src/main/scala/Difftest.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,14 @@ object DifftestModule {
679679
|void diffstate_perfcnt_finish(long long msec);
680680
|#endif // CONFIG_DIFFTEST_PERFCNT
681681
|""".stripMargin
682+
difftestCpp +=
683+
s"""
684+
|#ifdef CONFIG_DIFFTEST_QUERY
685+
|void difftest_query_init();
686+
|void difftest_query_step();
687+
|void difftest_query_finish();
688+
|#endif // CONFIG_DIFFTEST_QUERY
689+
|""".stripMargin
682690
difftestCpp += "#endif // __DIFFSTATE_H__"
683691
difftestCpp += ""
684692
FileControl.write(difftestCpp, "diffstate.h")

src/main/scala/util/Query.scala

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/***************************************************************************************
2+
* Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC)
3+
* Copyright (c) 2025 Institute of Computing Technology, Chinese Academy of Sciences
4+
*
5+
* DiffTest is licensed under Mulan PSL v2.
6+
* You can use this software according to the terms and conditions of the Mulan PSL v2.
7+
* You may obtain a copy of Mulan PSL v2 at:
8+
* http://license.coscl.org.cn/MulanPSL2
9+
*
10+
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11+
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12+
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13+
*
14+
* See the Mulan PSL v2 for more details.
15+
***************************************************************************************/
16+
17+
package difftest.util
18+
19+
import difftest.DifftestBundle
20+
import difftest.common.FileControl
21+
22+
import scala.collection.mutable.ListBuffer
23+
24+
object Query {
25+
private val tables = ListBuffer.empty[QueryTable]
26+
def register(gen: DifftestBundle, locPrefix: String) = {
27+
tables += new QueryTable(gen, locPrefix)
28+
}
29+
def register(gens: Seq[DifftestBundle], locPrefix: String) = {
30+
gens.foreach { gen => tables += new QueryTable(gen, locPrefix) }
31+
}
32+
def writeInvoke(gen: DifftestBundle): String = {
33+
tables.find(_.gen == gen).get.writeInvoke
34+
}
35+
def collect() = {
36+
val queryCpp = ListBuffer.empty[String]
37+
queryCpp +=
38+
s"""
39+
|#ifndef __DIFFTEST_QUERY_H__
40+
|#define __DIFFTEST_QUERY_H__
41+
|
42+
|#include <cstdint>
43+
|#include "diffstate.h"
44+
|#include "query.h"
45+
|
46+
|#ifdef CONFIG_DIFFTEST_QUERY
47+
|
48+
|class QueryStats: public QueryStatsBase {
49+
|public:
50+
| ${tables.map { t => s"Query* ${t.instName};" }.mkString("\n ")}
51+
| QueryStats(char *path): QueryStatsBase(path) {
52+
| ${tables.map(_.initInvoke).mkString("\n ")}
53+
| }
54+
| ${tables.map(_.initDecl).mkString("")}
55+
| ${tables.map(_.writeDecl).mkString("")}
56+
|};
57+
|#endif // CONFIG_DIFFTEST_QUERY
58+
|#endif // __DIFFTEST_QUERY_H__
59+
|""".stripMargin
60+
FileControl.write(queryCpp, "difftest-query.h")
61+
}
62+
}
63+
64+
class QueryTable(val gen: DifftestBundle, locPrefix: String) {
65+
val tableName: String = gen.desiredModuleName.replace("Difftest", "")
66+
// Args: (key, value)
67+
private val stepArgs: Seq[(String, String)] = Seq(("STEP", "query_step"))
68+
private val locArgs: Seq[(String, String)] = {
69+
val argList = ListBuffer.empty[(String, String)]
70+
argList += (("COREID", "coreid"))
71+
// resolve conflict with sql key
72+
if (gen.isIndexed) argList += (("MY_INDEX", "index"))
73+
if (gen.isFlatten) argList += (("ADDRESS", "address"))
74+
argList.toSeq
75+
}
76+
private val dataArgs: Seq[(String, String)] = {
77+
val dataPrefix = "packet->"
78+
val argList = ListBuffer.empty[(String, String)]
79+
for ((name, _, elem) <- gen.dataElements) {
80+
val isRemoved = gen.isFlatten && Seq("valid", "address").contains(name)
81+
if (!isRemoved) {
82+
if (elem.length == 1) argList += ((name.toUpperCase, dataPrefix + name))
83+
else
84+
Seq.tabulate(elem.length) { idx =>
85+
argList += (((name + s"_$idx").toUpperCase, dataPrefix + name + s"[$idx]"))
86+
}
87+
}
88+
}
89+
argList.toSeq
90+
}
91+
private val sqlArgs: Seq[(String, String)] = stepArgs ++ locArgs ++ dataArgs
92+
93+
val instName: String = "query_" + tableName
94+
val initDecl =
95+
s"""
96+
| void ${tableName}_init() {
97+
| const char* createSql = \" CREATE TABLE $tableName(\" \\
98+
| "ID INTEGER PRIMARY KEY AUTOINCREMENT," \\
99+
| ${sqlArgs.map("\"" + _._1 + " INT NOT NULL").mkString("", ",\" \\\n ", ");\";")}
100+
| const char* insertSql = \"INSERT INTO $tableName (${sqlArgs.map(_._1).mkString(",")}) \" \\
101+
| \" VALUES (${Seq.fill(sqlArgs.length) { "?" }.mkString(",")});\";
102+
| $instName = new Query(mem_db, createSql, insertSql);
103+
| }
104+
|""".stripMargin
105+
val initInvoke = s"${tableName}_init();"
106+
val writeDecl =
107+
s"""
108+
| void ${tableName}_write(${locArgs.map("uint8_t " + _._2).mkString(", ")}, ${gen.desiredModuleName}* packet) {
109+
| query_${tableName}->write(${sqlArgs.length}, ${sqlArgs.map(_._2).mkString(", ")});
110+
| }
111+
|""".stripMargin
112+
val writeInvoke = s"qStats->${tableName}_write(${locArgs.map(locPrefix + _._2).mkString(", ")}, packet);"
113+
}

src/test/csrc/common/query.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/***************************************************************************************
2+
* Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC)
3+
* Copyright (c) 2025 Institute of Computing Technology, Chinese Academy of Sciences
4+
*
5+
* DiffTest is licensed under Mulan PSL v2.
6+
* You can use this software according to the terms and conditions of the Mulan PSL v2.
7+
* You may obtain a copy of Mulan PSL v2 at:
8+
* http://license.coscl.org.cn/MulanPSL2
9+
*
10+
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11+
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12+
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13+
*
14+
* See the Mulan PSL v2 for more details.
15+
***************************************************************************************/
16+
17+
#ifdef CONFIG_DIFFTEST_QUERY
18+
#include "query.h"
19+
#include "difftest-query.h"
20+
21+
QueryStats *qStats;
22+
23+
void difftest_query_init() {
24+
char query_path[128];
25+
snprintf(query_path, 128, "%s/build/%s", getenv("NOOP_HOME"), "difftest_query.db");
26+
// remove exist file
27+
FILE *fp = fopen(query_path, "r");
28+
if (fp) {
29+
fclose(fp);
30+
remove(query_path);
31+
}
32+
qStats = new QueryStats(query_path);
33+
}
34+
35+
void difftest_query_step() {
36+
qStats->step();
37+
}
38+
39+
void difftest_query_finish() {
40+
delete qStats;
41+
}
42+
43+
#endif // CONFIG_DIFFTEST_QUERY

0 commit comments

Comments
 (0)