Skip to content

Commit

Permalink
Gen C++ and Verilog macros by GatewayConfig (#251)
Browse files Browse the repository at this point in the history
Currently all macros in Gateway can be decided by GatewayConfig,
we move macros inside Config for better comprehension.

Difftest-related macros in Verilog can be configured in generated
DifftestMacros.v, which should be included by all files use those macros.

Some redundant passing of config and return val of collect is removed.
Some macros are renamed for similar format.

Makefile and mk are changed to include generated/DifftestMacros.v
  • Loading branch information
klin02 authored Jan 17, 2024
1 parent 1e94c8c commit afabff2
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 75 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ PLUGIN_CSRC_DIR = $(abspath ./src/test/csrc/plugin)
PLUGIN_INC_DIR = $(abspath $(PLUGIN_CSRC_DIR)/include)
SIM_CXXFLAGS += -I$(PLUGIN_INC_DIR)

GEN_VSRC_DIR = $(BUILD_DIR)/generated-src
VSRC_DIR = $(abspath ./src/test/vsrc/common)
SIM_VSRC = $(shell find $(VSRC_DIR) -name "*.v" -or -name "*.sv")

Expand Down
7 changes: 4 additions & 3 deletions palladium.mk
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ PLDM_MACRO_FLAGS += +define+RANDOMIZE_DELAY=0
ifeq ($(RELEASE_WITH_ASSERT), 1)
PLDM_MACRO_FLAGS += +define+SYNTHESIS +define+TB_NO_DPIC
else
PLDM_MACRO_FLAGS += +define+DIFFTEST +define+TB_DPIC_NONBLOCK
PLDM_MACRO_FLAGS += +define+DIFFTEST
endif
PLDM_MACRO_FLAGS += $(PLDM_EXTRA_MACRO)

Expand All @@ -28,6 +28,7 @@ endif
# Compiler Args
IXCOM_FLAGS += -xecompile compilerOptions=$(PLDM_SCRIPTS_DIR)/compilerOptions.qel
IXCOM_FLAGS += +tb_import_systf+fwrite +tb_import_systf+fflush
IXCOM_FLAGS += $(addprefix -incdir , $(PLDM_VSRC_DIR))
IXCOM_FLAGS += $(PLDM_MACRO_FLAGS)
IXCOM_FLAGS += +dut+$(PLDM_TB_TOP)
ifeq ($(RELEASE_WITH_ASSERT), 1)
Expand All @@ -46,7 +47,7 @@ endif
IXCOM_FLAGS += +tfconfig+$(PLDM_SCRIPTS_DIR)/argConfigs.qel

# Verilog Files
PLDM_VSRC_DIR = $(RTL_DIR)
PLDM_VSRC_DIR = $(RTL_DIR) $(GEN_VSRC_DIR)
ifeq ($(RELEASE_WITH_ASSERT), 1)
PLDM_VSRC_DIR += $(abspath ./src/test/vsrc/vcs) $(abspath ./src/test/vsrc/common/SimJTAG.v)
else
Expand All @@ -71,7 +72,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 += $(SIM_CXXFLAGS) -I$(PLDM_CSRC_DIR) -DNUM_CORES=$(NUM_CORES) -DTB_DEFERRED_RESULT
PLDM_CXXFLAGS += $(SIM_CXXFLAGS) -I$(PLDM_CSRC_DIR) -DNUM_CORES=$(NUM_CORES)

# XMSIM Flags
XMSIM_FLAGS = --xmsim -64 +xcprof -profile -PROFTHREAD
Expand Down
26 changes: 11 additions & 15 deletions src/main/scala/DPIC.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import chisel3.experimental.{DataMirror, ExtModule}
import chisel3.util._
import difftest._
import difftest.gateway.{GatewayConfig, GatewayBundle}
import difftest.DifftestModule.streamToFile

import java.nio.charset.StandardCharsets
import java.nio.file.{Files, Paths}
Expand Down Expand Up @@ -128,14 +129,15 @@ class DPIC[T <: DifftestBundle](gen: T, config: GatewayConfig) extends ExtModule
// Initial for Palladium GFIFO
val gfifoInitial =
s"""
|`ifdef TB_DPIC_NONBLOCK
|`ifdef CONFIG_DIFFTEST_NONBLOCK
|`ifdef PALLADIUM
|initial $$ixc_ctrl("gfifo", "$dpicFuncName");
|`endif
|`endif // TB_DPIC_NONBLOCK
|`endif // CONFIG_DIFFTEST_NONBLOCK
|""".stripMargin
val modDef =
s"""
|`include "DifftestMacros.v"
|module $desiredName(
| $modPortsString
|);
Expand Down Expand Up @@ -186,9 +188,9 @@ object DPIC {
module.io
}

def collect(config: GatewayConfig): Seq[String] = {
def collect(): Unit = {
if (interfaces.isEmpty) {
return Seq()
return
}

val interfaceCpp = ListBuffer.empty[String]
Expand All @@ -199,10 +201,10 @@ object DPIC {
interfaceCpp += "#include \"diffstate.h\""
interfaceCpp += ""
interfaceCpp +=
s"""
"""
|class DPICBuffer : public DiffStateBuffer {
|private:
| DiffTestState buffer[${config.dutBufLen}];
| DiffTestState buffer[CONFIG_DIFFTEST_BUFLEN];
| int read_ptr = 0;
|public:
| DPICBuffer() {
Expand All @@ -213,7 +215,7 @@ object DPIC {
| }
| inline DiffTestState* next() {
| DiffTestState* ret = buffer+read_ptr;
| read_ptr = (read_ptr + 1) % ${config.dutBufLen};
| read_ptr = (read_ptr + 1) % CONFIG_DIFFTEST_BUFLEN;
| return ret;
| }
|};
Expand All @@ -222,10 +224,7 @@ object DPIC {
interfaceCpp += ""
interfaceCpp += "#endif // __DIFFTEST_DPIC_H__"
interfaceCpp += ""
val outputDir = sys.env("NOOP_HOME") + "/build/generated-src"
Files.createDirectories(Paths.get(outputDir))
val outputHeaderFile = outputDir + "/difftest-dpic.h"
Files.write(Paths.get(outputHeaderFile), interfaceCpp.mkString("\n").getBytes(StandardCharsets.UTF_8))
streamToFile(interfaceCpp, "difftest-dpic.h")

interfaceCpp.clear()
interfaceCpp += "#ifndef CONFIG_NO_DIFFTEST"
Expand Down Expand Up @@ -255,9 +254,6 @@ object DPIC {
interfaceCpp += ""
interfaceCpp += "#endif // CONFIG_NO_DIFFTEST"
interfaceCpp += ""
val outputFile = outputDir + "/difftest-dpic.cpp"
Files.write(Paths.get(outputFile), interfaceCpp.mkString("\n").getBytes(StandardCharsets.UTF_8))

Seq("CONFIG_DIFFTEST_DPIC")
streamToFile(interfaceCpp, "difftest-dpic.cpp")
}
}
28 changes: 20 additions & 8 deletions src/main/scala/Difftest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,8 @@ trait DifftestModule[T <: DifftestBundle] {
object DifftestModule {
private val enabled = true
private val instances = ListBuffer.empty[(DifftestBundle, String)]
private val macros = ListBuffer.empty[String]
private val cppMacros = ListBuffer.empty[String]
private val vMacros = ListBuffer.empty[String]

def apply[T <: DifftestBundle](
gen: T,
Expand Down Expand Up @@ -313,13 +314,15 @@ object DifftestModule {
difftest.step := 0.U

val gateway = Gateway.collect()
macros ++= gateway._1
instances ++= gateway._2
difftest.step := gateway._3
cppMacros ++= gateway._1
vMacros ++= gateway._2
instances ++= gateway._3
difftest.step := gateway._4

if (cppHeader.isDefined) {
generateCppHeader(cpu, cppHeader.get)
}
generateVeriogHeader()

val timer = RegInit(0.U(64.W)).suggestName("timer")
timer := timer + 1.U
Expand All @@ -343,7 +346,7 @@ object DifftestModule {
difftestCpp += "#include <cstdint>"
difftestCpp += ""

macros.foreach(m => difftestCpp += s"#define $m")
cppMacros.foreach(m => difftestCpp += s"#define $m")
difftestCpp += ""

val cpu_s = cpu.replace("-", "_").replace(" ", "").toUpperCase
Expand Down Expand Up @@ -409,11 +412,20 @@ object DifftestModule {
|""".stripMargin
difftestCpp += "#endif // __DIFFSTATE_H__"
difftestCpp += ""
streamToFile(difftestCpp, "diffstate.h")
}

def generateVeriogHeader(): Unit = {
val difftestVeriog = ListBuffer.empty[String]
vMacros.foreach(m => difftestVeriog += s"`define $m")
streamToFile(difftestVeriog, "DifftestMacros.v")
}

val outputDir = sys.env("NOOP_HOME") + "/build/generated-src"
def streamToFile(fileStream: ListBuffer[String], fileName: String) {
val outputDir = sys.env("NOOP_HOME") + "/build/generated-src/"
Files.createDirectories(Paths.get(outputDir))
val outputFile = outputDir + "/diffstate.h"
Files.write(Paths.get(outputFile), difftestCpp.mkString("\n").getBytes(StandardCharsets.UTF_8))
val outputFile = outputDir + fileName
Files.write(Paths.get(outputFile), fileStream.mkString("\n").getBytes(StandardCharsets.UTF_8))
}
}

Expand Down
50 changes: 31 additions & 19 deletions src/main/scala/Gateway.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,38 @@ case class GatewayConfig(
replaySize : Int = 256,
diffStateSelect: Boolean = false,
isBatch : Boolean = false,
batchSize : Int = 32
batchSize : Int = 32,
isNonBlock : Boolean = false,
)
{
require(!(diffStateSelect && isBatch))
if (squashReplay) require(isSquash)
def hasDutPos: Boolean = diffStateSelect || isBatch
def dutBufLen: Int = if (isBatch) batchSize else if (diffStateSelect) 2 else 1
def dutPosWidth: Int = log2Ceil(dutBufLen)
def maxStep: Int = if (isBatch) batchSize else 1
def stepWidth: Int = log2Ceil(maxStep + 1)
def hasDeferredResult: Boolean = isNonBlock
def needTraceInfo: Boolean = squashReplay
def needEndpoint: Boolean = hasGlobalEnable || diffStateSelect || isBatch || isSquash
// Macros Generation for Cpp and Verilog
def cppMacros: Seq[String] = {
val macros = ListBuffer.empty[String]
macros += s"CONFIG_DIFFTEST_${style.toUpperCase}"
macros += s"CONFIG_DIFFTEST_BUFLEN ${dutBufLen}"
if (isBatch) macros ++= Seq("CONFIG_DIFFTEST_BATCH", s"DIFFTEST_BATCH_SIZE ${batchSize}")
if (isSquash) macros += "CONFIG_DIFFTEST_SQUASH"
if (squashReplay) macros += "CONFIG_DIFFTEST_SQUASH_REPLAY"
if (hasDeferredResult) macros += "CONFIG_DIFFTEST_DEFERRED_RESULT"
macros.toSeq
}
def vMacros: Seq[String] = {
val macros = ListBuffer.empty[String]
macros += s"CONFIG_DIFFTEST_STEPWIDTH ${stepWidth}"
if (isNonBlock) macros += "CONFIG_DIFFTEST_NONBLOCK"
if (hasDeferredResult) macros += "CONFIG_DIFFTEST_DEFERRED_RESULT"
macros.toSeq
}
}

object Gateway {
Expand All @@ -68,20 +90,18 @@ object Gateway {
gen
}

def collect(): (Seq[String], Seq[(DifftestBundle, String)], UInt) = {
val macros = ListBuffer.empty[String]
def collect(): (Seq[String], Seq[String], Seq[(DifftestBundle, String)], UInt) = {
val extraInstances = ListBuffer.empty[(DifftestBundle, String)]
val step = WireInit(1.U)
if (config.needEndpoint) {
val endpoint = Module(new GatewayEndpoint(instances.toSeq, config))
macros ++= endpoint.macros
extraInstances ++= endpoint.extraInstances
step := endpoint.step
}
else {
macros ++= GatewaySink.collect(config)
GatewaySink.collect(config)
}
(macros.toSeq, extraInstances.toSeq, step)
(config.cppMacros, config.vMacros, extraInstances.toSeq, step)
}
}

Expand Down Expand Up @@ -193,10 +213,8 @@ class GatewayEndpoint(signals: Seq[DifftestBundle], config: GatewayConfig) exten
ports.foreach(port => port.dut_pos.get := select.asUInt)
}

val step_width = if (config.isBatch) log2Ceil(config.batchSize+1) else 1
val upper = if(config.isBatch) config.batchSize.U else 1.U
val step = IO(Output(UInt(step_width.W)))
step := Mux(enable, upper, 0.U)
val step = IO(Output(UInt(config.stepWidth.W)))
step := Mux(enable, config.maxStep.U, 0.U)

if (config.isBatch) {
for (ptr <- 0 until config.batchSize) {
Expand All @@ -212,13 +230,7 @@ class GatewayEndpoint(signals: Seq[DifftestBundle], config: GatewayConfig) exten
}
}

var macros = GatewaySink.collect(config)
if (config.isBatch) {
macros ++= Seq("CONFIG_DIFFTEST_BATCH", s"DIFFTEST_BATCH_SIZE ${config.batchSize}")
}
if (config.isSquash) {
macros ++= Squash.collect(config)
}
GatewaySink.collect(config)

val extraInstances = ListBuffer.empty[(DifftestBundle, String)]
if (config.needTraceInfo) {
Expand All @@ -234,9 +246,9 @@ object GatewaySink{
}
}

def collect(config: GatewayConfig): Seq[String] = {
def collect(config: GatewayConfig): Unit = {
config.style match {
case "dpic" => DPIC.collect(config)
case "dpic" => DPIC.collect()
}
}
}
Expand Down
7 changes: 1 addition & 6 deletions src/main/scala/Squash.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,6 @@ object Squash {
val module = Module(new SquashEndpoint(bundles, config))
module
}

def collect(config: GatewayConfig): Seq[String] = {
var macros = Seq("CONFIG_DIFFTEST_SQUASH")
if (config.squashReplay) macros ++= Seq("CONFIG_DIFFTEST_SQUASH_REPLAY")
macros
}
}

class SquashEndpoint(bundles: Seq[DifftestBundle], config: GatewayConfig) extends Module {
Expand Down Expand Up @@ -168,6 +162,7 @@ class SquashControl(config: GatewayConfig) extends ExtModule with HasExtModuleIn

setInline("SquashControl.v",
s"""
|`include "DifftestMacros.v"
|module SquashControl(
| input clock,
| input reset,
Expand Down
17 changes: 6 additions & 11 deletions src/test/vsrc/vcs/DeferredControl.v
Original file line number Diff line number Diff line change
@@ -1,25 +1,20 @@
`ifdef TB_DPIC_NONBLOCK
`define TB_DEFERRED_RESULT
`endif

`define STEP_WIDTH 8

`ifdef TB_DEFERRED_RESULT
`include "DifftestMacros.v"
`ifdef CONFIG_DIFFTEST_DEFERRED_RESULT
module DeferredControl(
input clock,
input reset,
input [`STEP_WIDTH - 1:0] step,
input [`CONFIG_DIFFTEST_STEPWIDTH - 1:0] step,
output reg simv_result
);

import "DPI-C" function int simv_result_fetch();
import "DPI-C" function void simv_nstep(int step);

`ifdef TB_DPIC_NONBLOCK
`ifdef CONFIG_DIFFTEST_NONBLOCK
`ifdef PALLADIUM
initial $ixc_ctrl("gfifo", "simv_nstep");
`endif // PALLADIUM
`endif TB_DPIC_NONBLOCK
`endif // CONFIG_DIFFTEST_NONBLOCK

reg [63:0] fetch_cycles;
initial fetch_cycles = 4999;
Expand Down Expand Up @@ -48,4 +43,4 @@ always @(posedge clock) begin
end

endmodule;
`endif // TB_DEFERRED_RESULT
`endif // CONFIG_DIFFTEST_DEFERRED_RESULT
Loading

0 comments on commit afabff2

Please sign in to comment.