add more mk_connections
[pinmux.git] / src / bsv / peripheral_gen.py
1 import types
2 from copy import deepcopy
3
4
5 class PBase(object):
6 def __init__(self, name):
7 self.name = name
8
9 def axibase(self, name, ifacenum):
10 name = name.upper()
11 return "%(name)s%(ifacenum)dBase" % locals()
12
13 def axiend(self, name, ifacenum):
14 name = name.upper()
15 return "%(name)s%(ifacenum)dEnd" % locals()
16
17 def axi_reg_def(self, start, name, ifacenum):
18 name = name.upper()
19 offs = self.num_axi_regs32() * 4 * 16
20 end = start + offs - 1
21 bname = self.axibase(name, ifacenum)
22 bend = self.axiend(name, ifacenum)
23 comment = "%d 32-bit regs" % self.num_axi_regs32()
24 return (" `define%(bname)s 'h%(start)08X\n"
25 " `define%(bend)s 'h%(end)08X // %(comment)s" % locals(),
26 offs)
27
28 def axi_slave_name(self, name, ifacenum):
29 name = name.upper()
30 return "{0}{1}_slave_num".format(name, ifacenum)
31
32 def axi_slave_idx(self, idx, name, ifacenum):
33 name = self.axi_slave_name(name, ifacenum)
34 return ("typedef {0} {1};".format(idx, name), 1)
35
36 def axi_addr_map(self, name, ifacenum):
37 bname = self.axibase(name, ifacenum)
38 bend = self.axiend(name, ifacenum)
39 name = self.axi_slave_name(name, ifacenum)
40 return """\
41 if(addr>=`{0} && addr<=`{1})
42 return tuple2(True,fromInteger(valueOf({2})));
43 else""".format(bname, bend, name)
44
45 def mkslow_peripheral(self):
46 return ''
47
48 def __mk_connection(self, aname, count):
49 txt = " mkConnection (slow_fabric.v_to_slaves\n" + \
50 " [fromInteger(valueOf({1}))],\n" + \
51 " {0});"
52
53 con = self._mk_connection().format(count, aname)
54 if not con:
55 return ''
56 return txt.format(con, aname)
57
58 def mk_connection(self, count):
59 aname = self.axi_slave_name(self.name, count)
60 return :elf.__mk_connection(aname, count)
61
62 def _mk_connection(self):
63 return ''
64
65
66 class uart(PBase):
67
68 def slowimport(self):
69 return " import Uart16550 :: *;"
70
71 def slowifdecl(self):
72 return " interface RS232_PHY_Ifc uart{0}_coe;\n" + \
73 " method Bit#(1) uart{0}_intr;"
74
75 def num_axi_regs32(self):
76 return 8
77
78 def mkslow_peripheral(self):
79 return " Uart16550_AXI4_Lite_Ifc uart{0} <- \n" + \
80 " mkUart16550(clocked_by uart_clock,\n" + \
81 " reset_by uart_reset, sp_clock, sp_reset);"
82
83 def _mk_connection(self):
84 return "uart{0}.slave_axi_uart"
85
86
87
88 class rs232(PBase):
89
90 def slowimport(self):
91 return " import Uart_bs::*;\n" + \
92 " import RS232_modified::*;"
93
94 def slowifdecl(self):
95 return " interface RS232 uart{0}_coe;"
96
97 def num_axi_regs32(self):
98 return 2
99
100 def mkslow_peripheral(self):
101 return " //Ifc_Uart_bs uart{0} <-" + \
102 " // mkUart_bs(clocked_by uart_clock,\n" + \
103 " // reset_by uart_reset,sp_clock, sp_reset);" +\
104 " Ifc_Uart_bs uart{0} <-" + \
105 " mkUart_bs(clocked_by sp_clock,\n" + \
106 " reset_by sp_reset, sp_clock, sp_reset);"
107
108 def _mk_connection(self):
109 return "uart{0}.slave_axi_uart"
110
111
112 class twi(PBase):
113
114 def slowimport(self):
115 return " import I2C_top :: *;"
116
117 def slowifdecl(self):
118 return " interface I2C_out i2c{0}_out;\n" + \
119 " method Bit#(1) i2c{0}_isint;"
120
121 def num_axi_regs32(self):
122 return 8
123
124 def mkslow_peripheral(self):
125 return " I2C_IFC i2c{0} <- mkI2CController();"
126
127 def _mk_connection(self):
128 return "i2c{0}.slave_i2c_axi"
129
130
131 class qspi(PBase):
132
133 def slowimport(self):
134 return " import qspi :: *;"
135
136 def slowifdecl(self):
137 return " interface QSPI_out qspi{0}_out;\n" + \
138 " method Bit#(1) qspi{0}_isint;"
139
140 def num_axi_regs32(self):
141 return 13
142
143 def mkslow_peripheral(self):
144 return " Ifc_qspi qspi{0} <- mkqspi();"
145
146 def _mk_connection(self):
147 return "qspi{0}.slave"
148
149
150 class pwm(PBase):
151
152 def slowimport(self):
153 return " import pwm::*;"
154
155 def slowifdecl(self):
156 return " interface PWMIO pwm{0}_o;"
157
158 def num_axi_regs32(self):
159 return 4
160
161 def mkslow_peripheral(self):
162 return " Ifc_PWM_bus pwm{0}_bus <- mkPWM_bus(sp_clock);"
163
164 def _mk_connection(self):
165 return "pwm{0}_bus.axi4_slave"
166
167
168 class gpio(PBase):
169
170 def slowimport(self):
171 return " import pinmux::*;\n" + \
172 " import mux::*;\n" + \
173 " import gpio::*;\n"
174
175 def slowifdecl(self):
176 return " interface GPIO_config#({1}) pad_config{0};"
177
178 def num_axi_regs32(self):
179 return 2
180
181 def axi_slave_idx(self, idx, name, ifacenum):
182 """ generates AXI slave number definition, except
183 GPIO also has a muxer per bank
184 """
185 name = name.upper()
186 (ret, x) = PBase.axi_slave_idx(self, idx, name, ifacenum)
187 (ret2, x) = PBase.axi_slave_idx(self, idx, "mux", ifacenum)
188 return ("%s\n%s" % (ret, ret2), 2)
189
190 def mkslow_peripheral(self):
191 return " MUX#({1}) mux{0} <- mkmux();\n" + \
192 " GPIO#({1}) gpio{0} <- mkgpio();"
193
194
195 axi_slave_declarations = """\
196 typedef 0 SlowMaster;
197 {0}
198 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
199 CLINT_slave_num;
200 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
201 Plic_slave_num;
202 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
203 AxiExp1_slave_num;
204 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
205 """
206
207
208 class CallFn(object):
209 def __init__(self, peripheral, name):
210 self.peripheral = peripheral
211 self.name = name
212
213 def __call__(self, *args):
214 #print "__call__", self.name, args
215 if not self.peripheral.slow:
216 return ''
217 return getattr(self.peripheral.slow, self.name)(*args[1:])
218
219
220 class PeripheralIface(object):
221 def __init__(self, ifacename):
222 self.slow = None
223 slow = slowfactory.getcls(ifacename)
224 if slow:
225 self.slow = slow(ifacename)
226 for fname in ['slowimport', 'slowifdecl', 'mkslow_peripheral',
227 'mk_connection']:
228 fn = CallFn(self, fname)
229 setattr(self, fname, types.MethodType(fn, self))
230
231 #print "PeripheralIface"
232 #print dir(self)
233
234 def axi_reg_def(self, start, count):
235 if not self.slow:
236 return ('', 0)
237 return self.slow.axi_reg_def(start, self.ifacename, count)
238
239 def axi_slave_idx(self, start, count):
240 if not self.slow:
241 return ('', 0)
242 return self.slow.axi_slave_idx(start, self.ifacename, count)
243
244 def axi_addr_map(self, count):
245 if not self.slow:
246 return ''
247 return self.slow.axi_addr_map(self.ifacename, count)
248
249
250 class PeripheralInterfaces(object):
251 def __init__(self):
252 pass
253
254 def slowimport(self, *args):
255 ret = []
256 for (name, count) in self.ifacecount:
257 #print "slowimport", name, self.data[name].slowimport
258 ret.append(self.data[name].slowimport())
259 return '\n'.join(list(filter(None, ret)))
260
261 def slowifdecl(self, *args):
262 ret = []
263 for (name, count) in self.ifacecount:
264 for i in range(count):
265 ret.append(self.data[name].slowifdecl().format(i, name))
266 return '\n'.join(list(filter(None, ret)))
267
268 def axi_reg_def(self, *args):
269 ret = []
270 start = 0x00011100 # start of AXI peripherals address
271 for (name, count) in self.ifacecount:
272 for i in range(count):
273 x = self.data[name].axi_reg_def(start, i)
274 #print ("ifc", name, x)
275 (rdef, offs) = x
276 ret.append(rdef)
277 start += offs
278 return '\n'.join(list(filter(None, ret)))
279
280 def axi_slave_idx(self, *args):
281 ret = []
282 start = 0
283 for (name, count) in self.ifacecount:
284 for i in range(count):
285 (rdef, offs) = self.data[name].axi_slave_idx(start, i)
286 #print ("ifc", name, rdef, offs)
287 ret.append(rdef)
288 start += offs
289 ret.append("typedef %d LastGen_slave_num" % (start - 1))
290 decls = '\n'.join(list(filter(None, ret)))
291 return axi_slave_declarations.format(decls)
292
293 def axi_addr_map(self, *args):
294 ret = []
295 for (name, count) in self.ifacecount:
296 for i in range(count):
297 ret.append(self.data[name].axi_addr_map(i))
298 return '\n'.join(list(filter(None, ret)))
299
300 def mkslow_peripheral(self, *args):
301 ret = []
302 for (name, count) in self.ifacecount:
303 for i in range(count):
304 ret.append(self.data[name].mkslow_peripheral().format(i))
305 return '\n'.join(list(filter(None, ret)))
306
307 def mk_connection(self, *args):
308 ret = []
309 for (name, count) in self.ifacecount:
310 for i in range(count):
311 txt = self.data[name].mk_connection(i)
312 ret.append(txt)
313 return '\n'.join(list(filter(None, ret)))
314
315
316 class PFactory(object):
317 def getcls(self, name):
318 return {'uart': uart,
319 'rs232': rs232,
320 'twi': twi,
321 'qspi': qspi,
322 'pwm': pwm,
323 'gpio': gpio
324 }.get(name, None)
325
326
327 slowfactory = PFactory()
328
329 if __name__ == '__main__':
330 p = uart()
331 print p.slowimport()
332 print p.slowifdecl()