From 17ab361abe56c3311d39b4141a68aefca09119ca Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Fri, 23 Mar 2018 16:43:44 +0000 Subject: [PATCH] move pinmux generator function to src/bsv directory --- src/bsv/__init__.py | 0 src/{ => bsv}/bsv_lib/AXI4_Lite_Types.bsv | 0 src/{ => bsv}/bsv_lib/Semi_FIFOF.bsv | 0 src/bsv/pinmux_generator.py | 239 ++++++++++++++++++++++ src/pinmux_generator.py | 236 ++------------------- 5 files changed, 254 insertions(+), 221 deletions(-) create mode 100644 src/bsv/__init__.py rename src/{ => bsv}/bsv_lib/AXI4_Lite_Types.bsv (100%) rename src/{ => bsv}/bsv_lib/Semi_FIFOF.bsv (100%) create mode 100644 src/bsv/pinmux_generator.py diff --git a/src/bsv/__init__.py b/src/bsv/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/bsv_lib/AXI4_Lite_Types.bsv b/src/bsv/bsv_lib/AXI4_Lite_Types.bsv similarity index 100% rename from src/bsv_lib/AXI4_Lite_Types.bsv rename to src/bsv/bsv_lib/AXI4_Lite_Types.bsv diff --git a/src/bsv_lib/Semi_FIFOF.bsv b/src/bsv/bsv_lib/Semi_FIFOF.bsv similarity index 100% rename from src/bsv_lib/Semi_FIFOF.bsv rename to src/bsv/bsv_lib/Semi_FIFOF.bsv diff --git a/src/bsv/pinmux_generator.py b/src/bsv/pinmux_generator.py new file mode 100644 index 0000000..7513d68 --- /dev/null +++ b/src/bsv/pinmux_generator.py @@ -0,0 +1,239 @@ +# ================================== Steps to add peripherals ============ +# Step-1: create interface declaration for the peripheral to be added. +# Remember these are interfaces defined for the pinmux and hence +# will be opposite to those defined at the peripheral. +# For eg. the output TX from the UART will be input (method Action) +# for the pinmux. +# These changes will have to be done in interface_decl.py +# Step-2 define the wires that will be required to transfer data from the +# peripheral interface to the IO cell and vice-versa. Create a +# mkDWire for each input/output between the peripheral and the +# pinmux. Also create an implicit wire of GenericIOType for each cell +# that can be connected to a each bit from the peripheral. +# These changes will have to be done in wire_def.py +# Step-3: create the definitions for each of the methods defined above. +# These changes will have to be done in interface_decl.py +# ======================================================================== + +# default module imports +import os +import os.path +import time +import math + +# 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(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 p.muxed_cells: + cnum = int(math.log(len(cell) - 1, 2)) + bsv_file.write(mux_interface.ifacefmt(cell[0], cnum)) + + 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)) + # ################################################## + diff --git a/src/pinmux_generator.py b/src/pinmux_generator.py index 661060f..407314c 100644 --- a/src/pinmux_generator.py +++ b/src/pinmux_generator.py @@ -17,231 +17,15 @@ # default module imports import getopt -import os import os.path import sys -import time -import math - -# 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(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 p.muxed_cells: - cnum = int(math.log(len(cell) - 1, 2)) - bsv_file.write(mux_interface.ifacefmt(cell[0], cnum)) - - 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)) - # ################################################## +from bsv.pinmux_generator import pinmuxgen as bsvgen def printhelp(): print ('''pinmux_generator.py [-o outputdir] [-v|--validate] [-h|--help] + [-t outputtype] + -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 @@ -253,9 +37,10 @@ if __name__ == '__main__': try: options, remainder = getopt.getopt( sys.argv[1:], - 'o:vh', + 'o:vht:', ['output=', 'validate', + 'outputtype=', 'help', 'version=', ]) @@ -264,15 +49,24 @@ if __name__ == '__main__': printhelp() sys.exit(1) + output_type = 'bsv' output_dir = None validate = False for opt, arg in options: if opt in ('-o', '--output'): output_dir = arg + elif opt in ('-t', '--outputtype'): + output_type = arg elif opt in ('-v', '--validate'): validate = True elif opt in ('-h', '--help'): printhelp() sys.exit(0) - pinmuxgen(output_dir, validate) + gentypes = {'bsv': bsvgen} + if not gentypes.has_key(output_type): + print "ERROR: output type '%s' does not exist" % output_type + printhelp() + sys.exit(0) + gentypes[output_type](output_dir, validate) + -- 2.30.2