@@ -57,15 +57,15 @@ import Text.Read (readEither)
57
57
import Text.Trifecta.Result hiding (Err )
58
58
59
59
import Clash.Backend
60
- (Backend (.. ), Usage (.. ), AggressiveXOptBB (.. ), RenderEnums (.. ))
60
+ (Backend (.. ), DomainMap , Usage (.. ), AggressiveXOptBB (.. ), RenderEnums (.. ))
61
61
import Clash.Netlist.BlackBox.Parser
62
62
import Clash.Netlist.BlackBox.Types
63
63
import Clash.Netlist.Types
64
64
(BlackBoxContext (.. ), Expr (.. ), HWType (.. ), Literal (.. ), Modifier (.. ),
65
65
Declaration (BlackBoxD ))
66
66
import qualified Clash.Netlist.Id as Id
67
67
import qualified Clash.Netlist.Types as N
68
- import Clash.Netlist.Util (typeSize , isVoid , stripVoid )
68
+ import Clash.Netlist.Util (typeSize , isVoid , stripAttributes , stripVoid )
69
69
import Clash.Signal.Internal
70
70
(ResetKind (.. ), ResetPolarity (.. ), InitBehavior (.. ), VDomainConfiguration (.. ))
71
71
import Clash.Util
@@ -185,10 +185,11 @@ verifyBlackBoxContext bbCtx (N.BBTemplate t) =
185
185
Just n ->
186
186
case indexMaybe (bbInputs bbCtx) n of
187
187
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." )
192
193
193
194
extractLiterals :: BlackBoxContext
194
195
-> [Expr ]
@@ -492,20 +493,20 @@ renderElem b (IF c t f) = do
492
493
syn <- hdlSyn
493
494
enums <- renderEnums
494
495
xOpt <- aggressiveXOptBB
495
- let c' = check (coerce xOpt) iw hdl syn enums c
496
+ c' <- check (coerce xOpt) iw hdl syn enums c
496
497
if c' > 0 then renderTemplate b t else renderTemplate b f
497
498
where
498
- check :: Bool -> Int -> HDL -> HdlSyn -> RenderEnums -> Element -> Int
499
+ check :: Backend backend => Bool -> Int -> HDL -> HdlSyn -> RenderEnums -> Element -> State backend Int
499
500
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
502
503
(Vector n _) -> n
503
504
Void (Just (Vector n _)) -> n
504
505
(MemBlob n _) -> n
505
506
Void (Just (MemBlob n _)) -> n
506
507
_ -> 0 -- HACK: So we can test in splitAt if one of the
507
508
-- 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
509
510
(l,_,_)
510
511
| Literal _ l' <- l ->
511
512
case l' of
@@ -533,16 +534,16 @@ renderElem b (IF c t f) = do
533
534
, [Literal _ (NumLit j)] <- extractLiterals bbCtx
534
535
-> fromInteger j
535
536
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
537
538
(RTree n _) -> n
538
539
_ -> 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
542
543
in case e of
543
544
Identifier _ Nothing -> 1
544
545
_ -> 0
545
- (IsLit n) -> let (e,_,_) = bbInputs b !! n
546
+ (IsLit n) -> pure $ let (e,_,_) = bbInputs b !! n
546
547
in case e of
547
548
DataCon {} -> 1
548
549
Literal {} -> 1
@@ -556,13 +557,13 @@ renderElem b (IF c t f) = do
556
557
RenderEnums True -> 1
557
558
RenderEnums False -> 0
558
559
isScalar _ _ = 0
559
- in isScalar hdl ty
560
+ in pure $ isScalar hdl ty
560
561
561
- (IsUndefined n) ->
562
+ (IsUndefined n) -> pure $
562
563
let (e, _, _) = bbInputs b !! n
563
564
in if xOpt && checkUndefined e then 1 else 0
564
565
565
- (IsActiveEnable n) ->
566
+ (IsActiveEnable n) -> pure $
566
567
let (e, ty, _) = bbInputs b !! n in
567
568
case ty of
568
569
Enable _ ->
@@ -584,52 +585,81 @@ renderElem b (IF c t f) = do
584
585
_ ->
585
586
error $ $ (curLoc) ++ " IsActiveEnable: Expected Bool or Enable, not: " ++ show ty
586
587
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 $
591
593
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 $
617
617
let (e,_,_) = bbInputs b !! n
618
618
in case exprToString e of
619
619
Just t2
620
620
| t1 == Text. pack t2 -> 1
621
621
| otherwise -> 0
622
622
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'
624
626
then 1
625
627
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
629
634
_ -> 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."
630
635
++ " \n Got: " ++ show c'
631
636
renderElem b e = fmap const (renderTag b e)
632
637
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
+
633
663
parseFail :: Text -> BlackBoxTemplate
634
664
parseFail t = case runParse t of
635
665
Failure errInfo ->
0 commit comments