#--------------------------------------------------------------------
# File      : gen_arch_info.py
#--------------------------------------------------------------------

import getpass
import socket
import time
import sys


exec(file("hard_params.py"))

def print_comments(cmd, x, y, cpu_per_cluster, bscpu):
    print "# TSAR hardware description in BIB (Boot Information Block) format"
    print "# This file is autogenerated by the command: " + cmd +  " %d %d %d %d" % (x, y, cpu_per_cluster, bscpu)
    print "# It is ready to be passed to info2bib utility so the binary format can be generated"
    print " "
    print "# " + getpass.getuser() + " on " + socket.gethostname() + " " + time.strftime("%H:%M:%S")
    print " "
    print " "
        
def print_header(x, y, bscpu, bstty, bsdma):
    print "[HEADER]"
    print "        REVISION=1"
    print "        ARCH=SOCLIB-TSAR"
    print "        XMAX=%d" % x
    print "        YMAX=%d" % y
    print "        BSCPU=%d" % bscpu
    print "        BSTTY=0x%x" % bstty
    print "        BSDMA=0x%x" % bsdma
    print "        BSHCRYPT=0" # Not supported
    print " "
    print " "


def print_cluster(x, y, x_width, y_width, cpu_per_cluster):
    mem_addr = ram_addr(x, y, x_width, y_width)
    mem_size = ram_size(x_width, y_width)
    xcu_base = replicated_periph_base_addr(x_width, y_width, XCU_TGTID)
    dma_base = replicated_periph_base_addr(x_width, y_width, DMA_TGTID)
    xcu_addr = replicated_periph_addr(x, y, x_width, y_width, xcu_base)
    dma_addr = replicated_periph_addr(x, y, x_width, y_width, dma_base)
    print "[CLUSTER]"

    cid = x * (1 << y_width) + y
    cpu_num = 0;
    while (cpu_num != cpu_per_cluster):
        gid = (cid << P_WIDTH) + cpu_num
        print "        [CPU]    ID=%d    OUTIRQ=%d" % (gid, (cpu_num * OUTPUT_IRQ_PER_PROC)) 
        cpu_num += 1
    
    print "        [DEV]    ID=RAM       BASE=%#.8x    SIZE=%#.8x    IRQ=-1    IRQTYPE=NONE" % (mem_addr, mem_size)
    print "        [DEV]    ID=XICU      BASE=%#.8x    SIZE=%#.8x    IRQ=-1    IRQTYPE=NONE" % (xcu_addr, DMA_SIZE)
    print "        [DEV]    ID=DMA       BASE=%#.8x    SIZE=%#.8x    IRQ=8     IRQTYPE=HWI"  % (dma_addr, XCU_SIZE)
    print " "
    print " "


def print_io_cluster(x, y, x_width, y_width, cpu_per_cluster):
    mem_addr = ram_addr(x, y, x_width, y_width)
    mem_size = ram_size(x_width, y_width)

    xcu_addr = periph_addr(x_width, y_width, XCU_TGTID)
    dma_addr = periph_addr(x_width, y_width, DMA_TGTID)
    ioc_addr = periph_addr(x_width, y_width, IOC_TGTID)
    tty_base = periph_addr(x_width, y_width, TTY_TGTID)
    fbf_addr = periph_addr(x_width, y_width, FBF_TGTID)
    
    print "[CLUSTER]"
    cpu_num = 0
    cid = x * (1 << y_width) + y
    while (cpu_num != cpu_per_cluster):
        gid = (cid << P_WIDTH) + cpu_num
        print "        [CPU]    ID=%d    OUTIRQ=%d" % (gid, (cpu_num * OUTPUT_IRQ_PER_PROC)) 
        cpu_num = cpu_num + 1
    
    print "        [DEV]    ID=RAM       BASE=%#.8x    SIZE=%#.8x    IRQ=-1    IRQTYPE=NONE" % (mem_addr, mem_size)
    print "        [DEV]    ID=XICU      BASE=%#.8x    SIZE=%#.8x    IRQ=-1    IRQTYPE=NONE" % (xcu_addr, XCU_SIZE)
    print "        [DEV]    ID=DMA       BASE=%#.8x    SIZE=%#.8x    IRQ=8     IRQTYPE=HWI"  % (dma_addr, DMA_SIZE)
    print "        [DEV]    ID=BLKDEV    BASE=%#.8x    SIZE=%#.8x    IRQ=31    IRQTYPE=HWI"  % (ioc_addr, IOC_SIZE)
    ntty = 0
    irq = 16
    while (ntty < NB_TTY_CHANNELS):
        tty_base_i = tty_base + ntty * TTY_CHANNEL_SIZE
        print "        [DEV]    ID=TTY       BASE=%#.8x    SIZE=%#.8x    IRQ=%d    IRQTYPE=HWI" % (tty_base_i, TTY_CHANNEL_SIZE, irq)
        irq += 1
        ntty += 1
    print "        [DEV]    ID=FB        BASE=%#.8x    SIZE=%#.8x    IRQ=-1    IRQTYPE=NONE" % (fbf_addr, FBF_SIZE)
    print " "
    print " "

def gen_arch_info(x, y, x_width, y_width, cpu_per_cluster, bscpu, arch_info_name):
    fp = open(arch_info_name, 'w')
    stdout = sys.stdout
    sys.stdout = fp

    x_io = get_x_io(x_width, y_width)
    y_io = get_y_io(x_width, y_width)

    ###########################################################################################
    # we force io_cid to 0 because this is the only cluster we know which will be present 
    # in all platform where the number of clusters is independant of x_width and y_width values
    # io_cid = 0 
    # @QM No.
    ###########################################################################################

    break_loop = 0
    xi = 0
    yi = 0
    while (xi < x):
        while (yi < y):
            if xi == x_io and yi == y_io:
                bsdma = periph_addr(x_width, y_width, DMA_TGTID)
                bstty = periph_addr(x_width, y_width, TTY_TGTID)
                break_loop = 1
                break
            else:
                bsdma = "error"
            yi = yi + 1

        if break_loop == 1:
            break
        yi = 0
        xi = xi + 1
    
    # Generate the description
    print_comments(sys.argv[0], x, y, cpu_per_cluster, bscpu)
    print_header(x, y, bscpu, bstty, bsdma)
    
    xi = 0
    yi = 0
    while (xi < x):
        while (yi < y):
            if xi == x_io and yi == y_io:
                print_io_cluster(xi, yi, x_width, y_width, cpu_per_cluster)
            else:
                print_cluster(xi, yi, x_width, y_width, cpu_per_cluster)
            yi = yi + 1
        yi = 0
        xi = xi + 1
    sys.stdout = stdout
    fp.close()

