From d580005c018dbded722b69463a0ba0b6a560f95c Mon Sep 17 00:00:00 2001
From: dwf1m12 <d.w.flynn@soton.ac.uk>
Date: Sun, 26 Feb 2023 23:08:45 +0000
Subject: [PATCH] update testbench for ft1248 target validation and file i/o

---
 .../mcu/verilog/axi_streamio8_buffer.v        |  46 ++++
 .../mcu/verilog/axi_streamio8_rxd_to_file.v   |  76 +++++++
 .../mcu/verilog/axi_streamio8_txd_from_file.v |  71 ++++++
 .../verilog/ft1248x1_to_axi_streamio_v1_0.v   | 209 ++++++++++++++++++
 .../systems/mcu/verilog/ft1248x1_track.v      | 125 +++++++++++
 .../nanosoc/systems/mcu/verilog/tb_nanosoc.v  | 110 ++++++++-
 .../nanosoc/systems/mcu/verilog/tbench_M0.vc  |   1 +
 .../systems/mcu/verilog/track_tb_iostream.v   | 111 ++++++++++
 .../nanosoc/systems/mcu/verilog/v2html_M0.vc  |   1 +
 GLIB/sync/verilog/SYNCHRONIZER_EDGES.v        |  42 ++++
 10 files changed, 780 insertions(+), 12 deletions(-)
 create mode 100644 Cortex-M0/nanosoc/systems/mcu/verilog/axi_streamio8_buffer.v
 create mode 100644 Cortex-M0/nanosoc/systems/mcu/verilog/axi_streamio8_rxd_to_file.v
 create mode 100644 Cortex-M0/nanosoc/systems/mcu/verilog/axi_streamio8_txd_from_file.v
 create mode 100644 Cortex-M0/nanosoc/systems/mcu/verilog/ft1248x1_to_axi_streamio_v1_0.v
 create mode 100644 Cortex-M0/nanosoc/systems/mcu/verilog/ft1248x1_track.v
 create mode 100644 Cortex-M0/nanosoc/systems/mcu/verilog/track_tb_iostream.v
 create mode 100644 GLIB/sync/verilog/SYNCHRONIZER_EDGES.v

diff --git a/Cortex-M0/nanosoc/systems/mcu/verilog/axi_streamio8_buffer.v b/Cortex-M0/nanosoc/systems/mcu/verilog/axi_streamio8_buffer.v
new file mode 100644
index 0000000..8dab103
--- /dev/null
+++ b/Cortex-M0/nanosoc/systems/mcu/verilog/axi_streamio8_buffer.v
@@ -0,0 +1,46 @@
+//-----------------------------------------------------------------------------
+// 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 : axi_stream 1-stage buffer
+//-----------------------------------------------------------------------------
+
+
+module axi_streamio8_buffer
+  (
+  input  wire  aclk,
+  input  wire  aresetn,
+  output wire  rxd8_ready,
+  input  wire  rxd8_valid,
+  input  wire  [7:0] rxd8_data,
+  input  wire  txd8_ready,
+  output wire  txd8_valid,
+  output wire  [7:0] txd8_data
+  );
+
+   reg [8:0] datareg;
+   
+always @(posedge aclk or negedge aresetn)
+begin
+  if (!aresetn)
+    datareg <= 9'b0_00000000;
+  else if (!datareg[8] & rxd8_valid)
+    datareg <= {1'b1, rxd8_data};
+  else if ( datareg[8] & txd8_ready)
+    datareg[8] <= 1'b0;
+end
+
+assign rxd8_ready = !datareg[8];
+
+assign txd8_valid =  datareg[8];
+assign txd8_data  =  datareg[7:0];
+
+endmodule
diff --git a/Cortex-M0/nanosoc/systems/mcu/verilog/axi_streamio8_rxd_to_file.v b/Cortex-M0/nanosoc/systems/mcu/verilog/axi_streamio8_rxd_to_file.v
new file mode 100644
index 0000000..6ac8054
--- /dev/null
+++ b/Cortex-M0/nanosoc/systems/mcu/verilog/axi_streamio8_rxd_to_file.v
@@ -0,0 +1,76 @@
+//-----------------------------------------------------------------------------
+// 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 axi_streamio8_rxd_to_file
+  #(parameter RXDFILENAME = "rxd.log",
+    parameter VERBOSE = 0)
+  (
+  input  wire       aclk,
+  input  wire       aresetn,
+  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;
+  
+   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
+             $fwrite(fd, "%c", ch);
+         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/Cortex-M0/nanosoc/systems/mcu/verilog/axi_streamio8_txd_from_file.v b/Cortex-M0/nanosoc/systems/mcu/verilog/axi_streamio8_txd_from_file.v
new file mode 100644
index 0000000..7ec60d9
--- /dev/null
+++ b/Cortex-M0/nanosoc/systems/mcu/verilog/axi_streamio8_txd_from_file.v
@@ -0,0 +1,71 @@
+//-----------------------------------------------------------------------------
+// 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 axi_streamio8_txd_from_file
+  #(parameter TXDFILENAME = "txd.cmd",
+    parameter VERBOSE = 0)
+  (
+  input  wire  aclk,
+  input  wire  aresetn,
+  input  wire  txd8_ready,
+  output wire  txd8_valid,
+  output wire  [7:0] txd8_data
+  );
+
+
+ //----------------------------------------------
+ //-- File I/O
+ //----------------------------------------------
+
+
+   integer        fd;       // channel descriptor for cmd file input
+   integer        ch;
+`define EOF -1
+
+   reg       valid;
+   reg [7:0] data8;
+   
+   initial
+     begin
+       valid <= 0;
+//       $timeformat(-9, 0, " ns", 14);
+       fd= $fopen(TXDFILENAME,"r");
+       if (fd == 0)
+          $write("** %m : input file failed to open **\n");
+       else begin
+         @(posedge aresetn);
+         ch =  $fgetc(fd);
+         while (ch != `EOF) begin
+           @(posedge aclk);
+           data8 <= (ch & 8'hff);
+           valid <= 1'b1;
+           @(posedge aclk);
+           while (txd8_ready == 1'b0)
+             @(posedge aclk);
+           valid <=0;
+           ch =  $fgetc(fd);
+         end
+         $write("** %m : file closed after stream TX completed **\n");
+         $fclose(fd);
+         valid <= 0;
+       end
+     end
+
+assign txd8_valid = valid;
+assign txd8_data = data8;
+
+endmodule
diff --git a/Cortex-M0/nanosoc/systems/mcu/verilog/ft1248x1_to_axi_streamio_v1_0.v b/Cortex-M0/nanosoc/systems/mcu/verilog/ft1248x1_to_axi_streamio_v1_0.v
new file mode 100644
index 0000000..e09c103
--- /dev/null
+++ b/Cortex-M0/nanosoc/systems/mcu/verilog/ft1248x1_to_axi_streamio_v1_0.v
@@ -0,0 +1,209 @@
+//-----------------------------------------------------------------------------
+// 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 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;
+always @(posedge aclk or negedge aresetn)
+  if (!aresetn)
+    rxstream <= 9'b000000000;
+  else if (!rxstream[8] & rxd_tvalid_i) // if empty can accept valid RX stream data
+    rxstream[8:0] <= {1'b1,rxd_tdata8_i};
+  else if (rxstream[8] & ft_clk_rising & ft_cmd_rxd &  (ft_state==5'b01110)) // hold until final shift completion
+    rxstream[8] <= 1'b0;
+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 &  rxd_tvalid_i & (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
diff --git a/Cortex-M0/nanosoc/systems/mcu/verilog/ft1248x1_track.v b/Cortex-M0/nanosoc/systems/mcu/verilog/ft1248x1_track.v
new file mode 100644
index 0000000..ba248f8
--- /dev/null
+++ b/Cortex-M0/nanosoc/systems/mcu/verilog/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 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/Cortex-M0/nanosoc/systems/mcu/verilog/tb_nanosoc.v b/Cortex-M0/nanosoc/systems/mcu/verilog/tb_nanosoc.v
index b6fccfb..3e0e716 100644
--- a/Cortex-M0/nanosoc/systems/mcu/verilog/tb_nanosoc.v
+++ b/Cortex-M0/nanosoc/systems/mcu/verilog/tb_nanosoc.v
@@ -247,21 +247,108 @@ wire ft_miso_in;
 assign P1[0] = ft_miso_in;
 wire ft_ssn_out = P1[3];
 
-//   bufif0 (P1[2], ft_miosio_i, ft_miosio_z);
+//
+// AXI stream io testing
+//
+
+wire txd8_ready;
+wire txd8_valid;
+wire [7:0] txd8_data ;
+
+wire rxd8_ready;
+wire rxd8_valid;
+wire [7:0] rxd8_data ;
+
+axi_streamio8_txd_from_file
+  #(.TXDFILENAME("adp.cmd"))
+  u_axi_streamio8_txd_from_file
+  (
+  .aclk       (XTAL1),
+  .aresetn    (NRST),
+  .txd8_ready (txd8_ready),
+  .txd8_valid (txd8_valid),
+  .txd8_data  (txd8_data)
+  );
+
+/*
+axi_streamio8_buffer
+  u_axi_streamio8_buffer
+  (
+  .aclk       (XTAL1),
+  .aresetn    (NRST),
+  .rxd8_ready (txd8_ready),
+  .rxd8_valid (txd8_valid),
+  .rxd8_data  (txd8_data),
+  .txd8_ready (rxd8_ready),
+  .txd8_valid (rxd8_valid),
+  .txd8_data  (rxd8_data)
+  );
+*/
+
+wire ft_miosio_o;
+wire ft_miosio_z;
+wire ft_miosio_i  = P1[2]; // & ft_miosio_z;
+assign P1[2] = (ft_miosio_z) ? 1'bz : ft_miosio_o;
+
+ft1248x1_to_axi_streamio_v1_0
+  u_ft1248x1_to_axi_streamio_v1_0
+  (
+  .ft_clk_i     (ft_clk_out),
+  .ft_ssn_i     (ft_ssn_out),
+  .ft_miso_o    (ft_miso_in),
+  .ft_miosio_i  (ft_miosio_i),
+  .ft_miosio_o  (ft_miosio_o),
+  .ft_miosio_z  (ft_miosio_z),
+  .aclk         (XTAL1),
+  .aresetn      (NRST),
+  .rxd_tready_o (txd8_ready),
+  .rxd_tvalid_i (txd8_valid),
+  .rxd_tdata8_i (txd8_data),
+  .txd_tready_i (rxd8_ready),
+  .txd_tvalid_o (rxd8_valid),
+  .txd_tdata8_o (rxd8_data)
+  );
+
+axi_streamio8_rxd_to_file
+  #(.RXDFILENAME("ft1248_out.log"))
+  u_axi_streamio8_rxd_to_file
+  (
+  .aclk         (XTAL1),
+  .aresetn      (NRST),
+  .rxd8_ready   (rxd8_ready),
+  .rxd8_valid   (rxd8_valid),
+  .rxd8_data    (rxd8_data)
+  );
+
+track_tb_iostream
+  u_track_tb_iostream
+  (
+  .aclk         (XTAL1),
+  .aresetn      (NRST),
+  .rxd8_ready   (rxd8_ready),
+  .rxd8_valid   (rxd8_valid),
+  .rxd8_data    (rxd8_data),
+  .DEBUG_TESTER_ENABLE  (debug_test_en1),
+  .AUXCTRL      ( ),
+  .SIMULATIONEND( )
+  );
+
 wire ft_clk2uart;
 wire ft_rxd2uart;
 wire ft_txd2uart;
 
-  cmsdk_ft1248x1_adpio //  #(.ADPFILENAME("ADPFILENAME.log"))
-    u_ft1248_adpio(
-    .ft_clk_i             (ft_clk_out),
-    .ft_ssn_i             (ft_ssn_out),
-    .ft_miso_o            (ft_miso_in),
-    .ft_miosio_io         (P1[2]),
-
-    .FTDI_CLK2UART_o      (ft_clk2uart),
-    .FTDI_OP2UART_o       (ft_rxd2uart),
-    .FTDI_IP2UART_o       (ft_txd2uart)
+ft1248x1_track
+  u_ft1248x1_track
+  (
+  .ft_clk_i     (ft_clk_out),
+  .ft_ssn_i     (ft_ssn_out),
+  .ft_miso_i    (ft_miso_in),
+  .ft_miosio_i  (ft_miosio_i),
+  .aclk         (XTAL1),
+  .aresetn      (NRST),
+  .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
   );
 
   cmsdk_uart_capture  #(.LOGFILENAME("ft1248_op.log"))
@@ -285,7 +372,6 @@ wire ft_txd2uart;
   );
 
 
- 
  // --------------------------------------------------------------------------------
  // Tracking CPU with Tarmac trace support
  // --------------------------------------------------------------------------------
diff --git a/Cortex-M0/nanosoc/systems/mcu/verilog/tbench_M0.vc b/Cortex-M0/nanosoc/systems/mcu/verilog/tbench_M0.vc
index 3e9c203..f79c6d0 100644
--- a/Cortex-M0/nanosoc/systems/mcu/verilog/tbench_M0.vc
+++ b/Cortex-M0/nanosoc/systems/mcu/verilog/tbench_M0.vc
@@ -58,6 +58,7 @@
 ../../../../../GLIB/pads/verilog/PAD_VDDSOC.v
 ../../../../../GLIB/pads/verilog/PAD_VSS.v
 ../../../../../GLIB/mem/verilog/SROM_Ax32.v
+../../../../../GLIB/sync/verilog/SYNCHRONIZER_EDGES.v
 
 // ================= Testbench path ===================
 -y ../../../../../../arm-AAA-ip/Corstone-101_Foundation_IP/BP210-BU-00000-r1p1-00rel0/logical/cmsdk_debug_tester/verilog
diff --git a/Cortex-M0/nanosoc/systems/mcu/verilog/track_tb_iostream.v b/Cortex-M0/nanosoc/systems/mcu/verilog/track_tb_iostream.v
new file mode 100644
index 0000000..4ca22a0
--- /dev/null
+++ b/Cortex-M0/nanosoc/systems/mcu/verilog/track_tb_iostream.v
@@ -0,0 +1,111 @@
+//-----------------------------------------------------------------------------
+// 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 : track output stream for testbench signalling
+//-----------------------------------------------------------------------------
+
+module track_tb_iostream
+  (
+  input  wire       aclk,
+  input  wire       aresetn,
+  input  wire       rxd8_ready,
+  input  wire       rxd8_valid,
+  input  wire [7:0] rxd8_data,
+  output wire       SIMULATIONEND,       // Simulation end indicator
+  output wire       DEBUG_TESTER_ENABLE, // Enable debug tester
+  output wire [7:0] AUXCTRL);            // Auxiliary control
+
+   reg       ready;
+   reg [7:0] data8;
+   
+   wire      nxt_end_simulation;
+   reg       reg_end_simulation;
+   reg       reg_esc_code_mode;  // Escape code mode
+   reg       reg_aux_ctrl_mode;  // Auxiliary control capture mode
+   reg [7:0] reg_aux_ctrl;       // Registered Auxiliary control
+   reg       reg_dbgtester_enable;
+
+
+assign nxt_end_simulation = (rxd8_valid & rxd8_ready & (rxd8_data==8'h04));
+
+  // Delay for simulation end
+  always @ (posedge aclk or negedge aresetn)
+  begin: p_sim_end
+  if (!aresetn)
+    begin
+    reg_end_simulation <= 1'b0;
+    end
+  else
+    begin
+    reg_end_simulation  <= nxt_end_simulation;
+    if (reg_end_simulation==1'b1)
+      begin
+        $display("Test Ended due to Ctrl-D\n");
+        $stop;
+      end
+    end
+  end
+
+  assign SIMULATIONEND = nxt_end_simulation & (!reg_end_simulation);
+
+  // Escape code mode register
+  always @(posedge aclk or negedge aresetn)
+  begin
+    if (!aresetn)
+      reg_esc_code_mode <= 1'b0;
+    else // Set to escape mode if ESC code is detected
+      if (rxd8_valid & rxd8_ready & (reg_esc_code_mode==1'b0) & (rxd8_data==8'h1B))
+        reg_esc_code_mode <= 1'b1;
+      else if (rxd8_valid & rxd8_ready)
+        reg_esc_code_mode <= 1'b0;
+  end
+
+  // Aux Ctrl capture mode register
+  always @(posedge aclk or negedge aresetn)
+  begin
+    if (!aresetn)
+      reg_aux_ctrl_mode <= 1'b0;
+    else // Set to Aux control capture mode if ESC-0x10 sequence is detected
+      if (rxd8_valid & rxd8_ready & (reg_esc_code_mode==1'b1) & (rxd8_data==8'h10))
+        reg_aux_ctrl_mode <= 1'b1;
+      else if (rxd8_valid & rxd8_ready)
+        reg_aux_ctrl_mode <= 1'b0;
+  end
+
+  // Aux Ctrl capture data register
+  always @(posedge aclk or negedge aresetn)
+  begin
+    if (!aresetn)
+      reg_aux_ctrl <= {8{1'b0}};
+    else // Capture received data to Aux control output if reg_aux_ctrl_mode is set
+      if (rxd8_valid & rxd8_ready & (reg_aux_ctrl_mode==1'b1))
+        reg_aux_ctrl <= rxd8_data;
+  end
+
+  assign AUXCTRL = reg_aux_ctrl;
+
+  // Debug tester enable
+  always @(posedge aclk or negedge aresetn)
+  begin
+    if (!aresetn)
+      reg_dbgtester_enable <= 1'b0;
+    else // Enable debug tester if ESC-0x11 sequence is detected
+      if (rxd8_valid & rxd8_ready & (reg_esc_code_mode==1'b1) & (rxd8_data==8'h11))
+        reg_dbgtester_enable <= 1'b1;
+      else if (rxd8_valid & rxd8_ready & (reg_esc_code_mode==1'b1) & (rxd8_data==8'h12))
+        // Disable debug tester if ESC-0x12 sequence is detected
+        reg_dbgtester_enable <= 1'b0;
+  end
+
+  assign DEBUG_TESTER_ENABLE = reg_dbgtester_enable;
+
+endmodule
diff --git a/Cortex-M0/nanosoc/systems/mcu/verilog/v2html_M0.vc b/Cortex-M0/nanosoc/systems/mcu/verilog/v2html_M0.vc
index f32853f..3f3fa70 100644
--- a/Cortex-M0/nanosoc/systems/mcu/verilog/v2html_M0.vc
+++ b/Cortex-M0/nanosoc/systems/mcu/verilog/v2html_M0.vc
@@ -62,6 +62,7 @@
 ../../../../../GLIB/pads/verilog/PAD_VDDSOC.v
 ../../../../../GLIB/pads/verilog/PAD_VSS.v
 ../../../../../GLIB/mem/verilog/SROM_Ax32.v
+../../../../../GLIB/sync/verilog/SYNCHRONIZER_EDGES.v
 
 // =============   IPLIB soclabs IP Library path  =============
 ../../../../../IPLIB/FT1248_streamio_v1_0/ft1248_streamio_v1_0.v
diff --git a/GLIB/sync/verilog/SYNCHRONIZER_EDGES.v b/GLIB/sync/verilog/SYNCHRONIZER_EDGES.v
new file mode 100644
index 0000000..c669ec1
--- /dev/null
+++ b/GLIB/sync/verilog/SYNCHRONIZER_EDGES.v
@@ -0,0 +1,42 @@
+// A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license.
+//
+// Contributors
+//
+// David Flynn (d.w.flynn@soton.ac.uk)
+//
+// Copyright © 2022, SoC Labs (www.soclabs.org)
+//-----------------------------------------------------------------------------
+
+module SYNCHRONIZER_EDGES (
+	input wire        testmode_i
+	,input wire       clk_i
+        ,input wire       reset_n_i
+	,input wire       asyn_i
+	,output wire      syn_o
+	,output wire      syn_del_o
+	,output wire      posedge_o
+	,output wire      negedge_o
+	);
+
+reg sync_stage1;
+reg sync_stage2;
+reg sync_stage3;
+
+  always @(posedge clk_i or negedge reset_n_i)
+    if(~reset_n_i) begin
+        sync_stage1 <= 1'b0;
+        sync_stage2 <= 1'b0;
+        sync_stage3 <= 1'b0;
+      end
+    else begin
+        sync_stage1 <= asyn_i;
+        sync_stage2 <= sync_stage1;
+        sync_stage3 <= sync_stage2;
+      end
+
+assign syn_o     = (testmode_i) ? asyn_i : sync_stage2;
+assign syn_del_o = (testmode_i) ? asyn_i : sync_stage3;
+assign posedge_o = (testmode_i) ? asyn_i : ( sync_stage2 & !sync_stage3);
+assign negedge_o = (testmode_i) ? asyn_i : (!sync_stage2 &  sync_stage3);
+
+endmodule
-- 
GitLab