Thx. I'll catch up with that tomorrow. Refereeing today. I am a little worried that there is a generic fault behind this, though, not just a particular issue. Can you explain what the fault was and what the cure is? I understood neither of them, not speaking more than a few phrases of VHDL.
I'll try. Your code above starts by conditionally scheduling the result (signal, in one delta cycle of future time) as x << y (C notation) provided y>=0, but what does the others =>'X' mean? Is that a variable assignment? Is that else just to write something meaningless and harmless because there has to be an "else" in VHDL so not to bother myself about it?
As a guarded scheduling of a shift left. It would be fine. Was the mistake that shift x y in Clash was translated first to if y>=0 then shiftL x y else shiftR x (-y), and then the shiftL part was translated to just result <= shiftL x y with no guard? Didn't the Clash if then else already translate to if then else in VHDL, thus getting the guard condition in place? So why would even the unguarded shiftL translation lead to a fault? I don't get it. Explanation welcome! It seems to me you just added an extra guard condition when there already was one there.
I replaced the uses of shift in my code with shiftL and shiftR in each instance, as appropriate, even putting in an explicit if then else when I didn't know the sign of the shift at compile time. That cured the original error and I got a lot farther.
The original VHDL translation was valid, by the way! It compiled. It was not correct, overall, but I am not convinced the fault is there. Now I am getting an error
../../src/ieee/v93/numeric_std-body.vhdl:173:5:@0ms:(assertion error): DIV, MOD,
or REM by zero
(this rest of the error spew below is just fluff because the IEE library, after getting -1 for looking for the position of the MSB in 0 and issuing an error notice from an assert statement, carries on and gets the bounds wrong in the rest of the routine ... nuts!)
./testbench:error: index (33) out of bounds (32 downto 0) at ../../src/ieee/v93/
numeric_std-body.vhdl:179
in process .testbench(structural).pipe_result_43@pipe(structural).write_stage_re
sult_3@write_stage(structural).exec_stageb_result_2@exec_stageb(structural).exec
b_result_0@execb(structural).alub_result_125@alub(structural).divsigned.P3
That is at least specific about where the error is from, and I GUARANTEE that it is not exercised neither in the Clash runtime nor in any possible Universe. It is from code for an ALU in Clash:
case alu_cmd of
...
AL_DIV -> runState (alu_div vi) s_
...
I guarantee that guard is not triggered.
The alu_div subroutine itself is not guarded:
alu_div :: Vec 4 Val
-> State ALS (Vec 4 (Maybe Val))
alu_div vi =
do
let (x :> y :> _ ) = vi
(z,o) = divs_c x y
modify (\alu -> alu { ov = o, except = o })
return (Just z :> repeat def)
However, there IS a guard on the int32 division it calls:
divs_c :: KnownNat n
=> Signed n -> Signed n -> (Signed n,Bool)
divs_c x y = (z,o) where (z,o) = if 0 == y || (minBound == x && -1 == y)
then (0, True)
else (x `div` y, False)
Now, AL_DIV is not the alu command in any instruction received on cycle zero (and no instruction at all would have got as far along the pipeline as the stage in which either of the two ALUs are situated - it is ALU(b) that complains - by then!) or later. It appears nowhere in the program executed by the hardware. There is no "mod" either, before you ask!
Furthermore, the actual low level routine DOES have a guard. It should sliently emit zero if it gets told to divide by zero.
I deduce/hypthesize that the circuits involved are being actuated despite the guards on them, on cycle zero, and they are getting zeros on input which in Clash cause nothing to happen because the output of those circuits is ignored and Clash is lazy, so never executes them.
But they are being translated to vhdl that evokes an error condition when they are executed, despite the output being discarded, so the semantics causes an abort, where it does not cause an abort in Clash, so the semantics of the translation differ, and it is not correct.
What do I have to do to work around this? (what you need to do to fix it is up to you :-).
[I think the translation of if then else is at fault. How ... I would need your explanation of what you think was wrong and why you think it is fixed!]
Thx again. I'll pick up the code tomorrow, I hope.
Peter