From 5f8da4622976ff14df878a00ab6b521154a1e121 Mon Sep 17 00:00:00 2001
From: Daniel Newbrook <dwn1c21@soton.ac.uk>
Date: Thu, 22 Jun 2023 16:29:44 +0100
Subject: [PATCH] Update NanoSoC FPGA verification files

---
 software/common/demos/interrupt_demo.c        |   2 +-
 .../drivers/ADP_UART_driver.py                | 111 ++++++++++++++----
 .../drivers/NanoSoC_Verification.py           |  35 ++++++
 .../python_verification/romtable_test.py      |  13 ++
 4 files changed, 139 insertions(+), 22 deletions(-)

diff --git a/software/common/demos/interrupt_demo.c b/software/common/demos/interrupt_demo.c
index 699d836..d412301 100644
--- a/software/common/demos/interrupt_demo.c
+++ b/software/common/demos/interrupt_demo.c
@@ -209,7 +209,7 @@ void UartExample(void)
   NVIC_DisableIRQ(EXP1_IRQn); // NVIC_DisableIRQ(UARTTX0_IRQn);   -disable both UART0 TX and UART1 RX IRQs
   NVIC_DisableIRQ(EXP2_IRQn); // NVIC_DisableIRQ(UARTRX1_IRQn);
 
- -return;
+  return;
 }
 
 // ----------------------------------------------------------
diff --git a/system/fpga_imp/python_verification/drivers/ADP_UART_driver.py b/system/fpga_imp/python_verification/drivers/ADP_UART_driver.py
index df4aafc..f7dabd5 100644
--- a/system/fpga_imp/python_verification/drivers/ADP_UART_driver.py
+++ b/system/fpga_imp/python_verification/drivers/ADP_UART_driver.py
@@ -2,7 +2,7 @@ import serial
 from time import time
 
 class ADP:
-    def __init__(self, iface = '/dev/ttyUSB2', base_addr = 0x80020000, baud = 115200):
+    def __init__(self, base_addr = 0x80020000, iface = '/dev/ttyUSB2', baud = 115200):
         self.interface  = iface
         self.baud       = baud
         self.uart       = None
@@ -14,7 +14,7 @@ class ADP:
         self.GPIO_ADDR  = 0xF0000000
         self.STS_ADDR   = 0xF0000004
         self.BASE_ADDR  = base_addr
-        self.RX_FIF0    = 0x00
+        self.RX_FIFO    = 0x00
         self.TX_FIFO    = 0x04
         self.STAT_REG   = 0x08
         self.CTRL_REG   = 0x0C
@@ -39,6 +39,9 @@ class ADP:
         if ((value & 0xFFFF0000) != 0xcafe0000):
             raise Exception("Target not responding correctly, check interface / baud rate...")
         
+    ##################################################################
+    # checkStatus: Read status of the UART to AXI 
+    ##################################################################     
     def checkStatus(self):
         addr = self.STS_ADDR
         cmd = bytearray([self.CMD_READ, 
@@ -58,9 +61,10 @@ class ADP:
 
         return value
     ##################################################################
-    # read32: Read a word from a specified address
+    # read8: Read a byte from the RX_FIFO
     ##################################################################
-    def read32(self, offset):
+    def read8(self):
+        offset = self.RX_FIFO;
         # Connect if required
         if self.uart == None:
             self.connect()
@@ -85,9 +89,10 @@ class ADP:
         return value
 
     ##################################################################
-    # write32: Write a word to a specified address
+    # write8: Write a byte to a the Tx FIFO
     ##################################################################
-    def write32(self, offset, value):
+    def write8(self, value):
+        offset = self.TX_FIFO
         # Connect if required
         if self.uart == None:
             self.connect()
@@ -102,15 +107,16 @@ class ADP:
                         (addr >> 8)   & 0xFF, 
                         (addr >> 0)   & 0xFF, 
                         (value >> 0)  & 0xFF, 
-                        (value>> 8)  & 0xFF, 
-                        (value >> 16)  & 0xFF, 
-                        (value >> 24)  & 0xFF])
+                        (0)  & 0xFF, 
+                        (0)  & 0xFF, 
+                        (0)  & 0xFF])
         self.uart.write(cmd)
 
     ##################################################################
-    # write: Write a block of data to a specified address
+    # write: Write a block of data to the Tx FIFO
     ##################################################################
-    def write(self, addr, buf, timeout = 1):
+    def write(self, buf):
+        timeout = 1
         # Connect if required
         if self.uart == None:
             self.connect()
@@ -118,19 +124,20 @@ class ADP:
         stop_time = time() + timeout
         wr_count = 0
         for i in buf:
-            while (self.read32(self.STAT_REG) & 1 << self.TX_FULL) and (time() < stop_time):
+            while (self.checkReg(self.STAT_REG) & 1 << self.TX_FULL) and (time() < stop_time):
                 pass
             if time() > stop_time:
                 wr_count = -1
                 break
-            self.write32(addr,ord(i))
+            self.write8(ord(i))
             wr_count += 1
         return wr_count
 
     ##################################################################
-    # read: Read a block of data from a specified address
+    # read: Read a block from the Rx FIFO
     ##################################################################
-    def read(self, addr, length):
+    def read(self, length):
+        addr = self.RX_FIFO
         # Connect if required
         if self.uart == None:
             self.connect()
@@ -139,16 +146,19 @@ class ADP:
         timeout = 1
         stop_time = time() + timeout
         for i in range(length):
-            while(not(self.read32(self.STAT_REG) & 1 << self.RX_VALID) and (time() < stop_time)):
+            while(not(self.checkReg(self.STAT_REG) & 1 << self.RX_VALID) and (time() < stop_time)):
                 pass
             if time() > stop_time:
                 break
-            buf += chr(self.read32(addr))
+            buf += chr(self.read8())
             stop_time = time() + timeout
 
         return buf
     
-    def readLine(self,addr):
+    ##################################################################
+    # readLine: Read a block from the Rx FIFO until newline character
+    ##################################################################
+    def readLine(self):
         if self.uart == None:
             self.connect()
 
@@ -157,13 +167,72 @@ class ADP:
         stop_time = time() + timeout
         stop=False
         while(not(stop)):
-            while(not(self.read32(self.STAT_REG) & 1 << self.RX_VALID) and (time() < stop_time)):
+            while(not(self.checkReg(self.STAT_REG) & 1 << self.RX_VALID) and (time() < stop_time)):
                 pass
             if time() > stop_time:
                 break
-            next_chr = chr(self.read32(addr))
+            next_chr = chr(self.read8())
             buf += next_chr
             stop_time = time() + timeout
             if (next_chr == '\n'):
                 stop = True
-        return buf
\ No newline at end of file
+        return buf
+    
+    ##################################################################
+    # checkReg: Read char from offset (self.CTRL_REG or self.STAT_REG)
+    ##################################################################
+    def checkReg(self,offset):
+        # Connect if required
+        if self.uart == None:
+            self.connect()
+
+        addr = self.BASE_ADDR+offset
+        # Send read command
+        cmd = bytearray([self.CMD_READ, 
+                         4, 
+                        (addr >> 24) & 0xFF, 
+                        (addr >> 16) & 0xFF, 
+                        (addr >> 8) & 0xFF, 
+                        (addr >> 0) & 0xFF])
+        self.uart.write(cmd)
+
+        value = 0
+        idx   = 0
+        while (idx < 4):
+            b = self.uart.read(1)
+            value |= (ord(b) << (idx * 8))
+            idx += 1
+
+        return value
+
+    ##################################################################
+    # writeReg: Write char to offset (self.CTRL_REG or self.STAT_REG)
+    ##################################################################  
+    def writeReg(self,offset,value):
+        # Connect if required
+        if self.uart == None:
+            self.connect()
+
+        addr = self.BASE_ADDR + offset
+
+        # Send write command
+        cmd = bytearray([self.CMD_WRITE,
+                         4, 
+                        (addr >> 24)  & 0xFF, 
+                        (addr >> 16)  & 0xFF, 
+                        (addr >> 8)   & 0xFF, 
+                        (addr >> 0)   & 0xFF, 
+                        (value >> 0)  & 0xFF, 
+                        (0)  & 0xFF, 
+                        (0)  & 0xFF, 
+                        (0)  & 0xFF])
+        self.uart.write(cmd)
+
+    def setupCtrlReg(self):
+        self.writeReg(self.CTRL_REG,0x00)
+
+    def monitorModeEnter(self):
+        self.writeReg(self.TX_FIFO,0x1b)
+
+    def monitorModeExit(self):
+        self.writeReg(self.TX_FIFO,0x04)
\ No newline at end of file
diff --git a/system/fpga_imp/python_verification/drivers/NanoSoC_Verification.py b/system/fpga_imp/python_verification/drivers/NanoSoC_Verification.py
index e69de29..a43f1c1 100644
--- a/system/fpga_imp/python_verification/drivers/NanoSoC_Verification.py
+++ b/system/fpga_imp/python_verification/drivers/NanoSoC_Verification.py
@@ -0,0 +1,35 @@
+import os, sys
+from progress.bar import Bar
+if os.environ["BOARDNAME"] == 'MPS3':
+    from .ADP_UART_driver import ADP
+
+class NanoSoC_APD:
+    def __init__(self):
+        self.adp = ADP(0x80020000)
+        print(self.adp.read(100))
+        self.adp.setupCtrlReg()
+        print(self.adp.read(100))
+        self.adp.monitorModeEnter()
+        print(self.adp.read(10))
+
+    ##################################################################
+    # writeHex: write a hex file to iRAM
+    ##################################################################       
+    def writeHex(self,file_name):
+        file_stats = os.stat(file_name)
+        file_len_in_bytes = round(file_stats.st_size/3)
+        print(f'file size in bytes is {file_len_in_bytes}')
+        bytecount_hex=hex(file_len_in_bytes)
+        self.adp.write('A 0x20000000\n')
+        print(self.adp.read(100))
+        self.adp.write('U ' +bytecount_hex+'\n')
+        print(self.adp.read(100))
+        count = file_len_in_bytes
+        with open(file_name, mode='r') as file:
+            with Bar('Uploading...', max=count) as bar:
+                for i in range(count) :
+                    b=file.readline()
+                    self.adp.write8(int(str.strip(b),16))
+                    bar.next()
+        print(self.adp.read(100))
+
diff --git a/system/fpga_imp/python_verification/romtable_test.py b/system/fpga_imp/python_verification/romtable_test.py
index e69de29..b4b9857 100644
--- a/system/fpga_imp/python_verification/romtable_test.py
+++ b/system/fpga_imp/python_verification/romtable_test.py
@@ -0,0 +1,13 @@
+import sys
+import os
+from drivers.NanoSoC_Verification import NanoSoC_APD
+
+
+NanoSoC = NanoSoC_APD()
+NanoSoC.writeHex('uart_tests.hex')
+print(NanoSoC.adp.read(500))
+NanoSoC.adp.write('C 0x200\n')
+NanoSoC.adp.write('C 0x201\n')
+print(NanoSoC.adp.read(100000))
+NanoSoC.adp.write('C 0x200\n')
+NanoSoC.adp.write('C 0x201\n')
-- 
GitLab