diff --git a/libs/libarchopenfpga/src/bitstream_setting.cpp b/libs/libarchopenfpga/src/bitstream_setting.cpp index afdf6998b..962726ec4 100644 --- a/libs/libarchopenfpga/src/bitstream_setting.cpp +++ b/libs/libarchopenfpga/src/bitstream_setting.cpp @@ -126,7 +126,7 @@ std::string BitstreamSetting::default_mode_bits_to_string( return mode_bits_str; } -std::string BitstreamSetting::clock_routing_network_name( +std::string BitstreamSetting::clock_routing_network( const BitstreamClockRoutingSettingId& clock_routing_setting_id) const { VTR_ASSERT(true == valid_bitstream_clock_routing_setting_id(clock_routing_setting_id)); diff --git a/libs/libarchopenfpga/src/bitstream_setting.h b/libs/libarchopenfpga/src/bitstream_setting.h index d5d17907e..18f1ec944 100644 --- a/libs/libarchopenfpga/src/bitstream_setting.h +++ b/libs/libarchopenfpga/src/bitstream_setting.h @@ -122,7 +122,7 @@ class BitstreamSetting { const BitstreamDefaultModeSettingId& default_mode_setting_id) const; /* Clock routing settings */ - std::string clock_routing_network_name( + std::string clock_routing_network( const BitstreamClockRoutingSettingId& clock_routing_setting_id) const; BasicPort clock_routing_pin( const BitstreamClockRoutingSettingId& clock_routing_setting_id) const; diff --git a/libs/libarchopenfpga/src/bitstream_setting_xml_constants.h b/libs/libarchopenfpga/src/bitstream_setting_xml_constants.h index 5cfb973fa..5ead77b83 100644 --- a/libs/libarchopenfpga/src/bitstream_setting_xml_constants.h +++ b/libs/libarchopenfpga/src/bitstream_setting_xml_constants.h @@ -17,6 +17,11 @@ constexpr const char* XML_DEFAULT_MODE_BITS_NODE_NAME = "default_mode_bits"; constexpr const char* XML_DEFAULT_MODE_BITS_ATTRIBUTE_NAME = "name"; constexpr const char* XML_DEFAULT_MODE_BITS_ATTRIBUTE_MODE_BITS = "mode_bits"; +/* Clock routing XML syntax */ +constexpr const char* XML_CLOCK_ROUTING_NODE_NAME = "default_mode_bits"; +constexpr const char* XML_CLOCK_ROUTING_ATTRIBUTE_NETWORK = "network"; +constexpr const char* XML_CLOCK_ROUTING_ATTRIBUTE_PIN = "pin"; + /* Interconnect XML syntax */ constexpr const char* XML_INTERCONNECT_NODE_NAME = "interconnect"; constexpr const char* XML_INTERCONNECT_ATTRIBUTE_NAME = "name"; diff --git a/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp b/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp index 664c5eec8..1a0cf2bbd 100644 --- a/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp +++ b/libs/libarchopenfpga/src/read_xml_bitstream_setting.cpp @@ -81,6 +81,34 @@ static void read_xml_bitstream_default_mode_setting( operating_pb_parser.modes(), mode_bits); } +/******************************************************************** + * Parse XML description for a pb_type annotation under a + *XML node + *******************************************************************/ +static void read_xml_bitstream_clock_routing_setting( + pugi::xml_node& xml_clk_routing, const pugiutil::loc_data& loc_data, + openfpga::BitstreamSetting& bitstream_setting) { + const std::string& ntwk_attr = + get_attribute(xml_clk_routing, XML_CLOCK_ROUTING_ATTRIBUTE_NETWORK, loc_data).as_string(); + + const std::string& pin_attr = + get_attribute(xml_clk_routing, XML_CLOCK_ROUTING_ATTRIBUTE_PIN, loc_data).as_string(); + /* Parse the port and apply sanity checks */ + openfpga::PortParser port_parser(pin_attr); + BasicPort pin = port_parser.port(); + if (!pin.is_valid()) { + archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_clk_routing), + "Invalid pin '%s' which should be valid port. For example, clk[1:1]\n", pin_attr.c_str()); + } + if (1 != pin.get_width()) { + archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_clk_routing), + "Invalid pin '%s' with a width of '%lu'. Only allow pin definition with width of 1. For example, clk[2:2]\n", pin_attr.c_str(), pin.get_width()); + } + + /* Add to bitstream setting */ + bitstream_setting.add_bitstream_clock_routing_setting(ntwk_attr, pin); +} + /******************************************************************** * Parse XML description for a pb_type annotation under a XML node *******************************************************************/ @@ -179,6 +207,9 @@ openfpga::BitstreamSetting read_xml_bitstream_setting( } else if (xml_child.name() == std::string(XML_DEFAULT_MODE_BITS_NODE_NAME)) { read_xml_bitstream_default_mode_setting(xml_child, loc_data, bitstream_setting); + } else if (xml_child.name() == std::string(XML_CLOCK_ROUTING_NODE_NAME)) { + read_xml_bitstream_clock_routing_setting(xml_child, loc_data, + bitstream_setting); } else if (xml_child.name() == std::string(XML_INTERCONNECT_NODE_NAME)) { read_xml_bitstream_interconnect_setting(xml_child, loc_data, bitstream_setting); diff --git a/libs/libarchopenfpga/src/write_xml_bitstream_setting.cpp b/libs/libarchopenfpga/src/write_xml_bitstream_setting.cpp index 0411984b1..53a5fee58 100644 --- a/libs/libarchopenfpga/src/write_xml_bitstream_setting.cpp +++ b/libs/libarchopenfpga/src/write_xml_bitstream_setting.cpp @@ -184,6 +184,33 @@ static void write_xml_bitstream_default_mode_setting( << "\n"; } +/******************************************************************** + * A writer to output a bitstream clock_routing setting to XML format + *******************************************************************/ +static void write_xml_bitstream_clock_routing_setting( + std::fstream& fp, const char* fname, + const openfpga::BitstreamSetting& bitstream_setting, + const BitstreamClockRoutingSettingId& bitstream_clock_routing_setting_id) { + /* Validate the file stream */ + openfpga::check_file_stream(fname, fp); + + fp << "\t" + << "<" << XML_CLOCK_ROUTING_NODE_NAME; + + /* Generate the full hierarchy name of the pb_type */ + write_xml_attribute(fp, XML_CLOCK_ROUTING_ATTRIBUTE_NETWORK, + bitstream_setting.clock_routing_network(bitstream_clock_routing_setting_id) + .c_str()); + + write_xml_attribute( + fp, XML_CLOCK_ROUTING_ATTRIBUTE_PIN, + bitstream_setting + .clock_routing_pin(bitstream_clock_routing_setting_id).to_verilog_string() + .c_str()); + fp << "/>" + << "\n"; +} + /******************************************************************** * A writer to output a bitstream interconnect setting to XML format *******************************************************************/ @@ -239,6 +266,13 @@ void write_xml_bitstream_setting( bitstream_default_mode_setting_id); } + /* Write clock_routing -related settings */ + for (const auto& bitstream_clock_routing_setting_id : + bitstream_setting.clock_routing_settings()) { + write_xml_bitstream_clock_routing_setting(fp, fname, bitstream_setting, + bitstream_clock_routing_setting_id); + } + /* Write interconnect -related settings */ for (const auto& bitstream_interc_setting_id : bitstream_setting.interconnect_settings()) {