Skip to content

Commit

Permalink
feat(query): support query for difftest-dpic data (#557)
Browse files Browse the repository at this point in the history
  • Loading branch information
klin02 authored Feb 5, 2025
1 parent b3dabd5 commit 199cfee
Show file tree
Hide file tree
Showing 10 changed files with 320 additions and 8 deletions.
15 changes: 11 additions & 4 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,13 @@ jobs:
./build/emu -i $WORKLOAD --diff $REF_SO
make clean
- name: Difftest with Squash Batch GlobalEnable and Query
run: |
cd $NOOP_HOME
make emu MILL_ARGS="--difftest-config ESB" DIFFTEST_QUERY=1 -j2
./build/emu -i $WORKLOAD --diff $REF_SO
make clean
- name: Difftest with JsonProfile and DiffTestIOTrace
run: |
cd $NOOP_HOME
Expand Down Expand Up @@ -237,10 +244,10 @@ jobs:
./build/simv +workload=$WORKLOAD +diff=$REF_SO
make clean
- name: Verilator Build with VCS Top (with DutZone PerfCnt)
- name: Verilator Build with VCS Top (with DutZone PerfCnt Query)
run: |
cd $NOOP_HOME
make simv MILL_ARGS="--difftest-config ZP" DIFFTEST_PERFCNT=1 VCS=verilator -j2
make simv MILL_ARGS="--difftest-config ZP" DIFFTEST_PERFCNT=1 DIFFTEST_QUERY=1 VCS=verilator -j2
./build/simv +workload=$WORKLOAD +no-diff +max-cycles=100000
./build/simv +workload=$WORKLOAD +diff=$REF_SO
make clean
Expand All @@ -261,10 +268,10 @@ jobs:
./build/simv +workload=$WORKLOAD +diff=$REF_SO
make clean
- name: Verilator Build with VCS Top (with GlobalEnable Squash Replay Batch InternalStep NonBlock PerfCnt)
- name: Verilator Build with VCS Top (with GlobalEnable Squash Replay Batch InternalStep NonBlock PerfCnt Query)
run: |
cd $NOOP_HOME
make simv MILL_ARGS="--difftest-config ESRBINP" DIFFTEST_PERFCNT=1 VCS=verilator -j2
make simv MILL_ARGS="--difftest-config ESRBINP" DIFFTEST_PERFCNT=1 DIFFTEST_QUERY=1 VCS=verilator -j2
./build/simv +workload=$WORKLOAD +no-diff +max-cycles=100000
./build/simv +workload=$WORKLOAD +diff=$REF_SO
make clean
Expand Down
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ SIM_CXXFLAGS += -I$(DIFFTEST_CSRC_DIR)
ifeq ($(DIFFTEST_PERFCNT), 1)
SIM_CXXFLAGS += -DCONFIG_DIFFTEST_PERFCNT
endif
ifeq ($(DIFFTEST_QUERY), 1)
SIM_CXXFLAGS += -DCONFIG_DIFFTEST_QUERY
SIM_LDFLAGS += -lsqlite3
endif
endif

# ChiselDB
Expand Down
2 changes: 1 addition & 1 deletion libso.mk
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ CC_OBJ_DIR = $(abspath $(BUILD_DIR)/cc_obj)
LIB_CSRC_DIR = $(abspath ./src/test/csrc/vcs)
LIB_CXXFILES = $(SIM_CXXFILES) $(shell find $(LIB_CSRC_DIR) -name "*.cpp")
LIB_CXXFLAGS = -m64 -c -fPIC -g -std=c++11
LIB_CXXFLAGS += $(subst \\\",\", $(SIM_CXXFLAGS)) -I$(LIB_CSRC_DIR) -DNUM_CORES=$(NUM_CORES)
LIB_CXXFLAGS += $(subst \\\",\", $(SIM_CXXFLAGS)) $(SIM_LDFLAGS) -I$(LIB_CSRC_DIR) -DNUM_CORES=$(NUM_CORES)

ifeq ($(WITH_DRAMSIM3),1)
LD_LIB = -L $(DRAMSIM3_HOME)/ -ldramsim3 -Wl,-rpath-link=$(DRAMSIM3_HOME)/libdramsim3.so
Expand Down
2 changes: 1 addition & 1 deletion palladium.mk
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ DPILIB_EMU = $(PLDM_BUILD_DIR)/libdpi_emu.so
PLDM_CSRC_DIR = $(abspath ./src/test/csrc/vcs)
PLDM_CXXFILES = $(SIM_CXXFILES) $(shell find $(PLDM_CSRC_DIR) -name "*.cpp")
PLDM_CXXFLAGS = -m64 -c -fPIC -g -std=c++11 -I$(PLDM_IXCOM) -I$(PLDM_SIMTOOL)
PLDM_CXXFLAGS += $(subst \\\",\", $(SIM_CXXFLAGS)) -I$(PLDM_CSRC_DIR) -DNUM_CORES=$(NUM_CORES)
PLDM_CXXFLAGS += $(subst \\\",\", $(SIM_CXXFLAGS)) $(SIM_LDFLAGS) -I$(PLDM_CSRC_DIR) -DNUM_CORES=$(NUM_CORES)

ifeq ($(WITH_DRAMSIM3),1)
PLDM_LD_LIB = -L $(DRAMSIM3_HOME)/ -ldramsim3 -Wl,-rpath-link=$(DRAMSIM3_HOME)/libdramsim3.so
Expand Down
25 changes: 23 additions & 2 deletions src/main/scala/DPIC.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import difftest._
import difftest.batch.{BatchInfo, BatchIO}
import difftest.common.FileControl
import difftest.gateway.{GatewayConfig, GatewayResult, GatewaySinkControl}
import difftest.util.Query

import scala.collection.mutable.ListBuffer

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

setInline(s"$desiredName.v", moduleBody)
Expand All @@ -202,6 +209,12 @@ class DPICBatch(template: Seq[DifftestBundle], batchIO: BatchIO, config: Gateway
unpack += getPacketDecl(gen, "", config)
unpack += s"memcpy(packet, data, sizeof(${gen.desiredModuleName}));"
unpack += s"data += ${elem_bytes.sum};"
unpack +=
s"""
|#ifdef CONFIG_DIFFTEST_QUERY
| ${Query.writeInvoke(gen)}
|#endif // CONFIG_DIFFTEST_QUERY
|""".stripMargin
unpack.toSeq.mkString("\n ")
}

Expand Down Expand Up @@ -260,6 +273,9 @@ class DPICBatch(template: Seq[DifftestBundle], batchIO: BatchIO, config: Gateway
| }
| else if (id == BatchInterval) {
| dut_index = (dut_index + 1) % CONFIG_DIFFTEST_BATCH_SIZE;
|#ifdef CONFIG_DIFFTEST_QUERY
| difftest_query_step();
|#endif // CONFIG_DIFFTEST_QUERY
| continue;
| }
| $bundleAssign
Expand Down Expand Up @@ -298,7 +314,9 @@ object DPIC {
val interfaces = ListBuffer.empty[(String, String, String)]

def apply(control: GatewaySinkControl, io: Valid[DifftestBundle], config: GatewayConfig): Unit = {
val module = Module(new DummyDPICWrapper(chiselTypeOf(io), config))
val bundleType = chiselTypeOf(io)
Query.register(bundleType.bits, "io_")
val module = Module(new DummyDPICWrapper(bundleType, config))
module.control := control
module.io := io
val dpic = module.dpic
Expand All @@ -309,6 +327,7 @@ object DPIC {
}

def batch(template: Seq[DifftestBundle], control: GatewaySinkControl, io: BatchIO, config: GatewayConfig): Unit = {
Query.register(template, "")
val module = Module(new DummyDPICBatchWrapper(template, chiselTypeOf(io), config))
module.control := control
module.io := io
Expand All @@ -320,6 +339,7 @@ object DPIC {
if (interfaces.isEmpty) {
return GatewayResult()
}
Query.collect()

val interfaceCpp = ListBuffer.empty[String]
interfaceCpp += "#ifndef __DIFFTEST_DPIC_H__"
Expand Down Expand Up @@ -384,6 +404,7 @@ object DPIC {
interfaceCpp += ""
interfaceCpp += "#include \"difftest.h\""
interfaceCpp += "#include \"difftest-dpic.h\""
interfaceCpp += "#include \"difftest-query.h\""
interfaceCpp += ""
interfaceCpp +=
s"""
Expand Down
8 changes: 8 additions & 0 deletions src/main/scala/Difftest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,14 @@ object DifftestModule {
|void diffstate_perfcnt_finish(long long msec);
|#endif // CONFIG_DIFFTEST_PERFCNT
|""".stripMargin
difftestCpp +=
s"""
|#ifdef CONFIG_DIFFTEST_QUERY
|void difftest_query_init();
|void difftest_query_step();
|void difftest_query_finish();
|#endif // CONFIG_DIFFTEST_QUERY
|""".stripMargin
difftestCpp += "#endif // __DIFFSTATE_H__"
difftestCpp += ""
FileControl.write(difftestCpp, "diffstate.h")
Expand Down
113 changes: 113 additions & 0 deletions src/main/scala/util/Query.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/***************************************************************************************
* Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC)
* Copyright (c) 2025 Institute of Computing Technology, Chinese Academy of Sciences
*
* DiffTest is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*
* See the Mulan PSL v2 for more details.
***************************************************************************************/

package difftest.util

import difftest.DifftestBundle
import difftest.common.FileControl

import scala.collection.mutable.ListBuffer

object Query {
private val tables = ListBuffer.empty[QueryTable]
def register(gen: DifftestBundle, locPrefix: String) = {
tables += new QueryTable(gen, locPrefix)
}
def register(gens: Seq[DifftestBundle], locPrefix: String) = {
gens.foreach { gen => tables += new QueryTable(gen, locPrefix) }
}
def writeInvoke(gen: DifftestBundle): String = {
tables.find(_.gen == gen).get.writeInvoke
}
def collect() = {
val queryCpp = ListBuffer.empty[String]
queryCpp +=
s"""
|#ifndef __DIFFTEST_QUERY_H__
|#define __DIFFTEST_QUERY_H__
|
|#include <cstdint>
|#include "diffstate.h"
|#include "query.h"
|
|#ifdef CONFIG_DIFFTEST_QUERY
|
|class QueryStats: public QueryStatsBase {
|public:
| ${tables.map { t => s"Query* ${t.instName};" }.mkString("\n ")}
| QueryStats(char *path): QueryStatsBase(path) {
| ${tables.map(_.initInvoke).mkString("\n ")}
| }
| ${tables.map(_.initDecl).mkString("")}
| ${tables.map(_.writeDecl).mkString("")}
|};
|#endif // CONFIG_DIFFTEST_QUERY
|#endif // __DIFFTEST_QUERY_H__
|""".stripMargin
FileControl.write(queryCpp, "difftest-query.h")
}
}

class QueryTable(val gen: DifftestBundle, locPrefix: String) {
val tableName: String = gen.desiredModuleName.replace("Difftest", "")
// Args: (key, value)
private val stepArgs: Seq[(String, String)] = Seq(("STEP", "query_step"))
private val locArgs: Seq[(String, String)] = {
val argList = ListBuffer.empty[(String, String)]
argList += (("COREID", "coreid"))
// resolve conflict with sql key
if (gen.isIndexed) argList += (("MY_INDEX", "index"))
if (gen.isFlatten) argList += (("ADDRESS", "address"))
argList.toSeq
}
private val dataArgs: Seq[(String, String)] = {
val dataPrefix = "packet->"
val argList = ListBuffer.empty[(String, String)]
for ((name, _, elem) <- gen.dataElements) {
val isRemoved = gen.isFlatten && Seq("valid", "address").contains(name)
if (!isRemoved) {
if (elem.length == 1) argList += ((name.toUpperCase, dataPrefix + name))
else
Seq.tabulate(elem.length) { idx =>
argList += (((name + s"_$idx").toUpperCase, dataPrefix + name + s"[$idx]"))
}
}
}
argList.toSeq
}
private val sqlArgs: Seq[(String, String)] = stepArgs ++ locArgs ++ dataArgs

val instName: String = "query_" + tableName
val initDecl =
s"""
| void ${tableName}_init() {
| const char* createSql = \" CREATE TABLE $tableName(\" \\
| "ID INTEGER PRIMARY KEY AUTOINCREMENT," \\
| ${sqlArgs.map("\"" + _._1 + " INT NOT NULL").mkString("", ",\" \\\n ", ");\";")}
| const char* insertSql = \"INSERT INTO $tableName (${sqlArgs.map(_._1).mkString(",")}) \" \\
| \" VALUES (${Seq.fill(sqlArgs.length) { "?" }.mkString(",")});\";
| $instName = new Query(mem_db, createSql, insertSql);
| }
|""".stripMargin
val initInvoke = s"${tableName}_init();"
val writeDecl =
s"""
| void ${tableName}_write(${locArgs.map("uint8_t " + _._2).mkString(", ")}, ${gen.desiredModuleName}* packet) {
| query_${tableName}->write(${sqlArgs.length}, ${sqlArgs.map(_._2).mkString(", ")});
| }
|""".stripMargin
val writeInvoke = s"qStats->${tableName}_write(${locArgs.map(locPrefix + _._2).mkString(", ")}, packet);"
}
43 changes: 43 additions & 0 deletions src/test/csrc/common/query.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/***************************************************************************************
* Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC)
* Copyright (c) 2025 Institute of Computing Technology, Chinese Academy of Sciences
*
* DiffTest is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*
* See the Mulan PSL v2 for more details.
***************************************************************************************/

#ifdef CONFIG_DIFFTEST_QUERY
#include "query.h"
#include "difftest-query.h"

QueryStats *qStats;

void difftest_query_init() {
char query_path[128];
snprintf(query_path, 128, "%s/build/%s", getenv("NOOP_HOME"), "difftest_query.db");
// remove exist file
FILE *fp = fopen(query_path, "r");
if (fp) {
fclose(fp);
remove(query_path);
}
qStats = new QueryStats(query_path);
}

void difftest_query_step() {
qStats->step();
}

void difftest_query_finish() {
delete qStats;
}

#endif // CONFIG_DIFFTEST_QUERY
Loading

0 comments on commit 199cfee

Please sign in to comment.