Bit select bug fixes

This commit is contained in:
Nick Gasson 2008-07-07 21:19:59 +01:00
parent 860a74ddd8
commit 4777966b4c
5 changed files with 48 additions and 13 deletions

View File

@ -212,8 +212,12 @@ static vhdl_expr *translate_binary(ivl_expr_t e)
return translate_logical(lhs, rhs, VHDL_BINOP_OR);
case '<':
return translate_relation(lhs, rhs, VHDL_BINOP_LT);
case 'L':
return translate_relation(lhs, rhs, VHDL_BINOP_LEQ);
case '>':
return translate_relation(lhs, rhs, VHDL_BINOP_GT);
case 'G':
return translate_relation(lhs, rhs, VHDL_BINOP_GEQ);
case 'l':
return translate_shift(lhs, rhs, VHDL_BINOP_SL);
case 'r':
@ -231,12 +235,23 @@ static vhdl_expr *translate_binary(ivl_expr_t e)
static vhdl_expr *translate_select(ivl_expr_t e)
{
vhdl_expr *from = translate_expr(ivl_expr_oper1(e));
vhdl_var_ref *from =
dynamic_cast<vhdl_var_ref*>(translate_expr(ivl_expr_oper1(e)));
if (NULL == from)
return NULL;
// Hack: resize it to the correct size
return from->resize(ivl_expr_width(e));
return NULL;
ivl_expr_t o2 = ivl_expr_oper2(e);
if (o2) {
vhdl_expr *base = translate_expr(ivl_expr_oper2(e));
if (NULL == base)
return NULL;
vhdl_type integer(VHDL_TYPE_INTEGER);
from->set_slice(base->cast(&integer), ivl_expr_width(e) - 1);
return from;
}
else
return from->resize(ivl_expr_width(e));
}
static vhdl_type *expr_to_vhdl_type(ivl_expr_t e)

View File

@ -194,9 +194,10 @@ static T *make_vhdl_assignment(vhdl_procedural *proc, stmt_container *container,
// The signal may have been renamed by the above call
signame = get_renamed_signal(sig);
}
// 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_type *ltype =
new vhdl_type(*proc->get_scope()->get_decl(signame)->get_type());
vhdl_var_ref *lval_ref = new vhdl_var_ref(signame.c_str(), ltype);
if (base)
lval_ref->set_slice(base, lval_width-1);

View File

@ -102,8 +102,6 @@ void remember_signal(ivl_signal_t sig, const vhdl_scope *scope)
{
assert(!seen_signal_before(sig));
std::cout << "remember_signal " << ivl_signal_name(sig) << std::endl;
signal_defn_t defn = { ivl_signal_basename(sig), scope };
g_known_signals[sig] = defn;
}

View File

@ -482,6 +482,25 @@ vhdl_var_ref::~vhdl_var_ref()
delete slice_;
}
void vhdl_var_ref::set_slice(vhdl_expr *s, int w)
{
assert(type_);
vhdl_type_name_t tname = type_->get_name();
assert(tname == VHDL_TYPE_UNSIGNED || tname == VHDL_TYPE_SIGNED);
slice_ = s;
slice_width_ = w;
if (type_)
delete type_;
if (w > 0)
type_ = new vhdl_type(tname, w);
else
type_ = vhdl_type::std_logic();
}
void vhdl_var_ref::emit(std::ostream &of, int level) const
{
of << name_;
@ -719,7 +738,7 @@ void vhdl_binop_expr::emit(std::ostream &of, int level) const
while (++it != operands_.end()) {
const char* ops[] = {
"and", "or", "=", "/=", "+", "-", "*", "<",
">", "sll", "srl", "xor", "&"
">", "<=", ">=", "sll", "srl", "xor", "&"
};
of << " " << ops[op_] << " ";

View File

@ -38,7 +38,7 @@ public:
bool constant() const { return isconst_; }
virtual vhdl_expr *cast(const vhdl_type *to);
virtual vhdl_expr *resize(int newwidth);
private:
protected:
vhdl_type *type_;
bool isconst_;
};
@ -56,7 +56,7 @@ public:
void emit(std::ostream &of, int level) const;
const std::string &get_name() const { return name_; }
void set_slice(vhdl_expr *s, int w=0) { slice_ = s; slice_width_ = w; }
void set_slice(vhdl_expr *s, int w=0);
private:
std::string name_;
vhdl_expr *slice_;
@ -74,6 +74,8 @@ enum vhdl_binop_t {
VHDL_BINOP_MULT,
VHDL_BINOP_LT,
VHDL_BINOP_GT,
VHDL_BINOP_LEQ,
VHDL_BINOP_GEQ,
VHDL_BINOP_SL,
VHDL_BINOP_SR,
VHDL_BINOP_XOR,