move pinmux generator function to src/bsv directory
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 23 Mar 2018 16:43:44 +0000 (16:43 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 23 Mar 2018 16:43:44 +0000 (16:43 +0000)
src/bsv/__init__.py [new file with mode: 0644]
src/bsv/bsv_lib/AXI4_Lite_Types.bsv [new file with mode: 0644]
src/bsv/bsv_lib/Semi_FIFOF.bsv [new file with mode: 0644]
src/bsv/pinmux_generator.py [new file with mode: 0644]
src/bsv_lib/AXI4_Lite_Types.bsv [deleted file]
src/bsv_lib/Semi_FIFOF.bsv [deleted file]
src/pinmux_generator.py

diff --git a/src/bsv/__init__.py b/src/bsv/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/bsv/bsv_lib/AXI4_Lite_Types.bsv b/src/bsv/bsv_lib/AXI4_Lite_Types.bsv
new file mode 100644 (file)
index 0000000..a1bb465
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+Copyright (c) 2013, IIT Madras
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+*  Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+*  Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+*  Neither the name of IIT Madras  nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+------------------------------------------------------------------------
+
+*/
+// Copyright (c) 2017 Bluespec, Inc.  All Rights Reserved
+
+package AXI4_Lite_Types;
+
+// ================================================================
+// BSV library imports
+
+import FIFOF       :: *;
+import Connectable :: *;
+
+// ----------------
+// BSV additional libs
+
+import Semi_FIFOF :: *;
+
+// ****************************************************************
+// ****************************************************************
+// Section: RTL-level interfaces
+// ****************************************************************
+// ****************************************************************
+
+// ================================================================
+// These are the signal-level interfaces for an AXI4-Lite master.
+// The (*..*) attributes ensure that when bsc compiles this to Verilog,
+// we get exactly the signals specified in the ARM spec.
+
+interface AXI4_Lite_Slave_IFC #(numeric type wd_addr,
+                               numeric type wd_data,
+                               numeric type wd_user);
+   // Wr Addr channel
+   (* always_ready, always_enabled *)
+   method Action m_awvalid ((* port="awvalid" *) Bool           awvalid,    // in
+                           (* port="awaddr" *)  Bit #(wd_addr) awaddr,     // in
+                           (* port="awsize" *)   Bit #(3) awsize,                                              // in
+                           (* port="awuser" *)  Bit #(wd_user) awuser);    // in
+   (* always_ready, result="awready" *)
+   method Bool m_awready;                                                   // out
+
+   // Wr Data channel
+   (* always_ready, always_enabled *)
+   method Action m_wvalid ((* port="wvalid" *) Bool                     wvalid,    // in
+                          (* port="wdata" *)  Bit #(wd_data)           wdata,     // in
+                          (* port="wstrb" *)  Bit #(TDiv #(wd_data,8)) wstrb);    // in
+   (* always_ready, result="wready" *)
+   method Bool m_wready;                                                           // out
+
+   // Wr Response channel
+   (* always_ready, result="bvalid" *)  method Bool           m_bvalid;                                 // out
+   (* always_ready, result="bresp" *)   method Bit #(2)       m_bresp;                                  // out
+   (* always_ready, result="buser" *)   method Bit #(wd_user) m_buser;                                  // out
+   (* always_ready, always_enabled *)   method Action m_bready  ((* port="bready" *)   Bool bready);    // in
+
+   // Rd Addr channel
+   (* always_ready, always_enabled *)
+   method Action m_arvalid ((* port="arvalid" *) Bool           arvalid,    // in
+                           (* port="araddr" *)  Bit #(wd_addr) araddr,     // in
+                                (* port="arsize" *)     Bit #(3)  arsize,        // in
+                           (* port="aruser" *)  Bit #(wd_user) aruser);    // in
+   (* always_ready, result="arready" *)
+   method Bool m_arready;                                                   // out
+
+   // Rd Data channel
+   (* always_ready, result="rvalid" *)  method Bool           m_rvalid;                                 // out
+   (* always_ready, result="rresp" *)   method Bit #(2)       m_rresp;                                  // out
+   (* always_ready, result="rdata" *)   method Bit #(wd_data) m_rdata;                                  // out
+   (* always_ready, result="ruser" *)   method Bit #(wd_user) m_ruser;                                  // out
+   (* always_ready, always_enabled *)   method Action m_rready  ((* port="rready" *)   Bool rready);    // in
+endinterface: AXI4_Lite_Slave_IFC
+// ================================================================
+// Higher-level types for payloads (rather than just bits)
+
+typedef enum { AXI4_LITE_OKAY, AXI4_LITE_EXOKAY, AXI4_LITE_SLVERR, AXI4_LITE_DECERR } AXI4_Lite_Resp
+deriving (Bits, Eq, FShow);
+
+// Write Address channel
+
+typedef struct {
+   Bit #(wd_addr)  awaddr;
+   Bit #(wd_user)  awuser;
+       Bit#(3)                                 awsize;
+   } AXI4_Lite_Wr_Addr #(numeric type wd_addr, numeric type wd_user)
+deriving (Bits, FShow);
+
+// Write Data channel
+
+typedef struct {
+   Bit #(wd_data)             wdata;
+   Bit #(TDiv #(wd_data, 8))  wstrb;
+   } AXI4_Lite_Wr_Data #(numeric type wd_data)
+deriving (Bits, FShow);
+
+// Write Response channel
+
+typedef struct {
+   AXI4_Lite_Resp  bresp;
+   Bit #(wd_user)  buser;
+   } AXI4_Lite_Wr_Resp #(numeric type wd_user)
+deriving (Bits, FShow);
+
+// Read Address channel
+
+typedef struct {
+   Bit #(wd_addr)  araddr;
+   Bit #(wd_user)  aruser;
+       Bit#(3)                  arsize;
+   } AXI4_Lite_Rd_Addr #(numeric type wd_addr, numeric type wd_user)
+deriving (Bits, FShow);
+
+// Read Data channel
+
+typedef struct {
+   AXI4_Lite_Resp  rresp;
+   Bit #(wd_data)  rdata;
+   Bit #(wd_user)  ruser;
+   } AXI4_Lite_Rd_Data #(numeric type wd_data, numeric type wd_user)
+deriving (Bits, FShow);
+
+// ================================================================
+// Slave transactor interface
+
+interface AXI4_Lite_Slave_Xactor_IFC #(numeric type wd_addr,
+                                      numeric type wd_data,
+                                      numeric type wd_user);
+   method Action reset;
+
+   // AXI side
+   interface AXI4_Lite_Slave_IFC #(wd_addr, wd_data, wd_user) axi_side;
+
+   // FIFOF side
+   interface FIFOF_O #(AXI4_Lite_Wr_Addr #(wd_addr, wd_user)) o_wr_addr;
+   interface FIFOF_O #(AXI4_Lite_Wr_Data #(wd_data))          o_wr_data;
+   interface FIFOF_I #(AXI4_Lite_Wr_Resp #(wd_user))          i_wr_resp;
+
+   interface FIFOF_O #(AXI4_Lite_Rd_Addr #(wd_addr, wd_user)) o_rd_addr;
+   interface FIFOF_I #(AXI4_Lite_Rd_Data #(wd_data, wd_user)) i_rd_data;
+endinterface: AXI4_Lite_Slave_Xactor_IFC
+
+// ----------------------------------------------------------------
+// Slave transactor
+
+module mkAXI4_Lite_Slave_Xactor (AXI4_Lite_Slave_Xactor_IFC #(wd_addr, wd_data, wd_user));
+
+   Bool unguarded = True;
+   Bool guarded   = False;
+
+   // These FIFOs are guarded on BSV side, unguarded on AXI side
+   FIFOF #(AXI4_Lite_Wr_Addr #(wd_addr, wd_user)) f_wr_addr <- mkGFIFOF (unguarded, guarded);
+   FIFOF #(AXI4_Lite_Wr_Data #(wd_data))          f_wr_data <- mkGFIFOF (unguarded, guarded);
+   FIFOF #(AXI4_Lite_Wr_Resp #(wd_user))          f_wr_resp <- mkGFIFOF (guarded, unguarded);
+
+   FIFOF #(AXI4_Lite_Rd_Addr #(wd_addr, wd_user)) f_rd_addr <- mkGFIFOF (unguarded, guarded);
+   FIFOF #(AXI4_Lite_Rd_Data #(wd_data, wd_user)) f_rd_data <- mkGFIFOF (guarded, unguarded);
+
+   // ----------------------------------------------------------------
+   // INTERFACE
+
+   method Action reset;
+      f_wr_addr.clear;
+      f_wr_data.clear;
+      f_wr_resp.clear;
+      f_rd_addr.clear;
+      f_rd_data.clear;
+   endmethod
+
+   // AXI side
+   interface axi_side = interface AXI4_Lite_Slave_IFC;
+                          // Wr Addr channel
+                          method Action m_awvalid (Bool           awvalid,
+                                                   Bit #(wd_addr) awaddr,
+                                                        Bit#(3) awsize,
+                                                   Bit #(wd_user) awuser);
+                             if (awvalid && f_wr_addr.notFull)
+                                f_wr_addr.enq (AXI4_Lite_Wr_Addr {awaddr: awaddr,
+                                                                       awsize:awsize,
+                                                                  awuser: awuser});
+                          endmethod
+
+                          method Bool m_awready;
+                             return f_wr_addr.notFull;
+                          endmethod
+
+                          // Wr Data channel
+                          method Action m_wvalid (Bool                      wvalid,
+                                                  Bit #(wd_data)            wdata,
+                                                  Bit #(TDiv #(wd_data, 8)) wstrb);
+                             if (wvalid && f_wr_data.notFull)
+                                f_wr_data.enq (AXI4_Lite_Wr_Data {wdata: wdata, wstrb: wstrb});
+                          endmethod
+
+                          method Bool m_wready;
+                             return f_wr_data.notFull;
+                          endmethod
+
+                          // Wr Response channel
+                          method Bool           m_bvalid = f_wr_resp.notEmpty;
+                          method Bit #(2)       m_bresp  = pack (f_wr_resp.first.bresp);
+                          method Bit #(wd_user) m_buser  = f_wr_resp.first.buser;
+                          method Action m_bready (Bool bready);
+                             if (bready && f_wr_resp.notEmpty)
+                                f_wr_resp.deq;
+                          endmethod
+
+                          // Rd Addr channel
+                          method Action m_arvalid (Bool           arvalid,
+                                                   Bit #(wd_addr) araddr,
+                                                        Bit#(3)                                 arsize,
+                                                   Bit #(wd_user) aruser);
+                             if (arvalid && f_rd_addr.notFull)
+                                f_rd_addr.enq (AXI4_Lite_Rd_Addr {araddr: araddr,
+                                                                       arsize: arsize,
+                                                                  aruser: aruser});
+                          endmethod
+
+                          method Bool m_arready;
+                             return f_rd_addr.notFull;
+                          endmethod
+
+                          // Rd Data channel
+                          method Bool           m_rvalid = f_rd_data.notEmpty;
+                          method Bit #(2)       m_rresp  = pack (f_rd_data.first.rresp);
+                          method Bit #(wd_data) m_rdata  = f_rd_data.first.rdata;
+                          method Bit #(wd_user) m_ruser  = f_rd_data.first.ruser;
+                          method Action m_rready (Bool rready);
+                             if (rready && f_rd_data.notEmpty)
+                                f_rd_data.deq;
+                          endmethod
+                       endinterface;
+
+   // FIFOF side
+   interface o_wr_addr = to_FIFOF_O (f_wr_addr);
+   interface o_wr_data = to_FIFOF_O (f_wr_data);
+   interface i_wr_resp = to_FIFOF_I (f_wr_resp);
+
+   interface o_rd_addr = to_FIFOF_O (f_rd_addr);
+   interface i_rd_data = to_FIFOF_I (f_rd_data);
+endmodule: mkAXI4_Lite_Slave_Xactor
+
+// ================================================================
+
+endpackage
diff --git a/src/bsv/bsv_lib/Semi_FIFOF.bsv b/src/bsv/bsv_lib/Semi_FIFOF.bsv
new file mode 100644 (file)
index 0000000..08ff7c1
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+Copyright (c) 2013, IIT Madras
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+*  Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+*  Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+*  Neither the name of IIT Madras  nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------
+
+*/
+// Copyright (c) 2017 Bluespec, Inc.  All Rights Reserved
+
+package Semi_FIFOF;
+
+// ================================================================
+// Separate interfaces for input-side and output-side of FIFOF.
+// Conversion functions to these, from FIFOF interfaces.
+
+// ================================================================
+// BSV library imports
+
+import FIFOF       :: *;
+import Connectable :: *;
+
+// ================================================================
+// Semi-FIFOF interfaces
+
+interface FIFOF_I #(type t);
+   method Action  enq (t x);
+   method Bool    notFull ();
+endinterface
+
+interface FIFOF_O #(type t);
+   method t       first ();
+   method Action  deq ();
+   method Bool    notEmpty ();
+endinterface
+
+// ================================================================
+// Converters from FIFOF
+
+function FIFOF_I #(t) to_FIFOF_I (FIFOF #(t) f);
+   return interface FIFOF_I;
+            method enq (x) = f.enq (x);
+            method notFull = f.notFull;
+         endinterface;
+endfunction
+
+function FIFOF_O #(t) to_FIFOF_O (FIFOF #(t) f);
+   return interface FIFOF_O;
+            method first    = f.first;
+            method deq      = f.deq;
+            method notEmpty = f.notEmpty;
+         endinterface;
+endfunction
+
+// ================================================================
+// Connections
+
+// ----------------
+// FIFOF_O to a FIFOF_I
+
+instance Connectable #(FIFOF_O #(t), FIFOF_I #(t));
+   module mkConnection #(FIFOF_O #(t) fo, FIFOF_I #(t) fi) (Empty);
+      rule rl_connect;
+        fi.enq (fo.first);
+        fo.deq;
+      endrule
+   endmodule
+endinstance
+
+// ----------------
+// FIFOF_O to a FIFOF
+
+instance Connectable #(FIFOF_O #(t), FIFOF #(t));
+   module mkConnection #(FIFOF_O #(t) fo, FIFOF #(t) fi) (Empty);
+      rule rl_connect;
+        fi.enq (fo.first);
+        fo.deq;
+      endrule
+   endmodule
+endinstance
+
+// ----------------
+// FIFOF to a FIFOF_I
+
+instance Connectable #(FIFOF #(t), FIFOF_I #(t));
+   module mkConnection #(FIFOF #(t) fo, FIFOF_I #(t) fi) (Empty);
+      rule rl_connect;
+        fi.enq (fo.first);
+        fo.deq;
+      endrule
+   endmodule
+endinstance
+
+// ================================================================
+// Convenience function combining first/enq
+
+function ActionValue #(t) pop_o (FIFOF_O #(t) f);
+   actionvalue
+      f.deq;
+      return f.first;
+   endactionvalue
+endfunction
+
+// ================================================================
+
+endpackage
diff --git a/src/bsv/pinmux_generator.py b/src/bsv/pinmux_generator.py
new file mode 100644 (file)
index 0000000..7513d68
--- /dev/null
@@ -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/bsv_lib/AXI4_Lite_Types.bsv b/src/bsv_lib/AXI4_Lite_Types.bsv
deleted file mode 100644 (file)
index a1bb465..0000000
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
-Copyright (c) 2013, IIT Madras
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-*  Redistributions of source code must retain the above copyright notice,
-   this list of conditions and the following disclaimer.
-*  Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-*  Neither the name of IIT Madras  nor the names of its contributors
-   may be used to endorse or promote products derived from this software
-   without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-------------------------------------------------------------------------
-
-*/
-// Copyright (c) 2017 Bluespec, Inc.  All Rights Reserved
-
-package AXI4_Lite_Types;
-
-// ================================================================
-// BSV library imports
-
-import FIFOF       :: *;
-import Connectable :: *;
-
-// ----------------
-// BSV additional libs
-
-import Semi_FIFOF :: *;
-
-// ****************************************************************
-// ****************************************************************
-// Section: RTL-level interfaces
-// ****************************************************************
-// ****************************************************************
-
-// ================================================================
-// These are the signal-level interfaces for an AXI4-Lite master.
-// The (*..*) attributes ensure that when bsc compiles this to Verilog,
-// we get exactly the signals specified in the ARM spec.
-
-interface AXI4_Lite_Slave_IFC #(numeric type wd_addr,
-                               numeric type wd_data,
-                               numeric type wd_user);
-   // Wr Addr channel
-   (* always_ready, always_enabled *)
-   method Action m_awvalid ((* port="awvalid" *) Bool           awvalid,    // in
-                           (* port="awaddr" *)  Bit #(wd_addr) awaddr,     // in
-                           (* port="awsize" *)   Bit #(3) awsize,                                              // in
-                           (* port="awuser" *)  Bit #(wd_user) awuser);    // in
-   (* always_ready, result="awready" *)
-   method Bool m_awready;                                                   // out
-
-   // Wr Data channel
-   (* always_ready, always_enabled *)
-   method Action m_wvalid ((* port="wvalid" *) Bool                     wvalid,    // in
-                          (* port="wdata" *)  Bit #(wd_data)           wdata,     // in
-                          (* port="wstrb" *)  Bit #(TDiv #(wd_data,8)) wstrb);    // in
-   (* always_ready, result="wready" *)
-   method Bool m_wready;                                                           // out
-
-   // Wr Response channel
-   (* always_ready, result="bvalid" *)  method Bool           m_bvalid;                                 // out
-   (* always_ready, result="bresp" *)   method Bit #(2)       m_bresp;                                  // out
-   (* always_ready, result="buser" *)   method Bit #(wd_user) m_buser;                                  // out
-   (* always_ready, always_enabled *)   method Action m_bready  ((* port="bready" *)   Bool bready);    // in
-
-   // Rd Addr channel
-   (* always_ready, always_enabled *)
-   method Action m_arvalid ((* port="arvalid" *) Bool           arvalid,    // in
-                           (* port="araddr" *)  Bit #(wd_addr) araddr,     // in
-                                (* port="arsize" *)     Bit #(3)  arsize,        // in
-                           (* port="aruser" *)  Bit #(wd_user) aruser);    // in
-   (* always_ready, result="arready" *)
-   method Bool m_arready;                                                   // out
-
-   // Rd Data channel
-   (* always_ready, result="rvalid" *)  method Bool           m_rvalid;                                 // out
-   (* always_ready, result="rresp" *)   method Bit #(2)       m_rresp;                                  // out
-   (* always_ready, result="rdata" *)   method Bit #(wd_data) m_rdata;                                  // out
-   (* always_ready, result="ruser" *)   method Bit #(wd_user) m_ruser;                                  // out
-   (* always_ready, always_enabled *)   method Action m_rready  ((* port="rready" *)   Bool rready);    // in
-endinterface: AXI4_Lite_Slave_IFC
-// ================================================================
-// Higher-level types for payloads (rather than just bits)
-
-typedef enum { AXI4_LITE_OKAY, AXI4_LITE_EXOKAY, AXI4_LITE_SLVERR, AXI4_LITE_DECERR } AXI4_Lite_Resp
-deriving (Bits, Eq, FShow);
-
-// Write Address channel
-
-typedef struct {
-   Bit #(wd_addr)  awaddr;
-   Bit #(wd_user)  awuser;
-       Bit#(3)                                 awsize;
-   } AXI4_Lite_Wr_Addr #(numeric type wd_addr, numeric type wd_user)
-deriving (Bits, FShow);
-
-// Write Data channel
-
-typedef struct {
-   Bit #(wd_data)             wdata;
-   Bit #(TDiv #(wd_data, 8))  wstrb;
-   } AXI4_Lite_Wr_Data #(numeric type wd_data)
-deriving (Bits, FShow);
-
-// Write Response channel
-
-typedef struct {
-   AXI4_Lite_Resp  bresp;
-   Bit #(wd_user)  buser;
-   } AXI4_Lite_Wr_Resp #(numeric type wd_user)
-deriving (Bits, FShow);
-
-// Read Address channel
-
-typedef struct {
-   Bit #(wd_addr)  araddr;
-   Bit #(wd_user)  aruser;
-       Bit#(3)                  arsize;
-   } AXI4_Lite_Rd_Addr #(numeric type wd_addr, numeric type wd_user)
-deriving (Bits, FShow);
-
-// Read Data channel
-
-typedef struct {
-   AXI4_Lite_Resp  rresp;
-   Bit #(wd_data)  rdata;
-   Bit #(wd_user)  ruser;
-   } AXI4_Lite_Rd_Data #(numeric type wd_data, numeric type wd_user)
-deriving (Bits, FShow);
-
-// ================================================================
-// Slave transactor interface
-
-interface AXI4_Lite_Slave_Xactor_IFC #(numeric type wd_addr,
-                                      numeric type wd_data,
-                                      numeric type wd_user);
-   method Action reset;
-
-   // AXI side
-   interface AXI4_Lite_Slave_IFC #(wd_addr, wd_data, wd_user) axi_side;
-
-   // FIFOF side
-   interface FIFOF_O #(AXI4_Lite_Wr_Addr #(wd_addr, wd_user)) o_wr_addr;
-   interface FIFOF_O #(AXI4_Lite_Wr_Data #(wd_data))          o_wr_data;
-   interface FIFOF_I #(AXI4_Lite_Wr_Resp #(wd_user))          i_wr_resp;
-
-   interface FIFOF_O #(AXI4_Lite_Rd_Addr #(wd_addr, wd_user)) o_rd_addr;
-   interface FIFOF_I #(AXI4_Lite_Rd_Data #(wd_data, wd_user)) i_rd_data;
-endinterface: AXI4_Lite_Slave_Xactor_IFC
-
-// ----------------------------------------------------------------
-// Slave transactor
-
-module mkAXI4_Lite_Slave_Xactor (AXI4_Lite_Slave_Xactor_IFC #(wd_addr, wd_data, wd_user));
-
-   Bool unguarded = True;
-   Bool guarded   = False;
-
-   // These FIFOs are guarded on BSV side, unguarded on AXI side
-   FIFOF #(AXI4_Lite_Wr_Addr #(wd_addr, wd_user)) f_wr_addr <- mkGFIFOF (unguarded, guarded);
-   FIFOF #(AXI4_Lite_Wr_Data #(wd_data))          f_wr_data <- mkGFIFOF (unguarded, guarded);
-   FIFOF #(AXI4_Lite_Wr_Resp #(wd_user))          f_wr_resp <- mkGFIFOF (guarded, unguarded);
-
-   FIFOF #(AXI4_Lite_Rd_Addr #(wd_addr, wd_user)) f_rd_addr <- mkGFIFOF (unguarded, guarded);
-   FIFOF #(AXI4_Lite_Rd_Data #(wd_data, wd_user)) f_rd_data <- mkGFIFOF (guarded, unguarded);
-
-   // ----------------------------------------------------------------
-   // INTERFACE
-
-   method Action reset;
-      f_wr_addr.clear;
-      f_wr_data.clear;
-      f_wr_resp.clear;
-      f_rd_addr.clear;
-      f_rd_data.clear;
-   endmethod
-
-   // AXI side
-   interface axi_side = interface AXI4_Lite_Slave_IFC;
-                          // Wr Addr channel
-                          method Action m_awvalid (Bool           awvalid,
-                                                   Bit #(wd_addr) awaddr,
-                                                        Bit#(3) awsize,
-                                                   Bit #(wd_user) awuser);
-                             if (awvalid && f_wr_addr.notFull)
-                                f_wr_addr.enq (AXI4_Lite_Wr_Addr {awaddr: awaddr,
-                                                                       awsize:awsize,
-                                                                  awuser: awuser});
-                          endmethod
-
-                          method Bool m_awready;
-                             return f_wr_addr.notFull;
-                          endmethod
-
-                          // Wr Data channel
-                          method Action m_wvalid (Bool                      wvalid,
-                                                  Bit #(wd_data)            wdata,
-                                                  Bit #(TDiv #(wd_data, 8)) wstrb);
-                             if (wvalid && f_wr_data.notFull)
-                                f_wr_data.enq (AXI4_Lite_Wr_Data {wdata: wdata, wstrb: wstrb});
-                          endmethod
-
-                          method Bool m_wready;
-                             return f_wr_data.notFull;
-                          endmethod
-
-                          // Wr Response channel
-                          method Bool           m_bvalid = f_wr_resp.notEmpty;
-                          method Bit #(2)       m_bresp  = pack (f_wr_resp.first.bresp);
-                          method Bit #(wd_user) m_buser  = f_wr_resp.first.buser;
-                          method Action m_bready (Bool bready);
-                             if (bready && f_wr_resp.notEmpty)
-                                f_wr_resp.deq;
-                          endmethod
-
-                          // Rd Addr channel
-                          method Action m_arvalid (Bool           arvalid,
-                                                   Bit #(wd_addr) araddr,
-                                                        Bit#(3)                                 arsize,
-                                                   Bit #(wd_user) aruser);
-                             if (arvalid && f_rd_addr.notFull)
-                                f_rd_addr.enq (AXI4_Lite_Rd_Addr {araddr: araddr,
-                                                                       arsize: arsize,
-                                                                  aruser: aruser});
-                          endmethod
-
-                          method Bool m_arready;
-                             return f_rd_addr.notFull;
-                          endmethod
-
-                          // Rd Data channel
-                          method Bool           m_rvalid = f_rd_data.notEmpty;
-                          method Bit #(2)       m_rresp  = pack (f_rd_data.first.rresp);
-                          method Bit #(wd_data) m_rdata  = f_rd_data.first.rdata;
-                          method Bit #(wd_user) m_ruser  = f_rd_data.first.ruser;
-                          method Action m_rready (Bool rready);
-                             if (rready && f_rd_data.notEmpty)
-                                f_rd_data.deq;
-                          endmethod
-                       endinterface;
-
-   // FIFOF side
-   interface o_wr_addr = to_FIFOF_O (f_wr_addr);
-   interface o_wr_data = to_FIFOF_O (f_wr_data);
-   interface i_wr_resp = to_FIFOF_I (f_wr_resp);
-
-   interface o_rd_addr = to_FIFOF_O (f_rd_addr);
-   interface i_rd_data = to_FIFOF_I (f_rd_data);
-endmodule: mkAXI4_Lite_Slave_Xactor
-
-// ================================================================
-
-endpackage
diff --git a/src/bsv_lib/Semi_FIFOF.bsv b/src/bsv_lib/Semi_FIFOF.bsv
deleted file mode 100644 (file)
index 08ff7c1..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
-Copyright (c) 2013, IIT Madras
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-*  Redistributions of source code must retain the above copyright notice,
-   this list of conditions and the following disclaimer.
-*  Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-*  Neither the name of IIT Madras  nor the names of its contributors
-   may be used to endorse or promote products derived from this software
-   without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------
-
-*/
-// Copyright (c) 2017 Bluespec, Inc.  All Rights Reserved
-
-package Semi_FIFOF;
-
-// ================================================================
-// Separate interfaces for input-side and output-side of FIFOF.
-// Conversion functions to these, from FIFOF interfaces.
-
-// ================================================================
-// BSV library imports
-
-import FIFOF       :: *;
-import Connectable :: *;
-
-// ================================================================
-// Semi-FIFOF interfaces
-
-interface FIFOF_I #(type t);
-   method Action  enq (t x);
-   method Bool    notFull ();
-endinterface
-
-interface FIFOF_O #(type t);
-   method t       first ();
-   method Action  deq ();
-   method Bool    notEmpty ();
-endinterface
-
-// ================================================================
-// Converters from FIFOF
-
-function FIFOF_I #(t) to_FIFOF_I (FIFOF #(t) f);
-   return interface FIFOF_I;
-            method enq (x) = f.enq (x);
-            method notFull = f.notFull;
-         endinterface;
-endfunction
-
-function FIFOF_O #(t) to_FIFOF_O (FIFOF #(t) f);
-   return interface FIFOF_O;
-            method first    = f.first;
-            method deq      = f.deq;
-            method notEmpty = f.notEmpty;
-         endinterface;
-endfunction
-
-// ================================================================
-// Connections
-
-// ----------------
-// FIFOF_O to a FIFOF_I
-
-instance Connectable #(FIFOF_O #(t), FIFOF_I #(t));
-   module mkConnection #(FIFOF_O #(t) fo, FIFOF_I #(t) fi) (Empty);
-      rule rl_connect;
-        fi.enq (fo.first);
-        fo.deq;
-      endrule
-   endmodule
-endinstance
-
-// ----------------
-// FIFOF_O to a FIFOF
-
-instance Connectable #(FIFOF_O #(t), FIFOF #(t));
-   module mkConnection #(FIFOF_O #(t) fo, FIFOF #(t) fi) (Empty);
-      rule rl_connect;
-        fi.enq (fo.first);
-        fo.deq;
-      endrule
-   endmodule
-endinstance
-
-// ----------------
-// FIFOF to a FIFOF_I
-
-instance Connectable #(FIFOF #(t), FIFOF_I #(t));
-   module mkConnection #(FIFOF #(t) fo, FIFOF_I #(t) fi) (Empty);
-      rule rl_connect;
-        fi.enq (fo.first);
-        fo.deq;
-      endrule
-   endmodule
-endinstance
-
-// ================================================================
-// Convenience function combining first/enq
-
-function ActionValue #(t) pop_o (FIFOF_O #(t) f);
-   actionvalue
-      f.deq;
-      return f.first;
-   endactionvalue
-endfunction
-
-// ================================================================
-
-endpackage
index 661060f63c7c8c0eee032161648e288d8fae8d6a..407314cd8d0153ced36a53150528dbe23c357cac 100644 (file)
 
 # 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)
+