Index: /trunk/modules/vci_profiler/caba/metadata/vci_profiler.sd
===================================================================
--- /trunk/modules/vci_profiler/caba/metadata/vci_profiler.sd	(revision 258)
+++ /trunk/modules/vci_profiler/caba/metadata/vci_profiler.sd	(revision 258)
@@ -0,0 +1,32 @@
+
+# -*- python -*-
+
+__id__ = "$Id: vci_profiler.sd 2060 2011-02-20 Ghassan $"
+__version__ = "$Revision: 2060 $"
+
+Module('caba:vci_profiler',
+	classname = 'soclib::caba::VciProfiler',
+	   tmpl_parameters = [
+	parameter.Module('vci_param',  default = 'caba:vci_param'),
+        parameter.Module('iss_t'),
+	],
+	header_files = ['../source/include/vci_profiler.h',],
+	implementation_files = ['../source/src/vci_profiler.cpp',],
+			  ports = [
+	Port('caba:vci_monitor', 'p_vci'),
+	Port('caba:bit_in', 'p_resetn', auto = 'resetn'),
+	Port('caba:clock_in', 'p_clk', auto = 'clock'),
+	],
+	uses = [
+		Uses('caba:base_module'),
+		Uses('common:mapping_table'),
+		Uses('caba:vci_buffers'),
+                Uses('config:config'),
+                Uses('common:iss2'),
+                Uses('caba:vci_cc_vcache_wrapper2_v1'),
+		],
+	instance_parameters = [
+	],
+	   extensions = [
+   ],
+)
Index: /trunk/modules/vci_profiler/caba/source/include/vci_profiler.h
===================================================================
--- /trunk/modules/vci_profiler/caba/source/include/vci_profiler.h	(revision 258)
+++ /trunk/modules/vci_profiler/caba/source/include/vci_profiler.h	(revision 258)
@@ -0,0 +1,148 @@
+/* -*- c++ -*-
+ *
+ * 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
+ *
+ * Copyright (c) UPMC, Lip6
+ *         Ghassan Almaless <ghassan.almaless@lip6.fr>, 2011
+ *
+ * Maintainers: Ghassan
+ */
+#ifndef SOCLIB_CABA_VCI_PROFILER_H
+#define SOCLIB_CABA_VCI_PROFILER_H
+
+#include <systemc>
+#include <iostream>
+#include <fstream>
+#include "vci_monitor.h"
+#include "vci_buffers.h"
+#include "caba_base_module.h"
+#include "mapping_table.h"
+//#include "config.h"
+#include "vci_cc_vcache_wrapper2_v1.h"
+
+namespace soclib {
+namespace caba {
+
+template<typename vci_param, typename iss_t>
+class VciProfiler
+	: public soclib::caba::BaseModule
+{
+
+protected:
+	SC_HAS_PROCESS(VciProfiler);
+
+public:
+    sc_core::sc_in<bool> p_resetn;
+    sc_core::sc_in<bool> p_clk;
+    soclib::caba::VciMonitor<vci_param> p_vci;
+
+    VciProfiler(
+              sc_core::sc_module_name insname,
+              size_t index, 
+              size_t x_id,
+              size_t y_id,
+              size_t x_width,
+              size_t y_width,
+              size_t addr_width);
+
+    void print_stats(void);
+    void clear_stats(void);
+    void set_limits(unsigned long limit1, unsigned long limit2);
+    void set_L1_cache(VciCcVCacheWrapper2V1<vci_param, iss_t> *l1);
+    ~VciProfiler();
+
+private:
+
+#define VCI_CMD_NR              4+7      // TODO: define vci_param::CMD_NR 
+
+
+    struct cmd_info_s
+    {
+        unsigned long trans;
+        unsigned long cost;
+        unsigned long remote;
+        unsigned long rcost;
+        unsigned long limit1;
+        unsigned long limit2;
+        unsigned long rmax_time;
+        unsigned long rmax_cost;
+        unsigned long raddr;
+        unsigned long lmax_time;
+        unsigned long lmax_cost;
+        unsigned long flits;
+        unsigned long rflits;
+        unsigned long distance;
+        unsigned long max_dist;
+        unsigned long d1_limit;
+        unsigned long d2_limit;
+    } m_cmd_tbl[VCI_CMD_NR]; 
+    
+    unsigned long m_index;
+    unsigned long m_xWidth;
+    unsigned long m_yWidth;
+    unsigned long m_width;
+    long m_x;
+    long m_y;
+    unsigned long m_bits;
+
+    unsigned long m_tm_now;
+    unsigned long m_tm_start;
+    unsigned long m_last_cmd;
+    unsigned long m_last_addr;
+    unsigned long m_limit1;
+    unsigned long m_limit2;
+    unsigned long m_d1_limit;
+    unsigned long m_d2_limit;
+    unsigned long m_period;
+    unsigned long m_threshold;
+    unsigned long m_debug_cntr;
+    bool m_isPending;
+    bool m_isCMDPending;
+    bool m_isPeriod;
+    bool m_isRemote;
+    bool m_isInstruction;
+    bool m_isDebug;
+
+    VciCcVCacheWrapper2V1<vci_param, iss_t> *m_l1;
+
+    unsigned long m_exchange_cntr;
+    unsigned long m_access_cntr;
+    unsigned long m_remote_cntr;
+    unsigned long m_cycles_cntr;
+    
+    //std::ofstream m_log;
+
+    void transition();
+};
+
+}}
+
+#endif /* SOCLIB_CABA_VCI_PROFILER_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_profiler/caba/source/src/vci_profiler.cpp
===================================================================
--- /trunk/modules/vci_profiler/caba/source/src/vci_profiler.cpp	(revision 258)
+++ /trunk/modules/vci_profiler/caba/source/src/vci_profiler.cpp	(revision 258)
@@ -0,0 +1,448 @@
+/* -*- c++ -*-
+ *
+ * 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
+ *
+ * Copyright (c) UPMC, Lip6
+ *         Ghassan Almaless <ghassan.almaless@lip6.fr>, 2011
+ *
+ * Maintainers: Ghassan
+ */
+
+#include "vci_profiler.h"
+#include <cstring>
+#include <iostream>
+#include "vci_buffers.h"
+#include <iostream>
+#include <iomanip>
+#include <cassert>
+#include <vector>
+
+namespace soclib {
+namespace caba {
+
+#define tmpl(...) template<typename vci_param, typename iss_t> __VA_ARGS__ VciProfiler<vci_param, iss_t>
+
+#define ABS(x) (((x) < 0) ? -(x) : (x))
+
+#define VCI_iRD_CMD             4
+#define VCI_iTLB_RD_CMD         5
+#define VCI_iTLB_LL_CMD         6
+#define VCI_iTLB_SC_CMD         7
+#define VCI_DTLB_RD_CMD         8
+#define VCI_DTLB_LL_CMD         9
+#define VCI_DTLB_SC_CMD         10
+
+#define _CMD_ITLB               0x1
+#define _CMD_DTLB               0x2   
+#define _CMD_USR                0x4
+
+static const char* vci_cmd_names[VCI_CMD_NR] = {"SC_CMD ", 
+                                                "RD_CMD ", 
+                                                "WR_CMD ", 
+                                                "LL_CMD ", 
+                                                "iRD_CMD",
+                                                "iTLB_RD_CMD",
+                                                "iTLB_LL_CMD",
+                                                "iTLB_SC_CMD",
+                                                "DTLB_RD_CMD",
+                                                "DTLB_LL_CMD",
+                                                "DTLB_SC_CMD"};
+
+tmpl(void)::print_stats()
+{
+    unsigned long local_cntr;
+    unsigned long total_cost;
+    unsigned long total_flits;
+    unsigned long total_rflits;
+    unsigned long total_estmtd_enrg;
+    std::ostream &output = m_l1->m_log;
+
+    if(m_period == 0)
+        return;
+    
+    total_cost        = 0;
+    total_flits       = 0;
+    total_rflits      = 0;
+    total_estmtd_enrg = 0;
+    
+    local_cntr = m_access_cntr - m_remote_cntr;
+    
+    output << name() << " Cycles: " << std::dec << m_tm_now << std::endl 
+           << "Access_Rate  = " << (double)  m_access_cntr / m_cycles_cntr << std::endl
+           << "Remote_%     = " << (double)  m_remote_cntr / m_access_cntr << std::endl
+           << "LL_%         = " << (double)  m_cmd_tbl[vci_param::CMD_LOCKED_READ].trans / m_access_cntr << std::endl
+           << "SC_%         = " << (double)  m_cmd_tbl[vci_param::CMD_STORE_COND].trans  / m_access_cntr << std::endl;
+    
+    for(long i = 0; i < VCI_CMD_NR; i++)
+    {
+
+        local_cntr = m_cmd_tbl[i].distance * m_cmd_tbl[i].rflits;
+
+        output << vci_cmd_names[i] << " [" 
+               << m_cmd_tbl[i].trans << ", "
+               << m_cmd_tbl[i].remote << ", "
+               << m_cmd_tbl[i].trans - m_cmd_tbl[i].remote  << ", "
+               << m_cmd_tbl[i].cost << ", "
+               << m_cmd_tbl[i].rcost << ", "
+               << m_cmd_tbl[i].cost - m_cmd_tbl[i].rcost << ", "
+               << m_cmd_tbl[i].limit1 << ", "
+               << m_cmd_tbl[i].limit2 << ", "
+               << m_cmd_tbl[i].rmax_cost << ", "
+               << m_cmd_tbl[i].rmax_time << ", "
+               << m_cmd_tbl[i].lmax_cost << ", "
+               << m_cmd_tbl[i].lmax_time << ", "
+               << m_cmd_tbl[i].flits <<  ", " 
+               << m_cmd_tbl[i].rflits << ", " << std::hex
+               << m_cmd_tbl[i].raddr << ", " << std::dec 
+               << m_cmd_tbl[i].distance << ","
+               << m_cmd_tbl[i].d1_limit << ","
+               << m_cmd_tbl[i].d2_limit << ","
+               << m_cmd_tbl[i].max_dist << ","
+               << local_cntr << "]" << std::endl;
+
+        total_cost        += m_cmd_tbl[i].cost;
+        total_flits       += m_cmd_tbl[i].flits;
+        total_rflits      += m_cmd_tbl[i].rflits;
+        total_estmtd_enrg += local_cntr;
+    }
+    
+    output << "Total_CMDs         = " << m_access_cntr << std::endl
+           << "Total_Cost         = " << total_cost << std::endl
+           << "Total_Flits        = " << total_flits << std::endl
+           << "Total_Remote_Flits = " << total_rflits << std::endl 
+           << "Total_Estmtd_Enrg  = " << total_estmtd_enrg << std::endl;
+}
+
+tmpl(void)::clear_stats()
+{
+    memset(m_cmd_tbl, 0, sizeof(m_cmd_tbl));
+    m_access_cntr = 0;
+    m_remote_cntr = 0;
+    m_cycles_cntr = 0;
+}
+
+
+tmpl(void)::set_limits(unsigned long limit1, unsigned long limit2)
+{
+    m_limit1 = limit1;
+    m_limit2 = limit2;
+}
+
+tmpl(void)::set_L1_cache(VciCcVCacheWrapper2V1<vci_param, iss_t> *l1)
+{
+    m_l1 = l1;
+}
+
+
+tmpl()::VciProfiler(
+                  sc_core::sc_module_name insname,
+                  size_t index, 
+                  size_t x_id,
+                  size_t y_id,
+                  size_t x_width,
+                  size_t y_width,
+                  size_t addr_width)
+	: BaseModule(insname),
+      p_resetn("resetn"),
+      p_clk("clk"),
+      p_vci("vci")
+{
+    clear_stats();
+    m_index        = index;
+    m_x            = x_id;
+    m_y            = y_id;
+    m_xWidth       = x_width;
+    m_yWidth       = y_width;
+    m_width        = x_width + y_width;
+    m_bits         = addr_width;
+    m_tm_now       = 0;
+    m_tm_start     = 0;
+    m_isPending    = false;
+    m_isCMDPending = false;
+    m_isPeriod     = false;
+    m_isDebug      = false;
+    m_last_cmd     = 0;
+    m_limit1       = 0;
+    m_limit2       = 0;
+    m_d1_limit     = 0;
+    m_d2_limit     = 0;
+    m_period       = 0;
+    m_debug_cntr   = 0;
+    m_threshold    = 1000000;
+
+    char *ptr = getenv("TSAR_PROFILER_PERIOD");
+
+    if(ptr != NULL)
+        m_period = atol(ptr);
+
+    ptr = getenv("TSAR_PROFILER_THRESHOLD");
+
+    if(ptr != NULL)
+        m_threshold = atol(ptr);
+
+    ptr = getenv("TSAR_PROFILER_DEBUG");
+
+    if(ptr != NULL)
+        m_isDebug = (atol(ptr) != 0) ? true : false;
+
+    ptr = getenv("TSAR_PROFILER_LIMIT1");
+
+    if(ptr != NULL)
+        m_limit1 = atol(ptr);
+
+    ptr = getenv("TSAR_PROFILER_LIMIT2");
+
+    if(ptr != NULL)
+        m_limit2 = atol(ptr);
+
+    ptr = getenv("TSAR_PROFILER_D1_LIMIT");
+
+    if(ptr != NULL)
+        m_d1_limit = atol(ptr);
+
+    ptr = getenv("TSAR_PROFILER_D2_LIMIT");
+
+    if(ptr != NULL)
+        m_d2_limit = atol(ptr);
+
+#if 0    
+    if(m_period != 0)
+        m_log.open(insname, std::ios::out);
+#endif
+
+	SC_METHOD(transition);
+	dont_initialize();
+	sensitive << p_clk.pos();
+}
+
+tmpl()::~VciProfiler()
+{
+}
+
+tmpl(void)::transition()
+{
+    unsigned long cmd;
+    unsigned long shift;
+    unsigned long msb;
+    long x_coord;
+    long y_coord;
+    unsigned long distance;
+    unsigned long cost;
+    bool isUser;
+    
+    std::ostream &output = m_l1->m_log;
+
+    if(m_period == 0)
+        return;
+
+    if( p_vci.cmdval.read() && p_vci.cmdack.read() )
+    {
+        if(m_isPending == false)
+        {
+            m_isCMDPending = true;
+            m_isPending    = true;
+            m_tm_start     = m_tm_now;
+            cmd            = p_vci.cmd.read();
+            m_access_cntr ++;
+
+            if((cmd == vci_param::CMD_READ) && (p_vci.trdid.read() > 1))
+                cmd = VCI_iRD_CMD;
+            
+            else if((cmd == vci_param::CMD_READ) && (p_vci.pktid.read() & _CMD_ITLB))
+                cmd = VCI_iTLB_RD_CMD;
+
+            else if((cmd == vci_param::CMD_READ) && (p_vci.pktid.read() & _CMD_DTLB))
+                cmd = VCI_DTLB_RD_CMD;
+
+            else if((cmd == vci_param::CMD_LOCKED_READ) && (p_vci.pktid.read() & _CMD_ITLB))
+                cmd = VCI_iTLB_LL_CMD;
+
+            else if((cmd == vci_param::CMD_LOCKED_READ) && (p_vci.pktid.read() & _CMD_DTLB))
+                cmd = VCI_DTLB_LL_CMD;
+
+            else if((cmd == vci_param::CMD_STORE_COND) && (p_vci.pktid.read() & _CMD_ITLB))
+                cmd = VCI_iTLB_SC_CMD;
+
+            else if((cmd == vci_param::CMD_STORE_COND) && (p_vci.pktid.read() & _CMD_DTLB))
+                cmd = VCI_DTLB_SC_CMD;
+
+            m_last_cmd  = cmd;
+            m_last_addr = p_vci.address.read();
+            m_cmd_tbl[cmd].trans ++;
+            m_cmd_tbl[cmd].flits += ((p_vci.plen.read() / 4) + 1);
+
+            shift    = m_bits - m_width;
+            msb      = m_last_addr >> shift;
+            distance = 0;
+
+            m_isRemote = (msb == m_index) ? false : true;
+            
+            if(m_isRemote == true)
+            {
+                isUser   = (p_vci.pktid.read() & _CMD_USR) ? true : false;
+                m_cmd_tbl[cmd].remote ++;
+                m_remote_cntr ++;
+                x_coord  = msb >> m_yWidth;
+                y_coord  = msb & ((1 << m_yWidth) - 1);
+                distance = ABS(m_x - x_coord) + ABS(m_y - y_coord);
+                
+                output << ">> " << vci_cmd_names[cmd] 
+                       << "\t(" << m_x << "," << m_y << ") --> (" 
+                       << x_coord << "," << y_coord << ")\t[ D: " 
+                       << distance << " @: " << std::hex << m_last_addr << std::dec 
+                       << " T: " << m_tm_now << " "<< ((isUser) ? "U" : "K") << " ]" << std::endl;
+                
+                m_cmd_tbl[cmd].rflits += ((p_vci.plen.read() / 4) + 1);
+                m_cmd_tbl[cmd].distance += distance;
+                
+                if(distance > m_cmd_tbl[cmd].max_dist)
+                    m_cmd_tbl[cmd].max_dist = distance;
+                
+                if(distance >= m_d2_limit)
+                    m_cmd_tbl[cmd].d2_limit ++;
+                else if(distance >= m_d1_limit)
+                    m_cmd_tbl[cmd].d1_limit ++;
+            }
+
+#if 1
+            if(m_isDebug)
+            {
+                output << ">>> " << std::dec
+                       << "Cycle: "<< m_tm_now
+                       << ", Addr " << std::hex << m_last_addr 
+                       << ", isRemote " << m_isRemote
+                       << ", Distance " << distance
+                       << ", " << vci_cmd_names[m_last_cmd];
+            }
+#endif
+        }
+
+        if(p_vci.eop.read())
+            m_isPending = false;
+    }
+
+    if ( p_vci.rspval.read() && p_vci.rspack.read() )
+    {
+        if( p_vci.reop.read() )
+        {
+            m_isCMDPending = false;
+            cost = m_tm_now - m_tm_start;
+
+            m_cmd_tbl[m_last_cmd].cost += cost;
+            
+            if(m_isRemote == true)
+                m_cmd_tbl[m_last_cmd].rcost += cost;
+
+            if(cost > m_limit2)
+                m_cmd_tbl[m_last_cmd].limit2 ++;
+            else if(cost > m_limit1) 
+                m_cmd_tbl[m_last_cmd].limit1 ++;
+
+            if(m_isRemote == true)
+            {   
+                if(cost > m_cmd_tbl[m_last_cmd].rmax_cost)
+                {
+                    m_cmd_tbl[m_last_cmd].rmax_time = m_tm_now;
+                    m_cmd_tbl[m_last_cmd].rmax_cost = cost;
+                    m_cmd_tbl[m_last_cmd].raddr = m_last_addr;
+                }
+            }
+            else
+            {
+                if(cost > m_cmd_tbl[m_last_cmd].lmax_cost)
+                {
+                    m_cmd_tbl[m_last_cmd].lmax_time = m_tm_now;
+                    m_cmd_tbl[m_last_cmd].lmax_cost = cost;
+                }
+            }
+#if 1
+            if(m_isDebug)
+            {
+                output << "  <<< " << std::dec
+                       << "Cycle: "<< m_tm_now
+                       << ", Cost: " << cost 
+                       << ", Addr " << std::hex << m_last_addr 
+                       << ", " << vci_cmd_names[m_last_cmd]
+                       << std::endl;
+            }
+#endif
+        }
+    }
+
+    m_tm_now ++;
+    m_cycles_cntr ++;
+
+#if 1
+    if((m_isCMDPending == true) && ((m_tm_now - m_tm_start) > m_threshold) && (m_isDebug == false))
+    {
+        output << "Threshold is reached: " << std::dec
+               << "Tm_now: " << m_tm_now 
+               << " Tm_start: " << m_tm_start
+               << " Val: " << m_tm_now - m_tm_start
+               << " Threshold: " << m_threshold
+               << std::endl;
+
+        m_isDebug = true;
+    }
+
+    if(m_isDebug == true)
+    {
+        m_l1->print_trace(0);
+        m_debug_cntr ++;
+    }
+
+    if(m_debug_cntr > 30)
+    {
+        m_isDebug = false;
+        print_stats();
+    }
+#endif
+
+    if((m_period != 0) && ((m_tm_now % m_period) == 0))
+    {
+        output << "Period reached, " << std::dec
+               << m_period << ", "
+               << m_tm_now << ", "
+               << m_isPeriod << ", "
+               << m_isCMDPending << std::endl;
+            
+        m_isPeriod = true;
+    }
+
+    if((m_isPeriod == true) && (m_isCMDPending == false))
+    {
+        print_stats();
+        clear_stats();
+        m_isPeriod = false;
+    }
+}
+
+}}
+
+// 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
+
