diff --git a/docs/source/manual/file_formats/bitstream_setting.rst b/docs/source/manual/file_formats/bitstream_setting.rst
index eb2af5ddf..d46751a14 100644
--- a/docs/source/manual/file_formats/bitstream_setting.rst
+++ b/docs/source/manual/file_formats/bitstream_setting.rst
@@ -16,6 +16,9 @@ This can define a hard-coded bitstream for a reconfigurable resource in FPGA fab
     <non_fabric name="<string>" file="<string>">
       <pb name="<string>" type="<string>" content="<string>"/>
     </non_fabric>
+    <overwrite_bitstream>
+      <bit value="<0 or 1>" path="<string>"/>
+    </overwrite_bitstream>
   </openfpga_bitstream_setting>
 
 pb_type-related Settings
@@ -75,7 +78,7 @@ The following syntax are applicable to the XML definition tagged by ``interconne
   The default path can be either ``iopad.inpad`` or ``ff.Q`` which corresponds to the first input and the second input respectively.
 
 non_fabric-related Settings
-^^^^^^^^^^^^^^^^^^^^^^^^
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 This is special syntax to extract PB defined parameter or attribute and save the data into dedicated JSON file outside of fabric bitstream
 
@@ -97,7 +100,7 @@ The following syntax are applicable to the XML definition tagged by ``non_fabric
 
     file="bram.json"
 
-.. option:: ``pb`` child element name="<string: pb_type child name>"
+.. option:: pb child element name="<string: pb_type child name>"
 
   Together with ``pb_type`` top level name, that is the source of the ``pb_type`` bitstream
 
@@ -112,6 +115,33 @@ The following syntax are applicable to the XML definition tagged by ``non_fabric
 
   The final ``pb_type`` name is "bram.bram_lr[mem_36K_tdp].mem_36K"
 
-.. option:: ``pb`` child element content="<string>"
+.. option:: pb child element content="<string>"
 
   The content of the ``pb_type`` data to be extracted. For example, ``content=".param INIT_i"`` means that the data will be extracted from the ``.param INIT_i`` line defined under the ``.blif model``.
+
+overwrite_bitstream-related Settings
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This is to allow user to set value of a list of bits which is represented using full path in the hierarchy of FPGA fabric
+
+This ``overwrite_bitstream`` settings has the highest priority than loading any external bitstream file
+
+Each bit to overwrite is represented by one ``bit`` child node/tag
+
+The following syntax are applicable to the XML definition tagged by ``bit`` node under ``overwrite_bitstream`` setting.
+
+.. option:: value="<0 or 1>"
+
+  The boolean ``0`` or ``1`` that will be set. For example, 
+
+  .. code-block:: xml
+
+    value="0"
+    
+.. option:: path="<string>"
+
+  ``path`` represents the location of this block in FPGA fabric, i.e., the full path in the hierarchy of FPGA fabric.
+
+  .. code-block:: xml
+
+    path="fpga_top.grid_clb_1__2_.logical_tile_clb_mode_clb__0.mem_fle_9_in_5[0]"
diff --git a/libs/libarchopenfpga/src/bitstream_setting.cpp b/libs/libarchopenfpga/src/bitstream_setting.cpp
index 7d763f9d2..6092bd91e 100644
--- a/libs/libarchopenfpga/src/bitstream_setting.cpp
+++ b/libs/libarchopenfpga/src/bitstream_setting.cpp
@@ -24,6 +24,12 @@ BitstreamSetting::interconnect_settings() const {
                          interconnect_setting_ids_.end());
 }
 
+BitstreamSetting::overwrite_bitstream_range
+BitstreamSetting::overwrite_bitstreams() const {
+  return vtr::make_range(overwrite_bitstream_ids_.begin(),
+                         overwrite_bitstream_ids_.end());
+}
+
 /************************************************************************
  * Constructors
  ***********************************************************************/
@@ -106,6 +112,18 @@ std::vector<NonFabricBitstreamSetting> BitstreamSetting::non_fabric() const {
   return non_fabric_;
 }
 
+std::string BitstreamSetting::overwrite_bitstream_path(
+  const OverwriteBitstreamId& id) const {
+  VTR_ASSERT(true == valid_overwrite_bitstream_id(id));
+  return overwrite_bitstream_paths_[id];
+}
+
+bool BitstreamSetting::overwrite_bitstream_value(
+  const OverwriteBitstreamId& id) const {
+  VTR_ASSERT(true == valid_overwrite_bitstream_id(id));
+  return overwrite_bitstream_values_[id];
+}
+
 /************************************************************************
  * Public Mutators
  ***********************************************************************/
@@ -178,6 +196,21 @@ void BitstreamSetting::add_non_fabric_pb(const std::string& pb,
   }
 }
 
+OverwriteBitstreamId BitstreamSetting::add_overwrite_bitstream(
+  const std::string& path, const bool& value) {
+  VTR_ASSERT(path.size());
+  VTR_ASSERT(overwrite_bitstream_ids_.size() ==
+             overwrite_bitstream_paths_.size());
+  VTR_ASSERT(overwrite_bitstream_paths_.size() ==
+             overwrite_bitstream_values_.size());
+  OverwriteBitstreamId id =
+    OverwriteBitstreamId(overwrite_bitstream_ids_.size());
+  overwrite_bitstream_ids_.push_back(id);
+  overwrite_bitstream_paths_.push_back(path);
+  overwrite_bitstream_values_.push_back(value);
+  return id;
+}
+
 /************************************************************************
  * Public Validators
  ***********************************************************************/
@@ -194,4 +227,14 @@ bool BitstreamSetting::valid_bitstream_interconnect_setting_id(
           interconnect_setting_ids_[interconnect_setting_id]);
 }
 
+bool BitstreamSetting::valid_overwrite_bitstream_id(
+  const OverwriteBitstreamId& id) const {
+  VTR_ASSERT(overwrite_bitstream_ids_.size() ==
+             overwrite_bitstream_paths_.size());
+  VTR_ASSERT(overwrite_bitstream_paths_.size() ==
+             overwrite_bitstream_values_.size());
+  return (size_t(id) < overwrite_bitstream_ids_.size()) &&
+         (id == overwrite_bitstream_ids_[id]);
+}
+
 }  // namespace openfpga
diff --git a/libs/libarchopenfpga/src/bitstream_setting.h b/libs/libarchopenfpga/src/bitstream_setting.h
index 1b12c8de3..042e850e0 100644
--- a/libs/libarchopenfpga/src/bitstream_setting.h
+++ b/libs/libarchopenfpga/src/bitstream_setting.h
@@ -61,11 +61,15 @@ class BitstreamSetting {
   typedef vtr::vector<BitstreamInterconnectSettingId,
                       BitstreamInterconnectSettingId>::const_iterator
     bitstream_interconnect_setting_iterator;
+  typedef vtr::vector<OverwriteBitstreamId,
+                      OverwriteBitstreamId>::const_iterator
+    overwrite_bitstream_iterator;
   /* Create range */
   typedef vtr::Range<bitstream_pb_type_setting_iterator>
     bitstream_pb_type_setting_range;
   typedef vtr::Range<bitstream_interconnect_setting_iterator>
     bitstream_interconnect_setting_range;
+  typedef vtr::Range<overwrite_bitstream_iterator> overwrite_bitstream_range;
 
  public: /* Constructors */
   BitstreamSetting();
@@ -73,6 +77,7 @@ class BitstreamSetting {
  public: /* Accessors: aggregates */
   bitstream_pb_type_setting_range pb_type_settings() const;
   bitstream_interconnect_setting_range interconnect_settings() const;
+  overwrite_bitstream_range overwrite_bitstreams() const;
 
  public: /* Public Accessors */
   std::string pb_type_name(
@@ -98,6 +103,8 @@ class BitstreamSetting {
   std::string default_path(
     const BitstreamInterconnectSettingId& interconnect_setting_id) const;
   std::vector<NonFabricBitstreamSetting> non_fabric() const;
+  std::string overwrite_bitstream_path(const OverwriteBitstreamId& id) const;
+  bool overwrite_bitstream_value(const OverwriteBitstreamId& id) const;
 
  public: /* Public Mutators */
   BitstreamPbTypeSettingId add_bitstream_pb_type_setting(
@@ -120,11 +127,15 @@ class BitstreamSetting {
   void add_non_fabric(const std::string& name, const std::string& file);
   void add_non_fabric_pb(const std::string& pb, const std::string& content);
 
+  OverwriteBitstreamId add_overwrite_bitstream(const std::string& path,
+                                               const bool& value);
+
  public: /* Public Validators */
   bool valid_bitstream_pb_type_setting_id(
     const BitstreamPbTypeSettingId& pb_type_setting_id) const;
   bool valid_bitstream_interconnect_setting_id(
     const BitstreamInterconnectSettingId& interconnect_setting_id) const;
+  bool valid_overwrite_bitstream_id(const OverwriteBitstreamId& id) const;
 
  private: /* Internal data */
   /* Pb type -related settings
@@ -162,6 +173,10 @@ class BitstreamSetting {
   vtr::vector<BitstreamInterconnectSettingId, std::string>
     interconnect_default_paths_;
   std::vector<NonFabricBitstreamSetting> non_fabric_;
+  vtr::vector<OverwriteBitstreamId, OverwriteBitstreamId>
+    overwrite_bitstream_ids_;
+  vtr::vector<OverwriteBitstreamId, std::string> overwrite_bitstream_paths_;
+  vtr::vector<OverwriteBitstreamId, bool> overwrite_bitstream_values_;
 };
 
 }  // namespace openfpga
diff --git a/libs/libarchopenfpga/src/bitstream_setting_fwd.h b/libs/libarchopenfpga/src/bitstream_setting_fwd.h
index bc5c2ab88..dbcc70553 100644
--- a/libs/libarchopenfpga/src/bitstream_setting_fwd.h
+++ b/libs/libarchopenfpga/src/bitstream_setting_fwd.h
@@ -15,11 +15,13 @@
 
 struct bitstream_pb_type_setting_id_tag;
 struct bitstream_interconnect_setting_id_tag;
+struct overwrite_bitstream_id_tag;
 
 typedef vtr::StrongId<bitstream_pb_type_setting_id_tag>
   BitstreamPbTypeSettingId;
 typedef vtr::StrongId<bitstream_interconnect_setting_id_tag>
   BitstreamInterconnectSettingId;
+typedef vtr::StrongId<overwrite_bitstream_id_tag> OverwriteBitstreamId;
 
 /* Short declaration of class */
 class BitstreamSetting;
diff --git a/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp b/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp
index 7f6bd1237..244703fc1 100644
--- a/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp
+++ b/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp
@@ -102,6 +102,30 @@ static void read_xml_non_fabric_bitstream_setting(
   }
 }
 
+/********************************************************************
+ * Parse XML description for a bit setting under a <bit> XML node
+ *******************************************************************/
+static void read_xml_overwrite_bitstream_setting(
+  pugi::xml_node& xml_overwrite_bitstream, const pugiutil::loc_data& loc_data,
+  openfpga::BitstreamSetting& bitstream_setting) {
+  // Loopthrough bit
+  for (pugi::xml_node xml_bit : xml_overwrite_bitstream.children()) {
+    if (xml_bit.name() != std::string("bit")) {
+      bad_tag(xml_bit, loc_data, xml_overwrite_bitstream, {"bit"});
+    }
+    const std::string& path_attr =
+      get_attribute(xml_bit, "path", loc_data).as_string();
+    const std::string& value_attr =
+      get_attribute(xml_bit, "value", loc_data).as_string();
+    if (value_attr != "0" && value_attr != "1") {
+      archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_bit),
+                     "Invalid value of overwrite_bitstream bit. Expect [0|1]");
+    }
+    /* Add to bit */
+    bitstream_setting.add_overwrite_bitstream(path_attr, value_attr == "1");
+  }
+}
+
 /********************************************************************
  * Parse XML codes about <openfpga_bitstream_setting> to an object
  *******************************************************************/
@@ -116,9 +140,10 @@ openfpga::BitstreamSetting read_xml_bitstream_setting(
     /* Error out if the XML child has an invalid name! */
     if ((xml_child.name() != std::string("pb_type")) &&
         (xml_child.name() != std::string("interconnect")) &&
-        (xml_child.name() != std::string("non_fabric"))) {
+        (xml_child.name() != std::string("non_fabric")) &&
+        (xml_child.name() != std::string("overwrite_bitstream"))) {
       bad_tag(xml_child, loc_data, Node,
-              {"pb_type | interconnect | non_fabric"});
+              {"pb_type | interconnect | non_fabric | overwrite_bitstream"});
     }
 
     if (xml_child.name() == std::string("pb_type")) {
@@ -127,10 +152,13 @@ openfpga::BitstreamSetting read_xml_bitstream_setting(
     } else if (xml_child.name() == std::string("interconnect")) {
       read_xml_bitstream_interconnect_setting(xml_child, loc_data,
                                               bitstream_setting);
-    } else {
-      VTR_ASSERT_SAFE(xml_child.name() == std::string("non_fabric"));
+    } else if (xml_child.name() == std::string("non_fabric")) {
       read_xml_non_fabric_bitstream_setting(xml_child, loc_data,
                                             bitstream_setting);
+    } else {
+      VTR_ASSERT_SAFE(xml_child.name() == std::string("overwrite_bitstream"));
+      read_xml_overwrite_bitstream_setting(xml_child, loc_data,
+                                           bitstream_setting);
     }
   }
 
diff --git a/libs/libfpgabitstream/src/bitstream_manager.cpp b/libs/libfpgabitstream/src/bitstream_manager.cpp
index cf18a6e86..291befb60 100644
--- a/libs/libfpgabitstream/src/bitstream_manager.cpp
+++ b/libs/libfpgabitstream/src/bitstream_manager.cpp
@@ -5,6 +5,10 @@
 
 #include <algorithm>
 
+#include "arch_error.h"
+#include "bitstream_manager_utils.h"
+#include "openfpga_port_parser.h"
+#include "openfpga_tokenizer.h"
 #include "vtr_assert.h"
 #include "vtr_log.h"
 
@@ -296,6 +300,69 @@ void BitstreamManager::add_output_net_id_to_block(
   block_output_net_ids_[block] = output_net_id;
 }
 
+void BitstreamManager::overwrite_bitstream(const std::string& path,
+                                           const bool& value) {
+  PortParser port_parser(path, PORT_PARSER_SUPPORT_SINGLE_INDEX_FORMAT);
+  if (!port_parser.valid()) {
+    archfpga_throw(__FILE__, __LINE__,
+                   "overwrite_bitstream bit path '%s' does not match format "
+                   "<full path in the hierarchy of FPGA fabric>[bit index]",
+                   path.c_str());
+  } else {
+    BasicPort port = port_parser.port();
+    size_t bit = port.get_lsb();
+    StringToken tokenizer(port.get_name());
+    std::vector<std::string> blocks = tokenizer.split(".");
+    std::vector<ConfigBlockId> block_ids;
+    ConfigBlockId block_id = ConfigBlockId::INVALID();
+    size_t found = 0;
+    for (size_t i = 0; i < blocks.size(); i++) {
+      if (i == 0) {
+        block_ids = find_bitstream_manager_top_blocks(*this);
+      } else {
+        block_ids = block_children(block_id);
+      }
+      // Reset
+      block_id = ConfigBlockId::INVALID();
+      // Find the one from the list that match the name
+      for (auto id : block_ids) {
+        if (block_name(id) == blocks[i]) {
+          block_id = id;
+          break;
+        }
+      }
+      if (block_id != ConfigBlockId::INVALID()) {
+        // Found one that match the name
+        found++;
+        if (found == blocks.size()) {
+          // Last one, no more child must end here
+          if (block_children(block_id).size() == 0) {
+            std::vector<ConfigBitId> ids = block_bits(block_id);
+            if (bit < ids.size()) {
+              VTR_ASSERT(valid_bit_id(ids[bit]));
+              bit_values_[ids[bit]] = value ? '1' : '0';
+            } else {
+              // No configuration bits at all or out of range, invalidate
+              found = 0;
+            }
+          } else {
+            // There are more child, hence the path still no end, invalidate
+            found = 0;
+          }
+        }
+      } else {
+        // Cannot match the name, just stop
+        break;
+      }
+    }
+    if (found != blocks.size()) {
+      archfpga_throw(__FILE__, __LINE__,
+                     "Failed to find path '%s' to overwrite bitstream",
+                     path.c_str());
+    }
+  }
+}
+
 /******************************************************************************
  * Public Validators
  ******************************************************************************/
diff --git a/libs/libfpgabitstream/src/bitstream_manager.h b/libs/libfpgabitstream/src/bitstream_manager.h
index 4af15084d..3cba54fc4 100644
--- a/libs/libfpgabitstream/src/bitstream_manager.h
+++ b/libs/libfpgabitstream/src/bitstream_manager.h
@@ -213,6 +213,9 @@ class BitstreamManager {
   void add_output_net_id_to_block(const ConfigBlockId& block,
                                   const std::string& output_net_id);
 
+  /* Set bit to the bitstream at the given path */
+  void overwrite_bitstream(const std::string& path, const bool& value);
+
  public: /* Public Validators */
   bool valid_bit_id(const ConfigBitId& bit_id) const;
 
diff --git a/libs/libopenfpgautil/src/openfpga_port_parser.cpp b/libs/libopenfpgautil/src/openfpga_port_parser.cpp
index 93b7e0899..da0a27368 100644
--- a/libs/libopenfpgautil/src/openfpga_port_parser.cpp
+++ b/libs/libopenfpgautil/src/openfpga_port_parser.cpp
@@ -5,6 +5,7 @@
 
 #include <cstring>
 
+#include "arch_error.h"
 #include "openfpga_tokenizer.h"
 #include "vtr_assert.h"
 #include "vtr_geometry.h"
@@ -19,9 +20,10 @@ namespace openfpga {
 /************************************************************************
  * Constructors
  ***********************************************************************/
-PortParser::PortParser(const std::string& data) {
+PortParser::PortParser(const std::string& data, const int support_format) {
   set_default_bracket();
   set_default_delim();
+  set_support_format(support_format);
   set_data(data);
 }
 
@@ -33,9 +35,18 @@ std::string PortParser::data() const { return data_; }
 
 BasicPort PortParser::port() const { return port_; }
 
+bool PortParser::valid() const { return valid_; }
+
 /************************************************************************
  * Public Mutators
  ***********************************************************************/
+void PortParser::set_support_format(const int support_format) {
+  VTR_ASSERT((support_format & PORT_PARSER_SUPPORT_ALL_FORMAT) != 0);
+  VTR_ASSERT((support_format & ~PORT_PARSER_SUPPORT_ALL_FORMAT) == 0);
+  support_format_ = support_format;
+  return;
+}
+
 void PortParser::set_data(const std::string& data) {
   data_ = data;
   parse();
@@ -47,6 +58,8 @@ void PortParser::set_data(const std::string& data) {
  ***********************************************************************/
 /* Parse the data */
 void PortParser::parse() {
+  valid_ = true;
+
   /* Create a tokenizer */
   StringToken tokenizer(data_);
 
@@ -54,11 +67,14 @@ void PortParser::parse() {
   std::vector<std::string> port_tokens = tokenizer.split(bracket_.x());
   /* Make sure we have a port name! */
   VTR_ASSERT_SAFE((1 == port_tokens.size()) || (2 == port_tokens.size()));
+
   /* Store the port name! */
   port_.set_name(port_tokens[0]);
 
   /* If we only have one token */
   if (1 == port_tokens.size()) {
+    // there is no [
+    valid_ = (support_format_ & PORT_PARSER_SUPPORT_NO_PORT_FORMAT) != 0;
     port_.set_width(1);
     return; /* We can finish here */
   }
@@ -72,19 +88,25 @@ void PortParser::parse() {
   /* Split the pin string now */
   tokenizer.set_data(pin_tokens[0]);
   pin_tokens = tokenizer.split(delim_);
+  VTR_ASSERT_SAFE((1 == pin_tokens.size()) || (2 == pin_tokens.size()));
 
   /* Check if we have LSB and MSB or just one */
   if (1 == pin_tokens.size()) {
     /* Single pin */
-    port_.set_width(std::stoi(pin_tokens[0]), std::stoi(pin_tokens[0]));
+    valid_ = (support_format_ & PORT_PARSER_SUPPORT_SINGLE_INDEX_FORMAT) != 0;
+    size_t temp = string_to_number(pin_tokens[0]);
+    port_.set_width(temp, temp);
   } else if (2 == pin_tokens.size()) {
     /* A number of pins.
      * Note that we always use the LSB for token[0] and MSB for token[1]
      */
-    if (std::stoi(pin_tokens[1]) < std::stoi(pin_tokens[0])) {
-      port_.set_width(std::stoi(pin_tokens[1]), std::stoi(pin_tokens[0]));
+    valid_ = (support_format_ & PORT_PARSER_SUPPORT_RANGE_FORMAT) != 0;
+    size_t temp0 = string_to_number(pin_tokens[0]);
+    size_t temp1 = string_to_number(pin_tokens[1]);
+    if (temp1 < temp0) {
+      port_.set_width(temp1, temp0);
     } else {
-      port_.set_width(std::stoi(pin_tokens[0]), std::stoi(pin_tokens[1]));
+      port_.set_width(temp0, temp1);
     }
   }
 
@@ -102,6 +124,24 @@ void PortParser::set_default_delim() {
   return;
 }
 
+/*
+  Make sure string is not empty and is all digit before stoi
+*/
+size_t PortParser::string_to_number(const std::string& str) {
+  bool bad_format = str.empty();
+  for (auto& chr : str) {
+    if (!std::isdigit(chr)) {
+      bad_format = true;
+      break;
+    }
+  }
+  if (bad_format) {
+    archfpga_throw(__FILE__, __LINE__,
+                   "Invalid string '%s' to call std::stoi()", str.c_str());
+  }
+  return (size_t)(std::stoi(str));
+}
+
 /************************************************************************
  * Member functions for MultiPortParser class
  ***********************************************************************/
diff --git a/libs/libopenfpgautil/src/openfpga_port_parser.h b/libs/libopenfpgautil/src/openfpga_port_parser.h
index f596fd309..ab61603e0 100644
--- a/libs/libopenfpgautil/src/openfpga_port_parser.h
+++ b/libs/libopenfpgautil/src/openfpga_port_parser.h
@@ -21,37 +21,51 @@
 /* namespace openfpga begins */
 namespace openfpga {
 
+constexpr int PORT_PARSER_SUPPORT_NO_PORT_FORMAT = (1 << 0);       // (5) below
+constexpr int PORT_PARSER_SUPPORT_SINGLE_INDEX_FORMAT = (1 << 1);  // (3) below
+constexpr int PORT_PARSER_SUPPORT_RANGE_FORMAT = (1 << 2);  // (1) and (2) below
+constexpr int PORT_PARSER_SUPPORT_ALL_FORMAT = ((1 << 3) - 1);
+
 /************************************************************************
  * Class PortParser: single port parser
  * Supported port definition:
- * 1. <port_name>[<LSB>:<MSB>]
- * 2. <port_name>[<MSB>:<LSB>]
- * 3. <port_name>[<single_pin_index>]
- * 4. <port_name>[]
- * 5. <port_name>
+ * (1) <port_name>[<LSB>:<MSB>]
+ * (2) <port_name>[<MSB>:<LSB>]
+ * (3) <port_name>[<single_pin_index>]
+ * (4) <port_name>[]  -- this is not currently supported. Two problems:
+ *                       * tokenizer will error out and
+ *                       * stoi cannot support empty string, and give
+ *                         std::invalid_argument error
+ * (5) <port_name>
  * In case 4 and 5, we will assign (-1,-1) for LSB and MSB
  ***********************************************************************/
 class PortParser {
  public: /* Constructors*/
-  PortParser(const std::string& data);
+  PortParser(const std::string& data,
+             const int support_format = PORT_PARSER_SUPPORT_ALL_FORMAT);
 
  public: /* Public Accessors */
   std::string data() const;
   BasicPort port() const;
+  bool valid() const;
 
  public: /* Public Mutators */
+  void set_support_format(const int support_format);
   void set_data(const std::string& data);
 
  private: /* Private Mutators */
   void parse();
   void set_default_bracket();
   void set_default_delim();
+  size_t string_to_number(const std::string& str);
 
  private:            /* Internal data */
   std::string data_; /* Lines to be splited */
+  int support_format_;
   vtr::Point<char> bracket_;
   char delim_;
   BasicPort port_;
+  bool valid_;
 };
 
 /************************************************************************
diff --git a/openfpga/src/base/openfpga_basic.cpp b/openfpga/src/base/openfpga_basic.cpp
index 240caaa6f..6546ff909 100644
--- a/openfpga/src/base/openfpga_basic.cpp
+++ b/openfpga/src/base/openfpga_basic.cpp
@@ -69,7 +69,19 @@ int call_external_command(const Command& cmd,
     return CMD_EXEC_FATAL_ERROR;
   }
 
-  return system(cmd_ss.c_str());
+  // Refer https://pubs.opengroup.org/onlinepubs/009695399/functions/system.html
+  // Refer
+  // https://pubs.opengroup.org/onlinepubs/009695399/functions/waitpid.html
+  int status = system(cmd_ss.c_str());
+  if (WIFEXITED(status)) {
+    // This is normal program exit, WEXITSTATUS() will help you shift the status
+    // accordingly (status >> 8)
+    // Becareful if the final status is 2 or beyond, program will not error
+    // as it is treated as CMD_EXEC_MINOR_ERROR
+    return WEXITSTATUS(status);
+  }
+  // Program maybe terminated because of various killed or stopped signal
+  return CMD_EXEC_FATAL_ERROR;
 }
 
 } /* end namespace openfpga */
diff --git a/openfpga/src/base/openfpga_bitstream_template.h b/openfpga/src/base/openfpga_bitstream_template.h
index c132e907f..af5bf1ae7 100644
--- a/openfpga/src/base/openfpga_bitstream_template.h
+++ b/openfpga/src/base/openfpga_bitstream_template.h
@@ -16,6 +16,7 @@
 #include "openfpga_digest.h"
 #include "openfpga_naming.h"
 #include "openfpga_reserved_words.h"
+#include "overwrite_bitstream.h"
 #include "read_xml_arch_bitstream.h"
 #include "report_bitstream_distribution.h"
 #include "vtr_log.h"
@@ -47,6 +48,10 @@ int fpga_bitstream_template(T& openfpga_ctx, const Command& cmd,
       g_vpr_ctx, openfpga_ctx, cmd_context.option_enable(cmd, opt_verbose));
   }
 
+  overwrite_bitstream(openfpga_ctx.mutable_bitstream_manager(),
+                      openfpga_ctx.bitstream_setting(),
+                      cmd_context.option_enable(cmd, opt_verbose));
+
   if (true == cmd_context.option_enable(cmd, opt_write_file)) {
     std::string src_dir_path =
       find_path_dir_name(cmd_context.option_value(cmd, opt_write_file));
diff --git a/openfpga/src/fpga_bitstream/build_device_bitstream.cpp b/openfpga/src/fpga_bitstream/build_device_bitstream.cpp
index 9d7b89789..a3fb26432 100644
--- a/openfpga/src/fpga_bitstream/build_device_bitstream.cpp
+++ b/openfpga/src/fpga_bitstream/build_device_bitstream.cpp
@@ -230,6 +230,7 @@ BitstreamManager build_device_bitstream(const VprContext& vpr_ctx,
     openfpga_ctx.vpr_device_annotation(), openfpga_ctx.vpr_routing_annotation(),
     vpr_ctx.device().rr_graph, openfpga_ctx.device_rr_gsb(),
     openfpga_ctx.flow_manager().compress_routing(), verbose);
+
   VTR_LOGV(verbose, "Done\n");
 
   VTR_LOGV(verbose, "Decoded %lu configuration bits into %lu blocks\n",
diff --git a/openfpga/src/fpga_bitstream/overwrite_bitstream.cpp b/openfpga/src/fpga_bitstream/overwrite_bitstream.cpp
new file mode 100644
index 000000000..e25d63e94
--- /dev/null
+++ b/openfpga/src/fpga_bitstream/overwrite_bitstream.cpp
@@ -0,0 +1,38 @@
+/********************************************************************
+ * This file includes functions to build bitstream from a mapped
+ * FPGA fabric.
+ * We decode the bitstream from configuration of routing multiplexers
+ * and Look-Up Tables (LUTs) which locate in CLBs and global routing
+ *architecture
+ *******************************************************************/
+
+/* Headers from vtrutil library */
+#include "overwrite_bitstream.h"
+
+#include "vtr_assert.h"
+#include "vtr_log.h"
+#include "vtr_time.h"
+
+/* begin namespace openfpga */
+namespace openfpga {
+
+/********************************************************************
+ * Overwrite bitstream retrieve from bitstream annotation XML which stored in
+ *BitstreamSetting
+ *******************************************************************/
+void overwrite_bitstream(openfpga::BitstreamManager& bitstream_manager,
+                         const openfpga::BitstreamSetting& bitstream_setting,
+                         const bool& verbose) {
+  vtr::ScopedStartFinishTimer timer("\nOverwrite Bitstream\n");
+
+  /* Apply overwrite_bitstream bit's path and value */
+  for (auto& id : bitstream_setting.overwrite_bitstreams()) {
+    std::string path = bitstream_setting.overwrite_bitstream_path(id);
+    bool value = bitstream_setting.overwrite_bitstream_value(id);
+    VTR_LOGV(verbose, "Overwrite bitstream path='%s' to value='%d'\n",
+             path.c_str(), value);
+    bitstream_manager.overwrite_bitstream(path, value);
+  }
+}
+
+} /* end namespace openfpga */
diff --git a/openfpga/src/fpga_bitstream/overwrite_bitstream.h b/openfpga/src/fpga_bitstream/overwrite_bitstream.h
new file mode 100644
index 000000000..de142232b
--- /dev/null
+++ b/openfpga/src/fpga_bitstream/overwrite_bitstream.h
@@ -0,0 +1,23 @@
+#ifndef OVERWRITE_BITSTREAM_H
+#define OVERWRITE_BITSTREAM_H
+
+/********************************************************************
+ * Include header files that are required by function declaration
+ *******************************************************************/
+
+#include "openfpga_context.h"
+
+/********************************************************************
+ * Function declaration
+ *******************************************************************/
+
+/* begin namespace openfpga */
+namespace openfpga {
+
+void overwrite_bitstream(openfpga::BitstreamManager& bitstream_manager,
+                         const openfpga::BitstreamSetting& bitstream_setting,
+                         const bool& verbose);
+
+} /* end namespace openfpga */
+
+#endif
diff --git a/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh b/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh
index 174b4cabe..8fc5e022c 100755
--- a/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh
+++ b/openfpga_flow/regression_test_scripts/fpga_bitstream_reg_test.sh
@@ -15,6 +15,9 @@ echo -e "Testing bitstream generation for an 48x48 FPGA device";
 run-task fpga_bitstream/generate_bitstream/configuration_chain/device_48x48 $@
 run-task fpga_bitstream/generate_bitstream/ql_memory_bank_shift_register/device_48x48 $@
 
+echo -e "Testing bitstream generation for an 4x4 FPGA device (randomly overwrite fabric bits)";
+run-task fpga_bitstream/overwrite_bitstream/device_4x4 $@
+
 echo -e "Testing bitstream generation for an 96x96 FPGA device";
 run-task fpga_bitstream/generate_bitstream/configuration_chain/device_96x96 $@
 run-task fpga_bitstream/generate_bitstream/ql_memory_bank_shift_register/device_72x72 $@
diff --git a/openfpga_flow/tasks/fpga_bitstream/overwrite_bitstream/device_4x4/config/task.conf b/openfpga_flow/tasks/fpga_bitstream/overwrite_bitstream/device_4x4/config/task.conf
new file mode 100644
index 000000000..67a1e028c
--- /dev/null
+++ b/openfpga_flow/tasks/fpga_bitstream/overwrite_bitstream/device_4x4/config/task.conf
@@ -0,0 +1,37 @@
+# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
+# Configuration file for running experiments
+# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
+# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
+# Each job execute fpga_flow script on combination of architecture & benchmark
+# timeout_each_job is timeout for each job
+# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
+
+[GENERAL]
+run_engine=openfpga_shell
+power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
+power_analysis = false
+spice_output=false
+verilog_output=true
+timeout_each_job = 20*60
+fpga_flow=vpr_blif
+
+[OpenFPGA_SHELL]
+openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/tasks/fpga_bitstream/overwrite_bitstream/device_4x4/config/test.openfpga
+openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_mem16K_40nm_openfpga.xml
+openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml
+openfpga_bitstream_setting_file=bitstream_annotation.xml
+openfpga_vpr_device_layout=4x4
+openfpga_ext_exec_python_script=${PATH:TASK_DIR}/config/test.py
+
+[ARCHITECTURES]
+arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileable_thru_channel_adder_chain_wide_mem16K_40nm.xml
+
+[BENCHMARKS]
+bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
+
+[SYNTHESIS_PARAM]
+bench0_top = and2
+bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
+bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
+
+[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
diff --git a/openfpga_flow/tasks/fpga_bitstream/overwrite_bitstream/device_4x4/config/test.openfpga b/openfpga_flow/tasks/fpga_bitstream/overwrite_bitstream/device_4x4/config/test.openfpga
new file mode 100644
index 000000000..1e9e3f79c
--- /dev/null
+++ b/openfpga_flow/tasks/fpga_bitstream/overwrite_bitstream/device_4x4/config/test.openfpga
@@ -0,0 +1,53 @@
+# Majority of the content refer to fix_device_example_script.openfpga
+
+ext_exec --command "python3 ${OPENFPGA_EXT_EXEC_PYTHON_SCRIPT} run_golden ${OPENFPGA_PATH}"
+
+ext_exec --command "python3 ${OPENFPGA_EXT_EXEC_PYTHON_SCRIPT} generate_testcase"
+
+# Run VPR for the 'and' design
+#--write_rr_graph example_rr_graph.xml
+vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling route --device ${OPENFPGA_VPR_DEVICE_LAYOUT}
+
+# Read OpenFPGA architecture definition
+read_openfpga_arch -f ${OPENFPGA_ARCH_FILE}
+
+# Read OpenFPGA simulation settings
+read_openfpga_simulation_setting -f ${OPENFPGA_SIM_SETTING_FILE}
+
+# Read OpenFPGA bitstream settings
+read_openfpga_bitstream_setting -f ${OPENFPGA_BITSTREAM_SETTING_FILE}
+
+# Annotate the OpenFPGA architecture to VPR data base
+# to debug use --verbose options
+link_openfpga_arch --activity_file ${ACTIVITY_FILE} --sort_gsb_chan_node_in_edges
+
+# Check and correct any naming conflicts in the BLIF netlist
+check_netlist_naming_conflict --fix --report ./netlist_renaming.xml
+
+# Apply fix-up to Look-Up Table truth tables based on packing results
+lut_truth_table_fixup
+
+# Build the module graph
+#  - Enabled compression on routing architecture modules
+#  - Enable pin duplication on grid modules
+build_fabric --compress_routing #--verbose
+
+# Repack the netlist to physical pbs
+# This must be done before bitstream generator and testbench generation
+# Strongly recommend it is done after all the fix-up have been applied
+repack #--verbose
+
+# Build the bitstream
+#  - Output the fabric-independent bitstream to a file
+build_architecture_bitstream --verbose
+
+# Build fabric-dependent bitstream
+build_fabric_bitstream --verbose
+
+# Write fabric-dependent bitstream
+write_fabric_bitstream --file fabric_bitstream.xml --format xml
+
+ext_exec --command "python3 ${OPENFPGA_EXT_EXEC_PYTHON_SCRIPT} validate"
+
+# Finish and exit OpenFPGA
+exit
diff --git a/openfpga_flow/tasks/fpga_bitstream/overwrite_bitstream/device_4x4/config/test.py b/openfpga_flow/tasks/fpga_bitstream/overwrite_bitstream/device_4x4/config/test.py
new file mode 100644
index 000000000..2997bb5d6
--- /dev/null
+++ b/openfpga_flow/tasks/fpga_bitstream/overwrite_bitstream/device_4x4/config/test.py
@@ -0,0 +1,120 @@
+import xml.etree.ElementTree as ET
+import sys
+import shutil
+import os
+import random
+
+random.seed()
+assert len(sys.argv) >= 2
+assert sys.argv[1] in ["run_golden", "generate_testcase", "validate"]
+TEST_BIT_COUNT = 200
+
+def read_fabric_bitstream_xml(file) :
+
+  bit_count = 0
+  tree = ET.parse(file)
+  root = tree.getroot()
+  assert root.tag == "fabric_bitstream", "Root tag is not 'fabric_bitstream', but '%s'" % root.tag
+  for region in root :
+    assert region.tag == "region", "fabric_bitstream child node tag is not 'region', but '%s'" % region.tag
+    for bit in region :
+      assert bit.tag == "bit", "region child node tag is not 'bit', but '%s'" % bit.tag
+      assert "path" in bit.attrib, "Attribute 'path' does not exist in bit node"
+      assert "value" in bit.attrib, "Attribute 'value' does not exist in bit node"
+      assert bit.attrib["value"] in ["0", "1"]
+      bit_count += 1
+  return [tree, bit_count]
+  
+def read_bitstream_annotation_xml(file) :
+  
+  xml = {}
+  tree = ET.parse(file)
+  root = tree.getroot()
+  assert root.tag == "openfpga_bitstream_setting", "Root tag is not 'openfpga_bitstream_setting', but '%s'" % root.tag
+  for overwrite_bitstream in root :
+    assert overwrite_bitstream.tag == "overwrite_bitstream", "openfpga_bitstream_setting child node tag is not 'overwrite_bitstream', but '%s'" % overwrite_bitstream.tag
+    for bit in overwrite_bitstream :
+      assert bit.tag == "bit", "overwrite_bitstream child node tag is not 'bit', but '%s'" % bit.tag
+      assert "path" in bit.attrib, "Attribute 'path' does not exist in bit node"
+      assert "value" in bit.attrib, "Attribute 'value' does not exist in bit node"
+      path = bit.attrib["path"]
+      assert path not in xml
+      index = path.rfind("[")
+      assert index != -1
+      path = "%s.mem_out%s" % (path[:index], path[index:])
+      assert path not in xml
+      assert bit.attrib["value"] in ["0", "1"]
+      xml[path] = bit.attrib["value"]
+  return xml
+
+if sys.argv[1] == "run_golden" :
+
+  assert len(sys.argv) >= 3
+  openfpga_exe = os.path.abspath("%s/build/openfpga/openfpga" % sys.argv[2])
+  assert os.path.exists(openfpga_exe)
+  shutil.rmtree("golden", ignore_errors=True)
+  os.mkdir("golden")
+  original_openfpga = open("and2_run.openfpga")
+  golden_openfpga = open("golden/and2_run.openfpga", "w")
+  for line in original_openfpga :
+    if line.find("ext_exec") == 0 :
+      pass
+    else :
+      golden_openfpga.write(line)
+  golden_openfpga.close()
+  original_openfpga.close()
+  bitstream_annotation = open("golden/bitstream_annotation.xml", "w")
+  bitstream_annotation.write("<openfpga_bitstream_setting/>\n")
+  bitstream_annotation.close()
+  shutil.copyfile("and2.blif", "golden/and2.blif")
+  shutil.copyfile("and2_ace_out.act", "golden/and2_ace_out.act")
+  cmd = "cd golden && %s -batch -f and2_run.openfpga > golden.log" % (openfpga_exe)
+  assert os.system(cmd) == 0
+
+elif sys.argv[1] == "generate_testcase" :
+  
+  (tree, bit_count) = read_fabric_bitstream_xml("golden/fabric_bitstream.xml")
+  random_bits = []
+  while len(random_bits) != TEST_BIT_COUNT :
+    bit = random.randint(0, bit_count - 1)
+    if bit not in random_bits :
+      random_bits.append(bit)
+  bitstream_annotation = open("bitstream_annotation.xml", "w")
+  bitstream_annotation.write("<openfpga_bitstream_setting>\n")
+  bitstream_annotation.write("  <overwrite_bitstream>\n")
+  index = 0
+  for region in tree.getroot() :
+    for bit in region :
+      if index in random_bits :
+        path = bit.attrib["path"]
+        value = bit.attrib["value"]
+        assert value in ["0", "1"]
+        path = path.replace(".mem_out[", "[")
+        bitstream_annotation.write("    <bit value=\"%s\" path=\"%s\"/>\n" % ("1" if value == "0" else "0", path))
+      index += 1
+  bitstream_annotation.write("  </overwrite_bitstream>\n")
+  bitstream_annotation.write("</openfpga_bitstream_setting>\n")
+  bitstream_annotation.close()
+
+else :
+
+  gtree = ET.parse("golden/fabric_bitstream.xml")
+  tree = ET.parse("fabric_bitstream.xml")
+  bitstream_annotation = read_bitstream_annotation_xml("bitstream_annotation.xml")
+  checked_count = 0
+  for gregion, region in zip(gtree.getroot(), tree.getroot()) :
+    for gbit, bit in zip(gregion, region) :
+      assert bit.attrib["path"] == gbit.attrib["path"]
+      path = bit.attrib["path"]
+      if path in bitstream_annotation :
+        # This is something we want to overwrite, hence the value should 
+        #   Same in the annotation file
+        #   Not same in golden fabric
+        assert bit.attrib["value"] != gbit.attrib["value"]
+        assert bit.attrib["value"] == bitstream_annotation[path]
+      else :
+        # This is not what we want to overwrite
+        # Hence the value should same in golden fabric
+        assert bit.attrib["value"] == gbit.attrib["value"]
+
+exit(0)