source: trunk/platforms/dsx/v3_1cluster_virt/cluster.py @ 228

Last change on this file since 228 was 22, checked in by bouyer, 15 years ago

Fix CPU address

  • Property svn:eol-style set to native
  • Property svn:keywords set to "Author Date Id Rev URL Revision"
  • Property svn:mime-type set to text/plain
File size: 6.2 KB
Line 
1
2__doc__ = '''
3This file is a Cluster library. It contains classes implementing the
4netlist of a cluster, for different tsar versions.
5'''
6
7class Cluster:
8    '''
9    A generic netlist of a cluster, which must be subclassed to
10    implement caches&dma instanciation
11    '''
12   
13    def __init__(self, pf, ringp, ringc, mtp, mtc, mtx, proc_count, cluster_no, cluster_base):
14        self.pf = pf
15        self.ringp = ringp
16        self.ringc = ringc
17        self.mtp = mtp
18        self.mtc = mtc
19        self.mtx = mtx
20        self.cluster_no = cluster_no
21
22        self.generate(proc_count, cluster_base)
23
24    def generate(self, proc_count, cluster_base):
25        '''
26        The core netlist, where caches and components are created
27        '''
28        self.cpu = []
29        for i in range(proc_count):
30            c = self.create_cpu(i,
31                                cluster_base
32                                + 0x10200000
33                                + 0x01000000 * (i+1)
34                                )
35            self.cpu.append(c)
36
37        memc, xram = self.create_memcache( segments = [(cluster_base, 0x02000000)] )
38        rom  = self.create_rom( segments = [(0xbfc00000, 0x00400000)], memc = memc )
39        tty  = self.create_tty( addr = 0xd0200000 )
40        dma  = self.create_dma( addr = 0xd1200000 )
41        xicu = self.create_xicu( addr = 0xd2200000, hwi_count = 3, cpu_count = proc_count )
42
43        xicu.hwi[0] // tty.irq[0]
44        xicu.hwi[1] // dma.irq
45
46        for p, cpu in enumerate(self.cpu):
47            for i in range(6):
48                xicu.irq[i+p*6] // cpu.irq[i]
49
50    def create_rom(self, segments, memc):
51        name = 'rom%d'%self.cluster_no
52        rom = self.pf.create('caba:vci_simple_ram', name, latency = 1)
53        self.ringp.to_target.new() // rom.vci
54        for addr, size in segments:
55            rom.addSegment(name, address = addr, size = size, cacheable = True)
56        return rom
57
58    def create_tty(self, addr):
59        name = 'tty%d'%self.cluster_no
60        tty = self.pf.create('caba:vci_multi_tty', name, names = ['tty0'])
61        self.ringp.to_target.new() // tty.vci
62        tty.addSegment(name, address = addr, size = 0x10, cacheable = False)
63        return tty
64
65    def create_xicu(self, addr, hwi_count, cpu_count):
66        name = 'xicu%d'%self.cluster_no
67        xicu = self.pf.create('caba:vci_xicu', name,
68                              pti_count = cpu_count,
69                              hwi_count = hwi_count,
70                              wti_count = cpu_count,
71                              irq_count = 6*cpu_count,
72                              )
73        self.ringp.to_target.new() // xicu.vci
74        xicu.addSegment(name, address = addr, size = 0x1000, cacheable = False)
75        return xicu
76   
77
78class ClusterV3(Cluster):
79    '''
80    A TsarV3 implementation, using vci_cc_vcache_wrapper2_v1,
81    vci_mem_cache_v3 and vci_dma_tsar_v2.
82    '''
83   
84    def create_rom(self, segments, memc):
85        # Here is a hack needed for TsarV3:
86        #
87        # memcache must have segments corresponding to the rom in
88        # order to handle cleanup messages emitted by the L1 caches on
89        # the coherency network (else, they could be routed to wrong
90        # places)
91        name = 'rom%d'%self.cluster_no
92        for addr, size in segments:
93            memc.addSegment(name+'_c', address = addr, size = size, cacheable = True, mt = self.mtc)
94        return Cluster.create_rom(self, segments, memc)
95
96    def create_cpu(self, cpuid, addr):
97            c = self.pf.create(
98                'caba:vci_cc_vcache_wrapper2_v1',
99                'proc_%d_%d' % (self.cluster_no, cpuid),
100                iss_t = "common:mips32el",
101                proc_id = cpuid,
102                icache_ways = 4,
103                icache_sets = 64,
104                icache_words = 16,
105                itlb_ways = 4,
106                itlb_sets = 16,
107                dcache_ways = 4,
108                dcache_sets = 64,
109                dcache_words = 16,
110                dtlb_ways = 4,
111                dtlb_sets = 16,
112                write_buf_size = 16,
113                )
114            self.ringc.to_initiator.new() // c.vci_ini_c
115            self.ringc.to_target.new() // c.vci_tgt
116            self.ringp.to_initiator.new() // c.vci_ini_rw
117
118            c.addSegment('proc_%d_%d' % (self.cluster_no, cpuid),
119                         address = addr,
120                         size = 0x10,
121                         cacheable = False,
122                         )
123
124            return c
125
126    def create_memcache(self, segments):
127        memc = self.pf.create('caba:vci_mem_cache_v3', 'memc',
128                              mtx = self.mtx,
129                              vci_ixr_index = (self.cluster_no,),
130                              nways = 16,
131                              nsets = 256,
132                              nwords = 16,
133                              heap_size = 1024
134                              )
135        self.ringc.to_target.new() // memc.vci_tgt_cleanup
136        self.ringp.to_target.new() // memc.vci_tgt
137        self.ringc.to_initiator.new() // memc.vci_ini
138
139        xram = self.pf.create('caba:vci_simple_ram', 'xram',
140                              mt = self.mtx,
141                              ident = (self.cluster_no,),
142                              latency = 1,
143                 )
144        memc.vci_ixr // xram.vci
145
146        for addr, size in segments:
147            # Here DSX knows the only way to address xram is through its
148            # vci port. It also knows the only associated mapping_table.
149            xram.addSegment('ram_x', address = addr, size = size, cacheable = True)
150
151            # For these segments, there is ambiguity for the mapping_table
152            # we are talking about, so we specify mt = ...
153            memc.addSegment('ram_p', address = addr, size = size, cacheable = True, mt = self.mtp)
154            memc.addSegment('ram_c', address = addr, size = size, cacheable = True, mt = self.mtc)
155        return memc, xram
156
157    def create_dma(self, addr):
158        name = 'dma%d'%self.cluster_no
159        dma = self.pf.create('caba:vci_dma_tsar_v2', name, burst_size = 64)
160        self.ringp.to_target.new() // dma.vci_target
161        self.ringp.to_initiator.new() // dma.vci_initiator
162        dma.addSegment(name, address = addr, size = 0x14, cacheable = False)
163        return dma
Note: See TracBrowser for help on using the repository browser.