diff --git a/include/aidge/data/Spikegen.hpp b/include/aidge/data/Spikegen.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1267fda9dffd4a49fd37e2f1c65a51072db4a8b4
--- /dev/null
+++ b/include/aidge/data/Spikegen.hpp
@@ -0,0 +1,10 @@
+#ifndef AIDGE_CORE_DATA_SPIKEGEN_H_
+#define AIDGE_CORE_DATA_SPIKEGEN_H_
+
+// Spikegen algorithm :
+//
+// time_data = data.repeat(time_steps)
+// spike_data = rate_conv(time_data)
+// return spike_data
+
+#endif
diff --git a/include/aidge/data/Tensor.hpp b/include/aidge/data/Tensor.hpp
index 5df59becdc41f12768935544a42aac24ffb3a333..76295270e4081d45cf0289f2e9feba5e3e4855fb 100644
--- a/include/aidge/data/Tensor.hpp
+++ b/include/aidge/data/Tensor.hpp
@@ -13,9 +13,7 @@
 #define AIDGE_CORE_DATA_TENSOR_H_
 
 #include <algorithm>
-#include <cstddef>      // std::size_t
-#include <cstring>
-#include <functional>   // std::multiplies
+#include <cstddef>      // std::size_t #include <cstring> #include <functional>   // std::multiplies
 #include <set>
 #include <memory>
 #include <numeric>      // std::accumulate
@@ -989,6 +987,18 @@ public:
         return ref(fallback, targetReqs.dataType(), device.first, device.second);
     }
 
+
+    /**
+     * @brief Repeat the tensor along a new first dimension.
+     * For example, if the current tensor has dimensions (n, m),
+     * calling repeat(10) returns a tensor of shape (10, n, m)
+     * with 10 copies of the original data.
+     *
+     * @param times number of repetitions (must be positive)
+     * @return Tensor new tensor containing the repeated data.
+     */
+    Tensor repeat(int times) const;
+
 private:
     /**
      * @brief Compute the number of elements in the Tensor.
diff --git a/src/data/Tensor.cpp b/src/data/Tensor.cpp
index b128833c9099385c72f25057400a65a6b9034c32..cf84306843d03cded0f5dd79dd58ecea9b5b7f4b 100644
--- a/src/data/Tensor.cpp
+++ b/src/data/Tensor.cpp
@@ -802,6 +802,43 @@ const Tensor& Tensor::ref(std::shared_ptr<Tensor>& fallback,
     }
 }
 
+Tensor Tensor::repeat(int times) const {
+    AIDGE_ASSERT(times > 0, "repeat count must be positive");
+
+    // Ensure that the source tensor is contiguous.
+    Tensor src = *this;
+    if (not src.isContiguous()) {
+        src = src.clone();
+        src.makeContiguous();
+    }
+
+    // Build new dimensions: new_dims = {times} followed by current dims.
+    std::vector<DimSize_t> newDims;
+    newDims.push_back(static_cast<DimSize_t>(times));
+    for (const auto &d : dims()) {
+        newDims.push_back(d);
+    }
+
+    // Create an output tensor with the new dimensions.
+    Tensor out(newDims);
+    out.setDataType(dataType(), false);
+    out.setDataFormat(dataFormat());
+    if (hasImpl()) {
+        out.setBackend(getImpl()->backend(), device());
+    }
+
+    // Each "block" is a copy of the data from the original tensor.
+    const std::size_t block = src.size();
+    // Loop over the repeat count and copy the block each time.
+    for (int i = 0; i < times; ++i) {
+        // out.getImpl()->copy(source pointer, number of elements, destination offset)
+        out.getImpl()->copy(src.getImpl()->rawPtr(src.getImplOffset()),
+                            block,
+                            i * block);
+    }
+    return out;
+}
+
 
 std::vector<std::size_t>
 Tensor::toCoord(const std::vector<DimSize_t>& dimensions, std::size_t index) {