-
Notifications
You must be signed in to change notification settings - Fork 3
/
Led.hs
165 lines (155 loc) · 7.47 KB
/
Led.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
{-|
Module : Ice40.Led
Description : LED Ice40 hard IP primitive
Copyright : (c) David Cox, 2021-2024
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)