Rework DFI interface code
[gram.git] / gram / phy / dfi.py
1 # This file is Copyright (c) 2015 Sebastien Bourdeauducq <sb@m-labs.hk>
2 # This file is Copyright (c) 2020 LambdaConcept <contact@lambdaconcept.com>
3
4 from nmigen import *
5 from nmigen.hdl.rec import *
6
7 __ALL__ = ["Interface"]
8
9 def phase_description(addressbits, bankbits, nranks, databits):
10 return [
11 # cmd description
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),
22 # wrdata description
23 ("wrdata", databits, DIR_FANOUT),
24 ("wrdata_en", 1, DIR_FANOUT),
25 ("wrdata_mask", databits//8, DIR_FANOUT),
26 # rddata description
27 ("rddata_en", 1, DIR_FANOUT),
28 ("rddata", databits, DIR_FANIN),
29 ("rddata_valid", 1, DIR_FANIN),
30 ]
31
32
33 class Interface:
34 def __init__(self, addressbits, bankbits, nranks, databits, nphases=1):
35 self.phases = []
36 for p in range(nphases):
37 p = Record(phase_description(addressbits, bankbits, nranks, databits))
38 self.phases += [p]
39 p.cas_n.reset = 1
40 p.cs_n.reset = (2**nranks-1)
41 p.ras_n.reset = 1
42 p.we_n.reset = 1
43 p.act_n.reset = 1
44
45 def connect(self, target):
46 if not isinstance(target, Interface):
47 raise TypeError("Target must be an instance of Interface, not {!r}"
48 .format(target))
49
50 ret = []
51 for i in range(min(len(self.phases), len(target.phases))):
52 ret += [self.phases[i].connect(target.phases[i])]
53
54 return ret