diff --git a/tgt-vhdl/stmt.cc b/tgt-vhdl/stmt.cc index 93c14fdaf..30637d7e1 100644 --- a/tgt-vhdl/stmt.cc +++ b/tgt-vhdl/stmt.cc @@ -150,13 +150,53 @@ static int draw_delay(vhdl_process *proc, ivl_statement_t stmt) /* * A wait statement waits for a level change on a @(..) list of - * signals. This needs to be implemented by an `if' statement - * inside the process (which the appropriate signals added to - * the sensitivity list). + * signals. + * TODO: This won't yet handle the posedge to rising_edge, etc. + * mapping. */ static int draw_wait(vhdl_process *proc, ivl_statement_t stmt) { - std::cout << "draw_wait" << std::endl; + int nevents = ivl_stmt_nevent(stmt); + for (int i = 0; i < nevents; i++) { + ivl_event_t event = ivl_stmt_events(stmt, i); + + if (ivl_event_nneg(event) != 0) + error("Negative edge events not supported yet"); + if (ivl_event_npos(event) != 0) + error("Positive edge events not supported yet"); + + int nany = ivl_event_nany(event); + for (int i = 0; i < nany; i++) { + ivl_nexus_t nexus = ivl_event_any(event, i); + std::cout << "event nexus " << ivl_nexus_name(nexus) << std::endl; + + int nptrs = ivl_nexus_ptrs(nexus); + for (int j = 0; j < nptrs; j++) { + ivl_nexus_ptr_t nexus_ptr = ivl_nexus_ptr(nexus, j); + + ivl_net_logic_t log; + ivl_signal_t sig; + if ((sig = ivl_nexus_ptr_sig(nexus_ptr))) { + const char *signame = ivl_signal_basename(sig); + std::cout << "signal " << signame << std::endl; + + proc->add_sensitivity(signame); + return 0; + } + else if ((log = ivl_nexus_ptr_log(nexus_ptr))) { + error("Nexus points to net logic"); + return 1; + } + else { + error("Nexus points to unknown"); + return 1; + } + } + } + } + + ivl_statement_t sub_stmt = ivl_stmt_sub_stmt(stmt); + return 0; } diff --git a/tgt-vhdl/vhdl_element.cc b/tgt-vhdl/vhdl_element.cc index 68e0d4721..bd59b40d2 100644 --- a/tgt-vhdl/vhdl_element.cc +++ b/tgt-vhdl/vhdl_element.cc @@ -229,6 +229,11 @@ void vhdl_process::add_decl(vhdl_decl* decl) decls_.push_back(decl); } +void vhdl_process::add_sensitivity(const char *name) +{ + sens_.push_back(name); +} + bool vhdl_process::have_declared_var(const std::string &name) const { decl_list_t::const_iterator it; @@ -244,7 +249,21 @@ void vhdl_process::emit(std::ofstream &of, int level) const emit_comment(of, level); if (name_.size() > 0) of << name_ << ": "; - of << "process is"; // TODO: sensitivity + of << "process "; + + int num_sens = sens_.size(); + if (num_sens > 0) { + of << "("; + string_list_t::const_iterator it; + for (it = sens_.begin(); it != sens_.end(); ++it) { + of << *it; + if (--num_sens > 0) + of << ", "; + } + of << ") "; + } + + of << "is"; emit_children(of, decls_, level); of << "begin"; emit_children(of, stmts_, level); diff --git a/tgt-vhdl/vhdl_element.hh b/tgt-vhdl/vhdl_element.hh index bbd7de589..76e475d3a 100644 --- a/tgt-vhdl/vhdl_element.hh +++ b/tgt-vhdl/vhdl_element.hh @@ -28,6 +28,8 @@ class vhdl_entity; class vhdl_arch; +typedef std::list string_list_t; + /* * Any VHDL syntax element. Each element can also contain a comment. */ @@ -246,11 +248,13 @@ public: void emit(std::ofstream &of, int level) const; void add_stmt(vhdl_seq_stmt *stmt); void add_decl(vhdl_decl *decl); + void add_sensitivity(const char *name); bool have_declared_var(const std::string &name) const; private: seq_stmt_list_t stmts_; decl_list_t decls_; std::string name_; + string_list_t sens_; }; @@ -296,7 +300,7 @@ private: std::string name_; vhdl_arch *arch_; // Entity may only have a single architecture std::string derived_from_; - std::list uses_; + string_list_t uses_; }; typedef std::list entity_list_t;