Add AST elements for unary/binary expressions to model logic gates

This commit is contained in:
Nick Gasson 2008-06-09 14:39:58 +01:00
parent d08f5af9c6
commit aa91186119
3 changed files with 115 additions and 0 deletions

View File

@ -25,6 +25,34 @@
#include <sstream>
#include <cassert>
/*
* Given a nexus and an architecture, find the first signal
* that is connected to the nexus, if there is one.
*/
static vhdl_var_ref *nexus_to_var_ref(vhdl_arch *arch, ivl_nexus_t nexus)
{
int nptrs = ivl_nexus_ptrs(nexus);
for (int i = 0; i < nptrs; i++) {
ivl_nexus_ptr_t nexus_ptr = ivl_nexus_ptr(nexus, i);
ivl_signal_t sig;
if ((sig = ivl_nexus_ptr_sig(nexus_ptr))) {
const char *signame = ivl_signal_basename(sig);
vhdl_decl *decl = arch->get_decl(signame);
assert(decl);
vhdl_type *type = new vhdl_type(*(decl->get_type()));
return new vhdl_var_ref(signame, type);
}
else {
// Ignore other types of nexus pointer
}
}
assert(false);
}
/*
* Translate all the primitive logic gates into concurrent
* signal assignments.
@ -35,6 +63,10 @@ static void declare_logic(vhdl_arch *arch, ivl_scope_t scope)
for (int i = 0; i < nlogs; i++) {
ivl_net_logic_t log = ivl_scope_log(scope, i);
// The output is always pin zero
ivl_nexus_t output = ivl_logic_pin(log, 0);
vhdl_var_ref *lhs = nexus_to_var_ref(arch, output);
switch (ivl_logic_type(log)) {
case IVL_LO_NOT:
break;

View File

@ -455,3 +455,49 @@ void vhdl_cassign_stmt::emit(std::ofstream &of, int level) const
rhs_->emit(of, level);
of << ";";
}
vhdl_unaryop_expr::~vhdl_unaryop_expr()
{
delete operand_;
}
void vhdl_unaryop_expr::emit(std::ofstream &of, int level) const
{
switch (op_) {
case VHDL_UNARYOP_NOT:
of << "not ";
break;
}
operand_->emit(of, level);
}
vhdl_binop_expr::~vhdl_binop_expr()
{
delete left_;
delete right_;
}
void vhdl_binop_expr::emit(std::ofstream &of, int level) const
{
// Expressions are fully parenthesized to remove any
// ambiguity in the output
of << "(";
right_->emit(of, level);
switch (op_) {
case VHDL_BINOP_AND:
of << " and ";
break;
case VHDL_BINOP_OR:
of << " or ";
break;
}
right_->emit(of, level);
of << ")";
}

View File

@ -53,6 +53,43 @@ private:
};
enum vhdl_binop_t {
VHDL_BINOP_AND,
VHDL_BINOP_OR,
};
class vhdl_binop_expr : public vhdl_expr {
public:
vhdl_binop_expr(vhdl_expr *left, vhdl_binop_t op,
vhdl_expr *right, vhdl_type *type)
: vhdl_expr(type), left_(left), right_(right), op_(op) {}
~vhdl_binop_expr();
void emit(std::ofstream &of, int level) const;
private:
vhdl_expr *left_, *right_;
vhdl_binop_t op_;
};
enum vhdl_unaryop_t {
VHDL_UNARYOP_NOT,
};
class vhdl_unaryop_expr : public vhdl_expr {
public:
vhdl_unaryop_expr(vhdl_unaryop_t op, vhdl_expr *operand,
vhdl_type *type)
: vhdl_expr(type), op_(op), operand_(operand) {}
~vhdl_unaryop_expr();
void emit(std::ofstream &of, int level) const;
private:
vhdl_unaryop_t op_;
vhdl_expr *operand_;
};
class vhdl_const_string : public vhdl_expr {
public:
vhdl_const_string(const char *value)