use class iterator for mk_connection (all of them)
[pinmux.git] / src / pinmux_generator.py
index cefc77d3151846c8f3908924cec0f4b430355878..b95377b4bad5d00485b4ed2c9fac5d56c8305b0a 100644 (file)
 
 # default module imports
 import getopt
-import os
 import os.path
 import sys
-import time
-import math
+from spec import modules, specgen, dummytest
 
-# project module imports
-from interface_decl import Interfaces, mux_interface, io_interface
-from parse import Parse
-from actual_pinmux import init
-from bus_transactors import axi4_lite
-
-copyright = '''
-/*
-   This BSV file has been generated by the PinMux tool available at:
-   https://bitbucket.org/casl/pinmux.
-
-   Authors: Neel Gala, Luke
-   Date of generation: ''' + time.strftime("%c") + '''
-*/
-'''
-header = copyright + '''
-package pinmux;
-
-   typedef struct{
-      Bit#(1) outputval;      // output from core to pad                bit7
-      Bit#(1) output_en;      // output enable from core to pad         bit6
-      Bit#(1) input_en;       // input enable from core to io_cell      bit5
-      Bit#(1) pullup_en;      // pullup enable from core to io_cell     bit4
-      Bit#(1) pulldown_en;    // pulldown enable from core to io_cell   bit3
-      Bit#(1) drivestrength;  // drivestrength from core to io_cell     bit2
-      Bit#(1) pushpull_en;    // pushpull enable from core to io_cell   bit1
-      Bit#(1) opendrain_en;   // opendrain enable form core to io_cell  bit0
-   } GenericIOType deriving(Eq,Bits,FShow);
-
-'''
-footer = '''
-     endinterface;
-   endmodule
-endpackage
-'''
-
-def pinmuxgen(pth=None, verify=True):
-    """ populating the file with the code
-    """
-
-    p = Parse(pth, verify)
-    init(p)
-    ifaces = Interfaces()
-    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 p.muxed_cells:
-            bsv_file.write(mux_interface.ifacefmt(cell[0],
-                                              int(math.log(len(cell) - 1, 2))))
-
-        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)''')
-        # ==============================================================
-
-        # == create method definitions for all peripheral interfaces ==#
-        ifaces.ifacefmt(bsv_file)
-
-        # ==============================================================
-
-        # ===== finish interface definition and start module definition=======
-        bsv_file.write('''
-   endinterface
-
-   interface Ifc_pinmux;
-      interface MuxSelectionLines mux_lines;
-      interface PeripheralSide peripheral_side;
-   endinterface
-   (*synthesize*)
-   module mkpinmux(Ifc_pinmux);
-''')
-        # ====================================================================
-
-        # ======================= 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 p.muxed_cells:
-            bsv_file.write(mux_interface.wirefmt(
-                cell[0], int(math.log(len(cell) - 1, 2))))
-
-        ifaces.wirefmt(bsv_file)
-
-        bsv_file.write("\n")
-        # ====================================================================
-        # ========================= Actual pinmuxing ========================#
-        bsv_file.write('''
-      /*====== This where the muxing starts for each io-cell======*/
-''')
-        bsv_file.write(p.pinmux)
-        bsv_file.write('''
-      /*============================================================*/
-''')
-        # ====================================================================
-        # ================= interface definitions for each method =============#
-        bsv_file.write('''
-    interface mux_lines = interface MuxSelectionLines
-''')
-        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
-''')
-        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;
-        method ActionValue#(Bool) write(Bit#({0}) addr, Bit#({1}) data);
-        method Tuple2#(Bool,Bit#({1})) read(Bit#({0}) addr);
-        interface PeripheralSide peripheral_side;
-    endinterface
-
-    module mkPinTop(Ifc_PintTop);
-        // instantiate the pin-mux module here
-        Ifc_pinmux pinmux <-mkpinmux;
-
-        // declare the registers which will be used to mux the IOs
-'''.format(p.ADDR_WIDTH, p.DATA_WIDTH))
-
-        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('''
-        // rule to connect the registers to the selection lines of the
-        // pin-mux module
-        rule connect_selection_registers;''')
-
-        for cell in p.muxed_cells:
-            bsv_file.write('''
-          pinmux.mux_lines.cell{0}_mux(rg_muxio_{0});'''.format(cell[0]))
-
-        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(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
-
-        bsv_file.write('''
-            default: err=True;
-          endcase
-          return err;
-        endmethod''')
-
-        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(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('''
-            default:err=True;
-          endcase
-          return tuple2(err,data);
-        endmethod
-        interface peripheral_side=pinmux.peripheral_side;
-    endmodule
-endpackage
-''')
-
-    # ######## 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]
+                                  [-t outputtype] [-s|--spec spec]
+    -s | spec       : generate from spec (python module)
+    -t | outputtype : outputtype, defaults to bsv
     -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',
+            'o:vht:s:',
             ['output=',
              'validate',
+             'test',
+             'outputtype=',
+             'spec=',
              'help',
              'version=',
              ])
     except getopt.GetoptError as err:
-        print "ERROR: %s" % str(err)
+        print ("ERROR: %s" % str(err))
         printhelp()
         sys.exit(1)
 
+    output_type = 'bsv'
     output_dir = None
     validate = False
+    spec = None
+    pinspec = None
+    testing = False
     for opt, arg in options:
         if opt in ('-o', '--output'):
             output_dir = arg
+        elif opt in ('-s', '--spec'):
+            pinspec = arg
+        elif opt in ('-t', '--outputtype'):
+            output_type = arg
         elif opt in ('-v', '--validate'):
             validate = True
+        elif opt in ('--test',):
+            testing = True
         elif opt in ('-h', '--help'):
             printhelp()
             sys.exit(0)
 
-    pinmuxgen(output_dir, validate)
+    if pinspec:
+        if pinspec not in modules:
+            print ("ERROR: spec type '%s' does not exist" % pinspec)
+            printhelp()
+            sys.exit(1)
+        module = modules[pinspec]
+
+        fname = os.path.join(output_dir or '', "%s.mdwn" % pinspec)
+        d = os.path.split(fname)[0]
+        if not os.path.exists(d):
+            os.makedirs(d)
+        with open(fname, "w") as of:
+            ps = module.pinspec()
+            pinout, bankspec, pinspec, fixedpins = ps.write(of)
+            if testing:
+                dummytest(ps, output_dir, output_type)
+            else:
+                specgen(of, output_dir, pinout,
+                        bankspec, ps.muxwidths, pinspec, fixedpins, ps.fastbus)
+    else:
+        if output_type == 'bsv':
+            from bsv.pinmux_generator import pinmuxgen as gentypes
+        elif output_type == 'myhdl':
+            from myhdlgen.pinmux_generator import pinmuxgen as gentypes
+        else:
+            print ("ERROR: output type '%s' does not exist" % output_type)
+            printhelp()
+            sys.exit(0)
 
+        gentypes(output_dir, validate)