packages feed

clash-vexriscv-0.1: data/vexriscv/Makefile

# SPDX-FileCopyrightText: 2022 Google LLC
#
# SPDX-License-Identifier: CC0-1.0

CLASH_VEXRISCV_DATA_DIR = $(dir $(MAKEFILE_LIST))
SCALA_CONFIG_DIR = SCALA_CONFIG_DIR-you-have-to-set-this-as-an-argument
CPU_NAME = CPU_NAME-you-have-to-set-this-as-an-argument

VERILATOR_DIR = verilator
VERILATOR_FLAGS = -CFLAGS '-O3 -fPIC' -Wno-fatal +1364-2001ext+v --trace

N := $(patsubst -j%,%,$(filter -j%,$(MAKEFLAGS)))

VERILATOR_CFLAGS = $(shell pkg-config --cflags verilator)
FFI_CPPFLAGS = $(VERILATOR_CFLAGS) -fPIC -O3 -I$(VERILATOR_DIR)

# XXX: Frustratingly, REPL only works with dynamic libraries, but Cabal prefers
#      static ones. On the flip side, normal *runs* only work with static
#      libraries. We therefore put them into separate directories so that we
#      can easily pick the right one depending on the use-case.
all: ../static/lib$(CPU_NAME)VexRiscvFFI.a ../dynamic/lib$(CPU_NAME)VexRiscvFFI.so

clean:
	rm -rf *.o *.v *.a *.so *.sbt ffi lib project src $(VERILATOR_DIR) target

build.sbt: $(CLASH_VEXRISCV_DATA_DIR)/build.sbt $(CLASH_VEXRISCV_DATA_DIR)/Makefile
	cp $(CLASH_VEXRISCV_DATA_DIR)/build.sbt build.sbt

project/%: $(CLASH_VEXRISCV_DATA_DIR)/project/% $(CLASH_VEXRISCV_DATA_DIR)/Makefile
	mkdir -p project
	cp $< $@

lib/vexriscv.jar: ../../vexriscv.jar $(CLASH_VEXRISCV_DATA_DIR)/Makefile
	mkdir -p lib
	cp ../../vexriscv.jar $@

ffi/%: $(CLASH_VEXRISCV_DATA_DIR)/ffi/% $(CLASH_VEXRISCV_DATA_DIR)/Makefile
	mkdir -p ffi
	cp $< $@
	sed -i 's/__CPU_NAME__/$(CPU_NAME)/g' $@

src/main/scala/cpu/%: $(SCALA_CONFIG_DIR)/% $(CLASH_VEXRISCV_DATA_DIR)/Makefile
	mkdir -p src/main/scala/cpu
	cp $< $@

$(CPU_NAME)VexRiscv.v: src/main/scala/cpu/$(CPU_NAME).scala lib/vexriscv.jar build.sbt project/build.properties project/Dependencies.scala $(CLASH_VEXRISCV_DATA_DIR)/Makefile
	# XXX: SBT cannot build in parallel without issues, so we separate the compile
	#      and runMain steps and guard the former with a lock file.
	flock $(HOME)/.sbt-lock sbt compile
	sbt "runMain cpu.$(CPU_NAME)"
	sed -i -E '/\/\/ Git hash  :.*$$/d' $(CPU_NAME)VexRiscv.v

$(VERILATOR_DIR)/V$(CPU_NAME)VexRiscv.mk $(VERILATOR_DIR)/V$(CPU_NAME)VexRiscv.h: $(CPU_NAME)VexRiscv.v $(CLASH_VEXRISCV_DATA_DIR)/Makefile
	verilator $(VERILATOR_FLAGS) --cc -Mdir $(VERILATOR_DIR) $(CPU_NAME)VexRiscv.v

$(VERILATOR_DIR)/V$(CPU_NAME)VexRiscv__ALL.a: $(VERILATOR_DIR)/V$(CPU_NAME)VexRiscv.mk $(CLASH_VEXRISCV_DATA_DIR)/Makefile
	cd $(VERILATOR_DIR); make -f V$(CPU_NAME)VexRiscv.mk -j $(N)

impl.o: ffi/impl.cpp ffi/interface.h $(VERILATOR_DIR)/V$(CPU_NAME)VexRiscv.h $(CLASH_VEXRISCV_DATA_DIR)/Makefile
	$(CXX) $(FFI_CPPFLAGS) -c ffi/impl.cpp -o impl.o

vimpl.o: ffi/vimpl.cpp ffi/interface.h $(shell pkg-config --variable=includedir verilator)/verilated.h $(shell pkg-config --variable=includedir verilator)/verilated_vcd_c.h $(VERILATOR_DIR)/V$(CPU_NAME)VexRiscv.h $(CLASH_VEXRISCV_DATA_DIR)/Makefile
	$(CXX) $(FFI_CPPFLAGS) -c ffi/vimpl.cpp -o vimpl.o

verilated_vcd_c.o: $(shell pkg-config --variable=includedir verilator)/verilated_vcd_c.cpp $(CLASH_VEXRISCV_DATA_DIR)/Makefile
	$(CXX) $(FFI_CPPFLAGS) -c $(shell pkg-config --variable=includedir verilator)/verilated_vcd_c.cpp -o verilated_vcd_c.o

verilated.o: $(shell pkg-config --variable=includedir verilator)/verilated.cpp $(CLASH_VEXRISCV_DATA_DIR)/Makefile
	$(CXX) $(FFI_CPPFLAGS) -c $(shell pkg-config --variable=includedir verilator)/verilated.cpp -o verilated.o

verilated_threads.o: $(shell pkg-config --variable=includedir verilator)/verilated_threads.cpp $(CLASH_VEXRISCV_DATA_DIR)/Makefile
	$(CXX) $(FFI_CPPFLAGS) -c $(shell pkg-config --variable=includedir verilator)/verilated_threads.cpp -o verilated_threads.o

V$(CPU_NAME)VexRiscv__ALL.a: $(VERILATOR_DIR)/V$(CPU_NAME)VexRiscv__ALL.a $(CLASH_VEXRISCV_DATA_DIR)/Makefile
	cp $(VERILATOR_DIR)/V$(CPU_NAME)VexRiscv__ALL.a V$(CPU_NAME)VexRiscv__ALL.a

lib$(CPU_NAME)VexRiscvFFI.a: V$(CPU_NAME)VexRiscv__ALL.a vimpl.o impl.o verilated.o verilated_threads.o verilated_vcd_c.o $(CLASH_VEXRISCV_DATA_DIR)/Makefile
	rm -f libVexRiscvFFI.a
	cp V$(CPU_NAME)VexRiscv__ALL.a lib$(CPU_NAME)VexRiscvFFI.a
	ar r \
		lib$(CPU_NAME)VexRiscvFFI.a \
		vimpl.o \
		impl.o \
		verilated.o \
		verilated_threads.o \
		verilated_vcd_c.o

lib$(CPU_NAME)VexRiscvFFI.so: lib$(CPU_NAME)VexRiscvFFI.a $(CLASH_VEXRISCV_DATA_DIR)/Makefile
	rm -f lib$(CPU_NAME)VexRiscvFFI.so
	$(CXX) -shared -o lib$(CPU_NAME)VexRiscvFFI.so -Wl,--whole-archive lib$(CPU_NAME)VexRiscvFFI.a -Wl,--no-whole-archive

../static/lib$(CPU_NAME)VexRiscvFFI.a: lib$(CPU_NAME)VexRiscvFFI.a $(CLASH_VEXRISCV_DATA_DIR)/Makefile
	mkdir -p ../static
	cp lib$(CPU_NAME)VexRiscvFFI.a ../static

../dynamic/lib$(CPU_NAME)VexRiscvFFI.so: lib$(CPU_NAME)VexRiscvFFI.so $(CLASH_VEXRISCV_DATA_DIR)/Makefile
	mkdir -p ../dynamic
	cp lib$(CPU_NAME)VexRiscvFFI.so ../dynamic