progress on design and dv skeleton

Signed-off-by: Matthew Ballance <matt.ballance@gmail.com>
diff --git a/.cproject b/.cproject
new file mode 100644
index 0000000..46d0d47
--- /dev/null
+++ b/.cproject
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+	<storageModule moduleId="org.eclipse.cdt.core.settings">
+		<cconfiguration id="cdt.managedbuild.toolchain.gnu.base.1694383177">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.1694383177" moduleId="org.eclipse.cdt.core.settings" name="Default">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="${ProjName}" buildProperties="" id="cdt.managedbuild.toolchain.gnu.base.1694383177" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
+					<folderInfo id="cdt.managedbuild.toolchain.gnu.base.1694383177.1122857214" name="/" resourcePath="">
+						<toolChain id="cdt.managedbuild.toolchain.gnu.base.131809142" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
+							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.GNU_ELF" id="cdt.managedbuild.target.gnu.platform.base.1240320977" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
+							<builder id="cdt.managedbuild.target.gnu.builder.base.1290324056" managedBuildOn="false" name="Gnu Make Builder.Default" superClass="cdt.managedbuild.target.gnu.builder.base"/>
+							<tool id="cdt.managedbuild.tool.gnu.archiver.base.196772775" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+							<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.924808443" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base"/>
+							<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.1172358105" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base"/>
+							<tool id="cdt.managedbuild.tool.gnu.c.linker.base.1791838648" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
+							<tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.1119201984" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base"/>
+							<tool id="cdt.managedbuild.tool.gnu.assembler.base.1714779076" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base"/>
+						</toolChain>
+					</folderInfo>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="open_mpw_user_project.null.1544849861" name="open_mpw_user_project"/>
+	</storageModule>
+	<storageModule moduleId="scannerConfiguration">
+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+</cproject>
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0a1f620
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+
+packages/
+simv.*
+obj_dir/
+
diff --git a/.project b/.project
new file mode 100644
index 0000000..2268f79
--- /dev/null
+++ b/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>open_mpw_user_project</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.python.pydev.PyDevBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+			<triggers>clean,full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.cdt.core.cnature</nature>
+		<nature>org.eclipse.cdt.core.ccnature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+		<nature>org.python.pydev.pythonNature</nature>
+	</natures>
+</projectDescription>
diff --git a/.pydevproject b/.pydevproject
new file mode 100644
index 0000000..4684ce1
--- /dev/null
+++ b/.pydevproject
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?eclipse-pydev version="1.0"?><pydev_project>
+    <pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
+    <pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python interpreter</pydev_property>
+    <pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
+        <path>/${PROJECT_DIR_NAME}/packages/wishbone-bfms/src</path>
+        <path>/${PROJECT_DIR_NAME}/dv/bringup/python</path>
+    </pydev_pathproperty>
+</pydev_project>
diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml
new file mode 100644
index 0000000..2e84de3
--- /dev/null
+++ b/.settings/language.settings.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project>
+	<configuration id="cdt.managedbuild.toolchain.gnu.base.1694383177" name="Default">
+		<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
+			<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
+			<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
+			<provider copy-of="extension" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser"/>
+			<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="1974865738666929643" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+				<language-scope id="org.eclipse.cdt.core.gcc"/>
+				<language-scope id="org.eclipse.cdt.core.g++"/>
+			</provider>
+			<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
+		</extension>
+	</configuration>
+</project>
\ No newline at end of file
diff --git a/bootstrap.sh b/bootstrap.sh
new file mode 100755
index 0000000..bc82ef0
--- /dev/null
+++ b/bootstrap.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+python=`which python3`
+
+if test "x$python" = "x"; then
+    echo "Note: falling back to python from python3"
+    python="python"
+fi
+
+
+# Check to see if ivpm is already installed
+$python -m ivpm --help >/dev/null 2>&1
+
+# Not installed, so clone a local copy
+if test $? -ne 0; then
+    echo "Note: ivpm is not installed -- fetching ..."
+    git clone https://github.com/mballance/ivpm .ivpm
+    export PYTHONPATH=`pwd`/.ivpm/src
+else
+    echo "Note: ivpm is already installed"
+fi
+
+# Fetch dependencies and setup virtual environment
+$python -m ivpm update
+
diff --git a/doc/BringupUsecases.md b/doc/BringupUsecases.md
new file mode 100644
index 0000000..4972dfc
--- /dev/null
+++ b/doc/BringupUsecases.md
@@ -0,0 +1,13 @@
+
+- 
+  - Hold fwrisc in reset state. 
+  - Access memory device from management interface
+  - Confirm
+  
+- 
+  - Hold fwrisc in reset state
+  - Load simple program into memory from management interface
+  - Clock fwrisc via LA interface
+  
+- 
+  - 
\ No newline at end of file
diff --git a/dv/bringup/Makefile b/dv/bringup/Makefile
new file mode 100644
index 0000000..990c880
--- /dev/null
+++ b/dv/bringup/Makefile
@@ -0,0 +1,41 @@
+BRINGUP_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
+RTL_DIR:=$(abspath $(BRINGUP_DIR)/../../rtl)
+PACKAGES_DIR:=$(abspath $(BRINGUP_DIR)/../../packages)
+FWRISC_RTL_DIR:=$(PACKAGES_DIR)/fwrisc/rtl
+
+#********************************************************************
+#* Source setup
+#********************************************************************
+FWRISC_SRCS = $(wildcard $(FWRISC_RTL_DIR)/*.sv)
+INCDIRS += $(FWRISC_RTL_DIR)
+
+DEFINES += MPRJ_IO_PADS=38
+SRCS += $(RTL_DIR)/fwpayload.v $(RTL_DIR)/user_project_wrapper.v
+SRCS += $(FWRISC_SRCS) 
+
+#********************************************************************
+#* cocotb testbench setup
+#********************************************************************
+MODULE=bringup_tb
+export MODULE
+PYTHONPATH := $(BRINGUP_DIR)/python:$(PYTHONPATH)
+export PYTHONPATH
+PATH := $(PACKAGES_DIR)/python/bin:$(PATH)
+export PATH
+COCOTB_PREFIX := $(shell $(PACKAGES_DIR)/python/bin/cocotb-config --prefix)
+VPI_LIBS += $(COCOTB_PREFIX)/cocotb/libs/libcocotbvpi_verilator.so
+
+
+VLSIM_CLKSPEC += -clkspec clk=10ns
+VLSIM_OPTIONS += -Wno-fatal --top-module bringup_tb
+SRCS += $(BRINGUP_DIR)/bringup_tb.sv
+
+SIM?=vlsim
+
+all : build run
+
+clean ::
+	echo "TODO"
+
+include $(BRINGUP_DIR)/../common/$(SIM).mk
+
diff --git a/dv/bringup/bringup_tb.sv b/dv/bringup/bringup_tb.sv
new file mode 100644
index 0000000..8fd59a2
--- /dev/null
+++ b/dv/bringup/bringup_tb.sv
@@ -0,0 +1,103 @@
+/****************************************************************************
+ * bringup_tb.sv
+ ****************************************************************************/
+
+`ifndef MPRJ_IO_PADS
+	`define MPRJ_IO_PADS 38
+`endif
+/**
+ * Module: bringup_tb
+ * 
+ * TODO: Add module documentation
+ */
+module bringup_tb(input clk);
+	
+`ifdef HAVE_HDL_CLOCKGEN
+	reg clk_r = 0;
+	assign clk_r = #5ns ~clk_r;
+`endif
+
+	wire clock = clk;
+	reg[15:0]			reset_cnt;
+	reg[15:0]			reset_key;
+	
+	always @(posedge clock) begin
+		if (reset_key != 16'ha520) begin
+			reset_key <= 16'ha520;
+			reset_cnt <= 16'h0000;
+		end else if (reset_cnt != 1000) begin
+			reset_cnt <= reset_cnt + 1;
+		end
+	end
+	
+	wire reset = (reset_key != 16'ha520 || reset_cnt != 1000);
+	
+	wire vdda1, vdda2, vssa1, vssa2, vccd1, vccd2, vssd1, vssd2;
+	wire wb_clk_i = clock;
+	wire wb_rst_i = reset;
+	wire wbs_stb_i;
+	wire wbs_cyc_i;
+	wire wbs_we_i;
+	wire [3:0] wbs_sel_i;
+	wire [31:0] wbs_dat_i;
+	wire [31:0] wbs_adr_i;
+	wire wbs_ack_o;
+	wire [31:0] wbs_dat_o;
+	
+	wire [127:0] la_data_in;
+	wire [127:0] la_data_out;
+	wire [127:0] la_oen = 128'hFFFF_FFFF_FFFF_FFFF__FFFF_FFFF_FFFF_FFFF;
+	
+	wire [`MPRJ_IO_PADS-1:0] io_in;
+	wire [`MPRJ_IO_PADS-1:0] io_out;
+	wire [`MPRJ_IO_PADS-1:0] io_oeb;
+
+	wire [`MPRJ_IO_PADS-8:0] analog_io;
+	
+	wire   user_clock2 = clock;
+
+	user_project_wrapper u_dut(
+			.vdda1(vdda1),	// User area 1 3.3V supply
+			.vdda2(vdda2),	// User area 2 3.3V supply
+			.vssa1(vssa1),	// User area 1 analog ground
+			.vssa2(vssa2),	// User area 2 analog ground
+			.vccd1(vccd1),	// User area 1 1.8V supply
+			.vccd2(vccd2),	// User area 2 1.8v supply
+			.vssd1(vssd1),	// User area 1 digital ground
+			.vssd2(vssd2),	// User area 2 digital ground
+
+			// Wishbone Slave ports (WB MI A)
+			.wb_clk_i(wb_clk_i),
+			.wb_rst_i(wb_rst_i),
+			.wbs_stb_i(wbs_stb_i),
+			.wbs_cyc_i(wbs_cyc_i),
+			.wbs_we_i(wbs_we_i),
+			.wbs_sel_i(wbs_sel_i),
+			.wbs_dat_i(wbs_dat_i),
+			.wbs_adr_i(wbs_adr_i),
+			.wbs_ack_o(wbs_ack_o),
+			.wbs_dat_o(wbs_dat_o),
+
+			// Logic Analyzer Signals
+			.la_data_in(la_data_in),
+			.la_data_out(la_data_out),
+			.la_oen(la_oen),
+
+			// IOs
+			.io_in(io_in),
+			.io_out(io_out),
+			.io_oeb(io_oeb),
+
+			// Analog (direct connection to GPIO pad---use with caution)
+			// Note that analog I/O is not available on the 7 lowest-numbered
+			// GPIO pads, and so the analog_io indexing is offset from the
+			// GPIO indexing by 7.
+			.analog_io(analog_io),
+
+			// Independent clock (on independent integer divider)
+			.user_clock2(user_clock2)
+			);
+
+endmodule
+
+
diff --git a/dv/bringup/python/__pycache__/bringup_tb.cpython-36.pyc b/dv/bringup/python/__pycache__/bringup_tb.cpython-36.pyc
new file mode 100644
index 0000000..f96b60b
--- /dev/null
+++ b/dv/bringup/python/__pycache__/bringup_tb.cpython-36.pyc
Binary files differ
diff --git a/dv/bringup/python/bringup_tb.py b/dv/bringup/python/bringup_tb.py
new file mode 100644
index 0000000..68e8135
--- /dev/null
+++ b/dv/bringup/python/bringup_tb.py
@@ -0,0 +1,12 @@
+'''
+Created on Nov 21, 2020
+
+@author: mballance
+'''
+import cocotb
+
+
+@cocotb.test()
+async def test(root):
+    print("Hello")
+
diff --git a/dv/common/vlsim.mk b/dv/common/vlsim.mk
new file mode 100644
index 0000000..1a34b7e
--- /dev/null
+++ b/dv/common/vlsim.mk
@@ -0,0 +1,45 @@
+#****************************************************************************
+#* vlsim.mk
+#*
+#* Simulator support for Verilator via the vlsim script
+#*
+#* SRCS           - List of source files
+#* INCDIRS        - Include paths
+#* DEFINES        - Defines
+#* SIM_ARGS       - generic simulation arguments
+#* VLSIM_SIM_ARGS - vlsim-specific simulation arguments
+#* VLSIM_CLKSPEC  - clock-generation options for VLSIM
+#* VPI_LIBS       - List of PLI libraries
+#* DPI_LIBS       - List of DPI libraries
+#* TIMEOUT        - Simulation timeout, in units of ns,us,ms,s
+#****************************************************************************
+
+COMMON_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
+PACKAGES_DIR := $(abspath $(COMMON_DIR)/../../packages)
+VLSIM := $(PACKAGES_DIR)/python/bin/vlsim
+
+ifneq (,$(DEBUG))
+VLSIM_OPTIONS += --trace-fst
+SIMV_ARGS += +vlsim.trace
+SIMV := simv.debug
+else
+SIMV := simv.ndebug
+endif
+
+VLSIM_OPTIONS += --vpi --public-flat-rw
+
+VLSIM_OPTIONS += $(foreach inc,$(INCDIRS),+incdir+$(inc))
+VLSIM_OPTIONS += $(foreach def,$(DEFINES),+define+$(def))
+SIMV_ARGS += $(foreach vpi,$(VPI_LIBS),+vpi=$(vpi))
+
+build : $(SIMV)
+
+$(SIMV) : $(SRCS)
+	$(VLSIM) -o $@ $(VLSIM_CLKSPEC) $(VLSIM_OPTIONS) $(SRCS)
+
+run : $(SIMV)
+	./$(SIMV) $(SIMV_ARGS)
+
+clean ::
+	rm -f simv.* simx.fst simx.vcd
+	rm -rf obj_dir
diff --git a/etc/ivpm.info b/etc/ivpm.info
new file mode 100644
index 0000000..56d699b
--- /dev/null
+++ b/etc/ivpm.info
@@ -0,0 +1,4 @@
+
+name=open_mpw_user_project
+version=0.0.1
+
diff --git a/etc/packages.mf b/etc/packages.mf
new file mode 100644
index 0000000..254989b
--- /dev/null
+++ b/etc/packages.mf
@@ -0,0 +1,3 @@
+
+fwrisc@https://github.com/mballance/fwrisc.git
+
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..d071710
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,7 @@
+
+cocotb
+vlsim
+
+-e git+https://github.com/pybfms/pybfms.git#egg=pybfms
+-e git+https://github.com/pybfms/wishbone_bfms.git#egg=wishbone_bfms
+
diff --git a/rtl/fwpayload.v b/rtl/fwpayload.v
new file mode 100644
index 0000000..7113a24
--- /dev/null
+++ b/rtl/fwpayload.v
@@ -0,0 +1,259 @@
+
+/****************************************************************************
+ * fwpayload.v
+ ****************************************************************************/
+
+  
+/**
+ * Module: fwpayload
+ * 
+ * Payload to go in Caravel
+ *
+ * - For simplicity, the IO's by and large mirror those of the user_project_wrapper
+ */
+module fwpayload(
+		inout vdda1,	// User area 1 3.3V supply
+		inout vdda2,	// User area 2 3.3V supply
+		inout vssa1,	// User area 1 analog ground
+		inout vssa2,	// User area 2 analog ground
+		inout vccd1,	// User area 1 1.8V supply
+		inout vccd2,	// User area 2 1.8v supply
+		inout vssd1,	// User area 1 digital ground
+		inout vssd2,	// User area 2 digital ground
+
+		// Wishbone Slave ports (WB MI A)
+		input 			wb_clk_i,
+		input 			wb_rst_i,
+		input 			wbs_stb_i,
+		input 			wbs_cyc_i,
+		input 			wbs_we_i,
+		input [3:0] 	wbs_sel_i,
+		input [31:0] 	wbs_dat_i,
+		input [31:0] 	wbs_adr_i,
+		output 			wbs_ack_o,
+		output [31:0] 					wbs_dat_o,
+
+		// Logic Analyzer Signals
+		input  [127:0] 					la_data_in,
+		output [127:0] 					la_data_out,
+		input  [127:0] 					la_oen,
+
+		// IOs
+		input  [`MPRJ_IO_PADS-1:0] 		io_in,
+		output [`MPRJ_IO_PADS-1:0] 		io_out,
+		output [`MPRJ_IO_PADS-1:0] 		io_oeb
+		);
+	
+	wire clk, rst;
+	
+	// Clock/reset control
+	// Allow the logic analyzer to take control of clock/reset
+	// Default to using the caravel clock/reset
+	assign clk = (~la_oen[127]) ? la_data_in[127]: wb_clk_i;
+	assign rst = (~la_oen[126]) ? la_data_in[126]: wb_rst_i;
+	
+	wire[31:0]			iaddr;
+	reg[31:0]			idata;
+	wire				ivalid;
+	wire				iready;
+	wire[31:0]			daddr;
+	wire[31:0]			dwdata;
+	wire[31:0]			dwstb;
+	wire				dwrite;
+	reg[31:0]			drdata;
+	wire				dvalid;
+	wire				dready;
+	
+
+	fwrisc_rv32imc u_core (
+				.clock(clk),
+				.reset(rst),
+		
+				.iaddr(iaddr),
+				.idata(idata),
+				.ivalid(ivalid),
+				.iready(iready),
+		
+				.dvalid(dvalid),
+				.daddr(daddr),
+				.dwdata(dwdata),
+				.dwstb(dwstb),
+				.dwrite(dwrite),
+				.drdata(drdata),
+				.dready(dready)
+			);
+	
+	// Probes
+	// - PC 
+	//   - [31:0] input
+	// - Regs
+	//   - [63:32] input  - registers (via mux)
+	//   - [68:64] output - select
+	//   - 127 output     - clock
+	//   - 126 output     - reset
+	localparam REG_PROBE_SEL_OFF = 64;
+	localparam REG_PROBE_OFF     = 32;
+	localparam PC_PROBE_OFF      = 0;
+	wire[4:0]             reg_probe_sel = (
+			la_oen[REG_PROBE_SEL_OFF+4:REG_PROBE_SEL_OFF] == 5'b0000)?
+			la_data_in[REG_PROBE_SEL_OFF+4:REG_PROBE_SEL_OFF]:5'b0000;
+	wire[31:0]            reg_probe;
+	wire[31:0]            pc_probe;
+	
+	assign la_data_out[REG_PROBE_OFF+31:REG_PROBE_OFF] = reg_probe;
+	assign la_data_out[PC_PROBE_OFF+31:PC_PROBE_OFF] = pc_probe;
+	
+
+	// 640 pixels
+	// 16x16?
+	// - Each block is 40p wide
+	// -
+	// - 40ns per pix, 1600ns per block
+	// TODO: dedicated reset for core, to allow us to isolate it from the system
+	// Video shift register
+	// - Need two levels
+	// - Output
+	// - Ready
+	// - Need clock divider to control shift rate
+	// - Need IRQ to signal empty
+
+	// Small memory (1KB ok?)
+	// - Must be dual-port with access from slave port
+	// ROM: 'h8000_0000
+	// RAM: 'h8000_8000
+	// LED: 'hC000_0000
+	reg[7:0]			ram_0[1023:0]; // 16k ram
+	reg[7:0]			ram_1[1023:0]; // 16k ram
+	reg[7:0]			ram_2[1023:0]; // 16k ram
+	reg[7:0]			ram_3[1023:0]; // 16k ram
+	reg[31:0]			rom[4095:0];   // 16k rom
+	reg[31:0]			led;
+	reg[31:0]			tx_r;
+	reg					iready_r, dready_r;
+	
+	assign iready = iready_r;
+	assign dready = dready_r;
+
+//	initial begin
+//		$readmemh("rom.hex", rom);
+//	end
+	
+	reg[31:0]			addr_d;
+	reg[31:0]			addr_i;
+	
+	always @(posedge clk) begin
+		addr_d <= daddr;
+		addr_i <= iaddr;
+
+		if (dvalid && dready && dwrite) begin
+			if (daddr[31:28] == 4'h8 && 
+					daddr[15:12] == 4'h8) begin
+				//				$display("Write to RAM: 'h%08h", daddr[13:2]);
+				if (dwstb[0]) ram_0[daddr[13:2]] <= dwdata[7:0];
+				if (dwstb[1]) ram_1[daddr[13:2]] <= dwdata[15:8];
+				if (dwstb[2]) ram_2[daddr[13:2]] <= dwdata[23:16];
+				if (dwstb[3]) ram_3[daddr[13:2]] <= dwdata[31:24];
+			end else if (daddr[31:28] == 4'hc) begin
+				if (daddr[3:2] == 4'h0) begin
+					led <= dwdata;
+				end else if (daddr[3:2] == 4'h1) begin
+					tx_r <= dwdata;
+				end
+			end
+		end
+	end
+	
+	always @(posedge clk) begin
+		// Prefer data access
+		if (dvalid) begin
+			dready_r <= 1;
+			iready_r <= 0;
+		end else if (ivalid) begin
+			iready_r <= 1;
+			dready_r <= 0;
+		end else begin
+			iready_r <= 0;
+			dready_r <= 0;
+		end
+	end
+
+	/****************************************************************
+	 * Simple WB to storage bridge
+	 ****************************************************************/
+	reg[1:0] wb_bridge_state = 0;
+
+	always @(posedge clk) begin
+		if (rst == 1) begin
+			wb_bridge_state <= 0;
+		end else begin
+			case (wb_bridge_state)
+				0:
+					if (wbs_cyc_i && wbs_stb_i) begin
+						wb_bridge_state <= 1;
+					end
+				1:
+					wb_bridge_state <= 2;
+				2:
+					wb_bridge_state <= 0;
+				default:
+					wb_bridge_state <= 0;
+			endcase
+		end
+	end
+
+	wire [31:0] storage_mgmt_addr    = wbs_adr_i; // [ADDRESS_WIDTH+(DATA_WIDTH/32):(DATA_WIDTH/32)+1];
+	wire storage_mgmt_rd_en          = (wbs_cyc_i & wbs_stb_i & !wbs_we_i);
+	wire storage_mgmt_wr_en          = (wbs_cyc_i & wbs_stb_i & wbs_we_i);
+	wire [3:0] storage_mgmt_byte_en  = wbs_sel_i;
+	wire [31:0] storage_mgmt_wr_dat  = wbs_dat_i;
+	wire [31:0] storage_mgmt_rd_dat;
+	
+	assign wbs_dat_o = storage_mgmt_rd_dat;
+	
+	assign wbs_ack_o = (wb_bridge_state == 2);
+
+	// TODO: allow to read 'ram' too
+	assign storage_mgmt_rd_dat = rom[wbs_adr_i[13:2]];
+	
+	always @(posedge clk) begin
+		if (storage_mgmt_wr_en) begin
+			rom[storage_mgmt_addr[13:2]] <= storage_mgmt_wr_dat;
+		end
+	end	
+	
+	always @* begin
+		if (addr_d[31:28] == 4'h8 && addr_d[15:12] == 4'h8) begin 
+			drdata = {
+					ram_3[addr_d[13:2]],
+					ram_2[addr_d[13:2]],
+					ram_1[addr_d[13:2]],
+					ram_0[addr_d[13:2]]
+				};
+		end else begin
+			drdata = rom[addr_d[13:2]];
+		end
+		
+		if (addr_i[31:28] == 4'h8 && addr_i[15:12] == 4'h8) begin
+			idata = {
+					ram_3[addr_d[13:2]],
+					ram_2[addr_d[13:2]],
+					ram_1[addr_d[13:2]],
+					ram_0[addr_d[13:2]]
+				};
+		end else begin
+			idata = rom[addr_i[13:2]];
+		end
+	end	
+	
+	// Some form of general I/O
+	// - GPIO?
+	// - 
+	
+	// Some form of specific I/O
+	// - UART?
+	// - SPI?
+	
+	
+endmodule
+
+
diff --git a/rtl/user_project_wrapper.v b/rtl/user_project_wrapper.v
new file mode 100644
index 0000000..c815dd5
--- /dev/null
+++ b/rtl/user_project_wrapper.v
@@ -0,0 +1,101 @@
+`default_nettype none
+/*
+ *-------------------------------------------------------------
+ *
+ * user_project_wrapper
+ *
+ * This wrapper enumerates all of the pins available to the
+ * user for the user project.
+ *
+ * An example user project is provided in this wrapper.  The
+ * example should be removed and replaced with the actual
+ * user project.
+ *
+ *-------------------------------------------------------------
+ */
+
+module user_project_wrapper #(
+    parameter BITS = 32
+)(
+    inout vdda1,	// User area 1 3.3V supply
+    inout vdda2,	// User area 2 3.3V supply
+    inout vssa1,	// User area 1 analog ground
+    inout vssa2,	// User area 2 analog ground
+    inout vccd1,	// User area 1 1.8V supply
+    inout vccd2,	// User area 2 1.8v supply
+    inout vssd1,	// User area 1 digital ground
+    inout vssd2,	// User area 2 digital ground
+
+    // Wishbone Slave ports (WB MI A)
+    input wb_clk_i,
+    input wb_rst_i,
+    input wbs_stb_i,
+    input wbs_cyc_i,
+    input wbs_we_i,
+    input [3:0] wbs_sel_i,
+    input [31:0] wbs_dat_i,
+    input [31:0] wbs_adr_i,
+    output wbs_ack_o,
+    output [31:0] wbs_dat_o,
+
+    // Logic Analyzer Signals
+    input  [127:0] la_data_in,
+    output [127:0] la_data_out,
+    input  [127:0] la_oen,
+
+    // IOs
+    input  [`MPRJ_IO_PADS-1:0] io_in,
+    output [`MPRJ_IO_PADS-1:0] io_out,
+    output [`MPRJ_IO_PADS-1:0] io_oeb,
+
+    // Analog (direct connection to GPIO pad---use with caution)
+    // Note that analog I/O is not available on the 7 lowest-numbered
+    // GPIO pads, and so the analog_io indexing is offset from the
+    // GPIO indexing by 7.
+    inout [`MPRJ_IO_PADS-8:0] analog_io,
+
+    // Independent clock (on independent integer divider)
+    input   user_clock2
+);
+
+    /*--------------------------------------*/
+    /* User project is instantiated  here   */
+    /*--------------------------------------*/
+	fwpayload payload (
+		.vdda1(vdda1),	// User area 1 3.3V power
+		.vdda2(vdda2),	// User area 2 3.3V power
+		.vssa1(vssa1),	// User area 1 analog ground
+		.vssa2(vssa2),	// User area 2 analog ground
+		.vccd1(vccd1),	// User area 1 1.8V power
+		.vccd2(vccd2),	// User area 2 1.8V power
+		.vssd1(vssd1),	// User area 1 digital ground
+		.vssd2(vssd2),	// User area 2 digital ground
+		
+		// MGMT core clock and reset
+    	.wb_clk_i(wb_clk_i),
+    	.wb_rst_i(wb_rst_i),
+    	
+    	// MGMT SoC Wishbone Slave
+		.wbs_cyc_i(wbs_cyc_i),
+		.wbs_stb_i(wbs_stb_i),
+		.wbs_we_i(wbs_we_i),
+		.wbs_sel_i(wbs_sel_i),
+		.wbs_adr_i(wbs_adr_i),
+		.wbs_dat_i(wbs_dat_i),
+		.wbs_ack_o(wbs_ack_o),
+		.wbs_dat_o(wbs_dat_o),
+		
+		// Logic Analyzer
+		.la_data_in(la_data_in),
+		.la_data_out(la_data_out),
+		.la_oen (la_oen),
+		
+		// IO Pads
+
+		.io_in (io_in),
+    	.io_out(io_out),
+    	.io_oeb(io_oeb)
+		);
+
+endmodule	// user_project_wrapper
+`default_nettype wire