Index: /branches/reconfiguration/modules/dspin_router/caba/source/include/dspin_router.h
===================================================================
--- /branches/reconfiguration/modules/dspin_router/caba/source/include/dspin_router.h	(revision 993)
+++ /branches/reconfiguration/modules/dspin_router/caba/source/include/dspin_router.h	(revision 994)
@@ -84,7 +84,4 @@
     DspinOutput<flit_width>     *p_out;
 
-    // reconfiguration port
-    sc_in<uint32_t>             *p_recovery_cfg;
-
     // constructor / destructor
     DspinRouter( sc_module_name  name,
@@ -95,5 +92,6 @@
                  const size_t    in_fifo_depth,
                  const size_t    out_fifo_depth,
-                 const bool      broadcast_supported = false );
+                 const bool      broadcast_supported = false,
+                 const bool      configuration_supported = false );
 
     ~DspinRouter();
@@ -107,4 +105,8 @@
         bool                 eop;
     } internal_flit_t;
+
+    // reconfiguration port
+    // port binding is performed with the bind_recovery_port() function
+    sc_in<uint32_t>             *p_recovery_cfg;
 
     // registers
@@ -135,19 +137,15 @@
     void    transition();
     void    genMoore();
+
     int     xfirst_route( size_t xdest, size_t ydest );
+    int     recovery_route( size_t xdest, size_t ydest );
     int     route( sc_uint<flit_width> data );
+
     int     broadcast_route( int iter, int source, sc_uint<flit_width> data );
     bool    is_broadcast( sc_uint<flit_width> data );
+    sc_uint<flit_width> compute_broadcast_header( int source );
 
-    // fault-recovery methods
     bool    is_destination_blackhole( size_t xdest, size_t ydest, int bhpos );
-    int     recovery_route( size_t xdest, size_t ydest );
-
-    public:
-
-    inline void set_disable_mask( int mask )
-    {
-        m_disable_mask = mask;
-    }
+    int     blackhole_position();
 
     inline bool is_network_recovery_enable()
@@ -161,10 +159,17 @@
     }
 
-    inline int blackhole_position()
+    inline bool is_reconfigurable()
     {
-        return (p_recovery_cfg->read() & 0xF);
+        return (p_recovery_cfg != NULL);
     }
 
-    void bind_recovery_port( sc_core::sc_signal<uint32_t> &s );
+    public:
+
+    inline void set_disable_mask( int mask )
+    {
+        m_disable_mask = mask;
+    }
+
+    void bind_recovery_port(sc_signal<uint32_t> &s);
 
     void print_trace();
Index: /branches/reconfiguration/modules/dspin_router/caba/source/src/dspin_router.cpp
===================================================================
--- /branches/reconfiguration/modules/dspin_router/caba/source/src/dspin_router.cpp	(revision 993)
+++ /branches/reconfiguration/modules/dspin_router/caba/source/src/dspin_router.cpp	(revision 994)
@@ -60,5 +60,6 @@
                              const size_t   in_fifo_depth,
                              const size_t   out_fifo_depth,
-                             const bool     broadcast_supported)
+                             const bool     broadcast_supported,
+                             const bool     configuration_supported)
     : soclib::caba::BaseModule(name),
 
@@ -67,4 +68,5 @@
       p_in( alloc_elems<DspinInput<flit_width> >("p_in", 5) ),
       p_out( alloc_elems<DspinOutput<flit_width> >("p_out", 5) ),
+      p_recovery_cfg(NULL),
 
       r_alloc_out( alloc_elems<sc_signal<bool> >("r_alloc_out", 5)),
@@ -116,5 +118,7 @@
         }
 
-        p_recovery_cfg = NULL;
+        if (configuration_supported) {
+            p_recovery_cfg = new sc_core::sc_in<uint32_t> ("p_recovery_cfg");
+        }
     } //  end constructor
 
@@ -122,5 +126,26 @@
     tmpl(/**/)::~DspinRouter()
     {
-        if ( p_recovery_cfg != NULL ) delete p_recovery_cfg;
+        if ( is_reconfigurable() ) delete p_recovery_cfg;
+    }
+
+    ///////////////////////////////////////////////////
+    tmpl(int)::blackhole_position()
+    {
+        if ( is_reconfigurable() ) {
+            return p_recovery_cfg->read() & 0xF;
+        }
+        return BH_NONE;
+    }
+
+    ///////////////////////////////////////////////////
+    tmpl(void)::bind_recovery_port(sc_signal<uint32_t> &s)
+    {
+        if (!is_reconfigurable()) {
+            std::cerr << "Error in " << name()
+                      << ": router configuration not supported." << std::endl
+                      << "Enable it during router instantiation." << std::endl;
+            exit(1);
+        }
+        (*p_recovery_cfg)(s);
     }
 
@@ -135,50 +160,42 @@
 
     ///////////////////////////////////////////////////
-    tmpl(void)::bind_recovery_port( sc_core::sc_signal<uint32_t> &s )
-    {
-        if (p_recovery_cfg == NULL) {
-            p_recovery_cfg = new sc_core::sc_in<uint32_t> ("p_recovery_cfg");
-        }
-        (*p_recovery_cfg)(s);
-    }
-
-    ///////////////////////////////////////////////////
     tmpl(bool)::is_destination_blackhole( size_t xdest, size_t ydest, int bhpos )
     {
         size_t xhole, yhole;
-        if (bhpos == BH_N) {
-            xhole = m_local_x;
-            yhole = m_local_y - 1;
-        }
-        else if (bhpos == BH_NW) {
-            xhole = m_local_x + 1;
-            yhole = m_local_y - 1;
-        }
-        else if (bhpos == BH_W) {
-            xhole = m_local_x + 1;
-            yhole = m_local_y;
-        }
-        else if (bhpos == BH_SW) {
-            xhole = m_local_x + 1;
-            yhole = m_local_y + 1;
-        }
-        else if (bhpos == BH_S) {
-            xhole = m_local_x;
-            yhole = m_local_y + 1;
-        }
-        else if (bhpos == BH_SE) {
-            xhole = m_local_x - 1;
-            yhole = m_local_y + 1;
-        }
-        else if (bhpos == BH_E) {
-            xhole = m_local_x - 1;
-            yhole = m_local_y;
-        }
-        else if (bhpos == BH_NE) {
-            xhole = m_local_x - 1;
-            yhole = m_local_y - 1;
-        }
-        else {
-            return false;
+        switch (bhpos) {
+            case BH_N:
+                xhole = m_local_x;
+                yhole = m_local_y - 1;
+                break;
+            case BH_NW:
+                xhole = m_local_x + 1;
+                yhole = m_local_y - 1;
+                break;
+            case BH_W:
+                xhole = m_local_x + 1;
+                yhole = m_local_y;
+                break;
+            case BH_SW:
+                xhole = m_local_x + 1;
+                yhole = m_local_y + 1;
+                break;
+            case BH_S:
+                xhole = m_local_x;
+                yhole = m_local_y + 1;
+                break;
+            case BH_SE:
+                xhole = m_local_x - 1;
+                yhole = m_local_y + 1;
+                break;
+            case BH_E:
+                xhole = m_local_x - 1;
+                yhole = m_local_y;
+                break;
+            case BH_NE:
+                xhole = m_local_x - 1;
+                yhole = m_local_y - 1;
+                break;
+            default:
+                return false;
         }
 
@@ -300,31 +317,28 @@
         size_t xdest = (size_t)(data >> m_x_shift) & m_x_mask;
         size_t ydest = (size_t)(data >> m_y_shift) & m_y_mask;
-        if ( p_recovery_cfg != NULL )
-        {
-            if (blackhole_position() != BH_NONE )
+        if ( blackhole_position() != BH_NONE )
+        {
+            // reroute the request if its destination is the blackhole (this
+            // is to implement the segment recovery mechanism)
+            if ( is_destination_blackhole(xdest, ydest, blackhole_position()) )
             {
-                // reroute the request if its destination is the blackhole (this
-                // is to implement the segment recovery mechanism)
-                if (is_destination_blackhole(xdest, ydest, blackhole_position()))
-                {
-                    int dir = migration_route();
+                int dir = migration_route();
 
 #if SOCLIB_MODULE_DEBUG
-                    std::cout << "<" << name() << "> migration: "
-                              << "route request to DIR = " << dir << std::endl;
+                std::cout << "<" << name() << "> migration: "
+                          << "route request to DIR = " << dir << std::endl;
 #endif
-                    return dir;
-                }
-
-                if (is_network_recovery_enable())
-                {
-                    int dir = recovery_route(xdest, ydest);
+                return dir;
+            }
+
+            if (is_network_recovery_enable())
+            {
+                int dir = recovery_route(xdest, ydest);
 
 #if SOCLIB_MODULE_DEBUG
-                    std::cout << "<" << name() << "> network recovery: "
-                              << "route request to DIR = " << dir << std::endl;
+                std::cout << "<" << name() << "> network recovery: "
+                          << "route request to DIR = " << dir << std::endl;
 #endif
-                    return dir;
-                }
+                return dir;
             }
         }
@@ -332,49 +346,115 @@
     }
 
-    //////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////
     tmpl(int)::broadcast_route(int step, int source, sc_uint<flit_width> data)
     {
-        int    sel  = REQ_NOP;
-        size_t xmin = (data >> (flit_width - 5 )) & 0x1F;
-        size_t xmax = (data >> (flit_width - 10)) & 0x1F;
-        size_t ymin = (data >> (flit_width - 15)) & 0x1F;
-        size_t ymax = (data >> (flit_width - 20)) & 0x1F;
+        const size_t lx   = m_local_x;
+        const size_t ly   = m_local_y;
+        const size_t xmin = (data >> (flit_width - 5 )) & 0x1F;
+        const size_t xmax = (data >> (flit_width - 10)) & 0x1F;
+        const size_t ymin = (data >> (flit_width - 15)) & 0x1F;
+        const size_t ymax = (data >> (flit_width - 20)) & 0x1F;
+        const int    bh   = blackhole_position();
+        int  sel = REQ_NOP;
+        bool ew  = ((data & 0x2) != 0);
 
         switch(source) {
         case REQ_LOCAL :
-            if      ( step == 1 )   sel = REQ_NORTH;
-            else if ( step == 2 )   sel = REQ_SOUTH;
-            else if ( step == 3 )   sel = REQ_EAST;
-            else if ( step == 4 )   sel = REQ_WEST;
+            if      ( step == 1 ) sel = REQ_NORTH;
+            else if ( step == 2 ) sel = REQ_SOUTH;
+            else if ( step == 3 ) {
+                if ( (bh == BH_N) && (lx != 0) && (ly != 1) ) {
+                    sel = REQ_NOP;
+                    break;
+                }
+                sel = REQ_EAST;
+            }
+            else if ( step == 4 ) {
+                if ( (bh == BH_NE) && (lx != 1) && (ly != 1) ) {
+                    sel = REQ_NOP;
+                    break;
+                }
+                sel = REQ_WEST;
+            }
         break;
         case REQ_NORTH :
-            if      ( step == 1 )   sel = REQ_SOUTH;
-            else if ( step == 2 )   sel = REQ_LOCAL;
-            else if ( step == 3 )   sel = REQ_NOP;
-            else if ( step == 4 )   sel = REQ_NOP;
+            if      ( step == 1 ) sel = REQ_SOUTH;
+            else if ( step == 2 ) sel = REQ_LOCAL;
+            else if ( step == 3 ) {
+                if ( bh == BH_SW ) {
+                    sel = REQ_EAST;
+                    break;
+                }
+                sel = REQ_NOP;
+            }
+            else if ( step == 4 ) {
+                if ( (bh == BH_SE) && (ew || (lx == 1)) ) {
+                    sel = REQ_WEST;
+                    break;
+                }
+                sel = REQ_NOP;
+            }
         break;
         case REQ_SOUTH :
-            if      ( step == 1 )   sel = REQ_NORTH;
-            else if ( step == 2 )   sel = REQ_LOCAL;
-            else if ( step == 3 )   sel = REQ_NOP;
-            else if ( step == 4 )   sel = REQ_NOP;
+            if      ( step == 1 ) sel = REQ_NORTH;
+            else if ( step == 2 ) sel = REQ_LOCAL;
+            else if ( step == 3 ) {
+                if ( bh == BH_NW ) {
+                    sel = REQ_EAST;
+                    break;
+                }
+                if ( (bh == BH_NE) && ((lx == 1) || (ly == 1)) ) {
+                    sel = REQ_WEST;
+                    break;
+                }
+                sel = REQ_NOP;
+            }
+            else if ( step == 4 ) sel = REQ_NOP;
         break;
         case REQ_EAST :
-            if      ( step == 1 )   sel = REQ_WEST;
-            else if ( step == 2 )   sel = REQ_NORTH;
-            else if ( step == 3 )   sel = REQ_SOUTH;
-            else if ( step == 4 )   sel = REQ_LOCAL;
+            if ( step == 1 ) {
+                if ( (bh == BH_NE) && (lx != 1) && (ly != 1) ) {
+                    sel = REQ_NOP;
+                    break;
+                }
+                sel = REQ_WEST;
+            }
+            else if ( step == 2 ) sel = REQ_NORTH;
+            else if ( step == 3 ) sel = REQ_SOUTH;
+            else if ( step == 4 ) sel = REQ_LOCAL;
         break;
         case REQ_WEST :
-            if      ( step == 1 )   sel = REQ_EAST;
-            else if ( step == 2 )   sel = REQ_NORTH;
-            else if ( step == 3 )   sel = REQ_SOUTH;
-            else if ( step == 4 )   sel = REQ_LOCAL;
+            if ( step == 1 ) {
+                if ( (bh == BH_N) && (ly != 1) ) {
+                    sel = REQ_NOP;
+                    break;
+                }
+                if ( (bh == BH_S) && !ew ) {
+                    sel = REQ_NOP;
+                    break;
+                }
+                sel = REQ_EAST;
+            }
+            else if ( step == 2 ) sel = REQ_NORTH;
+            else if ( step == 3 ) sel = REQ_SOUTH;
+            else if ( step == 4 ) sel = REQ_LOCAL;
         break;
         }
-        if      ( (sel == REQ_NORTH) && !(m_local_y < ymax) )   sel = REQ_NOP;
-        else if ( (sel == REQ_SOUTH) && !(m_local_y > ymin) )   sel = REQ_NOP;
-        else if ( (sel == REQ_EAST ) && !(m_local_x < xmax) )   sel = REQ_NOP;
-        else if ( (sel == REQ_WEST ) && !(m_local_x > xmin) )   sel = REQ_NOP;
+
+        if      ( (sel == REQ_NORTH) && !(ly < ymax) ) sel = REQ_NOP;
+        else if ( (sel == REQ_SOUTH) && !(ly > ymin) ) sel = REQ_NOP;
+        else if ( (sel == REQ_EAST ) && !(lx < xmax) ) sel = REQ_NOP;
+        else if ( (sel == REQ_WEST ) && !(lx > xmin) ) sel = REQ_NOP;
+
+#if 0
+        /* This code can be used if we want to inhibit requests to the
+         * blackhole. However, it is not strictly necessary because the
+         * blackhole will consume the request and will do nothing with it */
+
+        if      ( (sel == REQ_NORTH) && (bh == BH_S) ) sel = REQ_NOP;
+        else if ( (sel == REQ_SOUTH) && (bh == BH_N) ) sel = REQ_NOP;
+        else if ( (sel == REQ_EAST ) && (bh == BH_W) ) sel = REQ_NOP;
+        else if ( (sel == REQ_WEST ) && (bh == BH_E) ) sel = REQ_NOP;
+#endif
 
         return sel;
@@ -382,7 +462,48 @@
 
     /////////////////////////////////////////////////////////
-    tmpl(inline bool)::is_broadcast(sc_uint<flit_width> data)
+    tmpl(bool)::is_broadcast(sc_uint<flit_width> data)
     {
         return ( (data & 0x1) != 0);
+    }
+
+    /////////////////////////////////////////////////////////
+    tmpl(sc_uint<flit_width>)::compute_broadcast_header(int source)
+    {
+        const int bh = blackhole_position();
+        sc_uint<flit_width> header = r_fifo_in[source].read().data;
+        sc_uint<flit_width> mask = 0x2;
+        switch (source) {
+            case REQ_LOCAL:
+                if ( bh != BH_NONE ) {
+                    header |= mask;
+                }
+                break;
+            case REQ_EAST:
+                if ( (bh == BH_NE) || (bh == BH_E) ) {
+                    header |= mask;
+                }
+                break;
+            case REQ_WEST:
+                if ( (bh == BH_NW) || (bh == BH_W) || (bh == BH_SW) ) {
+                    header |= mask;
+                }
+                break;
+
+            /* Make sure that the EW bit is not set when it shouldn't.
+             * This can arrive if an initiator or a local interconnect uses
+             * the broadcast header reserved bits internally and don't reset
+             * them */
+            case REQ_NORTH:
+                if ( (bh == BH_NW) || (bh == BH_N) || (bh == BH_NE) ) {
+                    header &= ~mask;
+                }
+                break;
+            case REQ_SOUTH:
+                if ( (bh == BH_SW) || (bh == BH_S) || (bh == BH_SE) ) {
+                    header &= ~mask;
+                }
+                break;
+        }
+        return header;
     }
 
@@ -414,5 +535,19 @@
         };
 
+        const char* bh_str[] =
+        {
+            "BH_NONE",
+            "BH_N",
+            "BH_NE",
+            "BH_E",
+            "BH_SE",
+            "BH_S",
+            "BH_SW",
+            "BH_W",
+            "BH_NW"
+        };
+
         std::cout << "DSPIN_ROUTER " << name();
+        std::cout << " / bh = " << bh_str[blackhole_position()];
 
         for( size_t i = 0 ; i < 5 ; i++)  // loop on input ports
@@ -517,7 +652,18 @@
                              m_broadcast_supported )          // broadcast
                         {
+                            if ( r_fifo_in[i].read().eop )
+                            {
+                                std::cout << "ERROR in DSPIN_ROUTER " << name()
+                                          << " : broadcast packet must be 2 flits" << std::endl;
+                                exit(1);
+                            }
+
+                            internal_flit_t header;
+                            header.eop  = false;
+                            header.data = compute_broadcast_header(i);
+
                             fifo_in_read[i] = true;
-                            req_in[i]       = broadcast_route(1, i, r_fifo_in[i].read().data);
-                            r_buf_in[i]     = r_fifo_in[i].read();
+                            req_in[i]       = broadcast_route(1, i, header.data);
+                            r_buf_in[i]     = header;
                             r_index_in[i]   = req_in[i];
                             if( req_in[i] == REQ_NOP ) r_fsm_in[i] = INFSM_REQ_SECOND;
Index: /branches/reconfiguration/modules/dspin_router/caba/test/synthetic_test/Makefile
===================================================================
--- /branches/reconfiguration/modules/dspin_router/caba/test/synthetic_test/Makefile	(revision 994)
+++ /branches/reconfiguration/modules/dspin_router/caba/test/synthetic_test/Makefile	(revision 994)
@@ -0,0 +1,21 @@
+TAGS := cscope.out
+#SOCLIB_ARGS='--type=envsystemc'
+
+all: simul.x
+tags: $(TAGS)
+
+simul.x: top.cpp top.desc
+	soclib-cc $(SOCLIB_ARGS) -P -p top.desc -I. -o simul.x
+
+$(TAGS): top.desc
+	soclib-cc -p $< --tags --tags-type=cscope --tags-output=$@
+
+clean:
+	soclib-cc $(SOCLIB_ARGS) x -p top.desc -I.
+	rm -rf *.o *.x tty* term*
+
+distclean: clean
+	rm -rf logs
+
+.PHONY: simul.x $(TAGS)
+
Index: /branches/reconfiguration/modules/dspin_router/caba/test/synthetic_test/check_broadcast.sh
===================================================================
--- /branches/reconfiguration/modules/dspin_router/caba/test/synthetic_test/check_broadcast.sh	(revision 994)
+++ /branches/reconfiguration/modules/dspin_router/caba/test/synthetic_test/check_broadcast.sh	(revision 994)
@@ -0,0 +1,75 @@
+#!/usr/bin/env sh
+# @author	Cesar Armando Fuguet Tortolero
+# @date		24 May, 2015
+# @brief	This script validates that a broadcast transaction reaches once
+#			and only once every non-faulty router in the platform.
+file=$1
+awk '
+BEGIN {
+	sent=0
+	last=0
+	failure=0
+}
+#   Parse coordinates of routers
+#   /DSPIN_GENERATOR/ {
+#   	regex="\\[[0-9]+\\]\\[";
+#   	if (match($2,regex)) {
+#   		x=substr($2,RSTART+1,RLENGTH-3);
+#   	}
+#   	regex="\\]\\[[0-9]+\\]";
+#   	if (match($2,regex)) {
+#   		y=substr($2,RSTART+2,RLENGTH-3);
+#   	}
+#   }
+
+#   Parse the number of sent broadcast packets
+/broadcast sent packets += +/ {
+	if ($6 != 0) {
+		sent=$6;
+	}
+}
+#   Parse the number of received broadcast packets
+/broadcast received packets +=/ {
+	if ($6 == 0) {
+		zero++;
+	}
+	else {
+		# store the number of received packets of a router that actually
+		# received packets.
+		if (last == 0) {
+			last=$6
+		}
+		# test if the error is too important. The error is defined as
+		# difference between the number of packets received by different
+		# routers.
+		error=last - $6
+		if ((error > 20) || (error < -20)) {
+			failure=1
+			exit;
+		}
+	}
+}
+
+#   Validate the file
+END {
+	# an error was too important
+	if (failure == 1) {
+		exit 1
+	}
+
+	# it should be only two routers that do not receive the broadcast:
+	# the source and the faulty router.
+	if (zero != 2) {
+		exit 1;
+	}
+
+	# test if the error is too important
+	error=last - sent
+	if ((error > 20) || (error < -20)) {
+		exit 1;
+	}
+
+	exit 0;
+}' $file
+if [[ $? == 1 ]]; then exit 1; fi
+
Index: /branches/reconfiguration/modules/dspin_router/caba/test/synthetic_test/run.sh
===================================================================
--- /branches/reconfiguration/modules/dspin_router/caba/test/synthetic_test/run.sh	(revision 994)
+++ /branches/reconfiguration/modules/dspin_router/caba/test/synthetic_test/run.sh	(revision 994)
@@ -0,0 +1,23 @@
+#!/usr/bin/env sh
+LOGDIR=logs
+COMMON="-X 5 -Y 5 -N 3000"
+
+mkdir -p $LOGDIR
+for (( x = 0; x < 5; x++ )); do
+	for (( y = 0; y < 5; y++ )); do
+		for (( fx = 0; fx < 5; fx++ )); do
+			for (( fy = 0; fy < 5; fy++ )); do
+				if [[ ( $x == $fx ) && ( $y == $fy ) ]]; then continue; fi
+				LOGFILE=$LOGDIR/$(echo log'_'$x'_'$y'_'$fx'_'$fy);
+				ARGS="$COMMON -SX $x -SY $y -FX $fx -FY $fy";
+				echo "./simul.x $ARGS ($LOGFILE)"
+				./simul.x $ARGS > $LOGFILE 2>/dev/null;
+				./check_broadcast.sh $LOGFILE
+				if [[ $? == 1 ]]; then
+					echo "FAILURE";
+					exit 1;
+				fi
+			done
+		done
+	done
+done
Index: /branches/reconfiguration/modules/dspin_router/caba/test/synthetic_test/soclib.conf
===================================================================
--- /branches/reconfiguration/modules/dspin_router/caba/test/synthetic_test/soclib.conf	(revision 994)
+++ /branches/reconfiguration/modules/dspin_router/caba/test/synthetic_test/soclib.conf	(revision 994)
@@ -0,0 +1,12 @@
+# append compilation flags
+cflags = config.default.toolchain.cflags
+# cflags.extend(['-ggdb'])
+config.default.toolchain.set("cflags", cflags)
+
+# append modules' description file paths
+from os import environ
+from os.path import join
+tsarpath = environ['TSARPATH']
+config.addDescPath(join(tsarpath, "trunk/lib"))
+config.addDescPath(join(tsarpath, "branches/reconfiguration/communication"))
+config.addDescPath(join(tsarpath, "branches/reconfiguration/modules"))
Index: /branches/reconfiguration/modules/dspin_router/caba/test/synthetic_test/top.cpp
===================================================================
--- /branches/reconfiguration/modules/dspin_router/caba/test/synthetic_test/top.cpp	(revision 994)
+++ /branches/reconfiguration/modules/dspin_router/caba/test/synthetic_test/top.cpp	(revision 994)
@@ -0,0 +1,313 @@
+/**
+ * @author  Cesar Armando Fuguet Tortolero
+ * @date    24 May, 2015
+ * @brief   This platform allows the validation of the reconfigurable routing
+ *          algorithm on the DSPIN router component. The platform has been
+ *          specifically designed to test the routing of broadcast packets.
+ */
+#include <iostream>
+#include <systemc>
+#include <cassert>
+
+#include "dspin_router.h"
+#include "dspin_router_config.h"
+#include "dspin_packet_generator.h"
+#include "alloc_elems.h"
+
+#if _OPENMP
+#include <omp.h>
+#endif
+
+/*
+ * Platform constant parameters
+ */
+#define X_WIDTH 4
+#define Y_WIDTH 4
+
+#define FIFO_DEPTH 8
+#define NFLITS 2
+#define LOAD 1000
+#define BROADCAST_PERIOD 3
+#define DSPIN_WIDTH 39
+
+/*
+ * Platform default values
+ */
+#define X_SIZE 4
+#define Y_SIZE 4
+
+static inline int cluster(int x, int y)
+{
+    return (x << Y_WIDTH) | y;
+}
+
+static inline uint32_t configRouter(int bypass_mode,
+                                    int reallocation_dir,
+                                    int blackhole_pos)
+{
+    return (bypass_mode << 7) | (reallocation_dir << 4) | blackhole_pos;
+}
+
+int sc_main(int argc, char **argv)
+{
+    using namespace soclib::caba;
+    using namespace soclib::common;
+
+    typedef DspinPacketGenerator<DSPIN_WIDTH, DSPIN_WIDTH>
+        DspinGeneratorType;
+    typedef DspinRouter<DSPIN_WIDTH>
+        DspinRouterType;
+    typedef DspinSignals<DSPIN_WIDTH>
+        DspinSignalType;
+
+#if _OPENMP
+    omp_set_dynamic(false);
+    omp_set_num_threads(1);
+#endif
+
+    /* mesh size */
+    int xSize = X_SIZE;
+    int ySize = Y_SIZE;
+
+    /* (x,y) coordinates of the initiator router */
+    int xSrc = -1;
+    int ySrc = -1;
+
+    /* (x,y) coordinates of the faulty router */
+    int xFaulty = -1;
+    int yFaulty = -1;
+
+    /* enable the DSPIN router's debug */
+    int debug = false;
+
+    /* number of simulation cycles */
+    int simCycles = 100000;
+    for (int n = 1; n < argc; n = n + 2) {
+        if ((strcmp(argv[n], "-X") == 0) && ((n + 1) < argc)) {
+            xSize = strtol(argv[n + 1], NULL, 0);
+            continue;
+        }
+        if ((strcmp(argv[n], "-Y") == 0) && ((n + 1) < argc) ) {
+            ySize = strtol(argv[n + 1], NULL, 0);
+            continue;
+        }
+        if ((strcmp(argv[n], "-FX") == 0) && ((n + 1) < argc)) {
+            xFaulty = strtol(argv[n + 1], NULL, 0);
+            continue;
+        }
+        if ((strcmp(argv[n], "-FY") == 0) && ((n + 1) < argc) ) {
+            yFaulty = strtol(argv[n + 1], NULL, 0);
+            continue;
+        }
+        if ((strcmp(argv[n], "-SX") == 0) && ((n + 1) < argc)) {
+            xSrc = strtol(argv[n + 1], NULL, 0);
+            continue;
+        }
+        if ((strcmp(argv[n], "-SY") == 0) && ((n + 1) < argc) ) {
+            ySrc = strtol(argv[n + 1], NULL, 0);
+            continue;
+        }
+        if ((strcmp(argv[n], "-N") == 0) && ((n + 1) < argc) ) {
+            simCycles = strtol(argv[n + 1], NULL, 0);
+            assert(simCycles > 0);
+            continue;
+        }
+        if ((strcmp(argv[n], "-DEBUG") == 0)) {
+            debug = true;
+            continue;
+        }
+    }
+
+    assert (xFaulty < xSize );
+    assert (yFaulty < ySize );
+    assert (xSrc < xSize );
+    assert (ySrc < ySize );
+
+    DspinGeneratorType ***dspinGenerator = new DspinGeneratorType**[xSize];
+    DspinRouterType ***dspinRouter = new DspinRouterType**[xSize];
+    for (int x = 0; x < xSize; ++x) {
+        dspinGenerator[x] = new DspinGeneratorType*[ySize];
+        dspinRouter[x] = new DspinRouterType*[ySize];
+        for (int y = 0; y < ySize; ++y) {
+            const bool BROADCAST_SUPPORTED = true;
+            const bool CONFIGURATION_SUPPORTED = true;
+            std::ostringstream routerStr;
+            routerStr << "dspinRouter["<< x << "][" << y << "]";
+            dspinRouter[x][y] =
+                new DspinRouterType(routerStr.str().c_str(), x, y,
+                                    X_WIDTH, Y_WIDTH,
+                                    FIFO_DEPTH, FIFO_DEPTH,
+                                    BROADCAST_SUPPORTED,
+                                    CONFIGURATION_SUPPORTED);
+
+            if ((x == xFaulty) && (y == yFaulty)) {
+                dspinRouter[x][y]->set_disable_mask(0x1F);
+            }
+
+            int broadcast_period = 0;
+            int load = 0;
+            const int SRCID = cluster(x,y);
+            bool all = (xSrc == -1) && (ySrc == -1);
+            if (all || (cluster(x,y) == cluster(xSrc,ySrc))) {
+               broadcast_period = BROADCAST_PERIOD;
+               load = LOAD;
+            }
+            std::ostringstream generatorStr;
+            generatorStr << "dspinGenerator["<< x << "][" << y << "]";
+            dspinGenerator[x][y] =
+                new DspinGeneratorType(generatorStr.str().c_str(),
+                                       SRCID, NFLITS,
+                                       load, FIFO_DEPTH,
+                                       broadcast_period);
+        }
+    }
+
+    const int H = xSize - 1;
+    const int Y = ySize - 1;
+    sc_clock signal_clk("clk");
+    sc_core::sc_signal<bool> signal_resetn("signal_resetn");
+    DspinSignalType*** sDspinL =
+        alloc_elems<DspinSignalType>("sDspinL", xSize, ySize, 2);
+    DspinSignalType*** sDspinH =
+        alloc_elems<DspinSignalType>("sDspinH", H + 2, ySize, 2);
+    DspinSignalType*** sDspinV =
+        alloc_elems<DspinSignalType>("sDspinV", xSize, Y + 2, 2);
+    sc_signal<uint32_t> sConfigNONE("sConfigNONE");
+    sc_signal<uint32_t> sConfigN("sConfigN");
+    sc_signal<uint32_t> sConfigNW("sConfigNW");
+    sc_signal<uint32_t> sConfigNE("sConfigNE");
+    sc_signal<uint32_t> sConfigS("sConfigS");
+    sc_signal<uint32_t> sConfigSW("sConfigSW");
+    sc_signal<uint32_t> sConfigSE("sConfigSE");
+    sc_signal<uint32_t> sConfigW("sConfigW");
+    sc_signal<uint32_t> sConfigE("sConfigE");
+    for (int x = 0; x < xSize; ++x) {
+        for (int y = 0; y < ySize; ++y) {
+            dspinGenerator[x][y]->p_clk(signal_clk);
+            dspinGenerator[x][y]->p_resetn(signal_resetn);
+            dspinGenerator[x][y]->p_out(sDspinL[x][y][0]);
+            dspinGenerator[x][y]->p_in(sDspinL[x][y][1]);
+
+            dspinRouter[x][y]->p_clk(signal_clk);
+            dspinRouter[x][y]->p_resetn(signal_resetn);
+            dspinRouter[x][y]->p_in[0](sDspinV[x][y + 1][1]);
+            dspinRouter[x][y]->p_out[0](sDspinV[x][y + 1][0]);
+            dspinRouter[x][y]->p_in[1](sDspinV[x][y][0]);
+            dspinRouter[x][y]->p_out[1](sDspinV[x][y][1]);
+            dspinRouter[x][y]->p_in[2](sDspinH[x + 1][y][1]);
+            dspinRouter[x][y]->p_out[2](sDspinH[x + 1][y][0]);
+            dspinRouter[x][y]->p_in[3](sDspinH[x][y][0]);
+            dspinRouter[x][y]->p_out[3](sDspinH[x][y][1]);
+            dspinRouter[x][y]->p_in[4](sDspinL[x][y][0]);
+            dspinRouter[x][y]->p_out[4](sDspinL[x][y][1]);
+
+            if (x == (xFaulty + 1)) {
+                if (y == (yFaulty + 1)) {
+                    dspinRouter[x][y]->bind_recovery_port(sConfigNE);
+                    std::cout << "config NE" << std::endl;
+                    continue;
+                }
+                if (y == yFaulty) {
+                    dspinRouter[x][y]->bind_recovery_port(sConfigE);
+                    std::cout << "config E" << std::endl;
+                    continue;
+                }
+                if (y == (yFaulty - 1)) {
+                    dspinRouter[x][y]->bind_recovery_port(sConfigSE);
+                    std::cout << "config SE" << std::endl;
+                    continue;
+                }
+            }
+            if (x == xFaulty) {
+                if (y == (yFaulty + 1)) {
+                    dspinRouter[x][y]->bind_recovery_port(sConfigN);
+                    std::cout << "config N" << std::endl;
+                    continue;
+                }
+                if (y == (yFaulty - 1)) {
+                    dspinRouter[x][y]->bind_recovery_port(sConfigS);
+                    std::cout << "config S" << std::endl;
+                    continue;
+                }
+            }
+            if (x == (xFaulty - 1)) {
+                if (y == (yFaulty + 1)) {
+                    dspinRouter[x][y]->bind_recovery_port(sConfigNW);
+                    std::cout << "config NW" << std::endl;
+                    continue;
+                }
+                if (y == yFaulty) {
+                    dspinRouter[x][y]->bind_recovery_port(sConfigW);
+                    std::cout << "config W" << std::endl;
+                    continue;
+                }
+                if (y == (yFaulty - 1)) {
+                    dspinRouter[x][y]->bind_recovery_port(sConfigSW);
+                    std::cout << "config SW" << std::endl;
+                    continue;
+                }
+            }
+            dspinRouter[x][y]->bind_recovery_port(sConfigNONE);
+        }
+    }
+
+    sc_start(sc_core::SC_ZERO_TIME);
+    signal_resetn = 0;
+
+    /* initialize the configuration signals */
+    sConfigNONE.write(configRouter(0, REQ_NOP, BH_NONE));
+    sConfigN.write(configRouter(1, REQ_SOUTH, BH_N));
+    sConfigNE.write(configRouter(1, REQ_WEST, BH_NE));
+    sConfigE.write(configRouter(1, REQ_WEST, BH_E));
+    sConfigSE.write(configRouter(1, REQ_WEST, BH_SE));
+    sConfigS.write(configRouter(1, REQ_NORTH, BH_S));
+    sConfigSW.write(configRouter(1, REQ_EAST, BH_SW));
+    sConfigW.write(configRouter(1, REQ_EAST, BH_W));
+    sConfigNW.write(configRouter(1, REQ_EAST, BH_NW));
+
+    /* initialize mesh boundary signals */
+    for (int x = 0; x < xSize; ++x) {
+        sDspinV[x][0][0].write = false;
+        sDspinV[x][0][1].read = true;
+        sDspinV[x][ySize][0].read = true;
+        sDspinV[x][ySize][1].write = false;
+    }
+    for (int y = 0; y < ySize; ++y) {
+        sDspinH[0][y][0].write = false;
+        sDspinH[0][y][1].read = true;
+        sDspinH[xSize][y][0].read = true;
+        sDspinH[xSize][y][1].write = false;
+    }
+
+    sc_start(sc_core::sc_time(5, SC_NS));
+    signal_resetn = 1;
+
+    for(int i = 0; i < simCycles; ++i) {
+        if (!debug) {
+            sc_start(sc_core::sc_time(simCycles, SC_NS));
+            break;
+        }
+        std::cout << std::endl;
+        std::cout << "##########################################" << std::endl;
+        std::cout << "Simulation cycle " << i << std::endl;
+        std::cout << "##########################################" << std::endl;
+        std::cout << std::endl;
+        sc_start(sc_core::sc_time(1, SC_NS));
+        for (int x = 0; x < xSize; ++x) {
+            for (int y = 0; y < ySize; ++y) {
+                dspinRouter[x][y]->print_trace();
+            }
+        }
+    }
+    for (int x = 0; x < xSize; ++x) {
+        for (int y = 0; y < ySize; ++y) {
+            dspinGenerator[x][y]->print_stats();
+        }
+    }
+
+    return 0;
+}
+
+/*
+ * vim: ts=4 : sw=4 : sts=4 : et
+ */
Index: /branches/reconfiguration/modules/dspin_router/caba/test/synthetic_test/top.desc
===================================================================
--- /branches/reconfiguration/modules/dspin_router/caba/test/synthetic_test/top.desc	(revision 994)
+++ /branches/reconfiguration/modules/dspin_router/caba/test/synthetic_test/top.desc	(revision 994)
@@ -0,0 +1,16 @@
+# -*- python -*-
+
+# DSPIN network parameters
+dspin_size = 39
+
+todo = Platform(
+    'caba', 'top.cpp',
+    uses = [
+        Uses('caba:reconf:dspin_router',
+			 flit_width=dspin_size),
+
+        Uses('caba:dspin_packet_generator',
+             cmd_width=dspin_size,
+             rsp_width=dspin_size)
+    ])
+
