ice40-prim-0.3.0.1: src/Ice40/Led.hs
{-|
Module : Ice40.Led
Description : LED Ice40 hard IP primitive
Copyright : (c) David Cox, 2021
License : BSD 3-Clause
Maintainer : standardsemiconductor@gmail.com
LED hard IP primitive from [Lattice Ice Technology Library](https://github.com/standardsemiconductor/VELDT-info/blob/master/SBTICETechnologyLibrary201708.pdf). See [iCE40 LED Driver Usage Guide](https://github.com/standardsemiconductor/VELDT-info/blob/master/ICE40LEDDriverUsageGuide.pdf) for more information.
-}
module Ice40.Led ( led ) where
import Clash.Prelude
import Clash.Annotations.Primitive
import Data.String.Interpolate (i)
import Data.String.Interpolate.Util (unindent)
{-# ANN ledPrim (InlinePrimitive [Verilog] $ unindent [i|
[ { "BlackBox" :
{ "name" : "Ice40.Led.ledPrim"
, "kind" : "Declaration"
, "type" :
"ledPrim
:: Signal dom Bit -- ARG[0] leddcs
-> Clock dom -- ARG[1] leddclk
-> Signal dom Bit -- ARG[2] ledddat7
-> Signal dom Bit -- ARG[3] ledddat6
-> Signal dom Bit -- ARG[4] ledddat5
-> Signal dom Bit -- ARG[5] ledddat4
-> Signal dom Bit -- ARG[6] ledddat3
-> Signal dom Bit -- ARG[7] ledddat2
-> Signal dom Bit -- ARG[8] ledddat1
-> Signal dom Bit -- ARG[9] ledddat0
-> Signal dom Bit -- ARG[10] leddaddr3
-> Signal dom Bit -- ARG[11] leddaddr2
-> Signal dom Bit -- ARG[12] leddaddr1
-> Signal dom Bit -- ARG[13] leddaddr0
-> Signal dom Bool -- ARG[14] leddden
-> Signal dom Bool -- ARG[15] leddexe
-> Unbundled dom ( Bit -- pwmOut0
, Bit -- pwmOut1
, Bit -- pwmOut2
, Bool -- leddon
)"
, "template" :
"//SB_LEDDA_IP begin
wire ~GENSYM[pwmOut0][0];
wire ~GENSYM[pwmOut1][1];
wire ~GENSYM[pwmOut2][2];
wire ~GENSYM[leddon][3];
SB_LEDDA_IP SB_LEDDA_IP_INST (
.LEDDCS ( ~ARG[0] ),
.LEDDCLK ( ~ARG[1] ),
.LEDDDAT7 ( ~ARG[2] ),
.LEDDDAT6 ( ~ARG[3] ),
.LEDDDAT5 ( ~ARG[4] ),
.LEDDDAT4 ( ~ARG[5] ),
.LEDDDAT3 ( ~ARG[6] ),
.LEDDDAT2 ( ~ARG[7] ),
.LEDDDAT1 ( ~ARG[8] ),
.LEDDDAT0 ( ~ARG[9] ),
.LEDDADDR3 ( ~ARG[10] ),
.LEDDADDR2 ( ~ARG[11] ),
.LEDDADDR1 ( ~ARG[12] ),
.LEDDADDR0 ( ~ARG[13] ),
.LEDDDEN ( ~ARG[14] ),
.LEDDEXE ( ~ARG[15] ),
.PWMOUT0 ( ~SYM[0] ),
.PWMOUT1 ( ~SYM[1] ),
.PWMOUT2 ( ~SYM[2] ),
.LEDDON ( ~SYM[3] )
);
assign ~RESULT = {~SYM[0], ~SYM[1], ~SYM[2], ~SYM[3]};
//SB_LEDDA_IP end"
}
}
]
|]) #-}
{-# NOINLINE ledPrim #-}
ledPrim
:: Signal dom Bit -- ARG[0] leddcs - CS to write LEDD IP registers
-> Clock dom -- ARG[1] leddclk - Clock to write LEDD IP registers
-> Signal dom Bit -- ARG[2] ledddat7 - bit 7 data to write into the LEDD IP registers
-> Signal dom Bit -- ARG[3] ledddat6 - bit 6 data to write into the LEDD IP registers
-> Signal dom Bit -- ARG[4] ledddat5 - bit 5 data to write into the LEDD IP registers
-> Signal dom Bit -- ARG[5] ledddat4 - bit 4 data to write into the LEDD IP registers
-> Signal dom Bit -- ARG[6] ledddat3 - bit 3 data to write into the LEDD IP registers
-> Signal dom Bit -- ARG[7] ledddat2
-> Signal dom Bit -- ARG[8] ledddat1
-> Signal dom Bit -- ARG[9] ledddat0
-> Signal dom Bit -- ARG[10] leddaddr3
-> Signal dom Bit -- ARG[11] leddaddr2
-> Signal dom Bit -- ARG[12] leddaddr1
-> Signal dom Bit -- ARG[13] leddaddr0
-> Signal dom Bool -- ARG[14] leddden
-> Signal dom Bool -- ARG[15] leddexe
-> Unbundled dom ( Bit -- pwmOut0
, Bit -- pwmOut1
, Bit -- pwmOut2
, Bool -- leddon
)
ledPrim !_ !_ !_ !_ !_ !_ !_ !_ !_ !_ !_ !_ !_ !_ !_ !_ = (pure 0, pure 0, pure 0, pure False)
-- | SB_LEDDA_IP primitive generates the RGB PWM outputs for the RGB LED drivers.
--
-- LED Control Bus Addressable Registers
--
-- +---------------+----------+-------------------------------------------+--------+
-- | LEDD_ADR[3:0] | Name | Usage | Access |
-- +===============+==========+===========================================+========+
-- | 1000 | LEDDCR0 | LED Driver Control Register 0 | W |
-- +---------------+----------+-------------------------------------------+--------+
-- | 1001 | LEDDBR | LED Driver Pre-scale Register | W |
-- +---------------+----------+-------------------------------------------+--------+
-- | 1010 | LEDDONR | LED Driver ON Time Register | W |
-- +---------------+----------+-------------------------------------------+--------+
-- | 1011 | LEDDOFR | LED Driver OFF Time Register | W |
-- +---------------+----------+-------------------------------------------+--------+
-- | 0101 | LEDDBCRR | LED Driver Breathe On Control Register | W |
-- +---------------+----------+-------------------------------------------+--------+
-- | 0110 | LEDDBCFR | LED Driver Breate Off Control Register | W |
-- +---------------+----------+-------------------------------------------+--------+
-- | 0001 | LEDDPWRR | LED Driver Pulse Width Register for RED | W |
-- +---------------+----------+-------------------------------------------+--------+
-- | 0010 | LEDDPWRG | LED Driver Pulse Width Register for GREEN | W |
-- +---------------+----------+-------------------------------------------+--------+
-- | 0011 | LEDDPWRB | LED Driver Pulse Width Register for BLUE | W |
-- +---------------+----------+-------------------------------------------+--------+
led
:: HiddenClock dom
=> Signal dom Bit -- ^ cs - CS to write LEDD IP registers
-> Signal dom (BitVector 8) -- ^ dat - data to write into the LEDD IP registers
-> Signal dom (BitVector 4) -- ^ addr - LEDD IP register address
-> Signal dom Bool -- ^ en - data enable input to indicate data and address are stable
-> Signal dom Bool -- ^ exe - enable to IP to run the blinking sequence. When it is LOW, the sequence stops at the nearest OFF state
-> Unbundled dom ( Bit
, Bit
, Bit
, Bool
) -- ^ (pwmOut0, pwmOut1, pwmOut2, LED on indicator)
led cs dat addr en exe = (pwmOut0, pwmOut1, pwmOut2, on)
where
(pwmOut0, pwmOut1, pwmOut2, on) = ledPrim cs
hasClock
(bitAt 7 dat)
(bitAt 6 dat)
(bitAt 5 dat)
(bitAt 4 dat)
(bitAt 3 dat)
(bitAt 2 dat)
(bitAt 1 dat)
(bitAt 0 dat)
(bitAt 3 addr)
(bitAt 2 addr)
(bitAt 1 addr)
(bitAt 0 addr)
en
exe
bitAt :: KnownNat n => Index n -> Signal dom (BitVector n) -> Signal dom Bit
bitAt n = fmap (!n)