1 from operator
import itemgetter
4 from migen
.fhdl
.std
import *
5 from migen
.bank
.description
import CSRStatus
7 def get_macros(filename
):
8 f
= open(filename
, "r")
11 match
= re
.match("\w*#define\s+(\w+)\s+(.*)", line
, re
.IGNORECASE
)
13 r
[match
.group(1)] = match
.group(2)
16 def _get_rw_functions(reg_name
, reg_base
, size
, read_only
):
19 raise NotImplementedError("Register too large")
21 ctype
= "unsigned long long int"
23 ctype
= "unsigned int"
25 ctype
= "unsigned short int"
27 ctype
= "unsigned char"
29 r
+= "static inline "+ctype
+" "+reg_name
+"_read(void) {\n"
31 r
+= "\t"+ctype
+" r = MMPTR("+hex(reg_base
)+");\n"
32 for byte
in range(1, size
):
33 r
+= "\tr <<= 8;\n\tr |= MMPTR("+hex(reg_base
+4*byte
)+");\n"
34 r
+= "\treturn r;\n}\n"
36 r
+= "\treturn MMPTR("+hex(reg_base
)+");\n}\n"
39 r
+= "static inline void "+reg_name
+"_write("+ctype
+" value) {\n"
40 for byte
in range(size
):
41 shift
= (size
-byte
-1)*8
43 value_shifted
= "value >> "+str(shift
)
45 value_shifted
= "value"
46 r
+= "\tMMPTR("+hex(reg_base
+4*byte
)+") = "+value_shifted
+";\n"
50 def get_csr_header(csr_base
, bank_array
, interrupt_map
):
51 r
= "#ifndef __HW_CSR_H\n#define __HW_CSR_H\n#include <hw/common.h>\n"
52 for name
, csrs
, mapaddr
, rmap
in bank_array
.banks
:
53 r
+= "\n/* "+name
+" */\n"
54 reg_base
= csr_base
+ 0x800*mapaddr
55 r
+= "#define "+name
.upper()+"_BASE "+hex(reg_base
)+"\n"
57 nr
= (csr
.size
+ 7)//8
58 r
+= _get_rw_functions(name
+ "_" + csr
.name
, reg_base
, nr
, isinstance(csr
, CSRStatus
))
61 interrupt_nr
= interrupt_map
[name
]
65 r
+= "#define "+name
.upper()+"_INTERRUPT "+str(interrupt_nr
)+"\n"
69 def get_sdram_phy_header(sdram_phy
):
70 if sdram_phy
.phy_settings
.type not in ["SDR", "DDR", "LPDDR", "DDR2"]:
71 raise NotImplementedError("The SDRAM PHY header generator only supports SDR, DDR, LPDDR and DDR2")
73 r
= "#ifndef __HW_SDRAM_PHY_H\n#define __HW_SDRAM_PHY_H\n"
74 r
+= "#include <hw/common.h>\n#include <hw/csr.h>\n#include <hw/flags.h>\n\n"
76 r
+= "static void cdelay(int i);\n"
79 # commands_px functions
81 for n
in range(sdram_phy
.phy_settings
.nphases
):
83 static void command_p{n}(int cmd)
85 dfii_pi{n}_command_write(cmd);
86 dfii_pi{n}_command_issue_write(1);
87 }}""".format(n
=str(n
))
94 #define dfii_pird_address_write(X) dfii_pi{rdphase}_address_write(X)
95 #define dfii_piwr_address_write(X) dfii_pi{wrphase}_address_write(X)
97 #define dfii_pird_baddress_write(X) dfii_pi{rdphase}_baddress_write(X)
98 #define dfii_piwr_baddress_write(X) dfii_pi{wrphase}_baddress_write(X)
100 #define command_prd(X) command_p{rdphase}(X)
101 #define command_pwr(X) command_p{wrphase}(X)
102 """.format(rdphase
=str(sdram_phy
.phy_settings
.rdphase
), wrphase
=str(sdram_phy
.phy_settings
.wrphase
))
109 "PRECHARGE_ALL" : "DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
110 "MODE_REGISTER" : "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
111 "AUTO_REFRESH" : "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_CS",
112 "CKE" : "DFII_CONTROL_CKE"
115 def gen_cmd(comment
, a
, ba
, cmd
, delay
):
116 r
= "\t/* %s */\n" %comment
117 r
+= "\tdfii_pi0_address_write(0x%04X);\n" %a
118 r
+= "\tdfii_pi0_baddress_write(%d);\n" %ba
120 r
+= "\tdfii_control_write(%s);\n" %cmd
122 r
+= "\tcommand_p0(%s);\n" %cmd
123 r
+= "\tcdelay(%d);\n" %delay
128 r
+= "static void init_sequence(void)\n{\n"
130 cl
= sdram_phy
.phy_settings
.cl
132 if sdram_phy
.phy_settings
.type == "SDR":
133 bl
= 1*sdram_phy
.phy_settings
.nphases
134 mr
= log2_int(bl
) + (cl
<< 4)
138 ("Bring CKE high", 0x0000, 0, cmds
["CKE"], 2000),
139 ("Precharge All", 0x0400, 0, cmds
["PRECHARGE_ALL"], 0),
140 ("Load Mode Register / Reset DLL, CL=%d, BL=%d" %(cl
, bl
), mr
+ reset_dll
, 0, cmds
["MODE_REGISTER"], 200),
141 ("Precharge All", 0x0400, 0, cmds
["PRECHARGE_ALL"], 0),
142 ("Auto Refresh", 0x0, 0, cmds
["AUTO_REFRESH"], 4),
143 ("Load Mode Register / CL=%d, BL=%d" %(cl
, bl
), mr
, 0, cmds
["MODE_REGISTER"], 200)
146 elif sdram_phy
.phy_settings
.type == "DDR":
147 bl
= 2*sdram_phy
.phy_settings
.nphases
148 mr
= log2_int(bl
) + (cl
<< 4)
153 ("Bring CKE high", 0x0000, 0, cmds
["CKE"], 2000),
154 ("Precharge All", 0x0400, 0, cmds
["PRECHARGE_ALL"], 0),
155 ("Load Extended Mode Register", emr
, 1, cmds
["MODE_REGISTER"], 0),
156 ("Load Mode Register / Reset DLL, CL=%d, BL=%d" %(cl
, bl
), mr
+ reset_dll
, 0, cmds
["MODE_REGISTER"], 200),
157 ("Precharge All", 0x0400, 0, cmds
["PRECHARGE_ALL"], 0),
158 ("Auto Refresh", 0x0, 0, cmds
["AUTO_REFRESH"], 4),
159 ("Load Mode Register / CL=%d, BL=%d" %(cl
, bl
), mr
, 0, cmds
["MODE_REGISTER"], 200)
162 elif sdram_phy
.phy_settings
.type == "LPDDR":
163 bl
= 2*sdram_phy
.phy_settings
.nphases
164 mr
= log2_int(bl
) + (cl
<< 4)
169 ("Bring CKE high", 0x0000, 0, cmds
["CKE"], 2000),
170 ("Precharge All", 0x0400, 0, cmds
["PRECHARGE_ALL"], 0),
171 ("Load Extended Mode Register", emr
, 2, cmds
["MODE_REGISTER"], 0),
172 ("Load Mode Register / Reset DLL, CL=%d, BL=%d" %(cl
, bl
), mr
+ reset_dll
, 0, cmds
["MODE_REGISTER"], 200),
173 ("Precharge All", 0x0400, 0, cmds
["PRECHARGE_ALL"], 0),
174 ("Auto Refresh", 0x0, 0, cmds
["AUTO_REFRESH"], 4),
175 ("Load Mode Register / CL=%d, BL=%d" %(cl
, bl
), mr
, 0, cmds
["MODE_REGISTER"], 200)
178 elif sdram_phy
.phy_settings
.type == "DDR2":
179 bl
= 2*sdram_phy
.phy_settings
.nphases
180 mr
= log2_int(bl
) + (cl
<< 4)
185 ("Bring CKE high", 0x0000, 0, cmds
["CKE"], 2000),
186 ("Precharge All", 0x0400, 0, cmds
["PRECHARGE_ALL"], 0),
187 ("Load Extended Mode Register", emr
, 1, cmds
["MODE_REGISTER"], 0),
188 ("Load Mode Register / Reset DLL, CL=%d, BL=%d" %(cl
, bl
), mr
+ reset_dll
, 0, cmds
["MODE_REGISTER"], 200),
189 ("Precharge All", 0x0400, 0, cmds
["PRECHARGE_ALL"], 0),
190 ("Auto Refresh", 0x0, 0, cmds
["AUTO_REFRESH"], 4),
191 ("Load Mode Register / CL=%d, BL=%d" %(cl
, bl
), mr
, 0, cmds
["MODE_REGISTER"], 200)
194 for comment
, a
, ba
, cmd
, delay
in init_sequence
:
195 r
+= gen_cmd(comment
, a
, ba
, cmd
, delay
)