Generate VHDL processes from Verilog processes
This commit is contained in:
parent
fef0fd82ff
commit
9292a087e8
|
|
@ -22,13 +22,57 @@
|
|||
#include "vhdl_element.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
|
||||
/*
|
||||
* Convert a Verilog process to VHDL and add it to the architecture
|
||||
* of the given entity.
|
||||
*/
|
||||
static int generate_vhdl_process(vhdl_entity *ent, ivl_process_t proc)
|
||||
{
|
||||
vhdl_process *vhdl_proc = new vhdl_process();
|
||||
|
||||
// TODO: Add statements
|
||||
|
||||
// Add a comment indicating where it came from
|
||||
ivl_scope_t scope = ivl_process_scope(proc);
|
||||
const char *type = ivl_process_type(proc) == IVL_PR_INITIAL
|
||||
? "initial" : "always";
|
||||
std::ostringstream ss;
|
||||
ss << "Generated from " << type << " process in scope ";
|
||||
ss << ivl_scope_name(scope);
|
||||
vhdl_proc->set_comment(ss.str());
|
||||
|
||||
// Store it in the entity's architecture
|
||||
ent->get_arch()->add_stmt(vhdl_proc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int draw_process(ivl_process_t proc, void *cd)
|
||||
{
|
||||
ivl_scope_t scope = ivl_process_scope(proc);
|
||||
const char *scope_name = ivl_scope_name(scope);
|
||||
|
||||
std::cout << "process: scope " << scope_name << std::endl;
|
||||
|
||||
return 0;
|
||||
// A process should occur in a module scope, therefore it
|
||||
// should have already been assigned a VHDL entity
|
||||
assert(ivl_scope_type(scope) == IVL_SCT_MODULE);
|
||||
vhdl_entity *ent = find_entity(ivl_scope_tname(scope));
|
||||
assert(ent != NULL);
|
||||
|
||||
// If the scope this process belongs to is the same as the
|
||||
// VHDL entity was generated from, then create a VHDL process
|
||||
// from this Verilog process. This ensures that each process
|
||||
// is translated at most once, no matter how many times it
|
||||
// appears in the hierarchy.
|
||||
if (ent->get_derived_from() == scope_name) {
|
||||
std::cout << "New process encountered in " << scope_name << std::endl;
|
||||
return generate_vhdl_process(ent, proc);
|
||||
}
|
||||
else {
|
||||
std::cout << "Ignoring already seen process in ";
|
||||
std::cout << scope_name << std::endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,12 +35,16 @@ static vhdl_entity *create_entity_for(ivl_scope_t scope)
|
|||
// The type name will become the entity name
|
||||
const char *tname = ivl_scope_tname(scope);
|
||||
|
||||
// Remember the scope name this entity was derived from so
|
||||
// the correct processes can be added later
|
||||
const char *derived_from = ivl_scope_name(scope);
|
||||
|
||||
// Verilog does not have the entity/architecture distinction
|
||||
// so we always create a pair and associate the architecture
|
||||
// with the entity for convenience (this also means that we
|
||||
// retain a 1-to-1 mapping of scope to VHDL element)
|
||||
vhdl_arch *arch = new vhdl_arch(tname);
|
||||
vhdl_entity *ent = new vhdl_entity(tname, arch);
|
||||
vhdl_entity *ent = new vhdl_entity(tname, derived_from, arch);
|
||||
|
||||
// Build a comment to add to the entity/architecture
|
||||
std::ostringstream ss;
|
||||
|
|
@ -51,6 +55,9 @@ static vhdl_entity *create_entity_for(ivl_scope_t scope)
|
|||
arch->set_comment(ss.str());
|
||||
ent->set_comment(ss.str());
|
||||
|
||||
std::cout << "Generated entity " << tname;
|
||||
std::cout << " from " << ivl_scope_name(scope) << std::endl;
|
||||
|
||||
remember_entity(ent);
|
||||
return ent;
|
||||
}
|
||||
|
|
@ -67,10 +74,6 @@ static int draw_module(ivl_scope_t scope, ivl_scope_t parent)
|
|||
if (NULL == ent)
|
||||
ent = create_entity_for(scope);
|
||||
assert(ent);
|
||||
|
||||
if (parent != NULL) {
|
||||
std::cout << "parent " << ivl_scope_name(parent) << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,11 +51,11 @@ void error(const char *fmt, ...)
|
|||
/*
|
||||
* Find an entity given a type name.
|
||||
*/
|
||||
vhdl_entity *find_entity(const char *tname)
|
||||
vhdl_entity *find_entity(const std::string &tname)
|
||||
{
|
||||
entity_list_t::const_iterator it;
|
||||
for (it = g_entities.begin(); it != g_entities.end(); ++it) {
|
||||
if (strcmp((*it)->get_name(), tname) == 0)
|
||||
if ((*it)->get_name() == tname)
|
||||
return *it;
|
||||
}
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -85,8 +85,9 @@ void vhdl_element::emit_comment(std::ofstream &of, int level) const
|
|||
|
||||
//////// ENTITY ////////
|
||||
|
||||
vhdl_entity::vhdl_entity(const char *name, vhdl_arch *arch)
|
||||
: name_(name), arch_(arch)
|
||||
vhdl_entity::vhdl_entity(const char *name, const char *derived_from,
|
||||
vhdl_arch *arch)
|
||||
: name_(name), arch_(arch), derived_from_(derived_from)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -169,7 +170,7 @@ void vhdl_process::add_stmt(vhdl_seq_stmt* stmt)
|
|||
void vhdl_process::emit(std::ofstream &of, int level) const
|
||||
{
|
||||
emit_comment(of, level);
|
||||
if (name_)
|
||||
if (name_.size() > 0)
|
||||
of << name_ << ": ";
|
||||
of << "process is"; // TODO: sensitivity
|
||||
newline(of, level);
|
||||
|
|
|
|||
|
|
@ -72,19 +72,20 @@ typedef std::list<vhdl_seq_stmt*> seq_stmt_list_t;
|
|||
*/
|
||||
class vhdl_process : public vhdl_conc_stmt {
|
||||
public:
|
||||
vhdl_process(const char *name = NULL);
|
||||
vhdl_process(const char *name = "");
|
||||
virtual ~vhdl_process();
|
||||
|
||||
void emit(std::ofstream &of, int level) const;
|
||||
void add_stmt(vhdl_seq_stmt* stmt);
|
||||
private:
|
||||
seq_stmt_list_t stmts_;
|
||||
const char *name_;
|
||||
std::string name_;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* An architecture which implements an entity.
|
||||
* An architecture which implements an entity. Entities are `derived'
|
||||
* from instantiations of Verilog module scopes in the hierarchy.
|
||||
*/
|
||||
class vhdl_arch : public vhdl_element {
|
||||
public:
|
||||
|
|
@ -95,7 +96,7 @@ public:
|
|||
void add_stmt(vhdl_conc_stmt* stmt);
|
||||
private:
|
||||
conc_stmt_list_t stmts_;
|
||||
const char *name_, *entity_;
|
||||
std::string name_, entity_;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -105,15 +106,19 @@ private:
|
|||
*/
|
||||
class vhdl_entity : public vhdl_element {
|
||||
public:
|
||||
vhdl_entity(const char *name, vhdl_arch *arch);
|
||||
vhdl_entity(const char *name, const char *derived_from,
|
||||
vhdl_arch *arch);
|
||||
virtual ~vhdl_entity();
|
||||
|
||||
void emit(std::ofstream &of, int level=0) const;
|
||||
vhdl_arch *get_arch() const { return arch_; }
|
||||
const char *get_name() const { return name_; }
|
||||
const std::string &get_name() const { return name_; }
|
||||
|
||||
const std::string &get_derived_from() const { return derived_from_; }
|
||||
private:
|
||||
const char *name_;
|
||||
std::string name_;
|
||||
vhdl_arch *arch_; // Entity may only have a single architecture
|
||||
std::string derived_from_;
|
||||
};
|
||||
|
||||
typedef std::list<vhdl_entity*> entity_list_t;
|
||||
|
|
|
|||
|
|
@ -6,13 +6,15 @@
|
|||
|
||||
#include "vhdl_element.hh"
|
||||
|
||||
#include <string>
|
||||
|
||||
void error(const char *fmt, ...);
|
||||
|
||||
int draw_scope(ivl_scope_t scope, void *_parent);
|
||||
int draw_process(ivl_process_t net, void *cd);
|
||||
|
||||
void remember_entity(vhdl_entity *ent);
|
||||
vhdl_entity *find_entity(const char *tname);
|
||||
vhdl_entity *find_entity(const std::string &tname);
|
||||
|
||||
#endif /* #ifndef INC_VHDL_TARGET_H */
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue