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.
This commit is contained in:
Maciej Suminski 2014-09-29 16:04:43 +02:00
parent e352bea476
commit 675b7d8efa
3 changed files with 34 additions and 0 deletions

View File

@ -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_;
};

View File

@ -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<SequentialStmt*>*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<SequentialStmt*>::const_iterator s = statements_->begin()
; s != statements_->end(); ++s) {
if((ret = dynamic_cast<const ReturnStmt*>(*s))) {
const Expression*expr = ret->peek_expr();
if(const ExpName*n = dynamic_cast<const ExpName*>(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_ << "(";

View File

@ -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<InterfacePort*>*ports_;