source: soft/giet_vm/giet_python/mapping.py @ 306

Last change on this file since 306 was 305, checked in by alain, 11 years ago

Introducing python interface to generate the map.xml files.

  • Property svn:executable set to *
File size: 17.8 KB
Line 
1#!/usr/bin/env python
2
3#######################################################################################
4#   file   : giet_mapping.py
5#   date   : april 2014
6#   author : Alain Greiner
7#######################################################################################
8#  This file contains the classes required to define a generic mapping in python
9#  for the GIET_VM.
10# - A 'Mapping' contains + various structural constants,
11#                        + a 'Cluster' set,     (hardware architecture)
12#                        + a 'Vseg' set,        (kernel virtual segments mapping)
13#                        + a 'Vspace' set       (several user applications).
14# - A 'Cluster' contains + coordinates (x,y),
15#                        + a 'Pseg' set,        (all physical segments in cluster)
16#                        + a 'Proc' set,        (processors in cluster)
17#                        + a 'Peripheral' set   (peripherals in cluster)
18# - A 'Vspace' contains  + a 'Vseg' set,        (user virtual segments mapping)
19#                        + a 'Task' set         (user tasks mapping)
20####################################################################################
21
22#########################
23class Mapping( object ):
24#########################
25    def __init__( self,
26                  name,                   # mapping name
27                  x_size,                 # number of clusters in a row
28                  y_size,                 # number of clusters in a column
29                  nb_procs,               # max number of processors per cluster
30                  x_width      = 4,       # number of bits encoding x coordinate
31                  y_width      = 4,       # number of bits encoding y coordinate
32                  paddr_width  = 32,      # number of bits for physical address
33                  coherence    = False,   # hardware cache coherence
34                  irq_per_proc = 1,       # number or IRQ lines from XCU to processor
35                  use_ram_disk = False,   # architecture contains ram_disk when true
36                  x_io         = 0,       # cluster_io x coordinate
37                  y_io         = 0 ):     # cluster_io y coordinate
38
39        self.name         = name
40        self.paddr_width  = paddr_width           
41        self.coherence    = coherence
42        self.x_size       = x_size
43        self.y_size       = y_size
44        self.x_width      = x_width
45        self.y_width      = y_width
46        self.irq_per_proc = irq_per_proc
47        self.nb_procs     = nb_procs     
48        self.use_ram_disk = use_ram_disk
49        self.x_io         = x_io
50        self.y_io         = y_io
51
52        self.total_procs  = 0
53        self.total_globs  = 0
54
55        # clusters array
56        self.clusters     = []
57        for x in xrange (1<<x_width):
58            for y in xrange (1<<y_width):
59                self.clusters.append( Cluster(x,y) )
60
61        # globals array
62        self.globs        = []
63
64        # vspace array
65        self.vspaces      = []
66
67        return
68
69    ##########################
70    def addPseg( self, pseg ):
71        cluster_xy = pseg.base >> (self.paddr_width - self.x_width - self.y_width)
72        x = cluster_xy >> (self.y_width);
73        y = cluster_xy & ((1 << self.y_width) - 1) 
74        if (x >= self.x_size) or (y >= self.y_size):
75            print '(x,y) coordinates too large for pdeg %s' % str(pseg)
76        self.clusters[cluster_xy].psegs.append( pseg )
77        return
78
79    ######################################
80    def addPeripheral( self, peripheral ):
81        cluster_xy = peripheral.pseg.base >> (self.paddr_width - self.x_width - self.y_width)
82        x = cluster_xy >> (self.y_width);
83        y = cluster_xy & ((1 << self.y_width) - 1) 
84        if (x >= self.x_size) or (y >= self.y_size):
85            print '(x,y) coordinates too large for pdeg %s' % str(pseg)
86        self.clusters[cluster_xy].peripherals.append( peripheral )
87        return
88
89    ###########################
90    def addProc ( self, proc ):
91        cluster_xy = (proc.x << self.y_width) + proc.y
92        self.clusters[cluster_xy].procs.append( proc )
93        self.total_procs += 1
94        if (proc.x >= self.x_size) or (proc.y >= self.y_size):
95            print '(x,y) coordinates too large for node %s' % str(proc)
96        return
97
98    ############################
99    def addGlobal( self, vseg ):
100        self.globs.append( vseg ) 
101        return
102
103    ##############################
104    def addVspace( self, vspace ):
105        self.vspaces.append( vspace )
106        return
107   
108    ####################
109    def __str__( self ):    # xml generation for mapping
110        s = '<?xml version="1.0"?>\n\n'
111        s += '<mapping_info signature    = "0xDACE2014"\n'
112        s += '              name         = "%s"\n'   % (self.name)
113        s += '              x_size       = "%d"\n'   % (self.x_size)
114        s += '              y_size       = "%d"\n'   % (self.y_size)
115        s += '              x_width      = "%d"\n'   % (self.x_width)
116        s += '              y_width      = "%d"\n'   % (self.y_width)
117        s += '              irq_per_proc = "%d"\n'   % (self.irq_per_proc)
118        s += '              use_ram_disk = "%d"\n'   % (self.use_ram_disk)
119        s += '              x_io         = "%d"\n'   % (self.x_io)
120        s += '              y_io         = "%d" >\n' % (self.y_io)
121        s += '    <clusterset>\n'
122        for x in xrange ( self.x_size ):
123            for y in xrange ( self.y_size ):
124                cluster_xy = (x << self.y_width) + y
125                s += str( self.clusters[cluster_xy] )
126        s += '    </clusterset>\n'
127        s += '    <globalset>\n'
128        for vseg in self.globs:
129            s += str ( vseg )
130        s += '    </globalset>\n'
131        s += '    <vspaceset>\n'
132        for vspace in self.vspaces:
133            s += str( vspace )
134        s += '    </vspaceset>\n'
135        s += '</mapping_info>\n'
136        return s
137       
138#######################
139class Vspace( object ):
140#######################
141    def __init__( self, name, startname ):
142        self.name      = name           # application name
143        self.startname = startname      # name of vobj containing the start_vector
144        self.vsegs     = []
145        self.tasks     = []
146        return
147    ##########################
148    def addTask( self, task ):
149        self.tasks.append( task )
150        return
151
152    ##########################
153    def addVseg( self, vseg ):
154        self.vsegs.append( vseg )
155        return
156
157    ####################
158    def __str__( self ):   # xml for one vspace
159        s =  '        <vspace name="%s" startname="%s" >\n' % ( self.name, self.startname )
160        for vseg in self.vsegs:
161            s += str( vseg )
162        for task in self.tasks:
163            s += str( task )
164        s += '        </vspace>\n'
165        return s
166
167#####################
168class Task( object ):
169#####################
170    def __init__( self, name, trdid, x, y, p, stackname, heapname, startid, \
171                  usetty = False, usenic = False, usehba = False ):
172        self.name      = name       # thread name
173        self.trdid     = trdid      # thread index (unique in vspace)
174        self.x         = x          # processor x coordinate
175        self.y         = y          # processor y coordinate
176        self.p         = p          # processor local index 
177        self.stackname = stackname  # name of vobj containing the stack
178        self.heapname  = heapname   # name of vobj containing the heap
179        self.startid   = startid    # index in start_vector
180        self.usetty    = usetty     # request a private TTY channel
181        self.usenic    = usenic     # request a private NIC channel
182        self.usehba    = usehba     # request a private HBA channel
183        return
184
185    ####################
186    def __str__( self ):    # xml for one task
187        s = '        <task name="%s" trdid="%d" x="%d" y="%d" p="%d" stackname="%s" heapname="%s" startid="%d"' \
188            % (self.name, self.trdid, self.x, self.y, self.p, self.stackname, self.heapname, self.startid)
189        if self.usetty != 0:
190            s += ' usetty="1"' 
191        if self.usenic != 0:
192            s += ' usenic="1"' 
193        if self.usehba != 0:
194            s += ' usehba="1"' 
195        s += ' />\n'           
196        return s
197
198######################
199class Vseg( object ):
200######################
201    def __init__( self, name, vbase, mode, x, y, psegname, ident = False ):
202        assert mode in ['CXWU','CXW_','CX_U','CX__',
203                        'C_WU','C_W_','C__U','C___',
204                        '_XWU','_XW_','_X_U','_X__',
205                        '__WU','__W_','___U','____']
206        self.name     = name
207        self.vbase    = vbase
208        self.mode     = mode
209        self.x        = x
210        self.y        = y
211        self.psegname = psegname
212        self. ident   = ident
213        self.vobjs   = []
214        return
215
216    #####################
217    def add ( self, vo ):
218        self.vobjs.append( vo )
219        return
220
221    ####################
222    def __str__( self ):  # xml for one vseg
223        s = '        <vseg name="%s" vbase="0x%x" mode="%s" x="%d" y="%d" psegname="%s"' \
224            % ( self.name, self.vbase, self.mode, self.x, self.y, self.psegname )
225        if self.ident != 0:
226            s += ' ident="1"'
227        s += ' >\n'
228        for vobj in self.vobjs:
229            s += str( vobj )
230        s += '        </vseg>\n'
231        return s
232
233######################
234class Vobj( object ):
235######################
236    def __init__( self, name, length, vtype, binpath = None, align = 0, init = 0 ):
237        assert vtype in ['ELF','BLOB','PTAB','PERI','MWMR','LOCK', \
238                         'BUFFER','BARRIER','CONST','MEMSPACE','SCHED']
239        self.name     = name
240        self.vtype    = vtype
241        self.length   = length
242        self.binpath  = binpath
243        self.align    = align
244        self.init     = init 
245        return
246
247    ####################
248    def __str__( self ):  # xml for a vobj
249        s = '            <vobj name="%s" type="%s" length="0x%x"' \
250                           % ( self.name, self.vtype, self.length )
251        if (self.binpath != None):
252            s += ' binpath="%s"' % (self.binpath)
253        if (self.align != 0):
254            s += ' align="%d"' % (self.align)
255        if (self.init != 0):
256            s += ' init="%d"' % (self.init)
257        s += ' />\n'
258        return s
259
260#########################
261class Cluster ( object ):
262#########################
263    def __init__( self, x, y ):
264        self.x           = x
265        self.y           = y
266        self.psegs       = []
267        self.peripherals = []
268        self.procs       = []
269        return
270
271    ####################
272    def __str__( self ):  # xml for a cluster
273        s = '        <cluster x="%d" y="%d" >\n' % (self.x, self.y)
274        for pseg in self.psegs:
275            s += str( pseg )             # psegs type RAM
276        for peri in self.peripherals:
277            s += str(peri.pseg)          # psegs type PERI
278        for proc in self.procs:
279            s += str( proc )             # processors
280        for peri in self.peripherals:
281            s += str( peri )             # peripherals
282        s += '        </cluster>\n'
283        return s
284
285###########################
286class Processor ( object ):
287###########################
288    def __init__( self, x, y, lpid ):
289        self.x    = x
290        self.y    = y
291        self.lpid = lpid
292        return
293
294    ####################
295    def __str__( self ):   # xml for a processor     
296        return '            <proc index="%d" />\n' % (self.lpid)
297
298######################
299class Pseg ( object ):
300######################
301    def __init__( self, name, base, size, segtype ):
302        self.name     = name
303        self.base     = base
304        self.size     = size
305        self.segtype  = segtype
306        assert segtype in ['RAM','PERI']
307        return
308   
309    ####################
310    def __str__( self ):   # xml for a pseg
311        return '            <pseg name="%s" type="%s" base="0x%x" length="0x%x" />\n' \
312                % (self.name, self.segtype, self.base, self.size)
313
314############################
315class Peripheral ( object ):
316############################
317    def __init__( self, name, base, size, ptype, subtype, channels = 1):
318        self.channels   = channels
319        self.ptype      = ptype
320        self.subtype    = subtype
321        self.pseg       = Pseg( name, base, size, 'PERI' )
322        return
323
324    ####################
325    def __str__( self ):    # xml for a peripheral
326        s = '            <periph type="%s" subtype="%s" psegname="%s" channels="%d" >\n' \
327               % ( self.ptype, self.subtype, self.pseg.name, self.channels )
328        if ( self.ptype == 'PIC' ):
329            for i in self.irqs:
330                s += str( i )         #  picIrq
331        if ( (self.ptype == 'XCU') or (self.ptype == 'ICU') ):
332            for i in self.irqs:
333                s += str( i )         #  xcuIrq
334        s += '            </periph>\n'
335        return s
336
337########################
338class Tty( Peripheral ):
339########################
340    def __init__( self, name, base, size, channels ):
341        Peripheral.__init__( self, name, base, size, 'TTY', 'NONE', channels )
342        return
343
344########################
345class Dma( Peripheral ):
346########################
347    def __init__( self, name, base, size, channels ):
348        Peripheral.__init__( self, name, base, size, 'DMA', 'NONE', channels )
349        return
350
351########################
352class Bdv( Peripheral ):
353########################
354    def __init__( self, name, base, size ):
355        Peripheral.__init__( self, name, base, size, 'IOC', 'BDV' )
356        return
357
358########################
359class Spi( Peripheral ):
360########################
361    def __init__( self, name, base, size ):
362        Peripheral.__init__( self, name, base, size, 'IOC', 'SPI' )
363        return
364
365########################
366class Hba( Peripheral ):
367########################
368    def __init__( self, name, base, size, channels ):
369        Peripheral.__init__( self, name, base, size, 'IOC', 'HBA', channels )
370        return
371
372########################
373class Nic( Peripheral ):
374########################
375    def __init__( self, name, base, size, channels ):
376        Peripheral.__init__( self, name, base, size, 'NIC', 'NONE', channels )
377        return
378
379########################
380class Cma( Peripheral ):
381########################
382    def __init__( self, name, base, size, channels ):
383        Peripheral.__init__( self, name, base, size, 'CMA', 'NONE', channels )
384        return
385
386########################
387class Fbf( Peripheral ):
388########################
389    def __init__( self, name, base, size ):
390        Peripheral.__init__( self, name, base, size, 'FBF', 'NONE' )
391        return
392
393########################
394class Tim( Peripheral ):
395########################
396    def __init__( self, name, base, size, channels ):
397        Peripheral.__init__( self, name, base, size, 'TIM', 'NONE', channels )
398        return
399
400########################
401class Iob( Peripheral ):
402########################
403    def __init__( self, name, base, size ):
404        Peripheral.__init__( self, name, base, size, 'IOB', 'NONE' )
405        return
406
407########################
408class Rom( Peripheral ):
409########################
410    def __init__( self, name, base, size ):
411        Peripheral.__init__( self, name, base, size, 'ROM', 'NONE' )
412        return
413
414########################
415class Mmc( Peripheral ):
416########################
417    def __init__( self, name, base, size ):
418        Peripheral.__init__( self, name, base, size, 'MMC', 'NONE' )
419        return
420
421########################
422class Xcu( Peripheral ):
423########################
424    def __init__( self, name, base, size, channels ):
425        Peripheral.__init__( self, name, base, size, 'XCU', 'NONE', channels )
426        self.irqs  = []
427        return
428
429    def add ( self, irq ):
430        self.irqs.append( irq )
431        return
432
433########################
434class Icu( Peripheral ):
435########################
436    def __init__( self, name, base, size, channels ):
437        Peripheral.__init__( self, name, base, size, 'ICU', 'NONE', channels )
438        self.irqs  = []
439        return
440
441    ######################
442    def add ( self, irq ):
443        self.irqs.append( irq )
444        return
445
446########################
447class Pic( Peripheral ):
448########################
449    def __init__( self, name, base, size, channels ):
450        Peripheral.__init__( self, name, base, size, 'PIC', 'NONE', channels )
451        self.irqs  = []
452        return
453
454    ######################
455    def add ( self, irq ):
456        self.irqs.append( irq )
457        return
458
459########################
460class XcuIrq ( object ):
461########################
462    def __init__( self, srctype, srcid, isrtype, channel = 0, dstid = 0 ):
463        assert srctype in ['HWI','WTI','PTI']
464        assert isrtype in ['ISR_DEFAULT','ISR_TICK','ISR_TTY_RX','ISR_TTY_TX',
465                           'ISR_BDV', 'ISR_TIMER', 'ISR_WAKUP', 'ISR_NIC_RX',
466                           'ISR_NIC_TX','ISR_CMA','ISR_MMC']
467        assert srcid < 32
468        self.srctype = srctype
469        self.srcid   = srcid
470        self.isrtype = isrtype
471        self.channel = channel
472        self.dstid   = dstid
473        return
474
475    ####################
476    def __str__( self ):   # xml for an xcuIrq
477        s = '                <irq srctype="%s" srcid="%d" isr="%s" channel="%d" dstid="%d" />\n' \
478                % (self.srctype, self.srcid, self.isrtype, self.channel, self.dstid)
479        return s
480
481########################
482class PicIrq ( object ):
483########################
484    def __init__( self, srcid, dstx, dsty, dstid ):
485        assert srcid < 32
486        self.srcid   = srcid
487        self.dstx    = dstx
488        self.dsty    = dsty
489        self.dstid   = dstid
490        return
491
492    ####################
493    def __str__( self ):   # xml for a picIrq
494        s = '                <irq srcid="%d" dstx="%d" dsty="%d" dstid="%d" />\n' \
495                % (self.srcid, self.dstx, self.dsty, self.dstid)
496        return s
497
498
499# Local Variables:
500# tab-width: 4;
501# c-basic-offset: 4;
502# c-file-offsets:((innamespace . 0)(inline-open . 0));
503# indent-tabs-mode: nil;
504# End:
505#
506# vim: filetype=python:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
507
Note: See TracBrowser for help on using the repository browser.