copilot-bluespec 4.6 → 4.6.1
raw patch · 3 files changed
+76/−8 lines, 3 filesdep +fp-ieeedep ~copilot-coredep ~ieee754PVP ok
version bump matches the API change (PVP)
Dependencies added: fp-ieee
Dependency ranges changed: copilot-core, ieee754
API changes (from Hackage documentation)
Files
- CHANGELOG +5/−0
- copilot-bluespec.cabal +15/−3
- src/Copilot/Compile/Bluespec/Expr.hs +56/−5
CHANGELOG view
@@ -1,3 +1,8 @@+2026-01-07+ * Version bump (4.6.1). (#705)+ * Disable test suite via newly added manual cabal flag. (#673)+ * Fix translation of constant floating-point values. (#696)+ 2025-11-07 * Version bump (4.6). (#679) * Flip direction of interface inputs and outputs in Bluespec. (#677)
copilot-bluespec.cabal view
@@ -1,6 +1,6 @@ cabal-version : >= 1.10 name : copilot-bluespec-version : 4.6+version : 4.6.1 synopsis : A compiler for Copilot targeting FPGAs. description : This package is a back-end from Copilot to FPGAs in Bluespec.@@ -34,6 +34,11 @@ type: git location: https://github.com/Copilot-Language/copilot-bluespec.git +flag test-bluespec+ description: Enable tests that require the Bluespec compiler (bsc)+ default: False+ manual: True+ library default-language : Haskell2010 hs-source-dirs : src@@ -42,10 +47,12 @@ build-depends : base >= 4.9 && < 5 , directory >= 1.3 && < 1.4 , filepath >= 1.4 && < 1.6+ , fp-ieee >= 0.1.0 && < 0.2+ , ieee754 >= 0.8.0 && < 0.9 , pretty >= 1.1.2 && < 1.2 - , copilot-core >= 4.6 && < 4.7- , language-bluespec >= 0.1 && < 0.2+ , copilot-core >= 4.6.1 && < 4.7+ , language-bluespec >= 0.1 && < 0.2 exposed-modules : Copilot.Compile.Bluespec @@ -98,3 +105,8 @@ ghc-options: -Wall++ if flag(test-bluespec)+ buildable: True+ else+ buildable: False
src/Copilot/Compile/Bluespec/Expr.hs view
@@ -17,6 +17,8 @@ import Data.String (IsString (..)) import qualified Language.Bluespec.Classic.AST as BS import qualified Language.Bluespec.Classic.AST.Builtin.Ids as BS+import Numeric.Floating.IEEE.NaN (isSignaling, setPayloadSignaling, setPayload, getPayload)+import GHC.Float (double2Float, castFloatToWord32, castDoubleToWord64) -- Internal imports: Copilot import Copilot.Core@@ -611,14 +613,63 @@ -- | Translate a Copilot floating-point literal into a Bluespec expression. constFP :: Type ty -> Double -> BS.CExpr constFP ty d+ -- Bluespec internally represents all IEEE floating-point values as structs + -- so special symbols have to be called for constructing special values,+ -- e.g. NaN, inf, and -0.0. See+ -- https://github.com/B-Lang-org/bsc/blob/main/src/Libraries/Base3-Math/FloatingPoint.bsv#L441+ | isInfinite d = BS.CApply + (BS.CVar $ BS.mkId BS.NoPos "infinity") + [ if d < 0+ then BS.CCon BS.idTrue [] + else BS.CCon BS.idFalse []+ ]+ + | isNaN d = let + cexpr = BS.CHasType + ( BS.CLit $ BS.CLiteral BS.NoPos $ BS.LInt $+ BS.IntLit Nothing 10 cval+ )+ ( BS.CQType [] $ BS.TCon $ + BS.TyCon + (BS.mkId BS.NoPos ctype) + Nothing + BS.TIabstract+ )+ cval = case ty of + Float -> fromIntegral $ + castFloatToWord32 $ uncastDoubleNaNToFloat d+ Double -> fromIntegral $ + castDoubleToWord64 d+ _ -> impossible "constFP" "copilot-bluespec"+ ctype = case ty of + Float -> "Bit 32"+ Double -> "Bit 64"+ _ -> impossible "constFP" "copilot-bluespec"+ in BS.CApply (BS.CVar $ BS.mkId BS.NoPos "unpack") [cexpr]+ | d == 0 = BS.CApply + (BS.CVar $ BS.mkId BS.NoPos "zero") + [ if isNegativeZero d + then BS.CCon BS.idTrue [] + else BS.CCon BS.idFalse []+ ]+ | d > 0 = withTypeAnnotation ty $ cLit $ BS.LReal d -- Bluespec intentionally does not support negative literal syntax (e.g., -- -42.5), so we must create negative floating-point literals using the -- `negate` function.- | d >= 0 = withTypeAnnotation ty $ cLit $ BS.LReal d- | otherwise = withTypeAnnotation ty $- BS.CApply- (BS.CVar $ BS.idNegateAt BS.NoPos)- [cLit $ BS.LReal $ negate d]+ | otherwise = withTypeAnnotation ty $+ BS.CApply+ (BS.CVar $ BS.idNegateAt BS.NoPos)+ [cLit $ BS.LReal $ negate d]++-- Because NaNs are specially placed as bit-representations by `constfp` and `constfp` requires Doubles as inputs,+-- we need to convert NaN doubles safely into NaN floats. GHC Double2Float does not preserve signal nor payload +-- internals of NaNs so in this case we need a special conversion.+uncastDoubleNaNToFloat :: Double -> Float+uncastDoubleNaNToFloat nan = if (isSignaling nan) + then (setPayloadSignaling payload) + else (setPayload payload)+ where + payload = double2Float $ getPayload nan -- | Create a Bluespec expression consisting of a literal. cLit :: BS.Literal -> BS.CExpr