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
|
# 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
|