diff --git a/.gitignore b/.gitignore
index 331c9ff76b389207a36c97807dc7f131f5ce78f0..bcea41d78333fab67ea915ccf3093d6a7f1973cd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,4 +6,9 @@ simulate/
 imp/
 
 system/src/bootrom
-system/src/defines
\ No newline at end of file
+system/src/defines
+
+doc/tex/*.aux
+doc/tex/*.log
+doc/tex/*.out 
+doc/tex/*.toc
diff --git a/doc/megasoc_configuration_manual.pdf b/doc/megasoc_configuration_manual.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..f0cdc56eaa01a28ebfa54efdfadf233afb147c7f
Binary files /dev/null and b/doc/megasoc_configuration_manual.pdf differ
diff --git a/doc/megasoc_datasheet.pdf b/doc/megasoc_datasheet.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..facdd54a902155a2d78499a062393994ff9873a6
Binary files /dev/null and b/doc/megasoc_datasheet.pdf differ
diff --git a/doc/tex/megasoc_configuration_manual.tex b/doc/tex/megasoc_configuration_manual.tex
new file mode 100644
index 0000000000000000000000000000000000000000..e752ad100ad20905d19dca35cefda3cdad9734d7
--- /dev/null
+++ b/doc/tex/megasoc_configuration_manual.tex
@@ -0,0 +1,34 @@
+\documentclass{report}
+\usepackage{hyperref}
+\usepackage{tcolorbox,float}
+\usepackage{listings}
+
+\makeatletter
+\newfloat{info@box}{tbp}{loi}[section]% 1: Name of float environment. 2: Default placement (top, bottom, ...). 3: File extension if written to an aux-file (like toc, lof, lot, loa, ...). 4: Numbering within <section/subsection/...>.
+\makeatother
+\floatname{info@box}{Infobox}% Adapt caption.
+\newenvironment{infobox}[1][]{% Create new environment using info@box and tcolorbox
+   \begin{info@box}%
+      \begin{tcolorbox}[colback=red!15!white,%                    background color
+            colframe=red!75!black,%                               frame color
+            title=Additional information\ifstrempty{#1}{}{: #1}.% title
+         ]%
+}{%
+      \end{tcolorbox}%
+   \end{info@box}%
+}
+
+\title{megaSoC Configuration Manual}
+\author{\href{http://www.soclabs.org}{SoC Labs}}
+\begin{document}
+\maketitle
+\input{preamble.tex}
+\begin{infobox}
+    You must run 'source set\_env.sh' from the megasoc-project directory every time you open a new terminal!
+\end{infobox} \par
+ 
+\tableofcontents
+\clearpage
+\chapter{Introduction}
+
+\end{document}
\ No newline at end of file
diff --git a/doc/tex/megasoc_datasheet.tex b/doc/tex/megasoc_datasheet.tex
new file mode 100644
index 0000000000000000000000000000000000000000..48431354e620909eb5de37e85789f85fa8531392
--- /dev/null
+++ b/doc/tex/megasoc_datasheet.tex
@@ -0,0 +1,50 @@
+\documentclass{report}
+\usepackage{hyperref}
+
+\title{megaSoC Datasheet}
+\author{\href{http://www.soclabs.org}{SoC Labs}}
+\begin{document}
+\maketitle
+\input{preamble.tex}
+
+\tableofcontents
+\clearpage
+\chapter{Introduction}
+
+\section{Summary}
+
+
+\chapter{System}
+
+\section{Bus Interconnect}
+
+\section{Address Map}
+\subsection{Summary}
+
+\input{megasoc_sys_address_map.tex}
+
+\subsection{Peripheral Region}
+Below are the address regions for the System IO/Peripherals, detailed address maps for each peripheral are in chapter \ref{peripherals}
+\begin{center}
+    \begin{tabular}{||c | c | c ||}
+        \hline
+        Region & Start Address & End Address \\ 
+        \hline\hline
+        UART 0 & 0x40000000 & 0x40000FFF \\
+        \hline
+        Timer 1 & 0x40001000 & 0x40001FFF \\
+        \hline
+    \end{tabular}
+\end{center}
+
+\section{}
+
+
+\chapter{Peripherals} \label{peripherals} 
+
+\chapter{Recommended Testboard}
+
+
+
+
+\end{document}
diff --git a/doc/tex/megasoc_sys_address_map.tex b/doc/tex/megasoc_sys_address_map.tex
new file mode 100644
index 0000000000000000000000000000000000000000..077631922b58dc687cc02a2aea981cfeb95d4036
--- /dev/null
+++ b/doc/tex/megasoc_sys_address_map.tex
@@ -0,0 +1,25 @@
+\begin{center}
+    \begin{tabular}{||c | c | c ||}
+        \hline
+        Region & Start Address & End Address \\ 
+        \hline\hline
+        Boot-Rom & 0x00000000 & 0x0000FFFF \\
+        \hline
+        FLASH & 0x00400000 & 0x007FFFFF \\
+        \hline
+        SRAM & 0x00800000 & 0x0080FFFF \\
+        \hline
+        FLASH CTRL & 0x01000000 & 0x0100FFFF \\
+        \hline
+        DMA CTRL & 0x01010000 & 0x01011FFF \\
+        \hline
+        GIC & 0x01100000 & 0x01107FFF \\
+        \hline
+        PERIPHERAL & 0x40000000 & 0x5FFFFFFF \\
+        \hline
+        DEBUG & 0x60000000 & 0x7FFFFFFF \\
+        \hline
+        DRAM & 0x80000000 & 0xFFFFFFFF \\
+        \hline
+    \end{tabular}
+\end{center}
diff --git a/doc/tex/preamble.tex b/doc/tex/preamble.tex
new file mode 100644
index 0000000000000000000000000000000000000000..58943b8f10ec7da1f0f99edb85748da57a94a04f
--- /dev/null
+++ b/doc/tex/preamble.tex
@@ -0,0 +1 @@
+Preamble, copyrights licenses etc.
\ No newline at end of file
diff --git a/flist/project/megasoc_tb.flist b/flist/project/megasoc_tb.flist
index 9af37148d0699319d5e9c2fcf5033e491ebc904e..1a976d433c6e85334ddc09df4345b7864783dac5 100644
--- a/flist/project/megasoc_tb.flist
+++ b/flist/project/megasoc_tb.flist
@@ -23,5 +23,9 @@ $(SOCLABS_PROJECT_DIR)/verif/trace/megasoc_uart_capture.v
 $(SOCLABS_PROJECT_DIR)/verif/trace/megasoc_qspi_capture.v
 $(SOCLABS_PROJECT_DIR)/verif/control/logical/megasoc_clkreset.v
 
+$(SOCLABS_PROJECT_DIR)/verif/trace/megasoc_axi_stream_io_8_rxd_to_file.v
+$(SOCLABS_PROJECT_DIR)/verif/trace/megasoc_ft1248x4_to_axi_streamio_v1_0.v
+$(SOCLABS_PROJECT_DIR)/verif/trace/megasoc_ft1248x1_track.v
+$(SOCLABS_PROJECT_DIR)/megasoc_tech/logical/socdebug_tech/socket/f232h_ft1248_stream/verilog/SYNCHRONIZER_EDGES.v
 // $(SOCLABS_MEGASOC_TECH_DIR)/logical/MS_QSPI_XIP_CACHE/verify/vip/sst26wf080b.v
 
diff --git a/fpga/CICD/procs.tcl b/fpga/CICD/procs.tcl
index 5e3646baa5ba743fe0cf88096c76e920687b4827..52a07469f852a79c06b1dddb726874a975e34ad7 100644
--- a/fpga/CICD/procs.tcl
+++ b/fpga/CICD/procs.tcl
@@ -147,7 +147,15 @@ proc connect_zc702 {} {
 }
 
 proc connect_haps_sx {} {
-  
+  open_hw_manager
+  connect_hw_server -allow_non_jtag
+  open_hw_target -xvc_url 10.22.13.34:2542
+  set_property PROBES.FILE {/home/dwn1c21/SoC-Labs/megasoc_project/imp/fpga/megasoc/tmp_edit_project.runs/impl_1/megasoc_design_wrapper.ltx} [get_hw_devices xcvu19p_0]
+  set_property FULL_PROBES.FILE {/home/dwn1c21/SoC-Labs/megasoc_project/imp/fpga/megasoc/tmp_edit_project.runs/impl_1/megasoc_design_wrapper.ltx} [get_hw_devices xcvu19p_0]
+  set_property PROGRAM.FILE {/home/dwn1c21/SoC-Labs/megasoc_project/imp/fpga/megasoc/tmp_edit_project.runs/impl_1/megasoc_design_wrapper.bit} [get_hw_devices xcvu19p_0]
+  program_hw_devices [get_hw_devices xcvu19p_0]
+  refresh_hw_device [lindex [get_hw_devices xcvu19p_0] 0]
+  reset_hw_axi [get_hw_axis]
 }
 
 
diff --git a/fpga/targets/haps_sx/fpga_pinmap.xdc b/fpga/targets/haps_sx/fpga_pinmap.xdc
index 04d5014d84dced8fdb98a187240d8e55852186ae..1161157d7d0696242b17fb6499d9a8898982c04f 100644
--- a/fpga/targets/haps_sx/fpga_pinmap.xdc
+++ b/fpga/targets/haps_sx/fpga_pinmap.xdc
@@ -1,7 +1,14 @@
 set_property PACKAGE_PIN BK44 [get_ports nRESET_0]
 set_property PACKAGE_PIN BM44 [get_ports CLK_IN_P]
 set_property PACKAGE_PIN BN44 [get_ports CLK_IN_N]
-
+set_property PACKAGE_PIN AW16 [get_ports PMOD1_IO[0]]
+set_property PACKAGE_PIN AW15 [get_ports PMOD1_IO[1]]
+set_property PACKAGE_PIN AY14 [get_ports PMOD1_IO[2]]
+set_property PACKAGE_PIN AY13 [get_ports PMOD1_IO[3]]
+set_property PACKAGE_PIN AV16 [get_ports PMOD1_IO[4]]
+set_property PACKAGE_PIN AV15 [get_ports PMOD1_IO[5]]
+set_property PACKAGE_PIN AU17 [get_ports PMOD1_IO[6]]
+set_property PACKAGE_PIN AU16 [get_ports PMOD1_IO[7]]
 
 set_property IOSTANDARD DIFF_SSTL12 [get_ports CLK_IN_P]
 set_property IOSTANDARD DIFF_SSTL12 [get_ports CLK_IN_N]
diff --git a/fpga/targets/haps_sx/fpga_timing.xdc b/fpga/targets/haps_sx/fpga_timing.xdc
index 71862a424f4440085d5ad3e9db16d35acf98fd07..77c65e5dad8b5921884087f23fdfe83776e6788a 100644
--- a/fpga/targets/haps_sx/fpga_timing.xdc
+++ b/fpga/targets/haps_sx/fpga_timing.xdc
@@ -1 +1 @@
-create_clock -name CLK_IN_P -period 10 [get_ports CLK_IN_P]
+create_clock -name EXT_CLK -period 10 [get_ports CLK_IN_P]
diff --git a/fpga/targets/haps_sx/megasoc_design_wrapper.v b/fpga/targets/haps_sx/megasoc_design_wrapper.v
index 0959e0ed9e9d5ff473acd6df53702137f4ac8918..60a9b0142aee4f8fb459d2d9a150fd790ac3f929 100644
--- a/fpga/targets/haps_sx/megasoc_design_wrapper.v
+++ b/fpga/targets/haps_sx/megasoc_design_wrapper.v
@@ -10,33 +10,18 @@
 //--------------------------------------------------------------------------------
 `timescale 1 ps / 1 ps
 
-module megasoc_design_wrapper
-   (CLK_IN_P,
-   CLK_IN_N,
-    //QSPI_IO_e_0,
-    //QSPI_IO_i_0,
-    //QSPI_IO_o_0,
-    //QSPI_SCLK_0,
-    //QSPI_nCS_0,
-    nRESET_0);
-    
-  input CLK_IN_P;
-  input CLK_IN_N;
-  //output [3:0]QSPI_IO_e_0;
-  //input [3:0]QSPI_IO_i_0;
-  //output [3:0]QSPI_IO_o_0;
-  //output QSPI_SCLK_0;
-  //output QSPI_nCS_0;
-  input nRESET_0;
+module megasoc_design_wrapper(
+  input  wire   CLK_IN_P,
+  input  wire   CLK_IN_N,
+  input  wire   nRESET_0,
+  inout  wire [7:0] PMOD1_IO    
+);
 
-  wire CLK_IN_P;
-  wire CLK_IN_N;
   wire [3:0]QSPI_IO_e_0;
   wire [3:0]QSPI_IO_i_0;
   wire [3:0]QSPI_IO_o_0;
   wire QSPI_SCLK_0;
   wire QSPI_nCS_0;
-  wire nRESET_0;
 
   megasoc_design megasoc_design_i
        (.CLK_P(CLK_IN_P),
diff --git a/makefile b/makefile
index ca400597f52c14abc67b693977b2b45aca87ff39..3a2edf1805cb3fc452f4b145faffaf1f9b41a929 100644
--- a/makefile
+++ b/makefile
@@ -131,5 +131,12 @@ get_flash_model:
 
 first_time_setup: make_project build_ip get_flash_model
 
+docs:
+	pdflatex --output-directory=./doc/tex/ ./doc/tex/megasoc_datasheet.tex
+	pdflatex --output-directory=./doc/tex/ ./doc/tex/megasoc_datasheet.tex
+	pdflatex --output-directory=./doc/tex/ ./doc/tex/megasoc_configuration_manual.tex
+	pdflatex --output-directory=./doc/tex/ ./doc/tex/megasoc_configuration_manual.tex
+	mv ./doc/tex/megasoc_datasheet.pdf ./doc/megasoc_datasheet.pdf
+	mv ./doc/tex/megasoc_configuration_manual.pdf ./doc/megasoc_configuration_manual.pdf
 
 clean: clean_sim clean_all_code
\ No newline at end of file
diff --git a/megasoc_chip/chip/logical/megasoc_chip.v b/megasoc_chip/chip/logical/megasoc_chip.v
index b6233e14d980d11f4d24318f079cfacc9a8d48e7..575960ca8a3c991e2c6bfb3618ea403d5efd1e72 100644
--- a/megasoc_chip/chip/logical/megasoc_chip.v
+++ b/megasoc_chip/chip/logical/megasoc_chip.v
@@ -12,8 +12,9 @@
 //  megasoc_system
 
 module megasoc_chip(
-    input wire CLK_IN,
-    input wire nRESET,
+    input  wire         CLK_IN, // Main system clock input
+    input  wire         RT_CLK, // 32kHz real time clock
+    input  wire         nRESET,
 
     // QSPI signals
     output wire         QSPI_SCLK,
@@ -27,6 +28,16 @@ module megasoc_chip(
     output wire         UARTTXD,
     output wire         UARTTXEN,
 
+    // FT1248 Signals
+    output wire         FT_CLK_O,    // SCLK
+    output wire         FT_SSN_O,    // SS_N
+    input  wire         FT_MISO_I,   // MISO
+    output wire         FT_MIOSIO_O, // MIOSIO tristate output when enabled
+    output wire         FT_MIOSIO_E, // MIOSIO tristate output enable (active hi)
+    output wire         FT_MIOSIO_Z, // MIOSIO tristate output enable (active lo)
+    input  wire         FT_MIOSIO_I, // MIOSIO tristate input
+
+
     // DAP-lite Signals
     input  wire         nTRST,
     input  wire         SWCLKTCK,
@@ -41,15 +52,27 @@ module megasoc_chip(
 
 megasoc_system u_megasoc_system(
     .CLK_IN(CLK_IN),
+    .RT_CLK(RT_CLK),
     .nRESET(nRESET),
+
     .QSPI_SCLK(QSPI_SCLK),
     .QSPI_nCS(QSPI_nCS),
     .QSPI_IO_o(QSPI_IO_o),
     .QSPI_IO_i(QSPI_IO_i),
     .QSPI_IO_e(QSPI_IO_e),
+
     .UARTRXD(UARTRXD),
     .UARTTXD(UARTTXD),
     .UARTTXEN(UARTTXEN),
+
+    .FT_CLK_O(FT_CLK_O),
+    .FT_SSN_O(FT_SSN_O),
+    .FT_MISO_I(FT_MISO_I),
+    .FT_MIOSIO_O(FT_MIOSIO_O),
+    .FT_MIOSIO_E(FT_MIOSIO_E),
+    .FT_MIOSIO_Z(FT_MIOSIO_Z),
+    .FT_MIOSIO_I(FT_MIOSIO_I),
+
     .nTRST(nTRST),
     .SWCLKTCK(SWCLKTCK),
     .SWDITMS(SWDITMS),
diff --git a/megasoc_chip/pads/glib/logical/megasoc_chip_pads.v b/megasoc_chip/pads/glib/logical/megasoc_chip_pads.v
index 6dd410f1b1f45c2e65842736a235177fc3b424ef..ccb8d0123813d89df58ee379af42175f12e1b4db 100644
--- a/megasoc_chip/pads/glib/logical/megasoc_chip_pads.v
+++ b/megasoc_chip/pads/glib/logical/megasoc_chip_pads.v
@@ -22,6 +22,8 @@ module megasoc_chip_pads(
     // Clocks and Reset
     input  wire         REF_CLK_XTAL1,
     output wire         REF_CLK_XTAL2,
+    input  wire         RT_CLK_XTAL1,
+    output wire         RT_CLK_XTAL2,
     input  wire         PORESTn,
     input  wire         nSRST,
 
@@ -45,7 +47,13 @@ module megasoc_chip_pads(
     // QSPI Interface
     output wire         QSPI_SCLK,
     inout  wire [3:0]   QSPI_IO,
-    output wire         QSPI_nCS
+    output wire         QSPI_nCS,
+
+    // FT1248 
+    output wire         FT_CLK,     // SCLK
+    output wire         FT_SSN,     // SS_N
+    input  wire         FT_MISO,    // MISO
+    inout  wire         FT_MIOSIO   // MIOSIO 
 
     // Ethernet
 
@@ -56,6 +64,7 @@ module megasoc_chip_pads(
 
 );
 
+// QSPI
 wire [3:0]   QSPI_IO_o;
 wire [3:0]   QSPI_IO_i;
 wire [3:0]   QSPI_IO_e;
@@ -70,19 +79,41 @@ assign QSPI_IO_i[1] = QSPI_IO[1];
 assign QSPI_IO_i[2] = QSPI_IO[2];
 assign QSPI_IO_i[3] = QSPI_IO[3];
 
+// FT1248 
+wire        FT_MIOSIO_O;
+wire        FT_MIOSIO_E;
+wire        FT_MIOSIO_Z;
+wire        FT_MIOSIO_I;
+
+assign FT_MIOSIO = FT_MIOSIO_E ? FT_MIOSIO_O : 1'bz;
+
+assign FT_MIOSIO_I = FT_MIOSIO;
+
 assign REF_CLK_XTAL2 = REF_CLK_XTAL1;
+assign RT_CLK_XTAL2 = RT_CLK_XTAL1;
 
 megasoc_chip u_megasoc_chip(
     .CLK_IN(REF_CLK_XTAL1),
+    .RT_CLK(RT_CLK_XTAL1),
     .nRESET(PORESTn),
     .QSPI_SCLK(QSPI_SCLK),
     .QSPI_nCS(QSPI_nCS),
     .QSPI_IO_o(QSPI_IO_o),
     .QSPI_IO_i(QSPI_IO_i),
     .QSPI_IO_e(QSPI_IO_e),
+
     .UARTRXD(),
     .UARTTXD(),
     .UARTTXEN(),
+
+    .FT_CLK_O(FT_CLK),
+    .FT_SSN_O(FT_SSN),
+    .FT_MISO_I(FT_MISO),
+    .FT_MIOSIO_O(FT_MIOSIO_O),
+    .FT_MIOSIO_E(FT_MIOSIO_E),
+    .FT_MIOSIO_Z(FT_MIOSIO_Z),
+    .FT_MIOSIO_I(FT_MIOSIO_I),
+
     .nTRST(),
     .SWCLKTCK(),
     .SWDITMS(),
diff --git a/megasoc_system/logical/megasoc_system.v b/megasoc_system/logical/megasoc_system.v
index 31bc96365ca48e7e81c81d28048bf468a3e205a8..8e9b6f9c32f1e9184f2289a87540c588f13dd404 100644
--- a/megasoc_system/logical/megasoc_system.v
+++ b/megasoc_system/logical/megasoc_system.v
@@ -14,8 +14,9 @@
 
 `include "gen_defines.v"
 module megasoc_system(
-    input wire          CLK_IN,
-    input wire          nRESET,
+    input  wire         CLK_IN,
+    input  wire         RT_CLK, // 32kHz real time clock
+    input  wire         nRESET,
 
     // QSPI Signals
     output wire         QSPI_SCLK,
@@ -29,6 +30,15 @@ module megasoc_system(
     output wire         UARTTXD,
     output wire         UARTTXEN,
 
+    // FT1248 Signals
+    output wire         FT_CLK_O,    // SCLK
+    output wire         FT_SSN_O,    // SS_N
+    input  wire         FT_MISO_I,   // MISO
+    output wire         FT_MIOSIO_O, // MIOSIO tristate output when enabled
+    output wire         FT_MIOSIO_E, // MIOSIO tristate output enable (active hi)
+    output wire         FT_MIOSIO_Z, // MIOSIO tristate output enable (active lo)
+    input  wire         FT_MIOSIO_I, // MIOSIO tristate input
+
     // DAP-LITE external signals
     input  wire         nTRST,
     input  wire         SWCLKTCK,
@@ -42,6 +52,64 @@ module megasoc_system(
 
 );
 
+
+// DMA 350 APB Interface Wires
+wire [31:0]         PADDR_DMA_CTRL;
+wire [31:0]         PWDATA_DMA_CTRL;
+wire                PWRITE_DMA_CTRL;
+wire [2:0]          PPROT_DMA_CTRL;
+wire [3:0]          PSTRB_DMA_CTRL;
+wire                PENABLE_DMA_CTRL;
+wire                PSELx_DMA_CTRL;
+wire [31:0]         PRDATA_DMA_CTRL;
+wire                PSLVERR_DMA_CTRL;
+wire                PREADY_DMA_CTRL;
+
+// DMA 350 AXI Interface Wires
+wire [1:0]          AWID_DMA350;
+wire [43:0]         AWADDR_DMA350;
+wire [7:0]          AWLEN_DMA350;
+wire [2:0]          AWSIZE_DMA350;
+wire [1:0]          AWBURST_DMA350;
+wire                AWLOCK_DMA350;
+wire [3:0]          AWCACHE_DMA350;
+wire [2:0]          AWPROT_DMA350;
+wire                AWVALID_DMA350;
+wire                AWREADY_DMA350;
+
+wire [127:0]        WDATA_DMA350;
+wire [15:0]         WSTRB_DMA350;
+wire                WLAST_DMA350;
+wire                WVALID_DMA350;
+wire                WREADY_DMA350;
+
+wire [1:0]          BID_DMA350;
+wire [1:0]          BRESP_DMA350;
+wire                BVALID_DMA350;
+wire                BREADY_DMA350;
+
+wire [1:0]          ARID_DMA350;
+wire [43:0]         ARADDR_DMA350;
+wire [7:0]          ARLEN_DMA350;
+wire [2:0]          ARSIZE_DMA350;
+wire [1:0]          ARBURST_DMA350;
+wire                ARLOCK_DMA350;
+wire [3:0]          ARCACHE_DMA350;
+wire [2:0]          ARPROT_DMA350;
+wire                ARVALID_DMA350;
+wire                ARREADY_DMA350;
+
+wire [1:0]          RID_DMA350;
+wire [127:0]        RDATA_DMA350;
+wire [1:0]          RRESP_DMA350;
+wire                RLAST_DMA350;
+wire                RVALID_DMA350;
+wire                RREADY_DMA350;
+
+wire [3:0]              DMA350_irq_channel;
+wire                    DMA350_irq_comb_nonsec;
+
+
 wire [1:0]      AXI_SYS_EXP_awid;
 wire [31:0]     AXI_SYS_EXP_awaddr;
 wire [7:0]      AXI_SYS_EXP_awlen;
@@ -117,6 +185,7 @@ wire            AXI_EXP_SYS_rready;
 megasoc_tech_wrapper u_megasoc_tech_wrapper(
     .SYS_CLK(CLK_IN),
     .SYS_CLKEN(1'b1),
+    .RT_CLK(RT_CLK),
     .SYS_RESETn(nRESET),
 
     // Millisoc system AXI Manager
@@ -193,6 +262,58 @@ megasoc_tech_wrapper u_megasoc_tech_wrapper(
     .AXI_EXP_SYS_rlast(AXI_EXP_SYS_rlast),
     .AXI_EXP_SYS_rvalid(AXI_EXP_SYS_rvalid),
     .AXI_EXP_SYS_rready(AXI_EXP_SYS_rready),
+
+
+    .PADDR_DMA_CTRL(PADDR_DMA_CTRL),
+    .PWDATA_DMA_CTRL(PWDATA_DMA_CTRL),
+    .PWRITE_DMA_CTRL(PWRITE_DMA_CTRL),
+    .PPROT_DMA_CTRL(PPROT_DMA_CTRL),
+    .PSTRB_DMA_CTRL(PSTRB_DMA_CTRL),
+    .PENABLE_DMA_CTRL(PENABLE_DMA_CTRL),
+    .PSELx_DMA_CTRL(PSELx_DMA_CTRL),
+    .PRDATA_DMA_CTRL(PRDATA_DMA_CTRL),
+    .PSLVERR_DMA_CTRL(PSLVERR_DMA_CTRL),
+    .PREADY_DMA_CTRL(PREADY_DMA_CTRL),
+
+    .AWID_DMA350(AWID_DMA350),
+    .AWADDR_DMA350(AWADDR_DMA350),
+    .AWLEN_DMA350(AWLEN_DMA350),
+    .AWSIZE_DMA350(AWSIZE_DMA350),
+    .AWBURST_DMA350(AWBURST_DMA350),
+    .AWLOCK_DMA350(AWLOCK_DMA350),
+    .AWCACHE_DMA350(AWCACHE_DMA350),
+    .AWPROT_DMA350(AWPROT_DMA350),
+    .AWVALID_DMA350(AWVALID_DMA350),
+    .AWREADY_DMA350(AWREADY_DMA350),
+    .WDATA_DMA350(WDATA_DMA350),
+    .WSTRB_DMA350(WSTRB_DMA350),
+    .WLAST_DMA350(WLAST_DMA350),
+    .WVALID_DMA350(WVALID_DMA350),
+    .WREADY_DMA350(WREADY_DMA350),
+    .BID_DMA350(BID_DMA350),
+    .BRESP_DMA350(BRESP_DMA350),
+    .BVALID_DMA350(BVALID_DMA350),
+    .BREADY_DMA350(BREADY_DMA350),
+    .ARID_DMA350(ARID_DMA350),
+    .ARADDR_DMA350(ARADDR_DMA350),
+    .ARLEN_DMA350(ARLEN_DMA350),
+    .ARSIZE_DMA350(ARSIZE_DMA350),
+    .ARBURST_DMA350(ARBURST_DMA350),
+    .ARLOCK_DMA350(ARLOCK_DMA350),
+    .ARCACHE_DMA350(ARCACHE_DMA350),
+    .ARPROT_DMA350(ARPROT_DMA350),
+    .ARVALID_DMA350(ARVALID_DMA350),
+    .ARREADY_DMA350(ARREADY_DMA350),
+    .RID_DMA350(RID_DMA350),
+    .RDATA_DMA350(RDATA_DMA350),
+    .RRESP_DMA350(RRESP_DMA350),
+    .RLAST_DMA350(RLAST_DMA350),
+    .RVALID_DMA350(RVALID_DMA350),
+    .RREADY_DMA350(RREADY_DMA350),
+
+    .DMA350_irq_channel(DMA350_irq_channel),
+    .DMA350_irq_comb_nonsec(DMA350_irq_comb_nonsec),
+
     .QSPI_SCLK(QSPI_SCLK),
     .QSPI_nCS(QSPI_nCS),
     .QSPI_IO_o(QSPI_IO_o),
@@ -201,6 +322,15 @@ megasoc_tech_wrapper u_megasoc_tech_wrapper(
     .UARTRXD(UARTRXD),
     .UARTTXD(UARTTXD),
     .UARTTXEN(UARTTXEN),
+
+    .FT_CLK_O(FT_CLK_O),
+    .FT_SSN_O(FT_SSN_O),
+    .FT_MISO_I(FT_MISO_I),
+    .FT_MIOSIO_O(FT_MIOSIO_O),
+    .FT_MIOSIO_E(FT_MIOSIO_E),
+    .FT_MIOSIO_Z(FT_MIOSIO_Z),
+    .FT_MIOSIO_I(FT_MIOSIO_I),
+    
     .nTRST(nTRST),
     .SWCLKTCK(SWCLKTCK),
     .SWDITMS(SWDITMS),
@@ -211,6 +341,76 @@ megasoc_tech_wrapper u_megasoc_tech_wrapper(
     .SWDOEN(SWDOEN)
 );
 
+
+megasoc_tech_system_wrapper u_megasoc_tech_system_wrapper(
+    .CLK(CLK_IN),
+    .RESETn(nRESET),
+
+    .DMA350_PWAKEUP(1'b1),
+    .DMA350_PDEBUG(1'b0),
+    .DMA350_PSEL(PSELx_DMA_CTRL),
+    .DMA350_PENABLE(PENABLE_DMA_CTRL),
+    .DMA350_PPROT(PPROT_DMA_CTRL),
+    .DMA350_PWRITE(PWRITE_DMA_CTRL),
+    .DMA350_PADDR(PADDR_DMA_CTRL),
+    .DMA350_PWDATA(PWDATA_DMA_CTRL),
+    .DMA350_PSTRB(PSTRB_DMA_CTRL),
+    .DMA350_PREADY(PREADY_DMA_CTRL),
+    .DMA350_PSLVERR(PSLVERR_DMA_CTRL),
+    .DMA350_PRDATA(PRDATA_DMA_CTRL),
+
+    .DMA350_AWAKEUP_M0(),
+    .DMA350_AWVALID_M0(AWVALID_DMA350),
+    .DMA350_AWADDR_M0(AWADDR_DMA350),
+    .DMA350_AWBURST_M0(AWBURST_DMA350),
+    .DMA350_AWID_M0(AWID_DMA350),
+    .DMA350_AWLEN_M0(AWLEN_DMA350),
+    .DMA350_AWSIZE_M0(AWSIZE_DMA350),
+    .DMA350_AWQOS_M0(),
+    .DMA350_AWPROT_M0(AWPROT_DMA350),
+    .DMA350_AWREADY_M0(AWREADY_DMA350),
+    .DMA350_AWCACHE_M0(AWCACHE_DMA350),
+    .DMA350_AWINNER_M0(),
+    .DMA350_AWDOMAIN_M0(),
+
+    .DMA350_ARVALID_M0(ARVALID_DMA350),
+    .DMA350_ARADDR_M0(ARADDR_DMA350),
+    .DMA350_ARBURST_M0(ARBURST_DMA350),
+    .DMA350_ARID_M0(ARID_DMA350),
+    .DMA350_ARLEN_M0(ARLEN_DMA350),
+    .DMA350_ARSIZE_M0(ARSIZE_DMA350),
+    .DMA350_ARQOS_M0(),
+    .DMA350_ARPROT_M0(ARPROT_DMA350),
+    .DMA350_ARREADY_M0(ARREADY_DMA350),
+    .DMA350_ARCACHE_M0(ARCACHE_DMA350),
+    .DMA350_ARINNER_M0(),
+    .DMA350_ARDOMAIN_M0(),
+    .DMA350_ARCMDLINK_M0(),
+
+    .DMA350_WVALID_M0(WVALID_DMA350),
+    .DMA350_WLAST_M0(WLAST_DMA350),
+    .DMA350_WSTRB_M0(WSTRB_DMA350),
+    .DMA350_WDATA_M0(WDATA_DMA350),
+    .DMA350_WREADY_M0(WREADY_DMA350),
+
+    .DMA350_RVALID_M0(RVALID_DMA350),
+    .DMA350_RID_M0(RID_DMA350),
+    .DMA350_RLAST_M0(RLAST_DMA350),
+    .DMA350_RDATA_M0(RDATA_DMA350),
+    .DMA350_RPOISON_M0(2'b00),
+    .DMA350_RRESP_M0(RRESP_DMA350),
+    .DMA350_RREADY_M0(RREADY_DMA350),
+
+    .DMA350_BVALID_M0(BVALID_DMA350),
+    .DMA350_BID_M0(BID_DMA350),
+    .DMA350_BRESP_M0(BRESP_DMA350),
+    .DMA350_BREADY_M0(BREADY_DMA350),
+
+    .DMA350_irq_channel(DMA350_irq_channel),
+    .DMA350_irq_comb_nonsec(DMA350_irq_comb_nonsec)
+);
+
+
 `ifdef INC_EXP
 expansion_subsystem_wrapper u_megasoc_expansion_wrapper(
     .sys_clk(),
diff --git a/megasoc_tech b/megasoc_tech
index 13691c8c10cb58199dc78da621b29d58b8b732de..43c6ae6ac778989b0ea09101aea347d7c460729a 160000
--- a/megasoc_tech
+++ b/megasoc_tech
@@ -1 +1 @@
-Subproject commit 13691c8c10cb58199dc78da621b29d58b8b732de
+Subproject commit 43c6ae6ac778989b0ea09101aea347d7c460729a
diff --git a/verif/control/logical/megasoc_clkreset.v b/verif/control/logical/megasoc_clkreset.v
index a26ac6258e5b512fc685a2e7f2fa55c08ba458b8..b59515b9b6221717e68335cf00a174e0b01c743d 100644
--- a/verif/control/logical/megasoc_clkreset.v
+++ b/verif/control/logical/megasoc_clkreset.v
@@ -38,6 +38,7 @@
 
 module megasoc_clkreset(
   output wire CLK,
+  output wire CLK_RT,
   output wire NRST,
   output wire NRST_early,
   output wire NRST_late,
@@ -45,20 +46,28 @@ module megasoc_clkreset(
   );
 
   reg clock_q;
+  reg clock_rt;
 
   reg [15:0] shifter;
   
   initial
     begin
       clock_q   <= 1'b0;
+      clock_rt  <= 1'b0;
       shifter   <= 16'h0000;
       #40 clock_q <= 1'b1;
+      clock_rt <= 1'b1;
     end
 
-  always @(clock_q)
+  always @(clock_q) 
       #5 clock_q <= !clock_q;  // 10ns period, 100MHz
+  
+
+  always @(clock_rt)
+      #15259 clock_rt <= !clock_rt; // nearly 32.678 KHz
 
   assign CLK = clock_q;
+  assign CLK_RT = clock_rt;
 
   always @(posedge clock_q)
     if (! (&shifter)) // until full...
diff --git a/verif/testbench/logical/megasoc_tb.sv b/verif/testbench/logical/megasoc_tb.sv
index cb592f7c076cca95fe52e06f776760d7feaf4dce..587e68d7b26c2a73ccb85f22944679a82ac2b8fd 100644
--- a/verif/testbench/logical/megasoc_tb.sv
+++ b/verif/testbench/logical/megasoc_tb.sv
@@ -17,15 +17,29 @@ module megasoc_tb();
 `define CORTEXA53_UNIVENT_DPI_CAPTURE
 `define CORTEXA53_UNIVENT 
 
-wire EXT_CLK;
+wire EXT_CLK; // 100 MHz crystal clock 
+wire RT_CLK; // 32.768 kHz crystal clock
 wire nRESET;
 
 wire         QSPI_SCLK;
 wire [3:0]   QSPI_IO;
 wire         QSPI_nCS;
+wire         FT_CLK;   
+wire         FT_SSN;   
+wire         FT_MISO;  
+wire         FT_MIOSIO;
+
+wire        ft_miosio_i;
+wire        ft_miosio_o;
+wire        ft_miosio_z;
+
+assign ft_miosio_i = FT_MIOSIO;
+bufif1 #1 (FT_MIOSIO, ft_miosio_o, !ft_miosio_z);
+
 
 megasoc_clkreset u_megasoc_clkreset(
     .CLK(EXT_CLK),
+    .CLK_RT(RT_CLK),
     .NRST(nRESET)
 );
 
@@ -43,6 +57,8 @@ end
 megasoc_chip_pads u_megasoc_chip_pads(
     .REF_CLK_XTAL1(EXT_CLK),
     .REF_CLK_XTAL2(),
+    .RT_CLK_XTAL1(RT_CLK),
+    .RT_CLK_XTAL2(),
     .PORESTn(nRESET),
     .nSRST(nRESET),
     .GPIO_P0(),
@@ -60,7 +76,11 @@ megasoc_chip_pads u_megasoc_chip_pads(
     .DBGACK(),
     .QSPI_SCLK(QSPI_SCLK),
     .QSPI_IO(QSPI_IO),
-    .QSPI_nCS(QSPI_nCS)
+    .QSPI_nCS(QSPI_nCS),
+    .FT_CLK(FT_CLK),
+    .FT_SSN(FT_SSN),
+    .FT_MISO(FT_MISO),
+    .FT_MIOSIO(FT_MIOSIO)
 );
 
 sst26vf064b FLASH(
@@ -138,4 +158,68 @@ megasoc_qspi_capture #(
     .HRESP_o(`MEGASOC_QSPI_SUBSYSTEM.HRESP)
 );
 
+
+wire rxd8_tvalid;
+wire rxd8_tready;
+wire[7:0] rxd8_tdata;
+
+megasoc_ft1248x1_to_axi_streamio_v1_0 u_ft1248_to_axi_stream(
+    .ft_clk_i(FT_CLK),
+    .ft_ssn_i(FT_SSN),
+    .ft_miso_o(FT_MISO),
+    .ft_miosio_i(ft_miosio_i),
+    .ft_miosio_o(ft_miosio_o),
+    .ft_miosio_z(ft_miosio_z),
+    .aclk(EXT_CLK),
+    .aresetn(nRESET),
+    .txd_tvalid_o(rxd8_tvalid),
+    .txd_tdata8_o(rxd8_tdata),
+    .txd_tready_i(rxd8_tready),
+    .rxd_tready_o(),
+    .rxd_tdata8_i(8'h00),
+    .rxd_tvalid_i(1'b0)
+);
+
+
+megasoc_axi_stream_io_8_rxd_to_file#(
+    .RXDFILENAME("logs/ft1248_out.log")
+) u_megasoc_axi_stream_io_8_rxd_to_file (
+    .aclk         (EXT_CLK),
+    .aresetn      (nRESET),
+    .eof_received ( ),
+    .rxd8_ready   (rxd8_tready),
+    .rxd8_valid   (rxd8_tvalid),
+    .rxd8_data    (rxd8_tdata)
+  );
+
+
+wire ft_clk2uart;
+wire ft_rxd2uart;
+wire ft_txd2uart;
+
+megasoc_ft1248x1_track
+  u_megasoc_ft1248x1_track
+  (
+  .ft_clk_i     (FT_CLK),
+  .ft_ssn_i     (FT_SSN),
+  .ft_miso_i    (FT_MISO),
+  .ft_miosio_i  (ft_miosio_i),
+  .aclk         (EXT_CLK),
+  .aresetn      (nRESET),
+  .FTDI_CLK2UART_o      (ft_clk2uart),  // Clock (baud rate)
+  .FTDI_OP2UART_o       (ft_rxd2uart),  // Received data to UART capture
+  .FTDI_IP2UART_o       (ft_txd2uart)   // Transmitted data to UART capture
+  );
+
+  megasoc_uart_capture  #(.LOGFILENAME("logs/ft1248_op.log"), .VERBOSE(1))
+    u_megasoc_uart_capture1(
+    .RESETn               (nRESET),
+    .CLK                  (ft_clk2uart),
+    .RXD                  (ft_rxd2uart),
+    .DEBUG_TESTER_ENABLE  ( ), //debug_test_en2), //driven by u_nanosoc_track_tb_iostream
+    .SIMULATIONEND        (),      // This signal set to 1 at the end of simulation.
+    .AUXCTRL              ()
+  );
+
+
 endmodule
diff --git a/verif/trace/megasoc_axi_stream_io_8_rxd_to_file.v b/verif/trace/megasoc_axi_stream_io_8_rxd_to_file.v
new file mode 100644
index 0000000000000000000000000000000000000000..cdff4c0b647f32ca8a591551bef93e092723ea3a
--- /dev/null
+++ b/verif/trace/megasoc_axi_stream_io_8_rxd_to_file.v
@@ -0,0 +1,81 @@
+//-----------------------------------------------------------------------------
+// customised example Cortex-M0 controller UART with file logging
+// A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license.
+//
+// Contributors
+//
+// David Flynn (d.w.flynn@soton.ac.uk)
+//
+// Copyright (C) 2023, SoC Labs (www.soclabs.org)
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Abstract : FT1248 1-bit data off-chip interface (emulate FT232H device)
+// and allows cmsdk_uart_capture testbench models to log ADP ip, op streams
+//-----------------------------------------------------------------------------
+
+
+module megasoc_axi_stream_io_8_rxd_to_file
+  #(parameter RXDFILENAME = "rxd.log",
+    parameter VERBOSE = 0)
+  (
+  input  wire       aclk,
+  input  wire       aresetn,
+  output wire       eof_received,
+  output wire       rxd8_ready,
+  input  wire       rxd8_valid,
+  input  wire [7:0] rxd8_data
+  );
+
+ //----------------------------------------------
+ //-- File I/O
+ //----------------------------------------------
+
+
+   integer        fd;       // channel descriptor for cmd file input
+   integer        ch;
+`define EOF -1
+
+   reg       ready;
+   reg [7:0] data8;
+   
+   reg       nxt_end_simulation;
+   reg       reg_end_simulation;
+
+assign eof_received = nxt_end_simulation;
+
+   initial
+     begin
+       ready <= 0;
+       nxt_end_simulation <= 1'b0;
+       reg_end_simulation <= 1'b0;
+       fd= $fopen(RXDFILENAME,"w");
+       if (fd == 0)
+          $write("** %m : output log file failed to open **\n");
+       else begin
+         @(posedge aresetn);
+         while (!nxt_end_simulation) begin
+           @(posedge aclk);
+           ready <= 1'b1;
+           @(posedge aclk);
+           while (rxd8_valid == 1'b0)
+             @(posedge aclk);
+           ready <=0;
+           data8 <= rxd8_data;
+           ch = (rxd8_data & 8'hff);
+           if  (ch==8'h04) // Stop simulation if 0x04 is received
+             nxt_end_simulation <= 1'b1;
+           else begin
+             $fwrite(fd, "%c", ch);
+             if (VERBOSE) $write("%c", ch);
+             end
+         end
+         $write("** %m : log file closed after stream RX terminated **\n");
+         $fclose(fd);
+         ready <= 0;
+       end
+     end
+
+assign rxd8_ready = ready ;
+
+endmodule
diff --git a/verif/trace/megasoc_ft1248x1_track.v b/verif/trace/megasoc_ft1248x1_track.v
new file mode 100644
index 0000000000000000000000000000000000000000..a6f3091e90d7481eadb85019d5f3fa3d0a542aec
--- /dev/null
+++ b/verif/trace/megasoc_ft1248x1_track.v
@@ -0,0 +1,125 @@
+//-----------------------------------------------------------------------------
+// FT1248 1-bit-data to 8-bit AXI-Stream IO
+// A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license.
+//
+// Contributors
+//
+// David Flynn (d.w.flynn@soton.ac.uk)
+//
+// Copyright (C) 2022-3, SoC Labs (www.soclabs.org)
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Abstract : FT1248 1-bit data off-chip interface (emulate FT232H device)
+//-----------------------------------------------------------------------------
+
+ module megasoc_ft1248x1_track
+  (
+  input  wire  ft_clk_i,         // SCLK
+  input  wire  ft_ssn_i,         // SS_N
+  input  wire  ft_miso_i,        // MISO
+  input  wire  ft_miosio_i,       // MIOSIO tristate signal input
+
+  input  wire  aclk,             // external primary clock
+  input  wire  aresetn,          // external reset (active low)
+  
+  output wire  FTDI_CLK2UART_o, // Clock (baud rate)
+  output wire  FTDI_OP2UART_o, // Received data to UART capture
+  output wire  FTDI_IP2UART_o  // Transmitted data to UART capture
+  );
+
+//wire ft_clk;
+wire ft_clk_rising;
+wire ft_clk_falling;
+
+wire ft_ssn;
+wire ft_miosio_i_del;
+
+SYNCHRONIZER_EDGES u_sync_ft_clk (
+	.testmode_i(1'b0),
+	.clk_i(aclk),
+	.reset_n_i(aresetn),
+	.asyn_i(ft_clk_i),
+	.syn_o(),
+	.syn_del_o(),
+	.posedge_o(ft_clk_rising),
+	.negedge_o(ft_clk_falling)
+	);
+
+SYNCHRONIZER_EDGES u_sync_ft_ssn (
+	.testmode_i(1'b0),
+	.clk_i(aclk),
+	.reset_n_i(aresetn),
+	.asyn_i(ft_ssn_i),
+	.syn_o(ft_ssn),
+	.syn_del_o(),
+	.posedge_o( ),
+	.negedge_o( )
+	);
+
+SYNCHRONIZER_EDGES u_sync_ft_din (
+	.testmode_i(1'b0),
+	.clk_i(aclk),
+	.reset_n_i(aresetn),
+	.asyn_i(ft_miosio_i),
+	.syn_o( ),
+	.syn_del_o(ft_miosio_i_del),
+	.posedge_o( ),
+	.negedge_o( )
+	);
+
+//----------------------------------------------
+//-- FT1248 1-bit protocol State Machine
+//----------------------------------------------
+
+reg [4:0] ft_state; // 17-state for bit-serial
+wire [4:0] ft_nextstate = ft_state + 5'b00001;
+
+// advance state count on rising edge of ft_clk
+always @(posedge aclk or negedge aresetn)
+  if (!aresetn)
+    ft_state <= 5'b11111;  
+  else if (ft_ssn) // sync reset
+    ft_state <= 5'b11111;
+  else if (ft_clk_rising) // loop if multi-data
+//    ft_state <= (ft_state == 5'b01111) ? 5'b01000 : ft_nextstate;
+    ft_state <= ft_nextstate;
+
+// 16: bus turnaround (or bit[5])
+// 0 for CMD3
+// 3 for CMD2
+// 5 for CMD1
+// 6 for CMD0
+// 7 for cmd turnaround
+// 8 for data bit0
+// 9 for data bit1
+// 10 for data bit2
+// 11 for data bit3
+// 12 for data bit4
+// 13 for data bit5
+// 14 for data bit6
+// 15 for data bit7
+
+// capture 7-bit CMD on falling edge of clock (mid-data)
+reg [7:0] ft_cmd;
+// - valid sample ready after 7th edge (ready RX or TX data phase functionality)
+always @(posedge aclk or negedge aresetn)
+  if (!aresetn)
+    ft_cmd <= 8'b00000001;
+  else if (ft_ssn) // sync reset
+    ft_cmd <= 8'b00000001;
+  else if (ft_clk_falling & !ft_state[3] & !ft_nextstate[3]) // on shift if CMD phase)
+    ft_cmd <= {ft_cmd[6:0],ft_miosio_i};
+
+wire ft_cmd_valid = ft_cmd[7];
+wire ft_cmd_rxd =  ft_cmd[7] & !ft_cmd[6] & !ft_cmd[3] & !ft_cmd[1] &  ft_cmd[0];
+wire ft_cmd_txd =  ft_cmd[7] & !ft_cmd[6] & !ft_cmd[3] & !ft_cmd[1] & !ft_cmd[0];
+
+// serial data formatted with start bit for UART capture (on rising uart-clock)
+assign   FTDI_CLK2UART_o = !ft_clk_i;
+// suitable for CMSDK UART capture IO
+// inject a start bit low else mark high
+assign FTDI_OP2UART_o = (ft_cmd_txd & (ft_state[4:3]) == 2'b01) ? ft_miosio_i_del : !(ft_cmd_txd & (ft_state == 5'b00111)); 
+assign FTDI_IP2UART_o = (ft_cmd_rxd & (ft_state[4:3]) == 2'b01) ? ft_miosio_i     : !(ft_cmd_rxd & (ft_state == 5'b00111));
+
+endmodule
diff --git a/verif/trace/megasoc_ft1248x4_to_axi_streamio_v1_0.v b/verif/trace/megasoc_ft1248x4_to_axi_streamio_v1_0.v
new file mode 100644
index 0000000000000000000000000000000000000000..159775bbc3cfd6e79ee039bd6fa67169de65bbe3
--- /dev/null
+++ b/verif/trace/megasoc_ft1248x4_to_axi_streamio_v1_0.v
@@ -0,0 +1,214 @@
+//-----------------------------------------------------------------------------
+// FT1248 1-bit-data to 8-bit AXI-Stream IO
+// A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license.
+//
+// Contributors
+//
+// David Flynn (d.w.flynn@soton.ac.uk)
+//
+// Copyright (C) 2022-3, SoC Labs (www.soclabs.org)
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Abstract : FT1248 1-bit data off-chip interface (emulate FT232H device)
+//-----------------------------------------------------------------------------
+
+ module megasoc_ft1248x1_to_axi_streamio_v1_0 #
+ (
+         // Users to add parameters here
+
+         // User parameters ends
+         // Do not modify the parameters beyond this line
+
+
+         // Parameters of Axi Stream Bus Interface rxd8
+         parameter integer C_rxd8_TDATA_WIDTH    = 8,
+
+         // Parameters of Axi Stream Bus Interface txd8
+         parameter integer C_txd8_TDATA_WIDTH    = 8
+ )
+  (
+  input  wire  ft_clk_i,         // SCLK
+  input  wire  ft_ssn_i,         // SS_N
+  output wire  ft_miso_o,        // MISO
+//  inout  wire  ft_miosio_io,   // MIOSIO tristate output control
+  input  wire ft_miosio_i,
+  output wire ft_miosio_o,
+  output wire ft_miosio_z,
+
+  input  wire  aclk,             // external primary clock
+  input  wire  aresetn,          // external reset (active low)
+  
+  // Ports of Axi stream Bus Interface TXD
+  output wire  txd_tvalid_o,
+  output wire [7 : 0] txd_tdata8_o,
+  input  wire  txd_tready_i,
+
+  // Ports of Axi stream Bus Interface RXD
+  output wire  rxd_tready_o,
+  input  wire [7 : 0] rxd_tdata8_i,
+  input  wire  rxd_tvalid_i
+
+  );
+
+//wire ft_clk;
+wire ft_clk_rising;
+wire ft_clk_falling;
+
+wire ft_ssn;
+wire ft_miosio_i_del;
+
+SYNCHRONIZER_EDGES u_sync_ft_clk (
+	.testmode_i(1'b0),
+	.clk_i(aclk),
+	.reset_n_i(aresetn),
+	.asyn_i(ft_clk_i),
+	.syn_o(),
+	.syn_del_o(),
+	.posedge_o(ft_clk_rising),
+	.negedge_o(ft_clk_falling)
+	);
+
+SYNCHRONIZER_EDGES u_sync_ft_ssn (
+	.testmode_i(1'b0),
+	.clk_i(aclk),
+	.reset_n_i(aresetn),
+	.asyn_i(ft_ssn_i),
+	.syn_o(ft_ssn),
+	.syn_del_o(),
+	.posedge_o( ),
+	.negedge_o( )
+	);
+
+SYNCHRONIZER_EDGES u_sync_ft_din (
+	.testmode_i(1'b0),
+	.clk_i(aclk),
+	.reset_n_i(aresetn),
+	.asyn_i(ft_miosio_i),
+	.syn_o( ),
+	.syn_del_o(ft_miosio_i_del),
+	.posedge_o( ),
+	.negedge_o( )
+	);
+
+//----------------------------------------------
+//-- FT1248 1-bit protocol State Machine
+//----------------------------------------------
+
+reg [4:0] ft_state; // 17-state for bit-serial
+wire [4:0] ft_nextstate = ft_state + 5'b00001;
+
+// advance state count on rising edge of ft_clk
+always @(posedge aclk or negedge aresetn)
+  if (!aresetn)
+    ft_state <= 5'b11111;  
+  else if (ft_ssn) // sync reset
+    ft_state <= 5'b11111;
+  else if (ft_clk_rising) // loop if multi-data
+//    ft_state <= (ft_state == 5'b01111) ? 5'b01000 : ft_nextstate;
+    ft_state <= ft_nextstate;
+
+// 16: bus turnaround (or bit[5])
+// 0 for CMD3
+// 3 for CMD2
+// 5 for CMD1
+// 6 for CMD0
+// 7 for cmd turnaround
+// 8 for data bit0
+// 9 for data bit1
+// 10 for data bit2
+// 11 for data bit3
+// 12 for data bit4
+// 13 for data bit5
+// 14 for data bit6
+// 15 for data bit7
+
+// capture 7-bit CMD on falling edge of clock (mid-data)
+reg [7:0] ft_cmd;
+// - valid sample ready after 7th edge (ready RX or TX data phase functionality)
+always @(posedge aclk or negedge aresetn)
+  if (!aresetn)
+    ft_cmd <= 8'b00000001;
+  else if (ft_ssn) // sync reset
+    ft_cmd <= 8'b00000001;
+  else if (ft_clk_falling & !ft_state[3] & !ft_nextstate[3]) // on shift if CMD phase)
+    ft_cmd <= {ft_cmd[6:0],ft_miosio_i};
+
+wire ft_cmd_valid = ft_cmd[7];
+wire ft_cmd_rxd =  ft_cmd[7] & !ft_cmd[6] & !ft_cmd[3] & !ft_cmd[1] &  ft_cmd[0];
+wire ft_cmd_txd =  ft_cmd[7] & !ft_cmd[6] & !ft_cmd[3] & !ft_cmd[1] & !ft_cmd[0];
+
+// tristate enable for miosio (deselected status or serialized data for read command)
+wire   ft_miosio_e = ft_ssn_i | (ft_cmd_rxd & !ft_state[4] & ft_state[3]);
+assign ft_miosio_z = !ft_miosio_e;
+
+// capture (ft_cmd_txd) serial data out on falling edge of clock
+// bit [0] indicated byte valid
+reg [7:0] rxd_sr;
+always @(posedge aclk or negedge aresetn)
+  if (!aresetn)
+    rxd_sr <= 8'b00000000;
+  else if (ft_ssn) // sync reset
+    rxd_sr <= 8'b00000000;
+  else if (ft_clk_falling & ft_cmd_txd & (ft_state[4:3] == 2'b01))  //serial shift
+    rxd_sr <= {ft_miosio_i_del, rxd_sr[7:1]};
+   
+// AXI STREAM handshake interfaces
+// TX stream delivers valid FT1248 read data transfer
+// 8-bit write port with extra top-bit used as valid qualifer
+reg [8:0] txstream;
+always @(posedge aclk or negedge aresetn)
+  if (!aresetn)
+    txstream <= 9'b000000000;
+  else if (txstream[8] & txd_tready_i) // priority clear stream data valid when accepted
+    txstream[8] <= 1'b0;
+  else if (ft_clk_falling & ft_cmd_txd & (ft_state==5'b01111))  //load as last shift arrives
+    txstream[8:0] <= {1'b1, ft_miosio_i_del, rxd_sr[7:1]};
+
+assign txd_tvalid_o = txstream[8];
+assign txd_tdata8_o = txstream[7:0];
+
+
+// AXI STREAM handshake interfaces
+// RX stream accepts 8-bit data to transfer over FT1248 channel
+// 8-bit write port with extra top-bit used as valid qualifer
+
+reg [8:0] rxstream;
+reg rxstream_valid;
+always @(posedge aclk or negedge aresetn)
+  if (!aresetn) begin
+    rxstream <= 9'b000000000;
+    rxstream_valid <= 1'b0;
+  end else if (!rxstream[8] & rxd_tvalid_i) begin// if empty can accept valid RX stream data
+    rxstream_valid <= 1'b1;
+    rxstream[8:0] <= {1'b1,rxd_tdata8_i};
+  end else if (rxstream[8] & ft_clk_rising & ft_cmd_rxd &  (ft_state==5'b01110)) begin// hold until final shift completion
+    rxstream[8] <= 1'b0;
+    rxstream_valid <= 1'b0;
+  end
+assign rxd_tready_o = !rxstream[8]; // ready until loaded
+
+
+// shift TXD on rising edge of clock
+reg [8:0] txd_sr;
+// rewrite for clocked
+always @(posedge aclk or negedge aresetn)
+  if (!aresetn)
+    txd_sr <= 8'b00000000;
+  else if (ft_ssn) // sync reset
+    txd_sr <= 8'b00000000;
+  else if (ft_clk_falling & ft_cmd_rxd & rxstream_valid & (ft_state == 5'b00111))
+    txd_sr <=  rxstream[7:0];
+  else if (ft_clk_rising & ft_cmd_rxd & (ft_state[4:3] == 2'b01))  //serial shift
+    txd_sr <= {1'b0,txd_sr[7:1]};
+
+//FT1248 FIFO status signals
+
+// ft_miso_o reflects TXF when deselected
+assign ft_miosio_o =  (ft_ssn_i) ? txstream[8] : txd_sr[0];
+
+// ft_miso_o reflects RXE when deselected
+//assign ft_miso_o = (ft_ssn_i) ? !rxd_tvalid_i : ((ft_state == 5'b00111) & ((ft_cmd_txd) ? txstream[8]: !rxd_tvalid_i));
+assign ft_miso_o = (ft_ssn_i) ? !rxstream[8] : ((ft_state == 5'b00111) & ((ft_cmd_txd) ? txstream[8]: !rxstream[8]));
+
+endmodule