From af8c08e6a7e10ca3f26783ee335e5175da497b38 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Tue, 17 Jun 2008 20:16:16 +0100 Subject: [PATCH] Allow optional VHPI $finish implementation --- tgt-vhdl/stmt.cc | 15 ++++++++++++++- tgt-vhdl/vhdl.cc | 7 +++++++ tgt-vhdl/vhdl_syntax.cc | 3 ++- tgt-vhdl/vhdl_syntax.hh | 1 + tgt-vhdl/vhdl_target.h | 2 ++ tgt-vhdl/vhpi/finish.c | 6 ++++++ tgt-vhdl/vhpi/verilog_support.vhd | 15 +++++++++++++++ 7 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 tgt-vhdl/vhpi/finish.c create mode 100644 tgt-vhdl/vhpi/verilog_support.vhd diff --git a/tgt-vhdl/stmt.cc b/tgt-vhdl/stmt.cc index e40ef2002..1f5c57a11 100644 --- a/tgt-vhdl/stmt.cc +++ b/tgt-vhdl/stmt.cc @@ -110,11 +110,24 @@ static int draw_stask_display(vhdl_process *proc, stmt_container *container, * the simulator. This isn't great, as the simulator will * return a failure exit code when in fact it completed * successfully. + * + * An alternative is to use the VHPI interface supported by + * some VHDL simulators and implement the $finish funcitonality + * in C. This function can be enabled with the flag + * -puse-vhpi-finish=1. */ static int draw_stask_finish(vhdl_process *proc, stmt_container *container, ivl_statement_t stmt) { - container->add_stmt(new vhdl_assert_stmt("SIMULATION FINISHED")); + const char *use_vhpi = ivl_design_flag(get_vhdl_design(), "use-vhpi-finish"); + if (strcmp(use_vhpi, "1") == 0) { + proc->get_parent()->get_parent()->requires_package("work.Verilog_Support"); + container->add_stmt(new vhdl_pcall_stmt("work.Verilog_Support.Finish")); + } + else { + container->add_stmt(new vhdl_assert_stmt("SIMULATION FINISHED")); + } + return 0; } diff --git a/tgt-vhdl/vhdl.cc b/tgt-vhdl/vhdl.cc index f2c99b644..29ea76106 100644 --- a/tgt-vhdl/vhdl.cc +++ b/tgt-vhdl/vhdl.cc @@ -48,6 +48,7 @@ typedef std::map signal_defn_map_t; static int g_errors = 0; // Total number of errors encountered static entity_list_t g_entities; // All entities to emit static signal_defn_map_t g_known_signals; +static ivl_design_t g_design; /* @@ -124,6 +125,10 @@ const std::string &get_renamed_signal(ivl_signal_t sig) return g_known_signals[sig].renamed; } +ivl_design_t get_vhdl_design() +{ + return g_design; +} extern "C" int target_design(ivl_design_t des) { @@ -131,6 +136,8 @@ extern "C" int target_design(ivl_design_t des) unsigned int nroots; ivl_design_roots(des, &roots, &nroots); + g_design = des; + for (unsigned int i = 0; i < nroots; i++) draw_scope(roots[i], NULL); diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index 0af19d8b4..f3737b20b 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -495,7 +495,8 @@ void vhdl_expr_list::emit(std::ofstream &of, int level) const void vhdl_pcall_stmt::emit(std::ofstream &of, int level) const { of << name_; - exprs_.emit(of, level); + if (!exprs_.empty()) + exprs_.emit(of, level); of << ";"; } diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index 3399fc8f4..48beb159d 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -147,6 +147,7 @@ public: ~vhdl_expr_list(); void emit(std::ofstream &of, int level) const; + bool empty() const { return exprs_.empty(); } void add_expr(vhdl_expr *e); private: std::list exprs_; diff --git a/tgt-vhdl/vhdl_target.h b/tgt-vhdl/vhdl_target.h index 3612d0e4f..d681afe53 100644 --- a/tgt-vhdl/vhdl_target.h +++ b/tgt-vhdl/vhdl_target.h @@ -22,6 +22,8 @@ vhdl_expr *translate_expr(ivl_expr_t e); void remember_entity(vhdl_entity *ent); vhdl_entity *find_entity(const std::string &tname); +ivl_design_t get_vhdl_design(); + vhdl_var_ref *nexus_to_var_ref(vhdl_arch *arch, ivl_nexus_t nexus); void remember_signal(ivl_signal_t sig, const vhdl_entity *ent); diff --git a/tgt-vhdl/vhpi/finish.c b/tgt-vhdl/vhpi/finish.c new file mode 100644 index 000000000..7a544da0b --- /dev/null +++ b/tgt-vhdl/vhpi/finish.c @@ -0,0 +1,6 @@ +#include + +void finish(void) +{ + exit(0); +} diff --git a/tgt-vhdl/vhpi/verilog_support.vhd b/tgt-vhdl/vhpi/verilog_support.vhd new file mode 100644 index 000000000..eb77c4c06 --- /dev/null +++ b/tgt-vhdl/vhpi/verilog_support.vhd @@ -0,0 +1,15 @@ +-- +-- VHPI support routines for VHDL output. +-- + +package Verilog_Support is + procedure finish; + attribute foreign of finish : procedure is "VHPIDIRECT finish"; +end Verilog_Support; + +package body Verilog_Support is + procedure finish is + begin + assert false severity failure; + end finish; +end Verilog_Support;