forked from vlsi-lab/len5
-
Notifications
You must be signed in to change notification settings - Fork 0
/
makefile
243 lines (210 loc) · 8.12 KB
/
makefile
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
####################
# ----- INFO ----- #
####################
# Makefile to generate the LEN5 processor files and build the design with fusesoc
#############################
# ----- CONFIGURATION ----- #
#############################
# General configuration
MAKE ?= make
BUILD_DIR ?= $(realpath .)/build
# Software build configuration
PROJECT ?= hello_world
SUITE ?= embench
BENCHMARK ?= crc32
LINKER ?= $(realpath sw/linker/len5-sim.ld)
COPT ?= -O2
# RTL simulation
FIRMWARE ?= $(BUILD_DIR)/main.hex
MAX_CYCLES ?= 100000
LOG_LEVEL ?= LOG_MEDIUM
DUMP_TRACE ?= false
# Regression tests
TEST_DIRS := $(wildcard sw/applications/*/)
TESTS := $(patsubst sw/applications/%/,%,$(TEST_DIRS))
TESTS_EXCLUDE := timer alu_mult alu_div #TODO fix
TESTS := $(filter-out $(TESTS_EXCLUDE),$(TESTS))
# VARIABLES
# ---------
# RTL simulation files
SIM_CORE_FILES := $(shell find . -type f -name "*.core")
SIM_HDL_FILES := $(shell find rtl -type f -name "*.v" -o -name "*.sv" -o -name "*.svh")
SIM_HDL_FILES += $(shell find tb -type f -name "*.v" -o -name "*.sv" -o -name "*.svh")
SIM_CPP_FILES := $(shell find tb/verilator -type f -name "*.cpp" -o -name "*.hh")
#######################
# ----- TARGETS ----- #
#######################
# HDL source
# ----------
# Format code
.PHONY: format
format: | .check-fusesoc
@echo "## Formatting RTL code..."
fusesoc run --no-export --target format polito:len5:len5
# Static analysis
.PHONY: lint
lint: | .check-fusesoc
@echo "## Running static analysis..."
fusesoc run --no-export --target lint polito:len5:len5
# RTL simulation
# --------------
# Build Verilator model
# Re-run every time the necessary files (.core, RTL, CPP) change
.PHONY: verilator-build
verilator-build: $(BUILD_DIR)/.verilator.lock
$(BUILD_DIR)/.verilator.lock: $(SIM_CORE_FILES) $(SIM_HDL_FILES) $(SIM_CPP_FILES) | .check-fusesoc $(BUILD_DIR)/
@echo "## Building simulation model with Verilator..."
fusesoc run --no-export --target sim --tool verilator $(FUSESOC_FLAGS) --build polito:len5:len5
touch $@
# Run Verilator simulation
.PHONY: verilator-sim
verilator-sim: $(BUILD_DIR)/.verilator.lock $(BUILD_DIR)/main.hex | .check-fusesoc
fusesoc run --no-export --target sim --tool verilator --run $(FUSESOC_FLAGS) polito:len5:len5 \
--log_level=$(LOG_LEVEL) \
--firmware=$(FIRMWARE) \
--max_cycles=$(MAX_CYCLES) \
--dump_trace=$(DUMP_TRACE) \
$(FUSESOC_ARGS)
.PHONY: verilator-opt
verilator-opt: $(BUILD_DIR)/.verilator.lock $(BUILD_DIR)/main.hex | .check-fusesoc
fusesoc run --no-export --target sim --tool verilator --run $(FUSESOC_FLAGS) polito:len5:len5 \
--log_level=$(LOG_LEVEL) \
--firmware=$(FIRMWARE) \
--max_cycles=$(MAX_CYCLES) \
--dump_waves=false \
$(FUSESOC_ARGS)
$(BUILD_DIR)/sim-common/sim-trace.log: $(BUILD_DIR)/.verilator.lock $(BUILD_DIR)/main.hex
@echo "## Running simulation with Verilator..."
fusesoc run --no-export --target sim --tool verilator --run $(FUSESOC_FLAGS) polito:len5:len5 \
--log_level=$(LOG_LEVEL) \
--firmware=$(FIRMWARE) \
--max_cycles=$(MAX_CYCLES) \
--dump_trace=true \
--dump_waves=$(DUMP_WAVES) \
$(FUSESOC_ARGS)
# Open dumped waveform with GTKWave
.PHONY: verilator-waves
verilator-waves: $(BUILD_DIR)/sim-common/waves.fst | .check-gtkwave
gtkwave -a tb/misc/verilator-waves.gtkw $<
# QuestaSim
.PHONY: questasim-sim
questasim-sim: | app .check-fusesoc $(BUILD_DIR)/
@echo "## Running simulation with QuestaSim..."
fusesoc run --no-export --target sim --tool modelsim $(FUSESOC_FLAGS) --build polito:len5:len5 2>&1 | tee build/build.log
# Software
# --------
# Application from 'sw/applications'
# NOTE: the -B option to make forces recompilation everytime, which is needed since PROJECT is user-defined
.PHONY: app
app: | $(BUILD_DIR)/
@echo "## Building application '$(PROJECT)'"
$(MAKE) -BC sw app PROJECT=$(PROJECT) BUILD_DIR=$(BUILD_DIR) COPT=$(COPT)
.PHONY: benchmark
benchmark:
@echo "## Building suite $(SUITE) benchmark $(BENCHMARK)"
$(MAKE) -BC sw benchmark SUITE=$(SUITE) BUILD_DIR=$(BUILD_DIR) BENCHMARK=$(BENCHMARK)
.PHONY: run-benchmarks
run-benchmarks:
@echo "## Running suite $(SUITE)"
python3 scripts/benchmarks.py -s $(SUITE) -O=2 -P=1000
rm -rf build_*
# Simple test application
.PHONY: app-helloworld
app-helloworld:
@echo "## Building helloworld application"
$(MAKE) -BC sw PROJECT=hello_world BUILD_DIR=$(BUILD_DIR)
# Compile example applicationa and run RTL simulation
.PHONY: app-helloworld-questasim
run-helloworld-questasim: questasim-sim app-helloworld | .check-fusesoc
@echo "## Running helloworld application"
cd $(BUILD_DIR)/vlsi_polito_len5_0/sim-modelsim; \
make run PLUSARGS="c firmware=../../../sw/applications/hello_world.hex"; \
cd ../../..;
# Simulate the current application on Spike, in interactive mode (debug)
.PHONY: spike-sim
spike-sim: $(BUILD_DIR)/main.elf
@echo "## Running simulation with Spike..."
spike -m0xf000:0x100000,0x20000000:0x1000 -d $<
# Simulate the current application on Spike in silent mode and generate the instruction execution trace
.PHONY: spike-trace
spike-trace: $(BUILD_DIR)/sim-common/spike-trace.log
$(BUILD_DIR)/sim-common/spike-trace.log: $(BUILD_DIR)/main.elf | $(BUILD_DIR)/sim-common/
@echo "## Running simulation with Spike..."
spike --log=$@ -l -m0xf000:0x100000,0x20000000:0x1000 $<
# Compare the execution traces from Spike and the Verilator simulation
.PHONY: spike-check
spike-check: $(BUILD_DIR)/.verilator.lock | $(BUILD_DIR)/sim-common/ .check-fusesoc
@echo "## Launching Verilator simulation..."
fusesoc run --no-export --target sim --tool verilator --run $(FUSESOC_FLAGS) polito:len5:len5 \
--log_level=$(LOG_LEVEL) \
--firmware=$(FIRMWARE) \
--max_cycles=$(MAX_CYCLES) \
--dump_waves=false \
--dump_trace=true \
$(FUSESOC_ARGS)
@echo "## Running Spike simulation..."
spike --log=$(BUILD_DIR)/sim-common/spike-trace.log -l -m0xf000:0x100000,0x20000000:0x1000 $(BUILD_DIR)/main.elf
@echo "## Comparing Spike and Verilator traces..."
scripts/sim/cmp-trace.sh $(BUILD_DIR)/sim-common/sim-trace.log $(BUILD_DIR)/sim-common/spike-trace.log
# Check that nothing is broken
# ----------------------------
.PHONE: check
check: | check-alu .check-fusesoc
@echo "### Executing regression tests..."
@echo " ## Checking RTL..."
fusesoc run --no-export --target format polito:len5:len5
fusesoc run --no-export --target lint polito:len5:len5
@echo " ## Simulating test applications..."
$(foreach T, $(TESTS), eval $(MAKE) app PROJECT=$(T) COPT=-O0 && $(MAKE) spike-check || exit 1;)
$(foreach T, $(TESTS), eval $(MAKE) app PROJECT=$(T) COPT=-O1 && $(MAKE) spike-check || exit 1;)
$(foreach T, $(TESTS), eval $(MAKE) app PROJECT=$(T) COPT=-O2 && $(MAKE) spike-check || exit 1;)
@echo "\e[1;32m### SUCCESS: all checks passed!\e[0m"
.PHONY: check-alu
check-alu: | .check-fusesoc
@echo "## Checking ALU RTL..."
fusesoc run --no-export --target sim --tool verilator polito:len5:alu-tb \
--log_level=LOG_LOW \
--dump_waves=false \
--max_cycles=1000000
# Utilities
# ---------
# Check if fusesoc is available
.PHONY: .check-fusesoc
.check-fusesoc:
@if [ ! `which fusesoc` ]; then \
printf -- "### ERROR: 'fusesoc' is not in PATH. Is the correct conda environment active?\n" >&2; \
exit 1; fi
# Check if GTKWave is available
.PHONY: .check-gtkwave
.check-gtkwave:
@if [ ! `which gtkwave` ]; then \
printf -- "### ERROR: 'gtkwave' is not in PATH. Is the correct conda environment active?\n" >&2; \
exit 1; fi
# Run plotting scripts
.PHONY: charts
charts: w/benchmarks/embench/output/benchmarks.csv scripts/xheep_resultsO2.csv
mkdir -p $(BUILD_DIR)/charts
python3 scripts/ipc_charts.py --len5_report_file=sw/benchmarks/embench/output/backup_bench.csv --xheep_report_file=scripts/xheep_resultsO2.csv --chart_file=$(BUILD_DIR)/charts/ipc_chart.png
# Create new directories
%/:
mkdir -p $@
# Clean-up
.PHONY: clean
clean: clean-app clean-sim
.PHONY: clean-sim
clean-sim:
@rm -rf $(BUILD_DIR)
.PHONY: clean-app
clean-app:
$(MAKE) -C sw clean
.PHONY: .print
.print:
@echo "SIM_HDL_FILES: $(SIM_HDL_FILES)"
@echo "SIM_CPP_FILES: $(SIM_CPP_FILES)"
@echo "TESTS: $(TESTS)"
# Export variables for software linker script
# -------------------------------------------
export BUILD_DIR
export PROJECT
export LINKER
export COPT