Index: /trunk/platforms/linux_monocluster/.gdbinit
===================================================================
--- /trunk/platforms/linux_monocluster/.gdbinit	(revision 667)
+++ /trunk/platforms/linux_monocluster/.gdbinit	(revision 667)
@@ -0,0 +1,136 @@
+define connect
+    target remote localhost:2346
+end
+
+# useful macros for Linux
+define dmesg
+        set $__log_buf = $arg0
+        set $log_start = $arg1
+        set $log_end = $arg2
+        set $x = $log_start
+        echo "
+        while ($x < $log_end)
+                set $c = (char)(($__log_buf)[$x++])
+                printf "%c" , $c
+        end
+        echo "\n
+end
+document dmesg
+dmesg __log_buf log_start log_end
+Print the content of the kernel message buffer
+end
+
+define thread_info
+    set $th = (struct thread_info*)$gp
+    echo "thread_info="
+    print /x *$th
+end
+define task_struct
+    set $th = (struct thread_info*)$gp
+    set $ts = (struct task_struct*)$th->task
+    echo "task_struct="
+    print /x *$ts
+end
+define active_mm
+    set $th = (struct thread_info*)$gp
+    set $ts = (struct task_struct*)$th->task
+    set $amm = (struct mm_struct*)$ts->active_mm
+    echo "active_mm="
+    print /x *$amm
+end
+define pgd
+    set $th = (struct thread_info*)$gp
+    set $ts = (struct task_struct*)$th->task
+    set $ms = (struct mm_struct*)$ts->active_mm
+    set $pg = (pgd_t*)$ms->pgd
+    echo "pgd="
+    print /x {pgd_t[2048]}$pg
+end
+
+define task_struct_header
+    printf "Address      PID State     [User_EPC] [User-SP]  Kernel-SP  device comm\n"
+end
+
+define task_struct_show
+    # task_struct addr and PID
+    printf "0x%08X %5d", $arg0, $arg0->pid
+    # Place a '<' marker on the current task
+    #  if ($arg0 == current)
+    # For PowerPC, register r2 points to the "current" task
+    if ($arg0 == $r2)
+        printf "<"
+    else
+        printf " "
+    end
+    # State
+    if ($arg0->state == 0)
+        printf "Running   "
+    else
+        if ($arg0->state == 1)
+            printf "Sleeping  "
+        else
+            if ($arg0->state == 2)
+                printf "Disksleep "
+            else
+                if ($arg0->state == 4)
+                    printf "Zombie    "
+                else
+                    if ($arg0->state == 8)
+                        printf "sTopped   "
+                    else
+                        if ($arg0->state == 16)
+                            printf "Wpaging   "
+                        else
+                            printf "%2d       ", $arg0->state
+                        end
+                    end
+                end
+            end
+        end
+    end
+    # User PC
+    set $pt_regs = (struct pt_regs*)($arg0->stack + 0x2000 - sizeof(struct pt_regs))
+    if ($pt_regs->cp0_epc)
+        printf "0x%08X ", $pt_regs->cp0_epc
+    else
+        printf "           "
+    end
+    if ($pt_regs->regs[29])
+        printf "0x%08X ", $pt_regs->regs[29]
+    else
+        printf "           "
+    end
+    # Display the kernel stack pointer
+    set $th = (struct thread_info*)$arg0->stack
+    printf "0x%08X ", $th->ksp
+    # device
+    if ($arg0->signal->tty)
+        printf "%s   ", $arg0->signal->tty->name
+    else
+        printf "(none) "
+    end
+    # comm
+    printf "%s\n", $arg0->comm
+end
+
+define find_next_task
+    # Given a task address, find the next task in the linked list
+    set $t = (struct task_struct *)$arg0
+    set $offset=((char *)&$t->tasks - (char *)$t)
+    set $t=(struct task_struct *)((char *)$t->tasks.next- (char *)$offset)
+end
+
+define ps
+    # Print column headers
+    task_struct_header
+    set $t=&init_task
+    task_struct_show $t
+    find_next_task $t
+    # Walk the list
+    while &init_task!=$t
+        # Display useful info about each task
+        task_struct_show $t
+        find_next_task $t
+    end
+end
+
Index: /trunk/platforms/linux_monocluster/Makefile
===================================================================
--- /trunk/platforms/linux_monocluster/Makefile	(revision 667)
+++ /trunk/platforms/linux_monocluster/Makefile	(revision 667)
@@ -0,0 +1,84 @@
+# where is soclib?
+#
+SOCLIB_DIR=$(shell soclib-cc --getpath)
+
+# name definitions
+#
+SOCLIB_DESC=desc.py
+SOCLIB_TOP=top.cpp
+SIMULATOR_BINARY=system.x
+SIMULATOR_CMD=./$(SIMULATOR_BINARY) --nobanner
+
+# extra arguments for compilation
+#
+#SOCLIB_CC_ARGS=-v
+SOCLIB_CC_ARGS+=-b common:mips32
+
+# extra arguments for execution
+#
+# gdb
+# - F: start the simulation in a frozen state so it can be attached with a gdb
+#   client
+# - X: disable automatic break whenever an exception is caught, the exception
+#   handler will be called transparently
+# - S: make the simulation stop and wait for a gdb attachment whenever an
+#   exception is caught
+# - C: dump a trace of every inter-functions branch
+# - T: exit the simulator on trap exception
+# - Z: same as C but display only function's entrypoint
+# - W: disable automatic break whenever a watchpoint is hit, just report it on
+#   stderr (watchpoints can be defined using SOCLIB_GDB_WATCH)
+SIMULATOR_GDB=
+ifeq ("$(origin GDB)", "command line")
+    ifeq ($(GDB), 1)
+    	SIMULATOR_GDB=SOCLIB_GDB=FCX
+    else
+    	SIMULATOR_GDB=SOCLIB_GDB=$(GDB)
+    endif
+endif
+# ncpus
+SIMULATOR_NCPUS=4
+ifeq ("$(origin NCPUS)", "command line")
+	SIMULATOR_NCPUS=$(NCPUS)
+endif
+# vmlinux
+SIMULATOR_VMLINUX=./vmlinux
+ifeq ("$(origin VMLINUX)", "command line")
+	SIMULATOR_VMLINUX=$(VMLINUX)
+endif
+# dsk
+SIMULATOR_DSK=
+ifeq ("$(origin DSK)", "command line")
+	SIMULATOR_DSK=--dsk $(DSK)
+endif
+# trace
+SIMULATOR_TRACE=
+ifeq ("$(origin TRACE)", "command line")
+	SIMULATOR_TRACE=--trace $(TRACE)
+endif
+# ncycles
+SIMULATOR_NCYCLES=
+ifeq ("$(origin NCYCLES)", "command line")
+	SIMULATOR_NCYCLES=--ncycles $(NCYCLES)
+endif
+
+# recipes
+all: $(SIMULATOR_BINARY)
+
+$(SIMULATOR_BINARY): $(SOCLIB_DESC) $(SOCLIB_TOP)
+	soclib-cc $(SOCLIB_CC_ARGS) -P -p $(SOCLIB_DESC) -o $(SIMULATOR_BINARY)
+
+run_tsar_boot: all tsar_boot.bin
+	$(SIMULATOR_GDB) $(SIMULATOR_CMD) --ncpus $(SIMULATOR_NCPUS) --rom tsar_boot.bin $(SIMULATOR_DSK) $(SIMULATOR_TRACE) $(SIMULATOR_NCYCLES)
+
+run_dummy_boot: all
+	$(SIMULATOR_GDB) $(SIMULATOR_CMD) --ncpus $(SIMULATOR_NCPUS) --rom $(SIMULATOR_VMLINUX) $(SIMULATOR_DSK) --dummy-boot $(SIMULATOR_TRACE) $(SIMULATOR_NCYCLES)
+
+cscope.out:
+	soclib-cc -p $(SOCLIB_DESC) --tags
+
+clean:
+	soclib-cc -P -p $(SOCLIB_DESC) -x -o $(SIMULATOR_BINARY)
+	rm -f $(SIMULATOR_BINARY) *.o vci*
+
+.PHONY: $(SIMULATOR_BINARY)
Index: /trunk/platforms/linux_monocluster/README
===================================================================
--- /trunk/platforms/linux_monocluster/README	(revision 667)
+++ /trunk/platforms/linux_monocluster/README	(revision 667)
@@ -0,0 +1,61 @@
+April 2014, Joel Porquet
+
+This platform is known for being able to run Linux.
+
+----
+Pre-requisites:
+
+* A working version of SoCLib
+    - the command `soclib-cc --getpath` should return where SoCLib is installed
+* A working version of TSAR
+    - TSAR directory should be properly added to SoCLib's configuration: either
+      globally, or through the `soclib.conf` file present in this directory (in
+      which case, the environment variable `TSARDIR` should be defined to point
+      on TSAR directory)
+
+
+----
+Targets of the Makefile:
+
+* clean: clean the compilation files
+* all (or none): compile the simulation system
+* run_tsar_boot: runs the simulation system using a boot loader (in this case,
+  you want to use a blockdevice image that contains the kernel: see `DSK`
+  option below)
+* run_dummy_boot: runs the simulation system using directly Linux instead of a
+  boot loader (i.e. Linux is already loaded in RAM before execution).
+
+
+----
+Options for running:
+
+These options apply when using either `run_tsar_boot` or `run_dummy_boot`
+targets. Example: `make run_dummy_boot GDB=1 VMLINUX=../vmlinux DSK=dsk.img`
+
+* GDB=1|[FXSCTZW]: options to the GDB server (1 means FCX which is a good
+  default)
+* NCPUS=[1-4]: number of processors
+* DSK=[pathname]: path to a filesystem to use with the BlockDevice component
+  (also implies creating a system with such a component, other the component is
+  deactivated)
+* TRACE=[number]: enables tracing the simulation starting from a certain cycle
+* NCYCLES=[number]: runs the simulation for a certain number of cycles
+
+    Only for run_dummy_boot:
+    * VMLINUX=[pathname]: path to Linux `vmlinux` image
+
+
+----
+Using GDB server:
+
+A file named `.gdbinit` contains a few macros that can be useful for debugging
+Linux when using the GDB server.
+
+* connect: connect to the GDB server that runs within the simulation
+* dmesg: print the content of the kernel message buffer
+* thread_info: print the thread_info structure of the current task
+* task_struct: print the task_struct structure of the current task
+* active_mm: print the active_mm structure of the current task
+* pgd: print the content of the page table of the current task
+* ps: print the list of running tasks
+
Index: /trunk/platforms/linux_monocluster/desc.py
===================================================================
--- /trunk/platforms/linux_monocluster/desc.py	(revision 667)
+++ /trunk/platforms/linux_monocluster/desc.py	(revision 667)
@@ -0,0 +1,47 @@
+dspin_cmd_flit_size     = 39
+dspin_rsp_flit_size     = 32
+cell_size               = 4
+
+todo = Platform('caba', 'top.cpp',
+        uses = [
+            Uses('caba:vci_cc_vcache_wrapper',
+                dspin_in_width = dspin_cmd_flit_size,
+                dspin_out_width = dspin_rsp_flit_size,
+                iss_t = 'common:mips32el'),
+            Uses('caba:vci_cc_vcache_wrapper',
+                dspin_in_width = dspin_cmd_flit_size,
+                dspin_out_width = dspin_rsp_flit_size,
+                iss_t = 'common:gdb_iss',
+                gdb_iss_t = 'common:mips32el'),
+            Uses('caba:vci_simple_ram'),
+            Uses('caba:vci_simple_ram', cell_size = 8),
+            Uses('caba:vci_xicu'),
+            Uses('caba:vci_multi_tty'),
+            Uses('caba:vci_block_device_tsar'),
+            Uses('caba:vci_framebuffer'),
+            Uses('caba:vci_mem_cache',
+                memc_cell_size_int = cell_size,
+                memc_cell_size_ext = 8,
+                dspin_out_width = dspin_cmd_flit_size,
+                dspin_in_width = dspin_rsp_flit_size,
+                ),
+            Uses('caba:dspin_local_crossbar',
+                flit_width      =  dspin_cmd_flit_size),
+            Uses('caba:dspin_local_crossbar',
+                flit_width      = dspin_rsp_flit_size),
+            Uses('caba:vci_local_crossbar',
+                cell_size       = cell_size),
+            Uses('common:elf_file_loader'),
+            ],
+        cell_size = cell_size,
+        plen_size = 8,
+        addr_size = 32,
+        rerror_size = 1,
+        clen_size = 1,
+        rflag_size = 1,
+        srcid_size = 14,
+        pktid_size = 4,
+        trdid_size = 4,
+        wrplen_size = 1
+        )
+
Index: /trunk/platforms/linux_monocluster/segmentation.h
===================================================================
--- /trunk/platforms/linux_monocluster/segmentation.h	(revision 667)
+++ /trunk/platforms/linux_monocluster/segmentation.h	(revision 667)
@@ -0,0 +1,24 @@
+#ifndef _SEGMENTATION_H
+#define _SEGMENTATION_H
+
+#define MEMC_BASE   0x00000000
+#define MEMC_SIZE   0x10000000 // 256Mb
+
+#define BOOT_BASE   0xbfc00000
+#define BOOT_SIZE   0x00040000
+
+#define XICU_BASE   0x10000000
+#define XICU_SIZE   0x00001000 // 1 page
+
+#define MTTY_BASE   0x14000000
+#define MTTY_SIZE   0x0000000c // 3 mapped-registers
+
+#define BD_BASE     0x1c000000
+#define BD_SIZE     0x00000040 // 9 mapped-registers
+
+#define FB_XSIZE    640
+#define FB_YSIZE    480
+#define FB_BASE     0x20000000
+#define FB_SIZE     (FB_XSIZE * FB_YSIZE * 2)
+
+#endif
Index: /trunk/platforms/linux_monocluster/soclib.conf
===================================================================
--- /trunk/platforms/linux_monocluster/soclib.conf	(revision 667)
+++ /trunk/platforms/linux_monocluster/soclib.conf	(revision 667)
@@ -0,0 +1,5 @@
+#config.default.toolchain.set("cflags", config.default.toolchain.cflags + ['-ggdb'])
+
+import os
+config.addDescPath(os.environ['TSARDIR'] + "/trunk")
+
Index: /trunk/platforms/linux_monocluster/top.cpp
===================================================================
--- /trunk/platforms/linux_monocluster/top.cpp	(revision 667)
+++ /trunk/platforms/linux_monocluster/top.cpp	(revision 667)
@@ -0,0 +1,602 @@
+/*
+ * global config
+ */
+
+#define CONFIG_GDB_SERVER
+
+/*
+ * headers
+ */
+
+#include <systemc>
+#include <sys/time.h>
+#include <iostream>
+#include <cstdlib>
+#include <cstdarg>
+#include <inttypes.h>
+#include <limits.h>
+#ifdef _OPENMP
+#include <omp.h>
+#endif
+
+#ifdef CONFIG_GDB_SERVER
+#include "gdbserver.h"
+#endif
+
+#include "mapping_table.h"
+
+#include "mips32.h"
+#include "vci_mem_cache.h"
+#include "vci_cc_vcache_wrapper.h"
+#include "vci_block_device_tsar.h"
+
+#include "vci_simple_ram.h"
+#include "vci_multi_tty.h"
+#include "vci_xicu.h"
+#include "vci_framebuffer.h"
+
+#include "dspin_local_crossbar.h"
+#include "vci_local_crossbar.h"
+
+/*
+ * pf global config
+ */
+
+using namespace sc_core;
+using namespace soclib::caba;
+using namespace soclib::common;
+
+#define    cell_width            4
+#define    cell_width_ext        8
+#define    address_width         32
+#define    plen_width            8
+#define    error_width           1
+#define    clen_width            1
+#define    rflag_width           1
+#define    srcid_width           14
+#define    pktid_width           4
+#define    trdid_width           4
+#define    wrplen_width          1
+
+#define    dspin_cmd_width     39
+#define    dspin_rsp_width     32
+
+typedef VciParams<cell_width,
+        plen_width,
+        address_width,
+        error_width,
+        clen_width,
+        rflag_width,
+        srcid_width,
+        pktid_width,
+        trdid_width,
+        wrplen_width> vci_param;
+
+typedef VciParams<cell_width_ext,
+        plen_width,
+        address_width,
+        error_width,
+        clen_width,
+        rflag_width,
+        srcid_width,
+        pktid_width,
+        trdid_width,
+        wrplen_width> vci_param_ext;
+
+/*
+ * segmentation
+ */
+
+#include "segmentation.h"
+
+
+/*
+ * default parameters
+ */
+
+struct param_s {
+    size_t nr_cpus;
+    char *rom_path;
+    bool dsk;
+    char *dsk_path;
+    bool dummy_boot;
+    bool framebuffer;
+    bool trace_enabled;
+    size_t trace_start_cycle;
+    uint64_t ncycles;
+};
+
+#define PARAM_INITIALIZER   \
+{                           \
+    .nr_cpus = 1,           \
+    .rom_path = NULL,       \
+    .dsk = false,           \
+    .dsk_path = NULL,       \
+    .dummy_boot = false,    \
+    .framebuffer = false,   \
+    .trace_enabled = false, \
+    .trace_start_cycle = 0, \
+    .ncycles = 0,           \
+}
+
+static inline void print_param(const struct param_s &param)
+{
+    std::cout << std::endl;
+    std::cout << "simulation parameters:" << std::endl;
+    std::cout << "  nr_cpus     = " << param.nr_cpus << std::endl;
+    std::cout << "  rom         = " << param.rom_path << std::endl;
+    std::cout << "  dummy boot  = " << param.dummy_boot << std::endl;
+    std::cout << "  framebuffer = " << param.framebuffer << std::endl;
+    std::cout << "  dsk         = " << param.dsk << std::endl;
+    if (param.dsk)
+        std::cout << "    dsk_path  = " << param.dsk_path << std::endl;
+    std::cout << "  trace       = " << param.trace_enabled << std::endl;
+    if (param.trace_enabled)
+        std::cout << "    start cyc = " << param.trace_start_cycle << std::endl;
+    if (param.ncycles > 0)
+        std::cout << "    ncycles   = " << param.ncycles << std::endl;
+
+    std::cout << std::endl;
+}
+
+#define MAX_FROZEN_CYCLES 500000
+
+/*
+ * arguments parsing
+ */
+
+void args_parse(unsigned int argc, char *argv[], struct param_s &param)
+{
+    for (size_t n = 1; n < argc; n = n + 2)
+    {
+        if ((strcmp(argv[n], "--ncpus") == 0) && ((n + 1) < argc))
+        {
+            assert((param.nr_cpus = atoi(argv[n + 1]))
+                    && "insufficient memory");
+        }
+        else if ((strcmp(argv[n], "--rom") == 0) && ((n + 1) < argc))
+        {
+            assert((param.rom_path = strdup(argv[n + 1]))
+                    && "insufficient memory");
+        }
+        else if ((strcmp(argv[n], "--dsk") == 0) && ((n + 1) < argc))
+        {
+            param.dsk = true;
+            assert((param.dsk_path = strdup(argv[n + 1]))
+                    && "insufficient memory");
+        }
+        else if (strcmp(argv[n], "--dummy-boot") == 0)
+        {
+            param.dummy_boot = true;
+            /* we don't have an extra argument */
+            n = n - 1;
+        }
+        else if (strcmp(argv[n], "--framebuffer") == 0)
+        {
+            param.framebuffer = true;
+            /* we don't have an extra argument */
+            n = n - 1;
+        }
+        else if ((strcmp(argv[n], "--trace") == 0) && ((n + 1) < argc))
+        {
+            param.trace_enabled = true;
+            param.trace_start_cycle = atoi(argv[n + 1]);
+        }
+        else if ((strcmp(argv[n], "--ncycles") == 0) && ((n + 1) < argc))
+        {
+            param.ncycles = atoll(argv[n + 1]);
+        }
+        else
+        {
+            std::cout << "Error: don't understand option " << argv[n] << std::endl;
+            std::cout << "Accepted arguments are :" << std::endl;
+            std::cout << "--ncpus pathname" << std::endl;
+            std::cout << "--rom pathname" << std::endl;
+            std::cout << "[--dsk pathname]" << std::endl;
+            std::cout << "[--dummy-boot]" << std::endl;
+            std::cout << "[--framebuffer]" << std::endl;
+            std::cout << "[--trace trace_start_cycle]" << std::endl;
+            std::cout << "[--ncycles simulation_cycles]" << std::endl;
+            exit(0);
+        }
+    }
+
+    /* check parameters */
+    assert((param.nr_cpus <= 4) && "cannot support more than 4 cpus");
+    assert(param.rom_path && "--rom is not optional");
+
+    print_param(param);
+}
+
+
+/*
+ * netlist
+ */
+
+int _main(int argc, char *argv[])
+{
+#ifdef _OPENMP
+    omp_set_dynamic(false);
+    omp_set_num_threads(5);
+    std::cerr << "Built with openmp version " << _OPENMP << std::endl;
+#endif
+
+    struct param_s param = PARAM_INITIALIZER;
+
+    /* parse arguments */
+    args_parse(argc, argv, param);
+
+    /*
+     * mapping tables
+     */
+
+    /* data mapping table */
+    MappingTable maptabp(32, IntTab(0, 16), IntTab(0, srcid_width), 0xF0000000);
+
+    /* ram */
+    maptabp.add(Segment("mc_m", MEMC_BASE, MEMC_SIZE, IntTab(0, 0), true));
+    maptabp.add(Segment("boot", BOOT_BASE, BOOT_SIZE, IntTab(0, 1), true));
+
+    /* uncached peripherals */
+    maptabp.add(Segment("xicu", XICU_BASE, XICU_SIZE, IntTab(0, 2), false));
+    maptabp.add(Segment("tty",  MTTY_BASE, MTTY_SIZE, IntTab(0, 3), false));
+    maptabp.add(Segment("bd",   BD_BASE,   BD_SIZE,   IntTab(0, 4), false));
+    maptabp.add(Segment("fb",   FB_BASE,   FB_SIZE,   IntTab(0, 5), false));
+
+    std::cout << maptabp << std::endl;
+
+    /* xram mapping table */
+    MappingTable maptabx(32, IntTab(8), IntTab(8), 0x30000000);
+    maptabx.add(Segment("xram", MEMC_BASE, MEMC_SIZE, IntTab(0), false));
+
+    std::cout << maptabx << std::endl;
+
+    /*
+     * components
+     */
+
+    Loader loader;
+    loader.load_file(param.rom_path);
+
+#ifdef CONFIG_GDB_SERVER
+    typedef GdbServer<Mips32ElIss> proc_iss;
+    proc_iss::set_loader(loader);
+#else
+    typedef Mips32ElIss proc_iss;
+#endif
+
+    if (param.dummy_boot == true)
+    {
+        /* boot linux image directly */
+        uint64_t entry_addr = loader.get_entry_point_address();
+        std::cout << "setResetAdress: " << std::hex << entry_addr << std::endl << std::endl;
+        proc_iss::setResetAddress(entry_addr);
+    }
+
+    VciCcVCacheWrapper<vci_param, dspin_cmd_width, dspin_rsp_width, proc_iss > **proc;
+    proc = new VciCcVCacheWrapper<vci_param, dspin_cmd_width, dspin_rsp_width,
+         proc_iss >*[param.nr_cpus];
+    for (size_t i = 0; i < param.nr_cpus; i++)
+    {
+        std::ostringstream o;
+        o << "ccvache" << "[" << i << "]";
+        proc[i] = new VciCcVCacheWrapper<vci_param, dspin_cmd_width,
+            dspin_rsp_width, proc_iss >(
+                o.str().c_str(),    // name
+                i,                  // proc_id
+                maptabp,            // direct space
+                IntTab(0, i),       // srcid_d
+                i,                  // cc_global_id
+                8, 8,               // itlb size
+                8, 8,               // dtlb size
+                4, 64, 16,          // icache size
+                4, 64, 16,          // dcache size
+                4, 4,               // wbuf size
+                0, 0,               // x, y Width
+                MAX_FROZEN_CYCLES,  // max frozen cycles
+                param.trace_start_cycle,
+                param.trace_enabled);
+    }
+
+    VciSimpleRam<vci_param_ext> xram("xram", IntTab(0), maptabx, loader);
+
+    VciSimpleRam<vci_param> rom("rom", IntTab(0, 1), maptabp, loader);
+
+    VciMemCache<vci_param, vci_param_ext, dspin_rsp_width, dspin_cmd_width>
+        memc("memc",
+                maptabp,        // direct space
+                maptabx,        // xram space
+                IntTab(0),      // xram srcid
+                IntTab(0, 0),   // direct tgtid
+                0, 0,           // x, y width
+                16, 256, 16,    // cache size
+                3,              // max copies
+                4096, 8, 8, 8,  // HEAP size, TRT size, UPT size, IVT size
+                param.trace_start_cycle, param.trace_enabled);
+
+    VciXicu<vci_param> xicu("xicu", maptabp, IntTab(0, 2),
+            param.nr_cpus,  // #timers
+            3,              // #input hw irqs
+            param.nr_cpus,  // #ipis
+            param.nr_cpus); // #output irqs
+
+    VciMultiTty<vci_param> mtty("mtty", IntTab(0, 3), maptabp, "vcitty0", NULL);
+
+    VciBlockDeviceTsar<vci_param> *bd = NULL;
+    if (param.dsk == true)
+        bd = new VciBlockDeviceTsar<vci_param>("bd", maptabp,
+                IntTab(0, param.nr_cpus),   // srcid
+                IntTab(0, 4),               // tgtid
+                param.dsk_path);            // filename
+
+    VciFrameBuffer<vci_param> *fb = NULL;
+    if (param.framebuffer == true)
+        fb = new VciFrameBuffer<vci_param>("fb", IntTab(0, 5), maptabp,
+                FB_XSIZE, FB_YSIZE,     // window size
+                FbController::RGB_16);  // color type
+
+    /*
+     * Interconnects
+     */
+
+    /* data network */
+    VciLocalCrossbar<vci_param> xbar_d("xbar_d",
+            maptabp,        // mapping table
+            0,              // cluster coordinates
+            param.nr_cpus + 1, // #src
+            6,              // #dst
+            1);             // default target
+
+    /* coherence */
+    DspinLocalCrossbar<dspin_cmd_width> xbar_m2p_c("xbar_m2p_c",
+            maptabp,
+            0, 0,
+            0, 0,
+            srcid_width,
+            1, param.nr_cpus,
+            2, 2,
+            true,
+            false,
+            true);
+    DspinLocalCrossbar<dspin_rsp_width> xbar_p2m_c("xbar_p2m_c",
+            maptabp,
+            0, 0,
+            0, 0,
+            0,
+            param.nr_cpus, 1,
+            2, 2,
+            false,
+            false,
+            false);
+    DspinLocalCrossbar<dspin_cmd_width> xbar_clack_c("xbar_clack_c",
+            maptabp,
+            0, 0,
+            0, 0,
+            srcid_width,
+            1, param.nr_cpus,
+            1, 1,
+            true,
+            false,
+            false);
+
+    /*
+     * signals
+     */
+
+    /* clk and resetn */
+    sc_clock signal_clk ("clk");
+    sc_signal<bool> signal_resetn("resetn");
+
+    /* irq lines */
+    sc_signal<bool> **signal_proc_irq =
+        alloc_elems<sc_signal<bool> >("proc_irq", param.nr_cpus, proc_iss::n_irq);
+    sc_signal<bool> signal_mtty_irq("mtty_irq");
+    sc_signal<bool> signal_bd_irq("bd_irq");
+    sc_signal<bool> signal_memc_irq("memc_irq");
+
+    /* vci */
+    VciSignals<vci_param> *signal_vci_proc =
+        alloc_elems<VciSignals<vci_param> >("vci_proc", param.nr_cpus);
+    VciSignals<vci_param> signal_vci_ini_bd ("vci_ini_bd");
+
+    VciSignals<vci_param> signal_vci_memc ("vci_memc");
+    VciSignals<vci_param> signal_vci_rom ("vci_rom");
+    VciSignals<vci_param> signal_vci_xicu ("vci_xicu");
+    VciSignals<vci_param> signal_vci_tty ("vci_tty");
+    VciSignals<vci_param> signal_vci_tgt_bd ("vci_tgt_bd");
+    VciSignals<vci_param> signal_vci_fb ("vci_fb");
+
+    VciSignals<vci_param_ext> signal_vci_xram ("vci_xram");
+
+    /* fake signals for in/out of cluster */
+    VciSignals<vci_param> signal_vci_from_out("vci_from_out");
+    VciSignals<vci_param> signal_vci_to_out("vci_to_out");
+
+    /* Coherence DSPIN signals to local crossbar */
+    DspinSignals<dspin_cmd_width> signal_dspin_m2p_l2g;
+    DspinSignals<dspin_cmd_width> signal_dspin_m2p_g2l;
+    DspinSignals<dspin_rsp_width> signal_dspin_p2m_l2g;
+    DspinSignals<dspin_rsp_width> signal_dspin_p2m_g2l;
+    DspinSignals<dspin_cmd_width> signal_dspin_clack_l2g;
+    DspinSignals<dspin_cmd_width> signal_dspin_clack_g2l;
+
+    DspinSignals<dspin_cmd_width> signal_dspin_m2p_memc;
+    DspinSignals<dspin_cmd_width> signal_dspin_clack_memc;
+    DspinSignals<dspin_rsp_width> signal_dspin_p2m_memc;
+    DspinSignals<dspin_cmd_width> *signal_dspin_m2p_proc =
+        alloc_elems<DspinSignals<dspin_cmd_width> >("dspin_m2p_proc", param.nr_cpus);
+    DspinSignals<dspin_cmd_width> *signal_dspin_clack_proc =
+        alloc_elems<DspinSignals<dspin_cmd_width> >("dspin_clack_proc", param.nr_cpus);
+    DspinSignals<dspin_rsp_width> *signal_dspin_p2m_proc =
+        alloc_elems<DspinSignals<dspin_rsp_width> >("dspin_p2m_proc", param.nr_cpus);
+
+    /*
+     * netlist
+     */
+
+    /* components */
+    for (size_t i = 0; i < param.nr_cpus; i++)
+    {
+        proc[i]->p_clk(signal_clk);
+        proc[i]->p_resetn(signal_resetn);
+        for (size_t j = 0; j < proc_iss::n_irq; j++)
+            proc[i]->p_irq[j](signal_proc_irq[i][j]);
+        proc[i]->p_vci(signal_vci_proc[i]);
+        proc[i]->p_dspin_m2p(signal_dspin_m2p_proc[i]);
+        proc[i]->p_dspin_p2m(signal_dspin_p2m_proc[i]);
+        proc[i]->p_dspin_clack(signal_dspin_clack_proc[i]);
+    }
+
+    memc.p_clk(signal_clk);
+    memc.p_resetn(signal_resetn);
+    memc.p_irq(signal_memc_irq);
+    memc.p_vci_tgt(signal_vci_memc);
+    memc.p_dspin_p2m(signal_dspin_p2m_memc);
+    memc.p_dspin_m2p(signal_dspin_m2p_memc);
+    memc.p_dspin_clack(signal_dspin_clack_memc);
+    memc.p_vci_ixr(signal_vci_xram);
+
+    rom.p_clk(signal_clk);
+    rom.p_resetn(signal_resetn);
+    rom.p_vci(signal_vci_rom);
+
+    xicu.p_resetn(signal_resetn);
+    xicu.p_clk(signal_clk);
+    xicu.p_vci(signal_vci_xicu);
+    xicu.p_hwi[0](signal_mtty_irq);
+    xicu.p_hwi[1](signal_bd_irq);
+    xicu.p_hwi[2](signal_memc_irq);
+    for (size_t i = 0; i < param.nr_cpus; i++)
+        xicu.p_irq[i](signal_proc_irq[i][0]);
+
+    mtty.p_clk(signal_clk);
+    mtty.p_resetn(signal_resetn);
+    mtty.p_vci(signal_vci_tty);
+    mtty.p_irq[0](signal_mtty_irq);
+
+    if (param.dsk == true)
+    {
+        bd->p_clk(signal_clk);
+        bd->p_resetn(signal_resetn);
+        bd->p_vci_target(signal_vci_tgt_bd);
+        bd->p_vci_initiator(signal_vci_ini_bd);
+        bd->p_irq(signal_bd_irq);
+    }
+
+    if (param.framebuffer == true)
+    {
+        fb->p_clk(signal_clk);
+        fb->p_resetn(signal_resetn);
+        fb->p_vci(signal_vci_fb);
+    }
+
+    xram.p_clk(signal_clk);
+    xram.p_resetn(signal_resetn);
+    xram.p_vci(signal_vci_xram);
+
+    /* interconnects */
+    xbar_d.p_clk(signal_clk);
+    xbar_d.p_resetn(signal_resetn);
+    xbar_d.p_target_to_up(signal_vci_from_out);
+    xbar_d.p_initiator_to_up(signal_vci_to_out);
+    for (size_t i = 0; i < param.nr_cpus; i++)
+        xbar_d.p_to_initiator[i](signal_vci_proc[i]);
+    xbar_d.p_to_initiator[param.nr_cpus](signal_vci_ini_bd);
+    xbar_d.p_to_target[0](signal_vci_memc);
+    xbar_d.p_to_target[1](signal_vci_rom);
+    xbar_d.p_to_target[2](signal_vci_xicu);
+    xbar_d.p_to_target[3](signal_vci_tty);
+    xbar_d.p_to_target[4](signal_vci_tgt_bd);
+    xbar_d.p_to_target[5](signal_vci_fb);
+
+    xbar_m2p_c.p_clk(signal_clk);
+    xbar_m2p_c.p_resetn(signal_resetn);
+    xbar_m2p_c.p_global_out(signal_dspin_m2p_l2g);
+    xbar_m2p_c.p_global_in(signal_dspin_m2p_g2l);
+    xbar_m2p_c.p_local_in[0](signal_dspin_m2p_memc);
+    for (size_t i = 0; i < param.nr_cpus; i++)
+        xbar_m2p_c.p_local_out[i](signal_dspin_m2p_proc[i]);
+
+    xbar_clack_c.p_clk(signal_clk);
+    xbar_clack_c.p_resetn(signal_resetn);
+    xbar_clack_c.p_global_out(signal_dspin_clack_l2g);
+    xbar_clack_c.p_global_in(signal_dspin_clack_g2l);
+    xbar_clack_c.p_local_in[0](signal_dspin_clack_memc);
+    for (size_t i = 0; i < param.nr_cpus; i++)
+        xbar_clack_c.p_local_out[i](signal_dspin_clack_proc[i]);
+
+    xbar_p2m_c.p_clk(signal_clk);
+    xbar_p2m_c.p_resetn(signal_resetn);
+    xbar_p2m_c.p_global_out(signal_dspin_p2m_l2g);
+    xbar_p2m_c.p_global_in(signal_dspin_p2m_g2l);
+    xbar_p2m_c.p_local_out[0](signal_dspin_p2m_memc);
+    for (size_t i = 0; i < param.nr_cpus; i++)
+        xbar_p2m_c.p_local_in[i](signal_dspin_p2m_proc[i]);
+
+    /*
+     * simulation
+     */
+
+    for (size_t i = 0; i < param.nr_cpus; i++)
+        proc[i]->iss_set_debug_mask(0);
+
+    sc_start(sc_time(0, SC_NS));
+    signal_resetn = false;
+
+    sc_start(sc_time(1, SC_NS));
+    signal_resetn = true;
+
+    /* network boundaries initialization */
+    signal_dspin_m2p_l2g.write = false;
+    signal_dspin_m2p_l2g.read = true;
+    signal_dspin_m2p_g2l.write = false;
+    signal_dspin_m2p_g2l.read = true;
+
+    if (param.ncycles > 0)
+    {
+        for (size_t n = 1; n < param.ncycles; n++)
+        {
+            if (param.trace_enabled and (n > param.trace_start_cycle))
+            {
+                std::cout << "****************** cycle " << std::dec << n
+                    << " ************************************************" << std::endl;
+
+                proc[0]->print_trace();
+                memc.print_trace();
+
+                signal_vci_proc[0].print_trace("signal_vci_proc[0]");
+                signal_vci_memc.print_trace("signal_vci_memc");
+
+                signal_dspin_m2p_memc.print_trace("signal_m2p_memc");
+                signal_dspin_clack_memc.print_trace("signal_clack_memc");
+                signal_dspin_p2m_memc.print_trace("signal_p2m_memc");
+                for (size_t i = 0; i < param.nr_cpus; i++)
+                {
+                    std::ostringstream o;
+                    o << "signal_m2p_proc" << "[" << i << "]";
+                    signal_dspin_m2p_proc[i].print_trace(o.str().c_str());
+                }
+            }
+            sc_start(sc_core::sc_time(1, SC_NS));
+        }
+    } else {
+        sc_start();
+    }
+
+    return EXIT_SUCCESS;
+
+}
+
+int sc_main (int argc, char *argv[])
+{
+    try {
+        return _main(argc, argv);
+    } catch (std::exception &e) {
+        std::cout << e.what() << std::endl;
+    } catch (...) {
+        std::cout << "Unknown exception occured" << std::endl;
+        throw;
+    }
+    return EXIT_FAILURE;
+}
+
