From 0d9f1a3c6bd849c62d19b132949106f8ce8d9fd2 Mon Sep 17 00:00:00 2001 From: chungshien-chai Date: Sun, 28 Jul 2024 19:12:34 -0700 Subject: [PATCH] Forward searching the config bit + some minor refactor --- .../src/read_xml_bitstream_setting.cpp | 2 +- .../src/bitstream_manager.cpp | 97 +++++++++++++------ openfpga/src/base/openfpga_basic.cpp | 16 ++- .../device_4x4/config/test.py | 1 - 4 files changed, 78 insertions(+), 38 deletions(-) diff --git a/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp b/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp index 49b76e0b1..244703fc1 100644 --- a/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp +++ b/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp @@ -119,7 +119,7 @@ static void read_xml_overwrite_bitstream_setting( 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"); + "Invalid value of overwrite_bitstream bit. Expect [0|1]"); } /* Add to bit */ bitstream_setting.add_overwrite_bitstream(path_attr, value_attr == "1"); diff --git a/libs/libfpgabitstream/src/bitstream_manager.cpp b/libs/libfpgabitstream/src/bitstream_manager.cpp index 71aa36ffb..39c3515b3 100644 --- a/libs/libfpgabitstream/src/bitstream_manager.cpp +++ b/libs/libfpgabitstream/src/bitstream_manager.cpp @@ -5,6 +5,7 @@ #include +#include "arch_error.h" #include "bitstream_manager_utils.h" #include "openfpga_tokenizer.h" #include "vtr_assert.h" @@ -300,39 +301,73 @@ void BitstreamManager::add_output_net_id_to_block( void BitstreamManager::overwrite_bitstream(const std::string& path, const bool& value) { - ConfigBlockId block; - StringToken tokenizer(path); - std::vector blocks = tokenizer.split("."); - std::reverse(blocks.begin(), blocks.end()); - std::string current_block_name = ""; - bool match = false; - for (size_t i = 0; i < bit_values_.size() && !match; i++) { - block = bit_parent_blocks_[ConfigBitId(i)]; - if (valid_block_id(block)) { - size_t index = find_bitstream_manager_config_bit_index_in_parent_block( - *this, ConfigBitId(i)); - current_block_name = - block_name(block) + ("[" + std::to_string(index) + "]"); - if (current_block_name == blocks[0]) { - match = true; - for (size_t b = 1; b < blocks.size() && match; b++) { - block = block_parent(block); - if (valid_block_id(block)) { - if (block_name(block) != blocks[b]) { - match = false; - } - } else { - match = false; - } - } - if (match) { - if (!valid_block_id(block_parent(block))) { - bit_values_[ConfigBitId(i)] = value ? '1' : '0'; - } else { - match = false; - } + bool bad_format = true; + size_t index = path.rfind("["); + std::string bit_string = ""; + if (index != std::string::npos && path[path.size() - 1] == ']') { + bit_string = path.substr(index + 1, path.size() - index - 2); + bad_format = bit_string.size() == 0; + auto iter = bit_string.begin(); + while (!bad_format && iter != bit_string.end()) { + bad_format = !std::isdigit(*iter); + iter++; + } + } + if (bad_format) { + archfpga_throw(__FILE__, __LINE__, + "overwrite_bitstream bit path '%s' does not match format " + "[bit index]", + path.c_str()); + } else { + size_t bit = (size_t)(std::stoi(bit_string)); + StringToken tokenizer(path.substr(0, index)); + std::vector blocks = tokenizer.split("."); + std::vector 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 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()); } } } diff --git a/openfpga/src/base/openfpga_basic.cpp b/openfpga/src/base/openfpga_basic.cpp index ac10f007c..6546ff909 100644 --- a/openfpga/src/base/openfpga_basic.cpp +++ b/openfpga/src/base/openfpga_basic.cpp @@ -69,13 +69,19 @@ int call_external_command(const Command& cmd, return CMD_EXEC_FATAL_ERROR; } + // 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 (status & 0xFF) { - // First 8 bits are system signals - return 1; + 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); } - // real return was actually shifted 8 bits - return status >> 8; + // Program maybe terminated because of various killed or stopped signal + return CMD_EXEC_FATAL_ERROR; } } /* end namespace openfpga */ 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 index 5a5a00285..07d96a7da 100644 --- 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 @@ -100,7 +100,6 @@ else : gtree = ET.parse("golden/fabric_bitstream.xml") tree = ET.parse("fabric_bitstream.xml") bitstream_annotation = read_bitstream_annotation_xml("bitstream_annotation.xml") - status = 0 checked_count = 0 for gregion, region in zip(gtree.getroot(), tree.getroot()) : for gbit, bit in zip(gregion, region) :