mem-ruby: Make Bloom Filters SimObjects

Make all bloom filters SimObjects.

Change-Id: I586293cdfb559361cb868b3198368e8b9b193356
Signed-off-by: Daniel R. Carvalho <odanrc@yahoo.com.br>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/18736
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
diff --git a/src/mem/ruby/filters/AbstractBloomFilter.hh b/src/mem/ruby/filters/AbstractBloomFilter.hh
index 6722365..301a781 100644
--- a/src/mem/ruby/filters/AbstractBloomFilter.hh
+++ b/src/mem/ruby/filters/AbstractBloomFilter.hh
@@ -36,8 +36,10 @@
 
 #include "base/intmath.hh"
 #include "base/types.hh"
+#include "params/AbstractBloomFilter.hh"
+#include "sim/sim_object.hh"
 
-class AbstractBloomFilter
+class AbstractBloomFilter : public SimObject
 {
   protected:
     /** The filter itself. */
@@ -52,12 +54,10 @@
   public:
     /**
      * Create and clear the filter.
-     *
-     * @param size The number of filter entries.
-     * @param threshold The threshold that limits a set entry.
      */
-    AbstractBloomFilter(std::size_t size, int threshold)
-        : filter(size), sizeBits(floorLog2(size)), setThreshold(threshold)
+    AbstractBloomFilter(const AbstractBloomFilterParams* p)
+        : SimObject(p), filter(p->size), sizeBits(floorLog2(p->size)),
+          setThreshold(p->threshold)
     {
         clear();
     }
diff --git a/src/mem/ruby/filters/BlockBloomFilter.cc b/src/mem/ruby/filters/BlockBloomFilter.cc
index f59a175..a93e8ff 100644
--- a/src/mem/ruby/filters/BlockBloomFilter.cc
+++ b/src/mem/ruby/filters/BlockBloomFilter.cc
@@ -30,9 +30,10 @@
 
 #include "mem/ruby/common/Address.hh"
 #include "mem/ruby/system/RubySystem.hh"
+#include "params/BlockBloomFilter.hh"
 
-BlockBloomFilter::BlockBloomFilter(int size)
-    : AbstractBloomFilter(size, 1)
+BlockBloomFilter::BlockBloomFilter(const BlockBloomFilterParams* p)
+    : AbstractBloomFilter(p)
 {
 }
 
@@ -76,4 +77,8 @@
     return index;
 }
 
-
+BlockBloomFilter*
+BlockBloomFilterParams::create()
+{
+    return new BlockBloomFilter(this);
+}
diff --git a/src/mem/ruby/filters/BlockBloomFilter.hh b/src/mem/ruby/filters/BlockBloomFilter.hh
index fd75ba8..c386624 100644
--- a/src/mem/ruby/filters/BlockBloomFilter.hh
+++ b/src/mem/ruby/filters/BlockBloomFilter.hh
@@ -31,10 +31,12 @@
 
 #include "mem/ruby/filters/AbstractBloomFilter.hh"
 
+struct BlockBloomFilterParams;
+
 class BlockBloomFilter : public AbstractBloomFilter
 {
   public:
-    BlockBloomFilter(int size);
+    BlockBloomFilter(const BlockBloomFilterParams* p);
     ~BlockBloomFilter();
 
     void set(Addr addr) override;
diff --git a/src/mem/ruby/filters/BloomFilters.py b/src/mem/ruby/filters/BloomFilters.py
new file mode 100644
index 0000000..49ebaa3
--- /dev/null
+++ b/src/mem/ruby/filters/BloomFilters.py
@@ -0,0 +1,98 @@
+# Copyright (c) 2019 Inria
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Daniel Carvalho
+
+from m5.params import *
+from m5.proxy import *
+from m5.SimObject import SimObject
+
+class AbstractBloomFilter(SimObject):
+    type = 'AbstractBloomFilter'
+    abstract = True
+    cxx_header = "mem/ruby/filters/AbstractBloomFilter.hh"
+
+    size = Param.Int(4096, "Number of entries in the filter")
+
+    # Most of the filters are booleans, and thus saturate on 1
+    threshold = Param.Int(1, "Value at which an entry is considered as set")
+
+class BlockBloomFilter(AbstractBloomFilter):
+    type = 'BlockBloomFilter'
+    cxx_class = 'BlockBloomFilter'
+    cxx_header = "mem/ruby/filters/BlockBloomFilter.hh"
+
+class BulkBloomFilter(AbstractBloomFilter):
+    type = 'BulkBloomFilter'
+    cxx_class = 'BulkBloomFilter'
+    cxx_header = "mem/ruby/filters/BulkBloomFilter.hh"
+
+class H3BloomFilter(AbstractBloomFilter):
+    type = 'H3BloomFilter'
+    cxx_class = 'H3BloomFilter'
+    cxx_header = "mem/ruby/filters/H3BloomFilter.hh"
+
+    num_hashes = Param.Int(3, "Number of hashes")
+    threshold = Self.num_hashes
+    is_parallel = Param.Bool(False, "Whether hashing is done in parallel")
+
+class LSB_CountingBloomFilter(AbstractBloomFilter):
+    type = 'LSB_CountingBloomFilter'
+    cxx_class = 'LSB_CountingBloomFilter'
+    cxx_header = "mem/ruby/filters/LSB_CountingBloomFilter.hh"
+
+    # By default use 4-bit saturating counters
+    max_value = Param.Int(15, "Maximum value of the filter entries")
+
+    # We assume that isSet will return true only when the counter saturates
+    threshold = Self.max_value
+
+class MultiBitSelBloomFilter(AbstractBloomFilter):
+    type = 'MultiBitSelBloomFilter'
+    cxx_class = 'MultiBitSelBloomFilter'
+    cxx_header = "mem/ruby/filters/MultiBitSelBloomFilter.hh"
+
+    num_hashes = Param.Int(3, "Number of hashes")
+    threshold = Self.num_hashes
+    skip_bits = Param.Int(2, "Offset from block number")
+    is_parallel = Param.Bool(False, "Whether hashing is done in parallel")
+
+class MultiGrainBloomFilter(AbstractBloomFilter):
+    type = 'MultiGrainBloomFilter'
+    cxx_class = 'MultiGrainBloomFilter'
+    cxx_header = "mem/ruby/filters/MultiGrainBloomFilter.hh"
+
+    # This is the maximum value achievable of the sum of the hashed respective
+    # entry of the two filters
+    threshold = 2
+    page_filter_size = Param.Int(1024, "Number of entries in the page filter")
+
+class NonCountingBloomFilter(AbstractBloomFilter):
+    type = 'NonCountingBloomFilter'
+    cxx_class = 'NonCountingBloomFilter'
+    cxx_header = "mem/ruby/filters/NonCountingBloomFilter.hh"
+
+    skip_bits = Param.Int(2, "Offset from block number")
diff --git a/src/mem/ruby/filters/BulkBloomFilter.cc b/src/mem/ruby/filters/BulkBloomFilter.cc
index 251274b..f2a2108 100644
--- a/src/mem/ruby/filters/BulkBloomFilter.cc
+++ b/src/mem/ruby/filters/BulkBloomFilter.cc
@@ -30,9 +30,10 @@
 
 #include "mem/ruby/common/Address.hh"
 #include "mem/ruby/system/RubySystem.hh"
+#include "params/BulkBloomFilter.hh"
 
-BulkBloomFilter::BulkBloomFilter(int size)
-    : AbstractBloomFilter(size, 1), sectorBits(sizeBits - 1)
+BulkBloomFilter::BulkBloomFilter(const BulkBloomFilterParams* p)
+    : AbstractBloomFilter(p), sectorBits(sizeBits - 1)
 {
 }
 
@@ -155,3 +156,9 @@
 
     return result;
 }
+
+BulkBloomFilter*
+BulkBloomFilterParams::create()
+{
+    return new BulkBloomFilter(this);
+}
diff --git a/src/mem/ruby/filters/BulkBloomFilter.hh b/src/mem/ruby/filters/BulkBloomFilter.hh
index 7be00e6..54c976a 100644
--- a/src/mem/ruby/filters/BulkBloomFilter.hh
+++ b/src/mem/ruby/filters/BulkBloomFilter.hh
@@ -33,6 +33,8 @@
 
 #include "mem/ruby/filters/AbstractBloomFilter.hh"
 
+struct BulkBloomFilterParams;
+
 /**
  * Implementation of the bloom filter, as described in "Bulk Disambiguation of
  * Speculative Threads in Multiprocessors", by Ceze, Luis, et al.
@@ -40,7 +42,7 @@
 class BulkBloomFilter : public AbstractBloomFilter
 {
   public:
-    BulkBloomFilter(int size);
+    BulkBloomFilter(const BulkBloomFilterParams* p);
     ~BulkBloomFilter();
 
     void set(Addr addr) override;
diff --git a/src/mem/ruby/filters/H3BloomFilter.cc b/src/mem/ruby/filters/H3BloomFilter.cc
index 485cc31..2b64172 100644
--- a/src/mem/ruby/filters/H3BloomFilter.cc
+++ b/src/mem/ruby/filters/H3BloomFilter.cc
@@ -30,6 +30,7 @@
 
 #include "base/logging.hh"
 #include "mem/ruby/common/Address.hh"
+#include "params/H3BloomFilter.hh"
 
 static int H3[64][16] = {
     { 33268410,   395488709,  311024285,  456111753,
@@ -353,9 +354,9 @@
       394261773,  848616745,  15446017,   517723271,  },
 };
 
-H3BloomFilter::H3BloomFilter(int size, int num_hashes, bool parallel)
-    : AbstractBloomFilter(size, num_hashes), numHashes(num_hashes),
-      isParallel(parallel), parFilterSize(filter.size() / numHashes)
+H3BloomFilter::H3BloomFilter(const H3BloomFilterParams* p)
+    : AbstractBloomFilter(p), numHashes(p->num_hashes),
+      isParallel(p->is_parallel), parFilterSize(p->size / numHashes)
 {
     fatal_if(numHashes > 16, "There are only 16 hash functions implemented.");
 }
@@ -419,3 +420,8 @@
     return result;
 }
 
+H3BloomFilter*
+H3BloomFilterParams::create()
+{
+    return new H3BloomFilter(this);
+}
diff --git a/src/mem/ruby/filters/H3BloomFilter.hh b/src/mem/ruby/filters/H3BloomFilter.hh
index f92878b..62a8ec1 100644
--- a/src/mem/ruby/filters/H3BloomFilter.hh
+++ b/src/mem/ruby/filters/H3BloomFilter.hh
@@ -31,6 +31,8 @@
 
 #include "mem/ruby/filters/AbstractBloomFilter.hh"
 
+struct H3BloomFilterParams;
+
 /**
  * Implementation of the bloom filter as described in "Implementing Signatures
  * for Transactional Memory", by Sanchez, Daniel, et al.
@@ -38,7 +40,7 @@
 class H3BloomFilter : public AbstractBloomFilter
 {
   public:
-    H3BloomFilter(int size, int num_hashes, bool parallel);
+    H3BloomFilter(const H3BloomFilterParams* p);
     ~H3BloomFilter();
 
     void merge(const AbstractBloomFilter* other) override;
diff --git a/src/mem/ruby/filters/LSB_CountingBloomFilter.cc b/src/mem/ruby/filters/LSB_CountingBloomFilter.cc
index a718b43..0d899a7 100644
--- a/src/mem/ruby/filters/LSB_CountingBloomFilter.cc
+++ b/src/mem/ruby/filters/LSB_CountingBloomFilter.cc
@@ -30,12 +30,11 @@
 
 #include "mem/ruby/common/Address.hh"
 #include "mem/ruby/system/RubySystem.hh"
+#include "params/LSB_CountingBloomFilter.hh"
 
-LSB_CountingBloomFilter::LSB_CountingBloomFilter(std::size_t filter_size,
-                                                 int max_value)
-    // Here we assume that isSet will return true only when the counter
-    // saturates
-    : AbstractBloomFilter(filter_size, max_value), maxValue(max_value)
+LSB_CountingBloomFilter::LSB_CountingBloomFilter(
+    const LSB_CountingBloomFilterParams* p)
+    : AbstractBloomFilter(p), maxValue(p->max_value)
 {
 }
 
@@ -73,4 +72,8 @@
                      sizeBits - 1);
 }
 
-
+LSB_CountingBloomFilter*
+LSB_CountingBloomFilterParams::create()
+{
+    return new LSB_CountingBloomFilter(this);
+}
diff --git a/src/mem/ruby/filters/LSB_CountingBloomFilter.hh b/src/mem/ruby/filters/LSB_CountingBloomFilter.hh
index e9ffbcb..4bc0441 100644
--- a/src/mem/ruby/filters/LSB_CountingBloomFilter.hh
+++ b/src/mem/ruby/filters/LSB_CountingBloomFilter.hh
@@ -31,10 +31,12 @@
 
 #include "mem/ruby/filters/AbstractBloomFilter.hh"
 
+struct LSB_CountingBloomFilterParams;
+
 class LSB_CountingBloomFilter : public AbstractBloomFilter
 {
   public:
-    LSB_CountingBloomFilter(std::size_t filter_size, int max_value);
+    LSB_CountingBloomFilter(const LSB_CountingBloomFilterParams* p);
     ~LSB_CountingBloomFilter();
 
     void set(Addr addr) override;
diff --git a/src/mem/ruby/filters/MultiBitSelBloomFilter.cc b/src/mem/ruby/filters/MultiBitSelBloomFilter.cc
index c453d10..88fb8d3 100644
--- a/src/mem/ruby/filters/MultiBitSelBloomFilter.cc
+++ b/src/mem/ruby/filters/MultiBitSelBloomFilter.cc
@@ -29,13 +29,14 @@
 #include "mem/ruby/filters/MultiBitSelBloomFilter.hh"
 
 #include "mem/ruby/common/Address.hh"
+#include "params/MultiBitSelBloomFilter.hh"
 
-MultiBitSelBloomFilter::MultiBitSelBloomFilter(std::size_t filter_size,
-    int num_hashes, int skip_bits, bool is_parallel)
-    : AbstractBloomFilter(filter_size, num_hashes), numHashes(num_hashes),
-      skipBits(skip_bits),
-      parFilterSize(filter_size / numHashes),
-      isParallel(is_parallel)
+MultiBitSelBloomFilter::MultiBitSelBloomFilter(
+    const MultiBitSelBloomFilterParams* p)
+    : AbstractBloomFilter(p), numHashes(p->num_hashes),
+      skipBits(p->skip_bits),
+      parFilterSize(p->size / numHashes),
+      isParallel(p->is_parallel)
 {
 }
 
@@ -100,3 +101,9 @@
     }
     return result;
 }
+
+MultiBitSelBloomFilter*
+MultiBitSelBloomFilterParams::create()
+{
+    return new MultiBitSelBloomFilter(this);
+}
diff --git a/src/mem/ruby/filters/MultiBitSelBloomFilter.hh b/src/mem/ruby/filters/MultiBitSelBloomFilter.hh
index 914875f..501483d 100644
--- a/src/mem/ruby/filters/MultiBitSelBloomFilter.hh
+++ b/src/mem/ruby/filters/MultiBitSelBloomFilter.hh
@@ -31,11 +31,12 @@
 
 #include "mem/ruby/filters/AbstractBloomFilter.hh"
 
+struct MultiBitSelBloomFilterParams;
+
 class MultiBitSelBloomFilter : public AbstractBloomFilter
 {
   public:
-    MultiBitSelBloomFilter(std::size_t filter_size, int num_hashes,
-                           int skip_bits, bool is_parallel);
+    MultiBitSelBloomFilter(const MultiBitSelBloomFilterParams* p);
     ~MultiBitSelBloomFilter();
 
     void merge(const AbstractBloomFilter* other) override;
diff --git a/src/mem/ruby/filters/MultiGrainBloomFilter.cc b/src/mem/ruby/filters/MultiGrainBloomFilter.cc
index 7bf9dfe..8360564 100644
--- a/src/mem/ruby/filters/MultiGrainBloomFilter.cc
+++ b/src/mem/ruby/filters/MultiGrainBloomFilter.cc
@@ -30,10 +30,12 @@
 
 #include "mem/ruby/common/Address.hh"
 #include "mem/ruby/system/RubySystem.hh"
+#include "params/MultiGrainBloomFilter.hh"
 
-MultiGrainBloomFilter::MultiGrainBloomFilter(int head, int tail)
-    : AbstractBloomFilter(head, 2),
-      pageFilter(tail), pageFilterSizeBits(floorLog2(tail))
+MultiGrainBloomFilter::MultiGrainBloomFilter(
+    const MultiGrainBloomFilterParams* p)
+    : AbstractBloomFilter(p), pageFilter(p->page_filter_size),
+      pageFilterSizeBits(floorLog2(p->page_filter_size))
 {
 }
 
@@ -100,6 +102,8 @@
     return bitSelect(addr, bits, bits + pageFilterSizeBits - 1);
 }
 
-
-
-
+MultiGrainBloomFilter*
+MultiGrainBloomFilterParams::create()
+{
+    return new MultiGrainBloomFilter(this);
+}
diff --git a/src/mem/ruby/filters/MultiGrainBloomFilter.hh b/src/mem/ruby/filters/MultiGrainBloomFilter.hh
index d45b587..e895788 100644
--- a/src/mem/ruby/filters/MultiGrainBloomFilter.hh
+++ b/src/mem/ruby/filters/MultiGrainBloomFilter.hh
@@ -33,14 +33,12 @@
 
 #include "mem/ruby/filters/AbstractBloomFilter.hh"
 
+struct MultiGrainBloomFilterParams;
+
 class MultiGrainBloomFilter : public AbstractBloomFilter
 {
   public:
-    /**
-     * @param head Size of 1st bloom filter.
-     * @param tail size of 2nd bloom filter.
-     */
-    MultiGrainBloomFilter(int head, int tail);
+    MultiGrainBloomFilter(const MultiGrainBloomFilterParams* p);
     ~MultiGrainBloomFilter();
 
     void clear() override;
diff --git a/src/mem/ruby/filters/NonCountingBloomFilter.cc b/src/mem/ruby/filters/NonCountingBloomFilter.cc
index 3196eb6..61bc26f 100644
--- a/src/mem/ruby/filters/NonCountingBloomFilter.cc
+++ b/src/mem/ruby/filters/NonCountingBloomFilter.cc
@@ -30,9 +30,11 @@
 
 #include "mem/ruby/common/Address.hh"
 #include "mem/ruby/system/RubySystem.hh"
+#include "params/NonCountingBloomFilter.hh"
 
-NonCountingBloomFilter::NonCountingBloomFilter(std::size_t size, int skip_bits)
-    : AbstractBloomFilter(size, 1), skipBits(skip_bits)
+NonCountingBloomFilter::NonCountingBloomFilter(
+    const NonCountingBloomFilterParams* p)
+    : AbstractBloomFilter(p), skipBits(p->skip_bits)
 {
 }
 
@@ -76,4 +78,8 @@
                      sizeBits - 1);
 }
 
-
+NonCountingBloomFilter*
+NonCountingBloomFilterParams::create()
+{
+    return new NonCountingBloomFilter(this);
+}
diff --git a/src/mem/ruby/filters/NonCountingBloomFilter.hh b/src/mem/ruby/filters/NonCountingBloomFilter.hh
index 1553bec..614fee0 100644
--- a/src/mem/ruby/filters/NonCountingBloomFilter.hh
+++ b/src/mem/ruby/filters/NonCountingBloomFilter.hh
@@ -31,10 +31,12 @@
 
 #include "mem/ruby/filters/AbstractBloomFilter.hh"
 
+struct NonCountingBloomFilterParams;
+
 class NonCountingBloomFilter : public AbstractBloomFilter
 {
   public:
-    NonCountingBloomFilter(std::size_t filter_size, int skip_bits);
+    NonCountingBloomFilter(const NonCountingBloomFilterParams* p);
     ~NonCountingBloomFilter();
 
     void merge(const AbstractBloomFilter* other) override;
diff --git a/src/mem/ruby/filters/SConscript b/src/mem/ruby/filters/SConscript
index 5b7e583..13ecc5e 100644
--- a/src/mem/ruby/filters/SConscript
+++ b/src/mem/ruby/filters/SConscript
@@ -33,6 +33,8 @@
 if env['PROTOCOL'] == 'None':
     Return()
 
+SimObject('BloomFilters.py')
+
 Source('BlockBloomFilter.cc')
 Source('BulkBloomFilter.cc')
 Source('H3BloomFilter.cc')