First passing at blocking assignment
This commit is contained in:
parent
d2bebee9d9
commit
254ccb9ccb
|
|
@ -24,13 +24,15 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: Explanation here.
|
* 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;
|
std::cout << "blocking_assign_to " << var << std::endl;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -178,9 +178,13 @@ static int draw_noop(vhdl_process *proc, stmt_container *container,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
/*
|
||||||
static int draw_generic_assign(vhdl_process *proc, stmt_container *container,
|
* A non-blocking assignment inside a process. The semantics for
|
||||||
ivl_statement_t stmt, vhdl_expr *after = NULL)
|
* 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);
|
int nlvals = ivl_stmt_lvals(stmt);
|
||||||
if (nlvals != 1) {
|
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
|
// The type here can be null as it is never actually needed
|
||||||
vhdl_var_ref *lval_ref = new vhdl_var_ref(signame, NULL);
|
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)
|
if (after != NULL)
|
||||||
assign->set_after(after);
|
assign->set_after(after);
|
||||||
container->add_stmt(assign);
|
container->add_stmt(assign);
|
||||||
|
|
@ -232,22 +236,47 @@ static int draw_generic_assign(vhdl_process *proc, stmt_container *container,
|
||||||
return 0;
|
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,
|
static int draw_assign(vhdl_process *proc, stmt_container *container,
|
||||||
ivl_statement_t stmt)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -202,6 +202,19 @@ void vhdl_process::add_decl(vhdl_decl* decl)
|
||||||
decls_.push_back(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)
|
void vhdl_process::add_sensitivity(const char *name)
|
||||||
{
|
{
|
||||||
sens_.push_back(name);
|
sens_.push_back(name);
|
||||||
|
|
@ -548,6 +561,14 @@ void vhdl_nbassign_stmt::emit(std::ofstream &of, int level) const
|
||||||
of << ";";
|
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_const_bits::vhdl_const_bits(const char *value, int width)
|
||||||
: vhdl_expr(vhdl_type::nsigned(width))
|
: vhdl_expr(vhdl_type::nsigned(width))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
enum vhdl_wait_type_t {
|
||||||
VHDL_WAIT_INDEF, // Suspend indefinitely
|
VHDL_WAIT_INDEF, // Suspend indefinitely
|
||||||
VHDL_WAIT_FOR_NS, // Wait for a constant number of nanoseconds
|
VHDL_WAIT_FOR_NS, // Wait for a constant number of nanoseconds
|
||||||
|
|
@ -456,6 +465,7 @@ public:
|
||||||
void add_decl(vhdl_decl *decl);
|
void add_decl(vhdl_decl *decl);
|
||||||
void add_sensitivity(const char *name);
|
void add_sensitivity(const char *name);
|
||||||
bool have_declared_var(const std::string &name) const;
|
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; }
|
void set_initial(bool i) { initial_ = i; }
|
||||||
bool is_initial() const { return initial_; }
|
bool is_initial() const { return initial_; }
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -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 vhdl_entity *find_entity_for_signal(ivl_signal_t sig);
|
||||||
const std::string &get_renamed_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 */
|
#endif /* #ifndef INC_VHDL_TARGET_H */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue