From 6635605528ad7600fa190f8e485310da28ed5d69 Mon Sep 17 00:00:00 2001 From: Neel Date: Sat, 10 Mar 2018 22:47:45 +0530 Subject: [PATCH] initial commit with minimal templates --- .gitignore | 1 + Makefile | 44 +++++++++++++ src/actual_pinmux.py | 17 +++++ src/interface_decl.py | 36 +++++++++++ src/interface_def.py | 41 ++++++++++++ src/params.py | 8 +++ src/pinmux_generator.py | 139 ++++++++++++++++++++++++++++++++++++++++ src/wire_def.py | 39 +++++++++++ 8 files changed, 325 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 src/actual_pinmux.py create mode 100644 src/interface_decl.py create mode 100644 src/interface_def.py create mode 100644 src/params.py create mode 100644 src/pinmux_generator.py create mode 100644 src/wire_def.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0d20b64 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..cd4ddf8 --- /dev/null +++ b/Makefile @@ -0,0 +1,44 @@ +### 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 + diff --git a/src/actual_pinmux.py b/src/actual_pinmux.py new file mode 100644 index 0000000..944a816 --- /dev/null +++ b/src/actual_pinmux.py @@ -0,0 +1,17 @@ +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; + /*==============================================================*/ +''' +######################################################################## + + diff --git a/src/interface_decl.py b/src/interface_decl.py new file mode 100644 index 0000000..83d6cba --- /dev/null +++ b/src/interface_decl.py @@ -0,0 +1,36 @@ +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}; +''' +#=======================================# + + diff --git a/src/interface_def.py b/src/interface_def.py new file mode 100644 index 0000000..e491c12 --- /dev/null +++ b/src/interface_def.py @@ -0,0 +1,41 @@ +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; +''' +#==============================================# + + diff --git a/src/params.py b/src/params.py new file mode 100644 index 0000000..b94a501 --- /dev/null +++ b/src/params.py @@ -0,0 +1,8 @@ +#== Parameters ==# +N_MUX=1 # number of selection lines for the mux per io +N_IO=2 +N_UART=2 +N_SPI=0 +#================# + + diff --git a/src/pinmux_generator.py b/src/pinmux_generator.py new file mode 100644 index 0000000..fed54ea --- /dev/null +++ b/src/pinmux_generator.py @@ -0,0 +1,139 @@ +#############################======= 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: . + 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) +######################################################################## diff --git a/src/wire_def.py b/src/wire_def.py new file mode 100644 index 0000000..1568fe4 --- /dev/null +++ b/src/wire_def.py @@ -0,0 +1,39 @@ +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}}; + +''' +#===================================# + -- 2.30.2