clash-prelude 0.7.3 → 0.7.4
raw patch · 9 files changed
+542/−8 lines, 9 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ CLaSH.Annotations.TopEntity: [ClockSource] :: String -> Maybe (String, String) -> [(String, String)] -> Maybe (String, String) -> String -> Bool -> ClockSource
+ CLaSH.Annotations.TopEntity: [TopEntity] :: String -> [String] -> [String] -> [(String, Int)] -> [(String, Int)] -> [ClockSource] -> TopEntity
+ CLaSH.Annotations.TopEntity: [c_inp] :: ClockSource -> Maybe (String, String)
+ CLaSH.Annotations.TopEntity: [c_lock] :: ClockSource -> String
+ CLaSH.Annotations.TopEntity: [c_name] :: ClockSource -> String
+ CLaSH.Annotations.TopEntity: [c_outp] :: ClockSource -> [(String, String)]
+ CLaSH.Annotations.TopEntity: [c_reset] :: ClockSource -> Maybe (String, String)
+ CLaSH.Annotations.TopEntity: [c_sync] :: ClockSource -> Bool
+ CLaSH.Annotations.TopEntity: [t_clocks] :: TopEntity -> [ClockSource]
+ CLaSH.Annotations.TopEntity: [t_extraIn] :: TopEntity -> [(String, Int)]
+ CLaSH.Annotations.TopEntity: [t_extraOut] :: TopEntity -> [(String, Int)]
+ CLaSH.Annotations.TopEntity: [t_inputs] :: TopEntity -> [String]
+ CLaSH.Annotations.TopEntity: [t_name] :: TopEntity -> String
+ CLaSH.Annotations.TopEntity: [t_outputs] :: TopEntity -> [String]
+ CLaSH.Annotations.TopEntity: data ClockSource
+ CLaSH.Annotations.TopEntity: data TopEntity
+ CLaSH.Annotations.TopEntity: defClkAltera :: String -> String -> String -> ClockSource
+ CLaSH.Annotations.TopEntity: defClkXilinx :: String -> String -> String -> ClockSource
+ CLaSH.Annotations.TopEntity: defTop :: TopEntity
+ CLaSH.Annotations.TopEntity: instance Data ClockSource
+ CLaSH.Annotations.TopEntity: instance Data TopEntity
+ CLaSH.Annotations.TopEntity: instance Show ClockSource
+ CLaSH.Annotations.TopEntity: instance Show TopEntity
+ CLaSH.Signal.Internal: instance Show (SClock clk)
Files
- CHANGELOG.md +4/−0
- README.md +2/−0
- clash-prelude.cabal +4/−2
- src/CLaSH/Annotations/TopEntity.hs +354/−0
- src/CLaSH/Prelude.hs +4/−1
- src/CLaSH/Promoted/Symbol.hs +4/−2
- src/CLaSH/Signal/Internal.hs +6/−2
- src/CLaSH/Sized/Vector.hs +1/−1
- src/CLaSH/Tutorial.hs +163/−0
CHANGELOG.md view
@@ -1,5 +1,9 @@ # Changelog for [`clash-prelude` package](http://hackage.haskell.org/package/clash-prelude) +## 0.7.4 **May 5th 2015*+* New features:+ * Add `TopEntity` annotations+ ## 0.7.3 *April 22nd 2015* * New features: * Add the vector functions: `zip3`, `unzip3`, and `zipWith3`
README.md view
@@ -1,4 +1,6 @@ [](https://travis-ci.org/clash-lang/clash-prelude)+[](https://hackage.haskell.org/package/clash-prelude)+[](http://packdeps.haskellers.com/feed?needle=exact%3Aclash-prelude) = WARNING = Only works with GHC-7.10.* (http://www.haskell.org/ghc/download_ghc_7_10_1)!
clash-prelude.cabal view
@@ -1,5 +1,5 @@ Name: clash-prelude-Version: 0.7.3+Version: 0.7.4 Synopsis: CAES Language for Synchronous Hardware - Prelude library Description: CλaSH (pronounced ‘clash’) is a functional hardware description language that@@ -55,7 +55,9 @@ default-language: Haskell2010 ghc-options: -Wall -fexpose-all-unfoldings - Exposed-modules: CLaSH.Class.BitPack+ Exposed-modules: CLaSH.Annotations.TopEntity++ CLaSH.Class.BitPack CLaSH.Class.Num CLaSH.Class.Resize
+ src/CLaSH/Annotations/TopEntity.hs view
@@ -0,0 +1,354 @@+{-# LANGUAGE DeriveDataTypeable #-}++{-# OPTIONS_HADDOCK show-extensions #-}++{-|+Copyright : (C) 2015, University of Twente+License : BSD2 (see the file LICENSE)+Maintainer : Christiaan Baaij <christiaan.baaij@gmail.com>++The 'TopEntity' annotations described in this module make it easier to put your+design on an FPGA.++We can exert some control how the top level function is created by the CλaSH+compiler by annotating the @topEntity@ function with a 'TopEntity' annotation.+You apply these annotation using the @ANN@ pragma like so:++@+{\-\# ANN topEntity (TopEntity {t_name = ..., ... }) \#-\}+topEntity x = ...+@++For example, given the following specification:++@+topEntity :: Signal Bit -> Signal (BitVector 8)+topEntity key1 = leds+ where+ key1R = isRising 1 key1+ leds = mealy blinkerT (1,False,0) key1R++blinkerT (leds,mode,cntr) key1R = ((leds',mode',cntr'),leds)+ where+ -- clock frequency = 50e6 (50 MHz)+ -- led update rate = 333e-3 (every 333ms)+ cnt_max = 16650000 -- 50e6 * 333e-3++ cntr' | cntr == cnt_max = 0+ | otherwise = cntr + 1++ mode' | key1R = not mode+ | otherwise = mode++ leds' | cntr == 0 = if mode then complement leds+ else rotateL leds 1+ | otherwise = leds+@++The CλaSH compiler will normally generate the following @topEntity.vhdl@ file:++@+-- Automatically generated VHDL+library IEEE;+use IEEE.STD_LOGIC_1164.ALL;+use IEEE.NUMERIC_STD.ALL;+use IEEE.MATH_REAL.ALL;+use work.all;+use work.types.all;++entity topEntity is+ port(input_0 : in std_logic_vector(0 downto 0);+ -- clock+ system1000 : in std_logic;+ -- asynchronous reset: active low+ system1000_rstn : in std_logic;+ output_0 : out std_logic_vector(7 downto 0));+end;++architecture structural of topEntity is+begin+ topEntity_0_inst : entity topEntity_0+ port map+ (key1_i1 => input_0+ ,system1000 => system1000+ ,system1000_rstn => system1000_rstn+ ,topLet_o => output_0);+end;+@++However, if we add the following 'TopEntity' annotation in the file:++@+{\-\# ANN topEntity+ ('defTop'+ { t_name = "blinker"+ , t_inputs = [\"KEY1\"]+ , t_outputs = [\"LED\"]+ , t_extraIn = [ (\"CLOCK_50\", 1)+ , (\"KEY0\" , 1)+ ]+ , t_clocks = [ 'defClkAltera' "altpll50" "CLOCK_50(0)" "not KEY0(0)" ]+ }) \#-\}+@++The CλaSH compiler will generate the following @blinker.vhdl@ file instead:++@+-- Automatically generated VHDL+library IEEE;+use IEEE.STD_LOGIC_1164.ALL;+use IEEE.NUMERIC_STD.ALL;+use IEEE.MATH_REAL.ALL;+use work.all;+use work.types.all;++entity blinker is+ port(KEY1 : in std_logic_vector(0 downto 0);+ CLOCK_50 : in std_logic_vector(0 downto 0);+ KEY0 : in std_logic_vector(0 downto 0);+ LED : out std_logic_vector(7 downto 0));+end;++architecture structural of blinker is+ signal system1000 : std_logic;+ signal system1000_rstn : std_logic;+ signal altpll50_locked : std_logic;+begin+ altpll50_inst : entity altpll50+ port map+ (inclk0 => CLOCK_50(0)+ ,c0 => system1000+ ,areset => not KEY0(0)+ ,locked => altpll50_locked);++ -- reset system1000_rstn is asynchronously asserted, but synchronously de-asserted+ resetSync_n_0 : block+ signal n_1 : std_logic;+ signal n_2 : std_logic;+ begin+ process(system1000,altpll50_locked)+ begin+ if altpll50_locked = '0' then+ n_1 <= '0';+ n_2 <= '0';+ elsif rising_edge(system1000) then+ n_1 <= '1';+ n_2 <= n_1;+ end if;+ end process;++ system1000_rstn <= n_2;+ end block;++ topEntity_0_inst : entity topEntity_0+ port map+ (key1_i1 => KEY1+ ,system1000 => system1000+ ,system1000_rstn => system1000_rstn+ ,topLet_o => LED);+end;+@++Where we now have:++* A top-level component that is called @blinker@.+* Inputs and outputs that have a /user/-chosen name: @KEY1@, @LED@, etc.+* An instantiated <https://www.altera.com/literature/ug/ug_altpll.pdf PLL>+ component providing a stable clock signal from the free-running clock pin+ @CLOCK_50@.+* A reset that is /asynchronously/ asserted by the @lock@ signal originating from+ the PLL, meaning that your design is kept in reset until the PLL is+ providing a stable clock.+ The reset is additionally /synchronously/ de-asserted to prevent+ <http://en.wikipedia.org/wiki/Metastability_in_electronics metastability>+ of your design due to unlucky timing of the de-assertion of the reset.++See the documentation of 'TopEntity' for the meaning of all its fields.+-}+module CLaSH.Annotations.TopEntity+ ( -- * Data types+ TopEntity (..)+ , ClockSource (..)+ -- * Convenience functions+ , defTop+ , defClkAltera+ , defClkXilinx+ )+where++import Data.Data+import CLaSH.Signal.Explicit (systemClock)++-- | TopEntity annotation+data TopEntity+ = TopEntity+ { t_name :: String -- ^ The name the top-level component should+ -- have, put in a correspondingly named file.+ , t_inputs :: [String] -- ^ List of names that are assigned in-order+ -- to the inputs of the component.+ , t_outputs :: [String] -- ^ List of names that are assigned in-order+ -- to the outputs of the component.+ , t_extraIn :: [(String,Int)]+ -- ^ Extra input ports, where every tuple holds the name of the input port and+ -- the number of bits are used for that input port.+ --+ -- So given a bit-width @n@, the port has type:+ --+ -- @std_logic_vector (n-1 downto 0)@ in VHDL+ --+ -- and+ --+ -- @logic [n-1:0]@ in (System)Verilog.+ , t_extraOut :: [(String,Int)]+ -- ^ Extra output ports, where every tuple holds the name of the input port+ -- and the number of bits are used for that input port.+ --+ -- So given a bit-width @n@, the port has type:+ --+ -- @std_logic_vector (n-1 downto 0)@ in VHDL+ --+ -- and+ --+ -- @logic [n-1:0]@ in (System)Verilog.+ , t_clocks :: [ClockSource] -- ^ List of clock sources+ }+ deriving (Data,Show)++-- | A clock source+data ClockSource+ = ClockSource+ { c_name :: String -- ^ Component name+ , c_inp :: Maybe (String,String) -- ^ optional: @(Input port, clock pin/expression)@+ , c_outp :: [(String,String)]+ -- ^ List of @(Output port, clock)@+ --+ -- The best way to create the 'String' representing the name of the clock is+ -- to 'show' the corresponding singleton clock ('CLaSH.Signal.Explicit.sclock').+ --+ -- So given that you your design is synchronised to the 'CLaSH.Signal.Explicit.SystemClock'+ -- and some another clock @ClkA@+ --+ -- > type ClkA = 'Clk "clkA" 2000+ --+ -- the best way to connect output clock ports is by doing:+ --+ -- > ClockSource { ..+ -- > , c_outp = [("c0", show (sclock :: SClock SystemClock))+ -- > ,("c1", show (sclock :: SClock ClkA))+ -- > ]+ -- > , ..+ -- > }+ , c_reset :: Maybe (String,String) -- ^ optional: @(Reset port, reset pin/expression)@+ , c_lock :: String -- ^ Output port name of the clock source+ -- component indicating that the clock signal+ -- is stable.+ , c_sync :: Bool+ -- ^ Indicates whether the components synchronised by the clocks generated by+ -- this clock source are pulled out of reset simultaneously.+ --+ -- The recommended setting if 'False'.+ --+ -- When 'c_sync' is set to 'False', the compiler generates reset synchronisers+ -- which ensure that each component is synchronously pulled out of reset,+ -- preventing <http://en.wikipedia.org/wiki/Metastability_in_electronics metastability>+ -- introduced by unlucky timing of the reset de-assertion.+ --+ -- When 'c_sync' is set to 'True' those reset synchronisers are not generated+ -- and there is change for reset-induced metastability.+ }+ deriving (Data,Show)++-- | Default 'TopEntity' which has no clocks, and no specified names for the+-- input and output ports. Also has no clock sources:+--+-- >>> defTop+-- TopEntity {t_name = "topentity", t_inputs = [], t_outputs = [], t_extraIn = [], t_extraOut = [], t_clocks = []}+defTop :: TopEntity+defTop = TopEntity+ { t_name = "topentity"+ , t_inputs = []+ , t_outputs = []+ , t_extraIn = []+ , t_extraOut = []+ , t_clocks = []+ }++-- | A clock source that corresponds to the Altera PLL component with default+-- settings to provide a stable 'systemClock'.+--+-- >>> defClkAltera "altpll50" "CLOCK(0)" "not KEY(0)"+-- ClockSource {c_name = "altpll50", c_inp = Just ("inclk0","CLOCK(0)"), c_outp = [("c0","system1000")], c_reset = Just ("areset","not KEY(0)"), c_lock = "locked", c_sync = False}+--+-- Will generate the following VHDL:+--+-- > altpll50_inst : entity altpll50+-- > port map+-- > (inclk0 => CLOCK_50(0)+-- > ,c0 => system1000+-- > ,areset => not KEY0(0)+-- > ,locked => altpll50_locked);+--+-- If you are however generating (System)Verilog you should write:+--+-- >>> defClkAltera "altpll50" "CLOCK[0]" "~ KEY[0]"+-- ClockSource {c_name = "altpll50", c_inp = Just ("inclk0","CLOCK[0]"), c_outp = [("c0","system1000")], c_reset = Just ("areset","~ KEY[0]"), c_lock = "locked", c_sync = False}+--+-- so that the following (System)Verilog is created:+--+-- > altpll50 altpll50_inst+-- > (.inclk0 (CLOCK_50[0])+-- > ,.c0 (system1000)+-- > ,.areset (~ KEY0[0])+-- > ,.locked (altpll50_locked));+defClkAltera :: String -- ^ Name of the component.+ -> String -- ^ Clock Pin/Expression of the free running clock.+ -> String -- ^ Reset Pin/Expression controlling the reset of the PLL.+ -> ClockSource+defClkAltera pllName clkExpr resExpr = ClockSource+ { c_name = pllName+ , c_inp = Just ("inclk0",clkExpr)+ , c_outp = [("c0",show systemClock)]+ , c_reset = Just ("areset",resExpr)+ , c_lock = "locked"+ , c_sync = False+ }++-- | A clock source that corresponds to the Xilinx PLL/MMCM component with+-- settings to provide a stable 'systemClock'.+--+-- >>> defClkXilinx "clkwiz50" "CLOCK(0)" "not KEY(0)"+-- ClockSource {c_name = "clkwiz50", c_inp = Just ("CLK_IN1","CLOCK(0)"), c_outp = [("CLK_OUT1","system1000")], c_reset = Just ("RESET","not KEY(0)"), c_lock = "LOCKED", c_sync = False}+--+-- Will generate the following VHDL:+--+-- > clkwiz50_inst : entity clkwiz50+-- > port map+-- > (CLK_IN1 => CLOCK_50(0)+-- > ,CLK_OUT1 => system1000+-- > ,RESET => not KEY0(0)+-- > ,LOCKED => altpll50_locked);+--+-- If you are however generating (System)Verilog you should write:+--+-- >>> defClkXilinx "clkwiz50" "CLOCK[0]" "~ KEY[0]"+-- ClockSource {c_name = "clkwiz50", c_inp = Just ("CLK_IN1","CLOCK[0]"), c_outp = [("CLK_OUT1","system1000")], c_reset = Just ("RESET","~ KEY[0]"), c_lock = "LOCKED", c_sync = False}+--+-- so that the following (System)Verilog is created:+--+-- > clkwiz50 clkwiz50_inst+-- > (.CLK_IN1 (CLOCK_50[0])+-- > ,.CLK_OUT1 (system1000)+-- > ,.RESET (~ KEY0[0])+-- > ,.LOCKED (altpll50_locked));+defClkXilinx :: String -- ^ Name of the component.+ -> String -- ^ Clock Pin/Expression of the free running clock.+ -> String -- ^ Reset Pin/Expression controlling the reset of the PLL.+ -> ClockSource+defClkXilinx pllName clkExpr resExpr = ClockSource+ { c_name = pllName+ , c_inp = Just ("CLK_IN1",clkExpr)+ , c_outp = [("CLK_OUT1",show systemClock)]+ , c_reset = Just ("RESET",resExpr)+ , c_lock = "LOCKED"+ , c_sync = False+ }
src/CLaSH/Prelude.hs view
@@ -66,6 +66,8 @@ , module CLaSH.Sized.Fixed -- *** Fixed size vectors , module CLaSH.Sized.Vector+ -- ** Annotations+ , module CLaSH.Annotations.TopEntity -- ** Type-level natural numbers , module GHC.TypeLits , module CLaSH.Promoted.Nat@@ -102,6 +104,7 @@ splitAt, tail, take, unzip, unzip3, zip, zip3, zipWith, zipWith3) +import CLaSH.Annotations.TopEntity import CLaSH.Class.BitPack import CLaSH.Class.Num import CLaSH.Class.Resize@@ -137,7 +140,7 @@ "CLaSH.Prelude" re-exports most of the Haskell "Prelude" with the exception of the following: (++), (!!), concat, drop, foldl, foldl1, foldr, foldr1, head, init, iterate, last, length, map, repeat, replicate, reverse, scanl, scanr,-splitAt, tail, take, unzip, zip, zipWith.+splitAt, tail, take, unzip, unzip3, zip, zip3, zipWith, zipWith3. It instead exports the identically named functions defined in terms of 'CLaSH.Sized.Vector.Vec' at "CLaSH.Sized.Vector".
src/CLaSH/Promoted/Symbol.hs view
@@ -9,9 +9,11 @@ License : BSD2 (see the file LICENSE) Maintainer : Christiaan Baaij <christiaan.baaij@gmail.com> -}-module CLaSH.Promoted.Symbol where+module CLaSH.Promoted.Symbol+ (SSymbol (..), ssymbol, ssymbolToString)+where -import Data.Proxy (Proxy (..))+import Data.Proxy import GHC.TypeLits (KnownSymbol, Symbol, symbolVal) -- | Singleton value for a type-level string @s@
src/CLaSH/Signal/Internal.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE MagicHash #-}@@ -75,8 +76,8 @@ import Language.Haskell.TH.Syntax (Lift (..)) import CLaSH.Class.Num (ExtendingNum (..), SaturatingNum (..))-import CLaSH.Promoted.Nat (SNat)-import CLaSH.Promoted.Symbol (SSymbol)+import CLaSH.Promoted.Nat (SNat, snatToInteger)+import CLaSH.Promoted.Symbol (SSymbol, ssymbolToString) -- $setup -- >>> :set -XDataKinds@@ -94,6 +95,9 @@ data SClock (clk :: Clock) where SClock :: SSymbol name -> SNat period -> SClock ('Clk name period)++instance Show (SClock clk) where+ show (SClock nm r) = ssymbolToString nm ++ show (snatToInteger r) infixr 5 :- -- | A synchronized signal with samples of type @a@, explicitly synchronized to
src/CLaSH/Sized/Vector.hs view
@@ -1058,7 +1058,7 @@ -- However, when we try to do the same for 'Vec': -- -- @--- append xs ys = 'foldr' (:>) ys xs+-- append' xs ys = 'foldr' (:>) ys xs -- @ -- -- We get a type error
src/CLaSH/Tutorial.hs view
@@ -39,6 +39,9 @@ -- * Composition of sequential circuits -- $composition_sequential + -- * TopEntity annotations: controlling the VHDL/Verilog generation.+ -- $annotations+ -- * Advanced: Primitives -- $primitives @@ -734,6 +737,166 @@ The general rule of thumb is: always use 'mealy', unless you do pattern matching or construction of product types, then use 'mealyB'.+-}++{- $annotations+The 'TopEntity' annotations described in this section make it easier to put your+CλaSH design on an FPGA.++We can exert some control how the top level function is created by the CλaSH+compiler by annotating the @topEntity@ function with a 'TopEntity' annotation.+You apply these annotation using the @ANN@ pragma like so:++@+{\-\# ANN topEntity (TopEntity {t_name = ..., ... }) \#-\}+topEntity x = ...+@++For example, given the following specification:++@+topEntity :: Signal Bit -> Signal (BitVector 8)+topEntity key1 = leds+ where+ key1R = isRising 1 key1+ leds = mealy blinkerT (1,False,0) key1R++blinkerT (leds,mode,cntr) key1R = ((leds',mode',cntr'),leds)+ where+ -- clock frequency = 50e6 (50 MHz)+ -- led update rate = 333e-3 (every 333ms)+ cnt_max = 16650000 -- 50e6 * 333e-3++ cntr' | cntr == cnt_max = 0+ | otherwise = cntr + 1++ mode' | key1R = not mode+ | otherwise = mode++ leds' | cntr == 0 = if mode then complement leds+ else rotateL leds 1+ | otherwise = leds+@++The CλaSH compiler will normally generate the following @topEntity.vhdl@ file:++@+-- Automatically generated VHDL+library IEEE;+use IEEE.STD_LOGIC_1164.ALL;+use IEEE.NUMERIC_STD.ALL;+use IEEE.MATH_REAL.ALL;+use work.all;+use work.types.all;++entity topEntity is+ port(input_0 : in std_logic_vector(0 downto 0);+ -- clock+ system1000 : in std_logic;+ -- asynchronous reset: active low+ system1000_rstn : in std_logic;+ output_0 : out std_logic_vector(7 downto 0));+end;++architecture structural of topEntity is+begin+ topEntity_0_inst : entity topEntity_0+ port map+ (key1_i1 => input_0+ ,system1000 => system1000+ ,system1000_rstn => system1000_rstn+ ,topLet_o => output_0);+end;+@++However, if we add the following 'TopEntity' annotation in the file:++@+{\-\# ANN topEntity+ ('defTop'+ { t_name = "blinker"+ , t_inputs = [\"KEY1\"]+ , t_outputs = [\"LED\"]+ , t_extraIn = [ (\"CLOCK_50\", 1)+ , (\"KEY0\" , 1)+ ]+ , t_clocks = [ 'defClkAltera' "altpll50" "CLOCK_50(0)" "not KEY0(0)" ]+ }) \#-\}+@++The CλaSH compiler will generate the following @blinker.vhdl@ file instead:++@+-- Automatically generated VHDL+library IEEE;+use IEEE.STD_LOGIC_1164.ALL;+use IEEE.NUMERIC_STD.ALL;+use IEEE.MATH_REAL.ALL;+use work.all;+use work.types.all;++entity blinker is+ port(KEY1 : in std_logic_vector(0 downto 0);+ CLOCK_50 : in std_logic_vector(0 downto 0);+ KEY0 : in std_logic_vector(0 downto 0);+ LED : out std_logic_vector(7 downto 0));+end;++architecture structural of blinker is+ signal system1000 : std_logic;+ signal system1000_rstn : std_logic;+ signal altpll50_locked : std_logic;+begin+ altpll50_inst : entity altpll50+ port map+ (inclk0 => CLOCK_50(0)+ ,c0 => system1000+ ,areset => not KEY0(0)+ ,locked => altpll50_locked);++ -- reset system1000_rstn is asynchronously asserted, but synchronously de-asserted+ resetSync_n_0 : block+ signal n_1 : std_logic;+ signal n_2 : std_logic;+ begin+ process(system1000,altpll50_locked)+ begin+ if altpll50_locked = '0' then+ n_1 <= '0';+ n_2 <= '0';+ elsif rising_edge(system1000) then+ n_1 <= '1';+ n_2 <= n_1;+ end if;+ end process;++ system1000_rstn <= n_2;+ end block;++ topEntity_0_inst : entity topEntity_0+ port map+ (key1_i1 => KEY1+ ,system1000 => system1000+ ,system1000_rstn => system1000_rstn+ ,topLet_o => LED);+end;+@++Where we now have:++* A top-level component that is called @blinker@.+* Inputs and outputs that have a /user/-chosen name: @KEY1@, @LED@, etc.+* An instantiated <https://www.altera.com/literature/ug/ug_altpll.pdf PLL>+ component providing a stable clock signal from the free-running clock pin+ @CLOCK_50@.+* A reset that is /asynchronously/ asserted by the @lock@ signal originating from+ the PLL, meaning that your design is kept in reset until the PLL is+ providing a stable clock.+ The reset is additionally /synchronously/ de-asserted to prevent+ <http://en.wikipedia.org/wiki/Metastability_in_electronics metastability>+ of your design due to unlucky timing of the de-assertion of the reset.++See the documentation of 'TopEntity' for the meaning of all its fields. -} {- $primitives