Index: trunk/modules/vci_io_bridge/caba/metadata/vci_io_bridge.sd
===================================================================
--- trunk/modules/vci_io_bridge/caba/metadata/vci_io_bridge.sd	(revision 240)
+++ trunk/modules/vci_io_bridge/caba/metadata/vci_io_bridge.sd	(revision 240)
@@ -0,0 +1,98 @@
+
+# -*- python -*-
+
+__id__ = "$Id: vci_io_bridge.sd 20 2012-6-11 $"
+
+Module('caba:vci_io_bridge',
+	classname = 'soclib::caba::VciIoBridge',
+	tmpl_parameters = [ 
+        parameter.Module('vci_param_d', default = 'caba:vci_param',
+                            cell_size   = parameter.Reference("cell_size_d"),
+                            plen_size   = parameter.Reference("plen_size_d"),
+                            addr_size   = parameter.Reference("addr_size_d"),
+                            rerror_size = parameter.Reference("rerror_size_d"),
+                            clen_size   = parameter.Reference("clen_size_d"),  
+                            rflag_size  = parameter.Reference("rflag_size_d"), 
+                            srcid_size  = parameter.Reference("srcid_size_d"),
+                            pktid_size  = parameter.Reference("pktid_size_d"),
+                            trdid_size  = parameter.Reference("trdid_size_d"),
+                            wrplen_size = parameter.Reference("wrplen_size_d")),
+	    parameter.Module('vci_param_x', default = 'caba:vci_param',
+                            cell_size   = parameter.Reference("cell_size_x"),
+                            plen_size   = parameter.Reference("plen_size_x"),
+                            addr_size   = parameter.Reference("addr_size_x"),
+                            rerror_size = parameter.Reference("rerror_size_x"),
+                            clen_size   = parameter.Reference("clen_size_x"),  
+                            rflag_size  = parameter.Reference("rflag_size_x"), 
+                            srcid_size  = parameter.Reference("srcid_size_x"),
+                            pktid_size  = parameter.Reference("pktid_size_x"),
+                            trdid_size  = parameter.Reference("trdid_size_x"),
+                            wrplen_size = parameter.Reference("wrplen_size_x")),
+        parameter.Module('vci_param_io', default = 'caba:vci_param', 
+                            cell_size   = parameter.Reference("cell_size_io"),
+                            plen_size   = parameter.Reference("plen_size_io"),
+                            addr_size   = parameter.Reference("addr_size_io"),
+                            rerror_size = parameter.Reference("rerror_size_io"),
+                            clen_size   = parameter.Reference("clen_size_io"),  
+                            rflag_size  = parameter.Reference("rflag_size_io"), 
+                            srcid_size  = parameter.Reference("srcid_size_io"),
+                            pktid_size  = parameter.Reference("pktid_size_io"),
+                            trdid_size  = parameter.Reference("trdid_size_io"),
+                            wrplen_size = parameter.Reference("wrplen_size_io")),
+    ],
+	header_files =         [ '../source/include/vci_io_bridge.h',
+	                         '../source/include/transaction_tab_io.h'],
+	implementation_files = [ '../source/src/vci_io_bridge.cpp' ],
+	uses = [ Uses('caba:base_module'),
+	         Uses('common:mapping_table'),
+	         Uses('caba:generic_fifo'),
+	         Uses('caba:generic_tlb', 
+                       addr_t = parameter.StringExt('sc_dt::sc_uint<%d> ', 
+                       parameter.Reference('addr_size'))),
+ 	         Uses('common:address_decoding_table', 
+                       input_t  = 'unsigned long',
+                       output_t = 'bool'),
+ 	         Uses('common:address_decoding_table', 
+                       input_t  = 'unsigned long',
+                       output_t = 'int'),
+#	         Uses('common:address_masking_table', 
+#                       data_t = parameter.StringExt('sc_dt::sc_uint<%d> ', 
+#                       parameter.Reference('addr_size'))),
+           ],
+	ports = [ Port('caba:vci_initiator', 'p_vci_ini_dma'),
+	          Port('caba:vci_target', 'p_vci_tgt_dma'),
+              Port('caba:vci_initiator', 'p_vci_ini_config'),
+	          Port('caba:vci_target', 'p_vci_tgt_config'),
+              Port('caba:vci_initiator', 'p_vci_ini_miss'),
+	          Port('caba:bit_in','p_irq', parameter.Reference('nb_periph')),
+	          Port('caba:bit_in', 'p_resetn', auto = 'resetn'),
+	          Port('caba:clock_in', 'p_clk', auto = 'clock'), ],
+	instance_parameters = [ parameter.Int('nd_periph'),
+	                        parameter.Module('mtx', 'common:mapping_table'),
+	                        parameter.Module('mtd', 'common:mapping_table'),
+	                        parameter.Module('mtio', 'common:mapping_table'),
+	                        parameter.Module('seg_config_iob', 'common:segment'), 
+                            parameter.IntTab('tgt_index_iocluster'),
+#	                        parameter.IntTab('tgt_index_config'),
+	                        parameter.IntTab('init_index_direct'),
+	                        parameter.IntTab('tgt_index_iospace'),
+	                        parameter.IntTab('init_index_iospace'),
+	                        parameter.IntTab('init_index_dma'),
+    	                        parameter.Int('dcache_words'),
+    	                        parameter.Int('iotlb_ways'),
+    	                        parameter.Int('iotlb_sets'),
+    	                        parameter.Int('max_frozen_cycles'), ],
+	extensions = [ 'dsx:get_ident='
+                       'tgt_index_config:p_vci_tgt_config:mtd,'
+                       'init_index_direct:p_vci_init_miss:mtd,'
+                       'tgt_index_iospace:p_vci_tgt_dma:mtio,'
+                       'init_index_iospace:p_vci_init_config:mtio,'
+                       'init_index_dma:p_vci_ini_dma:mtx,'
+	               'dsx:cpu=wrapper:iss_t',
+	               'dsx:addressable=tgt_index_config,tgt_index_iospace',
+#                       'dsx:on_segment=mc:add_index:initiator_rw_index',
+	               ],
+
+#       debug = True,
+)
+
Index: trunk/modules/vci_io_bridge/caba/source/include/transaction_tab_io.h
===================================================================
--- trunk/modules/vci_io_bridge/caba/source/include/transaction_tab_io.h	(revision 240)
+++ trunk/modules/vci_io_bridge/caba/source/include/transaction_tab_io.h	(revision 240)
@@ -0,0 +1,230 @@
+#ifndef IOB_TRANSACTION_H_
+#define IOB_TRANSACTION_H_
+ 
+#include <inttypes.h>
+#include <systemc>
+#include <cassert>
+#include "arithmetics.h"
+
+#define DEBUG_IOB_TRANSACTION 0
+
+// The index of Transaction Tab Entry corresponds to the trdid of the VCI packet on XRAM network
+
+////////////////////////////////////////////////////////////////////////
+//                  A transaction tab entry         
+////////////////////////////////////////////////////////////////////////
+
+class TransactionTabIOEntry {
+  typedef uint32_t              size_t;
+
+ public:
+  bool 		            valid;     	    // entry valid 
+  size_t 	            srcid;     	    // processor requesting the transaction
+  size_t 	            trdid;     	    // processor requesting the transaction
+
+  /////////////////////////////////////////////////////////////////////
+  // The init() function initializes the entry 
+  /////////////////////////////////////////////////////////////////////
+  void init()
+  {
+    valid		= false;
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // The copy() function copies an existing entry
+  // Its arguments are :
+  // - source : the transaction tab entry to copy
+  ////////////////////////////////////////////////////////////////////
+  void copy(const TransactionTabIOEntry &source)
+  {
+    valid	    = source.valid;
+    srcid	    = source.srcid;
+    trdid	    = source.trdid;
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // The print() function prints the entry 
+  ////////////////////////////////////////////////////////////////////
+  void print(){
+    std::cout << "valid       = " << valid        << std::endl;
+    std::cout << "srcid       = " << srcid        << std::endl;
+    std::cout << "trdid       = " << trdid        << std::endl;
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // 		Constructors
+  /////////////////////////////////////////////////////////////////////
+
+  TransactionTabIOEntry()
+    {
+      valid=false;
+    }
+
+  TransactionTabIOEntry(const TransactionTabIOEntry &source){
+    valid	    = source.valid;
+    srcid	    = source.srcid;
+    trdid	    = source.trdid;
+  }
+
+}; // end class TransactionTabIOEntry
+
+////////////////////////////////////////////////////////////////////////
+//                  The transaction tab                              
+////////////////////////////////////////////////////////////////////////
+class TransactionTabIO{
+//  typedef uint32_t size_t;
+
+ private:
+  size_t size_tab;                // The size of the tab
+
+ public:
+  TransactionTabIOEntry *tab;       // The transaction tab
+
+  ////////////////////////////////////////////////////////////////////
+  //		Constructors
+  ////////////////////////////////////////////////////////////////////
+  TransactionTabIO()
+    {
+      size_tab=0;
+      tab=NULL;
+    }
+
+  TransactionTabIO(size_t n_entries)
+    {
+      size_tab = n_entries;
+      tab = new TransactionTabIOEntry[size_tab];
+    }
+
+  ~TransactionTabIO()
+    {
+      delete [] tab;
+    }
+
+  /////////////////////////////////////////////////////////////////////
+  // The size() function returns the size of the tab
+  /////////////////////////////////////////////////////////////////////
+  size_t size()
+  {
+    return size_tab;
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The init() function initializes the transaction tab entries
+  /////////////////////////////////////////////////////////////////////
+  void init()
+  {
+    for ( size_t i=0; i<size_tab; i++) {
+      tab[i].init();
+    }
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The print() function prints a transaction tab entry
+  // Arguments :
+  // - index : the index of the entry to print
+  /////////////////////////////////////////////////////////////////////
+  void print(const size_t index)
+  {
+    assert( (index < size_tab) 
+	    && "Invalid Transaction Tab Entry");
+    tab[index].print();
+    return;
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The read() function returns a transaction tab entry.
+  // Arguments :
+  // - index : the index of the entry to read
+  /////////////////////////////////////////////////////////////////////
+  TransactionTabIOEntry read(const size_t index)
+  {
+    assert( (index < size_tab) 
+	    && "Invalid Transaction Tab Entry");
+    return tab[index];
+  }
+  
+  /////////////////////////////////////////////////////////////////////
+  // The readSrcid() function returns the srcid field of a transaction tab entry.
+  // Arguments :
+  // - index : the index of the entry to read
+  /////////////////////////////////////////////////////////////////////
+  size_t readSrcid(const size_t index)
+  {
+    assert( (index < size_tab) 
+	    && "Invalid Transaction Tab Entry");
+    return tab[index].srcid;
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The readTrdid() function returns the trdid field of a transaction tab entry.
+  // Arguments :
+  // - index : the index of the entry to read
+  /////////////////////////////////////////////////////////////////////
+  size_t readTrdid(const size_t index)
+  {
+    assert( (index < size_tab) 
+	    && "Invalid Transaction Tab Entry");
+    return tab[index].trdid;
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The full() function returns the state of the transaction tab
+  // Arguments :
+  // - index : (return argument) the index of an empty entry 
+  // The function returns true if the transaction tab is full
+  /////////////////////////////////////////////////////////////////////
+  bool full(size_t &index)
+  {
+    for(size_t i=0; i<size_tab; i++){
+      if(!tab[i].valid){
+	    index=i;
+	    return false;	
+      }
+    }
+    return true;
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The set() function registers a transaction (read or write)
+  // to the XRAM in the transaction tab.
+  // Arguments :
+  // - index : index in the transaction tab
+  // - srcid : srcid of the initiator that caused the transaction
+  // - trdid : trdid of the initiator that caused the transaction
+  /////////////////////////////////////////////////////////////////////
+  void set(const size_t index,
+	   const size_t srcid,
+	   const size_t trdid) 
+  {
+    assert( (index < size_tab) 
+	    && "The selected entry is out of range in set() Transaction Tab");
+
+    tab[index].valid	        = true;
+    tab[index].srcid	        = srcid;
+    tab[index].trdid	        = trdid;
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The erase() function erases an entry in the transaction tab.
+  // Arguments :
+  // - index : the index of the request in the transaction tab
+  /////////////////////////////////////////////////////////////////////
+  void erase(const size_t index)
+  {
+    assert( (index < size_tab) 
+	    && "The selected entry is out of range in erase() Transaction Tab");
+    tab[index].valid	= false;
+  }
+}; // end class TransactionTabIO
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: trunk/modules/vci_io_bridge/caba/source/include/vci_io_bridge.h
===================================================================
--- trunk/modules/vci_io_bridge/caba/source/include/vci_io_bridge.h	(revision 240)
+++ trunk/modules/vci_io_bridge/caba/source/include/vci_io_bridge.h	(revision 240)
@@ -0,0 +1,622 @@
+/* -*- c++ -*-
+ * File : vci_io_bridge.h
+ * Copyright (c) UPMC, Lip6, SoC
+ * Date : 16/04/2012
+ *
+ * SOCLIB_LGPL_HEADER_BEGIN
+ * 
+ * This file is part of SoCLib, GNU LGPLv2.1.
+ * 
+ * SoCLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 of the License.
+ * 
+ * SoCLib is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with SoCLib; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ * 
+ * SOCLIB_LGPL_HEADER_END
+ */
+
+//////Utilisation Considerations////////////////////////////////////////////////
+//
+// - IOMMU PTPR pointer must fit in 32 bits (with a classical 2 level 4K page
+//   table in a 32 bit virtual space, it means a maximum of 45 bits in physical
+//   address)
+//
+// - Physical address must fit in two 32 bit words
+//
+// - Maximal number of flits in a write transaction cannot be bigger than (nÂ° of
+//   words in a chache line)/2
+//
+// - Page Tables must have the format used in TSAR (compatible with component
+//   generic_tlb)
+//
+// - IO's segment size must be the same in both networks
+//
+// - Write operations on IOMMU configuration registers (PTPR, ACTIVE) can only
+//   be done when DMA_TLB FSM is IDLE. It should, preferably, be done before
+//   starting any transfers. Pseudo register INVAL may be modified any time.
+//
+// - Similarly, write operations on the interruptions registers can only be done
+//   when the dedicated FSM is IDLE.                
+////////////////////////////////////////////////////////////////////////////////
+
+ 
+///////TODO List///////////////////////////////////////////////////////////////
+//
+// Tableau de correspondance d'adresses physique - IO (pour CONFIG_CMD)
+//
+// Conversion 32 (entree) Ã  64 (sortie) bits (champ data). Dans les deux senses (CMD et RSP)
+// 
+// Ne pas garder tous les champs WRITE CMD dans les FIFO a chaque flit
+// (seulement 'data' et 'be')
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef SOCLIB_CABA_VCI_IO_BRIDGE_H
+#define SOCLIB_CABA_VCI_IO_BRIDGE_H
+
+#include <inttypes.h>
+#include <systemc>
+#include "caba_base_module.h"
+#include "generic_fifo.h"
+#include "generic_tlb.h"
+#include "mapping_table.h"
+#include "address_decoding_table.h" 
+#include "static_assert.h"
+#include "transaction_tab_io.h"
+#include "vci_initiator.h"
+#include "vci_target.h"
+
+namespace soclib {
+namespace caba {
+
+using namespace soclib::common;
+
+////////////////////////////////////////////
+template<typename vci_param_d,typename vci_param_x, typename vci_param_io >
+class VciIoBridge
+////////////////////////////////////////////
+    : public soclib::caba::BaseModule
+{
+    typedef uint32_t tag_t;
+    typedef uint32_t type_t;
+    
+    // Address field may change between direct, extenal and IO network 
+    typedef typename vci_param_d::addr_t        paddr_t; 
+    typedef typename vci_param_x::addr_t        paddr_t_x; // Just the cache line, for example
+    typedef typename vci_param_io::addr_t       vaddr_t;
+    
+    // Data field may change for external network 
+    typedef typename vci_param_x::data_t      vci_data_t_x;
+    // Srcid field may change for external network 
+    typedef typename vci_param_x::srcid_t     vci_srcid_t_x;
+    
+    // Other fields must coincide   
+    typedef typename vci_param_d::srcid_t     vci_srcid_t;  
+    typedef typename vci_param_d::data_t      vci_data_t;   
+    typedef typename vci_param_d::be_t        vci_be_t;
+    typedef typename vci_param_d::trdid_t     vci_trdid_t;
+    typedef typename vci_param_d::pktid_t     vci_pktid_t;
+    typedef typename vci_param_d::plen_t      vci_plen_t;
+    typedef typename vci_param_d::cmd_t       vci_cmd_t;
+    typedef typename vci_param_d::contig_t    vci_contig_t;
+    typedef typename vci_param_d::eop_t       vci_eop_t;
+    typedef typename vci_param_d::const_t     vci_cons_t;
+    typedef typename vci_param_d::wrap_t      vci_wrap_t;
+    typedef typename vci_param_d::clen_t      vci_clen_t;
+    typedef typename vci_param_d::cfixed_t    vci_cfixed_t;
+
+    typedef typename vci_param_d::rerror_t    vci_rerror_t;
+
+    enum {
+        CACHE_LINE_MASK = 0xFFFFFFFFC0,  
+        PPN1_MASK = 0x0007FFFF,  
+        PPN2_MASK = 0x0FFFFFFF,  
+        K_PAGE_OFFSET_MASK = 0x00000FFF,  
+        M_PAGE_OFFSET_MASK = 0x001FFFFF,
+        PTE2_LINE_OFFSET   = 0x00007000, // bits 12,13,14.
+        PTE1_LINE_OFFSET   = 0x01E00000, // bits 21,22,23,24 
+    };
+ 
+    //DMA (from Peripherals to XRAM)
+    enum dma_cmd_fsm_state {  
+        DMA_CMD_IDLE,
+        DMA_CMD_TRT_LOCK,
+        DMA_CMD_TRT_WAIT,
+        DMA_CMD_TRT_SET,
+        DMA_CMD_FIFO_PUT,
+        DMA_CMD_FIFO_MISS_PUT,
+        DMA_CMD_TLB_MISS_WAIT,
+        DMA_CMD_TLB_MISS_STORE,
+        DMA_CMD_ERROR,
+    };
+   
+    enum dma_rsp_fsm_state {  
+        DMA_RSP_IDLE,
+        DMA_RSP_TRT_LOCK,
+        DMA_RSP_FIFO_PUT, 
+        DMA_RSP_FIFO_ERROR_PUT,
+    };
+    
+    // Allocates the transaction_tab_dma
+    enum alloc_trt_dma_fsm_state {
+        ALLOC_TRT_DMA_CMD,
+        ALLOC_TRT_DMA_RSP
+    };
+     
+
+    enum dma_tlb_fsm_state {   
+        DMA_TLB_IDLE,
+        DMA_TLB_MISS,
+        DMA_TLB_PTE1_GET,
+        DMA_TLB_PTE1_SELECT,
+        DMA_TLB_PTE1_UPDT,
+        DMA_TLB_PTE2_GET,                                                  
+        DMA_TLB_PTE2_SELECT,
+        DMA_TLB_PTE2_UPDT,
+        DMA_TLB_WAIT_TRANSACTION,
+        DMA_TLB_RETURN,
+        // Treatment of CONFIG FSM request
+        DMA_TLB_INVAL_CHECK,
+        DMA_TLB_INVAL_SCAN
+	};
+    
+    //CONFIG (from Direct Network to Peripherals)
+    enum config_cmd_fsm_state {  
+        CONFIG_CMD_IDLE,
+        CONFIG_CMD_TRT_LOCK,
+        CONFIG_CMD_TRT_WAIT,
+        CONFIG_CMD_TRT_SET,
+        CONFIG_CMD_FIFO_PUT,
+        
+        // IOB private configuration segment 
+        CONFIG_CMD_PTPR_WRITE,
+        CONFIG_CMD_PTPR_READ,
+        CONFIG_CMD_ACTIVE_WRITE,
+        CONFIG_CMD_ACTIVE_READ,
+        CONFIG_CMD_BVAR_READ,
+        CONFIG_CMD_ETR_READ,
+        CONFIG_CMD_BAD_ID_READ,
+        CONFIG_CMD_INVAL_REQ,
+        CONFIG_CMD_INVAL,
+        CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1,
+        CONFIG_CMD_IT_ADDR_IOMMU_WRITE_2,
+        CONFIG_CMD_IT_ADDR_IOMMU_READ_1,
+        CONFIG_CMD_IT_ADDR_IOMMU_READ_2,
+        CONFIG_CMD_IT_ADDR_WRITE_1,
+        CONFIG_CMD_IT_ADDR_WRITE_2,
+        CONFIG_CMD_IT_ADDR_READ_1,
+        CONFIG_CMD_IT_ADDR_READ_2,
+        CONFIG_CMD_ERROR_WAIT,
+        CONFIG_CMD_ERROR_RSP
+	};
+    
+    enum config_rsp_fsm_state {  
+        CONFIG_RSP_IDLE,
+        CONFIG_RSP_TRT_LOCK,
+        CONFIG_RSP_FIFO_PUT 
+    };
+    
+    // Allocates the transaction_tab_dma
+    enum alloc_trt_config_fsm_state {
+        ALLOC_TRT_CONFIG_CMD,
+        ALLOC_TRT_CONFIG_RSP
+	};
+    
+    //MISS TRANSACTIONS (to Direct Network)
+    enum miss_init_fsm_state {  
+        MISS_INIT_IDLE_MISS,
+        MISS_INIT_IDLE_IRQ,
+        MISS_INIT_IRQ_CMD,
+        MISS_INIT_IRQ_RSP,
+        MISS_INIT_TLB_MISS_CMD,
+        MISS_INIT_TLB_MISS_RSP
+	};
+    
+    /////////////////////////////////////////////////////////////////
+
+    // Configuration Error Type  
+    enum config_error_type {
+        READ_OK     = 0, 
+        READ_ERROR  = 1, 
+        WRITE_OK    = 2,
+        WRITE_ERROR = 3
+	};
+ 
+    // Miss types for iotlb
+    enum tlb_miss_type_e
+    {
+        PTE1_MISS, 
+        PTE2_MISS
+	};
+    
+    // IOB Configuration registers
+    // Required segment size = (8 + 2*nb_periph) words
+    enum {
+        IOB_IOMMU_PTPR = 0,     // R/W  : Page Table Pointer Register
+        IOB_IOMMU_ACTIVE = 1,   // R/W  : IOMMU activated if not 0
+        IOB_IOMMU_BVAR = 2,     // R    : Bad Virtual Address
+        IOB_IOMMU_ETR = 3,      // R    : Error type
+        IOB_IOMMU_BAD_ID = 4,   // R    : Faulty peripheral Index
+        IOB_INVAL_PTE = 5,      //   W  : Invalidate PTE. Virtual Address
+        IOB_IT_ADDR_IOMMU_LO = 6,    // R/W
+        IOB_IT_ADDR_IOMMU_HI = 7,    // R/W
+        IOB_IT_ADDR_BEGIN = 8        // R/W : One register by IO
+                                     // Addressed by two 32-bit words each
+    };
+
+    
+    // Error Type
+    enum mmu_error_type_e 
+    {
+        MMU_NONE                      = 0x0000, // None
+        MMU_WRITE_ACCES_VIOLATION     = 0x0008, // Write access of write access to a non writable page (bit W in flags)
+        MMU_WRITE_PT1_ILLEGAL_ACCESS  = 0x0040, // Write access of Bus Error accessing Table 1       
+        MMU_READ_PT1_UNMAPPED 	      = 0x1001, // Read access of Page fault on Page Table 1  	
+        MMU_READ_PT2_UNMAPPED 	      = 0x1002, // Read access of Page fault on Page Table 2  
+        MMU_READ_PT1_ILLEGAL_ACCESS   = 0x1040, // Read access of Bus Error in Table1 access      
+        MMU_READ_PT2_ILLEGAL_ACCESS   = 0x1080, // Read access of Bus Error in Table2 access 	
+        MMU_READ_DATA_ILLEGAL_ACCESS  = 0x1100, // Read access of Bus Error in cache access 
+    };
+    
+
+public:
+    sc_in<bool>                             p_clk;
+    sc_in<bool>                             p_resetn;
+    sc_in<bool>                             *p_irq_in;      
+    
+    soclib::caba::VciInitiator<vci_param_x>     p_vci_ini_dma; // XRAM Noc
+    soclib::caba::VciTarget<vci_param_io>       p_vci_tgt_dma;
+    
+    soclib::caba::VciInitiator<vci_param_io>    p_vci_ini_config;
+    soclib::caba::VciTarget<vci_param_d>        p_vci_tgt_config;
+    
+    soclib::caba::VciInitiator<vci_param_d>     p_vci_ini_miss;
+
+private:
+    const size_t  	m_words;
+    const size_t    m_nb_periph;
+
+    // STRUCTURAL PARAMETERS
+    // soclib::common::AddressDecodingTable<unsigned long, bool>   m_locality_table_config;
+    // soclib::common::AddressDecodingTable<unsigned long, int>    m_routing_table_config;
+    //const soclib::common::MappingTable&                   m_mtio; 
+    
+    uint32_t                    		m_transaction_tab_dma_lines;
+    TransactionTabIO      		    	m_transaction_tab_dma;	// dma transaction table
+    
+    uint32_t                    		m_transaction_tab_config_lines;
+    TransactionTabIO      		    	m_transaction_tab_config;	// config transaction table
+    
+    // Direct Network
+    const soclib::common::Segment                          	m_segment_config;
+    const vci_srcid_t                                      	m_srcid_miss;
+    // XRAM Network 
+    const vci_srcid_t_x                                   	m_srcid_dma;
+    // IO Network
+    const soclib::common::Segment                          	m_segment_io;
+    const vci_srcid_t                                      	m_srcid_config;
+
+    const size_t  						m_iotlb_ways;
+    const size_t  						m_iotlb_sets;
+    const size_t  						m_paddr_nbits;  
+
+
+    /////////////////////////////////////////////
+    // debug variables (for each FSM)
+    /////////////////////////////////////////////
+    uint32_t                            m_debug_start_cycle;
+    bool                                m_debug_ok;
+    
+    bool                                m_debug_dma_cmd_fsm;
+    bool                                m_debug_dma_rsp_fsm;
+    bool                                m_debug_dma_tlb_fsm;
+    bool                                m_debug_config_cmd_fsm;
+    bool                                m_debug_config_rsp_fsm;
+    bool                                m_debug_miss_init_fsm;
+
+    ///////////////////////////////
+    // MEMORY MAPPED REGISTERS
+    ///////////////////////////////
+    sc_signal<uint32_t>     r_iommu_ptpr;       // page table pointer register
+    sc_signal<bool>         r_iommu_active;         // iotlb mode
+    sc_signal<uint32_t>     r_iommu_bvar;       // iommu bad address
+    sc_signal<uint32_t>     r_iommu_etr;        // iommu error type
+    sc_signal<uint32_t>     r_iommu_bad_id;     // ID of the peripheral that tried bad operation
+    
+    sc_signal<paddr_t>     r_it_addr_iommu;        // iommu error type
+    paddr_t                *r_it_addr;        // iommu error type
+ 
+	///////////////////////////////////
+    // DMA_CMD FSM REGISTERS
+    ///////////////////////////////////
+    sc_signal<int>          r_dma_cmd_fsm;			        // state register
+    sc_signal<int>          r_dma_cmd_fsm_save; //saves current state when miss interruption happens
+    sc_signal<bool>         r_miss_interrupt;
+    
+    sc_signal<int>          r_dma_cmd_count;
+    sc_signal<vci_trdid_t>  r_dma_cmd_trt_index; 
+    sc_signal<paddr_t>      r_dma_paddr;
+    
+    GenericFifo<paddr_t>        m_dma_cmd_addr_fifo;
+    //GenericFifo<size_t>       m_dma_cmd_length_fifo;
+    GenericFifo<vci_srcid_t>    m_dma_cmd_srcid_fifo;
+    GenericFifo<vci_trdid_t>    m_dma_cmd_trdid_fifo;
+    GenericFifo<vci_pktid_t>    m_dma_cmd_pktid_fifo;
+    GenericFifo<vci_be_t>       m_dma_cmd_be_fifo;
+    GenericFifo<vci_cmd_t>      m_dma_cmd_cmd_fifo;
+    GenericFifo<vci_contig_t>   m_dma_cmd_contig_fifo;
+    GenericFifo<vci_data_t>     m_dma_cmd_data_fifo;
+    GenericFifo<vci_eop_t>      m_dma_cmd_eop_fifo;
+    GenericFifo<vci_cons_t>     m_dma_cmd_cons_fifo;
+    GenericFifo<vci_plen_t>     m_dma_cmd_plen_fifo;
+    GenericFifo<vci_wrap_t>     m_dma_cmd_wrap_fifo;
+    GenericFifo<vci_cfixed_t>   m_dma_cmd_cfixed_fifo;
+    GenericFifo<vci_clen_t>     m_dma_cmd_clen_fifo;
+
+    // Command storage registers (in case of miss tlb)
+    sc_signal<paddr_t>              r_miss_paddr; 
+    sc_signal<vci_cmd_t>            r_miss_cmd ;
+    sc_signal<vci_contig_t>         r_miss_contig; 
+    sc_signal<vci_cons_t>           r_miss_cons ;
+    sc_signal<vci_plen_t>           r_miss_plen ;
+    sc_signal<vci_wrap_t>           r_miss_wrap ;
+    sc_signal<vci_cfixed_t>         r_miss_cfixed; 
+    sc_signal<vci_clen_t>           r_miss_clen ;
+    sc_signal<vci_srcid_t>          r_miss_srcid ;
+    sc_signal<vci_trdid_t>          r_miss_trdid ;
+    sc_signal<vci_pktid_t>          r_miss_pktid ;
+    vci_data_t                      *r_miss_data ;  
+    vci_be_t                        *r_miss_be;
+    
+    // Error registers 
+    sc_signal<int>          r_dma_error_type;   
+    sc_signal<vci_trdid_t>  r_dma_error_trdid;  
+    sc_signal<vci_pktid_t>  r_dma_error_pktid;  
+    
+    ///////////////////////////////////
+    // DMA_TLB FSM REGISTERS
+    ///////////////////////////////////
+    sc_signal<int>          r_dma_tlb_fsm;		    // state register 
+    sc_signal<bool>         r_waiting_transaction;  // Flag for returning from
+                                                    // invalidation interruptions
+    sc_signal<int>          r_tlb_miss_type;
+
+    sc_signal<vaddr_t>      r_iotlb_vaddr;	        // virtual address for a tlb miss
+    sc_signal<paddr_t>      r_iotlb_paddr;		    // physical address of pte
+    sc_signal<uint32_t>     r_iotlb_pte_flags;	    // pte1 or first word of pte2
+    sc_signal<uint32_t>     r_iotlb_pte_ppn;	    // second word of pte2
+    sc_signal<size_t>       r_iotlb_way;		    // selected way in tlb    
+    sc_signal<size_t>       r_iotlb_set;		    // selected set in tlb    
+   
+    //////////////////////////////////////////////////////////////////
+    // IOTLB  
+    //////////////////////////////////////////////////////////////////
+    GenericTlb<paddr_t>       	r_iotlb;
+	
+    ///////////////////////////////////
+    // DMA_RSP FSM REGISTERS
+    ///////////////////////////////////
+    sc_signal<int>          r_dma_rsp_fsm;
+
+	sc_signal<vci_trdid_t>	r_dma_rtrdid; 
+	sc_signal<vci_srcid_t>	r_dma_rsrcid;	
+    
+    GenericFifo<vci_data_t>     m_dma_rsp_data_fifo;
+    GenericFifo<vci_srcid_t>    m_dma_rsp_rsrcid_fifo;
+    GenericFifo<vci_trdid_t>    m_dma_rsp_rtrdid_fifo;
+    GenericFifo<vci_pktid_t>    m_dma_rsp_rpktid_fifo;
+    GenericFifo<vci_eop_t>      m_dma_rsp_reop_fifo;
+    GenericFifo<vci_rerror_t>   m_dma_rsp_rerror_fifo;
+	
+    //Communication between DMA_CMD and DMA_RSP
+    sc_signal<bool>     r_dma_cmd_rsp_erase_req;
+	sc_signal<bool>     r_dma_cmd_error_req; 
+    //Communication between DMA_CMD and TLB 
+    sc_signal<bool>     r_dma_tlb_req;
+    sc_signal<bool>     r_tlb_dma_untreated; 
+	sc_signal<bool>     r_dma_tlb_error_req; 
+    sc_signal<int>      r_tlb_error_type;   
+    //Communication betweeen TLB and CONFIG_CMD
+    sc_signal<bool>         r_config_tlb_req;
+    sc_signal<vaddr_t>      r_config_tlb_inval_vaddr;
+    
+    ///////////////////////////////////
+    // ALLOC_TRT_DMA FSM REGISTERS
+    ///////////////////////////////////
+    sc_signal<int>          r_alloc_trt_dma_fsm;			// state register 
+
+
+    ///////////////////////////////////
+    // CONFIG_CMD FSM REGISTERS
+    ///////////////////////////////////
+    sc_signal<int>          r_config_cmd_fsm;		        // state register
+    
+    sc_signal<vci_trdid_t>       r_config_cmd_trt_index; 
+    
+    GenericFifo<paddr_t>        m_config_cmd_addr_fifo;
+    //GenericFifo<size_t>       m_config_cmd_length_fifo;
+    GenericFifo<vci_srcid_t>    m_config_cmd_srcid_fifo;
+    GenericFifo<vci_trdid_t>    m_config_cmd_trdid_fifo;
+    GenericFifo<vci_pktid_t>    m_config_cmd_pktid_fifo;
+    GenericFifo<vci_be_t>       m_config_cmd_be_fifo;
+    GenericFifo<vci_cmd_t>      m_config_cmd_cmd_fifo;
+    GenericFifo<vci_contig_t>   m_config_cmd_contig_fifo;
+    GenericFifo<vci_data_t>     m_config_cmd_data_fifo;
+    GenericFifo<vci_eop_t>      m_config_cmd_eop_fifo;
+    GenericFifo<vci_cons_t>     m_config_cmd_cons_fifo;
+    GenericFifo<vci_plen_t>     m_config_cmd_plen_fifo;
+    GenericFifo<vci_wrap_t>     m_config_cmd_wrap_fifo;
+    GenericFifo<vci_cfixed_t>   m_config_cmd_cfixed_fifo;
+    GenericFifo<vci_clen_t>     m_config_cmd_clen_fifo;
+    
+    
+    // Private configuration registers
+    sc_signal<int>          r_config_error_type; // rerror field
+    sc_signal<vci_data_t>   r_config_first_word;    
+    sc_signal<int>          r_it_index;
+    
+    GenericFifo<vci_data_t>   m_config_local_data_fifo;
+    GenericFifo<vci_srcid_t>  m_config_local_rsrcid_fifo;
+    GenericFifo<vci_trdid_t>  m_config_local_rtrdid_fifo;
+    GenericFifo<vci_pktid_t>  m_config_local_rpktid_fifo;
+    GenericFifo<vci_eop_t>    m_config_local_reop_fifo;
+    GenericFifo<vci_rerror_t> m_config_local_rerror_fifo;
+    sc_signal<vaddr_t>      r_config_vaddr;
+    
+
+    ///////////////////////////////////
+    // CONFIG_RSP FSM REGISTERS
+    ///////////////////////////////////
+    sc_signal<int>          r_config_rsp_fsm;
+
+	sc_signal<vci_trdid_t>	r_config_rtrdid; 
+	sc_signal<vci_srcid_t>	r_config_rsrcid;
+    
+    GenericFifo<vci_data_t>   m_config_rsp_data_fifo;
+    GenericFifo<vci_srcid_t>  m_config_rsp_rsrcid_fifo;
+    GenericFifo<vci_trdid_t>  m_config_rsp_rtrdid_fifo;
+    GenericFifo<vci_pktid_t>  m_config_rsp_rpktid_fifo;
+    GenericFifo<vci_eop_t>    m_config_rsp_reop_fifo;
+    GenericFifo<vci_rerror_t> m_config_rsp_rerror_fifo;
+	
+    // Defines priority between the two response FIFOs (local and remote)
+    sc_signal<bool>         r_config_rsp_fifo_local_priority; 
+                                                            
+    //Communication between CONFIG_CMD and CONFIG_RSP
+    sc_signal<bool>     r_config_cmd_rsp_erase_req; // used to signal an erasing on TRT table
+    
+    ///////////////////////////////////
+    // ALLOC_TRT_CONFIG FSM REGISTERS
+    ///////////////////////////////////
+    sc_signal<int>          r_alloc_trt_config_fsm;			        // state register 
+
+    ///////////////////////////////////
+    // MISS_INIT FSM REGISTERS
+    ///////////////////////////////////
+    sc_signal<int>          r_miss_init_fsm;
+
+	sc_signal<vci_data_t>	r_miss_rdata;
+	sc_signal<vci_pktid_t>	r_miss_rpktid; 
+	sc_signal<vci_trdid_t>	r_miss_rtrdid; 
+	sc_signal<vci_rerror_t>	r_miss_rerror; 
+	sc_signal<vci_eop_t>	r_miss_reop;  
+	//sc_signal<vci_data_t>	r_miss_rsrcid;
+	
+    sc_signal<size_t>	r_miss_rsp_cpt;
+    
+    //IRQ
+	sc_signal<uint32_t>	r_irq_pending;  
+	sc_signal<uint32_t>	r_irq_mask;  
+	sc_signal<uint32_t>	r_irq_chosen;  
+
+
+    //Communication between TLB and MISS_INIT 
+    sc_signal<bool>         r_tlb_miss_init_req;
+    sc_signal<bool>         r_miss_init_error; 
+    
+    ////////////////////////////////////
+    // MISS PREFETCH BUFFER
+    ///////////////////////////////////
+    //DMA_TLB FSM is its owner. 
+    //CONFIG FSM must set a request in order to access the resource (invalidation)
+
+    // Proposition : Buffer with some lines (4, for example). It could be
+    // indexed from the bit 20.
+ 
+    vci_data_t                *r_miss_buf_data;     // cache line data buffer 
+    bool                    r_miss_buf_valid;       // For individual invalidation,
+                                                    // we could rather use the Valid bit at each PTE
+    sc_signal<paddr_t>      r_miss_buf_tag;         // chache line number  
+    sc_signal<paddr_t>      r_miss_buf_vaddr_begin; // Virtual address of the first PTE on the line 
+    
+    bool                    r_miss_buf_first_level; // useful only if using both types of pages
+    
+    ////////////////////////////////
+    // Activity counters
+    ////////////////////////////////
+    
+    uint32_t m_cpt_total_cycles;            // total number of cycles
+    
+    // TLB activity counters
+    uint32_t m_cpt_iotlb_read;              // number of iotlb read
+    uint32_t m_cpt_iotlb_miss;              // number of iotlb miss
+    uint32_t m_cost_iotlb_miss;             // number of blocking cycles (not the treatment cycles itself)
+    uint32_t m_cpt_iotlbmiss_transaction;   // number of iotlb miss transactions to Mem Cache
+    uint32_t m_cost_iotlbmiss_transaction;  // cumulated duration for iotlb miss transactions
+
+    //Transaction Tabs (TRTs) activity counters
+    uint32_t m_cpt_trt_dma_full;            // DMA TRT full when a new command arrives
+    uint32_t m_cpt_trt_dma_full_cost;       // total number of cycles blocked
+    uint32_t m_cpt_trt_config_full;         // Config TRT full when a new command arrives
+    uint32_t m_cpt_trt_config_full_cost;    // total number of cycles blocked
+
+    // FSM activity counters
+    // unused on print_stats
+    uint32_t m_cpt_fsm_dma_cmd          [32]; 
+    uint32_t m_cpt_fsm_dma_rsp          [32]; 
+    uint32_t m_cpt_fsm_dma_tlb          [32]; 
+    uint32_t m_cpt_fsm_alloc_trt_dma    [32]; 
+    uint32_t m_cpt_fsm_config_cmd       [32]; 
+    uint32_t m_cpt_fsm_config_rsp       [32]; 
+    uint32_t m_cpt_fsm_alloc_trt_config [32]; 
+    uint32_t m_cpt_fsm_miss_init        [32];
+ 
+protected:
+    SC_HAS_PROCESS(VciIoBridge);
+
+public:
+    VciIoBridge(
+        sc_module_name insname,
+        size_t nb_periph,                               // maximun is 32
+        const soclib::common::MappingTable  &mtx,       //external network
+        const soclib::common::MappingTable  &mtd,       //direct network
+        const soclib::common::MappingTable  &mtio,      //io network
+        const soclib::common::Segment       &seg_config_iob,
+        const soclib::common::IntTab &tgt_index_iocluster,
+//        const soclib::common::IntTab &tgt_index_config,     // Direct Noc
+        const soclib::common::IntTab &init_index_direct,    // Direct Noc 
+        const soclib::common::IntTab &tgt_index_iospace,    // IO Noc
+        const soclib::common::IntTab &init_index_iospace,   // IO Noc
+        const soclib::common::IntTab &init_index_dma,       // XRAM Noc
+        size_t dcache_words,
+        size_t   iotlb_ways,
+        size_t   iotlb_sets,
+        uint32_t debug_start_cycle,
+        bool     debug_ok);
+
+    ~VciIoBridge();
+
+    void print_stats();
+    void clear_stats();
+    void print_trace(size_t mode = 0);
+    
+
+private:
+    void transition();
+    void genMoore();
+};
+
+}}
+
+#endif /* SOCLIB_CABA_VCI_CC_VCACHE_WRAPPER_V4_H */
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
+
+
+
Index: trunk/modules/vci_io_bridge/caba/source/src/vci_io_bridge.cpp
===================================================================
--- trunk/modules/vci_io_bridge/caba/source/src/vci_io_bridge.cpp	(revision 240)
+++ trunk/modules/vci_io_bridge/caba/source/src/vci_io_bridge.cpp	(revision 240)
@@ -0,0 +1,3320 @@
+/* i*- c++ -*-C
+ * File : vci_io_bridge.cpp
+ * Copyright (c) UPMC, Lip6, SoC
+ *
+ * SOCLIB_LGPL_HEADER_BEGIN
+ * 
+ * This file is part of SoCLib, GNU LGPLv2.1.
+ * 
+ * SoCLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 of the License.
+ * 
+ * SoCLib is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with SoCLib; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ * 
+ * SOCLIB_LGPL_HEADER_END
+ */
+
+#include <cassert>
+#include "arithmetics.h"
+#include "alloc_elems.h"
+#include "../include/vci_io_bridge.h"
+
+//////   debug services   ///////////////////////////////////////////////////////
+// All debug messages are conditionned by two variables:
+// - compile time : DEBUG_*** : defined below
+// - execution time : m_debug_***  : defined by constructor arguments
+//    m_debug_* = (m_debug_ok) and (m_cpt_cycle > m_debug_start_cycle)
+/////////////////////////////////////////////////////////////////////////////////
+
+#define DEBUG_DMA_CMD	    	1
+#define DEBUG_DMA_RSP	    	1
+#define DEBUG_DMA_TLB	    	1
+#define DEBUG_CONFIG_CMD		1
+#define DEBUG_CONFIG_RSP		1
+#define DEBUG_MISS_INIT 		1
+
+#define NEW_XRAM_VCI            0
+    
+#define IOMMU_ID		4097
+
+namespace soclib { 
+namespace caba {
+
+namespace {
+
+//DMA 
+const char *dma_cmd_fsm_state_str[] = {
+        "DMA_CMD_IDLE",
+        "DMA_CMD_TRT_LOCK",
+        "DMA_CMD_TRT_WAIT",
+        "DMA_CMD_TRT_SET",
+        "DMA_CMD_FIFO_PUT",
+        "DMA_CMD_FIFO_MISS_PUT",
+        "DMA_CMD_TLB_MISS_WAIT",
+        "DMA_CMD_TLB_MISS_STORE",
+        "DMA_CMD_ERROR",
+    };
+
+const char *dma_rsp_fsm_state_str[] = {
+        "DMA_RSP_IDLE",
+        "DMA_RSP_TRT_LOCK",
+        "DMA_RSP_FIFO_PUT",
+        "DMA_RSP_FIFO_ERROR_PUT",
+ };
+
+const char *alloc_trt_dma_fsm_state_str[] = {
+        "ALLOC_TRT_DMA_CMD",
+        "ALLOC_TRT_DMA_RSP",
+    };
+
+const char *dma_tlb_fsm_state_str[] = {
+        "DMA_TLB_IDLE",
+        "DMA_TLB_MISS",
+        "DMA_TLB_PTE1_GET",
+        "DMA_TLB_PTE1_SELECT",
+        "DMA_TLB_PTE1_UPDT",
+        "DMA_TLB_PTE2_GET",                                                  
+        "DMA_TLB_PTE2_SELECT",
+        "DMA_TLB_PTE2_UPDT",
+        "DMA_TLB_WAIT_TRANSACTION",
+        "DMA_TLB_RETURN",
+        "DMA_TLB_INVAL_CHECK",
+        "DMA_TLB_INVAL_SCAN",
+    };
+
+//CONFIG 
+const char *config_cmd_fsm_state_str[] = {
+        "CONFIG_CMD_IDLE",
+        "CONFIG_CMD_TRT_LOCK",
+        "CONFIG_CMD_TRT_WAIT",
+        "CONFIG_CMD_TRT_SET",
+        "CONFIG_CMD_FIFO_PUT",
+         
+        // IOB private configuration segment 
+        "CONFIG_CMD_PTPR_WRITE",
+        "CONFIG_CMD_PTPR_READ",
+        "CONFIG_CMD_ACTIVE_WRITE",
+        "CONFIG_CMD_ACTIVE_READ",
+        "CONFIG_CMD_BVAR_READ",
+        "CONFIG_CMD_ETR_READ",
+        "CONFIG_CMD_BAD_ID_READ",
+        "CONFIG_CMD_INVAL_REQ",
+        "CONFIG_CMD_INVAL",
+        "CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1",
+        "CONFIG_CMD_IT_ADDR_IOMMU_WRITE_2",
+        "CONFIG_CMD_IT_ADDR_IOMMU_READ_1",
+        "CONFIG_CMD_IT_ADDR_IOMMU_READ_2",
+        "CONFIG_CMD_IT_ADDR_WRITE_1",
+        "CONFIG_CMD_IT_ADDR_WRITE_2",
+        "CONFIG_CMD_IT_ADDR_READ_1",
+        "CONFIG_CMD_IT_ADDR_READ_2",
+        "CONFIG_CMD_ERROR_WAIT",
+        "CONFIG_CMD_ERROR_RSP",
+    };
+
+const char *config_rsp_fsm_state_str[] = {
+        "CONFIG_RSP_IDLE",
+        "CONFIG_RSP_TRT_LOCK",
+        "CONFIG_RSP_FIFO_PUT", 
+    };
+
+const char *alloc_trt_config_fsm_state_str[] = {
+        "ALLOC_TRT_CONFIG_CMD",
+        "ALLOC_TRT_CONFIG_RSP",
+    };
+
+//MISS TRANSACTIONS (to Direct Network) 
+const char *miss_init_fsm_state_str[] = {  
+        "MISS_INIT_IDLE_MISS",
+        "MISS_INIT_IDLE_IRQ",
+        "MISS_INIT_IRQ_CMD",
+        "MISS_INIT_IRQ_RSP",
+        "MISS_INIT_TLB_MISS_CMD",
+        "MISS_INIT_TLB_MISS_RSP",
+    };
+}
+
+#define tmpl(...)  template<typename vci_param_d,typename vci_param_x, typename vci_param_io> __VA_ARGS__ VciIoBridge<vci_param_d,vci_param_x,vci_param_io>
+
+/////////////////////////////////
+tmpl(/**/)::VciIoBridge(
+    sc_module_name 			            name,
+    size_t                              nb_periph,
+    const soclib::common::MappingTable 	&mtx,
+    const soclib::common::MappingTable 	&mtd,
+    const soclib::common::MappingTable 	&mtio,
+    const soclib::common::Segment       &seg_config_iob,
+    const soclib::common::IntTab 	    &tgt_index_iocluster,
+//    const soclib::common::IntTab 	    &tgt_index_config,
+    const soclib::common::IntTab 	    &init_index_direct,
+    const soclib::common::IntTab 	    &tgt_index_iospace,
+    const soclib::common::IntTab 	    &init_index_iospace,
+    const soclib::common::IntTab 	    &init_index_dma,
+    size_t                              dcache_words,
+    size_t 				                iotlb_ways,
+    size_t 				                iotlb_sets,
+    uint32_t				            debug_start_cycle,
+    bool				                debug_ok)
+    : soclib::caba::BaseModule(name),
+
+      p_clk("clk"),
+      p_resetn("resetn"),
+      p_irq_in(soclib::common::alloc_elems<sc_core::sc_in<bool> >("irq_in", nb_periph)),
+      p_vci_ini_dma("vci_ini_dma"),
+      p_vci_tgt_dma("vci_tgt_dma"),
+      p_vci_ini_config("vci_ini_config"),
+      p_vci_tgt_config("vci_tgt_config"),
+      p_vci_ini_miss("vci_ini_miss"),
+
+      m_words(dcache_words),
+      m_nb_periph(nb_periph),
+      
+      // m_locality_table_config(mtd.getLocalityTable<unsigned long>(tgt_index_iocluster)),
+      // These structures simulate what in hardware will be a correspondence table
+      // Between segments' base address on the direct space and on the IO space
+      // m_routing_table_config(mtd.getRoutingTable<unsigned long>(tgt_index_iocluster)), 
+      //m_mtio(mtio),
+      
+      m_transaction_tab_dma(2),
+      m_transaction_tab_config(1),
+      //Direct Network
+//      m_segment_config(mtd.getSegment(tgt_index_config)),
+      m_segment_config(seg_config_iob),
+      m_srcid_miss(mtx.indexForId(init_index_direct)), 
+      //XRAM Network
+      m_srcid_dma(mtx.indexForId(init_index_dma)),
+      //IO Network
+      m_segment_io(mtio.getSegment(tgt_index_iospace)),
+      m_srcid_config(mtio.indexForId(init_index_iospace)),
+
+      m_iotlb_ways(iotlb_ways),
+      m_iotlb_sets(iotlb_sets),
+      m_paddr_nbits(vci_param_d::N),
+
+      m_debug_start_cycle(debug_start_cycle),
+      m_debug_ok(debug_ok),
+
+      r_iommu_ptpr("r_iommu_ptpr"),
+      r_iommu_active("r_iommu_active"),
+      r_iommu_bvar("r_iommu_bvar"),
+      r_iommu_etr("r_iommu_etr"),
+      r_iommu_bad_id("r_iommu_bad_id"),
+      r_it_addr_iommu("r_it_addr_iommu"),
+
+      // DMA_CMD 
+      r_dma_cmd_fsm("r_dma_cmd_fsm"),
+      r_dma_cmd_fsm_save("r_dma_cmd_fsm_save"),      
+      r_miss_interrupt("r_miss_interrupt"),
+      r_dma_cmd_count("r_dma_cmd_count"),
+      r_dma_cmd_trt_index("r_dma_cmd_trt_index"),
+      r_dma_paddr("r_dma_paddr"),
+      // FIFOs
+      m_dma_cmd_addr_fifo("m_dma_cmd_addr_fifo",4),
+      //m_dma_cmd_length_fifo("m_dma_cmd_length_fifo",4),
+      m_dma_cmd_srcid_fifo("m_dma_cmd_srcid_fifo",4), 
+      m_dma_cmd_trdid_fifo("m_dma_cmd_trdid_fifo",4), 
+      m_dma_cmd_pktid_fifo("m_dma_cmd_pktid_fifo",4), 
+      m_dma_cmd_be_fifo("m_dma_cmd_be_fifo",4), 
+      m_dma_cmd_cmd_fifo("m_dma_cmd_cmd_fifo",4), 
+      m_dma_cmd_contig_fifo("m_dma_cmd_contig_fifo",4), 
+      m_dma_cmd_data_fifo("m_dma_cmd_data_fifo",4), 
+      m_dma_cmd_eop_fifo("m_dma_cmd_eop_fifo",4),
+      m_dma_cmd_cons_fifo("m_dma_cmd_cons_fifo",4), 
+      m_dma_cmd_plen_fifo("m_dma_cmd_plen_fifo",4), 
+      m_dma_cmd_wrap_fifo("m_dma_cmd_wrap_fifo",4), 
+      m_dma_cmd_cfixed_fifo("m_dma_cmd_cfixed_fifo",4),
+      m_dma_cmd_clen_fifo("m_dma_cmd_clen_fifo",4), 
+
+      r_miss_paddr       ("r_miss_paddr"), 
+      r_miss_cmd         ("r_miss_cmd"), 
+      r_miss_contig      ("r_miss_contig"),
+      r_miss_cons        ("r_miss_cons"),
+      r_miss_plen        ("r_miss_plen"),
+      r_miss_wrap        ("r_miss_wrap"),
+      r_miss_cfixed      ("r_miss_cfixed"),    
+      r_miss_clen        ("r_miss_clen"),
+      r_miss_srcid       ("r_miss_srcid"),
+      r_miss_trdid       ("r_miss_trdid"),
+      r_miss_pktid       ("r_miss_pktid"),
+
+      r_dma_error_type("r_dma_error_type"),      
+      r_dma_error_trdid("r_dma_error_trdid"), 
+      r_dma_error_pktid("r_dma_error_pktid"), 
+
+ 
+      r_dma_tlb_fsm("r_dma_tlb_fsm"),
+      r_waiting_transaction("r_waiting_transaction"),
+      r_tlb_miss_type("r_tlb_miss_type"),
+
+                     
+      r_iotlb_vaddr("r_iotlb_vaddr"),		 // virtual address for a tlb miss
+      r_iotlb_paddr("r_iotlb_paddr"),		 // physical address of pte
+      r_iotlb_pte_flags("r_iotlb_pte_flags"),// pte1 or first word of pte2
+      r_iotlb_pte_ppn("r_iotlb_pte_ppn"),	 // second word of pte2
+      r_iotlb_way("r_iotlb_way"),		     // selected way in tlb    
+      r_iotlb_set("r_iotlb_set"),		     // selected set in tlb    
+
+      r_iotlb("iotlb", IOMMU_ID, iotlb_ways,iotlb_sets,vci_param_d::N),
+      
+      //DMA_RSP
+      r_dma_rsp_fsm("r_dma_rsp_fsm"),
+      r_dma_rtrdid("r_dma_rtrdid"),
+      r_dma_rsrcid("r_dma_rsrcid"),
+      //Fifo's
+      m_dma_rsp_data_fifo("m_dma_rsp_data_fifo",4),
+      m_dma_rsp_rsrcid_fifo("m_dma_rsp_rsrcid_fifo",4),
+      m_dma_rsp_rtrdid_fifo("m_dma_rsp_rtrdid_fifo",4),
+      m_dma_rsp_rpktid_fifo("m_dma_rsp_rpktid_fifo",4),
+      m_dma_rsp_reop_fifo("m_dma_rsp_reop_fifo",4),
+      m_dma_rsp_rerror_fifo("m_dma_rsp_rerror_fifo",4),
+      
+      r_dma_cmd_rsp_erase_req("r_dma_cmd_rsp_erase_req"),
+      r_dma_cmd_error_req("r_dma_cmd_error_req"),
+      r_dma_tlb_req("r_dma_tlb_req"),
+      r_tlb_dma_untreated("r_tlb_dma_untreated"), 
+      r_dma_tlb_error_req("r_dma_tlb_error_req"),
+      r_config_tlb_req("r_config_tlb_req"),
+      r_config_tlb_inval_vaddr("r_config_tlb_inval_vaddr"), 
+      
+      // ALLOC TRT DMA
+      r_alloc_trt_dma_fsm("r_alloc_trt_dma_fsm"),
+      
+      // CONFIG CMD
+      r_config_cmd_fsm("r_config_cmd_fsm"),
+      r_config_cmd_trt_index("r_config_cmd_trt_index"),
+     
+      m_config_cmd_addr_fifo("m_config_cmd_addr_fifo",4),
+      //m_config_cmd_length_fifo("m_config_cmd_length_fifo",4),
+      m_config_cmd_srcid_fifo("m_config_cmd_srcid_fifo",4),
+      m_config_cmd_trdid_fifo("m_config_cmd_trdid_fifo",4),
+      m_config_cmd_pktid_fifo("m_config_cmd_pktid_fifo",4),
+      m_config_cmd_be_fifo("m_config_cmd_be_fifo",4),
+      m_config_cmd_cmd_fifo("m_config_cmd_cmd_fifo",4),
+      m_config_cmd_contig_fifo("m_config_cmd_contig_fifo",4),
+      m_config_cmd_data_fifo("m_config_cmd_data_fifo",4),
+      m_config_cmd_eop_fifo("m_config_cmd_eop_fifo",4),
+      m_config_cmd_cons_fifo("m_config_cmd_cons_fifo",4),
+      m_config_cmd_plen_fifo("m_config_cmd_plen_fifo",4),
+      m_config_cmd_wrap_fifo("m_config_cmd_wrap_fifo",4),
+      m_config_cmd_cfixed_fifo("m_config_cmd_cfixed_fifo",4),
+      m_config_cmd_clen_fifo("m_config_cmd_clen_fifo",4),
+      // Private configuration registers
+      r_config_error_type("r_config_error_type"),
+      r_config_first_word("r_config_first_word"),
+      r_it_index("r_it_index"),
+      //Fifo's
+      m_config_local_data_fifo("m_config_local_data_fifo",4),     
+      m_config_local_rsrcid_fifo("m_config_local_rsrcid_fifo",4),
+      m_config_local_rtrdid_fifo("m_config_local_rtrdid_fifo",4),
+      m_config_local_rpktid_fifo("m_config_local_rpktid_fifo",4),
+      m_config_local_reop_fifo("m_config_local_reop_fifo",4),
+      m_config_local_rerror_fifo("m_config_local_rerror_fifo",4),    
+      r_config_vaddr("r_config_vaddr"),
+    
+      // CONFIG RSP  
+      r_config_rsp_fsm("r_config_rsp_fsm"),
+      r_config_rtrdid("r_config_rtrdid"),
+      r_config_rsrcid("r_config_rsrcid"),
+      //Fifo's
+      m_config_rsp_data_fifo("m_config_rsp_data_fifo",4),     
+      m_config_rsp_rsrcid_fifo("m_config_rsp_rsrcid_fifo",4),
+      m_config_rsp_rtrdid_fifo("m_config_rsp_rtrdid_fifo",4),
+      m_config_rsp_rpktid_fifo("m_config_rsp_rpktid_fifo",4),
+      m_config_rsp_reop_fifo("m_config_rsp_reop_fifo",4),
+      m_config_rsp_rerror_fifo("m_config_rsp_rerror_fifo",4),    
+
+      // Communication between CONFIG CMD and CONFIG RSP
+      r_config_cmd_rsp_erase_req("r_config_cmd_rsp_erase_req"),      
+    
+      // ALLOC TRT CONFIG 
+      r_alloc_trt_config_fsm("r_alloc_trt_config_fsm"), 
+      // MISS INIT
+      r_miss_init_fsm("r_miss_init_fsm"), 
+      r_miss_rdata("r_miss_rdata"),
+      r_miss_rpktid("r_miss_rpktid"),
+      r_miss_rtrdid("r_miss_rtrdid"),
+      r_miss_rerror("r_miss_rerror"),
+      r_miss_reop("r_miss_reop"),
+      //r_miss_rsrcid("r_miss_rsrcid"),
+      r_miss_rsp_cpt("r_miss_rsp_cpt"),
+      //IRQ
+      r_irq_pending("r_irq_pending"),
+      r_irq_mask("r_irq_mask"),
+      r_irq_chosen("r_irq_chosen"),
+      
+      r_tlb_miss_init_req("r_tlb_miss_init_req"),
+      r_miss_init_error("r_miss_init_error"),
+      
+      r_miss_buf_valid("r_miss_buf_valid"),
+      r_miss_buf_tag("r_miss_buf_tag")
+{
+    assert( (vci_param_d::N <=  64) and
+            "ADDRESS cannot be bigger than 64 bits");
+    assert( (vci_param_d::B ==  vci_param_io::B) and
+            "DATA field must have the same size in Direct and IO Network");
+    assert ( (vci_param_d::B)*8 == 32 
+        and "Error: data field in Direct Noc must be 32 bits" );
+                    
+    
+    // Interruption Address vector, one entry for each IO
+    r_it_addr           = new paddr_t[nb_periph];
+    // One cache line buffer
+    r_miss_buf_data     = new vci_data_t[dcache_words];
+    // Command storage in case of miss TLB
+    // (dcache_words/2) => Maximal size of a write command 
+    r_miss_data     = new vci_data_t[dcache_words]; 
+    r_miss_be     = new vci_be_t[dcache_words];
+    
+    SC_METHOD(transition);
+    dont_initialize();
+    sensitive << p_clk.pos();
+  
+    SC_METHOD(genMoore);
+    dont_initialize();
+    sensitive << p_clk.neg();
+
+ }
+
+/////////////////////////////////////
+tmpl(/**/)::~VciIoBridge()
+/////////////////////////////////////
+{
+    delete [] r_it_addr;
+    delete [] r_miss_buf_data;
+    delete [] r_miss_data;
+    delete [] r_miss_be;
+    soclib::common::dealloc_elems(p_irq_in, m_nb_periph);
+}
+
+////////////////////////////////////
+tmpl(void)::print_trace(size_t mode)
+////////////////////////////////////
+{
+    // b0 : IOtlb trace
+
+    std::cout << std::dec << "IO_BRIDGE " << name() << std::endl;
+
+    std::cout << "  " << dma_cmd_fsm_state_str[r_dma_cmd_fsm.read()]
+              << " | " << dma_rsp_fsm_state_str[r_dma_rsp_fsm.read()]
+              << " | " << dma_tlb_fsm_state_str[r_dma_tlb_fsm.read()]
+              << " | " << alloc_trt_dma_fsm_state_str[r_alloc_trt_dma_fsm.read()]
+              << " | " << config_cmd_fsm_state_str[r_config_cmd_fsm.read()]
+              << " | " << config_rsp_fsm_state_str[r_config_rsp_fsm.read()]
+              << " | " << alloc_trt_config_fsm_state_str[r_alloc_trt_config_fsm.read()]
+              << " | " << miss_init_fsm_state_str[r_miss_init_fsm.read()];
+    std::cout << std::endl;
+
+    if(mode & 0x01)
+    {
+        std::cout << "  IOTLB" << std::endl;
+        r_iotlb.printTrace();
+    }
+    if(mode & 0x02)
+    {
+    	
+    }
+}
+
+
+
+////////////////////////
+tmpl(void)::print_stats()
+////////////////////////
+{
+    std::cout << name() << std::endl
+        << "- IOTLB MISS RATE      = " << (float)m_cpt_iotlb_miss/m_cpt_iotlb_read << std::endl
+        << "- IOTLB MISS COST         = " << (float)m_cost_iotlb_miss/m_cpt_iotlb_miss << std::endl
+        << "- IOTLB MISS TRANSACTION COST  = " << (float)m_cost_iotlbmiss_transaction/m_cpt_iotlbmiss_transaction << std::endl
+        << "- IOTLB MISS TRANSACTION RATE (OVER ALL MISSES)  = " << (float)m_cpt_iotlbmiss_transaction/m_cpt_iotlb_miss << std::endl;
+}
+
+////////////////////////
+tmpl(void)::clear_stats()
+////////////////////////
+{
+    m_cpt_iotlb_read                = 0;             
+    m_cpt_iotlb_miss                = 0;             
+    m_cost_iotlb_miss               = 0;
+    m_cpt_iotlbmiss_transaction     = 0;    
+    m_cost_iotlbmiss_transaction    = 0;   
+        
+    m_cpt_trt_dma_full          = 0;
+    m_cpt_trt_dma_full_cost     = 0;
+    m_cpt_trt_config_full          = 0;
+    m_cpt_trt_config_full_cost     = 0;
+}
+
+/////////////////////////
+tmpl(void)::transition()
+/////////////////////////
+{
+    if ( not p_resetn.read() ) 
+    {
+
+        r_dma_cmd_fsm		    = DMA_CMD_IDLE;
+        r_dma_rsp_fsm		    = DMA_RSP_IDLE;
+        r_alloc_trt_dma_fsm     = ALLOC_TRT_DMA_CMD;
+        r_dma_tlb_fsm	        = DMA_TLB_IDLE;
+        r_config_cmd_fsm	    = CONFIG_CMD_IDLE;
+        r_config_rsp_fsm	    = CONFIG_RSP_IDLE;
+        r_alloc_trt_config_fsm  = ALLOC_TRT_CONFIG_CMD;
+        r_miss_init_fsm		    = MISS_INIT_IDLE_MISS;
+
+        //miss buffer invalidation
+        r_miss_buf_valid = false; 
+        
+		r_iommu_active = false;
+
+        r_dma_cmd_count = 0;
+        
+        // initializing FIFOs
+        m_dma_cmd_addr_fifo.init();
+        m_dma_cmd_srcid_fifo.init();
+        m_dma_cmd_trdid_fifo.init();
+        m_dma_cmd_pktid_fifo.init();
+        m_dma_cmd_be_fifo.init();
+        m_dma_cmd_cmd_fifo.init();
+        m_dma_cmd_contig_fifo.init();
+        m_dma_cmd_data_fifo.init();
+        m_dma_cmd_eop_fifo.init();
+        m_dma_cmd_cons_fifo.init();
+        m_dma_cmd_plen_fifo.init();
+        m_dma_cmd_wrap_fifo.init();
+        m_dma_cmd_cfixed_fifo.init();
+        m_dma_cmd_clen_fifo.init();
+        
+        m_dma_rsp_rsrcid_fifo.init();
+        m_dma_rsp_rtrdid_fifo.init();
+        m_dma_rsp_rpktid_fifo.init();
+        m_dma_rsp_data_fifo.init();
+        m_dma_rsp_rerror_fifo.init();
+        m_dma_rsp_reop_fifo.init();
+        
+        m_config_cmd_addr_fifo.init();
+        m_config_cmd_srcid_fifo.init();
+        m_config_cmd_trdid_fifo.init();
+        m_config_cmd_pktid_fifo.init();
+        m_config_cmd_be_fifo.init();
+        m_config_cmd_cmd_fifo.init();
+        m_config_cmd_contig_fifo.init();
+        m_config_cmd_data_fifo.init();
+        m_config_cmd_eop_fifo.init();
+        m_config_cmd_cons_fifo.init();
+        m_config_cmd_plen_fifo.init();
+        m_config_cmd_wrap_fifo.init();
+        m_config_cmd_cfixed_fifo.init();
+        m_config_cmd_clen_fifo.init();
+        
+        m_config_rsp_rsrcid_fifo.init();
+        m_config_rsp_rtrdid_fifo.init();
+        m_config_rsp_rpktid_fifo.init();
+        m_config_rsp_data_fifo.init();
+        m_config_rsp_rerror_fifo.init();
+        m_config_rsp_reop_fifo.init();
+        
+        m_config_local_rsrcid_fifo.init();
+        m_config_local_rtrdid_fifo.init();
+        m_config_local_rpktid_fifo.init();
+        m_config_local_data_fifo.init();
+        m_config_local_rerror_fifo.init();
+        m_config_local_reop_fifo.init();
+
+        //Communication between DMA_CMD and DMA_RSP
+        r_dma_cmd_rsp_erase_req		=false;
+        r_dma_cmd_error_req         =false;
+        //Communication between DMA_CMD and TLB 
+        r_dma_tlb_req		        =false;
+        r_tlb_dma_untreated		    =false; 
+        //Communication betweeen TLB and CONFIG_CMD
+        r_config_tlb_req		    =false;
+        r_config_tlb_inval_vaddr	=false;
+	    r_dma_tlb_error_req         =false; 
+        r_tlb_error_type            =false;   
+        //Communication between CONFIG_CMD and CONFIG_RSP
+        r_config_cmd_rsp_erase_req  =false;
+        //Communication between TLB_MISS and MISS_INIT 
+        r_tlb_miss_init_req         =false;
+        r_miss_init_error           =false;
+        // Debug variables
+		m_debug_dma_rsp_fsm	        = false;
+		m_debug_dma_cmd_fsm         = false;
+        m_debug_dma_tlb_fsm         = false;
+        m_debug_config_cmd_fsm      = false;
+        m_debug_config_rsp_fsm      = false;
+        m_debug_miss_init_fsm       = false;
+        
+        r_irq_mask              = 0xFFFFFFFF;
+        r_irq_chosen            = 0;
+          
+	    // activity counters
+	    m_cpt_total_cycles      = 0;
+        m_cpt_iotlb_read       = 0;             
+        m_cpt_iotlb_miss       = 0;             
+        m_cpt_iotlbmiss_transaction      = 0;    
+        m_cost_iotlbmiss_transaction      = 0;   
+        
+        m_cpt_trt_dma_full          = 0;
+        m_cpt_trt_dma_full_cost     = 0;
+        m_cpt_trt_config_full          = 0;
+        m_cpt_trt_config_full_cost     = 0;
+
+        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_dma_cmd            [i]   = 0;
+        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_dma_rsp            [i]   = 0;
+        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_dma_tlb            [i]   = 0;
+        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_alloc_trt_dma      [i]   = 0;
+        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_config_cmd         [i]   = 0;
+        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_config_rsp         [i]   = 0;
+        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_alloc_trt_config   [i]   = 0;
+        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_miss_init          [i]   = 0;
+        return;
+    }
+
+    
+    //bool        miss_unposted      = false;
+    bool        dma_cmd_fifo_put    = false;
+    bool        dma_cmd_fifo_get    = false;
+    bool        dma_rsp_fifo_put    = false; 
+    bool        dma_rsp_fifo_get    = false; 
+    
+    bool        config_cmd_fifo_put = false;
+    bool        config_cmd_fifo_get = false;
+    bool        config_rsp_fifo_put = false;
+    bool        config_rsp_fifo_get = false;
+    bool        config_local_fifo_put = false;
+    bool        config_local_fifo_get = false;
+
+#ifdef INSTRUMENTATION
+    m_cpt_fsm_dma_cmd	        [r_dma_cmd_fsm.read()] ++;
+    m_cpt_fsm_dma_rsp	        [r_dma_rsp_fsm.read() ] ++;
+    m_cpt_fsm_dma_tlb   	    [r_dma_tlb_fsm.read() ] ++;
+    m_cpt_fsm_alloc_trt_dma  	[r_alloc_trt_dma_fsm.read() ] ++;
+    m_cpt_fsm_config_cmd	    [r_config_cmd_fsm.read() ] ++;
+    m_cpt_fsm_config_rsp	    [r_config_rsp_fsm.read() ] ++;
+    m_cpt_fsm_alloc_trt_config  [r_alloc_trt_config_fsm.read() ] ++;
+    m_cpt_fsm_miss_init	        [r_miss_init_fsm.read() ] ++;
+#endif
+
+    m_cpt_total_cycles++;
+
+    m_debug_dma_cmd_fsm        = (m_cpt_total_cycles > m_debug_start_cycle) and m_debug_ok;
+    m_debug_dma_rsp_fsm         = (m_cpt_total_cycles > m_debug_start_cycle) and m_debug_ok;
+    m_debug_dma_tlb_fsm    = (m_cpt_total_cycles > m_debug_start_cycle) and m_debug_ok;
+    m_debug_config_cmd_fsm      = (m_cpt_total_cycles > m_debug_start_cycle) and m_debug_ok;
+    m_debug_config_rsp_fsm     = (m_cpt_total_cycles > m_debug_start_cycle) and m_debug_ok;
+    m_debug_miss_init_fsm       = (m_cpt_total_cycles > m_debug_start_cycle) and m_debug_ok;
+
+    /////////////////////////////////////////////////////////////////////
+    // The DMA_CMD_FSM controls the following ressources:
+    // - r_dma_cmd_fsm
+    // - r_dma_srcid
+    // - r_dma_tlb_req (set)
+    // - r_tlb_dma_untreated (reset)
+    // - r_dma_cmd_rsp_erase_req (set)
+    ///////////////////////////////////////////////////////////////////////////////
+
+    switch( r_dma_cmd_fsm.read() ) 
+    {
+    //////////////
+    case DMA_CMD_IDLE:
+    {
+        // Treats an eventual request from TLB_MISS fsm 
+        // to send a command whose miss treatment is now finished
+        if ( r_tlb_dma_untreated.read() )
+        {
+            r_dma_cmd_fsm    = DMA_CMD_TRT_LOCK;//before posting we must update TRT
+            r_dma_cmd_fsm_save = DMA_CMD_IDLE;
+            r_miss_interrupt = true;
+            break;
+        }
+        // Error during miss treatment
+        else if (r_dma_tlb_error_req.read())
+        {
+            r_iommu_etr     = r_tlb_error_type.read(); 
+            r_iommu_bvar    = r_iotlb_vaddr.read();
+            r_iommu_bad_id  = r_miss_srcid.read();
+            // For DMA_RSP FSM
+            if(r_miss_cmd.read() == vci_param_io::CMD_WRITE) r_dma_error_type = WRITE_ERROR;
+            else r_dma_error_type = READ_ERROR;
+            r_dma_error_trdid   = r_miss_trdid.read(); 
+            r_dma_error_pktid   = r_miss_pktid.read(); 
+ 
+            r_dma_tlb_error_req = false; 
+            r_dma_cmd_fsm   = DMA_CMD_ERROR;
+        }
+
+        if ( p_vci_tgt_dma.cmdval.read() )
+        { 
+            if ( not r_iommu_active.read()) 	// iotlb not activated 
+            {
+                // physical address
+                r_dma_paddr = (paddr_t)p_vci_tgt_dma.address.read();
+                r_dma_cmd_fsm	= DMA_CMD_TRT_LOCK;
+            }
+            else if (r_dma_tlb_fsm.read() == DMA_TLB_IDLE ||
+                     r_dma_tlb_fsm.read() == DMA_TLB_WAIT_TRANSACTION )	  // iotlb activated
+            {
+                paddr_t	paddr;
+
+                
+                // We compute physical address and check access rights :
+                // - If MMU not activated :the physical address is equal to the virtual 
+                //address (identity mapping) and there is no access rights checking
+                // - If MMU activated : cacheability is defined by the C bit in the PTE,
+                //   the physical address is obtained from the TLB, and the access rights are
+                //   defined by the W bit in the PTE.
+
+                paddr_t		iotlb_paddr;
+                pte_info_t  iotlb_flags; 
+                size_t      iotlb_way;  
+                size_t      iotlb_set;
+                paddr_t     iotlb_nline;
+                bool		iotlb_hit   = false;;  
+
+
+#ifdef INSTRUMENTATION
+m_cpt_iotlb_read++;
+#endif
+
+                iotlb_hit = r_iotlb.translate(p_vci_tgt_dma.address.read(),
+                                            &iotlb_paddr,
+                                            &iotlb_flags,
+                                            &iotlb_nline,// unused
+                                            &iotlb_way,	 // unused
+                                            &iotlb_set );// unused
+            
+            
+                if ( iotlb_hit )	// tlb hit
+                { 
+                    paddr       = iotlb_paddr;
+					
+                    // access rights checking 
+                    if ( not iotlb_flags.w and 
+                        (p_vci_tgt_dma.cmd.read() == vci_param_io::CMD_WRITE) ) 
+                    {
+                        r_iommu_etr     = MMU_WRITE_ACCES_VIOLATION;  
+                        r_iommu_bvar    = p_vci_tgt_dma.address.read();
+                        r_iommu_bad_id  = p_vci_tgt_dma.srcid.read();
+                        r_dma_cmd_fsm   = DMA_CMD_ERROR;
+                        // For DMA_RSP
+                        r_dma_error_type    = WRITE_ERROR; 
+                        r_dma_error_trdid   = p_vci_tgt_dma.trdid.read(); 
+                        r_dma_error_pktid   = p_vci_tgt_dma.pktid.read(); 
+#if DEBUG_DMA_CMD
+if( m_debug_dma_cmd_fsm )
+{
+    std::cout << "  <IOB.DMA_CMD_IDLE> HIT in iotlb, but writable violation" << std::endl;
+}
+#endif
+                    break;
+                    }
+
+                    // Physical address registration 
+                    r_dma_paddr   = paddr;			
+                    r_dma_cmd_fsm	= DMA_CMD_TRT_LOCK;
+                }
+                // TLB miss: we enter TLB_MISS treatment sub-fsm
+                else 
+                {
+
+#ifdef INSTRUMENTATION
+m_cpt_iotlb_miss++;
+#endif
+                    if( r_dma_tlb_req.read() || r_tlb_dma_untreated.read() || r_dma_tlb_error_req.read() )
+                    {
+                        // There's already a ongoing request
+                        // or a completed request but not yet put on FIFO.
+                        // We stay blocked
+                        r_dma_cmd_fsm = DMA_CMD_TLB_MISS_WAIT;
+#if DEBUG_DMA_CMD
+if( m_debug_dma_cmd_fsm )
+{
+    std::cout << "  <IOB.DMA_CMD_IDLE> MISS in iotlb. There is a pending request." << std::endl;
+}
+#endif
+                    }
+                    else
+                    {
+                        // We register request virtual address, to be used by DMA_TLB_MISS FSM
+		                r_iotlb_vaddr = p_vci_tgt_dma.address.read();
+                        assert((r_dma_cmd_count.read() == 0)
+                                and "ERROR: TRT counter should be 0");
+                        r_dma_tlb_req   = true;
+                        r_dma_cmd_fsm   = DMA_CMD_TLB_MISS_STORE;
+#if DEBUG_DMA_CMD
+if( m_debug_dma_cmd_fsm )
+{
+    std::cout << "  <IOB.DMA_CMD_IDLE> MISS in iotlb. No pending request." << std::endl;
+}
+#endif
+                    }
+                } // end !hit 
+            } // end if tlb_activated
+        } // end if cmdval
+        break;
+    }
+    /////////////////////////
+    case DMA_CMD_TRT_LOCK:	// Waiting for the lock to modify Transaction Table
+    {
+        if ( r_alloc_trt_dma_fsm.read() == ALLOC_TRT_DMA_CMD ) 
+        {
+
+#if DEBUG_DMA_CMD
+if( m_debug_dma_cmd_fsm )
+{
+    std::cout << "  <IOB.DMA_CMD_TRT_LOCK> Check the TRT" << std::endl;
+}
+#endif
+            size_t 		wok_index = 0;
+            bool 		wok       = !m_transaction_tab_dma.full(wok_index);
+
+            if ( wok ) 	// TRT isn't full. Write the new transaction. 
+            {
+                r_dma_cmd_trt_index = (vci_trdid_t)wok_index;
+                r_dma_cmd_fsm       = DMA_CMD_TRT_SET;
+            } 
+            else 		// wait an empty entry in TRT
+            {
+                r_dma_cmd_rsp_erase_req = true;
+                r_dma_cmd_fsm       = DMA_CMD_TRT_WAIT;
+#if DEBUG_DMA_CMD
+if( m_debug_dma_cmd_fsm )
+{
+    std::cout << "  <IOB.DMA_CMD_TRT_LOCK> TRT is full. Going to TRT_WAIT state" << std::endl;
+}
+#endif
+            
+#ifdef INSTRUMENTATION        
+m_cpt_trt_dma_full++;
+#endif
+            }
+        }
+        break;
+    }
+    ////////////////
+    case DMA_CMD_TRT_WAIT:	// release the lock protecting the transaction tab
+                            // waits that RSP erases an entry 
+    { 
+#ifdef INSTRUMENTATION        
+m_cpt_trt_dma_full_cost++;
+#endif
+        // DMA_RSP will notify an erase action by reseting this register
+        if(!r_dma_cmd_rsp_erase_req.read())
+        {
+            r_dma_cmd_fsm = DMA_CMD_TRT_LOCK; // take the lock again
+        }
+        break;
+    }
+    ////////////////////////
+    case DMA_CMD_TRT_SET:	// register a new transaction in TRT
+    {  
+        if ( r_alloc_trt_dma_fsm.read() == ALLOC_TRT_DMA_CMD ) 
+        {
+            if(r_miss_interrupt.read())
+            {
+                m_transaction_tab_dma.set(r_dma_cmd_trt_index.read(),
+                                      r_miss_srcid.read(), 
+                                      r_miss_trdid.read() );
+                r_dma_cmd_fsm = DMA_CMD_FIFO_MISS_PUT;
+            }
+            else
+            {
+                m_transaction_tab_dma.set(r_dma_cmd_trt_index.read(),
+                                          p_vci_tgt_dma.srcid.read(), 
+                                          p_vci_tgt_dma.trdid.read() );
+                r_dma_cmd_fsm = DMA_CMD_FIFO_PUT;
+            }
+#if DEBUG_DMA_CMD
+if( m_debug_dma_cmd_fsm )
+{
+    std::cout << "  <IOB.DMA_CMD_TRT_SET> Set a new entry in TRT" << std::endl;
+    if(r_miss_interrupt.read()) std::cout << " From the Network " << std::endl;
+    else std::cout << " From miss interruption" << std::endl;
+}
+#endif
+        }
+        break;
+    }  
+    ///////////////////////
+    case DMA_CMD_FIFO_PUT:	 
+    {
+        if ( p_vci_tgt_dma.cmdval && m_dma_cmd_addr_fifo.wok() ) 
+        {
+            dma_cmd_fifo_put = true;
+            //miss_unposted = false;
+            if(  p_vci_tgt_dma.contig )    r_dma_paddr = r_dma_paddr.read() + 4;
+            if(  p_vci_tgt_dma.eop )    r_dma_cmd_fsm = DMA_CMD_IDLE;
+           
+#if DEBUG_DMA_CMD
+if( m_debug_dma_cmd_fsm ) 
+{
+    std::cout << "  <IOB.DMA_CMD_FIFO_PUT> Push into cmd_fifo:" 
+              << " address = " << std::hex << r_dma_paddr.read()
+              << " srcid = " << std::dec << m_srcid_dma
+              << " trdid = " << r_dma_cmd_trt_index.read()
+              << " wdata = " << std::hex << p_vci_tgt_dma.wdata.read()
+              << " be = " << p_vci_tgt_dma.be.read()
+              << " contig = " << p_vci_tgt_dma.contig.read()
+              << " eop = " << std::dec << p_vci_tgt_dma.eop.read() 
+              << " plen = " << std::dec << p_vci_tgt_dma.plen.read() << std::endl;
+}
+#endif
+        }
+        break;
+    }
+    ///////////////////////
+    case DMA_CMD_FIFO_MISS_PUT:	 
+    {
+        if ( m_dma_cmd_addr_fifo.wok() ) 
+        {
+            dma_cmd_fifo_put    = true;
+            //miss_unposted       = true;
+            if( r_miss_contig.read() )    r_miss_paddr = r_miss_paddr.read() + 4;
+            
+            if( r_dma_cmd_count.read() == 1 ) 
+            {
+                r_tlb_dma_untreated = false;
+                r_miss_interrupt = false;
+                r_dma_cmd_fsm = r_dma_cmd_fsm_save.read();
+            }
+            r_dma_cmd_count = r_dma_cmd_count.read() - 1;
+
+#if DEBUG_DMA_CMD
+if( m_debug_dma_cmd_fsm ) 
+{
+    std::cout << "  <IOB.DMA_CMD_FIFO_MISS_PUT> Push into cmd_fifo:" 
+              << " counter = " << std::hex << r_dma_cmd_count.read()
+              << " address = " << std::hex << r_miss_paddr.read()
+              << " srcid = " << std::dec << r_miss_srcid.read()
+              << " trdid = " << r_miss_trdid.read()
+              << " wdata = " << std::hex << r_miss_data
+              << " be = " << r_miss_be
+              << " plen = " << std::dec << r_miss_plen.read() << std::endl;
+}
+#endif
+        }
+        break;
+    }
+    ///////////////////
+    case DMA_CMD_TLB_MISS_WAIT: // to store the miss request there must be 
+                                // neither an ongoing request, nor a unposted finished request
+    {
+        // Treats an eventual request from TLB_MISS fsm 
+        // to send a command whose miss treatment is now finished
+        if ( r_tlb_dma_untreated.read() )
+        {
+            r_dma_cmd_fsm    = DMA_CMD_TRT_LOCK; //before posting we must update TRT
+            r_dma_cmd_fsm_save = DMA_CMD_TLB_MISS_WAIT;
+            r_miss_interrupt = true;
+            break;
+        }
+        // Error during miss treatment
+        else if (r_dma_tlb_error_req.read())
+        {
+            r_iommu_etr     = r_tlb_error_type.read(); 
+            r_iommu_bvar    = r_iotlb_vaddr.read();
+            r_iommu_bad_id  = r_miss_srcid.read();
+            // For DMA_RSP FSM
+            if(r_miss_cmd.read() == vci_param_io::CMD_WRITE) r_dma_error_type = WRITE_ERROR;
+            else r_dma_error_type = READ_ERROR;
+            r_dma_error_trdid   = r_miss_trdid.read(); 
+            r_dma_error_pktid   = r_miss_pktid.read(); 
+ 
+            r_dma_tlb_error_req = false; 
+            r_dma_cmd_fsm   = DMA_CMD_ERROR;
+        }
+
+#ifdef INSTRUMENTATION        
+m_cost_iotlb_miss++;  // Now it represents misses' total blocking cost (not the treatment cost itself)
+#endif
+        else if (not r_dma_tlb_req.read())
+        {
+            r_dma_cmd_fsm   = DMA_CMD_TLB_MISS_STORE;
+            assert((r_dma_cmd_count.read() == 0) and "ERROR: TRT counter should be 0");
+        }
+        break;
+    }
+    ///////////////////
+    case DMA_CMD_TLB_MISS_STORE:
+    {
+        if ( p_vci_tgt_dma.cmdval.read()) 
+        {
+            if(r_dma_cmd_count.read() == 0)
+            {
+                r_miss_cmd = p_vci_tgt_dma.cmd.read();
+                r_miss_contig = p_vci_tgt_dma.contig.read();
+                r_miss_cons = p_vci_tgt_dma.cons.read();
+                r_miss_plen = p_vci_tgt_dma.plen.read();
+                r_miss_wrap = p_vci_tgt_dma.wrap.read();
+                r_miss_cfixed = p_vci_tgt_dma.cfixed.read();
+                r_miss_clen = p_vci_tgt_dma.clen.read();
+                r_miss_srcid = p_vci_tgt_dma.srcid.read();
+                r_miss_trdid = p_vci_tgt_dma.trdid.read();
+                r_miss_pktid = p_vci_tgt_dma.pktid.read();
+                
+//                r_dma_tlb_req   = true;
+            }
+            
+            r_miss_data[r_dma_cmd_count.read()] = p_vci_tgt_dma.wdata.read();
+            r_miss_be[r_dma_cmd_count.read()] = p_vci_tgt_dma.be.read();
+            
+            r_dma_cmd_count = r_dma_cmd_count.read() + 1;
+            
+            if(  p_vci_tgt_dma.eop )  r_dma_cmd_fsm = DMA_CMD_IDLE;
+           
+#if DEBUG_DMA_CMD
+if( m_debug_dma_cmd_fsm ) 
+{
+    std::cout << "  <IOB.DMA_CMD_TLB_MISS_STORE> Storing VCI fields of command that originate the Miss:" 
+              << " counter = " << std::hex << r_dma_cmd_count.read()
+              << " address = " << std::hex << p_vci_tgt_dma.address.read()
+              << " srcid = " << std::dec << p_vci_tgt_dma.srcid.read()
+              << " trdid = " << p_vci_tgt_dma.trdid.read()
+              << " wdata = " << std::hex << p_vci_tgt_dma.wdata.read()
+              << " be = " << p_vci_tgt_dma.be.read()
+              << " plen = " << std::dec << p_vci_tgt_dma.plen.read() << std::endl;
+}
+#endif
+        }
+        break;
+    }
+    ///////////////////
+    case DMA_CMD_ERROR:
+    {
+        // Wait in case of pending request
+        // it isn't the case, generally
+        if(!r_dma_cmd_error_req.read())
+        { 
+            r_dma_cmd_error_req = true; 
+            r_dma_cmd_fsm       = DMA_CMD_IDLE;
+        }
+        break;
+    }
+    } // end switch DMA_CMD_FSM
+
+    /////////////////////////////////////////////////////////////////////
+    // The DMA_RSP_FSM controls the following ressources:
+    // - r_dma_rsp_fsm
+    // - r_dma_cmd_rsp_erase_req (reset) 
+    // - r_fma_error_req (reset)
+    // - 
+    //////////////////////////////////////////////////////////////////////////////
+    switch( r_dma_rsp_fsm.read() ) 
+    {
+    /////////////////////
+    case DMA_RSP_IDLE:
+    {    	
+        // Interruption from DMA_CMD following an error
+        if(r_dma_cmd_error_req.read()) r_dma_rsp_fsm = DMA_RSP_FIFO_ERROR_PUT;
+        
+        if(p_vci_ini_dma.rspval.read()) 
+		{
+			r_dma_rsp_fsm = DMA_RSP_TRT_LOCK;
+		}
+		break;
+    }
+    /////////////////////
+    case DMA_RSP_TRT_LOCK:
+    {    	
+        if ( r_alloc_trt_dma_fsm.read() == ALLOC_TRT_DMA_RSP ) 
+        {
+            
+#if DEBUG_DMA_RSP
+if( m_debug_dma_rsp_fsm )
+{
+    std::cout << "  <IOB.DMA_RSP_TRT_LOCK> Erase entry" << std::endl;
+}
+#endif
+            uint32_t trdid_xram = p_vci_ini_dma.rtrdid.read(); 
+            
+            r_dma_rsrcid = (vci_srcid_t)m_transaction_tab_dma.readSrcid(trdid_xram);
+            r_dma_rtrdid = (vci_trdid_t)m_transaction_tab_dma.readTrdid(trdid_xram);
+            m_transaction_tab_dma.erase(trdid_xram);
+            if (r_dma_cmd_rsp_erase_req.read()) r_dma_cmd_rsp_erase_req = false;
+            r_dma_rsp_fsm       = DMA_RSP_FIFO_PUT;
+        }        
+		break;
+    }
+    //////////////////
+    case DMA_RSP_FIFO_PUT:
+    {
+        if(p_vci_ini_dma.rspval.read() && m_dma_rsp_data_fifo.wok())
+    	{
+            dma_rsp_fifo_put = true;
+            if(p_vci_ini_dma.reop.read())   r_dma_rsp_fsm = DMA_RSP_IDLE;	
+
+#if DEBUG_DMA_RSP
+if( m_debug_dma_rsp_fsm ) 
+{
+    std::cout << "  <IOB.DMA_RSP_FIFO_PUT> Push into rsp_fifo:" 
+              << " rsrcid = " << std::dec << r_dma_rsrcid.read()
+              << " rtrdid = " << r_dma_rtrdid.read()
+              << " rdata = " << std::hex << p_vci_ini_dma.rdata.read()
+    << std::endl;
+}
+#endif
+    			
+    	}
+    	break;
+    }
+    //////////////////
+    case DMA_RSP_FIFO_ERROR_PUT:
+    {
+        if(m_dma_rsp_data_fifo.wok())
+    	{
+            dma_rsp_fifo_put = true;
+            r_dma_rsp_fsm = DMA_RSP_IDLE;	
+
+#if DEBUG_DMA_RSP
+if( m_debug_dma_rsp_fsm ) 
+{
+    std::cout << "  <IOB.DMA_RSP_FIFO_ERROR_PUT> Push into rsp_fifo:" 
+              << " rsrcid = " << std::dec << r_iommu_bad_id.read()
+              << " rtrdid = " << r_dma_error_trdid.read()
+              << " rerror = " << r_dma_error_type.read()
+              << " rdata = " << std::hex << 0
+    << std::endl;
+}
+#endif
+    			
+    	}
+    	break;
+    }
+    } // end switch DMA_RSP_FSM 
+
+    ////////////////////////////////////////////////////////////////////////////
+    // The ALLOC_TRT_DMA fsm allocates the access to the Transaction Table (m_transaction_tab_dma)
+    // with a round robin priority between 2 user FSMs :
+    // - DMA_CMD : to set a new entry
+    // - DMA_RSP : to read and erase an entry
+    // The ressource is always allocated.
+    ////////////////////////////////////////////////////////////////////////////
+    
+    switch ( r_alloc_trt_dma_fsm.read() ) 
+    {
+    ///////////////////
+    case ALLOC_TRT_DMA_CMD:
+    {
+        if ( r_dma_cmd_fsm.read() != DMA_CMD_TRT_LOCK ) 
+        {
+          if (r_dma_rsp_fsm.read() == DMA_RSP_TRT_LOCK) r_alloc_trt_dma_fsm = ALLOC_TRT_DMA_RSP;
+        }
+        break;
+    }
+    ///////////////////
+    case ALLOC_TRT_DMA_RSP:
+    {
+        if (r_dma_rsp_fsm.read() != DMA_RSP_TRT_LOCK) 
+        {
+            if (r_dma_cmd_fsm.read() == DMA_CMD_TRT_LOCK) r_alloc_trt_dma_fsm = ALLOC_TRT_DMA_CMD;
+        }
+        break;
+    }
+    } // end switch r_alloc_trt_dma_fsm
+    
+
+    ////////////////////////////////////////////////////////////////////////////
+    // The DMA_TLB_MISS FSM handles an IOTLB miss. It blocks the TGT_FSM.
+    // Input argument is:
+    // - r_iotlb_vaddr
+    // - r_dma_tlb_req (reset)
+    // - r_tlb_miss_init_req (set)
+    // - r_config_tlb_req (reset)
+    // - r_tlb_dma_untreated (set)
+    // 
+    // This fsm searchs the requested PTE on the  prefetch buffer.
+    // In case of miss,  it accesses the XRAM to find the missing TLB entry,
+    // It bypass the first level page table access if possible.
+    // It directly updates the iotlb, and writes into the 
+    // r_mmu_ins_* or r_mmu_data* error reporting registers.
+    ////////////////////////////////////////////////////////////////////////////////////
+    switch (r_dma_tlb_fsm.read())
+    {
+    case DMA_TLB_IDLE:
+    {
+        if(r_config_tlb_req)
+        {
+            r_config_tlb_req = false;
+            r_waiting_transaction = false;
+            r_dma_tlb_fsm = DMA_TLB_INVAL_CHECK;
+        // Request from CONFIG FSM following an PTE invalidation signal by OS
+        }
+        // Miss in IOTLB
+        else if(r_dma_tlb_req.read())   
+        {
+        // Checking prefetch buffer, by the virtual address
+        if(!r_miss_buf_first_level)
+        {
+            if( r_miss_buf_valid &&
+                (r_miss_buf_vaddr_begin.read() == 
+                (r_iotlb_vaddr.read()& ~PTE2_LINE_OFFSET & ~K_PAGE_OFFSET_MASK)))
+            {
+              // Hit
+                size_t pte_offset = (r_iotlb_vaddr.read()& PTE2_LINE_OFFSET)>>12; 
+              
+
+                uint32_t pte_flags = r_miss_buf_data[2*pte_offset];
+                uint32_t pte_ppn = r_miss_buf_data[2*pte_offset+1]; //because PTE2 is 2 words long
+                
+                // Bit valid checking
+                if ( not ( pte_flags & PTE_V_MASK) )	// unmapped
+                {
+                    //must not occur!
+                    std::cout << "IOMMU ERROR : " << name() << " DMA_TLB_IDLE state" << std::endl
+                                  << "The Page Table entry ins't valid (unmapped)" << std::endl;
+                       
+                    r_tlb_error_type          = MMU_READ_PT2_UNMAPPED;
+                    r_dma_tlb_error_req       = true;
+                    r_dma_tlb_req             = false;
+                        
+#if DEBUG_DMA_TLB
+if ( m_debug_dma_tlb_fsm )
+{
+    std::cout << "  <IOB.DMA_TLB_IDLE> PTE2 Unmapped"
+              << std::hex << " / paddr = " << r_iotlb_paddr.read()
+              << std::hex << " / PTE (first word) = " << pte_flags << std::endl;
+}
+#endif
+                    break; 
+                }
+
+                r_iotlb_pte_flags       = pte_flags; 
+                r_iotlb_pte_ppn         = pte_ppn;
+                r_dma_tlb_fsm           = DMA_TLB_PTE2_SELECT;
+                
+#if DEBUG_DMA_TLB
+if ( m_debug_dma_tlb_fsm )
+{
+    std::cout << "  <IOB.DMA_TLB_IDLE> Hit on the prefetch buffer for PTE2:"
+              << " PTE_FLAGS = " << std::hex << pte_flags 
+              << " PTE_PPN = " << std::hex << pte_ppn << std::endl;
+}
+#endif
+                break;    
+            }
+        }
+        else    // First level entries on buffer. Unused if only small pages
+        {
+           if( r_miss_buf_valid &&
+              (r_miss_buf_vaddr_begin.read() == 
+               (r_iotlb_vaddr.read()& ~PTE1_LINE_OFFSET & ~M_PAGE_OFFSET_MASK ))) 
+            // The virtual address corresponds to one entry on the buffer line
+            {
+              // Hit
+                size_t pte_offset = (r_iotlb_vaddr.read()& PTE1_LINE_OFFSET)>>21; 
+              
+                uint32_t pte_flags = r_miss_buf_data[pte_offset];
+                            
+                // Bit valid checking
+                if ( not ( pte_flags & PTE_V_MASK) )	// unmapped
+                {
+                    //must not occur!
+                    std::cout << "IOMMU ERROR " << name() << "DMA_TLB_IDLE state" << std::endl
+                                  << "The Page Table entry ins't valid (unmapped)" << std::endl;
+                       
+                    r_tlb_error_type          = MMU_READ_PT1_UNMAPPED;
+                    r_dma_tlb_error_req       = true;
+                    r_dma_tlb_req             = false;
+                        
+#if DEBUG_DMA_TLB
+if ( m_debug_dma_tlb_fsm )
+{
+    std::cout << "  <IOB.DMA_TLB_IDLE> First level entry Unmapped"
+              << std::hex << " / paddr = " << r_iotlb_paddr.read()
+              << std::hex << " / PTE = " << pte_flags << std::endl;
+}
+#endif
+                    break; 
+                }
+                
+                if( pte_flags & PTE_T_MASK ) 	//  PTD : me must access PT2
+                {
+                    // register bypass
+                    r_iotlb.set_bypass( r_iotlb_vaddr.read(),
+                                      pte_flags & ((1 << (m_paddr_nbits-PAGE_K_NBITS)) - 1), 
+                                     0); //nline, unused 
+
+                    //&PTE2 = PTBA + IX2 * 8
+                    // ps: PAGE_K_NBITS corresponds also to the size of a second level page table
+                    r_iotlb_paddr = (paddr_t)(pte_flags & ((1<<(m_paddr_nbits-PAGE_K_NBITS))-1)) << PAGE_K_NBITS |
+                                  (paddr_t)(((r_iotlb_vaddr.read() & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3);
+                    r_tlb_miss_init_req     = true;
+                    r_tlb_miss_type         = PTE2_MISS;
+                    r_dma_tlb_fsm           = DMA_TLB_WAIT_TRANSACTION;
+#ifdef INSTRUMENTATION
+m_cpt_iotlbmiss_transaction++;
+#endif
+
+#if DEBUG_DMA_TLB
+if ( m_debug_dma_tlb_fsm )
+{
+    std::cout << "  <IOB.DMA_TLB_IDLE> Hit on prefetch, but it is a PTD.Search PTE2"
+              << std::hex << " / paddr = " << r_iotlb_paddr.read()
+              << std::hex << " / PTD = " << pte_flags << std::endl;
+}
+#endif
+                }
+                else			//  PTE1 :  we must update the TLB
+                            //  Should not occur if working only with small pages
+                {
+                    r_iotlb_pte_flags   = pte_flags;
+                    r_dma_tlb_fsm  = DMA_TLB_PTE1_SELECT;
+
+#if DEBUG_DMA_TLB
+if ( m_debug_dma_tlb_fsm )
+{
+    std::cout << "  <IOB.DMA_TLB_PTE1_GET> Success. Big page"
+              << std::hex << " / paddr = " << r_iotlb_paddr.read()
+              << std::hex << " / PTE1 = " << pte_flags << std::endl;
+}
+#endif
+                }
+                break;
+            }
+        }
+       
+        r_dma_tlb_fsm = DMA_TLB_MISS; 
+
+#if DEBUG_DMA_TLB
+if ( m_debug_dma_tlb_fsm )
+{
+    std::cout << "  <IOB.DMA_TLB_IDLE> Miss on prefetch."
+              << std::hex << " / vaddr = " << r_iotlb_vaddr.read() << std::endl;
+}
+#endif
+        }
+        break;
+    }
+    /////////////////////
+    case DMA_TLB_MISS: // handling all tlb miss
+    {
+        uint32_t	ptba = 0; //28 bits en TSAR
+        bool		bypass;
+        paddr_t		pte_paddr;
+
+        // evaluate bypass in order to skip first level page table access
+        bypass = r_iotlb.get_bypass(r_iotlb_vaddr.read(), &ptba);
+        
+        //Request to MISS_INIT_FSM to start transaction on Direct Network       
+        if ( not bypass )     // Read PTE1/PTD1 in XRAM
+        {
+        // VOIR CONVENTION >> 13
+            pte_paddr = (paddr_t)((r_iommu_ptpr.read()) << (INDEX1_NBITS+2)) |
+                        (paddr_t)((r_iotlb_vaddr.read() >> PAGE_M_NBITS) << 2);
+            r_iotlb_paddr = pte_paddr;
+            
+            r_tlb_miss_init_req     = true;
+            r_tlb_miss_type         = PTE1_MISS;
+            r_dma_tlb_fsm           = DMA_TLB_WAIT_TRANSACTION;
+#ifdef INSTRUMENTATION
+m_cpt_iotlbmiss_transaction++;
+#endif
+        }
+        else                  // Read PTE2 in XRAM
+        {
+            //&PTE2 = PTBA + IX2 * 8
+            pte_paddr = (paddr_t)ptba << PAGE_K_NBITS |
+                        (paddr_t)(r_iotlb_vaddr.read()&PTD_ID2_MASK)>>(PAGE_K_NBITS-3);
+            
+            r_iotlb_paddr = pte_paddr;
+            
+            r_tlb_miss_init_req     = true;
+            r_tlb_miss_type         = PTE2_MISS;
+            r_dma_tlb_fsm           = DMA_TLB_WAIT_TRANSACTION;
+#ifdef INSTRUMENTATION
+m_cpt_iotlbmiss_transaction++;
+#endif
+        }
+
+#if DEBUG_DMA_TLB
+if ( m_debug_dma_tlb_fsm )
+{
+    std::cout << "  <IOB.DMA_TLB_MISS> IOTLB miss";
+    std::cout << " / VADDR = " << std::hex << r_iotlb_vaddr.read()
+              << " / BYPASS = " << bypass 
+              << " / PTE_ADR = " << pte_paddr << std::endl;
+}
+#endif
+  
+        break;
+    }
+    /////////////////////////  
+    case DMA_TLB_PTE1_GET:	// Try to read a PT1 entry in the miss buffer
+    {
+        
+        uint32_t  entry;
+        
+        paddr_t line_number  = (paddr_t)((r_iotlb_paddr.read())&(CACHE_LINE_MASK));
+        size_t word_position = (size_t)( ((r_iotlb_paddr.read())&(~CACHE_LINE_MASK))>>2 );
+
+        // Hit test. Just to verify. 
+        // Hit must happen, since we've just finished its' miss transaction
+        bool hit = (r_miss_buf_valid && (r_miss_buf_tag.read()== line_number) ); 
+        assert(hit and "Error: No hit on prefetch buffer after Miss Transaction"); 
+        
+        entry = r_miss_buf_data[word_position];
+            
+        // Bit valid checking
+        if ( not ( entry & PTE_V_MASK) )	// unmapped
+        {
+            //must not occur!
+            std::cout << "IOMMU ERROR " << name() << "DMA_TLB_IDLE state" << std::endl
+                      << "The Page Table entry ins't valid (unmapped)" << std::endl;
+                       
+            r_tlb_error_type          = MMU_READ_PT1_UNMAPPED;
+            r_dma_tlb_error_req       = true;
+            r_dma_tlb_req             = false;
+            r_dma_tlb_fsm             = DMA_TLB_IDLE;            
+#if DEBUG_DMA_TLB
+if ( m_debug_dma_tlb_fsm )
+{
+    std::cout << "  <IOB.DMA_PTE1_GET> First level entry Unmapped"
+              << std::hex << " / paddr = " << r_iotlb_paddr.read()
+              << std::hex << " / PTE = " << entry << std::endl;
+}
+#endif
+                    break; 
+        }
+    
+        if( entry & PTE_T_MASK ) 	//  PTD : me must access PT2
+        {
+            // register bypass
+            r_iotlb.set_bypass( r_iotlb_vaddr.read(),
+                                entry & ((1 << (m_paddr_nbits-PAGE_K_NBITS)) - 1), 
+                                0); //nline, unused 
+
+            //&PTE2 = PTBA + IX2 * 8
+            // ps: PAGE_K_NBITS corresponds also to the size of a second level page table
+            r_iotlb_paddr = (paddr_t)(entry & ((1<<(m_paddr_nbits-PAGE_K_NBITS))-1)) << PAGE_K_NBITS |
+                                (paddr_t)(((r_iotlb_vaddr.read() & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3);
+            r_tlb_miss_init_req     = true;
+            r_tlb_miss_type         = PTE2_MISS;
+            r_dma_tlb_fsm           = DMA_TLB_WAIT_TRANSACTION;
+#ifdef INSTRUMENTATION
+m_cpt_iotlbmiss_transaction++;
+#endif
+
+#if DEBUG_DMA_TLB
+if ( m_debug_dma_tlb_fsm )
+{
+    std::cout << "  <IOB.DMA_TLB_PTE1_GET> Success. Search PTE2"
+              << std::hex << " / paddr = " << r_iotlb_paddr.read()
+              << std::hex << " / PTD = " << entry << std::endl;
+}
+#endif
+        }
+        else			//  PTE1 :  we must update the IOTLB
+                        //  Should not occur if working only with small pages
+        {
+            r_iotlb_pte_flags   = entry;
+            r_dma_tlb_fsm  = DMA_TLB_PTE1_SELECT;
+
+#if DEBUG_DMA_TLB
+if ( m_debug_dma_tlb_fsm )
+{
+    std::cout << "  <IOB.DMA_TLB_PTE1_GET> Success. Big page"
+              << std::hex << " / paddr = " << r_iotlb_paddr.read()
+              << std::hex << " / PTE1 = " << entry << std::endl;
+}
+#endif
+        }
+        
+        break;
+    }
+    ////////////////////////////
+    case DMA_TLB_PTE1_SELECT:	// select a slot for PTE1 
+    {
+        size_t 	way;
+        size_t 	set;
+        
+        r_iotlb.select(  r_iotlb_vaddr.read(),
+                        true,  // PTE1 
+                        &way,
+                        &set );
+#ifdef INSTRUMENTATION
+m_cpt_iotlb_read++;
+#endif
+
+#if DEBUG_DMA_TLB
+if ( m_debug_dma_tlb_fsm )
+{
+    std::cout << "  <IOB.DMA_TLB_PTE1_SELECT> Select a slot in IOTLB:";
+    std::cout << " way = " << std::dec << way
+                  << " / set = " << set << std::endl;
+}
+#endif
+        r_iotlb_way = way;
+        r_iotlb_set = set;
+        r_dma_tlb_fsm     = DMA_TLB_PTE1_UPDT;
+        break;
+    }
+    //////////////////////////
+    case DMA_TLB_PTE1_UPDT:     // write a new PTE1 in tlb
+                                // not necessary to treat the L/R bit
+    {
+        //(OLD) paddr_t	  nline = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2);   
+        uint32_t  pte   = r_iotlb_pte_flags.read();
+        
+        r_miss_paddr = (paddr_t)( ((r_iotlb_pte_flags.read() & PPN1_MASK) << 21)
+                        | (r_iotlb_vaddr.read()& M_PAGE_OFFSET_MASK) );
+        
+        // update TLB
+        r_iotlb.write( true,		// 2M page
+                      pte,
+                      0,		// argument unused for a PTE1
+                      r_iotlb_vaddr.read(),    
+                      r_iotlb_way.read(), 
+                      r_iotlb_set.read(),
+                      0 );      //we set nline = 0
+#ifdef INSTRUMENTATION
+m_cpt_iotlb_write++;
+#endif
+
+#if DEBUG_DMA_TLB
+if ( m_debug_dma_tlb_fsm )
+{
+    std::cout   << "  <IOB.DMA_TLB_PTE1_UPDT> write PTE1 in IOTLB";
+    std::cout   << " / set = " << std::dec << r_iotlb_set.read()
+                << " / way = " << r_iotlb_way.read() << std::endl;
+    r_iotlb.printTrace();
+}
+#endif
+        // next state
+        r_dma_tlb_fsm = DMA_TLB_RETURN;	// exit sub-fsm
+        break;
+    }
+    /////////////////////////
+    case DMA_TLB_PTE2_GET:	// Try to read a PTE2 (64 bits) in the miss buffer
+    {    
+        uint32_t 	pte_flags;
+        uint32_t 	pte_ppn;
+        
+        paddr_t line_number  = (paddr_t)((r_iotlb_paddr.read())&(CACHE_LINE_MASK));
+        size_t word_position = (size_t)( ((r_iotlb_paddr.read())&(~CACHE_LINE_MASK))>>2 );
+        
+        
+        // Hit test. Just to verify.
+        bool hit = (r_miss_buf_valid && (r_miss_buf_tag.read()== line_number) ); 
+        assert(hit and "Error: No hit on prefetch buffer after Miss Transaction"); 
+        pte_flags= r_miss_buf_data[word_position];
+        pte_ppn= r_miss_buf_data[word_position+1]; //because PTE2 is 2 words long
+        // Bit valid checking
+        if ( not ( pte_flags & PTE_V_MASK) )	// unmapped
+        {
+            //must not occur!
+            std::cout << "IOMMU ERROR " << name() << "DMA_TLB_IDLE state" << std::endl
+                      << "The Page Table entry ins't valid (unmapped)" << std::endl;
+                       
+            r_tlb_error_type          = MMU_READ_PT2_UNMAPPED;
+            r_dma_tlb_error_req       = true;
+            r_dma_tlb_req             = false;
+            r_dma_tlb_fsm             = DMA_TLB_IDLE;            
+#if DEBUG_DMA_TLB
+if ( m_debug_dma_tlb_fsm )
+{
+    std::cout << "  <IOB.DMA_TLB_PTE2_GET> PTE2 Unmapped"
+              << std::hex << " / paddr = " << r_iotlb_paddr.read()
+              << std::hex << " / PTE = " << pte_flags << std::endl;
+}
+#endif
+                    break; 
+        }
+            
+        r_iotlb_pte_flags       = pte_flags; 
+        r_iotlb_pte_ppn         = pte_ppn;
+        r_dma_tlb_fsm           = DMA_TLB_PTE2_SELECT;
+                
+#if DEBUG_DMA_TLB
+if ( m_debug_dma_tlb_fsm )
+{
+    std::cout << "  <IOB.DMA_TLB_PTE2_GET> Mapped:"
+              << " PTE_FLAGS = " << std::hex << pte_flags 
+              << " PTE_PPN = " << std::hex << pte_ppn << std::endl;
+}
+#endif
+        break;
+    }
+    ////////////////////////////
+    case DMA_TLB_PTE2_SELECT:    // select a slot for PTE2
+    {
+        size_t way;
+        size_t set;
+
+        r_iotlb.select( r_iotlb_vaddr.read(),
+                        false,	// PTE2 
+                        &way,
+                        &set );
+#ifdef INSTRUMENTATION
+m_cpt_iotlb_read++;
+#endif
+
+#if DEBUG_DMA_TLB
+if ( m_debug_dma_tlb_fsm )
+{
+        std::cout << "  <IOB.DMA_TLB_PTE2_SELECT> Select a slot in IOTLB:";
+        std::cout << " way = " << std::dec << way
+                  << " / set = " << set << std::endl;
+}
+#endif
+        r_iotlb_way = way;
+        r_iotlb_set = set;
+        r_dma_tlb_fsm     = DMA_TLB_PTE2_UPDT;
+        break;
+    }
+    //////////////////////////
+    case DMA_TLB_PTE2_UPDT:      	// write a new PTE2 in tlb
+                                    // not necessary to treat the L/R bit
+    {
+        //(OLD) paddr_t	        nline     = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2);   
+        uint32_t        pte_flags = r_iotlb_pte_flags.read();
+        uint32_t        pte_ppn   = r_iotlb_pte_ppn.read();
+        
+        r_miss_paddr = (paddr_t)( ((r_iotlb_pte_ppn.read() & PPN2_MASK) << 12)
+                        | (r_iotlb_vaddr.read()& K_PAGE_OFFSET_MASK) );
+        
+        // update TLB for a PTE2
+        r_iotlb.write( false,	// 4K page
+                       pte_flags,
+                       pte_ppn,
+                       r_iotlb_vaddr.read(),    
+                       r_iotlb_way.read(), 
+                       r_iotlb_set.read(),
+                       0 );     // nline = 0
+#ifdef INSTRUMENTATION
+m_cpt_iotlb_write++;
+#endif
+
+#if DEBUG_DMA_TLB
+if ( m_debug_dma_tlb_fsm )
+{
+        std::cout << "  <IOB.DMA_TLB_PTE2_UPDT> write PTE2 in IOTLB";
+        std::cout << " / set = " << std::dec << r_iotlb_set.read()
+                  << " / way = " << r_iotlb_way.read() << std::endl;
+        r_iotlb.printTrace();
+}
+#endif
+        // next state
+        r_dma_tlb_fsm = DMA_TLB_RETURN;	// exit sub-fsm
+        break;
+    }
+    ///////////////////////
+    case DMA_TLB_WAIT_TRANSACTION:
+    {
+        // CONFIG FSM request following a invalidation signal sent by OS.
+        if(r_config_tlb_req)
+        {
+            r_config_tlb_req = false;
+            r_waiting_transaction = true;
+            r_dma_tlb_fsm = DMA_TLB_INVAL_CHECK;
+        }
+
+#ifdef INSTRUMENTATION
+m_cost_iotlbmiss_transaction++;
+#endif
+        if ( not r_tlb_miss_init_req )	//  Miss transaction is done 
+        { 
+	        if ( r_miss_init_error.read() ) // bus error 
+	        {
+                r_miss_init_error  = false;
+                r_tlb_error_type    = MMU_READ_DATA_ILLEGAL_ACCESS;
+                r_dma_tlb_error_req     = true;
+                r_dma_tlb_req           = false;
+                r_dma_tlb_fsm = DMA_TLB_IDLE;
+            }
+            else if(r_tlb_miss_type == PTE1_MISS)
+            {
+                r_dma_tlb_fsm = DMA_TLB_PTE1_GET; 
+        
+            }
+            else
+            {
+                r_dma_tlb_fsm = DMA_TLB_PTE2_GET;
+            }
+        }
+        break;
+    }
+    ///////////////////////
+    case DMA_TLB_RETURN:		// return to caller depending on tlb miss type
+    {
+#if DEBUG_DMA_TLB
+if ( m_debug_dma_tlb_fsm )
+{
+    std::cout << "  <IOB.DMA_TLB_RETURN> IOTLB MISS completed" << std::endl;
+}
+#endif
+        r_dma_tlb_req = false;
+        r_tlb_dma_untreated = true;
+        r_dma_tlb_fsm = DMA_TLB_IDLE;
+        break;
+    }
+    //////////////////////
+    case DMA_TLB_INVAL_CHECK:   // request from CONFIG FSM to invalidate all PTE on a given line
+                                // This state checks the necessity to invalidate prefetch buffer
+    {
+        // If a transaction is pending, no need to invalidate the prefetch
+        // We can ignore it, since we'll replace the line.
+        // The new line is necessarily up-to-date
+        if(!r_waiting_transaction.read() && r_miss_buf_valid)
+        {
+            if(!r_miss_buf_first_level)
+            {
+               if( r_miss_buf_vaddr_begin.read() == 
+                   (r_config_tlb_inval_vaddr.read()& ~PTE2_LINE_OFFSET) ) 
+                // The virtual address corresponds to one entry on the buffer line
+                {
+                    r_miss_buf_valid = false;   //change here for individual invalidation
+                }
+            }
+            else    // First level entries on buffer. Unused if only small pages
+            {
+               if( r_miss_buf_vaddr_begin.read() == 
+                   (r_config_tlb_inval_vaddr.read()& ~PTE1_LINE_OFFSET) ) 
+                // The virtual address corresponds to one entry on the buffer line
+                {
+                    r_miss_buf_valid = false;   //change here for individual invalidation
+                }
+            }
+        }
+        
+        // Invalidation on IOTLB
+        bool    ok;
+        ok = r_iotlb.inval(r_config_tlb_inval_vaddr.read());
+         
+        if(r_waiting_transaction.read()) r_dma_tlb_fsm =DMA_TLB_WAIT_TRANSACTION; 
+        else r_dma_tlb_fsm = DMA_TLB_IDLE;
+        break; 
+    }
+    } //end switch r_dma_tlb_fsm
+    
+    
+    /////////////////////////////////////////////////////////////////////
+    // The CONFIG_CMD_FSM is similar to the DMA_CMD_FSM, but without miss TLB treatmentcontrols the following ressources:
+    // - r_config_cmd_fsm
+    //
+    // - r_config_cmd_rsp_erase_req (set)
+    // - r_config_tlb_req (set)
+    /////////////////////////////////////////////////////////////////////
+
+    switch( r_config_cmd_fsm.read() ) 
+    {
+    //////////////
+    case CONFIG_CMD_IDLE:
+    {
+        if ( p_vci_tgt_config.cmdval.read() ) 
+        {
+#if DEBUG_CONFIG_CMD
+if( m_debug_config_cmd_fsm )
+{
+    std::cout << "  <IOB.CONFIG_CMD_IDLE> Configuration command received!" <<std::endl;
+    std::cout << " address = " << std::hex << p_vci_tgt_config.address.read()
+              << " srcid = " << std::dec << p_vci_tgt_config.srcid.read()
+              << " trdid = " << p_vci_tgt_config.trdid.read()
+              << " wdata = " << std::hex << p_vci_tgt_config.wdata.read()
+              << " be = " << p_vci_tgt_config.be.read()
+              << " plen = " << std::dec << p_vci_tgt_config.plen.read() << std::endl;
+}
+#endif
+            paddr_t config_paddr = p_vci_tgt_config.address.read();
+   
+//           // Just to verify 
+//           if(! m_locality_table_config[config_paddr] ) //cannot receive remote packets
+//           {
+//           std::cout << "IOB ERROR " << name() << " CONFIG_CMD_IDLE state" << std::endl
+//                         << "Received a remote packet" << std::endl;
+//               exit(0);
+//           }
+
+            bool read = (p_vci_tgt_config.cmd.read() == vci_param_d::CMD_READ);
+            
+            uint32_t              cell    = (uint32_t)((config_paddr & 0x1FF)>>2); 
+            
+            // Treatement of received command
+            // Verifies error, tests if the the command is for IOB itself 
+ 
+            // To IOB itself
+            if(m_segment_config.contains(config_paddr))
+            {
+                if(!read && (cell == IOB_IOMMU_PTPR)) 
+                    r_config_cmd_fsm = CONFIG_CMD_PTPR_WRITE;
+                else if(read && (cell == IOB_IOMMU_PTPR)) 
+                    r_config_cmd_fsm = CONFIG_CMD_PTPR_READ;
+                else if(!read && (cell == IOB_IOMMU_ACTIVE)) 
+                    r_config_cmd_fsm = CONFIG_CMD_ACTIVE_WRITE;
+                else if(read && (cell == IOB_IOMMU_ACTIVE)) 
+                    r_config_cmd_fsm = CONFIG_CMD_ACTIVE_READ;
+                else if(read && (cell == IOB_IOMMU_BVAR)) 
+                    r_config_cmd_fsm = CONFIG_CMD_BVAR_READ;
+                else if(read && (cell == IOB_IOMMU_ETR)) 
+                    r_config_cmd_fsm = CONFIG_CMD_ETR_READ;
+                else if(read && (cell == IOB_IOMMU_BAD_ID)) 
+                    r_config_cmd_fsm = CONFIG_CMD_BAD_ID_READ;
+                // PTE invalidation signaled by the OS
+                else if(!read && (cell == IOB_INVAL_PTE))
+                    r_config_cmd_fsm = CONFIG_CMD_INVAL_REQ;
+                else if(!read && (cell == IOB_IT_ADDR_IOMMU_LO)) 
+                    r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1;
+                else if(read && (cell == IOB_IT_ADDR_IOMMU_LO)) 
+                    r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_IOMMU_READ_1;
+                else if( !read && ((cell >= IOB_IT_ADDR_BEGIN)&&
+                        ( cell< (IOB_IT_ADDR_BEGIN +2*m_nb_periph-1) ) ) )
+                {
+                    // a factor two shows up because the registres come in couples
+                    r_it_index = (cell - IOB_IT_ADDR_BEGIN)/2;
+                    r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_WRITE_1;
+                } 
+                else if( read && ((cell >= IOB_IT_ADDR_BEGIN)&&
+                        (cell< (IOB_IT_ADDR_BEGIN +2*m_nb_periph-1))) ) 
+                {
+                    r_it_index = (cell - IOB_IT_ADDR_BEGIN)/2;
+                    r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_READ_1;
+                }
+                else
+                //Error. Wrong address, or invalid operation.
+                {
+                    if(read)    r_config_error_type = READ_ERROR;
+                    else        r_config_error_type = WRITE_ERROR;
+                    r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
+                }
+            }
+            // Must route the command to the correct IO
+            else
+            {
+                if(!p_vci_tgt_config.eop.read())
+                {
+                    //Error
+                    if(read)    r_config_error_type = READ_ERROR;
+                    else        r_config_error_type = WRITE_ERROR;
+                    r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
+                }
+                
+                // Find the corresponding address on IO Space
+//                int tgt_index = m_routing_table_config[config_paddr];
+//#if DEBUG_CONFIG_CMD
+//if( m_debug_config_cmd_fsm )
+//{
+//    std::cout << "  <IOB.CONFIG_CMD_IDLE> Routing a configuration packet" <<std::endl
+//            << "Target Index on Direct NoC: " << tgt_index << std::endl;
+//}
+//#endif
+//                soclib::common::Segment io_segment = m_mtio.getSegment(IntTab(tgt_index));
+//               #define L2 soclib::common::uint32_log2 
+//               paddr_t offset_mask = ( (1 << L2(io_segment.size())) - 1);
+//               #undef L2
+//               r_config_vaddr = (vaddr_t)( io_segment.baseAddress() | 
+//                               (vaddr_t)(config_paddr & offset_mask) ); 
+                
+                // TODO So far, it is in identity mapping
+                r_config_vaddr = (vaddr_t) config_paddr ; 
+                r_config_cmd_fsm	= CONFIG_CMD_TRT_LOCK;
+
+            }
+
+
+        } // end if cmdval
+        break;
+    }
+    /////////////////////////
+    case CONFIG_CMD_TRT_LOCK: // Waiting for the lock to modify Transaction Table
+    {
+        if ( r_alloc_trt_config_fsm.read() == ALLOC_TRT_CONFIG_CMD ) 
+        {
+
+#if DEBUG_CONFIG_CMD
+if( m_debug_config_cmd_fsm )
+{
+    std::cout << "  <IOB.CONFIG_CMD_TRT_LOCK> Check the TRT" << std::endl;
+}
+#endif
+            size_t 		wok_index = 0;
+            bool 		wok       = !m_transaction_tab_config.full(wok_index);
+
+            if ( wok ) 	// TRT isn't full. Write the new transaction. 
+            {
+                r_config_cmd_trt_index = (vci_trdid_t)wok_index;
+                r_config_cmd_fsm       = CONFIG_CMD_TRT_SET;
+            } 
+            else 		// wait an empty entry in TRT
+            {
+                r_config_cmd_fsm       = CONFIG_CMD_TRT_WAIT;
+                r_config_cmd_rsp_erase_req = true;
+#if DEBUG_CONFIG_CMD
+if( m_debug_config_cmd_fsm )
+{
+    std::cout << "  <IOB.CONFIG_CMD_TRT_LOCK> TRT is full. Going to TRT_WAIT state" << std::endl;
+}
+#endif
+            
+#ifdef INSTRUMENTATION        
+m_cpt_trt_config_full++;
+#endif
+            }
+        }
+        break;
+    }
+    ////////////////
+    case CONFIG_CMD_TRT_WAIT:	// release the lock protecting the transaction tab
+                                // waits that RSP erases an entry 
+    { 
+#ifdef INSTRUMENTATION        
+m_cpt_trt_config_full_cost++;
+#endif
+        // CONFIG_RSP will notify an erase action by reseting this register
+        if(!r_config_cmd_rsp_erase_req.read())
+        {
+            r_config_cmd_fsm = CONFIG_CMD_TRT_LOCK; // take the lock again
+        }
+        break;
+    }
+    ////////////////////////
+    case CONFIG_CMD_TRT_SET:	// register a new transaction in TRT
+    {  
+        if ( r_alloc_trt_config_fsm.read() == ALLOC_TRT_CONFIG_CMD ) 
+        {
+            m_transaction_tab_config.set(   r_config_cmd_trt_index.read(),
+                                            p_vci_tgt_config.srcid.read(), 
+                                            p_vci_tgt_config.trdid.read() );
+            
+            r_config_cmd_fsm = CONFIG_CMD_FIFO_PUT;
+#if DEBUG_CONFIG_CMD
+if( m_debug_config_cmd_fsm )
+{
+    std::cout << "  <IOB.CONFIG_CMD_TRT_SET> Set a new entry in TRT" << std::endl;
+}
+#endif
+        }
+        break;
+    }  
+    ///////////////////////
+    case CONFIG_CMD_FIFO_PUT:	 
+    {
+        if ( p_vci_tgt_config.cmdval && m_config_cmd_addr_fifo.wok() ) 
+        {
+            config_cmd_fifo_put = true;
+            if(  p_vci_tgt_config.eop )    r_config_cmd_fsm = CONFIG_CMD_IDLE;
+           
+#if DEBUG_CONFIG_CMD
+if( m_debug_config_cmd_fsm ) 
+{
+    std::cout << "  <IOB.CONFIG_CMD_FIFO_PUT> Push into config_cmd_fifo:" 
+              << " address = " << std::hex << r_config_vaddr.read()
+              << " srcid = " << std::dec << m_srcid_config
+              << " trdid = " << r_config_cmd_trt_index.read()
+              << " wdata = " << std::hex << p_vci_tgt_config.wdata.read()
+              << " be = " << p_vci_tgt_config.be.read()
+              << " plen = " << std::dec << p_vci_tgt_config.plen.read() << std::endl;
+}
+#endif
+        }
+        break;
+    }
+    
+    ///////////////////////////////
+    // Private Configuration States
+    ///////////////////////////////
+
+    //////////////////
+    case CONFIG_CMD_PTPR_WRITE: // Convention- The word received is in the format:
+                                // 00000 BASE_ADDRESS[39:13]
+                                // Same pattern as in iommu_ptpr register
+    {
+        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok()
+            && r_dma_tlb_fsm == DMA_TLB_IDLE )
+        {
+            // This verification could have been done on IDLE state
+            // It would save us one cycle 
+            if ( !p_vci_tgt_config.eop.read() )
+            {
+                std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_PTPR_WRITE state" << std::endl;
+                std::cout << " PTPR write command must contain one single flit" << std::endl;
+                r_config_error_type = WRITE_ERROR;
+                r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
+                break;
+            }
+            
+            // Depends on the convention
+            r_iommu_ptpr = (uint32_t)(p_vci_tgt_config.wdata.read()); 
+            
+            config_local_fifo_put = true;
+            r_config_cmd_fsm = CONFIG_CMD_IDLE;
+
+#if DEBUG_CONFIG_CMD
+if( m_debug_config_cmd_fsm ) 
+{
+    std::cout << "  <IOB.CONFIG_CMD_PTPR_WRITE> PTPR received:" 
+              << "r_iommu_ptpr = " << std::hex << (p_vci_tgt_config.wdata.read())
+              <<std::endl;
+}
+#endif
+        } 
+        break;
+    }
+    /////////////////////
+    case CONFIG_CMD_ACTIVE_WRITE: 
+    {
+        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok() 
+            && r_dma_tlb_fsm == DMA_TLB_IDLE )
+        {
+            // This verification could have been done on IDLE state
+            // It would save us one cycle 
+            if ( !p_vci_tgt_config.eop.read() )
+            {
+                std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_ACTIVE_WRITE state" << std::endl;
+                std::cout << " ACTIVE write command must contain one single flit" << std::endl;
+                r_config_error_type = WRITE_ERROR;
+                r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
+                break;
+            }
+            
+            r_iommu_active = (p_vci_tgt_config.wdata.read() != 0);
+            
+            config_local_fifo_put = true;
+            r_config_cmd_fsm = CONFIG_CMD_IDLE;
+        } 
+        break;
+    }
+    ///////////////////
+    case CONFIG_CMD_INVAL_REQ: // Blocks in case of untreated request
+    {   
+        if ( !r_config_tlb_req.read() )
+        {
+            r_config_tlb_req = true;     
+            r_config_cmd_fsm = CONFIG_CMD_INVAL;
+        } 
+        break;
+    }
+    ///////////////////
+    case CONFIG_CMD_INVAL: // Consuming the 32bit Virtual Address of the invalidated page
+    {
+        if ( p_vci_tgt_config.cmdval.read() && 
+                m_config_local_data_fifo.wok() ) 
+        {
+            
+            if ( !p_vci_tgt_config.eop.read() )
+            {
+                std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_INVAL state" << std::endl;
+                std::cout << " PTE invalidation commands must contain one single flit" << std::endl;
+                r_config_error_type = WRITE_ERROR;
+                r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
+                break;
+            }
+            
+            assert( (p_vci_tgt_config.wdata.read()& K_PAGE_OFFSET_MASK) == 0 
+                    and " Error : Invalid format for Page Virtual Address. At least the 12 LSB bits must be zero");
+
+            r_config_tlb_inval_vaddr = (vaddr_t)(p_vci_tgt_config.wdata.read());
+             
+            config_local_fifo_put = true;
+            r_config_cmd_fsm = CONFIG_CMD_IDLE;
+        } 
+        break;
+    }
+    //////////////////
+    case CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1: 
+    {
+        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok())
+        {
+            if(vci_param_d::N <= 32)
+            {
+            // address holds in one single flit
+                if (!p_vci_tgt_config.eop.read() )
+                {
+                    
+                    std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1 state" << std::endl;
+                    std::cout << " PTE invalidation command should contain just one flit" << std::endl;
+                    r_config_error_type = WRITE_ERROR;
+                    r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT;
+                }
+                else
+                {
+                    // If physical address holds on a single word
+                    r_it_addr[r_it_index.read()] = (paddr_t)(p_vci_tgt_config.wdata.read()); 
+                 
+                    config_local_fifo_put = true; 
+                    r_config_cmd_fsm = CONFIG_CMD_IDLE;
+                }
+        
+            }
+            else
+            {
+            // two flits are required to send address
+                if ( p_vci_tgt_config.eop.read() )
+                {
+                    
+                    std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1 state" << std::endl;
+                    std::cout << " PTE invalidation commands should contain two flits" << std::endl;
+                    r_config_error_type = WRITE_ERROR;
+                    r_config_cmd_fsm = CONFIG_CMD_ERROR_RSP;
+                }
+                else
+                {
+                    r_config_first_word = p_vci_tgt_config.wdata.read(); 
+                    r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_IOMMU_WRITE_2;
+                }
+            }
+        } 
+        break;
+    }
+    /////////////////
+    case CONFIG_CMD_IT_ADDR_IOMMU_WRITE_2: 
+    {
+        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok() )
+        {
+            if ( !p_vci_tgt_config.eop.read() )
+            {
+                std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_IOMMU_WRITE_2 state" << std::endl;
+                std::cout << " PTE invalidation commands must contain two flits" << std::endl;
+                r_config_error_type = WRITE_ERROR;
+                r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
+                break;
+            }
+            
+            // Depends on the convention
+            size_t mask_msb = (1 << (vci_param_d::N - 32)) - 1 ;
+            r_it_addr_iommu = (paddr_t)(r_config_first_word.read() |
+                                   ((p_vci_tgt_config.wdata.read()& mask_msb)<<32)); 
+             
+            config_local_fifo_put = true;
+            r_config_cmd_fsm = CONFIG_CMD_IDLE;
+        } 
+    }
+    //////////////////
+    case CONFIG_CMD_IT_ADDR_WRITE_1: 
+    {
+        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok())
+        {
+            if(vci_param_d::N <= 32)
+            {
+            // address holds in one single flit
+                if (!p_vci_tgt_config.eop.read() )
+                {
+                    
+                    std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_ADDR_WRITE_1 state" << std::endl;
+                    std::cout << " PTE invalidation command should contain just one flit" << std::endl;
+                    r_config_error_type = WRITE_ERROR;
+                    r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT;
+                    
+                   
+                }
+                else
+                {
+                    // If physical address holds on a single word
+                    r_it_addr[r_it_index.read()] = (paddr_t)(p_vci_tgt_config.wdata.read()); 
+                 
+                    config_local_fifo_put = true; 
+                    r_config_cmd_fsm = CONFIG_CMD_IDLE;
+                }
+        
+            }
+            else
+            {
+            // two flits are required to send address
+                if ( p_vci_tgt_config.eop.read() )
+                {
+                    
+                    std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_ADDR_WRITE_1 state" << std::endl;
+                    std::cout << " PTE invalidation commands should contain two flits" << std::endl;
+                    r_config_error_type = WRITE_ERROR;
+                    r_config_cmd_fsm = CONFIG_CMD_ERROR_RSP;
+                }
+                else
+                {
+                    r_config_first_word = p_vci_tgt_config.wdata.read();
+                    r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_WRITE_2;
+                }
+            } 
+        } 
+        break;
+    }
+    /////////////////
+    case CONFIG_CMD_IT_ADDR_WRITE_2: 
+    {
+        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok() )
+        {
+            if ( !p_vci_tgt_config.eop.read() )
+            {
+                std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_ADDR_WRITE_2 state" << std::endl;
+                std::cout << " PTE invalidation commands must contain two flits" << std::endl;
+                r_config_error_type = WRITE_ERROR;
+                r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
+                break;
+            }
+            
+            // Depends on the convention
+            size_t mask_msb = (1 << (vci_param_d::N - 32)) - 1 ;
+            r_it_addr[r_it_index.read()] = (paddr_t)(r_config_first_word.read() |
+                                ((p_vci_tgt_config.wdata.read()& mask_msb)<<32)); 
+             
+            config_local_fifo_put = true;
+            r_config_cmd_fsm = CONFIG_CMD_IDLE;
+        } 
+    }
+    //////////////////
+    case CONFIG_CMD_PTPR_READ: 
+    case CONFIG_CMD_ACTIVE_READ:
+    case CONFIG_CMD_BVAR_READ:
+    case CONFIG_CMD_ETR_READ:
+    case CONFIG_CMD_BAD_ID_READ:
+    case CONFIG_CMD_IT_ADDR_IOMMU_READ_1:
+    case CONFIG_CMD_IT_ADDR_READ_1:
+    {
+        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok() )
+        {
+            // This verification could have been done on IDLE state
+            // It would save us one cycle 
+            if ( !p_vci_tgt_config.eop.read() )
+            {
+                std::cout << "CONFIG_CMD ERROR " << name() << config_cmd_fsm_state_str[r_config_cmd_fsm.read()] << std::endl;
+                std::cout << " Read commands must contain one single flit" << std::endl;
+                r_config_error_type = READ_ERROR;
+                r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 
+                break;
+            }
+            
+            // fifo data receives the content of the corresponding register 
+            // (depending on the current state) 
+            config_local_fifo_put = true;
+            if(r_config_cmd_fsm.read()== CONFIG_CMD_IT_ADDR_READ_1)
+            r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_READ_2;
+            else if(r_config_cmd_fsm.read()== CONFIG_CMD_IT_ADDR_IOMMU_READ_1)
+            r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_IOMMU_READ_2;
+            else
+            r_config_cmd_fsm = CONFIG_CMD_IDLE;
+        } 
+        break;
+    }
+    //////////////////
+    case CONFIG_CMD_IT_ADDR_READ_2:
+    case CONFIG_CMD_IT_ADDR_IOMMU_READ_2:
+    {
+        if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok() )
+        {
+            config_local_fifo_put = true;
+            r_config_cmd_fsm = CONFIG_CMD_IDLE;
+        } 
+    }
+    //////////////////
+    case CONFIG_CMD_ERROR_WAIT: //receives the other flits of the same transaction
+    {
+        if ( p_vci_tgt_config.cmdval.read() && p_vci_tgt_config.eop.read() ) 
+        r_config_cmd_fsm = CONFIG_CMD_ERROR_RSP; 
+    }
+    ///////////////////
+    case CONFIG_CMD_ERROR_RSP:
+    {
+        if ( m_config_local_data_fifo.wok() )
+        {
+            config_local_fifo_put = true;
+            r_config_cmd_fsm = CONFIG_CMD_IDLE;
+        }
+        break;
+    }
+
+    } // end switch CONFIG_CMD FSM
+
+    /////////////////////////////////////////////////////////////////////
+    // The CONFIG_RSP_FSM controls the following ressources:
+    // - r_config_rsp_fsm
+    // - r_config_cmd_rsp_erase_req (reset) 
+    // - 
+    // - 
+    //////////////////////////////////////////////////////////////////////////////
+    switch( r_config_rsp_fsm.read() ) 
+    {
+    /////////////////////
+    case CONFIG_RSP_IDLE:
+    {    	
+        if(p_vci_ini_config.rspval.read()) 
+		{
+            r_config_rsp_fsm = CONFIG_RSP_TRT_LOCK;
+		}
+		break;
+    }
+    /////////////////////
+    case CONFIG_RSP_TRT_LOCK:
+    {    	
+        if ( r_alloc_trt_config_fsm.read() == ALLOC_TRT_CONFIG_RSP ) 
+        {
+            
+#if DEBUG_CONFIG_RSP
+if( m_debug_config_rsp_fsm )
+{
+    std::cout << "  <IOB.CONFIG_RSP_TRT_LOCK> Read and erase entry" << std::endl;
+}
+#endif
+            uint32_t trdid_iospace = p_vci_ini_config.rtrdid.read(); 
+            
+            r_config_rsrcid = (vci_srcid_t)m_transaction_tab_config.readSrcid(trdid_iospace);
+            r_config_rtrdid = (vci_trdid_t)m_transaction_tab_config.readTrdid(trdid_iospace);
+            m_transaction_tab_config.erase(trdid_iospace);
+            if (r_config_cmd_rsp_erase_req.read()) r_config_cmd_rsp_erase_req = false;
+            r_config_rsp_fsm       = CONFIG_RSP_FIFO_PUT;
+        }        
+		break;
+    }
+    //////////////////
+    case CONFIG_RSP_FIFO_PUT:
+    {
+        if(p_vci_ini_config.rspval.read() && m_config_rsp_data_fifo.wok())
+    	{
+            config_rsp_fifo_put = true;
+            if(p_vci_ini_config.reop.read())   r_config_rsp_fsm = CONFIG_RSP_IDLE;	
+
+#if DEBUG_CONFIG_RSP
+if( m_debug_config_rsp_fsm ) 
+{
+    std::cout << "  <IOB.CONFIG_RSP_FIFO_PUT> Push into rsp_fifo:" 
+              << " rsrcid = " << std::dec << r_config_rsrcid.read()
+              << " rtrdid = " << r_config_rtrdid.read()
+              << " rdata = " << std::hex << p_vci_ini_config.rdata.read()
+    << std::endl;
+}
+#endif
+    			
+    	}
+    	break;
+    }
+    } // end switch CONFIG_RSP FSM
+
+
+    ////////////////////////////////////////////////////////////////////////////
+    // The ALLOC_TRT_CONFIG fsm allocates the access to the Transaction Table (m_transaction_tab_config)
+    // with a round robin priority between 2 user FSMs :
+    // - CONFIG_CMD : to set a new entry
+    // - CONFIG_RSP : to read and erase an entry
+    // The ressource is always allocated.
+    ////////////////////////////////////////////////////////////////////////////////////
+    
+    switch ( r_alloc_trt_config_fsm.read() ) 
+    {
+    ///////////////////
+    case ALLOC_TRT_CONFIG_CMD:
+    {
+        if ( r_config_cmd_fsm.read() != CONFIG_CMD_TRT_LOCK ) 
+        {
+          if (r_config_rsp_fsm.read() == CONFIG_RSP_TRT_LOCK) r_alloc_trt_config_fsm = ALLOC_TRT_CONFIG_RSP;
+        }
+    }
+    ///////////////////
+    case ALLOC_TRT_CONFIG_RSP:
+    {
+        if (r_config_rsp_fsm.read() != CONFIG_RSP_TRT_LOCK) 
+        {
+            if (r_config_cmd_fsm.read() == CONFIG_CMD_TRT_LOCK) r_alloc_trt_config_fsm = ALLOC_TRT_CONFIG_CMD;
+        }
+    }
+    } // end switch r_alloc_trt_config_fsm
+
+    ////////////////////////////////////////////////////////////////////////////
+    // The MISS_INIT FSM sends a page table entry miss request into Direct Noc
+    // It controls the following ressources:
+    // - r_miss_init_fsm
+    // - r_tlb_miss_init_req (reset)
+    // - r_miss_buf_data
+    // - r_miss_buf_valid
+    // - r_miss_buf_tag
+    ////////////////////////////////////////////////////////////////////////////////////
+
+    // Building the interruption vector (systematically)
+    uint32_t irq_demands = 0;
+    for ( size_t i = 0; i<m_nb_periph; ++i )
+        irq_demands |= (p_irq_in[i].read() ? 1 : 0) << i;
+    
+    // For next cycle:
+        // Afectation of the new pending vector. 
+        // Not useful, unless Irq choice is postponed to next cycle
+    r_irq_pending = irq_demands & r_irq_mask.read();
+        // Updating Mask
+    r_irq_mask = r_irq_mask.read()| ~irq_demands;  
+    
+ 
+    switch ( r_miss_init_fsm.read() ) 
+    {
+        //////////////
+        case MISS_INIT_IDLE_MISS:
+        {
+            if(r_tlb_miss_init_req.read())
+            {
+                r_miss_init_fsm = MISS_INIT_TLB_MISS_CMD;
+            }
+            else if (irq_demands & r_irq_mask.read()){
+                // Choosing one interruption to send            
+                // Find the first bit 1 
+                // starting by the bit just after the last chosen
+                size_t i = (r_irq_chosen.read() + 1)% m_nb_periph;
+                bool found = false;
+                do
+                {
+                    if(irq_demands & r_irq_mask.read() & (1<<i)) 
+                    {
+                        r_irq_chosen = i;
+                        found = true;
+                    }
+                    i = (i+1) % m_nb_periph;
+                }
+                while(i != r_irq_chosen.read()+1 && !found); 
+
+                r_miss_init_fsm = MISS_INIT_IRQ_CMD;
+            }
+			break;
+        }
+        //////////////
+        case MISS_INIT_IDLE_IRQ:
+        {
+            if (irq_demands & r_irq_mask.read()){
+                // Choosing one interruption to send            
+                // Find the first bit 1 
+                // starting by the bit just after the last chosen
+                size_t i = (r_irq_chosen.read() + 1)% m_nb_periph;
+                bool found = false;
+                do
+                {
+                    if(irq_demands & r_irq_mask.read() & (1<<i)) 
+                    {
+                        r_irq_chosen = i;
+                        found = true;
+                    }
+                    i = (i+1) % m_nb_periph;
+                }
+                while(i != r_irq_chosen.read()+1 && !found); 
+
+                r_miss_init_fsm = MISS_INIT_IRQ_CMD;
+            }
+            else if(r_tlb_miss_init_req.read())
+            {
+                r_miss_init_fsm = MISS_INIT_TLB_MISS_CMD;
+            }
+			break;
+        }
+        /////////////////////////       // send a read request to Direct Network
+        case MISS_INIT_IRQ_CMD: 
+        {
+        if ( p_vci_ini_miss.cmdack ) 
+        {
+            // Masking chosen interruption, until it is resolved 
+            r_irq_mask = r_irq_mask.read() & ~(1<<r_irq_chosen.read());
+            r_miss_init_fsm = MISS_INIT_IRQ_RSP;		
+
+#if DEBUG_MISS_INIT
+if( m_debug_miss_init_fsm )
+{
+    std::cout << "  <IOB.MISS_INIT_IRQ_CMD> Send write (irq) command to XICU"
+              << " irq ID = " << std::dec << r_irq_chosen.read()
+              << " new mask = " << std::hex << (r_irq_mask.read() & ~(1<<r_irq_chosen.read()))
+     << std::endl;
+}
+#endif
+        }
+            break;
+        }
+        //////////////////
+        case MISS_INIT_IRQ_RSP:	
+        {
+            if ( p_vci_ini_miss.rspval.read() ) 
+            {
+                // It is a WRITE command, response in one single flit long
+                assert( p_vci_ini_miss.reop.read() and "Write answer should have one single flit" ); 
+                bool error;
+                
+                if ( (p_vci_ini_miss.rerror.read()&0x1) != 0 )  // error reported
+                {
+                    // TODO traiter error
+                    error = true;
+                }
+                r_miss_init_fsm = MISS_INIT_IDLE_MISS;
+            }
+            break;
+        }
+        /////////////////////////       // send a read request to Direct Network
+        case MISS_INIT_TLB_MISS_CMD: 
+        {
+        if ( p_vci_ini_miss.cmdack ) 
+        {
+            r_miss_rsp_cpt  = 0;    //counter for the response flits
+            r_miss_buf_tag  = ( (r_iotlb_paddr.read()) & CACHE_LINE_MASK ); 
+            r_miss_buf_valid = true;
+            
+            if(r_tlb_miss_type.read()== PTE1_MISS)
+                r_miss_buf_vaddr_begin =(r_iotlb_vaddr.read() & ~M_PAGE_OFFSET_MASK & ~PTE1_LINE_OFFSET);
+            else
+                r_miss_buf_vaddr_begin =(r_iotlb_vaddr.read() & ~K_PAGE_OFFSET_MASK & ~PTE2_LINE_OFFSET);
+                
+            r_miss_init_fsm = MISS_INIT_TLB_MISS_RSP;		
+
+#if DEBUG_MISS_INIT
+if( m_debug_miss_init_fsm )
+{
+    std::cout << "  <IOB.MISS_INIT_TLB_MISS_CMD> Send read (tlb entry) request to MEM CACHE: "
+    << " | address :  "<< std::hex <<(paddr_t)((r_iotlb_paddr.read())& CACHE_LINE_MASK)
+    << std::endl;
+}
+#endif
+        }
+            break;
+        }
+        //////////////////
+        case MISS_INIT_TLB_MISS_RSP:	
+        {
+            if ( p_vci_ini_miss.rspval.read() ) 
+            {
+                if ( (p_vci_ini_miss.rerror.read()&0x1) != 0 )  // error reported
+                {
+                    r_miss_init_error = true;
+                    if ( p_vci_ini_miss.reop.read() ) 
+                    {    
+                        r_miss_init_fsm = MISS_INIT_IDLE_IRQ;
+                        r_tlb_miss_init_req = false; 
+                    }
+#if DEBUG_MISS_INIT
+if( m_debug_miss_init_fsm ) 
+{
+    std::cout << " <IOB.MISS_INIT_TLB_MISS_RSP> ERROR " << std::endl; 
+}
+#endif
+                }
+                else
+                { 
+                    bool   eop  	= p_vci_ini_miss.reop.read();
+
+
+#if DEBUG_MISS_INIT
+if( m_debug_miss_init_fsm ) 
+{
+    std::cout << "  <IOB.MISS_INIT_TLB_MISS_RSP> Response from Mem Cache to a read (tlb entry) transaction. Count = " << r_miss_rsp_cpt.read()
+    <<" | Data = " << std::hex << p_vci_ini_miss.rdata.read() << std::endl; 
+}
+#endif
+
+                    assert(((eop == (r_miss_rsp_cpt.read() == (m_words-1))) ) 
+                        and "Error : invalid length for a response from MEM CACHE");
+                    r_miss_buf_data[r_miss_rsp_cpt] =  (uint32_t)p_vci_ini_miss.rdata.read();
+                    
+                    r_miss_rsp_cpt = r_miss_rsp_cpt.read() + 1;
+                    
+                    if ( eop ) 
+                    {
+                        r_tlb_miss_init_req = false;     //reset the request flip-flop
+                        r_miss_init_fsm = MISS_INIT_IDLE_IRQ;		
+                    }
+
+                }
+            }
+            break;
+        }
+
+    } // end  switch r_miss_init_fsm
+    
+    //////////////////////////////////
+    // Fifo consumption arbitration //
+    //////////////////////////////////
+    
+    // Round Robin priority for CONFIG_RSP FIFO consumption
+    r_config_rsp_fifo_local_priority = ! r_config_rsp_fifo_local_priority.read(); 
+    
+    //DMA CMD
+    dma_cmd_fifo_get = (p_vci_ini_dma.cmdack.read() && m_dma_cmd_addr_fifo.rok());
+    // DMA RSP
+    dma_rsp_fifo_get = (p_vci_tgt_dma.rspack.read() && m_dma_rsp_data_fifo.rok());
+    // CONFIG CMD
+    config_cmd_fifo_get = (p_vci_ini_config.cmdack.read() && m_config_cmd_addr_fifo.rok() );
+    // CONFIG RSP, detemines wich fifo to consume 
+    if(r_config_rsp_fifo_local_priority)
+    {
+        if(m_config_local_data_fifo.rok()) config_local_fifo_get = p_vci_tgt_config.rspack.read();
+        else if (m_config_rsp_data_fifo.rok()) config_rsp_fifo_get = p_vci_tgt_config.rspack.read();
+            
+    }
+    else
+    {
+        if (m_config_rsp_data_fifo.rok()) config_rsp_fifo_get = p_vci_tgt_config.rspack.read();
+        else if(m_config_local_data_fifo.rok()) config_local_fifo_get = p_vci_tgt_config.rspack.read();
+    }
+    ///////////////
+    //DMA_CMD Fifo
+    ///////////////
+    if(r_miss_interrupt)
+    {
+        m_dma_cmd_addr_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    r_miss_paddr.read() );
+        m_dma_cmd_cmd_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    r_miss_cmd.read() );
+        m_dma_cmd_contig_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    r_miss_contig.read() );
+        m_dma_cmd_cons_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    r_miss_cons.read() );
+        m_dma_cmd_plen_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    r_miss_plen.read() );
+        m_dma_cmd_wrap_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    r_miss_wrap.read() );
+        m_dma_cmd_cfixed_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    r_miss_cfixed.read() );
+        m_dma_cmd_clen_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    r_miss_clen.read() );
+        m_dma_cmd_srcid_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    m_srcid_dma ); //r_miss_srcid.read()
+        m_dma_cmd_trdid_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    r_miss_trdid.read() );
+        m_dma_cmd_pktid_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    r_miss_pktid.read() );
+        m_dma_cmd_data_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    r_miss_data[r_dma_cmd_count.read()-1] );
+        m_dma_cmd_be_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    r_miss_be[r_dma_cmd_count.read()-1] );
+        m_dma_cmd_eop_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    (r_dma_cmd_count.read() == 1) );
+    }
+    else 
+    {
+        m_dma_cmd_addr_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    r_dma_paddr.read() ); 
+        m_dma_cmd_cmd_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    p_vci_tgt_dma.cmd.read() );
+        m_dma_cmd_contig_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    p_vci_tgt_dma.contig.read() );
+        m_dma_cmd_cons_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    p_vci_tgt_dma.cons.read() );
+        m_dma_cmd_plen_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    p_vci_tgt_dma.plen.read() );
+        m_dma_cmd_wrap_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    p_vci_tgt_dma.wrap.read() );
+        m_dma_cmd_cfixed_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    p_vci_tgt_dma.cfixed.read() );
+        m_dma_cmd_clen_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    p_vci_tgt_dma.clen.read() );
+        m_dma_cmd_srcid_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    m_srcid_dma );
+        m_dma_cmd_trdid_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    r_dma_cmd_trt_index.read() );
+        m_dma_cmd_pktid_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    p_vci_tgt_dma.pktid.read() );
+        m_dma_cmd_data_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    p_vci_tgt_dma.wdata.read() ); // TODO change
+                                                            // For 64bits XRAM
+        m_dma_cmd_be_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                    p_vci_tgt_dma.be.read() ); 
+        m_dma_cmd_eop_fifo.update( dma_cmd_fifo_get,
+                                    dma_cmd_fifo_put,
+                                     p_vci_tgt_dma.eop.read() );
+    }
+
+    ///////////////
+    //DMA_RSP Fifo
+    ///////////////
+    if(r_dma_rsp_fsm.read() == DMA_RSP_FIFO_ERROR_PUT)
+    {
+        m_dma_rsp_data_fifo.update( dma_rsp_fifo_get,
+                                    dma_rsp_fifo_put,
+                                    0 );
+        m_dma_rsp_rsrcid_fifo.update( dma_rsp_fifo_get,
+                                    dma_rsp_fifo_put,
+                                    r_iommu_bad_id.read() ); 
+        m_dma_rsp_rtrdid_fifo.update( dma_rsp_fifo_get,
+                                    dma_rsp_fifo_put,
+                                    r_dma_error_trdid.read() ); 
+        m_dma_rsp_rpktid_fifo.update( dma_rsp_fifo_get,
+                                    dma_rsp_fifo_put,
+                                    r_dma_error_pktid.read() );
+        m_dma_rsp_reop_fifo.update( dma_rsp_fifo_get,
+                                   dma_rsp_fifo_put,
+                                   true );
+        m_dma_rsp_rerror_fifo.update( dma_rsp_fifo_get,
+                                      dma_rsp_fifo_put,
+                                      r_dma_error_type.read() );
+    }
+    else
+    {
+        m_dma_rsp_data_fifo.update( dma_rsp_fifo_get,
+                                    dma_rsp_fifo_put,
+                                    p_vci_ini_dma.rdata.read() );
+        m_dma_rsp_rsrcid_fifo.update( dma_rsp_fifo_get,
+                                    dma_rsp_fifo_put,
+                                    r_dma_rsrcid.read() ); 
+        m_dma_rsp_rtrdid_fifo.update( dma_rsp_fifo_get,
+                                    dma_rsp_fifo_put,
+                                    r_dma_rtrdid.read() ); 
+        m_dma_rsp_rpktid_fifo.update( dma_rsp_fifo_get,
+                                    dma_rsp_fifo_put,
+                                    p_vci_ini_dma.rpktid.read() );
+        m_dma_rsp_reop_fifo.update( dma_rsp_fifo_get,
+                                   dma_rsp_fifo_put,
+                                   p_vci_ini_dma.reop.read() );
+        m_dma_rsp_rerror_fifo.update( dma_rsp_fifo_get,
+                                      dma_rsp_fifo_put,
+                                      p_vci_ini_dma.rerror.read() );
+    }
+
+    //////////////////
+    //CONFIG_CMD Fifo
+    //////////////////
+    m_config_cmd_addr_fifo.update( config_cmd_fifo_get,
+                                config_cmd_fifo_put,
+                                r_config_vaddr.read() ); 
+    m_config_cmd_cmd_fifo.update( config_cmd_fifo_get,
+                                config_cmd_fifo_put,
+                                p_vci_tgt_config.cmd.read() );
+    m_config_cmd_contig_fifo.update( config_cmd_fifo_get,
+                                config_cmd_fifo_put,
+                                p_vci_tgt_config.contig.read() );
+    m_config_cmd_cons_fifo.update( config_cmd_fifo_get,
+                                config_cmd_fifo_put,
+                                p_vci_tgt_config.cons.read() );
+    m_config_cmd_plen_fifo.update( config_cmd_fifo_get,
+                                config_cmd_fifo_put,
+                                p_vci_tgt_config.plen.read() );
+    m_config_cmd_wrap_fifo.update( config_cmd_fifo_get,
+                                config_cmd_fifo_put,
+                                p_vci_tgt_config.wrap.read() );
+    m_config_cmd_cfixed_fifo.update( config_cmd_fifo_get,
+                                config_cmd_fifo_put,
+                                p_vci_tgt_config.cfixed.read() );
+    m_config_cmd_clen_fifo.update( config_cmd_fifo_get,
+                                config_cmd_fifo_put,
+                                p_vci_tgt_config.clen.read() );
+    m_config_cmd_srcid_fifo.update( config_cmd_fifo_get,
+                                config_cmd_fifo_put,
+                                m_srcid_config );
+    m_config_cmd_trdid_fifo.update( config_cmd_fifo_get,
+                                config_cmd_fifo_put,
+                                r_config_cmd_trt_index.read() ); 
+    m_config_cmd_pktid_fifo.update( config_cmd_fifo_get,
+                                config_cmd_fifo_put,
+                                p_vci_tgt_config.pktid.read() );
+    m_config_cmd_data_fifo.update( config_cmd_fifo_get,
+                                config_cmd_fifo_put,
+                                p_vci_tgt_config.wdata.read() );
+    m_config_cmd_be_fifo.update( config_cmd_fifo_get,
+                                config_cmd_fifo_put,
+                                p_vci_tgt_config.be.read() );
+    m_config_cmd_eop_fifo.update( config_cmd_fifo_get,
+                                    config_cmd_fifo_put,
+                                     p_vci_tgt_config.eop.read() );
+    
+    //////////////////
+    //CONFIG_RSP Fifo
+    //////////////////
+    m_config_rsp_data_fifo.update( config_rsp_fifo_get,
+                                config_rsp_fifo_put,
+                                p_vci_ini_config.rdata.read() );
+    m_config_rsp_rsrcid_fifo.update( config_rsp_fifo_get,
+                                config_rsp_fifo_put,
+                                r_config_rsrcid.read() );
+    m_config_rsp_rtrdid_fifo.update( config_rsp_fifo_get,
+                                config_rsp_fifo_put,
+                                r_config_rtrdid.read() );
+    m_config_rsp_rpktid_fifo.update( config_rsp_fifo_get,
+                                config_rsp_fifo_put,
+                                p_vci_ini_config.rpktid.read() );
+    m_config_rsp_reop_fifo.update( config_rsp_fifo_get,
+                               config_rsp_fifo_put,
+                               p_vci_ini_config.reop.read() );
+    m_config_rsp_rerror_fifo.update( config_rsp_fifo_get,
+                                  config_rsp_fifo_put,
+                                  p_vci_ini_config.rerror.read() );
+    
+    ///////////////////////
+    //CONFIG Local RSP Fifo
+    ///////////////////////
+    m_config_local_rsrcid_fifo.update( config_local_fifo_get,
+                                config_local_fifo_put,
+                                p_vci_tgt_config.srcid.read() );
+    m_config_local_rtrdid_fifo.update( config_local_fifo_get,
+                                config_local_fifo_put,
+                                p_vci_tgt_config.trdid.read() );
+    m_config_local_rpktid_fifo.update( config_local_fifo_get,
+                                config_local_fifo_put,
+                                p_vci_tgt_config.pktid.read() );
+    
+    switch( r_config_cmd_fsm.read() ) 
+    {
+    case CONFIG_CMD_PTPR_WRITE:
+    case CONFIG_CMD_ACTIVE_WRITE:
+    case CONFIG_CMD_IT_ADDR_IOMMU_WRITE_2:
+    case CONFIG_CMD_IT_ADDR_WRITE_2:
+    case CONFIG_CMD_INVAL:
+        m_config_local_data_fifo.update( config_local_fifo_get,
+                                config_local_fifo_put,
+                                0); 
+        m_config_local_rerror_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        WRITE_OK );
+        m_config_local_reop_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        true );
+        break;
+    case CONFIG_CMD_PTPR_READ:
+        m_config_local_data_fifo.update( config_local_fifo_get,
+                                config_local_fifo_put,
+                                r_iommu_ptpr.read()); 
+        m_config_local_rerror_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        READ_OK );
+        m_config_local_reop_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        true );
+        break;
+    case CONFIG_CMD_ACTIVE_READ:
+        m_config_local_data_fifo.update( config_local_fifo_get,
+                                config_local_fifo_put,
+                                r_iommu_active.read()); 
+        m_config_local_rerror_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        READ_OK );
+        m_config_local_reop_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        true );
+        break;
+    case CONFIG_CMD_BVAR_READ:
+        m_config_local_data_fifo.update( config_local_fifo_get,
+                                config_local_fifo_put,
+                                r_iommu_bvar.read()); 
+        m_config_local_rerror_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        READ_OK );
+        m_config_local_reop_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        true );
+        break;
+    case CONFIG_CMD_ETR_READ:
+        m_config_local_data_fifo.update( config_local_fifo_get,
+                                config_local_fifo_put,
+                                r_iommu_etr.read()); 
+        m_config_local_rerror_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        READ_OK );
+        m_config_local_reop_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        true );
+        break;
+    case CONFIG_CMD_BAD_ID_READ:
+        m_config_local_data_fifo.update( config_local_fifo_get,
+                                config_local_fifo_put,
+                                r_iommu_bad_id.read()); 
+        m_config_local_rerror_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        READ_OK );
+        m_config_local_reop_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        true );
+        break;
+    case CONFIG_CMD_IT_ADDR_IOMMU_READ_1:
+        m_config_local_data_fifo.update( config_local_fifo_get,
+                                config_local_fifo_put,
+                                (uint32_t)(r_it_addr_iommu.read() & 0xFFFFFFFF) ); 
+        m_config_local_rerror_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        READ_OK );
+        m_config_local_reop_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        false );
+        break;
+    case CONFIG_CMD_IT_ADDR_IOMMU_READ_2:
+        m_config_local_data_fifo.update( config_local_fifo_get,
+                                config_local_fifo_put,
+                               (uint32_t)((r_it_addr_iommu.read()>>32)&0xFF) ); 
+        m_config_local_rerror_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        READ_OK );
+        m_config_local_reop_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        true );
+        break;
+    case CONFIG_CMD_IT_ADDR_READ_1:
+        m_config_local_data_fifo.update( config_local_fifo_get,
+                                config_local_fifo_put,
+                               (uint32_t)(r_it_addr[r_it_index.read()] & 0xFFFFFFFF) ); 
+        m_config_local_rerror_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        READ_OK );
+        m_config_local_reop_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        false );
+        break;
+    case CONFIG_CMD_IT_ADDR_READ_2:
+        m_config_local_data_fifo.update( config_local_fifo_get,
+                                config_local_fifo_put,
+                                (uint32_t)((r_it_addr[r_it_index.read()]>>32)&0xFF) ); 
+        m_config_local_rerror_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        READ_OK );
+        m_config_local_reop_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        true );
+        break;
+    case CONFIG_CMD_ERROR_RSP:
+        m_config_local_data_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        0); 
+        m_config_local_rerror_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        r_config_error_type.read() );
+        m_config_local_reop_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        true );
+        break;
+    default:
+        m_config_local_data_fifo.update( config_local_fifo_get,
+                                config_local_fifo_put,
+                                0); 
+        m_config_local_rerror_fifo.update( config_local_fifo_get,
+                                        config_local_fifo_put,
+                                        0 );
+        m_config_local_reop_fifo.update( config_local_fifo_get,
+                               config_local_fifo_put,
+                               false );
+        break;
+    }
+
+} // end transition()
+
+///////////////////////
+tmpl(void)::genMoore()
+///////////////////////
+{
+    //////////////////
+    // DMA Commands //
+    //////////////////
+    
+    // VCI initiator command on the xram network
+    if(m_dma_cmd_addr_fifo.rok()) 
+    //&& p_vci_ini_dma.cmdack.read())
+    {
+        p_vci_ini_dma.cmdval  = true;
+        #if NEW_XRAM_VCI
+        p_vci_ini_dma.address = (paddr_t_x)(m_dma_cmd_addr_fifo.read() >> 6 )
+        #else
+        p_vci_ini_dma.address = m_dma_cmd_addr_fifo.read();
+        #endif
+        
+        p_vci_ini_dma.be      = m_dma_cmd_be_fifo.read();
+        p_vci_ini_dma.cmd     = m_dma_cmd_cmd_fifo.read();
+        p_vci_ini_dma.contig  = m_dma_cmd_contig_fifo.read();
+        #if NEW_XRAM_VCI
+        //TODO for 64 bits field
+        #else
+        p_vci_ini_dma.wdata   = m_dma_cmd_data_fifo.read(); // The first is in param_x
+                                                    // the second in param_io
+        #endif
+        p_vci_ini_dma.eop     = m_dma_cmd_eop_fifo.read();
+        p_vci_ini_dma.cons    = m_dma_cmd_cons_fifo.read();
+        p_vci_ini_dma.plen    = m_dma_cmd_plen_fifo.read();
+        p_vci_ini_dma.wrap    = m_dma_cmd_wrap_fifo.read();
+        p_vci_ini_dma.cfixed  = m_dma_cmd_cfixed_fifo.read();
+        p_vci_ini_dma.clen    = m_dma_cmd_clen_fifo.read();
+        p_vci_ini_dma.trdid   = m_dma_cmd_trdid_fifo.read();
+        p_vci_ini_dma.pktid   = m_dma_cmd_pktid_fifo.read();
+        p_vci_ini_dma.srcid   = m_dma_cmd_srcid_fifo.read();
+    }
+    else
+    {
+        p_vci_ini_dma.cmdval  = false;
+        p_vci_ini_dma.address = 0;
+        p_vci_ini_dma.be      = 0;
+        p_vci_ini_dma.cmd     = vci_param_x::CMD_NOP;
+        p_vci_ini_dma.contig  = false;
+        p_vci_ini_dma.wdata   = 0;
+        p_vci_ini_dma.eop     = false;
+        p_vci_ini_dma.cons    = true;
+        p_vci_ini_dma.plen    = 0;
+        p_vci_ini_dma.wrap    = false;
+        p_vci_ini_dma.cfixed  = false;
+        p_vci_ini_dma.clen    = 0;
+        p_vci_ini_dma.trdid   = 0;
+        p_vci_ini_dma.pktid   = 0; 
+    }
+    
+    // VCI target command on the IO network
+    // it depends on the DMA_CMD FSM state
+
+    switch ( r_dma_cmd_fsm.read() ) 
+    {
+    case DMA_CMD_IDLE:
+    case DMA_CMD_TRT_LOCK:	
+    case DMA_CMD_TRT_WAIT:	
+    case DMA_CMD_TRT_SET:	
+        p_vci_tgt_dma.cmdack  = false;
+        break;
+    case DMA_CMD_FIFO_PUT:
+    case DMA_CMD_FIFO_MISS_PUT:
+        p_vci_tgt_dma.cmdack  = m_dma_cmd_addr_fifo.wok();
+        break;
+    case DMA_CMD_TLB_MISS_WAIT:
+        p_vci_tgt_dma.cmdack  = false;
+        break;
+    case DMA_CMD_TLB_MISS_STORE:
+        p_vci_tgt_dma.cmdack  = true;
+        break;
+    case DMA_CMD_ERROR:
+        p_vci_tgt_dma.cmdack  = !r_dma_cmd_error_req.read();
+        break; 
+    }// end switch r_dma_cmd_fsm
+
+    //////////////////
+    // DMA Responses//
+    //////////////////
+    
+    // VCI target response on the IO network
+    if(m_dma_rsp_data_fifo.rok())
+    {
+        p_vci_tgt_dma.rspval  = true;
+		p_vci_tgt_dma.rsrcid  = m_dma_rsp_rsrcid_fifo.read();
+        p_vci_tgt_dma.rtrdid  = m_dma_rsp_rtrdid_fifo.read();
+        
+        p_vci_tgt_dma.rpktid  = m_dma_rsp_rpktid_fifo.read();
+    
+        #if NEW_XRAM_VCI
+        //TODO for 64 bit data field
+        #else 
+        p_vci_tgt_dma.rdata   = m_dma_rsp_data_fifo.read(); // The first is in param_io
+                                                    // the second in param_x
+        #endif 
+        
+        p_vci_tgt_dma.rerror  = m_dma_rsp_rerror_fifo.read();
+        p_vci_tgt_dma.reop    = m_dma_rsp_reop_fifo.read();
+    }
+    else
+    {
+        p_vci_tgt_dma.rspval  = false;
+        
+		p_vci_tgt_dma.rsrcid  = 0;
+		p_vci_tgt_dma.rdata   = 0;
+		p_vci_tgt_dma.rpktid  = 0;
+		p_vci_tgt_dma.rtrdid  = 0;
+		p_vci_tgt_dma.rerror  = 0;
+		p_vci_tgt_dma.reop    = false;
+
+    }
+
+    // VCI initiator response on the Xram Network
+    // it depends on the DMA_RSP FSM state
+    switch ( r_dma_rsp_fsm.read() ) 
+    {
+    case DMA_RSP_IDLE:
+    case DMA_RSP_TRT_LOCK:
+    case DMA_RSP_FIFO_ERROR_PUT:
+    {
+		p_vci_ini_dma.rspack = false;
+        break;
+    }
+    case DMA_RSP_FIFO_PUT:
+	{
+    	p_vci_ini_dma.rspack = m_dma_rsp_data_fifo.wok();
+        break;
+    }
+    }// end switch r_dma_rsp_fsm
+
+    /////////////////////
+    // CONFIG Commands //
+    /////////////////////
+
+    // VCI initiator command on the IO network
+    if(m_config_cmd_addr_fifo.rok())
+    {
+        p_vci_ini_config.cmdval  = true;
+        #if NEW_XRAM_VCI
+        p_vci_ini_config.address = (paddr_t_x)(m_config_cmd_addr_fifo.read() >> 6 )
+        #else
+        p_vci_ini_config.address = m_config_cmd_addr_fifo.read();
+        #endif
+        
+        p_vci_ini_config.be      = m_config_cmd_be_fifo.read();
+        p_vci_ini_config.cmd     = m_config_cmd_cmd_fifo.read();
+        p_vci_ini_config.contig  = m_config_cmd_contig_fifo.read();
+        #if NEW_XRAM_VCI
+        //TODO
+        #else
+        p_vci_ini_config.wdata   = m_config_cmd_data_fifo.read(); // The first is in param_x
+                                                    // the second in param_io
+        #endif
+        p_vci_ini_config.eop     = m_config_cmd_eop_fifo.read();
+        p_vci_ini_config.cons    = m_config_cmd_cons_fifo.read();
+        p_vci_ini_config.plen    = m_config_cmd_plen_fifo.read();
+        p_vci_ini_config.wrap    = m_config_cmd_wrap_fifo.read();
+        p_vci_ini_config.cfixed  = m_config_cmd_cfixed_fifo.read();
+        p_vci_ini_config.clen    = m_config_cmd_clen_fifo.read();
+        p_vci_ini_config.trdid   = m_config_cmd_trdid_fifo.read();
+        p_vci_ini_config.pktid   = m_config_cmd_pktid_fifo.read();
+    }
+    else
+    {
+        p_vci_ini_config.cmdval  = false;
+        p_vci_ini_config.address = 0;
+        p_vci_ini_config.be      = 0;
+        p_vci_ini_config.cmd     = vci_param_io::CMD_NOP;
+        p_vci_ini_config.contig  = false;
+        p_vci_ini_config.wdata   = 0;
+        p_vci_ini_config.eop     = false;
+        p_vci_ini_config.cons    = true;
+        p_vci_ini_config.plen    = 0;
+        p_vci_ini_config.wrap    = false;
+        p_vci_ini_config.cfixed  = false;
+        p_vci_ini_config.clen    = 0;
+        p_vci_ini_config.trdid   = 0;
+        p_vci_ini_config.pktid   = 0; 
+    }
+    
+    // VCI target command on the Direct network
+    // it depends on the CONFIG_CMD FSM state
+
+    switch ( r_config_cmd_fsm.read() ) 
+    {
+    case CONFIG_CMD_IDLE:
+    case CONFIG_CMD_TRT_LOCK:   
+    case CONFIG_CMD_TRT_WAIT: 
+    case CONFIG_CMD_TRT_SET: 
+    case CONFIG_CMD_IT_ADDR_IOMMU_READ_1:
+    case CONFIG_CMD_IT_ADDR_READ_1:
+    case CONFIG_CMD_ERROR_RSP:  
+    case CONFIG_CMD_INVAL_REQ:
+        p_vci_tgt_config.cmdack  = false;
+        break;
+    case CONFIG_CMD_FIFO_PUT:	  
+    case CONFIG_CMD_PTPR_WRITE:
+    case CONFIG_CMD_PTPR_READ:
+    case CONFIG_CMD_ACTIVE_WRITE:
+    case CONFIG_CMD_ACTIVE_READ:
+    case CONFIG_CMD_BVAR_READ:
+    case CONFIG_CMD_ETR_READ:
+    case CONFIG_CMD_BAD_ID_READ:
+    case CONFIG_CMD_IT_ADDR_IOMMU_WRITE_2:
+    case CONFIG_CMD_IT_ADDR_IOMMU_READ_2:
+    case CONFIG_CMD_IT_ADDR_WRITE_2:
+    case CONFIG_CMD_IT_ADDR_READ_2:
+    case CONFIG_CMD_INVAL: 
+        p_vci_tgt_config.cmdack  = m_config_cmd_addr_fifo.wok();
+        break;
+    case CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1:
+    case CONFIG_CMD_IT_ADDR_WRITE_1:
+    case CONFIG_CMD_ERROR_WAIT: 
+        p_vci_tgt_config.cmdack = true; 
+        break;
+    default: 
+        p_vci_tgt_config.cmdack  = false;
+        break;
+    }// end switch r_config_cmd_fsm
+
+    /////////////////////
+    // CONFIG Responses//
+    /////////////////////
+    
+    // VCI target response on the Direct network
+    if(r_config_rsp_fifo_local_priority)
+    {
+    if( m_config_local_data_fifo.rok() )
+    {
+        p_vci_tgt_config.rspval  = true;
+		p_vci_tgt_config.rsrcid  = m_config_local_rsrcid_fifo.read();
+        p_vci_tgt_config.rtrdid  = m_config_local_rtrdid_fifo.read();
+        p_vci_tgt_config.rpktid  = m_config_local_rpktid_fifo.read();
+        p_vci_tgt_config.rdata   = m_config_local_data_fifo.read();
+        p_vci_tgt_config.rerror  = m_config_local_rerror_fifo.read();
+        p_vci_tgt_config.reop    = m_config_local_reop_fifo.read();
+    }
+    else if(m_config_rsp_data_fifo.rok() )
+    {
+        p_vci_tgt_config.rspval  = true;
+		p_vci_tgt_config.rsrcid  = m_config_rsp_rsrcid_fifo.read();
+        p_vci_tgt_config.rtrdid  = m_config_rsp_rtrdid_fifo.read();
+        
+        p_vci_tgt_config.rpktid  = m_config_rsp_rpktid_fifo.read();
+    
+        p_vci_tgt_config.rdata   = m_config_rsp_data_fifo.read(); // The first is in param_d
+                                                    // the second in param_io
+        p_vci_tgt_config.rerror  = m_config_rsp_rerror_fifo.read();
+        p_vci_tgt_config.reop    = m_config_rsp_reop_fifo.read();
+    }
+    else
+    {
+        p_vci_tgt_config.rspval  = false;
+        
+		p_vci_tgt_config.rsrcid  = 0;
+		p_vci_tgt_config.rdata   = 0;
+		p_vci_tgt_config.rpktid  = 0;
+		p_vci_tgt_config.rtrdid  = 0;
+		p_vci_tgt_config.rerror  = 0;
+		p_vci_tgt_config.reop    = false;
+
+    }
+    }
+    else
+    {
+    if(m_config_rsp_data_fifo.rok() )
+    {
+        p_vci_tgt_config.rspval  = true;
+		p_vci_tgt_config.rsrcid  = m_config_rsp_rsrcid_fifo.read();
+        p_vci_tgt_config.rtrdid  = m_config_rsp_rtrdid_fifo.read();
+        
+        p_vci_tgt_config.rpktid  = m_config_rsp_rpktid_fifo.read();
+    
+        p_vci_tgt_config.rdata   = m_config_rsp_data_fifo.read(); // The first is in param_d
+                                                    // the second in param_io
+        p_vci_tgt_config.rerror  = m_config_rsp_rerror_fifo.read();
+        p_vci_tgt_config.reop    = m_config_rsp_reop_fifo.read();
+    }
+    else if( m_config_local_data_fifo.rok() )
+    {
+        p_vci_tgt_config.rspval  = true;
+		p_vci_tgt_config.rsrcid  = m_config_local_rsrcid_fifo.read();
+        p_vci_tgt_config.rtrdid  = m_config_local_rtrdid_fifo.read();
+        p_vci_tgt_config.rpktid  = m_config_local_rpktid_fifo.read();
+        p_vci_tgt_config.rdata   = m_config_local_data_fifo.read();
+        p_vci_tgt_config.rerror  = m_config_local_rerror_fifo.read();
+        p_vci_tgt_config.reop    = m_config_local_reop_fifo.read();
+    }
+    else
+    {
+        p_vci_tgt_config.rspval  = false;
+        
+		p_vci_tgt_config.rsrcid  = 0;
+		p_vci_tgt_config.rdata   = 0;
+		p_vci_tgt_config.rpktid  = 0;
+		p_vci_tgt_config.rtrdid  = 0;
+		p_vci_tgt_config.rerror  = 0;
+		p_vci_tgt_config.reop    = false;
+
+    }
+    }
+    
+    // VCI initiator response on the IO Network
+    // it depends on the CONFIG_RSP FSM state
+    switch ( r_config_rsp_fsm.read() ) 
+    {
+    case CONFIG_RSP_IDLE:
+    case CONFIG_RSP_TRT_LOCK:
+	p_vci_ini_config.rspack = false;
+        break;
+    case CONFIG_RSP_FIFO_PUT:
+		p_vci_ini_config.rspack = m_config_rsp_data_fifo.wok();
+        break;
+    }// end switch r_config_rsp_fsm
+
+    ////////////////////////////////////////////////////////////////
+    // VCI initiator command and response on from the Direct network 
+    // for Miss Transactions
+    p_vci_ini_miss.srcid   = m_srcid_miss;
+    
+    switch ( r_miss_init_fsm.read() ) 
+    {   
+    case MISS_INIT_IDLE_MISS:
+    case MISS_INIT_IDLE_IRQ:
+		p_vci_ini_miss.cmdval  = false;
+        p_vci_ini_miss.address = 0;
+        p_vci_ini_miss.be      = 0;
+        p_vci_ini_miss.cmd     = vci_param_d::CMD_NOP;
+        p_vci_ini_miss.contig  = false;
+        p_vci_ini_miss.wdata   = 0;
+        p_vci_ini_miss.eop     = false;
+        p_vci_ini_miss.cons    = true;
+        p_vci_ini_miss.plen    = 0;
+        p_vci_ini_miss.wrap    = false;
+        p_vci_ini_miss.cfixed  = false;
+        p_vci_ini_miss.clen    = 0;
+        p_vci_ini_miss.trdid   = 0;
+        p_vci_ini_miss.pktid   = 0;
+
+		p_vci_ini_miss.rspack = false;
+        break;
+    
+    case MISS_INIT_IRQ_CMD:
+        p_vci_ini_miss.cmdval  = true;
+        p_vci_ini_miss.address = (paddr_t)r_it_addr[r_irq_chosen.read()]; 
+        p_vci_ini_miss.wdata   = 0;
+        p_vci_ini_miss.plen    = vci_param_d::B;
+        p_vci_ini_miss.trdid   = 0;  
+        p_vci_ini_miss.cmd     = vci_param_d::CMD_READ;
+        p_vci_ini_miss.eop     = true;
+        
+        p_vci_ini_miss.be      = 0xF;
+        p_vci_ini_miss.pktid   = 0;
+        p_vci_ini_miss.cons    = false;
+        p_vci_ini_miss.wrap    = false;
+        p_vci_ini_miss.contig  = true;
+        p_vci_ini_miss.clen    = 0;
+        p_vci_ini_miss.cfixed  = false;
+        break;
+    
+    case MISS_INIT_IRQ_RSP:
+    case MISS_INIT_TLB_MISS_RSP:
+        p_vci_ini_miss.cmdval  = false;
+        p_vci_ini_miss.address = 0;
+        p_vci_ini_miss.be      = 0;
+        p_vci_ini_miss.cmd     = vci_param_d::CMD_NOP;
+        p_vci_ini_miss.contig  = false;
+        p_vci_ini_miss.wdata   = 0;
+        p_vci_ini_miss.eop     = false;
+        p_vci_ini_miss.cons    = true;
+        p_vci_ini_miss.plen    = 0;
+        p_vci_ini_miss.wrap    = false;
+        p_vci_ini_miss.cfixed  = false;
+        p_vci_ini_miss.clen    = 0;
+        p_vci_ini_miss.trdid   = 0;
+        p_vci_ini_miss.pktid   = 0;
+        
+        p_vci_ini_miss.rspack = true;
+ 
+        break;
+   
+    case MISS_INIT_TLB_MISS_CMD:
+        p_vci_ini_miss.cmdval  = true;
+        p_vci_ini_miss.address = (paddr_t)((r_iotlb_paddr.read())& CACHE_LINE_MASK);
+        p_vci_ini_miss.wdata   = 0x00000000;
+        p_vci_ini_miss.plen    = m_words*(vci_param_d::B);
+        p_vci_ini_miss.trdid   = 0;  //could be used as the index on a miss transaction table
+        p_vci_ini_miss.cmd     = vci_param_d::CMD_READ;
+        p_vci_ini_miss.eop     = true;
+        
+        p_vci_ini_miss.be      = 0xF;
+        p_vci_ini_miss.pktid   = 0;
+        p_vci_ini_miss.cons    = false;
+        p_vci_ini_miss.wrap    = false;
+        p_vci_ini_miss.contig  = true;
+        p_vci_ini_miss.clen    = 0;
+        p_vci_ini_miss.cfixed  = false;
+        break;
+
+    } // end switch r_miss_init_fsm
+} // end genMoore
+
+}}
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
