# ========================================================================
# default module imports
+import getopt
import os
+import os.path
import sys
import time
import math
# project module imports
-from interface_decl import ifaces, mux_interface, io_interface
-from wire_def import muxwire, generic_io
-from parse import N_IO, ADDR_WIDTH, DATA_WIDTH
-from parse import upper_offset, lower_offset
-from actual_pinmux import muxed_cells, pinmux
+from interface_decl import Interfaces, mux_interface, io_interface
+from parse import Parse
+from actual_pinmux import init
from bus_transactors import axi4_lite
-if not os.path.exists("bsv_src"):
- os.makedirs("bsv_src")
-
copyright = '''
/*
This BSV file has been generated by the PinMux tool available at:
Date of generation: ''' + time.strftime("%c") + '''
*/
'''
-header = copyright+'''
+header = copyright + '''
package pinmux;
typedef struct{
Bit#(1) opendrain_en; // opendrain enable form core to io_cell bit0
} GenericIOType deriving(Eq,Bits,FShow);
- interface MuxSelectionLines;
'''
footer = '''
endinterface;
endmodule
endpackage
'''
-# ============================================#
-# ==== populating the file with the code =====#
-# ============================================#
-# package and interface declaration followed by the generic io_cell definition
-with open("./bsv_src/pinmux.bsv", "w") as bsv_file:
- bsv_file.write(header)
- bsv_file.write('''
+def pinmuxgen(pth=None, verify=True):
+ """ populating the file with the code
+ """
+
+ p = Parse(pth, verify)
+ init(p)
+ ifaces = Interfaces(pth)
+ ifaces.ifaceadd('io', p.N_IO, io_interface, 0)
+
+ bp = 'bsv_src'
+ if pth:
+ bp = os.path.join(pth, bp)
+ if not os.path.exists(bp):
+ os.makedirs(bp)
+
+ pmp = os.path.join(bp, 'pinmux.bsv')
+ ptp = os.path.join(bp, 'PinTop.bsv')
+ bvp = os.path.join(bp, 'bus.bsv')
+
+ # package and interface declaration followed by
+ # the generic io_cell definition
+ with open(pmp, "w") as bsv_file:
+ bsv_file.write(header)
+
+ bsv_file.write('''\
+ interface MuxSelectionLines;
// declare the method which will capture the user pin-mux
// selection values.The width of the input is dependent on the number
// of muxes happening per IO. For now we have a generalized width
// where each IO will have the same number of muxes.''')
- for cell in muxed_cells:
- bsv_file.write(mux_interface.ifacefmt(cell[0],
- int(math.log(len(cell) - 1, 2))))
+ for cell in p.muxed_cells:
+ cnum = int(math.log(len(cell) - 1, 2))
+ bsv_file.write(mux_interface.ifacefmt(cell[0], cnum))
- bsv_file.write('''
+ bsv_file.write('''
endinterface
interface PeripheralSide;
// declare the interface to the IO cells.
// Each IO cell will have 8 input field (output from pin mux
// and on output field (input to pinmux)''')
- for i in range(0, N_IO):
- bsv_file.write('''\n // interface for IO CEll-{0}''')
- bsv_file.write(io_interface.ifacefmt(i))
- # ==============================================================
+ # ==============================================================
- # == create method definitions for all peripheral interfaces ==#
- ifaces.ifacefmt(bsv_file)
+ # == create method definitions for all peripheral interfaces ==#
+ ifaces.ifacefmt(bsv_file)
- # ==============================================================
+ # ==============================================================
- # ===== finish interface definition and start module definition=======
- bsv_file.write('''
+ # ===== finish interface definition and start module definition=======
+ bsv_file.write('''
endinterface
interface Ifc_pinmux;
(*synthesize*)
module mkpinmux(Ifc_pinmux);
''')
- # ====================================================================
+ # ====================================================================
- # ======================= create wire and registers =================#
- bsv_file.write('''
+ # ======================= create wire and registers =================#
+ bsv_file.write('''
// the followins wires capture the pin-mux selection
// values for each mux assigned to a CELL
''')
- for cell in muxed_cells:
- bsv_file.write(muxwire.format(
- cell[0], int(math.log(len(cell) - 1, 2))))
-
- bsv_file.write(
- '''\n // following wires capture the values sent to the IO Cell''')
- for i in range(0, N_IO):
- bsv_file.write(generic_io.format(i))
+ for cell in p.muxed_cells:
+ bsv_file.write(mux_interface.wirefmt(
+ cell[0], int(math.log(len(cell) - 1, 2))))
- ifaces.wirefmt(bsv_file)
+ ifaces.wirefmt(bsv_file)
- bsv_file.write("\n")
- # ====================================================================
- # ========================= Actual pinmuxing ========================#
- bsv_file.write('''
+ bsv_file.write("\n")
+ # ====================================================================
+ # ========================= Actual pinmuxing ========================#
+ bsv_file.write('''
/*====== This where the muxing starts for each io-cell======*/
''')
- bsv_file.write(pinmux)
- bsv_file.write('''
+ bsv_file.write(p.pinmux)
+ bsv_file.write('''
/*============================================================*/
''')
- # ====================================================================
- # ================= interface definitions for each method =============#
- bsv_file.write('''
+ # ====================================================================
+ # ================= interface definitions for each method =============#
+ bsv_file.write('''
interface mux_lines = interface MuxSelectionLines
''')
- for cell in muxed_cells:
- bsv_file.write(mux_interface.ifacedef(cell[0],
- int(math.log(len(cell) - 1, 2))))
- bsv_file.write('''
+ for cell in p.muxed_cells:
+ bsv_file.write(mux_interface.ifacedef(cell[0],
+ int(math.log(len(cell) - 1, 2))))
+ bsv_file.write('''
endinterface;
interface peripheral_side = interface PeripheralSide
''')
- for i in range(0, N_IO):
- bsv_file.write(io_interface.ifacedef(i))
- ifaces.ifacedef(bsv_file)
- bsv_file.write(footer)
- print("BSV file successfully generated: bsv_src/pinmux.bsv")
- # ======================================================================
-
-with open('bsv_src/PinTop.bsv', 'w') as bsv_file:
- bsv_file.write(copyright+'''
+ ifaces.ifacedef(bsv_file)
+ bsv_file.write(footer)
+ print("BSV file successfully generated: bsv_src/pinmux.bsv")
+ # ======================================================================
+
+ with open(ptp, 'w') as bsv_file:
+ bsv_file.write(copyright + '''
package PinTop;
import pinmux::*;
interface Ifc_PintTop;
Ifc_pinmux pinmux <-mkpinmux;
// declare the registers which will be used to mux the IOs
-'''.format(ADDR_WIDTH, DATA_WIDTH))
+'''.format(p.ADDR_WIDTH, p.DATA_WIDTH))
- for cell in muxed_cells:
- bsv_file.write('''
- Reg#(Bit#({0})) rg_muxio_{1} <-mkReg(0);'''.format(
- int(math.log(len(cell) - 1, 2)), cell[0]))
+ for cell in p.muxed_cells:
+ bsv_file.write('''
+ Reg#(Bit#({0})) rg_muxio_{1} <-mkReg(0);'''.format(
+ int(math.log(len(cell) - 1, 2)), cell[0]))
- bsv_file.write('''
+ bsv_file.write('''
// rule to connect the registers to the selection lines of the
// pin-mux module
rule connect_selection_registers;''')
- for cell in muxed_cells:
- bsv_file.write('''
+ for cell in p.muxed_cells:
+ bsv_file.write('''
pinmux.mux_lines.cell{0}_mux(rg_muxio_{0});'''.format(cell[0]))
- bsv_file.write('''
+ bsv_file.write('''
endrule
// method definitions for the write user interface
method ActionValue#(Bool) write(Bit#({2}) addr, Bit#({3}) data);
Bool err=False;
- case (addr[{0}:{1}])'''.format(upper_offset, lower_offset,
- ADDR_WIDTH, DATA_WIDTH))
- index = 0
- for cell in muxed_cells:
- bsv_file.write('''
+ case (addr[{0}:{1}])'''.format(p.upper_offset, p.lower_offset,
+ p.ADDR_WIDTH, p.DATA_WIDTH))
+ index = 0
+ for cell in p.muxed_cells:
+ bsv_file.write('''
{0}: rg_muxio_{1}<=truncate(data);'''.format(index, cell[0]))
- index = index + 1
+ index = index + 1
- bsv_file.write('''
+ bsv_file.write('''
default: err=True;
endcase
return err;
endmethod''')
- bsv_file.write('''
+ bsv_file.write('''
// method definitions for the read user interface
method Tuple2#(Bool,Bit#({3})) read(Bit#({2}) addr);
Bool err=False;
Bit#(32) data=0;
- case (addr[{0}:{1}])'''.format(upper_offset, lower_offset,
- ADDR_WIDTH, DATA_WIDTH))
- index = 0
- for cell in muxed_cells:
- bsv_file.write('''
- {0}: data=zeroExtend(rg_muxio_{1});'''.format(index, cell[0]))
- index = index + 1
+ case (addr[{0}:{1}])'''.format(p.upper_offset, p.lower_offset,
+ p.ADDR_WIDTH, p.DATA_WIDTH))
+ index = 0
+ for cell in p.muxed_cells:
+ bsv_file.write('''
+ {0}: data=zeroExtend(rg_muxio_{1});'''.format(index, cell[0]))
+ index = index + 1
- bsv_file.write('''
+ bsv_file.write('''
default:err=True;
endcase
return tuple2(err,data);
endpackage
''')
-# ######## Generate bus transactors ################
-with open('bsv_src/bus.bsv', 'w') as bsv_file:
- bsv_file.write(axi4_lite.format(ADDR_WIDTH, DATA_WIDTH))
-# ##################################################
+ # ######## Generate bus transactors ################
+ with open(bvp, 'w') as bsv_file:
+ bsv_file.write(axi4_lite.format(p.ADDR_WIDTH, p.DATA_WIDTH))
+ # ##################################################
+
+
+def printhelp():
+ print ('''pinmux_generator.py [-o outputdir] [-v|--validate] [-h|--help]
+ -o outputdir : defaults to bsv_src. also location for reading pinmux.txt
+ interfaces.txt and *.txt
+ -v | --validate : runs some validation on the pinmux
+ -h | --help : this help message
+''')
+
+
+if __name__ == '__main__':
+ try:
+ options, remainder = getopt.getopt(
+ sys.argv[1:],
+ 'o:vh',
+ ['output=',
+ 'validate',
+ 'help',
+ 'version=',
+ ])
+ except getopt.GetoptError as err:
+ print "ERROR: %s" % str(err)
+ printhelp()
+ sys.exit(1)
+
+ output_dir = None
+ validate = False
+ for opt, arg in options:
+ if opt in ('-o', '--output'):
+ output_dir = arg
+ elif opt in ('-v', '--validate'):
+ validate = True
+ elif opt in ('-h', '--help'):
+ printhelp()
+ sys.exit(0)
+
+ pinmuxgen(output_dir, validate)