[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