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