├── .mill-version ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── general-q-a.md │ ├── feature_request.md │ └── bug_report.md └── workflows │ └── format.yml ├── scripts ├── palladium │ ├── clock_gen.xel │ ├── run.tcl │ ├── argConfigs.qel │ ├── run_debug.tcl │ └── compilerOptions.qel ├── fpga_sim │ └── ci.sh ├── coverage │ └── vtransform.py └── fpga │ └── release.sh ├── config └── config.cpp ├── src ├── test │ ├── csrc │ │ ├── plugin │ │ │ ├── include │ │ │ │ └── tllogger.h │ │ │ ├── spikedasm │ │ │ │ ├── spikedasm.h │ │ │ │ └── spikedasm.cpp │ │ │ ├── xspdb │ │ │ │ ├── cpp │ │ │ │ │ ├── export.h │ │ │ │ │ └── export.cpp │ │ │ │ └── swig.i │ │ │ ├── simfrontend │ │ │ │ ├── debug.h │ │ │ │ ├── simfrontend.h │ │ │ │ ├── tracereader.h │ │ │ │ └── tracereader.cpp │ │ │ └── runahead │ │ │ │ ├── memdep.h │ │ │ │ └── memdep.cpp │ │ ├── gsim │ │ │ ├── unimpl-blackbox.cpp │ │ │ ├── gsim.cpp │ │ │ └── gsim.h │ │ ├── common │ │ │ ├── SimJTAG.cpp │ │ │ ├── device.h │ │ │ ├── uart.h │ │ │ ├── vga.h │ │ │ ├── sdcard.h │ │ │ ├── SimJTAG.h │ │ │ ├── flash.h │ │ │ ├── macro.h │ │ │ ├── dut.cpp │ │ │ ├── query.cpp │ │ │ ├── remote_bitbang.h │ │ │ ├── compress.h │ │ │ ├── perf.h │ │ │ ├── device.cpp │ │ │ ├── sdcard.cpp │ │ │ ├── lightsss.h │ │ │ ├── vga.cpp │ │ │ ├── perf.cpp │ │ │ ├── golden.h │ │ │ ├── args.h │ │ │ ├── lightsss.cpp │ │ │ ├── uart.cpp │ │ │ ├── query.h │ │ │ ├── flash.cpp │ │ │ ├── keyboard.cpp │ │ │ ├── common.h │ │ │ ├── dut.h │ │ │ ├── elfloader.cpp │ │ │ └── common.cpp │ │ ├── fpga_sim │ │ │ └── xdma_sim.h │ │ ├── verilator │ │ │ ├── waveform.h │ │ │ ├── waveform.cpp │ │ │ ├── snapshot.h │ │ │ ├── verilator.h │ │ │ └── verilator.cpp │ │ ├── difftest │ │ │ ├── diffstate.cpp │ │ │ ├── goldenmem.h │ │ │ └── difftrace.h │ │ ├── fpga │ │ │ ├── serial_port.h │ │ │ ├── xdma.h │ │ │ └── serial_port.cpp │ │ └── emu │ │ │ ├── main.cpp │ │ │ ├── emu.h │ │ │ └── simulator.h │ ├── vsrc │ │ ├── common │ │ │ ├── assert.v │ │ │ ├── ref.v │ │ │ └── SimJTAG.v │ │ ├── fpga │ │ │ └── fpga_clock_gate.v │ │ ├── vcs │ │ │ └── DeferredControl.v │ │ └── fpga_sim │ │ │ ├── xdma_axi.v │ │ │ ├── xdma_clock.v │ │ │ └── xdma_wrapper.v │ └── scala │ │ └── DifftestMain.scala └── main │ └── scala │ ├── util │ ├── Compatibility.scala │ ├── Lookup.scala │ ├── Delayer.scala │ └── Profile.scala │ ├── fpga │ └── AXI4.scala │ ├── Coverage.scala │ ├── common │ ├── FileControl.scala │ ├── SDCard.scala │ ├── LogPerfControl.scala │ └── WiringControl.scala │ ├── Validate.scala │ └── Replay.scala ├── .clang-format ├── fpga.mk ├── libso.mk ├── .scalafmt.conf ├── pdb.mk ├── emu.mk ├── palladium.mk └── galaxsim.mk /.mill-version: -------------------------------------------------------------------------------- 1 | 0.12.3 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /scripts/palladium/clock_gen.xel: -------------------------------------------------------------------------------- 1 | clockOption -add {technology CAKE 1} 2 | clockFrequency -add {clock 50MHz} 3 | -------------------------------------------------------------------------------- /scripts/palladium/run.tcl: -------------------------------------------------------------------------------- 1 | debug . 2 | host $env(PLDM_HOST) 3 | xc on -zt0 -xt0 -tbrun 4 | date 5 | run -swap 6 | run 7 | exit 8 | -------------------------------------------------------------------------------- /config/config.cpp: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | #include 3 | 4 | uint64_t PMEM_BASE = _PMEM_BASE; 5 | uint64_t FIRST_INST_ADDRESS = _FIRST_INST_ADDRESS; 6 | -------------------------------------------------------------------------------- /scripts/palladium/argConfigs.qel: -------------------------------------------------------------------------------- 1 | * $test$plusargs TB_IMPORT 2 | * $value$plusargs TB_IMPORT 3 | * $finish TB_IMPORT 4 | * $fatal TB_IMPORT 5 | * $random TB_IMPORT 6 | * $fwrite GFIFO 7 | LogPerfEndpoint $fwrite TB_IMPORT 8 | -------------------------------------------------------------------------------- /src/test/csrc/plugin/include/tllogger.h: -------------------------------------------------------------------------------- 1 | #ifndef _TL_LOGGER_H_ 2 | #define _TL_LOGGER_H_ 3 | 4 | #include "common.h" 5 | #include 6 | 7 | void init_logger(bool enable); 8 | void save_db(const char *zFilename); 9 | void checkpoint_db(const char *zFilename); 10 | #endif 11 | -------------------------------------------------------------------------------- /scripts/palladium/run_debug.tcl: -------------------------------------------------------------------------------- 1 | debug . 2 | host $env(PLDM_HOST) 3 | xc xt0 zt0 on -tbrun 4 | database -open pldm_db 5 | probe -create -all -depth all tb_top -database pldm_db 6 | xeset traceMemSize 20000 7 | xeset triggerPos 2 8 | run -swap 9 | run 10 | database -upload 11 | xc off 12 | exit 13 | -------------------------------------------------------------------------------- /src/main/scala/util/Compatibility.scala: -------------------------------------------------------------------------------- 1 | // This file addresses compatibility issues for Chisel. 2 | 3 | package chisel3 { 4 | 5 | import chisel3.internal._ 6 | 7 | object compatibility { 8 | // Return the internal implicit Clock 9 | def currentClock: Option[Clock] = Builder.currentClock 10 | 11 | // Return the internal implicit Reset 12 | def currentReset: Option[Reset] = Builder.currentReset 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /scripts/fpga_sim/ci.sh: -------------------------------------------------------------------------------- 1 | set -e # exit when some command failed 2 | set -o pipefail 3 | 4 | ./build/fpga-host --diff ready-to-run/riscv64-nemu-interpreter-so -i ready-to-run/microbench.bin & 5 | HOST_PID=$! 6 | 7 | sleep 2 8 | 9 | ./build/simv +workload=./ready-to-run/microbench.bin +e=0 +diff=./ready-to-run/riscv64-nemu-interpreter-so & #> build/try.txt 2>&1 & 10 | SIMV_PID=$! 11 | 12 | wait $HOST_PID 13 | HOST_EXIT_CODE=$? 14 | 15 | kill -9 $SIMV_PID 16 | 17 | exit $HOST_EXIT_CODE 18 | -------------------------------------------------------------------------------- /scripts/palladium/compilerOptions.qel: -------------------------------------------------------------------------------- 1 | emulatorConfiguration -add "host $env(PLDM_HOST)" {boards *} 2 | 3 | ########################### 4 | # compilerOption 5 | ########################### 6 | # compilerOption -add {visionMode FV} 7 | 8 | 9 | ########################### 10 | # precompileOption 11 | ########################### 12 | precompileOption -add noReset1X 13 | precompileOption -add keepSourceless 14 | 15 | ########################### 16 | # compileFindOptions 17 | ########################### 18 | set compileScript "compileFind -all -max_trials 3 -crit_paths 100 -names_crit" 19 | append compileScript ";userData -dump all ud.dump" 20 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | # See all possible options and defaults with: 3 | # clang-format --style=LLVM --dump-config 4 | Language: Cpp 5 | BasedOnStyle: LLVM 6 | AlignAfterOpenBracket: Align 7 | AlignConsecutiveMacros: 8 | Enabled: true 9 | AlignEscapedNewlines: Left 10 | AllowAllArgumentsOnNextLine: true 11 | AllowShortBlocksOnASingleLine: Empty 12 | AllowShortCaseLabelsOnASingleLine: true 13 | AllowShortEnumsOnASingleLine: false 14 | AllowShortFunctionsOnASingleLine: Empty 15 | AlwaysBreakBeforeMultilineStrings: true 16 | BracedInitializerIndentWidth: 2 17 | ColumnLimit: 120 18 | IncludeBlocks: Merge 19 | IndentCaseLabels: true 20 | InsertNewlineAtEOF: true 21 | PointerAlignment: Right 22 | ReflowComments: false 23 | SpaceBeforeRangeBasedForLoopColon: false 24 | -------------------------------------------------------------------------------- /src/test/csrc/gsim/unimpl-blackbox.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void SimJTAG(int __0, uint8_t _0, uint8_t &_1, uint8_t &_2, uint8_t &_3, uint8_t _4, uint8_t _5, uint8_t _6, uint8_t _7, 4 | uint32_t &_8) { 5 | _1 = 1; // TRSTn 6 | _2 = 0; // TMS 7 | _3 = 0; // TDI 8 | _8 = 0; 9 | } 10 | 11 | void imsic_csr_top(uint8_t _0, uint8_t _1, uint16_t _2, uint8_t _3, uint8_t _4, uint16_t _5, uint8_t _6, uint8_t _7, 12 | uint8_t _8, uint8_t _9, uint8_t _10, uint8_t _11, uint64_t _12, uint8_t &_13, uint64_t &_14, 13 | uint8_t &_15, uint8_t &_16, uint32_t &_17, uint32_t &_18, uint32_t &_19) { 14 | _13 = 0; 15 | _15 = 0; 16 | _16 = 0; // o_irq 17 | _17 = 0; 18 | _18 = 0; 19 | _19 = 0; 20 | } 21 | 22 | void PrintCommitIDModule(uint8_t _0, uint64_t _1, uint8_t _2) {} 23 | -------------------------------------------------------------------------------- /src/test/csrc/gsim/gsim.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2025 Institute of Computing Technology, Chinese Academy of Sciences 3 | * 4 | * DiffTest is licensed under Mulan PSL v2. 5 | * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 | * You may obtain a copy of Mulan PSL v2 at: 7 | * http://license.coscl.org.cn/MulanPSL2 8 | * 9 | * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10 | * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11 | * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12 | * 13 | * See the Mulan PSL v2 for more details. 14 | ***************************************************************************************/ 15 | 16 | #include "simulator.h" 17 | 18 | GsimSim::GsimSim() : dut(new SSimTop) {} 19 | 20 | GsimSim::~GsimSim() { 21 | delete dut; 22 | } 23 | -------------------------------------------------------------------------------- /src/test/csrc/plugin/spikedasm/spikedasm.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | #include 18 | 19 | bool spike_valid(); 20 | const char *spike_dasm(uint64_t inst); 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/general-q-a.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: General Q&A 3 | about: For general-purpose Q&A 4 | title: '' 5 | labels: question 6 | assignees: klin02, poemonsense 7 | 8 | --- 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | **Related component**: build | simulation framework | cosim with a REF 18 | 19 | **Describe the question** 20 | 21 | 22 | 23 | **What you expect us (DiffTest developers) to do for you** 24 | 25 | **Additional context** 26 | Add any other context about the problem here. 27 | -------------------------------------------------------------------------------- /src/test/csrc/plugin/xspdb/cpp/export.h: -------------------------------------------------------------------------------- 1 | #ifndef __SWIG_DIFFTEST_EXPORT__ 2 | #define __SWIG_DIFFTEST_EXPORT__ 3 | 4 | #include "difftest.h" 5 | #include "flash.h" 6 | #include "goldenmem.h" 7 | #include "ram.h" 8 | #include 9 | 10 | extern Difftest **difftest; 11 | 12 | Difftest *GetDifftest(int index); 13 | 14 | void InitRam(std::string image, uint64_t n_bytes); 15 | void InitFlash(std::string flash_bin); 16 | 17 | flash_device_t *GetFlash(); 18 | uint64_t FlashRead(uint32_t addr); 19 | int FlashWrite(uint32_t addr, uint64_t data); 20 | 21 | bool DifftestStepAndCheck(uint64_t pin, uint64_t val, uint64_t arg); 22 | uint64_t GetFuncAddressOfDifftestStepAndCheck(); 23 | int GetDifftestStat(); 24 | 25 | void GoldenMemInit(); 26 | void GoldenMemFinish(); 27 | void SetProxyRefSo(uint64_t addr); 28 | uint64_t GetProxyRefSo(); 29 | 30 | uint64_t Get_PMEM_BASE(); 31 | uint64_t Get_FIRST_INST_ADDRESS(); 32 | void Set_PMEM_BASE(uint64_t v); 33 | void Set_FIRST_INST_ADDRESS(uint64_t v); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/test/csrc/common/SimJTAG.cpp: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | 3 | #include "SimJTAG.h" 4 | #include "common.h" 5 | #include "remote_bitbang.h" 6 | #include 7 | #ifdef CONFIG_DIFFTEST_PERFCNT 8 | #include "perf.h" 9 | #endif // CONFIG_DIFFTEST_PERFCNT 10 | 11 | remote_bitbang_t *jtag; 12 | bool enable_simjtag = false; 13 | uint16_t remote_jtag_port = 23334; 14 | 15 | void jtag_init() { 16 | jtag = new remote_bitbang_t(remote_jtag_port); 17 | } 18 | 19 | int jtag_tick(unsigned char *jtag_TCK, unsigned char *jtag_TMS, unsigned char *jtag_TDI, unsigned char *jtag_TRSTn, 20 | unsigned char jtag_TDO) { 21 | #ifdef CONFIG_DIFFTEST_PERFCNT 22 | difftest_calls[perf_jtag_tick]++; 23 | difftest_bytes[perf_jtag_tick] += 5; 24 | #endif // CONFIG_DIFFTEST_PERFCNT 25 | if (!enable_simjtag) 26 | return 0; 27 | if (!jtag) { 28 | jtag_init(); 29 | } 30 | 31 | jtag->tick(jtag_TCK, jtag_TMS, jtag_TDI, jtag_TRSTn, jtag_TDO); 32 | 33 | return jtag->done() ? (jtag->exit_code() << 1 | 1) : 0; 34 | } 35 | -------------------------------------------------------------------------------- /src/test/csrc/common/device.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | #ifndef __DEVICE_H__ 18 | #define __DEVICE_H__ 19 | 20 | #include "common.h" 21 | 22 | void init_device(); 23 | void finish_device(); 24 | void poll_event(); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/test/csrc/common/uart.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2024 Beijing Institute of Open Source Chip (BOSC) 3 | * Copyright (c) 2020-2024 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 | #ifndef __UART_H 18 | #define __UART_H 19 | 20 | #include "common.h" 21 | 22 | extern "C" void uart_getc_legacy(uint8_t *ch); 23 | void init_uart(void); 24 | void finish_uart(void); 25 | #endif // __UART_H 26 | -------------------------------------------------------------------------------- /.github/workflows/format.yml: -------------------------------------------------------------------------------- 1 | name: format 2 | 3 | on: 4 | pull_request: 5 | branches: [ master ] 6 | 7 | jobs: 8 | format: 9 | runs-on: ubuntu-24.04 10 | steps: 11 | - uses: actions/checkout@v4 12 | with: 13 | repository: ${{ github.event.pull_request.head.repo.full_name }} 14 | ref: ${{ github.event.pull_request.head.ref }} 15 | 16 | - name: Mill Installation 17 | run: | 18 | sudo curl -L https://github.com/com-lihaoyi/mill/releases/download/0.11.1/0.11.1 > /usr/local/bin/mill 19 | chmod +x /usr/local/bin/mill 20 | 21 | - name: Clang Format Installation 22 | run: | 23 | pip install clang-format==18.1.4 24 | 25 | - name: Scala Formatter 26 | run: | 27 | make scala-format 28 | 29 | - name: Clang Formatter 30 | run: | 31 | make clang-format 32 | 33 | - name: Format Check 34 | run: | 35 | if [ -n "$(git status --porcelain)" ]; then 36 | echo "Please run 'make format' manually" 37 | exit 1 38 | fi 39 | -------------------------------------------------------------------------------- /src/test/csrc/common/vga.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2024 Beijing Institute of Open Source Chip (BOSC) 3 | * Copyright (c) 2020-2024 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 | #ifndef __VGA_H 18 | #define __VGA_H 19 | 20 | #include "common.h" 21 | 22 | extern "C" void put_pixel(uint32_t pixel); 23 | extern "C" void vmem_sync(void); 24 | void init_sdl(); 25 | void finish_sdl(); 26 | #endif // __VGA_H 27 | -------------------------------------------------------------------------------- /src/test/vsrc/common/assert.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | `ifndef TB_NO_DPIC 18 | import "DPI-C" function void xs_assert 19 | ( 20 | input longint line 21 | ); 22 | 23 | import "DPI-C" function void xs_assert_v2 24 | ( 25 | input string filename, 26 | input longint line 27 | ); 28 | 29 | `endif 30 | -------------------------------------------------------------------------------- /src/test/csrc/common/sdcard.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | #ifndef __SDCARD_H 18 | #define __SDCARD_H 19 | 20 | #include "common.h" 21 | 22 | extern FILE *fp; 23 | extern "C" void sd_setaddr(uint32_t addr); 24 | extern "C" void sd_read(uint32_t *data); 25 | void init_sd(void); 26 | void finish_sd(void); 27 | #endif // __SDCARD_H 28 | -------------------------------------------------------------------------------- /src/test/vsrc/fpga/fpga_clock_gate.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC) 3 | * Copyright (c) 2020-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 | module fpga_clock_gate( 17 | input CK, 18 | input E, 19 | output Q 20 | ); 21 | 22 | `ifdef SYNTHESIS 23 | BUFGCE bufgce_1 ( 24 | .O(Q), 25 | .I(CK), 26 | .CE(E) 27 | ); 28 | `else 29 | assign Q = CK & E; 30 | `endif // SYNTHESIS 31 | endmodule -------------------------------------------------------------------------------- /src/test/scala/DifftestMain.scala: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2024 Beijing Institute of Open Source Chip (BOSC) 3 | * Copyright (c) 2020-2024 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 18 | 19 | import chisel3.stage.ChiselGeneratorAnnotation 20 | import circt.stage._ 21 | import app.DifftestApp 22 | 23 | object DifftestMain extends DifftestApp { 24 | (new ChiselStage).execute(firrtlOpts, Seq(ChiselGeneratorAnnotation(gen)) ++ firtoolOptions) 25 | } 26 | -------------------------------------------------------------------------------- /src/main/scala/fpga/AXI4.scala: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2025 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2025 Beijing Institute of Open Source Chip 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.fpga 18 | import chisel3._ 19 | import chisel3.util._ 20 | 21 | class AXI4StreamBundle(val dataWidth: Int) extends Bundle { 22 | val data = UInt(dataWidth.W) 23 | val last = Bool() 24 | } 25 | 26 | class AXI4Stream(val dataWidth: Int) extends DecoupledIO(new AXI4StreamBundle(dataWidth)) 27 | -------------------------------------------------------------------------------- /src/test/csrc/common/SimJTAG.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2024 Beijing Institute of Open Source Chip (BOSC) 3 | * Copyright (c) 2020-2024 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 | #ifndef __SIMJTAG_H 18 | #define __SIMJTAG_H 19 | 20 | #include "common.h" 21 | 22 | extern "C" void jtag_init(); 23 | extern "C" int jtag_tick(unsigned char *jtag_TCK, unsigned char *jtag_TMS, unsigned char *jtag_TDI, 24 | unsigned char *jtag_TRSTn, unsigned char jtag_TDO); 25 | #endif // __SIMJTAG_H 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: klin02, poemonsense 7 | 8 | --- 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | **Related component**: build | simulation framework | cosim with a REF 18 | 19 | **Is your feature request related to a problem? Please describe.** 20 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 21 | 22 | **Describe the solution you'd like** 23 | A clear and concise description of what you want to happen. 24 | 25 | **Describe alternatives you've considered** 26 | A clear and concise description of any alternative solutions or features you've considered. 27 | 28 | **Additional context** 29 | Add any other context or screenshots about the feature request here. 30 | -------------------------------------------------------------------------------- /fpga.mk: -------------------------------------------------------------------------------- 1 | FPGA_TARGET = $(BUILD_DIR)/fpga-host 2 | FPGA_CSRC_DIR = $(abspath ./src/test/csrc/fpga) 3 | FPGA_CONFIG_DIR = $(abspath ./config) # Reserve storage for xdma configuration 4 | 5 | DMA_CHANNELS ?= 1 6 | USE_SERIAL_PORT ?= 1 7 | 8 | FPGA_CXXFILES = $(SIM_CXXFILES) $(shell find $(FPGA_CSRC_DIR) -name "*.cpp") 9 | FPGA_CXXFLAGS = $(subst \\\",\", $(SIM_CXXFLAGS)) -I$(FPGA_CSRC_DIR) -DCONFIG_DMA_CHANNELS=$(DMA_CHANNELS) -DFPGA_HOST 10 | FPGA_CXXFLAGS += -std=c++11 -O3 -flto -march=native -mtune=native 11 | FPGA_LDFLAGS = $(SIM_LDFLAGS) -lpthread -ldl 12 | 13 | fpga-build: fpga-clean fpga-host 14 | 15 | ifneq ($(FPGA_SIM), 1) 16 | ifneq ($(USE_SERIAL_PORT), 0) 17 | FPGA_CXXFLAGS += -DUSE_SERIAL_PORT 18 | endif 19 | endif 20 | 21 | ifeq ($(USE_XDMA_DDR_LOAD), 1) 22 | FPGA_CXXFLAGS += -DUSE_XDMA_DDR_LOAD 23 | endif 24 | 25 | ifeq ($(USE_THREAD_MEMPOOL), 1) 26 | FPGA_CXXFLAGS += -DUSE_THREAD_MEMPOOL 27 | endif 28 | 29 | $(FPGA_TARGET): $(FPGA_CXXFILES) 30 | $(CXX) $(FPGA_CXXFLAGS) $(FPGA_CXXFILES) -o $@ $(FPGA_LDFLAGS) 31 | 32 | fpga-host: $(FPGA_TARGET) 33 | 34 | fpga-clean: 35 | rm -f $(FPGA_TARGET) 36 | 37 | RELEASE_DIR ?= $(NOOP_HOME) 38 | fpga-release: 39 | bash ./scripts/fpga/release.sh $(NOOP_HOME) $(RELEASE_DIR) 40 | -------------------------------------------------------------------------------- /src/test/csrc/fpga_sim/xdma_sim.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC) 3 | * Copyright (c) 2020-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 | #ifndef __XDMA_SIM_H__ 17 | #define __XDMA_SIM_H__ 18 | #include 19 | #include 20 | 21 | void xdma_sim_open(int channel, bool is_host); 22 | void xdma_sim_close(int channel); 23 | int xdma_sim_read(int channel, char *buf, size_t size); 24 | int xdma_sim_write(int channel, const char *buf, uint8_t tlast, size_t size); 25 | 26 | #endif // __XDMA_SIM_H__ 27 | -------------------------------------------------------------------------------- /src/test/csrc/common/flash.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | #ifndef __FLASH_H 18 | #define __FLASH_H 19 | 20 | #include "common.h" 21 | 22 | struct flash_device_t { 23 | uint64_t *base; 24 | uint64_t size; 25 | char *img_path; 26 | uint64_t img_size; 27 | }; 28 | 29 | extern flash_device_t flash_dev; 30 | 31 | void init_flash(const char *flash_bin); 32 | void flash_finish(); 33 | 34 | extern "C" void flash_read(uint32_t addr, uint64_t *data); 35 | #endif // __FLASH_H 36 | -------------------------------------------------------------------------------- /libso.mk: -------------------------------------------------------------------------------- 1 | LIBDIFFTEST_SO = $(BUILD_DIR)/libdifftest.so 2 | CC_OBJ_DIR = $(abspath $(BUILD_DIR)/cc_obj) 3 | 4 | LIB_CSRC_DIR = $(abspath ./src/test/csrc/vcs) 5 | LIB_CXXFILES = $(SIM_CXXFILES) $(shell find $(LIB_CSRC_DIR) -name "*.cpp") 6 | LIB_CXXFLAGS = -m64 -c -fPIC -g -std=c++11 7 | LIB_CXXFLAGS += $(subst \\\",\", $(SIM_CXXFLAGS)) $(SIM_LDFLAGS) -I$(LIB_CSRC_DIR) 8 | 9 | ifeq ($(WITH_DRAMSIM3),1) 10 | LD_LIB = -L $(DRAMSIM3_HOME)/ -ldramsim3 -Wl,-rpath-link=$(DRAMSIM3_HOME)/libdramsim3.so 11 | endif 12 | 13 | # Include headers that are implicitly included by RTL simulators 14 | # Priority: (1) VCS, (2) Verilator 15 | ifneq ($(VCS_HOME),) 16 | LIB_CXXFLAGS += -I$(VCS_HOME)/include 17 | else 18 | VERILATOR_ROOT ?= $(shell verilator --getenv VERILATOR_ROOT 2> /dev/null) 19 | ifneq ($(VERILATOR_ROOT),) 20 | LIB_CXXFLAGS += -I$(VERILATOR_ROOT)/include/vltstd 21 | else 22 | LIBSO_WARNING_MISSING_HEADERS = 1 23 | endif 24 | endif 25 | 26 | $(CC_OBJ_DIR): 27 | mkdir -p $(CC_OBJ_DIR) 28 | 29 | difftest-so: $(CC_OBJ_DIR) 30 | ifeq ($(LIBSO_WARNING_MISSING_HEADERS),1) 31 | @echo "No available RTL simulators. Headers may be missing. Still try to build it." 32 | endif 33 | cd $(CC_OBJ_DIR) && \ 34 | $(CC) $(LIB_CXXFLAGS) $(LIB_CXXFILES) && \ 35 | $(CC) -o $(LIBDIFFTEST_SO) -m64 -shared *.o $(LD_LIB) 36 | -------------------------------------------------------------------------------- /src/main/scala/util/Lookup.scala: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC) 3 | * Copyright (c) 2020-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 chisel3._ 20 | import chisel3.util._ 21 | 22 | object LookupSeq { 23 | def apply[T <: Data](key: UInt, default: T, mapping: Iterable[(UInt, T)]): T = 24 | MuxLookup(key, default)(mapping.toSeq) 25 | } 26 | 27 | object LookupTree { 28 | def apply[T <: Data](key: UInt, mapping: Iterable[(UInt, T)]): T = 29 | Mux1H(mapping.map(p => (p._1 === key, p._2))) 30 | } 31 | -------------------------------------------------------------------------------- /src/test/csrc/common/macro.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | #ifndef __MACRO_H__ 18 | #define __MACRO_H__ 19 | 20 | #define str_temp(x) #x 21 | #define str(x) str_temp(x) 22 | 23 | #define concat_temp(x, y) x##y 24 | #define concat(x, y) concat_temp(x, y) 25 | #define concat3(x, y, z) concat(concat(x, y), z) 26 | #define concat4(x, y, z, w) concat3(concat(x, y), z, w) 27 | #define concat5(x, y, z, v, w) concat4(concat(x, y), z, v, w) 28 | 29 | #define MAP(c, f) c(f) 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/main/scala/Coverage.scala: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2025 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC) 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 18 | 19 | import circt.stage.FirtoolOption 20 | 21 | object Coverage { 22 | def parseArgs(args: Array[String]): (Array[String], Seq[FirtoolOption]) = { 23 | val supportedCoverTypes = Seq("branch") 24 | val firtoolOptions = supportedCoverTypes.map(c => s"--extract-$c-cover") 25 | val partitioned = args.partition(firtoolOptions.contains) 26 | (partitioned._2, partitioned._1.map(FirtoolOption)) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /.scalafmt.conf: -------------------------------------------------------------------------------- 1 | # This file is partially adapted from github/alejandrohdezma/sbt-scalafmt-defaults at 2 | # https://github.com/alejandrohdezma/sbt-scalafmt-defaults/blob/main/.scalafmt.conf 3 | # Some changes have been made against the original file based on the scalafmt doc. 4 | 5 | version = "3.7.17" 6 | 7 | runner.dialect = scala213 8 | preset = default 9 | 10 | maxColumn = 120 11 | indent.defnSite = 2 12 | indent.extendSite = 2 13 | 14 | newlines.avoidForSimpleOverflow=[slc, tooLong] 15 | 16 | assumeStandardLibraryStripMargin = true 17 | align.stripMargin = true 18 | 19 | align.preset = some 20 | align.multiline = false 21 | 22 | binPack.literalsIncludeSimpleExpr = true 23 | binPack.literalsExclude = [ "Term.Name" ] 24 | 25 | docstrings.style = keep 26 | 27 | rewrite.rules = [ 28 | AvoidInfix, 29 | RedundantParens, 30 | SortModifiers, 31 | PreferCurlyFors, 32 | Imports 33 | ] 34 | rewrite.redundantBraces.methodBodies = false 35 | rewrite.redundantBraces.stringInterpolation = false 36 | rewrite.imports.sort = scalastyle 37 | rewrite.trailingCommas.style = multiple 38 | 39 | rewriteTokens = { 40 | "⇒": "=>" 41 | "→": "->" 42 | "←": "<-" 43 | } 44 | 45 | includeCurlyBraceInSelectChains = false 46 | 47 | project.includePaths = ["glob:**.scala", "glob:**.sbt", "glob:**.sc", "glob:**.md"] 48 | project.excludePaths = ["glob:**metals.sbt"] 49 | -------------------------------------------------------------------------------- /src/test/csrc/common/dut.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * 4 | * DiffTest is licensed under Mulan PSL v2. 5 | * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 | * You may obtain a copy of Mulan PSL v2 at: 7 | * http://license.coscl.org.cn/MulanPSL2 8 | * 9 | * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10 | * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11 | * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12 | * 13 | * See the Mulan PSL v2 for more details. 14 | ***************************************************************************************/ 15 | 16 | #include "dut.h" 17 | 18 | SimStats stats; 19 | 20 | extern "C" uint32_t get_cover_number() { 21 | if (auto c = stats.get_feedback_cover()) { 22 | return c->get_total_points(); 23 | } 24 | return 0; 25 | } 26 | 27 | extern "C" void update_stats(uint8_t *icover_bitmap) { 28 | if (auto c = stats.get_feedback_cover()) { 29 | c->to_covered_bytes(icover_bitmap); 30 | } 31 | } 32 | 33 | extern "C" void display_uncovered_points() { 34 | stats.display_uncovered_points(); 35 | } 36 | 37 | extern "C" void set_cover_feedback(const char *name) { 38 | stats.set_feedback_cover(name); 39 | } 40 | -------------------------------------------------------------------------------- /src/test/csrc/common/query.cpp: -------------------------------------------------------------------------------- 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 44 | -------------------------------------------------------------------------------- /src/test/vsrc/vcs/DeferredControl.v: -------------------------------------------------------------------------------- 1 | `include "DifftestMacros.svh" 2 | `ifndef TB_NO_DPIC 3 | `ifdef CONFIG_DIFFTEST_DEFERRED_RESULT 4 | module DeferredControl( 5 | input clock, 6 | input reset, 7 | `ifndef CONFIG_DIFFTEST_INTERNAL_STEP 8 | input [`CONFIG_DIFFTEST_STEPWIDTH - 1:0] step, 9 | `endif // CONFIG_DIFFTEST_INTERNAL_STEP 10 | output reg [7:0] simv_result 11 | ); 12 | 13 | import "DPI-C" context function void set_deferred_result_scope(); 14 | 15 | reg [7:0] _res; 16 | initial begin 17 | set_deferred_result_scope(); 18 | _res = 8'b0; 19 | end 20 | 21 | export "DPI-C" function set_deferred_result; 22 | function void set_deferred_result(byte result); 23 | _res = result; 24 | endfunction 25 | 26 | `ifdef PALLADIUM 27 | initial $ixc_ctrl("sfifo", "set_deferred_result"); 28 | `endif // PALLADIUM 29 | 30 | `ifndef CONFIG_DIFFTEST_INTERNAL_STEP 31 | import "DPI-C" function void simv_nstep(int step); 32 | `ifdef CONFIG_DIFFTEST_NONBLOCK 33 | `ifdef PALLADIUM 34 | initial $ixc_ctrl("gfifo", "simv_nstep"); 35 | `endif // PALLADIUM 36 | `endif // CONFIG_DIFFTEST_NONBLOCK 37 | `endif // CONFIG_DIFFTEST_INTERNAL_STEP 38 | 39 | 40 | always @(posedge clock) begin 41 | if (reset) begin 42 | simv_result <= 8'b0; 43 | end 44 | else begin 45 | simv_result <= _res; 46 | `ifndef CONFIG_DIFFTEST_INTERNAL_STEP 47 | if (step != 0) begin 48 | simv_nstep(step); 49 | end 50 | `endif // CONFIG_DIFFTEST_INTERNAL_STEP 51 | end 52 | end 53 | 54 | endmodule; 55 | `endif // CONFIG_DIFFTEST_DEFERRED_RESULT 56 | `endif // TB_NO_DPIC 57 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG] Describe the bug" 5 | labels: bug 6 | assignees: klin02, poemonsense 7 | 8 | --- 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | **Related component**: build | simulation framework | cosim with a REF 18 | 19 | **Describe the bug** 20 | A clear and concise description of what the bug is. 21 | 22 | 23 | 24 | **To Reproduce** 25 | Steps to reproduce the behavior: 26 | 1. Clone the repository 27 | 2. Edit '....' 28 | 3. Build with the command '....' 29 | 4. See error 30 | 31 | **Expected behavior** 32 | A clear and concise description of what you expected to happen. 33 | 34 | **Screenshots** 35 | If applicable, add screenshots to help explain your problem. 36 | 37 | 38 | 39 | **What you expect us (DiffTest developers) to do for you** 40 | 41 | **Additional context** 42 | Add any other context about the problem here. 43 | -------------------------------------------------------------------------------- /src/test/csrc/common/remote_bitbang.h: -------------------------------------------------------------------------------- 1 | // See LICENSE.Berkeley for license details. 2 | 3 | #ifndef REMOTE_BITBANG_H 4 | #define REMOTE_BITBANG_H 5 | 6 | #include 7 | #include 8 | 9 | extern bool enable_simjtag; 10 | extern uint16_t remote_jtag_port; 11 | 12 | extern "C" void jtag_init(); 13 | 14 | class remote_bitbang_t { 15 | public: 16 | // Create a new server, listening for connections from localhost on the given 17 | // port. 18 | remote_bitbang_t(uint16_t port); 19 | 20 | // Do a bit of work. 21 | void tick(unsigned char *jtag_tck, unsigned char *jtag_tms, unsigned char *jtag_tdi, unsigned char *jtag_trstn, 22 | unsigned char jtag_tdo); 23 | 24 | unsigned char done() { 25 | return quit; 26 | } 27 | 28 | int exit_code() { 29 | return err; 30 | } 31 | 32 | private: 33 | int err; 34 | 35 | unsigned char tck; 36 | unsigned char tms; 37 | unsigned char tdi; 38 | unsigned char trstn; 39 | unsigned char tdo; 40 | unsigned char quit; 41 | 42 | int socket_fd; 43 | int client_fd; 44 | 45 | static const ssize_t buf_size = 64 * 1024; 46 | char recv_buf[buf_size]; 47 | ssize_t recv_start, recv_end; 48 | 49 | // Check for a client connecting, and accept if there is one. 50 | void accept(); 51 | // Execute any commands the client has for us. 52 | // But we only execute 1 because we need time for the 53 | // simulation to run. 54 | void execute_command(); 55 | 56 | // Reset. Currently does nothing. 57 | void reset(); 58 | 59 | void set_pins(char _tck, char _tms, char _tdi); 60 | }; 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /src/test/csrc/plugin/simfrontend/debug.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2025 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC) 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 | #ifndef TRACE_DEBUG_H 18 | #define TRACE_DEBUG_H 19 | 20 | #ifdef ENABLE_TRACE_DEBUG 21 | 22 | #define DEBUG_INFO_IF(condition, ...) \ 23 | do { \ 24 | if (condition) { \ 25 | __VA_ARGS__; \ 26 | } \ 27 | } while (0) 28 | 29 | // Implement it anywhere when you need it. 30 | bool get_debug_flag(); 31 | 32 | #define DEBUG_INFO(code) \ 33 | if (get_debug_flag()) { \ 34 | std::cout << "[TRACE] "; \ 35 | code; \ 36 | } 37 | 38 | #else 39 | 40 | #define DEBUG_INFO_IF(condition, ...) 41 | #define DEBUG_INFO(code) 42 | 43 | #endif // ENABLE_DEBUG 44 | 45 | #endif // TRACE_DEBUG_H 46 | -------------------------------------------------------------------------------- /src/test/vsrc/fpga_sim/xdma_axi.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC) 3 | * Copyright (c) 2020-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 | `include "DifftestMacros.svh" 17 | module xdma_axi( 18 | input clock, 19 | input reset, 20 | input [511:0] axi_tdata, 21 | input axi_tlast, 22 | output axi_tready, 23 | input axi_tvalid 24 | ); 25 | 26 | import "DPI-C" function bit v_xdma_tready(); 27 | import "DPI-C" function void v_xdma_write( 28 | input byte channel, 29 | input bit [511:0] axi_tdata, 30 | input bit axi_tlast 31 | ); 32 | 33 | reg axi_tready_r; 34 | assign axi_tready = axi_tready_r; 35 | always @(posedge clock) begin 36 | if (reset) begin 37 | axi_tready_r <= 1'b0; 38 | end 39 | else begin 40 | axi_tready_r <= v_xdma_tready(); 41 | if (axi_tvalid & axi_tready) begin 42 | v_xdma_write(0, axi_tdata, axi_tlast); 43 | end 44 | end 45 | end 46 | 47 | endmodule 48 | -------------------------------------------------------------------------------- /src/test/vsrc/fpga_sim/xdma_clock.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC) 3 | * Copyright (c) 2020-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 | module xdma_clock( 17 | input clock, 18 | input core_clock_enable, 19 | output core_clock 20 | ); 21 | 22 | wire clock_in; 23 | `ifdef ASYNC_CLK_2N 24 | // core_clock = clock / (2 * ASYNC_CLK_2N) 25 | reg core_clock_r; 26 | reg [7:0] clk_cnt; 27 | initial begin 28 | core_clock_r = 0; 29 | clk_cnt = 0; 30 | end 31 | always @(posedge clock) begin 32 | if (clk_cnt == `ASYNC_CLK_2N - 1) begin 33 | clk_cnt <= 0; 34 | core_clock_r <= ~core_clock_r; 35 | end 36 | else begin 37 | clk_cnt <= clk_cnt + 1; 38 | end 39 | end 40 | assign clock_in = core_clock_r; 41 | `else 42 | assign clock_in = clock; 43 | `endif // ASYNC_CLK_2N 44 | 45 | fpga_clock_gate clk_gate( 46 | .CK(clock_in), 47 | .E(core_clock_enable), 48 | .Q(core_clock) 49 | ); 50 | endmodule 51 | -------------------------------------------------------------------------------- /src/test/vsrc/fpga_sim/xdma_wrapper.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC) 3 | * Copyright (c) 2020-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 | `include "DifftestMacros.svh" 17 | module xdma_wrapper( 18 | input clock, 19 | input reset, 20 | input core_clock_enable, 21 | input axi_c2h_tlast, 22 | output axi_c2h_tready, 23 | input axi_c2h_tvalid, 24 | input [511:0] axi_c2h_tdata, 25 | output core_clock 26 | ); 27 | 28 | wire [`CONFIG_DIFFTEST_BATCH_IO_WITDH - 1:0] axi_tdata; 29 | wire [63:0] axi_tkeep; 30 | wire axi_tlast; 31 | wire axi_tready; 32 | wire axi_tvalid; 33 | xdma_clock xclock( 34 | .clock(clock), 35 | .core_clock_enable(core_clock_enable), 36 | .core_clock(core_clock) 37 | ); 38 | 39 | xdma_axi xaxi( 40 | .clock(clock), 41 | .reset(reset), 42 | .axi_tdata(axi_c2h_tdata), 43 | .axi_tlast(axi_c2h_tlast), 44 | .axi_tready(axi_c2h_tready), 45 | .axi_tvalid(axi_c2h_tvalid) 46 | ); 47 | 48 | endmodule 49 | -------------------------------------------------------------------------------- /src/test/csrc/common/compress.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | #ifndef COMPRESS_H 18 | #define COMPRESS_H 19 | 20 | #include "common.h" 21 | #include 22 | #include 23 | #ifndef NO_GZ_COMPRESSION 24 | #include 25 | #endif 26 | #ifndef NO_ZSTD_COMPRESSION 27 | #include 28 | #endif 29 | 30 | #define LOAD_SNAPSHOT 0 31 | #define LOAD_RAM 1 32 | 33 | double calcTime(timeval s, timeval e); 34 | 35 | bool isGzFile(const char *filename); 36 | long snapshot_compressToFile(uint8_t *ptr, const char *filename, long buf_size); 37 | long readFromGz(void *ptr, const char *file_name, long buf_size, uint8_t load_type); 38 | 39 | void nonzero_large_memcpy(const void *__restrict dest, const void *__restrict src, size_t n); 40 | 41 | bool isZstdFile(const char *filename); 42 | long readFromZstd(void *ptr, const char *file_name, long buf_size, uint8_t load_type); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/test/csrc/verilator/waveform.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2025 Institute of Computing Technology, Chinese Academy of Sciences 3 | * 4 | * DiffTest is licensed under Mulan PSL v2. 5 | * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 | * You may obtain a copy of Mulan PSL v2 at: 7 | * http://license.coscl.org.cn/MulanPSL2 8 | * 9 | * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10 | * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11 | * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12 | * 13 | * See the Mulan PSL v2 for more details. 14 | ***************************************************************************************/ 15 | 16 | #ifndef __WAVEFORM_H 17 | #define __WAVEFORM_H 18 | 19 | #include "verilated.h" 20 | #ifdef ENABLE_FST 21 | #include 22 | #else 23 | #include 24 | #endif // ENABLE_FST 25 | 26 | using TraceBindFunc = std::function; 27 | 28 | class EmuWaveform { 29 | private: 30 | #ifdef ENABLE_FST 31 | VerilatedFstC *tfp; 32 | #else 33 | VerilatedVcdC *tfp; 34 | #endif 35 | 36 | // waveform clock: this may differ from the CPU clock 37 | uint64_t waveform_clock; 38 | 39 | const char *default_filename(uint64_t cycles); 40 | 41 | public: 42 | EmuWaveform(TraceBindFunc trace, uint64_t cycles); 43 | EmuWaveform(TraceBindFunc trace, uint64_t cycles, const char *filename); 44 | 45 | ~EmuWaveform() { 46 | if (tfp) { 47 | tfp->close(); 48 | delete tfp; 49 | } 50 | } 51 | 52 | void tick(); 53 | }; 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /src/test/csrc/plugin/runahead/memdep.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | #ifndef MEMDEP_H 18 | #define MEMDEP_H 19 | 20 | #include "common.h" 21 | #include 22 | 23 | typedef struct MemInstInfo { 24 | uint64_t pc; 25 | uint64_t vaddr; 26 | } MemInstInfo; 27 | 28 | class MemdepWatchWindow { 29 | public: 30 | void commit_load(); 31 | void commit_store(); 32 | void commit_load(uint64_t pc); 33 | void commit_store(uint64_t pc); 34 | void watch_load(uint64_t pc, uint64_t vaddr); 35 | void watch_store(uint64_t pc, uint64_t vaddr); 36 | bool query_load_store_dep(uint64_t load_pc, uint64_t load_vaddr); 37 | void update_pred_matrix(bool dut_result, bool ref_result); 38 | void print_pred_matrix(); 39 | 40 | private: 41 | std::deque store_inflight; 42 | std::deque load_inflight; 43 | uint64_t total_dependency = 0; 44 | uint64_t pred_matrix[2][2] = {}; 45 | }; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/test/csrc/common/perf.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2024 Institute of Computing Technology, Chinese Academy of Sciences 3 | * 4 | * DiffTest is licensed under Mulan PSL v2. 5 | * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 | * You may obtain a copy of Mulan PSL v2 at: 7 | * http://license.coscl.org.cn/MulanPSL2 8 | * 9 | * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10 | * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11 | * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12 | * 13 | * See the Mulan PSL v2 for more details. 14 | ***************************************************************************************/ 15 | 16 | #ifndef __PERF_H__ 17 | #define __PERF_H__ 18 | 19 | #include "common.h" 20 | 21 | #ifdef CONFIG_DIFFTEST_PERFCNT 22 | static inline void difftest_perfcnt_print(const char *name, long long calls, long long bytes, long long msec) { 23 | long long calls_mean = calls * 1000 / msec; 24 | long long bytes_mean = bytes * 1000 / msec; 25 | printf("%30s %15lld %15lld/s %15lldB %15lldB/s\n", name, calls, calls_mean, bytes, bytes_mean); 26 | } 27 | void difftest_perfcnt_init(); 28 | void difftest_perfcnt_finish(uint64_t cycleCnt); 29 | enum DIFFTEST_PERF { 30 | perf_difftest_nstep, 31 | perf_difftest_ram_read, 32 | perf_difftest_ram_write, 33 | perf_flash_read, 34 | perf_sd_set_addr, 35 | perf_sd_read, 36 | perf_jtag_tick, 37 | perf_put_pixel, 38 | perf_vmem_sync, 39 | perf_pte_helper, 40 | perf_amo_helper, 41 | DIFFTEST_PERF_NUM 42 | }; 43 | extern long long difftest_calls[DIFFTEST_PERF_NUM], difftest_bytes[DIFFTEST_PERF_NUM]; 44 | #endif // CONFIG_DIFFTEST_PERFCNT 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/test/csrc/plugin/simfrontend/simfrontend.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2025 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC) 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 | #ifndef SIMFRONTEND_H 18 | #define SIMFRONTEND_H 19 | 20 | #include 21 | #include 22 | 23 | // Align with the functions defined in the blackbox within chisel. 24 | extern "C" void SimFrontFetch(int offset, uint64_t *pc, uint32_t *instr, uint32_t *preDecode); 25 | extern "C" void SimFrontUpdatePtr(uint32_t updateCount); 26 | extern "C" void SimFrontRedirect(uint32_t redirect_valid, uint32_t redirect_ftq_flag, uint32_t redirect_ftq_value, 27 | uint32_t redirect_type, uint64_t redirect_pc, uint64_t redirect_target); 28 | extern "C" void SimFrontGetFtqToBackEnd(uint64_t *pc, uint32_t *pack_data, uint64_t *newest_pc, 29 | uint32_t *newest_pack_data); 30 | extern "C" void SimFrontRobCommit(uint32_t valid, uint32_t ftqIdxFlag, uint32_t ftqIdxValue); 31 | 32 | bool init_sim_frontend(const std::string &file); 33 | #endif // SIMFRONTEND_H 34 | -------------------------------------------------------------------------------- /scripts/coverage/vtransform.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import sys 5 | 6 | 7 | def create_cover_macros(build_path, off_filters): 8 | all_files = map(lambda f: os.path.join(build_path, f), os.listdir(build_path)) 9 | def is_vfile(f): return os.path.isfile(f) and f.endswith(".v") 10 | vfiles = [f for f in all_files if is_vfile(f)] 11 | for filename in vfiles: 12 | lines = [] 13 | need_update, in_module = False, False 14 | fh = open(filename, "r") 15 | for line in fh: 16 | e = line.strip().split() 17 | if e and e[0] == "module": 18 | module_name = e[1].split("//")[0].replace("(", "") 19 | if True in map(lambda f: f(module_name), off_filters): 20 | assert (not in_module) 21 | lines.append("/*verilator coverage_off*/\n") 22 | in_module = True 23 | need_update = True 24 | elif in_module and e and e[0] == "endmodule": 25 | lines.append("/*verilator coverage_on*/\n") 26 | in_module = False 27 | lines.append(line) 28 | fh.close() 29 | if need_update: 30 | fh = open(filename, "w") 31 | fh.writelines(lines) 32 | fh.close() 33 | 34 | 35 | def is_sram_array(name): 36 | return name.startswith("array_") and name.endswith("_ext") 37 | 38 | 39 | def is_difftest(name): 40 | return name.startswith("Difftest") 41 | 42 | 43 | def is_helper(name): 44 | helper_modules = [ 45 | "FBHelper", "SDHelper", "FlashHelper" 46 | ] 47 | return name in helper_modules 48 | 49 | 50 | if __name__ == "__main__": 51 | build_path = sys.argv[1] 52 | off_filters = [is_sram_array, is_difftest, is_helper] 53 | create_cover_macros(build_path, off_filters) 54 | -------------------------------------------------------------------------------- /src/main/scala/common/FileControl.scala: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2024 Institute of Computing Technology, Chinese Academy of Sciences 3 | * 4 | * DiffTest is licensed under Mulan PSL v2. 5 | * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 | * You may obtain a copy of Mulan PSL v2 at: 7 | * http://license.coscl.org.cn/MulanPSL2 8 | * 9 | * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10 | * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11 | * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12 | * 13 | * See the Mulan PSL v2 for more details. 14 | ***************************************************************************************/ 15 | 16 | package difftest.common 17 | 18 | import java.nio.charset.StandardCharsets 19 | import java.nio.file.{Files, Paths, StandardOpenOption} 20 | 21 | object FileControl { 22 | def write(fileStream: Iterable[String], fileName: String): Unit = write(fileStream, fileName, append = false) 23 | 24 | def write(fileStream: Iterable[String], fileName: String, append: Boolean): Unit = { 25 | val outputDir = Paths.get(sys.env("NOOP_HOME"), "build", "generated-src") 26 | write(fileStream, fileName, outputDir.toString, append) 27 | } 28 | 29 | def write(fileStream: Iterable[String], fileName: String, outputDir: String, append: Boolean): Unit = { 30 | Files.createDirectories(Paths.get(outputDir)) 31 | val wmode = if (append) StandardOpenOption.APPEND else StandardOpenOption.TRUNCATE_EXISTING 32 | Files.write( 33 | Paths.get(outputDir, fileName), 34 | (fileStream.mkString("\n") + "\n").getBytes(StandardCharsets.UTF_8), 35 | Seq(StandardOpenOption.CREATE, wmode): _* 36 | ) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/csrc/common/device.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | #include "device.h" 18 | #include "flash.h" 19 | #include "sdcard.h" 20 | #include "uart.h" 21 | #include "vga.h" 22 | #ifdef SHOW_SCREEN 23 | #include 24 | #endif 25 | 26 | void send_key(uint8_t, bool); 27 | 28 | void init_device(void) { 29 | #ifdef SHOW_SCREEN 30 | init_sdl(); 31 | #endif 32 | init_uart(); 33 | init_sd(); 34 | } 35 | 36 | void finish_device(void) { 37 | #ifdef SHOW_SCREEN 38 | finish_sdl(); 39 | #endif 40 | finish_uart(); 41 | finish_sd(); 42 | } 43 | 44 | void poll_event() { 45 | #ifdef SHOW_SCREEN 46 | SDL_Event event; 47 | while (SDL_PollEvent(&event)) { 48 | switch (event.type) { 49 | case SDL_QUIT: 50 | break; //set_abort(); 51 | 52 | // If a key was pressed 53 | case SDL_KEYDOWN: 54 | case SDL_KEYUP: { 55 | uint8_t k = event.key.keysym.scancode; 56 | bool is_keydown = (event.key.type == SDL_KEYDOWN); 57 | send_key(k, is_keydown); 58 | break; 59 | } 60 | default: break; 61 | } 62 | } 63 | #endif 64 | } 65 | -------------------------------------------------------------------------------- /src/test/csrc/plugin/simfrontend/tracereader.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2025 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC) 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 | #ifndef TRACEREADER_H 18 | #define TRACEREADER_H 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | class MmapLineReader { 26 | public: 27 | explicit MmapLineReader() = default; 28 | explicit MmapLineReader(const std::string &filename); 29 | 30 | bool is_final = false; 31 | 32 | bool is_open = false; 33 | 34 | ~MmapLineReader(); 35 | 36 | bool init(const std::string &filename); 37 | 38 | bool get_next_line(std::string_view &line); 39 | 40 | bool probe_next_line(std::string_view &line); 41 | 42 | size_t get_line_read_count() const; 43 | 44 | private: 45 | MmapLineReader(const MmapLineReader &) = delete; 46 | MmapLineReader &operator=(const MmapLineReader &) = delete; 47 | 48 | int fd = -1; 49 | char *mapped_data = nullptr; 50 | size_t file_size = 0; 51 | 52 | const char *read_ptr = nullptr; 53 | const char *end_of_file = nullptr; 54 | 55 | size_t lines_read = 0; 56 | }; 57 | 58 | #endif // TRACEREADER_H 59 | -------------------------------------------------------------------------------- /src/test/csrc/difftest/diffstate.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2025 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2025 Beijing Institute of Open Source Chip 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 | #include "diffstate.h" 18 | #include "spikedasm.h" 19 | 20 | void DiffState::display() { 21 | Info("\n============== Commit Group Trace (Core %d) ==============\n", coreid); 22 | int group_index = 0; 23 | while (!retire_group_queue.empty()) { 24 | auto retire_group = retire_group_queue.front(); 25 | auto pc = retire_group.first; 26 | auto cnt = retire_group.second; 27 | retire_group_queue.pop(); 28 | Info("commit group [%02d]: pc %010lx cmtcnt %d%s\n", group_index, pc, cnt, 29 | retire_group_queue.empty() ? " <--" : ""); 30 | group_index++; 31 | } 32 | 33 | Info("\n============== Commit Instr Trace ==============\n"); 34 | int commit_index = 0; 35 | while (!commit_trace.empty()) { 36 | CommitTrace *trace = commit_trace.front(); 37 | commit_trace.pop(); 38 | trace->display_line(commit_index, use_spike, commit_trace.empty()); 39 | commit_index++; 40 | } 41 | 42 | fflush(stdout); 43 | } 44 | 45 | DiffState::DiffState(int coreid) : use_spike(spike_valid()), coreid(coreid) {} 46 | -------------------------------------------------------------------------------- /src/test/csrc/fpga/serial_port.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC) 3 | * Copyright (c) 2020-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 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #ifdef USE_SERIAL_PORT 25 | 26 | class SerialPort { 27 | public: 28 | SerialPort(const char *device) : fd_(-1), device_(device) {} 29 | ~SerialPort(); 30 | void start() { 31 | running = true; 32 | open_port(B115200); 33 | read_thread = std::thread(&SerialPort::start_read_thread, this); 34 | write_thread = std::thread(&SerialPort::start_write_thread, this); 35 | } 36 | void stop() { 37 | running = false; 38 | if (read_thread.joinable()) { 39 | read_thread.join(); 40 | } 41 | if (write_thread.joinable()) { 42 | write_thread.join(); 43 | } 44 | } 45 | 46 | private: 47 | bool running = false; 48 | int fd_; 49 | const char *device_; 50 | std::thread read_thread; 51 | std::thread write_thread; 52 | bool open_port(int baudrate); 53 | void close_port(); 54 | void start_read_thread(); 55 | void start_write_thread(); 56 | }; 57 | 58 | #endif // USE_SERIAL_PORT 59 | -------------------------------------------------------------------------------- /src/test/csrc/emu/main.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2022 Peng Cheng Laboratory 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 | #include "common.h" 18 | #include "dut.h" 19 | #include "emu.h" 20 | 21 | #ifdef FUZZER_LIB 22 | 23 | extern "C" int sim_main(int argc, const char **argv); 24 | int sim_main(int argc, const char *argv[]) { 25 | optind = 1; 26 | 27 | stats.reset(); 28 | 29 | #else 30 | int main(int argc, const char *argv[]) { 31 | #endif // FUZZER_LIB 32 | common_init_without_assertion(argv[0]); 33 | 34 | // initialize the design-under-test (DUT) 35 | auto emu = new Emulator(argc, argv); 36 | 37 | // allow assertions only after DUT resets 38 | common_enable_assert(); 39 | 40 | // main simulation loop 41 | while (!emu->is_finished()) { 42 | emu->tick(); 43 | } 44 | bool is_good = emu->is_good(); 45 | delete emu; 46 | 47 | #ifdef FUZZER_LIB 48 | stats.accumulate(); 49 | #endif 50 | stats.display(); 51 | 52 | common_finish(); 53 | 54 | #if defined(FUZZING) && !defined(FUZZER_LIB) 55 | if (!is_good) { 56 | volatile uint64_t *ptr = 0; 57 | uint64_t a = *ptr; 58 | } 59 | return 0; 60 | #else 61 | #ifdef FUZZER_LIB 62 | return !is_good || stats.exit_code == SimExitCode::unknown; 63 | #else 64 | return !is_good; 65 | #endif // FUZZER_LIB 66 | #endif // FUZZING && !FUZZER_LIB 67 | } 68 | -------------------------------------------------------------------------------- /pdb.mk: -------------------------------------------------------------------------------- 1 | PYTHON_DIR = $(abspath $(BUILD_DIR)/xspdb/pydifftest) 2 | PDB_OBJ_DIR = $(abspath $(BUILD_DIR)/xspdb/swig_obj) 3 | 4 | picker_include = $(shell picker --show_xcom_lib_location_cpp|grep include|awk '{print $$2}') 5 | 6 | PDB_SWIG_DIR = $(abspath src/test/csrc/plugin/xspdb) 7 | PDB_CXXFILES = $(SIM_CXXFILES) $(shell find $(PDB_SWIG_DIR)/cpp -name "*.cpp") $(shell find $(SIM_CONFIG_DIR) -name "*.cpp") 8 | PDB_CXXFLAGS = $(LIB_CXXFLAGS) $(subst \\\",\", $(SIM_CXXFLAGS)) 9 | 10 | ifeq ($(WITH_DRAMSIM3),1) 11 | PDB_LD_LIB = -L $(DRAMSIM3_HOME)/ -ldramsim3 -Wl,-rpath-link=$(DRAMSIM3_HOME)/libdramsim3.so 12 | endif 13 | 14 | PDB_CXXFLAGS += -I$(VCS_HOME)/include $(shell python3-config --includes) -I$(PDB_SWIG_DIR)/cpp 15 | PDB_LD_LIB += $(shell python3-config --ldflags) 16 | 17 | 18 | SWIG_INCLUDE = $(filter -I%, $(PDB_CXXFLAGS)) -I$(picker_include) 19 | ifeq ($(WITH_CHISELDB), 1) 20 | SWIG_D += -DENABLE_CHISEL_DB 21 | endif 22 | 23 | pydifftest: $(PYTHON_DIR)/_difftest.so 24 | 25 | $(PDB_OBJ_DIR)/python.i: 26 | rm -rf $(PDB_OBJ_DIR) $(PYTHON_DIR) 27 | mkdir -p $(PDB_OBJ_DIR) 28 | mkdir -p $(PYTHON_DIR) 29 | cp $(PDB_SWIG_DIR)/swig.i $(PDB_OBJ_DIR)/python.i 30 | echo "%extend DiffTestState {" >> $(PDB_OBJ_DIR)/python.i 31 | cat $(BUILD_DIR)/generated-src/difftest-state.h|grep Difftest|grep "\["|sed "s/\[/\ /g"|sed "s/\]/\ /g"|awk '{print $$1 " *get_"$$2"(int index){if(index<"$$3"){return &(self->"$$2"[index]);} return NULL;}"}' >> $(PDB_OBJ_DIR)/python.i 32 | echo "}" >> $(PDB_OBJ_DIR)/python.i 33 | 34 | $(PDB_OBJ_DIR)/difftest_wrap.cpp: $(PDB_OBJ_DIR)/python.i 35 | swig -c++ -outdir $(PYTHON_DIR) -o $(PDB_OBJ_DIR)/difftest_wrap.cpp $(SWIG_INCLUDE) -python $(SWIG_D) $(PDB_OBJ_DIR)/python.i 36 | $(eval PDB_CXXFILES = $(PDB_CXXFILES) $(PDB_OBJ_DIR)/difftest_wrap.cpp) 37 | 38 | $(PYTHON_DIR)/_difftest.so: $(PDB_OBJ_DIR)/difftest_wrap.cpp 39 | cd $(PDB_OBJ_DIR) && \ 40 | $(CC) $(PDB_CXXFLAGS) $(PDB_CXXFILES) && \ 41 | $(CC) -o $(PYTHON_DIR)/_difftest.so -m64 -shared *.o $(PDB_LD_LIB) $(SIM_LDFLAGS) 42 | echo $(SIM_LDFLAGS) > $(PYTHON_DIR)/sim_ld_flags.txt 43 | -------------------------------------------------------------------------------- /src/test/csrc/plugin/xspdb/cpp/export.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "export.h" 3 | 4 | Difftest *GetDifftest(int index) { 5 | if (index < NUM_CORES) 6 | return difftest[index]; 7 | return NULL; 8 | } 9 | 10 | void InitRam(std::string image, uint64_t n_bytes) { 11 | init_ram(image.c_str(), n_bytes); 12 | } 13 | 14 | void InitFlash(std::string flash_bin) { 15 | if (flash_bin.empty()) { 16 | init_flash(0); 17 | return; 18 | } 19 | init_flash(flash_bin.c_str()); 20 | } 21 | 22 | uint64_t FlashRead(uint32_t addr) { 23 | uint64_t data; 24 | flash_read(addr, &data); 25 | return data; 26 | } 27 | 28 | int FlashWrite(uint32_t addr, uint64_t data) { 29 | if (!flash_dev.base) { 30 | return -1; 31 | } 32 | uint32_t aligned_addr = addr & FLASH_ALIGH_MASK; 33 | uint64_t rIdx = aligned_addr / sizeof(uint64_t); 34 | if (rIdx >= flash_dev.size / sizeof(uint64_t)) { 35 | printf("[warning] read addr %x is out of bound\n", addr); 36 | return -1; 37 | } else { 38 | flash_dev.base[rIdx] = data; 39 | } 40 | return 0; 41 | } 42 | 43 | flash_device_t *GetFlash() { 44 | return &flash_dev; 45 | } 46 | 47 | int _diff_stat = -1; 48 | bool DifftestStepAndCheck(uint64_t pin, uint64_t val, uint64_t arg) { 49 | _diff_stat = difftest_nstep(1, true); 50 | return _diff_stat != STATE_RUNNING; 51 | } 52 | 53 | uint64_t GetFuncAddressOfDifftestStepAndCheck() { 54 | return (uint64_t)DifftestStepAndCheck; 55 | } 56 | 57 | int GetDifftestStat() { 58 | return _diff_stat; 59 | } 60 | 61 | void GoldenMemInit() { 62 | init_goldenmem(); 63 | } 64 | 65 | void GoldenMemFinish() { 66 | goldenmem_finish(); 67 | } 68 | 69 | void SetProxyRefSo(uint64_t addr) { 70 | difftest_ref_so = (const char *)addr; 71 | } 72 | 73 | uint64_t GetProxyRefSo() { 74 | return (uint64_t)difftest_ref_so; 75 | } 76 | 77 | uint64_t Get_PMEM_BASE() { 78 | return PMEM_BASE; 79 | } 80 | 81 | uint64_t Get_FIRST_INST_ADDRESS() { 82 | return FIRST_INST_ADDRESS; 83 | } 84 | 85 | void Set_PMEM_BASE(uint64_t v) { 86 | PMEM_BASE = v; 87 | } 88 | 89 | void Set_FIRST_INST_ADDRESS(uint64_t v) { 90 | FIRST_INST_ADDRESS = v; 91 | } 92 | -------------------------------------------------------------------------------- /src/test/csrc/common/sdcard.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | #include "sdcard.h" 18 | #include "common.h" 19 | #ifdef CONFIG_DIFFTEST_PERFCNT 20 | #include "perf.h" 21 | #endif // CONFIG_DIFFTEST_PERFCNT 22 | 23 | FILE *fp = NULL; 24 | 25 | void check_sdcard() { 26 | if (!fp) { 27 | eprintf(ANSI_COLOR_MAGENTA "[warning] sdcard img not found\n"); 28 | } 29 | } 30 | 31 | void sd_setaddr(uint32_t addr) { 32 | #ifdef CONFIG_DIFFTEST_PERFCNT 33 | difftest_calls[perf_sd_set_addr]++; 34 | difftest_bytes[perf_sd_set_addr] += 4; 35 | #endif // CONFIG_DIFFTEST_PERFCNT 36 | check_sdcard(); 37 | #ifdef SDCARD_IMAGE 38 | fseek(fp, addr, SEEK_SET); 39 | #endif 40 | //printf("set addr to 0x%08x\n", addr); 41 | //assert(0); 42 | } 43 | 44 | void sd_read(uint32_t *data) { 45 | #ifdef CONFIG_DIFFTEST_PERFCNT 46 | difftest_calls[perf_sd_read]++; 47 | difftest_bytes[perf_sd_read] += 4; 48 | #endif // CONFIG_DIFFTEST_PERFCNT 49 | check_sdcard(); 50 | #ifdef SDCARD_IMAGE 51 | fread(data, 4, 1, fp); 52 | #endif 53 | //printf("read data = 0x%08x\n", *data); 54 | //assert(0); 55 | } 56 | 57 | void init_sd(void) { 58 | #ifdef SDCARD_IMAGE 59 | fp = fopen(SDCARD_IMAGE, "r"); 60 | check_sdcard(); 61 | #endif 62 | } 63 | 64 | void finish_sd(void) { 65 | #ifdef SDCARD_IMAGE 66 | fclose(fp); 67 | #endif 68 | } 69 | -------------------------------------------------------------------------------- /src/test/vsrc/common/ref.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | `ifndef TB_NO_DPIC 18 | import "DPI-C" function byte pte_helper ( 19 | input longint satp, 20 | input longint vpn, 21 | output longint pte, 22 | output byte level 23 | ); 24 | `endif // TB_NO_DPIC 25 | 26 | module PTEHelper( 27 | input clock, 28 | input enable, 29 | input [63:0] satp, 30 | input [63:0] vpn, 31 | output reg [63:0] pte, 32 | output reg [ 7:0] level, 33 | output reg [ 7:0] pf 34 | ); 35 | always @(posedge clock) begin 36 | if (enable) begin 37 | `ifndef TB_NO_DPIC 38 | pf <= pte_helper(satp, vpn, pte, level); 39 | `endif // TB_NO_DPIC 40 | end 41 | end 42 | endmodule 43 | 44 | `ifndef TB_NO_DPIC 45 | import "DPI-C" function longint amo_helper( 46 | input byte cmd, 47 | input longint addr, 48 | input longint wdata, 49 | input byte mask 50 | ); 51 | `endif // TB_NO_DPIC 52 | 53 | module AMOHelper( 54 | input clock, 55 | input enable, 56 | input [ 4:0] cmd, 57 | input [63:0] addr, 58 | input [63:0] wdata, 59 | input [ 7:0] mask, 60 | output reg [63:0] rdata 61 | ); 62 | 63 | always @(posedge clock) begin 64 | if (enable) begin 65 | `ifndef TB_NO_DPIC 66 | rdata <= amo_helper(cmd, addr, wdata, mask); 67 | `endif // TB_NO_DPIC 68 | end 69 | end 70 | 71 | endmodule 72 | -------------------------------------------------------------------------------- /src/test/csrc/difftest/goldenmem.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | #ifndef __MEMORY_PADDR_H__ 18 | #define __MEMORY_PADDR_H__ 19 | 20 | #include "common.h" 21 | #include "ram.h" 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | typedef uint64_t uint64_t; 29 | typedef uint64_t word_t; 30 | 31 | extern uint8_t *pmem; 32 | extern uint8_t *pmem_flag; 33 | 34 | void init_goldenmem(); 35 | void goldenmem_finish(); 36 | 37 | extern "C" void update_goldenmem(uint64_t addr, void *data, uint64_t mask, int len, uint8_t flag = 0); 38 | extern "C" void read_goldenmem(uint64_t addr, void *data, uint64_t len, void *flag = NULL); 39 | 40 | /* convert the guest physical address in the guest program to host virtual address in NEMU */ 41 | void *guest_to_host(uint64_t addr); 42 | /* convert the host virtual address in NEMU to guest physical address in the guest program */ 43 | uint64_t host_to_guest(void *addr); 44 | 45 | word_t paddr_read(uint64_t addr, int len); 46 | word_t paddr_flag_read(uint64_t addr, int len); 47 | void paddr_write(uint64_t addr, word_t data, word_t flag, int len); 48 | bool is_sfence_safe(uint64_t addr, int len); 49 | bool in_pmem(uint64_t addr); 50 | 51 | #ifdef ENABLE_STORE_LOG 52 | void goldenmem_set_store_log(bool enable); 53 | void goldenmem_store_log_reset(); 54 | void goldenmem_store_log_restore(); 55 | #endif 56 | #endif 57 | -------------------------------------------------------------------------------- /src/main/scala/util/Delayer.scala: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2024 Beijing Institute of Open Source Chip (BOSC) 3 | * Copyright (c) 2020-2024 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 chisel3._ 20 | import chisel3.util._ 21 | 22 | private class Delayer[T <: Data](gen: T, n_cycles: Int) extends Module { 23 | val i = IO(Input(chiselTypeOf(gen))) 24 | val o = IO(Output(chiselTypeOf(gen))) 25 | } 26 | 27 | private class DelayReg[T <: Data](gen: T, n_cycles: Int) extends Delayer(gen, n_cycles) { 28 | var r = WireInit(i) 29 | for (_ <- 0 until n_cycles) { 30 | r = RegNext(r, 0.U.asTypeOf(gen)) 31 | } 32 | o := r 33 | } 34 | 35 | private class DelayMem[T <: Data](gen: T, n_cycles: Int) extends Delayer(gen, n_cycles) { 36 | val mem = Mem(n_cycles, chiselTypeOf(gen)) 37 | val ptr = RegInit(0.U(log2Ceil(n_cycles).W)) 38 | val init_flag = RegInit(false.B) 39 | mem(ptr) := i 40 | ptr := ptr + 1.U 41 | when(ptr === (n_cycles - 1).U) { 42 | init_flag := true.B 43 | ptr := 0.U 44 | } 45 | o := Mux(init_flag, mem(ptr), 0.U.asTypeOf(gen)) 46 | } 47 | 48 | object Delayer { 49 | def apply[T <: Data](gen: T, n_cycles: Int, useMem: Boolean = false): T = { 50 | if (n_cycles > 0) { 51 | val delayer = if (useMem) { 52 | Module(new DelayMem(gen, n_cycles)) 53 | } else { 54 | Module(new DelayReg(gen, n_cycles)) 55 | } 56 | delayer.i := gen 57 | delayer.o 58 | } else { 59 | gen 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/test/csrc/verilator/waveform.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2025 Institute of Computing Technology, Chinese Academy of Sciences 3 | * 4 | * DiffTest is licensed under Mulan PSL v2. 5 | * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 | * You may obtain a copy of Mulan PSL v2 at: 7 | * http://license.coscl.org.cn/MulanPSL2 8 | * 9 | * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10 | * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11 | * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12 | * 13 | * See the Mulan PSL v2 for more details. 14 | ***************************************************************************************/ 15 | 16 | #include "waveform.h" 17 | #include "common.h" 18 | 19 | EmuWaveform::EmuWaveform(TraceBindFunc trace, uint64_t cycles) : EmuWaveform(trace, cycles, default_filename(cycles)) {} 20 | 21 | EmuWaveform::EmuWaveform(TraceBindFunc trace, uint64_t cycles, const char *filename) : waveform_clock(cycles) { 22 | #if VM_TRACE == 1 23 | Verilated::traceEverOn(true); // Verilator must compute traced signals 24 | 25 | #ifdef ENABLE_FST 26 | tfp = new VerilatedFstC; 27 | #else 28 | tfp = new VerilatedVcdC; 29 | #endif 30 | 31 | trace(tfp, 99); // Trace 99 levels of hierarchy 32 | 33 | tfp->open(filename); 34 | Info("dump wave to %s...\n", filename); 35 | #endif // VM_TRACE == 1 36 | } 37 | 38 | const char *EmuWaveform::default_filename(uint64_t cycles) { 39 | char buf[32]; 40 | 41 | // append cycle count to filename if cycles > 0 42 | int cycle_len = 0; 43 | if (cycles > 0) { 44 | cycle_len = snprintf(buf, sizeof(buf), "_%ld", cycles); 45 | } 46 | 47 | // append suffix based on ENABLE_FST 48 | #ifdef ENABLE_FST 49 | const char *suffix = ".fst"; 50 | #else 51 | const char *suffix = ".vcd"; 52 | #endif 53 | int len = snprintf(buf + cycle_len, sizeof(buf) - cycle_len, "%s", suffix); 54 | assert(len == strlen(suffix)); 55 | 56 | return create_noop_filename(buf); 57 | } 58 | 59 | void EmuWaveform::tick() { 60 | #if VM_TRACE == 1 61 | tfp->dump(waveform_clock); 62 | waveform_clock++; 63 | #endif // VM_TRACE == 1 64 | } 65 | -------------------------------------------------------------------------------- /src/test/csrc/difftest/difftrace.h: -------------------------------------------------------------------------------- 1 | #ifndef __DIFFTRACE_H__ 2 | #define __DIFFTRACE_H__ 3 | 4 | #include "common.h" 5 | #ifdef CONFIG_DIFFTEST_IOTRACE 6 | #include "difftest-iotrace.h" 7 | #endif // CONFIG_DIFFTEST_IOTRACE 8 | #ifdef CONFIG_IOTRACE_ZSTD 9 | #include 10 | #include 11 | #include 12 | #include 13 | #endif // CONFIG_IOTRACE_ZSTD 14 | 15 | #ifdef CONFIG_IOTRACE_ZSTD 16 | class DiffTraceZstd { 17 | public: 18 | int trace_load_len = 0; 19 | bool need_load_new_file = true; 20 | 21 | DiffTraceZstd(uint64_t buffer_size) { 22 | trace_buffer_size = buffer_size; 23 | max_compress_size = 5000 * trace_buffer_size / 10; 24 | max_dcompress_size = 5000 * trace_buffer_size; 25 | io_trace_buffer.reserve(max_dcompress_size); 26 | }; 27 | 28 | ~DiffTraceZstd() { 29 | ZSTD_freeCCtx(trace_cctx); 30 | } 31 | 32 | void diff_zstd_next(const char *file_name, bool is_read); 33 | 34 | void diff_IOtrace_dump(const char *str, uint64_t len); 35 | 36 | bool diff_IOtrace_load(char *buffer, uint64_t len); 37 | int diff_IOtrace_ZstdDcompress(); 38 | 39 | private: 40 | uint64_t trace_buffer_size = 0; 41 | uint64_t max_compress_size = 0; // The number of bytes in a single compression 42 | uint64_t max_dcompress_size = 0; 43 | std::vector io_trace_buffer; 44 | 45 | ZSTD_CCtx *trace_cctx = NULL; 46 | ZSTD_DCtx *trace_dctx = NULL; 47 | std::fstream io_trace_file; 48 | }; 49 | #endif // CONFIG_IOTRACE_ZSTD 50 | 51 | template class DiffTrace { 52 | public: 53 | char trace_name[32]; 54 | bool is_read; 55 | #ifdef CONFIG_IOTRACE_ZSTD 56 | DiffTraceZstd *trace_zstd = NULL; 57 | #endif // CONFIG_IOTRACE_ZSTD 58 | 59 | DiffTrace(const char *trace_name, bool is_read, uint64_t buffer_size = 1024 * 1024); 60 | ~DiffTrace() { 61 | if (!is_read) { 62 | trace_file_next(); 63 | } 64 | if (buffer) { 65 | free(buffer); 66 | } 67 | #ifdef CONFIG_IOTRACE_ZSTD 68 | delete trace_zstd; 69 | #endif // CONFIG_IOTRACE_ZSTD 70 | } 71 | bool append(const T *trace); 72 | bool read_next(T *trace); 73 | void next_file_name(char *file_name); 74 | 75 | private: 76 | uint64_t buffer_size; 77 | uint64_t buffer_count = 0; 78 | T *buffer = nullptr; 79 | 80 | bool trace_file_next(); 81 | }; 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /src/test/csrc/common/lightsss.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | #ifndef __LIGHTSSS_H 18 | #define __LIGHTSSS_H 19 | 20 | #include "common.h" 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | typedef struct shinfo { 31 | bool flag; 32 | bool notgood; 33 | uint64_t endCycles; 34 | pid_t oldest; 35 | } shinfo; 36 | 37 | class ForkShareMemory { 38 | private: 39 | key_t key_n; 40 | int shm_id; 41 | 42 | public: 43 | shinfo *info; 44 | 45 | ForkShareMemory(); 46 | ~ForkShareMemory(); 47 | 48 | void shwait(); 49 | }; 50 | 51 | const int FORK_OK = 0; 52 | const int FORK_ERROR = 1; 53 | const int FORK_CHILD = 2; 54 | 55 | class LightSSS { 56 | pid_t pid = -1; 57 | int slotCnt = 0; 58 | int waitProcess = 0; 59 | // front() is the newest. back() is the oldest. 60 | std::deque pidSlot = {}; 61 | ForkShareMemory forkshm; 62 | 63 | public: 64 | int do_fork(); 65 | int wakeup_child(uint64_t cycles); 66 | bool is_child(); 67 | int do_clear(); 68 | uint64_t get_end_cycles() { 69 | return forkshm.info->endCycles; 70 | } 71 | }; 72 | 73 | #define FORK_PRINTF(format, args...) \ 74 | do { \ 75 | Info("[FORK_INFO pid(%d)] " format, getpid(), ##args); \ 76 | fflush(stdout); \ 77 | } while (0); 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /src/test/csrc/plugin/xspdb/swig.i: -------------------------------------------------------------------------------- 1 | %module difftest 2 | 3 | /* 4 | * Make SWIG ignore GCC-style attributes like __attribute__((packed)) 5 | * for parsing only. Do NOT redefine it in the generated wrapper code 6 | * to avoid ABI/layout mismatches with the compiled library. 7 | */ 8 | %define __attribute__(x) 9 | %enddef 10 | 11 | /* Also ignore common attribute aliases used in headers */ 12 | %define __packed 13 | %enddef 14 | %define __aligned(x) 15 | %enddef 16 | 17 | %{ 18 | #include "difftest.h" 19 | #include "export.h" 20 | #include "ram.h" 21 | #include "flash.h" 22 | #include "device.h" 23 | #include "difftest-state.h" 24 | #include "difftrace.h" 25 | #include "refproxy.h" 26 | %} 27 | 28 | #ifdef ENABLE_CHISEL_DB 29 | %{ 30 | #include "perfCCT.h" 31 | #include "chisel_db.h" 32 | %} 33 | #endif 34 | 35 | %apply unsigned long long {u_int64_t} 36 | %apply unsigned int {u_uint32_t} 37 | %apply unsigned short {u_uint16_t} 38 | %apply unsigned char {u_uint8_t} 39 | %apply unsigned long long {uint64_t} 40 | %apply unsigned int {uint32_t} 41 | %apply unsigned short {uint16_t} 42 | %apply unsigned char {uint8_t} 43 | %apply long long {i_int64_t} 44 | %apply int {i_int32_t} 45 | %apply short {i_int16_t} 46 | %apply char {i_int8_t} 47 | %apply long long {int64_t} 48 | %apply int {int32_t} 49 | %apply short {int16_t} 50 | %apply char {int8_t} 51 | 52 | %include stdint.i 53 | %include std_string.i 54 | %include std_map.i 55 | %include std_vector.i 56 | 57 | #ifdef ENABLE_CHISEL_DB 58 | %ignore std::mutex::mutex(const std::mutex&); 59 | %ignore std::mutex::operator=; 60 | #endif 61 | 62 | %include "difftest.h" 63 | %include "export.h" 64 | %include "ram.h" 65 | %include "flash.h" 66 | %include "device.h" 67 | %include "difftest-state.h" 68 | %include "difftrace.h" 69 | %include "refproxy.h" 70 | 71 | #ifdef ENABLE_CHISEL_DB 72 | %include "perfCCT.h" 73 | %include "chisel_db.h" 74 | #endif 75 | 76 | %define GAL_METHODS(STRUCT_TYPE, MEMBER) 77 | %extend STRUCT_TYPE { 78 | uint64_t get_##MEMBER##_address() { 79 | return (uint64_t)((void*)&(self->MEMBER)); 80 | } 81 | uint64_t get_##MEMBER##_length() { 82 | return (uint64_t)(sizeof(self->MEMBER)); 83 | } 84 | } 85 | %enddef 86 | 87 | GAL_METHODS(DifftestInstrCommit, pc) 88 | GAL_METHODS(DifftestInstrCommit, valid) 89 | GAL_METHODS(DifftestInstrCommit, instr) 90 | GAL_METHODS(DifftestTrapEvent, pc) 91 | GAL_METHODS(DifftestTrapEvent, code) 92 | GAL_METHODS(DifftestTrapEvent, hasTrap) 93 | -------------------------------------------------------------------------------- /src/test/csrc/common/vga.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | #include "vga.h" 18 | #include "common.h" 19 | #ifdef CONFIG_DIFFTEST_PERFCNT 20 | #include "perf.h" 21 | #endif // CONFIG_DIFFTEST_PERFCNT 22 | #ifdef SHOW_SCREEN 23 | #include 24 | 25 | #define SCREEN_PORT 0x100 // Note that this is not the standard 26 | #define SCREEN_MMIO 0x4100 27 | #define SCREEN_H 600 28 | #define SCREEN_W 800 29 | 30 | static uint32_t vmem[800 * 600]; 31 | 32 | static SDL_Window *window; 33 | static SDL_Renderer *renderer; 34 | static SDL_Texture *texture; 35 | 36 | void put_pixel(uint32_t pixel) { 37 | #ifdef CONFIG_DIFFTEST_PERFCNT 38 | difftest_calls[perf_put_pixel]++; 39 | difftest_bytes[perf_put_pixel] += 4; 40 | #endif // CONFIG_DIFFTEST_PERFCNT 41 | static int i = 0; 42 | vmem[i++] = pixel; 43 | if (i >= 800 * 600) 44 | i = 0; 45 | } 46 | 47 | void vmem_sync(void) { 48 | #ifdef CONFIG_DIFFTEST_PERFCNT 49 | difftest_calls[perf_vmem_sync]++; 50 | #endif // CONFIG_DIFFTEST_PERFCNT 51 | SDL_UpdateTexture(texture, NULL, vmem, SCREEN_W * sizeof(uint32_t)); 52 | SDL_RenderClear(renderer); 53 | SDL_RenderCopy(renderer, texture, NULL, NULL); 54 | SDL_RenderPresent(renderer); 55 | } 56 | 57 | void init_sdl() { 58 | SDL_Init(SDL_INIT_VIDEO); 59 | SDL_CreateWindowAndRenderer(SCREEN_W, SCREEN_H, 0, &window, &renderer); 60 | SDL_SetWindowTitle(window, "NOOP"); 61 | texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, SCREEN_W, SCREEN_H); 62 | } 63 | 64 | void finish_sdl() { 65 | memset(vmem, 0, sizeof(vmem)); 66 | } 67 | #else 68 | void put_pixel(uint32_t pixel) {} 69 | void vmem_sync(void) {} 70 | #endif 71 | -------------------------------------------------------------------------------- /src/test/csrc/common/perf.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2024 Institute of Computing Technology, Chinese Academy of Sciences 3 | * 4 | * DiffTest is licensed under Mulan PSL v2. 5 | * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 | * You may obtain a copy of Mulan PSL v2 at: 7 | * http://license.coscl.org.cn/MulanPSL2 8 | * 9 | * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10 | * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11 | * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12 | * 13 | * See the Mulan PSL v2 for more details. 14 | ***************************************************************************************/ 15 | 16 | #ifdef CONFIG_DIFFTEST_PERFCNT 17 | #include "perf.h" 18 | #include 19 | 20 | long long perf_run_msec = 0; 21 | long long difftest_calls[DIFFTEST_PERF_NUM] = {0}, difftest_bytes[DIFFTEST_PERF_NUM] = {0}; 22 | 23 | void difftest_perfcnt_init() { 24 | struct timespec ts; 25 | clock_gettime(CLOCK_MONOTONIC, &ts); 26 | perf_run_msec = ts.tv_sec * 1000 + ts.tv_nsec / 1000000; 27 | for (int i = 0; i < DIFFTEST_PERF_NUM; i++) { 28 | difftest_calls[i] = 0; 29 | difftest_bytes[i] = 0; 30 | } 31 | diffstate_perfcnt_init(); 32 | } 33 | 34 | void difftest_perfcnt_finish(uint64_t cycleCnt) { 35 | printf("==================== Difftest PerfCnt ====================\n"); 36 | struct timespec ts; 37 | clock_gettime(CLOCK_MONOTONIC, &ts); 38 | perf_run_msec = ts.tv_sec * 1000 + ts.tv_nsec / 1000000 - perf_run_msec; 39 | printf("Run time: %lld s %lld ms\n", perf_run_msec / 1000, perf_run_msec % 1000); 40 | float speed = (float)cycleCnt / (float)perf_run_msec; 41 | printf("Simulation speed: %.2f KHz\n", speed); 42 | printf("%30s %15s %17s %16s %18s\n", "DPIC_FUNC", "DPIC_CALLS", "DPIC_CALLS/s", "DPIC_BYTES", "DPIC_BYTES/s"); 43 | printf(">>> DiffState Func\n"); 44 | diffstate_perfcnt_finish(perf_run_msec); 45 | printf(">>> Other Difftest Func\n"); 46 | const char *func_name[DIFFTEST_PERF_NUM] = { 47 | "difftest_nstep", "difftest_ram_read", "difftest_ram_write", "flash_read", "sd_set_addr", "sd_read", 48 | "jtag_tick", "put_pixel", "vmem_sync", "pte_helper", "amo_helper", 49 | }; 50 | for (int i = 0; i < DIFFTEST_PERF_NUM; i++) { 51 | difftest_perfcnt_print(func_name[i], difftest_calls[i], difftest_bytes[i], perf_run_msec); 52 | } 53 | } 54 | #endif 55 | -------------------------------------------------------------------------------- /src/test/csrc/common/golden.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | /** 18 | * Headers for C/C++ REF models 19 | */ 20 | #ifndef __GOLDEN_H__ 21 | #define __GOLDEN_H__ 22 | 23 | #include "common.h" 24 | 25 | // REF Models 26 | extern "C" uint8_t pte_helper(uint64_t satp, uint64_t vpn, uint64_t *pte, uint8_t *level); 27 | extern "C" uint64_t amo_helper(uint8_t cmd, uint64_t addr, uint64_t wdata, uint8_t mask); 28 | 29 | typedef union PageTableEntry { 30 | struct { 31 | uint32_t v : 1; 32 | uint32_t r : 1; 33 | uint32_t w : 1; 34 | uint32_t x : 1; 35 | uint32_t u : 1; 36 | uint32_t g : 1; 37 | uint32_t a : 1; 38 | uint32_t d : 1; 39 | uint32_t rsw : 2; 40 | uint64_t ppn : 44; 41 | uint32_t rsvd : 7; 42 | uint32_t pbmt : 2; 43 | uint32_t n : 1; 44 | }; 45 | struct { 46 | uint32_t difftest_v : 1; 47 | uint32_t difftest_perm : 7; 48 | uint32_t difftest_rsw : 2; 49 | uint64_t difftest_ppn : 44; 50 | uint32_t difftest_rsvd : 7; 51 | uint32_t difftest_pbmt : 2; 52 | uint32_t difftest_n : 1; 53 | }; 54 | uint64_t val; 55 | } PTE; 56 | 57 | typedef union atpStruct { 58 | struct { 59 | uint64_t ppn : 44; 60 | uint32_t asid : 16; 61 | uint32_t mode : 4; 62 | }; 63 | uint64_t val; 64 | } Satp, Hgatp; 65 | #define noS2xlate 0 66 | #define onlyStage1 1 67 | #define onlyStage2 2 68 | #define allStage 3 69 | #define VPNiSHFT(i) (12 + 9 * (i)) 70 | #define GVPNi(addr, i, max) (((addr) >> (9 * (i) + 12)) & ((i == 3 || (i == 2 && max == 2)) ? 0x7ff : 0x1ff)) 71 | #define VPNi(vpn, i) (((vpn) >> (9 * (i))) & 0x1ff) 72 | #define NAPOTSHFT (12 + 4) // only support 64kb page 73 | #endif 74 | -------------------------------------------------------------------------------- /src/test/csrc/plugin/spikedasm/spikedasm.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | #include "spikedasm.h" 18 | #include 19 | #include 20 | #include 21 | 22 | // We cache the spike-dasm state here. If it is changed during running, the behavior is undefined. 23 | static bool is_tested = false, is_valid = true; 24 | 25 | // This is a place-holder command string. spike_dasm function will replace the inst. 26 | static char dasm_cmd[] = "echo \"DASM(01234567deadbeaf)\" | spike-dasm"; 27 | static const int dasm_offset = sizeof("echo \"DASM(") - 1; 28 | 29 | // We are using a global string as the result buffer. 30 | static char dasm_result[32]; 31 | 32 | bool spike_valid() { 33 | if (!is_tested) { 34 | is_tested = true; 35 | char cmd[128]; 36 | sprintf(cmd, "%s > /dev/null 2> /dev/null", dasm_cmd); 37 | is_valid = !system(cmd); 38 | } 39 | return is_valid; 40 | } 41 | 42 | static void execute_dasm_cmd() { 43 | FILE *ptr = popen(dasm_cmd, "r"); 44 | if (ptr) { 45 | fgets(dasm_result, sizeof(dasm_result), ptr); 46 | pclose(ptr); 47 | } else { 48 | printf("popen %s error\n", dasm_cmd); 49 | } 50 | } 51 | 52 | const char *spike_dasm(uint64_t inst) { 53 | char inst_hex_string[17]; 54 | sprintf(inst_hex_string, "%016lx", inst); 55 | memcpy(dasm_cmd + dasm_offset, inst_hex_string, 16); 56 | execute_dasm_cmd(); 57 | char *first_n_occ = strpbrk(dasm_result, "\n"); 58 | if (first_n_occ) 59 | *first_n_occ = '\0'; 60 | return dasm_result; 61 | } 62 | 63 | // This is an example usage. Not used. 64 | static int usage() { 65 | uint64_t input = 0x10500073L; 66 | 67 | if (spike_valid()) { 68 | printf("%s", spike_dasm(input)); 69 | } 70 | 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /src/test/csrc/gsim/gsim.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2025 Institute of Computing Technology, Chinese Academy of Sciences 3 | * 4 | * DiffTest is licensed under Mulan PSL v2. 5 | * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 | * You may obtain a copy of Mulan PSL v2 at: 7 | * http://license.coscl.org.cn/MulanPSL2 8 | * 9 | * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10 | * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11 | * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12 | * 13 | * See the Mulan PSL v2 for more details. 14 | ***************************************************************************************/ 15 | 16 | #ifndef __SIMULATOR_GSIM_H 17 | #define __SIMULATOR_GSIM_H 18 | 19 | #include "SimTop.h" 20 | 21 | class GsimSim final : public Simulator { 22 | private: 23 | SSimTop *dut; 24 | 25 | protected: 26 | inline unsigned get_uart_out_valid() override { 27 | return dut->get_difftest__DOT__uart__DOT__out__DOT__valid(); 28 | } 29 | inline uint8_t get_uart_out_ch() override { 30 | return dut->get_difftest__DOT__uart__DOT__out__DOT__ch(); 31 | } 32 | inline unsigned get_uart_in_valid() override { 33 | return dut->get_difftest__DOT__uart__DOT__in__DOT__valid(); 34 | } 35 | inline void set_uart_in_ch(uint8_t ch) override { 36 | dut->set_difftest__DOT__uart__DOT__in__DOT__ch(ch); 37 | } 38 | 39 | public: 40 | GsimSim(); 41 | ~GsimSim(); 42 | 43 | inline void set_clock(unsigned clock) override { 44 | // Gsim does not use explicit clock. Simply call step() instead. 45 | } 46 | inline void set_reset(unsigned reset) override { 47 | dut->set_reset(reset); 48 | } 49 | inline void step() override { 50 | dut->step(); 51 | } 52 | 53 | inline uint64_t get_difftest_exit() final { 54 | return dut->get_difftest__DOT__exit(); 55 | } 56 | inline uint64_t get_difftest_step() final { 57 | return dut->get_difftest__DOT__step(); 58 | } 59 | 60 | inline void set_perf_clean(unsigned clean) override { 61 | dut->set_difftest__DOT__perfCtrl__DOT__clean(clean); 62 | } 63 | inline void set_perf_dump(unsigned dump) override { 64 | dut->set_difftest__DOT__perfCtrl__DOT__dump(dump); 65 | } 66 | 67 | inline void set_log_begin(uint64_t begin) override { 68 | dut->set_difftest__DOT__logCtrl__DOT__begin(begin); 69 | } 70 | inline void set_log_end(uint64_t end) override { 71 | dut->set_difftest__DOT__logCtrl__DOT__end(end); 72 | } 73 | }; 74 | 75 | #endif // __SIMULATOR_GSIM_H 76 | -------------------------------------------------------------------------------- /src/test/csrc/common/args.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC) 3 | * Copyright (c) 2020-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 | #ifndef __ARGS_H 18 | #define __ARGS_H 19 | 20 | #include "common.h" 21 | 22 | struct CommonArgs { 23 | uint32_t reset_cycles = 50; 24 | uint32_t seed = 0; 25 | uint64_t max_cycles = -1; 26 | uint64_t fork_interval = 10000; // default: 10 seconds 27 | uint64_t max_instr = -1; 28 | uint64_t warmup_instr = -1; 29 | uint64_t stat_cycles = -1; 30 | uint64_t log_begin = 0, log_end = -1; 31 | uint64_t overwrite_nbytes = 0xe00; 32 | const char *dramsim3_ini = nullptr; 33 | uint64_t copy_ram_offset = 0; 34 | const char *dramsim3_outdir = nullptr; 35 | #ifdef DEBUG_REFILL 36 | uint64_t track_instr = 0; 37 | #endif 38 | #ifdef ENABLE_IPC 39 | uint64_t ipc_interval; 40 | FILE *ipc_file; 41 | uint64_t ipc_last_instr; 42 | uint64_t ipc_last_cycle; 43 | uint64_t ipc_times; 44 | #endif 45 | const char *image = "/dev/zero"; 46 | const char *instr_trace = nullptr; 47 | const char *gcpt_restore = nullptr; 48 | const char *snapshot_path = nullptr; 49 | const char *wave_path = nullptr; 50 | const char *ram_size = nullptr; 51 | const char *flash_bin = nullptr; 52 | const char *select_db = nullptr; 53 | const char *trace_name = nullptr; 54 | const char *footprints_name = nullptr; 55 | const char *linearized_name = nullptr; 56 | bool enable_waveform = false; 57 | bool enable_waveform_full = false; 58 | bool enable_ref_trace = false; 59 | bool enable_commit_trace = false; 60 | bool enable_snapshot = false; 61 | bool force_dump_result = false; 62 | bool enable_diff = true; 63 | bool enable_fork = false; 64 | bool enable_runahead = false; 65 | bool dump_db = false; 66 | bool trace_is_read = true; 67 | bool dump_coverage = false; 68 | bool image_as_footprints = false; 69 | bool overwrite_nbytes_autoset = false; 70 | }; 71 | 72 | CommonArgs parse_args(int argc, const char *argv[]); 73 | 74 | #endif // __ARGS_H 75 | -------------------------------------------------------------------------------- /src/main/scala/common/SDCard.scala: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2024 Institute of Computing Technology, Chinese Academy of Sciences 3 | * 4 | * XiangShan is licensed under Mulan PSL v2. 5 | * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 | * You may obtain a copy of Mulan PSL v2 at: 7 | * http://license.coscl.org.cn/MulanPSL2 8 | * 9 | * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10 | * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11 | * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12 | * 13 | * See the Mulan PSL v2 for more details. 14 | ***************************************************************************************/ 15 | 16 | package difftest.common 17 | 18 | import chisel3._ 19 | import chisel3.experimental.ExtModule 20 | import chisel3.util._ 21 | 22 | class DifftestSDCardRead extends Bundle { 23 | val setAddr = Input(Bool()) 24 | val addr = Input(UInt(32.W)) 25 | val ren = Input(Bool()) 26 | val data = Output(UInt(32.W)) 27 | } 28 | 29 | class SDCardHelper extends ExtModule with HasExtModuleInline { 30 | val clock = IO(Input(Clock())) 31 | val io = IO(new DifftestSDCardRead) 32 | 33 | val cppExtModule = 34 | """ 35 | |void SDCardHelper ( 36 | | uint8_t io_setAddr, 37 | | uint32_t io_addr, 38 | | uint8_t io_ren, 39 | | uint32_t& io_data 40 | |) { 41 | | if (io_ren) sd_read(&io_data); 42 | | if (io_setAddr) sd_setaddr(io_addr); 43 | |} 44 | |""".stripMargin 45 | difftest.DifftestModule.createCppExtModule("SDCardHelper", cppExtModule, Some("\"sdcard.h\"")) 46 | 47 | setInline( 48 | "SDCardHelper.v", 49 | s""" 50 | |`ifndef SYNTHESIS 51 | |import "DPI-C" function void sd_setaddr(input int addr); 52 | |import "DPI-C" function void sd_read(output int data); 53 | |`endif // SYNTHESIS 54 | | 55 | |module SDCardHelper ( 56 | | input clock, 57 | | input io_setAddr, 58 | | input [31:0] io_addr, 59 | | input io_ren, 60 | | output reg [31:0] io_data 61 | |); 62 | | 63 | |`ifndef SYNTHESIS 64 | | always@(negedge clock) begin 65 | | if (io_ren) sd_read(io_data); 66 | | end 67 | | always@(posedge clock) begin 68 | | if (io_setAddr) sd_setaddr(io_addr); 69 | | end 70 | |`endif // SYNTHESIS 71 | | 72 | |endmodule 73 | """.stripMargin, 74 | ) 75 | } 76 | 77 | class DifftestSDCard extends Module { 78 | val io = IO(new DifftestSDCardRead) 79 | 80 | val helper = Module(new SDCardHelper) 81 | helper.clock := clock 82 | 83 | io <> helper.io 84 | } 85 | 86 | object DifftestSDCard { 87 | def apply(): DifftestSDCardRead = { 88 | Module(new DifftestSDCard).io 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/test/csrc/common/lightsss.cpp: -------------------------------------------------------------------------------- 1 | #include "lightsss.h" 2 | 3 | ForkShareMemory::ForkShareMemory() { 4 | if ((key_n = ftok(".", 's') < 0)) { 5 | perror("Fail to ftok\n"); 6 | FAIT_EXIT 7 | } 8 | 9 | if ((shm_id = shmget(key_n, 1024, 0666 | IPC_CREAT)) == -1) { 10 | perror("shmget failed...\n"); 11 | FAIT_EXIT 12 | } 13 | 14 | void *ret = shmat(shm_id, NULL, 0); 15 | if (ret == (void *)-1) { 16 | perror("shmat failed...\n"); 17 | FAIT_EXIT 18 | } else { 19 | info = (shinfo *)ret; 20 | } 21 | 22 | info->flag = false; 23 | info->notgood = false; 24 | info->endCycles = 0; 25 | info->oldest = 0; 26 | } 27 | 28 | ForkShareMemory::~ForkShareMemory() { 29 | if (shmdt(info) == -1) { 30 | perror("detach error\n"); 31 | } 32 | shmctl(shm_id, IPC_RMID, NULL); 33 | } 34 | 35 | void ForkShareMemory::shwait() { 36 | while (true) { 37 | if (info->flag) { 38 | if (info->notgood) 39 | break; 40 | else 41 | exit(0); 42 | } else { 43 | sleep(WAIT_INTERVAL); 44 | } 45 | } 46 | } 47 | 48 | int LightSSS::do_fork() { 49 | //kill the oldest blocked checkpoint process 50 | if (slotCnt == SLOT_SIZE) { 51 | pid_t temp = pidSlot.back(); 52 | pidSlot.pop_back(); 53 | kill(temp, SIGKILL); 54 | int status = 0; 55 | waitpid(temp, NULL, 0); 56 | slotCnt--; 57 | } 58 | // fork a new checkpoint process and block it 59 | if ((pid = fork()) < 0) { 60 | eprintf("[%d]Error: could not fork process!\n", getpid()); 61 | return FORK_ERROR; 62 | } 63 | // the original process 64 | else if (pid != 0) { 65 | slotCnt++; 66 | pidSlot.push_front(pid); 67 | return FORK_OK; 68 | } 69 | // for the fork child 70 | waitProcess = 1; 71 | forkshm.shwait(); 72 | //checkpoint process wakes up 73 | //start wave dumping 74 | if (forkshm.info->oldest != getpid()) { 75 | FORK_PRINTF("Error, non-oldest process should not live. Parent Process should kill the process manually.\n") 76 | return FORK_ERROR; 77 | } 78 | return FORK_CHILD; 79 | } 80 | 81 | int LightSSS::wakeup_child(uint64_t cycles) { 82 | forkshm.info->endCycles = cycles; 83 | forkshm.info->oldest = pidSlot.back(); 84 | 85 | // only the oldest is wantted, so kill others by parent process. 86 | for (auto pid: pidSlot) { 87 | if (pid != forkshm.info->oldest) { 88 | kill(pid, SIGKILL); 89 | waitpid(pid, NULL, 0); 90 | } 91 | } 92 | // flush before wake up child. 93 | fflush(stdout); 94 | fflush(stderr); 95 | 96 | forkshm.info->notgood = true; 97 | forkshm.info->flag = true; 98 | int status = -1; 99 | waitpid(pidSlot.back(), &status, 0); 100 | return 0; 101 | } 102 | 103 | bool LightSSS::is_child() { 104 | return waitProcess; 105 | } 106 | 107 | int LightSSS::do_clear() { 108 | FORK_PRINTF("clear processes...\n") 109 | while (!pidSlot.empty()) { 110 | pid_t temp = pidSlot.back(); 111 | pidSlot.pop_back(); 112 | kill(temp, SIGKILL); 113 | waitpid(temp, NULL, 0); 114 | slotCnt--; 115 | } 116 | return 0; 117 | } 118 | -------------------------------------------------------------------------------- /src/main/scala/Validate.scala: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2024 Beijing Institute of Open Source Chip (BOSC) 3 | * Copyright (c) 2020-2024 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.validate 18 | 19 | import chisel3._ 20 | import chisel3.util._ 21 | import difftest._ 22 | import difftest.gateway.GatewayConfig 23 | 24 | object Validate { 25 | def apply(bundles: MixedVec[DifftestBundle], config: GatewayConfig): MixedVec[Valid[DifftestBundle]] = { 26 | val module = Module(new Validator(chiselTypeOf(bundles).toSeq, config)) 27 | module.in := bundles 28 | module.out 29 | } 30 | 31 | implicit class ValidateHelper(bundle: Valid[DifftestBundle]) { 32 | def inheritFrom(parent: Valid[DifftestBundle]): Unit = { 33 | bundle.valid := parent.valid 34 | bundle.bits.asInstanceOf[DiffTestIsInherited].inheritFrom(parent.bits) 35 | } 36 | def supportsSquashBase: Bool = bundle.bits.supportsSquashBase 37 | def supportsSquash(base: Valid[DifftestBundle]): Bool = bundle.bits.supportsSquash(base.bits) 38 | def squash(base: Valid[DifftestBundle]): Valid[DifftestBundle] = { 39 | if (!bundle.bits.bits.hasValid) { 40 | WireInit(Mux(bundle.valid, bundle, base)) 41 | } else { 42 | val gen = bundle.bits.squash(base.bits) 43 | val squashed = WireInit(0.U.asTypeOf(chiselTypeOf(bundle))) 44 | squashed.bits := gen 45 | squashed.valid := gen.bits.getValid 46 | squashed 47 | } 48 | } 49 | } 50 | } 51 | 52 | class Validator(bundles: Seq[DifftestBundle], config: GatewayConfig) extends Module { 53 | val in = IO(Input(MixedVec(bundles))) 54 | val out = IO(Output(MixedVec(bundles.map(Valid(_))))) 55 | val globalEnable = WireInit(true.B) 56 | if (config.hasGlobalEnable) { 57 | globalEnable := VecInit(in.flatMap(_.bits.needUpdate).toSeq).asUInt.orR 58 | } 59 | in.zip(out).foreach { case (i, o) => 60 | val valid = i.bits.getValid && globalEnable && Option 61 | .when(i.updateDependency.nonEmpty)( 62 | VecInit( 63 | in.filter(b => i.updateDependency.contains(b.desiredCppName)) 64 | .map(bundle => { 65 | // Only if the corresponding bundle is valid, we update this bundle 66 | bundle.coreid === i.coreid && bundle.bits.getValid 67 | }) 68 | .toSeq 69 | ).asUInt.orR 70 | ) 71 | .getOrElse(true.B) 72 | o := i.genValidBundle(valid) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/test/csrc/emu/emu.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2025 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | #ifndef __EMU_H 18 | #define __EMU_H 19 | 20 | #include "args.h" 21 | #include "common.h" 22 | #include "dut.h" 23 | #include "lightsss.h" 24 | #include "simulator.h" 25 | #include 26 | 27 | class Emulator final : public DUT { 28 | private: 29 | Simulator *dut_ptr; 30 | 31 | bool force_dump_wave = false; 32 | CommonArgs args; 33 | LightSSS *lightsss = NULL; 34 | #if VM_COVERAGE == 1 35 | VerilatedCovContext *coverage = NULL; 36 | #endif // VM_COVERAGE 37 | 38 | // emu control variable 39 | uint64_t cycles; 40 | int trapCode; 41 | uint32_t lasttime_snapshot = 0; 42 | uint64_t core_max_instr[NUM_CORES]; 43 | uint32_t lasttime_poll = 0; 44 | uint32_t elapsed_time; 45 | 46 | inline void reset_ncycles(size_t cycles); 47 | inline void single_cycle(); 48 | void trigger_stat_dump(); 49 | void display_stats(); 50 | 51 | inline const char *logdb_filename() { 52 | return create_noop_filename(".db"); 53 | } 54 | 55 | void snapshot_save(); 56 | void snapshot_load(const char *filename); 57 | 58 | inline const char *waveform_filename() { 59 | #ifdef ENABLE_FST 60 | const char *filename = create_noop_filename(".fst"); 61 | #else 62 | const char *filename = create_noop_filename(".vcd"); 63 | #endif 64 | Info("dump wave to %s...\n", filename); 65 | return filename; 66 | } 67 | 68 | const char *cycle_wavefile(uint64_t cycles); 69 | 70 | #if VM_COVERAGE == 1 71 | void save_coverage(); 72 | #endif 73 | 74 | void fork_child_init(); 75 | inline bool is_fork_child() { 76 | return lightsss->is_child(); 77 | } 78 | 79 | public: 80 | Emulator(int argc, const char *argv[]); 81 | ~Emulator(); 82 | uint64_t execute(uint64_t max_cycle, uint64_t max_instr); 83 | uint64_t get_cycles() const { 84 | return cycles; 85 | } 86 | CommonArgs get_args() const { 87 | return args; 88 | } 89 | bool is_good_trap() { 90 | #ifdef FUZZING 91 | return !(trapCode == STATE_ABORT); 92 | #else 93 | return trapCode == STATE_GOODTRAP || trapCode == STATE_LIMIT_EXCEEDED || trapCode == STATE_SIM_EXIT; 94 | #endif 95 | }; 96 | int get_trapcode() { 97 | return trapCode; 98 | } 99 | int tick(); 100 | int is_finished(); 101 | int is_good(); 102 | }; 103 | 104 | #endif 105 | -------------------------------------------------------------------------------- /src/test/csrc/verilator/snapshot.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | #ifndef SNAPSHOT_H 18 | #define SNAPSHOT_H 19 | 20 | #include "VSimTop.h" 21 | #include "compress.h" 22 | #include "ram.h" 23 | #include 24 | #include 25 | 26 | #define SNAPSHOT_SIZE (3UL * simMemory->get_size()) 27 | 28 | class VerilatedSaveMem : public VerilatedSerialize { 29 | unsigned long buf_size; 30 | uint8_t *buf = NULL; 31 | long size; 32 | 33 | public: 34 | VerilatedSaveMem() { 35 | buf_size = SNAPSHOT_SIZE; 36 | buf = NULL; 37 | size = 0; 38 | } 39 | ~VerilatedSaveMem() {} 40 | 41 | void init(const char *filename) { 42 | if (buf != NULL) { 43 | munmap(buf, SNAPSHOT_SIZE); 44 | buf = NULL; 45 | } 46 | buf = (uint8_t *)mmap(NULL, buf_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_NORESERVE, -1, 0); 47 | if (buf == (uint8_t *)MAP_FAILED) { 48 | printf("Cound not mmap 0x%lx bytes\n", SNAPSHOT_SIZE); 49 | assert(0); 50 | } 51 | size = 0; 52 | m_filename = filename; 53 | header(); 54 | } 55 | 56 | void unbuf_write(const void *__restrict datap, size_t size) VL_MT_UNSAFE_ONE { 57 | nonzero_large_memcpy(buf + this->size, datap, size); 58 | this->size += size; 59 | } 60 | 61 | void close() {} 62 | void flush(); 63 | void save(); 64 | }; 65 | 66 | class VerilatedRestoreMem : public VerilatedDeserialize { 67 | unsigned long buf_size; 68 | uint8_t *buf; 69 | long size, buf_ptr; 70 | // gzFile compressed_mem; 71 | 72 | public: 73 | VerilatedRestoreMem() { 74 | buf_size = SNAPSHOT_SIZE; 75 | buf = (uint8_t *)mmap(NULL, buf_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); 76 | if (buf == (uint8_t *)MAP_FAILED) { 77 | printf("Cound not mmap 0x%lx bytes\n", SNAPSHOT_SIZE); 78 | assert(0); 79 | } 80 | size = 0; 81 | buf_ptr = 0; 82 | } 83 | ~VerilatedRestoreMem() { 84 | close(); 85 | } 86 | 87 | void open(const char *filenamep) VL_MT_UNSAFE_ONE; 88 | void open(const std::string &filename) VL_MT_UNSAFE_ONE { 89 | open(filename.c_str()); 90 | } 91 | 92 | long unbuf_read(uint8_t *dest, long rsize); 93 | 94 | void close() override VL_MT_UNSAFE_ONE; 95 | void flush() override VL_MT_UNSAFE_ONE {} 96 | void fill() override VL_MT_UNSAFE_ONE; 97 | }; 98 | 99 | #endif // SNAPSHOT_H 100 | -------------------------------------------------------------------------------- /src/test/vsrc/common/SimJTAG.v: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | //VCS coverage exclude_file 3 | `ifdef TB_NO_DPIC 4 | `define DISABLE_SIMJTAG_DPIC 5 | `endif // TB_NO_DPIC 6 | `ifndef DISABLE_SIMJTAG_DPIC 7 | import "DPI-C" function int jtag_tick 8 | ( 9 | output bit jtag_TCK, 10 | output bit jtag_TMS, 11 | output bit jtag_TDI, 12 | output bit jtag_TRSTn, 13 | 14 | input bit jtag_TDO 15 | ); 16 | `endif // DISABLE_SIMJTAG_DPIC 17 | 18 | module SimJTAG #( 19 | parameter TICK_DELAY = 50 20 | )( 21 | 22 | input clock, 23 | input reset, 24 | 25 | input enable, 26 | input init_done, 27 | 28 | output jtag_TCK, 29 | output jtag_TMS, 30 | output jtag_TDI, 31 | output jtag_TRSTn, 32 | 33 | input jtag_TDO_data, 34 | input jtag_TDO_driven, 35 | 36 | output [31:0] exit 37 | ); 38 | 39 | `ifndef DISABLE_SIMJTAG_DPIC 40 | `ifdef PALLADIUM 41 | initial $ixc_ctrl("map_delays"); 42 | `endif 43 | reg [31:0] tickCounterReg; 44 | wire [31:0] tickCounterNxt; 45 | 46 | assign tickCounterNxt = (tickCounterReg == 0) ? TICK_DELAY : (tickCounterReg - 1); 47 | 48 | bit r_reset; 49 | 50 | logic [31:0] random_bits = $random; 51 | 52 | wire #0.1 __jtag_TDO = jtag_TDO_driven ? 53 | jtag_TDO_data : random_bits[0]; 54 | 55 | bit __jtag_TCK; 56 | bit __jtag_TMS; 57 | bit __jtag_TDI; 58 | bit __jtag_TRSTn; 59 | int __exit; 60 | 61 | reg init_done_sticky; 62 | 63 | assign #0.1 jtag_TCK = __jtag_TCK; 64 | assign #0.1 jtag_TMS = __jtag_TMS; 65 | assign #0.1 jtag_TDI = __jtag_TDI; 66 | assign #0.1 jtag_TRSTn = __jtag_TRSTn; 67 | 68 | assign #0.1 exit = __exit; 69 | 70 | always @(posedge clock) begin 71 | r_reset <= reset; 72 | if (reset || r_reset) begin 73 | __exit = 0; 74 | tickCounterReg <= TICK_DELAY; 75 | init_done_sticky <= 1'b0; 76 | __jtag_TCK = !__jtag_TCK; 77 | end else begin 78 | init_done_sticky <= init_done | init_done_sticky; 79 | if (enable && init_done_sticky) begin 80 | tickCounterReg <= tickCounterNxt; 81 | if (tickCounterReg == 0) begin 82 | __exit = jtag_tick( 83 | __jtag_TCK, 84 | __jtag_TMS, 85 | __jtag_TDI, 86 | __jtag_TRSTn, 87 | __jtag_TDO); 88 | end 89 | end // if (enable && init_done_sticky) 90 | end // else: !if(reset || r_reset) 91 | end // always @ (posedge clock) 92 | `else 93 | assign jtag_TCK = 1'b0; 94 | assign jtag_TMS = 1'b0; 95 | assign jtag_TDI = 1'b0; 96 | assign jtag_TRSTn = 1'b1; 97 | assign exit = 32'b0; 98 | `endif // DISABLE_SIMJTAG_DPIC 99 | 100 | endmodule 101 | -------------------------------------------------------------------------------- /src/test/csrc/common/uart.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | #include "uart.h" 18 | #include "common.h" 19 | #include "stdlib.h" 20 | 21 | #define QUEUE_SIZE 1024 22 | static char queue[QUEUE_SIZE] = {}; 23 | static int f = 0, r = 0; 24 | 25 | static void uart_enqueue(char ch) { 26 | int next = (r + 1) % QUEUE_SIZE; 27 | if (next != f) { 28 | // not full 29 | queue[r] = ch; 30 | r = next; 31 | } 32 | } 33 | 34 | static int uart_dequeue(void) { 35 | int k = 0; 36 | if (f != r) { 37 | k = queue[f]; 38 | f = (f + 1) % QUEUE_SIZE; 39 | } else { 40 | static int last = 0; 41 | k = "root\n"[last++]; 42 | if (last == 5) 43 | last = 0; 44 | // generate a random key every 1s for pal 45 | //k = -1;//"uiojkl"[rand()% 6]; 46 | } 47 | return k; 48 | } 49 | 50 | uint32_t uptime(void); 51 | uint8_t uart_getc() { 52 | static uint32_t lasttime = 0; 53 | uint32_t now = uptime(); 54 | 55 | uint8_t ch = -1; 56 | if (now - lasttime > 60 * 1000) { 57 | // 1 minute 58 | eprintf(ANSI_COLOR_RED "now = %ds\n" ANSI_COLOR_RESET, now / 1000); 59 | lasttime = now; 60 | } 61 | // if (now > 4 * 3600 * 1000) { // 4 hours 62 | // ch = uart_dequeue(); 63 | // } 64 | return ch; 65 | } 66 | 67 | void uart_getc_legacy(uint8_t *ch) { 68 | static uint32_t lasttime = 0; 69 | uint32_t now = uptime(); 70 | 71 | *ch = -1; 72 | if (now - lasttime > 60 * 1000) { 73 | // 1 minute 74 | eprintf(ANSI_COLOR_RED "now = %ds\n" ANSI_COLOR_RESET, now / 1000); 75 | lasttime = now; 76 | } 77 | if (now > 4 * 3600 * 1000) { // 4 hours 78 | *ch = uart_dequeue(); 79 | } 80 | } 81 | 82 | static void preset_input() { 83 | char rtthread_cmd[128] = "memtrace\n"; 84 | char init_cmd[128] = 85 | "2" // choose PAL 86 | "jjjjjjjkkkkkk" // walk to enemy 87 | ; 88 | char busybox_cmd[128] = 89 | "ls\n" 90 | "echo 123\n" 91 | "cd /root/benchmark\n" 92 | "ls\n" 93 | "./stream\n" 94 | "ls\n" 95 | "cd /root/redis\n" 96 | "ls\n" 97 | "ifconfig -a\n" 98 | "./redis-server\n"; 99 | char debian_cmd[128] = "root\n"; 100 | char *buf = debian_cmd; 101 | int i; 102 | for (i = 0; i < strlen(buf); i++) { 103 | uart_enqueue(buf[i]); 104 | } 105 | } 106 | 107 | void init_uart(void) { 108 | preset_input(); 109 | } 110 | 111 | void finish_uart(void) { 112 | memset(queue, 0, sizeof(queue)); 113 | f = 0; 114 | r = 0; 115 | } 116 | -------------------------------------------------------------------------------- /src/main/scala/common/LogPerfControl.scala: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * 4 | * DiffTest is licensed under Mulan PSL v2. 5 | * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 | * You may obtain a copy of Mulan PSL v2 at: 7 | * http://license.coscl.org.cn/MulanPSL2 8 | * 9 | * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10 | * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11 | * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12 | * 13 | * See the Mulan PSL v2 for more details. 14 | ***************************************************************************************/ 15 | 16 | package difftest.common 17 | 18 | import chisel3._ 19 | import chisel3.util._ 20 | import chisel3.reflect.DataMirror 21 | 22 | class LogPerfControl extends Bundle { 23 | val timer = UInt(64.W) 24 | val logEnable = Bool() 25 | val clean = Bool() 26 | val dump = Bool() 27 | } 28 | 29 | private class LogPerfHelper extends BlackBox with HasBlackBoxInline { 30 | val io = IO(Output(new LogPerfControl)) 31 | 32 | val cppExtModule = 33 | """ 34 | |void LogPerfHelper ( 35 | | uint64_t& timer, 36 | | uint8_t& logEnable, 37 | | uint8_t& clean, 38 | | uint8_t& dump 39 | |) { 40 | | timer = difftest$$timer; 41 | | logEnable = difftest$$log_enable; 42 | | clean = difftest$$perfCtrl$$clean; 43 | | dump = difftest$$perfCtrl$$dump; 44 | |} 45 | |""".stripMargin 46 | difftest.DifftestModule.createCppExtModule("LogPerfHelper", cppExtModule) 47 | 48 | val verilog = 49 | """`ifndef SIM_TOP_MODULE_NAME 50 | | `define SIM_TOP_MODULE_NAME SimTop 51 | |`endif 52 | | 53 | |/*verilator tracing_off*/ 54 | |/*verilator coverage_off*/ 55 | | 56 | |module LogPerfHelper( 57 | | output [63:0] timer, 58 | | output logEnable, 59 | | output clean, 60 | | output dump 61 | |); 62 | | 63 | |assign timer = `SIM_TOP_MODULE_NAME.difftest_timer; 64 | |assign logEnable = `SIM_TOP_MODULE_NAME.difftest_log_enable; 65 | |assign clean = `SIM_TOP_MODULE_NAME.difftest_perfCtrl_clean; 66 | |assign dump = `SIM_TOP_MODULE_NAME.difftest_perfCtrl_dump; 67 | | 68 | |endmodule 69 | | 70 | |""".stripMargin 71 | setInline("LogPerfHelper.v", verilog) 72 | } 73 | 74 | object LogPerfControl { 75 | private val instances = scala.collection.mutable.ListBuffer.empty[LogPerfControl] 76 | private def instantiate(): LogPerfControl = instances.addOne(WireInit(Module(new LogPerfHelper).io)).last 77 | 78 | def apply(): LogPerfControl = instances.find(DataMirror.isVisible).getOrElse(instantiate()) 79 | } 80 | 81 | object DifftestPerf { 82 | def apply(perfName: String, perfCnt: UInt) = { 83 | val helper = LogPerfControl.apply() 84 | val counter = RegInit(0.U(64.W)) 85 | val next_counter = WireInit(counter + perfCnt) 86 | counter := Mux(helper.clean, 0.U, next_counter) 87 | when(helper.dump) { 88 | printf(p"[DIFFTEST_PERF][time=${helper.timer}] $perfName, $next_counter\n") 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /emu.mk: -------------------------------------------------------------------------------- 1 | #*************************************************************************************** 2 | # Copyright (c) 2020-2025 Institute of Computing Technology, Chinese Academy of Sciences 3 | # Copyright (c) 2025 Beijing Institute of Open Source Chip 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 | EMU_ELF_NAME = emu 18 | # the target is named as fuzzer for clarity in fuzzing 19 | ifneq ($(FUZZER_LIB), ) 20 | EMU_ELF_NAME = fuzzer 21 | endif 22 | 23 | EMU = $(BUILD_DIR)/$(EMU_ELF_NAME) 24 | EMU_TOP = SimTop 25 | 26 | EMU_CSRC_DIR = $(abspath ./src/test/csrc/emu) 27 | EMU_CONFIG_DIR = $(abspath ./config) 28 | 29 | EMU_CXXFILES = $(SIM_CXXFILES) $(shell find $(EMU_CSRC_DIR) -name "*.cpp") 30 | EMU_CXXFLAGS = $(SIM_CXXFLAGS) -I$(EMU_CSRC_DIR) 31 | 32 | EMU_HEADERS := $(shell find $(SIM_CSRC_DIR) -name "*.h") \ 33 | $(shell find $(DIFFTEST_CSRC_DIR) -name "*.h") \ 34 | $(shell find $(EMU_CSRC_DIR) -name "*.h") 35 | 36 | ########## Supported Configuration Options ########## 37 | # trace (waveform) 38 | EMU_TRACE ?= 39 | 40 | # trace (waveform) underscore values 41 | EMU_TRACE_ALL ?= 42 | 43 | # multi-threading RTL-simulation 44 | EMU_THREADS ?= 0 45 | ifneq ($(EMU_THREADS),0) 46 | EMU_CXXFLAGS += -DEMU_THREAD=$(EMU_THREADS) 47 | endif 48 | 49 | # RTL-level savable models 50 | EMU_SNAPSHOT ?= 51 | ifeq ($(EMU_SNAPSHOT),1) 52 | EMU_CXXFLAGS += -DVM_SAVABLE 53 | endif 54 | 55 | # RTL-level structural coverage (instrumented by RTL simulators) 56 | EMU_COVERAGE ?= 57 | 58 | # optimization level for RTL simulators 59 | EMU_OPTIMIZE ?= -O3 60 | 61 | PGO_MAX_CYCLE ?= 100000 62 | PGO_EMU_ARGS ?= --no-diff 63 | 64 | LLVM_BOLT ?= $(shell readlink -f `command -v llvm-bolt 2> /dev/null`) 65 | # We use readlink -f to get the absolute path of llvm-bolt, it's 66 | # needed since we use argv[0]/../lib/libbolt_rt_instr.a as the path 67 | # to find the runtime library inside llvm-bolt. It's a workaround 68 | # for LLVM before commit abc2eae682("[BOLT] Enable standalone build (llvm#97130)"). 69 | # Ref: https://github.com/llvm/llvm-project/blob/release/18.x/bolt/lib/RuntimeLibs/RuntimeLibrary.cpp#L33 70 | # Ref: https://github.com/llvm/llvm-project/blob/release/18.x/bolt/tools/driver/llvm-bolt.cpp#L187 71 | PGO_BOLT ?= $(shell if [ -x "$(LLVM_BOLT)" ]; then echo 1; else echo 0; fi) 72 | 73 | include verilator.mk 74 | include gsim.mk 75 | 76 | ########## Emu build recipes ########## 77 | 78 | emu-verilator: verilator-emu 79 | @ln -sf $(VERILATOR_TARGET) $(EMU) 80 | 81 | emu-gsim: gsim-emu 82 | @ln -sf $(GSIM_EMU_TARGET) $(EMU) 83 | 84 | # By default, when no simulator is specified, emu refers to verilator-emu 85 | emu: 86 | ifeq ($(GSIM),1) 87 | @$(MAKE) emu-gsim 88 | else 89 | @$(MAKE) emu-verilator 90 | endif 91 | 92 | emu-mk: verilator-emu-mk 93 | 94 | clean-obj: verilator-clean-obj gsim-clean-obj 95 | -------------------------------------------------------------------------------- /src/test/csrc/common/query.h: -------------------------------------------------------------------------------- 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 | #ifndef __QUERY_H__ 18 | #define __QUERY_H__ 19 | 20 | #include "common.h" 21 | 22 | #ifdef CONFIG_DIFFTEST_QUERY 23 | #include 24 | 25 | class Query { 26 | protected: 27 | sqlite3_stmt *pPrepare = nullptr; 28 | sqlite3 *query_db = nullptr; 29 | 30 | public: 31 | Query(sqlite3 *db, const char *createSql, const char *insertSql) { 32 | query_db = db; 33 | char *errMsg; 34 | int rc; 35 | rc = sqlite3_exec(query_db, createSql, 0, 0, &errMsg); 36 | if (rc != SQLITE_OK) { 37 | printf("SQL error: %s\n", errMsg); 38 | assert(0); 39 | } 40 | rc = sqlite3_prepare_v2(query_db, insertSql, strlen(insertSql), &pPrepare, 0); 41 | if (rc != SQLITE_OK) { 42 | printf("SQL error: %s\n", sqlite3_errmsg(query_db)); 43 | assert(0); 44 | } 45 | } 46 | ~Query() { 47 | sqlite3_finalize(pPrepare); 48 | } 49 | void write(int count, ...) { 50 | va_list args; 51 | va_start(args, count); 52 | sqlite3_reset(pPrepare); 53 | for (int i = 0; i < count; i++) { 54 | sqlite3_bind_int(pPrepare, i + 1, va_arg(args, int)); 55 | } 56 | va_end(args); 57 | sqlite3_step(pPrepare); 58 | } 59 | }; 60 | 61 | class QueryStatsBase { 62 | public: 63 | char path[128]; 64 | long long query_step = 0; 65 | sqlite3 *mem_db = nullptr; 66 | QueryStatsBase(char *_path) { 67 | strncpy(path, _path, 128); 68 | sqlite3_open(":memory:", &mem_db); 69 | sqlite3_exec(mem_db, "PRAGMA synchronous = OFF", 0, 0, 0); 70 | sqlite3_exec(mem_db, "BEGIN;", 0, 0, 0); 71 | } 72 | ~QueryStatsBase() { 73 | sqlite3_exec(mem_db, "COMMIT;", 0, 0, 0); 74 | sqlite3 *disk_db = nullptr; 75 | sqlite3_backup *pBackup; 76 | int rc = sqlite3_open(path, &disk_db); 77 | if (rc == SQLITE_OK) { 78 | pBackup = sqlite3_backup_init(disk_db, "main", mem_db, "main"); 79 | if (pBackup) { 80 | (void)sqlite3_backup_step(pBackup, -1); 81 | (void)sqlite3_backup_finish(pBackup); 82 | } 83 | rc = sqlite3_errcode(disk_db); 84 | } 85 | sqlite3_close(disk_db); 86 | sqlite3_close(mem_db); 87 | } 88 | virtual void step() { 89 | query_step++; 90 | if (query_step % 10000 == 0) { 91 | sqlite3_exec(mem_db, "COMMIT;", 0, 0, 0); 92 | sqlite3_exec(mem_db, "BEGIN;", 0, 0, 0); 93 | } 94 | } 95 | }; 96 | 97 | class QueryStats; 98 | extern QueryStats *qStats; 99 | 100 | void difftest_query_init(); 101 | void difftest_query_step(); 102 | void difftest_query_finish(); 103 | #endif // CONFIG_DIFFTEST_QUERY 104 | #endif // __QUERY_H__ 105 | -------------------------------------------------------------------------------- /src/test/csrc/verilator/verilator.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2025 Institute of Computing Technology, Chinese Academy of Sciences 3 | * 4 | * DiffTest is licensed under Mulan PSL v2. 5 | * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 | * You may obtain a copy of Mulan PSL v2 at: 7 | * http://license.coscl.org.cn/MulanPSL2 8 | * 9 | * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10 | * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11 | * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12 | * 13 | * See the Mulan PSL v2 for more details. 14 | ***************************************************************************************/ 15 | 16 | #ifndef __SIMULATOR_VERILATOR_H 17 | #define __SIMULATOR_VERILATOR_H 18 | 19 | #include "VSimTop.h" 20 | #include "VSimTop__Syms.h" 21 | #include "waveform.h" 22 | #ifdef VM_SAVABLE 23 | #include "snapshot.h" 24 | #endif // VM_SAVABLE 25 | 26 | class VerilatorSim final : public Simulator { 27 | private: 28 | VSimTop *dut; 29 | 30 | #if VM_TRACE == 1 31 | TraceBindFunc trace_bind = [this](VerilatedTraceBaseC *tfp, int levels) { this->dut->trace(tfp, levels); }; 32 | EmuWaveform *waveform = nullptr; 33 | #endif // VM_TRACE == 1 34 | 35 | #ifdef VM_SAVABLE 36 | VerilatedSaveMem *snapshot_slot = nullptr; 37 | #endif // VM_SAVABLE 38 | 39 | protected: 40 | inline unsigned get_uart_out_valid() override { 41 | return dut->difftest_uart_out_valid; 42 | } 43 | inline uint8_t get_uart_out_ch() override { 44 | return dut->difftest_uart_out_ch; 45 | } 46 | inline unsigned get_uart_in_valid() override { 47 | return dut->difftest_uart_in_valid; 48 | } 49 | inline void set_uart_in_ch(uint8_t ch) override { 50 | dut->difftest_uart_in_ch = ch; 51 | } 52 | 53 | public: 54 | VerilatorSim(); 55 | ~VerilatorSim(); 56 | 57 | inline void set_clock(unsigned clock) override { 58 | dut->clock = clock; 59 | } 60 | inline void set_reset(unsigned reset) override { 61 | dut->reset = reset; 62 | } 63 | inline void step() override { 64 | dut->eval(); 65 | } 66 | 67 | inline uint64_t get_difftest_exit() override { 68 | return dut->difftest_exit; 69 | } 70 | inline uint64_t get_difftest_step() override { 71 | return dut->difftest_step; 72 | } 73 | 74 | inline void set_perf_clean(unsigned clean) override { 75 | dut->difftest_perfCtrl_clean = clean; 76 | } 77 | inline void set_perf_dump(unsigned dump) override { 78 | dut->difftest_perfCtrl_dump = dump; 79 | } 80 | 81 | inline void set_log_begin(uint64_t begin) override { 82 | dut->difftest_logCtrl_begin = begin; 83 | } 84 | inline void set_log_end(uint64_t end) override { 85 | dut->difftest_logCtrl_end = end; 86 | } 87 | 88 | void atClone() override; 89 | 90 | #if VM_TRACE == 1 91 | void waveform_init(uint64_t cycles) override; 92 | void waveform_init(uint64_t cycles, const char *filename) override; 93 | void waveform_tick() override; 94 | #endif // VM_TRACE == 1 95 | 96 | #ifdef VM_SAVABLE 97 | void snapshot_init() override; 98 | void snapshot_save(int index) override; 99 | std::function snapshot_take() override; 100 | std::function snapshot_load(const char *filename) override; 101 | #endif // VM_SAVABLE 102 | }; 103 | 104 | #endif // __SIMULATOR_VERILATOR_H 105 | -------------------------------------------------------------------------------- /src/test/csrc/plugin/runahead/memdep.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | #include "runahead.h" 18 | #include 19 | 20 | void MemdepWatchWindow::commit_load() { 21 | assert(load_inflight.size() > 0); 22 | load_inflight.pop_front(); 23 | } 24 | 25 | void MemdepWatchWindow::commit_store() { 26 | assert(store_inflight.size() > 0); 27 | store_inflight.pop_front(); 28 | } 29 | 30 | void MemdepWatchWindow::commit_load(uint64_t pc) { 31 | assert(pc == load_inflight.front().pc); 32 | commit_load(); 33 | } 34 | 35 | void MemdepWatchWindow::commit_store(uint64_t pc) { 36 | assert(pc == store_inflight.front().pc); 37 | commit_store(); 38 | } 39 | 40 | void MemdepWatchWindow::watch_load(uint64_t pc, uint64_t vaddr) { 41 | MemInstInfo load; 42 | load.pc = pc; 43 | load.vaddr = vaddr; 44 | load_inflight.push_back(load); 45 | if (load_inflight.size() > MEMDEP_WINDOW_SIZE) { 46 | load_inflight.pop_back(); 47 | } 48 | runahead_debug("Memdep watcher: start to watch load %lx, vaddr %lx\n", pc, vaddr); 49 | } 50 | 51 | void MemdepWatchWindow::watch_store(uint64_t pc, uint64_t vaddr) { 52 | MemInstInfo store; 53 | store.pc = pc; 54 | store.vaddr = vaddr; 55 | store_inflight.push_back(store); 56 | if (store_inflight.size() > MEMDEP_WINDOW_SIZE) { 57 | store_inflight.pop_back(); 58 | } 59 | runahead_debug("Memdep watcher: start to watch store %lx, vaddr %lx\n", pc, vaddr); 60 | } 61 | 62 | bool MemdepWatchWindow::query_load_store_dep(uint64_t load_pc, uint64_t load_vaddr) { 63 | runahead_debug("Memdep watcher: detecting dependency for load %lx, vaddr %lx\n", load_pc, load_vaddr); 64 | bool has_dependency = false; 65 | for (auto i: store_inflight) { 66 | runahead_debug("Memdep watcher: %lx (%lx) %lx\n", i.vaddr, i.pc, load_vaddr); 67 | if (((i.vaddr | 0x7) == (load_vaddr | 0x7)) && !((load_vaddr & 0xf0000000) == 0x40000000) // hard code mmio 68 | ) { 69 | has_dependency = true; 70 | runahead_debug("Memdep watcher: load %lx dependency detected: store pc %lx, vaddr %lx\n", load_pc, i.pc, 71 | load_vaddr); 72 | total_dependency++; 73 | } 74 | } 75 | return has_dependency; 76 | } 77 | 78 | void MemdepWatchWindow::update_pred_matrix(bool dut_result, bool ref_result) { 79 | pred_matrix[(int)dut_result][(int)ref_result]++; 80 | } 81 | 82 | void MemdepWatchWindow::print_pred_matrix() { 83 | printf("-------------- Memdep Watcher Result ----------------\n"); 84 | printf("DUT ndep REF ndep %ld\n", pred_matrix[0][0]); 85 | printf("DUT ndep REF dep %ld\n", pred_matrix[0][1]); 86 | printf("DUT dep REF ndep %ld\n", pred_matrix[1][0]); 87 | printf("DUT dep REF dep %ld\n", pred_matrix[1][1]); 88 | printf("-----------------------------------------------------\n"); 89 | } 90 | 91 | // MemdepWatchWindow::~MemdepWatchWindow(){ 92 | // print_pred_matrix(); 93 | // } 94 | -------------------------------------------------------------------------------- /src/test/csrc/common/flash.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | #include "flash.h" 18 | #include "common.h" 19 | #ifdef CONFIG_DIFFTEST_PERFCNT 20 | #include "perf.h" 21 | #endif // CONFIG_DIFFTEST_PERFCNT 22 | 23 | flash_device_t flash_dev = { 24 | nullptr, // base 25 | DEFAULT_EMU_FLASH_SIZE, // size 26 | nullptr, // img_path 27 | 0 // img_size 28 | }; 29 | 30 | void flash_read(uint32_t addr, uint64_t *data) { 31 | #ifdef CONFIG_DIFFTEST_PERFCNT 32 | difftest_calls[perf_flash_read]++; 33 | difftest_bytes[perf_flash_read] += 12; 34 | #endif // CONFIG_DIFFTEST_PERFCNT 35 | if (!flash_dev.base) { 36 | return; 37 | } 38 | //addr must be 8 bytes aligned first 39 | uint32_t aligned_addr = addr & FLASH_ALIGH_MASK; 40 | uint64_t rIdx = aligned_addr / sizeof(uint64_t); 41 | if (rIdx >= flash_dev.size / sizeof(uint64_t)) { 42 | printf("[warning] read addr %x is out of bound\n", addr); 43 | *data = 0; 44 | } else { 45 | *data = flash_dev.base[rIdx]; 46 | } 47 | } 48 | 49 | void init_flash(const char *flash_bin) { 50 | flash_dev.base = (uint64_t *)mmap(NULL, flash_dev.size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); 51 | if (flash_dev.base == (uint64_t *)MAP_FAILED) { 52 | printf("Warning: Insufficient phisical memory for flash\n"); 53 | flash_dev.size = 10 * 1024UL; //10 KB 54 | flash_dev.base = (uint64_t *)mmap(NULL, flash_dev.size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); 55 | if (flash_dev.base == (uint64_t *)MAP_FAILED) { 56 | printf("Error: Cound not mmap 0x%lx bytes for flash\n", flash_dev.size); 57 | assert(0); 58 | } 59 | } 60 | Info("Using simulated %luB flash\n", flash_dev.size); 61 | 62 | if (!flash_bin) { 63 | /** no specified flash_path, use defualt 3 instructions */ 64 | // addiw t0,zero,1 65 | // slli to,to, 0x1f 66 | // jr t0 67 | flash_dev.base[0] = 0x01f292930010029b; 68 | flash_dev.base[1] = 0x00028067; 69 | flash_dev.img_size = 2 * sizeof(uint64_t); 70 | return; 71 | } 72 | 73 | flash_dev.img_path = (char *)flash_bin; 74 | Info("use %s as flash bin\n", flash_dev.img_path); 75 | 76 | FILE *flash_fp = fopen(flash_dev.img_path, "r"); 77 | if (!flash_fp) { 78 | eprintf(ANSI_COLOR_MAGENTA "[error] flash img not found\n"); 79 | exit(1); 80 | } 81 | 82 | fseek(flash_fp, 0, SEEK_END); 83 | flash_dev.img_size = ftell(flash_fp); 84 | if (flash_dev.img_size > flash_dev.size) { 85 | printf("[warning] flash image size %ld bytes is out of bound, cut the image into %ld bytes\n", flash_dev.img_size, 86 | flash_dev.size); 87 | flash_dev.img_size = flash_dev.size; 88 | } 89 | fseek(flash_fp, 0, SEEK_SET); 90 | int ret = fread(flash_dev.base, flash_dev.img_size, 1, flash_fp); 91 | assert(ret == 1); 92 | fclose(flash_fp); 93 | } 94 | 95 | void flash_finish() { 96 | munmap(flash_dev.base, flash_dev.size); 97 | flash_dev.base = NULL; 98 | } 99 | -------------------------------------------------------------------------------- /src/test/csrc/common/keyboard.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | #include "common.h" 18 | #include "macro.h" 19 | 20 | // Note that this is not the standard 21 | /* clang-format off */ 22 | #define _KEYS(f) \ 23 | f(ESCAPE) f(F1) f(F2) f(F3) f(F4) f(F5) f(F6) f(F7) f(F8) f(F9) f(F10) f(F11) f(F12) \ 24 | f(GRAVE) f(1) f(2) f(3) f(4) f(5) f(6) f(7) f(8) f(9) f(0) f(MINUS) f(EQUALS) f(BACKSPACE) \ 25 | f(TAB) f(Q) f(W) f(E) f(R) f(T) f(Y) f(U) f(I) f(O) f(P) f(LEFTBRACKET) f(RIGHTBRACKET) f(BACKSLASH) \ 26 | f(CAPSLOCK) f(A) f(S) f(D) f(F) f(G) f(H) f(J) f(K) f(L) f(SEMICOLON) f(APOSTROPHE) f(RETURN) \ 27 | f(LSHIFT) f(Z) f(X) f(C) f(V) f(B) f(N) f(M) f(COMMA) f(PERIOD) f(SLASH) f(RSHIFT) \ 28 | f(LCTRL) f(APPLICATION) f(LALT) f(SPACE) f(RALT) f(RCTRL) \ 29 | f(UP) f(DOWN) f(LEFT) f(RIGHT) f(INSERT) f(DELETE) f(HOME) f(END) f(PAGEUP) f(PAGEDOWN) 30 | /* clang-format on */ 31 | 32 | #define _KEY_NAME(k) _KEY_##k, 33 | 34 | enum { 35 | _KEY_NONE = 0, 36 | MAP(_KEYS, _KEY_NAME) 37 | }; 38 | 39 | #define SDL_KEYMAP(k) [concat(SDL_SCANCODE_, k)] = concat(_KEY_, k), 40 | /* clang-format off */ 41 | static const uint32_t keymap[256] = { 42 | // MAP(_KEYS, SDL_KEYMAP) 43 | 0, 0, 0, 0, 43, 60, 58, 45, 31, 46, 47, 48, 36, 49, 50, 51, 44 | 62, 61, 37, 38, 29, 32, 44, 33, 35, 59, 30, 57, 34, 56, 15, 16, 45 | 17, 18, 19, 20, 21, 22, 23, 24, 54, 1, 27, 28, 70, 25, 26, 39, 46 | 40, 41, 0, 52, 53, 14, 63, 64, 65, 42, 2, 3, 4, 5, 6, 7, 47 | 8, 9, 10, 11, 12, 13, 0, 0, 0, 77, 79, 81, 78, 80, 82, 76, 48 | 75, 74, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49 | 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57 | 67, 55, 69, 0, 72, 66, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59 | }; 60 | /* clang-format on */ 61 | 62 | #define KEY_QUEUE_LEN 1024 63 | static int key_queue[KEY_QUEUE_LEN]; 64 | static int key_f = 0, key_r = 0; 65 | 66 | #define KEYDOWN_MASK 0x8000 67 | 68 | void send_key(uint8_t scancode, bool is_keydown) { 69 | if (keymap[scancode] != _KEY_NONE) { 70 | uint32_t am_scancode = keymap[scancode] | (is_keydown ? KEYDOWN_MASK : 0); 71 | key_queue[key_r] = am_scancode; 72 | key_r = (key_r + 1) % KEY_QUEUE_LEN; 73 | // detect key queue overflow 74 | assert(key_r != key_f); 75 | } 76 | } 77 | 78 | uint32_t read_key(void) { 79 | uint32_t key = _KEY_NONE; 80 | if (key_f != key_r) { 81 | key = key_queue[key_f]; 82 | key_f = (key_f + 1) % KEY_QUEUE_LEN; 83 | } 84 | return key; 85 | } 86 | -------------------------------------------------------------------------------- /src/test/csrc/common/common.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | #ifndef __COMMON_H 18 | #define __COMMON_H 19 | 20 | #include "config.h" 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #define ANSI_COLOR_RED "\x1b[31m" 36 | #define ANSI_COLOR_GREEN "\x1b[32m" 37 | #define ANSI_COLOR_YELLOW "\x1b[33m" 38 | #define ANSI_COLOR_BLUE "\x1b[34m" 39 | #define ANSI_COLOR_MAGENTA "\x1b[35m" 40 | #define ANSI_COLOR_CYAN "\x1b[36m" 41 | #define ANSI_COLOR_RESET "\x1b[0m" 42 | 43 | #ifdef WITH_DRAMSIM3 44 | #include "cosimulation.h" 45 | #endif 46 | 47 | extern int assert_count; 48 | extern const char *emu_path; 49 | 50 | extern int signal_num; 51 | void sig_handler(int signo); 52 | 53 | typedef uint64_t rtlreg_t; 54 | typedef uint64_t vaddr_t; 55 | typedef uint16_t ioaddr_t; 56 | 57 | extern bool sim_verbose; 58 | 59 | int eprintf(const char *fmt, ...); 60 | 61 | #define Info(...) \ 62 | do { \ 63 | if (sim_verbose) { \ 64 | eprintf(__VA_ARGS__); \ 65 | } \ 66 | } while (0) 67 | 68 | #define Assert(cond, ...) \ 69 | do { \ 70 | if (!(cond)) { \ 71 | fflush(stdout); \ 72 | fprintf(stderr, "\33[1;31m"); \ 73 | fprintf(stderr, __VA_ARGS__); \ 74 | fprintf(stderr, "\33[0m\n"); \ 75 | assert(cond); \ 76 | } \ 77 | } while (0) 78 | 79 | #define panic(...) Assert(0, __VA_ARGS__) 80 | 81 | #define fprintf_with_pid(stream, ...) \ 82 | do { \ 83 | fprintf(stream, "(%d) ", getpid()); \ 84 | fprintf(stream, __VA_ARGS__); \ 85 | } while (0) 86 | 87 | #define printf_with_pid(...) \ 88 | do { \ 89 | fprintf_with_pid(stdout, __VA_ARGS__); \ 90 | } while (0) 91 | 92 | #define TODO() panic("please implement me") 93 | 94 | // Initialize common functions, such as buffering, assertions, siganl handlers. 95 | void common_init(const char *program_name); 96 | 97 | // Some designs may raise assertions during the reset stage. 98 | // Use common_init_without_assertion with common_enable_assert to manually control assertions. 99 | void common_init_without_assertion(const char *program_name); 100 | void common_enable_assert(); 101 | 102 | // Enable external log system 103 | typedef int (*eprintf_handle_t)(const char *fmt, va_list ap); 104 | extern "C" void common_enable_log(eprintf_handle_t h); 105 | 106 | void common_finish(); 107 | 108 | uint32_t uptime(void); 109 | 110 | extern "C" void xs_assert(long long line); 111 | extern "C" void xs_assert_v2(const char *filename, long long line); 112 | 113 | const char *create_noop_filename(const char *suffix); 114 | 115 | #endif // __COMMON_H 116 | -------------------------------------------------------------------------------- /src/test/csrc/verilator/verilator.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2025 Institute of Computing Technology, Chinese Academy of Sciences 3 | * 4 | * DiffTest is licensed under Mulan PSL v2. 5 | * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 | * You may obtain a copy of Mulan PSL v2 at: 7 | * http://license.coscl.org.cn/MulanPSL2 8 | * 9 | * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10 | * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11 | * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12 | * 13 | * See the Mulan PSL v2 for more details. 14 | ***************************************************************************************/ 15 | 16 | #ifdef EMU_THREAD 17 | #include 18 | #endif 19 | 20 | #include "simulator.h" 21 | 22 | VerilatorSim::VerilatorSim() : dut(new VSimTop) {} 23 | 24 | VerilatorSim::~VerilatorSim() { 25 | #if VM_TRACE == 1 26 | if (waveform) { 27 | delete waveform; 28 | waveform = nullptr; 29 | } 30 | #endif 31 | 32 | #ifdef VM_SAVABLE 33 | if (snapshot_slot) { 34 | delete[] snapshot_slot; 35 | snapshot_slot = nullptr; 36 | } 37 | #endif // VM_SAVABLE 38 | 39 | delete dut; 40 | } 41 | 42 | void VerilatorSim::atClone() { 43 | #ifdef VERILATOR_VERSION_INTEGER // >= v4.220 44 | #if VERILATOR_VERSION_INTEGER >= 5016000 45 | // This will cause 288 bytes leaked for each one fork call. 46 | // However, one million snapshots cause only 288MB leaks, which is still acceptable. 47 | // See verilator/test_regress/t/t_wrapper_clone.cpp:48 to avoid leaks. 48 | dut->atClone(); 49 | #else 50 | #error Please use Verilator v5.016 or newer versions. 51 | #endif // check VERILATOR_VERSION_INTEGER values 52 | #elif EMU_THREAD > 1 // VERILATOR_VERSION_INTEGER not defined 53 | #ifdef VERILATOR_4_210 // v4.210 <= version < 4.220 54 | dut->vlSymsp->__Vm_threadPoolp = new VlThreadPool(dut_ptr->contextp(), EMU_THREAD - 1, 0); 55 | #else // older than v4.210 56 | dut->__Vm_threadPoolp = new VlThreadPool(dut_ptr->contextp(), EMU_THREAD - 1, 0); 57 | #endif 58 | #endif 59 | } 60 | 61 | #if VM_TRACE == 1 62 | void VerilatorSim::waveform_init(uint64_t cycles) { 63 | waveform = new EmuWaveform(trace_bind, cycles); 64 | } 65 | 66 | void VerilatorSim::waveform_init(uint64_t cycles, const char *filename) { 67 | waveform = new EmuWaveform(trace_bind, cycles, filename); 68 | } 69 | 70 | void VerilatorSim::waveform_tick() { 71 | waveform->tick(); 72 | } 73 | #endif // VM_TRACE == 1 74 | 75 | #ifdef VM_SAVABLE 76 | void VerilatorSim::snapshot_init() { 77 | snapshot_slot = new VerilatedSaveMem[2]; 78 | } 79 | 80 | void VerilatorSim::snapshot_save(int index) { 81 | if (snapshot_slot) { 82 | if (index >= 0) { 83 | snapshot_slot[index].save(); 84 | } else if (index == -1) { 85 | Info("Saving snapshots to file system. Please wait.\n"); 86 | snapshot_slot[0].save(); 87 | snapshot_slot[1].save(); 88 | Info("Please remove unused snapshots manually\n"); 89 | } 90 | } 91 | } 92 | 93 | std::function VerilatorSim::snapshot_take() { 94 | static int last_slot = 0; 95 | VerilatedSaveMem &stream = snapshot_slot[last_slot]; 96 | last_slot = !last_slot; 97 | 98 | stream.init(create_noop_filename(".snapshot")); 99 | stream << *dut; 100 | stream.flush(); 101 | 102 | return [&stream](void *datap, size_t size) { stream.unbuf_write(datap, size); }; 103 | } 104 | 105 | std::function VerilatorSim::snapshot_load(const char *filename) { 106 | auto stream = std::make_shared(); 107 | stream->open(filename); 108 | *stream >> *dut; 109 | 110 | return [stream](void *datap, size_t size) { stream->read((uint8_t *)datap, size); }; 111 | } 112 | #endif // VM_SAVABLE 113 | -------------------------------------------------------------------------------- /src/test/csrc/fpga/xdma.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC) 3 | * Copyright (c) 2020-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 | #ifndef __XDMA_H__ 17 | #define __XDMA_H__ 18 | 19 | #include "common.h" 20 | #include "mpool.h" 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #ifdef FPGA_SIM 30 | #include "xdma_sim.h" 31 | #endif // FPGA_SIM 32 | 33 | #define DMA_PACKGE_NUM 8 34 | 35 | // DMA_PADDING (packge_idx(1) + difftest_data) send width to be calculated by mod up 36 | #define DMA_PACKGE_LEN (CONFIG_DIFFTEST_BATCH_BYTELEN + 1) 37 | #define DMA_PACKGE_ALIGNED ((DMA_PACKGE_LEN + 63) / 64 * 64) 38 | #define DMA_PACKGE_PADDING (DMA_PACKGE_ALIGNED - DMA_PACKGE_LEN) 39 | 40 | typedef struct __attribute__((packed)) { 41 | uint8_t packge_idx; // idx of header packet is valid and idx of intermediate data is placeholder 42 | uint8_t diff_packge[CONFIG_DIFFTEST_BATCH_BYTELEN]; 43 | #if (DMA_PACKGE_PADDING > 0) 44 | uint8_t padding[DMA_PACKGE_PADDING]; 45 | #endif 46 | } DmaDiffPackge; 47 | 48 | typedef struct __attribute__((packed)) { 49 | DmaDiffPackge diff_packge[DMA_PACKGE_NUM]; 50 | } FpgaPackgeHead; 51 | 52 | class FpgaXdma { 53 | public: 54 | FpgaXdma(); 55 | 56 | void start() { 57 | running = true; 58 | #ifdef USE_THREAD_MEMPOOL 59 | std::unique_lock lock(thread_mtx); 60 | start_transmit_thread(); 61 | while (running) { 62 | thread_cv.wait(lock); // wait notify from stop 63 | } 64 | stop_thansmit_thread(); 65 | #else 66 | read_and_process(); 67 | #endif // USE_THREAD_MEMPOOL 68 | } 69 | void stop() { 70 | running = false; 71 | #ifdef USE_THREAD_MEMPOOL 72 | thread_cv.notify_one(); 73 | #endif // USE_THREAD_MEMPOOL 74 | } 75 | void ddr_load_workload(const char *workload) { 76 | core_reset(); 77 | device_write(true, workload, 0, 0); 78 | core_restart(); 79 | } 80 | 81 | void fpga_reset_io(bool enable) { 82 | if (enable) 83 | device_write(false, nullptr, 0x0, 0x1); 84 | else 85 | device_write(false, nullptr, 0x0, 0x0); 86 | } 87 | 88 | private: 89 | bool running = false; 90 | int xdma_c2h_fd[CONFIG_DMA_CHANNELS]; 91 | #ifdef CONFIG_USE_XDMA_H2C 92 | int xdma_h2c_fd; 93 | #endif 94 | 95 | void device_write(bool is_bypass, const char *workload, uint64_t addr, uint64_t value); 96 | void core_reset() { 97 | device_write(false, nullptr, 0x20000, 0x1); 98 | device_write(false, nullptr, 0x100000, 0x1); 99 | device_write(false, nullptr, 0x10000, 0x8); 100 | } 101 | 102 | void core_restart() { 103 | device_write(false, nullptr, 0x20000, 0); 104 | device_write(false, nullptr, 0x100000, 0); 105 | } 106 | 107 | #ifdef USE_THREAD_MEMPOOL 108 | std::mutex thread_mtx; 109 | std::condition_variable thread_cv; 110 | MemoryIdxPool xdma_mempool; 111 | std::thread receive_thread[CONFIG_DMA_CHANNELS]; 112 | std::thread process_thread; 113 | // thread api 114 | void start_transmit_thread(); 115 | void stop_thansmit_thread(); 116 | void read_xdma_thread(int channel); 117 | void write_difftest_thread(); 118 | #else 119 | void read_and_process(); 120 | #endif // USE_THREAD_MEMPOOL 121 | }; 122 | 123 | #endif 124 | -------------------------------------------------------------------------------- /src/test/csrc/plugin/simfrontend/tracereader.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2025 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC) 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 | #include "tracereader.h" 18 | #include "debug.h" 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | MmapLineReader::MmapLineReader(const std::string &filename) { 27 | if (init(filename)) { 28 | is_open = true; 29 | } 30 | } 31 | 32 | MmapLineReader::~MmapLineReader() { 33 | if (mapped_data) { 34 | munmap(mapped_data, file_size); 35 | } 36 | if (fd != -1) { 37 | close(fd); 38 | } 39 | } 40 | 41 | bool MmapLineReader::init(const std::string &filename) { 42 | fd = open(filename.c_str(), O_RDONLY); 43 | if (fd == -1) { 44 | perror("Error opening file"); 45 | return false; 46 | } 47 | 48 | struct stat sb; 49 | if (fstat(fd, &sb) == -1) { 50 | perror("Error getting file size"); 51 | close(fd); 52 | fd = -1; 53 | return false; 54 | } 55 | file_size = sb.st_size; 56 | 57 | if (file_size == 0) { 58 | is_final = true; 59 | is_open = true; 60 | read_ptr = nullptr; 61 | end_of_file = nullptr; 62 | return true; 63 | } 64 | 65 | mapped_data = static_cast(mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, fd, 0)); 66 | if (mapped_data == MAP_FAILED) { 67 | perror("Error mapping file to memory"); 68 | close(fd); 69 | fd = -1; 70 | mapped_data = nullptr; 71 | return false; 72 | } 73 | 74 | read_ptr = mapped_data; 75 | end_of_file = mapped_data + file_size; 76 | is_open = true; 77 | is_final = false; 78 | 79 | return true; 80 | } 81 | 82 | bool MmapLineReader::get_next_line(std::string_view &line) { 83 | if (read_ptr == nullptr || read_ptr >= end_of_file) { 84 | is_final = true; 85 | return false; 86 | } 87 | 88 | const void *newline_ptr_void = memchr(read_ptr, '\n', end_of_file - read_ptr); 89 | 90 | const char *line_start = read_ptr; 91 | const char *line_end; 92 | 93 | if (newline_ptr_void != nullptr) { 94 | 95 | line_end = static_cast(newline_ptr_void); 96 | read_ptr = line_end + 1; 97 | } else { 98 | line_end = end_of_file; 99 | read_ptr = end_of_file; 100 | } 101 | line = std::string_view(line_start, line_end - line_start); 102 | 103 | DEBUG_INFO(std::cout << std::hex << "Read Line: 0x" << lines_read << ", 0x" << line << std::dec << std::endl;) 104 | 105 | lines_read++; 106 | 107 | return true; 108 | } 109 | 110 | bool MmapLineReader::probe_next_line(std::string_view &line) { 111 | if (read_ptr == nullptr || read_ptr >= end_of_file) { 112 | return false; 113 | } 114 | 115 | const void *newline_ptr_void = memchr(read_ptr, '\n', end_of_file - read_ptr); 116 | 117 | const char *line_start = read_ptr; 118 | const char *line_end; 119 | 120 | if (newline_ptr_void != nullptr) { 121 | line_end = static_cast(newline_ptr_void); 122 | } else { 123 | line_end = end_of_file; 124 | } 125 | 126 | line = std::string_view(line_start, line_end - line_start); 127 | 128 | DEBUG_INFO(std::cout << std::hex << "Probe Line: 0x" << lines_read + 1 << ", 0x" << line << std::dec << std::endl;) 129 | return true; 130 | } 131 | 132 | size_t MmapLineReader::get_line_read_count() const { 133 | return lines_read; 134 | } 135 | -------------------------------------------------------------------------------- /src/test/csrc/common/dut.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * 4 | * DiffTest is licensed under Mulan PSL v2. 5 | * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 | * You may obtain a copy of Mulan PSL v2 at: 7 | * http://license.coscl.org.cn/MulanPSL2 8 | * 9 | * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10 | * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11 | * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12 | * 13 | * See the Mulan PSL v2 for more details. 14 | ***************************************************************************************/ 15 | 16 | #ifndef __DUT_H__ 17 | #define __DUT_H__ 18 | 19 | #include "common.h" 20 | #include "coverage.h" 21 | #include 22 | 23 | class DUT { 24 | public: 25 | DUT() {}; 26 | DUT(int argc, const char *argv[]) {}; 27 | virtual int tick() = 0; 28 | virtual int is_finished() = 0; 29 | virtual int is_good() = 0; 30 | }; 31 | 32 | #define simstats_display(s, ...) eprintf(ANSI_COLOR_GREEN s ANSI_COLOR_RESET, ##__VA_ARGS__) 33 | 34 | enum { 35 | STATE_GOODTRAP = 0, 36 | STATE_BADTRAP = 1, 37 | STATE_ABORT = 2, 38 | STATE_LIMIT_EXCEEDED = 3, 39 | STATE_SIG = 4, 40 | STATE_AMBIGUOUS = 5, 41 | STATE_SIM_EXIT = 6, 42 | STATE_FUZZ_COND = 7, 43 | STATE_RUNNING = -1 44 | }; 45 | 46 | enum class SimExitCode { 47 | good_trap, 48 | exceed_limit, 49 | bad_trap, 50 | exception_loop, 51 | ambiguous, 52 | sim_exit, 53 | difftest, 54 | unknown 55 | }; 56 | 57 | class SimStats { 58 | public: 59 | // coverage statistics 60 | std::vector cover; 61 | // simulation exit code 62 | SimExitCode exit_code; 63 | 64 | SimStats() { 65 | #ifdef CONFIG_DIFFTEST_INSTRCOVER 66 | auto c_instr = new InstrCoverage; 67 | cover.push_back(c_instr); 68 | #endif // CONFIG_DIFFTEST_INSTRCOVER 69 | #ifdef CONFIG_DIFFTEST_INSTRIMMCOVER 70 | auto c_instrimm = new InstrImmCoverage; 71 | cover.push_back(c_instrimm); 72 | #endif // CONFIG_DIFFTEST_INSTRIMMCOVER 73 | #ifdef FIRRTL_COVER 74 | auto c_firrtl = new FIRRTLCoverage; 75 | cover.push_back(c_firrtl); 76 | #endif // FIRRTL_COVER 77 | #ifdef LLVM_COVER 78 | auto c_llvm = new LLVMSanCoverage; 79 | cover.push_back(c_llvm); 80 | #endif // LLVM_COVER 81 | 82 | // #if defined(CONFIG_DIFFTEST_INSTRCOVER) && defined(FIRRTL_COVER) 83 | // auto c_union_instr_firrtl = new UnionCoverage(c_instr, c_firrtl); 84 | // cover.push_back(c_union_instr_firrtl); 85 | // #endif // CONFIG_DIFFTEST_INSTRCOVER && FIRRTL_COVER 86 | // #if defined(CONFIG_DIFFTEST_INSTRIMMCOVER) && defined(FIRRTL_COVER) 87 | // auto c_union_instrimm_firrtl = new UnionCoverage(c_instrimm, c_firrtl); 88 | // cover.push_back(c_union_instrimm_firrtl); 89 | // #endif // CONFIG_DIFFTEST_INSTRIMMCOVER && FIRRTL_COVER 90 | reset(); 91 | }; 92 | 93 | void reset() { 94 | for (auto cov: cover) { 95 | cov->reset(); 96 | } 97 | exit_code = SimExitCode::unknown; 98 | } 99 | 100 | void update(DiffTestState *state) { 101 | for (auto cov: cover) { 102 | cov->update(state); 103 | } 104 | } 105 | 106 | void display() { 107 | for (auto cov: cover) { 108 | cov->display(); 109 | } 110 | // simstats_display("ExitCode: %d\n", (int)exit_code); 111 | } 112 | 113 | void display_uncovered_points() { 114 | for (auto cov: cover) { 115 | cov->display_uncovered_points(); 116 | } 117 | fflush(stdout); 118 | } 119 | 120 | void accumulate() { 121 | for (auto cov: cover) { 122 | cov->accumulate(); 123 | } 124 | } 125 | 126 | void set_feedback_cover(const char *name) { 127 | for (auto cov: cover) { 128 | cov->update_is_feedback(name); 129 | } 130 | } 131 | 132 | Coverage *get_feedback_cover() { 133 | for (auto cov: cover) { 134 | if (cov->is_feedback) { 135 | return cov; 136 | } 137 | } 138 | printf("Failed to find any feedback coverage.\n"); 139 | return nullptr; 140 | } 141 | }; 142 | 143 | extern SimStats stats; 144 | 145 | #endif 146 | -------------------------------------------------------------------------------- /src/main/scala/Replay.scala: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2024 Institute of Computing Technology, Chinese Academy of Sciences 3 | * 4 | * DiffTest is licensed under Mulan PSL v2. 5 | * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 | * You may obtain a copy of Mulan PSL v2 at: 7 | * http://license.coscl.org.cn/MulanPSL2 8 | * 9 | * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10 | * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11 | * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12 | * 13 | * See the Mulan PSL v2 for more details. 14 | ***************************************************************************************/ 15 | 16 | package difftest.replay 17 | 18 | import chisel3._ 19 | import chisel3.experimental.ExtModule 20 | import chisel3.util._ 21 | import difftest._ 22 | import difftest.gateway.GatewayConfig 23 | 24 | object Replay { 25 | def apply(bundles: MixedVec[DifftestBundle], config: GatewayConfig): MixedVec[DifftestBundle] = { 26 | val module = Module(new ReplayEndpoint(chiselTypeOf(bundles).toSeq, config)) 27 | module.in := bundles 28 | module.out 29 | } 30 | } 31 | 32 | class ReplayEndpoint(bundles: Seq[DifftestBundle], config: GatewayConfig) extends Module { 33 | val in = IO(Input(MixedVec(bundles))) 34 | val info = WireInit(0.U.asTypeOf(new DiffTraceInfo(config))) 35 | val appendIn = WireInit(0.U.asTypeOf(MixedVec(bundles ++ Seq(chiselTypeOf(info))))) 36 | in.zipWithIndex.foreach { case (gen, idx) => appendIn(idx) := gen } 37 | appendIn.last := info 38 | val out = IO(Output(chiselTypeOf(appendIn))) 39 | 40 | val control = Module(new ReplayControl(config)) 41 | control.clock := clock 42 | control.reset := reset 43 | 44 | val buffer = Mem(config.replaySize, chiselTypeOf(appendIn)) 45 | val ptr = RegInit(0.U(config.replayWidth.W)) 46 | 47 | // write 48 | // ignore useless data when hasGlobalEnable 49 | val needStore = WireInit(true.B) 50 | if (config.hasGlobalEnable) { 51 | needStore := VecInit(in.flatMap(_.bits.needUpdate).toSeq).asUInt.orR 52 | } 53 | info.valid := needStore 54 | info.trace_head := ptr 55 | info.trace_size := 1.U 56 | when(needStore && !control.replay) { 57 | buffer(ptr) := appendIn 58 | ptr := ptr + 1.U 59 | when(ptr === (config.replaySize - 1).U) { 60 | ptr := 0.U 61 | } 62 | } 63 | 64 | // read 65 | val in_replay = RegInit(false.B) // indicates ptr in correct replay pos 66 | when(control.replay) { 67 | when(!in_replay) { 68 | in_replay := true.B 69 | ptr := control.replay_head // position of first corresponding replay data 70 | }.otherwise { 71 | ptr := ptr + 1.U 72 | when(ptr === (config.replaySize - 1).U) { 73 | ptr := 0.U 74 | } 75 | } 76 | } 77 | out := Mux(in_replay, buffer(ptr), appendIn) 78 | out.filter(_.desiredCppName == "trace_info").foreach { gen => 79 | val info = gen.asInstanceOf[DiffTraceInfo] 80 | info.in_replay := in_replay 81 | } 82 | } 83 | 84 | class ReplayControl(config: GatewayConfig) extends ExtModule with HasExtModuleInline { 85 | val clock = IO(Input(Clock())) 86 | val reset = IO(Input(Reset())) 87 | val replay = IO(Output(Bool())) 88 | val replay_head = IO(Output(UInt(config.replayWidth.W))) 89 | 90 | setInline( 91 | "ReplayControl.v", 92 | s""" 93 | |module ReplayControl( 94 | | input clock, 95 | | input reset, 96 | | output reg replay, 97 | | output reg [${config.replayWidth - 1}:0] replay_head 98 | |); 99 | | 100 | |`ifndef SYNTHESIS 101 | |`ifdef DIFFTEST 102 | |import "DPI-C" context function void set_replay_scope(); 103 | | 104 | |initial begin 105 | | set_replay_scope(); 106 | | replay = 1'b0; 107 | | replay_head = ${config.replayWidth}'b0; 108 | |end 109 | | 110 | |// For the C/C++ interface 111 | |export "DPI-C" function set_replay_head; 112 | |function void set_replay_head(int head); 113 | | replay = 1'b1; 114 | | replay_head = head; 115 | |endfunction 116 | |`endif // DIFFTEST 117 | |`endif // SYNTHESIS 118 | |endmodule; 119 | |""".stripMargin, 120 | ) 121 | } 122 | -------------------------------------------------------------------------------- /src/main/scala/util/Profile.scala: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2024 Institute of Computing Technology, Chinese Academy of Sciences 3 | * 4 | * DiffTest is licensed under Mulan PSL v2. 5 | * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 | * You may obtain a copy of Mulan PSL v2 at: 7 | * http://license.coscl.org.cn/MulanPSL2 8 | * 9 | * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10 | * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11 | * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12 | * 13 | * See the Mulan PSL v2 for more details. 14 | ***************************************************************************************/ 15 | 16 | package difftest.util 17 | 18 | import difftest.{DifftestBundle, DifftestModule} 19 | import difftest.common.FileControl 20 | import org.json4s.DefaultFormats 21 | import org.json4s.native._ 22 | 23 | import java.nio.file.{Files, Paths} 24 | 25 | // Note: json4s seems to load integers with BigInt. We may need to convert them into int if necessary 26 | 27 | case class BundleProfile( 28 | className: String, 29 | classArgs: Map[String, Any], 30 | delay: Int, 31 | ) { 32 | def toBundle: DifftestBundle = { 33 | val constructor = Class.forName(className).getConstructors()(0) 34 | val args = constructor.getParameters.map { param => 35 | (classArgs(param.getName), param.getType.getName) match { 36 | case (arg: BigInt, "int") => arg.toInt 37 | case (arg, _) => arg 38 | } 39 | } 40 | constructor.newInstance(args: _*).asInstanceOf[DifftestBundle] 41 | } 42 | } 43 | 44 | case class DifftestProfile( 45 | cpu: String, 46 | numCores: Int, 47 | cmdConfigs: Seq[String], 48 | bundles: Seq[BundleProfile], 49 | ) { 50 | def toJsonString: String = Serialization.writePretty(this)(DefaultFormats) 51 | } 52 | 53 | object DifftestProfile { 54 | def fromBundles(cpu: String, cmdConfigs: Seq[String], bundles: Seq[(DifftestBundle, Int)]): DifftestProfile = { 55 | val numCores = bundles.count(_._1.isUniqueIdentifier) 56 | // Note: numCores may be 0 when difftest interfaces are not connected 57 | require(numCores == 0 || bundles.length % numCores == 0, "cannot create the profile if cores are not symmetric") 58 | val nBundles = if (numCores > 0) bundles.length / numCores else 0 59 | val bundleProfiles = bundles.take(nBundles).map { case (b, d) => BundleProfile.fromBundle(b, d) } 60 | DifftestProfile(cpu, numCores, cmdConfigs, bundleProfiles) 61 | } 62 | 63 | def fromJson(filename: String): DifftestProfile = { 64 | val profileStr = new String(Files.readAllBytes(Paths.get(filename))) 65 | val profiles = JsonMethods.parse(profileStr).extract(DefaultFormats, manifest[Map[String, Any]]) 66 | val cpu = profiles("cpu").asInstanceOf[String] 67 | val numCores = profiles("numCores").asInstanceOf[BigInt].toInt 68 | val cmdConfigs = profiles("cmdConfigs").asInstanceOf[Seq[String]] 69 | val bundles = profiles("bundles").asInstanceOf[List[Map[String, Any]]].map { bundleProfileMap => 70 | BundleProfile( 71 | bundleProfileMap("className").asInstanceOf[String], 72 | bundleProfileMap("classArgs").asInstanceOf[Map[String, Any]], 73 | bundleProfileMap("delay").asInstanceOf[BigInt].toInt, 74 | ) 75 | } 76 | DifftestProfile(cpu, numCores, cmdConfigs, bundles) 77 | } 78 | } 79 | 80 | object BundleProfile { 81 | def fromBundle(bundle: DifftestBundle, delay: Int): BundleProfile = { 82 | BundleProfile(bundle.getClass.getName, bundle.classArgs, delay) 83 | } 84 | } 85 | 86 | object Profile { 87 | def generateJson( 88 | cpu: String, 89 | cmdConfigs: Seq[String], 90 | bundles: Seq[(DifftestBundle, Int)], 91 | profileName: String = "difftest", 92 | ): Unit = { 93 | val difftestProfile = DifftestProfile.fromBundles(cpu, cmdConfigs, bundles) 94 | FileControl.write(Seq(difftestProfile.toJsonString), s"${profileName}_profile.json") 95 | } 96 | 97 | // This function generates the json profile for current DiffTest interfaces. 98 | def generateJson(cpu: String): Unit = { 99 | val cmdConfigs = DifftestModule.get_command_configs() 100 | val bundles = DifftestModule.get_current_interfaces() 101 | generateJson(cpu, cmdConfigs, bundles) 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/test/csrc/fpga/serial_port.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC) 3 | * Copyright (c) 2020-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 | #include "serial_port.h" 18 | #include 19 | #include 20 | #include 21 | 22 | #ifdef USE_SERIAL_PORT 23 | 24 | bool SerialPort::open_port(int baudrate) { 25 | fd_ = open(device_, O_RDWR | O_NOCTTY | O_SYNC); 26 | if (fd_ < 0) { 27 | std::cerr << "Failed to open " << device_ << std::endl; 28 | return false; 29 | } 30 | struct termios tty; 31 | memset(&tty, 0, sizeof tty); 32 | if (tcgetattr(fd_, &tty) != 0) { 33 | std::cerr << "Error from tcgetattr" << std::endl; 34 | return false; 35 | } 36 | cfsetospeed(&tty, baudrate); 37 | cfsetispeed(&tty, baudrate); 38 | tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars 39 | tty.c_iflag &= ~IGNBRK; // disable break processing 40 | tty.c_lflag = 0; // no signaling chars, no echo, 41 | // no canonical processing 42 | tty.c_oflag = 0; // no remapping, no delays 43 | tty.c_cc[VMIN] = 1; // read blocks 44 | tty.c_cc[VTIME] = 1; // 0.1 seconds read timeout 45 | 46 | tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl 47 | 48 | tty.c_cflag |= (CLOCAL | CREAD); // ignore modem controls, 49 | // enable reading 50 | tty.c_cflag &= ~(PARENB | PARODD); // shut off parity 51 | tty.c_cflag &= ~CSTOPB; 52 | tty.c_cflag &= ~CRTSCTS; 53 | 54 | if (tcsetattr(fd_, TCSANOW, &tty) != 0) { 55 | std::cerr << "Error from tcsetattr" << std::endl; 56 | return false; 57 | } 58 | return true; 59 | } 60 | 61 | void SerialPort::close_port() { 62 | if (fd_ >= 0) { 63 | close(fd_); 64 | fd_ = -1; 65 | } 66 | } 67 | 68 | SerialPort::~SerialPort() { 69 | close_port(); 70 | } 71 | void SerialPort::start_read_thread() { 72 | char buf[256]; 73 | try { 74 | printf("SerailPort: start read from %s\n", device_); 75 | setvbuf(stdout, NULL, _IONBF, 0); 76 | while (running) { 77 | fd_set readfds; 78 | FD_ZERO(&readfds); 79 | FD_SET(fd_, &readfds); 80 | int ret = select(fd_ + 1, &readfds, nullptr, nullptr, nullptr); 81 | if (ret > 0 && FD_ISSET(fd_, &readfds)) { 82 | ssize_t n = read(fd_, buf, sizeof(buf) - 1); 83 | if (n > 0) { 84 | buf[n] = '\0'; 85 | printf("%s", buf); 86 | } 87 | } 88 | } 89 | } catch (const std::exception &e) { 90 | std::cerr << "SerialPort: exception " << e.what() << std::endl; 91 | } catch (...) { 92 | std::cerr << "SerialPort: unknown exception" << std::endl; 93 | } 94 | } 95 | 96 | void SerialPort::start_write_thread() { 97 | try { 98 | printf("SerialPort: start write to %s\n", device_); 99 | std::string line; 100 | while (running) { 101 | fd_set readfds; 102 | FD_ZERO(&readfds); 103 | FD_SET(STDIN_FILENO, &readfds); 104 | timeval tv{1, 0}; // eheck timeout per second 105 | int ret = select(STDIN_FILENO + 1, &readfds, nullptr, nullptr, &tv); 106 | if (ret > 0 && FD_ISSET(STDIN_FILENO, &readfds)) { 107 | std::string line; 108 | if (std::getline(std::cin, line)) { 109 | line.push_back('\n'); 110 | write(fd_, line.c_str(), line.size()); 111 | } 112 | } 113 | } 114 | } catch (const std::exception &e) { 115 | std::cerr << "SerialPort: exception " << e.what() << std::endl; 116 | } catch (...) { 117 | std::cerr << "SerialPort: unknown exception" << std::endl; 118 | } 119 | } 120 | 121 | #endif // USE_SERIAL_PORT 122 | -------------------------------------------------------------------------------- /scripts/fpga/release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # ---------------------------------------------------------- 5 | # 1. Extract CPU_DIR and RELEASE_DIR from args 6 | # ---------------------------------------------------------- 7 | 8 | CPU_DIR="$1" 9 | RELEASE_DIR="$2" 10 | if [ $# -ne 2 ]; then 11 | echo "Usage: $0 " 12 | exit 1 13 | fi 14 | DIFF_HOME="$CPU_DIR/difftest" 15 | PROFILE_JSON="$CPU_DIR/build/generated-src/difftest_profile.json" 16 | 17 | if [ ! -f "$PROFILE_JSON" ]; then 18 | echo "ERROR: difftest_profile.json not found at:" 19 | echo " $PROFILE_JSON" 20 | exit 1 21 | fi 22 | 23 | # ---------------------------------------------------------- 24 | # 2. Extract cpu and cmdConfigs from JSON 25 | # ---------------------------------------------------------- 26 | 27 | if [ command -v jq >/dev/null 2>&1 ]; then 28 | CPU_NAME=$(jq -r '.cpu' "$PROFILE_JSON") 29 | CMDS=$(jq -r '.cmdConfigs[]?' "$PROFILE_JSON") 30 | else 31 | CPU_NAME=$(grep -o '"cpu" *: *"[^"]*"' "$PROFILE_JSON" | sed 's/.*: *"//; s/"$//') 32 | CMDS=$(sed -n '/"cmdConfigs"/,/]/p' "$PROFILE_JSON" \ 33 | | grep -o '"[^"]*"' \ 34 | | sed 's/"//g') 35 | fi 36 | 37 | CPU_CONFIG="Unknown" 38 | DIFF_LEVEL="BasicDiff" 39 | DIFF_EXCLUDE= 40 | DIFF_CONFIG="Unknown" 41 | PREV="" 42 | 43 | for token in $CMDS; do 44 | if [[ "$token" == BOARD=* ]]; then 45 | CPU_CONFIG="${token#BOARD=}" 46 | fi 47 | if [ "$token" == "--enable-difftest" ]; then 48 | DIFF_LEVEL="FullDiff" 49 | fi 50 | if [ "$PREV" = "--config" ]; then 51 | CPU_CONFIG="$token" 52 | fi 53 | if [ "$PREV" = "--difftest-config" ]; then 54 | DIFF_CONFIG="$token" 55 | fi 56 | if [ "$PREV" = "--difftest-exclude" ]; then 57 | DIFF_EXCLUDE=$(echo "$token" | sed 's/\([^,]*\)/-no\1/g; s/,//g') 58 | fi 59 | PREV="$token" 60 | done 61 | if [ -n "$DIFF_EXCLUDE" ]; then 62 | DIFF_LEVEL="${DIFF_LEVEL}${DIFF_EXCLUDE}" 63 | fi 64 | 65 | DATE=$(date +"%Y%m%d") 66 | RELEASE_TAG="${DATE}_${CPU_NAME}_${CPU_CONFIG}_${DIFF_LEVEL}_${DIFF_CONFIG}" 67 | RELEASE_HOME="$CPU_DIR/$RELEASE_TAG" 68 | 69 | # ---------------------------------------------------------- 70 | # 3. Copy RTL and Source Code 71 | # ---------------------------------------------------------- 72 | 73 | mkdir -p ${RELEASE_HOME} 74 | 75 | echo "Copying $CPU_DIR/build/ into $RELEASE_HOME/build ..." 76 | rsync -av \ 77 | --exclude='rtl/*.fir' \ 78 | --exclude='*-compile/' \ 79 | --exclude='emu/' \ 80 | --exclude='simv*' \ 81 | "$CPU_DIR/build/" "$RELEASE_HOME/build/" 82 | echo "CPU Build copied." 83 | 84 | echo "Copying $DIFF_HOME into $RELEASE_HOME ..." 85 | rsync -av \ 86 | --include='config/***' \ 87 | --include='src/***' \ 88 | --include='*.mk' \ 89 | --include='Makefile' \ 90 | --exclude='*' \ 91 | "$DIFF_HOME/" "$RELEASE_HOME/difftest/" 92 | 93 | RELEASE_RTL="$RELEASE_HOME/build/rtl" 94 | echo "Copying $DIFF_HOME/src/test/vsrc/fpga into $RELEASE_RTL ..." 95 | cp $DIFF_HOME/src/test/vsrc/fpga/* $RELEASE_RTL 96 | echo "Difftest Source copied." 97 | 98 | echo "Replacing RAM with depth > 4000 to URAM ..." 99 | for f in "$RELEASE_RTL"/array_*.v; do 100 | [ -f "$f" ] || continue 101 | echo "$f" 102 | sed -i \ 103 | "s/reg \(\[[0-9]*:[0-9]*\]\) ram \[\([4-9][0-9]\{3,\}\|[1-9][0-9]\{4,\}\):0\];/(* ram_style = \"ultra\" *) reg \1 ram [\2:0];/g" \ 104 | "$f" 105 | done 106 | echo "Replacing done." 107 | 108 | # ----------------------------- 109 | # 4. Print Git Version 110 | # ----------------------------- 111 | 112 | GIT_FILE="$RELEASE_HOME/git-version.txt" 113 | echo "Generate Git Version to $GIT_FILE" 114 | 115 | { 116 | echo "Project Path: $CPU_DIR" 117 | echo "Generated at: $(date)" 118 | echo "===============================" 119 | echo " $CPU_NAME" 120 | echo "===============================" 121 | echo "Branch : $(git -C "$CPU_DIR" branch --show-current)" 122 | echo "Latest logs :" 123 | git -C $CPU_DIR log -n 10 --pretty=format:" %h | %ad | %an | %s" --date=short 124 | echo "" 125 | echo "===============================" 126 | echo " DiffTest" 127 | echo "===============================" 128 | echo "Branch : $(git -C "$DIFF_HOME" branch --show-current)" 129 | echo "Latest logs :" 130 | git -C $DIFF_HOME log -n 10 --pretty=format:" %h | %ad | %an | %s" --date=short 131 | echo "" 132 | } > "$GIT_FILE" 133 | 134 | echo "Release FpgaDiff to $RELEASE_HOME done." 135 | RELEASE_PKG="$RELEASE_DIR/$RELEASE_TAG.tar.gz" 136 | tar -zcf $RELEASE_PKG -C $(dirname $RELEASE_HOME) $(basename $RELEASE_HOME) 137 | -------------------------------------------------------------------------------- /palladium.mk: -------------------------------------------------------------------------------- 1 | PLDM_TB_TOP = tb_top 2 | PLDM_TOP_MODULE = $(SIM_TOP) 3 | 4 | PLDM_SCRIPTS_DIR = $(abspath ./scripts/palladium) 5 | PLDM_BUILD_DIR = $(abspath $(BUILD_DIR)/pldm-compile) 6 | PLDM_CC_OBJ_DIR = $(abspath $(PLDM_BUILD_DIR)/cc_obj) 7 | 8 | # Verilog Flags 9 | PLDM_VFLAGS = $(SIM_VFLAGS) +define+TOP_MODULE=$(PLDM_TOP_MODULE) 10 | PLDM_VFLAGS += +define+PALLADIUM 11 | PLDM_VFLAGS += +define+RANDOMIZE_MEM_INIT 12 | PLDM_VFLAGS += +define+RANDOMIZE_REG_INIT 13 | PLDM_VFLAGS += +define+RANDOMIZE_DELAY=0 14 | PLDM_VFLAGS += +define+DISABLE_SIMJTAG_DPIC 15 | PLDM_VFLAGS += $(PLDM_EXTRA_MACRO) 16 | 17 | ifeq ($(WORKLOAD_SWITCH),1) 18 | PLDM_VFLAGS += +define+ENABLE_WORKLOAD_SWITCH 19 | endif 20 | ifeq ($(WITH_DRAMSIM3),1) 21 | PLDM_VFLAGS += +define+WITH_DRAMSIM3 22 | endif 23 | 24 | # UA Args 25 | IXCOM_FLAGS = -clean -64 -ua +sv +ignoreSimVerCheck +xe_alt_xlm 26 | ifeq ($(SYNTHESIS), 1) 27 | IXCOM_FLAGS += +1xua 28 | else 29 | IXCOM_FLAGS += +iscDelay+tb_top -enableLargeSizeMem 30 | endif 31 | 32 | # Compiler Args 33 | IXCOM_FLAGS += -xecompile compilerOptions=$(PLDM_SCRIPTS_DIR)/compilerOptions.qel 34 | IXCOM_FLAGS += +gfifoDisp+tb_top 35 | IXCOM_FLAGS += $(addprefix -incdir , $(PLDM_VSRC_DIR)) 36 | IXCOM_FLAGS += $(PLDM_VFLAGS) 37 | IXCOM_FLAGS += +dut+$(PLDM_TB_TOP) 38 | ifeq ($(SYNTHESIS), 1) 39 | PLDM_CLOCK = clock_gen 40 | PLDM_CLOCK_DEF = $(PLDM_SCRIPTS_DIR)/$(PLDM_CLOCK).xel 41 | PLDM_CLOCK_SRC = $(PLDM_BUILD_DIR)/$(PLDM_CLOCK).sv 42 | IXCOM_FLAGS += +dut+$(PLDM_CLOCK) $(PLDM_CLOCK_SRC) 43 | endif 44 | 45 | # Other Args 46 | IXCOM_FLAGS += -v $(PLDM_IXCOM)/IXCclkgen.sv 47 | ifneq ($(SYNTHESIS), 1) 48 | IXCOM_FLAGS += +rtlCommentPragma +tran_relax -relativeIXCDIR -rtlNameForGenerate 49 | endif 50 | IXCOM_FLAGS += +tfconfig+$(PLDM_SCRIPTS_DIR)/argConfigs.qel 51 | 52 | # Verilog Files 53 | PLDM_VSRC_DIR = $(RTL_DIR) $(GEN_VSRC_DIR) $(abspath ./src/test/vsrc/vcs) $(abspath ./src/test/vsrc/common) 54 | PLDM_VFILELIST = $(PLDM_BUILD_DIR)/vfiles.f 55 | IXCOM_FLAGS += -F $(PLDM_VFILELIST) 56 | 57 | # VLAN Flags 58 | ifneq ($(SYNTHESIS), 1) 59 | VLAN_FLAGS = -64 -sv 60 | VLAN_FLAGS += $(addprefix -incdir , $(PLDM_VSRC_DIR)) 61 | VLAN_FLAGS += -vtimescale 1ns/1ns 62 | VLAN_FLAGS += $(PLDM_VFLAGS) 63 | VLAN_FLAGS += -F $(PLDM_VFILELIST) 64 | endif 65 | 66 | # SoftWare Compile 67 | PLDM_SIMTOOL = $(shell cds_root xrun)/tools/include 68 | PLDM_IXCOM = $(shell cds_root ixcom)/share/uxe/etc/ixcom 69 | DPILIB_EMU = $(PLDM_BUILD_DIR)/libdpi_emu.so 70 | PLDM_CSRC_DIR = $(abspath ./src/test/csrc/vcs) 71 | PLDM_CXXFILES = $(SIM_CXXFILES) $(shell find $(PLDM_CSRC_DIR) -name "*.cpp") 72 | PLDM_CXXFLAGS = -O3 -m64 -c -fPIC -g -std=c++11 -I$(PLDM_IXCOM) -I$(PLDM_SIMTOOL) 73 | PLDM_CXXFLAGS += $(subst \\\",\", $(SIM_CXXFLAGS)) $(SIM_LDFLAGS) -I$(PLDM_CSRC_DIR) 74 | 75 | ifeq ($(WITH_DRAMSIM3),1) 76 | PLDM_LD_LIB = -L $(DRAMSIM3_HOME)/ -ldramsim3 -Wl,-rpath-link=$(DRAMSIM3_HOME)/libdramsim3.so 77 | endif 78 | 79 | # XMSIM Flags 80 | XMSIM_FLAGS = --xmsim -64 +xcprof -profile -PROFTHREAD 81 | ifneq ($(SYNTHESIS), 1) 82 | XMSIM_FLAGS += -sv_lib ${DPILIB_EMU} 83 | endif 84 | XMSIM_FLAGS += $(PLDM_EXTRA_ARGS) 85 | XMSIM_FLAGS += -- 86 | 87 | $(PLDM_BUILD_DIR): 88 | mkdir -p $(PLDM_BUILD_DIR) 89 | 90 | $(PLDM_CC_OBJ_DIR): 91 | mkdir -p $(PLDM_CC_OBJ_DIR) 92 | 93 | $(PLDM_VFILELIST): 94 | find $(PLDM_VSRC_DIR) -name "*.v" -or -name "*.sv" >> $(PLDM_VFILELIST) 95 | 96 | $(PLDM_CLOCK_SRC): $(PLDM_CLOCK_DEF) 97 | ixclkgen -input $(PLDM_CLOCK_DEF) -output $(PLDM_CLOCK_SRC) -module $(PLDM_CLOCK) -hierarchy "$(PLDM_TB_TOP)." 98 | 99 | 100 | ifeq ($(SYNTHESIS), 1) 101 | pldm-build: $(PLDM_BUILD_DIR) $(PLDM_VFILELIST) $(PLDM_CLOCK_SRC) 102 | cd $(PLDM_BUILD_DIR) && \ 103 | ixcom $(IXCOM_FLAGS) -l $(PLDM_BUILD_DIR)/ixcom.log 104 | else 105 | pldm-build: $(PLDM_BUILD_DIR) $(PLDM_VFILELIST) $(DPILIB_EMU) 106 | cd $(PLDM_BUILD_DIR) && \ 107 | vlan $(VLAN_FLAGS) -l $(PLDM_BUILD_DIR)/vlan.log && \ 108 | ixcom $(IXCOM_FLAGS) -l $(PLDM_BUILD_DIR)/ixcom.log 109 | 110 | $(DPILIB_EMU): $(PLDM_CC_OBJ_DIR) 111 | cd $(PLDM_CC_OBJ_DIR) && \ 112 | $(CC) $(PLDM_CXXFLAGS) $(PLDM_CXXFILES) && \ 113 | $(CC) -o $@ -m64 -shared *.o $(PLDM_LD_LIB) 114 | endif 115 | 116 | pldm-run: $(PLDM_BUILD_DIR) 117 | cd $(PLDM_BUILD_DIR) && \ 118 | xeDebug $(XMSIM_FLAGS) -input $(PLDM_SCRIPTS_DIR)/run.tcl -l run-$$(date +%Y%m%d-%H%M%S).log 119 | 120 | pldm-debug: $(PLDM_BUILD_DIR) 121 | cd $(PLDM_BUILD_DIR) && \ 122 | xeDebug $(XMSIM_FLAGS) -fsdb -input $(PLDM_SCRIPTS_DIR)/run_debug.tcl -l debug-$$(date +%Y%m%d-%H%M%S).log 123 | 124 | pldm-clean: 125 | rm -rf $(PLDM_BUILD_DIR) 126 | -------------------------------------------------------------------------------- /src/main/scala/common/WiringControl.scala: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2024 Institute of Computing Technology, Chinese Academy of Sciences 3 | * 4 | * DiffTest is licensed under Mulan PSL v2. 5 | * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 | * You may obtain a copy of Mulan PSL v2 at: 7 | * http://license.coscl.org.cn/MulanPSL2 8 | * 9 | * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10 | * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11 | * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12 | * 13 | * See the Mulan PSL v2 for more details. 14 | ***************************************************************************************/ 15 | 16 | package difftest.common 17 | 18 | import chisel3._ 19 | import chisel3.util.experimental.BoringUtils 20 | import chisel3.reflect.DataMirror 21 | 22 | // Wrapper for the Chisel wiring utils. 23 | private object WiringControl { 24 | def addSource(data: Data, name: String): Unit = BoringUtils.addSource(data, s"difftest_$name") 25 | 26 | def addSink(data: Data, name: String): Unit = BoringUtils.addSink(data, s"difftest_$name") 27 | 28 | def tapAndRead[T <: Data](source: T): T = BoringUtils.tapAndRead(source) 29 | 30 | def bore[T <: Data](source: T): T = BoringUtils.bore(source) 31 | } 32 | 33 | private class WiringInfo(val data: Data, val name: String, val isHierarchical: Boolean) { 34 | private var nSources: Int = 0 35 | private var nSinks: Int = 0 36 | 37 | def setSource(): WiringInfo = { 38 | require(nSources == 0, s"$name already declared as a source") 39 | nSources += 1 40 | this 41 | } 42 | 43 | def addSink(): WiringInfo = { 44 | nSinks += 1 45 | this 46 | } 47 | 48 | def isPending: Boolean = nSources == 0 || nSinks == 0 49 | // (isSource, dataType, name) 50 | def toPendingTuple: Option[(Boolean, Data, String, Boolean)] = { 51 | if (isPending) { 52 | Some((nSources == 0, chiselTypeOf(data), name, isHierarchical)) 53 | } else { 54 | None 55 | } 56 | } 57 | } 58 | 59 | object DifftestWiring { 60 | private val wires = scala.collection.mutable.ListBuffer.empty[WiringInfo] 61 | private def getWire(data: Data, name: String, isHierarchical: Boolean): WiringInfo = { 62 | wires.find(_.name == name).getOrElse { 63 | val info = new WiringInfo(data, name, isHierarchical) 64 | wires.addOne(info) 65 | info 66 | } 67 | } 68 | 69 | def addSource[T <: Data](data: T, name: String, isHierarchical: Boolean): T = { 70 | getWire(data, name, isHierarchical).setSource() 71 | data 72 | } 73 | 74 | def addSource[T <: Data](data: T, name: String): T = { 75 | addSource[T](data, name, false) 76 | } 77 | 78 | def addSink[T <: Data](data: T, name: String, isHierarchical: Boolean): T = { 79 | val info = getWire(data, name, isHierarchical).addSink() 80 | require(!info.isPending, s"[${info.name}]: Wiring requires addSource before addSink") 81 | if (DataMirror.isVisible(info.data)) { 82 | data := info.data 83 | } else if (isHierarchical) { 84 | data := WiringControl.tapAndRead(info.data) 85 | } else { 86 | data := WiringControl.bore(info.data) 87 | } 88 | data 89 | } 90 | 91 | def addSink[T <: Data](data: T, name: String): T = { 92 | addSink[T](data, name, false) 93 | } 94 | 95 | def isEmpty: Boolean = !hasPending 96 | def hasPending: Boolean = wires.exists(_.isPending) 97 | def getPending: Seq[(Boolean, Data, String, Boolean)] = wires.flatMap(_.toPendingTuple).toSeq 98 | 99 | def createPendingWires(): Seq[Data] = { 100 | getPending.map { case (isSource, dataType, name, isHierarchical) => 101 | val target = WireInit(0.U.asTypeOf(dataType)).suggestName(name) 102 | if (isSource) { 103 | addSource(target, name, isHierarchical) 104 | } else { 105 | addSink(target, name, isHierarchical) 106 | } 107 | } 108 | } 109 | 110 | def createExtraIOs(flipped: Boolean = false): Seq[Data] = { 111 | getPending.map { case (isSource, dataType, name, _) => 112 | def do_direction(dt: Data): Data = if (isSource) Input(dt) else Output(dt) 113 | def do_flip(dt: Data): Data = if (flipped) Flipped(dt) else dt 114 | IO(do_flip(do_direction(dataType))).suggestName(name) 115 | } 116 | } 117 | 118 | def createAndConnectExtraIOs(): Seq[Data] = { 119 | createExtraIOs().zip(createPendingWires()).map { case (io, wire) => 120 | io <> wire 121 | io 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/test/csrc/common/elfloader.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2024 Axelera AI 3 | * 4 | * DiffTest is licensed under Mulan PSL v2. 5 | * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 | * You may obtain a copy of Mulan PSL v2 at: 7 | * http://license.coscl.org.cn/MulanPSL2 8 | * 9 | * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10 | * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11 | * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12 | * 13 | * See the Mulan PSL v2 for more details. 14 | ***************************************************************************************/ 15 | 16 | #include "elfloader.h" 17 | #include 18 | 19 | void ElfBinary::load() { 20 | assert(size >= sizeof(Elf64_Ehdr)); 21 | eh64 = (const Elf64_Ehdr *)raw; 22 | assert(IS_ELF32(*eh64) || IS_ELF64(*eh64)); 23 | 24 | if (IS_ELF32(*eh64)) 25 | parse(data32); 26 | else 27 | parse(data64); 28 | } 29 | 30 | template 31 | void ElfBinary::parse(ElfBinaryData &data) { 32 | data.eh = (const ehdr_t *)raw; 33 | data.ph = (const phdr_t *)(raw + data.eh->e_phoff); 34 | entry = data.eh->e_entry; 35 | assert(size >= data.eh->e_phoff + data.eh->e_phnum * sizeof(*data.ph)); 36 | for (unsigned i = 0; i < data.eh->e_phnum; i++) { 37 | if (data.ph[i].p_type == PT_LOAD && data.ph[i].p_memsz) { 38 | if (data.ph[i].p_filesz) { 39 | assert(size >= data.ph[i].p_offset + data.ph[i].p_filesz); 40 | sections.push_back({ 41 | .data_src = (const uint8_t *)raw + data.ph[i].p_offset, 42 | .data_dst = data.ph[i].p_paddr, 43 | .data_len = data.ph[i].p_filesz, 44 | .zero_dst = data.ph[i].p_paddr + data.ph[i].p_filesz, 45 | .zero_len = data.ph[i].p_memsz - data.ph[i].p_filesz, 46 | }); 47 | } 48 | } 49 | } 50 | std::sort(sections.begin(), sections.end(), 51 | [](const ElfSection &a, const ElfSection &b) { return a.data_dst < b.data_dst; }); 52 | } 53 | 54 | ElfBinaryFile::ElfBinaryFile(const char *filename) : filename(filename) { 55 | int fd = open(filename, O_RDONLY); 56 | struct stat s; 57 | assert(fd != -1); 58 | assert(fstat(fd, &s) >= 0); 59 | size = s.st_size; 60 | 61 | raw = (uint8_t *)mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); 62 | assert(raw != MAP_FAILED); 63 | close(fd); 64 | 65 | load(); 66 | } 67 | 68 | ElfBinaryFile::~ElfBinaryFile() { 69 | if (raw) 70 | munmap((void *)raw, size); 71 | } 72 | 73 | bool isElfFile(const char *filename) { 74 | int fd = -1; 75 | 76 | #ifdef NO_IMAGE_ELF 77 | return false; 78 | #endif 79 | 80 | fd = open(filename, O_RDONLY); 81 | assert(fd); 82 | 83 | uint8_t buf[4]; 84 | 85 | size_t sz = read(fd, buf, 4); 86 | if (!IS_ELF(*((const Elf64_Ehdr *)buf))) { 87 | close(fd); 88 | return false; 89 | } 90 | 91 | close(fd); 92 | return true; 93 | } 94 | 95 | long readFromElf(void *ptr, const char *file_name, long buf_size) { 96 | auto elf_file = ElfBinaryFile(file_name); 97 | 98 | if (elf_file.sections.size() < 1) { 99 | printf("The requested elf '%s' contains zero sections\n", file_name); 100 | return -1; 101 | } 102 | 103 | uint64_t len_written = 0; 104 | auto base_addr = elf_file.sections[0].data_dst; 105 | 106 | if (base_addr != PMEM_BASE) { 107 | printf( 108 | "The first address in the elf does not match the base of the physical memory.\n" 109 | "It is likely that execution leads to unexpected behaviour.\n"); 110 | } 111 | 112 | for (auto section: elf_file.sections) { 113 | auto len = section.data_len + section.zero_len; 114 | auto offset = section.data_dst - base_addr; 115 | 116 | if (offset + len > buf_size) { 117 | printf("The size (%ld bytes) of the section at address 0x%lx is larger than buf_size!\n", len, section.data_dst); 118 | return -1; 119 | } 120 | 121 | printf("Loading %ld bytes at address 0x%lx at offset 0x%lx\n", len, section.data_dst, offset); 122 | std::memset((uint8_t *)ptr + offset, 0, len); 123 | std::memcpy((uint8_t *)ptr + offset, section.data_src, section.data_len); 124 | len_written += len; 125 | } 126 | // Since we are unpacking the sections, the total amount of bytes is the last 127 | // section offset plus its size. 128 | auto last_section = elf_file.sections.back(); 129 | return last_section.data_dst - base_addr + last_section.data_len + last_section.zero_len; 130 | } 131 | -------------------------------------------------------------------------------- /galaxsim.mk: -------------------------------------------------------------------------------- 1 | #*************************************************************************************** 2 | # Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC) 3 | # Copyright (c) 2020-2025 Institute of Computing Technology, Chinese Academy of Sciences 4 | # Copyright (c) 2020-2025 X-EPIC Co., Ltd 5 | # 6 | # DiffTest is licensed under Mulan PSL v2. 7 | # You can use this software according to the terms and conditions of the Mulan PSL v2. 8 | # You may obtain a copy of Mulan PSL v2 at: 9 | # http://license.coscl.org.cn/MulanPSL2 10 | # 11 | # THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 12 | # EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 13 | # MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 14 | # 15 | # See the Mulan PSL v2 for more details. 16 | # 17 | # GalaxSim, developed by X-EPIC Technologies, is an event-driven Verilog/SystemVerilog simulator. 18 | # 19 | # GalaxSim Turbo, another innovation from X-EPIC, is a hybrid simulation accelerator that 20 | # combines event-driven and cycle-based methodologies. 21 | # 22 | # FusionDebug, a feature-rich debugger that supports a wide array of simulation debugging techniques. 23 | # 24 | # These 3 tools are available for free trial on the website: https://free.x-epic.com/ 25 | # 26 | #*************************************************************************************** 27 | RUN_BIN ?= $(DESIGN_DIR)/ready-to-run/copy_and_run.bin 28 | GLX = galaxsim 29 | GLX_TOP = tb_top 30 | GLX_TARGET = $(abspath $(BUILD_DIR)/xsim) 31 | GLX_BUILD_DIR = $(abspath $(BUILD_DIR)/xsim-compile) 32 | GLX_RUN_DIR = $(abspath $(BUILD_DIR)/$(notdir $(RUN_BIN))) 33 | 34 | 35 | GLX_CSRC_DIR = $(abspath ./src/test/csrc/vcs) 36 | GLX_CONFIG_DIR = $(abspath ./config) 37 | 38 | GLX_CXXFILES = $(SIM_CXXFILES) $(shell find $(GLX_CSRC_DIR) -name "*.cpp") 39 | 40 | GLX_CXXFLAGS = $(SIM_CXXFLAGS) -I$(GLX_CONFIG_DIR) -I$(GLX_CSRC_DIR) 41 | 42 | GLX_LDFLAGS = $(SIM_LDFLAGS) 43 | 44 | GLX_VSRC_DIR = $(abspath ./src/test/vsrc/vcs) 45 | 46 | GLX_VFILES = $(SIM_VSRC) $(shell find $(GLX_VSRC_DIR) -name "*.v" -or -name "*.sv") 47 | 48 | GLX_FLAGS = $(SIM_VFLAGS) 49 | GLX_FLAGS += -timescale=1ns/1ns -debug_access+all 50 | GLX_FLAGS += -j8 51 | GLX_FLAGS += +define+GLX 52 | ifeq ($(ENABLE_XPROP),1) 53 | GLX_FLAGS += -xprop 54 | else 55 | # randomize all undefined signals (instead of using X) 56 | # GLX_FLAGS += -initreg 57 | endif 58 | GLX_CXXFLAGS += -std=c++11 59 | 60 | 61 | GLX_FLAGS += -o $(GLX_TARGET) 62 | ifneq ($(ENABLE_XPROP),1) 63 | GLX_FLAGS += +define+RANDOMIZE_GARBAGE_ASSIGN 64 | GLX_FLAGS += +define+RANDOMIZE_INVALID_ASSIGN 65 | GLX_FLAGS += +define+RANDOMIZE_MEM_INIT 66 | GLX_FLAGS += +define+RANDOMIZE_REG_INIT 67 | endif 68 | # manually set RANDOMIZE_DELAY to avoid GLX from incorrect random initialize 69 | # NOTE: RANDOMIZE_DELAY must NOT be rounded to 0 70 | GLX_FLAGS += +define+RANDOMIZE_DELAY=1 71 | # SRAM lib defines 72 | GLX_FLAGS += +define+UNIT_DELAY +define+no_warning 73 | # C++ flags 74 | GLX_FLAGS += -XCFLAGS "$(GLX_CXXFLAGS)" -XLDFLAGS "$(GLX_LDFLAGS)" 75 | # search build for other missing verilog files 76 | GLX_FLAGS += -y $(RTL_DIR) +libext+.v +libext+.sv 77 | # search generated-src for verilog included files 78 | GLX_FLAGS += +incdir+$(GEN_VSRC_DIR) 79 | 80 | 81 | #glaxism turbo mode 82 | ifeq ($(GLX_TURBO),1) 83 | GLX_CXXFLAGS += -DVERILATOR_4_210 84 | GLX_FLAGS += -turbo_mode +define+VERILATOR_5 +define+VERILATOR=1 +define+PRINTF_COND=1 +define+RANDOMIZE_DELAY=0 85 | endif 86 | 87 | 88 | $(GLX_TARGET): $(SIM_TOP_V) $(GLX_CXXFILES) $(GLX_VFILES) 89 | $(GLX) $(GLX_USER_COMP_OPTS) $(GLX_FLAGS) $(SIM_TOP_V) $(GLX_CXXFILES) $(GLX_VFILES) 90 | 91 | xsim: $(GLX_TARGET) 92 | 93 | RUN_OPTS := +workload=$(RUN_BIN) 94 | 95 | #glaxism turbo threads 96 | ifneq ($(GLX_TURBO_THREADS),0) 97 | RUN_OPTS += -turbo_threads=$(GLX_TURBO_THREADS) 98 | endif 99 | 100 | ifeq ($(NO_DIFF),1) 101 | RUN_OPTS += +no-diff 102 | endif 103 | 104 | RUN_OPTS += -assert finish_maxfail=30 -assert maxfail=100 105 | 106 | xsim-run: 107 | $(shell if [ ! -e $(GLX_RUN_DIR) ]; then mkdir -p $(GLX_RUN_DIR); fi) 108 | touch $(GLX_RUN_DIR)/sim.log 109 | $(shell if [ -e $(GLX_RUN_DIR)/xsim ]; then rm -f $(GLX_RUN_DIR)/xsim; fi) 110 | $(shell if [ -e $(GLX_RUN_DIR)/xsim.data ]; then rm -rf $(GLX_RUN_DIR)/xsim.data; fi) 111 | $(shell if [ -e $(GLX_RUN_DIR)/xsim.src ]; then rm -rf $(GLX_RUN_DIR)/xsim.src; fi) 112 | cp $(GLX_TARGET) $(GLX_RUN_DIR)/xsim 113 | cp -r $(BUILD_DIR)/xsim.data $(GLX_RUN_DIR)/xsim.data 114 | cp -r $(BUILD_DIR)/xsim.src $(GLX_RUN_DIR)/xsim.src 115 | cd $(GLX_RUN_DIR) && (./xsim $(GLX_USER_RUN_OPTS) $(RUN_OPTS) | tee sim.log) 116 | 117 | glx-clean: 118 | rm -rf xsim xsim.data xsim.src $(GLX_BUILD_DIR) 119 | 120 | 121 | -------------------------------------------------------------------------------- /src/test/csrc/emu/simulator.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2025 Institute of Computing Technology, Chinese Academy of Sciences 3 | * 4 | * DiffTest is licensed under Mulan PSL v2. 5 | * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 | * You may obtain a copy of Mulan PSL v2 at: 7 | * http://license.coscl.org.cn/MulanPSL2 8 | * 9 | * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10 | * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11 | * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12 | * 13 | * See the Mulan PSL v2 for more details. 14 | ***************************************************************************************/ 15 | 16 | #ifndef __SIMULATOR_H 17 | #define __SIMULATOR_H 18 | 19 | #include "common.h" 20 | 21 | class Simulator { 22 | private: 23 | static void report_waveform_error() { 24 | printf("Waveform is unsupported in this simulator or disabled.\n"); 25 | printf("If you are using Verilator, please compile with EMU_TRACE=1 to enable it.\n"); 26 | throw std::runtime_error("Waveform not supported."); 27 | } 28 | 29 | static void report_snapshot_error(void *__restrict datap, size_t size) { 30 | printf("Snapshot is unsupported in this simulator or disabled.\n"); 31 | printf("If you are using Verilator, please compile with EMU_SNAPSHOT=1 to enable it.\n"); 32 | throw std::runtime_error("Snapshot not supported."); 33 | } 34 | 35 | protected: 36 | virtual unsigned get_uart_out_valid() = 0; 37 | virtual uint8_t get_uart_out_ch() = 0; 38 | virtual unsigned get_uart_in_valid() = 0; 39 | virtual void set_uart_in_ch(uint8_t ch) = 0; 40 | 41 | public: 42 | Simulator() = default; 43 | virtual ~Simulator() {}; 44 | 45 | /******* mandatory methods for child classes *******/ 46 | // Set the clock signal, 0 or 1. 47 | virtual void set_clock(unsigned clock) = 0; 48 | // Set the reset signal, 0 or 1. 49 | virtual void set_reset(unsigned reset) = 0; 50 | // Tick one step. Note this method may have various implementations. 51 | virtual void step() = 0; 52 | 53 | // Get the exit signal from DiffTest. 54 | virtual uint64_t get_difftest_exit() = 0; 55 | // Get the step signal from DiffTest. 56 | virtual uint64_t get_difftest_step() = 0; 57 | 58 | // Set the clean signal for performance counters. 59 | virtual void set_perf_clean(unsigned clean) = 0; 60 | // Set the dump signal for performance counters. 61 | virtual void set_perf_dump(unsigned dump) = 0; 62 | 63 | // Set the log begin signal. 64 | virtual void set_log_begin(uint64_t begin) = 0; 65 | // Set the log end signal. 66 | virtual void set_log_end(uint64_t end) = 0; 67 | 68 | /******* optional methods for child classes *******/ 69 | // To re-initialize the simulator upon a `fork()` call. 70 | virtual void atClone() {}; 71 | 72 | // To initialize the waveform. 73 | virtual void waveform_init(uint64_t cycles) { 74 | report_waveform_error(); 75 | } 76 | // To tick the waveform. 77 | virtual void waveform_init(uint64_t cycles, const char *filename) { 78 | report_waveform_error(); 79 | } 80 | // To tick the waveform for one timestamp. 81 | virtual void waveform_tick() { 82 | report_waveform_error(); 83 | }; 84 | 85 | // To initialize the simulation snapshot. 86 | virtual void snapshot_init() { 87 | report_snapshot_error(nullptr, 0); 88 | } 89 | // To clean the simulation snapshot. 90 | virtual void snapshot_save(int index) { 91 | report_snapshot_error(nullptr, 0); 92 | } 93 | // To save the simulation snapshot. 94 | virtual std::function snapshot_take() { 95 | return report_snapshot_error; 96 | } 97 | // To load the simulation snapshot from a file. 98 | virtual std::function snapshot_load(const char *filename) { 99 | return report_snapshot_error; 100 | } 101 | 102 | /******* final methods *******/ 103 | 104 | // Step the UART, this is used to read/write UART data. 105 | // This method cannot be overridden. 106 | inline void step_uart() { 107 | if (get_uart_out_valid()) { 108 | printf("%c", get_uart_out_ch()); 109 | fflush(stdout); 110 | } 111 | if (get_uart_in_valid()) { 112 | extern uint8_t uart_getc(); 113 | set_uart_in_ch(uart_getc()); 114 | } 115 | } 116 | }; 117 | 118 | #ifdef VERILATOR 119 | #define SIMULATOR VerilatorSim 120 | #include "verilator.h" 121 | #endif // VERILATOR 122 | 123 | #ifdef GSIM 124 | #define SIMULATOR GsimSim 125 | #include "gsim.h" 126 | #endif // GSIM 127 | 128 | #ifndef SIMULATOR 129 | #error "SIMULATOR undetected, please define it." 130 | #endif // SIMULATOR 131 | 132 | #endif 133 | -------------------------------------------------------------------------------- /src/test/csrc/common/common.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************************** 2 | * Copyright (c) 2020-2023 Institute of Computing Technology, Chinese Academy of Sciences 3 | * Copyright (c) 2020-2021 Peng Cheng Laboratory 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 | #include "common.h" 18 | #include 19 | #include 20 | #include 21 | 22 | int assert_count = 0; 23 | int signal_num = 0; 24 | const char *emu_path = NULL; 25 | 26 | // Usage in SV/Verilog: xs_assert(`__LINE__); 27 | void xs_assert(long long line) { 28 | if (assert_count >= 0) { 29 | printf("Assertion failed at line %lld.\n", line); 30 | assert_count++; 31 | } 32 | } 33 | 34 | // Usage in SV/Verilog: xs_assert_v2(`__FILE__, `__LINE__); 35 | void xs_assert_v2(const char *filename, long long line) { 36 | if (assert_count >= 0) { 37 | printf("Assertion failed at %s:%lld.\n", filename, line); 38 | assert_count++; 39 | } 40 | } 41 | 42 | void sig_handler(int signo) { 43 | if (signal_num != 0) 44 | exit(0); 45 | signal_num = signo; 46 | } 47 | 48 | static struct timeval boot = {}; 49 | 50 | uint32_t uptime(void) { 51 | struct timeval t; 52 | gettimeofday(&t, NULL); 53 | 54 | int s = t.tv_sec - boot.tv_sec; 55 | int us = t.tv_usec - boot.tv_usec; 56 | if (us < 0) { 57 | s--; 58 | us += 1000000; 59 | } 60 | 61 | return s * 1000 + (us + 500) / 1000; 62 | } 63 | 64 | static char mybuf[BUFSIZ]; 65 | 66 | void common_init_without_assertion(const char *program_name) { 67 | // set emu_path 68 | emu_path = program_name; 69 | 70 | const char *elf_name = strrchr(program_name, '/'); 71 | elf_name = elf_name ? elf_name + 1 : program_name; 72 | Info("%s compiled at %s, %s\n", elf_name, __DATE__, __TIME__); 73 | 74 | // set buffer for stderr 75 | setbuf(stderr, mybuf); 76 | 77 | // enable thousands separator for printf() 78 | setlocale(LC_NUMERIC, ""); 79 | 80 | // set up SIGINT handler 81 | if (signal(SIGINT, sig_handler) == SIG_ERR) { 82 | Info("\ncan't catch SIGINT\n"); 83 | } 84 | 85 | gettimeofday(&boot, NULL); 86 | 87 | assert_count = -1; 88 | signal_num = 0; 89 | } 90 | 91 | void common_enable_assert() { 92 | assert_count = 0; 93 | } 94 | 95 | void common_init(const char *program_name) { 96 | common_init_without_assertion(program_name); 97 | common_enable_assert(); 98 | } 99 | 100 | void common_finish() { 101 | fflush(stdout); 102 | } 103 | 104 | static eprintf_handle_t eprintf_handle = vprintf; 105 | 106 | extern "C" void common_enable_log(eprintf_handle_t h) { 107 | assert(h != NULL); 108 | eprintf_handle = h; 109 | } 110 | 111 | int eprintf(const char *fmt, ...) { 112 | va_list args; 113 | int ret; 114 | va_start(args, fmt); 115 | ret = (*eprintf_handle)(fmt, args); 116 | va_end(args); 117 | return ret; 118 | } 119 | 120 | bool sim_verbose = true; 121 | 122 | extern "C" void enable_sim_verbose() { 123 | sim_verbose = true; 124 | } 125 | 126 | extern "C" void disable_sim_verbose() { 127 | sim_verbose = false; 128 | } 129 | 130 | // formatted as follows: /build/ 131 | const char *create_noop_filename(const char *suffix) { 132 | static char noop_filename[1024] = ""; 133 | 134 | static int noop_len = 0; 135 | // initialize the NOOP_HOME only once 136 | if (!noop_len) { 137 | // get NOOP_HOME environment variable 138 | const char *noop_home = getenv("NOOP_HOME"); 139 | #ifdef NOOP_HOME 140 | if (noop_home == nullptr) { 141 | noop_home = NOOP_HOME; 142 | } 143 | #endif 144 | assert(noop_home != NULL); 145 | 146 | noop_len = snprintf(noop_filename, sizeof(noop_filename), "%s/build/", noop_home); 147 | } 148 | 149 | // get formatted time 150 | time_t now = time(NULL); 151 | int time_len = strftime(noop_filename + noop_len, sizeof(noop_filename) - noop_len, "%F-%H-%M-%S", localtime(&now)); 152 | 153 | // copy the suffix if provided 154 | if (suffix) { 155 | snprintf(noop_filename + noop_len + time_len, sizeof(noop_filename) - noop_len - time_len, "%s", suffix); 156 | } else { 157 | noop_filename[noop_len + time_len] = '\0'; // ensure null-termination 158 | } 159 | 160 | return noop_filename; 161 | } 162 | --------------------------------------------------------------------------------