Fully support ternary expressions
This commit is contained in:
parent
b9cecbef64
commit
78028a3310
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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_;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue