From 930e04f6c77a8b2a7cbf656d2f900ee6a8645b55 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Tue, 1 Jul 2008 11:28:02 +0100 Subject: [PATCH] Ensure port map expressions are globally static --- tgt-vhdl/scope.cc | 32 ++++++++++++++++++++++++++++++-- tgt-vhdl/vhdl_syntax.hh | 3 +++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/tgt-vhdl/scope.cc b/tgt-vhdl/scope.cc index b33f14c1f..0b7bce50d 100644 --- a/tgt-vhdl/scope.cc +++ b/tgt-vhdl/scope.cc @@ -313,9 +313,37 @@ static void map_signal(ivl_signal_t to, vhdl_entity *parent, ivl_nexus_t nexus = ivl_signal_nex(to, 0); vhdl_expr *to_e = nexus_to_expr(parent->get_arch()->get_scope(), nexus, to); - std::cout << "map " << ivl_signal_basename(to) << std::endl; - inst->map_port(ivl_signal_basename(to), to_e); + // The expressions in a VHDL port map must be 'globally static' + // i.e. they can't be arbitrary expressions + // To handle this, only vhdl_var_refs are mapped automatically + // Otherwise a temporary variable is created to store the + // result of the expression and that is mapped to the port + // This is actually a bit stricter than necessary: but turns out + // to be much easier to implement + const char *basename = ivl_signal_basename(to); + vhdl_var_ref *to_ref; + if ((to_ref = dynamic_cast(to_e))) { + inst->map_port(basename, to_ref); + } + else { + // Not a static expression + std::string tmpname(inst->get_inst_name().c_str()); + tmpname += "_"; + tmpname += basename; + tmpname += "_Expr"; + + vhdl_type *tmptype = new vhdl_type(*to_e->get_type()); + parent->get_arch()->get_scope()->add_decl + (new vhdl_signal_decl(tmpname.c_str(), tmptype)); + + vhdl_var_ref *tmp_ref1 = new vhdl_var_ref(tmpname.c_str(), NULL); + parent->get_arch()->add_stmt(new vhdl_cassign_stmt(tmp_ref1, to_e)); + + vhdl_var_ref *tmp_ref2 = new vhdl_var_ref(*tmp_ref1); + inst->map_port(basename, tmp_ref2); + } + return; /* int nptrs = ivl_nexus_ptrs(nexus); diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index 2487840ed..c87eea284 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -522,6 +522,9 @@ public: void emit(std::ostream &of, int level) const; void map_port(const char *name, vhdl_expr *expr); + + const std::string &get_comp_name() const { return comp_name_; } + const std::string &get_inst_name() const { return inst_name_; } private: std::string comp_name_, inst_name_; port_map_list_t mapping_;