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
|
targets += sim
vtop_dir = $(call per_target,vtop_dir)
vtop_exe = $(call per_target,vtop_exe)
vl_main = $(call per_target,vl_main)
vl_flags = $(call per_target,vl_flags)
vl_cflags = $(call per_target,vl_cflags)
vl_ldflags = $(call per_target,vl_ldflags)
define target/sim/prepare
enable_opt := 1
$(prepare_verilator_target)
endef
define target/sim/setup
$(setup_verilator_target)
$$(call target_var,vl_main) := $$(strip $$(call require_core_paths,$$(rule_top),vl_main))
endef
define target/sim/rules
$(verilator_target_rules)
.PHONY: $$(rule_top_path)/sim
$$(rule_top_path)/sim: $$(vtop_exe) $$(call core_objs,$$(rule_top),obj_deps)
$$(call run,RUN) cd $$(obj) && vl/Vtop
$(call target_entrypoint,$$(rule_top_path)/sim)
endef
define prepare_verilator_target
flow/type := sim
endef
define setup_verilator_target
$(call build_vars,$(addprefix enable_,rand threads trace cov opt lto prof))
$(call target_var,vl_flags) = $(common_vl_flags)
$(call target_var,vl_cflags) = $(common_vl_cflags)
$(call target_var,vl_ldflags) = $(common_vl_ldflags)
endef
$(eval $(call defer,common_vl_flags,$$(set_verilator_common)))
$(eval $(call defer,common_vl_cflags,$$(set_verilator_common)))
$(eval $(call defer,common_vl_ldflags,$$(set_verilator_common)))
define set_verilator_common
ifneq (,$$(enable_lto))
enable_opt := 1
endif
x_mode := $$(if $$(enable_rand),unique,fast)
static_flags := \
--x-assign $$(x_mode) --x-initial $$(x_mode) \
$$(if $$(enable_threads),--threads $$(call shell_checked,nproc)) \
$$(if $$(enable_trace),--trace --trace-fst --trace-structs) \
$$(if $$(enable_cov),--coverage) \
$$(if $$(enable_opt),-O3) \
$$(if $$(enable_prof),--prof-cfuncs) \
--cc --exe --prefix Vtop --MMD --MP --timescale 1ns/1ns
common_vl_flags := $$(static_flags) $$(core_info/$$(rule_top)/vl_flags)
common_vl_cflags := \
$$(if $$(enable_opt),-march=native -O3) \
$$(if $$(enable_lto),-flto)
common_vl_ldflags := \
$$(if $$(enable_lto),-flto)
endef
define verilator_target_rules
$(call target_var,vtop_dir) := $$(obj)/vl
$(call target_var,vtop_exe) := $$(vtop_dir)/Vtop
vtop_mk_file := $$(vtop_dir)/Vtop.mk
vtop_mk_stamp := $$(vtop_dir)/stamp
vtop_dep_file := $$(vtop_dir)/Vtop__ver.d
vtop_cpp_deps := \
$$(foreach dep,$$(dep_tree/$$(rule_top)),$$(call core_paths,$$(dep),vl_files)) \
$$(vl_main)
-include $$(vtop_dep_file)
$$(vtop_dep_file):
$$(vtop_exe): export VPATH := $$(src)
$$(vtop_exe): $$(vtop_mk_stamp) $$(vtop_cpp_deps)
$$(call run_submake,BUILD) $$(if $$(V),,-s) -C $$(vtop_dir) -f Vtop.mk
@touch -c $$@
$$(vtop_mk_file):
@rm -f $$@
$$(vtop_mk_stamp): $$(top_stamp) $$(vtop_mk_file) $$(verilator_hard_deps)
$$(eval $$(final_vflags))
$$(call run,VERILATE) $$(VERILATOR) $$(vl_flags) $$(verilator_src_args)
@touch $$@
$(call target_entrypoint,$$(vtop_exe))
endef
verilator_hard_deps = \
$(foreach dep,$(dep_tree/$(rule_top)),$(call core_paths_dyn,$(dep),rtl_files))
define final_vflags
$(call find_with_pkgconfig, \
$(call map_core_deps,vl_pkgconfig,$(rule_top)), \
$(call target_var,vl_cflags), \
$(call target_var,vl_ldflags))
$$(call target_var,vl_flags) += --Mdir $$(vtop_dir)
$$(call target_var,vl_cflags) := $$(strip $$(vl_cflags))
$$(call target_var,vl_ldflags) := $$(strip $$(vl_ldflags))
# Verilator's wrapper script can't handle `-CFLAGS ''` correctly
ifneq (,$$(vl_cflags))
$$(call target_var,vl_flags) += -CFLAGS '$$(vl_cflags)'
endif
ifneq (,$$(vl_ldflags))
$$(call target_var,vl_flags) += -LDFLAGS '$$(vl_ldflags)'
endif
endef
verilator_src_args = \
$(strip \
$(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), \
-y $(rtl_dir)) \
$(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 $(vl_main),$(vl_main),$(error $$(vl_main) not defined by target '$(rule_target)')))
|