[libre-riscv-dev] div/mod algorithm written in python
Jacob Lifshay
programmerjake at gmail.com
Sun Jul 21 21:54:21 BST 2019
making the exponent even is needed for sqrt and rsqrt -- not for div.
otherwise, the DivCore won't know if your trying to sqrt(2) or sqrt(4) and
will end up with an extra/missing factor of sqrt(2).
On Sun, Jul 21, 2019, 13:09 Luke Kenneth Casson Leighton <lkcl at lkcl.net>
wrote:
> jacob, you managed to somehow delete the modifications that i'd made,
> below. i've restored them as they're really important. we can't have
> a chain of OR gates in a sequence: it results in huge gate delay
> chains.
>
yosys can most likely rebalance gate chains (probably using abc) -- it's a
rather trivial optimization. if not, we can manually construct balanced
gate chains, but the way you tried to do it won't work in this instance.
>
> bool() is an operator (supported by yosys) that is specially optimised
> by creating an actual cell that performs a multi-input OR, in an
> extremely gate-efficient fashion. i've used it several times,
> including for a multi-input AND, by negating all the inputs and also
> negating the output.
>
> l.
>
> diff --git a/src/ieee754/div_rem_sqrt_rsqrt/core.py
> b/src/ieee754/div_rem_sqrt_rsqrt/core.py
> index e6a0b9b..da1be3a 100644
> --- a/src/ieee754/div_rem_sqrt_rsqrt/core.py
> +++ b/src/ieee754/div_rem_sqrt_rsqrt/core.py
> @@ -376,16 +376,19 @@ class DivPipeCoreCalculateStage(Elaboratable):
> bit_value ^= pass_flags[j]
> m.d.comb += next_bits.part(i, 1).eq(bit_value)
>
> - next_compare_rhs = 0
> + # XXX using a list to accumulate the bits and then using bool
> + # is IMPORTANT. if done using |= it results in a chain of OR
> gates.
> + l = [] # next_compare_rhs
> for i in range(radix):
> next_flag = pass_flags[i + 1] if i + 1 < radix else 0
> selected = Signal(name=f"selected_{i}", reset_less=True)
> m.d.comb += selected.eq(pass_flags[i] & ~next_flag)
> - next_compare_rhs |= Mux(selected,
> - trial_compare_rhs_values[i],
> - 0)
> + l.append(Mux(selected, trial_compare_rhs_values[i], 0)
> +
> + # concatenate the list of Mux results together and OR them using
> + # the bool operator.
> + m.d.comb += self.o.compare_rhs.eq(Cat(*l).bool())
>
bool can't be used here like this: compare_rhs is a multi-bit value that
needs to be muxed in from all the individual trial_compare_rhs_values --
bool returns a single-bit value
>
> - m.d.comb += self.o.compare_rhs.eq(next_compare_rhs)
> m.d.comb +=
> self.o.root_times_radicand.eq(self.i.root_times_radicand
> +
> ((self.i.divisor_radicand
> * next_bits)
>
did you run the divcore tests? it should fail quite quickly on this
modification.
Jacob
>
More information about the libre-riscv-dev
mailing list