From e959821813fdb12671ad847ce6daf4a76ea85df5 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 11 Nov 2020 13:59:24 -0700 Subject: [PATCH] [Tool] Enhance internal check functions for tile annotation --- .../src/read_xml_tile_annotation.cpp | 14 +++++++++ .../libarchopenfpga/src/tile_annotation.cpp | 29 +++++++++++++++++++ .../libarchopenfpga/src/tile_annotation.h | 8 ++++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/libopenfpga/libarchopenfpga/src/read_xml_tile_annotation.cpp b/libopenfpga/libarchopenfpga/src/read_xml_tile_annotation.cpp index 2e29a6110..692cd2288 100644 --- a/libopenfpga/libarchopenfpga/src/read_xml_tile_annotation.cpp +++ b/libopenfpga/libarchopenfpga/src/read_xml_tile_annotation.cpp @@ -50,6 +50,13 @@ void read_xml_tile_global_port_annotation(pugi::xml_node& xml_tile, TileGlobalPortId tile_global_port_id = tile_annotation.create_global_port(name_attr, tile_port_tokens[0], tile_port_parser.port()); + /* Report any duplicated port names */ + if (TileGlobalPortId::INVALID() == tile_global_port_id) { + archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_tile), + "Invalid port name '%s' which is defined more than once in the global port list!\n", + name_attr.c_str()); + } + /* Get is_clock attributes */ tile_annotation.set_global_port_is_clock(tile_global_port_id, get_attribute(xml_tile, "is_clock", loc_data, pugiutil::ReqOpt::OPTIONAL).as_bool(false)); @@ -61,6 +68,13 @@ void read_xml_tile_global_port_annotation(pugi::xml_node& xml_tile, /* Get default_value attributes */ tile_annotation.set_global_port_default_value(tile_global_port_id, get_attribute(xml_tile, "default_value", loc_data, pugiutil::ReqOpt::OPTIONAL).as_int(0)); + + /* Ensure valid port attributes */ + if (false == tile_annotation.valid_global_port_attributes(tile_global_port_id)) { + archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_tile), + "Invalid port attributes for '%s'! A port can only be clock or set or reset.\n", + name_attr.c_str()); + } } /******************************************************************** diff --git a/libopenfpga/libarchopenfpga/src/tile_annotation.cpp b/libopenfpga/libarchopenfpga/src/tile_annotation.cpp index 74f266e60..5bef68a31 100644 --- a/libopenfpga/libarchopenfpga/src/tile_annotation.cpp +++ b/libopenfpga/libarchopenfpga/src/tile_annotation.cpp @@ -66,6 +66,12 @@ size_t TileAnnotation::global_port_default_value(const TileGlobalPortId& global_ TileGlobalPortId TileAnnotation::create_global_port(const std::string& port_name, const std::string& tile_name, const BasicPort& tile_port) { + /* Ensure that the name is unique */ + std::map::iterator it = global_port_name2ids_.find(port_name); + if (it != global_port_name2ids_.end()) { + return TileGlobalPortId::INVALID(); + } + /* This is a legal name. we can create a new id */ TileGlobalPortId port_id = TileGlobalPortId(global_port_ids_.size()); global_port_ids_.push_back(port_id); @@ -77,6 +83,9 @@ TileGlobalPortId TileAnnotation::create_global_port(const std::string& port_name global_port_is_reset_.push_back(false); global_port_default_values_.push_back(0); + /* Register in the name-to-id map */ + global_port_name2ids_[port_name] = port_id; + return port_id; } @@ -112,4 +121,24 @@ bool TileAnnotation::valid_global_port_id(const TileGlobalPortId& global_port_id return ( size_t(global_port_id) < global_port_ids_.size() ) && ( global_port_id == global_port_ids_[global_port_id] ); } +bool TileAnnotation::valid_global_port_attributes(const TileGlobalPortId& global_port_id) const { + VTR_ASSERT(valid_global_port_id(global_port_id)); + + int attribute_counter = 0; + + if (true == global_port_is_clock_[global_port_id]) { + attribute_counter++; + } + + if (true == global_port_is_reset_[global_port_id]) { + attribute_counter++; + } + + if (true == global_port_is_set_[global_port_id]) { + attribute_counter++; + } + + return ((0 == attribute_counter) || (1 == attribute_counter)); +} + } /* namespace openfpga ends */ diff --git a/libopenfpga/libarchopenfpga/src/tile_annotation.h b/libopenfpga/libarchopenfpga/src/tile_annotation.h index 40fd5f2ea..b87ceb74a 100644 --- a/libopenfpga/libarchopenfpga/src/tile_annotation.h +++ b/libopenfpga/libarchopenfpga/src/tile_annotation.h @@ -62,6 +62,10 @@ class TileAnnotation { const size_t& default_value); public: /* Public validator */ bool valid_global_port_id(const TileGlobalPortId& global_port_id) const; + /* Validate attributes of a given global port + * - A port can only be defined as clock or set or reset + */ + bool valid_global_port_attributes(const TileGlobalPortId& global_port_id) const; private: /* Internal data */ /* Global port information for tiles */ vtr::vector global_port_ids_; @@ -72,9 +76,11 @@ class TileAnnotation { vtr::vector global_port_is_reset_; vtr::vector global_port_is_set_; vtr::vector global_port_default_values_; + + /* A fast lookup for port names */ + std::map global_port_name2ids_; }; } /* namespace openfpga ends */ #endif -