#!/usr/bin/env python

import dsx
import soclib
import soclib.component
import os

class Platform:
    def __init__(self, cluster_ctor, proc_count, binaries):
        self.pf = soclib.Architecture(cell_size = 4,
                                      plen_size = 8,
                                      addr_size = 64,
                                      rerror_size = 1,
                                      clen_size = 1,
                                      rflag_size = 1,
                                      srcid_size = 14,
                                      pktid_size = 4,
                                      trdid_size = 4,
                                      wrplen_size = 1
                                      )
        for name in ['mtp', 'mtc', 'mtx']:
            mt = self.pf.create('common:mapping_table', name,
                                addr_size = 40,
                                addr_bits = [16], srcid_bits = [14],
                                cacheability_mask = 0x0000300000)
            # create self.mt[pcx]
            setattr(self, name, mt)

        # create a dictionary containing
        # loader = x, loader2 = y, ...
        bins = {}
        for i, bin in enumerate(binaries):
            k = 'binary'
            if i:
                k += str(i+1)
            bins[k] = bin
        self.loader = self.pf.create('common:loader', 'loader', **bins)

        # self.ringc = self.pf.create(
        #     'caba:vci_simple_ring_network', 'ringc', 
        #     mt = mtc,
        #     ringid = (),
        #     wrapper_fifo_depth = 2, )
        # self.ringp = self.pf.create(
        #     'caba:vci_simple_ring_network', 'ringp', 
        #     mt = mtp,
        #     ringid = (),
        #     wrapper_fifo_depth = 2, )
        self.ringc = self.pf.create('caba:vci_simple_ring_network', 'ringc', 
                                    mt = self.mtc,
                                    ringid = (),
                                    wrapper_fifo_depth = 2)
        self.ringp = self.pf.create('caba:vci_simple_ring_network', 'ringp', 
                                    mt = self.mtp,
                                    ringid = (),
                                    wrapper_fifo_depth = 2)

        self.cluster = cluster_ctor(self.pf,
                                    self.ringp, self.ringc,
                                    self.mtp, self.mtc, self.mtx,
                                    proc_count = proc_count,
                                    cluster_no = 0,
                                    cluster_base = 0x00000000,
                                    )

    def simulator(self, outdir = 'hard'):
        self.pf.generate(soclib.PfDriver(outdir = outdir))

    def device_tree(self):
        from dsx.contrib.dts_platform.platform_to_dts import PlatformToDts
        import dsx.contrib.dts_platform.platform_handlers
        dtsgen = PlatformToDts(self.pf, self.mtp)
        return dtsgen.create_device_tree()

    def dts(self, output):
        from dsx.device_tree.dts import Driver
        dt = self.device_tree()
        dt.generate(Driver(
            outdir = '.',
            parent = None,
            output_file = output,
            ),)

    def dtb(self, output):
        from dsx.device_tree.dtb import Driver
        dt = self.device_tree()
        dt.generate(Driver(
            outdir = '.',
            parent = None,
            output_file = output,
            ),)

def main(cpus):
    from cluster import ClusterV3
    hard = Platform(ClusterV3, cpus, binaries = ["bin.soft"])
    hard.simulator('.')
#    hard.dts(os.path.basename(__file__)[:-2]+'dts')
#    hard.dtb(os.path.basename(__file__)[:-2]+'dtb')

if __name__ == '__main__':
    import sys
    cpus = 4
    if len(sys.argv) > 1:
        cpus = int(sys.argv[1])
    main(cpus)
