


def hard_config(x, y, x_width, y_width, p, hard_config, protocol):
    
    ram_tgtid = 0
    xcu_tgtid = 1
    dma_tgtid = 2
    tty_tgtid = 3
    ioc_tgtid = 4
    nic_tgtid = 5
    rom_tgtid = 6
    cma_tgtid = 7
    sim_tgtid = 8
    fbf_tgtid = 9

    nb_dma_channels = 1
    nb_cma_channels = 0
    nb_tty_channels = 4
    nb_ioc_channels = 1

    fbf_x_size = 1024
    fbf_y_size = 1024

    seg_rom_base = 0xbfc00000
    seg_rom_size = 0x00100000

    cluster_inc = 0x80000000 / (x * y) * 2
    cluster_io_id = seg_rom_base >> (32 - x_width - y_width)
    cluster_io_inc = cluster_io_id * cluster_inc
    ram_max_size = 0x40000000 / (x * y) # 1 Go Max
    
    seg_ram_base = 0x00000000
    seg_ram_size = min(0x10000000, ram_max_size)

    seg_xcu_base = (cluster_inc >> 1) + (xcu_tgtid << 19)
    seg_xcu_size = 0x00001000 # 4Ko

    seg_dma_base = (cluster_inc >> 1) + (dma_tgtid << 19)
    seg_dma_size = 0x00001000 * nb_dma_channels

    def periph_address(tgtid):
        return (cluster_inc >> 1) + cluster_io_inc + (tgtid << 19)

    seg_ioc_base = periph_address(ioc_tgtid);
    seg_ioc_size = 0x00001000

    seg_tty_base = periph_address(tty_tgtid)
    seg_tty_size = 0x00001000

    seg_fbf_base = periph_address(fbf_tgtid)
    seg_fbf_size = fbf_x_size * fbf_y_size * 2

    seg_nic_base = periph_address(nic_tgtid)
    seg_nic_size = 0x00080000

    seg_cma_base = periph_address(cma_tgtid)
    seg_cma_size = 0x00004000 * nb_cma_channels

    seg_sim_base = periph_address(sim_tgtid)
    seg_sim_size = 0x00001000

    header = '''
#ifndef _HARD_CONFIG_H_
#define _HARD_CONFIG_H_

/* Generated from run_simus.py */

/* General platform parameters */

#define X_SIZE                 %(x_size)d
#define Y_SIZE                 %(y_size)d
#define X_WIDTH                %(x_width)d
#define Y_WIDTH                %(y_width)d
#define P_WIDTH                4
#define X_IO                   0
#define Y_IO                   0
#define NB_PROCS_MAX           %(proc_per_clus)d
#define IRQ_PER_PROCESSOR      4
#define RESET_ADDRESS          0x%(seg_rom_base)x


/* Peripherals */

#define RAM_TGTID              %(ram_tgtid)d
#define XCU_TGTID              %(xcu_tgtid)d
#define DMA_TGTID              %(dma_tgtid)d
#define TTY_TGTID              %(tty_tgtid)d
#define IOC_TGTID              %(ioc_tgtid)d
#define NIC_TGTID              %(nic_tgtid)d
#define ROM_TGTID              %(rom_tgtid)d
#define CMA_TGTID              %(cma_tgtid)d
#define SIM_TGTID              %(sim_tgtid)d
#define FBF_TGTID              %(fbf_tgtid)d

#define NB_TTY_CHANNELS        %(nb_tty_channels)d
#define NB_IOC_CHANNELS        %(nb_ioc_channels)d
#define NB_NIC_CHANNELS        0
#define NB_CMA_CHANNELS        %(nb_cma_channels)d
#define NB_TIM_CHANNELS        0
#define NB_DMA_CHANNELS        %(nb_dma_channels)d

#define USE_XCU                1
#define USE_IOB                0
#define USE_PIC                0
#define USE_FBF                1

#define USE_IOC_BDV            1
#define USE_IOC_SDC            0
#define USE_IOC_HBA            0
#define USE_IOC_RDK            0

#define FBF_X_SIZE             %(fbf_x_size)d
#define FBF_Y_SIZE             %(fbf_y_size)d


/* base addresses and sizes for physical segments */

#define SEG_RAM_BASE           0x%(seg_ram_base)x
#define SEG_RAM_SIZE           0x%(seg_ram_size)x

#define SEG_CMA_BASE           0x0 // Component requires a multiple of 4K
#define SEG_CMA_SIZE           0x0

#define SEG_DMA_BASE           0x%(seg_dma_base)x
#define SEG_DMA_SIZE           0x%(seg_dma_size)x

#define SEG_FBF_BASE           0x%(seg_fbf_base)x
#define SEG_FBF_SIZE           0x%(seg_fbf_size)x

#define SEG_ICU_BASE           0xffffffff
#define SEG_ICU_SIZE           0x0

#define SEG_IOB_BASE           0xffffffff
#define SEG_IOB_SIZE           0x0

#define SEG_IOC_BASE           0x%(seg_ioc_base)x
#define SEG_IOC_SIZE           0x%(seg_ioc_size)x

#define SEG_MMC_BASE           0xffffffff
#define SEG_MMC_SIZE           0x0

#define SEG_MWR_BASE           0xffffffff
#define SEG_MWR_SIZE           0x0

#define SEG_ROM_BASE           0x%(seg_rom_base)x
#define SEG_ROM_SIZE           0x%(seg_rom_size)x

#define SEG_SIM_BASE           0x%(seg_sim_base)x
#define SEG_SIM_SIZE           0x%(seg_sim_size)x

#define SEG_NIC_BASE           0x%(seg_nic_base)x
#define SEG_NIC_SIZE           0x%(seg_nic_size)x

#define SEG_PIC_BASE           0xffffffff
#define SEG_PIC_SIZE           0x0

#define SEG_TIM_BASE           0xffffffff
#define SEG_TIM_SIZE           0x0

#define SEG_TTY_BASE           0x%(seg_tty_base)x
#define SEG_TTY_SIZE           0x%(seg_tty_size)x

#define SEG_XCU_BASE           0x%(seg_xcu_base)x
#define SEG_XCU_SIZE           0x%(seg_xcu_size)x

#define SEG_RDK_BASE           0xffffffff
#define SEG_RDK_SIZE           0x0

''' % dict(x_size = x, y_size = y, x_width = x_width, y_width = y_width,
        proc_per_clus = p,
        nb_tty_channels = nb_tty_channels,
        nb_ioc_channels = nb_ioc_channels,
        nb_cma_channels = nb_cma_channels,
        nb_dma_channels = nb_dma_channels,
        fbf_x_size = fbf_x_size, fbf_y_size = fbf_y_size,
        ram_tgtid = ram_tgtid,
        xcu_tgtid = xcu_tgtid,
        dma_tgtid = dma_tgtid,
        tty_tgtid = tty_tgtid,
        ioc_tgtid = ioc_tgtid,
        nic_tgtid = nic_tgtid,
        rom_tgtid = rom_tgtid,
        cma_tgtid = cma_tgtid,
        sim_tgtid = sim_tgtid,
        fbf_tgtid = fbf_tgtid,
        seg_ram_base = seg_ram_base,
        seg_ram_size = seg_ram_size,
        seg_dma_base = seg_dma_base,
        seg_dma_size = seg_dma_size,
        seg_fbf_base = seg_fbf_base,
        seg_fbf_size = seg_fbf_size,
        seg_ioc_base = seg_ioc_base,
        seg_ioc_size = seg_ioc_size,
        seg_rom_base = seg_rom_base,
        seg_rom_size = seg_rom_size,
        seg_sim_base = seg_sim_base,
        seg_sim_size = seg_sim_size,
        seg_nic_base = seg_nic_base,
        seg_nic_size = seg_nic_size,
        seg_tty_base = seg_tty_base,
        seg_tty_size = seg_tty_size,
        seg_xcu_base = seg_xcu_base,
        seg_xcu_size = seg_xcu_size)

    if protocol == 'wtidl':
        header += '#define WT_IDL\n'

    header += '#endif //_HD_CONFIG_H\n'

    file = open(hard_config, 'w')
    file.write(header)
    file.close()


if __name__ == "__main__":
    if len(sys.argv) != 6:
        print "Usage: %s <x> <y> <p> <hard_config-filename> <protocol>" % argv[0]
        print "with:"
        print "<x>: number of clusters in X"
        print "<y>: number of clusters in Y"
        print "<p>: number of processors per clusters"
        sys.exit(0)

    x = argv[1]
    y = argv[2]
    p = argv[3]
    hard_config_filename = argv[4]
    protocol = argv[5]

    hard_config(x, y, p, hard_config_filename, protocol)


