tgt-vhdl: Fix expression generation corner case and bug in xnor reduction operator
Certain types of expressions involving only constants would produce
ambiguous VHDL output. Fixed by qualifying one of the arguments. E.g.
('0' or '1') = '1'
Which is ambiguous becomes
(std_logic'('0') or '1') = '1'
This fixes the xnor_test test.
Reduce XNOR was implemented incorrectly because of trivial typo
This commit is contained in:
parent
9a48166855
commit
c81645ff46
|
|
@ -320,6 +320,19 @@ static vhdl_expr *translate_binary(ivl_expr_t e)
|
||||||
int rwidth = rhs->get_type()->get_width();
|
int rwidth = rhs->get_type()->get_width();
|
||||||
int result_width = ivl_expr_width(e);
|
int result_width = ivl_expr_width(e);
|
||||||
|
|
||||||
|
// There's a funny corner-case where both the LHS and RHS are constant
|
||||||
|
// single bit numbers and the VHDL compiler can't decide between the
|
||||||
|
// std_ulogic and bit overloads of various operators
|
||||||
|
const bool lnumber = ivl_expr_type(ivl_expr_oper1(e)) == IVL_EX_NUMBER;
|
||||||
|
const bool rnumber = ivl_expr_type(ivl_expr_oper2(e)) == IVL_EX_NUMBER;
|
||||||
|
if (lwidth == 1 && rwidth == 1 && lnumber && rnumber) {
|
||||||
|
// It's sufficient to qualify only one side
|
||||||
|
vhdl_fcall *lqual = new vhdl_fcall("std_logic'", lhs->get_type());
|
||||||
|
lqual->add_expr(lhs);
|
||||||
|
|
||||||
|
lhs = lqual;
|
||||||
|
}
|
||||||
|
|
||||||
// For === and !== we need to compare std_logic_vectors
|
// For === and !== we need to compare std_logic_vectors
|
||||||
// rather than signeds
|
// rather than signeds
|
||||||
vhdl_type std_logic_vector(VHDL_TYPE_STD_LOGIC_VECTOR, result_width-1, 0);
|
vhdl_type std_logic_vector(VHDL_TYPE_STD_LOGIC_VECTOR, result_width-1, 0);
|
||||||
|
|
|
||||||
|
|
@ -271,7 +271,7 @@ static vhdl_expr *lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm)
|
||||||
case IVL_LPM_RE_XOR:
|
case IVL_LPM_RE_XOR:
|
||||||
return reduction_lpm_to_expr(scope, lpm, SF_REDUCE_XOR, false);
|
return reduction_lpm_to_expr(scope, lpm, SF_REDUCE_XOR, false);
|
||||||
case IVL_LPM_RE_XNOR:
|
case IVL_LPM_RE_XNOR:
|
||||||
return reduction_lpm_to_expr(scope, lpm, SF_REDUCE_XOR, true);
|
return reduction_lpm_to_expr(scope, lpm, SF_REDUCE_XNOR, true);
|
||||||
case IVL_LPM_SIGN_EXT:
|
case IVL_LPM_SIGN_EXT:
|
||||||
return sign_extend_lpm_to_expr(scope, lpm);
|
return sign_extend_lpm_to_expr(scope, lpm);
|
||||||
case IVL_LPM_ARRAY:
|
case IVL_LPM_ARRAY:
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ void support_function::emit(std::ostream &of, int level) const
|
||||||
emit_reduction(of, level, "and", '1');
|
emit_reduction(of, level, "and", '1');
|
||||||
break;
|
break;
|
||||||
case SF_REDUCE_XOR:
|
case SF_REDUCE_XOR:
|
||||||
emit_reduction(of, level, "xnor", '0');
|
emit_reduction(of, level, "xor", '0');
|
||||||
break;
|
break;
|
||||||
case SF_REDUCE_XNOR:
|
case SF_REDUCE_XNOR:
|
||||||
emit_reduction(of, level, "xnor", '0');
|
emit_reduction(of, level, "xnor", '0');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue