Permalink
Browse files

tgt-vhdl: Fix expression generation corner case and bug in xnor reduc…

…tion 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
  • Loading branch information...
1 parent 9a48166 commit c81645ff46c42cd7a7b6c57a12ee23ce8c28a9e5 @nickg committed with steveicarus Apr 6, 2011
Showing with 15 additions and 2 deletions.
  1. +13 −0 tgt-vhdl/expr.cc
  2. +1 −1 tgt-vhdl/lpm.cc
  3. +1 −1 tgt-vhdl/support.cc
View
@@ -320,6 +320,19 @@ static vhdl_expr *translate_binary(ivl_expr_t e)
int rwidth = rhs->get_type()->get_width();
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
// rather than signeds
vhdl_type std_logic_vector(VHDL_TYPE_STD_LOGIC_VECTOR, result_width-1, 0);
View
@@ -271,7 +271,7 @@ static vhdl_expr *lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm)
case IVL_LPM_RE_XOR:
return reduction_lpm_to_expr(scope, lpm, SF_REDUCE_XOR, false);
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:
return sign_extend_lpm_to_expr(scope, lpm);
case IVL_LPM_ARRAY:
View
@@ -144,7 +144,7 @@ void support_function::emit(std::ostream &of, int level) const
emit_reduction(of, level, "and", '1');
break;
case SF_REDUCE_XOR:
- emit_reduction(of, level, "xnor", '0');
+ emit_reduction(of, level, "xor", '0');
break;
case SF_REDUCE_XNOR:
emit_reduction(of, level, "xnor", '0');

0 comments on commit c81645f

Please sign in to comment.