Skip to content

Commit d43460b

Browse files
authored
Merge pull request #2590 from clash-lang/remove-KnownDomain-preparation
Remove KnownDomain preparation
2 parents 6040b05 + 7aaadce commit d43460b

File tree

12 files changed

+134
-91
lines changed

12 files changed

+134
-91
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ADDED: You can now use ~PERIOD, ~ISSYNC, ~ISINITDEFINED and ~ACTIVEEDGE
2+
on arguments of type Clock,Reset,Enable,ClockN and DiffClock.
3+
4+
CHANGED: unsafeToReset and invertReset now have a KnownDomain constraint
5+
This was done in preparation for [Remove KnownDomain #2589](https://github.com/clash-lang/clash-compiler/pull/2589)

clash-cores/src/Clash/Cores/Xilinx/DcFifo/Internal/BlackBoxes.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ dcFifoBBTF DcConfig{..} bbCtx
178178
let domty = DSL.ety knownDomainWrite
179179
in case stripVoid domty of
180180
N.KnownDomain _ _ _ Synchronous _ _ ->
181-
DSL.unsafeToActiveHigh "wr_rst_high" domty wRst
181+
DSL.unsafeToActiveHigh "wr_rst_high" wRst
182182
N.KnownDomain _ _ _ Asynchronous _ _ ->
183183
error $
184184
show 'dcFifoTF <> ": dcFifo only supports synchronous resets"
@@ -190,7 +190,7 @@ dcFifoBBTF DcConfig{..} bbCtx
190190
let domty = DSL.ety knownDomainRead
191191
in case stripVoid domty of
192192
N.KnownDomain _ _ _ Synchronous _ _ ->
193-
DSL.unsafeToActiveHigh "rd_rst_high" domty rRst
193+
DSL.unsafeToActiveHigh "rd_rst_high" rRst
194194
N.KnownDomain _ _ _ Asynchronous _ _ ->
195195
error $
196196
show 'dcFifoTF <> ": dcFifo only supports synchronous resets"

clash-lib/clash-lib.cabal

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,6 @@ executable static-files
359359
docopt ^>= 0.7,
360360
extra,
361361
filepath
362-
Other-Modules: Paths_clash_lib
363362
GHC-Options: -Wall -Wcompat
364363
default-language: Haskell2010
365364
if impl(ghc >= 9.2.0)

clash-lib/prims/commonverilog/Clash_Signal_Internal.primitives.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99
name: Clash.Signal.Internal.unsafeToReset
1010
kind: Expression
1111
type: 'unsafeToReset ::
12-
Signal dom Bool -> Reset dom'
13-
template: ~ARG[0]
12+
KnownDomain dom => Signal dom Bool -> Reset dom'
13+
template: ~ARG[1]
1414
workInfo: Never

clash-lib/prims/vhdl/Clash_Signal_Internal.primitives.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,6 @@
230230
name: Clash.Signal.Internal.unsafeToReset
231231
kind: Declaration
232232
type: 'unsafeToReset ::
233-
Signal dom Bool -> Reset dom'
234-
template: ~RESULT <= '1' when ~ARG[0] = true else '0';
233+
KnownDomain dom => Signal dom Bool -> Reset dom'
234+
template: ~RESULT <= '1' when ~ARG[1] = true else '0';
235235
workInfo: Never

clash-lib/src/Clash/Netlist/BlackBox/Util.hs

Lines changed: 82 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,15 @@ import Text.Read (readEither)
5757
import Text.Trifecta.Result hiding (Err)
5858

5959
import Clash.Backend
60-
(Backend (..), Usage (..), AggressiveXOptBB(..), RenderEnums(..))
60+
(Backend (..), DomainMap, Usage (..), AggressiveXOptBB(..), RenderEnums(..))
6161
import Clash.Netlist.BlackBox.Parser
6262
import Clash.Netlist.BlackBox.Types
6363
import Clash.Netlist.Types
6464
(BlackBoxContext (..), Expr (..), HWType (..), Literal (..), Modifier (..),
6565
Declaration(BlackBoxD))
6666
import qualified Clash.Netlist.Id as Id
6767
import qualified Clash.Netlist.Types as N
68-
import Clash.Netlist.Util (typeSize, isVoid, stripVoid)
68+
import Clash.Netlist.Util (typeSize, isVoid, stripAttributes, stripVoid)
6969
import Clash.Signal.Internal
7070
(ResetKind(..), ResetPolarity(..), InitBehavior(..), VDomainConfiguration (..))
7171
import Clash.Util
@@ -185,10 +185,11 @@ verifyBlackBoxContext bbCtx (N.BBTemplate t) =
185185
Just n ->
186186
case indexMaybe (bbInputs bbCtx) n of
187187
Just _ -> Nothing
188-
Nothing ->
189-
Just ( "Blackbox required at least " ++ show (n+1)
190-
++ " arguments, but only " ++ show (length (bbInputs bbCtx))
191-
++ " were passed." )
188+
Nothing -> do
189+
let str = fromJust (fmap Text.unpack (getAp $ prettyElem e))
190+
Just ( "Blackbox used \"" ++ str ++ "\""
191+
++ ", but only " ++ show (length (bbInputs bbCtx))
192+
++ " arguments were passed." )
192193

193194
extractLiterals :: BlackBoxContext
194195
-> [Expr]
@@ -492,20 +493,20 @@ renderElem b (IF c t f) = do
492493
syn <- hdlSyn
493494
enums <- renderEnums
494495
xOpt <- aggressiveXOptBB
495-
let c' = check (coerce xOpt) iw hdl syn enums c
496+
c' <- check (coerce xOpt) iw hdl syn enums c
496497
if c' > 0 then renderTemplate b t else renderTemplate b f
497498
where
498-
check :: Bool -> Int -> HDL -> HdlSyn -> RenderEnums -> Element -> Int
499+
check :: Backend backend => Bool -> Int -> HDL -> HdlSyn -> RenderEnums -> Element -> State backend Int
499500
check xOpt iw hdl syn enums c' = case c' of
500-
(Size e) -> typeSize (lineToType b [e])
501-
(Length e) -> case lineToType b [e] of
501+
(Size e) -> pure $ typeSize (lineToType b [e])
502+
(Length e) -> pure $ case lineToType b [e] of
502503
(Vector n _) -> n
503504
Void (Just (Vector n _)) -> n
504505
(MemBlob n _) -> n
505506
Void (Just (MemBlob n _)) -> n
506507
_ -> 0 -- HACK: So we can test in splitAt if one of the
507508
-- vectors in the tuple had a zero length
508-
(Lit n) -> case bbInputs b !! n of
509+
(Lit n) -> pure $ case bbInputs b !! n of
509510
(l,_,_)
510511
| Literal _ l' <- l ->
511512
case l' of
@@ -533,16 +534,16 @@ renderElem b (IF c t f) = do
533534
, [Literal _ (NumLit j)] <- extractLiterals bbCtx
534535
-> fromInteger j
535536
k -> error $ $(curLoc) ++ ("IF: LIT must be a numeric lit:" ++ show k)
536-
(Depth e) -> case lineToType b [e] of
537+
(Depth e) -> pure $ case lineToType b [e] of
537538
(RTree n _) -> n
538539
_ -> error $ $(curLoc) ++ "IF: treedepth of non-tree type"
539-
IW64 -> if iw == 64 then 1 else 0
540-
(HdlSyn s) -> if s == syn then 1 else 0
541-
(IsVar n) -> let (e,_,_) = bbInputs b !! n
540+
IW64 -> pure $ if iw == 64 then 1 else 0
541+
(HdlSyn s) -> pure $ if s == syn then 1 else 0
542+
(IsVar n) -> pure $ let (e,_,_) = bbInputs b !! n
542543
in case e of
543544
Identifier _ Nothing -> 1
544545
_ -> 0
545-
(IsLit n) -> let (e,_,_) = bbInputs b !! n
546+
(IsLit n) -> pure $ let (e,_,_) = bbInputs b !! n
546547
in case e of
547548
DataCon {} -> 1
548549
Literal {} -> 1
@@ -556,13 +557,13 @@ renderElem b (IF c t f) = do
556557
RenderEnums True -> 1
557558
RenderEnums False -> 0
558559
isScalar _ _ = 0
559-
in isScalar hdl ty
560+
in pure $ isScalar hdl ty
560561

561-
(IsUndefined n) ->
562+
(IsUndefined n) -> pure $
562563
let (e, _, _) = bbInputs b !! n
563564
in if xOpt && checkUndefined e then 1 else 0
564565

565-
(IsActiveEnable n) ->
566+
(IsActiveEnable n) -> pure $
566567
let (e, ty, _) = bbInputs b !! n in
567568
case ty of
568569
Enable _ ->
@@ -584,52 +585,81 @@ renderElem b (IF c t f) = do
584585
_ ->
585586
error $ $(curLoc) ++ "IsActiveEnable: Expected Bool or Enable, not: " ++ show ty
586587

587-
(ActiveEdge edgeRequested n) ->
588-
let (_, ty, _) = bbInputs b !! n in
589-
case stripVoid ty of
590-
KnownDomain _ _ edgeActual _ _ _ ->
588+
(ActiveEdge edgeRequested n) -> do
589+
let (_, ty, _) = bbInputs b !! n
590+
domConf <- getDomainConf ty
591+
case domConf of
592+
VDomainConfiguration _ _ edgeActual _ _ _ -> pure $
591593
if edgeRequested == edgeActual then 1 else 0
592-
_ ->
593-
error $ $(curLoc) ++ "ActiveEdge: Expected `KnownDomain` or `KnownConfiguration`, not: " ++ show ty
594-
595-
(IsSync n) ->
596-
let (_, ty, _) = bbInputs b !! n in
597-
case stripVoid ty of
598-
KnownDomain _ _ _ Synchronous _ _ -> 1
599-
KnownDomain _ _ _ Asynchronous _ _ -> 0
600-
_ -> error $ $(curLoc) ++ "IsSync: Expected `KnownDomain` or `KnownConfiguration`, not: " ++ show ty
601-
602-
(IsInitDefined n) ->
603-
let (_, ty, _) = bbInputs b !! n in
604-
case stripVoid ty of
605-
KnownDomain _ _ _ _ Defined _ -> 1
606-
KnownDomain _ _ _ _ Unknown _ -> 0
607-
_ -> error $ $(curLoc) ++ "IsInitDefined: Expected `KnownDomain` or `KnownConfiguration`, not: " ++ show ty
608-
609-
(IsActiveHigh n) ->
610-
let (_, ty, _) = bbInputs b !! n in
611-
case stripVoid ty of
612-
KnownDomain _ _ _ _ _ ActiveHigh -> 1
613-
KnownDomain _ _ _ _ _ ActiveLow -> 0
614-
_ -> error $ $(curLoc) ++ "IsActiveHigh: Expected `KnownDomain` or `KnownConfiguration`, not: " ++ show ty
615-
616-
(StrCmp [Text t1] n) ->
594+
595+
(IsSync n) -> do
596+
let (_, ty, _) = bbInputs b !! n
597+
domConf <- getDomainConf ty
598+
case domConf of
599+
VDomainConfiguration _ _ _ Synchronous _ _ -> pure 1
600+
VDomainConfiguration _ _ _ Asynchronous _ _ -> pure 0
601+
602+
(IsInitDefined n) -> do
603+
let (_, ty, _) = bbInputs b !! n
604+
domConf <- getDomainConf ty
605+
case domConf of
606+
VDomainConfiguration _ _ _ _ Defined _ -> pure 1
607+
VDomainConfiguration _ _ _ _ Unknown _ -> pure 0
608+
609+
(IsActiveHigh n) -> do
610+
let (_, ty, _) = bbInputs b !! n
611+
domConf <- getDomainConf ty
612+
case domConf of
613+
VDomainConfiguration _ _ _ _ _ ActiveHigh -> pure 1
614+
VDomainConfiguration _ _ _ _ _ ActiveLow -> pure 0
615+
616+
(StrCmp [Text t1] n) -> pure $
617617
let (e,_,_) = bbInputs b !! n
618618
in case exprToString e of
619619
Just t2
620620
| t1 == Text.pack t2 -> 1
621621
| otherwise -> 0
622622
Nothing -> error $ $(curLoc) ++ "Expected a string literal: " ++ show e
623-
(And es) -> if all (/=0) (map (check xOpt iw hdl syn enums) es)
623+
(And es) -> do
624+
es' <- mapM (check xOpt iw hdl syn enums) es
625+
pure $ if all (/=0) es'
624626
then 1
625627
else 0
626-
CmpLE e1 e2 -> if check xOpt iw hdl syn enums e1 <= check xOpt iw hdl syn enums e2
627-
then 1
628-
else 0
628+
CmpLE e1 e2 -> do
629+
v1 <- check xOpt iw hdl syn enums e1
630+
v2 <- check xOpt iw hdl syn enums e2
631+
if v1 <= v2
632+
then pure 1
633+
else pure 0
629634
_ -> error $ $(curLoc) ++ "IF: condition must be: SIZE, LENGTH, LIT, DEPTH, IW64, VIVADO, OTHERSYN, ISVAR, ISLIT, ISUNDEFINED, ISACTIVEENABLE, ACTIVEEDGE, ISSYNC, ISINITDEFINED, ISACTIVEHIGH, STRCMP, AND, ISSCALAR or CMPLE."
630635
++ "\nGot: " ++ show c'
631636
renderElem b e = fmap const (renderTag b e)
632637

638+
getDomainConf :: (Backend backend, HasCallStack) => HWType -> State backend VDomainConfiguration
639+
getDomainConf = generalGetDomainConf domainConfigurations
640+
641+
generalGetDomainConf
642+
:: forall m. (Monad m, HasCallStack)
643+
=> (m DomainMap) -- ^ a way to get the `DomainMap`
644+
-> HWType -> m VDomainConfiguration
645+
generalGetDomainConf getDomainMap ty = case (snd . stripAttributes . stripVoid) ty of
646+
KnownDomain dom period activeEdge resetKind initBehavior resetPolarity ->
647+
pure $ VDomainConfiguration (Data.Text.unpack dom) (fromIntegral period) activeEdge resetKind initBehavior resetPolarity
648+
649+
Clock dom -> go dom
650+
ClockN dom -> go dom
651+
Reset dom -> go dom
652+
Enable dom -> go dom
653+
Product _DiffClock _ [Clock dom,_clkN] -> go dom
654+
t -> error $ "Don't know how to get a Domain out of HWType: " <> show t
655+
where
656+
go :: HasCallStack => N.DomainName -> m VDomainConfiguration
657+
go dom = do
658+
doms <- getDomainMap
659+
case HashMap.lookup dom doms of
660+
Nothing -> error $ "Can't find domain " <> show dom <> ". Please report an issue at https://github.com/clash-lang/clash-compiler/issues."
661+
Just conf -> pure conf
662+
633663
parseFail :: Text -> BlackBoxTemplate
634664
parseFail t = case runParse t of
635665
Failure errInfo ->

clash-lib/src/Clash/Primitives/DSL.hs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ import Clash.Annotations.Primitive (HDL (..), Primitive (..))
118118
import Clash.Annotations.SynthesisAttributes (Attr)
119119
import Clash.Backend hiding (Usage, fromBV, toBV)
120120
import Clash.Backend.VHDL (VHDLState)
121-
import Clash.Explicit.Signal (ResetPolarity(..))
122-
import Clash.Netlist.BlackBox.Util (exprToString, renderElem)
121+
import Clash.Explicit.Signal (ResetPolarity(..), vResetPolarity)
122+
import Clash.Netlist.BlackBox.Util (exprToString, getDomainConf, renderElem)
123123
import Clash.Netlist.BlackBox.Types
124124
(BlackBoxTemplate, Element(Component, Text), Decl(..))
125125
import qualified Clash.Netlist.Id as Id
@@ -204,6 +204,17 @@ instance Backend backend => HasIdentifierSet (BlockState backend) where
204204
instance HasUsageMap backend => HasUsageMap (BlockState backend) where
205205
usageMap = bsBackend.usageMap
206206

207+
liftToBlockState
208+
:: forall backend a. Backend backend
209+
=> State backend a -> State (BlockState backend) a
210+
liftToBlockState (StateT f) = StateT g
211+
where
212+
g :: BlockState backend -> Identity (a, BlockState backend)
213+
g sbsIn = do
214+
let sIn = _bsBackend sbsIn
215+
(res,sOut) <- f sIn
216+
pure (res, sbsIn{_bsBackend = sOut})
217+
207218
-- | A typed expression.
208219
data TExpr = TExpr
209220
{ ety :: HWType
@@ -1012,32 +1023,26 @@ unsafeToActiveHigh
10121023
:: Backend backend
10131024
=> Text
10141025
-- ^ Name hint
1015-
-> HWType
1016-
-- ^ 'KnownDomain'
10171026
-> TExpr
10181027
-- ^ Reset signal
10191028
-> State (BlockState backend) TExpr
1020-
unsafeToActiveHigh nm dom rExpr =
1021-
case extrResetPolarity dom of
1029+
unsafeToActiveHigh nm rExpr = do
1030+
resetLevel <- vResetPolarity <$> liftToBlockState (getDomainConf (ety rExpr))
1031+
case resetLevel of
10221032
ActiveHigh -> pure rExpr
10231033
ActiveLow -> notExpr nm rExpr
10241034

1025-
extrResetPolarity :: HWType -> ResetPolarity
1026-
extrResetPolarity (Void (Just (KnownDomain _ _ _ _ _ p))) = p
1027-
extrResetPolarity p = error ("Internal error: expected KnownDomain, got: " <> show p)
1028-
10291035
-- | Massage a reset to work as active-low reset.
10301036
unsafeToActiveLow
10311037
:: Backend backend
10321038
=> Text
10331039
-- ^ Name hint
1034-
-> HWType
1035-
-- ^ 'KnownDomain'
10361040
-> TExpr
10371041
-- ^ Reset signal
10381042
-> State (BlockState backend) TExpr
1039-
unsafeToActiveLow nm dom rExpr =
1040-
case extrResetPolarity dom of
1043+
unsafeToActiveLow nm rExpr = do
1044+
resetLevel <- vResetPolarity <$> liftToBlockState (getDomainConf (ety rExpr))
1045+
case resetLevel of
10411046
ActiveLow -> pure rExpr
10421047
ActiveHigh -> notExpr nm rExpr
10431048

clash-lib/src/Clash/Primitives/Intel/ClockGen.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ import qualified Prettyprinter.Interpolate as I
3636
data Variant = Altpll | AlteraPll
3737

3838
hdlUsed :: [Int]
39-
hdlUsed = [ knownDomIn, clk, rst ]
39+
hdlUsed = [ clk, rst ]
4040
where
41-
knownDomIn
41+
_knownDomIn
4242
:< _clocksClass
4343
:< _clocksCxt
4444
:< _numOutClocks
@@ -81,7 +81,7 @@ hdlTemplate ::
8181
BlackBoxContext ->
8282
State s Doc
8383
hdlTemplate variant bbCtx
84-
| [ knownDomIn
84+
| [ _knownDomIn
8585
, _clocksClass
8686
, _clocksCxt
8787
, _numOutClocks
@@ -110,7 +110,7 @@ hdlTemplate variant bbCtx
110110

111111
DSL.declarationReturn bbCtx (stdName variant <> "_block") $ do
112112

113-
rstHigh <- DSL.unsafeToActiveHigh "reset" (DSL.ety knownDomIn) rst
113+
rstHigh <- DSL.unsafeToActiveHigh "reset" rst
114114
pllOuts <- DSL.declareN "pllOut" pllOutTys
115115
locked <- DSL.declare "locked" Bit
116116
pllLock <- DSL.boolFromBit "pllLock" locked

clash-lib/src/Clash/Primitives/Xilinx/ClockGen.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ clockWizardTemplate
6565
-> BlackBoxContext
6666
-> State s Doc
6767
clockWizardTemplate isDifferential bbCtx
68-
| [ knownDomIn
68+
| [ _knownDomIn
6969
, _clocksClass
7070
, _clocksCxt
7171
, _numOutClocks
@@ -79,7 +79,7 @@ clockWizardTemplate isDifferential bbCtx
7979
clkWizInstName <- Id.makeBasic $ fromMaybe "clk_wiz" $ bbCtxName bbCtx
8080
DSL.declarationReturn bbCtx blockName $ do
8181

82-
rstHigh <- DSL.unsafeToActiveHigh "reset" (DSL.ety knownDomIn) rst
82+
rstHigh <- DSL.unsafeToActiveHigh "reset" rst
8383
pllOuts <- DSL.declareN "pllOut" pllOutTys
8484
locked <- DSL.declare "locked" Bit
8585
pllLock <- DSL.boolFromBit "pllLock" locked

clash-prelude/src/Clash/Signal/Internal.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,7 +1279,8 @@ unsafeFromReset (Reset r) = r
12791279
-- __NB__: You probably want to use 'unsafeFromActiveLow' or
12801280
-- 'unsafeFromActiveHigh'.
12811281
unsafeToReset
1282-
:: Signal dom Bool
1282+
:: KnownDomain dom
1283+
=> Signal dom Bool
12831284
-> Reset dom
12841285
unsafeToReset r = Reset r
12851286
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
@@ -1359,7 +1360,7 @@ unsafeFromActiveLow r =
13591360
SActiveLow -> r
13601361

13611362
-- | Invert reset signal
1362-
invertReset :: Reset dom -> Reset dom
1363+
invertReset :: KnownDomain dom => Reset dom -> Reset dom
13631364
invertReset = unsafeToReset . fmap not . unsafeFromReset
13641365

13651366
infixr 2 .||.

0 commit comments

Comments
 (0)