Advertisement
Sidsh

Blinker Haskell;

Jun 26th, 2022
246
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. {-# OPTIONS_GHC -fno-warn-orphans #-}
  2. module Blinker where
  3.  
  4. import Clash.Prelude
  5. import Clash.Intel.ClockGen
  6. import Clash.Annotations.SynthesisAttributes
  7.  
  8. -- Define a synthesis domain with a clock with a period of 20000 /ps/.
  9. -- i.e. 50 MHz
  10. createDomain vSystem{vName="Input", vPeriod=20000}
  11.  
  12. -- Define a synthesis domain with a clock with a period of 50000 /ps/.
  13. -- i.e. 20 MHz
  14. createDomain vSystem{vName="Dom20MHz", vPeriod=50000}
  15.  
  16. {-# ANN topEntity
  17.   (Synthesize
  18.     { t_name   = "blinker"
  19.     , t_inputs = [ PortName "CLOCK_50"
  20.                  , PortName "KEY0"
  21.                  , PortName "KEY1"
  22.                  ]
  23.     , t_output = PortName "LED"
  24.     }) #-}
  25. topEntity ::
  26.   -- | Incoming clock
  27.   --
  28.   -- Annotate with attributes to map the argument to the correct pin,
  29.   -- with the correct voltage settings, on the DE0-Nano development kit.
  30.   Clock Input
  31.     `Annotate` 'StringAttr "chip_pin" "R8"
  32.    `Annotate` 'StringAttr
  33.                 "altera_attribute" "-name IO_STANDARD \"3.3-V LVTTL\"" ->
  34.   -- | Reset signal, straight from KEY0
  35.   Signal Input Bool
  36.     `Annotate` 'StringAttr "chip_pin" "J15"
  37.    `Annotate` 'StringAttr
  38.                 "altera_attribute" "-name IO_STANDARD \"3.3-V LVTTL\"" ->
  39.   -- | Mode choice, straight from KEY1. See 'LedMode'.
  40.   Signal Dom20MHz Bit
  41.     `Annotate` 'StringAttr "chip_pin" "E1"
  42.    `Annotate` 'StringAttr
  43.                 "altera_attribute" "-name IO_STANDARD \"3.3-V LVTTL\"" ->
  44.   -- | Output containing 8 bits, corresponding to 8 LEDs
  45.   --
  46.   -- Use comma-seperated list in the "chip_pin" attribute to maps the
  47.   -- individual bits of the result to the correct pins on the DE0-Nano
  48.   -- development kit
  49.   Signal Dom20MHz (BitVector 8)
  50.     `Annotate` 'StringAttr
  51.                "chip_pin" "L3, B1, F3, D1, A11, B13, A13, A15"
  52.    `Annotate` 'StringAttr
  53.                 "altera_attribute" "-name IO_STANDARD \"3.3-V LVTTL\""
  54. topEntity clk50Mhz rstBtn modeBtn =
  55.   -- Connect our clock, reset, and enable lines to the corresponding
  56.   -- /implicit/ arguments of the 'mealy' and 'isRising' function.
  57.   exposeClockResetEnable
  58.     (mealy blinkerT initialStateBlinkerT . isRising 1)
  59.     clk20Mhz
  60.     rstSync
  61.     en
  62.     modeBtn
  63.   where
  64.   -- Enable line for subcomponents: we'll keep it always running
  65.   en = enableGen
  66.  
  67.   -- Start with the first LED turned on, in rotate mode, with the counter
  68.   -- on zero
  69.   initialStateBlinkerT = (1, Rotate, 0)
  70.  
  71.   -- Signal coming from the reset button is low when pressed, and high when
  72.   -- not pressed. We convert this signal to the polarity of our domain with
  73.   -- 'unsafeFromLowPolarity'.
  74.   rst = unsafeFromLowPolarity rstBtn
  75.  
  76.   -- Instantiate a PLL: this stabilizes the incoming clock signal and
  77.   -- indicates when the signal is stable. We're also using it to transform
  78.   -- an incoming clock signal running at 50 MHz to a clock signal running at
  79.   -- 20 MHz.
  80.   (clk20Mhz, pllStable) =
  81.     altpll
  82.       @Dom20MHz
  83.       (SSymbol @"altpll20")
  84.       clk50Mhz
  85.       rst
  86.  
  87.   -- Synchronize reset to clock signal coming from PLL. We want the reset to
  88.   -- remain asserted while the PLL is NOT stable, hence the conversion with
  89.   -- 'unsafeFromLowPolarity'
  90.   rstSync =
  91.     resetSynchronizer
  92.       clk20Mhz
  93.       (unsafeFromLowPolarity pllStable)
  94.  
  95. data LedMode
  96.   -- | After some period, rotate active led to the left
  97.   = Rotate
  98.   -- | After some period, turn on all LEDs that are turned off, and vice versa
  99.   | Complement
  100.   deriving (Generic, NFDataX)
  101.  
  102. flipMode :: LedMode -> LedMode
  103. flipMode Rotate = Complement
  104. flipMode Complement = Rotate
  105.  
  106. -- Finally, the actual behavior of the circuit
  107. blinkerT ::
  108.   (BitVector 8, LedMode, Index 6660000) ->
  109.   Bool ->
  110.   ((BitVector 8, LedMode, Index 6660000), BitVector 8)
  111. blinkerT (leds, mode, cntr) key1R = ((ledsN, modeN, cntrN), leds)
  112.   where
  113.     -- clock frequency = 20e6  (20 MHz)
  114.     -- led update rate = 333e-3 (every 333ms)
  115.     cnt_max = maxBound :: Index 6660000 -- 20e6 * 333e-3
  116.  
  117.     cntrN | cntr == cnt_max = 0
  118.           | otherwise       = cntr + 1
  119.  
  120.     modeN | key1R     = flipMode mode
  121.           | otherwise = mode
  122.  
  123.     ledsN | cntr == 0 =
  124.               case mode of
  125.                 Rotate -> rotateL leds 1
  126.                 Complement -> complement leds
  127.           | otherwise = leds
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement