diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index b4ffa87cd..073921cc4 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -1575,6 +1575,27 @@ value mod_ss(const value &a, const value &b) { return divmod_ss(a, b).second; } +template +CXXRTL_ALWAYS_INLINE +value modfloor_uu(const value &a, const value &b) { + return divmod_uu(a, b).second; +} + +// GHDL Modfloor operator. Returns r=a mod b, such that r has the same sign as b and +// a=b*N+r where N is some integer +// In practical terms, when a and b have different signs and the remainder returned by divmod_ss is not 0 +// then return the remainder + b +template +CXXRTL_ALWAYS_INLINE +value modfloor_ss(const value &a, const value &b) { + value r; + r = divmod_ss(a, b).second; + if((b.is_neg() != a.is_neg()) && !r.is_zero()) + return add_ss(b, r); + return r; +} + + // Memory helper struct memory_index { bool valid; diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 404755b1e..62768bd33 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -185,7 +185,7 @@ bool is_binary_cell(RTLIL::IdString type) ID($and), ID($or), ID($xor), ID($xnor), ID($logic_and), ID($logic_or), ID($shl), ID($sshl), ID($shr), ID($sshr), ID($shift), ID($shiftx), ID($eq), ID($ne), ID($eqx), ID($nex), ID($gt), ID($ge), ID($lt), ID($le), - ID($add), ID($sub), ID($mul), ID($div), ID($mod)); + ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($modfloor)); } bool is_extending_cell(RTLIL::IdString type)