diff options
Diffstat (limited to 'mk')
| -rw-r--r-- | mk/build.mk | 2 | ||||
| -rw-r--r-- | mk/cores.mk | 10 | ||||
| -rw-r--r-- | mk/quartus.mk | 128 | ||||
| -rw-r--r-- | mk/tools.mk | 2 | ||||
| -rw-r--r-- | mk/top.mk | 1 | ||||
| -rw-r--r-- | mk/verilator.mk | 12 |
6 files changed, 146 insertions, 9 deletions
diff --git a/mk/build.mk b/mk/build.mk index 40b2b9e..33bd81b 100644 --- a/mk/build.mk +++ b/mk/build.mk @@ -38,7 +38,7 @@ define setup_obj $$(obj): export CONTENTS := $$(build_id_text) $$(obj): - @mkdir -p $$@ && echo -n "$$$$CONTENTS" >$$@/build-vars + @mkdir -p $$@ && echo -n "$$$$CONTENTS" >$$@/build-vars && ln -Tsf ../../../ $$@/src endef define find_command_lazy diff --git a/mk/cores.mk b/mk/cores.mk index 7ce2e47..238ece4 100644 --- a/mk/cores.mk +++ b/mk/cores.mk @@ -17,6 +17,16 @@ core_paths = \ $(let prefix,$(core_info/$(1)/workdir), \ $(addprefix /$(if $(prefix),$(prefix)/),$(core_info/$(1)/$(2))))))) +require_core_paths = \ + $(strip \ + $(let val,$(strip $(call core_paths,$(1),$(2))), \ + $(if $(val),$(val),$(error core '$(1)' must define '$(2)')))) + +require_core_var = \ + $(strip \ + $(let val,$(core_info/$(1)/$(2)), \ + $(if $(val),$(val),$(error core '$(1)' must define '$(2)')))) + define add_core this := core_info/$(1) diff --git a/mk/quartus.mk b/mk/quartus.mk new file mode 100644 index 0000000..ae26a7d --- /dev/null +++ b/mk/quartus.mk @@ -0,0 +1,128 @@ +# Based on github:alexforencich/verilog-ethernet:example/DE2-115/fpga/common/quartus.mk + +targets += syn + +quartus_qsf = $(obj)/$(quartus_top).qsf +quartus_qpf = $(obj)/$(quartus_top).qpf +quartus_run = cd $(obj) && $(QUARTUS) + +quartus_top = $(call per_target,quartus_top) +quartus_device = $(call per_target,quartus_device) +quartus_family = "$(call per_target,quartus_family)" + +quartus_rtl = $(call per_target,quartus_rtl) +quartus_sdc = $(call per_target,quartus_sdc) +quartus_tcl = $(call per_target,quartus_tcl) +quartus_qip = $(call per_target,quartus_qip) +quartus_qsys = $(call per_target,quartus_qsys) +quartus_rtl_include = $(call per_target,quartus_rtl_include) + +quartus_platforms = $(call per_target,quartus_platforms) +quartus_src_files = $(quartus_rtl) $(quartus_sdc) $(quartus_qip) $(quartus_qsys) $(quartus_tcl) + +quartus_plat_qip = $(foreach plat,$(quartus_platforms),$(call quartus_plat_path,$(plat))) +quartus_plat_path = qsys/$(1)/synthesis/$(basename $(notdir $(core_info/$(1)/qsys_platform))).qip + +define target/syn/prepare + flow/type := syn +endef + +define target/syn/setup + $(call target_var,quartus_top) := $$(call require_core_var,$$(rule_top),rtl_top) + $(call target_var,quartus_device) := $$(call require_core_var,$$(rule_top),altera_device) + $(call target_var,quartus_family) := $$(call require_core_var,$$(rule_top),altera_family) +endef + +define target/syn/rules + deps := $$(dep_tree/$$(rule_top)) + + $(call target_var,quartus_rtl) := \ + $$(foreach dep,$$(deps),$$(call core_paths,$$(dep),rtl_files)) + + $(call target_var,quartus_rtl_include) := \ + $$(foreach dep,$$(deps),$$(call core_paths,$$(dep),rtl_include_dirs)) + + $(call target_var,quartus_sdc) := \ + $$(foreach dep,$$(deps),$$(call core_paths,$$(dep),sdc_files)) + + $(call target_var,quartus_qip) := \ + $$(foreach dep,$$(deps),$$(call core_paths,$$(dep),qip_files)) + + $(call target_var,quartus_tcl) := \ + $$(foreach dep,$$(deps),$$(call core_paths,$$(dep),qsf_files)) + + $(call target_var,quartus_platforms) := \ + $$(foreach dep,$$(deps),$$(if $$(core_info/$$(dep)/qsys_platform),$$(dep))) + + $(call target_var,quartus_qsys) := \ + $$(foreach dep,$$(quartus_platforms),$$(call core_paths,$$(dep),qsys_platform)) + + .PHONY: $$(rule_top_path)/syn + + $$(rule_top_path)/syn: $$(obj)/asm.stamp + + $$(obj)/asm.stamp: $$(obj)/sta.stamp + $$(call run,ASM) $$(quartus_run)_asm $$(quartus_top) + @touch $$@ + + $$(obj)/sta.stamp: $$(obj)/fit.stamp + $$(call run,STA) $$(quartus_run)_sta $$(quartus_top) + @touch $$@ + + $$(obj)/fit.stamp: $$(obj)/map.stamp + $$(call run,FIT) $$(quartus_run)_fit --part=$$(quartus_device) $$(quartus_top) + @touch $$@ + + $$(obj)/map.stamp: $$(quartus_qpf) + $$(call run,MAP) $$(quartus_run)_map --family=$(quartus_family) $$(quartus_top) + @touch $$@ + + $$(quartus_qsf) $$(quartus_qpf) &: \ + $$(top_stamp) $$(quartus_src_files) \ + $$(addprefix $$(obj)/,$$(quartus_plat_qip)) + $$(call run,QSF) \ + rm -f $$(quartus_qsf) $$(quartus_qpf) && \ + cd $$(obj) && \ + $$(QUARTUS)_sh \ + --prepare -f $$(quartus_family) -d $$(quartus_device) \ + -t $$(quartus_top) $$(quartus_top) && \ + exec >>$$(quartus_top).qsf && \ + echo -e "\n\n# Source files" && \ + assignment() { echo set_global_assignment -name $$$$1 $$$$2; } && \ + assignment_list() { \ + title="$$$$1"; \ + name="$$$$2"; \ + shift 2; \ + echo -e "\n# $$$$title" && \ + for x in $$$$@; do assignment "$$$${name}" "$$$$x"; done \ + } && \ + for x in $$(quartus_rtl); do \ + case $$$${x##*.} in \ + [Vv]) name=VERILOG_FILE ;; \ + [Ss][Vv]) name=SYSTEMVERILOG_FILE ;; \ + [Vv][Hh][Dd]) name=VHDL_FILE ;; \ + *) name=SOURCE_FILE ;; \ + esac; \ + assignment "$$$$name" "src/$$$$x"; \ + done && \ + assignment_list "Search paths" SEARCH_PATH $$(addprefix src/,$$(quartus_rtl_include)) && \ + assignment_list "Constraint files" SDC_FILE $$(addprefix src/,$$(quartus_sdc)) && \ + assignment_list "IPs" QIP_FILE $$(addprefix src/,$$(quartus_qip)) && \ + assignment_list "Platform IPs" QIP_FILE $$(quartus_plat_qip) && \ + assignment_list "Platforms" QSYS_FILE $$(addprefix src/,$$(quartus_qsys)) && \ + for x in $$(quartus_tcl); do printf "\n#\n# TCL file %s\n#\n" "$$$$x"; cat "src/$$$$x"; done + + $(call target_entrypoint,$(patsubst %,$$(obj)/%.stamp,map fit sta asm)) + + $$(foreach plat,$$(quartus_platforms),$$(eval $$(call quartus_qsys_rules,$$(plat)))) +endef + +define quartus_qsys_rules + qip_file := $$(obj)/$$(call quartus_plat_path,$(1)) + qsys_file := $$(call core_paths,$(1),qsys_platform) + + $$(qip_file): qsys_file := $$(qsys_file) + $$(qip_file): $$(call core_stamp,$(1)) $$(qsys_file) + $$(call run,QSYS,$$(qsys_file)) $$(QSYS_GENERATE) \ + -syn --part=$$(quartus_device) --output-directory=$$(obj)/qsys/$(1) $$(qsys_file) +endef diff --git a/mk/tools.mk b/mk/tools.mk index 9f3734e..9df3eff 100644 --- a/mk/tools.mk +++ b/mk/tools.mk @@ -2,6 +2,8 @@ define find_tools_lazy $(call find_command_lazy,cocotb-config,COCOTB_CONFIG) $(call find_command_lazy,genhtml,GENHTML) $(call find_command_lazy,pkg-config,PKG_CONFIG) + $(call find_command_lazy,qsys-generate,QSYS_GENERATE) + $(call find_command_lazy,quartus,QUARTUS) $(call find_command_lazy,verilator,VERILATOR) $(call shell_defer,cocotb_share,$$(COCOTB_CONFIG) --share) @@ -31,6 +31,7 @@ include mk/cocotb.mk include mk/cores.mk include mk/cov.mk include mk/output.mk +include mk/quartus.mk include mk/target.mk include mk/tools.mk include mk/verilator.mk diff --git a/mk/verilator.mk b/mk/verilator.mk index 56d8783..2692863 100644 --- a/mk/verilator.mk +++ b/mk/verilator.mk @@ -17,10 +17,7 @@ endef define target/sim/setup $(setup_verilator_target) - $$(call target_var,vl_main) := $$(strip $$(call core_paths,$$(rule_top),vl_main)) - ifeq (,$$(vl_main)) - $$(error core '$$(rule_top)' does not define vl_main) - endif + $$(call target_var,vl_main) := $$(strip $$(call require_core_paths,$$(rule_top),vl_main)) endef define target/sim/rules @@ -123,8 +120,8 @@ endef verilator_src_args = \ $(strip \ - $(let rtl_top,$(core_info/$(rule_top)/rtl_top), \ - $(if $(rtl_top),--top $(rtl_top),$(error core '$(rule_top)' must define rtl_top)) \ + $(let rtl_top,$(call require_core_var,$(rule_top),rtl_top), \ + --top $(rtl_top) \ $(foreach dep,$(dep_tree/$(rule_top)), \ $(let prefix,$(core_info/$(dep)/workdir)/, \ $(foreach rtl_dir,$(call core_paths,$(dep),rtl_dirs), \ @@ -132,6 +129,5 @@ verilator_src_args = \ $(foreach include_dir,$(call core_paths,$(dep),rtl_include_dirs), \ -I$(include_dir)) \ $(foreach src_file,$(call core_paths,$(dep),rtl_files) $(call core_paths,$(dep),vl_files), \ - $(src_file)))) \ - $(if $(core_info/$(rule_top)/rtl_files),,$(rtl_top))) \ + $(src_file))))) \ $(if $(vl_main),$(vl_main),$(error $$(vl_main) not defined by target '$(rule_target)'))) |
