| Copyright | (C) 2013-2015, University of Twente |
|---|---|
| License | BSD2 (see the file LICENSE) |
| Maintainer | Christiaan Baaij <christiaan.baaij@gmail.com> |
| Safe Haskell | None |
| Language | Haskell2010 |
| Extensions |
|
CLaSH.Signal.Explicit
Contents
Description
- data Signal' clk a
- data Clock = Clk Symbol Nat
- data SClock clk where
- sclock :: (KnownSymbol name, KnownNat period) => SClock (Clk name period)
- withSClock :: (KnownSymbol name, KnownNat period) => (SClock (Clk name period) -> a) -> a
- type SystemClock = Clk "system" 1000
- systemClock :: SClock SystemClock
- unsafeSynchronizer :: SClock clk1 -> SClock clk2 -> Signal' clk1 a -> Signal' clk2 a
- register' :: SClock clk -> a -> Signal' clk a -> Signal' clk a
- regEn' :: SClock clk -> a -> Signal' clk Bool -> Signal' clk a -> Signal' clk a
- class Bundle a where
- type Unbundled' clk a
- bundle' :: SClock clk -> Unbundled' clk a -> Signal' clk a
- unbundle' :: SClock clk -> Signal' clk a -> Unbundled' clk a
- simulateB' :: (Bundle a, Bundle b) => SClock clk1 -> SClock clk2 -> (Unbundled' clk1 a -> Unbundled' clk2 b) -> [a] -> [b]
Explicitly clocked synchronous signal
CλaSH supports explicitly clocked Signals in the form of:
Signal'(clk ::Clock) a
Where a is the type of the elements, and clk is the clock to which the
signal is synchronised. The type-parameter, clk, is of the kind Clock which
has types of the following shape:
Clk {- name :: -} Symbol {- period :: -} Nat
Where name is a type-level string (Symbol) representing the the
name of the clock, and period is a type-level natural number (Nat)
representing the clock period. Two concrete instances of a Clk could be:
type ClkA500 = Clk "A500" 500 type ClkB3250 = Clk "B3250" 3250
The periods of these clocks are however dimension-less, they do not refer to any explicit time-scale (e.g. nano-seconds). The reason for the lack of an explicit time-scale is that the CλaSH compiler would not be able guarantee that the circuit can run at the specified frequency. The clock periods are just there to indicate relative frequency differences between two different clocks. That is, a signal:
Signal' ClkA500 a
is synchronized to a clock that runs 6.5 times faster than the clock to which the signal:
Signal' ClkB3250 a
is synchronized to.
- NB: "Bad things"™ happen when you actually use a clock period of
0, so do not do that! - NB: You should be judicious using a clock with period of
1as you can never create a clock that faster!
A synchronized signal with samples of type a, explicitly synchronized to
a clock clk
NB: The constructor, (, is not synthesisable.:-)
Instances
| Functor (Signal' clk) | |
| Applicative (Signal' clk) | |
| Foldable (Signal' clk) | NB: Not synthesisable NB: In "
|
| Traversable (Signal' clk) | |
| Bounded a => Bounded (Signal' clk a) | |
| Enum a => Enum (Signal' clk a) | |
| Eq (Signal' clk a) | WARNING: ( |
| Fractional a => Fractional (Signal' clk a) | |
| Integral a => Integral (Signal' clk a) | WARNING: |
| Num a => Num (Signal' clk a) | |
| Ord a => Ord (Signal' clk a) | WARNING: |
| (Num a, Ord a) => Real (Signal' clk a) | WARNING: |
| Show a => Show (Signal' clk a) | |
| Bits a => Bits (Signal' clk a) | WARNING: |
| FiniteBits a => FiniteBits (Signal' clk a) | |
| Default a => Default (Signal' clk a) | |
| Lift a => Lift (Signal' clk a) | |
| SaturatingNum a => SaturatingNum (Signal' clk a) | |
| ExtendingNum a b => ExtendingNum (Signal' clk a) (Signal' clk b) | |
| type AResult (Signal' clk a) (Signal' clk b) = Signal' clk (AResult a b) | |
| type MResult (Signal' clk a) (Signal' clk b) = Signal' clk (MResult a b) |
Clock domain crossing
Clock
Singleton value for a type-level Clock with the given name and period
withSClock :: (KnownSymbol name, KnownNat period) => (SClock (Clk name period) -> a) -> a Source
type SystemClock = Clk "system" 1000 Source
The standard system clock with a period of 1000
systemClock :: SClock SystemClock Source
The singleton clock for SystemClock
Synchronisation primitive
Arguments
| :: SClock clk1 |
|
| -> SClock clk2 |
|
| -> Signal' clk1 a | |
| -> Signal' clk2 a |
The unsafeSynchronizer function is a primitive that must be used to
connect one clock domain to the other, and will be synthesised to a (bundle
of) wire(s) in the eventual circuit. This function should only be used as
part of a proper synchronisation component, such as the following dual
flip-flop synchronizer:
dualFlipFlop :: SClock clkA -> SClock clkB
-> Signal' clkA Bit -> Signal' clkB Bit
dualFlipFlop clkA clkB = register' clkB low . register' clkB low
. unsafeSynchronizer clkA clkB
The unsafeSynchronizer works in such a way that, given 2 clocks:
type Clk7 =Clk"clk7" 7 clk7 ::SClockClk7 clk7 =sclock
and
type Clk2 =Clk"clk2" 2 clk2 ::SClockClk2 clk2 =sclock
Oversampling followed by compression is the identity function plus 2 initial values:
register'clk7 i $unsafeSynchronizerclk2 clk7 $register'clk2 j $unsafeSynchronizerclk7 clk2 $register'clk7 k s == i :- j :- s
Something we can easily observe:
oversampling =register'clk2 99 .unsafeSynchronizerclk7 clk2 .register'clk7 50 almostId =register'clk7 70 .unsafeSynchronizerclk2 clk7 .register'clk2 99 .unsafeSynchronizerclk7 clk2 .register'clk7 50
>>>sample (oversampling (fromList [1..10]))[99, 50,1,1,1,2,2,2,2, 3,3,3,4,4,4,4, 5,5,5,6,6,6,6, 7,7,7,8,8,8,8, 9,9,9,10,10,10,10, ...>>>sample (almostId (fromList [1..10]))[70, 99,1,2,3,4,5,6,7,8,9,10,...
Basic circuit functions
regEn' :: SClock clk -> a -> Signal' clk Bool -> Signal' clk a -> Signal' clk a Source
Version of register' that only updates its content when its second
argument is asserted. So given:
type ClkA =Clk"A" 100 clkA ::SClockClkA clkA =sclockoscillate =register'clkA False (not1oscillate) count =regEn'clkA 0 oscillate (count + 1)
We get:
>>>sampleN 8 oscillate[False,True,False,True,False,True,False,True]>>>sampleN 8 count[0,0,1,1,2,2,3,3]
Product/Signal isomorphism
Isomorphism between a Signal of a product type (e.g. a tuple) and a
product type of Signal's.
Instances of Bundle must satisfy the following laws:
bundle'.unbundle'=idunbundle'.bundle'=id
By default, bundle' and unbundle', are defined as the identity, that is,
writing:
data D = A | B
instance Bundle D
is the same as:
data D = A | B instanceBundleD where typeUnbundled'clk D =Signal'clk Dbundle'_ s = sunbundle'_ s = s
Minimal complete definition
Nothing
Associated Types
type Unbundled' clk a Source
Methods
bundle' :: SClock clk -> Unbundled' clk a -> Signal' clk a Source
Example:
bundle' :: (Signal'clk a,Signal'clk b) ->Signal'clk (a,b)
However:
bundle' ::Signal'clkBit->Signal'clkBit
unbundle' :: SClock clk -> Signal' clk a -> Unbundled' clk a Source
Instances
| Bundle Bool | |
| Bundle Double | |
| Bundle Float | |
| Bundle Int | |
| Bundle Integer | |
| Bundle () | |
| Bundle (Maybe a) | |
| Bundle (Index n) | |
| Bundle (BitVector n) | |
| Bundle (Signed n) | |
| Bundle (Unsigned n) | |
| Bundle (Either a b) | |
| Bundle (a, b) | |
| KnownNat n => Bundle (Vec n a) | |
| Bundle (a, b, c) | |
| Bundle (Fixed rep int frac) | |
| Bundle (a, b, c, d) | |
| Bundle (a, b, c, d, e) | |
| Bundle (a, b, c, d, e, f) | |
| Bundle (a, b, c, d, e, f, g) | |
| Bundle (a, b, c, d, e, f, g, h) |
Simulation functions (not synthesisable)
Arguments
| :: (Bundle a, Bundle b) | |
| => SClock clk1 |
|
| -> SClock clk2 |
|
| -> (Unbundled' clk1 a -> Unbundled' clk2 b) | Function to simulate |
| -> [a] | |
| -> [b] |
Simulate a () function given a
list of samples of type Unbundled' clk1 a -> Unbundled' clk2 ba
type ClkA =Clk"A" 100 clkA ::SClockClkA clkA =sclock
>>>simulateB' clkA clkA (unbundle' clkA . register' clkA (8,8) . bundle' clkA) [(1,1), (2,2), (3,3)] :: [(Int,Int)][(8,8), (1,1), (2,2), (3,3), *** Exception: finite list
NB: This function is not synthesisable