First passing at blocking assignment

This commit is contained in:
Nick Gasson 2008-06-18 13:06:27 +01:00
parent d2bebee9d9
commit 254ccb9ccb
5 changed files with 82 additions and 20 deletions

View File

@ -24,13 +24,15 @@
#include <iostream>
#include <cassert>
#include <sstream>
#include <set>
/*
* TODO: Explanation here.
*/
static string_list_t g_assign_vars;
typedef std::set<std::string> string_set_t;
static string_set_t g_assign_vars;
void blocking_assign_to(std::string var)
void blocking_assign_to(vhdl_process *proc, std::string var)
{
std::cout << "blocking_assign_to " << var << std::endl;
}

View File

@ -178,9 +178,13 @@ static int draw_noop(vhdl_process *proc, stmt_container *container,
return 0;
}
template <class T>
static int draw_generic_assign(vhdl_process *proc, stmt_container *container,
ivl_statement_t stmt, vhdl_expr *after = NULL)
/*
* A non-blocking assignment inside a process. The semantics for
* this are essentially the same as VHDL's non-blocking signal
* assignment.
*/
static int draw_nbassign(vhdl_process *proc, stmt_container *container,
ivl_statement_t stmt, vhdl_expr *after = NULL)
{
int nlvals = ivl_stmt_lvals(stmt);
if (nlvals != 1) {
@ -218,7 +222,7 @@ static int draw_generic_assign(vhdl_process *proc, stmt_container *container,
// The type here can be null as it is never actually needed
vhdl_var_ref *lval_ref = new vhdl_var_ref(signame, NULL);
T *assign = new T(lval_ref, rhs);
vhdl_nbassign_stmt *assign = new vhdl_nbassign_stmt(lval_ref, rhs);
if (after != NULL)
assign->set_after(after);
container->add_stmt(assign);
@ -232,22 +236,47 @@ static int draw_generic_assign(vhdl_process *proc, stmt_container *container,
return 0;
}
/*
* A non-blocking assignment inside a process. The semantics for
* this are essentially the same as VHDL's non-blocking signal
* assignment.
*/
static int draw_nbassign(vhdl_process *proc, stmt_container *container,
ivl_statement_t stmt, vhdl_expr *after = NULL)
{
return draw_generic_assign<vhdl_nbassign_stmt>
(proc, container, stmt, after);
}
static int draw_assign(vhdl_process *proc, stmt_container *container,
ivl_statement_t stmt)
{
int nlvals = ivl_stmt_lvals(stmt);
if (nlvals != 1) {
error("Can only have 1 lval at the moment (found %d)", nlvals);
return 1;
}
ivl_lval_t lval = ivl_stmt_lval(stmt, 0);
ivl_signal_t sig;
if ((sig = ivl_lval_sig(lval))) {
const std::string &signame = get_renamed_signal(sig);
blocking_assign_to(proc, signame);
vhdl_decl *decl = proc->get_decl(signame);
assert(decl);
vhdl_expr *rhs_raw = translate_expr(ivl_stmt_rval(stmt));
if (NULL == rhs_raw)
return 1;
vhdl_expr *rhs = rhs_raw->cast(decl->get_type());
// As with non-blocking assignment, push assignments into the
// initialisation if we can
if (proc->is_initial() && ivl_signal_port(sig) == IVL_SIP_NONE) {
decl->set_initial(rhs);
}
else {
// The type here can be null as it is never actually needed
vhdl_var_ref *lval_ref = new vhdl_var_ref(signame.c_str(), NULL);
vhdl_assign_stmt *assign = new vhdl_assign_stmt(lval_ref, rhs);
container->add_stmt(assign);
}
}
else {
error("Only signals as lvals supported at the moment");
return 1;
}
return 0;
}

View File

@ -202,6 +202,19 @@ void vhdl_process::add_decl(vhdl_decl* decl)
decls_.push_back(decl);
}
vhdl_decl *vhdl_process::get_decl(const std::string &name) const
{
decl_list_t::const_iterator it;
for (it = decls_.begin(); it != decls_.end(); ++it) {
if ((*it)->get_name() == name)
return *it;
}
// Maybe it's a signal rather than a variable?
assert(get_parent());
return get_parent()->get_decl(name);
}
void vhdl_process::add_sensitivity(const char *name)
{
sens_.push_back(name);
@ -548,6 +561,14 @@ void vhdl_nbassign_stmt::emit(std::ofstream &of, int level) const
of << ";";
}
void vhdl_assign_stmt::emit(std::ofstream &of, int level) const
{
lhs_->emit(of, level);
of << " := ";
rhs_->emit(of, level);
of << ";";
}
vhdl_const_bits::vhdl_const_bits(const char *value, int width)
: vhdl_expr(vhdl_type::nsigned(width))
{

View File

@ -256,6 +256,15 @@ public:
};
class vhdl_assign_stmt : public vhdl_abstract_assign_stmt {
public:
vhdl_assign_stmt(vhdl_var_ref *lhs, vhdl_expr *rhs)
: vhdl_abstract_assign_stmt(lhs, rhs) {}
void emit(std::ofstream &of, int level) const;
};
enum vhdl_wait_type_t {
VHDL_WAIT_INDEF, // Suspend indefinitely
VHDL_WAIT_FOR_NS, // Wait for a constant number of nanoseconds
@ -456,6 +465,7 @@ public:
void add_decl(vhdl_decl *decl);
void add_sensitivity(const char *name);
bool have_declared_var(const std::string &name) const;
vhdl_decl *get_decl(const std::string &name) const;
void set_initial(bool i) { initial_ = i; }
bool is_initial() const { return initial_; }
private:

View File

@ -31,7 +31,7 @@ void rename_signal(ivl_signal_t sig, const std::string &renamed);
const vhdl_entity *find_entity_for_signal(ivl_signal_t sig);
const std::string &get_renamed_signal(ivl_signal_t sig);
void blocking_assign_to(std::string var);
void blocking_assign_to(vhdl_process *proc, std::string var);
#endif /* #ifndef INC_VHDL_TARGET_H */