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
-
5
1
6
2
from abc import abstractproperty
7
3
15
11
from math import log , log10 , exp , pi
16
12
from cmath import phase
17
13
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
-
23
14
__all__ = ["LatticeNexusPlatform" ]
24
15
25
- ### Warning, this platform was adapted from the ECP5 and has not yet been verified
26
-
27
16
class LatticeNexusPlatform (TemplatedPlatform ):
28
17
"""
29
18
.. rubric:: Oxide toolchain
@@ -228,9 +217,9 @@ class LatticeNexusPlatform(TemplatedPlatform):
228
217
"{{name}}.sdc" : r"""
229
218
{% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%}
230
219
{% 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}}]
232
221
{% 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("/")}}]
234
223
{% endif %}
235
224
{% endfor %}
236
225
{{get_override("add_constraints")|default("# (add_constraints placeholder)")}}
@@ -240,7 +229,7 @@ class LatticeNexusPlatform(TemplatedPlatform):
240
229
{% for port_name, pin_name, attrs in platform.iter_port_constraints_bits() -%}
241
230
ldc_set_location -site "{{pin_name}}" [get_ports {{port_name|tcl_escape}}]
242
231
{% 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}}]
244
233
{% endif %}
245
234
{% endfor %}
246
235
{{get_override("add_preferences")|default("# (add_preferences placeholder)")}}
@@ -466,7 +455,7 @@ def get_iddrx2(sclk, eclk, d, q0, q1, q2, q3):
466
455
o_Q1 = q1 [bit ],
467
456
o_Q2 = q2 [bit ],
468
457
o_Q3 = q3 [bit ],
469
- )
458
+ )
470
459
471
460
def get_iddr71 (sclk , eclk , d , q0 , q1 , q2 , q3 , q4 , q5 , q6 ):
472
461
for bit in range (len (d )):
@@ -485,6 +474,44 @@ def get_iddr71(sclk, eclk, d, q0, q1, q2, q3, q4, q5, q6):
485
474
#p_GSR="DISABLED",
486
475
)
487
476
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
+
488
515
def get_oddr (sclk , d0 , d1 , q ):
489
516
for bit in range (len (q )):
490
517
m .submodules += Instance ("ODDRX1" ,
@@ -524,6 +551,42 @@ def get_oddr71b(sclk, eclk, d0, d1, d2, d3, d4, d5, d6, q):
524
551
o_Q = q [bit ],
525
552
)
526
553
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
+
527
590
def get_ineg (z , invert ):
528
591
if invert :
529
592
a = Signal .like (z , name_suffix = "_n" )
@@ -559,6 +622,26 @@ def get_oneg(a, invert):
559
622
pin_i4 = get_ineg (pin .i4 , i_invert )
560
623
pin_i5 = get_ineg (pin .i5 , i_invert )
561
624
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 )
562
645
if "o" in pin .dir :
563
646
if pin .xdr < 2 :
564
647
pin_o = get_oneg (pin .o , o_invert )
@@ -578,6 +661,26 @@ def get_oneg(a, invert):
578
661
pin_o4 = get_oneg (pin .o4 , o_invert )
579
662
pin_o5 = get_oneg (pin .o5 , o_invert )
580
663
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 )
581
684
582
685
i = o = t = None
583
686
if "i" in pin .dir :
@@ -622,6 +725,20 @@ def get_oneg(a, invert):
622
725
get_oddr71 (pin .o_clk , pin .o_fclk , pin_o0 , pin_o1 , pin_o2 , pin_o3 , pin_o4 , pin_o5 , pin_o6 , o )
623
726
if pin .dir in ("oe" , "io" ):
624
727
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 )
625
742
else :
626
743
assert False
627
744
@@ -632,7 +749,7 @@ def get_input(self, pin, port, attrs, invert):
632
749
"single-ended input" ,
633
750
pin ,
634
751
attrs ,
635
- valid_xdrs = (0 , 1 , 2 , 4 , 7 ),
752
+ valid_xdrs = (0 , 1 , 2 , 4 , 7 , 8 , 10 ),
636
753
valid_attrs = True ,
637
754
)
638
755
m = Module ()
@@ -649,7 +766,7 @@ def get_output(self, pin, port, attrs, invert):
649
766
"single-ended output" ,
650
767
pin ,
651
768
attrs ,
652
- valid_xdrs = (0 , 1 , 2 , 4 , 7 ),
769
+ valid_xdrs = (0 , 1 , 2 , 4 , 7 , 8 , 10 ),
653
770
valid_attrs = True ,
654
771
)
655
772
m = Module ()
@@ -666,7 +783,7 @@ def get_tristate(self, pin, port, attrs, invert):
666
783
"single-ended tristate" ,
667
784
pin ,
668
785
attrs ,
669
- valid_xdrs = (0 , 1 , 2 , 4 , 7 ),
786
+ valid_xdrs = (0 , 1 , 2 , 4 , 7 , 8 , 10 ),
670
787
valid_attrs = True ,
671
788
)
672
789
m = Module ()
@@ -684,7 +801,7 @@ def get_input_output(self, pin, port, attrs, invert):
684
801
"single-ended input/output" ,
685
802
pin ,
686
803
attrs ,
687
- valid_xdrs = (0 , 1 , 2 , 4 , 7 ),
804
+ valid_xdrs = (0 , 1 , 2 , 4 , 7 , 8 , 10 ),
688
805
valid_attrs = True ,
689
806
)
690
807
m = Module ()
@@ -703,7 +820,7 @@ def get_diff_input(self, pin, port, attrs, invert):
703
820
"differential input" ,
704
821
pin ,
705
822
attrs ,
706
- valid_xdrs = (0 , 1 , 2 , 4 , 7 ),
823
+ valid_xdrs = (0 , 1 , 2 , 4 , 7 , 8 , 10 ),
707
824
valid_attrs = True ,
708
825
)
709
826
m = Module ()
@@ -720,7 +837,7 @@ def get_diff_output(self, pin, port, attrs, invert):
720
837
"differential output" ,
721
838
pin ,
722
839
attrs ,
723
- valid_xdrs = (0 , 1 , 2 , 4 , 7 ),
840
+ valid_xdrs = (0 , 1 , 2 , 4 , 7 , 8 , 10 ),
724
841
valid_attrs = True ,
725
842
)
726
843
m = Module ()
@@ -737,7 +854,7 @@ def get_diff_tristate(self, pin, port, attrs, invert):
737
854
"differential tristate" ,
738
855
pin ,
739
856
attrs ,
740
- valid_xdrs = (0 , 1 , 2 , 4 , 7 ),
857
+ valid_xdrs = (0 , 1 , 2 , 4 , 7 , 8 , 10 ),
741
858
valid_attrs = True ,
742
859
)
743
860
m = Module ()
@@ -755,7 +872,7 @@ def get_diff_input_output(self, pin, port, attrs, invert):
755
872
"differential input/output" ,
756
873
pin ,
757
874
attrs ,
758
- valid_xdrs = (0 , 1 , 2 , 4 , 7 ),
875
+ valid_xdrs = (0 , 1 , 2 , 4 , 7 , 8 , 10 ),
759
876
valid_attrs = True ,
760
877
)
761
878
m = Module ()
0 commit comments