split out peripheral interfaces to separate classes
[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
41 class uart(PBase):
42 def importfn(self):
43 return " import Uart16550 :: *;"
44
45 def ifacedecl(self):
46 return " interface RS232_PHY_Ifc uart{0}_coe;\n" + \
47 " method Bit#(1) uart{0}_intr;"
48
49 def num_axi_regs32(self):
50 return 8
51
52
53 class rs232(PBase):
54 def importfn(self):
55 return " import Uart_bs::*;\n" + \
56 " import RS232_modified::*;"
57
58 def ifacedecl(self):
59 return " interface RS232 uart{0}_coe;"
60
61 def num_axi_regs32(self):
62 return 2
63
64
65 class twi(PBase):
66 def importfn(self):
67 return " import I2C_top :: *;"
68
69 def ifacedecl(self):
70 return " interface I2C_out i2c{0}_out;\n" + \
71 " method Bit#(1) i2c{0}_isint;"
72
73 def num_axi_regs32(self):
74 return 8
75
76
77 class qspi(PBase):
78 def importfn(self):
79 return " import qspi :: *;"
80
81 def ifacedecl(self):
82 return " interface QSPI_out qspi{0}_out;\n" + \
83 " method Bit#(1) qspi{0}_isint;"
84
85 def num_axi_regs32(self):
86 return 13
87
88
89 class pwm(PBase):
90 def importfn(self):
91 return " import pwm::*;"
92
93 def ifacedecl(self):
94 return " interface PWMIO pwm_o;"
95
96 def num_axi_regs32(self):
97 return 4
98
99
100 class gpio(PBase):
101 def importfn(self):
102 return " import pinmux::*;\n" + \
103 " import mux::*;\n" + \
104 " import gpio::*;\n"
105
106 def ifacedecl(self):
107 return " interface GPIO_config#({1}) pad_config{0};"
108
109 def num_axi_regs32(self):
110 return 2
111
112 def axi_slave_idx(self, idx, name, ifacenum):
113 """ generates AXI slave number definition, except
114 GPIO also has a muxer per bank
115 """
116 name = name.upper()
117 (ret, x) = PBase.axi_slave_idx(self, idx, name, ifacenum)
118 (ret2, x) = PBase.axi_slave_idx(self, idx, "mux", ifacenum)
119 return ("%s\n%s" % (ret, ret2), 2)
120
121
122 axi_slave_declarations = """\
123 typedef 0 SlowMaster;
124 {0}
125 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
126 CLINT_slave_num;
127 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
128 Plic_slave_num;
129 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
130 AxiExp1_slave_num;
131 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
132 """
133
134
135 class PeripheralIface(object):
136 def __init__(self, ifacename):
137 self.slow = None
138 slow = slowfactory.getcls(ifacename)
139 if slow:
140 self.slow = slow()
141
142 def slowimport(self):
143 if not self.slow:
144 return ''
145 return self.slow.importfn().format()
146
147 def slowifdecl(self, count):
148 if not self.slow:
149 return ''
150 return self.slow.ifacedecl().format(count, self.ifacename)
151
152 def axi_reg_def(self, start, count):
153 if not self.slow:
154 return ('', 0)
155 return self.slow.axi_reg_def(start, self.ifacename, count)
156
157 def axi_slave_idx(self, start, count):
158 if not self.slow:
159 return ('', 0)
160 return self.slow.axi_slave_idx(start, self.ifacename, count)
161
162 def axi_addr_map(self, count):
163 if not self.slow:
164 return ''
165 return self.slow.axi_addr_map(self.ifacename, count)
166
167 class PeripheralInterfaces(object):
168 def __init__(self):
169 pass
170
171 def slowimport(self, *args):
172 ret = []
173 for (name, count) in self.ifacecount:
174 ret.append(self.data[name].slowimport())
175 return '\n'.join(list(filter(None, ret)))
176
177 def slowifdecl(self, *args):
178 ret = []
179 for (name, count) in self.ifacecount:
180 for i in range(count):
181 ret.append(self.data[name].slowifdecl(i))
182 return '\n'.join(list(filter(None, ret)))
183
184 def axi_reg_def(self, *args):
185 ret = []
186 start = 0x00011100 # start of AXI peripherals address
187 for (name, count) in self.ifacecount:
188 for i in range(count):
189 x = self.data[name].axi_reg_def(start, i)
190 print ("ifc", name, x)
191 (rdef, offs) = x
192 ret.append(rdef)
193 start += offs
194 return '\n'.join(list(filter(None, ret)))
195
196 def axi_slave_idx(self, *args):
197 ret = []
198 start = 0
199 for (name, count) in self.ifacecount:
200 for i in range(count):
201 (rdef, offs) = self.data[name].axi_slave_idx(start, i)
202 print ("ifc", name, rdef, offs)
203 ret.append(rdef)
204 start += offs
205 ret.append("typedef %d LastGen_slave_num" % (start - 1))
206 decls = '\n'.join(list(filter(None, ret)))
207 return axi_slave_declarations.format(decls)
208
209 def axi_addr_map(self, *args):
210 ret = []
211 for (name, count) in self.ifacecount:
212 for i in range(count):
213 ret.append(self.data[name].axi_addr_map(i))
214 return '\n'.join(list(filter(None, ret)))
215
216
217 class PFactory(object):
218 def getcls(self, name):
219 return {'uart': uart,
220 'rs232': rs232,
221 'twi': twi,
222 'qspi': qspi,
223 'pwm': pwm,
224 'gpio': gpio
225 }.get(name, None)
226
227 slowfactory = PFactory()
228