Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unsafe{From,To}Active{Low,High} #2540

Merged
merged 2 commits into from Jul 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion changelog/2022-07-26T13_16_31-05_00_reset_polarity_dsl
@@ -1 +1 @@
INTERNAL NEW: Added `unsafeToHighPolarity` and `unsafeToLowPolarity` to `Clash.Primitives.DSL`. [#2270](https://github.com/clash-lang/clash-compiler/pull/2270)
INTERNAL NEW: Added `unsafeToActiveHigh` and `unsafeToActiveLow` to `Clash.Primitives.DSL`. [#2270](https://github.com/clash-lang/clash-compiler/pull/2270)
1 change: 1 addition & 0 deletions changelog/2023-07-13T14_49_23+02_00_rename_from_polarity
@@ -0,0 +1 @@
DEPRECATED: `unsafeFromLowPolarity`, `unsafeFromHighPolarity`, `unsafeToLowPolarity`, `unsafeToHighPolarity` have been replaced by `unsafeFromActiveLow`, `unsafeFromActiveHigh`, `unsafeToActiveLow`, `unsafeToActiveHigh`. While former ones will continue to exist, a deprecation warning has been added pointing to the latter ones.
4 changes: 2 additions & 2 deletions clash-cores/src/Clash/Cores/Xilinx/DcFifo.hs
Expand Up @@ -177,8 +177,8 @@ dcFifo DcConfig{..} wClk wRst rClk rRst writeData rEnable =
_ -> error $ show 'dcFifo <> " only supports synchronous resets"

where
rstSignalR = unsafeToHighPolarity rRst
rstSignalW = unsafeToHighPolarity wRst
rstSignalR = unsafeToActiveHigh rRst
rstSignalW = unsafeToActiveHigh wRst

fifoSize = natToNum @(2 ^ depth - 1) @Int
dataCount = fromIntegral . Seq.length
Expand Down
Expand Up @@ -178,7 +178,7 @@ dcFifoBBTF DcConfig{..} bbCtx
let domty = DSL.ety knownDomainWrite
in case stripVoid domty of
N.KnownDomain _ _ _ Synchronous _ _ ->
DSL.unsafeToHighPolarity "wr_rst_high" domty wRst
DSL.unsafeToActiveHigh "wr_rst_high" domty wRst
N.KnownDomain _ _ _ Asynchronous _ _ ->
error $
show 'dcFifoTF <> ": dcFifo only supports synchronous resets"
Expand All @@ -190,7 +190,7 @@ dcFifoBBTF DcConfig{..} bbCtx
let domty = DSL.ety knownDomainRead
in case stripVoid domty of
N.KnownDomain _ _ _ Synchronous _ _ ->
DSL.unsafeToHighPolarity "rd_rst_high" domty rRst
DSL.unsafeToActiveHigh "rd_rst_high" domty rRst
N.KnownDomain _ _ _ Asynchronous _ _ ->
error $
show 'dcFifoTF <> ": dcFifo only supports synchronous resets"
Expand Down
6 changes: 3 additions & 3 deletions clash-cores/test/Test/Cores/Xilinx/DcFifo.hs
Expand Up @@ -260,7 +260,7 @@ testOverflow = testCase "Overflows appropriately" $ do

fifo = dcFifo @4 defConfig{dcOverflow = True} clk noRst clk noRst
clk = clockGen @D3
noRst = unsafeFromHighPolarity $ pure False
noRst = unsafeFromActiveHigh $ pure False
drive15 = mealy clk noRst enableGen go 15 (pure ())
go 0 _ = (0 :: Int, Nothing)
go n _ = (n-1, Just (1 :: Int))
Expand Down Expand Up @@ -361,11 +361,11 @@ throughFifo d _ _ feed drain wrDataList rdStalls = rdDataList
where

wrClk = clockGen @write
noWrRst = unsafeFromHighPolarity $ pure False
noWrRst = unsafeFromActiveHigh $ pure False
wrEna = enableGen @write

rdClk = clockGen @read
noRdRst = unsafeFromHighPolarity $ pure False
noRdRst = unsafeFromActiveHigh $ pure False
rdEna = enableGen @read

wrData =
Expand Down
12 changes: 6 additions & 6 deletions clash-lib/src/Clash/Primitives/DSL.hs
Expand Up @@ -76,8 +76,8 @@ module Clash.Primitives.DSL
, unsignedFromBitVector
, boolFromBits

, unsafeToHighPolarity
, unsafeToLowPolarity
, unsafeToActiveHigh
, unsafeToActiveLow

-- ** Operations
, andExpr
Expand Down Expand Up @@ -988,7 +988,7 @@ andExpr nm a b = do
assign nm $ TExpr Bool (Identifier (Id.unsafeMake andTxt) Nothing)

-- | Massage a reset to work as active-high reset.
unsafeToHighPolarity
unsafeToActiveHigh
:: Backend backend
=> Text
-- ^ Name hint
Expand All @@ -997,7 +997,7 @@ unsafeToHighPolarity
-> TExpr
-- ^ Reset signal
-> State (BlockState backend) TExpr
unsafeToHighPolarity nm dom rExpr =
unsafeToActiveHigh nm dom rExpr =
case extrResetPolarity dom of
ActiveHigh -> pure rExpr
ActiveLow -> notExpr nm rExpr
Expand All @@ -1007,7 +1007,7 @@ extrResetPolarity (Void (Just (KnownDomain _ _ _ _ _ p))) = p
extrResetPolarity p = error ("Internal error: expected KnownDomain, got: " <> show p)

-- | Massage a reset to work as active-low reset.
unsafeToLowPolarity
unsafeToActiveLow
:: Backend backend
=> Text
-- ^ Name hint
Expand All @@ -1016,7 +1016,7 @@ unsafeToLowPolarity
-> TExpr
-- ^ Reset signal
-> State (BlockState backend) TExpr
unsafeToLowPolarity nm dom rExpr =
unsafeToActiveLow nm dom rExpr =
case extrResetPolarity dom of
ActiveLow -> pure rExpr
ActiveHigh -> notExpr nm rExpr
Expand Down
2 changes: 1 addition & 1 deletion clash-lib/src/Clash/Primitives/Xilinx/ClockGen.hs
Expand Up @@ -64,7 +64,7 @@ clockWizardDifferentialTemplate bbCtx
clkWizInstName <- Id.makeBasic "clockWizardDifferential_inst"
DSL.declarationReturn bbCtx "clockWizardDifferential" $ do

rstHigh <- DSL.unsafeToHighPolarity "reset" (DSL.ety knownDomIn) rst
rstHigh <- DSL.unsafeToActiveHigh "reset" (DSL.ety knownDomIn) rst
pllOut <- DSL.declare "pllOut" Bit
locked <- DSL.declare "locked" Bit
pllLock <- DSL.boolFromBit "pllLock" locked
Expand Down
8 changes: 4 additions & 4 deletions clash-prelude/src/Clash/Annotations/TopEntity.hs
Expand Up @@ -84,8 +84,8 @@ topEntity clk20 rstBtn enaBtn modeBtn =

-- Signal coming from the reset button is low when pressed, and high when
-- not pressed. We convert this signal to the polarity of our domain with
-- /unsafeFromLowPolarity/.
rst = 'Clash.Signal.unsafeFromLowPolarity' ('Clash.Signal.unsafeFromReset' rstBtn)
-- /unsafeFromActiveLow/.
rst = 'Clash.Signal.unsafeFromActiveLow' ('Clash.Signal.unsafeFromReset' rstBtn)

-- Instantiate a PLL: this stabilizes the incoming clock signal and indicates
-- when the signal is stable. We're also using it to transform an incoming
Expand All @@ -99,11 +99,11 @@ topEntity clk20 rstBtn enaBtn modeBtn =

-- Synchronize reset to clock signal coming from PLL. We want the reset to
-- remain active while the PLL is NOT stable, hence the conversion with
-- /unsafeFromLowPolarity/
-- /unsafeFromActiveLow/
rstSync =
'Clash.Prelude.resetSynchronizer'
clk50
('Clash.Signal.unsafeFromLowPolarity' pllStable)
('Clash.Signal.unsafeFromActiveLow' pllStable)

blinkerT
:: (BitVector 8, Bool, Index 16650001)
Expand Down
2 changes: 1 addition & 1 deletion clash-prelude/src/Clash/Clocks/Deriving.hs
Expand Up @@ -51,7 +51,7 @@ derive' n = do
-- Implementation of 'clocks'
clkImpl <- [| Clock SSymbol Nothing |]
lockImpl <- [| unsafeSynchronizer clockGen clockGen
(unsafeToLowPolarity $(varE rst)) |]
(unsafeToActiveLow $(varE rst)) |]
let
noInline = PragmaD $ InlineP (mkName "clocks") NoInline FunLike AllPhases
clkImpls = replicate n clkImpl
Expand Down
2 changes: 1 addition & 1 deletion clash-prelude/src/Clash/Explicit/DDR.hs
Expand Up @@ -92,7 +92,7 @@ ddrIn#
-> a
-> Signal fast a
-> Signal slow (a,a)
ddrIn# (Clock _ Nothing) (unsafeToHighPolarity -> hRst) (fromEnable -> ena) i0 i1 i2 =
ddrIn# (Clock _ Nothing) (unsafeToActiveHigh -> hRst) (fromEnable -> ena) i0 i1 i2 =
case resetKind @fast of
SAsynchronous ->
goAsync
Expand Down
22 changes: 14 additions & 8 deletions clash-prelude/src/Clash/Explicit/Reset.hs
Expand Up @@ -30,10 +30,16 @@ module Clash.Explicit.Reset
, systemResetGen
, unsafeToReset
, unsafeFromReset
, unsafeToHighPolarity
, unsafeToLowPolarity
, unsafeToActiveHigh
, unsafeToActiveLow
, unsafeFromActiveHigh
, unsafeFromActiveLow

-- * Deprecated
, unsafeFromHighPolarity
, unsafeFromLowPolarity
, unsafeToHighPolarity
, unsafeToLowPolarity
) where

import Data.Type.Equality ((:~:)(Refl))
Expand Down Expand Up @@ -111,7 +117,7 @@ import GHC.TypeLits (type (+))
-- -> Signal System (BitVector 8)
-- topEntity clk rst key1 =
-- let (pllOut,pllStable) = altpll (SSymbol @"altpll50") clk rst
-- rstSync = 'resetSynchronizer' pllOut (unsafeToHighPolarity pllStable)
-- rstSync = 'resetSynchronizer' pllOut (unsafeToActiveHigh pllStable)
-- in exposeClockResetEnable leds pllOut rstSync enableGen
-- where
-- key1R = isRising 1 key1
Expand Down Expand Up @@ -184,8 +190,8 @@ resetSynchronizer clk rst = rstOut
-- designed with this environment in mind.
--
-- === __Example 1__
-- >>> let sampleResetN n = sampleN n . unsafeToHighPolarity
-- >>> let resetFromList = unsafeFromHighPolarity . fromList
-- >>> let sampleResetN n = sampleN n . unsafeToActiveHigh
-- >>> let resetFromList = unsafeFromActiveHigh . fromList
-- >>> let rst = resetFromList [True, True, False, False, True, False, False, True, True, False, True, True]
-- >>> sampleResetN 12 (resetGlitchFilter d2 systemClockGen rst)
-- [True,True,True,True,False,False,False,False,False,True,True,True]
Expand Down Expand Up @@ -230,7 +236,7 @@ resetGlitchFilter SNat clk rst =
--
-- Example:
--
-- >>> let sampleWithReset = sampleN 8 . unsafeToHighPolarity
-- >>> let sampleWithReset = sampleN 8 . unsafeToActiveHigh
-- >>> sampleWithReset (holdReset @System clockGen enableGen (SNat @2) (resetGenN (SNat @3)))
-- [True,True,True,True,True,False,False,False]
--
Expand All @@ -239,7 +245,7 @@ resetGlitchFilter SNat clk rst =
-- intermediate assertions of the reset signal:
--
-- >>> let rst = fromList [True, False, False, False, True, False, False, False]
-- >>> sampleWithReset (holdReset @System clockGen enableGen (SNat @2) (unsafeFromHighPolarity rst))
-- >>> sampleWithReset (holdReset @System clockGen enableGen (SNat @2) (unsafeFromActiveHigh rst))
-- [True,True,True,False,True,True,True,False]
--
holdReset
Expand All @@ -255,7 +261,7 @@ holdReset
-- ^ Reset to extend
-> Reset dom
holdReset clk en SNat rst =
unsafeFromHighPolarity ((/=maxBound) <$> counter)
unsafeFromActiveHigh ((/=maxBound) <$> counter)
where
counter :: Signal dom (Index (n+1))
counter = register clk rst en 0 (satSucc SatBound <$> counter)
Expand Down
18 changes: 12 additions & 6 deletions clash-prelude/src/Clash/Explicit/Signal.hs
Expand Up @@ -206,10 +206,10 @@ module Clash.Explicit.Signal
, Reset
, unsafeToReset
, unsafeFromReset
, unsafeToHighPolarity
, unsafeToLowPolarity
, unsafeFromHighPolarity
, unsafeFromLowPolarity
, unsafeToActiveHigh
, unsafeToActiveLow
, unsafeFromActiveHigh
, unsafeFromActiveLow
-- * Basic circuit functions
, andEnable
, enable -- DEPRECATED
Expand Down Expand Up @@ -267,6 +267,12 @@ module Clash.Explicit.Signal
, readFromBiSignal
, writeToBiSignal
, mergeBiSignalOuts

-- * Deprecated
, unsafeFromHighPolarity
, unsafeFromLowPolarity
, unsafeToHighPolarity
, unsafeToLowPolarity
)
where

Expand Down Expand Up @@ -813,7 +819,7 @@ simulateB_lazy f = simulate_lazy (bundle . f . unbundle)

-- | Like 'fromList', but resets on reset and has a defined reset value.
--
-- >>> let rst = unsafeFromHighPolarity (fromList [True, True, False, False, True, False])
-- >>> let rst = unsafeFromActiveHigh (fromList [True, True, False, False, True, False])
-- >>> let res = fromListWithReset @System rst Nothing [Just 'a', Just 'b', Just 'c']
-- >>> sampleN 6 res
-- [Nothing,Nothing,Just 'a',Just 'b',Nothing,Just 'a']
Expand All @@ -827,7 +833,7 @@ fromListWithReset
-> [a]
-> Signal dom a
fromListWithReset rst resetValue vals =
go (unsafeToHighPolarity rst) vals
go (unsafeToActiveHigh rst) vals
where
go (r :- rs) _ | r = resetValue :- go rs vals
go (_ :- rs) [] = deepErrorX "fromListWithReset: input ran out" :- go rs []
Expand Down
12 changes: 6 additions & 6 deletions clash-prelude/src/Clash/Intel/ClockGen.hs
Expand Up @@ -77,13 +77,13 @@ import Clash.Signal.Internal
-- where
-- (clk, pllStable) =
-- 'altpll' \@'Clash.Signal.System' ('SSymbol' \@\"altpll50to100\") clkInp
-- ('Clash.Signal.unsafeFromLowPolarity' rstInp)
-- rst = 'Clash.Signal.resetSynchronizer' clk ('Clash.Signal.unsafeFromLowPolarity' pllStable)
-- ('Clash.Signal.unsafeFromActiveLow' rstInp)
-- rst = 'Clash.Signal.resetSynchronizer' clk ('Clash.Signal.unsafeFromActiveLow' pllStable)
-- @
--
-- 'Clash.Signal.resetSynchronizer' will keep the reset asserted when
-- @pllStable@ is 'False', hence the use of
-- @'Clash.Signal.unsafeFromLowPolarity' pllStable@. Your circuit will have
-- @'Clash.Signal.unsafeFromActiveLow' pllStable@. Your circuit will have
-- signals of type @'Signal' 'Clash.Signal.System'@ and all the clocks and
-- resets of your components will be the @clk@ and @rst@ signals generated here
-- (modulo local resets, which will be based on @rst@ or never asserted at all
Expand Down Expand Up @@ -179,13 +179,13 @@ altpll !_ = knownDomain @domIn `seq` knownDomain @domOut `seq` clocks
-- where
-- (clk :: 'Clock' 'Clash.Signal.System', pllStable :: 'Signal' 'Clash.Signal.System' 'Bool')
-- 'alteraPll' ('SSymbol' \@\"alterapll50to100\") clkInp
-- ('Clash.Signal.unsafeFromLowPolarity' rstInp)
-- rst = 'Clash.Signal.resetSynchronizer' clk ('Clash.Signal.unsafeFromLowPolarity' pllStable)
-- ('Clash.Signal.unsafeFromActiveLow' rstInp)
-- rst = 'Clash.Signal.resetSynchronizer' clk ('Clash.Signal.unsafeFromActiveLow' pllStable)
-- @
--
-- 'Clash.Signal.resetSynchronizer' will keep the reset asserted when
-- @pllStable@ is 'False', hence the use of
-- @'Clash.Signal.unsafeFromLowPolarity' pllStable@. Your circuit will have
-- @'Clash.Signal.unsafeFromActiveLow' pllStable@. Your circuit will have
-- signals of type @'Signal' 'Clash.Signal.System'@ and all the clocks and
-- resets of your components will be the @clk@ and @rst@ signals generated here
-- (modulo local resets, which will be based on @rst@ or never asserted at all
Expand Down
22 changes: 14 additions & 8 deletions clash-prelude/src/Clash/Signal.hs
Expand Up @@ -136,10 +136,10 @@ module Clash.Signal
, Reset
, unsafeToReset
, unsafeFromReset
, unsafeToHighPolarity
, unsafeToLowPolarity
, unsafeFromHighPolarity
, unsafeFromLowPolarity
, unsafeToActiveHigh
, unsafeToActiveLow
, unsafeFromActiveHigh
, unsafeFromActiveLow
#ifdef CLASH_MULTIPLE_HIDDEN
, convertReset
#endif
Expand Down Expand Up @@ -262,6 +262,12 @@ module Clash.Signal
, HiddenClockName
, HiddenResetName
, HiddenEnableName

-- * Deprecated
, unsafeFromHighPolarity
, unsafeFromLowPolarity
, unsafeToHighPolarity
, unsafeToLowPolarity
)
where

Expand Down Expand Up @@ -417,7 +423,7 @@ topEntity
-> Signal System (BitVector 8)
topEntity clk rst key1 =
let (pllOut,pllStable) = 'Clash.Intel.ClockGen.altpll' (SSymbol \@\"altpll50\") clk rst
rstSync = 'resetSynchronizer' pllOut (unsafeToHighPolarity pllStable)
rstSync = 'resetSynchronizer' pllOut (unsafeToActiveHigh pllStable)
in 'exposeClockResetEnable' leds pllOut rstSync enableGen
where
key1R = isRising 1 key1
Expand All @@ -434,7 +440,7 @@ topEntity
-> Signal System (BitVector 8)
topEntity clk rst key1 =
let (pllOut,pllStable) = 'Clash.Intel.ClockGen.altpll' (SSymbol \@\"altpll50\") clk rst
rstSync = 'resetSynchronizer' pllOut (unsafeToHighPolarity pllStable)
rstSync = 'resetSynchronizer' pllOut (unsafeToActiveHigh pllStable)
in 'withClockResetEnable' pllOut rstSync enableGen leds
where
key1R = isRising 1 key1
Expand Down Expand Up @@ -2234,7 +2240,7 @@ unsafeSynchronizer =
--
-- Example:
--
-- >>> sampleN @System 8 (unsafeToHighPolarity (holdReset (SNat @2)))
-- >>> sampleN @System 8 (unsafeToActiveHigh (holdReset (SNat @2)))
-- [True,True,True,False,False,False,False,False]
--
-- 'holdReset' holds the reset for an additional 2 clock cycles for a total
Expand All @@ -2252,7 +2258,7 @@ holdReset m =

-- | Like 'fromList', but resets on reset and has a defined reset value.
--
-- >>> let rst = unsafeFromHighPolarity (fromList [True, True, False, False, True, False])
-- >>> let rst = unsafeFromActiveHigh (fromList [True, True, False, False, True, False])
-- >>> let res = withReset rst (fromListWithReset Nothing [Just 'a', Just 'b', Just 'c'])
-- >>> sampleN @System 6 res
-- [Nothing,Nothing,Just 'a',Just 'b',Nothing,Just 'a']
Expand Down