Merge pull request #1374 from YosysHQ/eddie/fix1371

Fix two non-deterministic behaviours that cause divergence between compilers
This commit is contained in:
Eddie Hung 2019-09-15 13:56:07 -07:00 committed by GitHub
commit 2b93b8fc74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 5 deletions

View File

@ -135,9 +135,11 @@ struct SigPool
} }
}; };
template <typename T, class Compare = std::less<T>> template <typename T, class Compare = void>
struct SigSet struct SigSet
{ {
static_assert(!std::is_same<Compare,void>::value, "Default value for `Compare' class not found for SigSet<T>. Please specify.");
struct bitDef_t : public std::pair<RTLIL::Wire*, int> { struct bitDef_t : public std::pair<RTLIL::Wire*, int> {
bitDef_t() : std::pair<RTLIL::Wire*, int>(NULL, 0) { } bitDef_t() : std::pair<RTLIL::Wire*, int>(NULL, 0) { }
bitDef_t(const RTLIL::SigBit &bit) : std::pair<RTLIL::Wire*, int>(bit.wire, bit.offset) { } bitDef_t(const RTLIL::SigBit &bit) : std::pair<RTLIL::Wire*, int>(bit.wire, bit.offset) { }
@ -220,6 +222,13 @@ struct SigSet
} }
}; };
template<typename T>
class SigSet<T, typename std::enable_if<!std::is_pointer<T>::value>::type> : public SigSet<T, std::less<T>> {};
template<typename T>
using sort_by_name_id_guard = typename std::enable_if<std::is_same<T,RTLIL::Cell*>::value>::type;
template<typename T>
class SigSet<T, sort_by_name_id_guard<T>> : public SigSet<T, RTLIL::sort_by_name_id<typename std::remove_pointer<T>::type>> {};
struct SigMap struct SigMap
{ {
mfp<SigBit> database; mfp<SigBit> database;

View File

@ -48,14 +48,25 @@ struct AlumaccWorker
RTLIL::SigSpec cached_cf, cached_of, cached_sf; RTLIL::SigSpec cached_cf, cached_of, cached_sf;
RTLIL::SigSpec get_lt() { RTLIL::SigSpec get_lt() {
if (GetSize(cached_lt) == 0) if (GetSize(cached_lt) == 0) {
cached_lt = is_signed ? alu_cell->module->Xor(NEW_ID, get_of(), get_sf()) : get_cf(); if (is_signed) {
get_of();
get_sf();
cached_lt = alu_cell->module->Xor(NEW_ID, cached_of, cached_sf);
}
else
cached_lt = get_cf();
}
return cached_lt; return cached_lt;
} }
RTLIL::SigSpec get_gt() { RTLIL::SigSpec get_gt() {
if (GetSize(cached_gt) == 0) if (GetSize(cached_gt) == 0) {
cached_gt = alu_cell->module->Not(NEW_ID, alu_cell->module->Or(NEW_ID, get_lt(), get_eq()), false, alu_cell->get_src_attribute()); get_lt();
get_eq();
SigSpec Or = alu_cell->module->Or(NEW_ID, cached_lt, cached_eq);
cached_gt = alu_cell->module->Not(NEW_ID, Or, false, alu_cell->get_src_attribute());
}
return cached_gt; return cached_gt;
} }