Skip to content

Commit 6ce2b21

Browse files
authored
vendor.lattice_ecp5: replicate OE signal for each output bit.
nextpnr can only pack OE FFs into IOLOGIC when there's one OFS1P3DX per output, rather than one shared instance.
1 parent a2da34a commit 6ce2b21

File tree

1 file changed

+19
-12
lines changed

1 file changed

+19
-12
lines changed

nmigen/vendor/lattice_ecp5.py

+19-12
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,16 @@ def get_oreg(clk, d, q):
387387
o_Q=q[bit]
388388
)
389389

390+
def get_oereg(clk, oe, q):
391+
for bit in range(len(q)):
392+
m.submodules += Instance("OFS1P3DX",
393+
i_SCLK=clk,
394+
i_SP=Const(1),
395+
i_CD=Const(0),
396+
i_D=oe,
397+
o_Q=q[bit]
398+
)
399+
390400
def get_iddr(sclk, d, q0, q1):
391401
for bit in range(len(d)):
392402
m.submodules += Instance("IDDRX1F",
@@ -508,7 +518,7 @@ def get_oneg(a, invert):
508518
if "o" in pin.dir:
509519
o = Signal(pin.width, name="{}_xdr_o".format(pin.name))
510520
if pin.dir in ("oe", "io"):
511-
t = Signal(1, name="{}_xdr_t".format(pin.name))
521+
t = Signal(pin.width, name="{}_xdr_t".format(pin.name))
512522

513523
if pin.xdr == 0:
514524
if "i" in pin.dir:
@@ -523,31 +533,28 @@ def get_oneg(a, invert):
523533
if "o" in pin.dir:
524534
get_oreg(pin.o_clk, pin_o, o)
525535
if pin.dir in ("oe", "io"):
526-
get_oreg(pin.o_clk, ~pin.oe, t)
536+
get_oereg(pin.o_clk, ~pin.oe, t)
527537
elif pin.xdr == 2:
528538
if "i" in pin.dir:
529539
get_iddr(pin.i_clk, i, pin_i0, pin_i1)
530540
if "o" in pin.dir:
531541
get_oddr(pin.o_clk, pin_o0, pin_o1, o)
532542
if pin.dir in ("oe", "io"):
533-
# It looks like Diamond will not pack an OREG as a tristate register in a DDR PIO.
534-
# It is not clear what is the recommended set of primitives for this task.
535-
# Similarly, nextpnr will not pack anything as a tristate register in a DDR PIO.
536-
get_oreg(pin.o_clk, ~pin.oe, t)
543+
get_oereg(pin.o_clk, ~pin.oe, t)
537544
elif pin.xdr == 4:
538545
if "i" in pin.dir:
539546
get_iddrx2(pin.i_clk, pin.i_fclk, i, pin_i0, pin_i1, pin_i2, pin_i3)
540547
if "o" in pin.dir:
541548
get_oddrx2(pin.o_clk, pin.o_fclk, pin_o0, pin_o1, pin_o2, pin_o3, o)
542549
if pin.dir in ("oe", "io"):
543-
get_oreg(pin.o_clk, ~pin.oe, t)
550+
get_oereg(pin.o_clk, ~pin.oe, t)
544551
elif pin.xdr == 7:
545552
if "i" in pin.dir:
546553
get_iddr71b(pin.i_clk, pin.i_fclk, i, pin_i0, pin_i1, pin_i2, pin_i3, pin_i4, pin_i5, pin_i6)
547554
if "o" in pin.dir:
548555
get_oddr71b(pin.o_clk, pin.o_fclk, pin_o0, pin_o1, pin_o2, pin_o3, pin_o4, pin_o5, pin_o6, o)
549556
if pin.dir in ("oe", "io"):
550-
get_oreg(pin.o_clk, ~pin.oe, t)
557+
get_oereg(pin.o_clk, ~pin.oe, t)
551558
else:
552559
assert False
553560

@@ -584,7 +591,7 @@ def get_tristate(self, pin, port, attrs, invert):
584591
i, o, t = self._get_xdr_buffer(m, pin, o_invert=invert)
585592
for bit in range(pin.width):
586593
m.submodules["{}_{}".format(pin.name, bit)] = Instance("OBZ",
587-
i_T=t,
594+
i_T=t[bit],
588595
i_I=o[bit],
589596
o_O=port.io[bit]
590597
)
@@ -597,7 +604,7 @@ def get_input_output(self, pin, port, attrs, invert):
597604
i, o, t = self._get_xdr_buffer(m, pin, i_invert=invert, o_invert=invert)
598605
for bit in range(pin.width):
599606
m.submodules["{}_{}".format(pin.name, bit)] = Instance("BB",
600-
i_T=t,
607+
i_T=t[bit],
601608
i_I=o[bit],
602609
o_O=i[bit],
603610
io_B=port.io[bit]
@@ -635,7 +642,7 @@ def get_diff_tristate(self, pin, port, attrs, invert):
635642
i, o, t = self._get_xdr_buffer(m, pin, o_invert=invert)
636643
for bit in range(pin.width):
637644
m.submodules["{}_{}".format(pin.name, bit)] = Instance("OBZ",
638-
i_T=t,
645+
i_T=t[bit],
639646
i_I=o[bit],
640647
o_O=port.p[bit],
641648
)
@@ -648,7 +655,7 @@ def get_diff_input_output(self, pin, port, attrs, invert):
648655
i, o, t = self._get_xdr_buffer(m, pin, i_invert=invert, o_invert=invert)
649656
for bit in range(pin.width):
650657
m.submodules["{}_{}".format(pin.name, bit)] = Instance("BB",
651-
i_T=t,
658+
i_T=t[bit],
652659
i_I=o[bit],
653660
o_O=i[bit],
654661
io_B=port.p[bit],

0 commit comments

Comments
 (0)