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
62from abc import abstractproperty
73
1511from math import log , log10 , exp , pi
1612from 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-
2716class 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