Simple bufif cases
This commit is contained in:
parent
6243736481
commit
65720f49fe
|
|
@ -143,6 +143,29 @@ static vhdl_expr *input_to_expr(vhdl_scope *scope, vhdl_unaryop_t op,
|
|||
return new vhdl_unaryop_expr(op, operand, vhdl_type::std_logic());
|
||||
}
|
||||
|
||||
static void bufif_logic(vhdl_arch *arch, ivl_net_logic_t log, bool if0)
|
||||
{
|
||||
ivl_nexus_t output = ivl_logic_pin(log, 0);
|
||||
vhdl_var_ref *lhs = nexus_to_var_ref(arch->get_scope(), output);
|
||||
assert(lhs);
|
||||
|
||||
vhdl_expr *val = nexus_to_expr(arch->get_scope(), ivl_logic_pin(log, 1));
|
||||
assert(val);
|
||||
|
||||
vhdl_expr *sel = nexus_to_expr(arch->get_scope(), ivl_logic_pin(log, 2));
|
||||
assert(val);
|
||||
|
||||
vhdl_expr *on = new vhdl_const_bit(if0 ? '0' : '1');
|
||||
vhdl_expr *cmp = new vhdl_binop_expr(sel, VHDL_BINOP_EQ, on, NULL);
|
||||
|
||||
// TODO: This value needs to depend on the net type
|
||||
vhdl_const_bit *z = new vhdl_const_bit('0');
|
||||
vhdl_cassign_stmt *cass = new vhdl_cassign_stmt(lhs, z);
|
||||
cass->add_condition(val, cmp);
|
||||
|
||||
arch->add_stmt(cass);
|
||||
}
|
||||
|
||||
static vhdl_expr *translate_logic(vhdl_scope *scope, ivl_net_logic_t log)
|
||||
{
|
||||
switch (ivl_logic_type(log)) {
|
||||
|
|
@ -162,7 +185,7 @@ static vhdl_expr *translate_logic(vhdl_scope *scope, ivl_net_logic_t log)
|
|||
case IVL_LO_PULLDOWN:
|
||||
return new vhdl_const_bit('0');
|
||||
default:
|
||||
error("Don't know how to translate logic type = %d",
|
||||
error("Don't know how to translate logic type = %d to expression",
|
||||
ivl_logic_type(log));
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -178,16 +201,26 @@ 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 =
|
||||
dynamic_cast<vhdl_var_ref*>(nexus_to_expr(arch->get_scope(), output));
|
||||
if (NULL == lhs)
|
||||
continue; // Not suitable for continuous assignment
|
||||
|
||||
vhdl_expr *rhs = translate_logic(arch->get_scope(), log);
|
||||
|
||||
arch->add_stmt(new vhdl_cassign_stmt(lhs, rhs));
|
||||
switch (ivl_logic_type(log)) {
|
||||
case IVL_LO_BUFIF0:
|
||||
bufif_logic(arch, log, true);
|
||||
break;
|
||||
case IVL_LO_BUFIF1:
|
||||
bufif_logic(arch, log, false);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
// The output is always pin zero
|
||||
ivl_nexus_t output = ivl_logic_pin(log, 0);
|
||||
vhdl_var_ref *lhs =
|
||||
dynamic_cast<vhdl_var_ref*>(nexus_to_expr(arch->get_scope(), output));
|
||||
if (NULL == lhs)
|
||||
continue; // Not suitable for continuous assignment
|
||||
|
||||
vhdl_expr *rhs = translate_logic(arch->get_scope(), log);
|
||||
arch->add_stmt(new vhdl_cassign_stmt(lhs, rhs));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -649,12 +649,36 @@ vhdl_cassign_stmt::~vhdl_cassign_stmt()
|
|||
{
|
||||
delete lhs_;
|
||||
delete rhs_;
|
||||
|
||||
for (std::list<when_part_t>::const_iterator it = whens_.begin();
|
||||
it != whens_.end();
|
||||
++it) {
|
||||
delete (*it).value;
|
||||
delete (*it).cond;
|
||||
}
|
||||
}
|
||||
|
||||
void vhdl_cassign_stmt::add_condition(vhdl_expr *value, vhdl_expr *cond)
|
||||
{
|
||||
when_part_t when = { value, cond };
|
||||
whens_.push_back(when);
|
||||
}
|
||||
|
||||
void vhdl_cassign_stmt::emit(std::ostream &of, int level) const
|
||||
{
|
||||
lhs_->emit(of, level);
|
||||
of << " <= ";
|
||||
if (!whens_.empty()) {
|
||||
for (std::list<when_part_t>::const_iterator it = whens_.begin();
|
||||
it != whens_.end();
|
||||
++it) {
|
||||
(*it).value->emit(of, level);
|
||||
of << " when ";
|
||||
(*it).cond->emit(of, level);
|
||||
of << " ";
|
||||
}
|
||||
of << "else ";
|
||||
}
|
||||
rhs_->emit(of, level);
|
||||
of << ";";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -216,6 +216,8 @@ typedef std::list<vhdl_conc_stmt*> conc_stmt_list_t;
|
|||
|
||||
/*
|
||||
* A concurrent signal assignment (i.e. not part of a process).
|
||||
* Can have any number of `when' clauses, in which case the original
|
||||
* rhs becomes the `else' part.
|
||||
*/
|
||||
class vhdl_cassign_stmt : public vhdl_conc_stmt {
|
||||
public:
|
||||
|
|
@ -224,9 +226,15 @@ public:
|
|||
~vhdl_cassign_stmt();
|
||||
|
||||
void emit(std::ostream &of, int level) const;
|
||||
void add_condition(vhdl_expr *value, vhdl_expr *cond);
|
||||
private:
|
||||
vhdl_var_ref *lhs_;
|
||||
vhdl_expr *rhs_;
|
||||
|
||||
struct when_part_t {
|
||||
vhdl_expr *value, *cond;
|
||||
};
|
||||
std::list<when_part_t> whens_;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue