--- /dev/null
+### Makefile for the cclass project
+
+TOP_MODULE:=mkpinmux
+TOP_FILE:=pinmux.bsv
+TOP_DIR:=./bsv_src/
+WORKING_DIR := $(shell pwd)
+
+BSVINCDIR:= .:%/Prelude:%/Libraries:%/Libraries/BlueNoC:./bsv_src
+default: gen_pinmux gen_verilog
+
+check-blue:
+ @if test -z "$$BLUESPECDIR"; then echo "BLUESPECDIR variable not set"; exit 1; fi;
+
+###### Setting the variables for bluespec compile #$############################
+BSVCOMPILEOPTS:= -check-assert -suppress-warnings G0020 -keep-fires -opt-undetermined-vals -remove-false-rules -remove-empty-rules -remove-starved-rules
+BSVLINKOPTS:=-parallel-sim-link 8 -keep-fires
+VERILOGDIR:=./verilog/
+BSVBUILDDIR:=./bsv_build/
+BSVOUTDIR:=./bin
+################################################################################
+
+########## BSIM COMPILE, LINK AND SIMULATE TARGETS #################################
+.PHONY: check-restore
+check-restore:
+ @if [ "$(define_macros)" != "$(old_define_macros)" ]; then make clean ; fi;
+
+.PHONY: gen_pinmux
+gen_pinmux:
+ @python ./src/pinmux_generator.py
+
+.PHONY: gen_verilog
+gen_verilog: check-restore check-blue
+ @echo Compiling mkTbSoc in Verilog for simulations ...
+ @mkdir -p $(BSVBUILDDIR);
+ @mkdir -p $(VERILOGDIR);
+ bsc -u -verilog -elab -vdir $(VERILOGDIR) -bdir $(BSVBUILDDIR) -info-dir $(BSVBUILDDIR) $(define_macros) -D verilog=True $(BSVCOMPILEOPTS) -verilog-filter ${BLUESPECDIR}/bin/basicinout -p $(BSVINCDIR) -g $(TOP_MODULE) $(TOP_DIR)/$(TOP_FILE) 2>&1 | tee bsv_compile.log
+ @echo Compilation finished
+
+########################################################################################
+
+.PHONY: clean
+clean:
+ rm -rf $(BSVBUILDDIR) *.log $(BSVOUTDIR) ./bbl* verilog obj_dir bsv_src src/*.pyc
+
--- /dev/null
+from params import *
+#== Actual pinmuxing ==# TODO: Need to get this as a templete
+pinmux='''
+ /*=============== THIS IS WHERE ACTUAL MUXING HAPPENS ==========*/
+ cell0_out=wrmux0==0?uart0_rx_io:uart1_rx_io;
+ rule get_input_for_rx;
+ if(wrmux0==0)
+ wruart0_rx<=cell0_in;
+ else
+ wruart1_rx<=cell0_in;
+ endrule
+ cell1_out=wrmux1==0?uart0_tx_io:uart1_tx_io;
+ /*==============================================================*/
+'''
+########################################################################
+
+
--- /dev/null
+from params import *
+
+#######====== Interface declarations =======#########
+mux_interface='''
+ method Action cell{0}_mux(Bit#('''+str(N_MUX)+''') in);'''
+
+io_interface='''
+ (*always_ready*) method Bit#(1) io_outputval_{0};
+ (*always_ready*) method Bit#(1) io_output_en_{0};
+ (*always_ready*) method Bit#(1) io_input_en_{0};
+ (*always_ready*) method Bit#(1) io_pullup_en_{0};
+ (*always_ready*) method Bit#(1) io_pulldown_en_{0};
+ (*always_ready*) method Bit#(1) io_drivestrength_{0};
+ (*always_ready*) method Bit#(1) io_pushpull_en_{0};
+ (*always_ready*) method Bit#(1) io_opendrain_en_{0};
+ (*always_ready,always_enabled,result="io"*) method Action io_inputval_{0}(Bit#(1) in);
+'''
+#== Peripheral Interface definitions ==#
+# these are the interface of the peripherals to the pin mux
+# Outputs from the peripherals will be inputs to the pinmux
+# module. Hence the change in direction for most pins
+
+uartinterface_decl='''
+ (*always_ready,always_enabled*) method Action tx_{0}(Bit#(1) in);
+ (*always_ready,always_enabled*) method Bit#(1) rx_{0};
+'''
+
+spiinterface_decl='''
+ (*always_ready,always_enabled*) method Action sclk_{0} (Bit#(1) in);
+ (*always_ready,always_enabled*) method Action mosi_{0} (Bit#(1) in);
+ (*always_ready,always_enabled*) method Action ss_{0} (Bit#(1) in);
+ (*always_ready,always_enabled*) method Bit#(1) miso_{0};
+'''
+#=======================================#
+
+
--- /dev/null
+from params import *
+#=== templates for interface definitions ======#
+mux_interface_def='''
+ method Action cell{0}_mux (Bit#('''+str(N_MUX)+''') in );
+ wrmux{0}<=in;
+ endmethod
+'''
+io_interface_def='''
+ method io_outputval_{0}=cell{0}_out.outputval;
+ method io_output_en_{0}=cell{0}_out.output_en;
+ method io_input_en_{0}=cell{0}_out.input_en;
+ method io_pullup_en_{0}=cell{0}_out.pullup_en;
+ method io_pulldown_en_{0}=cell{0}_out.pulldown_en;
+ method io_drivestrength_{0}=cell{0}_out.drivestrength;
+ method io_pushpull_en_{0}=cell{0}_out.pushpull_en;
+ method io_opendrain_en_{0}=cell{0}_out.opendrain_en;
+ method Action io_inputval_{0}(Bit#(1) in);
+ cell{0}_in<=in;
+ endmethod
+'''
+uartinterface_def='''
+ method rx_{0}=wruart{0}_rx;
+ method Action tx_{0}(Bit#(1) in);
+ wruart{0}_tx<=in;
+ endmethod
+'''
+spiinterface_def='''
+ method Action sclk_{0} (Bit#(1) in);
+ wrspi{0}_sclk<=in;
+ endmethod
+ method Action mosi_{0} (Bit#(1) in);
+ wrspi{0}_mosi<=in;
+ endmethod
+ method Action ss_{0} (Bit#(1) in);
+ wrspi{0}_ss<=in;
+ endmethod
+ method Bit#(1) miso_{0}=wrspi{0}_miso;
+'''
+#==============================================#
+
+
--- /dev/null
+#== Parameters ==#
+N_MUX=1 # number of selection lines for the mux per io
+N_IO=2
+N_UART=2
+N_SPI=0
+#================#
+
+
--- /dev/null
+#############################======= 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
+# 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 sys
+import time
+
+# project module imports
+from interface_decl import *
+from interface_def import *
+from params import *
+from wire_def import *
+from actual_pinmux import *
+
+if not os.path.exists("bsv_src"):
+ os.makedirs("bsv_src")
+
+bsv_file=open("./bsv_src/pinmux.bsv","w")
+header='''
+/*
+ This BSV file has been generated by the PinMux tool available at: <website>.
+ Authors: Neel Gala, Luke
+ Date of generation: '''+time.strftime("%c")+'''
+*/
+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);
+
+ interface Ifc_pinmux;
+'''
+footer='''
+ endmodule
+endpackage
+'''
+###############################################
+###=== populating the file with the code ===###
+###############################################
+
+# package and interface declaration followed by the generic io_cell definition
+bsv_file.write(header)
+
+bsv_file.write('''
+
+ // 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 i in range(0,N_IO):
+ bsv_file.write(mux_interface.format(i))
+
+bsv_file.write('''
+
+ // 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.format(i))
+################################################################
+
+#== create method definitions for all peripheral interfaces ==#
+for i in range(0,N_UART):
+ bsv_file.write('''
+ // interface declaration between UART-{0} and pinmux'''.format(i))
+ bsv_file.write(uartinterface_decl.format(i));
+
+for i in range(0,N_SPI):
+ bsv_file.write('''
+ // interface declaration between SPI-{0} and pinmux'''.format(i))
+ bsv_file.write(spiinterface_decl.format(i));
+################################################################
+
+####=== finish interface definition and start module definition===####
+bsv_file.write('''
+ endinterface
+ 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 i in range(0,N_IO):
+ bsv_file.write(muxwire.format(i))
+
+
+bsv_file.write('''\n // following wires capture the values to be sent to the IO Cell''')
+for i in range(0,N_IO):
+ bsv_file.write(generic_io.format(i))
+
+for i in range(0,N_UART):
+ bsv_file.write('''\n // following wires capture the parameters to the IO CELL if uart-{0} is
+ // allotted to it'''.format(i))
+ bsv_file.write(uartwires.format(i))
+
+for i in range(0,N_SPI):
+ bsv_file.write('''\n // following wires capture the parameters to the IO CELL if spi-{0} is
+ // allotted to it'''.format(i))
+ bsv_file.write(spiwires.format(i))
+bsv_file.write("\n")
+######################################################################
+#########################== Actual pinmuxing ==#######################
+bsv_file.write(pinmux);
+######################################################################
+################=== interface definitions for each method ===###########
+for i in range(0,N_IO):
+ bsv_file.write(mux_interface_def.format(i))
+for i in range(0,N_IO):
+ bsv_file.write(io_interface_def.format(i))
+for i in range(0,N_UART):
+ bsv_file.write(uartinterface_def.format(i))
+for i in range(0,N_SPI):
+ bsv_file.write(spiinterface_def.format(i))
+bsv_file.write(footer)
+########################################################################
--- /dev/null
+from params import *
+#== Intermediate wire definitions ==#
+muxwire='''
+ Wire#(Bit#('''+str(N_MUX)+''')) wrmux{0} <-mkDWire(0);'''
+generic_io='''
+ GenericIOType cell{0}_out=unpack(0);
+ Wire#(Bit#(1)) cell{0}_in <-mkDWire(0);
+'''
+uartwires='''
+ Wire#(Bit#(1)) wruart{0}_rx <-mkDWire(0);
+ Wire#(Bit#(1)) wruart{0}_tx <-mkDWire(0);
+ GenericIOType uart{0}_rx_io=GenericIOType{{outputval:0, output_en:0, input_en:1,
+ pullup_en:0, pulldown_en:0, pushpull_en:0,
+ drivestrength:0, opendrain_en:0}};
+ GenericIOType uart{0}_tx_io=GenericIOType{{outputval:wruart{0}_tx, output_en:1, input_en:0,
+ pullup_en:0, pulldown_en:0, pushpull_en:0,
+ drivestrength:0, opendrain_en:0}};
+'''
+spiwires='''
+ Wire#(Bit#(1)) wrspi{0}_sclk <-mkDWire(0);
+ Wire#(Bit#(1)) wrspi{0}_mosi <-mkDWire(0);
+ Wire#(Bit#(1)) wrspi{0}_ss <-mkDWire(0);
+ Wire#(Bit#(1)) wrspi{0}_miso <-mkDWire(0);
+ GenericIOType spi{0}_sclk = GenericIOType{{outputval:wrspi{0}_sclk, output_en:1, input_en:0,
+ pullup_en:0, pulldown_en:0, pushpull_en:0,
+ drivestrength:0, opendrain_en:0}};
+ GenericIOType spi{0}_mosi = GenericIOType{{outputval:wrspi{0}_mosi, output_en:1, input_en:0,
+ pullup_en:0, pulldown_en:0, pushpull_en:0,
+ drivestrength:0, opendrain_en:0}};
+ GenericIOType spi{0}_ss = GenericIOType{{outputval:wrspi{0}_ss, output_en:1, input_en:0,
+ pullup_en:0, pulldown_en:0, pushpull_en:0,
+ drivestrength:0, opendrain_en:0}};
+ GenericIOType spi{0}_miso = GenericIOType{{outputval:0, output_en:0, input_en:1,
+ pullup_en:0, pulldown_en:0, pushpull_en:0,
+ drivestrength:0, opendrain_en:0}};
+
+'''
+#===================================#
+