Skip to content

Commit 750a0ab

Browse files
committed
update Lattice Nexus vendor platform to comply with RFC#18
1 parent 92fdf9b commit 750a0ab

File tree

2 files changed

+144
-23
lines changed

2 files changed

+144
-23
lines changed

amaranth/vendor/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"LatticeICE40Platform",
1111
"LatticeMachXO2Platform",
1212
"LatticeMachXO3LPlatform",
13+
"LatticeNexusPlatform",
1314
"QuicklogicPlatform",
1415
"XilinxPlatform",
1516
]
@@ -35,6 +36,9 @@ def __getattr__(name):
3536
if name in ("LatticeMachXO2Platform", "LatticeMachXO3LPlatform"):
3637
from ._lattice_machxo_2_3l import LatticeMachXO2Or3LPlatform
3738
return LatticeMachXO2Or3LPlatform
39+
if name == "LatticeNexusPlatform":
40+
from ._lattice_nexus import LatticeNexusPlatform
41+
return LatticeNexusPlatform
3842
if name == "QuicklogicPlatform":
3943
from ._quicklogic import QuicklogicPlatform
4044
return QuicklogicPlatform

amaranth/vendor/lattice_nexus.py renamed to amaranth/vendor/_lattice_nexus.py

Lines changed: 140 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
# NXOSCA and NXPLL is part of LiteX. Modified for Amaranth Nexus Platform (Nate Slager <slagernate@gmail.com>)
2-
# Copyright (c) 2020 David Corrigan <davidcorrigan714@gmail.com>
3-
# SPDX-License-Identifier: BSD-2-Clause
4-
51

62
from abc import abstractproperty
73

@@ -15,15 +11,8 @@
1511
from math import log, log10, exp, pi
1612
from cmath import phase
1713

18-
io_i2 = namedtuple('io_i2',['io', 'i2', 'IPP_CTRL', 'BW_CTL_BIAS', 'IPP_SEL'])
19-
nx_pll_param_permutation = namedtuple("nx_pll_param_permutation",[
20-
"C1","C2","C3","C4","C5","C6",
21-
"IPP_CTRL","BW_CTL_BIAS","IPP_SEL","CSET","CRIPPLE","V2I_PP_RES","IPI_CMP"])
22-
2314
__all__ = ["LatticeNexusPlatform"]
2415

25-
### Warning, this platform was adapted from the ECP5 and has not yet been verified
26-
2716
class LatticeNexusPlatform(TemplatedPlatform):
2817
"""
2918
.. rubric:: Oxide toolchain
@@ -228,9 +217,9 @@ class LatticeNexusPlatform(TemplatedPlatform):
228217
"{{name}}.sdc": r"""
229218
{% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%}
230219
{% if port_signal is not none -%}
231-
create_clock -name {{port_signal.name|tcl_escape}} -period {{1000000000/frequency}} [get_ports "{{port_signal.name}}"]
220+
create_clock -name {{port_signal.name|tcl_escape}} -period {{1000000000/frequency}} [get_ports {{port_signal.name}}]
232221
{% else -%}
233-
create_clock -name "{{net_signal.name|tcl_escape}}" -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")}}]
222+
create_clock -name {{net_signal.name|tcl_escape}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")}}]
234223
{% endif %}
235224
{% endfor %}
236225
{{get_override("add_constraints")|default("# (add_constraints placeholder)")}}
@@ -240,7 +229,7 @@ class LatticeNexusPlatform(TemplatedPlatform):
240229
{% for port_name, pin_name, attrs in platform.iter_port_constraints_bits() -%}
241230
ldc_set_location -site "{{pin_name}}" [get_ports {{port_name|tcl_escape}}]
242231
{% if attrs -%}
243-
ldc_set_port -iobuf "{%- for key, value in attrs.items() %} {{key}}={{value}}{% endfor %}" [get_ports {{port_name|tcl_escape}}]
232+
ldc_set_port -iobuf { {%- for key, value in attrs.items() %} {{key}}={{value}}{% endfor %} } [get_ports {{port_name|tcl_escape}}]
244233
{% endif %}
245234
{% endfor %}
246235
{{get_override("add_preferences")|default("# (add_preferences placeholder)")}}
@@ -466,7 +455,7 @@ def get_iddrx2(sclk, eclk, d, q0, q1, q2, q3):
466455
o_Q1=q1[bit],
467456
o_Q2=q2[bit],
468457
o_Q3=q3[bit],
469-
)
458+
)
470459

471460
def get_iddr71(sclk, eclk, d, q0, q1, q2, q3, q4, q5, q6):
472461
for bit in range(len(d)):
@@ -485,6 +474,44 @@ def get_iddr71(sclk, eclk, d, q0, q1, q2, q3, q4, q5, q6):
485474
#p_GSR="DISABLED",
486475
)
487476

477+
def get_iddrx4(sclk, eclk, d, q0, q1, q2, q3, q4, q5, q6, q7):
478+
for bit in range(len(d)):
479+
m.submodules += Instance("IDDRX4",
480+
i_SCLK=sclk,
481+
i_ECLK=eclk,
482+
i_RST=Const(0),
483+
i_ALIGNWD=Const(0),
484+
i_D=d[bit],
485+
o_Q0=q0[bit],
486+
o_Q1=q1[bit],
487+
o_Q2=q2[bit],
488+
o_Q3=q3[bit],
489+
o_Q4=q4[bit],
490+
o_Q5=q5[bit],
491+
o_Q6=q6[bit],
492+
o_Q7=q7[bit],
493+
)
494+
495+
def get_iddrx5(sclk, eclk, d, q0, q1, q2, q3, q4, q5, q6, q7, q8, q9):
496+
for bit in range(len(d)):
497+
m.submodules += Instance("IDDRX5",
498+
i_SCLK=sclk,
499+
i_ECLK=eclk,
500+
i_RST=Const(0),
501+
i_ALIGNWD=Const(0),
502+
i_D=d[bit],
503+
o_Q0=q0[bit],
504+
o_Q1=q1[bit],
505+
o_Q2=q2[bit],
506+
o_Q3=q3[bit],
507+
o_Q4=q4[bit],
508+
o_Q5=q5[bit],
509+
o_Q6=q6[bit],
510+
o_Q7=q7[bit],
511+
o_Q8=q8[bit],
512+
o_Q9=q9[bit],
513+
)
514+
488515
def get_oddr(sclk, d0, d1, q):
489516
for bit in range(len(q)):
490517
m.submodules += Instance("ODDRX1",
@@ -524,6 +551,42 @@ def get_oddr71b(sclk, eclk, d0, d1, d2, d3, d4, d5, d6, q):
524551
o_Q=q[bit],
525552
)
526553

554+
def get_oddrx4(sclk, eclk, d0, d1, d2, d3, d4, d5, d6, d7, q):
555+
for bit in range(len(d)):
556+
m.submodules += Instance("ODDRX4",
557+
i_SCLK=sclk,
558+
i_ECLK=eclk,
559+
i_RST=Const(0),
560+
i_D0=d0[bit],
561+
i_D1=d1[bit],
562+
i_D2=d2[bit],
563+
i_D3=d3[bit],
564+
i_D4=d4[bit],
565+
i_D5=d5[bit],
566+
i_D6=d6[bit],
567+
i_D7=d7[bit],
568+
o_Q=q[bit],
569+
)
570+
571+
def get_oddrx5(sclk, eclk, d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, q):
572+
for bit in range(len(d)):
573+
m.submodules += Instance("ODDRX5",
574+
i_SCLK=sclk,
575+
i_ECLK=eclk,
576+
i_RST=Const(0),
577+
i_D0=d0[bit],
578+
i_D1=d1[bit],
579+
i_D2=d2[bit],
580+
i_D3=d3[bit],
581+
i_D4=d4[bit],
582+
i_D5=d5[bit],
583+
i_D6=d6[bit],
584+
i_D7=d7[bit],
585+
i_D8=d8[bit],
586+
i_D9=d9[bit],
587+
o_Q=q[bit],
588+
)
589+
527590
def get_ineg(z, invert):
528591
if invert:
529592
a = Signal.like(z, name_suffix="_n")
@@ -559,6 +622,26 @@ def get_oneg(a, invert):
559622
pin_i4 = get_ineg(pin.i4, i_invert)
560623
pin_i5 = get_ineg(pin.i5, i_invert)
561624
pin_i6 = get_ineg(pin.i6, i_invert)
625+
elif pin.xdr == 8:
626+
pin_i0 = get_ineg(pin.i0, i_invert)
627+
pin_i1 = get_ineg(pin.i1, i_invert)
628+
pin_i2 = get_ineg(pin.i2, i_invert)
629+
pin_i3 = get_ineg(pin.i3, i_invert)
630+
pin_i4 = get_ineg(pin.i4, i_invert)
631+
pin_i5 = get_ineg(pin.i5, i_invert)
632+
pin_i6 = get_ineg(pin.i6, i_invert)
633+
pin_i7 = get_ineg(pin.i7, i_invert)
634+
elif pin.xdr == 10:
635+
pin_i0 = get_ineg(pin.i0, i_invert)
636+
pin_i1 = get_ineg(pin.i1, i_invert)
637+
pin_i2 = get_ineg(pin.i2, i_invert)
638+
pin_i3 = get_ineg(pin.i3, i_invert)
639+
pin_i4 = get_ineg(pin.i4, i_invert)
640+
pin_i5 = get_ineg(pin.i5, i_invert)
641+
pin_i6 = get_ineg(pin.i6, i_invert)
642+
pin_i7 = get_ineg(pin.i7, i_invert)
643+
pin_i8 = get_ineg(pin.i8, i_invert)
644+
pin_i9 = get_ineg(pin.i9, i_invert)
562645
if "o" in pin.dir:
563646
if pin.xdr < 2:
564647
pin_o = get_oneg(pin.o, o_invert)
@@ -578,6 +661,26 @@ def get_oneg(a, invert):
578661
pin_o4 = get_oneg(pin.o4, o_invert)
579662
pin_o5 = get_oneg(pin.o5, o_invert)
580663
pin_o6 = get_oneg(pin.o6, o_invert)
664+
elif pin.xdr == 8:
665+
pin_o0 = get_oneg(pin.o0, o_invert)
666+
pin_o1 = get_oneg(pin.o1, o_invert)
667+
pin_o2 = get_oneg(pin.o2, o_invert)
668+
pin_o3 = get_oneg(pin.o3, o_invert)
669+
pin_o4 = get_oneg(pin.o4, o_invert)
670+
pin_o5 = get_oneg(pin.o5, o_invert)
671+
pin_o6 = get_oneg(pin.o6, o_invert)
672+
pin_o7 = get_oneg(pin.o7, o_invert)
673+
elif pin.xdr == 10:
674+
pin_o0 = get_oneg(pin.o0, o_invert)
675+
pin_o1 = get_oneg(pin.o1, o_invert)
676+
pin_o2 = get_oneg(pin.o2, o_invert)
677+
pin_o3 = get_oneg(pin.o3, o_invert)
678+
pin_o4 = get_oneg(pin.o4, o_invert)
679+
pin_o5 = get_oneg(pin.o5, o_invert)
680+
pin_o6 = get_oneg(pin.o6, o_invert)
681+
pin_o7 = get_oneg(pin.o7, o_invert)
682+
pin_o8 = get_oneg(pin.o8, o_invert)
683+
pin_o9 = get_oneg(pin.o9, o_invert)
581684

582685
i = o = t = None
583686
if "i" in pin.dir:
@@ -622,6 +725,20 @@ def get_oneg(a, invert):
622725
get_oddr71(pin.o_clk, pin.o_fclk, pin_o0, pin_o1, pin_o2, pin_o3, pin_o4, pin_o5, pin_o6, o)
623726
if pin.dir in ("oe", "io"):
624727
get_oereg(pin.o_clk, ~pin.oe, t)
728+
elif pin.xdr == 8:
729+
if "i" in pin.dir:
730+
get_iddrx4(pin.i_clk, pin.i_fclk, i, pin_i0, pin_i1, pin_i2, pin_i3, pin_i4, pin_i5, pin_i6, pin_i7)
731+
if "o" in pin.dir:
732+
get_oddrx4(pin.o_clk, pin.o_fclk, pin_o0, pin_o1, pin_o2, pin_o3, pin_o4, pin_o5, pin_o6, pin_07, o)
733+
if pin.dir in ("oe", "io"):
734+
get_oereg(pin.o_clk, ~pin.oe, t)
735+
elif pin.xdr == 10:
736+
if "i" in pin.dir:
737+
get_iddrx5(pin.i_clk, pin.i_fclk, i, pin_i0, pin_i1, pin_i2, pin_i3, pin_i4, pin_i5, pin_i6, pin_i7, pin_i8, pin_i9)
738+
if "o" in pin.dir:
739+
get_oddrx5(pin.o_clk, pin.o_fclk, pin_o0, pin_o1, pin_o2, pin_o3, pin_o4, pin_o5, pin_o6, pin_07, pin_o8, pin_o9, o)
740+
if pin.dir in ("oe", "io"):
741+
get_oereg(pin.o_clk, ~pin.oe, t)
625742
else:
626743
assert False
627744

@@ -632,7 +749,7 @@ def get_input(self, pin, port, attrs, invert):
632749
"single-ended input",
633750
pin,
634751
attrs,
635-
valid_xdrs=(0, 1, 2, 4, 7),
752+
valid_xdrs=(0, 1, 2, 4, 7, 8, 10),
636753
valid_attrs=True,
637754
)
638755
m = Module()
@@ -649,7 +766,7 @@ def get_output(self, pin, port, attrs, invert):
649766
"single-ended output",
650767
pin,
651768
attrs,
652-
valid_xdrs=(0, 1, 2, 4, 7),
769+
valid_xdrs=(0, 1, 2, 4, 7, 8, 10),
653770
valid_attrs=True,
654771
)
655772
m = Module()
@@ -666,7 +783,7 @@ def get_tristate(self, pin, port, attrs, invert):
666783
"single-ended tristate",
667784
pin,
668785
attrs,
669-
valid_xdrs=(0, 1, 2, 4, 7),
786+
valid_xdrs=(0, 1, 2, 4, 7, 8, 10),
670787
valid_attrs=True,
671788
)
672789
m = Module()
@@ -684,7 +801,7 @@ def get_input_output(self, pin, port, attrs, invert):
684801
"single-ended input/output",
685802
pin,
686803
attrs,
687-
valid_xdrs=(0, 1, 2, 4, 7),
804+
valid_xdrs=(0, 1, 2, 4, 7, 8, 10),
688805
valid_attrs=True,
689806
)
690807
m = Module()
@@ -703,7 +820,7 @@ def get_diff_input(self, pin, port, attrs, invert):
703820
"differential input",
704821
pin,
705822
attrs,
706-
valid_xdrs=(0, 1, 2, 4, 7),
823+
valid_xdrs=(0, 1, 2, 4, 7, 8, 10),
707824
valid_attrs=True,
708825
)
709826
m = Module()
@@ -720,7 +837,7 @@ def get_diff_output(self, pin, port, attrs, invert):
720837
"differential output",
721838
pin,
722839
attrs,
723-
valid_xdrs=(0, 1, 2, 4, 7),
840+
valid_xdrs=(0, 1, 2, 4, 7, 8, 10),
724841
valid_attrs=True,
725842
)
726843
m = Module()
@@ -737,7 +854,7 @@ def get_diff_tristate(self, pin, port, attrs, invert):
737854
"differential tristate",
738855
pin,
739856
attrs,
740-
valid_xdrs=(0, 1, 2, 4, 7),
857+
valid_xdrs=(0, 1, 2, 4, 7, 8, 10),
741858
valid_attrs=True,
742859
)
743860
m = Module()
@@ -755,7 +872,7 @@ def get_diff_input_output(self, pin, port, attrs, invert):
755872
"differential input/output",
756873
pin,
757874
attrs,
758-
valid_xdrs=(0, 1, 2, 4, 7),
875+
valid_xdrs=(0, 1, 2, 4, 7, 8, 10),
759876
valid_attrs=True,
760877
)
761878
m = Module()

0 commit comments

Comments
 (0)