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:
Nick Gasson 2011-04-06 22:12:16 +01:00 committed by Stephen Williams
parent 9a48166855
commit c81645ff46
3 changed files with 15 additions and 2 deletions

View File

@ -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);

View File

@ -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:

View File

@ -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');