@@ -69,7 +69,7 @@ module Clash.Tutorial (
69
69
-- * Clash vs Lava
70
70
-- $vslava
71
71
72
- -- * Migration guide from Clash 0.7
72
+ -- * Migration guide from Clash 0.99
73
73
-- $migration
74
74
)
75
75
where
@@ -2268,84 +2268,85 @@ and / or easy to use as the standard Haskell features.
2268
2268
2269
2269
{- $migration
2270
2270
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>
2311
2301
2312
2302
=== Examples
2313
2303
2314
2304
==== FIR filter
2315
2305
2316
- FIR filter in Clash 0.7 :
2306
+ FIR filter in Clash 1.0 :
2317
2307
2318
2308
@
2319
2309
module FIR where
2320
2310
2321
- import CLaSH.Prelude
2311
+ import Clash.Prelude
2312
+ import Clash.Explicit.Testbench
2322
2313
2323
2314
dotp :: SaturatingNum a
2324
2315
=> Vec (n + 1) a
2325
2316
-> Vec (n + 1) a
2326
2317
-> a
2327
2318
dotp as bs = fold boundedPlus (zipWith boundedMult as bs)
2328
2319
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
2331
2323
fir coeffs x_t = y_t
2332
2324
where
2333
2325
y_t = dotp coeffs \<$\> bundle xs
2334
2326
xs = window x_t
2335
2327
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 #-}
2341
2335
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
2344
2344
@
2345
2345
2346
2346
FIR filter in current version:
2347
2347
2348
2348
@
2349
+
2349
2350
module FIR where
2350
2351
2351
2352
import Clash.Prelude
@@ -2363,7 +2364,7 @@ fir
2363
2364
, KnownNat n
2364
2365
, SaturatingNum a
2365
2366
, NFDataX a )
2366
- => Vec (n + 1) a -> Signal dom a -> Signal dom a
2367
+ => Vec (n + 1) a -> Signal tag a -> Signal tag a
2367
2368
fir coeffs x_t = y_t
2368
2369
where
2369
2370
y_t = dotp coeffs \<$\> bundle xs
@@ -2390,28 +2391,37 @@ testBench = done
2390
2391
2391
2392
==== Blinker circuit
2392
2393
2393
- Blinker circuit in Clash 0.7 :
2394
+ Blinker circuit in Clash 0.99 :
2394
2395
2395
2396
@
2397
+ {- # LANGUAGE NoMonoLocalBinds #-}
2396
2398
module Blinker where
2397
2399
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
2399
2405
2400
2406
{\-\# 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\"
2409
2414
}) \#-\}
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
2412
2422
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)
2415
2425
2416
2426
blinkerT (leds,mode,cntr) key1R = ((leds',mode',cntr'),leds)
2417
2427
where
@@ -2430,17 +2440,26 @@ blinkerT (leds,mode,cntr) key1R = ((leds',mode',cntr'),leds)
2430
2440
| otherwise = leds
2431
2441
@
2432
2442
2433
- Blinker in the current version :
2443
+ Blinker in Clash 1.0 :
2434
2444
2435
2445
@
2436
2446
module Blinker where
2437
2447
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')
2441
2457
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}
2444
2463
2445
2464
{\-\# ANN topEntity
2446
2465
('Synthesize'
@@ -2452,42 +2471,76 @@ import "Clash.Intel.ClockGen"
2452
2471
, t_output = PortName \"LED\"
2453
2472
}) \#-\}
2454
2473
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
2461
2489
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
2467
2507
(SSymbol \@\"altpll50\")
2468
- clk
2469
- ('Clash.Signal.unsafeFromLowPolarity' rst)
2508
+ clk20
2509
+ rst
2470
2510
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'
2471
2514
rstSync =
2472
2515
'Clash.Signal.resetSynchronizer'
2473
- pllOut
2474
- ('Clash.Signal. unsafeFromLowPolarity' pllStable)
2475
- enableGen
2516
+ clk50
2517
+ (unsafeFromLowPolarity pllStable)
2518
+ en
2476
2519
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)
2478
2529
where
2479
2530
-- clock frequency = 50e6 (50 MHz)
2480
2531
-- 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
2482
2533
2483
2534
cntr' | cntr == cnt_max = 0
2484
2535
| otherwise = cntr + 1
2485
2536
2486
- mode' | key1R = not mode
2537
+ mode' | key1R = flipMode mode
2487
2538
| otherwise = mode
2488
2539
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
2491
2544
| otherwise = leds
2492
2545
@
2493
2546
-}
0 commit comments