Skip to content

Commit

Permalink
Don't warn about integer primitives in enum ops
Browse files Browse the repository at this point in the history
To prevent Clash from warning about integer primitives in HDL
that originate from uses of fromEnum / toEnum in user code, the
functions are now primitives for the sized types in Clash.
  • Loading branch information
Alex McKenna authored and martijnbastiaan committed Feb 2, 2022
1 parent 72ed41b commit 22df733
Show file tree
Hide file tree
Showing 18 changed files with 402 additions and 14 deletions.
@@ -0,0 +1 @@
CHANGED: toEnum/fromEnum on sized types is now less eager to report warnings about integer functions being used [#2046](https://github.com/clash-lang/clash-compiler/issues/2046).
76 changes: 75 additions & 1 deletion clash-ghc/src-ghc/Clash/GHC/Evaluator/Primitive.hs
Expand Up @@ -2,7 +2,7 @@
Copyright : (C) 2013-2016, University of Twente,
2016-2017, Myrtle Software Ltd,
2017 , QBayLogic, Google Inc.,
2021 , QBayLogic B.V.
2021-2022, QBayLogic B.V.
License : BSD2 (see the file LICENSE)
Maintainer : QBayLogic B.V. <devops@qbaylogic.com>
-}
Expand Down Expand Up @@ -1929,6 +1929,12 @@ ghcPrimStep tcm isSubj pInfo tys args mach = case primName pInfo of
"Clash.Sized.Internal.BitVector.le##" | [(0,i),(0,j)] <- bitLiterals args
-> reduce (boolToBoolLiteral tcm ty (i <= j))

-- Enum
"Clash.Sized.Internal.BitVector.toEnum##"
| [i] <- intLiterals' args
-> let Bit msk val = BitVector.toEnum## (fromInteger i)
in reduce (mkBitLit ty (toInteger msk) (toInteger val))

-- Bits
"Clash.Sized.Internal.BitVector.and##"
| [i,j] <- bitLiterals args
Expand Down Expand Up @@ -2131,6 +2137,18 @@ ghcPrimStep tcm isSubj pInfo tys args mach = case primName pInfo of
, Just val <- reifyNat kn (liftBitVector2Bool BitVector.le# ty tcm args)
-> reduce val

-- Enum

"Clash.Sized.Internal.BitVector.toEnum#"
| let resTyInfo@(_,_,kn) = extractTySizeInfo tcm ty tys
, Just val <- reifyNat kn (liftInteger2BitVector (BitVector.toEnum# . fromInteger) resTyInfo args)
-> reduce val

"Clash.Sized.Internal.BitVector.fromEnum#"
| Just (_, kn) <- extractKnownNat tcm tys
, Just val <- reifyNat kn (liftBitVector2Int (toInteger . BitVector.fromEnum#) args)
-> reduce val

-- Bounded
"Clash.Sized.Internal.BitVector.minBound#"
| Just (nTy,len) <- extractKnownNat tcm tys
Expand Down Expand Up @@ -2303,6 +2321,16 @@ ghcPrimStep tcm isSubj pInfo tys args mach = case primName pInfo of
| Just (i,j) <- indexLiterals args
-> reduce (boolToBoolLiteral tcm ty (i <= j))

-- Enum
"Clash.Sized.Internal.Index.toEnum#"
| [i] <- intLiterals' args
, Just (nTy, mb) <- extractKnownNat tcm tys
-> reduce (mkIndexLit ty nTy mb i)

"Clash.Sized.Internal.Index.fromEnum#"
| [i] <- indexLiterals' args
-> reduce (integerToIntLiteral i)

-- Bounded
"Clash.Sized.Internal.Index.maxBound#"
| Just (nTy,mb) <- extractKnownNat tcm tys
Expand Down Expand Up @@ -2409,6 +2437,16 @@ ghcPrimStep tcm isSubj pInfo tys args mach = case primName pInfo of
"Clash.Sized.Internal.Signed.le#" | Just (i,j) <- signedLiterals args
-> reduce (boolToBoolLiteral tcm ty (i <= j))

-- Enum
"Clash.Sized.Internal.Signed.toEnum#"
| [i] <- intLiterals' args
, Just (litTy, mb) <- extractKnownNat tcm tys
-> reduce (mkSignedLit ty litTy mb i)

"Clash.Sized.Internal.Signed.fromEnum#"
| [i] <- signedLiterals' args
-> reduce (integerToIntLiteral i)

-- Bounded
"Clash.Sized.Internal.Signed.minBound#"
| Just (litTy,mb) <- extractKnownNat tcm tys
Expand Down Expand Up @@ -2616,6 +2654,16 @@ ghcPrimStep tcm isSubj pInfo tys args mach = case primName pInfo of
"Clash.Sized.Internal.Unsigned.le#" | Just (i,j) <- unsignedLiterals args
-> reduce (boolToBoolLiteral tcm ty (i <= j))

-- Enum
"Clash.Sized.Internal.Unsigned.toEnum#"
| [i] <- intLiterals' args
, Just (litTy, mb) <- extractKnownNat tcm tys
-> reduce (mkUnsignedLit ty litTy mb i)

"Clash.Sized.Internal.Unsigned.fromEnum#"
| [i] <- unsignedLiterals' args
-> reduce (integerToIntLiteral i)

-- Bounded
"Clash.Sized.Internal.Unsigned.minBound#"
| Just (nTy,len) <- extractKnownNat tcm tys
Expand Down Expand Up @@ -4403,6 +4451,32 @@ liftBitVector2Bool f ty tcm args _p
in Just $ boolToBoolLiteral tcm ty val
| otherwise = Nothing

liftInteger2BitVector
:: KnownNat n
=> (Integer -> BitVector n)
-> (Type, Type, Integer)
-> [Value]
-> (Proxy n -> Maybe Term)
liftInteger2BitVector f resTyInfo args _p
| [i] <- intLiterals' args
= let BV msk val = f i
in Just (mkBitVectorLit' resTyInfo (toInteger msk) (toInteger val))

| otherwise
= Nothing

liftBitVector2Int
:: KnownNat n
=> (BitVector n -> Integer)
-> [Value]
-> (Proxy n -> Maybe Term)
liftBitVector2Int f args _p
| [i] <- bitVectorLiterals' args
= let val = f (toBV i)
in Just $ integerToIntLiteral val
| otherwise
= Nothing

liftSized2 :: (KnownNat n, Integral (sized n))
=> ([Value] -> [Integer])
-- ^ literal argument extraction function
Expand Down
Expand Up @@ -91,6 +91,14 @@
, "template" : "~VAR[i][0][0] ? 1'bx : ~VAR[i][1][0]"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.BitVector.toEnum##"
, "workInfo" : "Never"
, "kind" : "Expression"
, "type" : "toEnum## :: Int -> Bit"
, "template" : "~ARG[0][0]"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.BitVector.and##"
, "kind" : "Expression"
Expand Down Expand Up @@ -167,6 +175,13 @@
, "templateFunction" : "Clash.Primitives.Sized.ToInteger.bvToIntegerVerilog"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.BitVector.fromEnum#"
, "workInfo" : "Never"
, "kind" : "Expression"
, "type" : "fromEnum# :: KnownNat n => BitVector n -> Int"
, "template" : "~IF~SIZE[~TYP[1]]~THEN~IF~CMPLE[~SIZE[~TYPO]][~SIZE[~TYP[1]]]~THEN$unsigned(~VAR[bv][1][0+:~SIZE[~TYPO]])~ELSE$unsigned({{(~SIZE[~TYPO]-~SIZE[~TYP[1]]) {1'b0}},~VAR[bv][1]})~FI~ELSE~SIZE[~TYPO]'sd0~FI" }
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.BitVector.size#"
, "workInfo" : "Constant"
Expand Down Expand Up @@ -287,6 +302,14 @@
, "template" : "~IF~CMPLE[~SIZE[~TYPO]][~SIZE[~TYP[2]]]~THEN$unsigned(~VAR[i][2][0+:~SIZE[~TYPO]])~ELSE$unsigned({{(~SIZE[~TYPO]-~SIZE[~TYP[2]]) {1'b0}},~VAR[i][2]})~FI"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.BitVector.toEnum#"
, "workInfo" : "Never"
, "kind" : "Expression"
, "type" : "toEnum# :: KnownNat n => Int -> BitVector n"
, "template" : "~IF~CMPLE[~SIZE[~TYPO]][~SIZE[~TYP[1]]]~THEN$unsigned(~VAR[i][1][0+:~SIZE[~TYPO]])~ELSE$unsigned({{(~SIZE[~TYPO]-~SIZE[~TYP[1]]) {1'b0}},~VAR[i][1]})~FI"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.BitVector.plus#"
, "kind" : "Declaration"
Expand Down
Expand Up @@ -64,6 +64,22 @@
, "template" : "~ARG[0]-~SIZE[~TYPO]'d1"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.Index.fromEnum#"
, "workInfo" : "Never"
, "kind" : "Expression"
, "type" : "fromEnum# :: KnownNat n => Index n -> Int"
, "template" : "~IF~SIZE[~TYP[1]]~THEN~IF~CMPLE[~SIZE[~TYPO]][~SIZE[~TYP[1]]]~THEN$unsigned(~VAR[i][1][0+:~SIZE[~TYPO]])~ELSE$unsigned({{(~SIZE[~TYPO]-~SIZE[~TYP[1]]) {1'b0}},~VAR[i][1]})~FI~ELSE~SIZE[~TYPO]'sd0~FI"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.Index.toEnum#"
, "workInfo" : "Never"
, "kind" : "Expression"
, "type" : "toEnum# :: KnownNat n => Int -> Index n"
, "template" : "~IF~CMPLE[~SIZE[~TYPO]][~SIZE[~TYP[1]]]~THEN$unsigned(~VAR[i][1][0+:~SIZE[~TYPO]])~ELSE$unsigned({{(~SIZE[~TYPO]-~SIZE[~TYP[1]]) {1'b0}},~VAR[i][1]})~FI"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.Index.+#"
, "kind" : "Expression"
Expand Down
Expand Up @@ -46,6 +46,14 @@
, "templateFunction" : "Clash.Primitives.Sized.ToInteger.signedToIntegerVerilog"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.Signed.fromEnum#"
, "workInfo" : "Never"
, "kind" : "Expression"
, "type" : "fromEnum# :: KnownNat n => Signed n -> Int"
, "template" : "~IF~SIZE[~TYP[1]]~THEN~IF~CMPLE[~SIZE[~TYPO]][~SIZE[~TYP[1]]]~THEN$signed(~VAR[i][1][0+:~SIZE[~TYPO]])~ELSE$signed({{(~SIZE[~TYPO]-~SIZE[~TYP[1]]) {1'b0}},~VAR[i][1]})~FI~ELSE~SIZE[~TYPO]'sd0~FI"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.Signed.size#"
, "workInfo" : "Constant"
Expand Down Expand Up @@ -117,6 +125,14 @@
, "template" : "~IF~CMPLE[~SIZE[~TYPO]][~SIZE[~TYP[1]]]~THEN$signed(~VAR[i][1][0+:~SIZE[~TYPO]])~ELSE$signed({{(~SIZE[~TYPO]-~SIZE[~TYP[1]]) {1'b0}},~VAR[i][1]})~FI"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.Signed.toEnum#"
, "workInfo" : "Never"
, "kind" : "Expression"
, "type" : "toEnum# :: KnownNat n => Int -> Signed n"
, "template" : "~IF~CMPLE[~SIZE[~TYPO]][~SIZE[~TYP[1]]]~THEN$signed(~VAR[i][1][0+:~SIZE[~TYPO]])~ELSE$signed({{(~SIZE[~TYPO]-~SIZE[~TYP[1]]) {1'b0}},~VAR[i][1]})~FI"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.Signed.plus#"
, "kind" : "Declaration"
Expand Down
Expand Up @@ -46,6 +46,14 @@
, "templateFunction" : "Clash.Primitives.Sized.ToInteger.unsignedToIntegerVerilog"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.Unsigned.fromEnum#"
, "workInfo" : "Never"
, "kind" : "Expression"
, "type" : "fromEnum# :: KnownNat n => Unsigned n -> Int"
, "template" : "~IF~SIZE[~TYP[1]]~THEN~IF~CMPLE[~SIZE[~TYPO]][~SIZE[~TYP[1]]]~THEN$unsigned(~VAR[i][1][0+:~SIZE[~TYPO]])~ELSE$unsigned({{(~SIZE[~TYPO]-~SIZE[~TYP[1]]) {1'b0}},~VAR[i][1]})~FI~ELSE~SIZE[~TYPO]'sd0~FI"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.Unsigned.size#"
, "workInfo" : "Constant"
Expand Down Expand Up @@ -108,6 +116,14 @@
, "template" : "~IF~CMPLE[~SIZE[~TYPO]][~SIZE[~TYP[1]]]~THEN$unsigned(~VAR[i][1][0+:~SIZE[~TYPO]])~ELSE$unsigned({{(~SIZE[~TYPO]-~SIZE[~TYP[1]]) {1'b0}},~VAR[i][1]})~FI"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.Unsigned.toEnum#"
, "workInfo" : "Never"
, "kind" : "Expression"
, "type" : "toEnum# :: KnownNat n => Int -> Unsigned n"
, "template" : "~IF~CMPLE[~SIZE[~TYPO]][~SIZE[~TYP[1]]]~THEN$unsigned(~VAR[i][1][0+:~SIZE[~TYPO]])~ELSE$unsigned({{(~SIZE[~TYPO]-~SIZE[~TYP[1]]) {1'b0}},~VAR[i][1]})~FI"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.Unsigned.plus#"
, "kind" : "Declaration"
Expand Down
24 changes: 24 additions & 0 deletions clash-lib/prims/vhdl/Clash_Sized_Internal_BitVector.primitives
Expand Up @@ -86,6 +86,14 @@
, "template" : "~IF~LIT[0]~THEN'U'~ELSE~ARG[1](0)~FI"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.BitVector.toEnum##"
, "workInfo" : "Never"
, "kind" : "Expression"
, "type" : "toEnum## :: Int -> Bit"
, "template" : "~ARG[0](0)"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.BitVector.and##"
, "kind" : "Expression"
Expand Down Expand Up @@ -457,6 +465,22 @@ end process;
, "template" : "std_logic_vector(resize(unsigned(std_logic_vector(~ARG[2])),~SIZE[~TYPO]))"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.BitVector.toEnum#"
, "workInfo" : "Never"
, "kind" : "Expression"
, "type" : "toEnum# :: KnownNat n => Int -> BitVector n"
, "template" : "std_logic_vector(resize(unsigned(std_logic_vector(~ARG[1])),~SIZE[~TYPO]))"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.BitVector.fromEnum#"
, "workInfo" : "Never"
, "kind" : "Expression"
, "type" : "fromEnum# :: KnownNat n => BitVector n -> Int"
, "template" : "~IF~SIZE[~TYP[1]]~THENsigned(std_logic_vector(resize(unsigned(~ARG[1]),~SIZE[~TYPO])))~ELSEto_signed(0,~SIZE[~TYPO])~FI"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.BitVector.plus#"
, "kind" : "Expression"
Expand Down
16 changes: 16 additions & 0 deletions clash-lib/prims/vhdl/Clash_Sized_Internal_Index.primitives
Expand Up @@ -64,6 +64,22 @@
, "template" : "to_unsigned(~LIT[0]-1,~SIZE[~TYPO])"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.Index.toEnum#"
, "workInfo" : "Never"
, "kind" : "Expression"
, "type" : "toEnum# :: KnownNat n => Int -> Index n"
, "template" : "resize(unsigned(std_logic_vector(~ARG[1])),~SIZE[~TYPO])"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.Index.fromEnum#"
, "workInfo" : "Never"
, "kind" : "Expression"
, "type" : "fromEnum# :: KnownNat n => Index n -> Int"
, "template" : "~IF~SIZE[~TYP[1]]~THENsigned(std_logic_vector(resize(~ARG[1],~SIZE[~TYPO])))~ELSEto_signed(0,~SIZE[~TYPO])~FI"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.Index.+#"
, "kind" : "Expression"
Expand Down
16 changes: 16 additions & 0 deletions clash-lib/prims/vhdl/Clash_Sized_Internal_Signed.primitives
Expand Up @@ -112,6 +112,22 @@
, "templateFunction" : "Clash.Primitives.Sized.Signed.fromIntegerTF"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.Signed.toEnum#"
, "workInfo" : "Never"
, "kind" : "Expression"
, "type" : "toEnum# :: KnownNat n => Int -> Signed n"
, "template" : "resize(signed(std_logic_vector(~ARG[1])),~SIZE[~TYPO])"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.Signed.fromEnum#"
, "workInfo" : "Never"
, "kind" : "Expression"
, "type" : "fromEnum# :: KnownNat n => Signed n -> Int"
, "template" : "~IF~SIZE[~TYP[1]]~THENresize(~ARG[1],~SIZE[~TYPO])~ELSEto_signed(0,~SIZE[~TYPO])~FI"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.Signed.plus#"
, "kind" : "Expression"
Expand Down
16 changes: 16 additions & 0 deletions clash-lib/prims/vhdl/Clash_Sized_Internal_Unsigned.primitives
Expand Up @@ -102,6 +102,22 @@
, "template" : "resize(unsigned(std_logic_vector(~ARG[1])),~LIT[0])"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.Unsigned.toEnum#"
, "workInfo" : "Never"
, "kind" : "Expression"
, "type" : "toEnum# :: KnownNat n => Int -> Unsigned n"
, "template" : "resize(unsigned(std_logic_vector(~ARG[1])),~SIZE[~TYPO])"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.Unsigned.fromEnum#"
, "workInfo" : "Never"
, "kind" : "Expression"
, "type" : "fromEnum# :: KnownNat n => Unsigned n -> Int"
, "template" : "~IF~SIZE[~TYP[1]]~THENsigned(std_logic_vector(resize(~ARG[1],~SIZE[~TYPO])))~ELSEto_signed(0,~SIZE[~TYPO])~FI"
}
}
, { "BlackBox" :
{ "name" : "Clash.Sized.Internal.Unsigned.plus#"
, "kind" : "Expression"
Expand Down

0 comments on commit 22df733

Please sign in to comment.