diff --git a/.gitignore b/.gitignore
index 6657ec99697c479852eaeed4bfb4755f8af38d8c..ae518f6aba543317eae6f128989895b1920d855a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,6 +19,7 @@ cmake-build-*
 
 # editor environments
 .idea
+fontconfig/
 
 # left overs from autotools setups
 config.log
diff --git a/src/drv/mbuf/mbuf_probe/CMakeLists.txt b/src/drv/mbuf/mbuf_probe/CMakeLists.txt
index 715c84526de9b13845521d82de3b363b3743c6b5..302c0fb74c13349db5941008865338ca9aaf3615 100644
--- a/src/drv/mbuf/mbuf_probe/CMakeLists.txt
+++ b/src/drv/mbuf/mbuf_probe/CMakeLists.txt
@@ -5,10 +5,13 @@ add_executable(mbuf_probe
         mbuf_decoders.cc
         analyze_daq_multi_dc.cc
         analyze_rmipc.cc
+        analyze_awg_data.cc
+        analyze_header.cc
         check_size.cc)
 target_include_directories(mbuf_probe PRIVATE
         ${CMAKE_CURRENT_SOURCE_DIR}/..
         ${CMAKE_CURRENT_SOURCE_DIR}/../../include
+        ${CMAKE_SOURCE_DIR}/src/shmem
         )
 target_link_libraries(mbuf_probe PUBLIC driver::shmem driver::ini_parsing)
 target_requires_cpp11(mbuf_probe PRIVATE)
diff --git a/src/drv/mbuf/mbuf_probe/analyze_awg_data.cc b/src/drv/mbuf/mbuf_probe/analyze_awg_data.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e3bd6897086185a99a65cfca8c9ad82a32245406
--- /dev/null
+++ b/src/drv/mbuf/mbuf_probe/analyze_awg_data.cc
@@ -0,0 +1,79 @@
+//
+// Created by erik.vonreis on 4/29/21.
+//
+
+#include <iostream>
+#include "shmem_awg.h"
+#include "analyze_awg_data.hh"
+#include "analyze_header.hh"
+
+
+using namespace std;
+
+namespace analyze
+{
+
+
+    void dump_awg_data(volatile AWG_DATA *awg_data)
+    {
+        int hunt_state = 0;
+        int slot = 0;
+
+        auto detected_type = analyze_header(awg_data);
+        if(detected_type != MBUF_AWG_DATA)
+        {
+            cout << "WARNING: attempting to analyze AWG_DATA structure, but structure was of type " << detected_type << endl;
+        }
+
+        while(true)
+        {
+            int page_index = FIND_PAGE_INDEX(slot,0);
+            volatile AWG_DATA_PAGE * page = & awg_data->page[page_index];
+
+            printf("slot: %1d status: %4x d: ", slot, page->status);
+            for ( int i = 0; i < 4; ++i )
+            {
+                printf("%12.5g", page->buf[i]);
+            }
+            cout << "\r" << flush;
+
+            // update slot if necessary to look for active slots
+            switch(hunt_state)
+            {
+            case 1:
+            case 0:
+                if(page->status != 0)
+                {
+                    ++hunt_state;
+                }
+                else
+                {
+                    hunt_state = 0;
+                }
+                break;
+            case 2:
+                if(page->status != 0)
+                {
+                    slot = (++slot) % AWG_SLOTS;
+                }
+                else
+                {
+                    hunt_state = 0;
+                }
+
+            }
+
+            usleep(20000);
+        }
+    }
+
+    void analyze_awg_data( volatile void*    buffer,
+                           std::size_t       size,
+                           const ConfigOpts& options )
+    {
+
+        dump_awg_data(
+            reinterpret_cast<volatile AWG_DATA *>(buffer)
+            );
+    }
+}
\ No newline at end of file
diff --git a/src/drv/mbuf/mbuf_probe/analyze_awg_data.hh b/src/drv/mbuf/mbuf_probe/analyze_awg_data.hh
new file mode 100644
index 0000000000000000000000000000000000000000..1a546a4b55169fac87b9e5119b2264648347c534
--- /dev/null
+++ b/src/drv/mbuf/mbuf_probe/analyze_awg_data.hh
@@ -0,0 +1,18 @@
+//
+// Created by erik.vonreis on 4/29/21.
+//
+
+#ifndef DAQD_TRUNK_ANALYZE_AWG_DATA_HH
+#define DAQD_TRUNK_ANALYZE_AWG_DATA_HH
+
+#include <cstddef>
+#include "mbuf_probe.hh"
+
+namespace analyze
+{
+    void analyze_awg_data( volatile void*    buffer,
+        std::size_t       size,
+        const ConfigOpts& options );
+}
+
+#endif // DAQD_TRUNK_ANALYZE_AWG_DATA_HH
diff --git a/src/drv/mbuf/mbuf_probe/analyze_header.cc b/src/drv/mbuf/mbuf_probe/analyze_header.cc
new file mode 100644
index 0000000000000000000000000000000000000000..29c143292edc3ef51593663f9227bdf033195b50
--- /dev/null
+++ b/src/drv/mbuf/mbuf_probe/analyze_header.cc
@@ -0,0 +1,57 @@
+//
+// Created by erik.vonreis on 4/29/21.
+//
+
+#include <iostream>
+
+#include "analyze_header.hh"
+#include "shmem_all.h"
+
+using namespace std;
+
+namespace analyze
+{
+    MBufStructures analyze_header(volatile void * header_void)
+    {
+        auto header = reinterpret_cast<volatile SHMEM_HEADER *>(header_void);
+
+        auto version = SHMEM_GET_VERSION(header);
+        auto id = SHMEM_GET_ID(header);
+
+        MBufStructures detected_type = MBUF_INVALID;
+
+        if(id)
+        {
+           switch(id)
+           {
+           case AWG_DATA_ID:
+               detected_type = MBUF_AWG_DATA;
+               cout << "Detected AWG_DATA struct ";
+               break;
+           }
+        }
+        else
+        {
+            //couldn't identify
+            cout << "Could not identify structure\n";
+        }
+
+        if(version)
+        {
+            cout << "version " << version << endl;
+        }
+        else
+        {
+            if(id)
+            {
+                cout << "version 0 (illegal.  version should be positive) \n";
+            }
+            else
+            {
+                //ignore bad version if id was also bad.
+            }
+        }
+        return detected_type;
+    }
+
+}
\ No newline at end of file
diff --git a/src/drv/mbuf/mbuf_probe/analyze_header.hh b/src/drv/mbuf/mbuf_probe/analyze_header.hh
new file mode 100644
index 0000000000000000000000000000000000000000..4eac820411a74d3294a596ecb92370807d53425e
--- /dev/null
+++ b/src/drv/mbuf/mbuf_probe/analyze_header.hh
@@ -0,0 +1,22 @@
+//
+// Created by erik.vonreis on 4/29/21.
+//
+
+#ifndef DAQD_TRUNK_ANALYZE_HEADER_H
+#define DAQD_TRUNK_ANALYZE_HEADER_H
+
+#endif // DAQD_TRUNK_ANALYZE_HEADER_H
+
+#include <cstddef>
+#include "mbuf_probe.hh"
+
+namespace analyze
+{
+
+    /**
+     * Prints info from standard mbuf header for certain mbuf structures.
+     * Returns the structure type if it can be determined and is
+     * incorporated in MBufStructures, otherwise returns MBUF_INVALID
+     */
+    MBufStructures analyze_header(volatile void * header);
+}
\ No newline at end of file
diff --git a/src/drv/mbuf/mbuf_probe/mbuf_probe.cc b/src/drv/mbuf/mbuf_probe/mbuf_probe.cc
index e1879d55910c472e9732592555a8e1c38112b584..2cff9cbc1894933c8e3e11225aa200e678f76e56 100644
--- a/src/drv/mbuf/mbuf_probe/mbuf_probe.cc
+++ b/src/drv/mbuf/mbuf_probe/mbuf_probe.cc
@@ -27,6 +27,7 @@
 #include "mbuf_probe.hh"
 #include "analyze_daq_multi_dc.hh"
 #include "analyze_rmipc.hh"
+#include "analyze_awg_data.hh"
 #include "gap_check.hh"
 #include "check_size.hh"
 
@@ -73,6 +74,7 @@ usage( const char* progname )
     std::cout << "\trmIpcStr (or rmipcstr) Analyze a models output buffer\n";
     std::cout
         << "\tdaq_multi_cycle Analyze the output of a streamer/local_dc\n";
+    std::cout << "\tAWG_DATA Analyze the data streaming from awg.\n";
 }
 
 ConfigOpts
@@ -94,6 +96,10 @@ parse_options( int argc, char* argv[] )
     struct_lookup.insert( std::make_pair( "rmipcstr", MBUF_RMIPC ) );
     struct_lookup.insert(
         std::make_pair( "daq_multi_cycle", MBUF_DAQ_MULTI_DC ) );
+    struct_lookup.insert(
+           std::make_pair( "awg_data", MBUF_AWG_DATA) );
+    struct_lookup.insert(
+        std::make_pair( "AWG_DATA", MBUF_AWG_DATA) );
 
     std::deque< std::string > args;
     for ( int i = 1; i < argc; ++i )
@@ -355,8 +361,12 @@ handle_analyze( const ConfigOpts& opts )
     case MBUF_DAQ_MULTI_DC:
         analyze::analyze_multi_dc( buffer, opts.buffer_size, opts );
         break;
+    case MBUF_AWG_DATA:
+        analyze::analyze_awg_data(buffer, opts.buffer_size, opts);
+        break;
+    case MBUF_INVALID:
     default:
-        std::cout << "Unknown analysis type\n";
+        std::cout << "Unknown analysis type: " << opts.analysis_type << std::endl;
         return ERROR;
     }
     return OK;
@@ -391,7 +401,7 @@ handle_check_size( const ConfigOpts& opts )
         check_mbuf_sizes::check_size_multi( buffer, opts.buffer_size, opts );
         break;
     default:
-        std::cout << "Unknown analysis type for the check size commandn";
+        std::cout << "Unknown analysis type for the check size command";
         return ERROR;
     }
     return OK;
diff --git a/src/drv/mbuf/mbuf_probe/mbuf_probe.hh b/src/drv/mbuf/mbuf_probe/mbuf_probe.hh
index 9609af1d65deb0c970b37f9ee354c95245580baa..58b9cb04933dbc2d61465a366f9bb39e037a8f33 100644
--- a/src/drv/mbuf/mbuf_probe/mbuf_probe.hh
+++ b/src/drv/mbuf/mbuf_probe/mbuf_probe.hh
@@ -35,6 +35,7 @@ enum MBufStructures
     MBUF_INVALID,
     MBUF_RMIPC,
     MBUF_DAQ_MULTI_DC,
+    MBUF_AWG_DATA,
 };
 
 struct ConfigOpts
diff --git a/src/fe/moduleLoadCommon.c b/src/fe/moduleLoadCommon.c
index 4d6e76cd4a838bca24acd062737c04273144e4fd..9c675d53c77ef86ca6b2b8ed149c25260dd95451 100644
--- a/src/fe/moduleLoadCommon.c
+++ b/src/fe/moduleLoadCommon.c
@@ -16,6 +16,8 @@ print_io_info( CDS_HARDWARE* cdsp , int iopmodel)
 #endif
     printf( "" SYSTEM_NAME_STRING_LOWER ":EPICSM at 0x%lx\n",
             (unsigned long)_epics_shm );
+    printf( "" SYSTEM_NAME_STRING_LOWER ":AWGSM at 0x%lx\n",
+            (unsigned long)_awg_shm );
     printf( "" SYSTEM_NAME_STRING_LOWER ":IPC    at 0x%lx\n",
             (unsigned long)_ipc_shm );
     printf( "" SYSTEM_NAME_STRING_LOWER ":IOMEM  at 0x%lx size 0x%lx\n",
@@ -250,6 +252,8 @@ detach_shared_memory( )
     char fname[ 128 ];
 
     ret = mbuf_release_area( SYSTEM_NAME_STRING_LOWER, _epics_shm );
+    sprintf( fname, "%s%s", SYSTEM_NAME_STRING_LOWER, SHMEM_AWG_SUFFIX);
+    ret = mbuf_release_area( fname, _awg_shm );
     ret = mbuf_release_area( "ipc", _ipc_shm );
     ret = mbuf_release_area( "shmipc", _shmipc_shm );
     sprintf( fname, "%s_daq", SYSTEM_NAME_STRING_LOWER );
@@ -276,6 +280,18 @@ attach_shared_memory( )
     pLocalEpics = (CDS_EPICS*)&( (RFM_FE_COMMS*)_epics_shm )->epicsSpace;
     pLocalEpics->epicsOutput.fe_status = 0;
 
+    /// Allocate AWG data memory area
+    ret = mbuf_allocate_area("" SYSTEM_NAME_STRING_LOWER SHMEM_AWG_SUFFIX, SHMEM_AWG_SIZE, 0 );
+    if ( ret < 0 )
+    {
+        printk( "" SYSTEM_NAME_STRING_LOWER
+                ": ERROR: mbuf_allocate_area(awg) failed; ret = %d\n",
+                ret );
+        return -12;
+    }
+    // Set pointer to AWG area
+    _awg_shm = (volatile AWG_DATA *)( kmalloc_area[ ret ] );
+
     /// Allocate IPC memory area
     ret = mbuf_allocate_area( "ipc", 32 * 1024 * 1024, 0 );
     if ( ret < 0 )
diff --git a/src/fe/rcguserCommon.c b/src/fe/rcguserCommon.c
index fb0c38a4208d25afbf9184f823963a19a6d9351f..925861f4b83b2b4ddf5704b6597cc48e8813bb88 100644
--- a/src/fe/rcguserCommon.c
+++ b/src/fe/rcguserCommon.c
@@ -28,7 +28,18 @@ attach_shared_memory( char* sysname )
         return -1;
     }
     printf( "EPICSM at 0x%lx\n", (long)_epics_shm );
-
+    
+    // awg data shm used to stream data from awgtpman
+    sprintf( shm_name, "%s%s", sysname, SHMEM_AWG_SUFFIX );
+    findSharedMemory( sysname );
+    _awg_shm = (volatile AWG_DATA *)addr;
+    if ( (uint64_t)_awg_shm < 0 )
+    {
+        printf( "mbuf_allocate_area() failed; ret = %d\n", _awg_shm );
+        return -1;
+    }
+    printf( "AWGSM at 0x%lx\n", (long)_awg_shm );
+    
     // ipc_shm used to communicate with IOP
     findSharedMemory( "ipc" );
     _ipc_shm = (char*)addr;
diff --git a/src/gds/awgtpman/CMakeLists.txt b/src/gds/awgtpman/CMakeLists.txt
index e438f3483e474bb5fe0d6b9fffcf3d86152df928..a603b4433200c0d0c74885c5ce7b1647e45c2f72 100644
--- a/src/gds/awgtpman/CMakeLists.txt
+++ b/src/gds/awgtpman/CMakeLists.txt
@@ -25,14 +25,17 @@ add_executable(awgtpman
         confserver.c
         sockutil.c
         tconv.c
+        shared_memory.c
 
         ../../util/modelrate.c
-        )
+        ../../drv/shmem.c)
 
 target_include_directories(awgtpman PRIVATE
         ${CMAKE_CURRENT_SOURCE_DIR}
-        ${CMAKE_CURRENT_SOURCE_DIR}/../../include
+        ${CMAKE_SOURCE_DIR}/src/include
         ${RPC_OUTPUT_DIR}
+        ${CMAKE_SOURCE_DIR}/src/shmem
+        ${CMAKE_SOURCE_DIR}/src/drv/mbuf
         )
 
 target_link_libraries(awgtpman PRIVATE
diff --git a/src/gds/awgtpman/awg.c b/src/gds/awgtpman/awg.c
index bec0f9210d5e16474a799904d155cd2cd8bafd91..2a803bf5373510e33c92517ec0393995a8ccee89 100644
--- a/src/gds/awgtpman/awg.c
+++ b/src/gds/awgtpman/awg.c
@@ -82,12 +82,12 @@ static char *versionId = "Version $Id$" ;
 #include "dtt/testpoint.h"
 #include "dtt/testpointinfo.h"
 #endif
-#include "dtt/map.h"
+#include "shmem_awg.h"
 #include "dtt/targets.h"
 #include "dtt/hardware.h"
 #include "dtt/rmorg.h"
 #include "dtt/rmapi.h"
-
+#include "shared_memory.h"
 
 /*----------------------------------------------------------------------*/
 /*                                                         		*/
@@ -148,9 +148,7 @@ static char *versionId = "Version $Id$" ;
 #else
 #define _MAX_BUF		8	
 #endif
-/* This will need to go higher for systems faster than 32 kHz */
-/* or if DCU block size is increased */
-#define _MAX_PAGE		(DAQ_DCU_SIZE/256)
+
 #define _DAC_PAGE		1024	
 #define _LSCTP_PAGE		TP_LSC_CHN_LEN	
 #define _ASCTP_PAGE		TP_ASC_CHN_LEN	
@@ -252,21 +250,28 @@ Organization of generating waveforms:
    };
    typedef struct filter_coeff_t filter_coeff_t;
 
-   struct awgpagebuf_t {
-      /* ouput type */
-      AWG_OutputType	otype;
-      /* output pointer (testpoints) */
-      float*		optr;
-      /* channel number (DAC) */
-      int		onum;
-      /* page length */
-      int		pagelen;
-      /* status of page buffer */
-      int		status;
-      /* buffer for page */
-      float		page [_MAX_PAGE];
-   };
-   typedef struct awgpagebuf_t awgpagebuf_t;
+
+
+    /**
+     *
+     */
+    struct awgpagebuf_t {
+        /* ouput type */
+        AWG_OutputType	otype;
+        /* output pointer (testpoints) */
+        float*		optr;
+        /* page index into shared memory */
+        int             page_index;
+        /* channel number (DAC) */
+        int		onum;
+        /* page length */
+        int		pagelen;
+        /* status of page buffer */
+        int		status;
+        /* buffer for page */
+        float		page [_MAX_PAGE];
+    };
+    typedef struct awgpagebuf_t awgpagebuf_t;
 
    struct awgbuf_t {
       /* ready flag: 0 - not ready, 1 - ready, 2 - in process */
@@ -315,6 +320,8 @@ Organization of generating waveforms:
 #endif
 
 
+
+
 /*----------------------------------------------------------------------*/
 /*                                                         		*/
 /* Globals: AWG[] - configuration and status of module			*/
@@ -409,7 +416,7 @@ Organization of generating waveforms:
    static int readTPinfo (taisec_t tai, int epoch);
 #endif
    static int getTPslot (AWG_OutputType type, int tpID, 
-                     taisec_t time, int epoch, float** tpptr);
+                     taisec_t time, int epoch, float** tpptr, int *page_index);
    static int invalidateTPslots (int epoch);
    static void retireAWGComp (tainsec_t time);
 #ifdef _AWG_DAC
@@ -955,23 +962,27 @@ Organization of generating waveforms:
       awgpagebuf_t*	p;		/* pointer to awg page */
       for (i = 0, p = buf->buf; i < MAX_NUM_AWG; i++, p++) {
          /* test whether valid test point channel */
+
+         AWG_DATA_PAGE *target_page;
          switch (p->otype) 
          {
             case awgLSCtp:
             case awgDAC: /* copy DAC channel into LSC EXC if necessary */
                {
                   if ((p->pagelen != _LSCTP_PAGE) ||
-                     (p->optr == NULL)) {
+                     (p->page_index < 0)){
                      continue;
                   }
+                  target_page = &shmemAwgData->page[p->page_index];
                   break;
                }
             case awgASCtp:
                {
                   if ((p->pagelen != _ASCTP_PAGE) ||
-                     (p->optr == NULL)) {
+                     (p->page_index < 0)) {
                      continue;
                   }
+                  target_page = &shmemAwgData->page[p->page_index];
                   break;
                }
             case awgMem:
@@ -980,6 +991,7 @@ Organization of generating waveforms:
                      (p->optr == NULL)) {
                      continue;
                   }
+                  target_page = (AWG_DATA_PAGE  *)p->optr;
                   break;
                }
             default:
@@ -987,96 +999,13 @@ Organization of generating waveforms:
                   continue;
                }
          }
-      
+
+
+
          /* now start transfer */
-         /* memcpy ((void*) p->optr, (void*) p->page, 
-                p->pagelen * sizeof (float)); */
-         /* don't forget to write status */
-         p->status = 0;
-         {
-            static int cnt = 0;
-            if (buf->epoch == 0) {
-               cnt = 0;
-            #if 0
-               printf ("addr = 0x%x size = %d\n", (int) p->optr, 
-                      (int) (p->pagelen + 1) * sizeof (float));
-               printf ("values = %g %g %g %g\n",
-                      p->page[p->pagelen-1], p->page[p->pagelen-2],
-                      p->page[p->pagelen-3], p->page[p->pagelen-4]);
-            #endif
-            }
-         /*
-            if (1 || buf->epoch == 8) {
-               float x[4];
-               static int ofs[100] = {0, 0, 0, 0, 0, 0};
-               if (buf->epoch == 0) {
-                  ofs[i] = (int) p->optr + 
-                           (p->pagelen - 3) * sizeof (float);
-               }
-               if (ofs[i]) {
-                  if (i == 2) {
-                     printf ("ofs[2] = %i\n", ofs[i]);
-                  }
-                  rmRead (_RM_ID, (char*)x, ofs[i], 
-                         4 * sizeof (float), 0);
-                  printf ("values prev. = %g %g %g %g\n",
-                         x[3], x[2], x[1], x[0]);
-               }
-            }
-         */
-         }
-      #if RMEM_LAYOUT == 1
-      /* Interleave the writes to slow network blasting a bit */
-      {
-      int j, k;
-      int sz =  (p->pagelen + 1) * sizeof (float);
-      int nc = sz/awgInterleave;
-      void *srcptr = (void*) &p->status;
-      int destidx = (int) p->optr;
-      for(j = 0; j < nc; j++) {
-             rmWrite (0, srcptr, destidx, awgInterleave, 0);
-      #if TARGET != (TARGET_L1_GDS_AWG1 + 20) && TARGET != (TARGET_L1_GDS_AWG1 + 21)
-              if (AWG[i].rmem) rmWrite (1, srcptr, destidx, awgInterleave, 0);
-      #endif
-         srcptr += awgInterleave;
-         destidx += awgInterleave;
-      
-         /* VME accesses to slow things down */
-         for (k = 0; k < awgVmeReadDelay; k++) statusTimingCard();
-      /*		*((int *) (ICS115_0_BASE_ADDRESS+0x50008)) = 0;*/
-      }
-           rmWrite (0, srcptr, destidx, sz - awgInterleave*nc, 0);
-           if (AWG[i].rmem) rmWrite (1, srcptr, destidx, sz - awgInterleave*nc, 0);
-      }
-      #if 0
-         rmWrite (0, (void*) &p->status, (int) p->optr, 
-                  (p->pagelen + 1) * sizeof (float), 0);
-         rmWrite (1, (void*) &p->status, (int) p->optr, 
-                  (p->pagelen + 1) * sizeof (float), 0);
-      #endif
-      #else
-         {int i; 
-            for (i = 0; i < 5; ++i) 
-               rmWrite (_RM_ID, (void*) &p->status, (int) p->optr, 
-                       (p->pagelen + 1) * sizeof (float), 0);
-	  }
-      #endif
-         /*{
-            if (1 || buf->epoch == 0) {
-               float x[4];
-               static int ofs[100] = {0, 0, 0, 0, 0, 0};
-               if (buf->epoch == 0) {
-                  ofs[i] = (int) p->optr + 
-                           (p->pagelen - 3) * sizeof (float);
-               }
-               if (ofs[i]) {
-                  rmRead (_RM_ID, (char*)x, ofs[i], 
-                         4 * sizeof (float), 0);
-                  printf ("values prev. = %g %g %g %g\n",
-                         x[3], x[2], x[1], x[0]);
-               }
-            }
-         }*/
+         memcpy(target_page->buf, p->page, p->pagelen * sizeof(float));
+         target_page->status = 0;
+
       }
    }
 #endif
@@ -1269,12 +1198,13 @@ Organization of generating waveforms:
 /*                      time - time of waveform				*/
 /*                      epoch - epoch of waveform	      		*/
 /*                      tpptr - pointer to TP data			*/
+/*                      pageindex - index into shared memory page array */
 /*                                                         		*/
 /* Procedure Returns: slot # if successful, <0 otherwise		*/
 /*                                                         		*/
 /*----------------------------------------------------------------------*/
    int getTPslot (AWG_OutputType type, int tpID, 
-                     taisec_t time, int epoch, float** tpptr)
+                     taisec_t time, int epoch, float** tpptr, int *page_index)
    {
    #ifdef _NO_TESTPOINTS
       return -1;
@@ -1330,6 +1260,7 @@ Organization of generating waveforms:
             break;
          }
       }
+      *page_index = -1;
       /* calculate address in reflective memory */
       if ((slot >= 0) && (tpptr != NULL)) {
       #if 0 && RMEM_LAYOUT == 1
@@ -1338,7 +1269,9 @@ Organization of generating waveforms:
          /* Don't forget status word at beginning of channel data! */
          tpBase += slot * TP_DATUM_LEN * (tpChnLen + 1);
       #endif
-         *tpptr = (float*) CHN_ADDR (tpBase, tpSize, epoch);
+         //*tpptr = (float*) CHN_ADDR (tpBase, tpSize, epoch);
+         *tpptr = NULL;
+         *page_index = FIND_PAGE_INDEX(slot, epoch);
       }
       else if (tpptr != NULL) {
          *tpptr = NULL;
@@ -1369,52 +1302,12 @@ Organization of generating waveforms:
       return -1;
    
    #else
-      int		tplistlen;	/* length of testpoint list */
-      long		tpBase;		/* offset to TP data block */
-      long		tpSize;		/* size of TP data block */
-      long		tpChnLen;	/* length of tp channel */
-      int		i;		/* index */
-      int		slot;		/* test point slot */
-      int		tpptr;		/* pointer to test point slot */
-      int 		status;		/* channel status flag */
-   
-      status = _INVALID_RM_CHANNEL;
-      for (i = 0; i < 2; i++) {
-         /* LSC or DAC */
-         if (i == 0) {
-            tplistlen = TP_LSC_EX_NUM;
-            tpBase = _LSCX_BASE;
-            tpSize = _LSCX_SIZE;
-            tpChnLen = TP_LSC_CHN_LEN;
-         }
-         /* ASC */
-         else {
-            tplistlen = TP_ASC_EX_NUM;
-            tpBase = _ASCX_BASE;
-            tpSize = _ASCX_SIZE;
-            tpChnLen = TP_ASC_CHN_LEN;
-         }
-         /* go through tp slot list */
-         tpptr = CHN_ADDR (tpBase, tpSize, epoch);
-         for (slot = 0; slot < tplistlen; slot++) {
-         #if RMEM_LAYOUT > 0
-            rmWrite (0, (char*) &status, tpptr, TP_DATUM_LEN, 0);
-         #if TARGET != (TARGET_L1_GDS_AWG1 + 20) && TARGET != (TARGET_L1_GDS_AWG1 + 21)
-            rmWrite (1, (char*) &status, tpptr, TP_DATUM_LEN, 0);
-         #endif
-         /*printf("inv tpslot 0/1 at 0x%x len=%d values=0x%x\n",
-         tpptr, TP_DATUM_LEN, status);*/
-         /*	    for (k = 0; k < awgVmeReadDelay; k++)
-         *((int *) 0x50201000) = 0;*/
-         #else	
-            rmWrite (_RM_ID, (char*) &status, tpptr, TP_DATUM_LEN, 0);
-         #endif
-            /* Don't forget status word at beginning of channel data! */
-            tpptr += TP_DATUM_LEN * (tpChnLen + 1);
-         }
-      }
-   
-      return 0;
+        for (int slot = 0; slot < AWG_SLOTS; slot++) {
+
+            int page_index = FIND_PAGE_INDEX(slot,  epoch);
+            shmemAwgData->page[page_index].status = _INVALID_RM_CHANNEL;
+        }
+        return 0;
    #endif
    }
 
@@ -1977,7 +1870,7 @@ Organization of generating waveforms:
             {
                /* complete buffer information */
                if (getTPslot (AWG[ID].otype, AWG[ID].ID, 
-                  time, epoch, &pbuf->optr) >= 0) {
+                  time, epoch, &pbuf->optr, &pbuf->page_index) >= 0) {
                   pbuf->otype = AWG[ID].otype;
                   pbuf->onum = AWG[ID].ID;
                   pbuf->pagelen = AWG[ID].pagesize;
@@ -1996,7 +1889,7 @@ Organization of generating waveforms:
                pbuf->optr = NULL;
                /* copy into LSC testpoint as well? */
                if (getTPslot (awgLSCtp, TP_ID_DAC_OFS + AWG[ID].ID, 
-                  time, epoch, &pbuf->optr) < 0) {
+                  time, epoch, &pbuf->optr, &pbuf->page_index) < 0) {
                   pbuf->optr = NULL;
                }
                break;
diff --git a/src/gds/awgtpman/awgtpman.c b/src/gds/awgtpman/awgtpman.c
index e6bbb012000f30b365350329b6892a1ce8747374..aaedcb6e624c84c2f4f56d118cc09e3bb0bea1bc 100644
--- a/src/gds/awgtpman/awgtpman.c
+++ b/src/gds/awgtpman/awgtpman.c
@@ -16,6 +16,8 @@ static char *versionId = "Version $Id$" ;
 #include "dtt/rmapi.h"
 #include "drv/cdsHardware.h"
 #include "modelrate.h"
+#include "shmem_awg.h"
+#include "shared_memory.h"
 
 #ifdef OS_VXWORKS
 #define _PRIORITY_TPMAN		40
@@ -289,6 +291,14 @@ CDS_HARDWARE cdsPciModules;
 #ifdef __linux__
       initReflectiveMemory();
 #endif
+      if(!OpenAwgDataSharedMemory(system_name))
+      {
+          fprintf(stderr, "Failed to open mbuf for awg streaming.\n");
+          _exit(2);
+      }
+
+
+
       if (run_awg) {
         nice(-20);
       }
diff --git a/src/gds/awgtpman/dtt/awgtype.h b/src/gds/awgtpman/dtt/awgtype.h
index 64aa74b6aafa22cab46d4fc2046844f265e47ac7..9d2f110e1b95524c8427ae5c32391760b85342b6 100644
--- a/src/gds/awgtpman/dtt/awgtype.h
+++ b/src/gds/awgtpman/dtt/awgtype.h
@@ -75,6 +75,10 @@ extern "C" {
 #include "dtt/gdsrand.h"
 #include "tconv.h"
 #include "dtt/gdstask.h"
+#include "hardware.h"
+#include "map.h"
+#include "shmem_awg.h"
+
 #endif
 
 /**@name Arbitrary Waveform Generator Type Definitions
@@ -320,7 +324,7 @@ extern "C" {
     @author MRP, Apr. 1998
     @see Arbitrary Waveform Generator
 *********************************************************************/
-#define	MAX_NUM_AWG			9
+#define	MAX_NUM_AWG			AWG_SLOTS
 
 /** Maximum number of components per waveform. This number has to 
     be large enough to hold all scheduled components. This number
@@ -496,48 +500,7 @@ extern "C" {
 
 /*@{*/
 
-/** Identification for an LSC test point channel
-
-    @author DS, Jul. 1998
-    @see Arbitrary Waveform Generator
-*********************************************************************/
-#define	AWG_LSC_TESTPOINT		1
-
-/** Identification for an ASC test point channel
 
-    @author DS, Jul. 1998
-    @see Arbitrary Waveform Generator
-*********************************************************************/
-#define	AWG_ASC_TESTPOINT		2
-
-/** Identification for a DAC channel
-
-    @author DS, Jul. 1998
-    @see Arbitrary Waveform Generator
-*********************************************************************/
-#define	AWG_DAC_CHANNEL			3
-
-/** Identification for a DS340 channel
-
-    @author DS, Jul. 1998
-    @see Arbitrary Waveform Generator
-*********************************************************************/
-#define	AWG_DS340_CHANNEL		4
-
-/** Identification for a channel which gets written to file.
-
-    @author DS, Jul. 1998
-    @see Arbitrary Waveform Generator
-*********************************************************************/
-#define	AWG_FILE_CHANNEL		5
-
-/** Identification for a channel which gets written to an aboslute
-    address in reflective memory.
-
-    @author DS, Jul. 1998
-    @see Arbitrary Waveform Generator
-*********************************************************************/
-#define	AWG_MEM_CHANNEL			6
 
 /*@}*/
 
@@ -647,33 +610,7 @@ extern "C" {
    };
    typedef enum AWG_WaveType AWG_WaveType;
 
-/** Recognized output modes.
-    The output of an arbitrary waveform generator can be an LSC or
-    ASC test point, a DAC channel, a DS340 channel or a file (test
-    only).
-   
-    @author MRP, Apr. 1998
-    @see Arbitrary Waveform Generator
-*********************************************************************/
-   enum AWG_OutputType {
-   #if 0
-   /** output disabled */
-   awgNone = 0,
-   #endif
-   /** output to an LSC tespoint */
-   awgLSCtp = AWG_LSC_TESTPOINT,
-   /** output to an ASC tespoint */
-   awgASCtp = AWG_ASC_TESTPOINT,
-   /** output to a DAC channel */
-   awgDAC = AWG_DAC_CHANNEL,
-   /** output to a DS340 function generator */
-   awgDS340 = AWG_DS340_CHANNEL,
-   /** output to a file */
-   awgFile = AWG_FILE_CHANNEL,
-   /** output to an absolute memory location */
-   awgMem = AWG_MEM_CHANNEL
-   };
-   typedef enum AWG_OutputType AWG_OutputType;
+
 
 /** Structure to describe a component of a waveform.
 
@@ -723,6 +660,29 @@ extern "C" {
    };
    typedef struct AWG_Gain AWG_Gain;
 
+    /** Recognized output modes.
+    The output of an arbitrary waveform generator can be an LSC or
+    ASC test point, a DAC channel, a DS340 channel or a file (test
+    only).
+
+    @author MRP, Apr. 1998
+    @see Arbitrary Waveform Generator
+    *********************************************************************/
+    enum AWG_OutputType {
+        /** output to an LSC tespoint */
+        awgLSCtp = AWG_LSC_TESTPOINT,
+        /** output to an ASC tespoint */
+        awgASCtp = AWG_ASC_TESTPOINT,
+        /** output to a DAC channel */
+        awgDAC = AWG_DAC_CHANNEL,
+        /** output to a DS340 function generator */
+        awgDS340 = AWG_DS340_CHANNEL,
+        /** output to a file */
+        awgFile = AWG_FILE_CHANNEL,
+        /** output to an absolute memory location */
+        awgMem = AWG_MEM_CHANNEL
+    };
+    typedef enum AWG_OutputType AWG_OutputType;
 
 #ifndef _GDS_AWGAPI_H
 /** Structure to describe an arbitrary waveform generator.
diff --git a/src/gds/awgtpman/dtt/rmorg.h b/src/gds/awgtpman/dtt/rmorg.h
index fddb34df349984f9ddb28c84799a4a89dd1eb6c1..8a483b6c72fbcb5c3e6cd1dd0262a0e6272f1866 100644
--- a/src/gds/awgtpman/dtt/rmorg.h
+++ b/src/gds/awgtpman/dtt/rmorg.h
@@ -72,7 +72,7 @@ extern "C" {
 
 /* Header File List: */
 #include "dtt/hardware.h"
-#include "dtt/map.h"
+#include "map.h"
 
 /** @name Reflective Memory Organization
     This module defines the organizational structure of the reflective
diff --git a/src/gds/awgtpman/shared_memory.c b/src/gds/awgtpman/shared_memory.c
new file mode 100644
index 0000000000000000000000000000000000000000..876fd7f1fc09560ddc1f32be896745d5380ef283
--- /dev/null
+++ b/src/gds/awgtpman/shared_memory.c
@@ -0,0 +1,24 @@
+//
+// Created by erik.vonreis on 4/27/21.
+//
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include "shared_memory.h"
+#include "shmem_awg.h"
+#include "drv/shmem.h"
+
+volatile AWG_DATA *shmemAwgData = NULL;
+
+int OpenAwgDataSharedMemory(const char *model_name)
+{
+    char buff[256];
+    strncpy(buff, model_name, sizeof(buff));
+    buff[sizeof(buff)-1] = 0;
+    strncat(buff, SHMEM_AWG_SUFFIX, sizeof(buff));
+    shmemAwgData = (volatile AWG_DATA *)shmem_open_segment(buff, SHMEM_AWG_SIZE);
+    AWG_DATA_INIT(shmemAwgData);
+    return (shmemAwgData!=NULL) ? -1 : 0;
+}
\ No newline at end of file
diff --git a/src/gds/awgtpman/shared_memory.h b/src/gds/awgtpman/shared_memory.h
new file mode 100644
index 0000000000000000000000000000000000000000..37ae79f493ce58941cc3af2a114c6f64df685188
--- /dev/null
+++ b/src/gds/awgtpman/shared_memory.h
@@ -0,0 +1,21 @@
+//
+// Created by erik.vonreis on 4/27/21.
+// functions for interfacing AWG with shared memory
+//
+
+#ifndef DAQD_TRUNK_SHARED_MEMORY_H
+#define DAQD_TRUNK_SHARED_MEMORY_H
+
+#include <stdint.h>
+
+#include "shmem_awg.h"
+
+extern volatile AWG_DATA *shmemAwgData;
+
+/**
+ * Open up the awg streaming into a global pointer, shmemAwgData
+ * @returns 0 on failuer, nonzero on success
+ */
+int OpenAwgDataSharedMemory(const char *model_name);
+
+#endif // DAQD_TRUNK_SHARED_MEMORY_H
diff --git a/src/include/controller.h b/src/include/controller.h
index 2343226f180e486e0d6c3e837ef5a9cea3b5a698..c36335724492a8ce64d212ba2d647c8087764d0f 100644
--- a/src/include/controller.h
+++ b/src/include/controller.h
@@ -289,9 +289,12 @@ char fp[ 64 * 1024 ];
 #define PERIOD_COUNT 1
 #define MAX_UDELAY 19999
 
+#include "../shmem/shmem_all.h"
+
 char*          build_date = __DATE__ " " __TIME__;
 extern int     iop_rfm_valid;
 volatile char* _epics_shm; ///< Ptr to EPICS shared memory area
+volatile AWG_DATA *_awg_shm;
 char*          _ipc_shm; ///< Ptr to inter-process communication area
 char*          _daq_shm; ///< Ptr to frame builder comm shared mem area
 // char*          _gds_shm; ///< Ptr to frame builder comm shared mem area
diff --git a/src/include/drv/daqLib.c b/src/include/drv/daqLib.c
index c9775957bd0ee7124159f63ff8c8d43520978f63..993df275fff2eb7f9e15d5f44355508e37b843a9 100644
--- a/src/include/drv/daqLib.c
+++ b/src/include/drv/daqLib.c
@@ -2,9 +2,12 @@
  *	\brief File contains routines to support DAQ on realtime systems. \n
  *	\author R.Bork, A. Ivanov
  */
+ 
+#include "../../shmem/shmem_all.h"
 
 volatile DAQ_INFO_BLOCK* pInfo; ///< Ptr to DAQ config in shmem.
 extern volatile char*    _epics_shm; ///< Ptr to EPICS shmem block
+extern volatile AWG_DATA *_awg_shm;
 extern long              daqBuffer; ///< Address of daqLib swing buffers.
 extern char*     _daq_shm; ///< Pointer to DAQ base address in shared memory.
 struct rmIpcStr* dipc; ///< Pointer to DAQ IPC data in shared memory.
@@ -123,7 +126,7 @@ daqWrite( int            flag,
     static int tpNumNet[ DAQ_GDS_MAX_TP_ALLOWED ]; /* TP/EXC selects to send to
                                                       FB.	*/
     static int      totalChans; /* DAQ + TP + EXC chans selected.	*/
-    int*            statusPtr;
+
     volatile float* dataPtr; /* Ptr to excitation chan data.		*/
     int             exChanOffset; /* shmem offset to next EXC value.	*/
     int             tpx;
@@ -696,25 +699,23 @@ daqWrite( int            flag,
                 if ( localTable[ ii ].type < DAQ_SRC_FM_EXC )
                     continue;
 
-                exChanOffset = localTable[ ii ].sigNum * excDataSize;
-                statusPtr =
-                    (int*)( exciteDataPtr + excBlockNum * DAQ_DCU_BLOCK_SIZE +
-                            exChanOffset );
-                if ( *statusPtr == 0 )
+                //find right page for the excitation
+                int page_index = FIND_PAGE_INDEX(localTable[ ii ].sigNum, excBlockNum);
+                AWG_DATA_PAGE *awg_page = _awg_shm->page + page_index;
+
+                if ( awg_page->status == 0 )
                 {
                     validEx = FE_ERROR_EXC_SET;
-                    dataPtr = (float*)( exciteDataPtr +
-                                        excBlockNum * DAQ_DCU_BLOCK_SIZE +
-                                        exChanOffset + excSlot * 4 + 4 );
+                    
                     if ( localTable[ ii ].type == DAQ_SRC_FM_EXC )
                     {
                         dspPtr->data[ localTable[ ii ].fmNum ].exciteInput =
-                            *dataPtr;
+                            awg_page->buf[excSlot];
                     }
                     else if ( localTable[ ii ].type == DAQ_SRC_NFM_EXC )
                     {
                         // extra excitation
-                        excSignal[ localTable[ ii ].fmNum ] = *dataPtr;
+                        excSignal[ localTable[ ii ].fmNum ] = awg_page->buf[excSlot];
                     }
                 }
                 // else dspPtr->data[localTable[ii].fmNum].exciteInput = 0.0;
diff --git a/src/nds/CMakeLists.txt b/src/nds/CMakeLists.txt
index 356a947811e5176936ee2620d0ca7bd68586cf9b..7842c5a76e81d22b846dd265284a558229db146f 100644
--- a/src/nds/CMakeLists.txt
+++ b/src/nds/CMakeLists.txt
@@ -8,7 +8,7 @@ set( NDS_SRC
         main.cc
         spec.cc
         scanarchivedir.cc
-        )
+        ../shmem/awg_data.h ../shmem/shmem_header.h ../shmem/shmem_all.h)
 
 execute_process(COMMAND uname -a
         OUTPUT_VARIABLE NDS_UNAME)
diff --git a/src/shmem/awg_data.h b/src/shmem/awg_data.h
new file mode 100644
index 0000000000000000000000000000000000000000..3639473ac2d54afb900cf8f28b5571a2d7ba5f72
--- /dev/null
+++ b/src/shmem/awg_data.h
@@ -0,0 +1,56 @@
+//
+// Created by erik.vonreis on 4/27/21.
+//
+
+#ifndef DAQD_TRUNK_AWG_DATA_H
+#define DAQD_TRUNK_AWG_DATA_H
+
+#include "daq_core_defs.h"
+#include "shmem_header.h"
+
+// maximum supported model rate in samples per second.
+#define MAX_MODEL_RATE_SPS (64 * 1024)
+
+// maximum supported width of a single datum in the awg data
+#define MAX_SAMPLE_WIDTH_BYTES (sizeof(float))
+
+// Maximum page size.  Awg is streamed one page per epoch per slot.
+// _max_page_size is 2^20 samples per second ( > 1 megasample) * sizeof(double) / 16 epochs per second
+#define _MAX_PAGE (MAX_MODEL_RATE_SPS * MAX_SAMPLE_WIDTH_BYTES / DAQ_NUM_DATA_BLOCKS_PER_SECOND)
+
+typedef struct AWG_DATA_PAGE
+{
+    uint32_t status;
+    float buf[_MAX_PAGE];
+} AWG_DATA_PAGE;
+
+// number channels of excitation that can be run at once per model (DCU).
+#define AWG_SLOTS (9)
+
+// number of epochs buffered per slot.
+// If we wanted to increase this number beyond the number of epochs per second,
+// then FIND_PAGE_INDEX would have to be changed.
+#define AWG_EPOCHS_PER_SLOT (16)
+
+// total number of data pages in the awg shared memory.
+#define AWG_PAGE_COUNT (AWG_SLOTS * AWG_EPOCHS_PER_SLOT)
+
+/**
+ * Primary structure for awg shared memory
+ * Contains all the pages passed between awg and the models.
+ */
+typedef struct AWG_DATA
+{
+    SHMEM_HEADER _header;
+    AWG_DATA_PAGE page[AWG_PAGE_COUNT];
+} AWG_DATA;
+
+#define AWG_DATA_ID (1)  // structure identification.  Should be unique to the structure.
+#define AWG_DATA_VERSION (1)
+
+#define AWG_DATA_INIT(AD_PTR) SHMEM_SET_VERSION(AD_PTR, AWG_DATA_ID, AWG_DATA_VERSION)
+
+// convert a slot number and epoch count into
+#define FIND_PAGE_INDEX(SLOT, EPOCH) ((SLOT*AWG_EPOCHS_PER_SLOT) + (EPOCH % AWG_EPOCHS_PER_SLOT))
+
+#endif // DAQD_TRUNK_AWG_DATA_H
diff --git a/src/gds/awgtpman/dtt/map.h b/src/shmem/map.h
similarity index 89%
rename from src/gds/awgtpman/dtt/map.h
rename to src/shmem/map.h
index 8560591f619d8e3c2f748a5b5bd1fbb7b2d38cac..29d597e0c9182be2325af09711a774883e9df078 100644
--- a/src/gds/awgtpman/dtt/map.h
+++ b/src/shmem/map.h
@@ -1,5 +1,5 @@
 /* Version: $Id$ */
-#include "hardware.h"
+//#include "dtt/hardware.h"
 #if (RMEM_LAYOUT == 0)
 #error
 #include "map_v1.h"
diff --git a/src/gds/awgtpman/dtt/map_v3.h b/src/shmem/map_v3.h
similarity index 88%
rename from src/gds/awgtpman/dtt/map_v3.h
rename to src/shmem/map_v3.h
index 9a77000029cd0cdb5b9e3125895a1b11745e4f5b..eeec839615826966a37ff417fc73faf368cfb402 100644
--- a/src/gds/awgtpman/dtt/map_v3.h
+++ b/src/shmem/map_v3.h
@@ -6,19 +6,14 @@
  * DAQ system inter-processor communication definitions.
  */
 
-#define DCU_COUNT 26
+#include "daq_core_defs.h"
+
 #define DAQ_BASE_ADDRESS	0x2000000
 #define DAQ_DATA_BASE_ADD	(DAQ_BASE_ADDRESS + 0x100000)
 
-#define DAQ_DCU_SIZE		0x400000
-#define DAQ_DCU_BLOCK_SIZE	(DAQ_DCU_SIZE/16)
-
 #define DAQ_EDCU_SIZE		0x400000
 #define DAQ_EDCU_BLOCK_SIZE	0x20000
 
-#define DAQ_NUM_DATA_BLOCKS	16
-#define DAQ_NUM_DATA_BLOCKS_PER_SECOND	16
-
 /*
  * Inter-processor communication structures
  */
@@ -46,6 +41,48 @@ struct rmIpcStr {       /* IPC area structure                   */
   blockPropT bp [DAQ_NUM_DATA_BLOCKS];  /* An array of block property structures */
 };
 
+/** Identification for an LSC test point channel
+
+    @author DS, Jul. 1998
+    @see Arbitrary Waveform Generator
+*********************************************************************/
+#define	AWG_LSC_TESTPOINT		1
+
+/** Identification for an ASC test point channel
+
+    @author DS, Jul. 1998
+    @see Arbitrary Waveform Generator
+*********************************************************************/
+#define	AWG_ASC_TESTPOINT		2
+
+/** Identification for a DAC channel
+
+    @author DS, Jul. 1998
+    @see Arbitrary Waveform Generator
+*********************************************************************/
+#define	AWG_DAC_CHANNEL			3
+
+/** Identification for a DS340 channel
+
+    @author DS, Jul. 1998
+    @see Arbitrary Waveform Generator
+*********************************************************************/
+#define	AWG_DS340_CHANNEL		4
+
+/** Identification for a channel which gets written to file.
+
+    @author DS, Jul. 1998
+    @see Arbitrary Waveform Generator
+*********************************************************************/
+#define	AWG_FILE_CHANNEL		5
+
+/** Identification for a channel which gets written to an aboslute
+    address in reflective memory.
+
+    @author DS, Jul. 1998
+    @see Arbitrary Waveform Generator
+*********************************************************************/
+#define	AWG_MEM_CHANNEL			6
 /*
  * DCU IDs
  */
@@ -210,7 +247,7 @@ static unsigned int const dcuNet[DCU_COUNT] = {3,3,3,3,0,
 #define DAQ_GDS_DCU_NUM       4
 
 /* Total number of channels allowed per DCU */
-#define DCU_MAX_CHANNELS	128
+#define DCU_MAX_CHANNELS	512
 
 /* RFM offset of DCU DAQ configuration area; used for communicating
    configuration from Epics processor to a front-end processor */
diff --git a/src/shmem/readme.txt b/src/shmem/readme.txt
new file mode 100644
index 0000000000000000000000000000000000000000..151457bf29adde622672e77285d1afebd6082c9c
--- /dev/null
+++ b/src/shmem/readme.txt
@@ -0,0 +1,7 @@
+The shmem directory contains header files describing the name, size and structure used for a shared memory block.
+
+The definitive version of the structure is also defined here under a separate file.
+
+shared memories can either be host-wide, or model-specific.
+For host-wide shared memories, the full name is given as shmem_<memname>_name.
+For model_specific shared memories, a suffix is given as shmem_<memname>_suffix.  Append this suffix to the model name to get the shared memory name.
diff --git a/src/shmem/shmem_all.h b/src/shmem/shmem_all.h
new file mode 100644
index 0000000000000000000000000000000000000000..4cf7c4dadc7977643606071a971940941ed9c885
--- /dev/null
+++ b/src/shmem/shmem_all.h
@@ -0,0 +1,10 @@
+//
+// Created by erik.vonreis on 4/29/21.
+//
+
+#ifndef DAQD_TRUNK_SHMEM_ALL_H
+#define DAQD_TRUNK_SHMEM_ALL_H
+
+#include "shmem_awg.h"
+
+#endif // DAQD_TRUNK_SHMEM_ALL_H
diff --git a/src/shmem/shmem_awg.h b/src/shmem/shmem_awg.h
new file mode 100644
index 0000000000000000000000000000000000000000..2747ee7d8518b21dd48355a23f725a7c98169346
--- /dev/null
+++ b/src/shmem/shmem_awg.h
@@ -0,0 +1,11 @@
+#ifndef SHMEM_AWG_H
+#define SHMEM_AWG_H
+
+#include "awg_data.h"
+
+#define SHMEM_AWG_SUFFIX "_awg"
+#define SHMEM_AWG_SIZE (64*(1024)*(1024))
+
+#define SHMEM_AWG_STRUCT AWG_DATA;
+
+#endif //SHMEM_AWG_H
diff --git a/src/shmem/shmem_header.h b/src/shmem/shmem_header.h
new file mode 100644
index 0000000000000000000000000000000000000000..88f854e75053f56f599170fc42cf2bdc7aba7e23
--- /dev/null
+++ b/src/shmem/shmem_header.h
@@ -0,0 +1,38 @@
+//
+// Created by erik.vonreis on 4/27/21.
+//
+
+#ifndef DAQD_TRUNK_SHMEM_HEADER_H
+#define DAQD_TRUNK_SHMEM_HEADER_H
+
+// header to suppport version control for shared memory structures.
+typedef struct SHMEM_HEADER
+{
+    uint32_t magic_bytes;  // used to verify structure is using this header
+    uint32_t struct_id;  //unique id that identifies the structure type (1 = AWG_DATA, 2 = ...
+    uint32_t version;  // should be 1 or more
+} SHMEM_HEADER;
+
+#define SHMEM_HEADER_MAGIC_BYTES (0xf000beef)
+
+/**
+ * Pass a pointer to the header, and a version number.
+ * Sets version number and magic bytes.
+ */
+#define SHMEM_SET_VERSION(HEADER_PTR, ID, VERSION)  { SHMEM_HEADER *_h_p_ = HEADER_PTR; \
+        _h_p_->magic_bytes = SHMEM_HEADER_MAGIC_BYTES;                                  \
+        _h_p_->struct_id = ID;                                                                                \
+        _h_p_->version = VERSION; }
+
+/**
+ * Get the version number of a shared memory structure
+ * Returns 0 if the structure does not start with a properly intialized
+ * SHMEM_HEADER
+ */
+#define SHMEM_GET_VERSION(HDR_PTR)  ( (((SHMEM_HEADER *)HDR_PTR)->magic_bytes == SHMEM_HEADER_MAGIC_BYTES) \
+                                      ? ((SHMEM_HEADER *)HDR_PTR)->version : 0 )
+
+#define SHMEM_GET_ID(HDR_PTR)  ( (((SHMEM_HEADER *)HDR_PTR)->magic_bytes == SHMEM_HEADER_MAGIC_BYTES) \
+                                      ? ((SHMEM_HEADER *)HDR_PTR)->struct_id : 0 )
+
+#endif // DAQD_TRUNK_SHMEM_HEADER_H