From a5db0297b0d17c4ecaaa6db5c062f507f7673c79 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Tue, 22 Jul 2008 15:44:29 +0100 Subject: [PATCH 1/8] Unary minus --- tgt-vhdl/expr.cc | 3 +++ tgt-vhdl/vhdl_syntax.cc | 3 +++ tgt-vhdl/vhdl_syntax.hh | 1 + 3 files changed, 7 insertions(+) diff --git a/tgt-vhdl/expr.cc b/tgt-vhdl/expr.cc index f64ac4ac6..9e383dfc9 100644 --- a/tgt-vhdl/expr.cc +++ b/tgt-vhdl/expr.cc @@ -149,6 +149,9 @@ static vhdl_expr *translate_unary(ivl_expr_t e) case '~': return new vhdl_unaryop_expr (VHDL_UNARYOP_NOT, operand, new vhdl_type(*operand->get_type())); + case '-': + return new vhdl_unaryop_expr + (VHDL_UNARYOP_NEG, operand, new vhdl_type(*operand->get_type())); case 'N': // NOR return translate_reduction(SF_REDUCE_OR, true, operand); case '|': diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index 3cc70853a..a14f11e6d 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -657,6 +657,9 @@ void vhdl_unaryop_expr::emit(std::ostream &of, int level) const case VHDL_UNARYOP_NOT: of << "not "; break; + case VHDL_UNARYOP_NEG: + of << "-"; + break; } operand_->emit(of, level); of << ")"; diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index fcf06286a..c6a2c727f 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -107,6 +107,7 @@ private: enum vhdl_unaryop_t { VHDL_UNARYOP_NOT, + VHDL_UNARYOP_NEG, }; class vhdl_unaryop_expr : public vhdl_expr { From 30fdadc5252f1d9746ac76177af9959bacd4ef58 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Wed, 23 Jul 2008 13:40:42 +0100 Subject: [PATCH 2/8] Support delays in logic devices --- tgt-vhdl/scope.cc | 21 +++++++++++++++++++-- tgt-vhdl/vhdl_syntax.cc | 6 ++++++ tgt-vhdl/vhdl_syntax.hh | 5 +++-- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/tgt-vhdl/scope.cc b/tgt-vhdl/scope.cc index ac1202fff..69808076b 100644 --- a/tgt-vhdl/scope.cc +++ b/tgt-vhdl/scope.cc @@ -242,9 +242,26 @@ static void declare_logic(vhdl_arch *arch, ivl_scope_t scope) dynamic_cast(nexus_to_expr(arch->get_scope(), output)); if (NULL == lhs) continue; // Not suitable for continuous assignment - + vhdl_expr *rhs = translate_logic(arch->get_scope(), log); - arch->add_stmt(new vhdl_cassign_stmt(lhs, rhs)); + vhdl_cassign_stmt *ass = new vhdl_cassign_stmt(lhs, rhs); + + ivl_expr_t delay = ivl_logic_delay(log, 1); + vhdl_expr *after; + if (delay && (after = translate_expr(delay))) { + // Need to make 'after' a time value + // we can do this by multiplying by 1ns + vhdl_type integer(VHDL_TYPE_INTEGER); + after = after->cast(&integer); + + vhdl_expr *ns1 = new vhdl_const_time(1, TIME_UNIT_NS); + after = new vhdl_binop_expr(after, VHDL_BINOP_MULT, ns1, + vhdl_type::time()); + + ass->set_after(after); + } + + arch->add_stmt(ass); } } } diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index a14f11e6d..2f5e9f56f 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -611,6 +611,12 @@ void vhdl_cassign_stmt::emit(std::ostream &of, int level) const of << "else "; } rhs_->emit(of, level); + + if (after_) { + of << " after "; + after_->emit(of, level); + } + of << ";"; } diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index c6a2c727f..f7acf9762 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -227,14 +227,15 @@ typedef std::list conc_stmt_list_t; class vhdl_cassign_stmt : public vhdl_conc_stmt { public: vhdl_cassign_stmt(vhdl_var_ref *lhs, vhdl_expr *rhs) - : lhs_(lhs), rhs_(rhs) {} + : lhs_(lhs), rhs_(rhs), after_(NULL) {} ~vhdl_cassign_stmt(); void emit(std::ostream &of, int level) const; void add_condition(vhdl_expr *value, vhdl_expr *cond); + void set_after(vhdl_expr *a) { after_ = a; } private: vhdl_var_ref *lhs_; - vhdl_expr *rhs_; + vhdl_expr *rhs_, *after_; struct when_part_t { vhdl_expr *value, *cond; From 1409207defa5cbdd0fd10765ab0c639e7320ec2b Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Wed, 23 Jul 2008 14:31:41 +0100 Subject: [PATCH 3/8] Correctly indent case statements --- tgt-vhdl/support.cc | 4 ++-- tgt-vhdl/vhdl_helper.hh | 6 ++++-- tgt-vhdl/vhdl_syntax.cc | 14 ++++++++++---- tgt-vhdl/vhdl_syntax.hh | 2 +- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/tgt-vhdl/support.cc b/tgt-vhdl/support.cc index 159618739..4c396407f 100644 --- a/tgt-vhdl/support.cc +++ b/tgt-vhdl/support.cc @@ -86,9 +86,9 @@ void support_function::emit(std::ostream &of, int level) const of << "(B : Boolean) return std_logic is" << nl_string(level) << "begin" << nl_string(indent(level)) << "if B then" << nl_string(indent(indent(level))) - << "return '1'" << nl_string(indent(level)) + << "return '1';" << nl_string(indent(level)) << "else" << nl_string(indent(indent(level))) - << "return '0'" << nl_string(indent(level)) + << "return '0';" << nl_string(indent(level)) << "end if;" << nl_string(level); break; case SF_REDUCE_OR: diff --git a/tgt-vhdl/vhdl_helper.hh b/tgt-vhdl/vhdl_helper.hh index a3f6f0704..d003ff1ef 100644 --- a/tgt-vhdl/vhdl_helper.hh +++ b/tgt-vhdl/vhdl_helper.hh @@ -28,7 +28,8 @@ template void emit_children(std::ostream &of, const std::list &children, - int level, const char *delim="") + int level, const char *delim = "", + bool trailing_newline = true) { // Don't indent if there are no children if (children.size() == 0) @@ -42,7 +43,8 @@ void emit_children(std::ostream &of, if (--sz > 0) of << delim; } - newline(of, level); + if (trailing_newline) + newline(of, level); } } diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index 2f5e9f56f..9637d1fe1 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -192,9 +192,9 @@ void stmt_container::add_stmt(vhdl_seq_stmt *stmt) stmts_.push_back(stmt); } -void stmt_container::emit(std::ostream &of, int level) const +void stmt_container::emit(std::ostream &of, int level, bool newline) const { - emit_children(of, stmts_, level); + emit_children(of, stmts_, level, "", newline); } vhdl_comp_inst::vhdl_comp_inst(const char *inst_name, const char *comp_name) @@ -724,7 +724,7 @@ void vhdl_case_branch::emit(std::ostream &of, int level) const of << "when "; when_->emit(of, level); of << " =>"; - stmts_.emit(of, indent(level)); + stmts_.emit(of, indent(level), false); } vhdl_case_stmt::~vhdl_case_stmt() @@ -740,8 +740,14 @@ void vhdl_case_stmt::emit(std::ostream &of, int level) const newline(of, indent(level)); case_branch_list_t::const_iterator it; - for (it = branches_.begin(); it != branches_.end(); ++it) + int n = branches_.size(); + for (it = branches_.begin(); it != branches_.end(); ++it) { (*it)->emit(of, level); + if (--n > 0) + newline(of, indent(level)); + else + newline(of, level); + } of << "end case;"; } diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index f7acf9762..f54eb4f64 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -261,7 +261,7 @@ public: ~stmt_container(); void add_stmt(vhdl_seq_stmt *stmt); - void emit(std::ostream &of, int level) const; + void emit(std::ostream &of, int level, bool newline=true) const; bool empty() const { return stmts_.empty(); } private: std::list stmts_; From e4c2400eb20673f700a7d8da3bb5ada3392fa250 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Wed, 23 Jul 2008 16:18:49 +0100 Subject: [PATCH 4/8] Refactor the expression->time code into a single function --- tgt-vhdl/expr.cc | 18 ++++++++++++++++++ tgt-vhdl/scope.cc | 15 ++------------- tgt-vhdl/stmt.cc | 24 +++--------------------- tgt-vhdl/vhdl_target.h | 1 + 4 files changed, 24 insertions(+), 34 deletions(-) diff --git a/tgt-vhdl/expr.cc b/tgt-vhdl/expr.cc index 9e383dfc9..f0aec0019 100644 --- a/tgt-vhdl/expr.cc +++ b/tgt-vhdl/expr.cc @@ -484,3 +484,21 @@ vhdl_expr *translate_expr(ivl_expr_t e) return NULL; } } + +/* + * Translate an expression into a time. This is achieved simply + * by multiplying the expression by 1ns. + */ +vhdl_expr *translate_time_expr(ivl_expr_t e) +{ + vhdl_expr *time = translate_expr(e); + if (NULL == time) + return NULL; + + vhdl_type integer(VHDL_TYPE_INTEGER); + time = time->cast(&integer); + + vhdl_expr *ns1 = new vhdl_const_time(1, TIME_UNIT_NS); + return new vhdl_binop_expr(time, VHDL_BINOP_MULT, ns1, + vhdl_type::time()); +} diff --git a/tgt-vhdl/scope.cc b/tgt-vhdl/scope.cc index 69808076b..826def5ad 100644 --- a/tgt-vhdl/scope.cc +++ b/tgt-vhdl/scope.cc @@ -247,19 +247,8 @@ static void declare_logic(vhdl_arch *arch, ivl_scope_t scope) vhdl_cassign_stmt *ass = new vhdl_cassign_stmt(lhs, rhs); ivl_expr_t delay = ivl_logic_delay(log, 1); - vhdl_expr *after; - if (delay && (after = translate_expr(delay))) { - // Need to make 'after' a time value - // we can do this by multiplying by 1ns - vhdl_type integer(VHDL_TYPE_INTEGER); - after = after->cast(&integer); - - vhdl_expr *ns1 = new vhdl_const_time(1, TIME_UNIT_NS); - after = new vhdl_binop_expr(after, VHDL_BINOP_MULT, ns1, - vhdl_type::time()); - - ass->set_after(after); - } + if (delay) + ass->set_after(translate_time_expr(delay)); arch->add_stmt(ass); } diff --git a/tgt-vhdl/stmt.cc b/tgt-vhdl/stmt.cc index 87efac0e2..68e9e20ec 100644 --- a/tgt-vhdl/stmt.cc +++ b/tgt-vhdl/stmt.cc @@ -269,19 +269,8 @@ static T *make_assignment(vhdl_procedural *proc, stmt_container *container, container->add_stmt(a); ivl_expr_t i_delay; - if (NULL == after && (i_delay = ivl_stmt_delay_expr(stmt))) { - if ((after = translate_expr(i_delay)) == NULL) - return NULL; - - // Need to make 'after' a time value - // we can do this by multiplying by 1ns - vhdl_type integer(VHDL_TYPE_INTEGER); - after = after->cast(&integer); - - vhdl_expr *ns1 = new vhdl_const_time(1, TIME_UNIT_NS); - after = new vhdl_binop_expr(after, VHDL_BINOP_MULT, ns1, - vhdl_type::time()); - } + if (NULL == after && (i_delay = ivl_stmt_delay_expr(stmt))) + after = translate_time_expr(i_delay); if (after != NULL) a->set_after(after); @@ -349,16 +338,9 @@ static int draw_delay(vhdl_procedural *proc, stmt_container *container, time = new vhdl_const_time(value, TIME_UNIT_NS); } else { - time = translate_expr(ivl_stmt_delay_expr(stmt)); + time = translate_time_expr(ivl_stmt_delay_expr(stmt)); if (NULL == time) return 1; - - vhdl_type integer(VHDL_TYPE_INTEGER); - time = time->cast(&integer); - - vhdl_expr *ns1 = new vhdl_const_time(1, TIME_UNIT_NS); - time = new vhdl_binop_expr(time, VHDL_BINOP_MULT, ns1, - vhdl_type::time()); } // If the sub-statement is an assignment then VHDL lets diff --git a/tgt-vhdl/vhdl_target.h b/tgt-vhdl/vhdl_target.h index 20584eecf..62e784845 100644 --- a/tgt-vhdl/vhdl_target.h +++ b/tgt-vhdl/vhdl_target.h @@ -22,6 +22,7 @@ int draw_stmt(vhdl_procedural *proc, stmt_container *container, int draw_lpm(vhdl_arch *arch, ivl_lpm_t lpm); vhdl_expr *translate_expr(ivl_expr_t e); +vhdl_expr *translate_time_expr(ivl_expr_t e); vhdl_var_ref *lpm_output(vhdl_scope *scope, ivl_lpm_t lpm); void remember_entity(vhdl_entity *ent); From 8bee5b11082339b5b4eb63760ab6377dfe6e0c54 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Thu, 24 Jul 2008 14:30:10 +0100 Subject: [PATCH 5/8] Add `forever' statement type --- tgt-vhdl/stmt.cc | 13 +++++++++++++ tgt-vhdl/vhdl_syntax.cc | 7 +++++++ tgt-vhdl/vhdl_syntax.hh | 9 +++++++++ 3 files changed, 29 insertions(+) diff --git a/tgt-vhdl/stmt.cc b/tgt-vhdl/stmt.cc index 68e9e20ec..a1d152f5b 100644 --- a/tgt-vhdl/stmt.cc +++ b/tgt-vhdl/stmt.cc @@ -559,6 +559,17 @@ int draw_while(vhdl_procedural *proc, stmt_container *container, return 0; } +int draw_forever(vhdl_procedural *proc, stmt_container *container, + ivl_statement_t stmt) +{ + vhdl_loop_stmt *loop = new vhdl_loop_stmt; + container->add_stmt(loop); + + draw_stmt(proc, loop->get_container(), ivl_stmt_sub_stmt(stmt)); + + return 0; +} + /* * Generate VHDL statements for the given Verilog statement and * add them to the given VHDL process. The container is the @@ -593,6 +604,8 @@ int draw_stmt(vhdl_procedural *proc, stmt_container *container, return draw_case(proc, container, stmt); case IVL_ST_WHILE: return draw_while(proc, container, stmt); + case IVL_ST_FOREVER: + return draw_forever(proc, container, stmt); default: error("No VHDL translation for statement at %s:%d (type = %d)", ivl_stmt_file(stmt), ivl_stmt_lineno(stmt), diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index 9637d1fe1..0fe655b1e 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -766,6 +766,13 @@ void vhdl_while_stmt::emit(std::ostream &of, int level) const of << "end loop;"; } +void vhdl_loop_stmt::emit(std::ostream &of, int level) const +{ + of << "loop"; + stmts_.emit(of, level); + of << "end loop;"; +} + vhdl_function::vhdl_function(const char *name, vhdl_type *ret_type) : vhdl_decl(name, ret_type) { diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index f54eb4f64..06a7d4125 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -408,6 +408,15 @@ private: }; +class vhdl_loop_stmt : public vhdl_seq_stmt { +public: + stmt_container *get_container() { return &stmts_; } + void emit(std::ostream &of, int level) const; +private: + stmt_container stmts_; +}; + + /* * A procedure call. Which is a statement, unlike a function * call which is an expression. From 39c9c54760af6964738ab757815ec11ede0584df Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Thu, 24 Jul 2008 14:52:06 +0100 Subject: [PATCH 6/8] Add repeat statement --- tgt-vhdl/stmt.cc | 22 ++++++++++++++++++++++ tgt-vhdl/vhdl_syntax.cc | 16 ++++++++++++++++ tgt-vhdl/vhdl_syntax.hh | 15 +++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/tgt-vhdl/stmt.cc b/tgt-vhdl/stmt.cc index a1d152f5b..187134854 100644 --- a/tgt-vhdl/stmt.cc +++ b/tgt-vhdl/stmt.cc @@ -570,6 +570,26 @@ int draw_forever(vhdl_procedural *proc, stmt_container *container, return 0; } +int draw_repeat(vhdl_procedural *proc, stmt_container *container, + ivl_statement_t stmt) +{ + vhdl_expr *times = translate_expr(ivl_stmt_cond_expr(stmt)); + if (NULL == times) + return 1; + + vhdl_type integer(VHDL_TYPE_INTEGER); + times = times->cast(&integer); + + const char *it_name = "Verilog_Repeat"; + vhdl_for_stmt *loop = + new vhdl_for_stmt(it_name, new vhdl_const_int(1), times); + container->add_stmt(loop); + + draw_stmt(proc, loop->get_container(), ivl_stmt_sub_stmt(stmt)); + + return 0; +} + /* * Generate VHDL statements for the given Verilog statement and * add them to the given VHDL process. The container is the @@ -606,6 +626,8 @@ int draw_stmt(vhdl_procedural *proc, stmt_container *container, return draw_while(proc, container, stmt); case IVL_ST_FOREVER: return draw_forever(proc, container, stmt); + case IVL_ST_REPEAT: + return draw_repeat(proc, container, stmt); default: error("No VHDL translation for statement at %s:%d (type = %d)", ivl_stmt_file(stmt), ivl_stmt_lineno(stmt), diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index 0fe655b1e..07a26f5d3 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -773,6 +773,22 @@ void vhdl_loop_stmt::emit(std::ostream &of, int level) const of << "end loop;"; } +vhdl_for_stmt::~vhdl_for_stmt() +{ + delete from_; + delete to_; +} + +void vhdl_for_stmt::emit(std::ostream &of, int level) const +{ + of << "for " << lname_ << " in "; + from_->emit(of, level); + of << " to "; + to_->emit(of, level); + of << " "; + loop_.emit(of, level); +} + vhdl_function::vhdl_function(const char *name, vhdl_type *ret_type) : vhdl_decl(name, ret_type) { diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index 06a7d4125..50c3d305d 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -417,6 +417,21 @@ private: }; +class vhdl_for_stmt : public vhdl_seq_stmt { +public: + vhdl_for_stmt(const char *lname, vhdl_expr *from, vhdl_expr *to) + : lname_(lname), from_(from), to_(to) {} + ~vhdl_for_stmt(); + + stmt_container *get_container() { return loop_.get_container(); } + void emit(std::ostream &of, int level) const; +private: + vhdl_loop_stmt loop_; + const char *lname_; + vhdl_expr *from_, *to_; +}; + + /* * A procedure call. Which is a statement, unlike a function * call which is an expression. From d3296d48955540c9d2b651e84dc3557730c2619f Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Thu, 24 Jul 2008 15:22:25 +0100 Subject: [PATCH 7/8] Refactor while/for loop code to use common base --- tgt-vhdl/vhdl_syntax.cc | 7 +++---- tgt-vhdl/vhdl_syntax.hh | 28 +++++++++++++--------------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index 07a26f5d3..aa3b419d8 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -761,9 +761,8 @@ void vhdl_while_stmt::emit(std::ostream &of, int level) const { of << "while "; test_->emit(of, level); - of << " loop"; - stmts_.emit(of, level); - of << "end loop;"; + of << " "; + vhdl_loop_stmt::emit(of, level); } void vhdl_loop_stmt::emit(std::ostream &of, int level) const @@ -786,7 +785,7 @@ void vhdl_for_stmt::emit(std::ostream &of, int level) const of << " to "; to_->emit(of, level); of << " "; - loop_.emit(of, level); + vhdl_loop_stmt::emit(of, level); } vhdl_function::vhdl_function(const char *name, vhdl_type *ret_type) diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index 50c3d305d..551e4636f 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -395,38 +395,36 @@ private: }; -class vhdl_while_stmt : public vhdl_seq_stmt { +class vhdl_loop_stmt : public vhdl_seq_stmt { +public: + virtual ~vhdl_loop_stmt() {} + + stmt_container *get_container() { return &stmts_; } + void emit(std::ostream &of, int level) const; +private: + stmt_container stmts_; +}; + + +class vhdl_while_stmt : public vhdl_loop_stmt { public: vhdl_while_stmt(vhdl_expr *test) : test_(test) {} ~vhdl_while_stmt(); - stmt_container *get_container() { return &stmts_; } void emit(std::ostream &of, int level) const; private: vhdl_expr *test_; - stmt_container stmts_; }; -class vhdl_loop_stmt : public vhdl_seq_stmt { -public: - stmt_container *get_container() { return &stmts_; } - void emit(std::ostream &of, int level) const; -private: - stmt_container stmts_; -}; - - -class vhdl_for_stmt : public vhdl_seq_stmt { +class vhdl_for_stmt : public vhdl_loop_stmt { public: vhdl_for_stmt(const char *lname, vhdl_expr *from, vhdl_expr *to) : lname_(lname), from_(from), to_(to) {} ~vhdl_for_stmt(); - stmt_container *get_container() { return loop_.get_container(); } void emit(std::ostream &of, int level) const; private: - vhdl_loop_stmt loop_; const char *lname_; vhdl_expr *from_, *to_; }; From 5a098197296d76da869df106e0c6f9c96561abea Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Thu, 24 Jul 2008 16:00:12 +0100 Subject: [PATCH 8/8] Catch case of select expression on non-variable --- tgt-vhdl/display.cc | 2 +- tgt-vhdl/expr.cc | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tgt-vhdl/display.cc b/tgt-vhdl/display.cc index c599aabc3..e70f1bce5 100644 --- a/tgt-vhdl/display.cc +++ b/tgt-vhdl/display.cc @@ -162,7 +162,7 @@ int draw_stask_display(vhdl_procedural *proc, stmt_container *container, } else { vhdl_expr *base = translate_expr(net); - if (NULL == base) + if (NULL == base) return 1; display_write(container, base); diff --git a/tgt-vhdl/expr.cc b/tgt-vhdl/expr.cc index f0aec0019..007abb203 100644 --- a/tgt-vhdl/expr.cc +++ b/tgt-vhdl/expr.cc @@ -355,8 +355,10 @@ static vhdl_expr *translate_select(ivl_expr_t e) { vhdl_var_ref *from = dynamic_cast(translate_expr(ivl_expr_oper1(e))); - if (NULL == from) + if (NULL == from) { + error("Can only select from variable reference"); return NULL; + } ivl_expr_t o2 = ivl_expr_oper2(e); if (o2) { @@ -454,7 +456,7 @@ vhdl_expr *translate_expr(ivl_expr_t e) { assert(e); ivl_expr_type_t type = ivl_expr_type(e); - + switch (type) { case IVL_EX_STRING: return translate_string(e);