Fully support ternary expressions

This commit is contained in:
Nick Gasson 2008-07-28 12:59:10 +01:00
parent b9cecbef64
commit 78028a3310
3 changed files with 64 additions and 4 deletions

View File

@ -419,9 +419,35 @@ static vhdl_expr *translate_ufunc(ivl_expr_t e)
static vhdl_expr *translate_ternary(ivl_expr_t e)
{
error("Ternary expression only supported as RHS of assignment");
support_function_t sf;
int width = ivl_expr_width(e);
bool issigned = ivl_expr_signed(e) != 0;
if (width == 1)
sf = SF_TERNARY_LOGIC;
else if (issigned)
sf = SF_TERNARY_SIGNED;
else
sf = SF_TERNARY_UNSIGNED;
return NULL;
require_support_function(sf);
vhdl_expr *test = translate_expr(ivl_expr_oper1(e));
vhdl_expr *true_part = translate_expr(ivl_expr_oper2(e));
vhdl_expr *false_part = translate_expr(ivl_expr_oper3(e));
if (!test || !true_part || !false_part)
return NULL;
vhdl_type boolean(VHDL_TYPE_BOOLEAN);
test = test->cast(&boolean);
vhdl_fcall *fcall =
new vhdl_fcall(support_function::function_name(sf),
vhdl_type::type_for(width, issigned));
fcall->add_expr(test);
fcall->add_expr(true_part);
fcall->add_expr(false_part);
return fcall;
}
static vhdl_expr *translate_concat(ivl_expr_t e)

View File

@ -46,6 +46,12 @@ const char *support_function::function_name(support_function_t type)
return "Reduce_AND";
case SF_REDUCE_XOR:
return "Reduce_XOR";
case SF_TERNARY_LOGIC:
return "Ternary_Logic";
case SF_TERNARY_UNSIGNED:
return "Ternary_Unsigned";
case SF_TERNARY_SIGNED:
return "Ternary_Signed";
default:
assert(false);
}
@ -61,12 +67,20 @@ vhdl_type *support_function::function_type(support_function_t type)
case SF_REDUCE_OR:
case SF_REDUCE_AND:
case SF_REDUCE_XOR:
case SF_TERNARY_LOGIC:
return vhdl_type::std_logic();
default:
assert(false);
}
}
void support_function::emit_ternary(std::ostream &of, int level) const
{
of << "begin" << nl_string(indent(level))
<< "if T then return X; else return Y; end if;"
<< nl_string(level);
}
void support_function::emit(std::ostream &of, int level) const
{
of << "function " << function_name(type_);
@ -80,7 +94,7 @@ void support_function::emit(std::ostream &of, int level) const
case SF_SIGNED_TO_BOOLEAN:
of << "(X : signed) return Boolean is" << nl_string(level)
<< "begin" << nl_string(indent(level))
<< "return X /= To_Signed(0, X'Length);" << nl_string (level);
<< "return X /= To_Signed(0, X'Length);" << nl_string(level);
break;
case SF_BOOLEAN_TO_LOGIC:
of << "(B : Boolean) return std_logic is" << nl_string(level)
@ -121,6 +135,21 @@ void support_function::emit(std::ostream &of, int level) const
<< "end loop;" << nl_string(indent(level))
<< "return R;" << nl_string(level);
break;
case SF_TERNARY_LOGIC:
of << "(T : Boolean; X, Y : std_logic) return std_logic is"
<< nl_string(level);
emit_ternary(of, level);
break;
case SF_TERNARY_SIGNED:
of << "(T : Boolean; X, Y : signed) return signed is"
<< nl_string(level);
emit_ternary(of, level);
break;
case SF_TERNARY_UNSIGNED:
of << "(T : Boolean; X, Y : signed) return unsigned is"
<< nl_string(level);
emit_ternary(of, level);
break;
default:
assert(false);
}

View File

@ -24,12 +24,15 @@
#include "vhdl_syntax.hh"
enum support_function_t {
SF_UNSIGNED_TO_BOOLEAN,
SF_UNSIGNED_TO_BOOLEAN = 0,
SF_SIGNED_TO_BOOLEAN,
SF_BOOLEAN_TO_LOGIC,
SF_REDUCE_OR,
SF_REDUCE_AND,
SF_REDUCE_XOR,
SF_TERNARY_LOGIC,
SF_TERNARY_UNSIGNED,
SF_TERNARY_SIGNED,
};
class support_function : public vhdl_function {
@ -42,6 +45,8 @@ public:
static vhdl_type *function_type(support_function_t type);
private:
void emit_ternary(std::ostream &of, int level) const;
support_function_t type_;
};