Skip to content

Commit

Permalink
gsim: support gsim based on verilator framework
Browse files Browse the repository at this point in the history
  • Loading branch information
klin02 committed Oct 31, 2024
1 parent 85823eb commit 2074f16
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 14 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ BUILD_DIR = $(DESIGN_DIR)/build
RTL_DIR = $(BUILD_DIR)/rtl
RTL_SUFFIX ?= sv
SIM_TOP_V = $(RTL_DIR)/$(SIM_TOP).$(RTL_SUFFIX)
SIM_TOP_FIR = $(RTL_DIR)/$(SIM_TOP).fir

# generate difftest files for non-chisel design.
.DEFAULT_GOAL := difftest_verilog
Expand Down Expand Up @@ -228,6 +229,7 @@ SIM_CXXFLAGS += -Werror
endif

include verilator.mk
include gsim.mk
include vcs.mk
include palladium.mk
include libso.mk
Expand Down
37 changes: 37 additions & 0 deletions gsim.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#***************************************************************************************
# Copyright (c) 2024 Beijing Institute of Open Source Chip (BOSC)
# Copyright (c) 2020-2024 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.
#***************************************************************************************

GSIM_TOP = SimTop
GSIM_TARGET = $(abspath $(BUILD_DIR)/gsim)
GSIM_BUILD_DIR = $(abspath $(BUILD_DIR)/gsim-compile)

GSIM_CSRC_DIR = $(abspath ./src/test/csrc/verilator)
GSIM_CONFIG_DIR = $(abspath ./config)

GSIM_CXXFILES = $(SIM_CXXFILES) $(shell find $(GSIM_CSRC_DIR) -name "*.cpp")
GSIM_CXXFLAGS = $(SIM_CXXFLAGS) -I$(GSIM_CSRC_DIR) -DNUM_CORES=$(NUM_CORES) -DGSIM
GSIM_LDFLAGS = $(SIM_LDFLAGS) -ldl

GSIM_HOME := $(abspath $(GSIM_HOME))

$(GSIM_TARGET):
ifndef GSIM_HOME
$(error GSIM_HOME is not set, please set manually)
endif
# make -C $(GSIM_HOME) compile BUILD_DIR=$(GSIM_BUILD_DIR) NAME=$(GSIM_TOP) FIRRTL_FILE=$(SIM_TOP_FIR)
make -C $(GSIM_HOME) build-emu BUILD_DIR=$(GSIM_BUILD_DIR) NAME=$(GSIM_TOP) target=$(GSIM_TARGET) GSIM_CXXFILES="$(GSIM_CXXFILES)" GSIM_CXXFLAGS="$(GSIM_CXXFLAGS)" GSIM_LDFLAGS="$(GSIM_LDFLAGS)"

gsim: $(GSIM_TARGET)
2 changes: 1 addition & 1 deletion src/test/csrc/common/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include "common.h"
#include "dut.h"

#ifdef VERILATOR
#if defined(VERILATOR) || defined(GSIM)
#include "emu.h"
#define DUT_MODEL Emulator
#endif
Expand Down
90 changes: 84 additions & 6 deletions src/test/csrc/verilator/emu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,13 +325,16 @@ inline EmuArgs parse_args(int argc, const char *argv[]) {
args.ipc_file = fopen(ipc_file, "w");
#endif

#ifdef VERILATOR
Verilated::commandArgs(argc, argv); // Prepare extra args for TLMonitor
#endif // VERILATOR
return args;
}

Emulator::Emulator(int argc, const char *argv[])
: dut_ptr(new VSimTop), cycles(0), trapCode(STATE_RUNNING), elapsed_time(uptime()) {
: dut_ptr(new DUT_TOP), cycles(0), trapCode(STATE_RUNNING), elapsed_time(uptime()) {

#ifdef VERILATOR
#if !defined(VERILATOR_VERSION_INTEGER) || VERILATOR_VERSION_INTEGER < 5026000
// Large designs may cause segmentation fault due to stack overflow.
// Legacy versions of Verilator do not automatically set the stack size.
Expand All @@ -344,17 +347,20 @@ Emulator::Emulator(int argc, const char *argv[])
printf("[warning] cannot set stack size. Large designs may cause SIGSEGV.\n");
}
#endif
#endif // VERILATOR

args = parse_args(argc, argv);
#ifdef ENABLE_CONSTANTIN
void constantinLoad();
constantinLoad();
#endif // CONSTANTIN
#ifdef VERILATOR
// srand
srand(args.seed);
srand48(args.seed);
Verilated::randSeed(args.seed);
Verilated::randReset(2);
#endif // VERILATOR

// init remote-bitbang
if (enable_simjtag) {
Expand Down Expand Up @@ -434,8 +440,14 @@ Emulator::Emulator(int argc, const char *argv[])
#endif

// set log time range and log level
#ifdef VERILATOR
dut_ptr->difftest_logCtrl_begin = args.log_begin;
dut_ptr->difftest_logCtrl_end = args.log_end;
#endif // VERILATOR
#ifdef GSIM
dut_ptr->set_difftest$$logCtrl$$begin(args.log_begin);
dut_ptr->set_difftest$$logCtrl$$end(args.log_end);
#endif // GSIM

#ifndef CONFIG_NO_DIFFTEST
// init difftest
Expand Down Expand Up @@ -580,6 +592,7 @@ inline void Emulator::reset_ncycles(size_t cycles) {
return;
}
for (int i = 0; i < cycles; i++) {
#ifdef VERILATOR
dut_ptr->reset = 1;
#ifdef COVERAGE_PORT_RESET
dut_ptr->coverage_reset = dut_ptr->reset;
Expand Down Expand Up @@ -612,6 +625,14 @@ inline void Emulator::reset_ncycles(size_t cycles) {
#ifdef COVERAGE_PORT_RESET
dut_ptr->coverage_reset = dut_ptr->reset;
#endif // COVERAGE_PORT_RESET
#endif // VERILATOR

#ifdef GSIM
dut_ptr->set_reset(1);
dut_ptr->step();
dut_ptr->set_reset(0);
dut_ptr->step();
#endif // GSIM
}
}

Expand All @@ -620,11 +641,13 @@ inline void Emulator::single_cycle() {
goto end_single_cycle;
}

#ifdef VERILATOR
dut_ptr->clock = 1;
#ifdef COVERAGE_PORT_CLOCK
dut_ptr->coverage_clock = dut_ptr->clock;
#endif // COVERAGE_PORT_CLOCK
dut_ptr->eval();
#endif // VERILATOR

#if VM_TRACE == 1
if (args.enable_waveform) {
Expand All @@ -649,6 +672,7 @@ inline void Emulator::single_cycle() {
dramsim3_step();
#endif

#ifdef VERILATOR
if (dut_ptr->difftest_uart_out_valid) {
printf("%c", dut_ptr->difftest_uart_out_ch);
fflush(stdout);
Expand All @@ -663,6 +687,20 @@ inline void Emulator::single_cycle() {
dut_ptr->coverage_clock = dut_ptr->clock;
#endif // COVERAGE_PORT_CLOCK
dut_ptr->eval();
#endif // VERILATOR

#ifdef GSIM
dut_ptr->step();
if (dut_ptr->get_difftest$$uart$$out$$valid()) {
printf("%c", dut_ptr->get_difftest$$uart$$out$$ch());
fflush(stdout);
}
if (dut_ptr->get_difftest$$uart$$in$$valid()) {
extern uint8_t uart_getc();
uint8_t ch = uart_getc();
dut_ptr->set_difftest$$uart$$in$$ch(ch);
}
#endif // GSIM

#if VM_TRACE == 1
if (args.enable_waveform && args.enable_waveform_full) {
Expand Down Expand Up @@ -749,11 +787,17 @@ int Emulator::tick() {
}

// exit signal: non-zero exit exits the simulation. exit all 1's indicates good.
if (dut_ptr->difftest_exit) {
if (dut_ptr->difftest_exit == -1UL) {
#ifdef VERILATOR
uint64_t difftest_exit = dut_ptr->difftest_exit;
#endif
#ifdef GSIM
uint64_t difftest_exit = 0; // TODO: gsim API
#endif
if (difftest_exit) {
if (difftest_exit == -1UL) {
trapCode = STATE_SIM_EXIT;
} else {
Info("The simulation aborted via the top-level exit of 0x%lx.\n", dut_ptr->difftest_exit);
Info("The simulation aborted via the top-level exit of 0x%lx.\n", difftest_exit);
trapCode = STATE_ABORT;
}
}
Expand All @@ -766,13 +810,25 @@ int Emulator::tick() {
auto trap = difftest[i]->get_trap_event();
if (trap->instrCnt >= args.warmup_instr) {
Info("Warmup finished. The performance counters will be dumped and then reset.\n");
#ifdef VERILATOR
dut_ptr->difftest_perfCtrl_clean = 1;
dut_ptr->difftest_perfCtrl_dump = 1;
#endif // VERILATOR
#ifdef GSIM
dut_ptr->set_difftest$$perfCtrl$$clean(1);
dut_ptr->set_difftest$$perfCtrl$$dump(1);
#endif // GSIM
args.warmup_instr = -1;
}
if (trap->cycleCnt % args.stat_cycles == args.stat_cycles - 1) {
#ifdef VERILATOR
dut_ptr->difftest_perfCtrl_clean = 1;
dut_ptr->difftest_perfCtrl_dump = 1;
#endif // VERILATOR
#ifdef GSIM
dut_ptr->set_difftest$$perfCtrl$$clean(1);
dut_ptr->set_difftest$$perfCtrl$$dump(1);
#endif // GSIM
}
#ifdef ENABLE_IPC
if (trap->instrCnt >= args.ipc_times * args.ipc_interval &&
Expand Down Expand Up @@ -807,16 +863,26 @@ int Emulator::tick() {
#ifdef CONFIG_NO_DIFFTEST
args.max_cycles--;
#endif // CONFIG_NO_DIFFTEST
#ifdef VERILATOR
dut_ptr->difftest_perfCtrl_clean = 0;
dut_ptr->difftest_perfCtrl_dump = 0;

#endif // VERILATOR
#ifdef GSIM
dut_ptr->set_difftest$$perfCtrl$$clean(0);
dut_ptr->set_difftest$$perfCtrl$$dump(0);
#endif // GSIM
#ifndef CONFIG_NO_DIFFTEST
int step = 0;
if (args.trace_name && args.trace_is_read) {
step = 1;
difftest_trace_read();
} else {
#ifdef VERILATOR
step = dut_ptr->difftest_step;
#endif // VERILATOR
#ifdef GSIM
step = 1; // TODO: gsim API
#endif // GSIM
}

static uint64_t stuck_timer = 0;
Expand Down Expand Up @@ -906,7 +972,11 @@ int Emulator::tick() {
}

int Emulator::is_finished() {
return Verilated::gotFinish() || trapCode != STATE_RUNNING;
return
#ifdef VERILATOR
Verilated::gotFinish() ||
#endif // VERILATOR
trapCode != STATE_RUNNING;
}

int Emulator::is_good() {
Expand Down Expand Up @@ -992,10 +1062,18 @@ inline void Emulator::save_coverage(time_t t) {
#endif

void Emulator::trigger_stat_dump() {
#ifdef VERILATOR
dut_ptr->difftest_perfCtrl_dump = 1;
if (get_args().force_dump_result) {
dut_ptr->difftest_logCtrl_end = -1;
}
#endif // VERILATOR
#ifdef GSIM
dut_ptr->set_difftest$$perfCtrl$$dump(1);
if (get_args().force_dump_result) {
dut_ptr->set_difftest$$logCtrl$$end(-1);
}
#endif // GSIM
single_cycle();
}

Expand Down
22 changes: 15 additions & 7 deletions src/test/csrc/verilator/emu.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,30 @@
#ifndef __EMU_H
#define __EMU_H

#ifdef VERILATOR
#include "VSimTop.h"
#include "VSimTop__Syms.h"
#define DUT_TOP VSimTop
#endif // VERILATOR
#ifdef GSIM
#include "SimTop.h"
#define DUT_TOP SSimTop
#endif
#include "common.h"
#include "dut.h"
#include "lightsss.h"
#include "snapshot.h"
#include <sys/types.h>
#ifdef ENABLE_FST
#include <verilated_fst_c.h>
#else
#include <verilated_vcd_c.h> // Trace file format header
#endif
#ifdef EMU_THREAD
#include <verilated_threads.h>
#endif
#if VM_TRACE == 1
#ifdef ENABLE_FST
#include <verilated_fst_c.h>
#else
#include <verilated_vcd_c.h> // Trace file format header
#endif
#endif // ENABLE_FST
#endif // VM_TRACE

struct EmuArgs {
uint32_t reset_cycles = 50;
Expand Down Expand Up @@ -85,12 +91,14 @@ struct EmuArgs {

class Emulator final : public DUT {
private:
VSimTop *dut_ptr;
DUT_TOP *dut_ptr;
#if VM_TRACE == 1
#ifdef ENABLE_FST
VerilatedFstC *tfp;
#else
VerilatedVcdC *tfp;
#endif
#endif // VM_TRACE == 1
bool force_dump_wave = false;
#ifdef VM_SAVABLE
VerilatedSaveMem *snapshot_slot = nullptr;
Expand Down

0 comments on commit 2074f16

Please sign in to comment.