diff --git a/verif/cocotb/adp_cocotb_driver.py b/verif/cocotb/adp_cocotb_driver.py
index 539753136f0f734a0f738ba6d441c523ba8cbeff..ce99d546954e191e4a5848b4dcd5d60e5563e6a5 100644
--- a/verif/cocotb/adp_cocotb_driver.py
+++ b/verif/cocotb/adp_cocotb_driver.py
@@ -7,6 +7,7 @@
 # Copyright 2021-3, SoC Labs (www.soclabs.org)
 #-----------------------------------------------------------------------------
 import cocotb
+import os
 
 # Class for ADP AXI Stream Interface
 class ADP():
@@ -41,6 +42,11 @@ class ADP():
             else:
                 return read_str.strip()
                               
+    # Write ADP String
+    @cocotb.coroutine
+    async def write8(self, val):
+        await self.send.write([val])
+        
     # Write ADP String
     @cocotb.coroutine
     async def write(self, string):
@@ -59,7 +65,24 @@ class ADP():
         
     # Exit Monitor Mode
     @cocotb.coroutine
-    async def monitorModeEnter(self):
+    async def monitorModeExit(self):
         self.dut.log.info("Exiting ADP Monitor Mode")
         await self.send.write([0x04])
-        self.monitor_mode = False
\ No newline at end of file
+        self.monitor_mode = False
+    
+    # Write Hex File into System
+    @cocotb.coroutine
+    async def writeHex(self, file_name, address=0x20000000):
+        self.dut.log.info(f"Writing {file_name} to {hex(address)}")
+        file_stats = os.stat(file_name)
+        file_len_in_bytes = round(file_stats.st_size/3)
+        bytecount_hex=hex(file_len_in_bytes)
+        await self.write(f'A {str(hex(address))}\n')
+        await self.write(f'U {str(bytecount_hex)}\n')
+        count = file_len_in_bytes
+        with open(file_name, mode='r') as file:
+            for i in range(count) :
+                b=file.readline()
+                await self.write8(int(str.strip(b),16))
+        await self.write8(0x0a)
+        self.dut.log.info("Finished Send Code")
\ No newline at end of file
diff --git a/verif/cocotb/test_adp.py b/verif/cocotb/test_adp.py
index f262cec73c0cae21a7b866d38328541c36b43796..edfdd6909cdcaacf14cf78985f90c59a5652074a 100644
--- a/verif/cocotb/test_adp.py
+++ b/verif/cocotb/test_adp.py
@@ -9,6 +9,7 @@
 from random import randint, randrange, getrandbits, shuffle
 from collections.abc import Iterable
 
+import os
 import logging
 import cocotb
 from cocotb.clock import Clock
@@ -23,8 +24,8 @@ CLK_PERIOD = (10, "ns")
 
 # Control ADP AXI Stream bus and create ADP Driver Object
 def setup_adp(dut):
-    adp_sender = AxiStreamSource(AxiStreamBus.from_prefix(dut, "txd8"), dut.XTAL1, dut.NRST)
-    adp_reciever = AxiStreamSink(AxiStreamBus.from_prefix(dut, "rxd8"), dut.XTAL1, dut.NRST)
+    adp_sender = AxiStreamSource(AxiStreamBus.from_prefix(dut, "txd8"), dut.XTAL1, dut.NRST, reset_active_level=False)
+    adp_reciever = AxiStreamSink(AxiStreamBus.from_prefix(dut, "rxd8"), dut.XTAL1, dut.NRST, reset_active_level=False)
     logging.getLogger("cocotb.nanosoc_tb.rxd8").setLevel(logging.WARNING)
     logging.getLogger("cocotb.nanosoc_tb.txd8").setLevel(logging.WARNING)
     driver = ADP(dut, adp_sender, adp_reciever)
@@ -33,11 +34,13 @@ def setup_adp(dut):
 # Start Clocks and Reset System
 @cocotb.coroutine
 async def setup_dut(dut):
+    adp_driver = setup_adp(dut)
     cocotb.start_soon(Clock(dut.XTAL1, *CLK_PERIOD).start())
     dut.NRST.value = 0
     await ClockCycles(dut.XTAL1, 2)
     dut.NRST.value = 1
     await ClockCycles(dut.XTAL1, 2)
+    return adp_driver
 
 # Wait for bootcode to finish
 @cocotb.coroutine
@@ -48,20 +51,30 @@ async def wait_bootcode(dut, driver):
         dut.log.info(read_str)
         if read_str == bootcode_last:
             break
+            
+# Wait for bootcode to finish
+@cocotb.coroutine
+async def wait_hello(dut, driver):
+    test_passed = "** TEST PASSED **"
+    while True:
+        read_str = await driver.readLine()
+        dut.log.info(read_str)
+        if chr(0x04) in read_str:
+            dut.log.info(read_str)
+            break
 
 # Basic Test Clocks Test
 @cocotb.test()
 async def test_clocks(dut):
     """Tests Clocks and Resets in Cocotb"""
     log = logging.getLogger(f"cocotb.test")
-    await setup_dut(dut)
+    adp_driver = await setup_dut(dut, adp_driver)
     log.info("Setup Complete")
 
 # Basic Test Reading from ADP
 @cocotb.test()
 async def test_adp_read(dut):
-    await setup_dut(dut)
-    adp_driver = setup_adp(dut)
+    adp_driver = await setup_dut(dut)
     dut.log.info("Setup Complete")
     dut.log.info("Starting Test")
     await wait_bootcode(dut, adp_driver)
@@ -70,8 +83,7 @@ async def test_adp_read(dut):
 # Basic Test Write to ADP
 @cocotb.test()
 async def test_adp_write(dut):
-    await setup_dut(dut)
-    adp_driver = setup_adp(dut)
+    adp_driver = await setup_dut(dut)
     dut.log.info("Setup Complete")
     dut.log.info("Starting Test")
     await wait_bootcode(dut, adp_driver)
@@ -82,6 +94,24 @@ async def test_adp_write(dut):
     for i in range(4):
         dut.log.info(await adp_driver.readLine())
     dut.log.info("ADP Write Test Complete")
+    
+# Basic Software Load Test
+@cocotb.test()
+async def test_adp_hello(dut):
+    hello_hex = os.environ.get("SOCLABS_PROJECT_DIR")+"/simulate/sim/hello/image.hex"
+    adp_driver = await setup_dut(dut)
+    dut.log.info("Setup Complete")
+    dut.log.info("Starting Test")
+    await wait_bootcode(dut, adp_driver)
+    dut.log.info("Bootcode Finished")
+    await adp_driver.monitorModeEnter()
+    await adp_driver.writeHex(hello_hex, 0x20000000)
+    await adp_driver.monitorModeExit()
+    dut.NRST.value = 0
+    await ClockCycles(dut.XTAL1, 2)
+    dut.NRST.value = 1
+    await wait_hello(dut, adp_driver)
+    dut.log.info("ADP Write Test Complete")