remove GenericIOType and FunctionType for now
[pinmux.git] / src / bsv / pinmux_generator.py
1 # ================================== Steps to add peripherals ============
2 # Step-1: create interface declaration for the peripheral to be added.
3 # Remember these are interfaces defined for the pinmux and hence
4 # will be opposite to those defined at the peripheral.
5 # For eg. the output TX from the UART will be input (method Action)
6 # for the pinmux.
7 # These changes will have to be done in interface_decl.py
8 # Step-2 define the wires that will be required to transfer data from the
9 # peripheral interface to the IO cell and vice-versa. Create a
10 # mkDWire for each input/output between the peripheral and the
11 # pinmux. Also create an implicit wire of GenericIOType for each cell
12 # that can be connected to a each bit from the peripheral.
13 # These changes will have to be done in wire_def.py
14 # Step-3: create the definitions for each of the methods defined above.
15 # These changes will have to be done in interface_decl.py
16 # ========================================================================
17
18 # default module imports
19 import shutil
20 import os
21 import os.path
22 import time
23
24 # project module imports
25 from bsv.interface_decl import Interfaces, mux_interface, io_interface
26 from parse import Parse
27 from bsv.actual_pinmux import init
28 from bsv.bus_transactors import axi4_lite
29
30 copyright = '''
31 /*
32 This BSV file has been generated by the PinMux tool available at:
33 https://bitbucket.org/casl/pinmux.
34
35 Authors: Neel Gala, Luke
36 Date of generation: ''' + time.strftime("%c") + '''
37 */
38 '''
39 header = copyright + '''
40 package pinmux;
41
42 '''
43 footer = '''
44 endinterface;
45 endmodule
46 endpackage
47 '''
48
49
50 def pinmuxgen(pth=None, verify=True):
51 """ populating the file with the code
52 """
53
54 p = Parse(pth, verify)
55 ifaces = Interfaces(pth)
56 ifaces.ifaceadd('io', p.N_IO, io_interface, 0)
57 init(p, ifaces)
58
59 bp = 'bsv_src'
60 if pth:
61 bp = os.path.join(pth, bp)
62 if not os.path.exists(bp):
63 os.makedirs(bp)
64 bl = os.path.join(bp, 'bsv_lib')
65 if not os.path.exists(bl):
66 os.makedirs(bl)
67
68 cwd = os.path.split(__file__)[0]
69
70 # copy over template and library files
71 shutil.copyfile(os.path.join(cwd, 'Makefile.template'),
72 os.path.join(bp, 'Makefile'))
73 cwd = os.path.join(cwd, 'bsv_lib')
74 for fname in ['AXI4_Lite_Types.bsv', 'Semi_FIFOF.bsv']:
75 shutil.copyfile(os.path.join(cwd, fname),
76 os.path.join(bl, fname))
77
78 bus = os.path.join(bp, 'busenable.bsv')
79 pmp = os.path.join(bp, 'pinmux.bsv')
80 ptp = os.path.join(bp, 'PinTop.bsv')
81 bvp = os.path.join(bp, 'bus.bsv')
82
83 write_pmp(pmp, p, ifaces)
84 write_ptp(ptp, p, ifaces)
85 write_bvp(bvp, p, ifaces)
86 write_bus(bus, p, ifaces)
87
88
89 def write_bus(bus, p, ifaces):
90 # package and interface declaration followed by
91 # the generic io_cell definition
92 with open(bus, "w") as bsv_file:
93 ifaces.busfmt(bsv_file)
94
95
96 def write_pmp(pmp, p, ifaces):
97 # package and interface declaration followed by
98 # the generic io_cell definition
99 with open(pmp, "w") as bsv_file:
100 bsv_file.write(header)
101
102 cell_bit_width = 'Bit#(%d)' % p.cell_bitwidth
103 bsv_file.write('''\
104 interface MuxSelectionLines;
105
106 // declare the method which will capture the user pin-mux
107 // selection values.The width of the input is dependent on the number
108 // of muxes happening per IO. For now we have a generalized width
109 // where each IO will have the same number of muxes.''')
110
111 for cell in p.muxed_cells:
112 bsv_file.write(mux_interface.ifacefmt(cell[0], cell_bit_width))
113
114 bsv_file.write('''
115 endinterface
116
117 interface PeripheralSide;
118 // declare the interface to the IO cells.
119 // Each IO cell will have 8 input field (output from pin mux
120 // and on output field (input to pinmux)''')
121 # ==============================================================
122
123 # == create method definitions for all peripheral interfaces ==#
124 ifaces.ifacefmt(bsv_file)
125
126 # ==============================================================
127
128 # ===== finish interface definition and start module definition=======
129 bsv_file.write('''
130 endinterface
131
132 interface Ifc_pinmux;
133 interface MuxSelectionLines mux_lines;
134 interface PeripheralSide peripheral_side;
135 endinterface
136 (*synthesize*)
137 module mkpinmux(Ifc_pinmux);
138 ''')
139 # ====================================================================
140
141 # ======================= create wire and registers =================#
142 bsv_file.write('''
143 // the followins wires capture the pin-mux selection
144 // values for each mux assigned to a CELL
145 ''')
146 for cell in p.muxed_cells:
147 bsv_file.write(mux_interface.wirefmt(
148 cell[0], cell_bit_width))
149
150 ifaces.wirefmt(bsv_file)
151
152 bsv_file.write("\n")
153 # ====================================================================
154 # ========================= Actual pinmuxing ========================#
155 bsv_file.write('''
156 /*====== This where the muxing starts for each io-cell======*/
157 ''')
158 bsv_file.write(p.pinmux)
159 bsv_file.write('''
160 /*============================================================*/
161 ''')
162 # ====================================================================
163 # ================= interface definitions for each method =============#
164 bsv_file.write('''
165 interface mux_lines = interface MuxSelectionLines
166 ''')
167 for cell in p.muxed_cells:
168 bsv_file.write(
169 mux_interface.ifacedef(
170 cell[0], cell_bit_width))
171 bsv_file.write('''
172 endinterface;
173 interface peripheral_side = interface PeripheralSide
174 ''')
175 ifaces.ifacedef(bsv_file)
176 bsv_file.write(footer)
177 print("BSV file successfully generated: bsv_src/pinmux.bsv")
178 # ======================================================================
179
180
181 def write_ptp(ptp, p, ifaces):
182 with open(ptp, 'w') as bsv_file:
183 bsv_file.write(copyright + '''
184 package PinTop;
185 import pinmux::*;
186 interface Ifc_PintTop;
187 method ActionValue#(Bool) write(Bit#({0}) addr, Bit#({1}) data);
188 method Tuple2#(Bool,Bit#({1})) read(Bit#({0}) addr);
189 interface PeripheralSide peripheral_side;
190 endinterface
191
192 module mkPinTop(Ifc_PintTop);
193 // instantiate the pin-mux module here
194 Ifc_pinmux pinmux <-mkpinmux;
195
196 // declare the registers which will be used to mux the IOs
197 '''.format(p.ADDR_WIDTH, p.DATA_WIDTH))
198
199 cell_bit_width = str(p.cell_bitwidth)
200 for cell in p.muxed_cells:
201 bsv_file.write('''
202 Reg#(Bit#({0})) rg_muxio_{1} <-mkReg(0);'''.format(
203 cell_bit_width, cell[0]))
204
205 bsv_file.write('''
206 // rule to connect the registers to the selection lines of the
207 // pin-mux module
208 rule connect_selection_registers;''')
209
210 for cell in p.muxed_cells:
211 bsv_file.write('''
212 pinmux.mux_lines.cell{0}_mux(rg_muxio_{0});'''.format(cell[0]))
213
214 bsv_file.write('''
215 endrule
216 // method definitions for the write user interface
217 method ActionValue#(Bool) write(Bit#({2}) addr, Bit#({3}) data);
218 Bool err=False;
219 case (addr[{0}:{1}])'''.format(p.upper_offset, p.lower_offset,
220 p.ADDR_WIDTH, p.DATA_WIDTH))
221 index = 0
222 for cell in p.muxed_cells:
223 bsv_file.write('''
224 {0}: rg_muxio_{1}<=truncate(data);'''.format(index, cell[0]))
225 index = index + 1
226
227 bsv_file.write('''
228 default: err=True;
229 endcase
230 return err;
231 endmethod''')
232
233 bsv_file.write('''
234 // method definitions for the read user interface
235 method Tuple2#(Bool,Bit#({3})) read(Bit#({2}) addr);
236 Bool err=False;
237 Bit#(32) data=0;
238 case (addr[{0}:{1}])'''.format(p.upper_offset, p.lower_offset,
239 p.ADDR_WIDTH, p.DATA_WIDTH))
240 index = 0
241 for cell in p.muxed_cells:
242 bsv_file.write('''
243 {0}: data=zeroExtend(rg_muxio_{1});'''.format(index, cell[0]))
244 index = index + 1
245
246 bsv_file.write('''
247 default:err=True;
248 endcase
249 return tuple2(err,data);
250 endmethod
251 interface peripheral_side=pinmux.peripheral_side;
252 endmodule
253 endpackage
254 ''')
255
256
257 def write_bvp(bvp, p, ifaces):
258 # ######## Generate bus transactors ################
259 with open(bvp, 'w') as bsv_file:
260 bsv_file.write(axi4_lite.format(p.ADDR_WIDTH, p.DATA_WIDTH))
261 # ##################################################