Files
fmn_processor/Makefile

194 lines
7.6 KiB
Makefile
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
COMMON_DIR := common
FPGA_BOARD = zybo_z7_10
TOCLEAN = $(filter %log %.jou %.rpt %.mmi %.dcp %.csv\
%.wdb vivado% updatemem% usage_statistics_webtalk%,$(wildcard *))
TOCLEAN += $(wildcard _*) .Xil out RTL build download.bit $(MEM_DIR)
TOCLEAN += ./bench/programs_rust/target/riscv64i/release
# macro de verbosité
VERB := 0
# macro de vérification de variables d'environnement
check_vars = $(foreach v, $1, $(if $(filter undefined, $(origin $v)),\
if [ "$v" = "XILINX_VIVADO" ]; then \
echo "⚠️ Tapez : source /bigsoft/Xilinx/Vivado/2019.1/settings64.sh"; \
exit 1; \
else \
echo "⚠️ ⚡⚡ Variable d'environnement $v manquante ⚡⚡⚠️ "; \
$(MAKE) --no-print-directory help; \
exit 1; \
fi;))
all: help
help:
@awk 'BEGIN {FS = ":.*##!"; printf "Usage: make \033[32m<commande>\033[0m \
[PROG=<nom du fichier de test sans extension>] \
[CYCLES=durée de la simulation] [VERB=1 pour la verbosité]\
\nCommandes par \033[36mcatégories :\n"} \
/^[a-zA-Z0-9_-]+:.*##!/ { printf " \033[32m%-15s\033[0m %s\n", $$1, $$2 } \
/^##@/ { printf "\n\033[36m%s\033[0m\n", substr($$0, 5) }' $(MAKEFILE_LIST)
###############################################################################
## Partie Compilation
BENCH_DIR := bench
MEM_DIR := $(BENCH_DIR)/mem
SRC_SW := $(shell find $(BENCH_DIR) -name '*.s' -type f | sed 's/^bench\///g')
SRC_SW += $(wildcard $(BENCH_DIR)/*.c) # Contient tous les .s et .c du projet
SRC_TESTS_SW := $(shell find $(BENCH_DIR)/tests -name '*.s' -type f | sed 's/^bench\///g')
MEM = $(addprefix $(MEM_DIR)/, $(addsuffix .mem, $(basename $(SRC_SW)))) # Tous les .mem du projet
MEM_TESTS = $(addprefix test-, $(addprefix $(MEM_DIR)/, $(addsuffix .mem, $(basename $(SRC_TESTS_SW))))) # Tous les .mem du projet en test
PREFIX := $(shell command -v riscv64-unknown-elf-gcc >/dev/null 2>&1 && echo riscv64-unknown-elf- || echo /matieres/3MMFMN/riscv32/bin/riscv32-unknown-elf-)
CC := $(PREFIX)gcc
OBJDUMP := $(PREFIX)objdump
OBJCOPY := $(PREFIX)objcopy
OBTOMEM := common/objtomem.awk
## Flags
ASFLAGS :=-march=rv64im -mabi=lp64 -ffreestanding -nostdlib -T $(BENCH_DIR)/link.ld
CFLAGS :=$(ASFLAGS)
ELFFLAGS :=$(ASFLAGS) $(MEM_DIR)/crt.o -Os -fno-unroll-loops
ODFLAGS :=-j .text -j .rodata -j .data -s
## Paramètres de tests
TEST_MAX_RAM := 11000000 ## Limite de ram pour les tests en KB
TEST_MAX_PROCS := $$(($$(nproc) - 2)) ## Garde un processeur libre
.PRECIOUS: $(MEM_DIR)/%.elf
.PHONY: synthese fpga clean compile autotest simulation force
force:
compile: $(MEM)
$(MEM_DIR):
@mkdir -p $@/tests/op
@mkdir -p $@/programs
@mkdir -p $@/programs_rust
.PRECIOUS: $(MEM_DIR)/programs_rust/%.elf
$(MEM_DIR)/programs_rust/%.elf: bench/programs_rust/% force $(MEM_DIR)/crt.o |$(MEM_DIR)
cd bench/programs_rust && cargo build --release --bin=$(basename $(notdir $@))
cp -f bench/programs_rust/target/riscv64i/release/$(basename $(notdir $@)) $@
$(MEM_DIR)/crt.o: $(BENCH_DIR)/crt.S |$(MEM_DIR)
$(CC) $(CFLAGS) -c $< -o $@
$(MEM_DIR)/%.elf: $(BENCH_DIR)/%.c $(MEM_DIR)/crt.o |$(MEM_DIR)
$(CC) $(ELFFLAGS) $< -o $@
$(MEM_DIR)/%.elf: $(BENCH_DIR)/%.s |$(MEM_DIR)
$(CC) $(CFLAGS) -o $@ $<
$(MEM_DIR)/%.mem: $(MEM_DIR)/%.elf |$(MEM_DIR)
$(OBJCOPY) -O binary --verilog-data-width 8 $< $@.bin
python3 common/swap_endian.py $@.bin $@.bin.swapped 8
$(OBJCOPY) -I binary -O verilog --verilog-data-width 8 $@.bin.swapped $@
rm $@.bin $@.bin.swapped
test-$(MEM_DIR)/%.mem: $(MEM_DIR)/%.mem |$(MEM_DIR)
@PROG="$(shell echo $< | sed "s/^bench\/mem\///g" | sed "s/\.mem$$//g")" PROOT=$(shell pwd) ./mill TPchisel.test.testOnly $(TOP_REP).$(TOP_TEST) -- -z "$(shell echo $< | sed "s/^bench\/mem\///g" | sed "s/\.mem$$//g")"
###############################################################################
##@ Simulation
TOP := ZzTop
TOP_REP := projet
PATH_SRC := src/main/scala/$(TOP_REP)
TOP_TEST := $(addsuffix Spec, $(TOP))
CYCLES=500
INSTRUCTIONS=1000
# Pour filtrer les tests dans une simulation
ifdef PROG
FILTRE_TEST:= -- -z "$(PROG)"
endif
mill:
@curl -L https://raw.githubusercontent.com/lefou/millw/0.4.11/millw > mill
@chmod +x mill
autotest: mill test-bench/mem/tests/$(PROG).mem ##! Lance la simulation automatique pour tous les tests ou juste celui fourni dans PROG
testall: mill compile ##! Lance la simulation automatique pour tous les tests en parallèle
@# Limite le nombre de processeurs et la ram utilisée pour les tests parallèle
@( \
ulimit -v $(TEST_MAX_RAM); \
PROOT=$(PWD) taskset -c 0-$(TEST_MAX_PROCS) ./mill TPchisel.test.testOnly $(TOP_REP).ZzTopAllSpec \
)
$(PROG): $(MEM_DIR)/$(PROG).mem
simulation: mill $(PROG) ##! Lance gtkwave sur le test fourni dans PROG et produit le log du pc
@$(call check_vars,PROG)
@PROOT=$(PWD) PROG=$(PROG) CYCLES=$(CYCLES) ./mill TPchisel.test.testOnly $(TOP_REP).$(TOP_TEST) -- -DemitVcd=1 -z "gtkwave"
@cp -f ./build/chiselsim/ZzTopSpec/Simulation-pour-gtkwave/workdir-verilator/core_pc.log .
@gtkwave -a common/config.gtkw ./build/chiselsim/ZzTopSpec/Simulation-pour-gtkwave/workdir-verilator/trace.vcd
spike-simulation: mill $(PROG) ##! Simule INSTRUCTIONS instructions de PROG avec spike et produit un log du PC dans spike_pc.log
spike --log spike.log --instructions=$$(($(INSTRUCTIONS) + 5)) -m0x10000:0x20000,0x80000000:0x00020000 -l $(MEM_DIR)/$(PROG).elf
cat spike.log | sed "/>>>>/d" | awk '{print $$3}' | tail -n $(INSTRUCTIONS) > spike_pc.log
###############################################################################
##@ Passage sur carte
SRC := $(wildcard $(PATH_SRC)/*.scala)
SRC += $(wildcard src/main/resources/vsrc/*.v)
FPGA := xc7z010-clg400-1
SRC_SV := RTL/$(TOP_REP).$(TOP)/$(TOP).sv
XILINX_PREFIX := $(XILINX_VIVADO)/bin/
MEM_FILE:= $(MEM_DIR)/$(PROG).mem
MMI_FILE:=$(TOP).mmi
MEM_ID=$(shell grep -oP 'InstPath="\K[^"]+' $(MMI_FILE))
PARAM = $(MEM_FILE) false # Variable pour passer des parametres au générateur SV
.PRECIOUS: golden.bit
# Créer un hash unique de la variable
PROG_HASH := $(shell echo "$(PROG)" | md5sum | cut -d' ' -f1)
RTL: $(SRC_SV) ##! Génération du SystemVerilog
$(SRC_SV): mill $(SRC)
./mill TPchisel.runMain common.EmitModule $(TOP_REP).$(TOP) $(PARAM)
$(TOP)_utilization.rpt $(TOP)_timing.rpt $(TOP)_summary.rpt: $(COMMON_DIR)/synthese.vivado.tcl RTL
@$(call check_vars,XILINX_VIVADO)
$(XILINX_PREFIX)vivado -nolog -nojournal -mode batch -source $< -tclargs $(FPGA) $(TOP) $(TOP_REP)
synthese: $(TOP)_utilization.rpt $(TOP)_timing.rpt $(TOP)_summary.rpt ##! Réalise la synthèse grossière pour évaluer les performances
@echo "Rapport d'utilisation disponible dans $(TOP)_utilization.rpt"
@echo "Rapport de timing disponible dans $(TOP)_timing.rpt"
@python3 $(COMMON_DIR)/parse_report.py $^
golden.bit: $(COMMON_DIR)/bitstream.vivado.tcl $(COMMON_DIR)/$(TOP).xdc RTL
@$(call check_vars,XILINX_VIVADO PROG)
$(XILINX_PREFIX)vivado -nolog -nojournal -mode batch -source $< -tclargs $(FPGA) $(TOP) $(TOP_REP) $@ $(MEM_FILE)
.prog_$(PROG_HASH):
@rm -f .prog_* # Supprimer les anciens marqueurs
@touch $@
download.bit: golden.bit $(MEM_FILE) $(MMI_FILE) .prog_$(PROG_HASH)
@$(call check_vars,XILINX_VIVADO PROG)
$(XILINX_PREFIX)updatemem -debug -force --meminfo $(MMI_FILE) --data $(MEM_FILE) --proc $(MEM_ID) --bit $< --out $@
fpga: download.bit $(COMMON_DIR)/programFPGA.vivado.tcl ##! Génére le fichier de configuration du FPGA et le programme
@$(call check_vars,XILINX_VIVADO)
$(XILINX_PREFIX)vivado -nolog -nojournal -mode batch -source $(COMMON_DIR)/programFPGA.vivado.tcl -nolog -nojournal \
-tclargs $<
flash: download.bit
openFPGALoader -b $(FPGA_BOARD) $<
clean: ##! Fais le nettoyage
rm -rf $(TOCLEAN)