Connect DDR PHY
[litex.git] / milkymist / s6ddrphy / __init__.py
1 from migen.fhdl.structure import *
2 from migen.bus import dfi
3
4 class S6DDRPHY:
5 def __init__(self, a, ba, d):
6 ins = []
7 outs = []
8 inouts = []
9
10 for name in [
11 "clk2x_90",
12 "clk4x_wr_left",
13 "clk4x_wr_strb_left",
14 "clk4x_wr_right",
15 "clk4x_wr_strb_right",
16 "clk4x_rd_left",
17 "clk4x_rd_strb_left",
18 "clk4x_rd_right",
19 "clk4x_rd_strb_right",
20 "reset_n"
21 ]:
22 s = Signal(name=name)
23 setattr(self, name, s)
24 ins.append((name, s))
25
26 self._sd_pins = []
27 sd_d = d//4
28 for name, width, l in [
29 ("sd_clk_out_p", 1, outs),
30 ("sd_clk_out_n", 1, outs),
31 ("sd_a", a, outs),
32 ("sd_ba", ba, outs),
33 ("sd_cs_n", 1, outs),
34 ("sd_cke", 1, outs),
35 ("sd_ras_n", 1, outs),
36 ("sd_cas_n", 1, outs),
37 ("sd_we_n", 1, outs),
38 ("sd_dq", sd_d, inouts),
39 ("sd_dm", sd_d//8, outs),
40 ("sd_dqs", sd_d//8, inouts)
41
42 ]:
43 s = Signal(BV(width), name=name)
44 setattr(self, name, s)
45 l.append((name, s))
46 self._sd_pins.append(s)
47
48 self.dfi = dfi.Interface(a, ba, d)
49 ins += self.dfi.get_standard_names(True, False)
50 outs += self.dfi.get_standard_names(False, True)
51
52 ins += [
53 ("cfg_al", BV(3)),
54 ("cfg_cl", BV(3)),
55 ("cfg_bl", BV(2)),
56 ("cfg_regdimm", BV(1)),
57
58 ("init_done", BV(1)),
59
60 ("cpg_busy", BV(1)),
61
62 ("diag_dq_recal", BV(1)),
63 ("diag_io_sel", BV(9)),
64 ("diag_disable_cal_on_startup", BV(1)),
65 ("diag_cal_bits", BV(2)),
66 ("diag_short_cal", BV(1))
67 ]
68 outs += [
69 ("phy_cal_done", BV(1)),
70
71 ("cpg_r_req", BV(1)),
72 ("cpg_w_req", BV(1)),
73 ("cpg_addr", BV(a)),
74 ("cpg_b_size", BV(4))
75 ]
76
77 self._inst = Instance("spartan6_soft_phy",
78 outs,
79 ins,
80 inouts,
81 [
82 ("DSIZE", d),
83 ("NUM_AD", a),
84 ("NUM_BA", ba),
85 ("ADDR_WIDTH", 31),
86 ("DQ_IO_LOC", Constant(2**32-1, BV(32))),
87 ("DM_IO_LOC", Constant(2**4-1, BV(4)))
88 ],
89 clkport="clk")
90
91 def get_fragment(self):
92 comb = [
93 self._inst.ins["cfg_al"].eq(0),
94 self._inst.ins["cfg_cl"].eq(3),
95 self._inst.ins["cfg_bl"].eq(1),
96 self._inst.ins["cfg_regdimm"].eq(0),
97
98 self._inst.ins["diag_dq_recal"].eq(0),
99 self._inst.ins["diag_io_sel"].eq(0),
100 self._inst.ins["diag_disable_cal_on_startup"].eq(0),
101 self._inst.ins["diag_cal_bits"].eq(0),
102 self._inst.ins["diag_short_cal"].eq(0)
103 ]
104 return Fragment(comb, instances=[self._inst], pads=set(self._sd_pins))