diff --git a/ODIN_II/SRC/HardSoftLogicMixer.cpp b/ODIN_II/SRC/HardSoftLogicMixer.cpp new file mode 100644 index 00000000000..2f32f874544 --- /dev/null +++ b/ODIN_II/SRC/HardSoftLogicMixer.cpp @@ -0,0 +1,74 @@ +/* + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "HardSoftLogicMixer.hpp" + +#include // INT_MAX +#include + +#include "multipliers.h" // instantiate_simple_soft_multiplier +#include "odin_error.h" // error_message + +HardSoftLogicMixer::HardSoftLogicMixer() { + for (int i = 0; i < operation_list_END; i++) { + if (i == MULTIPLY) { + this->_opts[i] = new MultsOpt(); + } else { + this->_opts[i] = new MixingOpt(); + } + } +} + +HardSoftLogicMixer::~HardSoftLogicMixer() { + for (int i = 0; i < operation_list_END; i++) { + delete this->_opts[i]; + } +} +void HardSoftLogicMixer::note_candidate_node(nnode_t* opNode) { + _nodes_by_opt[opNode->type].push_back(opNode); +} + +bool HardSoftLogicMixer::hardenable(nnode_t* node) { + return this->_opts[node->type]->hardenable(node); +} + +bool HardSoftLogicMixer::enabled(nnode_t* node) { + return this->_opts[node->type]->enabled(); +} + +int HardSoftLogicMixer::hard_blocks_needed(operation_list opt) { + return _nodes_by_opt[opt].size(); +} + +void HardSoftLogicMixer::partial_map_node(nnode_t* node, short traverse_number, netlist_t* netlist) { + _opts[node->type]->partial_map_node(node, traverse_number, netlist, this); +} + +void HardSoftLogicMixer::perform_optimizations(netlist_t* netlist) { + if (_opts[MULTIPLY]->enabled()) { + int blocks_needed = this->hard_blocks_needed(MULTIPLY); + _opts[MULTIPLY]->set_blocks_needed(blocks_needed); + _opts[MULTIPLY]->assign_weights(netlist, _nodes_by_opt[MULTIPLY]); + _opts[MULTIPLY]->perform(netlist, _nodes_by_opt[MULTIPLY]); + _opts[MULTIPLY]->instantiate_soft_logic(netlist, _nodes_by_opt[MULTIPLY]); + } +} diff --git a/ODIN_II/SRC/MixingOptimization.cpp b/ODIN_II/SRC/MixingOptimization.cpp new file mode 100644 index 00000000000..5825e7afbf1 --- /dev/null +++ b/ODIN_II/SRC/MixingOptimization.cpp @@ -0,0 +1,178 @@ +/* + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "MixingOptimization.hpp" + +#include // INT_MAX +#include + +#include "netlist_statistic.h" // mixing_optimization_stats +#include "multipliers.h" // instantiate_simple_soft_multiplier +#include "odin_error.h" // error_message +#include "adders.h" // hard_adders +#include "HardSoftLogicMixer.hpp" // HardSoftLogicMixer + +void MixingOpt::scale_counts() { + if (this->_blocks_count < 0 || this->_blocks_count == INT_MAX || this->_ratio < 0.0 || this->_ratio > 1.0) { + error_message(NETLIST, unknown_location, "%s", + "The parameters for optimization kind:%i are configured incorrectly : count %i, ratio %f\n", this->_kind, this->_blocks_count, this->_ratio); + exit(0); + } + this->_blocks_count = this->_blocks_count * this->_ratio; +} + +void MixingOpt::assign_weights(netlist_t* /*netlist*/, std::vector /*nodes*/) { + // compute weights for all noted nodes + error_message(NETLIST, unknown_location, "%s", + "Assign_weights mixing optimization was called for optimization without specification provided, for kind %i\n", this->_kind); + exit(0); +} + +void MixingOpt::perform(netlist_t*, std::vector&) { + error_message(NETLIST, unknown_location, "%s", + "Performing mixing optimization was called for optimization without method provided, for kind %i\n", this->_kind); + exit(0); +} + +MultsOpt::MultsOpt(int _exact) + : MixingOpt(1.0, MULTIPLY) { + this->_blocks_count = _exact; + this->_enabled = true; +} + +MultsOpt::MultsOpt(float ratio) + : MixingOpt(ratio, MULTIPLY) { + if (ratio < 0.0 || ratio > 1.0) { + error_message(NETLIST, unknown_location, "%s", + "Miltipliers mixing optimization is started with wrong ratio %f\n", ratio); + exit(0); + } + + //Explicitly set all hard block multipliers to max + this->_blocks_count = INT_MAX; + this->_enabled = true; +} + +bool MultsOpt::hardenable(nnode_t* node) { + int mult_size = std::max(node->input_port_sizes[0], node->input_port_sizes[1]); + return (hard_multipliers && (mult_size > min_mult)); +} + +void MultsOpt::assign_weights(netlist_t* netlist, std::vector nodes) { + // compute weights for all noted nodes + for (size_t i = 0; i < nodes.size(); i++) { + mixing_optimization_stats(nodes[i], netlist); + } +} + +void MultsOpt::perform(netlist_t* netlist, std::vector& weighted_nodes) { + size_t nodes_count = weighted_nodes.size(); + + // per optimization, instantiate hard logic + for (int i = 0; i < this->_blocks_count; i++) { + int maximal_cost = -1; + int index = -1; + for (size_t j = 0; j < nodes_count; j++) { + // if found a new maximal cost that is higher than a current maximum AND is not restricted by input + // params for minimal "hardenable" multiplier width + if (maximal_cost < weighted_nodes[j]->weight && this->hardenable(weighted_nodes[j])) { + maximal_cost = weighted_nodes[j]->weight; + index = j; + } + } + + // if there are no suitable nodes left, leave the loop to + // implement remaining nodes in soft logic + if (index < 0) + break; + + // indicate for future iterations the node was hardened + weighted_nodes[index]->weight = -1; + + if (hard_multipliers) { + instantiate_hard_multiplier(weighted_nodes[index], this->cached_traverse_value, netlist); + } + } + + // From the end of the vector, remove all nodes that were implemented in hard logic. The remaining + // nodes will be instantiated in soft_map_remaining_nodes + for (int i = nodes_count - 1; i >= 0; i--) { + if (weighted_nodes[i]->weight == -1) { + weighted_nodes.erase(weighted_nodes.begin() + i); + } + } +} + +void MixingOpt::set_blocks_needed(int new_count) { + this->_blocks_count = new_count; +} + +void MultsOpt::set_blocks_needed(int new_count) { + // with development for fixed_layout, this value will change + int availableHardBlocks = INT_MAX; + int hardBlocksNeeded = new_count; + int hardBlocksCount = availableHardBlocks; + + if (hardBlocksCount > hardBlocksNeeded) { + hardBlocksCount = hardBlocksNeeded; + } + + if (hardBlocksCount < this->_blocks_count) { + this->_blocks_count = hardBlocksCount; + } + + this->scale_counts(); +} +void MixingOpt::instantiate_soft_logic(netlist_t* /*netlist*/, std::vector /* nodes*/) { + error_message(NETLIST, unknown_location, "%s", + "Performing instantiate_soft_logic was called for optimization without method provided, for kind %i\n", this->_kind); + exit(0); +} + +void MixingOpt::partial_map_node(nnode_t* /*node*/, short /*traverse_value*/, netlist_t*, /*netlist*/ HardSoftLogicMixer* /*mixer*/) { + error_message(NETLIST, unknown_location, "%s", + "Performing partial_map_node was called for optimization without method provided, for kind %i\n", this->_kind); + exit(0); +} + +void MultsOpt::partial_map_node(nnode_t* node, short traverse_value, netlist_t* netlist, HardSoftLogicMixer* mixer) { + if (mixer->enabled(node) && mixer->hardenable(node)) { + mixer->note_candidate_node(node); + } else if (mixer->hardenable(node)) { + instantiate_hard_multiplier(node, traverse_value, netlist); + } else if (!hard_adders) { + instantiate_simple_soft_multiplier(node, traverse_value, netlist); + } + this->cached_traverse_value = traverse_value; +} + +void MultsOpt::instantiate_soft_logic(netlist_t* netlist, std::vector nodes) { + unsigned int size = nodes.size(); + for (unsigned int j = 0; j < size; j++) { + instantiate_simple_soft_multiplier(nodes[j], this->cached_traverse_value, netlist); + } + for (int i = size - 1; i >= 0; i--) { + nodes[i] = free_nnode(nodes[i]); + nodes.erase(nodes.begin() + i); + } +} diff --git a/ODIN_II/SRC/include/HardSoftLogicMixer.hpp b/ODIN_II/SRC/include/HardSoftLogicMixer.hpp new file mode 100644 index 00000000000..75683f32710 --- /dev/null +++ b/ODIN_II/SRC/include/HardSoftLogicMixer.hpp @@ -0,0 +1,96 @@ +/* + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef HARD_SOFT_LOGIC_MIXER_HPP +#define HARD_SOFT_LOGIC_MIXER_HPP + +#include "odin_types.h" // netlist_t, config_t +#include "MixingOptimization.hpp" + +class HardSoftLogicMixer { + public: + HardSoftLogicMixer(); + ~HardSoftLogicMixer(); + /*---------------------------------------------------------------------- + * Returns whether the specific node is a candidate for implementing + * in hard block + *--------------------------------------------------------------------- + */ + bool hardenable(nnode_t* node); + + /*---------------------------------------------------------------------- + * Function: map_deferred_blocksQueries if mixing optimization is enabled for this kind of + * of hard blocks + *--------------------------------------------------------------------- + */ + bool enabled(nnode_t* node); + + /*---------------------------------------------------------------------- + * Function: perform_optimizations + * For all noted nodes, that were noted as candidates to be implemented + * on the hard blocks, launches corresponding procedure of chosing the + * corresponding blocks + * Parameters: netlist_t * + *--------------------------------------------------------------------- + */ + void perform_optimizations(netlist_t* netlist); + + /*---------------------------------------------------------------------- + * Function: partial_map_node + * High-level call to provide support for partial mapping layer + * Parameters: + * node_t * : pointer to node needs to perform mapping + * netlist_t : pointer to netlist + *--------------------------------------------------------------------- + */ + void partial_map_node(nnode_t* node, short traverse_number, netlist_t*); + + /*---------------------------------------------------------------------- + * Function: note_candidate_node + * Calculates number of available hard blocks by issuing a call, + * traverses the netlist and statistics to figure out + * which operation should be implemented on the hard block + * Parameters: + * node_t * : pointer to candidate node + *--------------------------------------------------------------------- + */ + void note_candidate_node(nnode_t* node); + + // This is a container containing all optimization passes + MixingOpt* _opts[operation_list_END]; + + private: + /*---------------------------------------------------------------------- + * Function: hard_blocks_needed + * Returns cached value calculated from netlist, for a specific optimiza + * tion kind + *--------------------------------------------------------------------- + */ + int hard_blocks_needed(operation_list); + + // This array is composed of vectors, that store nodes that + // are potential candidates for performing mixing optimization + std::vector _nodes_by_opt[operation_list_END]; +}; + +#endif diff --git a/ODIN_II/SRC/include/MixingOptimization.hpp b/ODIN_II/SRC/include/MixingOptimization.hpp new file mode 100644 index 00000000000..47a6d4b985f --- /dev/null +++ b/ODIN_II/SRC/include/MixingOptimization.hpp @@ -0,0 +1,230 @@ +/* + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef MIXING_OPTIMIZATION_HPP +#define MIXING_OPTIMIZATION_HPP +#include "odin_types.h" // netlist_t, config_t + +class HardSoftLogicMixer; +/** + * @brief A base class in hierarchy for complex synthesis + * allowing for mixing soft and hard logic + */ +class MixingOpt { + public: + /** + * @brief Construct a new Mixing Opt object for disabled optimization + * usable for querying 'hardenable' condition + */ + MixingOpt() { _enabled = false; }; + + /** + * @brief Construct a new Mixing Opt object + * + * By default, all optimizations only share + * the ratio of blocks to be implemented in + * hard logic + * @param ratio, a value within 0 to 1 to + * implement ratio*requested hard blocks in + * hard logic + * @param kind a kind of blocks that correspond + * to optimization pass + */ + MixingOpt(float ratio, operation_list kind) + : _kind(kind) { + _ratio = ratio; + }; + + /** + * @brief Destroy the Mixing Opt object + * required by compiler + */ + virtual ~MixingOpt() = default; + + /** + * @brief assign weights to the candidate nodes vector, according to netlist_statistic + * + * @param nnode_t* pointer to the node + */ + virtual void assign_weights(netlist_t* netlist, std::vector nodes); + + /** + * @brief Checks if the optimization is enabled for this node + * + * @param nodes pointer to the vector with mults + */ + virtual bool enabled() { + return _enabled; + } + + /** + * @brief Instantiates an alternative (not on hard blocks) + * implementation for the operation + * + * @param netlist + * @param nodes + */ + virtual void instantiate_soft_logic(netlist_t* netlist, std::vector nodes); + + /** + * @brief performs the optimization pass, varies between kinds. + * If the implementation is not provided within the inherited class + * will throw ODIN error + * + * @param netlist_t* pointer to a global netlist + * @param std::vector a vector with nodes the optimization + * pass is concerned (all of which are potential candidates to + * be implemented in hard blocks for a given _kind) + */ + virtual void perform(netlist_t*, std::vector&); + + /** + * @brief Set the blocks of blocks required + * by counting in netlist + * + * @param count + */ + virtual void set_blocks_needed(int count); + + operation_list get_kind() { + return _kind; + } + + /** + * @brief based on criteria for hardening given kind of operation, return + * if the node should be implemented in hard blocks + * + * @param nnode_t* pointer to the node + */ + virtual bool hardenable(nnode_t*) { + return false; + } + + /** + * @brief allowing for replacing with dynamic polymorphism for different + * kinds of nodes + * + * @param nnode_t* pointer to the node + */ + virtual void partial_map_node(nnode_t*, short, netlist_t*, HardSoftLogicMixer*); + + protected: + /** + * @brief a routine that will multiply + * required blocks by the ratio + */ + virtual void scale_counts(); + + /** + * @brief this variable allows to cache traverse value + * + */ + short cached_traverse_value; + + // an integer representing the number of required hard blocks + // that should be estimated and updated through set blocks needed + int _blocks_count = -1; + // a boolean type to double check if the optimization is enabled + bool _enabled = false; + // a parameter allowing for scaling counts + float _ratio = -1.0; + // an enum kind variable, corresponding to an optimization pass + operation_list _kind = operation_list_END; +}; + +class MultsOpt : public MixingOpt { + public: + /** + * @brief Construct a new Mults Opt object for disabled optimization + * usable for querying 'hardenable' condition + */ + MultsOpt() + : MixingOpt(){}; + + /** + * @brief Construct a new Mults Opt object + * from ratio parameter + * @param ratio + */ + MultsOpt(float ratio); + /** + * @brief Construct a new Mults Opt object + * allowing to set exact number of multipliers + * that will be used + * @param exact + */ + MultsOpt(int exact); + + /** + * @brief assign weights to the candidate nodes vector, according to netlist_statistic + * + * @param nodes pointer to the vector with mults + */ + virtual void assign_weights(netlist_t* netlist, std::vector nodes); + + /** + * @brief allowing for replacing with dynamic polymorphism for different + * kinds of nodes + * + * @param nnode_t* pointer to the node + */ + virtual void partial_map_node(nnode_t*, short, netlist_t*, HardSoftLogicMixer*); + /** + * @brief Instantiates an alternative (not on hard blocks) + * implementation for the operation + * + * @param netlist + * @param nodes + */ + virtual void instantiate_soft_logic(netlist_t* netlist, std::vector nodes); + + /** + * @brief performs the optimization pass, specifically for multipliers. + * If the implementation is not provided within the inherited class + * will throw ODIN error + * + * @param netlist_t* pointer to a global netlist + * @param std::vector a vector with nodes the optimization + * pass is concerned (all of which are potential candidates to + * be implemented in hard blocks for a given _kind) + */ + virtual void perform(netlist_t* netlist, std::vector&); + + /** + * @brief Set the blocks of blocks required + * by counting in netlist. Has to be overriden, to account + * with specifics of optimization + * + * @param count + */ + virtual void set_blocks_needed(int); + + /** + * @brief based on criteria for hardening given kind of operation, return + * if the node should be implemented in hard blocks + * + * @param nnode_t* pointer to the node + */ + virtual bool hardenable(nnode_t*); +}; + +#endif diff --git a/ODIN_II/SRC/include/netlist_statistic.h b/ODIN_II/SRC/include/netlist_statistic.h index ff12c86edd7..eaffa84bebd 100644 --- a/ODIN_II/SRC/include/netlist_statistic.h +++ b/ODIN_II/SRC/include/netlist_statistic.h @@ -3,6 +3,9 @@ #include "netlist_utils.h" +static const unsigned int traversal_id = 0; +static const uintptr_t mult_optimization_traverse_value = (const uintptr_t)&traversal_id; + stat_t* get_stats(signal_list_t* input_signals, signal_list_t* output_signals, netlist_t* netlist, uintptr_t traverse_mark_number); stat_t* get_stats(nnode_t** node_list, long long node_count, netlist_t* netlist, uintptr_t traverse_mark_number); stat_t* get_stats(nnet_t** net_list, long long net_count, netlist_t* netlist, uintptr_t traverse_mark_number); @@ -14,4 +17,15 @@ stat_t* delete_stat(stat_t* stat); void init_stat(netlist_t* netlist); void compute_statistics(netlist_t* netlist, bool display); +/** + * @brief This function will calculate and assign weights related + * to mixing hard and soft logic implementation for certain kind + * of logic blocks + * @param node + * The node that needs its weight to be assigned + * @param netlist + * netlist, has to be passed to the counting functions + */ +void mixing_optimization_stats(nnode_t* node, netlist_t* netlist); + #endif // NETLIST_STATISTIC_HPP diff --git a/ODIN_II/SRC/include/odin_globals.h b/ODIN_II/SRC/include/odin_globals.h index e4ddccf55a3..26e8898428d 100644 --- a/ODIN_II/SRC/include/odin_globals.h +++ b/ODIN_II/SRC/include/odin_globals.h @@ -4,6 +4,7 @@ #include "odin_types.h" #include "string_cache.h" #include "read_xml_arch_file.h" +#include "HardSoftLogicMixer.hpp" extern t_logical_block_type* type_descriptors; @@ -46,4 +47,9 @@ extern netlist_t* blif_netlist; /* Global variable for read_blif function call */ extern netlist_t* read_blif_netlist; +/* logic optimization mixer, once ODIN is classy, could remove that + * and pass as member variable + */ +extern HardSoftLogicMixer* mixer; + #endif diff --git a/ODIN_II/SRC/include/odin_types.h b/ODIN_II/SRC/include/odin_types.h index ab9163ac929..4ce5880671c 100644 --- a/ODIN_II/SRC/include/odin_types.h +++ b/ODIN_II/SRC/include/odin_types.h @@ -141,6 +141,10 @@ struct global_args_t { argparse::ArgValue sim_random_seed; argparse::ArgValue interactive_simulation; + + // Arguments for mixing hard and soft logic + argparse::ArgValue exact_mults; + argparse::ArgValue mults_ratio; }; /** @@ -493,6 +497,12 @@ struct nnode_t { edge_type_e edge_type; // bool covered = false; + // For mixing soft and hard logic optimizations + // a field that is used for storing weights towards the + // mixing optimization. + // value of -1 is reserved for hardened blocks + long weight = 0; + //Generic gate output unsigned char generic_output; //describes the output (1 or 0) of generic blocks }; diff --git a/ODIN_II/SRC/netlist_statistic.cpp b/ODIN_II/SRC/netlist_statistic.cpp index 2491f59982e..d528e8e4c0d 100644 --- a/ODIN_II/SRC/netlist_statistic.cpp +++ b/ODIN_II/SRC/netlist_statistic.cpp @@ -69,6 +69,25 @@ void init_stat(netlist_t* netlist) { netlist->num_logic_element = 0; } +void mixing_optimization_stats(nnode_t* node, netlist_t* netlist) { + // Reinitialize statistics (to avoid interference) + init_stat(netlist); + // assuming the optimization is started from the node of the type that + // matches the node type + switch (node->type) { + case MULTIPLY: { + stat_t* multiply_stats = get_stats(node, netlist, mult_optimization_traverse_value); + node->weight = multiply_stats->downward.max_depth; + vtr::free(multiply_stats); + break; + } + default: + error_message(NETLIST, unknown_location, "%s", + "Counting weights for mixing optimization for %i: Hard block type is unimplemented", node->type); + break; + } +} + static void print_stats(metric_t* m) { printf("\n\t%s:%0.4lf\n\t%s: %0.4lf\n\t%s: %0.4lf\n\t%s: %0.4lf\n", "shortest path", m->min_depth, diff --git a/ODIN_II/SRC/odin_ii.cpp b/ODIN_II/SRC/odin_ii.cpp index a1409a1fcb0..a2033d9cbdd 100644 --- a/ODIN_II/SRC/odin_ii.cpp +++ b/ODIN_II/SRC/odin_ii.cpp @@ -61,6 +61,7 @@ #include "vtr_util.h" #include "vtr_path.h" #include "vtr_memory.h" +#include "HardSoftLogicMixer.hpp" #define DEFAULT_OUTPUT "." @@ -73,6 +74,7 @@ std::vector logical_block_types; short physical_lut_size = -1; int block_tag = -1; ids default_net_type = WIRE; +HardSoftLogicMixer* mixer; enum ODIN_ERROR_CODE { SUCCESS, @@ -165,6 +167,7 @@ static ODIN_ERROR_CODE synthesize_verilog() { /* point where we convert netlist to FPGA or other hardware target compatible format */ printf("Performing Partial Map to target device\n"); partial_map_top(verilog_netlist); + mixer->perform_optimizations(verilog_netlist); /* Find any unused logic in the netlist and remove it */ remove_unused_logic(verilog_netlist); @@ -217,7 +220,7 @@ netlist_t* start_odin_ii(int argc, char** argv) { printf("Odin failed to initialize %s with exit code%d\n", vtr_error.what(), ERROR_INITIALIZATION); exit(ERROR_INITIALIZATION); } - + mixer = new HardSoftLogicMixer(); try { /* Set up the global arguments to their default. */ set_default_config(); @@ -322,7 +325,7 @@ netlist_t* start_odin_ii(int argc, char** argv) { printf("\n"); printf("Odin ran with exit status: %d\n", SUCCESS); fflush(stdout); - + delete mixer; return odin_netlist; } @@ -548,6 +551,18 @@ void get_options(int argc, char** argv) { .nargs('+') .metavar("PINS_TO_MONITOR"); + auto& mixing_opt_grp = parser.add_argument_group("mixing hard and soft logic optimization"); + + mixing_opt_grp.add_argument(global_args.exact_mults, "--exact_mults") + .help("To enable mixing hard block and soft logic implementation of adders") + .default_value("-1") + .action(argparse::Action::STORE); + + mixing_opt_grp.add_argument(global_args.mults_ratio, "--mults_ratio") + .help("To enable mixing hard block and soft logic implementation of adders") + .default_value("-1.0") + .action(argparse::Action::STORE); + parser.parse_args(argc, argv); //Check required options @@ -607,6 +622,13 @@ void get_options(int argc, char** argv) { if (global_args.permissive.value()) { warning_message(PARSE_ARGS, unknown_location, "%s", "Permissive flag is ON. Undefined behaviour may occur\n"); } + if (global_args.mults_ratio >= 0.0 && global_args.mults_ratio <= 1.0) { + delete mixer->_opts[MULTIPLY]; + mixer->_opts[MULTIPLY] = new MultsOpt(global_args.mults_ratio); + } else if (global_args.exact_mults >= 0) { + delete mixer->_opts[MULTIPLY]; + mixer->_opts[MULTIPLY] = new MultsOpt(global_args.exact_mults); + } } /*--------------------------------------------------------------------------- diff --git a/ODIN_II/SRC/partial_map.cpp b/ODIN_II/SRC/partial_map.cpp index d3441a6941f..25697f0b189 100644 --- a/ODIN_II/SRC/partial_map.cpp +++ b/ODIN_II/SRC/partial_map.cpp @@ -221,12 +221,7 @@ void partial_map_node(nnode_t* node, short traverse_number, netlist_t* netlist) instantiate_multi_port_mux(node, traverse_number, netlist); break; case MULTIPLY: { - int mult_size = std::max(node->input_port_sizes[0], node->input_port_sizes[1]); - if (hard_multipliers && mult_size >= min_mult) { - instantiate_hard_multiplier(node, traverse_number, netlist); - } else if (!hard_adders) { - instantiate_simple_soft_multiplier(node, traverse_number, netlist); - } + mixer->partial_map_node(node, traverse_number, netlist); break; } case MEMORY: { diff --git a/ODIN_II/SRC/simulate_blif.cpp b/ODIN_II/SRC/simulate_blif.cpp index 2edc4443a75..9246185bafd 100644 --- a/ODIN_II/SRC/simulate_blif.cpp +++ b/ODIN_II/SRC/simulate_blif.cpp @@ -2021,7 +2021,11 @@ static int verify_test_vector_headers(FILE* in, lines_t* l) { return false; } else if (next == ' ' || next == '\t' || next == '\n') { if (buffer_length) { - if (strcmp(l->lines[current_line]->name, buffer)) { + if (current_line > l->count) { + warning_message(SIMULATION, unknown_location, + "%s\n", + "Vector header mismatch: the number of header is shorter than in your vector file!\n"); + } else if (strcmp(l->lines[current_line]->name, buffer)) { char* expected_header = generate_vector_header(l); warning_message(SIMULATION, unknown_location, "Vector header mismatch: \n " diff --git a/ODIN_II/regression_test/benchmark/suite/complex_synthesis_suite/task_list.conf b/ODIN_II/regression_test/benchmark/suite/complex_synthesis_suite/task_list.conf new file mode 100644 index 00000000000..e868896da91 --- /dev/null +++ b/ODIN_II/regression_test/benchmark/suite/complex_synthesis_suite/task_list.conf @@ -0,0 +1 @@ +regression_test/benchmark/task/mixing_optimization/* diff --git a/ODIN_II/regression_test/benchmark/suite/light_suite/task_list.conf b/ODIN_II/regression_test/benchmark/suite/light_suite/task_list.conf index f1fb6987ca1..405d3debd62 100644 --- a/ODIN_II/regression_test/benchmark/suite/light_suite/task_list.conf +++ b/ODIN_II/regression_test/benchmark/suite/light_suite/task_list.conf @@ -8,3 +8,4 @@ regression_test/benchmark/task/keywords/* regression_test/benchmark/task/syntax regression_test/benchmark/task/FIR regression_test/benchmark/task/micro +regression_test/benchmark/suite/complex_synthesis_suite diff --git a/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_full/simulation_result.json b/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_full/simulation_result.json new file mode 100644 index 00000000000..2a0fc35c7f6 --- /dev/null +++ b/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_full/simulation_result.json @@ -0,0 +1,325 @@ +{ + "mults_auto_full/bm_base_multiply/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_full/bm_base_multiply/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "bm_base_multiply.blif", + "max_rss(MiB)": 101, + "exec_time(ms)": 765.4, + "simulation_time(ms)": 631.6, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 47, + "Po": 78, + "logic element": 110, + "latch": 71, + "Multiplier": 3, + "generic logic size": 4, + "Longest Path": 9, + "Average Path": 4, + "Estimated LUTs": 110, + "Total Node": 185 + }, + "mults_auto_full/bm_base_multiply/k6_N10_40nm": { + "test_name": "mults_auto_full/bm_base_multiply/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "blif": "bm_base_multiply.blif", + "max_rss(MiB)": 144.3, + "exec_time(ms)": 1509.8, + "simulation_time(ms)": 1445.6, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 47, + "Po": 78, + "logic element": 795, + "latch": 71, + "generic logic size": 6, + "Longest Path": 26, + "Average Path": 6, + "Estimated LUTs": 795, + "Total Node": 867 + }, + "mults_auto_full/bm_match1_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_full/bm_match1_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "bm_match1_str_arch.blif", + "max_rss(MiB)": 127.2, + "exec_time(ms)": 850.2, + "simulation_time(ms)": 707.2, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 88, + "Po": 144, + "logic element": 144, + "latch": 72, + "Multiplier": 3, + "generic logic size": 4, + "Longest Path": 5, + "Average Path": 4, + "Estimated LUTs": 144, + "Total Node": 220 + }, + "mults_auto_full/bm_match1_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_full/bm_match1_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "blif": "bm_match1_str_arch.blif", + "max_rss(MiB)": 612.9, + "exec_time(ms)": 4095.3, + "simulation_time(ms)": 3860.4, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 88, + "Po": 144, + "logic element": 3872, + "latch": 72, + "generic logic size": 6, + "Longest Path": 74, + "Average Path": 6, + "Estimated LUTs": 3872, + "Total Node": 3945 + }, + "mults_auto_full/bm_match2_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_full/bm_match2_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "bm_match2_str_arch.blif", + "max_rss(MiB)": 154.5, + "exec_time(ms)": 1403.8, + "simulation_time(ms)": 1067.9, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 54, + "Po": 99, + "logic element": 99, + "latch": 54, + "Adder": 173, + "Multiplier": 4, + "generic logic size": 4, + "Longest Path": 25, + "Average Path": 5, + "Estimated LUTs": 99, + "Total Node": 331 + }, + "mults_auto_full/bm_match2_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_full/bm_match2_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "blif": "bm_match2_str_arch.blif", + "max_rss(MiB)": 489.8, + "exec_time(ms)": 3560, + "simulation_time(ms)": 3281.9, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 54, + "Po": 99, + "logic element": 3211, + "latch": 54, + "generic logic size": 6, + "Longest Path": 32, + "Average Path": 7, + "Estimated LUTs": 3211, + "Total Node": 3266 + }, + "mults_auto_full/bm_match3_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_full/bm_match3_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "bm_match3_str_arch.blif", + "max_rss(MiB)": 97.8, + "exec_time(ms)": 542, + "simulation_time(ms)": 407.2, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 54, + "Po": 54, + "logic element": 54, + "latch": 54, + "Adder": 50, + "Multiplier": 1, + "generic logic size": 4, + "Longest Path": 24, + "Average Path": 5, + "Estimated LUTs": 54, + "Total Node": 160 + }, + "mults_auto_full/bm_match3_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_full/bm_match3_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "blif": "bm_match3_str_arch.blif", + "max_rss(MiB)": 90.9, + "exec_time(ms)": 771.6, + "simulation_time(ms)": 721.5, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 54, + "Po": 54, + "logic element": 375, + "latch": 54, + "generic logic size": 6, + "Longest Path": 58, + "Average Path": 5, + "Estimated LUTs": 375, + "Total Node": 430 + }, + "mults_auto_full/bm_match4_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_full/bm_match4_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "bm_match4_str_arch.blif", + "max_rss(MiB)": 155.5, + "exec_time(ms)": 1251.4, + "simulation_time(ms)": 1048.9, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 51, + "Po": 216, + "logic element": 216, + "latch": 108, + "Adder": 74, + "Multiplier": 3, + "generic logic size": 4, + "Longest Path": 42, + "Average Path": 4, + "Estimated LUTs": 216, + "Total Node": 402 + }, + "mults_auto_full/bm_match4_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_full/bm_match4_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "blif": "bm_match4_str_arch.blif", + "max_rss(MiB)": 238.5, + "exec_time(ms)": 2038.8, + "simulation_time(ms)": 1925.5, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 51, + "Po": 216, + "logic element": 1367, + "latch": 108, + "generic logic size": 6, + "Longest Path": 49, + "Average Path": 5, + "Estimated LUTs": 1367, + "Total Node": 1476 + }, + "mults_auto_full/bm_match5_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_full/bm_match5_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "bm_match5_str_arch.blif", + "max_rss(MiB)": 140.9, + "exec_time(ms)": 971.6, + "simulation_time(ms)": 800.3, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 90, + "Po": 54, + "logic element": 54, + "latch": 54, + "Adder": 125, + "Multiplier": 6, + "generic logic size": 4, + "Longest Path": 27, + "Average Path": 5, + "Estimated LUTs": 54, + "Total Node": 240 + }, + "mults_auto_full/bm_match5_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_full/bm_match5_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "blif": "bm_match5_str_arch.blif", + "max_rss(MiB)": 319.7, + "exec_time(ms)": 2530.9, + "simulation_time(ms)": 2400.5, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 90, + "Po": 54, + "logic element": 2147, + "latch": 54, + "generic logic size": 6, + "Longest Path": 34, + "Average Path": 6, + "Estimated LUTs": 2147, + "Total Node": 2202 + }, + "mults_auto_full/multiply_hard_block/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_full/multiply_hard_block/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "multiply_hard_block.blif", + "max_rss(MiB)": 59.9, + "exec_time(ms)": 100.9, + "simulation_time(ms)": 14.1, + "test_coverage(%)": 100, + "Pi": 8, + "Po": 8, + "logic element": 8, + "Multiplier": 2, + "generic logic size": 4, + "Longest Path": 4, + "Average Path": 4, + "Estimated LUTs": 8, + "Total Node": 10 + }, + "mults_auto_full/twobits_arithmetic_multiply/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_full/twobits_arithmetic_multiply/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "twobits_arithmetic_multiply.blif", + "max_rss(MiB)": 57.5, + "exec_time(ms)": 91.5, + "simulation_time(ms)": 5.4, + "test_coverage(%)": 90.6, + "Latch Drivers": 1, + "Pi": 5, + "Po": 5, + "logic element": 12, + "latch": 4, + "Multiplier": 1, + "generic logic size": 4, + "Longest Path": 8, + "Average Path": 5, + "Estimated LUTs": 12, + "Total Node": 18 + }, + "mults_auto_full/twobits_arithmetic_multiply/k6_N10_40nm": { + "test_name": "mults_auto_full/twobits_arithmetic_multiply/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "blif": "twobits_arithmetic_multiply.blif", + "max_rss(MiB)": 38.2, + "exec_time(ms)": 19.1, + "simulation_time(ms)": 7.1, + "test_coverage(%)": 92.5, + "Latch Drivers": 1, + "Pi": 5, + "Po": 5, + "logic element": 21, + "latch": 4, + "generic logic size": 6, + "Longest Path": 9, + "Average Path": 5, + "Estimated LUTs": 21, + "Total Node": 26 + }, + "DEFAULT": { + "test_name": "n/a", + "architecture": "n/a", + "blif": "n/a", + "exit": 0, + "leaks": 0, + "errors": [], + "warnings": [], + "expectation": [], + "max_rss(MiB)": -1, + "exec_time(ms)": -1, + "simulation_time(ms)": -1, + "test_coverage(%)": -1, + "Latch Drivers": 0, + "Pi": 0, + "Po": 0, + "logic element": 0, + "latch": 0, + "Adder": -1, + "Multiplier": -1, + "Memory": -1, + "Hard Ip": -1, + "generic logic size": -1, + "Longest Path": 0, + "Average Path": 0, + "Estimated LUTs": 0, + "Total Node": 0 + } +} diff --git a/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_full/synthesis_result.json b/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_full/synthesis_result.json new file mode 100644 index 00000000000..3065933f70d --- /dev/null +++ b/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_full/synthesis_result.json @@ -0,0 +1,321 @@ +{ + "mults_auto_full/bm_base_multiply/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_full/bm_base_multiply/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "bm_base_multiply.v", + "max_rss(MiB)": 60.2, + "exec_time(ms)": 91.2, + "synthesis_time(ms)": 15.7, + "Latch Drivers": 1, + "Pi": 47, + "Po": 78, + "logic element": 32, + "latch": 71, + "Adder": 0, + "Multiplier": 3, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 8, + "Average Path": 3, + "Estimated LUTs": 32, + "Total Node": 107 + }, + "mults_auto_full/bm_base_multiply/k6_N10_40nm": { + "test_name": "mults_auto_full/bm_base_multiply/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "bm_base_multiply.v", + "max_rss(MiB)": 45.3, + "exec_time(ms)": 32.1, + "synthesis_time(ms)": 23.8, + "Latch Drivers": 1, + "Pi": 47, + "Po": 78, + "logic element": 717, + "latch": 71, + "generic logic size": 6, + "Longest Path": 25, + "Average Path": 5, + "Estimated LUTs": 717, + "Total Node": 789 + }, + "mults_auto_full/bm_match1_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_full/bm_match1_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "bm_match1_str_arch.v", + "max_rss(MiB)": 58.9, + "exec_time(ms)": 88, + "synthesis_time(ms)": 11.1, + "Latch Drivers": 1, + "Pi": 88, + "Po": 144, + "latch": 72, + "Adder": 0, + "Multiplier": 3, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 4, + "Average Path": 3, + "Total Node": 76 + }, + "mults_auto_full/bm_match1_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_full/bm_match1_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "bm_match1_str_arch.v", + "max_rss(MiB)": 57.8, + "exec_time(ms)": 85.4, + "synthesis_time(ms)": 77, + "Latch Drivers": 1, + "Pi": 88, + "Po": 144, + "logic element": 3728, + "latch": 72, + "generic logic size": 6, + "Longest Path": 73, + "Average Path": 5, + "Estimated LUTs": 3728, + "Total Node": 3801 + }, + "mults_auto_full/bm_match2_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_full/bm_match2_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "bm_match2_str_arch.v", + "max_rss(MiB)": 59.9, + "exec_time(ms)": 97.5, + "synthesis_time(ms)": 17.8, + "Latch Drivers": 1, + "Pi": 54, + "Po": 99, + "latch": 54, + "Adder": 173, + "Multiplier": 4, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 24, + "Average Path": 4, + "Total Node": 232 + }, + "mults_auto_full/bm_match2_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_full/bm_match2_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "bm_match2_str_arch.v", + "max_rss(MiB)": 53.6, + "exec_time(ms)": 69, + "synthesis_time(ms)": 60.6, + "Latch Drivers": 1, + "Pi": 54, + "Po": 99, + "logic element": 3112, + "latch": 54, + "generic logic size": 6, + "Longest Path": 31, + "Average Path": 6, + "Estimated LUTs": 3112, + "Total Node": 3167 + }, + "mults_auto_full/bm_match3_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_full/bm_match3_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "bm_match3_str_arch.v", + "max_rss(MiB)": 58.3, + "exec_time(ms)": 111.9, + "synthesis_time(ms)": 9.1, + "Latch Drivers": 1, + "Pi": 54, + "Po": 54, + "latch": 54, + "Adder": 50, + "Multiplier": 1, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 23, + "Average Path": 4, + "Total Node": 106 + }, + "mults_auto_full/bm_match3_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_full/bm_match3_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "bm_match3_str_arch.v", + "max_rss(MiB)": 41.7, + "exec_time(ms)": 21.1, + "synthesis_time(ms)": 12.7, + "Latch Drivers": 1, + "Pi": 54, + "Po": 54, + "logic element": 321, + "latch": 54, + "generic logic size": 6, + "Longest Path": 57, + "Average Path": 4, + "Estimated LUTs": 321, + "Total Node": 376 + }, + "mults_auto_full/bm_match4_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_full/bm_match4_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "bm_match4_str_arch.v", + "max_rss(MiB)": 60.8, + "exec_time(ms)": 130.9, + "synthesis_time(ms)": 19, + "Latch Drivers": 1, + "Pi": 51, + "Po": 216, + "latch": 108, + "Adder": 74, + "Multiplier": 3, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 41, + "Average Path": 3, + "Total Node": 186 + }, + "mults_auto_full/bm_match4_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_full/bm_match4_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "bm_match4_str_arch.v", + "max_rss(MiB)": 47.7, + "exec_time(ms)": 41.1, + "synthesis_time(ms)": 32.7, + "Latch Drivers": 1, + "Pi": 51, + "Po": 216, + "logic element": 1151, + "latch": 108, + "generic logic size": 6, + "Longest Path": 48, + "Average Path": 4, + "Estimated LUTs": 1151, + "Total Node": 1260 + }, + "mults_auto_full/bm_match5_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_full/bm_match5_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "bm_match5_str_arch.v", + "max_rss(MiB)": 59.1, + "exec_time(ms)": 89.4, + "synthesis_time(ms)": 12.6, + "Latch Drivers": 1, + "Pi": 90, + "Po": 54, + "latch": 54, + "Adder": 125, + "Multiplier": 6, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 26, + "Average Path": 4, + "Total Node": 186 + }, + "mults_auto_full/bm_match5_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_full/bm_match5_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "bm_match5_str_arch.v", + "max_rss(MiB)": 48.9, + "exec_time(ms)": 47.1, + "synthesis_time(ms)": 38.7, + "Latch Drivers": 1, + "Pi": 90, + "Po": 54, + "logic element": 2093, + "latch": 54, + "generic logic size": 6, + "Longest Path": 33, + "Average Path": 5, + "Estimated LUTs": 2093, + "Total Node": 2148 + }, + "mults_auto_full/multiply_hard_block/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_full/multiply_hard_block/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "multiply_hard_block.v", + "warnings": [ + "multiply_hard_block.v:9:2 [AST] Attempting to convert this instance to a hard block (multiply) - unnamed port connections will be matched according to hard block specification and may produce unexpected results" + ], + "max_rss(MiB)": 56, + "exec_time(ms)": 70.8, + "synthesis_time(ms)": 2.3, + "Pi": 8, + "Po": 8, + "Adder": 0, + "Multiplier": 2, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 3, + "Average Path": 3, + "Total Node": 2 + }, + "mults_auto_full/multiply_hard_block/k6_N10_40nm": { + "test_name": "mults_auto_full/multiply_hard_block/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "multiply_hard_block.v", + "exit": 134, + "errors": [ + "multiply_hard_block.v:8:1 [AST] Can't find module name multiply" + ] + }, + "mults_auto_full/twobits_arithmetic_multiply/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_full/twobits_arithmetic_multiply/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "twobits_arithmetic_multiply.v", + "max_rss(MiB)": 55.7, + "exec_time(ms)": 76.7, + "synthesis_time(ms)": 1.8, + "Latch Drivers": 1, + "Pi": 5, + "Po": 5, + "logic element": 7, + "latch": 4, + "Adder": 0, + "Multiplier": 1, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 7, + "Average Path": 4, + "Estimated LUTs": 7, + "Total Node": 13 + }, + "mults_auto_full/twobits_arithmetic_multiply/k6_N10_40nm": { + "test_name": "mults_auto_full/twobits_arithmetic_multiply/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "twobits_arithmetic_multiply.v", + "max_rss(MiB)": 39, + "exec_time(ms)": 7.7, + "synthesis_time(ms)": 1.9, + "Latch Drivers": 1, + "Pi": 5, + "Po": 5, + "logic element": 16, + "latch": 4, + "generic logic size": 6, + "Longest Path": 8, + "Average Path": 4, + "Estimated LUTs": 16, + "Total Node": 21 + }, + "DEFAULT": { + "test_name": "n/a", + "architecture": "n/a", + "verilog": "n/a", + "exit": 0, + "leaks": 0, + "errors": [], + "warnings": [], + "expectation": [], + "max_rss(MiB)": -1, + "exec_time(ms)": -1, + "synthesis_time(ms)": -1, + "Latch Drivers": 0, + "Pi": 0, + "Po": 0, + "logic element": 0, + "latch": 0, + "Adder": -1, + "Multiplier": -1, + "Memory": -1, + "Hard Ip": -1, + "generic logic size": -1, + "Longest Path": 0, + "Average Path": 0, + "Estimated LUTs": 0, + "Total Node": 0 + } +} diff --git a/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_full/task.conf b/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_full/task.conf new file mode 100644 index 00000000000..f1f33cfe22a --- /dev/null +++ b/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_full/task.conf @@ -0,0 +1,32 @@ +############################################## +# Configuration file for running experiments +############################################## +# Path to directory of circuits to use +# setup the architecture +archs_dir=../vtr_flow/arch/timing + +# hard adder and frac mul +arch_list_add=k6_frac_N10_frac_chain_mem32K_40nm.xml +# frac mul +arch_list_add=k6_frac_N10_mem32k_40nm.xml +# mul +arch_list_add=k6_N10_mem32k_40nm.xml +# no hard block +arch_list_add=k6_N10_40nm.xml + +# setup the circuits +circuits_dir=regression_test/benchmark/verilog + +# unit test +circuit_list_add=operators/twobits_arithmetic_multiply.v +# simple wide multiplication +circuit_list_add=micro/bm_base_multiply.v +# harblock mul +circuit_list_add=micro/multiply_hard_block.v +# complex mutliplication +circuit_list_add=micro/bm_match[012345]_str_arch.v + +synthesis_params= --mults_ratio 1.0 + +synthesis_parse_file=regression_test/parse_result/conf/synth.toml +simulation_parse_file=regression_test/parse_result/conf/sim.toml diff --git a/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_half/simulation_result.json b/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_half/simulation_result.json new file mode 100644 index 00000000000..18a5f6cc018 --- /dev/null +++ b/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_half/simulation_result.json @@ -0,0 +1,323 @@ +{ + "mults_auto_half/bm_base_multiply/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_half/bm_base_multiply/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "bm_base_multiply.blif", + "max_rss(MiB)": 131.5, + "exec_time(ms)": 1187.5, + "simulation_time(ms)": 1051.4, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 47, + "Po": 78, + "logic element": 454, + "latch": 71, + "Multiplier": 1, + "generic logic size": 4, + "Longest Path": 25, + "Average Path": 5, + "Estimated LUTs": 454, + "Total Node": 527 + }, + "mults_auto_half/bm_base_multiply/k6_N10_40nm": { + "test_name": "mults_auto_half/bm_base_multiply/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "blif": "bm_base_multiply.blif", + "max_rss(MiB)": 144.6, + "exec_time(ms)": 2065.9, + "simulation_time(ms)": 1986.3, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 47, + "Po": 78, + "logic element": 795, + "latch": 71, + "generic logic size": 6, + "Longest Path": 26, + "Average Path": 6, + "Estimated LUTs": 795, + "Total Node": 867 + }, + "mults_auto_half/bm_match1_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_half/bm_match1_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "bm_match1_str_arch.blif", + "max_rss(MiB)": 309.5, + "exec_time(ms)": 2995.4, + "simulation_time(ms)": 2725.4, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 88, + "Po": 144, + "logic element": 1775, + "latch": 72, + "Multiplier": 1, + "generic logic size": 4, + "Longest Path": 74, + "Average Path": 5, + "Estimated LUTs": 1775, + "Total Node": 1849 + }, + "mults_auto_half/bm_match1_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_half/bm_match1_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "blif": "bm_match1_str_arch.blif", + "max_rss(MiB)": 612.7, + "exec_time(ms)": 4697.8, + "simulation_time(ms)": 4462.7, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 88, + "Po": 144, + "logic element": 3872, + "latch": 72, + "generic logic size": 6, + "Longest Path": 74, + "Average Path": 6, + "Estimated LUTs": 3872, + "Total Node": 3945 + }, + "mults_auto_half/bm_match2_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_half/bm_match2_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "bm_match2_str_arch.blif", + "max_rss(MiB)": 199.6, + "exec_time(ms)": 2072, + "simulation_time(ms)": 1833.1, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 54, + "Po": 99, + "logic element": 565, + "latch": 54, + "Adder": 173, + "Multiplier": 2, + "generic logic size": 4, + "Longest Path": 31, + "Average Path": 6, + "Estimated LUTs": 565, + "Total Node": 795 + }, + "mults_auto_half/bm_match2_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_half/bm_match2_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "blif": "bm_match2_str_arch.blif", + "max_rss(MiB)": 489.8, + "exec_time(ms)": 3950.4, + "simulation_time(ms)": 3753.8, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 54, + "Po": 99, + "logic element": 3211, + "latch": 54, + "generic logic size": 6, + "Longest Path": 32, + "Average Path": 7, + "Estimated LUTs": 3211, + "Total Node": 3266 + }, + "mults_auto_half/bm_match3_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_half/bm_match3_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "bm_match3_str_arch.blif", + "max_rss(MiB)": 119.2, + "exec_time(ms)": 1043.6, + "simulation_time(ms)": 825.4, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 54, + "Po": 54, + "logic element": 287, + "latch": 54, + "Adder": 50, + "generic logic size": 4, + "Longest Path": 31, + "Average Path": 5, + "Estimated LUTs": 287, + "Total Node": 392 + }, + "mults_auto_half/bm_match3_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_half/bm_match3_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "blif": "bm_match3_str_arch.blif", + "max_rss(MiB)": 91.3, + "exec_time(ms)": 833.6, + "simulation_time(ms)": 777.4, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 54, + "Po": 54, + "logic element": 375, + "latch": 54, + "generic logic size": 6, + "Longest Path": 58, + "Average Path": 5, + "Estimated LUTs": 375, + "Total Node": 430 + }, + "mults_auto_half/bm_match4_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_half/bm_match4_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "bm_match4_str_arch.blif", + "max_rss(MiB)": 192.9, + "exec_time(ms)": 2030.2, + "simulation_time(ms)": 1830.6, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 51, + "Po": 216, + "logic element": 604, + "latch": 108, + "Adder": 74, + "Multiplier": 1, + "generic logic size": 4, + "Longest Path": 48, + "Average Path": 5, + "Estimated LUTs": 604, + "Total Node": 788 + }, + "mults_auto_half/bm_match4_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_half/bm_match4_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "blif": "bm_match4_str_arch.blif", + "max_rss(MiB)": 238.4, + "exec_time(ms)": 2740.3, + "simulation_time(ms)": 2620.9, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 51, + "Po": 216, + "logic element": 1367, + "latch": 108, + "generic logic size": 6, + "Longest Path": 49, + "Average Path": 5, + "Estimated LUTs": 1367, + "Total Node": 1476 + }, + "mults_auto_half/bm_match5_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_half/bm_match5_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "bm_match5_str_arch.blif", + "max_rss(MiB)": 209.4, + "exec_time(ms)": 2198.2, + "simulation_time(ms)": 1997.2, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 90, + "Po": 54, + "logic element": 753, + "latch": 54, + "Adder": 125, + "Multiplier": 3, + "generic logic size": 4, + "Longest Path": 32, + "Average Path": 5, + "Estimated LUTs": 753, + "Total Node": 936 + }, + "mults_auto_half/bm_match5_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_half/bm_match5_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "blif": "bm_match5_str_arch.blif", + "max_rss(MiB)": 319.7, + "exec_time(ms)": 3413.6, + "simulation_time(ms)": 3220.1, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 90, + "Po": 54, + "logic element": 2147, + "latch": 54, + "generic logic size": 6, + "Longest Path": 34, + "Average Path": 6, + "Estimated LUTs": 2147, + "Total Node": 2202 + }, + "mults_auto_half/multiply_hard_block/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_half/multiply_hard_block/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "multiply_hard_block.blif", + "max_rss(MiB)": 59.9, + "exec_time(ms)": 118.1, + "simulation_time(ms)": 17.4, + "test_coverage(%)": 100, + "Pi": 8, + "Po": 8, + "logic element": 17, + "Multiplier": 1, + "generic logic size": 4, + "Longest Path": 7, + "Average Path": 4, + "Estimated LUTs": 17, + "Total Node": 18 + }, + "mults_auto_half/twobits_arithmetic_multiply/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_half/twobits_arithmetic_multiply/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "twobits_arithmetic_multiply.blif", + "max_rss(MiB)": 55.1, + "exec_time(ms)": 101.8, + "simulation_time(ms)": 5.6, + "test_coverage(%)": 92.5, + "Latch Drivers": 1, + "Pi": 5, + "Po": 5, + "logic element": 21, + "latch": 4, + "generic logic size": 4, + "Longest Path": 9, + "Average Path": 5, + "Estimated LUTs": 21, + "Total Node": 26 + }, + "mults_auto_half/twobits_arithmetic_multiply/k6_N10_40nm": { + "test_name": "mults_auto_half/twobits_arithmetic_multiply/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "blif": "twobits_arithmetic_multiply.blif", + "max_rss(MiB)": 37.9, + "exec_time(ms)": 19.4, + "simulation_time(ms)": 5.7, + "test_coverage(%)": 92.5, + "Latch Drivers": 1, + "Pi": 5, + "Po": 5, + "logic element": 21, + "latch": 4, + "generic logic size": 6, + "Longest Path": 9, + "Average Path": 5, + "Estimated LUTs": 21, + "Total Node": 26 + }, + "DEFAULT": { + "test_name": "n/a", + "architecture": "n/a", + "blif": "n/a", + "exit": 0, + "leaks": 0, + "errors": [], + "warnings": [], + "expectation": [], + "max_rss(MiB)": -1, + "exec_time(ms)": -1, + "simulation_time(ms)": -1, + "test_coverage(%)": -1, + "Latch Drivers": 0, + "Pi": 0, + "Po": 0, + "logic element": 0, + "latch": 0, + "Adder": -1, + "Multiplier": -1, + "Memory": -1, + "Hard Ip": -1, + "generic logic size": -1, + "Longest Path": 0, + "Average Path": 0, + "Estimated LUTs": 0, + "Total Node": 0 + } +} diff --git a/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_half/synthesis_result.json b/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_half/synthesis_result.json new file mode 100644 index 00000000000..1f634d8b12e --- /dev/null +++ b/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_half/synthesis_result.json @@ -0,0 +1,333 @@ +{ + "mults_auto_half/bm_base_multiply/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_half/bm_base_multiply/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "bm_base_multiply.v", + "max_rss(MiB)": 61.3, + "exec_time(ms)": 110.6, + "synthesis_time(ms)": 30.9, + "Latch Drivers": 1, + "Pi": 47, + "Po": 78, + "logic element": 376, + "latch": 71, + "Adder": 0, + "Multiplier": 1, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 24, + "Average Path": 4, + "Estimated LUTs": 376, + "Total Node": 449 + }, + "mults_auto_half/bm_base_multiply/k6_N10_40nm": { + "test_name": "mults_auto_half/bm_base_multiply/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "bm_base_multiply.v", + "max_rss(MiB)": 45.5, + "exec_time(ms)": 33, + "synthesis_time(ms)": 24.4, + "Latch Drivers": 1, + "Pi": 47, + "Po": 78, + "logic element": 717, + "latch": 71, + "generic logic size": 6, + "Longest Path": 25, + "Average Path": 5, + "Estimated LUTs": 717, + "Total Node": 789 + }, + "mults_auto_half/bm_match1_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_half/bm_match1_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "bm_match1_str_arch.v", + "max_rss(MiB)": 65.7, + "exec_time(ms)": 113.5, + "synthesis_time(ms)": 35.3, + "Latch Drivers": 1, + "Pi": 88, + "Po": 144, + "logic element": 1631, + "latch": 72, + "Adder": 0, + "Multiplier": 1, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 73, + "Average Path": 4, + "Estimated LUTs": 1631, + "Total Node": 1705 + }, + "mults_auto_half/bm_match1_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_half/bm_match1_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "bm_match1_str_arch.v", + "max_rss(MiB)": 57.9, + "exec_time(ms)": 85.5, + "synthesis_time(ms)": 76.8, + "Latch Drivers": 1, + "Pi": 88, + "Po": 144, + "logic element": 3728, + "latch": 72, + "generic logic size": 6, + "Longest Path": 73, + "Average Path": 5, + "Estimated LUTs": 3728, + "Total Node": 3801 + }, + "mults_auto_half/bm_match2_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_half/bm_match2_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "bm_match2_str_arch.v", + "max_rss(MiB)": 61.4, + "exec_time(ms)": 104.1, + "synthesis_time(ms)": 18.1, + "Latch Drivers": 1, + "Pi": 54, + "Po": 99, + "logic element": 466, + "latch": 54, + "Adder": 173, + "Multiplier": 2, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 30, + "Average Path": 5, + "Estimated LUTs": 466, + "Total Node": 696 + }, + "mults_auto_half/bm_match2_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_half/bm_match2_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "bm_match2_str_arch.v", + "max_rss(MiB)": 53.3, + "exec_time(ms)": 71.2, + "synthesis_time(ms)": 62.3, + "Latch Drivers": 1, + "Pi": 54, + "Po": 99, + "logic element": 3112, + "latch": 54, + "generic logic size": 6, + "Longest Path": 31, + "Average Path": 6, + "Estimated LUTs": 3112, + "Total Node": 3167 + }, + "mults_auto_half/bm_match3_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_half/bm_match3_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "bm_match3_str_arch.v", + "max_rss(MiB)": 59.3, + "exec_time(ms)": 87.1, + "synthesis_time(ms)": 10, + "Latch Drivers": 1, + "Pi": 54, + "Po": 54, + "logic element": 233, + "latch": 54, + "Adder": 50, + "Multiplier": 0, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 30, + "Average Path": 4, + "Estimated LUTs": 233, + "Total Node": 338 + }, + "mults_auto_half/bm_match3_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_half/bm_match3_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "bm_match3_str_arch.v", + "max_rss(MiB)": 41.8, + "exec_time(ms)": 21, + "synthesis_time(ms)": 12.7, + "Latch Drivers": 1, + "Pi": 54, + "Po": 54, + "logic element": 321, + "latch": 54, + "generic logic size": 6, + "Longest Path": 57, + "Average Path": 4, + "Estimated LUTs": 321, + "Total Node": 376 + }, + "mults_auto_half/bm_match4_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_half/bm_match4_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "bm_match4_str_arch.v", + "max_rss(MiB)": 62.2, + "exec_time(ms)": 111.1, + "synthesis_time(ms)": 23.6, + "Latch Drivers": 1, + "Pi": 51, + "Po": 216, + "logic element": 388, + "latch": 108, + "Adder": 74, + "Multiplier": 1, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 47, + "Average Path": 4, + "Estimated LUTs": 388, + "Total Node": 572 + }, + "mults_auto_half/bm_match4_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_half/bm_match4_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "bm_match4_str_arch.v", + "max_rss(MiB)": 47.6, + "exec_time(ms)": 42.2, + "synthesis_time(ms)": 34, + "Latch Drivers": 1, + "Pi": 51, + "Po": 216, + "logic element": 1151, + "latch": 108, + "generic logic size": 6, + "Longest Path": 48, + "Average Path": 4, + "Estimated LUTs": 1151, + "Total Node": 1260 + }, + "mults_auto_half/bm_match5_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_half/bm_match5_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "bm_match5_str_arch.v", + "max_rss(MiB)": 61.6, + "exec_time(ms)": 103, + "synthesis_time(ms)": 22.6, + "Latch Drivers": 1, + "Pi": 90, + "Po": 54, + "logic element": 699, + "latch": 54, + "Adder": 125, + "Multiplier": 3, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 31, + "Average Path": 4, + "Estimated LUTs": 699, + "Total Node": 882 + }, + "mults_auto_half/bm_match5_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_half/bm_match5_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "bm_match5_str_arch.v", + "max_rss(MiB)": 48.5, + "exec_time(ms)": 47.4, + "synthesis_time(ms)": 39.1, + "Latch Drivers": 1, + "Pi": 90, + "Po": 54, + "logic element": 2093, + "latch": 54, + "generic logic size": 6, + "Longest Path": 33, + "Average Path": 5, + "Estimated LUTs": 2093, + "Total Node": 2148 + }, + "mults_auto_half/multiply_hard_block/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_half/multiply_hard_block/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "multiply_hard_block.v", + "warnings": [ + "multiply_hard_block.v:9:2 [AST] Attempting to convert this instance to a hard block (multiply) - unnamed port connections will be matched according to hard block specification and may produce unexpected results" + ], + "max_rss(MiB)": 55.8, + "exec_time(ms)": 57.1, + "synthesis_time(ms)": 1.7, + "Pi": 8, + "Po": 8, + "logic element": 9, + "Adder": 0, + "Multiplier": 1, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 6, + "Average Path": 3, + "Estimated LUTs": 9, + "Total Node": 10 + }, + "mults_auto_half/multiply_hard_block/k6_N10_40nm": { + "test_name": "mults_auto_half/multiply_hard_block/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "multiply_hard_block.v", + "exit": 134, + "errors": [ + "multiply_hard_block.v:8:1 [AST] Can't find module name multiply" + ] + }, + "mults_auto_half/twobits_arithmetic_multiply/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_half/twobits_arithmetic_multiply/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "twobits_arithmetic_multiply.v", + "max_rss(MiB)": 56.2, + "exec_time(ms)": 60.6, + "synthesis_time(ms)": 1.7, + "Latch Drivers": 1, + "Pi": 5, + "Po": 5, + "logic element": 16, + "latch": 4, + "Adder": 0, + "Multiplier": 0, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 8, + "Average Path": 4, + "Estimated LUTs": 16, + "Total Node": 21 + }, + "mults_auto_half/twobits_arithmetic_multiply/k6_N10_40nm": { + "test_name": "mults_auto_half/twobits_arithmetic_multiply/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "twobits_arithmetic_multiply.v", + "max_rss(MiB)": 38.8, + "exec_time(ms)": 10.8, + "synthesis_time(ms)": 2.6, + "Latch Drivers": 1, + "Pi": 5, + "Po": 5, + "logic element": 16, + "latch": 4, + "generic logic size": 6, + "Longest Path": 8, + "Average Path": 4, + "Estimated LUTs": 16, + "Total Node": 21 + }, + "DEFAULT": { + "test_name": "n/a", + "architecture": "n/a", + "verilog": "n/a", + "exit": 0, + "leaks": 0, + "errors": [], + "warnings": [], + "expectation": [], + "max_rss(MiB)": -1, + "exec_time(ms)": -1, + "synthesis_time(ms)": -1, + "Latch Drivers": 0, + "Pi": 0, + "Po": 0, + "logic element": 0, + "latch": 0, + "Adder": -1, + "Multiplier": -1, + "Memory": -1, + "Hard Ip": -1, + "generic logic size": -1, + "Longest Path": 0, + "Average Path": 0, + "Estimated LUTs": 0, + "Total Node": 0 + } +} diff --git a/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_half/task.conf b/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_half/task.conf new file mode 100644 index 00000000000..8962ff4a567 --- /dev/null +++ b/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_half/task.conf @@ -0,0 +1,32 @@ +############################################## +# Configuration file for running experiments +############################################## +# Path to directory of circuits to use +# setup the architecture +archs_dir=../vtr_flow/arch/timing + +# hard adder and frac mul +arch_list_add=k6_frac_N10_frac_chain_mem32K_40nm.xml +# frac mul +arch_list_add=k6_frac_N10_mem32k_40nm.xml +# mul +arch_list_add=k6_N10_mem32k_40nm.xml +# no hard block +arch_list_add=k6_N10_40nm.xml + +# setup the circuits +circuits_dir=regression_test/benchmark/verilog + +# unit test +circuit_list_add=operators/twobits_arithmetic_multiply.v +# simple wide multiplication +circuit_list_add=micro/bm_base_multiply.v +# harblock mul +circuit_list_add=micro/multiply_hard_block.v +# complex mutliplication +circuit_list_add=micro/bm_match[012345]_str_arch.v + +synthesis_params= --mults_ratio 0.5 + +synthesis_parse_file=regression_test/parse_result/conf/synth.toml +simulation_parse_file=regression_test/parse_result/conf/sim.toml diff --git a/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_none/simulation_result.json b/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_none/simulation_result.json new file mode 100644 index 00000000000..83e9e9c2fd8 --- /dev/null +++ b/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_none/simulation_result.json @@ -0,0 +1,317 @@ +{ + "mults_auto_none/bm_base_multiply/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_none/bm_base_multiply/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "bm_base_multiply.blif", + "max_rss(MiB)": 143.5, + "exec_time(ms)": 1623.1, + "simulation_time(ms)": 1479.1, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 47, + "Po": 78, + "logic element": 637, + "latch": 71, + "generic logic size": 4, + "Longest Path": 26, + "Average Path": 6, + "Estimated LUTs": 637, + "Total Node": 709 + }, + "mults_auto_none/bm_base_multiply/k6_N10_40nm": { + "test_name": "mults_auto_none/bm_base_multiply/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "blif": "bm_base_multiply.blif", + "max_rss(MiB)": 144.5, + "exec_time(ms)": 1789.8, + "simulation_time(ms)": 1693.6, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 47, + "Po": 78, + "logic element": 795, + "latch": 71, + "generic logic size": 6, + "Longest Path": 26, + "Average Path": 6, + "Estimated LUTs": 795, + "Total Node": 867 + }, + "mults_auto_none/bm_match1_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_none/bm_match1_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "bm_match1_str_arch.blif", + "max_rss(MiB)": 334.2, + "exec_time(ms)": 3093.5, + "simulation_time(ms)": 2880.7, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 88, + "Po": 144, + "logic element": 2008, + "latch": 72, + "generic logic size": 4, + "Longest Path": 74, + "Average Path": 6, + "Estimated LUTs": 2008, + "Total Node": 2081 + }, + "mults_auto_none/bm_match1_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_none/bm_match1_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "blif": "bm_match1_str_arch.blif", + "max_rss(MiB)": 612.5, + "exec_time(ms)": 4793, + "simulation_time(ms)": 4555.6, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 88, + "Po": 144, + "logic element": 3872, + "latch": 72, + "generic logic size": 6, + "Longest Path": 74, + "Average Path": 6, + "Estimated LUTs": 3872, + "Total Node": 3945 + }, + "mults_auto_none/bm_match2_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_none/bm_match2_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "bm_match2_str_arch.blif", + "max_rss(MiB)": 249.8, + "exec_time(ms)": 2880, + "simulation_time(ms)": 2640.6, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 54, + "Po": 99, + "logic element": 1031, + "latch": 54, + "Adder": 173, + "generic logic size": 4, + "Longest Path": 32, + "Average Path": 7, + "Estimated LUTs": 1031, + "Total Node": 1259 + }, + "mults_auto_none/bm_match2_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_none/bm_match2_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "blif": "bm_match2_str_arch.blif", + "max_rss(MiB)": 489.7, + "exec_time(ms)": 4139.2, + "simulation_time(ms)": 3946.5, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 54, + "Po": 99, + "logic element": 3211, + "latch": 54, + "generic logic size": 6, + "Longest Path": 32, + "Average Path": 7, + "Estimated LUTs": 3211, + "Total Node": 3266 + }, + "mults_auto_none/bm_match3_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_none/bm_match3_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "bm_match3_str_arch.blif", + "max_rss(MiB)": 119.1, + "exec_time(ms)": 1052.8, + "simulation_time(ms)": 817, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 54, + "Po": 54, + "logic element": 287, + "latch": 54, + "Adder": 50, + "generic logic size": 4, + "Longest Path": 31, + "Average Path": 5, + "Estimated LUTs": 287, + "Total Node": 392 + }, + "mults_auto_none/bm_match3_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_none/bm_match3_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "blif": "bm_match3_str_arch.blif", + "max_rss(MiB)": 90.9, + "exec_time(ms)": 725.6, + "simulation_time(ms)": 673.1, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 54, + "Po": 54, + "logic element": 375, + "latch": 54, + "generic logic size": 6, + "Longest Path": 58, + "Average Path": 5, + "Estimated LUTs": 375, + "Total Node": 430 + }, + "mults_auto_none/bm_match4_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_none/bm_match4_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "bm_match4_str_arch.blif", + "max_rss(MiB)": 217.5, + "exec_time(ms)": 2459.1, + "simulation_time(ms)": 2170.1, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 51, + "Po": 216, + "logic element": 837, + "latch": 108, + "Adder": 74, + "generic logic size": 4, + "Longest Path": 49, + "Average Path": 5, + "Estimated LUTs": 837, + "Total Node": 1020 + }, + "mults_auto_none/bm_match4_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_none/bm_match4_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "blif": "bm_match4_str_arch.blif", + "max_rss(MiB)": 238.4, + "exec_time(ms)": 2527.9, + "simulation_time(ms)": 2407.6, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 51, + "Po": 216, + "logic element": 1367, + "latch": 108, + "generic logic size": 6, + "Longest Path": 49, + "Average Path": 5, + "Estimated LUTs": 1367, + "Total Node": 1476 + }, + "mults_auto_none/bm_match5_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_none/bm_match5_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "bm_match5_str_arch.blif", + "max_rss(MiB)": 288.1, + "exec_time(ms)": 2865.8, + "simulation_time(ms)": 2571.8, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 90, + "Po": 54, + "logic element": 1452, + "latch": 54, + "Adder": 125, + "generic logic size": 4, + "Longest Path": 34, + "Average Path": 6, + "Estimated LUTs": 1452, + "Total Node": 1632 + }, + "mults_auto_none/bm_match5_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_none/bm_match5_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "blif": "bm_match5_str_arch.blif", + "max_rss(MiB)": 319.7, + "exec_time(ms)": 3560, + "simulation_time(ms)": 3432, + "test_coverage(%)": 100, + "Latch Drivers": 1, + "Pi": 90, + "Po": 54, + "logic element": 2147, + "latch": 54, + "generic logic size": 6, + "Longest Path": 34, + "Average Path": 6, + "Estimated LUTs": 2147, + "Total Node": 2202 + }, + "mults_auto_none/multiply_hard_block/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_none/multiply_hard_block/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "multiply_hard_block.blif", + "max_rss(MiB)": 55.6, + "exec_time(ms)": 124.7, + "simulation_time(ms)": 17, + "test_coverage(%)": 100, + "Pi": 8, + "Po": 8, + "logic element": 26, + "generic logic size": 4, + "Longest Path": 7, + "Average Path": 5, + "Estimated LUTs": 26, + "Total Node": 26 + }, + "mults_auto_none/twobits_arithmetic_multiply/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_none/twobits_arithmetic_multiply/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "blif": "twobits_arithmetic_multiply.blif", + "max_rss(MiB)": 54.8, + "exec_time(ms)": 112, + "simulation_time(ms)": 5.6, + "test_coverage(%)": 92.5, + "Latch Drivers": 1, + "Pi": 5, + "Po": 5, + "logic element": 21, + "latch": 4, + "generic logic size": 4, + "Longest Path": 9, + "Average Path": 5, + "Estimated LUTs": 21, + "Total Node": 26 + }, + "mults_auto_none/twobits_arithmetic_multiply/k6_N10_40nm": { + "test_name": "mults_auto_none/twobits_arithmetic_multiply/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "blif": "twobits_arithmetic_multiply.blif", + "max_rss(MiB)": 37.6, + "exec_time(ms)": 23.4, + "simulation_time(ms)": 5.6, + "test_coverage(%)": 92.5, + "Latch Drivers": 1, + "Pi": 5, + "Po": 5, + "logic element": 21, + "latch": 4, + "generic logic size": 6, + "Longest Path": 9, + "Average Path": 5, + "Estimated LUTs": 21, + "Total Node": 26 + }, + "DEFAULT": { + "test_name": "n/a", + "architecture": "n/a", + "blif": "n/a", + "exit": 0, + "leaks": 0, + "errors": [], + "warnings": [], + "expectation": [], + "max_rss(MiB)": -1, + "exec_time(ms)": -1, + "simulation_time(ms)": -1, + "test_coverage(%)": -1, + "Latch Drivers": 0, + "Pi": 0, + "Po": 0, + "logic element": 0, + "latch": 0, + "Adder": -1, + "Multiplier": -1, + "Memory": -1, + "Hard Ip": -1, + "generic logic size": -1, + "Longest Path": 0, + "Average Path": 0, + "Estimated LUTs": 0, + "Total Node": 0 + } +} diff --git a/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_none/synthesis_result.json b/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_none/synthesis_result.json new file mode 100644 index 00000000000..8db97a1f818 --- /dev/null +++ b/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_none/synthesis_result.json @@ -0,0 +1,333 @@ +{ + "mults_auto_none/bm_base_multiply/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_none/bm_base_multiply/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "bm_base_multiply.v", + "max_rss(MiB)": 62, + "exec_time(ms)": 102.6, + "synthesis_time(ms)": 22.6, + "Latch Drivers": 1, + "Pi": 47, + "Po": 78, + "logic element": 559, + "latch": 71, + "Adder": 0, + "Multiplier": 0, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 25, + "Average Path": 5, + "Estimated LUTs": 559, + "Total Node": 631 + }, + "mults_auto_none/bm_base_multiply/k6_N10_40nm": { + "test_name": "mults_auto_none/bm_base_multiply/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "bm_base_multiply.v", + "max_rss(MiB)": 45.4, + "exec_time(ms)": 32.8, + "synthesis_time(ms)": 24.2, + "Latch Drivers": 1, + "Pi": 47, + "Po": 78, + "logic element": 717, + "latch": 71, + "generic logic size": 6, + "Longest Path": 25, + "Average Path": 5, + "Estimated LUTs": 717, + "Total Node": 789 + }, + "mults_auto_none/bm_match1_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_none/bm_match1_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "bm_match1_str_arch.v", + "max_rss(MiB)": 66.3, + "exec_time(ms)": 116.6, + "synthesis_time(ms)": 37.6, + "Latch Drivers": 1, + "Pi": 88, + "Po": 144, + "logic element": 1864, + "latch": 72, + "Adder": 0, + "Multiplier": 0, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 73, + "Average Path": 5, + "Estimated LUTs": 1864, + "Total Node": 1937 + }, + "mults_auto_none/bm_match1_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_none/bm_match1_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "bm_match1_str_arch.v", + "max_rss(MiB)": 58.1, + "exec_time(ms)": 102.3, + "synthesis_time(ms)": 94, + "Latch Drivers": 1, + "Pi": 88, + "Po": 144, + "logic element": 3728, + "latch": 72, + "generic logic size": 6, + "Longest Path": 73, + "Average Path": 5, + "Estimated LUTs": 3728, + "Total Node": 3801 + }, + "mults_auto_none/bm_match2_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_none/bm_match2_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "bm_match2_str_arch.v", + "max_rss(MiB)": 62.9, + "exec_time(ms)": 110.9, + "synthesis_time(ms)": 31.1, + "Latch Drivers": 1, + "Pi": 54, + "Po": 99, + "logic element": 932, + "latch": 54, + "Adder": 173, + "Multiplier": 0, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 31, + "Average Path": 6, + "Estimated LUTs": 932, + "Total Node": 1160 + }, + "mults_auto_none/bm_match2_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_none/bm_match2_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "bm_match2_str_arch.v", + "max_rss(MiB)": 53.5, + "exec_time(ms)": 65.6, + "synthesis_time(ms)": 57.3, + "Latch Drivers": 1, + "Pi": 54, + "Po": 99, + "logic element": 3112, + "latch": 54, + "generic logic size": 6, + "Longest Path": 31, + "Average Path": 6, + "Estimated LUTs": 3112, + "Total Node": 3167 + }, + "mults_auto_none/bm_match3_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_none/bm_match3_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "bm_match3_str_arch.v", + "max_rss(MiB)": 58.8, + "exec_time(ms)": 92.2, + "synthesis_time(ms)": 12.8, + "Latch Drivers": 1, + "Pi": 54, + "Po": 54, + "logic element": 233, + "latch": 54, + "Adder": 50, + "Multiplier": 0, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 30, + "Average Path": 4, + "Estimated LUTs": 233, + "Total Node": 338 + }, + "mults_auto_none/bm_match3_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_none/bm_match3_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "bm_match3_str_arch.v", + "max_rss(MiB)": 42, + "exec_time(ms)": 21, + "synthesis_time(ms)": 12.6, + "Latch Drivers": 1, + "Pi": 54, + "Po": 54, + "logic element": 321, + "latch": 54, + "generic logic size": 6, + "Longest Path": 57, + "Average Path": 4, + "Estimated LUTs": 321, + "Total Node": 376 + }, + "mults_auto_none/bm_match4_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_none/bm_match4_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "bm_match4_str_arch.v", + "max_rss(MiB)": 63.1, + "exec_time(ms)": 123.9, + "synthesis_time(ms)": 26.9, + "Latch Drivers": 1, + "Pi": 51, + "Po": 216, + "logic element": 621, + "latch": 108, + "Adder": 74, + "Multiplier": 0, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 48, + "Average Path": 4, + "Estimated LUTs": 621, + "Total Node": 804 + }, + "mults_auto_none/bm_match4_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_none/bm_match4_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "bm_match4_str_arch.v", + "max_rss(MiB)": 47.5, + "exec_time(ms)": 39.3, + "synthesis_time(ms)": 31.1, + "Latch Drivers": 1, + "Pi": 51, + "Po": 216, + "logic element": 1151, + "latch": 108, + "generic logic size": 6, + "Longest Path": 48, + "Average Path": 4, + "Estimated LUTs": 1151, + "Total Node": 1260 + }, + "mults_auto_none/bm_match5_str_arch/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_none/bm_match5_str_arch/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "bm_match5_str_arch.v", + "max_rss(MiB)": 63.4, + "exec_time(ms)": 104.5, + "synthesis_time(ms)": 31.4, + "Latch Drivers": 1, + "Pi": 90, + "Po": 54, + "logic element": 1398, + "latch": 54, + "Adder": 125, + "Multiplier": 0, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 33, + "Average Path": 5, + "Estimated LUTs": 1398, + "Total Node": 1578 + }, + "mults_auto_none/bm_match5_str_arch/k6_N10_40nm": { + "test_name": "mults_auto_none/bm_match5_str_arch/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "bm_match5_str_arch.v", + "max_rss(MiB)": 48.6, + "exec_time(ms)": 45.4, + "synthesis_time(ms)": 37.7, + "Latch Drivers": 1, + "Pi": 90, + "Po": 54, + "logic element": 2093, + "latch": 54, + "generic logic size": 6, + "Longest Path": 33, + "Average Path": 5, + "Estimated LUTs": 2093, + "Total Node": 2148 + }, + "mults_auto_none/multiply_hard_block/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_none/multiply_hard_block/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "multiply_hard_block.v", + "warnings": [ + "multiply_hard_block.v:9:2 [AST] Attempting to convert this instance to a hard block (multiply) - unnamed port connections will be matched according to hard block specification and may produce unexpected results" + ], + "max_rss(MiB)": 55.7, + "exec_time(ms)": 83.2, + "synthesis_time(ms)": 2.5, + "Pi": 8, + "Po": 8, + "logic element": 18, + "Adder": 0, + "Multiplier": 0, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 6, + "Average Path": 4, + "Estimated LUTs": 18, + "Total Node": 18 + }, + "mults_auto_none/multiply_hard_block/k6_N10_40nm": { + "test_name": "mults_auto_none/multiply_hard_block/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "multiply_hard_block.v", + "exit": 134, + "errors": [ + "multiply_hard_block.v:8:1 [AST] Can't find module name multiply" + ] + }, + "mults_auto_none/twobits_arithmetic_multiply/k6_frac_N10_frac_chain_mem32K_40nm": { + "test_name": "mults_auto_none/twobits_arithmetic_multiply/k6_frac_N10_frac_chain_mem32K_40nm", + "architecture": "k6_frac_N10_frac_chain_mem32K_40nm.xml", + "verilog": "twobits_arithmetic_multiply.v", + "max_rss(MiB)": 56.2, + "exec_time(ms)": 47.7, + "synthesis_time(ms)": 1.8, + "Latch Drivers": 1, + "Pi": 5, + "Po": 5, + "logic element": 16, + "latch": 4, + "Adder": 0, + "Multiplier": 0, + "Memory": 0, + "generic logic size": 4, + "Longest Path": 8, + "Average Path": 4, + "Estimated LUTs": 16, + "Total Node": 21 + }, + "mults_auto_none/twobits_arithmetic_multiply/k6_N10_40nm": { + "test_name": "mults_auto_none/twobits_arithmetic_multiply/k6_N10_40nm", + "architecture": "k6_N10_40nm.xml", + "verilog": "twobits_arithmetic_multiply.v", + "max_rss(MiB)": 39.4, + "exec_time(ms)": 7.1, + "synthesis_time(ms)": 1.8, + "Latch Drivers": 1, + "Pi": 5, + "Po": 5, + "logic element": 16, + "latch": 4, + "generic logic size": 6, + "Longest Path": 8, + "Average Path": 4, + "Estimated LUTs": 16, + "Total Node": 21 + }, + "DEFAULT": { + "test_name": "n/a", + "architecture": "n/a", + "verilog": "n/a", + "exit": 0, + "leaks": 0, + "errors": [], + "warnings": [], + "expectation": [], + "max_rss(MiB)": -1, + "exec_time(ms)": -1, + "synthesis_time(ms)": -1, + "Latch Drivers": 0, + "Pi": 0, + "Po": 0, + "logic element": 0, + "latch": 0, + "Adder": -1, + "Multiplier": -1, + "Memory": -1, + "Hard Ip": -1, + "generic logic size": -1, + "Longest Path": 0, + "Average Path": 0, + "Estimated LUTs": 0, + "Total Node": 0 + } +} diff --git a/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_none/task.conf b/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_none/task.conf new file mode 100644 index 00000000000..44c19ad2789 --- /dev/null +++ b/ODIN_II/regression_test/benchmark/task/mixing_optimization/mults_auto_none/task.conf @@ -0,0 +1,32 @@ +############################################## +# Configuration file for running experiments +############################################## +# Path to directory of circuits to use +# setup the architecture +archs_dir=../vtr_flow/arch/timing + +# hard adder and frac mul +arch_list_add=k6_frac_N10_frac_chain_mem32K_40nm.xml +# frac mul +arch_list_add=k6_frac_N10_mem32k_40nm.xml +# mul +arch_list_add=k6_N10_mem32k_40nm.xml +# no hard block +arch_list_add=k6_N10_40nm.xml + +# setup the circuits +circuits_dir=regression_test/benchmark/verilog + +# unit test +circuit_list_add=operators/twobits_arithmetic_multiply.v +# simple wide multiplication +circuit_list_add=micro/bm_base_multiply.v +# harblock mul +circuit_list_add=micro/multiply_hard_block.v +# complex mutliplication +circuit_list_add=micro/bm_match[012345]_str_arch.v + +synthesis_params= --mults_ratio 0.0 + +synthesis_parse_file=regression_test/parse_result/conf/synth.toml +simulation_parse_file=regression_test/parse_result/conf/sim.toml diff --git a/doc/src/odin/dev_guide/regression_test.md b/doc/src/odin/dev_guide/regression_test.md index 0debab2d62a..cff1425d81a 100644 --- a/doc/src/odin/dev_guide/regression_test.md +++ b/doc/src/odin/dev_guide/regression_test.md @@ -297,7 +297,11 @@ This regression test targets cases that require a lot of ram and time. The micro regression tests targets hards blocks and pieces that can be easily instantiated in architectures. -### opertators +### mixing_optimization + +The mixing optimization regression tests targets mixing implementations for operations implementable in hard blocks and their soft logic counterparts that can be can be easily instantiated in architectures. + +### operators This regression test targets the functionality of different opertators. It checks bit size capacity and behaviour. @@ -318,6 +322,8 @@ This set of regression test includes benchmarks targetting compiler directives a ```bash benchmark ├── suite + │   ├── complex_synthesis_suite + │   │ └── task_list.conf │   ├── full_suite │   │   └── task_list.conf │   ├── heavy_suite @@ -410,6 +416,19 @@ benchmark │   │   ├── simulation_result.json │   │   ├── synthesis_result.json │   │   └── task.conf + │   ├── mixing_optimization + |   |   ├── mults_auto_full + │   │   |   ├── simulation_result.json + │   │   |   |── synthesis_result.json + │   │   |   └── task.conf + |   |   ├── mults_auto_half + │   │   |   ├── simulation_result.json + │   │   |   |── synthesis_result.json + │   │   |   └── task.conf + |   |   ├── mults_auto_none + │   │   |   ├── simulation_result.json + │   │   |   |── synthesis_result.json + │   │   |   └── task.conf │   ├── operators │   │   ├── simulation_result.json │   │   ├── synthesis_result.json diff --git a/doc/src/odin/dev_guide/verify_script.md b/doc/src/odin/dev_guide/verify_script.md index dcb58483d79..2b1fc0fdbd9 100644 --- a/doc/src/odin/dev_guide/verify_script.md +++ b/doc/src/odin/dev_guide/verify_script.md @@ -33,6 +33,9 @@ The following examples are being performed in the ODIN_II directory: ### Generating Results for a New Task +To generate new results, `synthesis_parse_file` and `simulation_parse_file` must be specified +in task.conf file. + The following commands will generate the results of a new regression test using N processors: ```bash diff --git a/vtr_flow/scripts/python_libs/vtr/util.py b/vtr_flow/scripts/python_libs/vtr/util.py index 554b331da1c..2b6d4a790d2 100644 --- a/vtr_flow/scripts/python_libs/vtr/util.py +++ b/vtr_flow/scripts/python_libs/vtr/util.py @@ -466,7 +466,7 @@ def load_config_lines(filepath, allow_includes=True): else: config_lines.append(line) except IOError as error: - raise InspectError("Error opening config file ({})".format(error)) + raise InspectError("Error opening config file ({})".format(error)) from error return config_lines