# Copyright cocotb contributors
# Copyright (c) 2013 Potential Ventures Ltd
# Copyright (c) 2013 SolarFlare Communications Inc
# Licensed under the Revised BSD License, see LICENSE for details.
# SPDX-License-Identifier: BSD-3-Clause

TOPLEVEL_LANG ?= verilog

ifneq ($(or $(filter-out $(TOPLEVEL_LANG),verilog),$(VHDL_SOURCES)),)

$(COCOTB_RESULTS_FILE):
	@echo "Skipping simulation as only Verilog is supported on simulator=$(SIM)"
debug: $(COCOTB_RESULTS_FILE)

else

CMD_BIN := iverilog

ifdef ICARUS_BIN_DIR
    CMD := $(shell :; command -v $(ICARUS_BIN_DIR)/$(CMD_BIN) 2>/dev/null)
else
    # auto-detect bin dir from system path
    CMD := $(shell :; command -v $(CMD_BIN) 2>/dev/null)
    ICARUS_BIN_DIR := $(shell dirname $(CMD))
endif

ifdef COCOTB_TOPLEVEL
  TOPMODULE_ARG := -s $(COCOTB_TOPLEVEL)
else
  TOPMODULE_ARG :=
endif

COMPILE_ARGS += -f $(SIM_BUILD)/cmds.f

ifdef VERILOG_INCLUDE_DIRS
    COMPILE_ARGS += $(addprefix -I, $(VERILOG_INCLUDE_DIRS))
endif

# Compilation phase

ifeq ($(WAVES), 1)
    VERILOG_SOURCES += $(SIM_BUILD)/cocotb_iverilog_dump.v
    COMPILE_ARGS += -s cocotb_iverilog_dump
    FST = -fst
else ifeq ($(WAVES),0)
    # Disable waveform output
    FST = -none
endif

$(SIM_BUILD)/sim.vvp: $(VERILOG_SOURCES) $(CUSTOM_COMPILE_DEPS) | $(SIM_BUILD)
	@echo "+timescale+$(COCOTB_HDL_TIMEUNIT)/$(COCOTB_HDL_TIMEPRECISION)" > $(SIM_BUILD)/cmds.f
	$(CMD) -o $(SIM_BUILD)/sim.vvp $(TOPMODULE_ARG) -g2012 $(COMPILE_ARGS) $(EXTRA_ARGS) $(VERILOG_SOURCES)

$(SIM_BUILD)/cocotb_iverilog_dump.v: | $(SIM_BUILD)
	@echo 'module cocotb_iverilog_dump();' > $@
	@echo 'initial begin' >> $@
	@echo '    $$dumpfile("$(SIM_BUILD)/$(COCOTB_TOPLEVEL).fst");' >> $@
	@echo '    $$dumpvars(0, $(COCOTB_TOPLEVEL));' >> $@
	@echo 'end' >> $@
	@echo 'endmodule' >> $@

# Execution phase

$(COCOTB_RESULTS_FILE): $(SIM_BUILD)/sim.vvp $(CUSTOM_SIM_DEPS)
	$(RM) $(COCOTB_RESULTS_FILE)

	COCOTB_TEST_MODULES=$(call deprecate,MODULE,COCOTB_TEST_MODULES) COCOTB_TESTCASE=$(call deprecate,TESTCASE,COCOTB_TESTCASE) COCOTB_TEST_FILTER=$(COCOTB_TEST_FILTER) COCOTB_TOPLEVEL=$(call deprecate,TOPLEVEL,COCOTB_TOPLEVEL) TOPLEVEL_LANG=$(TOPLEVEL_LANG) \
        $(SIM_CMD_PREFIX) $(ICARUS_BIN_DIR)/vvp -M $(shell $(PYTHON_BIN) -m cocotb_tools.config --lib-dir) -m $(shell $(PYTHON_BIN) -m cocotb_tools.config --lib-name vpi icarus) $(SIM_ARGS) $(EXTRA_ARGS) $(SIM_BUILD)/sim.vvp $(FST) $(call deprecate,PLUSARGS,COCOTB_PLUSARGS) $(SIM_CMD_SUFFIX)

	$(call check_results)

debug: $(SIM_BUILD)/sim.vvp $(CUSTOM_SIM_DEPS)
	$(RM) -r $(COCOTB_RESULTS_FILE)

	COCOTB_TEST_MODULES=$(call deprecate,MODULE,COCOTB_TEST_MODULES) COCOTB_TESTCASE=$(call deprecate,TESTCASE,COCOTB_TESTCASE) COCOTB_TEST_FILTER=$(COCOTB_TEST_FILTER) COCOTB_TOPLEVEL=$(call deprecate,TOPLEVEL,COCOTB_TOPLEVEL) TOPLEVEL_LANG=$(TOPLEVEL_LANG) \
        $(SIM_CMD_PREFIX) gdb --args $(ICARUS_BIN_DIR)/vvp -M $(shell $(PYTHON_BIN) -m cocotb_tools.config --lib-dir) -m $(shell $(PYTHON_BIN) -m cocotb_tools.config --lib-name vpi icarus) $(SIM_ARGS) $(EXTRA_ARGS) $(SIM_BUILD)/sim.vvp $(FST) $(call deprecate,PLUSARGS,COCOTB_PLUSARGS) $(SIM_CMD_SUFFIX)

	$(call check_results)

endif
