Hi, I am trying to write a simple 8-bit ripple carry adder in Clash as shown in the code below which doesn’t work atm.
As per my understanding, forall n. KnownNat n
puts the type-constraints saying that n
is known at compile time, which is true for all values of n
. So, shouldn’t the rippleCarryAdder as bs cout
work just fine? The call should have n-1
size which should be valid as per the constraints.
Is my understanding correct? What am I missing here?
Thanks in advance
rippleCarryAdder :: forall n . KnownNat n => Vec n Bit -> Vec n Bit -> Bit -> (Vec n Bit, Bit)
rippleCarryAdder Nil Nil cin = (Nil, cin)
rippleCarryAdder (as :< a) (bs :< b) cin =
let
(y, cout) = fullAdder a b cin
(ys, cfinal) = rippleCarryAdder as bs cout
in
(ys :< y, cfinal)
-- 8 bit rippple carry adder
topEntity:: Vec 8 Bit -> Vec 8 Bit -> Bit -> (Vec 8 Bit, Bit)
topEntity= rippleCarryAdder
clashi> :r
[1 of 1] Compiling EightBitAdder ( EightBitAdder.hs, interpreted )
EightBitAdder.hs:28:19: error:
• Couldn't match type ‘n’ with ‘n0 + 1’
Expected: Vec n Bit
Actual: Vec (n0 + 1) Bit
‘n’ is a rigid type variable bound by
the type signature for:
rippleCarryAdder :: forall (n :: Nat).
KnownNat n =>
Vec n Bit -> Vec n Bit -> Bit -> (Vec n Bit, Bit)
at EightBitAdder.hs:26:1-94
• In the pattern: as :< a
In an equation for ‘rippleCarryAdder’:
rippleCarryAdder (as :< a) (bs :< b) cin
= let
(y, cout) = fullAdder a b cin
(ys, cfinal) = rippleCarryAdder as bs cout
in (ys :< y, cfinal)
• Relevant bindings include
rippleCarryAdder :: Vec n Bit
-> Vec n Bit -> Bit -> (Vec n Bit, Bit)
(bound at EightBitAdder.hs:27:1)
|
28 | rippleCarryAdder (as :< a) (bs :< b) cin =
| ^^^^^^^
Failed, no modules loaded.