diff --git a/include/aidge/operator/Conv.hpp b/include/aidge/operator/Conv.hpp
index b1e3e34b0eff681632d90cb8314ebd8c96722eec..e9e1e9cb990603938d62bd06e05cc358d9325b88 100644
--- a/include/aidge/operator/Conv.hpp
+++ b/include/aidge/operator/Conv.hpp
@@ -14,6 +14,7 @@
 
 #include <array>
 #include <cmath>
+#include <cstddef>
 #include <numeric>
 #include <vector>
 
@@ -33,13 +34,13 @@ class Conv_Op : public Operator,
                 public Registrable<Conv_Op<DIM>, std::string, std::unique_ptr<OperatorImpl>(const Conv_Op<DIM> &)>,
                 public StaticAttributes<ConvAttr, std::array<DimSize_t, DIM>, std::array<DimSize_t, DIM>, DimSize_t,
                                        DimSize_t, std::array<DimSize_t, DIM>> {
-public:
+private:
     // FIXME: change accessibility
     std::array<std::shared_ptr<Tensor>, 3> mInputs = {std::make_shared<Tensor>(), std::make_shared<Tensor>(),
                                                       std::make_shared<Tensor>()};
     const std::shared_ptr<Tensor> mOutput = std::make_shared<Tensor>();
 
-   public:
+public:
     static constexpr const char *Type = "Conv";
 
     Conv_Op() = delete;
@@ -127,6 +128,43 @@ public:
 
     bool outputDimsForwarded() const override final { return !(mOutput->empty()); }
 
+    std::vector<std::pair<std::size_t, std::vector<DimSize_t>>> computeReceptiveField(const std::size_t firstIdx, const std::vector<DimSize_t>& outputDims, const IOIndex_t outputIdx = 0) const override {
+        if (outputIdx != 0) {
+            AIDGE_THROW_OR_ABORT(std::runtime_error, "Conv_Op Operator has got only one output Tensor.");
+        }
+        if ((outputDims.size() == (DIM+2)) && outputDimsForwarded()) {
+            // Offset
+            const auto outputIdxDims = mOutput->getCoord(firstIdx);
+            auto inputIdxDims = outputIdxDims; // batch idx is the same
+            inputIdxDims[1] = 0; // each channel is used so start with the first one
+
+            for (DimIdx_t i = 0; i < (DIM+2); ++i) {
+                if (((outputDims[i] + outputIdxDims[i]) > mOutput->dims<DIM+2>()[i]) || (outputDims[i] == 0)) {
+                    AIDGE_THROW_OR_ABORT(std::runtime_error, "Given outputDim out of range for dimension %lu (%lu + %lu)", static_cast<std::size_t>(i), outputIdxDims[i], outputDims[i]);
+                }
+            }
+
+            // padding is not a parameter of Conv_Op. It is handled in Pad_Op Operator
+            // Width
+            std::vector<DimSize_t> inputDims;
+            inputDims.push_back(outputDims[0]); // same batch value
+            inputDims.push_back(mInputs[0]->dims()[1]); // every input channel is used
+
+            for (DimIdx_t i = 0; i < DIM; ++i) {
+                inputDims.push_back((outputDims[2+static_cast<std::size_t>(i)] - 1)
+                            * this->template getAttr<ConvAttr::StrideDims>()[static_cast<std::size_t>(i)]
+                            + 1
+                            + (this->template getAttr<ConvAttr::KernelDims>()[static_cast<std::size_t>(i)] - 1)
+                            * this->template getAttr<ConvAttr::DilationDims>()[static_cast<std::size_t>(i)]);
+                inputIdxDims[2+i] *= this->template getAttr<ConvAttr::StrideDims>()[static_cast<std::size_t>(i)];
+            }
+            std::vector<std::pair<std::size_t, std::vector<DimSize_t>>> res = std::vector<std::pair<std::size_t, std::vector<DimSize_t>>>();
+            res.push_back(std::pair<std::size_t, std::vector<DimSize_t>>(mInputs[0]->getIdx(inputIdxDims), inputDims));
+            return res;
+        }
+        AIDGE_THROW_OR_ABORT(std::runtime_error, "Given outputDim out of range or output dim not forwarded yet.");
+    }
+
 
     inline Tensor& input(const IOIndex_t inputIdx) const override final {
         assert(inputIdx < 3 && "operators supports only 3 inputs");
diff --git a/unit_tests/operator/Test_Conv_Op.cpp b/unit_tests/operator/Test_Conv_Op.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..86078e063d8263e49218fbb87eca64c9f229b288
--- /dev/null
+++ b/unit_tests/operator/Test_Conv_Op.cpp
@@ -0,0 +1,79 @@
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+#include <catch2/catch_test_macros.hpp>
+#include <cstddef>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "aidge/graph/GraphView.hpp"
+#include "aidge/graph/Node.hpp"
+#include "aidge/operator/Conv.hpp"
+#include "aidge/operator/Producer.hpp"
+#include "aidge/utils/Types.h"
+
+namespace Aidge {
+TEST_CASE("[core/operator] Conv_Op(computeReceptiveField)", "[Operator][computeReceptiveFiled][Conv]") {
+    auto dataProvider = Producer({16, 3, 224, 224}, "dataProvider");
+    auto conv1 = Conv(3, 32, {5, 5}, "conv1");          // output dims: {16, 32, 220, 220}
+    auto conv2 = Conv(32, 64, {3, 3}, "conv2");         // output dims: {16, 64, 218, 218}
+    auto conv3 = Conv(64, 10, {2, 2}, "conv3", {2,2});  // output dims: {16, 10, 109, 109}
+    auto conv4 = Conv(10, 10, {1, 1}, "conv4");         // output dims: {16, 10, 109, 109}
+
+    auto g = std::make_shared<GraphView>("TestGraph");
+
+    dataProvider->addChild(conv1, 0);
+    g->add(conv1);
+    g->addChild(conv2, conv1, 0);
+    g->addChild(conv3, conv2, 0);
+    g->addChild(conv4, conv3, 0);
+
+    g->forwardDims();
+
+    SECTION("Check individual receptive fields") {
+        auto res1 = conv1->getOperator()->computeReceptiveField(0, {16,32,10,10});
+        auto res2 = conv2->getOperator()->computeReceptiveField(conv2->getOperator()->output(0).getIdx({3,20,100,28}), {4,20,30,40});
+        auto res3 = conv3->getOperator()->computeReceptiveField(0, {1,1,109,109});
+        auto res4 = conv4->getOperator()->computeReceptiveField(conv4->getOperator()->input(0).getIdx({5,0,108,108}), {10,10,1,1});
+
+        REQUIRE(((res1[0].first == 0) && (res1[0].second == std::vector<DimSize_t>({16, 3, 14, 14}))));
+        REQUIRE(((res2[0].first == conv2->getOperator()->input(0).getIdx({3,0,100,28})) && (res2[0].second == std::vector<DimSize_t>({4, 32, 32, 42}))));
+        REQUIRE(((res3[0].first == 0) && (res3[0].second == std::vector<DimSize_t>({1, 64, 218, 218}))));
+        REQUIRE(((res4[0].first == conv4->getOperator()->input(0).getIdx({5, 0, 108, 108})) && (res4[0].second == std::vector<DimSize_t>({10, 10, 1, 1}))));
+    }
+
+    SECTION("Check receptive field propagation") {
+        // input:  first-{5, 0, 50, 50}  dims-{1, 1, 1, 1}
+        auto res4 = conv4->getOperator()->computeReceptiveField(conv4->getOperator()->input(0).getIdx({5,0,50,50}), {1,1,1,1});
+        // conv4 RF:  first-{5, 0, 50, 50}  dims-{1, 10, 1, 1}
+        auto res3 = conv3->getOperator()->computeReceptiveField(res4[0].first, res4[0].second);
+        // conv3 RF:  first-{5, 0, 100, 100} dims-{1, 64, 2, 2}
+        auto res2 = conv2->getOperator()->computeReceptiveField(res3[0].first, res3[0].second);
+        // conv2 RF:  first-{5, 0, 100, 100} dims-{1, 32, 4, 4}
+        auto res1 = conv1->getOperator()->computeReceptiveField(res2[0].first, res2[0].second);
+        // conv1 RF:  first-{5, 0, 100, 100} dims-{1, 3, 8, 8}
+
+        REQUIRE(((res1[0].first == conv1->getOperator()->input(0).getIdx({5, 0, 100, 100})) && (res1[0].second == std::vector<DimSize_t>({1, 3, 8, 8}))));
+
+
+        // std::cout << "conv1: {";
+        // std::cout << conv1->getOperator()->input(0).getCoord(res1[0].first)[0] << ", "
+        //           << conv1->getOperator()->input(0).getCoord(res1[0].first)[1] << ", "
+        //           << conv1->getOperator()->input(0).getCoord(res1[0].first)[2] << ", "
+        //           << conv1->getOperator()->input(0).getCoord(res1[0].first)[3] << "} - {";
+        // std::cout << res1[0].second[0] << ", "
+        //           << res1[0].second[1] << ", "
+        //           << res1[0].second[2] << ", "
+        //           << res1[0].second[3] << "}" << std::endl;
+    }
+}
+}  // namespace Aidge
\ No newline at end of file