1 from functools
import reduce
2 from operator
import add
7 control_tokens
= [0b1101010100, 0b0010101011, 0b0101010100, 0b1010101011]
10 class Encoder(Module
):
20 # stage 1 - count number of 1s in data
24 n1d
.eq(reduce(add
, [self
.d
[i
] for i
in range(8)])),
28 # stage 2 - add 9th bit
31 self
.comb
+= q_m8_n
.eq((n1d
> 4) |
((n1d
== 4) & ~d
[0]))
34 curval
= curval ^ d
[i
] ^ q_m8_n
37 self
.sync
+= q_m
[i
].eq(curval
)
38 self
.sync
+= q_m
[8].eq(~q_m8_n
)
40 # stage 3 - count number of 1s and 0s in q_m[:8]
45 n0q_m
.eq(reduce(add
, [~q_m
[i
] for i
in range(8)])),
46 n1q_m
.eq(reduce(add
, [q_m
[i
] for i
in range(8)])),
50 # stage 4 - final encoding
51 cnt
= Signal((6, True))
58 self
.sync
+= new_c
.eq(s_c
), new_de
.eq(s_de
)
59 s_c
, s_de
= new_c
, new_de
62 If((cnt
== 0) |
(n1q_m
== n0q_m
),
63 self
.out
[9].eq(~q_m_r
[8]),
64 self
.out
[8].eq(q_m_r
[8]),
66 self
.out
[:8].eq(q_m_r
[:8]),
67 cnt
.eq(cnt
+ n1q_m
- n0q_m
)
69 self
.out
[:8].eq(~q_m_r
[:8]),
70 cnt
.eq(cnt
+ n0q_m
- n1q_m
)
73 If((~cnt
[5] & (n1q_m
> n0q_m
)) |
(cnt
[5] & (n0q_m
> n1q_m
)),
75 self
.out
[8].eq(q_m_r
[8]),
76 self
.out
[:8].eq(~q_m_r
[:8]),
77 cnt
.eq(cnt
+ Cat(0, q_m_r
[8]) + n0q_m
- n1q_m
)
80 self
.out
[8].eq(q_m_r
[8]),
81 self
.out
[:8].eq(q_m_r
[:8]),
82 cnt
.eq(cnt
- Cat(0, ~q_m_r
[8]) + n1q_m
- n0q_m
)
86 self
.out
.eq(Array(control_tokens
)[s_c
]),
91 class _EncoderSerializer(Module
):
92 def __init__(self
, serdesstrobe
, pad_p
, pad_n
):
93 self
.submodules
.encoder
= RenameClockDomains(Encoder(), "pix")
94 self
.d
, self
.c
, self
.de
= self
.encoder
.d
, self
.encoder
.c
, self
.encoder
.de
98 # 2X soft serialization
100 self
.sync
.pix2x
+= ed_2x
.eq(Mux(ClockSignal("pix"), self
.encoder
.out
[:5], self
.encoder
.out
[5:]))
102 # 5X hard serialization
103 cascade_di
= Signal()
104 cascade_do
= Signal()
105 cascade_ti
= Signal()
106 cascade_to
= Signal()
110 p_DATA_WIDTH
=5, p_DATA_RATE_OQ
="SDR", p_DATA_RATE_OT
="SDR",
111 p_SERDES_MODE
="MASTER", p_OUTPUT_MODE
="DIFFERENTIAL",
114 i_OCE
=1, i_IOCE
=serdesstrobe
, i_RST
=0,
115 i_CLK0
=ClockSignal("pix10x"), i_CLK1
=0, i_CLKDIV
=ClockSignal("pix2x"),
116 i_D1
=ed_2x
[4], i_D2
=0, i_D3
=0, i_D4
=0,
117 i_T1
=0, i_T2
=0, i_T3
=0, i_T4
=0,
119 i_SHIFTIN1
=1, i_SHIFTIN2
=1,
120 i_SHIFTIN3
=cascade_do
, i_SHIFTIN4
=cascade_to
,
121 o_SHIFTOUT1
=cascade_di
, o_SHIFTOUT2
=cascade_ti
),
123 p_DATA_WIDTH
=5, p_DATA_RATE_OQ
="SDR", p_DATA_RATE_OT
="SDR",
124 p_SERDES_MODE
="SLAVE", p_OUTPUT_MODE
="DIFFERENTIAL",
126 i_OCE
=1, i_IOCE
=serdesstrobe
, i_RST
=0,
127 i_CLK0
=ClockSignal("pix10x"), i_CLK1
=0, i_CLKDIV
=ClockSignal("pix2x"),
128 i_D1
=ed_2x
[0], i_D2
=ed_2x
[1], i_D3
=ed_2x
[2], i_D4
=ed_2x
[3],
129 i_T1
=0, i_T2
=0, i_T3
=0, i_T4
=0,
131 i_SHIFTIN1
=cascade_di
, i_SHIFTIN2
=cascade_ti
,
132 i_SHIFTIN3
=1, i_SHIFTIN4
=1,
133 o_SHIFTOUT3
=cascade_do
, o_SHIFTOUT4
=cascade_to
),
134 Instance("OBUFDS", i_I
=pad_se
, o_O
=pad_p
, o_OB
=pad_n
)
139 def __init__(self
, serdesstrobe
, pads
):
140 self
.hsync
= Signal()
141 self
.vsync
= Signal()
149 self
.submodules
.es0
= _EncoderSerializer(serdesstrobe
, pads
.data0_p
, pads
.data0_n
)
150 self
.submodules
.es1
= _EncoderSerializer(serdesstrobe
, pads
.data1_p
, pads
.data1_n
)
151 self
.submodules
.es2
= _EncoderSerializer(serdesstrobe
, pads
.data2_p
, pads
.data2_n
)
153 self
.es0
.d
.eq(self
.r
),
154 self
.es1
.d
.eq(self
.g
),
155 self
.es2
.d
.eq(self
.b
),
156 self
.es0
.c
.eq(Cat(self
.hsync
, self
.vsync
)),
159 self
.es0
.de
.eq(self
.de
),
160 self
.es1
.de
.eq(self
.de
),
161 self
.es2
.de
.eq(self
.de
),
165 class _EncoderTB(Module
):
166 def __init__(self
, inputs
):
168 self
._iter
_inputs
= iter(inputs
)
169 self
._end
_cycle
= None
170 self
.submodules
.dut
= Encoder()
171 self
.comb
+= self
.dut
.de
.eq(1)
173 def do_simulation(self
, selfp
):
174 if self
._end
_cycle
is None:
176 nv
= next(self
._iter
_inputs
)
177 except StopIteration:
178 self
._end
_cycle
= selfp
.simulator
.cycle_counter
+ 4
181 if selfp
.simulator
.cycle_counter
== self
._end
_cycle
:
183 if selfp
.simulator
.cycle_counter
> 4:
184 self
.outs
.append(selfp
.dut
.out
)
193 c
= control_tokens
.index(b
)
201 value
= _bit(b
, 0) ^
_bit(b
, 9)
202 for i
in range(1, 8):
203 value |
= (_bit(b
, i
) ^
_bit(b
, i
-1) ^
(~
_bit(b
, 8) & 1)) << i
205 return de
, hsync
, vsync
, value
207 if __name__
== "__main__":
208 from migen
.sim
.generic
import run_simulation
209 from random
import Random
212 test_list
= [rng
.randrange(256) for i
in range(500)]
213 tb
= _EncoderTB(test_list
)
216 check
= [_decode_tmds(out
)[3] for out
in tb
.outs
]
217 assert(check
== test_list
)
227 print("0/1: {}/{} ({:.2f})".format(nb0
, nb1
, nb0
/nb1
))