Skip to content

Commit 7d2b92b

Browse files
Add migration guide for 0.99 -> 1.0
1 parent d1f325e commit 7d2b92b

File tree

1 file changed

+147
-94
lines changed

1 file changed

+147
-94
lines changed

clash-prelude/src/Clash/Tutorial.hs

Lines changed: 147 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ module Clash.Tutorial (
6969
-- * Clash vs Lava
7070
-- $vslava
7171

72-
-- * Migration guide from Clash 0.7
72+
-- * Migration guide from Clash 0.99
7373
-- $migration
7474
)
7575
where
@@ -2268,84 +2268,85 @@ and / or easy to use as the standard Haskell features.
22682268

22692269
{- $migration
22702270
2271-
* The top name in the module hierarchy has changed from \"@CLaSH@\" to
2272-
\"@Clash@\".
2273-
2274-
* There is no longer any distinction between @Signal@ and @Signal'@, there is
2275-
only 'Signal' which has a /dom/ and /value/ type variable.
2276-
2277-
@
2278-
data Signal (dom :: Domain) a
2279-
@
2280-
2281-
The /dom/ refers to a synthesis domain. See "Clash.Explicit.Signal" for more
2282-
information on domains and how to use them.
2283-
2284-
* The \"@Clash.Prelude.Explicit@\" module has been removed because all 'Signal's
2285-
have a /domain/ annotation now. There is a "Clash.Explicit.Prelude" module,
2286-
but it serves a different purpose: it exports a prelude where all synchronous
2287-
components have an explicit clock (and reset) value; "Clash.Prelude" exports
2288-
synchronous components with <Clash-Signal.html#hiddenclockandreset hidden clock and reset> arguments.
2289-
Note that "Clash.Prelude" and "Clash.Explicit.Prelude" have overlapping
2290-
definitions, meaning you must use /qualified/ imports to disambiguate.
2291-
2292-
* All synchronous components have clock and reset arguments now, they appear as
2293-
<Clash-Signal.html#hiddenclockandreset hidden> arguments when you use
2294-
"Clash.Prelude", and as normal arguments when you use "Clash.Explicit.Prelude".
2295-
2296-
* HDL Testbench generation is no longer predicated on the existence of a
2297-
top-level /testInput/ and /expectedOutput/ function. Instead, top-level functions
2298-
called /testBench/ are now picked up as the entry-point for HDL test benches.
2299-
Alternatively you can use a 'Clash.Annotations.TestBench' /ANN/ pragma.
2300-
2301-
* 'Clash.Annotations.TopEntity' annotations have received a complete overhaul,
2302-
and you should just rewrite them from scratch. Additionally, designs can
2303-
contain multiple 'Clash.Annotations.Synthesize' to split generated HDL over
2304-
multiple output directories.
2305-
2306-
* With the overhaul of 'Clash.Annotations.TopEntity' annotations and the
2307-
introduction of explicit clock and reset arguments, PLLs and other clock
2308-
sources are now regular Clash functions such as those found in
2309-
"Clash.Intel.ClockGen" and "Clash.Xilinx.ClockGen".
2310-
2271+
* Clash has overhauled the way synthesis options are represented. You can read
2272+
about this change in the blogpost: <https://clash-lang.org/blog/0005-synthesis-domain/ New feature: configurable initial values>.
2273+
The executive summary is as follows:
2274+
2275+
+------------------------------------------------------------------------------+--------------------------------------------------------------------+
2276+
| __0.99__ | __1.0__ |
2277+
+------------------------------------------------------------------------------+--------------------------------------------------------------------+
2278+
| @topEntity (clk::Clock d 'Source) rst = withClockReset f clk rst@ | @topEntity clk rst = withClockResetEnable clk rst enableGen f@ |
2279+
+------------------------------------------------------------------------------+--------------------------------------------------------------------+
2280+
| @topEntity (clk::Clock d 'Gated) rst = withClockReset f clk rst@ | @topEntity clk rst enable = withClockResetEnable clk rst enable f@ |
2281+
+------------------------------------------------------------------------------+--------------------------------------------------------------------+
2282+
| @data A = ... @ (and @A@ is used as state, for example in register or mealy) | @data A = ... deriving (Generic,NFDataX)@ |
2283+
+------------------------------------------------------------------------------+--------------------------------------------------------------------+
2284+
| @SystemClockReset@ | @SystemClockResetEnable@ |
2285+
+------------------------------------------------------------------------------+--------------------------------------------------------------------+
2286+
| @HiddenClockReset dom gated sync@ | @HiddenClockResetEnable dom@ |
2287+
+------------------------------------------------------------------------------+--------------------------------------------------------------------+
2288+
| @HiddenClock dom gated@ | @HiddenClock dom@ |
2289+
+------------------------------------------------------------------------------+--------------------------------------------------------------------+
2290+
| @HiddenReset dom sync@ | @HiddenReset dom@ |
2291+
+------------------------------------------------------------------------------+--------------------------------------------------------------------+
2292+
| @Clock dom gated@ | @Clock dom@ |
2293+
+------------------------------------------------------------------------------+--------------------------------------------------------------------+
2294+
| @Reset dom sync@ | @Reset dom@ |
2295+
+------------------------------------------------------------------------------+--------------------------------------------------------------------+
2296+
2297+
* @outputVerifier@ now operates on two domains. If you only need one, simply
2298+
change it to @outputVerifier'@
2299+
2300+
* For an overview of all other changes, check out <https://github.com/clash-lang/clash-compiler/blob/1.0/clash-ghc/CHANGELOG.md the changelog>
23112301
23122302
=== Examples
23132303
23142304
==== FIR filter
23152305
2316-
FIR filter in Clash 0.7:
2306+
FIR filter in Clash 1.0:
23172307
23182308
@
23192309
module FIR where
23202310
2321-
import CLaSH.Prelude
2311+
import Clash.Prelude
2312+
import Clash.Explicit.Testbench
23222313
23232314
dotp :: SaturatingNum a
23242315
=> Vec (n + 1) a
23252316
-> Vec (n + 1) a
23262317
-> a
23272318
dotp as bs = fold boundedPlus (zipWith boundedMult as bs)
23282319
2329-
fir :: (Default a, KnownNat n, SaturatingNum a)
2330-
=> Vec (n + 1) a -> Signal a -> Signal a
2320+
fir
2321+
:: (Default a, KnownNat n, SaturatingNum a, HiddenClockReset domain gated synchronous)
2322+
=> Vec (n + 1) a -> Signal domain a -> Signal domain a
23312323
fir coeffs x_t = y_t
23322324
where
23332325
y_t = dotp coeffs \<$\> bundle xs
23342326
xs = window x_t
23352327
2336-
topEntity :: Signal (Signed 16) -> Signal (Signed 16)
2337-
topEntity = fir (2:>3:>(-2):>8:>Nil)
2338-
2339-
testInput :: Signal (Signed 16)
2340-
testInput = stimuliGenerator (2:>3:>(-2):>8:>Nil)
2328+
topEntity
2329+
:: Clock System Source
2330+
-> Reset System Asynchronous
2331+
-> Signal System (Signed 16)
2332+
-> Signal System (Signed 16)
2333+
topEntity = exposeClockReset (fir (2:>3:>(-2):>8:>Nil))
2334+
{-# NOINLINE topEntity #-}
23412335
2342-
expectedOutput :: Signal (Signed 16) -> Signal Bool
2343-
expectedOutput = outputVerifier' (4:>12:>1:>20:>Nil)
2336+
testBench :: Signal System Bool
2337+
testBench = done
2338+
where
2339+
testInput = stimuliGenerator clk rst (2:>3:>(-2):>8:>Nil)
2340+
expectedOutput = outputVerifier clk rst (4:>12:>1:>20:>Nil)
2341+
done = expectedOutput (topEntity clk rst testInput)
2342+
clk = tbSystemClockGen (not \<$\> done)
2343+
rst = systemResetGen
23442344
@
23452345
23462346
FIR filter in current version:
23472347
23482348
@
2349+
23492350
module FIR where
23502351
23512352
import Clash.Prelude
@@ -2363,7 +2364,7 @@ fir
23632364
, KnownNat n
23642365
, SaturatingNum a
23652366
, NFDataX a )
2366-
=> Vec (n + 1) a -> Signal dom a -> Signal dom a
2367+
=> Vec (n + 1) a -> Signal tag a -> Signal tag a
23672368
fir coeffs x_t = y_t
23682369
where
23692370
y_t = dotp coeffs \<$\> bundle xs
@@ -2390,28 +2391,37 @@ testBench = done
23902391
23912392
==== Blinker circuit
23922393
2393-
Blinker circuit in Clash 0.7:
2394+
Blinker circuit in Clash 0.99:
23942395
23952396
@
2397+
{-# LANGUAGE NoMonoLocalBinds #-}
23962398
module Blinker where
23972399
2398-
import CLaSH.Prelude
2400+
import Clash.Prelude
2401+
import Clash.Promoted.Symbol
2402+
import Clash.Intel.ClockGen
2403+
2404+
type Dom50 = Dom \"System\" 20000
23992405
24002406
{\-\# ANN topEntity
2401-
(defTop
2402-
{ t_name = "blinker"
2403-
, t_inputs = [\"KEY1\"]
2404-
, t_outputs = [\"LED\"]
2405-
, t_extraIn = [ (\"CLOCK_50\", 1)
2406-
, (\"KEY0\" , 1)
2407-
]
2408-
, t_clocks = [ altpll "altpll50" "CLOCK_50(0)" "not KEY0(0)" ]
2407+
(Synthesize
2408+
{ t_name = \"blinker\"
2409+
, t_inputs = [ PortName \"CLOCK_50\"
2410+
, PortName \"KEY0\"
2411+
, PortName \"KEY1\"
2412+
]
2413+
, t_output = PortName \"LED\"
24092414
}) \#-\}
2410-
topEntity :: Signal Bit -> Signal (BitVector 8)
2411-
topEntity key1 = leds
2415+
topEntity
2416+
:: Clock Dom50 Source
2417+
-> Reset Dom50 Asynchronous
2418+
-> Signal Dom50 Bit
2419+
-> Signal Dom50 (BitVector 8)
2420+
topEntity clk rst =
2421+
exposeClockReset (mealy blinkerT (1,False,0) . isRising 1) pllOut rstSync
24122422
where
2413-
key1R = isRising 1 key1
2414-
leds = mealy blinkerT (1,False,0) key1R
2423+
(pllOut,pllStable) = altpll \@Dom50 (SSymbol \@ \"altpll50\") clk rst
2424+
rstSync = resetSynchronizer pllOut (unsafeToAsyncReset pllStable)
24152425
24162426
blinkerT (leds,mode,cntr) key1R = ((leds',mode',cntr'),leds)
24172427
where
@@ -2430,17 +2440,26 @@ blinkerT (leds,mode,cntr) key1R = ((leds',mode',cntr'),leds)
24302440
| otherwise = leds
24312441
@
24322442
2433-
Blinker in the current version:
2443+
Blinker in Clash 1.0:
24342444
24352445
@
24362446
module Blinker where
24372447
2438-
import "Clash.Signal"
2439-
import "Clash.Prelude"
2440-
import "Clash.Intel.ClockGen"
2448+
import Clash.Prelude
2449+
import Clash.Intel.ClockGen
2450+
2451+
data LedMode
2452+
= Rotate
2453+
-- ^ After some period, rotate active led to the left
2454+
| Complement
2455+
-- ^ After some period, turn on all disable LEDs, and vice versa
2456+
deriving (Generic, 'Undefined')
24412457
2442-
'createDomain' 'vSystem'{vName="DomInput", vPeriod=20000}
2443-
'createDomain' 'vSystem'{vName="Dom50", vPeriod=50000}
2458+
-- Define a synthesis domain with a clock with a period of 20000 /ps/.
2459+
'createDomain' 'vSystem'{vName=\"Input\", vPeriod=20000}
2460+
2461+
-- Define a synthesis domain with a clock with a period of 50000 /ps/.
2462+
'createDomain' 'vSystem'{vName=\"Dom50\", vPeriod=50000}
24442463
24452464
{\-\# ANN topEntity
24462465
('Synthesize'
@@ -2452,42 +2471,76 @@ import "Clash.Intel.ClockGen"
24522471
, t_output = PortName \"LED\"
24532472
}) \#-\}
24542473
topEntity
2455-
:: 'Clock' \"DomInput\"
2456-
-> 'Signal' \"DomInput\" Bool
2457-
-> 'Signal' \"Dom50\" Bit
2458-
-> 'Signal' \"Dom50\" (BitVector 8)
2459-
topEntity clk rst =
2460-
'exposeClockResetEnable' circuit pllOut rstSync enableGen
2474+
:: Clock Input
2475+
-- ^ Incoming clock
2476+
-> Signal Input Bool
2477+
-- ^ Reset signal, straight from KEY0
2478+
-> Signal Dom50 Bit
2479+
-- ^ Mode choice, straight from KEY1. See \'LedMode\'.
2480+
-> Signal Dom50 (BitVector 8)
2481+
-- ^ Output containing 8 bits, corresponding to 8 LEDs
2482+
topEntity clk20 rstBtn modeBtn =
2483+
exposeClockResetEnable
2484+
(mealy blinkerT initialStateBlinkerT . isRising 1)
2485+
clk50
2486+
rstSync
2487+
en
2488+
modeBtn
24612489
where
2462-
circuit = 'mealy' blinkerT (1,False,0) . 'Clash.Prelude.isRising' 1
2463-
2464-
(pllOut, pllStable) =
2465-
'Clash.Intel.ClockGen.altpll'
2466-
\@\"Dom50\"
2490+
-- | Enable line for subcomponents: we'll keep it always running
2491+
en = enableGen
2492+
2493+
-- Start with the first LED turned on, in rotate mode, with the counter on zero
2494+
initialStateBlinkerT = (1, Rotate, 0)
2495+
2496+
-- Signal coming from the reset button is low when pressed, and high when
2497+
-- not pressed. We convert this signal to the polarity of our domain with
2498+
-- 'unsafeFromActiveLow'.
2499+
rst = 'Clash.Signal.unsafeFromLowPolarity' rstBtn
2500+
2501+
-- Instantiate a PLL: this stabilizes the incoming clock signal and indicates
2502+
-- when the signal is stable. We're also using it to transform an incoming
2503+
-- clock signal running at 20 MHz to a clock signal running at 50 MHz.
2504+
(clk50, pllStable) =
2505+
altpll
2506+
\@Dom50
24672507
(SSymbol \@\"altpll50\")
2468-
clk
2469-
('Clash.Signal.unsafeFromLowPolarity' rst)
2508+
clk20
2509+
rst
24702510
2511+
-- Synchronize reset to clock signal coming from PLL. We want the reset to
2512+
-- remain active while the PLL is NOT stable, hence the conversion with
2513+
-- 'unsafeFromActiveLow'
24712514
rstSync =
24722515
'Clash.Signal.resetSynchronizer'
2473-
pllOut
2474-
('Clash.Signal.unsafeFromLowPolarity' pllStable)
2475-
enableGen
2516+
clk50
2517+
(unsafeFromLowPolarity pllStable)
2518+
en
24762519
2477-
blinkerT (leds,mode,cntr) key1R = ((leds',mode',cntr'),leds)
2520+
flipMode :: LedMode -> LedMode
2521+
flipMode Rotate = Complement
2522+
flipMode Complement = Rotate
2523+
2524+
blinkerT
2525+
:: (BitVector 8, LedMode, Index 16650001)
2526+
-> Bool
2527+
-> ((BitVector 8, LedMode, Index 16650001), BitVector 8)
2528+
blinkerT (leds, mode, cntr) key1R = ((leds', mode', cntr'), leds)
24782529
where
24792530
-- clock frequency = 50e6 (50 MHz)
24802531
-- led update rate = 333e-3 (every 333ms)
2481-
cnt_max = 16650000 :: (Index 16650001) -- 50e6 * 333e-3
2532+
cnt_max = 16650000 :: Index 16650001 -- 50e6 * 333e-3
24822533
24832534
cntr' | cntr == cnt_max = 0
24842535
| otherwise = cntr + 1
24852536
2486-
mode' | key1R = not mode
2537+
mode' | key1R = flipMode mode
24872538
| otherwise = mode
24882539
2489-
leds' | cntr == 0 = if mode then complement leds
2490-
else rotateL leds 1
2540+
leds' | cntr == 0 =
2541+
case mode of
2542+
Rotate -> rotateL leds 1
2543+
Complement -> complement leds
24912544
| otherwise = leds
24922545
@
24932546
-}

0 commit comments

Comments
 (0)