Skip to content

Commit

Permalink
Merge pull request #86 from orsonmmz/files
Browse files Browse the repository at this point in the history
Basic support for std.textio/ieee.std_logic_textio
  • Loading branch information
steveicarus committed Dec 7, 2015
2 parents a62a095 + ab025f1 commit fbeac72
Show file tree
Hide file tree
Showing 40 changed files with 1,701 additions and 203 deletions.
1 change: 1 addition & 0 deletions driver/main.c
Expand Up @@ -1072,6 +1072,7 @@ int main(int argc, char **argv)
how to handle them. */
fprintf(iconfig_file, "sys_func:%s%csystem.sft\n", base, sep);
fprintf(iconfig_file, "sys_func:%s%cvhdl_sys.sft\n", base, sep);
fprintf(iconfig_file, "sys_func:%s%cvhdl_textio.sft\n", base, sep);

/* If verilog-2005/09/12 is enabled or icarus-misc or verilog-ams,
* then include the v2005_math library. */
Expand Down
1 change: 1 addition & 0 deletions main.cc
Expand Up @@ -832,6 +832,7 @@ int main(int argc, char*argv[])
// Start the module list with the base system module.
add_vpi_module("system");
add_vpi_module("vhdl_sys");
add_vpi_module("vhdl_textio");

flags["-o"] = strdup("a.out");
min_typ_max_flag = TYP;
Expand Down
2 changes: 2 additions & 0 deletions verilog.spec
Expand Up @@ -102,6 +102,8 @@ rm -rf $RPM_BUILD_ROOT
%attr(-,root,root) %{_libdir}/ivl%{suff}/v2009.vpi
%attr(-,root,root) %{_libdir}/ivl%{suff}/vhdl_sys.sft
%attr(-,root,root) %{_libdir}/ivl%{suff}/vhdl_sys.vpi
%attr(-,root,root) %{_libdir}/ivl%{suff}/vhdl_textio.sft
%attr(-,root,root) %{_libdir}/ivl%{suff}/vhdl_textio.vpi
%attr(-,root,root) %{_libdir}/ivl%{suff}/vpi_debug.vpi
%attr(-,root,root) %{_libdir}/ivl%{suff}/cadpli.vpl
%attr(-,root,root) %{_libdir}/libvpi%{suff}.a
Expand Down
22 changes: 19 additions & 3 deletions vhdlpp/architec.cc
Expand Up @@ -20,6 +20,7 @@
# include "architec.h"
# include "expression.h"
# include "parse_types.h"
# include "sequential.h"
// Need this for parse_errors?
# include "parse_api.h"
# include <cassert>
Expand Down Expand Up @@ -229,18 +230,33 @@ Expression*ComponentInstantiation::find_generic_map(perm_string by_name) const
return p->second;
}

StatementList::StatementList(std::list<SequentialStmt*>*statement_list)
{
if(statement_list)
statements_.splice(statements_.end(), *statement_list);
}

StatementList::~StatementList()
{
for(std::list<SequentialStmt*>::iterator it = statements_.begin();
it != statements_.end(); ++it) {
delete *it;
}
}

ProcessStatement::ProcessStatement(perm_string iname,
std::list<Expression*>*sensitivity_list,
std::list<SequentialStmt*>*statements_list)
: iname_(iname)
: StatementList(statements_list), iname_(iname)
{
if (sensitivity_list)
sensitivity_list_.splice(sensitivity_list_.end(), *sensitivity_list);
if (statements_list)
statements_list_.splice(statements_list_.end(), *statements_list);
}

ProcessStatement::~ProcessStatement()
{
for(std::list<Expression*>::iterator it = sensitivity_list_.begin();
it != sensitivity_list_.end(); ++it) {
delete *it;
}
}
49 changes: 41 additions & 8 deletions vhdlpp/architec.h
Expand Up @@ -215,28 +215,61 @@ class ComponentInstantiation : public Architecture::Statement {
std::map<perm_string,Expression*> port_map_;
};

class ProcessStatement : public Architecture::Statement {
class StatementList : public Architecture::Statement {
public:
StatementList(std::list<SequentialStmt*>*statement_list);
virtual ~StatementList();

virtual int elaborate(Entity*ent, Architecture*arc);
virtual int emit(ostream&out, Entity*entity, Architecture*arc);
virtual void dump(ostream&out, int indent =0) const;

std::list<SequentialStmt*>& stmt_list() { return statements_; }

private:
std::list<SequentialStmt*> statements_;
};

// There is no direct VHDL countepart to SV 'initial' statement,
// but we can still use it during the translation process.
class InitialStatement : public StatementList {
public:
InitialStatement(std::list<SequentialStmt*>*statement_list)
: StatementList(statement_list) {}

int emit(ostream&out, Entity*entity, Architecture*arc);
void dump(ostream&out, int indent =0) const;
};

// There is no direct VHDL countepart to SV 'final' statement,
// but we can still use it during the translation process.
class FinalStatement : public StatementList {
public:
FinalStatement(std::list<SequentialStmt*>*statement_list)
: StatementList(statement_list) {}

int emit(ostream&out, Entity*entity, Architecture*arc);
void dump(ostream&out, int indent =0) const;
};

class ProcessStatement : public StatementList {

public:
ProcessStatement(perm_string iname,
std::list<Expression*>*sensitivity_list,
std::list<SequentialStmt*>*statement_list);
~ProcessStatement();

virtual int elaborate(Entity*ent, Architecture*arc);
virtual int emit(ostream&out, Entity*entity, Architecture*arc);
virtual void dump(ostream&out, int indent =0) const;
int elaborate(Entity*ent, Architecture*arc);
int emit(ostream&out, Entity*entity, Architecture*arc);
void dump(ostream&out, int indent =0) const;

private:
int rewrite_as_always_edge_(Entity*ent, Architecture*arc);
int extract_anyedge_(Entity*ent, Architecture*arc);

private:
perm_string iname_;

std::list<Expression*> sensitivity_list_;
std::list<SequentialStmt*> statements_list_;

};

#endif /* IVL_architec_H */
31 changes: 25 additions & 6 deletions vhdlpp/architec_debug.cc
Expand Up @@ -95,6 +95,30 @@ void SignalAssignment::dump(ostream&out, int indent) const
}
}

void StatementList::dump(ostream&out, int indent) const
{
out << setw(indent+3) << "" << "sequence of statements:" << endl;

for (list<SequentialStmt*>::const_iterator cur = statements_.begin()
; cur != statements_.end() ; ++cur) {
(*cur)->dump(out, indent+4);
}
}

void InitialStatement::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "InitialStatement file=" << get_fileline() << endl;

StatementList::dump(out, indent);
}

void FinalStatement::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "FinalStatment file=" << get_fileline() << endl;

StatementList::dump(out, indent);
}

void ProcessStatement::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "ProcessStatement name_=" << iname_
Expand All @@ -107,10 +131,5 @@ void ProcessStatement::dump(ostream&out, int indent) const
(*cur)->dump(out, indent+4);
}

out << setw(indent+3) << "" << "sequence of statements:" << endl;

for (list<SequentialStmt*>::const_iterator cur = statements_list_.begin()
; cur != statements_list_.end() ; ++cur) {
(*cur)->dump(out, indent+4);
}
StatementList::dump(out, indent);
}
36 changes: 26 additions & 10 deletions vhdlpp/architec_elaborate.cc
Expand Up @@ -59,6 +59,14 @@ int Architecture::elaborate(Entity*entity)
cur->second->elaborate_init_expr(entity, this);
}

// Create 'initial' and 'final' blocks for implicit
// initalization and clean-up actions
if(!initializers_.empty())
statements_.push_front(new InitialStatement(&initializers_));

if(!finalizers_.empty())
statements_.push_front(new FinalStatement(&finalizers_));

for (list<Architecture::Statement*>::iterator cur = statements_.begin()
; cur != statements_.end() ; ++cur) {

Expand Down Expand Up @@ -179,11 +187,11 @@ int ProcessStatement::rewrite_as_always_edge_(Entity*, Architecture*)
return -1;

// If there are multiple statements, I give up.
if (statements_list_.size() != 1)
if (stmt_list().size() != 1)
return -1;

Expression*se = sensitivity_list_.front();
SequentialStmt*stmt_raw = statements_list_.front();
SequentialStmt*stmt_raw = stmt_list().front();

// If the statement is not an if-statement, I give up.
IfSequential*stmt = dynamic_cast<IfSequential*> (stmt_raw);
Expand Down Expand Up @@ -258,22 +266,33 @@ int ProcessStatement::rewrite_as_always_edge_(Entity*, Architecture*)
// Replace the statement with the body of the always
// statement, which is the true clause of the top "if"
// statement. There should be no "else" clause.
assert(statements_list_.size() == 1);
statements_list_.pop_front();
assert(stmt_list().size() == 1);
stmt_list().pop_front();

stmt->extract_true(statements_list_);
stmt->extract_true(stmt_list());

delete stmt;

return 0;
}

int StatementList::elaborate(Entity*ent, Architecture*arc)
{
int errors = 0;

for (std::list<SequentialStmt*>::iterator it = statements_.begin();
it != statements_.end(); ++it) {
errors += (*it)->elaborate(ent, arc);
}

return errors;
}

/*
* Change the "process (<expr>) <stmt>" into "always @(<expr>) ..."
*/
int ProcessStatement::extract_anyedge_(Entity*, Architecture*)
{

vector<Expression*> se;
while (! sensitivity_list_.empty()) {
se.push_back(sensitivity_list_.front());
Expand All @@ -297,10 +316,7 @@ int ProcessStatement::elaborate(Entity*ent, Architecture*arc)
extract_anyedge_(ent, arc);
}

for (list<SequentialStmt*>::iterator cur = statements_list_.begin()
; cur != statements_list_.end() ; ++cur) {
errors += (*cur)->elaborate(ent, arc);
}
StatementList::elaborate(ent, arc);

return errors;
}
Expand Down
37 changes: 31 additions & 6 deletions vhdlpp/architec_emit.cc
Expand Up @@ -246,6 +246,36 @@ int IfGenerate::emit(ostream&out, Entity*ent, Architecture*arc)
return errors;
}

int StatementList::emit(ostream&out, Entity*ent, Architecture*arc)
{
int errors = 0;

for (std::list<SequentialStmt*>::iterator it = statements_.begin();
it != statements_.end(); ++it) {
errors += (*it)->emit(out, ent, arc);
}

return errors;
}

int InitialStatement::emit(ostream&out, Entity*ent, Architecture*arc)
{
out << "initial begin" << endl;
int errors = StatementList::emit(out, ent, arc);
out << "end" << endl;

return errors;
}

int FinalStatement::emit(ostream&out, Entity*ent, Architecture*arc)
{
out << "final begin" << endl;
int errors = StatementList::emit(out, ent, arc);
out << "end" << endl;

return errors;
}

/*
* Emit a process statement using "always" syntax.
*
Expand All @@ -256,14 +286,9 @@ int IfGenerate::emit(ostream&out, Entity*ent, Architecture*arc)
*/
int ProcessStatement::emit(ostream&out, Entity*ent, Architecture*arc)
{
int errors = 0;

out << "always begin" << endl;

for (list<SequentialStmt*>::iterator cur = statements_list_.begin()
; cur != statements_list_.end() ; ++cur) {
errors += (*cur)->emit(out, ent, arc);
}
int errors = StatementList::emit(out, ent, arc);

if (! sensitivity_list_.empty()) {
out << "@(";
Expand Down
8 changes: 2 additions & 6 deletions vhdlpp/debug.cc
Expand Up @@ -415,12 +415,8 @@ void ExpRelation::dump(ostream&out, int indent) const

void ExpString::dump(ostream&out, int indent) const
{
out << setw(indent) << "" << "String \"";
for(vector<char>::const_iterator it = value_.begin();
it != value_.end(); ++it)
out << *it;
out << "\""
<< " at " << get_fileline() << endl;
out << setw(indent) << "" << "String \"" << value_;
out << "\"" << " at " << get_fileline() << endl;
}

void ExpUAbs::dump(ostream&out, int indent) const
Expand Down
4 changes: 4 additions & 0 deletions vhdlpp/entity.h
Expand Up @@ -45,6 +45,10 @@ class InterfacePort : public LineInfo {
: mode(PORT_NONE), type(typ), expr(NULL)
{}

InterfacePort(const VType*typ, port_mode_t mod)
: mode(mod), type(typ), expr(NULL)
{}

// Port direction from the source code.
port_mode_t mode;
// Name of the port from the source code
Expand Down
4 changes: 1 addition & 3 deletions vhdlpp/expression.cc
Expand Up @@ -632,10 +632,8 @@ ExpShift::ExpShift(ExpShift::shift_t op, Expression*op1, Expression*op2)
}

ExpString::ExpString(const char* value)
: value_(strlen(value))
: value_(value)
{
for(size_t idx = 0; idx < value_.size(); idx += 1)
value_[idx] = value[idx];
}

ExpString::~ExpString()
Expand Down

0 comments on commit fbeac72

Please sign in to comment.