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