__doc__ = ''' This file is a Cluster library. It contains classes implementing the netlist of a cluster, for different tsar versions. ''' class Cluster: ''' A generic netlist of a cluster, which must be subclassed to implement caches&dma instanciation ''' def __init__(self, pf, ringp, ringc, mtp, mtc, mtx, proc_count, cluster_no, cluster_base): self.pf = pf self.ringp = ringp self.ringc = ringc self.mtp = mtp self.mtc = mtc self.mtx = mtx self.cluster_no = cluster_no self.generate(proc_count, cluster_base) def generate(self, proc_count, cluster_base): ''' The core netlist, where caches and components are created ''' self.cpu = [] for i in range(proc_count): c = self.create_cpu(i, cluster_base + 0x01200000 + 0x01000000 * i ) self.cpu.append(c) memc, xram = self.create_memcache( segments = [ ('reset', 0xbfc00000, 0x00010000), ('excep', 0x80000000, 0x00010000), ('text', 0x00400000, 0x00050000), ('data', 0x10000000, 0x00100000), ] ) tty = self.create_tty( addr = 0xc0200000, tty_count = 1 ) xicu = self.create_xicu( addr = 0xd2200000, pti_count = 1, hwi_count = 3, wti_count = 4, irq_count = 4) dma = self.create_dma( addr = 0xd1200000, burst_size = 64) fb = self.create_fb( addr = 0xe2200000, width = 320, height = 200, subsampling = 422) tty.irq[0] // xicu.hwi[0] for i in range(proc_count): self.cpu[i].irq[0] // xicu.irq[i] dma.irq // xicu.hwi[1] def create_dma(self, addr, burst_size): name = 'dma%d'%self.cluster_no dma = self.pf.create('caba:vci_dma_vhdl', name, burst_size = burst_size) self.ringp.to_target.new() // dma.vci_target self.ringp.to_initiator.new() // dma.vci_initiator dma.addSegment(name, address = addr, size = 0x1000, cacheable = False) return dma def create_fb(self, addr, width, height, subsampling): name = 'fb%d'%self.cluster_no fb = self.pf.create('caba:vci_framebuffer', name, width = width, height = height, subsampling = subsampling) self.ringp.to_target.new() // fb.vci fb.addSegment(name, address = addr, size = width * height * 2, cacheable = False) return fb def create_tty(self, addr, tty_count = 1): names = map(lambda x:'tty%d'%x, range(tty_count)) name = 'tty%d'%self.cluster_no tty = self.pf.create('caba:vci_multi_tty', name, names = names) self.ringp.to_target.new() // tty.vci tty.addSegment(name, address = addr, size = 0x1000, cacheable = False) return tty def create_xicu(self, addr, pti_count, hwi_count, wti_count, irq_count): name = 'xicu' xicu = self.pf.create('caba:vci_xicu', name, pti_count = pti_count, hwi_count = hwi_count, wti_count = wti_count, irq_count = irq_count) self.ringp.to_target.new() // xicu.vci xicu.addSegment(name, address = addr, size = 0x1000, cacheable = False) return xicu class ClusterV3(Cluster): ''' A TsarV3 implementation, using vci_cc_vcache_wrapper2_v1, vci_mem_cache_v3 and vci_dma_tsar_v2. ''' def create_cpu(self, cpuid, addr): c = self.pf.create( 'caba:vci_cc_xcache_wrapper_v1', 'proc_%d_%d' % (self.cluster_no, cpuid), iss_t = "common:mips32el", proc_id = cpuid, icache_ways = 4, icache_sets = 64, icache_words = 16, dcache_ways = 4, dcache_sets = 64, dcache_words = 16, write_buf_size = 16, ) self.ringc.to_initiator.new() // c.vci_ini_c self.ringc.to_target.new() // c.vci_tgt self.ringp.to_initiator.new() // c.vci_ini_rw c.addSegment('proc_%d_%d' % (self.cluster_no, cpuid), address = addr, size = 0x10, cacheable = False, ) return c def create_memcache(self, segments): memc = self.pf.create('caba:vci_mem_cache_v1', 'memc', mtx = self.mtx, vci_ixr_index = (self.cluster_no,), nways = 16, nsets = 256, nwords = 16, ) self.ringc.to_target.new() // memc.vci_tgt_cleanup self.ringp.to_target.new() // memc.vci_tgt self.ringc.to_initiator.new() // memc.vci_ini xram = self.pf.create('caba:vci_simple_ram', 'xram', mt = self.mtx, ident = (self.cluster_no,), latency = 1, ) memc.vci_ixr // xram.vci for name, addr, size in segments: # Here DSX knows the only way to address xram is through its # vci port. It also knows the only associated mapping_table. xram.addSegment('ram_x_'+name, address = addr, size = size, cacheable = True) # For these segments, there is ambiguity for the mapping_table # we are talking about, so we specify mt = ... memc.addSegment('ram_p_'+name, address = addr, size = size, cacheable = True, mt = self.mtp) memc.addSegment('ram_c_'+name, address = addr, size = size, cacheable = True, mt = self.mtc) return memc, xram