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