diff --git a/libopenfpga/libarchopenfpga/src/read_xml_technology_library.cpp b/libopenfpga/libarchopenfpga/src/read_xml_technology_library.cpp index f2f082116..2437a1089 100644 --- a/libopenfpga/libarchopenfpga/src/read_xml_technology_library.cpp +++ b/libopenfpga/libarchopenfpga/src/read_xml_technology_library.cpp @@ -122,6 +122,10 @@ void read_xml_device_transistor(pugi::xml_node& xml_device_transistor, tech_lib.set_transistor_model_min_width(device_model, transistor_type, get_attribute(xml_device_transistor, "min_width", loc_data).as_float(0.)); + /* Parse the transistor maximum width, by default we consider the same as minimum width */ + tech_lib.set_transistor_model_max_width(device_model, transistor_type, + get_attribute(xml_device_transistor, "max_width", loc_data, pugiutil::ReqOpt::OPTIONAL).as_float(tech_lib.transistor_model_min_width(device_model, transistor_type))); + /* Parse the transistor variation name */ tech_lib.set_transistor_model_variation_name(device_model, transistor_type, get_attribute(xml_device_transistor, "variation", loc_data).as_string()); diff --git a/libopenfpga/libarchopenfpga/src/technology_library.cpp b/libopenfpga/libarchopenfpga/src/technology_library.cpp index 3f8e8e7f9..aa97abe80 100644 --- a/libopenfpga/libarchopenfpga/src/technology_library.cpp +++ b/libopenfpga/libarchopenfpga/src/technology_library.cpp @@ -157,6 +157,18 @@ float TechnologyLibrary::transistor_model_min_width(const TechnologyModelId& mod return transistor_model_min_widths_[model_id][transistor_type]; } +/* Access the maximum width of a transistor (either PMOS or NMOS) for a technology model + * Note: This is ONLY applicable to transistor model + */ +float TechnologyLibrary::transistor_model_max_width(const TechnologyModelId& model_id, + const e_tech_lib_transistor_type& transistor_type) const { + /* validate the model_id */ + VTR_ASSERT(valid_model_id(model_id)); + /* This is only applicable to transistor model */ + VTR_ASSERT(TECH_LIB_MODEL_TRANSISTOR == model_type(model_id)); + return transistor_model_max_widths_[model_id][transistor_type]; +} + /* Access the minimum width of a transistor (either PMOS or NMOS) for a technology model * Note: This is ONLY applicable to transistor model */ @@ -270,6 +282,7 @@ TechnologyModelId TechnologyLibrary::add_model(const std::string& name) { transistor_model_names_.emplace_back(); transistor_model_chan_lengths_.emplace_back(); transistor_model_min_widths_.emplace_back(); + transistor_model_max_widths_.emplace_back(); transistor_model_variation_names_.emplace_back(); transistor_model_variation_ids_.push_back(std::array{TechnologyVariationId::INVALID(), TechnologyVariationId::INVALID()}); @@ -394,6 +407,19 @@ void TechnologyLibrary::set_transistor_model_min_width(const TechnologyModelId& return; } +/* Set the maximum width for either PMOS or NMOS of a model in the library + * This is ONLY applicable to transistors + */ +void TechnologyLibrary::set_transistor_model_max_width(const TechnologyModelId& model_id, + const e_tech_lib_transistor_type& transistor_type, + const float& max_width) { + /* validate the model_id */ + VTR_ASSERT(valid_model_id(model_id)); + VTR_ASSERT(TECH_LIB_MODEL_TRANSISTOR == model_type(model_id)); + transistor_model_max_widths_[model_id][transistor_type] = max_width; + return; +} + /* Set the variation name for either PMOS or NMOS of a model in the library * This is ONLY applicable to transistors */ diff --git a/libopenfpga/libarchopenfpga/src/technology_library.h b/libopenfpga/libarchopenfpga/src/technology_library.h index a38acade3..ba90eff1d 100644 --- a/libopenfpga/libarchopenfpga/src/technology_library.h +++ b/libopenfpga/libarchopenfpga/src/technology_library.h @@ -101,6 +101,8 @@ class TechnologyLibrary { const e_tech_lib_transistor_type& transistor_type) const; float transistor_model_min_width(const TechnologyModelId& model_id, const e_tech_lib_transistor_type& transistor_type) const; + float transistor_model_max_width(const TechnologyModelId& model_id, + const e_tech_lib_transistor_type& transistor_type) const; TechnologyVariationId transistor_model_variation(const TechnologyModelId& model_id, const e_tech_lib_transistor_type& transistor_type) const; public: /* Public Accessors: Basic data query on RRAM models */ @@ -138,6 +140,9 @@ class TechnologyLibrary { void set_transistor_model_min_width(const TechnologyModelId& model_id, const e_tech_lib_transistor_type& transistor_type, const float& min_width); + void set_transistor_model_max_width(const TechnologyModelId& model_id, + const e_tech_lib_transistor_type& transistor_type, + const float& max_width); void set_transistor_model_variation_name(const TechnologyModelId& model_id, const e_tech_lib_transistor_type& transistor_type, const std::string& variation_name); @@ -231,6 +236,15 @@ class TechnologyLibrary { */ vtr::vector> transistor_model_min_widths_; + /* The maximum width of a transistor. + * This should be defined by your technology vendor + * The maximum width of a transistor will be used to size your transistors + * If the required width in circuit models in larger then the max width, + * multiple transistor bin will be instanciated. + * For FinFET, the maximum width should be the same as min_width + */ + vtr::vector> transistor_model_max_widths_; + /* The variation name and id binded to PMOS and NMOS transistor * We expect users to provide the exact name of variation defined in this technology library * the name and id will be automatically matched by using function link_model_to_variation() diff --git a/libopenfpga/libarchopenfpga/src/write_xml_circuit_library.cpp b/libopenfpga/libarchopenfpga/src/write_xml_circuit_library.cpp index 88fc0d3b2..5dd69ca8e 100644 --- a/libopenfpga/libarchopenfpga/src/write_xml_circuit_library.cpp +++ b/libopenfpga/libarchopenfpga/src/write_xml_circuit_library.cpp @@ -92,6 +92,25 @@ void write_xml_design_technology(std::fstream& fp, fp << "/>" << "\n"; } +/******************************************************************** + * A writer to output the device technology of a circuit model to XML format + *******************************************************************/ +static +void write_xml_device_technology(std::fstream& fp, + const char* fname, + const CircuitLibrary& circuit_lib, + const CircuitModelId& model) { + /* Validate the file stream */ + openfpga::check_file_stream(fname, fp); + + if (!circuit_lib.device_model_name(model).empty()) { + fp << "\t\t\t" << "" << "\n"; + } +} + /******************************************************************** * A writer to output a circuit port to XML format *******************************************************************/ @@ -401,6 +420,9 @@ void write_xml_circuit_model(std::fstream& fp, /* Write the design technology of circuit model */ write_xml_design_technology(fp, fname, circuit_lib, model); + /* Write the device technology of circuit model */ + write_xml_device_technology(fp, fname, circuit_lib, model); + /* Write the input buffer information of circuit model, * only applicable when this circuit model is neither inverter nor buffer */ diff --git a/libopenfpga/libarchopenfpga/src/write_xml_technology_library.cpp b/libopenfpga/libarchopenfpga/src/write_xml_technology_library.cpp index 6f3f6fe0d..bf15bbe32 100644 --- a/libopenfpga/libarchopenfpga/src/write_xml_technology_library.cpp +++ b/libopenfpga/libarchopenfpga/src/write_xml_technology_library.cpp @@ -60,6 +60,7 @@ void write_xml_device_model(std::fstream& fp, write_xml_attribute(fp, "name", tech_lib.transistor_model_name(device_model, TECH_LIB_TRANSISTOR_PMOS).c_str()); write_xml_attribute(fp, "chan_length", tech_lib.transistor_model_chan_length(device_model, TECH_LIB_TRANSISTOR_PMOS)); write_xml_attribute(fp, "min_width", tech_lib.transistor_model_min_width(device_model, TECH_LIB_TRANSISTOR_PMOS)); + write_xml_attribute(fp, "max_width", tech_lib.transistor_model_max_width(device_model, TECH_LIB_TRANSISTOR_PMOS)); if (TechnologyVariationId::INVALID() != tech_lib.transistor_model_variation(device_model, TECH_LIB_TRANSISTOR_PMOS)) { write_xml_attribute(fp, "variation", tech_lib.variation_name(tech_lib.transistor_model_variation(device_model, TECH_LIB_TRANSISTOR_PMOS)).c_str()); }