https://github.com/antonblanchard/microwatt/blob/master/countzero.vhdl https://git.libre-soc.org/?p=soc.git;a=blob;f=src/soc/countzero/countzero.py;hb=HEAD to be added to logical pipeline
hm i don't think the count_right functionality is working correctly. it appears to count from the left up to the last 1, i.e. it returns (64-countleftzeros) this is count leading zeros: * cntlzd. RA,RS (Rc=1) n <- 0 do while n < 64 if (RS)[n] = 1 then leave n <- n + 1 RA <- n and this is count trailing zeros: * cnttzd. RA,RS (Rc=1) n <- 0 do while n < 64 if (RS)[63-n] = 0b1 then leave n <- n + 1 RA <- EXTZ64(n) i am inclined to suggest that the entire input be inverted via a mux and that encoder *not* try to do inversion.
i *think* this fixes it: --- a/src/soc/countzero/countzero.py +++ b/src/soc/countzero/countzero.py @@ -53,14 +53,14 @@ class ZeroCounter(Elaboratable): with m.Else(): m.d.comb += ret.eq(3) with m.Else(): - with m.If(v[0]): - m.d.comb += ret.eq(0) - with m.Elif(v[1]): - m.d.comb += ret.eq(1) + with m.If(v[3]): + m.d.comb += ret.eq(3) with m.Elif(v[2]): m.d.comb += ret.eq(2) + with m.Elif(v[1]): + m.d.comb += ret.eq(1) with m.Else(): - m.d.comb += ret.eq(3) + m.d.comb += ret.eq(0) return ret r = IntermediateResult()
tobias i added this in: https://git.libre-soc.org/?p=soc.git;a=blob;f=src/soc/logical/main_stage.py;h=76be8a6404b1648de20f10dc8a933b6c586d5a1c;hb=HEAD next i'll put in a unit test into logical/test_pipe_caller.py
*face-palm* i just realised that countzero is basically a PriorityEncoder https://github.com/m-labs/nmigen/blob/master/nmigen/lib/coding.py and that 90% of countzero.py can disappear as a result (sigh) however it is not *just* a PriorityEncoder: countzero not only changes the end from which it counts (MSB instead of LSB), it changes 32-bit and 64-bit modes as well. i am inclined however to suggest leaving that for now: what this does mean however is that the formal proof is one that revolves around PriorityEncoder more than anything else. i will raise a suitable bugreport for that, now.