Pretty-print VHDL output

This commit is contained in:
Nick Gasson 2008-05-29 16:24:16 +01:00
parent e178baefbd
commit e38494a10c
4 changed files with 183 additions and 15 deletions

View File

@ -23,6 +23,26 @@
#include <iostream>
#include <fstream>
#include <cstdarg>
#include <cstdio>
static int g_errors = 0; // Total number of errors encountered
/*
* Called when an unrecoverable problem is encountered.
*/
void error(const char *fmt, ...)
{
std::va_list args;
va_start(args, fmt);
std::printf("VHDL conversion error: "); // Source/line number?
std::vprintf(fmt, args);
std::putchar('\n');
va_end(args);
g_errors++;
}
extern "C" int target_design(ivl_design_t des)
{
@ -40,11 +60,15 @@ extern "C" int target_design(ivl_design_t des)
// Dummy output to test regression script
vhdl_entity test_ent(scope_name);
vhdl_arch test_arch(scope_name);
vhdl_process test_proc;
test_arch.set_comment("I am a comment");
test_arch.add_stmt(&test_proc);
test_proc.set_comment("I am a process");
test_ent.emit(outfile);
test_arch.emit(outfile);
}
outfile.close();
return 0;
return g_errors;
}

View File

@ -20,6 +20,68 @@
#include "vhdl_element.hh"
#include <algorithm>
//////// HELPER FUNCTIONS ////////
static const int VHDL_INDENT = 2; // Spaces to indent
static int indent(int level)
{
return level + VHDL_INDENT;
}
/*
* Emit a newline and indent to the correct level.
*/
static void newline(std::ofstream &of, int level)
{
of << std::endl;
while (level--)
of << ' ';
}
static void blank_line(std::ofstream &of, int level)
{
of << std::endl;
newline(of, level);
}
template <class T>
void emit_children(std::ofstream &of,
const std::list<T*> &children,
int level)
{
// Don't indent if there are no children
if (children.size() == 0)
newline(of, level);
else {
typename std::list<T*>::const_iterator it;
for (it = children.begin(); it != children.end(); ++it) {
newline(of, indent(level));
(*it)->emit(of, indent(level));
}
newline(of, level);
}
}
//////// ALL ELEMENTS ////////
void vhdl_element::set_comment(std::string comment)
{
comment_ = comment;
}
void vhdl_element::emit_comment(std::ofstream &of, int level) const
{
if (comment_.size() > 0) {
of << "-- " << comment_;
newline(of, level);
}
}
//////// ENTITY ////////
@ -29,11 +91,15 @@ vhdl_entity::vhdl_entity(const char *name)
}
void vhdl_entity::emit(std::ofstream &of)
void vhdl_entity::emit(std::ofstream &of, int level) const
{
of << "entity " << name_ << " is" << std::endl;
emit_comment(of, level);
of << "entity " << name_ << " is";
// ...ports...
of << "end entity; " << std::endl;
// newline(indent(level));
newline(of, level);
of << "end entity; ";
blank_line(of, level); // Extra blank line after entities
}
@ -45,12 +111,52 @@ vhdl_arch::vhdl_arch(const char *entity, const char *name)
}
void vhdl_arch::emit(std::ofstream &of)
void vhdl_arch::add_stmt(vhdl_conc_stmt* stmt)
{
of << "architecture " << name_ << " of " << entity_;
of << " is" << std::endl;
// ...declarations...
of << "begin" << std::endl;
// ...statements...
of << "end architecture;" << std::endl;
stmts_.push_back(stmt);
}
void vhdl_arch::emit(std::ofstream &of, int level) const
{
emit_comment(of, level);
of << "architecture " << name_ << " of " << entity_;
of << " is";
// ...declarations...
// newline(indent(level));
newline(of, level);
of << "begin";
emit_children<vhdl_conc_stmt>(of, stmts_, level);
of << "end architecture;";
blank_line(of, level); // Extra blank line after architectures;
}
//////// PROCESS ////////
vhdl_process::vhdl_process(const char *name)
: name_(name)
{
}
void vhdl_process::add_stmt(vhdl_seq_stmt* stmt)
{
stmts_.push_back(stmt);
}
void vhdl_process::emit(std::ofstream &of, int level) const
{
emit_comment(of, level);
if (name_)
of << name_ << ": ";
of << "process is"; // TODO: sensitivity
newline(of, level);
// ...declarations...
of << "begin";
newline(of, level);
// ...statements...
of << "wait;"; // Just to stop the simulation hanging
newline(of, level);
of << "end process;";
newline(of, level);
}

View File

@ -22,28 +22,64 @@
#define INC_VHDL_ELEMENT_HH
#include <fstream>
#include <list>
#include <string>
class vhdl_element;
typedef std::list<vhdl_element*> element_list_t;
class vhdl_element {
public:
virtual void emit(std::ofstream &of) = 0;
public:
virtual void emit(std::ofstream &of, int level=0) const = 0;
void set_comment(std::string comment);
protected:
void emit_comment(std::ofstream &of, int level) const;
private:
std::string comment_;
};
class vhdl_entity : public vhdl_element {
public:
vhdl_entity(const char *name);
void emit(std::ofstream &of);
void emit(std::ofstream &of, int level=0) const;
private:
const char *name_;
};
class vhdl_conc_stmt : public vhdl_element {
};
typedef std::list<vhdl_conc_stmt*> conc_stmt_list_t;
class vhdl_seq_stmt : public vhdl_element {
};
typedef std::list<vhdl_seq_stmt*> seq_stmt_list_t;
class vhdl_process : public vhdl_conc_stmt {
public:
vhdl_process(const char *name = NULL);
void emit(std::ofstream &of, int level) const;
void add_stmt(vhdl_seq_stmt* stmt);
private:
seq_stmt_list_t stmts_;
const char *name_;
};
class vhdl_arch : public vhdl_element {
public:
vhdl_arch(const char *entity, const char *name="Behavioural");
void emit(std::ofstream &of);
void emit(std::ofstream &of, int level=0) const;
void add_stmt(vhdl_conc_stmt* stmt);
private:
conc_stmt_list_t stmts_;
const char *name_, *entity_;
};
#endif

View File

@ -4,5 +4,7 @@
#include "vhdl_config.h"
#include "ivl_target.h"
void error(const char *fmt, ...);
#endif /* #ifndef INC_VHDL_TARGET_H */