f2e6b2e5666634263fcdb76981a55144031621bd
1 from migen
.fhdl
.std
import *
2 from migen
.fhdl
.specials
import Tristate
3 from migen
.genlib
.cdc
import MultiReg
4 from migen
.genlib
.fsm
import FSM
, NextState
5 from migen
.genlib
.misc
import chooser
6 from migen
.bank
.description
import CSRStorage
, CSRStatus
, AutoCSR
9 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x3D, 0x17, 0x32, 0x12, 0x2A, 0x6A, 0xBF, 0x00,
10 0x05, 0x17, 0x01, 0x03, 0x80, 0x28, 0x1E, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
12 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xB2, 0x0C, 0x00, 0x40, 0x41, 0x00, 0x26, 0x30, 0x18, 0x88,
13 0x36, 0x00, 0x28, 0x1E, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x4D, 0x31, 0x20,
14 0x44, 0x56, 0x49, 0x20, 0x6D, 0x69, 0x78, 0x65, 0x72, 0x0A, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
15 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
16 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34,
19 class EDID(Module
, AutoCSR
):
20 def __init__(self
, pads
, default
=_default_edid
):
21 self
._r
_hpd
_notif
= CSRStatus()
22 self
._r
_hpd
_en
= CSRStorage()
23 self
.specials
.mem
= Memory(8, 128, init
=default
)
28 if hasattr(pads
, "hpd_notif"):
29 self
.specials
+= MultiReg(pads
.hpd_notif
, self
._r
_hpd
_notif
.status
)
31 self
.comb
+= self
._r
_hpd
_notif
.status
.eq(1)
32 if hasattr(pads
, "hpd_en"):
33 self
.comb
+= pads
.hpd_en
.eq(self
._r
_hpd
_en
.storage
)
39 _sda_drv_reg
= Signal()
40 _sda_i_async
= Signal()
41 self
.sync
+= _sda_drv_reg
.eq(sda_drv
)
43 MultiReg(pads
.scl
, scl_raw
),
44 Tristate(pads
.sda
, 0, _sda_drv_reg
, _sda_i_async
),
45 MultiReg(_sda_i_async
, sda_i
)
49 samp_count
= Signal(6)
52 Cat(samp_count
, samp_carry
).eq(samp_count
+ 1),
53 If(samp_carry
, scl_i
.eq(scl_raw
))
60 sda_falling
= Signal()
66 scl_rising
.eq(scl_i
& ~scl_r
),
67 sda_rising
.eq(sda_i
& ~sda_r
),
68 sda_falling
.eq(~sda_i
& sda_r
)
72 self
.comb
+= start
.eq(scl_i
& sda_falling
)
75 counter
= Signal(max=9)
77 If(start
, counter
.eq(0)),
82 counter
.eq(counter
+ 1),
83 din
.eq(Cat(sda_i
, din
[:7]))
89 update_is_read
= Signal()
90 self
.sync
+= If(update_is_read
, is_read
.eq(din
[0]))
92 offset_counter
= Signal(max=128)
97 offset_counter
.eq(din
)
99 offset_counter
.eq(offset_counter
+ 1)
102 rdport
= self
.mem
.get_port()
103 self
.specials
+= rdport
104 self
.comb
+= rdport
.adr
.eq(offset_counter
)
109 self
.comb
+= If(zero_drv
, sda_drv
.eq(1)).Elif(data_drv
, sda_drv
.eq(~data_bit
))
111 data_drv_en
= Signal()
112 data_drv_stop
= Signal()
113 self
.sync
+= If(data_drv_en
, data_drv
.eq(1)).Elif(data_drv_stop
, data_drv
.eq(0))
114 self
.sync
+= If(data_drv_en
, chooser(rdport
.dat_r
, counter
, data_bit
, 8, reverse
=True))
117 self
.submodules
+= fsm
119 fsm
.act("WAIT_START")
120 fsm
.act("RCV_ADDRESS",
123 update_is_read
.eq(1),
124 NextState("ACK_ADDRESS0")
126 NextState("WAIT_START")
130 fsm
.act("ACK_ADDRESS0",
131 If(~scl_i
, NextState("ACK_ADDRESS1"))
133 fsm
.act("ACK_ADDRESS1",
135 If(scl_i
, NextState("ACK_ADDRESS2"))
137 fsm
.act("ACK_ADDRESS2",
143 NextState("RCV_OFFSET")
148 fsm
.act("RCV_OFFSET",
151 NextState("ACK_OFFSET0")
154 fsm
.act("ACK_OFFSET0",
155 If(~scl_i
, NextState("ACK_OFFSET1"))
157 fsm
.act("ACK_OFFSET1",
159 If(scl_i
, NextState("ACK_OFFSET2"))
161 fsm
.act("ACK_OFFSET2",
163 If(~scl_i
, NextState("RCV_ADDRESS"))
170 NextState("ACK_READ")
180 NextState("WAIT_START")
187 for state
in fsm
.actions
.keys():
188 fsm
.act(state
, If(start
, NextState("RCV_ADDRESS")))
189 fsm
.act(state
, If(~self
._r
_hpd
_en
.storage
, NextState("WAIT_START")))