Index: soft/giet_vm/giet_python/mapping.py
===================================================================
--- soft/giet_vm/giet_python/mapping.py	(revision 305)
+++ soft/giet_vm/giet_python/mapping.py	(revision 319)
@@ -1,113 +1,523 @@
 #!/usr/bin/env python
 
-#######################################################################################
+import sys
+
+##########################################################################################
 #   file   : giet_mapping.py
 #   date   : april 2014
 #   author : Alain Greiner
-#######################################################################################
-#  This file contains the classes required to define a generic mapping in python
-#  for the GIET_VM.
-# - A 'Mapping' contains + various structural constants,
-#                        + a 'Cluster' set,     (hardware architecture)
-#                        + a 'Vseg' set,        (kernel virtual segments mapping)
-#                        + a 'Vspace' set       (several user applications).
-# - A 'Cluster' contains + coordinates (x,y), 
-#                        + a 'Pseg' set,        (all physical segments in cluster)
-#                        + a 'Proc' set,        (processors in cluster)
-#                        + a 'Peripheral' set   (peripherals in cluster)
-# - A 'Vspace' contains  + a 'Vseg' set,        (user virtual segments mapping)
-#                        + a 'Task' set         (user tasks mapping)
-####################################################################################
-
-#########################
+##########################################################################################
+#  This file contains the classes required to define a mapping for the GIET_VM.
+# - A 'Mapping' contains a set of 'Cluster'   (hardware architecture)
+#                        a set of 'Vseg'      (kernel virtual segments mapping)
+#                        a set of 'Vspace'    (several user applications).
+# - A 'Cluster' contains a set of 'Pseg'      (all physical segments in cluster)
+#                        a set of 'Proc'      (processors in cluster)
+#                        a set of 'Periph'    (peripherals in cluster)
+#                        a set of 'Coproc'    (coprocessors in cluster)
+# - A 'Vspace' contains  a set of 'Vseg'      (user virtual segments mapping)
+#                        a set of 'Task'      (user tasks mapping)
+# - A 'Vseg'   contains  a set of 'Vobj'
+# - A 'Periph' contains  a set of 'Irq'       (only for XCU, ICU and PIC types )
+# - A 'Coproc' contains  a set of 'Cpports'   (one port per MWMR channel)
+##########################################################################################
+# Implementation Note
+# As described above, the various objects are distributed in the PYTHON structure:
+# For example the psegs set is split in several subsets (one subset per cluster),
+# or the tasks set is split in several subsets (one subset per vspace), etc...
+# In the C binary data structure used by the giet_vm, all objects of same type
+# are stored in a linear array (one single array for all psegs for example). 
+# For all objects, we compute and store in the  PYTHON object itsel a "global index" 
+# corresponding to the index in this global array, and this index can be used as 
+# a pseudo-pointer to identify a specific object of a given type.
+##########################################################################################
+
+######################################################################################
+# These global lists must be consistent with enums in mapping_info.h or irq_handler.h
+######################################################################################
+PERIPHTYPES =    [
+                  'CMA',
+                  'DMA',
+                  'FBF',
+                  'ICU',
+                  'IOB',
+                  'IOC',
+                  'MMC',
+                  'MWR',
+                  'NIC',
+                  'ROM',
+                  'SIM',
+                  'TIM',
+                  'TTY',
+                  'XCU',
+                  'PIC',
+                 ]
+
+PERIPHSUBTYPES = [
+                  'BDV',
+                  'HBA',
+                  'SPI',
+                  'NONE',
+                 ]
+
+IRQTYPES =       [
+                  'HWI',
+                  'WTI',
+                  'PTI',
+                 ]
+
+ISRTYPES =       [
+                  'ISR_DEFAULT',
+                  'ISR_TICK',
+                  'ISR_TTY_RX',
+                  'ISR_TTY_TX',
+                  'ISR_BDV',
+                  'ISR_TIMER',
+                  'ISR_WAKUP',
+                  'ISR_NIC_RX',
+                  'ISR_NIC_TX',
+                  'ISR_CMA',
+                  'ISR_MMC',
+                  'ISR_DMA',
+                  'ISR_SPI',
+                 ]
+
+VOBJTYPES =      [
+                  'ELF',
+                  'BLOB',
+                  'PTAB',
+                  'PERI',
+                  'MWMR',
+                  'LOCK',
+                  'BUFFER',
+                  'BARRIER',
+                  'CONST',
+                  'MEMSPACE',
+                  'SCHED',
+                 ]
+
+VSEGMODES =      [
+                  '____',
+                  '___U',
+                  '__W_',
+                  '__WU',
+                  '_X__',
+                  '_X_U',
+                  '_XW_',
+                  '_XWU',
+                  'C___',
+                  'C__U',
+                  'C_W_',
+                  'C_WU',
+                  'CX__',
+                  'CX_U',
+                  'CXW_',
+                  'CXWU',
+                 ]
+
+PSEGTYPES =      [
+                  'RAM',
+                  'ROM',        # deprecated => use PERI
+                  'PERI',
+                 ]
+
+CP_PORT_DIRS =   [
+                  'TO_COPROC',
+                  'FROM_COPROC',
+                 ]
+
+##########################################################################################
 class Mapping( object ):
-#########################
+##########################################################################################
     def __init__( self,
-                  name,                   # mapping name 
-                  x_size,                 # number of clusters in a row
-                  y_size,                 # number of clusters in a column
-                  nb_procs,               # max number of processors per cluster
-                  x_width      = 4,       # number of bits encoding x coordinate
-                  y_width      = 4,       # number of bits encoding y coordinate
-                  paddr_width  = 32,      # number of bits for physical address
-                  coherence    = False,   # hardware cache coherence 
-                  irq_per_proc = 1,       # number or IRQ lines from XCU to processor 
-                  use_ram_disk = False,   # architecture contains ram_disk when true
-                  x_io         = 0,       # cluster_io x coordinate
-                  y_io         = 0 ):     # cluster_io y coordinate
-
-        self.name         = name
-        self.paddr_width  = paddr_width           
-        self.coherence    = coherence
-        self.x_size       = x_size
-        self.y_size       = y_size
-        self.x_width      = x_width
-        self.y_width      = y_width
-        self.irq_per_proc = irq_per_proc
-        self.nb_procs     = nb_procs      
-        self.use_ram_disk = use_ram_disk
-        self.x_io         = x_io
-        self.y_io         = y_io
-
-        self.total_procs  = 0
-        self.total_globs  = 0
-
-        # clusters array
-        self.clusters     = []
-        for x in xrange (1<<x_width):
-            for y in xrange (1<<y_width):
-                self.clusters.append( Cluster(x,y) )
-
-        # globals array
-        self.globs        = []
-
-        # vspace array
-        self.vspaces      = []
+                  name,                          # mapping name 
+                  x_size,                        # number of clusters in a row
+                  y_size,                        # number of clusters in a column
+                  procs_max,                     # max number of processors per cluster
+                  x_width = 4,                   # number of bits encoding x coordinate
+                  y_width = 4,                   # number of bits encoding y coordinate
+                  paddr_width = 40,              # number of bits for physical address
+                  coherence = 1,                 # hardware cache coherence when non-zero
+                  irq_per_proc = 1,              # number or IRQs from XCU to processor 
+                  use_ramdisk = False,           # use ramdisk when true
+                  x_io = 0,                      # cluster_io x coordinate
+                  y_io = 0,                      # cluster_io y coordinate
+                  reset_address = 0xBFC00000 ):  # Processor wired boot_address
+
+        self.signature      = 0xDACE2014
+        self.name           = name
+        self.paddr_width    = paddr_width           
+        self.coherence      = coherence
+        self.x_size         = x_size
+        self.y_size         = y_size
+        self.x_width        = x_width
+        self.y_width        = y_width
+        self.irq_per_proc   = irq_per_proc
+        self.procs_max      = procs_max      
+        self.use_ramdisk    = use_ramdisk
+        self.x_io           = x_io
+        self.y_io           = y_io
+        self.reset_address  = reset_address
+
+        self.vseg_increment = 0x10000
+
+        self.total_vspaces  = 0
+        self.total_globals  = 0
+        self.total_psegs    = 0
+        self.total_vsegs    = 0
+        self.total_vobjs    = 0
+        self.total_tasks    = 0
+        self.total_procs    = 0
+        self.total_irqs     = 0
+        self.total_coprocs  = 0
+        self.total_cpports  = 0
+        self.total_periphs  = 0
+
+        self.clusters       = []
+        self.globs          = []
+        self.vspaces        = []
+
+        for x in xrange( self.x_size ):
+            for y in xrange( self.y_size ):
+                cluster = Cluster( x , y )
+                cluster.index = (x * self.y_size) + y 
+                self.clusters.append( cluster )
 
         return
 
-    ##########################
-    def addPseg( self, pseg ):
-        cluster_xy = pseg.base >> (self.paddr_width - self.x_width - self.y_width)
+    ##########################    add a ram pseg in a cluster
+    def addRam( self, 
+                name,                  # pseg name
+                base,                  # pseg base address
+                size ):                # pseg length (bytes)
+       
+        # check coordinates (obtained from the base address)
+        cluster_xy = base >> (self.paddr_width - self.x_width - self.y_width)
         x = cluster_xy >> (self.y_width);
         y = cluster_xy & ((1 << self.y_width) - 1) 
-        if (x >= self.x_size) or (y >= self.y_size):
-            print '(x,y) coordinates too large for pdeg %s' % str(pseg)
-        self.clusters[cluster_xy].psegs.append( pseg )
-        return
-
-    ######################################
-    def addPeripheral( self, peripheral ):
-        cluster_xy = peripheral.pseg.base >> (self.paddr_width - self.x_width - self.y_width)
+
+        assert (base & 0xFFF) == 0
+
+        assert (x < self.x_size) and (y < self.y_size)
+        
+        cluster_id = (x * self.y_size) + y
+
+        # add one pseg in the mapping
+        pseg = Pseg( name, base, size, x, y, 'RAM' )
+        self.clusters[cluster_id].psegs.append( pseg )
+        pseg.index = self.total_psegs
+        self.total_psegs += 1
+
+        return pseg
+
+    ##############################   add a peripheral and the associated pseg in a cluster
+    def addPeriph( self, 
+                   name,               # associated pseg name
+                   base,               # associated pseg base address
+                   size,               # associated pseg length (bytes)
+                   ptype,              # peripheral type 
+                   subtype  = 'NONE',  # peripheral subtype
+                   channels = 1,       # number of channels
+                   arg      = 0 ):     # optional argument (semantic depends on ptype)
+
+        # check cluster coordinates (obtained from the base address)
+        cluster_xy = base >> (self.paddr_width - self.x_width - self.y_width)
         x = cluster_xy >> (self.y_width);
         y = cluster_xy & ((1 << self.y_width) - 1) 
-        if (x >= self.x_size) or (y >= self.y_size):
-            print '(x,y) coordinates too large for pdeg %s' % str(pseg)
-        self.clusters[cluster_xy].peripherals.append( peripheral )
+
+        assert (x < self.x_size) and (y < self.y_size)
+
+        assert (base & 0xFFF) == 0
+
+        assert ptype in PERIPHTYPES
+
+        assert subtype in PERIPHSUBTYPES
+
+        cluster_id = (x * self.y_size) + y
+
+        # add one pseg into mapping
+        pseg = Pseg( name, base, size, x, y, 'PERI' )
+        self.clusters[cluster_id].psegs.append( pseg )
+        pseg.index = self.total_psegs
+        self.total_psegs += 1
+
+        # add one periph into mapping
+        periph = Periph( pseg, ptype, subtype, channels, arg ) 
+        self.clusters[cluster_id].periphs.append( periph )
+        periph.index = self.total_periphs
+        self.total_periphs += 1
+
+        return periph
+
+    ################################   add an IRQ in a peripheral
+    def addIrq( self,
+                periph,                # peripheral containing IRQ (PIC or XCU)
+                index,                 # peripheral input port index
+                isrtype,               # ISR type
+                channel = 0 ):         # channel for multi-channels ISR
+
+        assert isrtype in ISRTYPES
+
+        assert index < 32
+
+        # add one irq into mapping  
+        irq = Irq( 'HWI', index , isrtype, channel )
+        periph.irqs.append( irq )
+        irq.index = self.total_irqs
+        self.total_irqs += 1
+
+        return irq
+
+    ##########################    add a processor in a cluster
+    def addProc( self, 
+                 x,                    # cluster x coordinate
+                 y,                    # cluster y coordinate
+                 p ):                  # processor local index
+
+        assert (x < self.x_size) and (y < self.y_size)
+
+        cluster_id = (x * self.y_size) + y
+
+        # add one proc into mapping 
+        proc = Processor( x, y, p )
+        self.clusters[cluster_id].procs.append( proc )
+        proc.index = self.total_procs
+        self.total_procs += 1
+
+        return proc
+
+    ##############################    add a coprocessor in a cluster
+    def addCoproc( self, 
+                   name,               # associated pseg name
+                   base,               # associated pseg base address
+                   size ):             # associated pseg length
+        
+        # check cluster coordinates (obtained from the base address)
+        cluster_xy = base >> (self.paddr_width - self.x_width - self.y_width)
+        x = cluster_xy >> (self.y_width);
+        y = cluster_xy & ((1 << self.y_width) - 1) 
+
+        assert (x < self.x_size) and (y < self.y_size)
+
+        cluster_id = (x * self.y_size) + y
+
+        # add one pseg into mapping
+        pseg = Pseg( name, base, size, x, y, 'PERI' )
+        self.clusters[cluster_id].psegs.append( pseg )
+        pseg.index = self.total_psegs
+        self.total_psegs += 1
+
+        # add one coproc into mapping
+        periph = Coproc( pseg ) 
+        self.clusters[cluster_id].coprocs.append( coproc )
+        periph.index = self.total_coprocs
+        self.total_coprocs += 1
+
+        return coproc
+
+    ##################################    add a port in a coprocessor 
+    def addPort( self, 
+                 coproc,               # coprocessor containing the port
+                 direction,            # direction (TO_COPROC / FROM_COPROC)
+                 vspacename,           # name of vspace using the coproc
+                 mwmrname ):           # name of the vobj defining the MWMR channel
+
+        assert direction in CP_PORT_DIRS
+
+        # add one cpport into mapping
+        port = Cpport( direction, vspacename, mwmrname )
+        coproc.ports.append( port )
+        port.index = self.total_cpports
+        self.total_cpports += 1
+
+        return port
+
+    ############################    add one (or several) global vseg into mapping 
+    def addGlobal( self, 
+                   name,                # vseg name
+                   vbase,               # virtual base address
+                   size,                # vobj length (bytes)
+                   mode,                # CXWU flags
+                   vtype,               # vobj type
+                   x,                   # destination x coordinate
+                   y,                   # destination y coordinate
+                   pseg,                # destination pseg name
+                   identity   = False,  # identity mapping required if true
+                   replicated = False,  # replicated in all clusters if true
+                   binpath    = '' ):   # pathname for binary code
+
+        assert (identity and replicated) == False
+
+        assert mode in VSEGMODES
+
+        assert vtype in VOBJTYPES
+
+        assert (vbase & 0xFFF) == 0
+
+        assert (x < self.x_size) and (y < self.y_size)
+
+        if ( replicated ):                  # replicated
+            for x_rep in xrange( self.x_size ):            
+                for y_rep in xrange( self.y_size ):            
+                    vbase_rep = vbase + (((x_rep << self.y_width) + y_rep) << 16)
+                    name_rep  = name + '_%d_%d' % ( x_rep , y_rep )
+  
+                    # add one vseg [x,y] into mapping
+                    vseg = Vseg( name_rep, vbase_rep, mode, x_rep, y_rep, pseg, identity )
+                    self.globs.append( vseg )
+                    self.total_globals += 1
+                    vseg.index = self.total_vsegs 
+                    self.total_vsegs += 1
+            
+                    # add one vobj [x,y] in the mapping
+                    vobj = Vobj( name_rep, size, vtype, binpath, 0, 0 )
+                    vseg.vobjs.append( vobj )
+                    vobj.index = self.total_vobjs
+                    self.total_vobjs += 1
+
+        else:                          # single vseg
+            # add one vseg into mapping
+            vseg = Vseg( name, vbase, mode, x, y, pseg, identity )
+            self.globs.append( vseg )
+            self.total_globals += 1
+            vseg.index = self.total_vsegs 
+            self.total_vsegs += 1
+            
+            # add one vobj into mapping
+            vobj = Vobj( name, size, vtype, binpath, 0, 0 )
+            vseg.vobjs.append( vobj )
+            vobj.index = self.total_vobjs
+            self.total_vobjs += 1
+
         return
 
-    ###########################
-    def addProc ( self, proc ):
-        cluster_xy = (proc.x << self.y_width) + proc.y
-        self.clusters[cluster_xy].procs.append( proc )
-        self.total_procs += 1
-        if (proc.x >= self.x_size) or (proc.y >= self.y_size):
-            print '(x,y) coordinates too large for node %s' % str(proc)
-        return
-
-    ############################
-    def addGlobal( self, vseg ):
-        self.globs.append( vseg ) 
-        return
-
-    ##############################
-    def addVspace( self, vspace ):
+    ################################    add a vspace into mapping
+    def addVspace( self, 
+                   name,                # vspace name
+                   startname ):         # name of vobj containing start_vector
+
+        # add one vspace into mapping
+        vspace = Vspace( name, startname )
         self.vspaces.append( vspace )
-        return
+        vspace.index = self.total_vspaces
+        self.total_vspaces += 1
+
+        return vspace
     
-    ####################
-    def __str__( self ):    # xml generation for mapping
+    #################################   add a private vseg and a vobj in a vspace
+    def addVseg( self,
+                 vspace,                # vspace containing the vseg 
+                 name,                  # vseg name
+                 vbase,                 # virtual base address
+                 size,                  # vobj length (bytes)
+                 mode,                  # CXWU flags
+                 vtype,                 # vobj type
+                 x,                     # destination x coordinate
+                 y,                     # destination y coordinate
+                 pseg,                  # destination pseg name
+                 binpath = '',          # pathname for binary code
+                 align   = 0,           # alignment required
+                 init    = 0 ):         # initial value
+
+        assert mode in VSEGMODES
+
+        assert vtype in VOBJTYPES
+
+        assert (x < self.x_size) and (y < self.y_size)
+
+        # add one vseg into mapping
+        vseg = Vseg( name, vbase, mode, x, y, pseg )
+        vspace.vsegs.append( vseg )
+        vseg.index = self.total_vsegs
+        self.total_vsegs += 1
+
+        # add one vobj into mapping
+        vobj = Vobj( name, size, vtype, binpath, align, init )
+        vseg.vobjs.append( vobj )
+        vobj.index = self.total_vobjs
+        self.total_vobjs += 1
+
+        return vseg
+
+    ################################    add a vobj in a private vseg
+    def addVobj( self, 
+                 vseg,                  # vseg containing vobj
+                 name,                  # vobj name
+                 size,                  # vobj length (bytes)
+                 vtype,                 # vobj type
+                 binpath = '',          # pathname to binary
+                 align   = 0,           # alignment constraint
+                 init    = 0 ):         # initial value
+
+        assert vtype in VOBJTYPES
+
+        # add one vobj into mapping
+        vobj = Vobj( name, size, vtype, binpath, align, init )
+        vseg.vobjs.append( vobj )
+        vobj.index = self.total_vobjs
+        self.total_vobjs += 1
+
+        return vobj
+
+    ################################    add a task in a vspace 
+    def addTask( self, 
+                 vspace,                # vspace containing task
+                 name,                  # task name
+                 trdid,                 # task index in vspace
+                 x,                     # destination x coordinate
+                 y,                     # destination y coordinate
+                 lpid,                  # destination processor local index
+                 stackname,             # name of vobj containing stack
+                 heapname,              # name of vobj containing heap
+                 startid,               # index in start_vector
+                 usetty = False,        # request a private TTY channel
+                 usenic = False,        # request a private NIC channel
+                 usecma = False,        # request a private CMA channel
+                 usehba = False,        # request a private HBA channel
+                 usetim = False ):      # request a private TIM channel
+                 
+        assert (x < self.x_size) and (y < self.y_size)
+
+        assert lpid < self.procs_max
+
+        # add one task into mapping 
+        task = Task( name, trdid, x, y, lpid, stackname, heapname, startid,
+                     usetty, usenic, usecma, usehba, usetim )
+        vspace.tasks.append( task )
+        task.index = self.total_tasks
+        self.total_tasks += 1
+
+        return task
+
+    #################################
+    def str2bytes( self, nbytes, s ):    # string => nbytes_packed byte array
+
+        byte_stream = bytearray()
+        length = len( s )
+        if length < (nbytes - 1):
+            for b in s:
+                byte_stream.append( b )
+            for x in xrange(nbytes-length):
+                byte_stream.append( '\0' )
+        else:
+            print 'error in str2bytes() string %s too long' % s
+            sys.exit(1)
+
+        return byte_stream
+
+    ###################################
+    def int2bytes( self, nbytes, val ):    # integer => nbytes litle endian byte array  
+
+        byte_stream = bytearray()
+        for n in xrange( nbytes ):
+            byte_stream.append( (val >> (n<<3)) & 0xFF )
+
+        return byte_stream
+
+    ################
+    def xml( self ):    # xml file generation for mapping
+
         s = '<?xml version="1.0"?>\n\n'
-        s += '<mapping_info signature    = "0xDACE2014"\n'
+        s += '<mapping_info signature    = "0x%x"\n' % (self.signature)
         s += '              name         = "%s"\n'   % (self.name)
         s += '              x_size       = "%d"\n'   % (self.x_size)
@@ -116,383 +526,2009 @@
         s += '              y_width      = "%d"\n'   % (self.y_width)
         s += '              irq_per_proc = "%d"\n'   % (self.irq_per_proc)
-        s += '              use_ram_disk = "%d"\n'   % (self.use_ram_disk)
+        s += '              use_ramdisk  = "%d"\n'   % (self.use_ramdisk)
         s += '              x_io         = "%d"\n'   % (self.x_io)
         s += '              y_io         = "%d" >\n' % (self.y_io)
+        s += '\n'
+
         s += '    <clusterset>\n'
         for x in xrange ( self.x_size ):
             for y in xrange ( self.y_size ):
-                cluster_xy = (x << self.y_width) + y 
-                s += str( self.clusters[cluster_xy] )
+                cluster_id = (x * self.y_size) + y 
+                s += self.clusters[cluster_id].xml()
         s += '    </clusterset>\n'
+        s += '\n'
+
         s += '    <globalset>\n'
-        for vseg in self.globs:
-            s += str ( vseg )
+        for vseg in self.globs: s += vseg.xml()
         s += '    </globalset>\n'
+        s += '\n'
+
         s += '    <vspaceset>\n'
-        for vspace in self.vspaces:
-            s += str( vspace )
+        for vspace in self.vspaces: s += vspace.xml()
         s += '    </vspaceset>\n'
+
         s += '</mapping_info>\n'
         return s
-       
-#######################
+
+    #########################
+    def cbin( self, verbose ):     # C binary structure generation for mapping
+
+        byte_stream = bytearray()
+
+        # header
+        byte_stream += self.int2bytes(4,  self.signature)
+        byte_stream += self.int2bytes(4,  self.x_size)         
+        byte_stream += self.int2bytes(4,  self.y_size)       
+        byte_stream += self.int2bytes(4,  self.x_width)     
+        byte_stream += self.int2bytes(4,  self.y_width)   
+        byte_stream += self.int2bytes(4,  self.x_io)     
+        byte_stream += self.int2bytes(4,  self.y_io)   
+        byte_stream += self.int2bytes(4,  self.irq_per_proc)   
+        byte_stream += self.int2bytes(4,  self.use_ramdisk)   
+        byte_stream += self.int2bytes(4,  self.total_globals)   
+        byte_stream += self.int2bytes(4,  self.total_vspaces)   
+        byte_stream += self.int2bytes(4,  self.total_psegs)   
+        byte_stream += self.int2bytes(4,  self.total_vsegs)   
+        byte_stream += self.int2bytes(4,  self.total_vobjs)   
+        byte_stream += self.int2bytes(4,  self.total_tasks)   
+        byte_stream += self.int2bytes(4,  self.total_procs)   
+        byte_stream += self.int2bytes(4,  self.total_irqs)   
+        byte_stream += self.int2bytes(4,  self.total_coprocs)   
+        byte_stream += self.int2bytes(4,  self.total_cpports)   
+        byte_stream += self.int2bytes(4,  self.total_periphs)     
+        byte_stream += self.str2bytes(32, self.name)
+
+        if ( verbose ):
+            print '\n' 
+            print 'name          = %s' % self.name
+            print 'signature     = %x' % self.signature
+            print 'x_size        = %d' % self.x_size
+            print 'y_size        = %d' % self.y_size
+            print 'x_width       = %d' % self.x_width
+            print 'y_width       = %d' % self.y_width
+            print 'x_io          = %d' % self.x_io  
+            print 'y_io          = %d' % self.y_io  
+            print 'irq_per_proc  = %d' % self.irq_per_proc
+            print 'use_ramdisk   = %d' % self.use_ramdisk
+            print 'total_globals = %d' % self.total_globals
+            print 'total_psegs   = %d' % self.total_psegs  
+            print 'total_vsegs   = %d' % self.total_vsegs  
+            print 'total_vobjs   = %d' % self.total_vobjs  
+            print 'total_tasks   = %d' % self.total_tasks  
+            print 'total_procs   = %d' % self.total_procs  
+            print 'total_irqs    = %d' % self.total_irqs   
+            print 'total_coprocs = %d' % self.total_coprocs
+            print 'total_cpports = %d' % self.total_cpports
+            print 'total_periphs = %d' % self.total_periphs
+            print '\n' 
+
+        # clusters array
+        index = 0
+        for cluster in self.clusters:
+            byte_stream += cluster.cbin( self, verbose, index )
+            index += 1
+
+        if ( verbose ): print '\n'
+
+        # psegs array
+        index = 0
+        for cluster in self.clusters:
+            for pseg in cluster.psegs: 
+                byte_stream += pseg.cbin( self, verbose, index, cluster )
+                index += 1
+
+        if ( verbose ): print '\n'
+
+        # vspaces array
+        index = 0
+        for vspace in self.vspaces:   
+            byte_stream += vspace.cbin( self, verbose, index ) 
+            index += 1
+
+        if ( verbose ): print '\n'
+
+        # vsegs array
+        index = 0
+        for vseg in self.globs:
+            byte_stream += vseg.cbin( self, verbose, index )
+            index += 1
+        for vspace in self.vspaces:
+            for vseg in vspace.vsegs: 
+                byte_stream += vseg.cbin( self, verbose, index )
+                index += 1
+
+        if ( verbose ): print '\n'
+
+        # vobjs array
+        index = 0
+        for vseg in self.globs:
+            for vobj in vseg.vobjs:
+                byte_stream += vobj.cbin( self, verbose, index )
+                index += 1
+        for vspace in self.vspaces:
+            for vseg in vspace.vsegs: 
+                for vobj in vseg.vobjs:
+                    byte_stream += vobj.cbin( self, verbose, index ) 
+                    index += 1
+
+        if ( verbose ): print '\n'
+
+        # tasks array
+        index = 0
+        for vspace in self.vspaces:
+            for task in vspace.tasks: 
+                byte_stream += task.cbin( self, verbose, index, vspace )
+                index += 1
+
+        if ( verbose ): print '\n'
+
+        # procs array
+        index = 0
+        for cluster in self.clusters:
+            for proc in cluster.procs: 
+                byte_stream += proc.cbin( self, verbose, index )
+                index += 1
+                
+        if ( verbose ): print '\n'
+
+        # irqs array
+        index = 0 
+        for cluster in self.clusters:
+            for periph in cluster.periphs:
+                for irq in periph.irqs:
+                    byte_stream += irq.cbin( self, verbose, index )
+                    index += 1
+
+        if ( verbose ): print '\n'
+
+        # coprocs array
+        index = 0
+        for cluster in self.clusters:
+            for coproc in cluster.coprocs: 
+                byte_stream += coproc.cbin( self, verbose, index ) 
+                index += 1
+
+        if ( verbose ): print '\n'
+
+        # cpports array
+        index = 0
+        for cluster in self.clusters:
+            for coproc in cluster.coprocs: 
+                for port in coproc.ports:
+                    byte_stream += port.cbin( self, verbose, index )
+                    index += 1
+
+        if ( verbose ): print '\n'
+
+        # periphs array
+        index = 0
+        for cluster in self.clusters:
+            for periph in cluster.periphs: 
+                byte_stream += periph.cbin( self, verbose, index )
+                index += 1
+
+        return byte_stream
+    # end of cbin()
+ 
+    #######################
+    def giet_vsegs( self ):      # compute string for giet_vsegs.ld file 
+                                 # required by giet_vm compilation
+
+        # search the vsegs required for the giet_vsegs.ld  
+        boot_code_found      = False
+        boot_data_found      = False
+        kernel_uncdata_found = False
+        kernel_data_found    = False
+        kernel_code_found    = False
+        kernel_init_found    = False
+        for vseg in self.globs:
+            if ( vseg.name == 'seg_boot_code' ):
+                boot_code_vbase      = vseg.vbase 
+                boot_code_size       = vseg.vobjs[0].length
+                boot_code_found      = True
+
+            if ( vseg.name == 'seg_boot_data' ):  
+                boot_data_vbase      = vseg.vbase 
+                boot_data_size       = vseg.vobjs[0].length
+                boot_data_found      = True
+
+            if ( vseg.name == 'seg_kernel_uncdata' ):
+                kernel_uncdata_vbase = vseg.vbase 
+                kernel_uncdata_size  = vseg.vobjs[0].length
+                kernel_uncdata_found = True
+
+            if ( vseg.name == 'seg_kernel_data' ):
+                kernel_data_vbase    = vseg.vbase 
+                kernel_data_size     = vseg.vobjs[0].length
+                kernel_data_found    = True
+
+            if ( vseg.name == 'seg_kernel_code' ):
+                kernel_code_vbase    = vseg.vbase 
+                kernel_code_size     = vseg.vobjs[0].length
+                kernel_code_found    = True
+
+            if ( vseg.name == 'seg_kernel_init' ):
+                kernel_init_vbase    = vseg.vbase 
+                kernel_init_size     = vseg.vobjs[0].length
+                kernel_init_found    = True
+
+        # check if all required vsegs have been found
+        if ( boot_code_found      == False ): 
+             print 'error in giet_vsegs() : seg_boot_code vseg missing'
+             sys.exit()
+
+        if ( boot_data_found      == False ): 
+             print 'error in giet_vsegs() : seg_boot_data vseg missing'
+             sys.exit()
+
+        if ( kernel_data_found    == False ): 
+             print 'error in giet_vsegs() : seg_kernel_data vseg missing'
+             sys.exit()
+
+        if ( kernel_uncdata_found == False ):
+             print 'error in giet_vsegs() : seg_kernel_uncdata vseg missing'
+             sys.exit()
+
+        if ( kernel_code_found    == False ):
+             print 'error in giet_vsegs() : seg_kernel_data vseg missing'
+             sys.exit()
+
+        if ( kernel_init_found    == False ):
+             print 'error in giet_vsegs() : seg_kernel_init vseg missing'
+             sys.exit()
+
+        # build string
+        s =  '/* Generated by tsarmap for %s */\n'  % self.name 
+        s += '\n'
+
+        s += 'boot_code_vbase      = 0x%x;\n'   % boot_code_vbase 
+        s += 'boot_code_size       = 0x%x;\n'   % boot_code_size  
+        s += '\n'
+        s += 'boot_data_vbase      = 0x%x;\n'   % boot_data_vbase 
+        s += 'boot_data_size       = 0x%x;\n'   % boot_data_size  
+        s += '\n'
+        s += 'kernel_code_vbase    = 0x%x;\n'   % kernel_code_vbase 
+        s += 'kernel_code_size     = 0x%x;\n'   % kernel_code_size  
+        s += '\n'
+        s += 'kernel_data_vbase    = 0x%x;\n'   % kernel_data_vbase 
+        s += 'kernel_data_size     = 0x%x;\n'   % kernel_data_size  
+        s += '\n'
+        s += 'kernel_uncdata_vbase = 0x%x;\n'   % kernel_uncdata_vbase 
+        s += 'kernel_uncdata_size  = 0x%x;\n'   % kernel_uncdata_size  
+        s += '\n'
+        s += 'kernel_init_vbase    = 0x%x;\n'   % kernel_init_vbase 
+        s += 'kernel_init_size     = 0x%x;\n'   % kernel_init_size  
+        s += '\n'
+
+        return s
+        
+    ########################
+    def hard_config( self ):     # compute string for hard_config.h file required by
+                                 # - top.cpp compilation
+                                 # - giet_vm compilation
+                                 # - tsar_preloader compilation
+
+        nb_total_procs = 0
+
+        # for each peripheral type, define default values
+        # for pbase address, size, number of components, and channels 
+        nb_cma       = 0
+        cma_channels = 0
+        seg_cma_base = 0xFFFFFFFF
+        seg_cma_size = 0
+
+        nb_dma       = 0
+        dma_channels = 0
+        seg_dma_base = 0xFFFFFFFF
+        seg_dma_size = 0
+
+        nb_fbf       = 0
+        fbf_channels = 0
+        seg_fbf_base = 0xFFFFFFFF
+        seg_fbf_size = 0
+
+        nb_icu       = 0
+        icu_channels = 0
+        seg_icu_base = 0xFFFFFFFF
+        seg_icu_size = 0
+
+        nb_iob       = 0
+        iob_channels = 0
+        seg_iob_base = 0xFFFFFFFF
+        seg_iob_size = 0
+
+        nb_ioc       = 0
+        ioc_channels = 0
+        seg_ioc_base = 0xFFFFFFFF
+        seg_ioc_size = 0
+
+        nb_mmc       = 0
+        mmc_channels = 0
+        seg_mmc_base = 0xFFFFFFFF
+        seg_mmc_size = 0
+
+        nb_mwr       = 0
+        mwr_channels = 0
+        seg_mwr_base = 0xFFFFFFFF
+        seg_mwr_size = 0
+
+        nb_nic       = 0
+        nic_channels = 0
+        seg_nic_base = 0xFFFFFFFF
+        seg_nic_size = 0
+
+        nb_pic       = 0
+        pic_channels = 0
+        seg_pic_base = 0xFFFFFFFF
+        seg_pic_size = 0
+
+        nb_rom       = 0
+        rom_channels = 0
+        seg_rom_base = 0xFFFFFFFF
+        seg_rom_size = 0
+
+        nb_sim       = 0
+        sim_channels = 0
+        seg_sim_base = 0xFFFFFFFF
+        seg_sim_size = 0
+
+        nb_tim       = 0
+        tim_channels = 0
+        seg_tim_base = 0xFFFFFFFF
+        seg_tim_size = 0
+
+        nb_tty       = 0
+        tty_channels = 0
+        seg_tty_base = 0xFFFFFFFF
+        seg_tty_size = 0
+
+        nb_xcu       = 0
+        xcu_channels = 0
+        seg_xcu_base = 0xFFFFFFFF
+        seg_xcu_size = 0
+
+        use_bdv = False
+        use_spi = False
+        use_hba = False
+
+        # get peripherals attributes
+        for cluster in self.clusters:
+            for periph in cluster.periphs:
+                if   ( periph.ptype == 'CMA' ):  
+                    seg_cma_base = periph.pseg.base & 0xFFFFFFFF
+                    seg_cma_size = periph.pseg.size
+                    cma_channels = periph.channels
+                    nb_cma +=1
+
+                elif ( periph.ptype == 'DMA' ):  
+                    seg_dma_base = periph.pseg.base & 0xFFFFFFFF 
+                    seg_dma_size = periph.pseg.size
+                    dma_channels = periph.channels
+                    nb_dma +=1
+
+                elif ( periph.ptype == 'FBF' ):  
+                    seg_fbf_base = periph.pseg.base & 0xFFFFFFFF
+                    seg_fbf_size = periph.pseg.size
+                    fbf_channels = periph.channels
+                    nb_fbf +=1
+
+                elif ( periph.ptype == 'ICU' ):  
+                    seg_icu_base = periph.pseg.base & 0xFFFFFFFF
+                    seg_icu_size = periph.pseg.size
+                    icu_channels = periph.channels
+                    nb_icu +=1
+
+                elif ( periph.ptype == 'IOB' ):
+                    seg_iob_base = periph.pseg.base & 0xFFFFFFFF
+                    seg_iob_size = periph.pseg.size
+                    iob_channels = periph.channels
+                    nb_iob +=1
+
+                elif ( periph.ptype == 'IOC' ):  
+                    seg_ioc_base = periph.pseg.base & 0xFFFFFFFF
+                    seg_ioc_size = periph.pseg.size
+                    ioc_channels = periph.channels
+                    nb_ioc += 1
+                    if   ( periph.subtype == 'BDV' ): use_bdv = True
+                    elif ( periph.subtype == 'HBA' ): use_hba = True
+                    elif ( periph.subtype == 'SPI' ): use_spi = True
+
+                elif ( periph.ptype == 'MMC' ):
+                    seg_mmc_base = periph.pseg.base & 0xFFFFFFFF
+                    seg_mmc_size = periph.pseg.size
+                    mmc_channels = periph.channels
+                    nb_mmc +=1
+
+                elif ( periph.ptype == 'MWR' ):
+                    seg_mwr_base = periph.pseg.base & 0xFFFFFFFF
+                    seg_wmr_size = periph.pseg.size
+                    mwr_channels = periph.channels
+                    nb_mwr +=1
+
+                elif ( periph.ptype == 'ROM' ):
+                    seg_rom_base = periph.pseg.base & 0xFFFFFFFF
+                    seg_rom_size = periph.pseg.size
+                    rom_channels = periph.channels
+                    nb_rom +=1
+
+                elif ( periph.ptype == 'SIM' ):
+                    seg_sim_base = periph.pseg.base & 0xFFFFFFFF
+                    seg_sim_size = periph.pseg.size
+                    sim_channels = periph.channels
+                    nb_sim +=1
+
+                elif ( periph.ptype == 'NIC' ):  
+                    seg_nic_base = periph.pseg.base & 0xFFFFFFFF
+                    seg_nic_size = periph.pseg.size
+                    nic_channels = periph.channels
+                    nb_nic +=1
+
+                elif ( periph.ptype == 'PIC' ):  
+                    seg_pic_base = periph.pseg.base & 0xFFFFFFFF
+                    seg_pic_size = periph.pseg.size
+                    pic_channels = periph.channels
+                    nb_pic +=1
+    
+                elif ( periph.ptype == 'TIM' ):  
+                    seg_tim_base = periph.pseg.base & 0xFFFFFFFF
+                    seg_tim_size = periph.pseg.size
+                    tim_channels = periph.channels
+                    nb_tim +=1
+    
+                elif ( periph.ptype == 'TTY' ):
+                    seg_tty_base = periph.pseg.base & 0xFFFFFFFF
+                    seg_tty_size = periph.pseg.size
+                    tty_channels = periph.channels
+                    nb_tty +=1
+    
+                elif ( periph.ptype == 'XCU' ):  
+                    seg_xcu_base = periph.pseg.base & 0xFFFFFFFF
+                    seg_xcu_size = periph.pseg.size
+                    xcu_channels = periph.channels
+                    nb_xcu +=1
+    
+        # don't mix ICU and XCU
+        assert ( nb_icu*nb_xcu == 0 )   
+
+        # no more than two access to external peripherals
+        assert ( nb_fbf <= 2 ) 
+        assert ( nb_cma <= 2 ) 
+        assert ( nb_ioc <= 2 ) 
+        assert ( nb_nic <= 2 ) 
+        assert ( nb_tim <= 2 ) 
+        assert ( nb_tty <= 2 ) 
+        assert ( nb_pic <= 2 )
+
+        # one and only one type of IOC controller
+        assert ( use_hba or use_bdv or use_spi )
+        assert ( (use_hba and use_bdv) == False )
+        assert ( (use_hba and use_spi) == False )
+        assert ( (use_bdv and use_spi) == False )
+                
+        # Compute total number of processors
+        for cluster in self.clusters:
+            nb_total_procs += len( cluster.procs )
+
+        # Compute physical addresses for BOOT vsegs
+        boot_mapping_found   = False
+        boot_code_found      = False
+        boot_data_found      = False
+        boot_buffer_found    = False
+        boot_stack_found     = False
+
+        for vseg in self.globs:
+            if ( vseg.name == 'seg_boot_mapping' ):
+                boot_mapping_base       = vseg.vbase 
+                boot_mapping_size       = vseg.vobjs[0].length
+                boot_mapping_ident      = vseg.ident
+                boot_mapping_found      = True
+
+            if ( vseg.name == 'seg_boot_code' ):
+                boot_code_base          = vseg.vbase 
+                boot_code_size          = vseg.vobjs[0].length
+                boot_code_ident         = vseg.ident
+                boot_code_found         = True
+
+            if ( vseg.name == 'seg_boot_data' ):  
+                boot_data_base          = vseg.vbase 
+                boot_data_size          = vseg.vobjs[0].length
+                boot_data_ident         = vseg.ident
+                boot_data_found         = True
+
+            if ( vseg.name == 'seg_boot_buffer' ):
+                boot_buffer_base        = vseg.vbase 
+                boot_buffer_size        = vseg.vobjs[0].length
+                boot_buffer_ident       = vseg.ident
+                boot_buffer_found       = True
+
+            if ( vseg.name == 'seg_boot_stack' ):
+                boot_stack_base         = vseg.vbase 
+                boot_stack_size         = vseg.vobjs[0].length
+                boot_stack_ident        = vseg.ident
+                boot_stack_found        = True
+
+        # check all BOOT vsegs are found and identity mapping
+        if ( (boot_mapping_found == False) or (boot_mapping_ident == False) ):
+             print 'error in hard_config() : seg_boot_mapping missing or not ident'
+             sys.exit()
+
+        if ( (boot_code_found == False) or (boot_code_ident == False) ): 
+             print 'error in hard_config() : seg_boot_code missing or not ident'
+             sys.exit()
+
+        if ( (boot_data_found == False) or (boot_data_ident == False) ): 
+             print 'error in hard_config() : seg_boot_data missing or not ident'
+             sys.exit()
+
+        if ( (boot_buffer_found == False) or (boot_buffer_ident == False) ): 
+             print 'error in hard_config() : seg_boot_buffer missing or not ident'
+             sys.exit()
+
+        if ( (boot_stack_found == False) or (boot_stack_ident == False) ):
+             print 'error in giet_vsegs() : seg_boot_stack missing or not ident'
+             sys.exit()
+
+        # Search RAMDISK global vseg if required
+        seg_rdk_base =  0xFFFFFFFF
+        seg_rdk_size =  0
+        seg_rdk_found = False
+
+        if self.use_ramdisk:
+            for vseg in self.globs:
+                if ( vseg.name == 'seg_ramdisk' ):
+                    seg_rdk_base  = vseg.vbase
+                    seg_rdk_size  = vseg.vobjs[0].length
+                    seg_rdk_found = True
+
+            if ( seg_rdk_found == False ):
+                print 'Error in hard_config() "seg_ramdisk" not found'
+                sys.exit(1)
+
+        # build string
+        s =  '/* Generated by tsarmap for %s */\n'  % self.name   
+        s += '\n'
+        s += '#ifndef HARD_CONFIG_H\n'
+        s += '#define HARD_CONFIG_H\n'
+        s += '\n'
+
+        s += '/* General platform parameters */\n' 
+        s += '\n'
+        s += '#define X_SIZE                 %d\n'    % self.x_size
+        s += '#define Y_SIZE                 %d\n'    % self.y_size
+        s += '#define X_WIDTH                %d\n'    % self.x_width
+        s += '#define Y_WIDTH                %d\n'    % self.y_width
+        s += '#define X_IO                   %d\n'    % self.x_io
+        s += '#define Y_IO                   %d\n'    % self.y_io  
+        s += '#define NB_PROCS_MAX           %d\n'    % self.procs_max
+        s += '#define IRQ_PER_PROCESSOR      %d\n'    % self.irq_per_proc
+        s += '#define RESET_ADDRESS          0x%x\n'  % self.reset_address
+        s += '#define NB_TOTAL_PROCS         %d\n'    % nb_total_procs
+        s += '\n'
+
+        s += '/* Peripherals */\n' 
+        s += '\n'
+        s += '#define NB_TTY_CHANNELS        %d\n'    % tty_channels
+        s += '#define NB_IOC_CHANNELS        %d\n'    % ioc_channels
+        s += '#define NB_NIC_CHANNELS        %d\n'    % nic_channels
+        s += '#define NB_CMA_CHANNELS        %d\n'    % cma_channels
+        s += '#define NB_TIM_CHANNELS        %d\n'    % tim_channels
+        s += '#define NB_DMA_CHANNELS        %d\n'    % dma_channels
+        s += '\n'
+        s += '#define USE_XCU                %d\n'    % ( nb_xcu != 0 )
+        s += '#define USE_IOB                %d\n'    % ( nb_iob != 0 )
+        s += '#define USE_PIC                %d\n'    % ( nb_pic != 0 )
+        s += '#define USE_FBF                %d\n'    % ( nb_fbf != 0 )
+        s += '\n'
+        s += '#define USE_IOC_BDV            %d\n'    % use_bdv
+        s += '#define USE_IOC_SPI            %d\n'    % use_spi
+        s += '#define USE_IOC_HBA            %d\n'    % use_hba
+        s += '\n'
+        s += '#define USE_RAMDISK            %d\n'    % self.use_ramdisk
+        s += '\n'
+
+        s += '/* physical base addresses for peripherals */\n'
+        s += '\n'
+        s += '#define SEG_CMA_BASE           0x%x\n'  % seg_cma_base            
+        s += '#define SEG_CMA_SIZE           0x%x\n'  % seg_cma_size            
+        s += '\n'
+        s += '#define SEG_DMA_BASE           0x%x\n'  % seg_dma_base            
+        s += '#define SEG_DMA_SIZE           0x%x\n'  % seg_cma_size            
+        s += '\n'
+        s += '#define SEG_FBF_BASE           0x%x\n'  % seg_fbf_base            
+        s += '#define SEG_FBF_SIZE           0x%x\n'  % seg_cma_size            
+        s += '\n'
+        s += '#define SEG_ICU_BASE           0x%x\n'  % seg_icu_base            
+        s += '#define SEG_ICU_SIZE           0x%x\n'  % seg_cma_size            
+        s += '\n'
+        s += '#define SEG_IOB_BASE           0x%x\n'  % seg_iob_base            
+        s += '#define SEG_IOB_SIZE           0x%x\n'  % seg_cma_size            
+        s += '\n'
+        s += '#define SEG_IOC_BASE           0x%x\n'  % seg_ioc_base            
+        s += '#define SEG_IOC_SIZE           0x%x\n'  % seg_ioc_size            
+        s += '\n'
+        s += '#define SEG_MMC_BASE           0x%x\n'  % seg_mmc_base            
+        s += '#define SEG_MMC_SIZE           0x%x\n'  % seg_mmc_size            
+        s += '\n'
+        s += '#define SEG_MWR_BASE           0x%x\n'  % seg_mwr_base            
+        s += '#define SEG_MWR_SIZE           0x%x\n'  % seg_mwr_size            
+        s += '\n'
+        s += '#define SEG_ROM_BASE           0x%x\n'  % seg_rom_base            
+        s += '#define SEG_ROM_SIZE           0x%x\n'  % seg_rom_size            
+        s += '\n'
+        s += '#define SEG_SIM_BASE           0x%x\n'  % seg_sim_base            
+        s += '#define SEG_SIM_SIZE           0x%x\n'  % seg_sim_size            
+        s += '\n'
+        s += '#define SEG_NIC_BASE           0x%x\n'  % seg_nic_base            
+        s += '#define SEG_NIC_SIZE           0x%x\n'  % seg_nic_size            
+        s += '\n'
+        s += '#define SEG_PIC_BASE           0x%x\n'  % seg_pic_base            
+        s += '#define SEG_PIC_SIZE           0x%x\n'  % seg_pic_size            
+        s += '\n'
+        s += '#define SEG_TIM_BASE           0x%x\n'  % seg_tim_base            
+        s += '#define SEG_TIM_SIZE           0x%x\n'  % seg_tim_size            
+        s += '\n'
+        s += '#define SEG_TTY_BASE           0x%x\n'  % seg_tty_base            
+        s += '#define SEG_TTY_SIZE           0x%x\n'  % seg_tty_size            
+        s += '\n'
+        s += '#define SEG_XCU_BASE           0x%x\n'  % seg_xcu_base            
+        s += '#define SEG_XCU_SIZE           0x%x\n'  % seg_xcu_size            
+        s += '\n'
+        s += '#define SEG_RDK_BASE           0x%x\n'  % seg_rdk_base
+        s += '#define SEG_RDK_SIZE           0x%x\n'  % seg_rdk_size
+        s += '\n'
+        s += '#define VSEG_CLUSTER_INCREMENT 0x%x\n'  % self.vseg_increment
+        s += '\n'
+
+        s += '/* physical base addresses for identity mapped boot vsegs */\n'
+        s += '\n'
+        s += '#define SEG_BOOT_MAPPING_BASE  0x%x\n'  % boot_mapping_base
+        s += '#define SEG_BOOT_MAPPING_SIZE  0x%x\n'  % boot_mapping_size
+        s += '\n'
+        s += '#define SEG_BOOT_CODE_BASE     0x%x\n'  % boot_code_base
+        s += '#define SEG_BOOT_CODE_SIZE     0x%x\n'  % boot_code_size
+        s += '\n'
+        s += '#define SEG_BOOT_DATA_BASE     0x%x\n'  % boot_data_base
+        s += '#define SEG_BOOT_DATA_SIZE     0x%x\n'  % boot_data_size
+        s += '\n'
+        s += '#define SEG_BOOT_BUFFER_BASE   0x%x\n'  % boot_buffer_base
+        s += '#define SEG_BOOT_BUFFER_SIZE   0x%x\n'  % boot_buffer_size
+        s += '\n'
+        s += '#define SEG_BOOT_STACK_BASE    0x%x\n'  % boot_stack_base
+        s += '#define SEG_BOOT_STACK_SIZE    0x%x\n'  % boot_stack_size
+        s += '#endif\n'
+        
+        return s
+
+    # end of hard_config()
+
+    #######################
+    def netbsd_dts( self ):    # compute string for netbsd.dts file generation,
+                               # used for netbsd configuration  
+        # header
+        s =  '/dts-v1/;\n'
+        s += '\n'
+        s += '/{\n'
+        s += '  #address-cells = <2>;\n'  
+        s += '  #size-cells    = <1>;\n'  
+
+        # cpus (for each cluster)
+        s += '  cpus {\n'
+        s += '    #address-cells = <1>;\n'
+        s += '    #size-cells    = <0>;\n'
+
+        for cluster in self.clusters:
+            for proc in cluster.procs:
+                proc_id = (((cluster.x << self.y_width) + cluster.y) * self.procs_max) + proc.lpid
+
+                s += '    Mips,32@0x%x {\n'                % proc_id
+                s += '      device_type = "cpu";\n'
+                s += '      icudev_type = "cpu:mips";\n'
+                s += '      name        = "Mips,32";\n'
+                s += '      reg         = <0x%x>;\n'     % proc_id
+                s += '    };\n'
+                s += '\n'
+
+        s += '  };\n'
+
+        # rams (for each cluster)
+        for cluster in self.clusters:
+            for pseg in cluster.psegs:
+
+                if ( pseg.segtype == 'RAM' ):
+                    msb  = pseg.base >> 32
+                    lsb  = pseg.base & 0xFFFFFFFF
+                    size = pseg.size
+
+                    s += '  %s@0x%x {\n' % (pseg.name, pseg.base)
+                    s += '    cached      = <1>;\n'
+                    s += '    device_type = "memory";\n'
+                    s += '    reg         = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
+                    s += '  };\n'
+
+        # peripherals (for each cluster)
+        for cluster in self.clusters:
+
+            # research XCU component 
+            found_xcu = False
+            for periph in cluster.periphs:
+                if ( (periph.ptype == 'XCU') ):  
+                    found_xcu = True
+                    xcu = periph
+                    msb  = periph.pseg.base >> 32
+                    lsb  = periph.pseg.base & 0xFFFFFFFF
+                    size = periph.pseg.size
+
+                    s += '  %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
+                    s += '    device_type = "soclib:xicu:root";\n'
+                    s += '    reg         = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
+                    s += '    input_lines = <%d>;\n'    % periph.arg1  
+                    s += '    ipis        = <%d>;\n'    % periph.arg2 
+                    s += '    timers      = <%d>;\n'    % periph.arg3
+
+                    output_id = 0            # output index from XCU
+                    for lpid in xrange ( len(cluster.procs) ):        # destination processor index
+                        for itid in xrange ( self.irq_per_proc ):     # input irq index on processor
+                            proc_id = (((cluster.x << self.y_width) + cluster.y) * self.procs_max) + lpid
+                            s += '    out@%d {\n' % output_id
+                            s += '      device_type = "soclib:xicu:filter";\n'
+                            s += '      irq         = <&{/cpus/Mips,32@0x%x} %d>;\n' % (proc_id, itid)
+                            s += '      output_line = <%d>;\n' % output_id 
+                            s += '      parent      = <&{/%s@0x%x}>;\n' % (periph.pseg.name, periph.pseg.base)
+                            s += '    };\n'
+
+                            output_id += 1
+
+                    s += '  };\n'
+
+            # research PIC component
+            found_pic = False
+            for periph in cluster.periphs:
+                if ( periph.ptype == 'PIC' ):  
+                    found_pic = True
+                    pic  = periph
+                    msb  = periph.pseg.base >> 32
+                    lsb  = periph.pseg.base & 0xFFFFFFFF
+                    size = periph.pseg.size
+
+                    s += '  %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
+                    s += '    device_type = "soclib:pic:root";\n'
+                    s += '    reg         = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
+                    s += '    input_lines = <%d>;\n'    % periph.channels  
+                    s += '  };\n'
+
+            if ( (found_xcu == False) and (found_pic == False) and (len(cluster.periphs) > 0) ):
+                print 'error in netbsd_dts() : No XCU/PIC in cluster(%d,%d)' % (cluster.x, cluster.y)
+                sys.exit(1)    
+             
+            if ( found_pic == True ):  irq_tgt = pic
+            else:                      irq_tgt = xcu
+            
+            # get all others peripherals in cluster
+            for periph in cluster.periphs:
+                msb  = periph.pseg.base >> 32
+                lsb  = periph.pseg.base & 0xFFFFFFFF
+                size = periph.pseg.size
+
+                # research DMA component
+                if ( periph.ptype == 'DMA' ):
+
+                    s += '  %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
+                    s += '    device_type   = "soclib:dma";\n'
+                    s += '    reg           = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
+                    s += '    channel_count = <%d>;\n' % periph.channels
+
+                    # multi-channels : get HWI index (to XCU) for each channel
+                    for channel in xrange( periph.channels ):
+                        hwi_id = 0xFFFFFFFF
+                        for irq in xcu.irqs:
+                            if ( (irq.isrtype == 'ISR_DMA') and (irq.channel == channel) ): 
+                                hwi_id = irq.srcid
+                        if ( hwi_id == 0xFFFFFFFF ):
+                            print 'error in netbsd.dts() ISR_DMA channel %d not found' % channel
+                            sys.exit(1)
+
+                        name = '%s@0x%x' % (xcu.pseg.name, xcu.pseg.base)
+                        s += '    irq@%d{\n' % channel
+                        s += '      device_type = "soclib:periph:irq";\n'
+                        s += '      output_line = <%d>;\n' % channel
+                        s += '      irq         = <&{/%s}  %d>;\n' % (name, hwi_id)
+                        s += '      parent      = <&{/%s@0x%x}>;\n' % (periph.pseg.name, periph.pseg.base)
+                        s += '    };\n'
+
+                    s += '  };\n'       
+
+                # research MMC component
+                elif ( periph.ptype == 'MMC' ):
+
+                    # get irq line index associated to MMC in XCU
+                    irq_in = 0xFFFFFFFF
+                    for irq in xcu.irqs:
+                        if ( irq.isrtype == 'ISR_MMC' ): irq_in = irq.srcid
+                    if ( irq_in == 0xFFFFFFFF ):
+                        print 'error in netbsd.dts() ISR_MMC not found'
+                        sys.exit(1)
+
+                    s += '  %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
+                    s += '    device_type = "soclib:mmc";\n'
+                    s += '    irq         = <&{/%s@0x%x}  %d>;\n' % (irq_tgt.pseg.name, irq_tgt.pseg.base, irq_in)
+                    s += '    reg         = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
+                    s += '  };\n' 
+
+                # research FBF component
+                elif ( periph.ptype == 'FBF' ):  
+
+                    s += '  %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
+                    s += '    device_type = "soclib:framebuffer";\n'
+                    s += '    mode        = <32>;\n'                    # bits par pixel
+                    s += '    width       = <%d>;\n'    % periph.arg1
+                    s += '    height      = <%d>;\n'    % periph.arg2  
+                    s += '    reg         = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
+                    s += '  };\n'
+
+                # research IOC component
+                elif ( periph.ptype == 'IOC' ):  
+
+                    if   ( periph.subtype == 'BDV' ):
+
+                        # get irq line index associated to bdv
+                        irq_in = 0xFFFFFFFF
+                        for irq in irq_tgt.irqs:
+                            if ( irq.isrtype == 'ISR_BDV' ): irq_in = irq.srcid
+                        if ( irq_in == 0xFFFFFFFF ):
+                            print 'error in netbsd.dts() ISR_BDV not found'
+                            sys.exit(1)
+
+                        s += '  %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
+                        s += '    device_type = "soclib:blockdevice";\n'
+                        s += '    irq         = <&{/%s@0x%x}  %d>;\n' % (irq_tgt.pseg.name, irq_tgt.pseg.base, irq_in)
+                        s += '    reg         = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
+                        s += '  };\n'
+
+                    elif ( periph.subtype == 'HBA' ):
+                        print 'error in netbsd_dts() : HBA peripheral not supported by NetBSD'
+                        sys.exit(1)
+
+                    elif ( periph.subtype == 'SPI' ):
+
+                        # get irq line index associated to spi
+                        irq_in = 0xFFFFFFFF
+                        for irq in irq_tgt.irqs:
+                            if ( irq.isrtype == 'ISR_SPI' ): irq_in = irq.srcid
+                        if ( irq_in == 0xFFFFFFFF ):
+                            print 'error in netbsd.dts() ISR_SPI not found'
+                            sys.exit(1)
+
+                        s += '  %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
+                        s += '    device_type = "soclib:spi";\n'
+                        s += '    irq         = <&{/%s@0x%x}  %d>;\n' % (irq_tgt.pseg.name, irq_tgt.pseg.base, irq_in)
+                        s += '    reg         = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
+                        s += '  };\n'
+
+                # research ROM component
+                elif ( periph.ptype == 'ROM' ):
+
+                    s += '  %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
+                    s += '    device_type = "rom";\n'
+                    s += '    cached      = <1>;\n'
+                    s += '    reg         = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
+                    s += '  };\n'
+
+                # research SIM component
+                elif ( periph.ptype == 'SIM' ):
+
+                    s += '  %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
+                    s += '    device_type = "soclib:simhelper";\n'
+                    s += '    reg         = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
+                    s += '  };\n'
+
+                # research TTY component
+                elif ( periph.ptype == 'TTY' ):
+
+                    s += '  %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
+                    s += '    device_type   = "soclib:tty";\n'
+                    s += '    reg           = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
+                    s += '    channel_count = < %d >;\n' % periph.channels 
+
+                    # multi-channels : get HWI index (to XCU or PIC) for each channel
+                    for channel in xrange( periph.channels ):
+                        hwi_id = 0xFFFFFFFF
+                        for irq in irq_tgt.irqs:
+                            if ( (irq.isrtype == 'ISR_TTY_RX') and (irq.channel == channel) ): 
+                                hwi_id = irq.srcid
+                        if ( hwi_id == 0xFFFFFFFF ):
+                            print 'error in netbsd.dts() ISR_TTY_RX channel %d not found' % channel
+                            sys.exit(1)
+
+                        name = '%s@0x%x' % (irq_tgt.pseg.name, irq_tgt.pseg.base)
+                        s += '    irq@%d{\n' % channel
+                        s += '      device_type = "soclib:periph:irq";\n'
+                        s += '      output_line = <%d>;\n' % channel
+                        s += '      irq         = <&{/%s}  %d>;\n' % (name, hwi_id)
+                        s += '      parent      = <&{/%s@0x%x}>;\n' % (periph.pseg.name, periph.pseg.base)
+                        s += '    };\n'
+
+                    s += '  };\n'
+    
+                # research IOB component
+                elif ( periph.ptype == 'IOB' ):
+
+                    s += '  %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
+                    s += '    device_type = "soclib:iob";\n'
+                    s += '    reg         = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
+                    s += '  };\n'
+
+                # research NIC component
+                elif ( periph.ptype == 'NIC' ):  
+
+                    s += '  %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
+                    s += '    device_type   = "soclib:nic";\n'
+                    s += '    reg           = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
+                    s += '    channel_count = < %d >;\n' % periph.channels
+
+                    # multi-channels : get HWI index (to XCU or PIC) for RX & TX IRQs
+                    # RX IRQ : (2*channel) / TX IRQs : (2*channel + 1)
+                    for channel in xrange( periph.channels ):
+                        hwi_id = 0xFFFFFFFF
+                        for irq in irq_tgt.irqs:
+                            if ( (irq.isrtype == 'ISR_NIC_RX') and (irq.channel == channel) ): 
+                                hwi_id = irq.srcid
+                        if ( hwi_id == 0xFFFFFFFF ):
+                            print 'error in netbsd.dts() ISR_NIC_RX channel %d not found' % channel
+                            sys.exit(1)
+
+                        name = '%s@0x%x' % (irq_tgt.pseg.name, irq_tgt.pseg.base)
+                        s += '    irq_rx@%d{\n' % channel
+                        s += '      device_type = "soclib:periph:irq";\n'
+                        s += '      output_line = <%d>;\n' % (2*channel)
+                        s += '      irq         = <&{/%s}  %d>;\n' % (name, hwi_id)
+                        s += '      parent      = <&{/%s@0x%x}>;\n' % (periph.pseg.name, periph.pseg.base)
+                        s += '    };\n'
+
+                        hwi_id = 0xFFFFFFFF
+                        for irq in irq_tgt.irqs:
+                            if ( (irq.isrtype == 'ISR_NIC_TX') and (irq.channel == channel) ): 
+                                hwi_id = irq.srcid
+                        if ( hwi_id == 0xFFFFFFFF ):
+                            print 'error in netbsd.dts() ISR_NIC_TX channel %d not found' % channel
+                            sys.exit(1)
+
+                        name = '%s@0x%x' % (irq_tgt.pseg.name, irq_tgt.pseg.base)
+                        s += '    irq_tx@%d{\n' % channel
+                        s += '      device_type = "soclib:periph:irq";\n'
+                        s += '      output_line = <%d>;\n' % (2*channel + 1)
+                        s += '      irq         = <&{/%s}  %d>;\n' % (name, hwi_id)
+                        s += '      parent      = <&{/%s@0x%x}>;\n' % (periph.pseg.name, periph.pseg.base)
+                        s += '    };\n'
+ 
+                    s += '  };\n'
+
+                # research CMA component
+                elif ( periph.ptype == 'CMA' ):  
+
+                    s += '  %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
+                    s += '    device_type   = "soclib:cma";\n'
+                    s += '    reg           = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
+                    s += '    channel_count = < %d >;\n' % periph.channels
+
+                    # multi-channels : get HWI index (to XCU or PIC) for each channel
+                    for channel in xrange( periph.channels ):
+                        hwi_id = 0xFFFFFFFF
+                        for irq in irq_tgt.irqs:
+                            if ( (irq.isrtype == 'ISR_CMA') and (irq.channel == channel) ): 
+                                hwi_id = irq.srcid
+                        if ( hwi_id == 0xFFFFFFFF ):
+                            print 'error in netbsd.dts() ISR_CMA channel %d not found' % channel
+                            sys.exit(1)
+
+                        name = '%s@0x%x' % (irq_tgt.pseg.name, irq_tgt.pseg.base)
+                        s += '    irq@%d{\n' % channel
+                        s += '      device_type = "soclib:periph:irq";\n'
+                        s += '      output_line = <%d>;\n' % channel
+                        s += '      irq         = <&{/%s}  %d>;\n' % (name, hwi_id)
+                        s += '      parent      = <&{/%s@0x%x}>;\n' % (periph.pseg.name, periph.pseg.base)
+                        s += '    };\n'
+
+                    s += '  };\n'
+
+                # research TIM component
+                elif ( periph.ptype == 'TIM' ):  
+
+                    print 'error in netbsd_dts() : TIM peripheral not supported by NetBSD'
+                    sys.exit(1)
+
+                # research MWR component
+                elif ( periph.ptype == 'MWR' ):
+
+                    print 'error in netbsd_dts() : MWR peripheral not supported by NetBSD'
+                    sys.exit(1)
+
+                # research ICU component
+                elif ( periph.ptype == 'ICU' ):  
+                    print 'error in netbsd_dts() : ICU peripheral not supported by NetBSD'
+                    sys.exit(1)
+
+        # topology
+        s += '\n'
+        s += '  topology {\n'
+        s += '    #address-cells = <2>;\n'
+        s += '    #size-cells = <0>;\n'
+        for cluster in self.clusters:
+            s += '    cluster@%d,%d {\n' % (cluster.x, cluster.y) 
+            s += '      reg     = <%d %d>;\n' % (cluster.x, cluster.y)
+            s += '      devices = <\n'
+
+            offset = ((cluster.x << self.y_width) + cluster.y) * self.procs_max
+            for proc in cluster.procs:
+                s += '                &{/cpus/Mips,32@0x%x}\n' % (offset + proc.lpid)
+            for periph in cluster.periphs:
+                s += '                &{/%s@0x%x}\n' % (periph.pseg.name, periph.pseg.base)
+
+            s += '                >;\n'
+            s += '    };\n'
+        s += '  };\n'
+        s += '};\n'
+
+        return s
+        # end netbsd_dts( )
+
+    ###########################
+    def almos_archinfo( self ):    # compute string for arch.info file generation,
+                                   # used for almos configuration  
+        # header
+        s =  '# arch.info file generated by tsarmap for %s\n' % self.name
+        s += '\n'
+        s += '[HEADER]\n'
+        s += '        REVISION=1\n'
+        s += '        ARCH=%s\n'            % self.name
+        s += '        XMAX=%d\n'            % self.x_size
+        s += '        YMAX=%d\n'            % self.y_size
+        s += '        CPU_NR=%d\n'          % self.procs_max
+        s += '\n'
+
+        # clusters
+        cluster_id = 0
+        for cluster in self.clusters:
+
+            ram = None
+            nb_cpus = len( cluster.procs )
+            nb_devs = len( cluster.periphs )
+            if ( len( cluster.coprocs ) != 0 ):
+                print 'Error in almos_archinfo() coprocessors not supported yet'
+                sys.exit(1)
+
+            # search a RAM
+            for pseg in cluster.psegs:
+                if ( pseg.segtype == 'RAM' ): 
+                    ram     = pseg
+                    nb_devs += 1
+
+            # search XCU to get IRQs indexes if cluster contains peripherals
+            if ( len( cluster.periphs ) != 0 ):
+                tty_irq_id = None
+                bdv_irq_id = None
+                dma_irq_id = None
+
+                for periph in cluster.periphs:
+                    if ( periph.ptype == 'XCU' ): 
+                        # scan irqs
+                        for irq in periph.irqs:
+                            if ( irq.isrtype == 'ISR_TTY_RX' ) : tty_irq_id = irq.srcid
+                            if ( irq.isrtype == 'ISR_BDV'    ) : bdv_irq_id = irq.srcid
+                            if ( irq.isrtype == 'ISR_DMA'    ) : dma_irq_id = irq.srcid
+
+            # Build the cluster description
+            s += '[CLUSTER]\n'
+            s += '         CID=%d\n'        % cluster_id 
+            s += '         ARCH_CID=0x%x\n' % ((cluster.x << self.y_width) + cluster.y) 
+            s += '         CPU_NR=%d\n'     % nb_cpus
+            s += '         DEV_NR=%d\n'     % nb_devs
+            
+
+            # Handling RAM when cluster contain a RAM
+            if (ram != None ):
+                base  = ram.base
+                size  = ram.size
+                irqid = -1
+                s += '         DEVID=RAM'  
+                s += '  BASE=0x%x  SIZE=0x%x  IRQ=-1\n' % ( base, size )
+
+            # Handling peripherals
+            for periph in cluster.periphs:
+                base  = periph.pseg.base
+                size  = periph.pseg.size
+
+                if   ( periph.ptype == 'XCU' ): 
+
+                    s += '         DEVID=XICU'  
+                    s += '  BASE=0x%x  SIZE=0x%x  IRQ=-1\n' % ( base, size )
+
+                elif ( (periph.ptype == 'TTY') 
+                       and (tty_irq_id != None) ):
+
+                    s += '         DEVID=TTY'  
+                    s += '  BASE=0x%x  SIZE=0x%x  IRQ=%d\n' % ( base, size, tty_irq_id )
+
+                elif ( (periph.ptype == 'DMA') 
+                       and (dma_irq_id != None) ):
+
+                    s += '         DEVID=DMA'
+                    s += '  BASE=0x%x  SIZE=0x%x  IRQ=%d\n' % ( base, size, dma_irq_id )
+
+                elif ( periph.ptype == 'FBF' ):
+
+                    s += '         DEVID=FB'
+                    s += '  BASE=0x%x  SIZE=0x%x  IRQ=-1\n' % ( base, size )
+
+                elif ( (periph.ptype == 'IOC') and (periph.subtype == 'BDV')
+                       and (bdv_irq_id != None) ):
+
+                    s += '         DEVID=BLKDEV'  
+                    s += '  BASE=0x%x  SIZE=0x%x  IRQ=%d\n' % ( base, size, bdv_irq_id )
+
+                elif ( periph.ptype == 'PIC' ):
+
+                        s += '         DEVID=IOPIC'  
+                        s += '  BASE=0x%x  SIZE=0x%x  IRQ=-1\n' % ( base, size )
+
+                else:
+                    print '# Warning from almos_archinfo() in cluster[%d,%d]' \
+                          % (cluster.x, cluster.y)
+                    print '# peripheral type %s/%s not supported yet\n' \
+                          % ( periph.ptype, periph.subtype )
+                  
+            cluster_id += 1
+
+        return s
+
+    # end of almos_archinfo()
+
+
+
+
+
+
+
+
+###########################################################################################
+class Cluster ( object ):
+###########################################################################################
+    def __init__( self,
+                  x, 
+                  y ):
+        
+        self.index       = 0             # global index (set by Mapping constructor)
+        self.x           = x             # x coordinate
+        self.y           = y             # y coordinate
+        self.psegs       = []            # filled by addRam() or addPeriph()
+        self.procs       = []            # filled by addProc()
+        self.coprocs     = []            # filled by addCoproc()
+        self.periphs     = []            # filled by addPeriph()
+
+        return
+
+    ################
+    def xml( self ):  # xml for a cluster
+
+        s = '        <cluster x="%d" y="%d" >\n' % (self.x, self.y)
+        for pseg in self.psegs:   s += pseg.xml()  
+        for proc in self.procs:   s += proc.xml()
+        for copr in self.coprocs: s += copr.xml() 
+        for peri in self.periphs: s += peri.xml()  
+        s += '        </cluster>\n'
+
+        return s
+
+    #############################################
+    def cbin( self, mapping, verbose, expected ):    # C binary structure for Cluster
+
+        if ( verbose ):
+            print '*** cbin for cluster [%d,%d]' % (self.x, self.y)
+
+        # check index
+        if (self.index != expected):
+            print 'error in Cluster.cbin() : cluster global index = %d / expected = %d' \
+                  % (self.index, expected )
+            sys.exit(1)
+
+        # compute global index for first pseg 
+        if ( len(self.psegs) > 0 ):
+            pseg_id = self.psegs[0].index
+        else:
+            pseg_id = 0
+
+        # compute global index for first proc 
+        if ( len(self.procs) > 0 ):
+            proc_id = self.procs[0].index
+        else:
+            proc_id = 0
+
+        # compute global index for first coproc 
+        if ( len(self.coprocs) > 0 ):
+            coproc_id = self.coprocs[0].index
+        else:
+            coproc_id = 0
+
+        # compute global index for first periph 
+        if ( len(self.periphs) > 0 ):
+            periph_id = self.periphs[0].index
+        else:
+            periph_id = 0
+
+        byte_stream = bytearray()
+        byte_stream += mapping.int2bytes( 4 , self.x )                 # x coordinate
+        byte_stream += mapping.int2bytes( 4 , self.y )                 # x coordinate
+        byte_stream += mapping.int2bytes( 4 , len( self.psegs ) )      # number of psegs in cluster
+        byte_stream += mapping.int2bytes( 4 , pseg_id )                # first pseg global index
+        byte_stream += mapping.int2bytes( 4 , len( self.procs ) )      # number of procs in cluster
+        byte_stream += mapping.int2bytes( 4 , proc_id )                # first proc global index
+        byte_stream += mapping.int2bytes( 4 , len( self.coprocs ) )    # number of coprocs in cluster
+        byte_stream += mapping.int2bytes( 4 , coproc_id )              # first coproc global index
+        byte_stream += mapping.int2bytes( 4 , len( self.periphs ) )    # number of periphs in cluster
+        byte_stream += mapping.int2bytes( 4 , periph_id )              # first periph global index
+ 
+        if ( verbose ):
+            print 'nb_psegs   = %d' %  len( self.psegs )
+            print 'pseg_id    = %d' %  pseg_id
+            print 'nb_procs   = %d' %  len( self.procs )
+            print 'proc_id    = %d' %  proc_id
+            print 'nb_coprocs = %d' %  len( self.coprocs )
+            print 'coproc_id  = %d' %  coproc_id
+            print 'nb_periphs = %d' %  len( self.periphs )
+            print 'periph_id  = %d' %  periph_id
+
+        return byte_stream
+
+###########################################################################################
 class Vspace( object ):
-#######################
-    def __init__( self, name, startname ):
-        self.name      = name           # application name
+###########################################################################################
+    def __init__( self, 
+                  name, 
+                  startname ):
+
+        self.index     = 0              # global index ( set by addVspace() )
+        self.name      = name           # vspace name
         self.startname = startname      # name of vobj containing the start_vector
-        self.vsegs     = []
+        self.vsegs     = []             
         self.tasks     = []
+
         return
-    ##########################
-    def addTask( self, task ):
-        self.tasks.append( task )
+
+    ################
+    def xml( self ):   # xml for one vspace
+
+        s =  '        <vspace name="%s" startname="%s" >\n' % ( self.name, self.startname )
+        for vseg in self.vsegs: s += vseg.xml()
+        for task in self.tasks: s += task.xml() 
+        s += '        </vspace>\n'
+
+        return s
+
+    #############################################
+    def cbin( self, mapping, verbose, expected ):   # C binary structure for Vspace
+
+        if ( verbose ):
+            print '*** cbin for vspace %s' % (self.name)
+
+        # check index
+        if (self.index != expected):
+            print 'error in Vspace.cbin() : vspace global index = %d / expected = %d' \
+                  % (self.index, expected )
+            sys.exit(1)
+
+        # compute global index for vobj containing start_vector
+        vobj_start_id = 0xFFFFFFFF
+        for vseg in self.vsegs:
+            if ( vseg.vobjs[0].name == self.startname ):
+                vobj_start_id = vseg.vobjs[0].index
+        if ( vobj_start_id == 0xFFFFFFFF ):
+            print 'error in Vspace.cbin() : startname %s not found for vspace %s' \
+                  % ( self.startname, self.name )
+            sys.exit(1)
+ 
+        # compute first vseg, vobj, task global index
+        first_vseg_id = self.vsegs[0].index
+        first_vobj_id = self.vsegs[0].vobjs[0].index
+        first_task_id = self.tasks[0].index
+        
+        # compute number of vobjs, tasks, vsegs
+        nb_vsegs = len( self.vsegs )
+        nb_tasks = len( self.tasks )
+        nb_vobjs = 0
+        for vseg in self.vsegs:
+            nb_vobjs += len( vseg.vobjs )
+
+        byte_stream = bytearray()
+        byte_stream += mapping.str2bytes( 32, self.name )         # vspace name
+        byte_stream += mapping.int2bytes( 4,  vobj_start_id )     # vobj start_vector 
+        byte_stream += mapping.int2bytes( 4,  nb_vsegs )          # number of vsegs
+        byte_stream += mapping.int2bytes( 4,  nb_vobjs )          # number of vobjs
+        byte_stream += mapping.int2bytes( 4,  nb_tasks )          # number of tasks
+        byte_stream += mapping.int2bytes( 4,  first_vseg_id )     # first vseg global index
+        byte_stream += mapping.int2bytes( 4,  first_vobj_id )     # first vobj global index
+        byte_stream += mapping.int2bytes( 4,  first_task_id )     # first task global index
+
+        if ( verbose ):
+            print 'start_id   = %d' %  vobj_start_id
+            print 'nb_vsegs   = %d' %  nb_vsegs
+            print 'nb_vobjs   = %d' %  nb_vobjs
+            print 'nb_tasks   = %d' %  nb_tasks
+            print 'vseg_id    = %d' %  first_vseg_id
+            print 'vobj_id    = %d' %  first_vobj_id
+            print 'task_id    = %d' %  first_task_id
+
+        return byte_stream
+
+###########################################################################################
+class Task( object ):
+###########################################################################################
+    def __init__( self, 
+                  name, 
+                  trdid, 
+                  x, 
+                  y,
+                  p, 
+                  stackname, 
+                  heapname, 
+                  startid,
+                  usetty = False, 
+                  usenic = False, 
+                  usecma = False,
+                  usehba = False, 
+                  usetim = False ):
+
+        self.index     = 0             # global index value set by addTask()
+        self.name      = name          # tsk name
+        self.trdid     = trdid         # task index (unique in vspace)
+        self.x         = x             # cluster x coordinate 
+        self.y         = y             # cluster y coordinate 
+        self.p         = p             # processor local index  
+        self.stackname = stackname     # name of vobj containing the stack
+        self.heapname  = heapname      # name of vobj containing the heap
+        self.startid   = startid       # index in start_vector
+        self.usetty    = usetty        # request a private TTY channel
+        self.usenic    = usenic        # request a private NIC channel
+        self.usecma    = usecma        # request a private CMA channel
+        self.usehba    = usehba        # request a private HBA channel
+        self.usetim    = usetim        # request a private TIM channel
         return
 
-    ##########################
-    def addVseg( self, vseg ):
-        self.vsegs.append( vseg )
+    ################
+    def xml( self ):    # xml for one task
+
+        s =  '            <task name="%s"' % self.name
+        s += ' trdid="%d"'                 % self.trdid
+        s += ' x="%d"'                     % self.x
+        s += ' y="%d"'                     % self.y
+        s += ' p="%d"'                     % self.p
+        s += ' stackname="%s"'             % self.stackname
+        s += ' heapname="%s"'              % self.heapname
+        s += ' startid="%d"'               % self.startid
+        if self.usetty != 0: s += ' usetty="1"'  
+        if self.usenic != 0: s += ' usenic="1"'  
+        if self.usecma != 0: s += ' usehba="1"'  
+        if self.usehba != 0: s += ' usehba="1"'  
+        if self.usetim != 0: s += ' usehba="1"'  
+        s += ' />\n'           
+
+        return s
+
+    #####################################################
+    def cbin( self, mapping, verbose, expected, vspace ):  # C binary data structure for Task 
+
+        if ( verbose ):
+            print '*** cbin for task %s in vspace %s' % (self.name, vspace.name)
+
+        # check index
+        if (self.index != expected):
+            print 'error in Task.cbin() : task global index = %d / expected = %d' \
+                  % (self.index, expected )
+            sys.exit(1)
+
+        # compute cluster global index
+        cluster_id = (self.x * mapping.y_size) + self.y
+
+        # compute vobj local index for stack
+        vobj_stack_id = 0xFFFFFFFF
+        for vseg in vspace.vsegs:
+            if ( vseg.vobjs[0].name == self.stackname ):
+                vobj_stack_id = vseg.vobjs[0].index 
+        if ( vobj_stack_id == 0xFFFFFFFF ):
+            print 'error in Task.cbin() : stackname %s not found for task %s in vspace %s' \
+                  % ( self.stackname, self.name, vspace.name )
+            sys.exit(1)
+
+        # compute vobj local index for heap
+        vobj_heap_id = 0xFFFFFFFF
+        for vseg in vspace.vsegs:
+            if ( vseg.vobjs[0].name == self.heapname ):
+                vobj_heap_id = vseg.vobjs[0].index
+        if ( vobj_heap_id == 0xFFFFFFFF ):
+            print 'error in Task.cbin() : heapname %s not found for task %s in vspace %s' \
+                  % ( self.heapname, self.name, vspace.name )
+            sys.exit(1)
+
+        byte_stream = bytearray()
+        byte_stream += mapping.str2bytes( 32, self.name )       # task name in vspace
+        byte_stream += mapping.int2bytes( 4,  cluster_id )      # cluster global index
+        byte_stream += mapping.int2bytes( 4,  self.p )          # processor local index in cluster
+        byte_stream += mapping.int2bytes( 4,  self.trdid )      # thread local index in vspace
+        byte_stream += mapping.int2bytes( 4,  vobj_stack_id )   # stack vobj local index
+        byte_stream += mapping.int2bytes( 4,  vobj_heap_id )    # heap vobj local index
+        byte_stream += mapping.int2bytes( 4,  self.startid )    # index in start vector    
+        byte_stream += mapping.int2bytes( 4,  self.usetty )     # TTY channel required     
+        byte_stream += mapping.int2bytes( 4,  self.usenic )     # NIC channel required     
+        byte_stream += mapping.int2bytes( 4,  self.usecma )     # CMA channel required     
+        byte_stream += mapping.int2bytes( 4,  self.usehba )     # IOC channel required     
+        byte_stream += mapping.int2bytes( 4,  self.usetim )     # TIM channel required
+
+        if ( verbose ):
+            print 'clusterid  = %d' %  cluster_id
+            print 'lpid       = %d' %  self.p
+            print 'trdid      = %d' %  self.trdid 
+            print 'stackid    = %d' %  vobj_stack_id 
+            print 'heapid     = %d' %  vobj_heap_id 
+            print 'startid    = %d' %  self.startid   
+     
+        return byte_stream
+
+###########################################################################################
+class Vseg( object ):
+###########################################################################################
+    def __init__( self, 
+                  name, 
+                  vbase, 
+                  mode, 
+                  x, 
+                  y, 
+                  psegname, 
+                  ident = False ):
+
+        assert mode in VSEGMODES
+
+        self.index      = 0                   # global index ( set by addVseg() )
+        self.name       = name                # vseg name
+        self.vbase      = vbase & 0xFFFFFFFF  # virtual base address in vspace 
+        self.mode       = mode                # CXWU access rights
+        self.x          = x                   # x coordinate of destination cluster 
+        self.y          = y                   # y coordinate of destination cluster
+        self.psegname   = psegname            # name of pseg in destination cluster
+        self.ident      = ident               # identity mapping required
+        self.vobjs      = []
         return
 
-    ####################
-    def __str__( self ):   # xml for one vspace
-        s =  '        <vspace name="%s" startname="%s" >\n' % ( self.name, self.startname )
-        for vseg in self.vsegs:
-            s += str( vseg )
-        for task in self.tasks:
-            s += str( task )
-        s += '        </vspace>\n'
+    ################
+    def xml( self ):  # xml for one vseg 
+
+        s =  '            <vseg name="%s" vbase="0x%x" mode="%s" x="%d" y="%d" psegname="%s"' \
+             % ( self.name, self.vbase, self.mode, self.x, self.y, self.psegname )
+        if ( self.ident ):  s += ' ident="1" >\n'
+        else:               s += ' >\n'
+        for vobj in self.vobjs: s += vobj.xml()
+        s += '            </vseg>\n'
+
         return s
 
-#####################
-class Task( object ):
-#####################
-    def __init__( self, name, trdid, x, y, p, stackname, heapname, startid, \
-                  usetty = False, usenic = False, usehba = False ):
-        self.name      = name       # thread name
-        self.trdid     = trdid      # thread index (unique in vspace)
-        self.x         = x          # processor x coordinate 
-        self.y         = y          # processor y coordinate 
-        self.p         = p          # processor local index  
-        self.stackname = stackname  # name of vobj containing the stack
-        self.heapname  = heapname   # name of vobj containing the heap
-        self.startid   = startid    # index in start_vector
-        self.usetty    = usetty     # request a private TTY channel
-        self.usenic    = usenic     # request a private NIC channel
-        self.usehba    = usehba     # request a private HBA channel
-        return
-
-    ####################
-    def __str__( self ):    # xml for one task
-        s = '        <task name="%s" trdid="%d" x="%d" y="%d" p="%d" stackname="%s" heapname="%s" startid="%d"' \
-            % (self.name, self.trdid, self.x, self.y, self.p, self.stackname, self.heapname, self.startid)
-        if self.usetty != 0:
-            s += ' usetty="1"'  
-        if self.usenic != 0:
-            s += ' usenic="1"'  
-        if self.usehba != 0:
-            s += ' usehba="1"'  
-        s += ' />\n'           
-        return s
-
-######################
-class Vseg( object ):
-######################
-    def __init__( self, name, vbase, mode, x, y, psegname, ident = False ):
-        assert mode in ['CXWU','CXW_','CX_U','CX__',
-                        'C_WU','C_W_','C__U','C___',
-                        '_XWU','_XW_','_X_U','_X__',
-                        '__WU','__W_','___U','____']
-        self.name     = name
-        self.vbase    = vbase
-        self.mode     = mode
-        self.x        = x
-        self.y        = y
-        self.psegname = psegname
-        self. ident   = ident
-        self.vobjs   = []
-        return
-
-    #####################
-    def add ( self, vo ):
-        self.vobjs.append( vo )
-        return
-
-    ####################
-    def __str__( self ):  # xml for one vseg
-        s = '        <vseg name="%s" vbase="0x%x" mode="%s" x="%d" y="%d" psegname="%s"' \
-            % ( self.name, self.vbase, self.mode, self.x, self.y, self.psegname )
-        if self.ident != 0:
-            s += ' ident="1"'
-        s += ' >\n'
-        for vobj in self.vobjs:
-            s += str( vobj )
-        s += '        </vseg>\n'
-        return s
-
-######################
+    #############################################
+    def cbin( self, mapping, verbose, expected ):    # C binary structure for Vseg
+
+        if ( verbose ):
+            print '*** cbin for vseg[%d] %s' % (self.index, self.name)
+
+        # check index
+        if (self.index != expected):
+            print 'error in Vseg.cbin() : vseg global index = %d / expected = %d' \
+                  % (self.index, expected )
+            sys.exit(1)
+
+        # compute pseg_id
+        pseg_id = 0xFFFFFFFF
+        cluster_id = (self.x * mapping.y_size) + self.y
+        cluster = mapping.clusters[cluster_id]
+        for pseg in cluster.psegs:
+            if (self.psegname == pseg.name):
+                pseg_id = pseg.index
+        if (pseg_id == 0xFFFFFFFF):
+            print 'error in Vseg.cbin() : psegname %s not found for vseg %s in cluster %d' \
+                  % ( self.psegname, self.name, cluster_id )
+            sys.exit(1)
+
+        # compute numerical value for mode
+        mode_id = 0xFFFFFFFF
+        for x in xrange( len(VSEGMODES) ):  
+            if ( self.mode == VSEGMODES[x] ):  
+                mode_id = x
+        if ( mode_id == 0xFFFFFFFF ):
+            print 'error in Vseg.cbin() : undefined vseg mode %s' % self.mode
+            sys.exit(1)
+
+        # compute vobj_id
+        vobj_id = self.vobjs[0].index  
+
+        byte_stream = bytearray()
+        byte_stream += mapping.str2bytes( 32, self.name )       # vseg name 
+        byte_stream += mapping.int2bytes( 4,  self.vbase )      # virtual base address
+        byte_stream += mapping.int2bytes( 8,  0 )               # physical base address
+        byte_stream += mapping.int2bytes( 4,  0 )               # vseg size (bytes)
+        byte_stream += mapping.int2bytes( 4,  pseg_id )         # physical segment global index
+        byte_stream += mapping.int2bytes( 4,  mode_id )         # CXWU flags
+        byte_stream += mapping.int2bytes( 4,  len(self.vobjs) ) # number of vobjs in vseg
+        byte_stream += mapping.int2bytes( 4,  vobj_id )         # first vobj global index 
+        byte_stream += mapping.int2bytes( 4,  0 )               # linked list of vsegs on same pseg
+        byte_stream += mapping.int2bytes( 1,  0 )               # mapped when non zero
+        byte_stream += mapping.int2bytes( 1,  self.ident )      # identity mapping when non zero
+        byte_stream += mapping.int2bytes( 2,  0 )               # reserved (padding)
+
+        if ( verbose ):
+            print 'vbase      = %x' %  self.vbase
+            print 'pseg_id    = %d' %  pseg_id
+            print 'mode       = %s' %  self.mode
+            print 'nb_vobjs   = %d' %  len(self.vobjs)
+            print 'vobj_id    = %d' %  vobj_id 
+     
+        return byte_stream
+
+###########################################################################################
 class Vobj( object ):
-######################
-    def __init__( self, name, length, vtype, binpath = None, align = 0, init = 0 ):
+###########################################################################################
+    def __init__( self,
+                  name, 
+                  length, 
+                  vtype, 
+                  binpath = '', 
+                  align   = 0, 
+                  init    = 0 ):
+
         assert vtype in ['ELF','BLOB','PTAB','PERI','MWMR','LOCK', \
                          'BUFFER','BARRIER','CONST','MEMSPACE','SCHED']
-        self.name     = name
-        self.vtype    = vtype
-        self.length   = length
-        self.binpath  = binpath
-        self.align    = align
-        self.init     = init  
+
+        assert (vtype != 'ELF') or (binpath != '')
+
+        self.index    = 0        # global index ( set by addVobj() )
+        self.name     = name     # vobj name (unique in vspace)
+        self.vtype    = vtype    # vobj type (defined in mapping_info.h)
+        self.length   = length   # vobj size (bytes)
+        self.binpath  = binpath  # pathname for (ELF type)
+        self.align    = align    # required alignment (logarithm of 2)
+        self.init     = init     # initialisation value (for BARRIER or MWMR types)
+
         return
 
-    ####################
-    def __str__( self ):  # xml for a vobj
+    ################
+    def xml( self ):  # xml for a vobj
+
         s = '            <vobj name="%s" type="%s" length="0x%x"' \
                            % ( self.name, self.vtype, self.length )
-        if (self.binpath != None):
-            s += ' binpath="%s"' % (self.binpath)
-        if (self.align != 0):
-            s += ' align="%d"' % (self.align)
-        if (self.init != 0):
-            s += ' init="%d"' % (self.init)
+        if (self.binpath != ''):   s += ' binpath="%s"' % (self.binpath)
+        if (self.align   != 0 ):   s += ' align="%d"' % (self.align)
+        if (self.init    != 0 ):   s += ' init="%d"' % (self.init)
         s += ' />\n'
+
         return s
 
-#########################
-class Cluster ( object ):
-#########################
-    def __init__( self, x, y ):
-        self.x           = x
-        self.y           = y
-        self.psegs       = []
-        self.peripherals = []
-        self.procs       = []
+    #############################################
+    def cbin( self, mapping, verbose, expected ):    # C binary structure for Vobj
+
+        # check index
+        if (self.index != expected):
+            print 'error in Vobj.cbin() : vobj global index = %d / expected = %d' \
+                  % (self.index, expected )
+            sys.exit(1)
+        elif ( verbose ):
+            print '*** cbin for vobj[%d] %s' % (self.index, self.name)
+
+        # compute numerical value for vtype
+        vtype_int = 0xFFFFFFFF
+        for x in xrange( len(VOBJTYPES) ):  
+            if ( self.vtype == VOBJTYPES[x] ):  
+                vtype_int = x
+        if ( vtype_int == 0xFFFFFFFF ):
+            print 'error in Vobj.cbin() : undefined vobj type %s' % self.vtype
+            sys.exit(1)
+
+        byte_stream = bytearray()
+        byte_stream += mapping.str2bytes( 32, self.name )       # vobj name 
+        byte_stream += mapping.str2bytes( 64, self.binpath )    # pathname for .elf file
+        byte_stream += mapping.int2bytes( 4 , vtype_int )       # vobj type
+        byte_stream += mapping.int2bytes( 4 , self.length )     # vobj size
+        byte_stream += mapping.int2bytes( 4 , self.align )      # required alignment
+        byte_stream += mapping.int2bytes( 4 , 0 )               # virtual base address
+        byte_stream += mapping.int2bytes( 8 , 0 )               # physical base address
+        byte_stream += mapping.int2bytes( 4 , self.init )       # init value
+     
+        if ( verbose ):
+            print 'binpath    = %s' %  self.binpath
+            print 'type       = %s' %  self.vtype
+            print 'length     = %x' %  self.length
+       
+        return byte_stream
+
+###########################################################################################
+class Processor ( object ):
+###########################################################################################
+    def __init__( self,
+                  x, 
+                  y, 
+                  lpid ):
+
+        self.index    = 0      # global index ( set by addProc() )
+        self.x        = x      # x cluster coordinate
+        self.y        = y      # y cluster coordinate
+        self.lpid     = lpid   # processor local index
+
         return
 
-    ####################
-    def __str__( self ):  # xml for a cluster
-        s = '        <cluster x="%d" y="%d" >\n' % (self.x, self.y)
-        for pseg in self.psegs:
-            s += str( pseg )             # psegs type RAM
-        for peri in self.peripherals:
-            s += str(peri.pseg)          # psegs type PERI
-        for proc in self.procs:
-            s += str( proc )             # processors
-        for peri in self.peripherals:
-            s += str( peri )             # peripherals
-        s += '        </cluster>\n'
-        return s
-
-###########################
-class Processor ( object ):
-###########################
-    def __init__( self, x, y, lpid ):
-        self.x    = x
-        self.y    = y
-        self.lpid = lpid
-        return
-
-    ####################
-    def __str__( self ):   # xml for a processor      
+    ################
+    def xml( self ):   # xml for a processor      
         return '            <proc index="%d" />\n' % (self.lpid)
 
-######################
+    #############################################
+    def cbin( self, mapping, verbose, expected ):    # C binary structure for Proc
+
+        if ( verbose ):
+            print '*** cbin for proc %d in cluster (%d,%d)' % (self.lpid, self.x, self.y)
+
+        # check index
+        if (self.index != expected):
+            print 'error in Proc.cbin() : proc global index = %d / expected = %d' \
+                  % (self.index, expected )
+            sys.exit(1)
+
+        byte_stream = bytearray()
+        byte_stream += mapping.int2bytes( 4 , self.lpid )       # local index
+     
+        return byte_stream
+
+###########################################################################################
 class Pseg ( object ):
-######################
-    def __init__( self, name, base, size, segtype ):
-        self.name     = name
-        self.base     = base
-        self.size     = size
-        self.segtype  = segtype
-        assert segtype in ['RAM','PERI']
+###########################################################################################
+    def __init__( self, 
+                  name, 
+                  base, 
+                  size, 
+                  x,
+                  y,
+                  segtype ):
+
+        assert( segtype in PSEGTYPES )
+
+        self.index    = 0       # global index ( set by addPseg() )
+        self.name     = name    # pseg name (unique in cluster)
+        self.base     = base    # physical base address
+        self.size     = size    # segment size (bytes)
+        self.x        = x       # cluster x coordinate 
+        self.y        = y       # cluster y coordinate 
+        self.segtype  = segtype # RAM / PERI (defined in mapping_info.h)
+
         return
    
-    ####################
-    def __str__( self ):   # xml for a pseg
+    ################
+    def xml( self ):   # xml for a pseg
+
         return '            <pseg name="%s" type="%s" base="0x%x" length="0x%x" />\n' \
                 % (self.name, self.segtype, self.base, self.size)
 
-############################
-class Peripheral ( object ):
-############################
-    def __init__( self, name, base, size, ptype, subtype, channels = 1):
-        self.channels   = channels
-        self.ptype      = ptype
-        self.subtype    = subtype
-        self.pseg       = Pseg( name, base, size, 'PERI' )
+    ######################################################
+    def cbin( self, mapping, verbose, expected, cluster ):    # C binary structure for Pseg
+
+        if ( verbose ):
+            print '*** cbin for pseg[%d] %s in cluster[%d,%d]' \
+                  % (self.index, self.name, cluster.x, cluster.y)
+
+        # check index
+        if (self.index != expected):
+            print 'error in Pseg.cbin() : pseg global index = %d / expected = %d' \
+                  % (self.index, expected )
+            sys.exit(1)
+        
+        # compute numerical value for segtype
+        segtype_int = 0xFFFFFFFF
+        for x in xrange( len(PSEGTYPES) ):  
+            if ( self.segtype == PSEGTYPES[x] ):  
+                segtype_int = x
+        if ( segtype_int == 0xFFFFFFFF ):
+            print 'error in Pseg.cbin() : undefined segment type %s' % self.segtype
+            sys.exit(1)
+
+        byte_stream = bytearray()
+        byte_stream += mapping.str2bytes( 32, self.name )      # pseg name 
+        byte_stream += mapping.int2bytes( 8 , self.base )      # physical base address
+        byte_stream += mapping.int2bytes( 8 , self.size )      # segment length
+        byte_stream += mapping.int2bytes( 4 , segtype_int )    # segment type
+        byte_stream += mapping.int2bytes( 4 , cluster.index )  # cluster global index
+        byte_stream += mapping.int2bytes( 4 , 0 )              # linked list of vsegs 
+
+        if ( verbose ):
+            print 'pbase      = %x' %  self.base
+            print 'size       = %x' %  self.size
+            print 'type       = %s' %  self.segtype
+        
+        return byte_stream
+
+###########################################################################################
+class Periph ( object ):
+###########################################################################################
+    def __init__( self, 
+                  pseg,               # associated pseg
+                  ptype,              # peripheral type
+                  subtype  = 'NONE',  # peripheral subtype
+                  channels = 1,       # for multi-channels peripherals
+                  arg      = 0 ):     # optional argument (semantic depends on ptype)
+
+        assert ptype in PERIPHTYPES
+
+        assert subtype in PERIPHSUBTYPES
+
+        self.index    = 0            # global index ( set by addPeriph() )
+        self.channels = channels  
+        self.ptype    = ptype 
+        self.subtype  = subtype 
+        self.arg      = arg
+        self.pseg     = pseg
+        self.irqs     = []
         return
 
-    ####################
-    def __str__( self ):    # xml for a peripheral
-        s = '            <periph type="%s" subtype="%s" psegname="%s" channels="%d" >\n' \
-               % ( self.ptype, self.subtype, self.pseg.name, self.channels )
-        if ( self.ptype == 'PIC' ):
-            for i in self.irqs:
-                s += str( i )         #  picIrq
-        if ( (self.ptype == 'XCU') or (self.ptype == 'ICU') ):
-            for i in self.irqs:
-                s += str( i )         #  xcuIrq
+    ################
+    def xml( self ):    # xml for a periph
+
+        s =  '            <periph type="%s"' % self.ptype
+        s += ' subtype="%s"'                 % self.subtype
+        s += ' psegname="%s"'                % self.pseg.name
+        s += ' channels="%d"'                % self.channels
+        s += ' arg="%d" >\n'                 % self.arg
+        if ( (self.ptype == 'PIC') or (self.ptype == 'XCU') or (self.ptype == 'ICU') ):
+            for irq in self.irqs: s += irq.xml()
         s += '            </periph>\n'
+
         return s
 
-########################
-class Tty( Peripheral ):
-########################
-    def __init__( self, name, base, size, channels ):
-        Peripheral.__init__( self, name, base, size, 'TTY', 'NONE', channels )
+    #############################################
+    def cbin( self, mapping, verbose, expected ):    # C binary structure for Periph
+
+        if ( verbose ):
+            print '*** cbin for periph %s in cluster [%d,%d]' \
+                  % (self.ptype, self.pseg.x, self.pseg.y)
+
+        # check index
+        if (self.index != expected):
+            print 'error in Periph.cbin() : periph global index = %d / expected = %d' \
+                  % (self.index, expected )
+            sys.exit(1)
+
+        # compute pseg global index
+        pseg_id = self.pseg.index
+
+        # compute first irq global index
+        if ( len(self.irqs) > 0 ):
+            irq_id = self.irqs[0].index
+        else:
+            irq_id = 0
+
+        # compute numerical value for ptype
+        ptype_id = 0xFFFFFFFF
+        for x in xrange( len(PERIPHTYPES) ):  
+            if ( self.ptype == PERIPHTYPES[x] ):  ptype_id = x
+        if ( ptype_id == 0xFFFFFFFF ):
+            print 'error in Periph.cbin() : undefined peripheral type %s' % self.ptype
+            sys.exit(1)
+
+        # compute numerical value for subtype
+        subtype_id = 0xFFFFFFFF
+        for x in xrange( len(PERIPHSUBTYPES) ):  
+            if ( self.subtype == PERIPHSUBTYPES[x] ):  subtype_id = x
+
+        # compute
+        byte_stream = bytearray()
+        byte_stream += mapping.int2bytes( 4 , ptype_id )         # peripheral type      
+        byte_stream += mapping.int2bytes( 4 , subtype_id )       # peripheral subtype
+        byte_stream += mapping.int2bytes( 4 , pseg_id )          # pseg global index 
+        byte_stream += mapping.int2bytes( 4 , self.channels )    # number of channels
+        byte_stream += mapping.int2bytes( 4 , self.arg )         # optionnal argument
+        byte_stream += mapping.int2bytes( 4 , len( self.irqs ) ) # number of input irqs 
+        byte_stream += mapping.int2bytes( 4 , irq_id )           # first irq global index 
+
+        if ( verbose ):
+            print 'ptype      = %d' %  ptype_id
+            print 'pseg_id    = %d' %  pseg_id
+            print 'nb_irqs    = %d' %  len( self.irqs )
+            print 'irq_id     = %d' %  irq_id        
+        return byte_stream
+
+###########################################################################################
+class Irq ( object ):
+###########################################################################################
+    def __init__( self, 
+                  irqtype,         # input IRQ type : HWI / WTI / PTI (for XCU only)
+                  srcid,           # input IRQ index (for XCU or PIC)
+                  isrtype,         # Type of ISR to be executed
+                  channel = 0 ):   # channel index for multi-channel ISR
+
+        assert irqtype in IRQTYPES
+        assert isrtype in ISRTYPES
+        assert srcid < 32
+
+        self.index   = 0        # global index ( set by addIrq() )
+        self.irqtype = irqtype  # IRQ type 
+        self.srcid   = srcid    # source IRQ index
+        self.isrtype = isrtype  # ISR type 
+        self.channel = channel  # channel index (for multi-channels ISR)
         return
 
-########################
-class Dma( Peripheral ):
-########################
-    def __init__( self, name, base, size, channels ):
-        Peripheral.__init__( self, name, base, size, 'DMA', 'NONE', channels )
+    ################
+    def xml( self ):   # xml for Irq
+
+        return '                <irq srctype="%s" srcid="%d" isr="%s" channel="%d" />\n' \
+                % ( self.irqtype, self.srcid, self.isrtype, self.channel )
+
+    #############################################
+    def cbin( self, mapping, verbose, expected ):     # C binary structure for Irq
+
+        if ( verbose ):
+            print '*** cbin for irq[%d]' % (self.index) 
+
+        # check index
+        if (self.index != expected):
+            print 'error in Irq.cbin() : irq global index = %d / expected = %d' \
+                  % (self.index, expected )
+            sys.exit(1)
+
+        # compute numerical value for irqtype
+        irqtype_id = 0xFFFFFFFF
+        for x in xrange( len(IRQTYPES) ):
+            if ( self.irqtype == IRQTYPES[x] ):  
+                irqtype_id = x
+        if ( irqtype_id == 0xFFFFFFFF ):
+            print 'error in Irq.cbin() : undefined irqtype %s' % self.irqtype
+            sys.exit(1)
+
+        # compute numerical value for isrtype
+        isrtype_id = 0xFFFFFFFF
+        for x in xrange( len(ISRTYPES) ):  
+            if ( self.isrtype == ISRTYPES[x] ):  
+                isrtype_id = x
+        if ( isrtype_id == 0xFFFFFFFF ):
+            print 'error in Irq.cbin() : undefined isrtype %s' % self.isrtype
+            sys.exit(1)
+
+        byte_stream = bytearray()
+        byte_stream += mapping.int2bytes( 4,  irqtype_id )
+        byte_stream += mapping.int2bytes( 4,  self.srcid )
+        byte_stream += mapping.int2bytes( 4,  isrtype_id )
+        byte_stream += mapping.int2bytes( 4,  self.channel )
+        byte_stream += mapping.int2bytes( 4,  0 )
+        byte_stream += mapping.int2bytes( 4,  0 )
+
+        if ( verbose ):
+            print 'irqtype    = %s' %  self.irqtype
+            print 'srcid      = %d' %  self.srcid
+            print 'isrtype    = %s' %  self.isrtype
+            print 'channel    = %d' %  self.channel
+
+        return byte_stream
+
+###########################################################################################
+class Coproc ( object ):
+###########################################################################################
+    def __init__( self, 
+                  pseg ):           # associated pseg 
+
+        self.index    = 0        # global index value set by addCoproc()
+        self.pseg     = pseg
+        self.ports    = []
+
         return
 
-########################
-class Bdv( Peripheral ):
-########################
-    def __init__( self, name, base, size ):
-        Peripheral.__init__( self, name, base, size, 'IOC', 'BDV' )
+    ################
+    def xml( self ):    # xml for Coproc  
+
+        print 'error in Coproc.xml() : not defined yet'
+        sys.exit(1)
+
+        return 
+
+    #############################################
+    def cbin( self, mapping, verbose, expected ):    # C binary structure for Coproc
+
+        if ( verbose ):
+            print '*** cbin for coproc in cluster (%d,%d)' % (self.pseg.x, self.pseg.y)
+
+        # check index
+        if (self.index != expected):
+            print 'error in Coproc.cbin() : coproc global index = %d / expected = %d' \
+                  % (self.index, expected )
+            sys.exit(1)
+
+        # compute pseg global index
+        pseg_id = self.pseg.index
+
+        # compute first port global index
+        port_id = self.ports[0].index
+
+        byte_stream = bytearray()
+        byte_stream += mapping.str2bytes( 32, self.pseg.name )    # probablement inutile (AG)
+        byte_stream += mapping.int2bytes( 4 , pseg_id )           # pseg global index 
+        byte_stream += mapping.int2bytes( 4 , len( self.ports ) ) # number of input irqs 
+        byte_stream += mapping.int2bytes( 4 , port_id )           # first port global index 
+        
+        if ( verbose ):
+            print 'irqtype    = %s' %  self.irqtype
+            print 'pseg_id    = %d' %  pseg_id
+            print 'nb_ports   = %d' %  len( self.ports )
+            print 'port_id      %d' %  port_id
+          
+        return byte_stream
+
+###########################################################################################
+class Cpport ( object ):
+###########################################################################################
+    def __init__( self, 
+                  direction, 
+                  vspacename, 
+                  mwmrname ):
+
+        self.index      = 0           # global index ( set by addCpport() )
+        self.direction  = direction   # TO_COPROC / FROM_COPROC
+        self.vspacename = vspacename  # name of vspace containing mwmr channel
+        self.mwmrname   = mwmrname    # name of vobj defining mwmr channel
+
         return
 
-########################
-class Spi( Peripheral ):
-########################
-    def __init__( self, name, base, size ):
-        Peripheral.__init__( self, name, base, size, 'IOC', 'SPI' )
-        return
-
-########################
-class Hba( Peripheral ):
-########################
-    def __init__( self, name, base, size, channels ):
-        Peripheral.__init__( self, name, base, size, 'IOC', 'HBA', channels )
-        return
-
-########################
-class Nic( Peripheral ):
-########################
-    def __init__( self, name, base, size, channels ):
-        Peripheral.__init__( self, name, base, size, 'NIC', 'NONE', channels )
-        return
-
-########################
-class Cma( Peripheral ):
-########################
-    def __init__( self, name, base, size, channels ):
-        Peripheral.__init__( self, name, base, size, 'CMA', 'NONE', channels )
-        return
-
-########################
-class Fbf( Peripheral ):
-########################
-    def __init__( self, name, base, size ):
-        Peripheral.__init__( self, name, base, size, 'FBF', 'NONE' )
-        return
-
-########################
-class Tim( Peripheral ):
-########################
-    def __init__( self, name, base, size, channels ):
-        Peripheral.__init__( self, name, base, size, 'TIM', 'NONE', channels )
-        return
-
-########################
-class Iob( Peripheral ):
-########################
-    def __init__( self, name, base, size ):
-        Peripheral.__init__( self, name, base, size, 'IOB', 'NONE' )
-        return
-
-########################
-class Rom( Peripheral ):
-########################
-    def __init__( self, name, base, size ):
-        Peripheral.__init__( self, name, base, size, 'ROM', 'NONE' )
-        return
-
-########################
-class Mmc( Peripheral ):
-########################
-    def __init__( self, name, base, size ):
-        Peripheral.__init__( self, name, base, size, 'MMC', 'NONE' )
-        return
-
-########################
-class Xcu( Peripheral ):
-########################
-    def __init__( self, name, base, size, channels ):
-        Peripheral.__init__( self, name, base, size, 'XCU', 'NONE', channels )
-        self.irqs  = []
-        return
-
-    def add ( self, irq ):
-        self.irqs.append( irq )
-        return
-
-########################
-class Icu( Peripheral ):
-########################
-    def __init__( self, name, base, size, channels ):
-        Peripheral.__init__( self, name, base, size, 'ICU', 'NONE', channels )
-        self.irqs  = []
-        return
-
-    ######################
-    def add ( self, irq ):
-        self.irqs.append( irq )
-        return
-
-########################
-class Pic( Peripheral ):
-########################
-    def __init__( self, name, base, size, channels ):
-        Peripheral.__init__( self, name, base, size, 'PIC', 'NONE', channels )
-        self.irqs  = []
-        return
-
-    ######################
-    def add ( self, irq ):
-        self.irqs.append( irq )
-        return
-
-########################
-class XcuIrq ( object ):
-########################
-    def __init__( self, srctype, srcid, isrtype, channel = 0, dstid = 0 ):
-        assert srctype in ['HWI','WTI','PTI']
-        assert isrtype in ['ISR_DEFAULT','ISR_TICK','ISR_TTY_RX','ISR_TTY_TX',
-                           'ISR_BDV', 'ISR_TIMER', 'ISR_WAKUP', 'ISR_NIC_RX',
-                           'ISR_NIC_TX','ISR_CMA','ISR_MMC']
-        assert srcid < 32
-        self.srctype = srctype
-        self.srcid   = srcid
-        self.isrtype = isrtype
-        self.channel = channel
-        self.dstid   = dstid
-        return
-
-    ####################
-    def __str__( self ):   # xml for an xcuIrq
-        s = '                <irq srctype="%s" srcid="%d" isr="%s" channel="%d" dstid="%d" />\n' \
-                % (self.srctype, self.srcid, self.isrtype, self.channel, self.dstid)
-        return s
-
-########################
-class PicIrq ( object ):
-########################
-    def __init__( self, srcid, dstx, dsty, dstid ):
-        assert srcid < 32
-        self.srcid   = srcid
-        self.dstx    = dstx
-        self.dsty    = dsty
-        self.dstid   = dstid
-        return
-
-    ####################
-    def __str__( self ):   # xml for a picIrq
-        s = '                <irq srcid="%d" dstx="%d" dsty="%d" dstid="%d" />\n' \
-                % (self.srcid, self.dstx, self.dsty, self.dstid)
-        return s
+    ################
+    def xml( self ):    # xml for Cpport
+
+        print 'error in Cpport.xml() : not defined yet'
+        sys.exit(1)
+
+        return 
+
+    #############################################
+    def cbin( self, mapping, verbose, expected ):    # C binary structure for Cpport
+
+        if ( verbose ):
+            print '*** cbin for cpport[%d]' % (self.index)
+
+        # check index
+        if ( self.index != expected ):
+            print 'error in Cpport.cbin() : port global index = %d / expected = %d' \
+                  % ( self.index, expected )
+            sys.exit(1)
+
+        # compute numerical value for direction
+        if ( self.direction == 'TO_COPROC' ):
+             dir_int = 0
+        else:
+             dir_int = 1
+
+        # compute vspace global index
+        vspace_id = 0xFFFFFFFF
+        for vspace in mapping.vspaces:
+            if ( self.vspacename == vspace.name ): 
+                vspace_id = vspace.index
+        if (vspace_id == 0xFFFFFFFF):
+            print 'error in Cpport.cbin() : vspace name %s not found' \
+                  % ( self.vspacename )
+            sys.exit(1)
+
+        # compute mwmr global index
+        mwmr_id = 0xFFFFFFFF
+        for vseg in mapping.vspace[vspace_id].vsegs:
+            for vobj in vseg.vobjs:
+                if (self.mwmrname == vobj.name): 
+                    mwmr_id = vobj.index
+        if (mwmr_id == 0xFFFFFFFF):
+            print 'error in Cpport.cbin() : mwmr vobj name %s not found in vspace %s' \
+                  % ( self.mwmrname, self.vspacename )
+            sys.exit(1)
+
+        byte_stream = bytearray()
+        byte_stream += mapping.int2bytes( 4 , dir_int )         # pseg global index 
+        byte_stream += mapping.int2bytes( 4 , vspace_id )       # vspace global index  
+        byte_stream += mapping.int2bytes( 4 , mwmr_id )         # mwmr vobj global index 
+        
+        if ( verbose ):
+            print 'direction  = %s' %  self.direction
+            print 'vspace_id  = %d' %  vspace_id
+            print 'mwmr_id    = %d' %  mwmr_id
+
+        return byte_stream
 
 
Index: soft/giet_vm/giet_python/tsarmap
===================================================================
--- soft/giet_vm/giet_python/tsarmap	(revision 319)
+++ soft/giet_vm/giet_python/tsarmap	(revision 319)
@@ -0,0 +1,207 @@
+#!/usr/bin/env python
+
+#######################################################################################
+#   file   : tsarmap
+#   date   : april 2014
+#   author : Alain Greiner
+#######################################################################################
+# This generic script maps one or several multi-tasks applications on a specific 
+# instance of the multi-processors/multi-clusters TSAR architecture. 
+#
+# It generates the files required for hardware and software compilation:
+#
+# 1) The "hard_config.h" file is used to generate the top.cppnetbsd file (hardware),
+#    and to compile the tsar_preloader.elf, the GietVM boot.elf and kernel.elf files.
+#
+# 2) The optionals "map.bin" and vsegs.ld" files are used to configure the GietVM.
+#
+# 3) The optional "netbsd.dts" file can be used to configure NetBSD.
+#
+# 4) The optional "arch.bib" file can be used to configure ALMOS.
+#
+# 5) An optional "map.xml" file can be generated for debug. 
+#######################################################################################
+# The hardware parameters  are:
+#  - x_size    : number of clusters in a row
+#  - y_size    : number of clusters in a column
+#  - nprocs    : number of processors per cluster
+#######################################################################################
+# The supported platforms are:
+# - tsar_generic_iob
+# - tsar_generic_leti
+#######################################################################################
+# The supported parallel applications are:
+# - sort (one thread per processor)
+# - transpose (one thread per processor)
+#######################################################################################
+
+from optparse import OptionParser
+
+from mapping import *
+
+from transpose import *
+from sort import *
+
+import sys
+
+######################################################################################
+#   define command line arguments   
+######################################################################################
+
+parser = OptionParser()
+
+parser.add_option( '--arch', type = 'string', dest = 'arch_path',
+                   help = 'define pathname to architecture' )
+
+parser.add_option( '--x', type = 'int', dest = 'x_size', 
+                   default = 2,
+                   help = 'define number of clusters in a row' )
+
+parser.add_option( '--y', type = 'int', dest = 'y_size', 
+                   default = 2,
+                   help = 'define number of clusters in a column' )
+
+parser.add_option( '--p', type = 'int', dest = 'nprocs', 
+                   default = 2,
+                   help = 'define number of processors per cluster' )
+
+parser.add_option( '--v', action = 'store_true', dest = 'verbose',
+                   default = False,
+                   help = 'display detailed report on map.bin file generation' )
+
+parser.add_option( '--netbsd', type = 'string', dest = 'netbsd_path', 
+                   help = 'define pathname for the netbsd.dts file' )
+
+parser.add_option( '--almos', type = 'string', dest = 'almos_path', 
+                   help = 'define pathname for the arch.bib file' )
+
+parser.add_option( '--giet', type = 'string', dest = 'giet_path', 
+                   help = 'define pathname for the map.bin & vsegs.ld file ' )
+
+parser.add_option( '--xml', type = 'string', dest = 'xml_path', 
+                   help = 'define pathname for the map.xml file' )
+
+############  supported applications   ###############################################
+
+parser.add_option( '--transpose', action = 'store_true', dest = 'transpose',
+                   default = False,
+                   help = 'map the "transpose" application for the GIET' )
+
+parser.add_option( '--sort', action = 'store_true', dest = 'sort',     
+                   default = False,
+                   help = 'map the "sort" application for the GIET' )
+
+######################################################################################
+#   Get command line arguments
+######################################################################################
+
+(options,args) = parser.parse_args()
+
+x_size        = options.x_size      # number of clusters in a row
+y_size        = options.y_size      # number of clusters in a column
+nprocs        = options.nprocs      # number of processors in a cluster
+
+verbose       = options.verbose     # report on map.bin generation if True
+
+netbsd_path   = options.netbsd_path # path for netbsd.dts file 
+almos_path    = options.almos_path  # path for arch.bib file
+giet_path     = options.giet_path   # path for map.bin & vsegs.ld files
+
+arch_path     = options.arch_path   # path to selected architecture
+
+xml_path      = options.xml_path    # path for map.xml file     
+
+map_transpose = options.transpose   # map "sort" application if True
+map_sort      = options.sort        # map "transpose" application if True
+
+######################################################################################
+#   build empty platform (no applications yet)
+######################################################################################
+
+if   ( arch_path == None  ):  
+    print 'You must select a generic architecture on the command line' 
+    sys.exit(1)
+
+# dynamically append the architecture to PYTHON path (directory pathname)
+sys.path.append( arch_path )
+
+# dynamically import the PYTHON mapping generator module (file name)
+select = __import__( 'genmap' )
+
+# build mapping calling the function (function name)
+mapping = select.genmap( x_size, y_size, nprocs )
+print '[tsarmap] platform %s build' % mapping.name 
+
+# generate the hard_confi.h file for top.cpp compilation
+pathname = arch_path + '/hard_config.h'
+f = open ( pathname, 'w' )
+f.write( mapping.hard_config() )
+print '[tsarmap] %s generated' % pathname
+
+######################################################################################
+#   complete mapping with application(s) as required
+######################################################################################
+
+if ( map_transpose ): 
+    transpose( mapping )
+    print '[tsarmap] application "transpose" loaded'
+
+if ( map_sort ):      
+    sort( mapping )
+    print '[tsarmap] application "sort" loaded'
+
+######################################################################################
+#   Generate xml file if required.
+#   It can be used for debug.
+######################################################################################
+
+if ( xml_path != None ):
+    pathname = xml_path + '/map.xml'
+    f = open ( pathname, 'w' )
+    f.write( mapping.xml() )
+    print '[tsarmap] %s generated for debug' % pathname
+
+######################################################################################
+#   Generate netbsd.dts file if required.
+#   It is used for NetBSD configuration.
+######################################################################################
+
+if ( (netbsd_path != None) and (arch_path != None) ):
+    pathname = netbsd_path + '/netbsd.dts'
+    f = open ( pathname, 'w' )
+    f.write( mapping.netbsd_dts() )
+    print '[tsarmap] %s generated for netbsd' % pathname
+
+######################################################################################
+#   Generate arch.bib file if required.
+#   It is used for ALMOS configuration.
+######################################################################################
+
+if ( (almos_path != None) and (arch_path != None) ):
+    pathname = almos_path + '/arch.info'
+    f = open ( pathname, 'w' )
+    f.write( mapping.almos_arch() )
+    print '[tsarmap] %s generated for almos' % pathname
+
+######################################################################################
+#   Generate map.bin, giet_vsegs.ld, and hard_config.h files if required.
+#   They are used for GietVM compilation and configuration.
+######################################################################################
+
+if ( (giet_path != None) and (arch_path != None) ):
+
+    pathname = giet_path + '/map.bin'
+    f = open ( pathname, 'w' )
+    f.write( str( mapping.cbin( verbose ) ) )
+    print '[tsarmap] %s generated for giet_vm' % pathname
+
+    pathname = giet_path + '/hard_config.h'
+    f = open ( pathname, 'w' )
+    f.write( mapping.hard_config() )
+    print '[tsarmap] %s generated for giet_vm' % pathname
+
+    pathname = giet_path + '/giet_vsegs.ld'
+    f = open ( pathname, 'w' )
+    f.write( mapping.giet_vsegs() )
+    print '[tsarmap] %s generated for giet_vm' % pathname
+
