Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FPGA: Add the function of fpga core difftest #453

Draft
wants to merge 25 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b92802c
fpga: Add pcie XDMA framework
xiaokamikami Aug 27, 2024
3f7ab6f
fpga: add mpool
xiaokamikami Aug 28, 2024
e751d31
difftest: Move mempool to common code
xiaokamikami Aug 28, 2024
b4b28b7
fpga: Add function of difftest through dma interface
xiaokamikami Aug 29, 2024
67a9783
fpga: add independent compilation and usage support under fpga
xiaokamikami Aug 29, 2024
5f6268d
fpga: modify the xdma initi process
xiaokamikami Sep 18, 2024
2a05b3c
difftest: Fixed an issue where the block structure was not memory safe
xiaokamikami Sep 20, 2024
888d69c
fpga: The memory pool with sliding window was added to realize multi-…
xiaokamikami Sep 23, 2024
2579335
fpga: fix mpool format
xiaokamikami Sep 23, 2024
3962f9e
fpga: modify xdma to be multi-channel configurable and use a sliding …
xiaokamikami Sep 23, 2024
d069b96
fpga: Improve the operation logic of fpga diff
xiaokamikami Sep 24, 2024
57f90b4
fpga: Remove redundant mempool-MemoryBlock definitions
xiaokamikami Sep 25, 2024
bbb56ea
fpga: The adaptation pack processes the new batch
xiaokamikami Sep 25, 2024
40e65b0
CI: add fpga-diff compile ci
xiaokamikami Sep 25, 2024
8040a33
fpga: svdpi.h is not referenced when fpga is used
xiaokamikami Sep 26, 2024
69eaa7d
fpga: Burn workload to fpga ddr at boot time
xiaokamikami Sep 26, 2024
8f1b15f
fpga: Load memory for the ref module
xiaokamikami Sep 27, 2024
2c3e0a2
fpga: The optimal parameters of mpool are adjusted
xiaokamikami Nov 1, 2024
4ac9cfa
fpga: batch processing on fpga diff data is used by default
xiaokamikami Nov 4, 2024
6adf675
fpga: remove the redundant include and disable DB on fpga
xiaokamikami Nov 4, 2024
3d02dfd
fpga: fix formate
xiaokamikami Nov 4, 2024
c75b3be
fpga: fix a stuck startup bug
xiaokamikami Nov 6, 2024
b214051
fpga: Add idx verification for dma packets and initiate process repai…
xiaokamikami Nov 8, 2024
fcc98c7
fpga: mpool fix computation of free_num
xiaokamikami Nov 11, 2024
64f8928
difftest: Turn off h2c when it is not needed
xiaokamikami Nov 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -450,3 +450,44 @@ jobs:
make difftest_verilog PROFILE=../build/generated-src/difftest_profile.json NUMCORES=1 CONFIG=ZEL MFC=1
make simv VCS=verilator WITH_CHISELDB=0 WITH_CONSTANTIN=0 IOTRACE_ZSTD=1
./build/simv +workload=../ready-to-run/microbench.bin +e=0 +diff=../ready-to-run/riscv64-nemu-interpreter-so +iotrace-name=../iotrace

# test-difftest-fpga:
# runs-on: ubuntu-22.04

# needs: test-difftest-main

# steps:
# - uses: actions/checkout@v4

# - name: Prepare environment
# run: |
# cd $GITHUB_WORKSPACE/..
# git config --global url."https://github.com/".insteadOf [email protected]:
# git config --global url."https://".insteadOf git://
# git clone https://github.com/OpenXiangShan/xs-env
# cd xs-env
# sudo -s ./setup-tools.sh
# source ./setup.sh

# - name: Prepare NutShell
# run: |
# cd $GITHUB_WORKSPACE/../xs-env
# rm -r NutShell
# git clone -b dev-difftest --single-branch https://github.com/OSCPU/NutShell.git
# cd NutShell && git submodule update --init
# rm -r difftest
# cp -r $GITHUB_WORKSPACE .

# - name: Enable -Werror for EMU Build
# run: |
# echo "CXX_NO_WARNING=1" >> $GITHUB_ENV

# - name: FPGA-difftest Build
# run: |
# cd $GITHUB_WORKSPACE/../xs-env
# source ./env.sh
# cd $GITHUB_WORKSPACE/../xs-env/NutShell
# source ./env.sh
# make clean
# make sim-verilog MILL_ARGS="--difftest-config ENBF" -j2
# make fpga-build DMA_CHANNELS=2 WITH_CHISELDB=0 WITH_CONSTANTIN=0
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ SIM_VSRC = $(shell find $(VSRC_DIR) -name "*.v" -or -name "*.sv")

# DiffTest support
DIFFTEST_CSRC_DIR = $(abspath ./src/test/csrc/difftest)
# FPGA-Difftest support
FPGA ?= 0

DIFFTEST_CXXFILES = $(shell find $(DIFFTEST_CSRC_DIR) -name "*.cpp")
ifeq ($(NO_DIFF), 1)
SIM_CXXFLAGS += -DCONFIG_NO_DIFFTEST
Expand All @@ -90,15 +93,19 @@ endif
endif

# ChiselDB
ifneq ($(FPGA),1)
WITH_CHISELDB ?= 1
endif
ifeq ($(WITH_CHISELDB), 1)
SIM_CXXFILES += $(BUILD_DIR)/chisel_db.cpp
SIM_CXXFLAGS += -I$(BUILD_DIR) -DENABLE_CHISEL_DB
SIM_LDFLAGS += -lsqlite3
endif

# ConstantIn
ifneq ($(FPGA),1)
WITH_CONSTANTIN ?= 1
endif
ifeq ($(WITH_CONSTANTIN), 1)
SIM_CXXFILES += $(BUILD_DIR)/constantin.cpp
SIM_CXXFLAGS += -I$(BUILD_DIR) -DENABLE_CONSTANTIN
Expand Down Expand Up @@ -231,6 +238,7 @@ include verilator.mk
include vcs.mk
include palladium.mk
include libso.mk
include fpga.mk

clean: vcs-clean pldm-clean
rm -rf $(BUILD_DIR)
Expand Down
22 changes: 22 additions & 0 deletions fpga.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

FPGA = FPGA_HOST
FPGA_TARGET = $(abspath $(BUILD_DIR)/simv)
FPGA_BUILD_DIR = $(abspath $(BUILD_DIR)/simv-compile)
FPGA_RUN_DIR = $(abspath $(BUILD_DIR)/$(notdir $(RUN_BIN)))

FPGA_CSRC_DIR = $(abspath ./src/test/csrc/fpga)
FPGA_CONFIG_DIR = $(abspath ./config)

FPGA_CXXFILES = $(SIM_CXXFILES) $(shell find $(FPGA_CSRC_DIR) -name "*.cpp") -include cstring
FPGA_CXXFLAGS = $(subst \\\",\", $(SIM_CXXFLAGS)) -I$(FPGA_CSRC_DIR) -DNUM_CORES=$(NUM_CORES) -O2
FPGA_LDFLAGS = $(SIM_LDFLAGS) -lpthread -ldl

DMA_CHANNELS?=1
FPGA_LDFLAGS += -DCONFIG_DMA_CHANNELS=$(DMA_CHANNELS)

fpga-build: fpga-clean fpga-host

fpga-host:
$(CXX) $(FPGA_CXXFLAGS) $(FPGA_CXXFILES) $^ -o $@ $(FPGA_LDFLAGS)
fpga-clean:
rm -f fpga-host
11 changes: 8 additions & 3 deletions src/main/scala/DPIC.scala
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ private class DummyDPICBatchWrapper(

object DPIC {
val interfaces = ListBuffer.empty[(String, String, String)]
var defMacros = new StringBuilder()

def apply(control: GatewaySinkControl, io: Valid[DifftestBundle], config: GatewayConfig): Unit = {
val module = Module(new DummyDPICWrapper(chiselTypeOf(io), config))
Expand All @@ -314,6 +315,12 @@ object DPIC {
module.control := control
module.io := io
val dpic = module.dpic
if (!config.isFPGA)
defMacros ++=
s"""
|#ifdef CONFIG_DIFFTEST_BATCH
|#include "svdpi.h"
|#endif // CONFIG_DIFFTEST_BATCH""".stripMargin
interfaces += ((dpic.dpicFuncName, dpic.dpicFuncProto, dpic.dpicFunc))
}

Expand All @@ -328,12 +335,10 @@ object DPIC {
interfaceCpp += ""
interfaceCpp += "#include <cstdint>"
interfaceCpp += "#include \"diffstate.h\""
interfaceCpp += "#ifdef CONFIG_DIFFTEST_BATCH"
interfaceCpp += "#include \"svdpi.h\""
interfaceCpp += "#endif // CONFIG_DIFFTEST_BATCH"
interfaceCpp += "#ifdef CONFIG_DIFFTEST_PERFCNT"
interfaceCpp += "#include \"perf.h\""
interfaceCpp += "#endif // CONFIG_DIFFTEST_PERFCNT"
interfaceCpp += defMacros.toString()
interfaceCpp += ""
interfaceCpp +=
"""
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/Gateway.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ case class GatewayConfig(
def dutBufLen: Int = if (isBatch) batchSize else 1
def maxStep: Int = if (isBatch) batchSize else 1
def stepWidth: Int = log2Ceil(maxStep + 1)
def batchArgByteLen: (Int, Int) = if (isNonBlock) (3600, 400) else (7200, 800)
def batchArgByteLen: (Int, Int) = if (isNonBlock) (3600, 400) else if (isFPGA) (3650, 445) else (7200, 800)
def hasDeferredResult: Boolean = isNonBlock || hasInternalStep
def needTraceInfo: Boolean = hasReplay
def needEndpoint: Boolean =
Expand Down
167 changes: 167 additions & 0 deletions src/test/csrc/common/mpool.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/***************************************************************************************
* Copyright (c) 2024 Beijing Institute of Open Source Chip (BOSC)
* Copyright (c) 2020-2024 Institute of Computing Technology, Chinese Academy of Sciences
*
* DiffTest is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*
* See the Mulan PSL v2 for more details.
***************************************************************************************/
#include "mpool.h"

void MemoryPool::init_memory_pool() {
memory_pool.reserve(NUM_BLOCKS);
for (size_t i = 0; i < NUM_BLOCKS; ++i) {
memory_pool.emplace_back();
block_mutexes[i].unlock();
}
}

void MemoryPool::cleanup_memory_pool() {
cv_empty.notify_all();
cv_filled.notify_all();
memory_pool.clear();
}

void MemoryPool::unlock_thread() {
cv_empty.notify_all();
cv_filled.notify_all();
}

char *MemoryPool::get_free_chunk() {
page_head = (write_index++) & REM_NUM_BLOCKS;
{
std::unique_lock<std::mutex> lock(block_mutexes[page_head]);
cv_empty.wait(lock, [this] { return empty_blocks > 0; });
}

--empty_blocks;
block_mutexes[page_head].lock();
return memory_pool[page_head].data.get();
}

void MemoryPool::set_busy_chunk() {
memory_pool[page_head].is_free = false;
block_mutexes[page_head].unlock();
cv_filled.notify_one();
++filled_blocks;
}

const char *MemoryPool::get_busy_chunk() {
page_end = (read_index++) & REM_NUM_BLOCKS;
{
std::unique_lock<std::mutex> lock(block_mutexes[page_end]);
cv_filled.wait(lock, [this] { return filled_blocks > 0; });
}
--filled_blocks;
block_mutexes[page_end].lock();
return memory_pool[page_end].data.get();
}

void MemoryPool::set_free_chunk() {
memory_pool[page_end].is_free = true;
block_mutexes[page_end].unlock();
cv_empty.notify_one();
++empty_blocks;
}

// Cleaning up memory pools
void MemoryIdxPool::cleanupMemoryPool() {
cv_empty.notify_all();
cv_filled.notify_all();
}

// Write a specified free block of a free window
bool MemoryIdxPool::write_free_chunk(uint8_t idx, const char *data) {
size_t page_w_idx;
{
std::lock_guard<std::mutex> lock(offset_mutexes);

page_w_idx = idx + group_w_offset;
// Processing of winding data at the boundary
if (memory_pool[page_w_idx].is_free.load() == false) {
size_t this_group = group_w_idx.load();
size_t offset = ((this_group & REM_MAX_GROUPING_IDX) * MAX_IDX);
page_w_idx = idx + offset;
write_next_count++;
// Lookup failed
if (memory_pool[page_w_idx].is_free.load() == false) {
printf("This block has been written, and there is a duplicate packge idx %d\n", idx);
return false;
}
} else {
write_count++;
// Proceed to the next group
if (write_count == MAX_IDX) {
memcpy(memory_pool[page_w_idx].data.get(), data, 4096);
memory_pool[page_w_idx].is_free.store(false);
size_t next_w_idx = wait_next_free_group();
group_w_offset = (next_w_idx & REM_MAX_GROUPING_IDX) * MAX_IDX;
write_count = write_next_count;
write_next_count = 0;
return true;
}
}
memory_pool[page_w_idx].is_free.store(false);
}
memcpy(memory_pool[page_w_idx].data.get(), data, 4096);

return true;
}

void MemoryIdxPool::wait_mempool_start() {
std::unique_lock<std::mutex> lock(window_mutexes);
cv_filled.wait(lock);
}

bool MemoryIdxPool::read_busy_chunk(char *data) {
size_t page_r_idx = read_count + group_r_offset;
size_t this_r_idx = ++read_count;

if (this_r_idx == MAX_IDX) {
read_count = 0;
size_t next_r_idx = wait_next_full_group();
group_r_offset = ((next_r_idx & REM_MAX_GROUPING_IDX) * MAX_IDX);
}
if (memory_pool[page_r_idx].is_free.load() == true) {
printf("An attempt was made to read the block of free %zu\n", page_r_idx);
return false;
}

memcpy(data, memory_pool[page_r_idx].data.get(), 4096);
memory_pool[page_r_idx].is_free.store(true);
return true;
}

size_t MemoryIdxPool::wait_next_free_group() {
size_t free_num = empty_blocks.fetch_sub(1, std::memory_order_relaxed) - 1;
cv_filled.notify_all();
//Reserve at least two free blocks
if (free_num <= 2) {
std::unique_lock<std::mutex> lock(window_mutexes);
cv_empty.wait(lock, [this] { return empty_blocks.load() > 1; });
}
return group_w_idx.fetch_add(1);
}

size_t MemoryIdxPool::wait_next_full_group() {
size_t free_num = empty_blocks.fetch_add(1, std::memory_order_relaxed) + 1;
cv_empty.notify_all();

if (free_num >= MAX_GROUP_READ) {
std::unique_lock<std::mutex> lock(window_mutexes);
cv_filled.wait(lock, [this] { return empty_blocks.load() < MAX_GROUP_READ; });
}
return group_r_idx.fetch_add(1);
}

bool MemoryIdxPool::check_group() {
bool result = (group_w_idx.load() > group_r_idx.load()) ? true : false;
return result;
}
Loading
Loading