1 # This file is Copyright (c) 2015 Sebastien Bourdeauducq <sb@m-labs.hk>
2 # This file is Copyright (c) 2020 LambdaConcept <contact@lambdaconcept.com>
5 from nmigen
.hdl
.rec
import *
7 __ALL__
= ["Interface"]
9 def phase_description(addressbits
, bankbits
, nranks
, databits
):
12 ("address", addressbits
, DIR_FANOUT
),
13 ("bank", bankbits
, DIR_FANOUT
),
14 ("cas_n", 1, DIR_FANOUT
),
15 ("cs_n", nranks
, DIR_FANOUT
),
16 ("ras_n", 1, DIR_FANOUT
),
17 ("we_n", 1, DIR_FANOUT
),
18 ("cke", nranks
, DIR_FANOUT
),
19 ("odt", nranks
, DIR_FANOUT
),
20 ("reset_n", 1, DIR_FANOUT
),
21 ("act_n", 1, DIR_FANOUT
),
23 ("wrdata", databits
, DIR_FANOUT
),
24 ("wrdata_en", 1, DIR_FANOUT
),
25 ("wrdata_mask", databits
//8, DIR_FANOUT
),
27 ("rddata_en", 1, DIR_FANOUT
),
28 ("rddata", databits
, DIR_FANIN
),
29 ("rddata_valid", 1, DIR_FANIN
),
34 def __init__(self
, addressbits
, bankbits
, nranks
, databits
, nphases
=1):
36 for p
in range(nphases
):
37 p
= Record(phase_description(addressbits
, bankbits
, nranks
, databits
))
40 p
.cs_n
.reset
= (2**nranks
-1)
45 def connect(self
, target
):
46 if not isinstance(target
, Interface
):
47 raise TypeError("Target must be an instance of Interface, not {!r}"
51 for i
in range(min(len(self
.phases
), len(target
.phases
))):
52 ret
+= [self
.phases
[i
].connect(target
.phases
[i
])]