Skip to content

Commit

Permalink
Merge pull request #1586 from clash-lang/revert-resetSynchronizer-1.2
Browse files Browse the repository at this point in the history
Revert reset synchronizer patch in 1.2 branch
  • Loading branch information
martijnbastiaan authored Nov 9, 2020
2 parents 3d78018 + c7a07cd commit ce0723d
Show file tree
Hide file tree
Showing 12 changed files with 62 additions and 338 deletions.
3 changes: 0 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ reduceTypeFamily [#1469](https://github.com/clash-lang/clash-compiler/issues/146
* Clash no longer produces erroneous HDL in very specific cases [#1536](https://github.com/clash-lang/clash-compiler/issues/1536)
* Usage of `fold` inside other HO primitives (e.g., `map`) no longer fails [#1524](https://github.com/clash-lang/clash-compiler/issues/1524)

Changed:
* Due to difficulties using `resetSynchronizer` we've decided to make this function always insert a synchronizer. See: [#1528](https://github.com/clash-lang/clash-compiler/issues/1528).

## 1.2.4 *July 28th 2020*
* Changed:
* Relaxed upper bound versions of `aeson` and `dlist`, in preparation for the new Stack LTS.
Expand Down
28 changes: 0 additions & 28 deletions clash-lib/prims/systemverilog/Clash_Signal_Internal.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,34 +25,6 @@ end~FI
// delay end"
}
}
, { "BlackBox" :
{ "name" : "Clash.Signal.Internal.asyncRegister#"
, "kind" : "Declaration"
, "type" :
"asyncRegister#
:: ( KnownDomain dom -- ARG[0]
, NFDataX a ) -- ARG[1]
=> Clock dom -- ARG[2]
-> Reset dom -- ARG[3]
-> Enable dom -- ARG[4]
-> a -- ARG[5] (powerup value)
-> a -- ARG[6] (reset value)
-> Signal clk a -- ARG[7]
-> Signal clk a"
, "resultName" : { "template" : "~CTXNAME" }
, "resultInit" : { "template" : "~IF~ISINITDEFINED[0]~THEN~CONST[5]~ELSE~FI" }
, "template" :
"// async register begin
always_ff @(~IF~ACTIVEEDGE[Rising][0]~THENposedge~ELSEnegedge~FI ~ARG[2] or ~IF ~ISACTIVEHIGH[0] ~THEN posedge ~ELSE negedge ~FI ~VAR[rst][3]) begin : ~GENSYM[~RESULT_register][1]
if (~IF ~ISACTIVEHIGH[0] ~THEN ~ELSE ! ~FI~VAR[rst][3]) begin
~RESULT <= ~CONST[6];
end else ~IF ~ISACTIVEENABLE[4] ~THEN if (~ARG[4]) ~ELSE ~FI begin
~RESULT <= ~ARG[7];
end
end
// async register end"
}
}
, { "BlackBox" :
{ "name" : "Clash.Signal.Internal.register#"
, "kind" : "Declaration"
Expand Down
29 changes: 0 additions & 29 deletions clash-lib/prims/verilog/Clash_Signal_Internal.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,35 +26,6 @@ end~FI
// delay end"
}
}
, { "BlackBox" :
{ "name" : "Clash.Signal.Internal.asyncRegister#"
, "kind" : "Declaration"
, "type" :
"asyncRegister#
:: ( KnownDomain dom -- ARG[0]
, NFDataX a ) -- ARG[1]
=> Clock dom -- ARG[2]
-> Reset dom -- ARG[3]
-> Enable dom -- ARG[4]
-> a -- ARG[5] (powerup value)
-> a -- ARG[6] (reset value)
-> Signal clk a -- ARG[7]
-> Signal clk a"
, "outputReg" : true
, "resultName" : { "template" : "~CTXNAME" }
, "resultInit" : { "template" : "~IF~ISINITDEFINED[0]~THEN~CONST[5]~ELSE~FI" }
, "template" :
"// async register begin
always @(~IF~ACTIVEEDGE[Rising][0]~THENposedge~ELSEnegedge~FI ~ARG[2] or ~IF ~ISACTIVEHIGH[0] ~THEN posedge ~ELSE negedge ~FI ~VAR[rst][3]) begin : ~GENSYM[~RESULT_register][1]
if (~IF ~ISACTIVEHIGH[0] ~THEN ~ELSE ! ~FI~VAR[rst][3]) begin
~RESULT <= ~CONST[6];
end else ~IF ~ISACTIVEENABLE[4] ~THENif (~ARG[4]) ~ELSE~FIbegin
~RESULT <= ~ARG[7];
end
end
// async register end"
}
}
, { "BlackBox" :
{ "name" : "Clash.Signal.Internal.register#"
, "kind" : "Declaration"
Expand Down
37 changes: 1 addition & 36 deletions clash-lib/prims/vhdl/Clash_Signal_Internal.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,48 +31,13 @@ end process;~FI
-- delay end"
}
}
, { "BlackBox" :
{ "name" : "Clash.Signal.Internal.asyncRegister#"
, "kind" : "Declaration"
, "type" :
"asyncRegister#
:: ( KnownDomain dom -- ARG[0]
, NFDataX a ) -- ARG[1]
=> Clock dom -- ARG[2]
-> Reset dom -- ARG[3]
-> Enable dom -- ARG[4]
-> a -- ARG[5] (powerup value)
-> a -- ARG[6] (reset value)
-> Signal clk a -- ARG[7]
-> Signal clk a"
, "resultName" : { "template" : "~CTXNAME" }
, "resultInit" : { "template" : "~IF~ISINITDEFINED[0]~THEN~CONST[5]~ELSE~FI" }
, "template" :
"-- async register begin
~SYM[2] : process(~ARG[2],~ARG[3])
begin
if ~ARG[3] = ~IF ~ISACTIVEHIGH[0] ~THEN '1' ~ELSE '0' ~FI then
~RESULT <= ~CONST[6];
elsif ~IF~ACTIVEEDGE[Rising][0]~THENrising_edge~ELSEfalling_edge~FI(~ARG[2]) then
~IF ~ISACTIVEENABLE[4] ~THEN
if ~ARG[4] then
~RESULT <= ~ARG[7];
end if;
~ELSE
~RESULT <= ~ARG[7];
~FI
end if;
end process;
-- async register end"
}
}
, { "BlackBox" :
{ "name" : "Clash.Signal.Internal.register#"
, "kind" : "Declaration"
, "type" :
"register#
:: ( KnownDomain dom -- ARG[0]
, NFDataX a ) -- ARG[1]
, Undefined a ) -- ARG[1]
=> Clock dom -- ARG[2]
-> Reset dom -- ARG[3]
-> Enable dom -- ARG[4]
Expand Down
70 changes: 14 additions & 56 deletions clash-prelude/src/Clash/Explicit/Signal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -372,83 +372,41 @@ systemResetGen = resetGen
-- reset, then asynchronous assertion of the reset of component \"B"\ can induce
-- meta-stability in component \"A\". To prevent this from happening you need
-- to use a proper synchronizer, for example one of the synchronizers in
-- "Clash.Explicit.Synchronizer".
-- "Clash.Explicit.Synchronizer"
--
-- === __Example 1__
-- The circuit below detects a rising bit (i.e., a transition from 0 to 1) in a
-- given argument. It takes a reset that is not synchronized to any of the other
-- incoming signals and synchronizes it using 'resetSynchronizer'.
--
-- @
-- topEntity
-- :: Clock System
-- -> Reset System
-- -> Enable System
-- -> Signal System Bit
-- -> Signal System (BitVector 8)
-- topEntity clk asyncRst ena key1 =
-- withClockResetEnable clk rst ena leds
-- where
-- rst = 'resetSynchronizer' clk asyncRst
-- key1R = isRising 1 key1
-- leds = mealy blinkerT (1, False, 0) key1R
-- @
--
-- === __Example 2__
-- Similar to /Example 1/ this circuit detects a rising bit (i.e., a transition
-- from 0 to 1) in a given argument. It takes a clock that is not stable yet and
-- a reset singal that is not synchronized to any other signals. It stabalizes
-- the clock and then synchronizes the reset signal.
-- === __Example__
--
-- @
-- topEntity
-- :: Clock System
-- -> Reset System
-- -> Signal System Bit
-- -> Signal System (BitVector 8)
-- topEntity clk rst ena key1 =
-- topEntity clk rst key1 =
-- let (pllOut,pllStable) = altpll (SSymbol @"altpll50") clk rst
-- rstSync = 'resetSynchronizer' pllOut (unsafeToHighPolarity pllStable)
-- in exposeClockResetEnable leds pllOut rstSync enableGen
-- in exposeClockResetEnable leds pllOut rstSync
-- where
-- key1R = isRising 1 key1
-- leds = mealy blinkerT (1, False, 0) key1R
-- @
--
-- === __Implementation details__
-- 'resetSynchronizer' implements the following circuit:
--
-- @
-- rst
-- --------------------------------------+
-- | |
-- +----v----+ +----v----+
-- deasserted | | | |
-- ---------------> +-------> +-------->
-- | | | |
-- +---|> | +---|> |
-- | | | | | |
-- | +---------+ | +---------+
-- clk | |
-- -----------------------------+
-- @
--
-- This corresponds to figure 3d at <https://www.embedded.com/asynchronous-reset-synchronization-and-distribution-challenges-and-solutions/>
--
resetSynchronizer
:: forall dom
. KnownDomain dom
=> Clock dom
-> Reset dom
-> Enable dom
-- ^ Warning: this argument will be removed in future versions of Clash.
-> Reset dom
resetSynchronizer clk rst ena =
unsafeToReset (asyncReg (asyncReg (pure (not isActiveHigh))))
where
isActiveHigh = case resetPolarity @dom of { SActiveHigh -> True; _ -> False }
asyncReg = asyncRegister# clk rst ena isActiveHigh isActiveHigh
{-# NOINLINE resetSynchronizer #-} -- Give reset synchronizer its own HDL file
resetSynchronizer clk rst en =
case resetKind @dom of
SAsynchronous ->
let isActiveHigh = case resetPolarity @dom of { SActiveHigh -> True; _ -> False }
r1 = register clk rst en isActiveHigh (pure (not isActiveHigh))
r2 = register clk rst en isActiveHigh r1
in unsafeToReset r2
SSynchronous ->
-- Reset is already synchronous, nothing to do!
rst

-- | Calculate the period, in __ps__, given a frequency in __Hz__
--
Expand Down
9 changes: 8 additions & 1 deletion clash-prelude/src/Clash/Explicit/Testbench.hs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ import Clash.Explicit.Signal
(Clock, Reset, System, Signal, clockPeriod, toEnable, fromList, register,
unbundle, unsafeSynchronizer, veryUnsafeSynchronizer)
import Clash.Signal.Internal (Clock (..), Reset (..))
import Clash.Signal (mux, KnownDomain, Enable)
import Clash.Signal
(mux, DomainResetKind, ResetKind(Asynchronous), KnownDomain,
Enable)
import Clash.Sized.Index (Index)
import Clash.Sized.Internal.BitVector
(BitVector, isLike)
Expand Down Expand Up @@ -191,6 +193,7 @@ outputVerifier'
:: forall l a dom
. ( KnownNat l
, KnownDomain dom
, DomainResetKind dom ~ 'Asynchronous
, Eq a
, ShowX a )
=> Clock dom
Expand Down Expand Up @@ -253,6 +256,7 @@ outputVerifier
. ( KnownNat l
, KnownDomain testDom
, KnownDomain circuitDom
, DomainResetKind testDom ~ 'Asynchronous
, Eq a
, ShowX a )
=> Clock testDom
Expand Down Expand Up @@ -296,6 +300,7 @@ outputVerifierBitVector'
. ( KnownNat l
, KnownNat n
, KnownDomain dom
, DomainResetKind dom ~ 'Asynchronous
)
=> Clock dom
-- ^ Clock to which the input signal is synchronized to
Expand All @@ -318,6 +323,7 @@ outputVerifierBitVector
, KnownNat n
, KnownDomain testDom
, KnownDomain circuitDom
, DomainResetKind testDom ~ 'Asynchronous
)
=> Clock testDom
-- ^ Clock to which the input signal is synchronized to
Expand Down Expand Up @@ -381,6 +387,7 @@ biTbClockGen
:: forall testDom circuitDom
. ( KnownDomain testDom
, KnownDomain circuitDom
, DomainResetKind testDom ~ 'Asynchronous
)
=> Signal testDom Bool
-> (Clock testDom, Clock circuitDom)
Expand Down
4 changes: 3 additions & 1 deletion clash-prelude/src/Clash/Prelude/Testbench.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import GHC.TypeLits (KnownNat)
import qualified Clash.Explicit.Testbench as E
import Clash.Signal
(HiddenClock, HiddenReset, HiddenClockResetEnable, Signal,
hideClock, hideReset, hideClockResetEnable)
DomainResetKind, ResetKind(Asynchronous), hideClock, hideReset, hideClockResetEnable)
import Clash.Promoted.Nat (SNat)
import Clash.Sized.BitVector (BitVector)
import Clash.Sized.Vector (Vec)
Expand Down Expand Up @@ -153,6 +153,7 @@ outputVerifier'
:: ( KnownNat l
, Eq a
, ShowX a
, DomainResetKind dom ~ 'Asynchronous
, HiddenClock dom
, HiddenReset dom )
=> Vec l a
Expand All @@ -170,6 +171,7 @@ outputVerifier' = hideReset (hideClock E.outputVerifier')
outputVerifierBitVector'
:: ( KnownNat l
, KnownNat n
, DomainResetKind dom ~ 'Asynchronous
, HiddenClock dom
, HiddenReset dom )
=> Vec l (BitVector n)
Expand Down
Loading

0 comments on commit ce0723d

Please sign in to comment.