From c287281bbe7c11e4890d77bb1b636c914716930a Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 22 Jan 2015 18:29:43 +0100 Subject: [PATCH] vhdlpp: Tries to determine if function return type is fixed size. Added Subprogram::fixed_return_type() method. --- vhdlpp/subprogram.cc | 69 ++++++++++++++++++++++++++++++++++---------- vhdlpp/subprogram.h | 14 +++++---- 2 files changed, 62 insertions(+), 21 deletions(-) diff --git a/vhdlpp/subprogram.cc b/vhdlpp/subprogram.cc index 19aa56e62..b663a8cc7 100644 --- a/vhdlpp/subprogram.cc +++ b/vhdlpp/subprogram.cc @@ -78,6 +78,10 @@ void Subprogram::fix_port_types() } } + // Try to settle at a fixed width return type. + if(fixed_return_type()) + return; + // Check if the returned type is an unbounded vector. if(check_unb_vector(return_type_)) { if(!statements_) @@ -87,12 +91,10 @@ void Subprogram::fix_port_types() // statements to comply with the modified return type. for (std::list::iterator s = statements_->begin() ; s != statements_->end(); ++s) { - cast_return_type r(return_type_) ; + cast_return_type r(return_type_); (*s)->visit(r); } } - - //fix_return_type(); } bool Subprogram::check_unb_vector(const VType*&type) @@ -172,30 +174,65 @@ const VType*Subprogram::peek_param_type(int idx) const return (*p)->type; } -void Subprogram::fix_return_type(void) -{ - if(!statements_) - return; +struct check_return_type : public SeqStmtVisitor { + check_return_type(const Subprogram*subp) : subp_(subp), ret_type_(NULL) {} - 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))) { + void operator() (SequentialStmt*s) + { + ReturnStmt*ret; + if((ret = dynamic_cast(s))) { const Expression*expr = ret->peek_expr(); + const VType*t = NULL; if(const ExpName*n = dynamic_cast(expr)) { - if(Variable*v = find_variable(n->peek_name())) + if(Variable*v = subp_->find_variable(n->peek_name())) t = v->peek_type(); } else { t = expr->peek_type(); } - if(t) - return_type_ = t; + if(!t) { // cannot determine the type at least in one case + ret_type_ = NULL; + return; + } + + if(!ret_type_) { // this is first processed return statement + ret_type_ = t; + } else if(!t->type_match(ret_type_)) { + // the function can return different types, + // we cannot have fixed width + ret_type_ = NULL; + return; + } } } + + const VType*get_type() const { return ret_type_; } + +private: + const Subprogram*subp_; + const VType*ret_type_; +}; + +bool Subprogram::fixed_return_type(void) +{ + if(!statements_) + return false; + + check_return_type r(this); + + for (std::list::iterator s = statements_->begin() + ; s != statements_->end(); ++s) { + (*s)->visit(r); + } + + const VType*return_type = r.get_type(); + if(return_type && !return_type->is_unbounded()) { + return_type_ = return_type; + return true; + } else { + return false; + } } void Subprogram::write_to_stream(ostream&fd) const diff --git a/vhdlpp/subprogram.h b/vhdlpp/subprogram.h index b37fe6cd4..21cdaa053 100644 --- a/vhdlpp/subprogram.h +++ b/vhdlpp/subprogram.h @@ -63,13 +63,17 @@ class Subprogram : public LineInfo, public ScopeBase { void dump(std::ostream&fd) const; private: - // Determines appropriate return type, basing on the *first* return - // statement found in the function body. In case of std_logic_vector - // VHDL requires skipping its size, contrary to Verilog. - void fix_return_type(void); + // Tries to set the return type to a fixed type. VHDL functions that + // return std_logic_vectors do not specify its length, as SystemVerilog + // demands. + // The function goes through the function body looking for return + // statments and probes the returned type. If it is the same for every + // statemnt then we can assume that the function returns vector of a + // fixed size. + bool fixed_return_type(); // Iterates through the list of function ports to fix all quirks related - // to translation between VHDL and SystemVerilog. + // to translation between VHDL and SystemVerilog. void fix_port_types(); // Creates a typedef for an unbounded vector and updates the given type.