diff --git a/.gitignore b/.gitignore
index 0f1ba16fa86744ee44916b736f669acf2852c7f2..7b2d62e1a43fca2afdf9d9e6930ea86a4b4d2bce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,8 @@ logical/SMC
 logical/nic400_expansion_subsystem
 logical/shared
 
+simulate
+
 verif/cocotb/sim_build
 verif/cocotb/__pycache__
 verif/cocotb/*.vstf
diff --git a/flist/expansion_subsystem.vc b/flist/expansion_subsystem.vc
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b590b146b39c82ccd6c676f6652cb26643bc6dca 100644
--- a/flist/expansion_subsystem.vc
+++ b/flist/expansion_subsystem.vc
@@ -0,0 +1,10 @@
+
+$(SOCLABS_EXP_SUBSYSTEM_TECH_DIR)/logical/expansion_region/verilog/expansion_region.v
+$(SOCLABS_EXP_SUBSYSTEM_TECH_DIR)/logical/SRAM/verilog/SRAM_wrapper.v 
+$(SOCLABS_EXP_SUBSYSTEM_TECH_DIR)/logical/SRAM/verilog/SRAM.v 
+$(SOCLABS_EXP_SUBSYSTEM_TECH_DIR)/logical/top_expansion_subsystem/verilog/expansion_subsystem_wrapper.v 
+
+
+-F $(SOCLABS_EXP_SUBSYSTEM_TECH_DIR)/logical/dma350/logical/ada_top_sldma350/verilog/ada_top_sldma350.vc
+-F $(SOCLABS_EXP_SUBSYSTEM_TECH_DIR)/logical/nic400_expansion_subsystem/logical/nic400_expansion_subsystem/nic400/verilog/nic400_expansion_subsystem.vc
+-F $(SOCLABS_EXP_SUBSYSTEM_TECH_DIR)/logical/SMC/logical/sie300_axi5_sram_ctrl_expansion_subsystem/verilog/sie300_axi5_sram_ctrl_expansion_subsystem.vc 
\ No newline at end of file
diff --git a/flows/makefile.simulate b/flows/makefile.simulate
index 91d57772019f0cd08a20e7ddc176495b8a7353ba..1cbab6b1459707248674a5b5825950b4005553d4 100644
--- a/flows/makefile.simulate
+++ b/flows/makefile.simulate
@@ -1,4 +1,4 @@
-#-----------------------------------------------------------------------------
+#-------------------------------------------------------------------------------------
 # Expansion subsystem Simulation Makefile 
 # A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license.
 #
@@ -7,4 +7,153 @@
 # David Mapstone (d.a.mapstone@soton.ac.uk)
 # Daniel Newbrook (d.newbrook@soton.ac.uk)
 # Copyright (C) 2021-4, SoC Labs (www.soclabs.org)
-#-----------------------------------------------------------------------------
+#-------------------------------------------------------------------------------------
+
+
+# MTI options
+MTI_VC_OPTIONS    = +acc
+MTI_VC_OPTIONS    += -suppress 2892
+MTI_VC_OPTIONS    += -f $(TBENCH_VC) $(ADP_OPTIONS)
+
+MTI_RUN_OPTIONS   = -voptargs=+acc
+
+# VCS options
+VCS_OPTIONS    = +vcs+lic+wait +v2k -sverilog -override_timescale=1ns/1ps +lint=all,noTMR,noVCDE -debug
+VCS_SIM_OPTION = +vcs+lic+wait +vcs+flush+log -assert nopostproc
+VCS_VC_OPTIONS = -f $(TBENCH_VC) $(ADP_OPTIONS)
+
+# XM verilog options
+XMSIM_OPTIONS  = -unbuffered -64bit -status -LICQUEUE -f xmsim.args -cdslib cds.lib -hdlvar hdl.var -NBASYNC
+XM_VC_OPTIONS  = -f $(TBENCH_VC) $(ADP_OPTIONS) 
+
+# ------- Cocotb Variables -----------
+# Convert Simulator Name for Cocotb
+COCOTB_SIMULATOR ?= questa
+
+ifeq ($(SIMULATOR),mti)
+	COCOTB_SIMULATOR := questa
+else ifeq ($(SIMULATOR),xm)
+	COCOTB_SIMULATOR := xcelium
+else ifeq ($(SIMULATOR),vcs)
+	COCOTB_SIMULATOR := vcs
+endif
+
+# Cocotb GUI Variable
+GUI ?= 0
+
+# Cocotb Test Location
+COCOTB_TEST_DIR := $(SOCLABS_EXP_SUBSYSTEM_TECH_DIR)/verif/cocotb
+
+# Cocotb Scratch Directory
+COCOTB_DIR := $(EXP_SIM_TOP_DIR)/cocotb
+COCOTB_SCRATCH_DIR := $(COCOTB_DIR)/scratch
+
+# Filelist for Cocotb 
+MAKEFILE_FILELIST     := $(COCOTB_DIR)/makefile.flist
+
+
+
+# Create a List of PHONY Targets
+.PHONY: compile_$(SIMULATOR) run_$(SIMULATOR) sim_$(SIMULATOR)
+
+# ------- Simulator redirect -----------
+
+compile: compile_$(SIMULATOR)
+
+run: run_$(SIMULATOR)
+
+sim: sim_$(SIMULATOR)
+
+# Preload IMEM in Simulation
+compile_mti: EXPANSION_SUBSYSTEM_DEFINES += IMEM_0_RAM_PRELOAD
+compile_vcs: EXPANSION_SUBSYSTEM_DEFINES += IMEM_0_RAM_PRELOAD
+compile_xm:  EXPANSION_SUBSYSTEM_DEFINES += IMEM_0_RAM_PRELOAD
+
+make_workspace:
+	@if [ ! -d $(EXP_SIM_DIR) ] ; then \
+	  mkdir -p $(EXP_SIM_DIR); \
+	fi
+	@if [ ! -d $(EXP_SIM_DIR)/logs ] ; then \
+	  mkdir -p $(EXP_SIM_DIR)/logs; \
+	fi
+
+
+# ------- VCS -----------
+
+# Compile RTL
+compile_vcs : gen_defs 
+	cd $(EXP_SIM_DIR); vcs $(VCS_OPTIONS) -f tbench.vc  $(DEFINES_VC)  | tee compile_vcs.log
+
+
+# Run simulation in batch mode
+run_vcs : code compile_vcs
+	@echo quit > $(EXP_SIM_DIR)/quit.do
+	cd $(EXP_SIM_DIR); ./simv $(VCS_SIM_OPTION) -define ADP_FILE=adp.cmd < quit.do | tee logs/run_$(TESTNAME).log ;
+
+# Run simulation in interactive mode
+sim_vcs : code compile_vcs
+	cd $(EXP_SIM_DIR); ./simv -gui +vcs+lic+wait +vcs+flush+log &
+
+# ------- XM -----------
+
+# Compile RTL
+compile_xm : bootrom gen_defs 
+	@echo ADP_FILE
+	@echo $(ADP_OPTIONS)
+	cd $(EXP_SIM_DIR); xmprep  +overwrite $(XM_VC_OPTIONS) $(DEFINES_VC) +debug -timescale 1ns/1ps -top $(TB_TOP) | tee compile_xm.log
+	cd $(EXP_SIM_DIR); xmvlog  -work worklib -f xmvlog_ver.args | tee -a compile_xm.log
+	cd $(EXP_SIM_DIR); xmelab  -mess -f xmelab.args -access +r | tee -a compile_xm.log
+	
+# Note : If coverage is required, you can add -coverage all to xmelab
+
+# Run simulation in batch mode
+run_xm : code compile_xm
+	@echo run  >  $(EXP_SIM_DIR)/run.tcl.tmp
+	@echo exit >> $(EXP_SIM_DIR)/run.tcl.tmp
+	@mv  $(EXP_SIM_DIR)/run.tcl.tmp $(EXP_SIM_DIR)/run.tcl
+	cd $(EXP_SIM_DIR); xmsim $(XMSIM_OPTIONS) -input run.tcl  | tee logs/run_$(TESTNAME).log ;
+
+# Run simulation in interactive mode
+sim_xm : code compile_xm
+	cd $(EXP_SIM_DIR); xmsim -gui $(XMSIM_OPTIONS)
+
+# ------- MTI -----------
+
+# Compile RTL
+compile_mti : lib_mti
+	cd $(EXP_SIM_DIR); vlog -incr -lint +v2k -f $(TBENCH_VC) $(ADP_OPTIONS) $(DEFINES_VC) | tee compile_mti.log
+
+# Run simulation in batch mode
+run_mti :  compile_mti
+	@echo "run -all" > $(EXP_SIM_DIR)/run.tcl.tmp
+	@echo "quit -f" >> $(EXP_SIM_DIR)/run.tcl.tmp
+	@mv  $(EXP_SIM_DIR)/run.tcl.tmp $(EXP_SIM_DIR)/run.tcl
+	cd $(EXP_SIM_DIR); vsim $(MTI_RUN_OPTIONS) -c $(TB_TOP) -do run.tcl | tee $(EXP_SIM_DIR)/logs/run_$(TESTNAME).log ;
+
+run_mti_to:
+	timeout 2s $(MAKE) run_mti >> /dev/null 2>&1 
+	
+run_mti_wrap:
+	$(MAKE) run_mti_to
+	
+# Run simulation in interactive mode
+sim_mti : compile_mti
+	cd $(EXP_SIM_DIR); vsim $(MTI_RUN_OPTIONS) -gui $(TB_TOP) &
+
+# Create work directory
+lib_mti :
+	@if [ -d $(EXP_SIM_DIR)/work ] ; then \
+          true ; \
+	else \
+	  vlib  $(EXP_SIM_DIR)/work; \
+	fi
+
+
+run_cocotb: DEFINES_VC += COCOTB_SIM
+run_cocotb:
+	@mkdir -p $(EXP_SIM_DIR)
+	@cd $(EXP_SIM_DIR); $(MAKE) -C $(SOCLABS_EXP_SUBSYSTEM_TECH_DIR)/verif/cocotb clean SIM_BUILD=$(COCOTB_SCRATCH_DIR)
+	@cd $(EXP_SIM_DIR); $(MAKE) -C $(SOCLABS_EXP_SUBSYSTEM_TECH_DIR)/verif/cocotb sim MODULE=$(MODULE) SIM=$(COCOTB_SIMULATOR) TESTCASE=$(TESTNAME) GUI=$(GUI) SIM_BUILD=$(COCOTB_SCRATCH_DIR)
+
+sim_cocotb: GUI=1
+sim_cocotb: run_cocotb
diff --git a/logical/top_expansion_subsystem/verilog/expansion_subsystem_wrapper.v b/logical/top_expansion_subsystem/verilog/expansion_subsystem_wrapper.v
index e2798869d6fa1c4e281475e645857222f030ab95..917eb94753de48c6234b6e286ff2b7619c01494b 100644
--- a/logical/top_expansion_subsystem/verilog/expansion_subsystem_wrapper.v
+++ b/logical/top_expansion_subsystem/verilog/expansion_subsystem_wrapper.v
@@ -71,7 +71,7 @@ module expansion_subsystem_wrapper(
     input wire         AXI_EXP_SS_rready,
 
     // AXI System output port
-    output wire [1:0]     AXI_SYS_awid,
+    output wire [2:0]     AXI_SYS_awid,
     output wire [31:0]    AXI_SYS_awaddr,
     output wire [7:0]     AXI_SYS_awlen,
     output wire [2:0]     AXI_SYS_awsize,
@@ -86,11 +86,11 @@ module expansion_subsystem_wrapper(
     output wire           AXI_SYS_wlast,
     output wire           AXI_SYS_wvalid,
     input wire            AXI_SYS_wready,
-    input wire  [1:0]     AXI_SYS_bid,
+    input wire  [2:0]     AXI_SYS_bid,
     input wire  [1:0]     AXI_SYS_bresp,
     input wire            AXI_SYS_bvalid,
     output wire           AXI_SYS_bready,
-    output wire [1:0]     AXI_SYS_arid,
+    output wire [2:0]     AXI_SYS_arid,
     output wire [31:0]    AXI_SYS_araddr,
     output wire [7:0]     AXI_SYS_arlen,
     output wire [2:0]     AXI_SYS_arsize,
@@ -100,7 +100,7 @@ module expansion_subsystem_wrapper(
     output wire [2:0]     AXI_SYS_arprot,
     output wire           AXI_SYS_arvalid,
     input wire            AXI_SYS_arready,
-    input wire  [1:0]     AXI_SYS_rid,
+    input wire  [2:0]     AXI_SYS_rid,
     input wire  [63:0]    AXI_SYS_rdata,
     input wire  [1:0]     AXI_SYS_rresp,
     input wire            AXI_SYS_rlast,
diff --git a/makefile b/makefile
index 1c76bfcebf512c965e0c8e59e73e8ca45c6be94c..6372a8a240aa2093acdd0ff17ef07436620516e5 100644
--- a/makefile
+++ b/makefile
@@ -12,6 +12,42 @@
 
 include ./flows/makefile.simulate
 include ./make.cfg
+
+
+#-------------------------------------
+# - Commonly Overloaded Variables
+#-------------------------------------
+# Name of test directory - Default Test is Hello World
+TESTNAME   ?= hello
+
+# Simulator type (mti/vcs/xm)
+SIMULATOR   = mti
+
+# Is an accelerator subsystem present in the design?
+ACCELERATOR ?= yes
+
+# Is this for a backend ASIC flow?
+ASIC ?= no
+
+#-------------------------------------
+# - Directory Setups
+#-------------------------------------
+# Directory of Testcodes
+TESTCODES_DIR    := $(SOCLABS_EXP_SUBSYSTEM_TECH_DIR)/testcodes
+
+# Project System Directory
+FPGA_IMP_DIR     := $(SOCLABS_EXP_SUBSYSTEM_TECH_DIR)/imp/fpga
+
+# Directory to put simulation files
+EXP_SIM_TOP_DIR := $(SOCLABS_EXP_SUBSYSTEM_TECH_DIR)/simulate/sim
+EXP_SIM_DIR     := $(EXP_SIM_TOP_DIR)/$(TESTNAME)
+
+
+
+DESIGN_VC            ?= $(SOCLABS_EXP_SUBSYSTEM_TECH_DIR)/flist/expansion_subsystem.vc
+TBENCH_VC            ?= $(SOCLABS_EXP_SUBSYSTEM_TECH_DIR)/verif/testbench/logical/expansion_subsystem_tb.vc
+TB_TOP               ?= expansion_subsystem_tb
+
 build_dma350:
 	@$(DMA350_IP_LOGICAL_DIR)/generate --config ./socrates/DMA350/config/cfg_dma_axi.yaml --output ./logical/dma350/
 build_sie300_sram_ctrl:
diff --git a/verif/cocotb/expansion_subsystem_tests.py b/verif/cocotb/expansion_subsystem_tests.py
index d1e25e521ff017b84d5eef7c8d0e3146ec4afce7..0c2074e4dc352cac316a45622bd6bdd84c856777 100644
--- a/verif/cocotb/expansion_subsystem_tests.py
+++ b/verif/cocotb/expansion_subsystem_tests.py
@@ -29,13 +29,14 @@ from cocotb.clock import Clock
 from cocotb.triggers import RisingEdge, Timer, ClockCycles
 from cocotb.regression import TestFactory
 
-from cocotbext.axi import AxiBus, AxiMaster, AxiBurstType, AxiSlave
+from cocotbext.axi import AxiBus, AxiMaster, AxiRam, AxiBurstType, AxiSlave
 
 
 SRAM_0_BASE_ADDR = 0x60000000
 SRAM_1_BASE_ADDR = 0x60040000
 SRAM_0_BASE_ADDR_HI = 0x68000000
 SRAM_1_BASE_ADDR_HI = 0x68040000
+EXT_SRAM_BASE_ADDR = 0x00000000
 
 class TB:
     def __init__(self,dut):
@@ -47,17 +48,24 @@ class TB:
         cocotb.start_soon(Clock(dut.sys_clk, 1.25, units="ns").start())
         cocotb.start_soon(Clock(dut.exp_clk, 1, units="ns").start())
         self.axi_master = AxiMaster(AxiBus.from_prefix(dut,"AXI_EXP_SS"), dut.sys_clk, dut.resetn, reset_active_level=False)
-        self.axi_slave = AxiSlave(AxiBus.from_prefix(dut,"AXI_SYS"), dut.sys_clk, dut.expresetn, reset_active_level=False)
+        self.axi_ram= AxiRam(AxiBus.from_prefix(dut,"AXI_SYS"), dut.sys_clk, dut.expresetn, reset_active_level=False, size=2**32)
+        self.axi_ram.write_if.log.setLevel(logging.DEBUG)
+        self.axi_ram.read_if.log.setLevel(logging.DEBUG)
     def set_idle_generator(self, generator=None):
         if generator:
             self.axi_master.write_if.aw_channel.set_pause_generator(generator())
             self.axi_master.write_if.w_channel.set_pause_generator(generator())
             self.axi_master.read_if.ar_channel.set_pause_generator(generator())
+            self.axi_ram.write_if.b_channel.set_pause_generator(generator())
+            self.axi_ram.read_if.r_channel.set_pause_generator(generator())
 
     def set_backpressure_generator(self, generator=None):
         if generator:
             self.axi_master.write_if.b_channel.set_pause_generator(generator())
             self.axi_master.read_if.r_channel.set_pause_generator(generator())
+            self.axi_ram.write_if.aw_channel.set_pause_generator(generator())
+            self.axi_ram.write_if.w_channel.set_pause_generator(generator())
+            self.axi_ram.read_if.ar_channel.set_pause_generator(generator())
 
     async def cycle_reset(self):
         self.dut.resetn.setimmediatevalue(1)
@@ -111,6 +119,27 @@ async def init_sram_random(dut, tb, base_addr):
 
     await RisingEdge(dut.sys_clk)
 
+async def init_ext_sram_random(dut, tb, base_addr):
+    data = random.bytes(2048)
+    tb.axi_ram.write(base_addr, data)
+    tb.axi_ram.write(base_addr+2048, data)
+    tb.axi_ram.write(base_addr+4096, data)
+    tb.axi_ram.write(base_addr+6144, data)
+    tb.axi_ram.write(base_addr+8192, data)
+    tb.axi_ram.write(base_addr+10240, data)
+    tb.axi_ram.write(base_addr+12288, data)
+    tb.axi_ram.write(base_addr+14336, data)
+
+    await RisingEdge(dut.sys_clk)
+
+
+async def init_sram_incr(dut, tb, base_addr):
+    data = bytearray(range(256))
+    for i in range(64):
+        await tb.axi_master.write(base_addr+i*256, data)
+
+    await RisingEdge(dut.sys_clk)
+
 async def SRAM_test_write(dut, tb, base_addr, byte_lanes, size):
     for length in list(range(1, byte_lanes*2))+[8192]:
         for offset in list(range(byte_lanes))+list(range(8192-byte_lanes, 8192)):
@@ -284,3 +313,71 @@ async def DMA350_basic_transfer(dut, idle_inserter=None, backpressure_inserter=N
     bandwidth = 128*transactions/(tend-tstart)
     tb.log.info("Bandwidth of DMA transfer = " + str(bandwidth) + " Gbps")
 
+
+@cocotb.test()
+async def DMA350_to_external_SRAM(dut, idle_inserter=None, backpressure_inserter=None, size=None):
+    transactions = 0x1FF
+    tb = TB(dut)
+    await tb.cycle_reset()
+    await RisingEdge(dut.sys_clk)
+    await RisingEdge(dut.sys_clk)
+    await init_sram_random(dut, tb, SRAM_0_BASE_ADDR)
+    await dma350.AdaSetSourceAddress(dut, tb, 0, SRAM_0_BASE_ADDR)
+    await dma350.AdaSetDestAddress(dut, tb, 0, EXT_SRAM_BASE_ADDR)
+    await dma350.AdaSetTranSize(dut, tb, 0, transactions, transactions)
+    await dma350.AdaSetChControl(dut, tb, 0, dma350_regtype.TRANSIZE_type.bits128, 15, dma350_regtype.XYTYPE_type.cont, dma350_regtype.XYTYPE_type.dis, 0, 0, 0, 0, 0, 0, 0, 0)
+    await dma350.AdaSetIntrEn(dut, tb, 0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0)
+    await dma350.AdaSetChDESTRANSCFG(dut, tb, 0, 0x4, 0x4, 0x0, 0x1, 0x0, 0xF)
+    await dma350.AdaSetChSRCTRANSCFG(dut, tb, 0, 0x4, 0x4, 0x0, 0x1, 0x0, 0xF)
+    await dma350.AdaSetChXADDRINC(dut, tb, 0, 0x1, 0x1)
+    await dma350.AdaGetIntrEn(dut, tb, 0)
+    tstart=cocotb.utils.get_sim_time('ns')
+    await dma350.AdaEnable(dut, tb, 0)
+    tb.log.info("DMA Transfer started")
+    ch_enabled = 1
+    while ch_enabled == 1:
+        ch_enabled = dut.u_DMA350.ch_enabled.value
+        await ClockCycles(dut.sys_clk, 1)
+    tb.log.info("DMA Transfer finished")
+    tend = cocotb.utils.get_sim_time('ns')
+    ch_stat = await dma350.AdaGetStatus(dut, tb, 0)
+    n_cycles = (tend-tstart)/(transactions)
+    tb.log.info("Tstart: " + str(tstart) + " Tend: " + str(tend))
+    tb.log.info("Average no of clocks per transaction = " + str(n_cycles))
+    bandwidth = 128*transactions/(tend-tstart)
+    tb.log.info("Bandwidth of DMA transfer = " + str(bandwidth) + " Gbps")
+
+@cocotb.test()
+async def DMA350_from_external_SRAM(dut, idle_inserter=None, backpressure_inserter=None, size=None):
+    transactions = 0x1FF
+    tb = TB(dut)
+    await tb.cycle_reset()
+    await RisingEdge(dut.sys_clk)
+    await RisingEdge(dut.sys_clk)
+    await init_ext_sram_random(dut, tb, EXT_SRAM_BASE_ADDR)
+    await dma350.AdaSetSourceAddress(dut, tb, 0, EXT_SRAM_BASE_ADDR)
+    await dma350.AdaSetDestAddress(dut, tb, 0, SRAM_0_BASE_ADDR)
+    await dma350.AdaSetTranSize(dut, tb, 0, transactions, transactions)
+    await dma350.AdaSetChControl(dut, tb, 0, dma350_regtype.TRANSIZE_type.bits128, 15, dma350_regtype.XYTYPE_type.cont, dma350_regtype.XYTYPE_type.dis, 0, 0, 0, 0, 0, 0, 0, 0)
+    await dma350.AdaSetIntrEn(dut, tb, 0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0)
+    await dma350.AdaSetChDESTRANSCFG(dut, tb, 0, 0x4, 0x4, 0x0, 0x1, 0x0, 0xF)
+    await dma350.AdaSetChSRCTRANSCFG(dut, tb, 0, 0x4, 0x4, 0x0, 0x1, 0x0, 0xF)
+    await dma350.AdaSetChXADDRINC(dut, tb, 0, 0x1, 0x1)
+    await dma350.AdaGetIntrEn(dut, tb, 0)
+    tstart=cocotb.utils.get_sim_time('ns')
+    await dma350.AdaEnable(dut, tb, 0)
+    tb.log.info("DMA Transfer started")
+    ch_enabled = 1
+    while ch_enabled == 1:
+        ch_enabled = dut.u_DMA350.ch_enabled.value
+        await ClockCycles(dut.sys_clk, 1)
+    tb.log.info("DMA Transfer finished")
+    tend = cocotb.utils.get_sim_time('ns')
+    ch_stat = await dma350.AdaGetStatus(dut, tb, 0)
+    n_cycles = (tend-tstart)/(transactions)
+    tb.log.info("Tstart: " + str(tstart) + " Tend: " + str(tend))
+    tb.log.info("Average no of clocks per transaction = " + str(n_cycles))
+    bandwidth = 128*transactions/(tend-tstart)
+    tb.log.info("Bandwidth of DMA transfer = " + str(bandwidth) + " Gbps")
+
+
diff --git a/verif/testbench/logical/clk_ctrl.v b/verif/testbench/logical/clk_ctrl.v
new file mode 100644
index 0000000000000000000000000000000000000000..61917ad21a9244968f8efd36f79644032fc95f79
--- /dev/null
+++ b/verif/testbench/logical/clk_ctrl.v
@@ -0,0 +1,112 @@
+
+module clk_ctrl (
+    input  wire     SYSCLK,
+    input  wire     NRST,
+    input  wire     EXPCLK,
+    input  wire     EXP_NRST,
+
+    output wire     CSYSREQ_CD_sys,
+    input  wire     CSYSACK_CD_sys,
+    input  wire     CACTIVE_CD_sys,
+    
+    output wire     CSYSREQ_CD_exp,
+    input  wire     CSYSACK_CD_exp,
+    input  wire     CACTIVE_CD_exp
+);
+
+parameter  IDLE=2'b00, REQ=2'b01, ACK=2'b10, ACT=2'b11;
+reg [1:0] state_sys;
+reg [1:0] state_sys_next;
+
+reg [1:0] state_exp;
+reg [1:0] state_exp_next;
+
+reg CSYSREQ_CD_sys_reg;
+reg SYS_ACT;
+reg CSYSREQ_CD_exp_reg;
+reg EXP_ACT;
+
+
+always @(posedge SYSCLK or negedge NRST) begin
+    if (!NRST) begin
+        state_sys <= IDLE;
+        CSYSREQ_CD_sys_reg <= 0;
+        SYS_ACT<=0;
+    end
+    else 
+        state_sys <= state_sys_next;
+end
+
+always @(*) begin
+    state_sys_next = state_sys;
+    case(state_sys)
+        IDLE : begin
+            if(!SYS_ACT)
+                state_sys_next = REQ;
+        end
+        REQ: begin
+            CSYSREQ_CD_sys_reg = 1;
+            state_sys_next = ACK;
+        end
+        ACK: begin
+            if(CSYSACK_CD_sys) begin
+                $display("CLK CTRL: System clock enable acknowledged");
+                state_sys_next = ACT;
+            end
+        end
+        ACT: begin
+            if(CACTIVE_CD_sys) begin
+                $display("CLK CTRL: System clock active");
+                SYS_ACT = 1;
+                state_sys_next = IDLE;
+            end
+        end
+    endcase
+end
+
+assign CSYSREQ_CD_sys = CSYSREQ_CD_sys_reg;
+
+
+always @(posedge EXPCLK or negedge EXP_NRST) begin
+    if (!EXP_NRST) begin
+        state_exp <= IDLE;
+        CSYSREQ_CD_exp_reg <= 0;
+        EXP_ACT<=0;
+    end
+    else 
+        state_exp <= state_exp_next;
+end
+
+always @(*) begin
+    state_exp_next = state_exp;
+    case(state_exp)
+        IDLE : begin
+            if(!EXP_ACT)
+                state_exp_next = REQ;
+        end
+        REQ: begin
+            CSYSREQ_CD_exp_reg = 1;
+            state_exp_next = ACK;
+        end
+        ACK: begin
+            if(CSYSACK_CD_exp) begin
+                $display("CLK CTRL: Expansion clock enable acknowledged");
+                state_exp_next = ACT;
+            end
+        end
+        ACT: begin
+            if(CACTIVE_CD_exp) begin
+                $display("CLK CTRL: Expansion clock active");
+                SYS_ACT = 1;
+                state_exp_next = IDLE;
+            end
+        end
+    endcase
+end
+
+
+assign CSYSREQ_CD_exp = CSYSREQ_CD_exp_reg;
+
+
+
+endmodule
\ No newline at end of file
diff --git a/verif/testbench/logical/clk_reset.v b/verif/testbench/logical/clk_reset.v
new file mode 100644
index 0000000000000000000000000000000000000000..1a7b905eccb2caee15672a9ac01ac269a8b102a4
--- /dev/null
+++ b/verif/testbench/logical/clk_reset.v
@@ -0,0 +1,86 @@
+//-----------------------------------------------------------------------------
+// Expansion subsystem clock and power on generator adapted from Arm CMSDK Simple clock and power on reset generator
+// A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license.
+//
+// Contributors
+//
+// David Flynn (d.w.flynn@soton.ac.uk)
+//
+// Copyright � 2021-3, SoC Labs (www.soclabs.org)
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// The confidential and proprietary information contained in this file may
+// only be used by a person authorised under and to the extent permitted
+// by a subsisting licensing agreement from Arm Limited or its affiliates.
+//
+//            (C) COPYRIGHT 2010-2013 Arm Limited or its affiliates.
+//                ALL RIGHTS RESERVED
+//
+// This entire notice must be reproduced on all copies of this file
+// and copies of this file may only be made by a person if such person is
+// permitted to do so under the terms of a subsisting license agreement
+// from Arm Limited or its affiliates.
+//
+//      SVN Information
+//
+//      Checked In          : $Date: 2017-10-10 15:55:38 +0100 (Tue, 10 Oct 2017) $
+//
+//      Revision            : $Revision: 371321 $
+//
+//      Release Information : Cortex-M System Design Kit-r1p1-00rel0
+//
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// Abstract : Simple clock and power on reset generator
+//-----------------------------------------------------------------------------
+`timescale 1ns/1ps
+
+module clkreset(
+  output wire SYSCLK,
+  output wire EXPCLK,
+  output wire NRST,
+  output wire EXP_NRST
+  );
+
+  reg clock_q;
+  reg clock_q_exp;
+
+  reg [7:0] shifter;
+  reg [15:0] exp_shifter;
+  
+  initial
+    begin
+      clock_q   <= 1'b0;
+      clock_q_exp <= 1'b1;
+      shifter   <= 8'h00;
+      exp_shifter <= 16'h0000;
+      #10 clock_q <= 1'b1;
+      #10 clock_q_exp <= 1'b1;
+    end
+
+  always @(clock_q) begin
+      #1 clock_q <= !clock_q;  // 2ns period, 500 MHz
+  end
+  assign SYSCLK = clock_q;
+    always @(clock_q_exp) begin
+      #0.5 clock_q_exp <= !clock_q_exp;  // 1ns period, 1000 MHz
+  end
+  assign EXPCLK = clock_q_exp;
+
+  always @(posedge clock_q)
+    if (! (&shifter)) // until full...
+      shifter   <= {shifter[6:0], 1'b1}; // shift left, fill with 1's
+
+  assign NRST       =  shifter[7];
+
+  always @(posedge clock_q_exp)
+    if (! (&exp_shifter)) // until full...
+      exp_shifter   <= {exp_shifter[14:0], 1'b1}; // shift left, fill with 1's
+
+  assign EXP_NRST   =  exp_shifter[15];
+
+endmodule
+
+
+
diff --git a/verif/testbench/logical/expansion_subsystem_tb.v b/verif/testbench/logical/expansion_subsystem_tb.v
index edc0204c8bae38f31c7a553ad2f3a589f66e3d65..50cb009a9b3c07ed70adbd5daf5452ee7de36c88 100644
--- a/verif/testbench/logical/expansion_subsystem_tb.v
+++ b/verif/testbench/logical/expansion_subsystem_tb.v
@@ -1,11 +1,251 @@
-
+`timescale 1ns/1ps
 module expansion_subsystem_tb;
 
+// Clock and Reset Signals
+wire    SYSCLK;
+wire    EXPCLK;
+wire    NRST;
+wire    EXP_NRST;
+
+// Clock Control Signals
+wire    CSYSREQ_CD_sys;
+wire    CSYSACK_CD_sys;
+wire    CACTIVE_CD_sys;
+wire    CSYSREQ_CD_exp;
+wire    CSYSACK_CD_exp;
+wire    CACTIVE_CD_exp;
+
+
+reg [31:0] timer;
+initial begin 
+    #500 timer <= 32'd0;
+end
+clkreset u_clkreset(
+    .SYSCLK(SYSCLK),
+    .EXPCLK(EXPCLK),
+    .NRST(NRST),
+    .EXP_NRST(EXP_NRST)
+);
+
+clk_ctrl u_clk_ctrl(
+    .SYSCLK(SYSCLK),
+    .NRST(NRST),
+    .EXPCLK(EXPCLK),
+    .EXP_NRST(EXP_NRST),
+
+    .CSYSREQ_CD_sys(CSYSREQ_CD_sys),
+    .CSYSACK_CD_sys(CSYSACK_CD_sys),
+    .CACTIVE_CD_sys(CACTIVE_CD_sys),
+
+    .CSYSREQ_CD_exp(CSYSREQ_CD_exp),
+    .CSYSACK_CD_exp(CSYSACK_CD_exp),
+    .CACTIVE_CD_exp(CACTIVE_CD_exp)
+);
+
+// AXI EXP SS
+wire            AXI_EXP_SS_awid;
+wire  [31:0]    AXI_EXP_SS_awaddr;
+wire  [7:0]     AXI_EXP_SS_awlen;
+wire  [2:0]     AXI_EXP_SS_awsize;
+wire  [1:0]     AXI_EXP_SS_awburst;
+wire            AXI_EXP_SS_awlock;
+wire  [3:0]     AXI_EXP_SS_awcache;
+wire  [2:0]     AXI_EXP_SS_awprot;
+wire            AXI_EXP_SS_awvalid;
+wire            AXI_EXP_SS_awready;
+wire  [63:0]    AXI_EXP_SS_wdata;
+wire  [7:0]     AXI_EXP_SS_wstrb;
+wire            AXI_EXP_SS_wlast;
+wire            AXI_EXP_SS_wvalid;
+wire            AXI_EXP_SS_wready;
+wire            AXI_EXP_SS_bid;
+wire [1:0]      AXI_EXP_SS_bresp;
+wire            AXI_EXP_SS_bvalid;
+wire            AXI_EXP_SS_bready;
+wire            AXI_EXP_SS_arid;
+wire  [31:0]    AXI_EXP_SS_araddr;
+wire  [7:0]     AXI_EXP_SS_arlen;
+wire  [2:0]     AXI_EXP_SS_arsize;
+wire  [1:0]     AXI_EXP_SS_arburst;
+wire            AXI_EXP_SS_arlock;
+wire  [3:0]     AXI_EXP_SS_arcache;
+wire  [2:0]     AXI_EXP_SS_arprot;
+wire            AXI_EXP_SS_arvalid;
+wire            AXI_EXP_SS_arready;
+wire            AXI_EXP_SS_rid;
+wire [63:0]     AXI_EXP_SS_rdata;
+wire [1:0]      AXI_EXP_SS_rresp;
+wire            AXI_EXP_SS_rlast;
+wire            AXI_EXP_SS_rvalid;
+wire            AXI_EXP_SS_rready;
+
+// AXI System output port
+wire [1:0]      AXI_SYS_awid;
+wire [31:0]     AXI_SYS_awaddr;
+wire [7:0]      AXI_SYS_awlen;
+wire [2:0]      AXI_SYS_awsize;
+wire [1:0]      AXI_SYS_awburst;
+wire            AXI_SYS_awlock;
+wire [3:0]      AXI_SYS_awcache;
+wire [2:0]      AXI_SYS_awprot;
+wire            AXI_SYS_awvalid;
+wire            AXI_SYS_awready;
+wire [63:0]     AXI_SYS_wdata;
+wire [7:0]      AXI_SYS_wstrb;
+wire            AXI_SYS_wlast;
+wire            AXI_SYS_wvalid;
+wire            AXI_SYS_wready;
+wire  [1:0]     AXI_SYS_bid;
+wire  [1:0]     AXI_SYS_bresp;
+wire            AXI_SYS_bvalid;
+wire            AXI_SYS_bready;
+wire [1:0]      AXI_SYS_arid;
+wire [31:0]     AXI_SYS_araddr;
+wire [7:0]      AXI_SYS_arlen;
+wire [2:0]      AXI_SYS_arsize;
+wire [1:0]      AXI_SYS_arburst;
+wire            AXI_SYS_arlock;
+wire [3:0]      AXI_SYS_arcache;
+wire [2:0]      AXI_SYS_arprot;
+wire            AXI_SYS_arvalid;
+wire            AXI_SYS_arready;
+wire  [1:0]     AXI_SYS_rid;
+wire  [63:0]    AXI_SYS_rdata;
+wire  [1:0]     AXI_SYS_rresp;
+wire            AXI_SYS_rlast;
+wire            AXI_SYS_rvalid;
+wire            AXI_SYS_rready;
+
+
+expansion_subsystem_wrapper u_expansion_subsystem_wrapper(
+    .sys_clk(SYSCLK),
+    .resetn(NRST),
+    .exp_clk(EXPCLK),
+    .exp_clken(1'b1),
+    .expresetn(EXP_NRST),
 
+    .CSYSREQ_CD_sys(CSYSREQ_CD_sys),
+    .CSYSACK_CD_sys(CSYSACK_CD_sys),
+    .CACTIVE_CD_sys(CACTIVE_CD_sys),
 
+    .CSYSREQ_CD_exp(CSYSREQ_CD_exp),
+    .CSYSACK_CD_exp(CSYSACK_CD_exp),
+    .CACTIVE_CD_exp(CACTIVE_CD_exp),
 
+    .AXI_EXP_SS_awid(AXI_EXP_SS_awid),
+    .AXI_EXP_SS_awaddr(AXI_EXP_SS_awaddr),
+    .AXI_EXP_SS_awlen(AXI_EXP_SS_awlen),
+    .AXI_EXP_SS_awsize(AXI_EXP_SS_awsize),
+    .AXI_EXP_SS_awburst(AXI_EXP_SS_awburst),
+    .AXI_EXP_SS_awlock(AXI_EXP_SS_awlock),
+    .AXI_EXP_SS_awcache(AXI_EXP_SS_awcache),
+    .AXI_EXP_SS_awprot(AXI_EXP_SS_awprot),
+    .AXI_EXP_SS_awvalid(AXI_EXP_SS_awvalid),
+    .AXI_EXP_SS_awready(AXI_EXP_SS_awready),
+    .AXI_EXP_SS_wdata(AXI_EXP_SS_wdata),
+    .AXI_EXP_SS_wstrb(AXI_EXP_SS_wstrb),
+    .AXI_EXP_SS_wlast(AXI_EXP_SS_wlast),
+    .AXI_EXP_SS_wvalid(AXI_EXP_SS_wvalid),
+    .AXI_EXP_SS_wready(AXI_EXP_SS_wready),
+    .AXI_EXP_SS_bid(AXI_EXP_SS_bid),
+    .AXI_EXP_SS_bresp(AXI_EXP_SS_bresp),
+    .AXI_EXP_SS_bvalid(AXI_EXP_SS_bvalid),
+    .AXI_EXP_SS_bready(AXI_EXP_SS_bready),
+    .AXI_EXP_SS_arid(AXI_EXP_SS_arid),
+    .AXI_EXP_SS_araddr(AXI_EXP_SS_araddr),
+    .AXI_EXP_SS_arlen(AXI_EXP_SS_arlen),
+    .AXI_EXP_SS_arsize(AXI_EXP_SS_arsize),
+    .AXI_EXP_SS_arburst(AXI_EXP_SS_arburst),
+    .AXI_EXP_SS_arlock(AXI_EXP_SS_arlock),
+    .AXI_EXP_SS_arcache(AXI_EXP_SS_arcache),
+    .AXI_EXP_SS_arprot(AXI_EXP_SS_arprot),
+    .AXI_EXP_SS_arvalid(AXI_EXP_SS_arvalid),
+    .AXI_EXP_SS_arready(AXI_EXP_SS_arready),
+    .AXI_EXP_SS_rid(AXI_EXP_SS_rid),
+    .AXI_EXP_SS_rdata(AXI_EXP_SS_rdata),
+    .AXI_EXP_SS_rresp(AXI_EXP_SS_rresp),
+    .AXI_EXP_SS_rlast(AXI_EXP_SS_rlast),
+    .AXI_EXP_SS_rvalid(AXI_EXP_SS_rvalid),
+    .AXI_EXP_SS_rready(AXI_EXP_SS_rready),
 
+    .AXI_SYS_awid(AXI_SYS_awid),
+    .AXI_SYS_awaddr(AXI_SYS_awaddr),
+    .AXI_SYS_awlen(AXI_SYS_awlen),
+    .AXI_SYS_awsize(AXI_SYS_awsize),
+    .AXI_SYS_awburst(AXI_SYS_awburst),
+    .AXI_SYS_awlock(AXI_SYS_awlock),
+    .AXI_SYS_awcache(AXI_SYS_awcache),
+    .AXI_SYS_awprot(AXI_SYS_awprot),
+    .AXI_SYS_awvalid(AXI_SYS_awvalid),
+    .AXI_SYS_awready(AXI_SYS_awready),
+    .AXI_SYS_wdata(AXI_SYS_wdata),
+    .AXI_SYS_wstrb(AXI_SYS_wstrb),
+    .AXI_SYS_wlast(AXI_SYS_wlast),
+    .AXI_SYS_wvalid(AXI_SYS_wvalid),
+    .AXI_SYS_wready(AXI_SYS_wready),
+    .AXI_SYS_bid(AXI_SYS_bid),
+    .AXI_SYS_bresp(AXI_SYS_bresp),
+    .AXI_SYS_bvalid(AXI_SYS_bvalid),
+    .AXI_SYS_bready(AXI_SYS_bready),
+    .AXI_SYS_arid(AXI_SYS_arid),
+    .AXI_SYS_araddr(AXI_SYS_araddr),
+    .AXI_SYS_arlen(AXI_SYS_arlen),
+    .AXI_SYS_arsize(AXI_SYS_arsize),
+    .AXI_SYS_arburst(AXI_SYS_arburst),
+    .AXI_SYS_arlock(AXI_SYS_arlock),
+    .AXI_SYS_arcache(AXI_SYS_arcache),
+    .AXI_SYS_arprot(AXI_SYS_arprot),
+    .AXI_SYS_arvalid(AXI_SYS_arvalid),
+    .AXI_SYS_arready(AXI_SYS_arready),
+    .AXI_SYS_rid(AXI_SYS_rid),
+    .AXI_SYS_rdata(AXI_SYS_rdata),
+    .AXI_SYS_rresp(AXI_SYS_rresp),
+    .AXI_SYS_rlast(AXI_SYS_rlast),
+    .AXI_SYS_rvalid(AXI_SYS_rvalid),
+    .AXI_SYS_rready(AXI_SYS_rready),
 
+    .irq_dma_channel(),
+    .irq_dma_comb_nonsec()
+);
 
+trickbox u_trickbox(
+    .SYSCLK(SYSCLK),
+    .NRST(NRST),
+    .AXI_EXP_SS_awid(AXI_EXP_SS_awid),
+    .AXI_EXP_SS_awaddr(AXI_EXP_SS_awaddr),
+    .AXI_EXP_SS_awlen(AXI_EXP_SS_awlen),
+    .AXI_EXP_SS_awsize(AXI_EXP_SS_awsize),
+    .AXI_EXP_SS_awburst(AXI_EXP_SS_awburst),
+    .AXI_EXP_SS_awlock(AXI_EXP_SS_awlock),
+    .AXI_EXP_SS_awcache(AXI_EXP_SS_awcache),
+    .AXI_EXP_SS_awprot(AXI_EXP_SS_awprot),
+    .AXI_EXP_SS_awvalid(AXI_EXP_SS_awvalid),
+    .AXI_EXP_SS_awready(AXI_EXP_SS_awready),
+    .AXI_EXP_SS_wdata(AXI_EXP_SS_wdata),
+    .AXI_EXP_SS_wstrb(AXI_EXP_SS_wstrb),
+    .AXI_EXP_SS_wlast(AXI_EXP_SS_wlast),
+    .AXI_EXP_SS_wvalid(AXI_EXP_SS_wvalid),
+    .AXI_EXP_SS_wready(AXI_EXP_SS_wready),
+    .AXI_EXP_SS_bid(AXI_EXP_SS_bid),
+    .AXI_EXP_SS_bresp(AXI_EXP_SS_bresp),
+    .AXI_EXP_SS_bvalid(AXI_EXP_SS_bvalid),
+    .AXI_EXP_SS_bready(AXI_EXP_SS_bready),
+    .AXI_EXP_SS_arid(AXI_EXP_SS_arid),
+    .AXI_EXP_SS_araddr(AXI_EXP_SS_araddr),
+    .AXI_EXP_SS_arlen(AXI_EXP_SS_arlen),
+    .AXI_EXP_SS_arsize(AXI_EXP_SS_arsize),
+    .AXI_EXP_SS_arburst(AXI_EXP_SS_arburst),
+    .AXI_EXP_SS_arlock(AXI_EXP_SS_arlock),
+    .AXI_EXP_SS_arcache(AXI_EXP_SS_arcache),
+    .AXI_EXP_SS_arprot(AXI_EXP_SS_arprot),
+    .AXI_EXP_SS_arvalid(AXI_EXP_SS_arvalid),
+    .AXI_EXP_SS_arready(AXI_EXP_SS_arready),
+    .AXI_EXP_SS_rid(AXI_EXP_SS_rid),
+    .AXI_EXP_SS_rdata(AXI_EXP_SS_rdata),
+    .AXI_EXP_SS_rresp(AXI_EXP_SS_rresp),
+    .AXI_EXP_SS_rlast(AXI_EXP_SS_rlast),
+    .AXI_EXP_SS_rvalid(AXI_EXP_SS_rvalid),
+    .AXI_EXP_SS_rready(AXI_EXP_SS_rready)
+);
 
 endmodule
\ No newline at end of file
diff --git a/verif/testbench/logical/expansion_subsystem_tb.vc b/verif/testbench/logical/expansion_subsystem_tb.vc
new file mode 100644
index 0000000000000000000000000000000000000000..2637c9e98fd6d87211dc0a8b250697b76aa51ede
--- /dev/null
+++ b/verif/testbench/logical/expansion_subsystem_tb.vc
@@ -0,0 +1,6 @@
+
+$(SOCLABS_EXP_SUBSYSTEM_TECH_DIR)/verif/testbench/logical/expansion_subsystem_tb.v 
+$(SOCLABS_EXP_SUBSYSTEM_TECH_DIR)/verif/testbench/logical/clk_reset.v
+$(SOCLABS_EXP_SUBSYSTEM_TECH_DIR)/verif/testbench/logical/clk_ctrl.v
+
+-F $(SOCLABS_EXP_SUBSYSTEM_TECH_DIR)/flist/expansion_subsystem.vc
diff --git a/verif/testbench/logical/trickbox/trickbox.v b/verif/testbench/logical/trickbox/trickbox.v
new file mode 100644
index 0000000000000000000000000000000000000000..70e5e0b24073cade47add3249843dbbc76cac306
--- /dev/null
+++ b/verif/testbench/logical/trickbox/trickbox.v
@@ -0,0 +1,45 @@
+
+module trickbox(
+    input  wire     SYSCLK,
+    input  wire     NRST,
+
+    // AXI Trickbox output port 
+    output wire         AXI_EXP_SS_awid,
+    output wire  [31:0] AXI_EXP_SS_awaddr,
+    output wire  [7:0]  AXI_EXP_SS_awlen,
+    output wire  [2:0]  AXI_EXP_SS_awsize,
+    output wire  [1:0]  AXI_EXP_SS_awburst,
+    output wire         AXI_EXP_SS_awlock,
+    output wire  [3:0]  AXI_EXP_SS_awcache,
+    output wire  [2:0]  AXI_EXP_SS_awprot,
+    output wire         AXI_EXP_SS_awvalid,
+    input  wire         AXI_EXP_SS_awready,
+    output wire  [63:0] AXI_EXP_SS_wdata,
+    output wire  [7:0]  AXI_EXP_SS_wstrb,
+    output wire         AXI_EXP_SS_wlast,
+    output wire         AXI_EXP_SS_wvalid,
+    input  wire         AXI_EXP_SS_wready,
+    input  wire         AXI_EXP_SS_bid,
+    input  wire [1:0]   AXI_EXP_SS_bresp,
+    input  wire         AXI_EXP_SS_bvalid,
+    output wire         AXI_EXP_SS_bready,
+    output wire         AXI_EXP_SS_arid,
+    output wire  [31:0] AXI_EXP_SS_araddr,
+    output wire  [7:0]  AXI_EXP_SS_arlen,
+    output wire  [2:0]  AXI_EXP_SS_arsize,
+    output wire  [1:0]  AXI_EXP_SS_arburst,
+    output wire         AXI_EXP_SS_arlock,
+    output wire  [3:0]  AXI_EXP_SS_arcache,
+    output wire  [2:0]  AXI_EXP_SS_arprot,
+    output wire         AXI_EXP_SS_arvalid,
+    input  wire         AXI_EXP_SS_arready,
+    input  wire         AXI_EXP_SS_rid,
+    input  wire [63:0]  AXI_EXP_SS_rdata,
+    input  wire [1:0]   AXI_EXP_SS_rresp,
+    input  wire         AXI_EXP_SS_rlast,
+    input  wire         AXI_EXP_SS_rvalid,
+    output wire         AXI_EXP_SS_rready
+);
+
+
+endmodule
\ No newline at end of file