| 1 |  | 
|---|
| 2 | __doc__ = ''' | 
|---|
| 3 | This file is a Cluster library. It contains classes implementing the | 
|---|
| 4 | netlist of a cluster, for different tsar versions. | 
|---|
| 5 | ''' | 
|---|
| 6 |  | 
|---|
| 7 | class 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 |                                 + 0x01200000 | 
|---|
| 33 |                                 + 0x01000000 * i | 
|---|
| 34 |                                 ) | 
|---|
| 35 |             self.cpu.append(c) | 
|---|
| 36 |  | 
|---|
| 37 |         memc, xram = self.create_memcache( segments = [ | 
|---|
| 38 |             ('reset', 0xbfc00000, 0x00010000), | 
|---|
| 39 |             ('excep', 0x80000000, 0x00010000), | 
|---|
| 40 |             ('text', 0x00400000, 0x00050000), | 
|---|
| 41 |             ('data', 0x10000000, 0x00100000), | 
|---|
| 42 |             ] ) | 
|---|
| 43 |         tty  = self.create_tty( addr = 0xc0200000, tty_count = 1 ) | 
|---|
| 44 |         xicu = self.create_xicu( addr = 0xd2200000, pti_count = 1,  | 
|---|
| 45 |                                                     hwi_count = 1, | 
|---|
| 46 |                                                     wti_count = 4,  | 
|---|
| 47 |                                                     irq_count = 4) | 
|---|
| 48 |         tty.irq[0] // xicu.hwi[0] | 
|---|
| 49 |         for i in range(proc_count): | 
|---|
| 50 |             self.cpu[i].irq[0] // xicu.irq[i] | 
|---|
| 51 |  | 
|---|
| 52 |     def create_tty(self, addr, tty_count = 1): | 
|---|
| 53 |         names = map(lambda x:'tty%d'%x, range(tty_count)) | 
|---|
| 54 |         name = 'tty%d'%self.cluster_no | 
|---|
| 55 |         tty = self.pf.create('caba:vci_multi_tty', name, names = names) | 
|---|
| 56 |         self.ringp.to_target.new() // tty.vci | 
|---|
| 57 |         tty.addSegment(name, address = addr, size = 0x40, cacheable = False) | 
|---|
| 58 |         return tty | 
|---|
| 59 |      | 
|---|
| 60 |     def create_xicu(self, addr, pti_count, hwi_count, wti_count, irq_count): | 
|---|
| 61 |         name = 'xicu' | 
|---|
| 62 |         xicu = self.pf.create('caba:vci_xicu_vhdl', name, pti_count = pti_count, | 
|---|
| 63 |                                                           hwi_count = hwi_count, | 
|---|
| 64 |                                                           wti_count = wti_count, | 
|---|
| 65 |                                                           irq_count = irq_count) | 
|---|
| 66 |         self.ringp.to_target.new() // xicu.vci | 
|---|
| 67 |         xicu.addSegment(name, address = addr, size = 0x1000, cacheable = False) | 
|---|
| 68 |         return xicu | 
|---|
| 69 |  | 
|---|
| 70 |  | 
|---|
| 71 | class ClusterV3(Cluster): | 
|---|
| 72 |     ''' | 
|---|
| 73 |     A TsarV3 implementation, using vci_cc_vcache_wrapper2_v1, | 
|---|
| 74 |     vci_mem_cache_v3 and vci_dma_tsar_v2. | 
|---|
| 75 |     ''' | 
|---|
| 76 |  | 
|---|
| 77 |     def create_cpu(self, cpuid, addr): | 
|---|
| 78 |             c = self.pf.create( | 
|---|
| 79 |                 'caba:vci_cc_xcache_wrapper_v1', | 
|---|
| 80 |                 'proc_%d_%d' % (self.cluster_no, cpuid), | 
|---|
| 81 |                 iss_t = "common:mips32el", | 
|---|
| 82 |                 proc_id = cpuid, | 
|---|
| 83 |                 icache_ways = 4, | 
|---|
| 84 |                 icache_sets = 64, | 
|---|
| 85 |                 icache_words = 16, | 
|---|
| 86 |                 dcache_ways = 4, | 
|---|
| 87 |                 dcache_sets = 64, | 
|---|
| 88 |                 dcache_words = 16, | 
|---|
| 89 |                 write_buf_size = 16, | 
|---|
| 90 |                 ) | 
|---|
| 91 |             self.ringc.to_initiator.new() // c.vci_ini_c | 
|---|
| 92 |             self.ringc.to_target.new() // c.vci_tgt | 
|---|
| 93 |             self.ringp.to_initiator.new() // c.vci_ini_rw | 
|---|
| 94 |  | 
|---|
| 95 |             c.addSegment('proc_%d_%d' % (self.cluster_no, cpuid), | 
|---|
| 96 |                          address = addr, | 
|---|
| 97 |                          size = 0x10, | 
|---|
| 98 |                          cacheable = False, | 
|---|
| 99 |                          ) | 
|---|
| 100 |  | 
|---|
| 101 |             return c | 
|---|
| 102 |  | 
|---|
| 103 |     def create_memcache(self, segments): | 
|---|
| 104 |         memc = self.pf.create('caba:vci_mem_cache_v1', 'memc', | 
|---|
| 105 |                               mtx = self.mtx, | 
|---|
| 106 |                               vci_ixr_index = (self.cluster_no,), | 
|---|
| 107 |                               nways = 16, | 
|---|
| 108 |                               nsets = 256, | 
|---|
| 109 |                               nwords = 16, | 
|---|
| 110 |                               ) | 
|---|
| 111 |         self.ringc.to_target.new() // memc.vci_tgt_cleanup | 
|---|
| 112 |         self.ringp.to_target.new() // memc.vci_tgt | 
|---|
| 113 |         self.ringc.to_initiator.new() // memc.vci_ini | 
|---|
| 114 |  | 
|---|
| 115 |         xram = self.pf.create('caba:vci_simple_ram', 'xram', | 
|---|
| 116 |                               mt = self.mtx, | 
|---|
| 117 |                               ident = (self.cluster_no,), | 
|---|
| 118 |                               latency = 1, | 
|---|
| 119 |                  ) | 
|---|
| 120 |         memc.vci_ixr // xram.vci | 
|---|
| 121 |  | 
|---|
| 122 |         for name, addr, size in segments: | 
|---|
| 123 |             # Here DSX knows the only way to address xram is through its | 
|---|
| 124 |             # vci port. It also knows the only associated mapping_table. | 
|---|
| 125 |             xram.addSegment('ram_x_'+name, address = addr, size = size, cacheable = True) | 
|---|
| 126 |  | 
|---|
| 127 |             # For these segments, there is ambiguity for the mapping_table | 
|---|
| 128 |             # we are talking about, so we specify mt = ... | 
|---|
| 129 |             memc.addSegment('ram_p_'+name, address = addr, size = size, cacheable = True, mt = self.mtp) | 
|---|
| 130 |             memc.addSegment('ram_c_'+name, address = addr, size = size, cacheable = True, mt = self.mtc) | 
|---|
| 131 |         return memc, xram | 
|---|