diff --git a/array.cc b/array.cc
index a614fd8..d826972 100644
--- a/array.cc
+++ b/array.cc
@@ -123,7 +123,7 @@ void ArrayST::optimize_array()
 
 			//		from best area to worst area -->worst timing to best timing
 			if ((((local_result.cycle_time - throughput) <= 1e-10 ) && (local_result.access_time - latency)<= 1e-10)||
-					(local_result.data_array2->area_efficiency < area_efficiency_threshold && l_ip.assoc == 0))
+               (local_result.data_array2.area_efficiency < area_efficiency_threshold && l_ip.assoc == 0))
 			{  //if no satisfiable solution is found,the most aggressive one is left
 				candidate_solutions.push_back(local_result);
 				//output_data_csv(candidate_solutions.back());
@@ -229,24 +229,24 @@ void ArrayST::optimize_array()
 		local_result.power.readOp.leakage*long_channel_device_reduction;
 	local_result.power = local_result.power* pppm_t;
 
-	local_result.data_array2->power.readOp.dynamic *= sckRation;
-	local_result.data_array2->power.writeOp.dynamic *= sckRation;
-	local_result.data_array2->power.searchOp.dynamic *= sckRation;
-	local_result.data_array2->power.readOp.leakage *= l_ip.nbanks;
-	local_result.data_array2->power.readOp.longer_channel_leakage =
-		local_result.data_array2->power.readOp.leakage*long_channel_device_reduction;
-	local_result.data_array2->power = local_result.data_array2->power* pppm_t;
+   local_result.data_array2.power.readOp.dynamic *= sckRation;
+   local_result.data_array2.power.writeOp.dynamic *= sckRation;
+   local_result.data_array2.power.searchOp.dynamic *= sckRation;
+   local_result.data_array2.power.readOp.leakage *= l_ip.nbanks;
+   local_result.data_array2.power.readOp.longer_channel_leakage =
+      local_result.data_array2.power.readOp.leakage*long_channel_device_reduction;
+   local_result.data_array2.power = local_result.data_array2.power* pppm_t;
 
 
 	if (!(l_ip.pure_cam || l_ip.pure_ram || l_ip.fully_assoc) && l_ip.is_cache)
 	{
-		local_result.tag_array2->power.readOp.dynamic *= sckRation;
-		local_result.tag_array2->power.writeOp.dynamic *= sckRation;
-		local_result.tag_array2->power.searchOp.dynamic *= sckRation;
-		local_result.tag_array2->power.readOp.leakage *= l_ip.nbanks;
-		local_result.tag_array2->power.readOp.longer_channel_leakage =
-			local_result.tag_array2->power.readOp.leakage*long_channel_device_reduction;
-		local_result.tag_array2->power = local_result.tag_array2->power* pppm_t;
+      local_result.tag_array2.power.readOp.dynamic *= sckRation;
+      local_result.tag_array2.power.writeOp.dynamic *= sckRation;
+      local_result.tag_array2.power.searchOp.dynamic *= sckRation;
+      local_result.tag_array2.power.readOp.leakage *= l_ip.nbanks;
+      local_result.tag_array2.power.readOp.longer_channel_leakage =
+         local_result.tag_array2.power.readOp.leakage*long_channel_device_reduction;
+      local_result.tag_array2.power = local_result.tag_array2.power* pppm_t;
 	}
 
 
@@ -277,21 +277,21 @@ void ArrayST::leakage_feedback(double temperature)
   local_result.power.readOp.longer_channel_leakage = local_result.power.readOp.leakage*long_channel_device_reduction;
   local_result.power = local_result.power* pppm_t;
 
-  local_result.data_array2->power.readOp.dynamic *= sckRation;
-  local_result.data_array2->power.writeOp.dynamic *= sckRation;
-  local_result.data_array2->power.searchOp.dynamic *= sckRation;
-  local_result.data_array2->power.readOp.leakage *= l_ip.nbanks;
-  local_result.data_array2->power.readOp.longer_channel_leakage = local_result.data_array2->power.readOp.leakage*long_channel_device_reduction;
-  local_result.data_array2->power = local_result.data_array2->power* pppm_t;
+  local_result.data_array2.power.readOp.dynamic *= sckRation;
+  local_result.data_array2.power.writeOp.dynamic *= sckRation;
+  local_result.data_array2.power.searchOp.dynamic *= sckRation;
+  local_result.data_array2.power.readOp.leakage *= l_ip.nbanks;
+  local_result.data_array2.power.readOp.longer_channel_leakage = local_result.data_array2.power.readOp.leakage*long_channel_device_reduction;
+  local_result.data_array2.power = local_result.data_array2.power* pppm_t;
 
   if (!(l_ip.pure_cam || l_ip.pure_ram || l_ip.fully_assoc) && l_ip.is_cache)
   {
-    local_result.tag_array2->power.readOp.dynamic *= sckRation;
-    local_result.tag_array2->power.writeOp.dynamic *= sckRation;
-    local_result.tag_array2->power.searchOp.dynamic *= sckRation;
-    local_result.tag_array2->power.readOp.leakage *= l_ip.nbanks;
-    local_result.tag_array2->power.readOp.longer_channel_leakage = local_result.tag_array2->power.readOp.leakage*long_channel_device_reduction;
-    local_result.tag_array2->power = local_result.tag_array2->power* pppm_t;
+    local_result.tag_array2.power.readOp.dynamic *= sckRation;
+    local_result.tag_array2.power.writeOp.dynamic *= sckRation;
+    local_result.tag_array2.power.searchOp.dynamic *= sckRation;
+    local_result.tag_array2.power.readOp.leakage *= l_ip.nbanks;
+    local_result.tag_array2.power.readOp.longer_channel_leakage = local_result.tag_array2.power.readOp.leakage*long_channel_device_reduction;
+    local_result.tag_array2.power = local_result.tag_array2.power* pppm_t;
   }
 }
 
diff --git a/cacti/Ucache.cc b/cacti/Ucache.cc
index 8f78fd6..f5de1f3 100644
--- a/cacti/Ucache.cc
+++ b/cacti/Ucache.cc
@@ -447,48 +447,48 @@ bool calculate_time(
 
 
 
-bool check_uca_org(uca_org_t & u, min_values_t *minval)
+bool check_uca_org(uca_org_t & u, const min_values_t & minval)
 {
-  if (((u.access_time - minval->min_delay)*100/minval->min_delay) > g_ip->delay_dev) {
+  if (((u.access_time - minval.min_delay)*100/minval.min_delay) > g_ip->delay_dev) {
     return false;
   }
-  if (((u.power.readOp.dynamic - minval->min_dyn)/minval->min_dyn)*100 >
+  if (((u.power.readOp.dynamic - minval.min_dyn)/minval.min_dyn)*100 >
       g_ip->dynamic_power_dev) {
     return false;
   }
-  if (((u.power.readOp.leakage - minval->min_leakage)/minval->min_leakage)*100 >
+  if (((u.power.readOp.leakage - minval.min_leakage)/minval.min_leakage)*100 >
       g_ip->leakage_power_dev) {
     return false;
   }
-  if (((u.cycle_time - minval->min_cyc)/minval->min_cyc)*100 >
+  if (((u.cycle_time - minval.min_cyc)/minval.min_cyc)*100 >
       g_ip->cycle_time_dev) {
     return false;
   }
-  if (((u.area - minval->min_area)/minval->min_area)*100 >
+  if (((u.area - minval.min_area)/minval.min_area)*100 >
       g_ip->area_dev) {
     return false;
   }
   return true;
 }
 
-bool check_mem_org(mem_array & u, const min_values_t *minval)
+bool check_mem_org(mem_array & u, const min_values_t & minval)
 {
-  if (((u.access_time - minval->min_delay)*100/minval->min_delay) > g_ip->delay_dev) {
+  if (((u.access_time - minval.min_delay)*100/minval.min_delay) > g_ip->delay_dev) {
     return false;
   }
-  if (((u.power.readOp.dynamic - minval->min_dyn)/minval->min_dyn)*100 >
+  if (((u.power.readOp.dynamic - minval.min_dyn)/minval.min_dyn)*100 >
       g_ip->dynamic_power_dev) {
     return false;
   }
-  if (((u.power.readOp.leakage - minval->min_leakage)/minval->min_leakage)*100 >
+  if (((u.power.readOp.leakage - minval.min_leakage)/minval.min_leakage)*100 >
       g_ip->leakage_power_dev) {
     return false;
   }
-  if (((u.cycle_time - minval->min_cyc)/minval->min_cyc)*100 >
+  if (((u.cycle_time - minval.min_cyc)/minval.min_cyc)*100 >
       g_ip->cycle_time_dev) {
     return false;
   }
-  if (((u.area - minval->min_area)/minval->min_area)*100 >
+  if (((u.area - minval.min_area)/minval.min_area)*100 >
       g_ip->area_dev) {
     return false;
   }
@@ -498,7 +498,7 @@ bool check_mem_org(mem_array & u, const min_values_t *minval)
 
 
 
-void find_optimal_uca(uca_org_t *res, min_values_t * minval, list<uca_org_t> & ulist)
+void find_optimal_uca(uca_org_t * res, const min_values_t & minval, list<uca_org_t> & ulist)
 {
   double cost = 0;
   double min_cost = BIGNUM;
@@ -520,7 +520,7 @@ void find_optimal_uca(uca_org_t *res, min_values_t * minval, list<uca_org_t> & u
   {
     if (g_ip->ed == 1)
     {
-      cost = ((niter)->access_time/minval->min_delay) * ((niter)->power.readOp.dynamic/minval->min_dyn);
+      cost = ((niter)->access_time/minval.min_delay) * ((niter)->power.readOp.dynamic/minval.min_dyn);
       if (min_cost > cost)
       {
         min_cost = cost;
@@ -529,9 +529,9 @@ void find_optimal_uca(uca_org_t *res, min_values_t * minval, list<uca_org_t> & u
     }
     else if (g_ip->ed == 2)
     {
-      cost = ((niter)->access_time/minval->min_delay)*
-             ((niter)->access_time/minval->min_delay)*
-             ((niter)->power.readOp.dynamic/minval->min_dyn);
+      cost = ((niter)->access_time/minval.min_delay)*
+             ((niter)->access_time/minval.min_delay)*
+             ((niter)->power.readOp.dynamic/minval.min_dyn);
       if (min_cost > cost)
       {
         min_cost = cost;
@@ -549,11 +549,11 @@ void find_optimal_uca(uca_org_t *res, min_values_t * minval, list<uca_org_t> & u
 
       if (v)
       {
-        cost = (d  * ((niter)->access_time/minval->min_delay) +
-                c  * ((niter)->cycle_time/minval->min_cyc) +
-                dp * ((niter)->power.readOp.dynamic/minval->min_dyn) +
-                lp * ((niter)->power.readOp.leakage/minval->min_leakage) +
-                a  * ((niter)->area/minval->min_area));
+        cost = (d  * ((niter)->access_time/minval.min_delay) +
+                c  * ((niter)->cycle_time/minval.min_cyc) +
+                dp * ((niter)->power.readOp.dynamic/minval.min_dyn) +
+                lp * ((niter)->power.readOp.leakage/minval.min_leakage) +
+                a  * ((niter)->area/minval.min_area));
         //fprintf(stderr, "cost = %g\n", cost);
 
         if (min_cost > cost) {
@@ -581,7 +581,7 @@ void find_optimal_uca(uca_org_t *res, min_values_t * minval, list<uca_org_t> & u
 
 
 
-void filter_tag_arr(const min_values_t * min, list<mem_array *> & list)
+void filter_tag_arr(const min_values_t & min, list<mem_array *> & list)
 {
   double cost = BIGNUM;
   double cur_cost;
@@ -600,11 +600,11 @@ void filter_tag_arr(const min_values_t * min, list<mem_array *> & list)
     bool v = check_mem_org(*list.back(), min);
     if (v)
     {
-      cur_cost = wt_delay   * (list.back()->access_time/min->min_delay) +
-        wt_dyn     * (list.back()->power.readOp.dynamic/min->min_dyn) +
-        wt_leakage * (list.back()->power.readOp.leakage/min->min_leakage) +
-        wt_area    * (list.back()->area/min->min_area) +
-        wt_cyc     * (list.back()->cycle_time/min->min_cyc);
+      cur_cost = wt_delay   * (list.back()->access_time/min.min_delay) +
+        wt_dyn     * (list.back()->power.readOp.dynamic/min.min_dyn) +
+        wt_leakage * (list.back()->power.readOp.leakage/min.min_leakage) +
+        wt_area    * (list.back()->area/min.min_area) +
+        wt_cyc     * (list.back()->cycle_time/min.min_cyc);
     }
     else
     {
@@ -652,8 +652,8 @@ void filter_data_arr(list<mem_array *> & curr_list)
 
     if (m == NULL) exit(1);
 
-    if(((m->access_time - m->arr_min->min_delay)/m->arr_min->min_delay > 0.5) &&
-       ((m->power.readOp.dynamic - m->arr_min->min_dyn)/m->arr_min->min_dyn > 0.5))
+    if(((m->access_time - m->arr_min.min_delay)/m->arr_min.min_delay > 0.5) &&
+       ((m->power.readOp.dynamic - m->arr_min.min_dyn)/m->arr_min.min_dyn > 0.5))
     {
       delete m;
       iter = curr_list.erase(iter);
@@ -784,14 +784,14 @@ void solve(uca_org_t *fin_res)
 //  }
 
 
-  min_values_t * d_min = new min_values_t();
-  min_values_t * t_min = new min_values_t();
-  min_values_t * cache_min = new min_values_t();
+  min_values_t d_min = min_values_t();
+  min_values_t t_min = min_values_t();
+  min_values_t cache_min = min_values_t();
 
   for (uint32_t t = 0; t < nthreads; t++)
   {
-    d_min->update_min_values(calc_array[t].data_res);
-    t_min->update_min_values(calc_array[t].tag_res);
+    d_min.update_min_values(calc_array[t].data_res);
+    t_min.update_min_values(calc_array[t].tag_res);
   }
 
   for (miter = data_arr.begin(); miter != data_arr.end(); miter++)
@@ -814,8 +814,8 @@ void solve(uca_org_t *fin_res)
     for (miter = data_arr.begin(); miter != data_arr.end(); miter++)
     {
       uca_org_t & curr_org  = sol_list.back();
-      curr_org.tag_array2  = NULL;
-      curr_org.data_array2 = (*miter);
+      //curr_org.tag_array2  = NULL;
+      curr_org.data_array2 = *(*miter);
 
       curr_org.find_delay();
       curr_org.find_energy();
@@ -823,7 +823,7 @@ void solve(uca_org_t *fin_res)
       curr_org.find_cyc();
 
       //update min values for the entire cache
-      cache_min->update_min_values(curr_org);
+      cache_min.update_min_values(curr_org);
 
       sol_list.push_back(uca_org_t());
     }
@@ -839,8 +839,8 @@ void solve(uca_org_t *fin_res)
       for (miter = data_arr.begin(); miter != data_arr.end(); miter++)
       {
         uca_org_t & curr_org  = sol_list.back();
-        curr_org.tag_array2  = arr_temp;
-        curr_org.data_array2 = (*miter);
+        curr_org.tag_array2  = *arr_temp;
+        curr_org.data_array2 = *(*miter);
 
         curr_org.find_delay();
         curr_org.find_energy();
@@ -848,7 +848,7 @@ void solve(uca_org_t *fin_res)
         curr_org.find_cyc();
 
         //update min values for the entire cache
-        cache_min->update_min_values(curr_org);
+        cache_min.update_min_values(curr_org);
 
         sol_list.push_back(uca_org_t());
       }
@@ -861,13 +861,6 @@ void solve(uca_org_t *fin_res)
 
   sol_list.clear();
 
-  for (miter = data_arr.begin(); miter != data_arr.end(); ++miter)
-  {
-    if (*miter != fin_res->data_array2)
-    {
-      delete *miter;
-    }
-  }
   data_arr.clear();
 
   for (uint32_t t = 0; t < nthreads; t++)
@@ -877,34 +870,28 @@ void solve(uca_org_t *fin_res)
   }
 
   delete [] calc_array;
-  delete cache_min;
-  delete d_min;
-  delete t_min;
 }
 
 void update(uca_org_t *fin_res)
 {
-  if(fin_res->tag_array2)
-  {
     init_tech_params(g_ip->F_sz_um,true);
-    DynamicParameter tag_arr_dyn_p(true, g_ip->pure_ram, g_ip->pure_cam, fin_res->tag_array2->Nspd, fin_res->tag_array2->Ndwl, fin_res->tag_array2->Ndbl, fin_res->tag_array2->Ndcm, fin_res->tag_array2->Ndsam_lev_1, fin_res->tag_array2->Ndsam_lev_2, g_ip->is_main_mem);
+    DynamicParameter tag_arr_dyn_p(true, g_ip->pure_ram, g_ip->pure_cam, fin_res->tag_array2.Nspd, fin_res->tag_array2.Ndwl, fin_res->tag_array2.Ndbl, fin_res->tag_array2.Ndcm, fin_res->tag_array2.Ndsam_lev_1, fin_res->tag_array2.Ndsam_lev_2, g_ip->is_main_mem);
     if(tag_arr_dyn_p.is_valid)
     {
       UCA * tag_arr = new UCA(tag_arr_dyn_p);
-      fin_res->tag_array2->power = tag_arr->power;
+      fin_res->tag_array2.power = tag_arr->power;
     }
     else
     {
       cout << "ERROR: Cannot retrieve array structure for leakage feedback" << endl;
       exit(1);
     }
-  }
   init_tech_params(g_ip->F_sz_um,false);
-  DynamicParameter data_arr_dyn_p(false, g_ip->pure_ram, g_ip->pure_cam, fin_res->data_array2->Nspd, fin_res->data_array2->Ndwl, fin_res->data_array2->Ndbl, fin_res->data_array2->Ndcm, fin_res->data_array2->Ndsam_lev_1, fin_res->data_array2->Ndsam_lev_2, g_ip->is_main_mem);
+  DynamicParameter data_arr_dyn_p(false, g_ip->pure_ram, g_ip->pure_cam, fin_res->data_array2.Nspd, fin_res->data_array2.Ndwl, fin_res->data_array2.Ndbl, fin_res->data_array2.Ndcm, fin_res->data_array2.Ndsam_lev_1, fin_res->data_array2.Ndsam_lev_2, g_ip->is_main_mem);
   if(data_arr_dyn_p.is_valid)
   {
     UCA * data_arr = new UCA(data_arr_dyn_p);
-    fin_res->data_array2->power = data_arr->power;
+    fin_res->data_array2.power = data_arr->power;
   }
   else
   {
diff --git a/cacti/Ucache.h b/cacti/Ucache.h
index cbd578f..835d32d 100644
--- a/cacti/Ucache.h
+++ b/cacti/Ucache.h
@@ -39,24 +39,6 @@
 #include "nuca.h"
 
 
-class min_values_t
-{
-  public:
-    double min_delay;
-    double min_dyn;
-    double min_leakage;
-    double min_area;
-    double min_cyc;
-
-    min_values_t() : min_delay(BIGNUM), min_dyn(BIGNUM), min_leakage(BIGNUM), min_area(BIGNUM), min_cyc(BIGNUM) { }
-
-    void update_min_values(const min_values_t * val);
-    void update_min_values(const uca_org_t & res);
-    void update_min_values(const nuca_org_t * res);
-    void update_min_values(const mem_array * res);
-};
-
-
 
 struct solution
 {
diff --git a/cacti/cacti_interface.cc b/cacti/cacti_interface.cc
index 99d734d..7c28f5e 100644
--- a/cacti/cacti_interface.cc
+++ b/cacti/cacti_interface.cc
@@ -68,13 +68,13 @@ bool mem_array::lt(const mem_array * m1, const mem_array * m2)
 
 void uca_org_t::find_delay()
 {
-  mem_array * data_arr = data_array2;
-  mem_array * tag_arr  = tag_array2;
+  mem_array & data_arr = data_array2;
+  mem_array & tag_arr  = tag_array2;
 
   // check whether it is a regular cache or scratch ram
   if (g_ip->pure_ram|| g_ip->pure_cam || g_ip->fully_assoc)
   {
-    access_time = data_arr->access_time;
+    access_time = data_arr.access_time;
   }
   // Both tag and data lookup happen in parallel
   // and the entire set is sent over the data array h-tree without
@@ -82,23 +82,23 @@ void uca_org_t::find_delay()
   // power overhead Nav
   else if (g_ip->fast_access == true)
   {
-    access_time = MAX(tag_arr->access_time, data_arr->access_time);
+    access_time = MAX(tag_arr.access_time, data_arr.access_time);
   }
   // Tag is accessed first. On a hit, way-select signal along with the
   // address is sent to read/write the appropriate block in the data
   // array
   else if (g_ip->is_seq_acc == true)
   {
-    access_time = tag_arr->access_time + data_arr->access_time;
+    access_time = tag_arr.access_time + data_arr.access_time;
   }
   // Normal access: tag array access and data array access happen in parallel.
   // But, the data array will wait for the way-select and transfer only the
   // appropriate block over the h-tree.
   else
   {
-    access_time = MAX(tag_arr->access_time + data_arr->delay_senseamp_mux_decoder,
-                      data_arr->delay_before_subarray_output_driver) +
-                  data_arr->delay_from_subarray_output_driver_to_output;
+    access_time = MAX(tag_arr.access_time + data_arr.delay_senseamp_mux_decoder,
+                      data_arr.delay_before_subarray_output_driver) +
+                  data_arr.delay_from_subarray_output_driver_to_output;
   }
 }
 
@@ -107,9 +107,9 @@ void uca_org_t::find_delay()
 void uca_org_t::find_energy()
 {
   if (!(g_ip->pure_ram|| g_ip->pure_cam || g_ip->fully_assoc))//(g_ip->is_cache)
-    power = data_array2->power + tag_array2->power;
+    power = data_array2.power + tag_array2.power;
   else
-    power = data_array2->power;
+    power = data_array2.power;
 }
 
 
@@ -118,13 +118,13 @@ void uca_org_t::find_area()
 {
   if (g_ip->pure_ram|| g_ip->pure_cam || g_ip->fully_assoc)//(g_ip->is_cache == false)
   {
-    cache_ht  = data_array2->height;
-    cache_len = data_array2->width;
+    cache_ht  = data_array2.height;
+    cache_len = data_array2.width;
   }
   else
   {
-    cache_ht  = MAX(tag_array2->height, data_array2->height);
-    cache_len = tag_array2->width + data_array2->width;
+    cache_ht  = MAX(tag_array2.height, data_array2.height);
+    cache_len = tag_array2.width + data_array2.width;
   }
   area = cache_ht * cache_len;
 }
@@ -134,10 +134,10 @@ void uca_org_t::adjust_area()
   double area_adjust;
   if (g_ip->pure_ram|| g_ip->pure_cam || g_ip->fully_assoc)
   {
-    if (data_array2->area_efficiency/100.0<0.2)
+    if (data_array2.area_efficiency/100.0<0.2)
     {
     	//area_adjust = sqrt(area/(area*(data_array2->area_efficiency/100.0)/0.2));
-    	area_adjust = sqrt(0.2/(data_array2->area_efficiency/100.0));
+      area_adjust = sqrt(0.2/(data_array2.area_efficiency/100.0));
     	cache_ht  = cache_ht/area_adjust;
     	cache_len = cache_len/area_adjust;
     }
@@ -149,26 +149,29 @@ void uca_org_t::find_cyc()
 {
   if ((g_ip->pure_ram|| g_ip->pure_cam || g_ip->fully_assoc))//(g_ip->is_cache == false)
   {
-    cycle_time = data_array2->cycle_time;
+    cycle_time = data_array2.cycle_time;
   }
   else
   {
-    cycle_time = MAX(tag_array2->cycle_time,
-                    data_array2->cycle_time);
+    cycle_time = MAX(tag_array2.cycle_time,
+                    data_array2.cycle_time);
   }
 }
 
 uca_org_t :: uca_org_t()
-:tag_array2(0),
- data_array2(0)
 {
 
 }
 
 void uca_org_t :: cleanup()
 {
-	  if (data_array2!=0)
-		  delete data_array2;
-	  if (tag_array2!=0)
-		  delete tag_array2;
+}
+
+// Clear out all data used as the DB key, especially unused bits
+// such that they're zero and not old data that might be different per run
+InputParameter::InputParameter()
+{
+    size_t o1 = offsetof(InputParameter, first),
+           o2 = offsetof(InputParameter, last);
+    memset((char*)this + o1, 0, o2 - o1);
 }
diff --git a/cacti/cacti_interface.h b/cacti/cacti_interface.h
index f6b6424..d356634 100644
--- a/cacti/cacti_interface.h
+++ b/cacti/cacti_interface.h
@@ -47,6 +47,7 @@ using namespace std;
 class min_values_t;
 class mem_array;
 class uca_org_t;
+class nuca_org_t;
 
 
 class powerComponents
@@ -107,14 +108,16 @@ enum Wire_type
 
 
 
-class InputParameter
+struct InputParameter
 {
-  public:
+    InputParameter();
     void parse_cfg(const string & infile);
 
     bool error_checking();  // return false if the input parameters are problematic
     void display_ip();
 
+    long first; // used to know where the interesting data is
+
     unsigned int cache_sz;  // in bytes
     unsigned int line_sz;
     unsigned int assoc;
@@ -200,6 +203,8 @@ class InputParameter
   int pipeline_stages;
   int per_stage_vector;
   bool with_clock_grid;
+
+    long last; // used to know where the interesting data is
 };
 
 
@@ -351,11 +356,117 @@ typedef struct{
 } results_mem_array;
 
 
+class min_values_t
+{
+  public:
+    double min_delay;
+    double min_dyn;
+    double min_leakage;
+    double min_area;
+    double min_cyc;
+
+    min_values_t() : min_delay(BIGNUM), min_dyn(BIGNUM), min_leakage(BIGNUM), min_area(BIGNUM), min_cyc(BIGNUM) { }
+
+    void update_min_values(const min_values_t * val);
+    void update_min_values(const uca_org_t & res);
+    void update_min_values(const nuca_org_t * res);
+    void update_min_values(const mem_array * res);
+};
+
+
+class mem_array
+{
+  public:
+  int    Ndcm;
+  int    Ndwl;
+  int    Ndbl;
+  double Nspd;
+  int    deg_bl_muxing;
+  int    Ndsam_lev_1;
+  int    Ndsam_lev_2;
+  double access_time;
+  double cycle_time;
+  double multisubbank_interleave_cycle_time;
+  double area_ram_cells;
+  double area;
+  powerDef power;
+  double delay_senseamp_mux_decoder;
+  double delay_before_subarray_output_driver;
+  double delay_from_subarray_output_driver_to_output;
+  double height;
+  double width;
+
+  double mat_height;
+  double mat_length;
+  double subarray_length;
+  double subarray_height;
+
+  double delay_route_to_bank,
+         delay_input_htree,
+         delay_row_predecode_driver_and_block,
+         delay_row_decoder,
+         delay_bitlines,
+         delay_sense_amp,
+         delay_subarray_output_driver,
+         delay_dout_htree,
+         delay_comparator,
+         delay_matchlines;
+
+  double all_banks_height,
+         all_banks_width,
+         area_efficiency;
+
+  powerDef power_routing_to_bank;
+  powerDef power_addr_input_htree;
+  powerDef power_data_input_htree;
+  powerDef power_data_output_htree;
+  powerDef power_htree_in_search;
+  powerDef power_htree_out_search;
+  powerDef power_row_predecoder_drivers;
+  powerDef power_row_predecoder_blocks;
+  powerDef power_row_decoders;
+  powerDef power_bit_mux_predecoder_drivers;
+  powerDef power_bit_mux_predecoder_blocks;
+  powerDef power_bit_mux_decoders;
+  powerDef power_senseamp_mux_lev_1_predecoder_drivers;
+  powerDef power_senseamp_mux_lev_1_predecoder_blocks;
+  powerDef power_senseamp_mux_lev_1_decoders;
+  powerDef power_senseamp_mux_lev_2_predecoder_drivers;
+  powerDef power_senseamp_mux_lev_2_predecoder_blocks;
+  powerDef power_senseamp_mux_lev_2_decoders;
+  powerDef power_bitlines;
+  powerDef power_sense_amps;
+  powerDef power_prechg_eq_drivers;
+  powerDef power_output_drivers_at_subarray;
+  powerDef power_dataout_vertical_htree;
+  powerDef power_comparators;
+
+  powerDef power_cam_bitline_precharge_eq_drv;
+  powerDef power_searchline;
+  powerDef power_searchline_precharge;
+  powerDef power_matchlines;
+  powerDef power_matchline_precharge;
+  powerDef power_matchline_to_wordline_drv;
+
+  min_values_t arr_min;
+  enum Wire_type wt;
+
+  // dram stats
+  double activate_energy, read_energy, write_energy, precharge_energy,
+  refresh_power, leak_power_subbank_closed_page, leak_power_subbank_open_page,
+  leak_power_request_and_reply_networks;
+
+  double precharge_delay;
+
+  static bool lt(const mem_array * m1, const mem_array * m2);
+};
+
+
 class uca_org_t
 {
   public:
-    mem_array * tag_array2;
-    mem_array * data_array2;
+    mem_array tag_array2;
+    mem_array data_array2;
     double access_time;
     double cycle_time;
     double area;
@@ -541,92 +652,5 @@ uca_org_t cacti_interface(
     int REPEATERS_IN_HTREE_SEGMENTS_in,//TODO for now only wires with repeaters are supported
     int p_input);
 
-class mem_array
-{
-  public:
-  int    Ndcm;
-  int    Ndwl;
-  int    Ndbl;
-  double Nspd;
-  int    deg_bl_muxing;
-  int    Ndsam_lev_1;
-  int    Ndsam_lev_2;
-  double access_time;
-  double cycle_time;
-  double multisubbank_interleave_cycle_time;
-  double area_ram_cells;
-  double area;
-  powerDef power;
-  double delay_senseamp_mux_decoder;
-  double delay_before_subarray_output_driver;
-  double delay_from_subarray_output_driver_to_output;
-  double height;
-  double width;
-
-  double mat_height;
-  double mat_length;
-  double subarray_length;
-  double subarray_height;
-
-  double delay_route_to_bank,
-         delay_input_htree,
-         delay_row_predecode_driver_and_block,
-         delay_row_decoder,
-         delay_bitlines,
-         delay_sense_amp,
-         delay_subarray_output_driver,
-         delay_dout_htree,
-         delay_comparator,
-         delay_matchlines;
-
-  double all_banks_height,
-         all_banks_width,
-         area_efficiency;
-
-  powerDef power_routing_to_bank;
-  powerDef power_addr_input_htree;
-  powerDef power_data_input_htree;
-  powerDef power_data_output_htree;
-  powerDef power_htree_in_search;
-  powerDef power_htree_out_search;
-  powerDef power_row_predecoder_drivers;
-  powerDef power_row_predecoder_blocks;
-  powerDef power_row_decoders;
-  powerDef power_bit_mux_predecoder_drivers;
-  powerDef power_bit_mux_predecoder_blocks;
-  powerDef power_bit_mux_decoders;
-  powerDef power_senseamp_mux_lev_1_predecoder_drivers;
-  powerDef power_senseamp_mux_lev_1_predecoder_blocks;
-  powerDef power_senseamp_mux_lev_1_decoders;
-  powerDef power_senseamp_mux_lev_2_predecoder_drivers;
-  powerDef power_senseamp_mux_lev_2_predecoder_blocks;
-  powerDef power_senseamp_mux_lev_2_decoders;
-  powerDef power_bitlines;
-  powerDef power_sense_amps;
-  powerDef power_prechg_eq_drivers;
-  powerDef power_output_drivers_at_subarray;
-  powerDef power_dataout_vertical_htree;
-  powerDef power_comparators;
-
-  powerDef power_cam_bitline_precharge_eq_drv;
-  powerDef power_searchline;
-  powerDef power_searchline_precharge;
-  powerDef power_matchlines;
-  powerDef power_matchline_precharge;
-  powerDef power_matchline_to_wordline_drv;
-
-  min_values_t *arr_min;
-  enum Wire_type wt;
-
-  // dram stats
-  double activate_energy, read_energy, write_energy, precharge_energy,
-  refresh_power, leak_power_subbank_closed_page, leak_power_subbank_open_page,
-  leak_power_request_and_reply_networks;
-
-  double precharge_delay;
-
-  static bool lt(const mem_array * m1, const mem_array * m2);
-};
-
 
 #endif
diff --git a/cacti/io.cc b/cacti/io.cc
index 3bcf5b8..18c62b0 100644
--- a/cacti/io.cc
+++ b/cacti/io.cc
@@ -34,6 +34,7 @@
 #include <fstream>
 #include <iostream>
 #include <sstream>
+#include <db.h>
 
 
 #include "io.h"
@@ -1438,22 +1439,22 @@ void output_data_csv(const uca_org_t & fin_res)
     file << g_ip->out_w << ", ";
     file << fin_res.access_time*1e+9 << ", ";
     file << fin_res.cycle_time*1e+9 << ", ";
-//    file << fin_res.data_array2->multisubbank_interleave_cycle_time*1e+9 << ", ";
-//    file << fin_res.data_array2->delay_request_network*1e+9 << ", ";
-//    file << fin_res.data_array2->delay_inside_mat*1e+9 <<  ", ";
+//    file << fin_res.data_array2.multisubbank_interleave_cycle_time*1e+9 << ", ";
+//    file << fin_res.data_array2.delay_request_network*1e+9 << ", ";
+//    file << fin_res.data_array2.delay_inside_mat*1e+9 <<  ", ";
 //    file << fin_res.data_array2.delay_reply_network*1e+9 << ", ";
 
 //    if (!(g_ip->fully_assoc || g_ip->pure_cam || g_ip->pure_ram))
 //        {
-//    	  file << fin_res.tag_array2->access_time*1e+9 << ", ";
+//    	  file << fin_res.tag_array2.access_time*1e+9 << ", ";
 //        }
 //    else
 //    {
 //    	file << 0 << ", ";
 //    }
-//    file << fin_res.data_array2->access_time*1e+9 << ", ";
-//    file << fin_res.data_array2->dram_refresh_period*1e+6 << ", ";
-//    file << fin_res.data_array2->dram_array_availability <<  ", ";
+//    file << fin_res.data_array2.access_time*1e+9 << ", ";
+//    file << fin_res.data_array2.dram_refresh_period*1e+6 << ", ";
+//    file << fin_res.data_array2.dram_array_availability <<  ", ";
     if (g_ip->fully_assoc || g_ip->pure_cam)
     {
     	file << fin_res.power.searchOp.dynamic*1e+9 << ", ";
@@ -1466,13 +1467,13 @@ void output_data_csv(const uca_org_t & fin_res)
     file << fin_res.power.writeOp.dynamic*1e+9 << ", ";
 //    if (!(g_ip->fully_assoc || g_ip->pure_cam || g_ip->pure_ram))
 //        {
-//        	file << fin_res.tag_array2->power.readOp.dynamic*1e+9 << ", ";
+//        	file << fin_res.tag_array2.power.readOp.dynamic*1e+9 << ", ";
 //        }
 //        	else
 //        {
 //        		file << "NA" << ", ";
 //        }
-//    file << fin_res.data_array2->power.readOp.dynamic*1e+9 << ", ";
+//    file << fin_res.data_array2.power.readOp.dynamic*1e+9 << ", ";
 //    if (g_ip->fully_assoc || g_ip->pure_cam)
 //        {
 //    	    file << fin_res.power.searchOp.dynamic*1000/fin_res.cycle_time << ", ";
@@ -1487,22 +1488,22 @@ void output_data_csv(const uca_org_t & fin_res)
 //    file << fin_res.data_array.refresh_power / fin_res.data_array.total_power.readOp.leakage << ", ";
     file << fin_res.area*1e-6 << ", ";
 
-    file << fin_res.data_array2->Ndwl << ", ";
-    file << fin_res.data_array2->Ndbl << ", ";
-    file << fin_res.data_array2->Nspd << ", ";
-    file << fin_res.data_array2->deg_bl_muxing << ", ";
-    file << fin_res.data_array2->Ndsam_lev_1 << ", ";
-    file << fin_res.data_array2->Ndsam_lev_2 << ", ";
-    file << fin_res.data_array2->area_efficiency << ", ";
+    file << fin_res.data_array2.Ndwl << ", ";
+    file << fin_res.data_array2.Ndbl << ", ";
+    file << fin_res.data_array2.Nspd << ", ";
+    file << fin_res.data_array2.deg_bl_muxing << ", ";
+    file << fin_res.data_array2.Ndsam_lev_1 << ", ";
+    file << fin_res.data_array2.Ndsam_lev_2 << ", ";
+    file << fin_res.data_array2.area_efficiency << ", ";
     if (!(g_ip->fully_assoc || g_ip->pure_cam || g_ip->pure_ram))
     {
-    file << fin_res.tag_array2->Ndwl << ", ";
-    file << fin_res.tag_array2->Ndbl << ", ";
-    file << fin_res.tag_array2->Nspd << ", ";
-    file << fin_res.tag_array2->deg_bl_muxing << ", ";
-    file << fin_res.tag_array2->Ndsam_lev_1 << ", ";
-    file << fin_res.tag_array2->Ndsam_lev_2 << ", ";
-    file << fin_res.tag_array2->area_efficiency << ", ";
+    file << fin_res.tag_array2.Ndwl << ", ";
+    file << fin_res.tag_array2.Ndbl << ", ";
+    file << fin_res.tag_array2.Nspd << ", ";
+    file << fin_res.tag_array2.deg_bl_muxing << ", ";
+    file << fin_res.tag_array2.Ndsam_lev_1 << ", ";
+    file << fin_res.tag_array2.Ndsam_lev_2 << ", ";
+    file << fin_res.tag_array2.area_efficiency << ", ";
     }
     else
     {
@@ -1597,16 +1598,16 @@ void output_UCA(uca_org_t *fr)
   cout << "    Access time (ns): " << fr->access_time*1e9 << endl;
   cout << "    Cycle time (ns):  " << fr->cycle_time*1e9 << endl;
   if (g_ip->data_arr_ram_cell_tech_type >= 4) {
-    cout << "    Precharge Delay (ns): " << fr->data_array2->precharge_delay*1e9 << endl;
-    cout << "    Activate Energy (nJ): " << fr->data_array2->activate_energy*1e9 << endl;
-    cout << "    Read Energy (nJ): " << fr->data_array2->read_energy*1e9 << endl;
-    cout << "    Write Energy (nJ): " << fr->data_array2->write_energy*1e9 << endl;
-    cout << "    Precharge Energy (nJ): " << fr->data_array2->precharge_energy*1e9 << endl;
-    cout << "    Leakage Power Closed Page (mW): " << fr->data_array2->leak_power_subbank_closed_page*1e3 << endl;
-    cout << "    Leakage Power Open Page (mW): " << fr->data_array2->leak_power_subbank_open_page*1e3 << endl;
-    cout << "    Leakage Power I/O (mW): " << fr->data_array2->leak_power_request_and_reply_networks*1e3 << endl;
+    cout << "    Precharge Delay (ns): " << fr->data_array2.precharge_delay*1e9 << endl;
+    cout << "    Activate Energy (nJ): " << fr->data_array2.activate_energy*1e9 << endl;
+    cout << "    Read Energy (nJ): " << fr->data_array2.read_energy*1e9 << endl;
+    cout << "    Write Energy (nJ): " << fr->data_array2.write_energy*1e9 << endl;
+    cout << "    Precharge Energy (nJ): " << fr->data_array2.precharge_energy*1e9 << endl;
+    cout << "    Leakage Power Closed Page (mW): " << fr->data_array2.leak_power_subbank_closed_page*1e3 << endl;
+    cout << "    Leakage Power Open Page (mW): " << fr->data_array2.leak_power_subbank_open_page*1e3 << endl;
+    cout << "    Leakage Power I/O (mW): " << fr->data_array2.leak_power_request_and_reply_networks*1e3 << endl;
     cout << "    Refresh power (mW): " <<
-      fr->data_array2->refresh_power*1e3 << endl;
+      fr->data_array2.refresh_power*1e3 << endl;
   }
   else {
 	  if ((g_ip->fully_assoc|| g_ip->pure_cam))
@@ -1638,24 +1639,24 @@ void output_UCA(uca_org_t *fr)
     fr->cache_ht*1e-3 << " x " << fr->cache_len*1e-3 << endl << endl;
 
 
-  cout << "    Best Ndwl : " << fr->data_array2->Ndwl << endl;
-  cout << "    Best Ndbl : " << fr->data_array2->Ndbl << endl;
-  cout << "    Best Nspd : " << fr->data_array2->Nspd << endl;
-  cout << "    Best Ndcm : " << fr->data_array2->deg_bl_muxing << endl;
-  cout << "    Best Ndsam L1 : " << fr->data_array2->Ndsam_lev_1 << endl;
-  cout << "    Best Ndsam L2 : " << fr->data_array2->Ndsam_lev_2 << endl << endl;
+  cout << "    Best Ndwl : " << fr->data_array2.Ndwl << endl;
+  cout << "    Best Ndbl : " << fr->data_array2.Ndbl << endl;
+  cout << "    Best Nspd : " << fr->data_array2.Nspd << endl;
+  cout << "    Best Ndcm : " << fr->data_array2.deg_bl_muxing << endl;
+  cout << "    Best Ndsam L1 : " << fr->data_array2.Ndsam_lev_1 << endl;
+  cout << "    Best Ndsam L2 : " << fr->data_array2.Ndsam_lev_2 << endl << endl;
 
   if ((!(g_ip->pure_ram|| g_ip->pure_cam || g_ip->fully_assoc)) && !g_ip->is_main_mem)
   {
-    cout << "    Best Ntwl : " << fr->tag_array2->Ndwl << endl;
-    cout << "    Best Ntbl : " << fr->tag_array2->Ndbl << endl;
-    cout << "    Best Ntspd : " << fr->tag_array2->Nspd << endl;
-    cout << "    Best Ntcm : " << fr->tag_array2->deg_bl_muxing << endl;
-    cout << "    Best Ntsam L1 : " << fr->tag_array2->Ndsam_lev_1 << endl;
-    cout << "    Best Ntsam L2 : " << fr->tag_array2->Ndsam_lev_2 << endl;
+    cout << "    Best Ntwl : " << fr->tag_array2.Ndwl << endl;
+    cout << "    Best Ntbl : " << fr->tag_array2.Ndbl << endl;
+    cout << "    Best Ntspd : " << fr->tag_array2.Nspd << endl;
+    cout << "    Best Ntcm : " << fr->tag_array2.deg_bl_muxing << endl;
+    cout << "    Best Ntsam L1 : " << fr->tag_array2.Ndsam_lev_1 << endl;
+    cout << "    Best Ntsam L2 : " << fr->tag_array2.Ndsam_lev_2 << endl;
   }
 
-  switch (fr->data_array2->wt) {
+  switch (fr->data_array2.wt) {
     case (0):
       cout <<  "    Data array, H-tree wire type: Delay optimized global wires\n";
       break;
@@ -1675,12 +1676,12 @@ void output_UCA(uca_org_t *fr)
       cout <<  "    Data array, wire type: Low swing wires\n";
       break;
     default:
-      cout << "ERROR - Unknown wire type " << (int) fr->data_array2->wt <<endl;
+      cout << "ERROR - Unknown wire type " << (int) fr->data_array2.wt <<endl;
       exit(0);
   }
 
   if (!(g_ip->pure_ram|| g_ip->pure_cam || g_ip->fully_assoc)) {
-    switch (fr->tag_array2->wt) {
+    switch (fr->tag_array2.wt) {
       case (0):
         cout <<  "    Tag array, H-tree wire type: Delay optimized global wires\n";
         break;
@@ -1700,7 +1701,7 @@ void output_UCA(uca_org_t *fr)
         cout <<  "    Tag array, wire type: Low swing wires\n";
         break;
       default:
-        cout << "ERROR - Unknown wire type " << (int) fr->tag_array2->wt <<endl;
+        cout << "ERROR - Unknown wire type " << (int) fr->tag_array2.wt <<endl;
         exit(-1);
     }
   }
@@ -1714,61 +1715,61 @@ void output_UCA(uca_org_t *fr)
     cout << endl << "Time Components:" << endl << endl;
 
     cout << "  Data side (with Output driver) (ns): " <<
-      fr->data_array2->access_time/1e-9 << endl;
+      fr->data_array2.access_time/1e-9 << endl;
 
     cout <<  "\tH-tree input delay (ns): " <<
-      fr->data_array2->delay_route_to_bank * 1e9 +
-      fr->data_array2->delay_input_htree * 1e9 << endl;
+      fr->data_array2.delay_route_to_bank * 1e9 +
+      fr->data_array2.delay_input_htree * 1e9 << endl;
 
     if (!(g_ip->pure_cam || g_ip->fully_assoc))
     {
       cout <<  "\tDecoder + wordline delay (ns): " <<
-        fr->data_array2->delay_row_predecode_driver_and_block * 1e9 +
-        fr->data_array2->delay_row_decoder * 1e9 << endl;
+        fr->data_array2.delay_row_predecode_driver_and_block * 1e9 +
+        fr->data_array2.delay_row_decoder * 1e9 << endl;
     }
     else
     {
         cout <<  "\tCAM search delay (ns): " <<
-          fr->data_array2->delay_matchlines * 1e9 << endl;
+          fr->data_array2.delay_matchlines * 1e9 << endl;
     }
 
     cout <<  "\tBitline delay (ns): " <<
-      fr->data_array2->delay_bitlines/1e-9 << endl;
+      fr->data_array2.delay_bitlines/1e-9 << endl;
 
     cout <<  "\tSense Amplifier delay (ns): " <<
-      fr->data_array2->delay_sense_amp * 1e9 << endl;
+      fr->data_array2.delay_sense_amp * 1e9 << endl;
 
 
     cout <<  "\tH-tree output delay (ns): " <<
-      fr->data_array2->delay_subarray_output_driver * 1e9 +
-      fr->data_array2->delay_dout_htree * 1e9 << endl;
+      fr->data_array2.delay_subarray_output_driver * 1e9 +
+      fr->data_array2.delay_dout_htree * 1e9 << endl;
 
     if ((!(g_ip->pure_ram|| g_ip->pure_cam || g_ip->fully_assoc)) && !g_ip->is_main_mem)
     {
       /* tag array stats */
       cout << endl << "  Tag side (with Output driver) (ns): " <<
-        fr->tag_array2->access_time/1e-9 << endl;
+        fr->tag_array2.access_time/1e-9 << endl;
 
       cout <<  "\tH-tree input delay (ns): " <<
-        fr->tag_array2->delay_route_to_bank * 1e9 +
-        fr->tag_array2->delay_input_htree * 1e9 << endl;
+        fr->tag_array2.delay_route_to_bank * 1e9 +
+        fr->tag_array2.delay_input_htree * 1e9 << endl;
 
       cout <<  "\tDecoder + wordline delay (ns): " <<
-        fr->tag_array2->delay_row_predecode_driver_and_block * 1e9 +
-        fr->tag_array2->delay_row_decoder * 1e9 << endl;
+        fr->tag_array2.delay_row_predecode_driver_and_block * 1e9 +
+        fr->tag_array2.delay_row_decoder * 1e9 << endl;
 
       cout <<  "\tBitline delay (ns): " <<
-        fr->tag_array2->delay_bitlines/1e-9 << endl;
+        fr->tag_array2.delay_bitlines/1e-9 << endl;
 
       cout <<  "\tSense Amplifier delay (ns): " <<
-        fr->tag_array2->delay_sense_amp * 1e9 << endl;
+        fr->tag_array2.delay_sense_amp * 1e9 << endl;
 
       cout <<  "\tComparator delay (ns): " <<
-        fr->tag_array2->delay_comparator * 1e9 << endl;
+        fr->tag_array2.delay_comparator * 1e9 << endl;
 
       cout <<  "\tH-tree output delay (ns): " <<
-        fr->tag_array2->delay_subarray_output_driver * 1e9 +
-        fr->tag_array2->delay_dout_htree * 1e9 << endl;
+        fr->tag_array2.delay_subarray_output_driver * 1e9 +
+        fr->tag_array2.delay_dout_htree * 1e9 << endl;
     }
 
 
@@ -1779,55 +1780,55 @@ void output_UCA(uca_org_t *fr)
     if (!(g_ip->pure_cam || g_ip->fully_assoc))
     {
     	cout << "  Data array: Total dynamic read energy/access  (nJ): " <<
-    	      fr->data_array2->power.readOp.dynamic * 1e9 << endl;
+    	      fr->data_array2.power.readOp.dynamic * 1e9 << endl;
     	cout << "\tTotal leakage read/write power of a bank (mW): " <<
-    	        fr->data_array2->power.readOp.leakage * 1e3 << endl;
+    	        fr->data_array2.power.readOp.leakage * 1e3 << endl;
 
     	cout << "\tTotal energy in H-tree (that includes both "
     	      "address and data transfer) (nJ): " <<
-    	        (fr->data_array2->power_addr_input_htree.readOp.dynamic +
-    	         fr->data_array2->power_data_output_htree.readOp.dynamic +
-    	         fr->data_array2->power_routing_to_bank.readOp.dynamic) * 1e9 << endl;
+    	        (fr->data_array2.power_addr_input_htree.readOp.dynamic +
+    	         fr->data_array2.power_data_output_htree.readOp.dynamic +
+    	         fr->data_array2.power_routing_to_bank.readOp.dynamic) * 1e9 << endl;
 
     	cout << "\tTotal leakage power in H-tree (that includes both "
     	      "address and data network) ((mW)): " <<
-    	        (fr->data_array2->power_addr_input_htree.readOp.leakage +
-    	         fr->data_array2->power_data_output_htree.readOp.leakage +
-    	         fr->data_array2->power_routing_to_bank.readOp.leakage) * 1e3 << endl;
+    	        (fr->data_array2.power_addr_input_htree.readOp.leakage +
+    	         fr->data_array2.power_data_output_htree.readOp.leakage +
+    	         fr->data_array2.power_routing_to_bank.readOp.leakage) * 1e3 << endl;
 
     	cout << "\tTotal gate leakage power in H-tree (that includes both "
     	      "address and data network) ((mW)): " <<
-    	        (fr->data_array2->power_addr_input_htree.readOp.gate_leakage +
-    	         fr->data_array2->power_data_output_htree.readOp.gate_leakage +
-    	         fr->data_array2->power_routing_to_bank.readOp.gate_leakage) * 1e3 << endl;
+    	        (fr->data_array2.power_addr_input_htree.readOp.gate_leakage +
+    	         fr->data_array2.power_data_output_htree.readOp.gate_leakage +
+    	         fr->data_array2.power_routing_to_bank.readOp.gate_leakage) * 1e3 << endl;
 
     	cout << "\tOutput Htree inside bank Energy (nJ): " <<
-    	   fr->data_array2->power_data_output_htree.readOp.dynamic * 1e9 << endl;
+    	   fr->data_array2.power_data_output_htree.readOp.dynamic * 1e9 << endl;
     	cout <<  "\tDecoder (nJ): " <<
-    	   fr->data_array2->power_row_predecoder_drivers.readOp.dynamic * 1e9 +
-    	   fr->data_array2->power_row_predecoder_blocks.readOp.dynamic * 1e9 << endl;
+    	   fr->data_array2.power_row_predecoder_drivers.readOp.dynamic * 1e9 +
+    	   fr->data_array2.power_row_predecoder_blocks.readOp.dynamic * 1e9 << endl;
     	cout <<  "\tWordline (nJ): " <<
-    	   fr->data_array2->power_row_decoders.readOp.dynamic * 1e9 << endl;
+    	   fr->data_array2.power_row_decoders.readOp.dynamic * 1e9 << endl;
     	cout <<  "\tBitline mux & associated drivers (nJ): " <<
-    	   fr->data_array2->power_bit_mux_predecoder_drivers.readOp.dynamic * 1e9 +
-    	   fr->data_array2->power_bit_mux_predecoder_blocks.readOp.dynamic * 1e9 +
-    	   fr->data_array2->power_bit_mux_decoders.readOp.dynamic * 1e9 << endl;
+    	   fr->data_array2.power_bit_mux_predecoder_drivers.readOp.dynamic * 1e9 +
+    	   fr->data_array2.power_bit_mux_predecoder_blocks.readOp.dynamic * 1e9 +
+    	   fr->data_array2.power_bit_mux_decoders.readOp.dynamic * 1e9 << endl;
     	cout <<  "\tSense amp mux & associated drivers (nJ): " <<
-    	   fr->data_array2->power_senseamp_mux_lev_1_predecoder_drivers.readOp.dynamic * 1e9 +
-    	   fr->data_array2->power_senseamp_mux_lev_1_predecoder_blocks.readOp.dynamic * 1e9 +
-    	   fr->data_array2->power_senseamp_mux_lev_1_decoders.readOp.dynamic * 1e9  +
-    	   fr->data_array2->power_senseamp_mux_lev_2_predecoder_drivers.readOp.dynamic * 1e9 +
-    	   fr->data_array2->power_senseamp_mux_lev_2_predecoder_blocks.readOp.dynamic * 1e9 +
-    	   fr->data_array2->power_senseamp_mux_lev_2_decoders.readOp.dynamic * 1e9 << endl;
+    	   fr->data_array2.power_senseamp_mux_lev_1_predecoder_drivers.readOp.dynamic * 1e9 +
+    	   fr->data_array2.power_senseamp_mux_lev_1_predecoder_blocks.readOp.dynamic * 1e9 +
+    	   fr->data_array2.power_senseamp_mux_lev_1_decoders.readOp.dynamic * 1e9  +
+    	   fr->data_array2.power_senseamp_mux_lev_2_predecoder_drivers.readOp.dynamic * 1e9 +
+    	   fr->data_array2.power_senseamp_mux_lev_2_predecoder_blocks.readOp.dynamic * 1e9 +
+    	   fr->data_array2.power_senseamp_mux_lev_2_decoders.readOp.dynamic * 1e9 << endl;
 
     	cout <<  "\tBitlines precharge and equalization circuit (nJ): " <<
-    	    	   fr->data_array2->power_prechg_eq_drivers.readOp.dynamic * 1e9 << endl;
+    	    	   fr->data_array2.power_prechg_eq_drivers.readOp.dynamic * 1e9 << endl;
     	cout <<  "\tBitlines (nJ): " <<
-    	   fr->data_array2->power_bitlines.readOp.dynamic * 1e9 << endl;
+    	   fr->data_array2.power_bitlines.readOp.dynamic * 1e9 << endl;
     	cout <<  "\tSense amplifier energy (nJ): " <<
-    	   fr->data_array2->power_sense_amps.readOp.dynamic * 1e9 << endl;
+    	   fr->data_array2.power_sense_amps.readOp.dynamic * 1e9 << endl;
     	cout <<  "\tSub-array output driver (nJ): " <<
-    	   fr->data_array2->power_output_drivers_at_subarray.readOp.dynamic * 1e9 << endl;
+    	   fr->data_array2.power_output_drivers_at_subarray.readOp.dynamic * 1e9 << endl;
     }
 
         else if (g_ip->pure_cam)
@@ -1835,226 +1836,226 @@ void output_UCA(uca_org_t *fr)
 
            	cout << "  CAM array:"<<endl;
             	cout << "  Total dynamic associative search energy/access  (nJ): " <<
-                      fr->data_array2->power.searchOp.dynamic * 1e9 << endl;
+                      fr->data_array2.power.searchOp.dynamic * 1e9 << endl;
     	        cout << "\tTotal energy in H-tree (that includes both "
     	            	      "match key and data transfer) (nJ): " <<
-    	              (fr->data_array2->power_htree_in_search.searchOp.dynamic +
-    	               fr->data_array2->power_htree_out_search.searchOp.dynamic +
-    	               fr->data_array2->power_routing_to_bank.searchOp.dynamic) * 1e9 << endl;
+    	              (fr->data_array2.power_htree_in_search.searchOp.dynamic +
+    	               fr->data_array2.power_htree_out_search.searchOp.dynamic +
+    	               fr->data_array2.power_routing_to_bank.searchOp.dynamic) * 1e9 << endl;
     	        cout << "\tKeyword input and result output Htrees inside bank Energy (nJ): " <<
-    	              (fr->data_array2->power_htree_in_search.searchOp.dynamic +
-    	       	               fr->data_array2->power_htree_out_search.searchOp.dynamic) * 1e9 << endl;
+    	              (fr->data_array2.power_htree_in_search.searchOp.dynamic +
+    	       	               fr->data_array2.power_htree_out_search.searchOp.dynamic) * 1e9 << endl;
     	        cout <<  "\tSearchlines (nJ): " <<
-    	          	   fr->data_array2->power_searchline.searchOp.dynamic * 1e9 +
-    	          	   fr->data_array2->power_searchline_precharge.searchOp.dynamic * 1e9 << endl;
+    	          	   fr->data_array2.power_searchline.searchOp.dynamic * 1e9 +
+    	          	   fr->data_array2.power_searchline_precharge.searchOp.dynamic * 1e9 << endl;
     	        cout <<  "\tMatchlines  (nJ): " <<
-    	               fr->data_array2->power_matchlines.searchOp.dynamic * 1e9 +
-    	        	   fr->data_array2->power_matchline_precharge.searchOp.dynamic * 1e9 << endl;
+    	               fr->data_array2.power_matchlines.searchOp.dynamic * 1e9 +
+    	        	   fr->data_array2.power_matchline_precharge.searchOp.dynamic * 1e9 << endl;
     	        cout <<  "\tSub-array output driver (nJ): " <<
-    	          	   fr->data_array2->power_output_drivers_at_subarray.searchOp.dynamic * 1e9 << endl;
+    	          	   fr->data_array2.power_output_drivers_at_subarray.searchOp.dynamic * 1e9 << endl;
 
 
             	cout <<endl<< "  Total dynamic read energy/access  (nJ): " <<
-            	      fr->data_array2->power.readOp.dynamic * 1e9 << endl;
+            	      fr->data_array2.power.readOp.dynamic * 1e9 << endl;
     	        cout << "\tTotal energy in H-tree (that includes both "
     	            	      "address and data transfer) (nJ): " <<
-    	              (fr->data_array2->power_addr_input_htree.readOp.dynamic +
-    	               fr->data_array2->power_data_output_htree.readOp.dynamic +
-    	               fr->data_array2->power_routing_to_bank.readOp.dynamic) * 1e9 << endl;
+    	              (fr->data_array2.power_addr_input_htree.readOp.dynamic +
+    	               fr->data_array2.power_data_output_htree.readOp.dynamic +
+    	               fr->data_array2.power_routing_to_bank.readOp.dynamic) * 1e9 << endl;
     	        cout << "\tOutput Htree inside bank Energy (nJ): " <<
-    	          	   fr->data_array2->power_data_output_htree.readOp.dynamic * 1e9 << endl;
+    	          	   fr->data_array2.power_data_output_htree.readOp.dynamic * 1e9 << endl;
     	        cout <<  "\tDecoder (nJ): " <<
-    	          	   fr->data_array2->power_row_predecoder_drivers.readOp.dynamic * 1e9 +
-    	          	   fr->data_array2->power_row_predecoder_blocks.readOp.dynamic * 1e9 << endl;
+    	          	   fr->data_array2.power_row_predecoder_drivers.readOp.dynamic * 1e9 +
+    	          	   fr->data_array2.power_row_predecoder_blocks.readOp.dynamic * 1e9 << endl;
     	        cout <<  "\tWordline (nJ): " <<
-    	          	   fr->data_array2->power_row_decoders.readOp.dynamic * 1e9 << endl;
+    	          	   fr->data_array2.power_row_decoders.readOp.dynamic * 1e9 << endl;
     	        cout <<  "\tBitline mux & associated drivers (nJ): " <<
-    	          	   fr->data_array2->power_bit_mux_predecoder_drivers.readOp.dynamic * 1e9 +
-    	          	   fr->data_array2->power_bit_mux_predecoder_blocks.readOp.dynamic * 1e9 +
-    	           	   fr->data_array2->power_bit_mux_decoders.readOp.dynamic * 1e9 << endl;
+    	          	   fr->data_array2.power_bit_mux_predecoder_drivers.readOp.dynamic * 1e9 +
+    	          	   fr->data_array2.power_bit_mux_predecoder_blocks.readOp.dynamic * 1e9 +
+    	           	   fr->data_array2.power_bit_mux_decoders.readOp.dynamic * 1e9 << endl;
     	        cout <<  "\tSense amp mux & associated drivers (nJ): " <<
-    	         	   fr->data_array2->power_senseamp_mux_lev_1_predecoder_drivers.readOp.dynamic * 1e9 +
-    	          	   fr->data_array2->power_senseamp_mux_lev_1_predecoder_blocks.readOp.dynamic * 1e9 +
-    	          	   fr->data_array2->power_senseamp_mux_lev_1_decoders.readOp.dynamic * 1e9  +
-    	           	   fr->data_array2->power_senseamp_mux_lev_2_predecoder_drivers.readOp.dynamic * 1e9 +
-    	           	   fr->data_array2->power_senseamp_mux_lev_2_predecoder_blocks.readOp.dynamic * 1e9 +
-    	          	   fr->data_array2->power_senseamp_mux_lev_2_decoders.readOp.dynamic * 1e9 << endl;
+    	         	   fr->data_array2.power_senseamp_mux_lev_1_predecoder_drivers.readOp.dynamic * 1e9 +
+    	          	   fr->data_array2.power_senseamp_mux_lev_1_predecoder_blocks.readOp.dynamic * 1e9 +
+    	          	   fr->data_array2.power_senseamp_mux_lev_1_decoders.readOp.dynamic * 1e9  +
+    	           	   fr->data_array2.power_senseamp_mux_lev_2_predecoder_drivers.readOp.dynamic * 1e9 +
+    	           	   fr->data_array2.power_senseamp_mux_lev_2_predecoder_blocks.readOp.dynamic * 1e9 +
+    	          	   fr->data_array2.power_senseamp_mux_lev_2_decoders.readOp.dynamic * 1e9 << endl;
     	        cout <<  "\tBitlines (nJ): " <<
-    	          	   fr->data_array2->power_bitlines.readOp.dynamic * 1e9 +
-    	          	   fr->data_array2->power_prechg_eq_drivers.readOp.dynamic * 1e9<< endl;
+    	          	   fr->data_array2.power_bitlines.readOp.dynamic * 1e9 +
+    	          	   fr->data_array2.power_prechg_eq_drivers.readOp.dynamic * 1e9<< endl;
     	        cout <<  "\tSense amplifier energy (nJ): " <<
-    	          	   fr->data_array2->power_sense_amps.readOp.dynamic * 1e9 << endl;
+    	          	   fr->data_array2.power_sense_amps.readOp.dynamic * 1e9 << endl;
     	        cout <<  "\tSub-array output driver (nJ): " <<
-    	          	   fr->data_array2->power_output_drivers_at_subarray.readOp.dynamic * 1e9 << endl;
+    	          	   fr->data_array2.power_output_drivers_at_subarray.readOp.dynamic * 1e9 << endl;
 
             	cout << endl <<"  Total leakage power of a bank (mW): " <<
-                      fr->data_array2->power.readOp.leakage * 1e3 << endl;
+                      fr->data_array2.power.readOp.leakage * 1e3 << endl;
         }
         else
         {
         	cout << "  Fully associative array:"<<endl;
         	cout << "  Total dynamic associative search energy/access  (nJ): " <<
-                  fr->data_array2->power.searchOp.dynamic * 1e9 << endl;
+                  fr->data_array2.power.searchOp.dynamic * 1e9 << endl;
 	        cout << "\tTotal energy in H-tree (that includes both "
 	            	      "match key and data transfer) (nJ): " <<
-	              (fr->data_array2->power_htree_in_search.searchOp.dynamic +
-	               fr->data_array2->power_htree_out_search.searchOp.dynamic +
-	               fr->data_array2->power_routing_to_bank.searchOp.dynamic) * 1e9 << endl;
+	              (fr->data_array2.power_htree_in_search.searchOp.dynamic +
+	               fr->data_array2.power_htree_out_search.searchOp.dynamic +
+	               fr->data_array2.power_routing_to_bank.searchOp.dynamic) * 1e9 << endl;
 	        cout << "\tKeyword input and result output Htrees inside bank Energy (nJ): " <<
-	              (fr->data_array2->power_htree_in_search.searchOp.dynamic +
-	       	               fr->data_array2->power_htree_out_search.searchOp.dynamic) * 1e9 << endl;
+	              (fr->data_array2.power_htree_in_search.searchOp.dynamic +
+	       	               fr->data_array2.power_htree_out_search.searchOp.dynamic) * 1e9 << endl;
 	        cout <<  "\tSearchlines (nJ): " <<
-	          	   fr->data_array2->power_searchline.searchOp.dynamic * 1e9 +
-	          	   fr->data_array2->power_searchline_precharge.searchOp.dynamic * 1e9 << endl;
+	          	   fr->data_array2.power_searchline.searchOp.dynamic * 1e9 +
+	          	   fr->data_array2.power_searchline_precharge.searchOp.dynamic * 1e9 << endl;
 	        cout <<  "\tMatchlines  (nJ): " <<
-	               fr->data_array2->power_matchlines.searchOp.dynamic * 1e9 +
-	        	   fr->data_array2->power_matchline_precharge.searchOp.dynamic * 1e9 << endl;
+	               fr->data_array2.power_matchlines.searchOp.dynamic * 1e9 +
+	        	   fr->data_array2.power_matchline_precharge.searchOp.dynamic * 1e9 << endl;
 	        cout <<  "\tData portion wordline (nJ): " <<
-	          	   fr->data_array2->power_matchline_to_wordline_drv.searchOp.dynamic * 1e9 << endl;
+	          	   fr->data_array2.power_matchline_to_wordline_drv.searchOp.dynamic * 1e9 << endl;
 	        cout <<  "\tData Bitlines (nJ): " <<
-	          	   fr->data_array2->power_bitlines.searchOp.dynamic * 1e9 +
-	          	   fr->data_array2->power_prechg_eq_drivers.searchOp.dynamic * 1e9 << endl;
+	          	   fr->data_array2.power_bitlines.searchOp.dynamic * 1e9 +
+	          	   fr->data_array2.power_prechg_eq_drivers.searchOp.dynamic * 1e9 << endl;
 	        cout <<  "\tSense amplifier energy (nJ): " <<
-	          	   fr->data_array2->power_sense_amps.searchOp.dynamic * 1e9 << endl;
+	          	   fr->data_array2.power_sense_amps.searchOp.dynamic * 1e9 << endl;
 	        cout <<  "\tSub-array output driver (nJ): " <<
-	          	   fr->data_array2->power_output_drivers_at_subarray.searchOp.dynamic * 1e9 << endl;
+	          	   fr->data_array2.power_output_drivers_at_subarray.searchOp.dynamic * 1e9 << endl;
 
 
         	cout <<endl<< "  Total dynamic read energy/access  (nJ): " <<
-        	      fr->data_array2->power.readOp.dynamic * 1e9 << endl;
+        	      fr->data_array2.power.readOp.dynamic * 1e9 << endl;
 	        cout << "\tTotal energy in H-tree (that includes both "
 	            	      "address and data transfer) (nJ): " <<
-	              (fr->data_array2->power_addr_input_htree.readOp.dynamic +
-	               fr->data_array2->power_data_output_htree.readOp.dynamic +
-	               fr->data_array2->power_routing_to_bank.readOp.dynamic) * 1e9 << endl;
+	              (fr->data_array2.power_addr_input_htree.readOp.dynamic +
+	               fr->data_array2.power_data_output_htree.readOp.dynamic +
+	               fr->data_array2.power_routing_to_bank.readOp.dynamic) * 1e9 << endl;
 	        cout << "\tOutput Htree inside bank Energy (nJ): " <<
-	          	   fr->data_array2->power_data_output_htree.readOp.dynamic * 1e9 << endl;
+	          	   fr->data_array2.power_data_output_htree.readOp.dynamic * 1e9 << endl;
 	        cout <<  "\tDecoder (nJ): " <<
-	          	   fr->data_array2->power_row_predecoder_drivers.readOp.dynamic * 1e9 +
-	          	   fr->data_array2->power_row_predecoder_blocks.readOp.dynamic * 1e9 << endl;
+	          	   fr->data_array2.power_row_predecoder_drivers.readOp.dynamic * 1e9 +
+	          	   fr->data_array2.power_row_predecoder_blocks.readOp.dynamic * 1e9 << endl;
 	        cout <<  "\tWordline (nJ): " <<
-	          	   fr->data_array2->power_row_decoders.readOp.dynamic * 1e9 << endl;
+	          	   fr->data_array2.power_row_decoders.readOp.dynamic * 1e9 << endl;
 	        cout <<  "\tBitline mux & associated drivers (nJ): " <<
-	          	   fr->data_array2->power_bit_mux_predecoder_drivers.readOp.dynamic * 1e9 +
-	          	   fr->data_array2->power_bit_mux_predecoder_blocks.readOp.dynamic * 1e9 +
-	           	   fr->data_array2->power_bit_mux_decoders.readOp.dynamic * 1e9 << endl;
+	          	   fr->data_array2.power_bit_mux_predecoder_drivers.readOp.dynamic * 1e9 +
+	          	   fr->data_array2.power_bit_mux_predecoder_blocks.readOp.dynamic * 1e9 +
+	           	   fr->data_array2.power_bit_mux_decoders.readOp.dynamic * 1e9 << endl;
 	        cout <<  "\tSense amp mux & associated drivers (nJ): " <<
-	         	   fr->data_array2->power_senseamp_mux_lev_1_predecoder_drivers.readOp.dynamic * 1e9 +
-	          	   fr->data_array2->power_senseamp_mux_lev_1_predecoder_blocks.readOp.dynamic * 1e9 +
-	          	   fr->data_array2->power_senseamp_mux_lev_1_decoders.readOp.dynamic * 1e9  +
-	           	   fr->data_array2->power_senseamp_mux_lev_2_predecoder_drivers.readOp.dynamic * 1e9 +
-	           	   fr->data_array2->power_senseamp_mux_lev_2_predecoder_blocks.readOp.dynamic * 1e9 +
-	          	   fr->data_array2->power_senseamp_mux_lev_2_decoders.readOp.dynamic * 1e9 << endl;
+	         	   fr->data_array2.power_senseamp_mux_lev_1_predecoder_drivers.readOp.dynamic * 1e9 +
+	          	   fr->data_array2.power_senseamp_mux_lev_1_predecoder_blocks.readOp.dynamic * 1e9 +
+	          	   fr->data_array2.power_senseamp_mux_lev_1_decoders.readOp.dynamic * 1e9  +
+	           	   fr->data_array2.power_senseamp_mux_lev_2_predecoder_drivers.readOp.dynamic * 1e9 +
+	           	   fr->data_array2.power_senseamp_mux_lev_2_predecoder_blocks.readOp.dynamic * 1e9 +
+	          	   fr->data_array2.power_senseamp_mux_lev_2_decoders.readOp.dynamic * 1e9 << endl;
 	        cout <<  "\tBitlines (nJ): " <<
-	          	   fr->data_array2->power_bitlines.readOp.dynamic * 1e9 +
-	          	   fr->data_array2->power_prechg_eq_drivers.readOp.dynamic * 1e9<< endl;
+	          	   fr->data_array2.power_bitlines.readOp.dynamic * 1e9 +
+	          	   fr->data_array2.power_prechg_eq_drivers.readOp.dynamic * 1e9<< endl;
 	        cout <<  "\tSense amplifier energy (nJ): " <<
-	          	   fr->data_array2->power_sense_amps.readOp.dynamic * 1e9 << endl;
+	          	   fr->data_array2.power_sense_amps.readOp.dynamic * 1e9 << endl;
 	        cout <<  "\tSub-array output driver (nJ): " <<
-	          	   fr->data_array2->power_output_drivers_at_subarray.readOp.dynamic * 1e9 << endl;
+	          	   fr->data_array2.power_output_drivers_at_subarray.readOp.dynamic * 1e9 << endl;
 
         	cout << endl <<"  Total leakage power of a bank (mW): " <<
-                  fr->data_array2->power.readOp.leakage * 1e3 << endl;
+                  fr->data_array2.power.readOp.leakage * 1e3 << endl;
       }
 
 
     if ((!(g_ip->pure_ram|| g_ip->pure_cam || g_ip->fully_assoc)) && !g_ip->is_main_mem)
     {
       cout << endl << "  Tag array:  Total dynamic read energy/access (nJ): " <<
-        fr->tag_array2->power.readOp.dynamic * 1e9 << endl;
+        fr->tag_array2.power.readOp.dynamic * 1e9 << endl;
       cout << "\tTotal leakage read/write power of a bank (mW): " <<
-          fr->tag_array2->power.readOp.leakage * 1e3 << endl;
+          fr->tag_array2.power.readOp.leakage * 1e3 << endl;
       cout << "\tTotal energy in H-tree (that includes both "
         "address and data transfer) (nJ): " <<
-          (fr->tag_array2->power_addr_input_htree.readOp.dynamic +
-           fr->tag_array2->power_data_output_htree.readOp.dynamic +
-           fr->tag_array2->power_routing_to_bank.readOp.dynamic) * 1e9 << endl;
+          (fr->tag_array2.power_addr_input_htree.readOp.dynamic +
+           fr->tag_array2.power_data_output_htree.readOp.dynamic +
+           fr->tag_array2.power_routing_to_bank.readOp.dynamic) * 1e9 << endl;
 
       cout << "\tTotal leakage power in H-tree (that includes both "
   	      "address and data network) ((mW)): " <<
-  	        (fr->tag_array2->power_addr_input_htree.readOp.leakage +
-  	         fr->tag_array2->power_data_output_htree.readOp.leakage +
-  	         fr->tag_array2->power_routing_to_bank.readOp.leakage) * 1e3 << endl;
+  	        (fr->tag_array2.power_addr_input_htree.readOp.leakage +
+  	         fr->tag_array2.power_data_output_htree.readOp.leakage +
+  	         fr->tag_array2.power_routing_to_bank.readOp.leakage) * 1e3 << endl;
 
   	  cout << "\tTotal gate leakage power in H-tree (that includes both "
   	      "address and data network) ((mW)): " <<
-  	        (fr->tag_array2->power_addr_input_htree.readOp.gate_leakage +
-  	         fr->tag_array2->power_data_output_htree.readOp.gate_leakage +
-  	         fr->tag_array2->power_routing_to_bank.readOp.gate_leakage) * 1e3 << endl;
+  	        (fr->tag_array2.power_addr_input_htree.readOp.gate_leakage +
+  	         fr->tag_array2.power_data_output_htree.readOp.gate_leakage +
+  	         fr->tag_array2.power_routing_to_bank.readOp.gate_leakage) * 1e3 << endl;
 
       cout << "\tOutput Htree inside a bank Energy (nJ): " <<
-        fr->tag_array2->power_data_output_htree.readOp.dynamic * 1e9 << endl;
+        fr->tag_array2.power_data_output_htree.readOp.dynamic * 1e9 << endl;
       cout <<  "\tDecoder (nJ): " <<
-        fr->tag_array2->power_row_predecoder_drivers.readOp.dynamic * 1e9 +
-        fr->tag_array2->power_row_predecoder_blocks.readOp.dynamic * 1e9 << endl;
+        fr->tag_array2.power_row_predecoder_drivers.readOp.dynamic * 1e9 +
+        fr->tag_array2.power_row_predecoder_blocks.readOp.dynamic * 1e9 << endl;
       cout <<  "\tWordline (nJ): " <<
-        fr->tag_array2->power_row_decoders.readOp.dynamic * 1e9 << endl;
+        fr->tag_array2.power_row_decoders.readOp.dynamic * 1e9 << endl;
       cout <<  "\tBitline mux & associated drivers (nJ): " <<
-        fr->tag_array2->power_bit_mux_predecoder_drivers.readOp.dynamic * 1e9 +
-        fr->tag_array2->power_bit_mux_predecoder_blocks.readOp.dynamic * 1e9 +
-        fr->tag_array2->power_bit_mux_decoders.readOp.dynamic * 1e9 << endl;
+        fr->tag_array2.power_bit_mux_predecoder_drivers.readOp.dynamic * 1e9 +
+        fr->tag_array2.power_bit_mux_predecoder_blocks.readOp.dynamic * 1e9 +
+        fr->tag_array2.power_bit_mux_decoders.readOp.dynamic * 1e9 << endl;
       cout <<  "\tSense amp mux & associated drivers (nJ): " <<
-        fr->tag_array2->power_senseamp_mux_lev_1_predecoder_drivers.readOp.dynamic * 1e9 +
-        fr->tag_array2->power_senseamp_mux_lev_1_predecoder_blocks.readOp.dynamic * 1e9 +
-        fr->tag_array2->power_senseamp_mux_lev_1_decoders.readOp.dynamic * 1e9  +
-        fr->tag_array2->power_senseamp_mux_lev_2_predecoder_drivers.readOp.dynamic * 1e9 +
-        fr->tag_array2->power_senseamp_mux_lev_2_predecoder_blocks.readOp.dynamic * 1e9 +
-        fr->tag_array2->power_senseamp_mux_lev_2_decoders.readOp.dynamic * 1e9 << endl;
+        fr->tag_array2.power_senseamp_mux_lev_1_predecoder_drivers.readOp.dynamic * 1e9 +
+        fr->tag_array2.power_senseamp_mux_lev_1_predecoder_blocks.readOp.dynamic * 1e9 +
+        fr->tag_array2.power_senseamp_mux_lev_1_decoders.readOp.dynamic * 1e9  +
+        fr->tag_array2.power_senseamp_mux_lev_2_predecoder_drivers.readOp.dynamic * 1e9 +
+        fr->tag_array2.power_senseamp_mux_lev_2_predecoder_blocks.readOp.dynamic * 1e9 +
+        fr->tag_array2.power_senseamp_mux_lev_2_decoders.readOp.dynamic * 1e9 << endl;
       cout <<  "\tBitlines precharge and equalization circuit (nJ): " <<
-        fr->tag_array2->power_prechg_eq_drivers.readOp.dynamic * 1e9 << endl;
+        fr->tag_array2.power_prechg_eq_drivers.readOp.dynamic * 1e9 << endl;
       cout <<  "\tBitlines (nJ): " <<
-        fr->tag_array2->power_bitlines.readOp.dynamic * 1e9 << endl;
+        fr->tag_array2.power_bitlines.readOp.dynamic * 1e9 << endl;
       cout <<  "\tSense amplifier energy (nJ): " <<
-        fr->tag_array2->power_sense_amps.readOp.dynamic * 1e9 << endl;
+        fr->tag_array2.power_sense_amps.readOp.dynamic * 1e9 << endl;
       cout <<  "\tSub-array output driver (nJ): " <<
-        fr->tag_array2->power_output_drivers_at_subarray.readOp.dynamic * 1e9 << endl;
+        fr->tag_array2.power_output_drivers_at_subarray.readOp.dynamic * 1e9 << endl;
     }
 
     cout << endl << endl <<  "Area Components:" << endl << endl;
     /* Data array area stats */
     if (!(g_ip->pure_cam || g_ip->fully_assoc))
-    	cout <<  "  Data array: Area (mm2): " << fr->data_array2->area * 1e-6 << endl;
+    	cout <<  "  Data array: Area (mm2): " << fr->data_array2.area * 1e-6 << endl;
     else if (g_ip->pure_cam)
-    	cout <<  "  CAM array: Area (mm2): " << fr->data_array2->area * 1e-6 << endl;
+    	cout <<  "  CAM array: Area (mm2): " << fr->data_array2.area * 1e-6 << endl;
     else
-    	cout <<  "  Fully associative cache array: Area (mm2): " << fr->data_array2->area * 1e-6 << endl;
+    	cout <<  "  Fully associative cache array: Area (mm2): " << fr->data_array2.area * 1e-6 << endl;
     cout <<  "\tHeight (mm): " <<
-      fr->data_array2->all_banks_height*1e-3 << endl;
+      fr->data_array2.all_banks_height*1e-3 << endl;
     cout <<  "\tWidth (mm): " <<
-      fr->data_array2->all_banks_width*1e-3 << endl;
+      fr->data_array2.all_banks_width*1e-3 << endl;
     if (g_ip->print_detail) {
       cout <<  "\tArea efficiency (Memory cell area/Total area) - " <<
-        fr->data_array2->area_efficiency << " %" << endl;
+        fr->data_array2.area_efficiency << " %" << endl;
       cout << "\t\tMAT Height (mm): " <<
-        fr->data_array2->mat_height*1e-3 << endl;
+        fr->data_array2.mat_height*1e-3 << endl;
       cout << "\t\tMAT Length (mm): " <<
-        fr->data_array2->mat_length*1e-3 << endl;
+        fr->data_array2.mat_length*1e-3 << endl;
       cout << "\t\tSubarray Height (mm): " <<
-        fr->data_array2->subarray_height*1e-3 << endl;
+        fr->data_array2.subarray_height*1e-3 << endl;
       cout << "\t\tSubarray Length (mm): " <<
-        fr->data_array2->subarray_length*1e-3 << endl;
+        fr->data_array2.subarray_length*1e-3 << endl;
     }
 
     /* Tag array area stats */
     if ((!(g_ip->pure_ram|| g_ip->pure_cam || g_ip->fully_assoc)) && !g_ip->is_main_mem)
     {
-      cout << endl << "  Tag array: Area (mm2): " << fr->tag_array2->area * 1e-6 << endl;
+      cout << endl << "  Tag array: Area (mm2): " << fr->tag_array2.area * 1e-6 << endl;
       cout <<  "\tHeight (mm): " <<
-        fr->tag_array2->all_banks_height*1e-3 << endl;
+        fr->tag_array2.all_banks_height*1e-3 << endl;
       cout <<  "\tWidth (mm): " <<
-        fr->tag_array2->all_banks_width*1e-3 << endl;
+        fr->tag_array2.all_banks_width*1e-3 << endl;
       if (g_ip->print_detail)
       {
         cout <<  "\tArea efficiency (Memory cell area/Total area) - " <<
-          fr->tag_array2->area_efficiency << " %" << endl;
+          fr->tag_array2.area_efficiency << " %" << endl;
       cout << "\t\tMAT Height (mm): " <<
-        fr->tag_array2->mat_height*1e-3 << endl;
+        fr->tag_array2.mat_height*1e-3 << endl;
       cout << "\t\tMAT Length (mm): " <<
-        fr->tag_array2->mat_length*1e-3 << endl;
+        fr->tag_array2.mat_length*1e-3 << endl;
       cout << "\t\tSubarray Height (mm): " <<
-        fr->tag_array2->subarray_height*1e-3 << endl;
+        fr->tag_array2.subarray_height*1e-3 << endl;
       cout << "\t\tSubarray Length (mm): " <<
-        fr->tag_array2->subarray_length*1e-3 << endl;
+        fr->tag_array2.subarray_length*1e-3 << endl;
       }
     }
     Wire wpr;
@@ -2190,8 +2191,42 @@ uca_org_t cacti_interface(InputParameter  * const local_interface)
   init_tech_params(g_ip->F_sz_um, false);
   Wire winit; // Do not delete this line. It initializes wires.
 
+
+  static DB *dbp = NULL;
+
+  if (dbp == NULL)
+  {
+    char filename[1024];
+    snprintf(filename, 1024, "%s/mcpat-%s.db", getenv("TMPDIR") ? getenv("TMPDIR") : "/tmp", getenv("USER"));
+    db_create(&dbp, NULL, 0);
+    dbp->open(dbp, NULL, filename, NULL, DB_HASH, DB_CREATE, 0);
+  }
+
+  DBT key, data;
+  memset(&key, 0, sizeof(DBT));
+  memset(&data, 0, sizeof(DBT));
+
+  size_t o1 = offsetof(InputParameter, first),
+         o2 = offsetof(InputParameter, last);
+  key.data = (char*)g_ip + o1;
+  key.size = o2 - o1;
+
+  if (DB_NOTFOUND == dbp->get(dbp, NULL, &key, &data, 0))
+  {
   solve(&fin_res);
 
+    data.data = &fin_res;
+    data.size = sizeof(fin_res);
+    dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE);
+    dbp->sync(dbp, 0);
+  }
+  else
+  {
+    assert(sizeof(fin_res) == data.size);
+    memcpy(&fin_res, data.data, sizeof(fin_res));
+  }
+
+
 //  g_ip->display_ip();
 //  output_UCA(&fin_res);
 //  output_data_csv(fin_res);
diff --git a/cacti/nuca.cc b/cacti/nuca.cc
index 6e04c31..3865263 100644
--- a/cacti/nuca.cc
+++ b/cacti/nuca.cc
@@ -236,8 +236,8 @@ Nuca::sim_nuca()
   }
   cout << "Simulating various NUCA configurations\n";
   for (it=bank_start; it<iterations; it++) { /* different bank count values */
-    ures.tag_array2 = &tag;
-    ures.data_array2 = &data;
+    ures.tag_array2 = tag;
+    ures.data_array2 = data;
     /*
      * find the optimal bank organization
      */
diff --git a/core.cc b/core.cc
index b442e74..d12beb8 100644
--- a/core.cc
+++ b/core.cc
@@ -2095,7 +2095,7 @@ void InstFetchU::computeEnergy(bool is_tdp)
     }
 
     icache.power_t.readOp.dynamic	+= (icache.caches->stats_t.readAc.hit*icache.caches->local_result.power.readOp.dynamic+
-    		//icache.caches->stats_t.readAc.miss*icache.caches->local_result.tag_array2->power.readOp.dynamic+
+         //icache.caches->stats_t.readAc.miss*icache.caches->local_result.tag_array2.power.readOp.dynamic+
     		icache.caches->stats_t.readAc.miss*icache.caches->local_result.power.readOp.dynamic+ //assume tag data accessed in parallel
     		icache.caches->stats_t.readAc.miss*icache.caches->local_result.power.writeOp.dynamic); //read miss in Icache cause a write to Icache
     icache.power_t.readOp.dynamic	+=  icache.missb->stats_t.readAc.access*icache.missb->local_result.power.searchOp.dynamic +
@@ -3096,7 +3096,7 @@ void LoadStoreU::computeEnergy(bool is_tdp)
 	LSQ->power_t.reset();
     dcache.power_t.readOp.dynamic	+= (dcache.caches->stats_t.readAc.hit*dcache.caches->local_result.power.readOp.dynamic+
     		dcache.caches->stats_t.readAc.miss*dcache.caches->local_result.power.readOp.dynamic+
-    		dcache.caches->stats_t.writeAc.miss*dcache.caches->local_result.tag_array2->power.readOp.dynamic+
+         dcache.caches->stats_t.writeAc.miss*dcache.caches->local_result.tag_array2.power.readOp.dynamic+
     		dcache.caches->stats_t.writeAc.access*dcache.caches->local_result.power.writeOp.dynamic);
 
     if (cache_p==Write_back)
diff --git a/mcpat.mk b/mcpat.mk
index 9aacbe0..1dedd4a 100644
--- a/mcpat.mk
+++ b/mcpat.mk
@@ -9,7 +9,7 @@ endif
 
 
 LIBS = 
-INCS = -lm
+INCS = -lm -ldb
 
 ifeq ($(TAG),dbg)
   DBG = -Wall 
diff --git a/mcpatXeonCore.mk b/mcpatXeonCore.mk
index 20cf0dd..e941219 100644
--- a/mcpatXeonCore.mk
+++ b/mcpatXeonCore.mk
@@ -9,7 +9,7 @@ endif
 
 
 LIBS = 
-INCS = -lm
+INCS = -lm -ldb
 
 ifeq ($(TAG),dbg)
   DBG = -Wall 
diff --git a/sharedcache.cc b/sharedcache.cc
index c422235..2d16538 100644
--- a/sharedcache.cc
+++ b/sharedcache.cc
@@ -763,18 +763,18 @@ void SharedCache::computeEnergy(bool is_tdp)
 	if (!((cachep.dir_ty==ST&& cacheL==L1Directory)||(cachep.dir_ty==ST&& cacheL==L2Directory)))
 	{
 		unicache.power_t.readOp.dynamic	+= (unicache.caches->stats_t.readAc.hit*unicache.caches->local_result.power.readOp.dynamic+
-				unicache.caches->stats_t.readAc.miss*unicache.caches->local_result.tag_array2->power.readOp.dynamic+
-				unicache.caches->stats_t.writeAc.miss*unicache.caches->local_result.tag_array2->power.writeOp.dynamic+
+            unicache.caches->stats_t.readAc.miss*unicache.caches->local_result.tag_array2.power.readOp.dynamic+
+            unicache.caches->stats_t.writeAc.miss*unicache.caches->local_result.tag_array2.power.writeOp.dynamic+
 				unicache.caches->stats_t.writeAc.access*unicache.caches->local_result.power.writeOp.dynamic);//write miss will also generate a write later
 
 		if (cachep.dir_ty==SBT)
 		{
-			unicache.power_t.readOp.dynamic	+= homenode_stats_t.readAc.hit * (unicache.caches->local_result.data_array2->power.readOp.dynamic*dir_overhead +
-						unicache.caches->local_result.tag_array2->power.readOp.dynamic) +
-					homenode_stats_t.readAc.miss*unicache.caches->local_result.tag_array2->power.readOp.dynamic +
-					homenode_stats_t.writeAc.miss*unicache.caches->local_result.tag_array2->power.readOp.dynamic +
-			        homenode_stats_t.writeAc.hit*(unicache.caches->local_result.data_array2->power.writeOp.dynamic*dir_overhead +
-							unicache.caches->local_result.tag_array2->power.readOp.dynamic+
+         unicache.power_t.readOp.dynamic  += homenode_stats_t.readAc.hit * (unicache.caches->local_result.data_array2.power.readOp.dynamic*dir_overhead +
+                  unicache.caches->local_result.tag_array2.power.readOp.dynamic) +
+               homenode_stats_t.readAc.miss*unicache.caches->local_result.tag_array2.power.readOp.dynamic +
+               homenode_stats_t.writeAc.miss*unicache.caches->local_result.tag_array2.power.readOp.dynamic +
+                 homenode_stats_t.writeAc.hit*(unicache.caches->local_result.data_array2.power.writeOp.dynamic*dir_overhead +
+                     unicache.caches->local_result.tag_array2.power.readOp.dynamic+
 					homenode_stats_t.writeAc.miss*unicache.caches->local_result.power.writeOp.dynamic);//write miss on dynamic home node will generate a replacement write on whole cache block
 
 
