Simple implementation of IVL_EX_SELECT

This commit is contained in:
Nick Gasson 2008-06-21 16:17:44 +01:00
parent 7cba9f3cb2
commit c70fb4ba08
3 changed files with 38 additions and 5 deletions

View File

@ -37,7 +37,7 @@ static vhdl_expr *translate_string(ivl_expr_t e)
* A reference to a signal in an expression. It's assumed that the * A reference to a signal in an expression. It's assumed that the
* signal has already been defined elsewhere. * signal has already been defined elsewhere.
*/ */
static vhdl_expr *translate_signal(ivl_expr_t e) static vhdl_var_ref *translate_signal(ivl_expr_t e)
{ {
ivl_signal_t sig = ivl_expr_signal(e); ivl_signal_t sig = ivl_expr_signal(e);
@ -149,6 +149,8 @@ static vhdl_expr *translate_binary(ivl_expr_t e)
switch (ivl_expr_opcode(e)) { switch (ivl_expr_opcode(e)) {
case '+': case '+':
return translate_numeric(lhs, rhs, VHDL_BINOP_ADD); return translate_numeric(lhs, rhs, VHDL_BINOP_ADD);
case '-':
return translate_numeric(lhs, rhs, VHDL_BINOP_SUB);
case 'e': case 'e':
return translate_relation(lhs, rhs, VHDL_BINOP_EQ); return translate_relation(lhs, rhs, VHDL_BINOP_EQ);
case 'E': case 'E':
@ -186,6 +188,21 @@ static vhdl_expr *translate_binary(ivl_expr_t e)
} }
} }
vhdl_expr *translate_select(ivl_expr_t e)
{
vhdl_expr *from = translate_expr(ivl_expr_oper1(e));
if (NULL == from)
return NULL;
// Hack: resize it to the correct size
vhdl_type *rtype = vhdl_type::nsigned(ivl_expr_width(e));
vhdl_fcall *resize = new vhdl_fcall("Resize", rtype);
resize->add_expr(from);
resize->add_expr(new vhdl_const_int(ivl_expr_width(e)));
return resize;
}
/* /*
* Generate a VHDL expression from a Verilog expression. * Generate a VHDL expression from a Verilog expression.
*/ */
@ -205,6 +222,8 @@ vhdl_expr *translate_expr(ivl_expr_t e)
return translate_unary(e); return translate_unary(e);
case IVL_EX_BINARY: case IVL_EX_BINARY:
return translate_binary(e); return translate_binary(e);
case IVL_EX_SELECT:
return translate_select(e);
default: default:
error("No VHDL translation for expression at %s:%d (type = %d)", error("No VHDL translation for expression at %s:%d (type = %d)",
ivl_expr_file(e), ivl_expr_lineno(e), type); ivl_expr_file(e), ivl_expr_lineno(e), type);

View File

@ -518,9 +518,20 @@ void vhdl_pcall_stmt::emit(std::ofstream &of, int level) const
of << ";"; of << ";";
} }
vhdl_var_ref::~vhdl_var_ref()
{
if (slice_)
delete slice_;
}
void vhdl_var_ref::emit(std::ofstream &of, int level) const void vhdl_var_ref::emit(std::ofstream &of, int level) const
{ {
of << name_; of << name_;
if (slice_) {
of << "(";
slice_->emit(of, level);
of << ")";
}
} }
void vhdl_const_string::emit(std::ofstream &of, int level) const void vhdl_const_string::emit(std::ofstream &of, int level) const

View File

@ -40,17 +40,20 @@ private:
/* /*
* A normal scalar variable reference. * A scalar or array variable reference.
*/ */
class vhdl_var_ref : public vhdl_expr { class vhdl_var_ref : public vhdl_expr {
public: public:
vhdl_var_ref(const char *name, vhdl_type *type) vhdl_var_ref(const char *name, vhdl_type *type,
: vhdl_expr(type), name_(name) {} vhdl_expr *slice = NULL)
: vhdl_expr(type), name_(name), slice_(slice) {}
~vhdl_var_ref();
void emit(std::ofstream &of, int level) const; void emit(std::ofstream &of, int level) const;
const std::string &get_name() const { return name_; } const std::string &get_name() const { return name_; }
private: private:
std::string name_; std::string name_;
vhdl_expr *slice_;
}; };