forked from OpenXiangShan/difftest
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgsim.mk
More file actions
164 lines (146 loc) · 6.81 KB
/
gsim.mk
File metadata and controls
164 lines (146 loc) · 6.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#***************************************************************************************
# Copyright (c) 2025 Institute of Computing Technology, Chinese Academy of Sciences
# Copyright (c) 2024-2025 Beijing Institute of Open Source Chip (BOSC)
#
# DiffTest is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
# http://license.coscl.org.cn/MulanPSL2
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#
# See the Mulan PSL v2 for more details.
#***************************************************************************************
GSIM_BIN ?= gsim
GSIM_CXX = clang++ # only support clang++14 or above
GSIM_EMU_BUILD_DIR = $(abspath $(BUILD_DIR)/gsim-compile)
GSIM_EMU_TARGET = $(abspath $(GSIM_EMU_BUILD_DIR)/emu)
##############################################
### Running GSIM to generate cpp model
##############################################
GSIM_GEN_CSRC_DIR = $(GSIM_EMU_BUILD_DIR)/model
GSIM_FLAGS = --supernode-max-size=15 --cpp-max-size-KB=8192 --sep-mod=__DOT__ --sep-aggr=__DOT__
$(GSIM_GEN_CSRC_DIR)/$(SIM_TOP)0.cpp: $(RTL_DIR)/$(SIM_TOP).fir
@mkdir -p $(@D)
$(GSIM_BIN) $(GSIM_FLAGS) --dir $(@D) $< | tee $(GSIM_EMU_BUILD_DIR)/gsim-gen-cpp.log
gsim-gen-cpp: $(GSIM_GEN_CSRC_DIR)/$(SIM_TOP)0.cpp
##############################################
### Building EMU from cpp model generated by GSIM
##############################################
GSIM_OTHER_CSRC_DIR = $(abspath ./src/test/csrc/gsim)
GSIM_CXXFILES = $(EMU_CXXFILES) $(shell find $(GSIM_OTHER_CSRC_DIR) -name "*.cpp")
# We need to replace extra '\' as this is native in Makefile for GSIM
GSIM_CXXFLAGS = $(subst \\\",\", $(EMU_CXXFLAGS))
GSIM_CXXFLAGS += -I$(GSIM_OTHER_CSRC_DIR) -I$(GSIM_GEN_CSRC_DIR)/ -DGSIM
GSIM_CXXFLAGS += $(EMU_OPTIMIZE) -fbracket-depth=2048 -Wno-parentheses-equality $(PGO_CFLAGS)
GSIM_LDFLAGS = $(SIM_LDFLAGS) -ldl $(PGO_LDFLAGS)
# $(1): object file
# $(2): source file
# $(3): compile flags
# $(4): object file list
# $(5): extra dependency
define GSIM_CXX_TEMPLATE =
$(1): $(2) $(THIS_MAKEFILE) $(5)
@mkdir -p $$(@D) && echo + CXX $$<
@$(GSIM_CXX) $$< $(3) -c -o $$@
$(4) += $(1)
endef
# $(1): object file
# $(2): source file
# $(3): ld flags
define GSIM_LD_TEMPLATE =
$(1): $(2)
@mkdir -p $$(@D) && echo + LD $$@
@$(GSIM_CXX) $$^ $(3) -o $$@
endef
$(foreach x, $(GSIM_CXXFILES), $(eval \
$(call GSIM_CXX_TEMPLATE, $(GSIM_EMU_BUILD_DIR)/other/$(basename $(notdir $(x))).o, $(x), $(GSIM_CXXFLAGS), GSIM_EMU_OBJS,)))
$(foreach x, $(shell find $(GSIM_GEN_CSRC_DIR) -name "*.cpp" 2> /dev/null), $(eval \
$(call GSIM_CXX_TEMPLATE, $(GSIM_EMU_BUILD_DIR)/model/$(basename $(notdir $(x))).o, $(x), $(GSIM_CXXFLAGS), GSIM_EMU_OBJS,)))
$(eval $(call GSIM_LD_TEMPLATE, $(GSIM_EMU_TARGET), $(GSIM_EMU_OBJS), $(GSIM_LDFLAGS)))
gsim-build-emu: $(GSIM_EMU_TARGET)
gsim-clean-obj:
-@rm -f $(GSIM_EMU_OBJS) $(GSIM_EMU_TARGET)
# Profile Guided Optimization
GSIM_EMU_PGO_DIR = $(GSIM_EMU_BUILD_DIR)/pgo
gsim-gen-emu:
ifdef PGO_WORKLOAD
ifneq ($(PGO_BOLT),1)
@echo "If available, please use install llvm-bolt for much reduced PGO build time."
@echo "Building PGO profile..."
@stat $(PGO_WORKLOAD) > /dev/null
@$(MAKE) gsim-clean-obj
@mkdir -p $(GSIM_EMU_PGO_DIR)
@sync -d $(BUILD_DIR) -d $(GSIM_EMU_BUILD_DIR)
@$(MAKE) gsim-build-emu \
PGO_CFLAGS="-fprofile-generate=$(GSIM_EMU_PGO_DIR)" \
PGO_LDFLAGS="-fprofile-generate=$(GSIM_EMU_PGO_DIR)"
@echo "Training emu with PGO Workload..."
@sync -d $(BUILD_DIR) -d $(GSIM_EMU_BUILD_DIR)
$(GSIM_EMU_TARGET) -i $(PGO_WORKLOAD) --max-cycles=$(PGO_MAX_CYCLE) \
1>$(GSIM_EMU_PGO_DIR)/`date +%s`.log \
2>$(GSIM_EMU_PGO_DIR)/`date +%s`.err \
$(PGO_EMU_ARGS)
@sync -d $(BUILD_DIR) -d $(GSIM_EMU_BUILD_DIR)
ifdef LLVM_PROFDATA
# When using LLVM's profile-guided optimization, the raw data can not
# directly be used in -fprofile-use. We need to use a specific version of
# llvm-profdata. This happens when verilator compiled with CC=clang
# CXX=clang++. In this case, we should add LLVM_PROFDATA=llvm-profdata
# when calling make. For GCC, this step should be skipped. Also, some
# machines may have multiple versions of llvm-profdata. So please never
# add default value for LLVM_PROFDATA unless we have a proper way to probe
# the compiler and the corresponding llvm-profdata value.
$(LLVM_PROFDATA) merge $(GSIM_EMU_PGO_DIR)/*.profraw -o $(GSIM_EMU_PGO_DIR)/default.profdata
else # ifdef LLVM_PROFDATA
@echo ""
@echo "----------------------- NOTICE BEGIN -----------------------"
@echo "If your verilator is compiled with LLVM, please don't forget"
@echo "to add LLVM_PROFDATA=llvm-profdata when calling make."
@echo ""
@echo "If your verilator is compiled with GCC, please ignore this"
@echo "message and NEVER adding LLVM_PROFDATA when calling make."
@echo "----------------------- NOTICE END -----------------------"
@echo ""
endif # ifdef LLVM_PROFDATA
@echo "Building emu with PGO profile..."
@$(MAKE) gsim-clean-obj
@sync -d $(BUILD_DIR) -d $(GSIM_EMU_BUILD_DIR)
@$(MAKE) gsim-build-emu \
PGO_CFLAGS="-fprofile-use=$(GSIM_EMU_PGO_DIR)" \
PGO_LDFLAGS="-fprofile-use=$(GSIM_EMU_PGO_DIR)"
else # ifneq ($(PGO_BOLT),1)
@echo "Building emu..."
@$(MAKE) gsim-build-emu PGO_LDFLAGS="-Wl,--emit-relocs -fuse-ld=bfd"
@mv $(GSIM_EMU_TARGET) $(GSIM_EMU_TARGET).pre-bolt
@sync -d $(BUILD_DIR) -d $(GSIM_EMU_BUILD_DIR)
@echo "Training emu with PGO Workload..."
@mkdir -p $(GSIM_EMU_PGO_DIR)
@sync -d $(BUILD_DIR) -d $(GSIM_EMU_BUILD_DIR)
@((perf record -j any,u -o $(GSIM_EMU_PGO_DIR)/perf.data -- sh -c "\
$(GSIM_EMU_TARGET).pre-bolt -i $(PGO_WORKLOAD) --max-cycles=$(PGO_MAX_CYCLE) \
1>$(GSIM_EMU_PGO_DIR)/`date +%s`.log \
2>$(GSIM_EMU_PGO_DIR)/`date +%s`.err \
$(PGO_EMU_ARGS)") && \
perf2bolt -p=$(GSIM_EMU_PGO_DIR)/perf.data -o=$(GSIM_EMU_PGO_DIR)/perf.fdata $(GSIM_EMU_TARGET).pre-bolt) || \
(echo -e "\033[31mlinux-perf is not available, fallback to instrumentation-based PGO\033[0m" && \
$(LLVM_BOLT) $(GSIM_EMU_TARGET).pre-bolt \
-instrument --instrumentation-file=$(GSIM_EMU_PGO_DIR)/perf.fdata \
-o $(GSIM_EMU_PGO_DIR)/emu.instrumented && \
$(GSIM_EMU_PGO_DIR)/emu.instrumented -i $(PGO_WORKLOAD) --max-cycles=$(PGO_MAX_CYCLE) \
1>$(GSIM_EMU_PGO_DIR)/`date +%s`.log \
2>$(GSIM_EMU_PGO_DIR)/`date +%s`.err \
$(PGO_EMU_ARGS))
@echo "Processing BOLT profile data..."
@$(LLVM_BOLT) $(GSIM_EMU_TARGET).pre-bolt -o $(GSIM_EMU_TARGET) -data=$(GSIM_EMU_PGO_DIR)/perf.fdata -reorder-blocks=ext-tsp
endif # ifneq ($(PGO_BOLT),1)
else # ifdef PGO_WORKLOAD
@echo "Building emu..."
$(MAKE) gsim-build-emu
endif # ifdef PGO_WORKLOAD
@sync -d $(BUILD_DIR) -d $(GSIM_EMU_BUILD_DIR)
gsim-emu:
$(MAKE) gsim-gen-cpp
$(MAKE) gsim-gen-emu