From 675b7d8efabc2275924c029462f56c01ce3797cc Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 29 Sep 2014 16:04:43 +0200 Subject: [PATCH] vhdlpp: Support for std_logic_vector return type in functions. VHDL does not allow to specify the size of returned std_logic_vector, whereas Verilog requires the size to be known in advance. The size of the vector is determined by checking the type of expression used in the return statement. --- vhdlpp/sequential.h | 2 ++ vhdlpp/subprogram.cc | 28 ++++++++++++++++++++++++++++ vhdlpp/subprogram.h | 4 ++++ 3 files changed, 34 insertions(+) diff --git a/vhdlpp/sequential.h b/vhdlpp/sequential.h index 9aff1aaa9..9271e4ed3 100644 --- a/vhdlpp/sequential.h +++ b/vhdlpp/sequential.h @@ -120,6 +120,8 @@ class ReturnStmt : public SequentialStmt { int emit(ostream&out, Entity*entity, Architecture*arc); void dump(ostream&out, int indent) const; + const Expression*peek_expr() const { return val_; }; + private: Expression*val_; }; diff --git a/vhdlpp/subprogram.cc b/vhdlpp/subprogram.cc index 47641550c..8f071fd25 100644 --- a/vhdlpp/subprogram.cc +++ b/vhdlpp/subprogram.cc @@ -21,6 +21,7 @@ # include "subprogram.h" # include "entity.h" # include "vtype.h" +# include "sequential.h" # include "ivl_assert.h" using namespace std; @@ -45,6 +46,7 @@ void Subprogram::set_program_body(list*stmt) { ivl_assert(*this, statements_==0); statements_ = stmt; + fix_return_type(); } bool Subprogram::compare_specification(Subprogram*that) const @@ -78,6 +80,32 @@ bool Subprogram::compare_specification(Subprogram*that) const return true; } +void Subprogram::fix_return_type(void) +{ + if(!statements_) + return; + + const ReturnStmt*ret = NULL; + const VType*t = NULL; + + for (std::list::const_iterator s = statements_->begin() + ; s != statements_->end(); ++s) { + if((ret = dynamic_cast(*s))) { + const Expression*expr = ret->peek_expr(); + + if(const ExpName*n = dynamic_cast(expr)) { + if(Variable*v = find_variable(n->peek_name())) + t = v->peek_type(); + } else { + t = expr->peek_type(); + } + + if(t) + return_type_ = t; + } + } +} + void Subprogram::write_to_stream(ostream&fd) const { fd << " function " << name_ << "("; diff --git a/vhdlpp/subprogram.h b/vhdlpp/subprogram.h index 7af6c9e2f..68d924d00 100644 --- a/vhdlpp/subprogram.h +++ b/vhdlpp/subprogram.h @@ -57,6 +57,10 @@ class Subprogram : public LineInfo, public ScopeBase { void dump(std::ostream&fd) const; private: + // Determines appropriate return type. Un case of std_logic_vector + // VHDL requires skipping its size in contrary to Verilog + void fix_return_type(void); + perm_string name_; const ScopeBase*parent_; std::list*ports_;