| Copyright | (C) 2013-2016 University of Twente |
|---|---|
| License | BSD2 (see the file LICENSE) |
| Maintainer | Christiaan Baaij <christiaan.baaij@gmail.com> |
| Safe Haskell | Trustworthy |
| Language | Haskell2010 |
| Extensions |
|
Clash.Sized.Fixed
Contents
Description
Fixed point numbers
- The
Numoperators for the given types saturate on overflow, and use truncation as the rounding method. Fixedhas an instance forFractionalmeaning you use fractional literals(3.75 ::.SFixed4 18)- Both integer literals and fractional literals are clipped to
minBoundandmaxBound. - There is no
Floatinginstance forFixed, but you can use$$(to createfLitd)Fixedpoint literal fromDoubleconstant at compile-time. - Use Constraint synonyms when writing type signatures
for polymorphic functions that use
Fixedpoint numbers.
BEWARE: rounding by truncation introduces a sign bias!
- Truncation for positive numbers effectively results in: round towards zero.
- Truncation for negative numbers effectively results in: round towards -infinity.
Synopsis
- type SFixed = Fixed Signed
- sf :: SNat frac -> Signed (int + frac) -> SFixed int frac
- unSF :: SFixed int frac -> Signed (int + frac)
- type UFixed = Fixed Unsigned
- uf :: SNat frac -> Unsigned (int + frac) -> UFixed int frac
- unUF :: UFixed int frac -> Unsigned (int + frac)
- divide :: DivideC rep int1 frac1 int2 frac2 => Fixed rep int1 frac1 -> Fixed rep int2 frac2 -> Fixed rep ((int1 + frac2) + 1) (int2 + frac1)
- fLit :: forall rep int frac size. (size ~ (int + frac), KnownNat frac, Bounded (rep size), Integral (rep size)) => Double -> Q (TExp (Fixed rep int frac))
- fLitR :: forall rep int frac size. (size ~ (int + frac), KnownNat frac, Bounded (rep size), Integral (rep size)) => Double -> Fixed rep int frac
- newtype Fixed (rep :: Nat -> *) (int :: Nat) (frac :: Nat) = Fixed {}
- resizeF :: forall rep int1 frac1 int2 frac2. ResizeFC rep int1 frac1 int2 frac2 => Fixed rep int1 frac1 -> Fixed rep int2 frac2
- fracShift :: KnownNat frac => Fixed rep int frac -> Int
- type NumSFixedC int frac = (KnownNat ((int + int) + (frac + frac)), KnownNat (frac + frac), KnownNat (int + int), KnownNat (int + frac), KnownNat frac, KnownNat int)
- type ENumSFixedC int1 frac1 int2 frac2 = (KnownNat (int2 + frac2), KnownNat ((1 + Max int1 int2) + Max frac1 frac2), KnownNat (Max frac1 frac2), KnownNat (1 + Max int1 int2), KnownNat (int1 + frac1), KnownNat frac2, KnownNat int2, KnownNat frac1, KnownNat int1)
- type FracSFixedC int frac = (NumSFixedC int frac, KnownNat (((int + frac) + 1) + (int + frac)))
- type ResizeSFC int1 frac1 int2 frac2 = (KnownNat int1, KnownNat frac1, KnownNat int2, KnownNat frac2, KnownNat (int2 + frac2), KnownNat (int1 + frac1))
- type DivideSC int1 frac1 int2 frac2 = (KnownNat (((int1 + frac2) + 1) + (int2 + frac1)), KnownNat frac2, KnownNat int2, KnownNat frac1, KnownNat int1)
- type NumUFixedC int frac = NumSFixedC int frac
- type ENumUFixedC int1 frac1 int2 frac2 = ENumSFixedC int1 frac1 int2 frac2
- type FracUFixedC int frac = FracSFixedC int frac
- type ResizeUFC int1 frac1 int2 frac2 = ResizeSFC int1 frac1 int2 frac2
- type DivideUC int1 frac1 int2 frac2 = DivideSC int1 frac1 int2 frac2
- type NumFixedC rep int frac = (SaturatingNum (rep (int + frac)), ExtendingNum (rep (int + frac)) (rep (int + frac)), MResult (rep (int + frac)) (rep (int + frac)) ~ rep ((int + int) + (frac + frac)), BitSize (rep ((int + int) + (frac + frac))) ~ (int + ((int + frac) + frac)), BitPack (rep ((int + int) + (frac + frac))), Bits (rep ((int + int) + (frac + frac))), KnownNat (BitSize (rep (int + frac))), BitPack (rep (int + frac)), Enum (rep (int + frac)), Bits (rep (int + frac)), Ord (rep (int + frac)), Resize rep, KnownNat int, KnownNat frac)
- type ENumFixedC rep int1 frac1 int2 frac2 = (Bounded (rep ((1 + Max int1 int2) + Max frac1 frac2)), Num (rep ((1 + Max int1 int2) + Max frac1 frac2)), Bits (rep ((1 + Max int1 int2) + Max frac1 frac2)), ExtendingNum (rep (int1 + frac1)) (rep (int2 + frac2)), MResult (rep (int1 + frac1)) (rep (int2 + frac2)) ~ rep ((int1 + int2) + (frac1 + frac2)), KnownNat int1, KnownNat int2, KnownNat frac1, KnownNat frac2, Resize rep)
- type FracFixedC rep int frac = (NumFixedC rep int frac, DivideC rep int frac int frac, Integral (rep (int + frac)), KnownNat int, KnownNat frac)
- type ResizeFC rep int1 frac1 int2 frac2 = (Resize rep, Ord (rep (int1 + frac1)), Num (rep (int1 + frac1)), Bits (rep (int1 + frac1)), Bits (rep (int2 + frac2)), Bounded (rep (int2 + frac2)), KnownNat int1, KnownNat frac1, KnownNat int2, KnownNat frac2)
- type DivideC rep int1 frac1 int2 frac2 = (Resize rep, Integral (rep (((int1 + frac2) + 1) + (int2 + frac1))), Bits (rep (((int1 + frac2) + 1) + (int2 + frac1))), KnownNat int1, KnownNat frac1, KnownNat int2, KnownNat frac2)
- asRepProxy :: Fixed rep int frac -> Proxy rep
- asIntProxy :: Fixed rep int frac -> Proxy int
SFixed: Signed Fixed point numbers
type SFixed = Fixed Signed Source #
Signed Fixed-point number, with int integer bits (including sign-bit)
and frac fractional bits.
- The range
SFixedintfracnumbers is: [-(2^(int-1)) .. 2^(int-1) - 2^-frac] - The resolution of
SFixedintfracnumbers is: 2^frac - The
Numoperators for this type saturate on overflow, and use truncation as the rounding method.
>>>maxBound :: SFixed 3 43.9375>>>minBound :: SFixed 3 4-4.0>>>read (show (maxBound :: SFixed 3 4)) :: SFixed 3 43.9375>>>1 + 2 :: SFixed 3 43.0>>>2 + 3 :: SFixed 3 43.9375>>>(-2) + (-3) :: SFixed 3 4-4.0>>>1.375 * (-0.8125) :: SFixed 3 4-1.125>>>(1.375 :: SFixed 3 4) `mul` (-0.8125 :: SFixed 3 4) :: SFixed 6 8-1.1171875>>>(2 :: SFixed 3 4) `add` (3 :: SFixed 3 4) :: SFixed 4 45.0>>>(-2 :: SFixed 3 4) `add` (-3 :: SFixed 3 4) :: SFixed 4 4-5.0
unSF :: SFixed int frac -> Signed (int + frac) Source #
See the underlying representation of a Signed Fixed-point integer
UFixed: Unsigned Fixed point numbers
type UFixed = Fixed Unsigned Source #
Unsigned Fixed-point number, with int integer bits and frac
fractional bits
- The range
UFixedintfracnumbers is: [0 .. 2^int- 2^-frac] - The resolution of
UFixedintfracnumbers is: 2^frac - The
Numoperators for this type saturate on overflow, and use truncation as the rounding method.
>>>maxBound :: UFixed 3 47.9375>>>minBound :: UFixed 3 40.0>>>1 + 2 :: UFixed 3 43.0>>>2 + 6 :: UFixed 3 47.9375>>>1 - 3 :: UFixed 3 40.0>>>1.375 * 0.8125 :: UFixed 3 41.0625>>>(1.375 :: UFixed 3 4) `mul` (0.8125 :: UFixed 3 4) :: UFixed 6 81.1171875>>>(2 :: UFixed 3 4) `add` (6 :: UFixed 3 4) :: UFixed 4 48.0
However, sub does not saturate to minBound on underflow:
>>>(1 :: UFixed 3 4) `sub` (3 :: UFixed 3 4) :: UFixed 4 414.0
unUF :: UFixed int frac -> Unsigned (int + frac) Source #
See the underlying representation of an Unsigned Fixed-point integer
Division
divide :: DivideC rep int1 frac1 int2 frac2 => Fixed rep int1 frac1 -> Fixed rep int2 frac2 -> Fixed rep ((int1 + frac2) + 1) (int2 + frac1) Source #
Fixed point division
When used in a polymorphic setting, use the following Constraint synonyms for less verbose type signatures:
for:DivideCrep int1 frac1 int2 frac2Fixedrep int1 frac1 ->Fixedrep int2 frac2 ->Fixedrep (int1 + frac2 + 1) (int2 + frac1)for:DivideSCrep int1 frac1 int2 frac2SFixedint1 frac1 ->SFixedint2 frac2 ->SFixed(int1 + frac2 + 1) (int2 + frac1)for:DivideUCrep int1 frac1 int2 frac2UFixedint1 frac1 ->UFixedint2 frac2 ->UFixed(int1 + frac2 + 1) (int2 + frac1)
Compile-time Double conversion
fLit :: forall rep int frac size. (size ~ (int + frac), KnownNat frac, Bounded (rep size), Integral (rep size)) => Double -> Q (TExp (Fixed rep int frac)) Source #
Convert, at compile-time, a Double constant to a Fixed-point literal.
The conversion saturates on overflow, and uses truncation as its rounding
method.
So when you type:
n = $$(fLitpi) ::SFixed4 4
The compiler sees:
n =Fixed(fromInteger 50) ::SFixed4 4
Upon evaluation you see that the value is rounded / truncated in accordance to the fixed point representation:
>>>n3.125
Further examples:
>>>sin 0.5 :: Double0.479425538604203>>>$$(fLit (sin 0.5)) :: SFixed 1 80.4765625>>>atan 0.2 :: Double0.19739555984988078>>>$$(fLit (atan 0.2)) :: SFixed 1 80.1953125>>>$$(fLit (atan 0.2)) :: SFixed 1 200.19739532470703125
Run-time Double conversion (not synthesizable)
fLitR :: forall rep int frac size. (size ~ (int + frac), KnownNat frac, Bounded (rep size), Integral (rep size)) => Double -> Fixed rep int frac Source #
Convert, at run-time, a Double to a Fixed-point.
NB: this functions is not synthesizable
Creating data-files
An example usage of this function is for example to convert a data file
containing Doubles to a data file with ASCI-encoded binary numbers to be
used by a synthesizable function like asyncRomFile.
For example, given a file Data.txt containing:
1.2 2.0 3.0 4.0 -1.0 -2.0 -3.5 -4.0
which we want to put in a ROM, interpreting them as 8.8 signed fixed point
numbers. What we do is that we first create a conversion utility,
createRomFile, which uses fLitR:
createRomFile.hs:
module Main where
import Clash.Prelude
import System.Environment
import qualified Data.List as L
createRomFile
:: KnownNat n
=> (Double -> BitVector n)
-> FilePath
-> FilePath
-> IO ()
createRomFile convert fileR fileW = do
f <- readFile fileR
let ds :: [Double]
ds = L.concat . (L.map . L.map) read . L.map words $ lines f
bvs = L.map (filter (/= '_') . show . convert) ds
writeFile fileW (unlines bvs)
toSFixed8_8 :: Double -> SFixed 8 8
toSFixed8_8 = fLitR
main :: IO ()
main = do
[fileR,fileW] <- getArgs
createRomFile (pack . toSFixed8_8) fileR fileW
We then compile this to an executable:
$ clash --make createRomFile.hs
We can then use this utility to convert our Data.txt file which contains
Doubles to a Data.bin file which will containing the desired ASCI-encoded
binary data:
$ ./createRomFile "Data.txt" "Data.bin"
Which results in a Data.bin file containing:
0000000100110011 0000001000000000 0000001100000000 0000010000000000 1111111100000000 1111111000000000 1111110010000000 1111110000000000
We can then use this Data.bin file in for our ROM:
romF :: Unsigned 3 -> Unsigned 3 -> SFixed 8 8 romF rowAddr colAddr =unpack$asyncRomFiled8 "Data.bin" ((rowAddr * 4) + colAddr)
And see that it works as expected:
>>> romF 1 2 -3.5 >>> romF 0 0 1.19921875
Using Template Haskell
For those of us who like to live on the edge, another option is to convert
our Data.txt at compile-time using
Template Haskell.
For this we first create a module CreateRomFileTH.hs:
module CreateRomFileTH (romDataFromFile) where
import Clash.Prelude
import qualified Data.List as L
import Language.Haskell.TH (ExpQ, litE, stringL)
import Language.Haskell.TH.Syntax (qRunIO)
createRomFile :: KnownNat n => (Double -> BitVector n)
-> FilePath -> FilePath -> IO ()
createRomFile convert fileR fileW = do
f <- readFile fileR
let ds :: [Double]
ds = L.concat . (L.map . L.map) read . L.map words $ lines f
bvs = L.map (filter (/= '_') . show . convert) ds
writeFile fileW (unlines bvs)
romDataFromFile :: KnownNat n => (Double -> BitVector n) -> String -> ExpQ
romDataFromFile convert fileR = do
let fileW = fileR L.++ ".bin"
bvF <- qRunIO (createRomFile convert fileR fileW)
litE (stringL fileW)
Instead of first converting Data.txt to Data.bin, we will now use the
romDataFromFile function to convert Data.txt to a new file in the proper
format at compile-time of our new romF' function:
import Clash.Prelude
import CreateRomFileTH
toSFixed8_8 :: Double -> SFixed 8 8
toSFixed8_8 = fLitR
romF' :: Unsigned 3 -> Unsigned 3 -> SFixed 8 8
romF' rowAddr colAddr = unpack $
asyncRomFile d8
$(romDataFromFile (pack . toSFixed8_8) "Data.txt") -- Template Haskell splice
((rowAddr * 4) + colAddr)
And see that it works just like the romF function from earlier:
>>> romF' 1 2 -3.5 >>> romF' 0 0 1.19921875
Fixed point wrapper
newtype Fixed (rep :: Nat -> *) (int :: Nat) (frac :: Nat) Source #
Fixed-point number
Where:
repis the underlying representationintis the number of bits used to represent the integer partfracis the number of bits used to represent the fractional part
The Num operators for this type saturate to maxBound on overflow and
minBound on underflow, and use truncation as the rounding method.
Instances
| Bounded (rep (int + frac)) => Bounded (Fixed rep int frac) Source # | |
| Enum (rep (int + frac)) => Enum (Fixed rep int frac) Source # | |
Defined in Clash.Sized.Fixed Methods succ :: Fixed rep int frac -> Fixed rep int frac # pred :: Fixed rep int frac -> Fixed rep int frac # toEnum :: Int -> Fixed rep int frac # fromEnum :: Fixed rep int frac -> Int # enumFrom :: Fixed rep int frac -> [Fixed rep int frac] # enumFromThen :: Fixed rep int frac -> Fixed rep int frac -> [Fixed rep int frac] # enumFromTo :: Fixed rep int frac -> Fixed rep int frac -> [Fixed rep int frac] # enumFromThenTo :: Fixed rep int frac -> Fixed rep int frac -> Fixed rep int frac -> [Fixed rep int frac] # | |
| Eq (rep (int + frac)) => Eq (Fixed rep int frac) Source # | |
| FracFixedC rep int frac => Fractional (Fixed rep int frac) Source # | The operators of this instance saturate on overflow, and use truncation as the rounding method. When used in a polymorphic setting, use the following Constraint synonyms for less verbose type signatures:
|
| (Typeable rep, Typeable int, Typeable frac, Data (rep (int + frac))) => Data (Fixed rep int frac) Source # | |
Defined in Clash.Sized.Fixed Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Fixed rep int frac -> c (Fixed rep int frac) # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Fixed rep int frac) # toConstr :: Fixed rep int frac -> Constr # dataTypeOf :: Fixed rep int frac -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (Fixed rep int frac)) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Fixed rep int frac)) # gmapT :: (forall b. Data b => b -> b) -> Fixed rep int frac -> Fixed rep int frac # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Fixed rep int frac -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Fixed rep int frac -> r # gmapQ :: (forall d. Data d => d -> u) -> Fixed rep int frac -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Fixed rep int frac -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Fixed rep int frac -> m (Fixed rep int frac) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Fixed rep int frac -> m (Fixed rep int frac) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Fixed rep int frac -> m (Fixed rep int frac) # | |
| NumFixedC rep int frac => Num (Fixed rep int frac) Source # | The operators of this instance saturate on overflow, and use truncation as the rounding method. When used in a polymorphic setting, use the following Constraint synonyms for less verbose type signatures:
|
Defined in Clash.Sized.Fixed Methods (+) :: Fixed rep int frac -> Fixed rep int frac -> Fixed rep int frac # (-) :: Fixed rep int frac -> Fixed rep int frac -> Fixed rep int frac # (*) :: Fixed rep int frac -> Fixed rep int frac -> Fixed rep int frac # negate :: Fixed rep int frac -> Fixed rep int frac # abs :: Fixed rep int frac -> Fixed rep int frac # signum :: Fixed rep int frac -> Fixed rep int frac # fromInteger :: Integer -> Fixed rep int frac # | |
| Ord (rep (int + frac)) => Ord (Fixed rep int frac) Source # | |
Defined in Clash.Sized.Fixed Methods compare :: Fixed rep int frac -> Fixed rep int frac -> Ordering # (<) :: Fixed rep int frac -> Fixed rep int frac -> Bool # (<=) :: Fixed rep int frac -> Fixed rep int frac -> Bool # (>) :: Fixed rep int frac -> Fixed rep int frac -> Bool # (>=) :: Fixed rep int frac -> Fixed rep int frac -> Bool # max :: Fixed rep int frac -> Fixed rep int frac -> Fixed rep int frac # min :: Fixed rep int frac -> Fixed rep int frac -> Fixed rep int frac # | |
| (size ~ (int + frac), KnownNat frac, Bounded (rep size), Integral (rep size)) => Read (Fixed rep int frac) Source # | None of the |
| (NumFixedC rep int frac, Integral (rep (int + frac))) => Real (Fixed rep int frac) Source # | |
Defined in Clash.Sized.Fixed Methods toRational :: Fixed rep int frac -> Rational # | |
| (FracFixedC rep int frac, NumFixedC rep int frac, Integral (rep (int + frac))) => RealFrac (Fixed rep int frac) Source # | |
Defined in Clash.Sized.Fixed | |
| (size ~ (int + frac), KnownNat frac, Integral (rep size)) => Show (Fixed rep int frac) Source # | |
| (Lift (rep (int + frac)), KnownNat frac, KnownNat int, Typeable rep) => Lift (Fixed rep int frac) Source # | |
| Arbitrary (rep (int + frac)) => Arbitrary (Fixed rep int frac) Source # | |
| CoArbitrary (rep (int + frac)) => CoArbitrary (Fixed rep int frac) Source # | |
Defined in Clash.Sized.Fixed Methods coarbitrary :: Fixed rep int frac -> Gen b -> Gen b # | |
| Bits (rep (int + frac)) => Bits (Fixed rep int frac) Source # | Instance functions do not saturate.
Meaning that " |
Defined in Clash.Sized.Fixed Methods (.&.) :: Fixed rep int frac -> Fixed rep int frac -> Fixed rep int frac # (.|.) :: Fixed rep int frac -> Fixed rep int frac -> Fixed rep int frac # xor :: Fixed rep int frac -> Fixed rep int frac -> Fixed rep int frac # complement :: Fixed rep int frac -> Fixed rep int frac # shift :: Fixed rep int frac -> Int -> Fixed rep int frac # rotate :: Fixed rep int frac -> Int -> Fixed rep int frac # zeroBits :: Fixed rep int frac # bit :: Int -> Fixed rep int frac # setBit :: Fixed rep int frac -> Int -> Fixed rep int frac # clearBit :: Fixed rep int frac -> Int -> Fixed rep int frac # complementBit :: Fixed rep int frac -> Int -> Fixed rep int frac # testBit :: Fixed rep int frac -> Int -> Bool # bitSizeMaybe :: Fixed rep int frac -> Maybe Int # bitSize :: Fixed rep int frac -> Int # isSigned :: Fixed rep int frac -> Bool # shiftL :: Fixed rep int frac -> Int -> Fixed rep int frac # unsafeShiftL :: Fixed rep int frac -> Int -> Fixed rep int frac # shiftR :: Fixed rep int frac -> Int -> Fixed rep int frac # unsafeShiftR :: Fixed rep int frac -> Int -> Fixed rep int frac # rotateL :: Fixed rep int frac -> Int -> Fixed rep int frac # rotateR :: Fixed rep int frac -> Int -> Fixed rep int frac # | |
| FiniteBits (rep (int + frac)) => FiniteBits (Fixed rep int frac) Source # | |
Defined in Clash.Sized.Fixed Methods finiteBitSize :: Fixed rep int frac -> Int # countLeadingZeros :: Fixed rep int frac -> Int # countTrailingZeros :: Fixed rep int frac -> Int # | |
| Default (rep (int + frac)) => Default (Fixed rep int frac) Source # | |
Defined in Clash.Sized.Fixed | |
| NFData (rep (int + frac)) => NFData (Fixed rep int frac) Source # | |
Defined in Clash.Sized.Fixed | |
| NumFixedC rep int frac => SaturatingNum (Fixed rep int frac) Source # | |
Defined in Clash.Sized.Fixed Methods satAdd :: SaturationMode -> Fixed rep int frac -> Fixed rep int frac -> Fixed rep int frac Source # satSub :: SaturationMode -> Fixed rep int frac -> Fixed rep int frac -> Fixed rep int frac Source # satMul :: SaturationMode -> Fixed rep int frac -> Fixed rep int frac -> Fixed rep int frac Source # | |
| NFDataX (rep (int + frac)) => NFDataX (Fixed rep int frac) Source # | |
Defined in Clash.Sized.Fixed | |
| (size ~ (int + frac), KnownNat frac, Integral (rep size)) => ShowX (Fixed rep int frac) Source # | |
| BitPack (rep (int + frac)) => BitPack (Fixed rep int frac) Source # | |
| Bundle (Fixed rep int frac) Source # | |
Defined in Clash.Signal.Bundle | |
| Bundle (Fixed rep int frac) Source # | |
Defined in Clash.Signal.Delayed.Bundle | |
| ENumFixedC rep int1 frac1 int2 frac2 => ExtendingNum (Fixed rep int1 frac1) (Fixed rep int2 frac2) Source # | When used in a polymorphic setting, use the following Constraint synonyms for less verbose type signatures:
|
Defined in Clash.Sized.Fixed Associated Types type AResult (Fixed rep int1 frac1) (Fixed rep int2 frac2) Source # type MResult (Fixed rep int1 frac1) (Fixed rep int2 frac2) Source # Methods add :: Fixed rep int1 frac1 -> Fixed rep int2 frac2 -> AResult (Fixed rep int1 frac1) (Fixed rep int2 frac2) Source # sub :: Fixed rep int1 frac1 -> Fixed rep int2 frac2 -> AResult (Fixed rep int1 frac1) (Fixed rep int2 frac2) Source # mul :: Fixed rep int1 frac1 -> Fixed rep int2 frac2 -> MResult (Fixed rep int1 frac1) (Fixed rep int2 frac2) Source # | |
| type Unbundled dom d (Fixed rep int frac) Source # | |
Defined in Clash.Signal.Delayed.Bundle | |
| type Unbundled dom (Fixed rep int frac) Source # | |
Defined in Clash.Signal.Bundle | |
| type BitSize (Fixed rep int frac) Source # | |
Defined in Clash.Sized.Fixed | |
| type AResult (Fixed rep int1 frac1) (Fixed rep int2 frac2) Source # | |
| type MResult (Fixed rep int1 frac1) (Fixed rep int2 frac2) Source # | |
resizeF :: forall rep int1 frac1 int2 frac2. ResizeFC rep int1 frac1 int2 frac2 => Fixed rep int1 frac1 -> Fixed rep int2 frac2 Source #
Saturating resize operation, truncates for rounding
>>>0.8125 :: SFixed 3 40.8125>>>resizeF (0.8125 :: SFixed 3 4) :: SFixed 2 30.75>>>3.4 :: SFixed 3 43.375>>>resizeF (3.4 :: SFixed 3 4) :: SFixed 2 31.875>>>maxBound :: SFixed 2 31.875
When used in a polymorphic setting, use the following Constraint synonyms for less verbose type signatures:
fracShift :: KnownNat frac => Fixed rep int frac -> Int Source #
Get the position of the virtual point of a Fixed-point number
Constraint synonyms
Writing polymorphic functions over fixed point numbers can be a potentially verbose due to the many class constraints induced by the functions and operators of this module.
Writing a simple multiply-and-accumulate function can already give rise to many lines of constraints:
mac :: (KnownNatfrac ,KnownNat(frac + frac) ,KnownNat(int + frac) ,KnownNat(1 + (int + frac)) ,KnownNat((int + frac) + (int + frac)) , ((int + int) + (frac + frac)) ~ ((int + frac) + (int + frac)) ) =>SFixedint frac ->SFixedint frac ->SFixedint frac ->SFixedint frac mac s x y = s + (x * y)
But with constraint synonyms, you can write the type signature like this:
mac1 ::NumSFixedCint frac =>SFixedint frac ->SFixedint frac ->SFixedint frac ->SFixedint frac mac1 s x y = s + (x * y)
Where NumSFixedC refers to the Constraints needed by the operators of
the Num class for the SFixed datatype.
Although the number of constraints for the mac function defined earlier might
be considered small, here is an "this way lies madness" example where you
really want to use constraint kinds:
mac2 :: (KnownNatfrac1 ,KnownNatfrac2 ,KnownNatfrac3 ,KnownNat(Max frac1 frac2) ,KnownNat(int1 + frac1) ,KnownNat(int2 + frac2) ,KnownNat(int3 + frac3) ,KnownNat(frac1 + frac2) ,KnownNat(Max (frac1 + frac2) frac3) ,KnownNat(((int1 + int2) + (frac1 + frac2)) + (int3 + frac3)) ,KnownNat((int1 + int2) + (frac1 + frac2)) ,KnownNat(1 + Max (int1 + frac1) (int2 + frac2)) ,KnownNat(1 + Max (int1 + int2) int3 + Max (frac1 + frac2) frac3) ,KnownNat((1 + Max int1 int2) + Max frac1 frac2) ,KnownNat((1 + Max ((int1 + int2) + (frac1 + frac2)) (int3 + frac3))) , ((int1 + frac1) + (int2 + frac2)) ~ ((int1 + int2) + (frac1 + frac2)) , (((int1 + int2) + int3) + ((frac1 + frac2) + frac3)) ~ (((int1 + int2) + (frac1 + frac2)) + (int3 + frac3)) ) =>SFixedint1 frac1 ->SFixedint2 frac2 ->SFixedint3 frac3 ->SFixed(1 + Max (int1 + int2) int3) (Max (frac1 + frac2) frac3) mac2 x y s = (x `mul` y) `add` s
Which, with the proper constraint kinds can be reduced to:
mac3 :: (ENumSFixedCint1 frac1 int2 frac2 ,ENumSFixedC(int1 + int2) (frac1 + frac2) int3 frac3 ) =>SFixedint1 frac1 ->SFixedint2 frac2 ->SFixedint3 frac3 ->SFixed(1 + Max (int1 + int2) int3) (Max (frac1 + frac2) frac3) mac3 x y s = (x `mul` y) `add` s
Constraint synonyms for SFixed
type NumSFixedC int frac = (KnownNat ((int + int) + (frac + frac)), KnownNat (frac + frac), KnownNat (int + int), KnownNat (int + frac), KnownNat frac, KnownNat int) Source #
type ENumSFixedC int1 frac1 int2 frac2 = (KnownNat (int2 + frac2), KnownNat ((1 + Max int1 int2) + Max frac1 frac2), KnownNat (Max frac1 frac2), KnownNat (1 + Max int1 int2), KnownNat (int1 + frac1), KnownNat frac2, KnownNat int2, KnownNat frac1, KnownNat int1) Source #
Constraint for the ExtendingNum instance of SFixed
type FracSFixedC int frac = (NumSFixedC int frac, KnownNat (((int + frac) + 1) + (int + frac))) Source #
Constraint for the Fractional instance of SFixed
type ResizeSFC int1 frac1 int2 frac2 = (KnownNat int1, KnownNat frac1, KnownNat int2, KnownNat frac2, KnownNat (int2 + frac2), KnownNat (int1 + frac1)) Source #
type DivideSC int1 frac1 int2 frac2 = (KnownNat (((int1 + frac2) + 1) + (int2 + frac1)), KnownNat frac2, KnownNat int2, KnownNat frac1, KnownNat int1) Source #
Constraint synonyms for UFixed
type NumUFixedC int frac = NumSFixedC int frac Source #
type ENumUFixedC int1 frac1 int2 frac2 = ENumSFixedC int1 frac1 int2 frac2 Source #
Constraint for the ExtendingNum instance of UFixed
type FracUFixedC int frac = FracSFixedC int frac Source #
Constraint for the Fractional instance of UFixed
Constraint synonyms for Fixed wrapper
type NumFixedC rep int frac = (SaturatingNum (rep (int + frac)), ExtendingNum (rep (int + frac)) (rep (int + frac)), MResult (rep (int + frac)) (rep (int + frac)) ~ rep ((int + int) + (frac + frac)), BitSize (rep ((int + int) + (frac + frac))) ~ (int + ((int + frac) + frac)), BitPack (rep ((int + int) + (frac + frac))), Bits (rep ((int + int) + (frac + frac))), KnownNat (BitSize (rep (int + frac))), BitPack (rep (int + frac)), Enum (rep (int + frac)), Bits (rep (int + frac)), Ord (rep (int + frac)), Resize rep, KnownNat int, KnownNat frac) Source #
type ENumFixedC rep int1 frac1 int2 frac2 = (Bounded (rep ((1 + Max int1 int2) + Max frac1 frac2)), Num (rep ((1 + Max int1 int2) + Max frac1 frac2)), Bits (rep ((1 + Max int1 int2) + Max frac1 frac2)), ExtendingNum (rep (int1 + frac1)) (rep (int2 + frac2)), MResult (rep (int1 + frac1)) (rep (int2 + frac2)) ~ rep ((int1 + int2) + (frac1 + frac2)), KnownNat int1, KnownNat int2, KnownNat frac1, KnownNat frac2, Resize rep) Source #
Constraint for the ExtendingNum instance of Fixed
type FracFixedC rep int frac = (NumFixedC rep int frac, DivideC rep int frac int frac, Integral (rep (int + frac)), KnownNat int, KnownNat frac) Source #
Constraint for the Fractional instance of Fixed
type ResizeFC rep int1 frac1 int2 frac2 = (Resize rep, Ord (rep (int1 + frac1)), Num (rep (int1 + frac1)), Bits (rep (int1 + frac1)), Bits (rep (int2 + frac2)), Bounded (rep (int2 + frac2)), KnownNat int1, KnownNat frac1, KnownNat int2, KnownNat frac2) Source #
Constraint for the resizeF function
type DivideC rep int1 frac1 int2 frac2 = (Resize rep, Integral (rep (((int1 + frac2) + 1) + (int2 + frac1))), Bits (rep (((int1 + frac2) + 1) + (int2 + frac1))), KnownNat int1, KnownNat frac1, KnownNat int2, KnownNat frac2) Source #
Constraint for the divide function
Proxy
asRepProxy :: Fixed rep int frac -> Proxy rep Source #