/* -*- 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




