diff --git a/docs/source/arch_lang/circuit_library.rst b/docs/source/arch_lang/circuit_library.rst index 2cab83abd..bf32fc113 100644 --- a/docs/source/arch_lang/circuit_library.rst +++ b/docs/source/arch_lang/circuit_library.rst @@ -272,7 +272,7 @@ A circuit model may consist of a number of ports. The port list is mandatory in - ``io="true|false"`` Specify if this port should be treated as an I/O port of an FPGA fabric. When this is enabled, this port of each circuit model instanciated in FPGA will be added as an I/O of an FPGA. - .. note:: ``io`` is only valid for ``input`` ports + .. note:: global ``output`` ports must be ``io`` ports - ``mode_select="true|false"`` Specify if this port controls the mode switching in a configurable logic block. This is due to that a configurable logic block can operate in different modes, which is controlled by SRAM bits. @@ -296,3 +296,113 @@ A circuit model may consist of a number of ports. The port list is mandatory in .. note:: Different types of ``circuit_model`` have different XML syntax, with which users can highly customize their circuit topologies. See refer to examples of :ref:``circuit_model_example`` for more details. .. note:: Note that we have a list of reserved port names, which indicate the usage of these ports when building FPGA fabrics. Please do not use ``mem_out``, ``mem_inv``, ``bl``, ``wl``, ``blb``, ``wlb``, ``ccff_head`` and ``ccff_tail``. + +FPGA I/O Port +^^^^^^^^^^^^^ + +The ``circuit_model`` support not only highly customizable circuit-level modeling but also flexible I/O connection in the FPGA fabric. +Typically, circuit ports appear in the primitive modules of a FPGA fabric. +However, it is also very common that some circuit ports should be I/O of a FPGA fabric. +Using syntax ``is_global`` and ``is_io``, users can freely define how these ports are connected as FPGA I/Os. + +In principle, when ``is_global`` is set ``true``, the port will appear as an FPGA I/O. +The syntax ``is_io`` is applicable when ``is_global`` is ``true``. +When ``is_io`` is ``true``, the port from different instances will be treated as independent I/Os. +When ``is_io`` is ``false``, the port from different instances will be treated as the same I/Os, which are short-wired. + +To beef up, the following examples will explain how to use ``is_global`` and ``is_io`` to achieve different types of connections to FPGA I/Os. + +.. option:: Global short-wired inputs + +.. code-block:: xml + + + +The global inputs are short wired across different instances. +These inputs are widely seen in FPGAs, such as clock ports, which are shared between sequential elements. + +:numref:`fig_global_input_ports` shows an example on how the global inputs are wired inside FPGA fabric. + +.. _fig_global_input_ports: + +.. figure:: ./figures/global_input_ports.png + :scale: 100% + :alt: classical inverter 1x symbol + + Short-wired global inputs as an FPGA I/O + +.. option:: Global short-wired inouts + +.. code-block:: xml + + + +The global inouts are short wired across different instances. + +:numref:`fig_global_ioput_ports` shows an example on how the global inouts are wired inside FPGA fabric. + +.. _fig_global_inout_ports: + +.. figure:: ./figures/global_inout_ports.png + :scale: 100% + :alt: classical inverter 1x symbol + + Short-wired global inouts as an FPGA I/O + +.. option:: General-purpose inputs + +.. code-block:: xml + + + +The general-purpose inputs are independent wired from different instances to separated FPGA I/Os. +For example, power-gating signals can be applied to each tile of a FPGA. + +:numref:`fig_gpin_ports` shows an example on how the general-purpose inputs are wired inside FPGA fabric. + +.. _fig_gpin_ports: + +.. figure:: ./figures/gpin_ports.png + :scale: 100% + :alt: classical inverter 1x symbol + + General-purpose inputs as separated FPGA I/Os + +.. option:: General-purpose I/O + +.. code-block:: xml + + + +The general-purpose I/O are independent wired from different instances to separated FPGA I/Os. +In practice, inout of GPIO cell is typically wired like this. + +:numref:`fig_gpin_ports` shows an example on how the general-purpose inouts are wired inside FPGA fabric. + +.. _fig_gpio_ports: + +.. figure:: ./figures/gpio_ports.png + :scale: 100% + :alt: classical inverter 1x symbol + + General-purpose inouts as separated FPGA I/Os + +.. option:: General-purpose outputs + +.. code-block:: xml + + + +The general-purpose outputs are independent wired from different instances to separated FPGA outputs. +In practice, these outputs are typically spypads to probe internal signals of a FPGA. + +:numref:`fig_gpout_ports` shows an example on how the general-purpose outputs are wired inside FPGA fabric. + +.. _fig_gpout_ports: + +.. figure:: ./figures/gpout_ports.png + :scale: 100% + :alt: classical inverter 1x symbol + + General-purpose outputs as separated FPGA I/Os + diff --git a/docs/source/arch_lang/figures/global_inout_ports.png b/docs/source/arch_lang/figures/global_inout_ports.png new file mode 100644 index 000000000..9dd7d2b89 Binary files /dev/null and b/docs/source/arch_lang/figures/global_inout_ports.png differ diff --git a/docs/source/arch_lang/figures/global_input_ports.png b/docs/source/arch_lang/figures/global_input_ports.png new file mode 100644 index 000000000..4c9025ab3 Binary files /dev/null and b/docs/source/arch_lang/figures/global_input_ports.png differ diff --git a/docs/source/arch_lang/figures/gpin_ports.png b/docs/source/arch_lang/figures/gpin_ports.png new file mode 100644 index 000000000..08da0b8c3 Binary files /dev/null and b/docs/source/arch_lang/figures/gpin_ports.png differ diff --git a/docs/source/arch_lang/figures/gpio_ports.png b/docs/source/arch_lang/figures/gpio_ports.png new file mode 100644 index 000000000..4b0362c7b Binary files /dev/null and b/docs/source/arch_lang/figures/gpio_ports.png differ diff --git a/docs/source/arch_lang/figures/gpout_ports.png b/docs/source/arch_lang/figures/gpout_ports.png new file mode 100644 index 000000000..e5140bd99 Binary files /dev/null and b/docs/source/arch_lang/figures/gpout_ports.png differ diff --git a/docs/source/openfpga_shell/launch_openfpga_shell.rst b/docs/source/openfpga_shell/launch_openfpga_shell.rst index 3ef6e9fb5..8ef7e3858 100644 --- a/docs/source/openfpga_shell/launch_openfpga_shell.rst +++ b/docs/source/openfpga_shell/launch_openfpga_shell.rst @@ -11,6 +11,8 @@ To launch OpenFPGA shell, users can choose two modes. Launch OpenFPGA in interactive mode where users type-in command by command and get runtime results + .. warning:: Currently OpenFPGA does not support continued lines and comments + .. option:: --file or -f Launch OpenFPGA in script mode where users write commands in scripts and FPGA will execute them diff --git a/docs/source/openfpga_shell/openfpga_commands.rst b/docs/source/openfpga_shell/openfpga_commands.rst index 8f71cdb54..3712cea0d 100644 --- a/docs/source/openfpga_shell/openfpga_commands.rst +++ b/docs/source/openfpga_shell/openfpga_commands.rst @@ -194,7 +194,7 @@ FPGA-SDC - ``--constrain_zero_delay_paths`` Constrain all the zero-delay paths in FPGA fabric - .. note:: Zero-delay path may cause errors in some PnR tools as it is considered illegal + .. note:: Zero-delay path may cause errors in some PnR tools as it is considered illegal - ``--verbose`` Enable verbose output diff --git a/docs/source/openfpga_shell/openfpga_script.rst b/docs/source/openfpga_shell/openfpga_script.rst index dde33a044..7c9bd5548 100644 --- a/docs/source/openfpga_shell/openfpga_script.rst +++ b/docs/source/openfpga_shell/openfpga_script.rst @@ -4,8 +4,20 @@ OpenFPGA Script Format ---------------------- OpenFPGA accepts a simplified tcl-like script format. -Commented lines are started with `#`. -Note that comments can be added inline or as a new line. + +.. option:: Comments + + Any content after a ``#`` will be treated as comments. + Comments will not be executed. + + .. note:: comments can be added inline or as a new line. See the example below + +.. option:: Continued line + + Lines to be continued should be finished with ``\``. + Continued lines will be conjuncted and executed as one line + + .. note:: please ensure necessary spaces. Otherwise it may cause command parser fail. The following is an example. @@ -21,7 +33,8 @@ The following is an example. #write_openfpga_arch -f ./arch_echo.xml # Annotate the OpenFPGA architecture to VPR data base - link_openfpga_arch --activity_file ./test_blif/and.act --sort_gsb_chan_node_in_edges #--verbose + link_openfpga_arch --activity_file ./test_blif/and.act \ + --sort_gsb_chan_node_in_edges #--verbose # Check and correct any naming conflicts in the BLIF netlist check_netlist_naming_conflict --fix --report ./netlist_renaming.xml @@ -35,7 +48,8 @@ The following is an example. # Build the module graph # - Enabled compression on routing architecture modules # - Enable pin duplication on grid modules - build_fabric --compress_routing --duplicate_grid_pin #--verbose + build_fabric --compress_routing \ + --duplicate_grid_pin #--verbose # Repack the netlist to physical pbs # This must be done before bitstream generator and testbench generation @@ -44,14 +58,21 @@ The following is an example. # Build the bitstream # - Output the fabric-independent bitstream to a file - build_architecture_bitstream --verbose --file /var/tmp/xtang/openfpga_test_src/fabric_indepenent_bitstream.xml + build_architecture_bitstream --verbose \ + --file /var/tmp/xtang/openfpga_test_src/fabric_indepenent_bitstream.xml # Build fabric-dependent bitstream build_fabric_bitstream --verbose # Write the Verilog netlist for FPGA fabric # - Enable the use of explicit port mapping in Verilog netlist - write_fabric_verilog --file /var/tmp/xtang/openfpga_test_src/SRC --explicit_port_mapping --include_timing --include_signal_init --support_icarus_simulator --print_user_defined_template --verbose + write_fabric_verilog --file /var/tmp/xtang/openfpga_test_src/SRC \ + --explicit_port_mapping \ + --include_timing \ + --include_signal_init \ + --support_icarus_simulator \ + --print_user_defined_template \ + --verbose # Write the Verilog testbench for FPGA fabric # - We suggest the use of same output directory as fabric Verilog netlists @@ -59,7 +80,11 @@ The following is an example. # - Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA # - Enable pre-configured top-level testbench which is a fast verification skipping programming phase # - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts - write_verilog_testbench --file /var/tmp/xtang/openfpga_test_src/SRC --reference_benchmark_file_path /var/tmp/xtang/and.v --print_top_testbench --print_preconfig_top_testbench --print_simulation_ini /var/tmp/xtang/openfpga_test_src/simulation_deck.ini + write_verilog_testbench --file /var/tmp/xtang/openfpga_test_src/SRC \ + --reference_benchmark_file_path /var/tmp/xtang/and.v \ + --print_top_testbench \ + --print_preconfig_top_testbench \ + --print_simulation_ini /var/tmp/xtang/openfpga_test_src/simulation_deck.ini # Write the SDC files for PnR backend # - Turn on every options here diff --git a/libopenfpga/libarchopenfpga/src/check_circuit_library.cpp b/libopenfpga/libarchopenfpga/src/check_circuit_library.cpp index 2e8c1a214..0abc16a0e 100644 --- a/libopenfpga/libarchopenfpga/src/check_circuit_library.cpp +++ b/libopenfpga/libarchopenfpga/src/check_circuit_library.cpp @@ -317,6 +317,18 @@ size_t check_circuit_library_ports(const CircuitLibrary& circuit_lib) { } } + /* Check global output ports: make sure they are all I/Os */ + for (const auto& port : circuit_lib.ports()) { + if ( (circuit_lib.port_is_global(port)) + && (CIRCUIT_MODEL_PORT_OUTPUT == circuit_lib.port_type(port)) + && (false == circuit_lib.port_is_io(port)) ) { + VTR_LOG_ERROR("Circuit port (type=%s) of model (name=%s) is defined as global output port but not an I/O!\n", + CIRCUIT_MODEL_PORT_TYPE_STRING[size_t(circuit_lib.port_type(port))], + circuit_lib.model_name(port).c_str()); + num_err++; + } + } + /* Check set/reset/config_enable ports: make sure they are all global ports */ for (const auto& port : circuit_lib.ports()) { if ( ( (circuit_lib.port_is_set(port)) diff --git a/libopenfpga/libarchopenfpga/src/read_xml_circuit_library.cpp b/libopenfpga/libarchopenfpga/src/read_xml_circuit_library.cpp index cd8ffd1c5..ba6e6af7f 100644 --- a/libopenfpga/libarchopenfpga/src/read_xml_circuit_library.cpp +++ b/libopenfpga/libarchopenfpga/src/read_xml_circuit_library.cpp @@ -489,9 +489,7 @@ void read_xml_circuit_port(pugi::xml_node& xml_port, /* Identify if the port is for io, this is only applicable to INPUT ports. * By default, it will NOT be a mode selection port */ - if (CIRCUIT_MODEL_PORT_INPUT == circuit_lib.port_type(port)) { - circuit_lib.set_port_is_io(port, get_attribute(xml_port, "io", loc_data, pugiutil::ReqOpt::OPTIONAL).as_bool(false)); - } + circuit_lib.set_port_is_io(port, get_attribute(xml_port, "is_io", loc_data, pugiutil::ReqOpt::OPTIONAL).as_bool(false)); /* Identify if the port is for mode selection, this is only applicable to SRAM ports. * By default, it will NOT be a mode selection port diff --git a/libopenfpga/libopenfpgashell/src/command_exit_codes.h b/libopenfpga/libopenfpgashell/src/command_exit_codes.h new file mode 100644 index 000000000..f1490e533 --- /dev/null +++ b/libopenfpga/libopenfpgashell/src/command_exit_codes.h @@ -0,0 +1,27 @@ +#ifndef COMMAND_EXIT_CODES_H +#define COMMAND_EXIT_CODES_H + +/* Begin namespace openfpga */ +namespace openfpga { + +/********************************************************************* + * Exit codes to signal success/failure status of command execution + * Depend on the exit code, OpenFPGA shell will decide to continue or abort + ********************************************************************/ + +/* Never been executed */ +constexpr int CMD_EXEC_NONE = -1; + +/* Everything OK */ +constexpr int CMD_EXEC_SUCCESS = 0; + +/* Fatal error occurred, we have to abort and do not execute the rest of commands */ +constexpr int CMD_EXEC_FATAL_ERROR = 1; + +/* See minor errors but it will not impact the downsteam. We can continue to execute the rest of commands */ +constexpr int CMD_EXEC_MINOR_ERROR = 2; + + +} /* End namespace openfpga */ + +#endif diff --git a/libopenfpga/libopenfpgashell/src/shell.h b/libopenfpga/libopenfpgashell/src/shell.h index 427580010..1a49b313c 100644 --- a/libopenfpga/libopenfpgashell/src/shell.h +++ b/libopenfpga/libopenfpgashell/src/shell.h @@ -10,6 +10,7 @@ #include "vtr_range.h" #include "command.h" #include "command_context.h" +#include "command_exit_codes.h" #include "shell_fwd.h" /* Begin namespace openfpga */ @@ -88,25 +89,49 @@ class Shell { ShellCommandId add_command(const Command& cmd, const char* descr); void set_command_class(const ShellCommandId& cmd_id, const ShellCommandClassId& cmd_class_id); /* Link the execute function to a command - * We support here three types of functions to be executed in the shell - * 1. Standard function, including the data exchange and commands - * 2. Short function, including only the data exchange - * 3. Built-in function, including only the shell envoriment variables - * 4. Marco function, which directly call a macro function without command parsing + * We support here different types of functions to be executed in the shell * Users just need to specify the function object and its type will be automatically inferred + * + * Note that all the function should return exit codes complying to the shell_exit_code.h + * execept the internal functions + */ + + /* Standard function, including the data exchange and commands + * This function requires the data exchange to be constant + * This is designed for outputting functions requiring external data than the */ void set_command_const_execute_function(const ShellCommandId& cmd_id, - std::function exec_func); + std::function exec_func); + + /* Standard function, including the data exchange and commands + * This function allows modification to the data exchange + * This is designed for implementing functions requiring external data than the + */ void set_command_execute_function(const ShellCommandId& cmd_id, - std::function exec_func); + std::function exec_func); + + /* Short function, including only the data exchange + * This function requires the data exchange to be constant + * This is designed for outputting functions without external data than the + */ void set_command_const_execute_function(const ShellCommandId& cmd_id, - std::function exec_func); + std::function exec_func); + + /* Short function, including only the data exchange + * This function allows modification to the data exchange + * This is designed for internal implementing functions without external data than the + */ void set_command_execute_function(const ShellCommandId& cmd_id, - std::function exec_func); + std::function exec_func); + + /* Built-in function, including only the shell envoriment variables */ void set_command_execute_function(const ShellCommandId& cmd_id, std::function exec_func); + + /* Marco function, which directly call a macro function without command parsing */ void set_command_execute_function(const ShellCommandId& cmd_id, std::function exec_func); + void set_command_dependency(const ShellCommandId& cmd_id, const std::vector& cmd_dependency); ShellCommandClassId add_command_class(const char* name); @@ -126,7 +151,7 @@ class Shell { /* Execute a command, the command line is the user's input to launch a command * The common_context is the data structure to exchange data between commands */ - void execute_command(const char* cmd_line, T& common_context); + int execute_command(const char* cmd_line, T& common_context); private: /* Internal data */ /* Name of the shell, this will appear in the interactive mode */ std::string name_; @@ -162,10 +187,10 @@ class Shell { * 3. Built-in function, including only the shell envoriment variables * 4. Marco function, which directly call a macro function without command parsing */ - vtr::vector> command_const_execute_functions_; - vtr::vector> command_standard_execute_functions_; - vtr::vector> command_short_const_execute_functions_; - vtr::vector> command_short_execute_functions_; + vtr::vector> command_const_execute_functions_; + vtr::vector> command_standard_execute_functions_; + vtr::vector> command_short_const_execute_functions_; + vtr::vector> command_short_execute_functions_; vtr::vector> command_builtin_execute_functions_; vtr::vector> command_macro_execute_functions_; @@ -175,7 +200,7 @@ class Shell { vtr::vector command_execute_function_types_; /* A flag to indicate if the command has been executed */ - vtr::vector command_status_; + vtr::vector command_status_; /* Dependency graph for different commands, * This helps the shell interface to check if a command need other commands to be run before its execution diff --git a/libopenfpga/libopenfpgashell/src/shell.tpp b/libopenfpga/libopenfpgashell/src/shell.tpp index 5fe043f8e..69ec89ab9 100644 --- a/libopenfpga/libopenfpgashell/src/shell.tpp +++ b/libopenfpga/libopenfpgashell/src/shell.tpp @@ -131,7 +131,7 @@ ShellCommandId Shell::add_command(const Command& cmd, const char* descr) { command_short_execute_functions_.emplace_back(); command_builtin_execute_functions_.emplace_back(); command_macro_execute_functions_.emplace_back(); - command_status_.push_back(false); /* By default, the command should be marked as never executed */ + command_status_.push_back(CMD_EXEC_NONE); /* By default, the command should be marked as fatal error as it has been never executed */ command_dependencies_.emplace_back(); /* Register the name in the name2id map */ @@ -155,7 +155,7 @@ void Shell::set_command_class(const ShellCommandId& cmd_id, const ShellComman template void Shell::set_command_const_execute_function(const ShellCommandId& cmd_id, - std::function exec_func) { + std::function exec_func) { VTR_ASSERT(true == valid_command_id(cmd_id)); command_execute_function_types_[cmd_id] = CONST_STANDARD; command_const_execute_functions_[cmd_id] = exec_func; @@ -163,7 +163,7 @@ void Shell::set_command_const_execute_function(const ShellCommandId& cmd_id, template void Shell::set_command_execute_function(const ShellCommandId& cmd_id, - std::function exec_func) { + std::function exec_func) { VTR_ASSERT(true == valid_command_id(cmd_id)); command_execute_function_types_[cmd_id] = STANDARD; command_standard_execute_functions_[cmd_id] = exec_func; @@ -171,7 +171,7 @@ void Shell::set_command_execute_function(const ShellCommandId& cmd_id, template void Shell::set_command_const_execute_function(const ShellCommandId& cmd_id, - std::function exec_func) { + std::function exec_func) { VTR_ASSERT(true == valid_command_id(cmd_id)); command_execute_function_types_[cmd_id] = CONST_SHORT; command_short_const_execute_functions_[cmd_id] = exec_func; @@ -179,7 +179,7 @@ void Shell::set_command_const_execute_function(const ShellCommandId& cmd_id, template void Shell::set_command_execute_function(const ShellCommandId& cmd_id, - std::function exec_func) { + std::function exec_func) { VTR_ASSERT(true == valid_command_id(cmd_id)); command_execute_function_types_[cmd_id] = SHORT; command_short_execute_functions_[cmd_id] = exec_func; @@ -341,9 +341,15 @@ void Shell::run_script_mode(const char* script_file_name, T& context) { /* Process the command only when the full command line in ended */ if (!cmd_line.empty()) { VTR_LOG("\nCommand line to execute: %s\n", cmd_line.c_str()); - execute_command(cmd_line.c_str(), context); + int status = execute_command(cmd_line.c_str(), context); /* Empty the line ready to start a new line */ cmd_line.clear(); + + /* Check the execution status of the command, if fatal error happened, we should abort immediately */ + if (CMD_EXEC_FATAL_ERROR == status) { + VTR_LOG("Fatal error occurred!\nAbort and enter interactive mode\n"); + break; + } } } fp.close(); @@ -376,16 +382,49 @@ void Shell::print_commands() const { template void Shell::exit() const { + /* Check all the command status, if we see fatal errors or minor errors, we drop an error code */ + int exit_code = 0; + for (const int& status : command_status_) { + if ( (status == CMD_EXEC_FATAL_ERROR) + || (status == CMD_EXEC_MINOR_ERROR) ) { + exit_code = 1; + break; + } + } + + /* Show error message if we detect any errors */ + int num_err = 0; + if (0 != exit_code) { + VTR_LOG("\n"); + for (const ShellCommandId& cmd : commands()) { + if (command_status_[cmd] == CMD_EXEC_FATAL_ERROR) { + VTR_LOG_ERROR("Command '%s' execution has fatal errors\n", + commands_[cmd].name().c_str()); + num_err++; + } + + if (command_status_[cmd] == CMD_EXEC_MINOR_ERROR) { + VTR_LOG_ERROR("Command '%s' execution has minor errors\n", + commands_[cmd].name().c_str()); + num_err++; + } + } + } + + VTR_LOG("\nFinish execution with %d errors\n", + num_err); + VTR_LOG("\nThank you for using %s!\n", name().c_str()); - std::exit(0); + + std::exit(exit_code); } /************************************************************************ * Private executors ***********************************************************************/ template -void Shell::execute_command(const char* cmd_line, +int Shell::execute_command(const char* cmd_line, T& common_context) { /* Tokenize the line */ openfpga::StringToken tokenizer(cmd_line); @@ -396,17 +435,18 @@ void Shell::execute_command(const char* cmd_line, if (ShellCommandId::INVALID() == cmd_id) { VTR_LOG("Try to call a command '%s' which is not defined!\n", tokens[0].c_str()); - return; + return CMD_EXEC_FATAL_ERROR; } /* Check the dependency graph to see if all the prequistics have been met */ for (const ShellCommandId& dep_cmd : command_dependencies_[cmd_id]) { - if (false == command_status_[dep_cmd]) { + if ( (CMD_EXEC_NONE == command_status_[dep_cmd]) + || (CMD_EXEC_FATAL_ERROR == command_status_[dep_cmd]) ) { VTR_LOG("Command '%s' is required to be executed before command '%s'!\n", commands_[dep_cmd].name().c_str(), commands_[cmd_id].name().c_str()); /* Echo the command help desk */ print_command_options(commands_[cmd_id]); - return; + return CMD_EXEC_FATAL_ERROR; } } @@ -421,25 +461,22 @@ void Shell::execute_command(const char* cmd_line, argv[itok] = (char*)malloc((tokens[itok].length() + 1) * sizeof(char)); strcpy(argv[itok], tokens[itok].c_str()); } - /* Execute the marco function */ - command_macro_execute_functions_[cmd_id](tokens.size(), argv); + /* Execute the marco function and record the execution status */ + command_status_[cmd_id] = command_macro_execute_functions_[cmd_id](tokens.size(), argv); /* Free the argv */ for (size_t itok = 0; itok < tokens.size(); ++itok) { free(argv[itok]); } free(argv); - /* Change the status of the command */ - command_status_[cmd_id] = true; - /* Finish for macro command, return */ - return; + return command_status_[cmd_id]; } if (false == parse_command(tokens, commands_[cmd_id], command_contexts_[cmd_id])) { /* Echo the command */ print_command_options(commands_[cmd_id]); - return; + return CMD_EXEC_FATAL_ERROR; } /* Parse succeed. Let user to confirm selected options */ @@ -448,31 +485,38 @@ void Shell::execute_command(const char* cmd_line, /* Execute the command depending on the type of function ! */ switch (command_execute_function_types_[cmd_id]) { case CONST_STANDARD: - command_const_execute_functions_[cmd_id](common_context, commands_[cmd_id], command_contexts_[cmd_id]); + command_status_[cmd_id] = command_const_execute_functions_[cmd_id](common_context, commands_[cmd_id], command_contexts_[cmd_id]); break; case STANDARD: - command_standard_execute_functions_[cmd_id](common_context, commands_[cmd_id], command_contexts_[cmd_id]); + command_status_[cmd_id] = command_standard_execute_functions_[cmd_id](common_context, commands_[cmd_id], command_contexts_[cmd_id]); break; case CONST_SHORT: - command_short_const_execute_functions_[cmd_id](common_context); + command_status_[cmd_id] = command_short_const_execute_functions_[cmd_id](common_context); break; case SHORT: - command_short_execute_functions_[cmd_id](common_context); + command_status_[cmd_id] = command_short_execute_functions_[cmd_id](common_context); break; case BUILTIN: command_builtin_execute_functions_[cmd_id](); + /* Built-in execution is always correct */ + command_status_[cmd_id] = CMD_EXEC_SUCCESS; break; /* MACRO should be executed eariler in this function. It should not appear here */ default: /* This is not allowed! Error out */ - VTR_LOG("Invalid type of execute function for command '%s'!\n", - commands_[cmd_id].name().c_str()); + VTR_LOG_ERROR("Invalid type of execute function for command '%s'!\n", + commands_[cmd_id].name().c_str()); /* Exit the shell using the exit() function inside this class! */ - exit(); + return CMD_EXEC_FATAL_ERROR; } - /* Change the status of the command */ - command_status_[cmd_id] = true; + /* Forbid users to return the status CMD_EXEC_NONE */ + if (CMD_EXEC_NONE == command_status_[cmd_id]) { + VTR_LOG_ERROR("It is illegal to return never-executed status for an executed command!\n"); + return CMD_EXEC_FATAL_ERROR; + } + + return command_status_[cmd_id]; } /************************************************************************ diff --git a/libopenfpga/libopenfpgashell/test/test_shell.cpp b/libopenfpga/libopenfpgashell/test/test_shell.cpp index 649859d85..0edc257dd 100644 --- a/libopenfpga/libopenfpgashell/test/test_shell.cpp +++ b/libopenfpga/libopenfpgashell/test/test_shell.cpp @@ -15,16 +15,20 @@ class ShellContext { }; static -void shell_execute_set(ShellContext& context, +int shell_execute_set(ShellContext& context, const Command& cmd, const CommandContext& cmd_context) { CommandOptionId opt_id = cmd.option("value"); /* Get the value of a in the command context */ context.a = std::atoi(cmd_context.option_value(cmd, opt_id).c_str()); + + return CMD_EXEC_SUCCESS; } static -void shell_execute_print(ShellContext& context) { +int shell_execute_print(ShellContext& context) { VTR_LOG("a=%d\n", context.a); + + return CMD_EXEC_SUCCESS; } static @@ -35,7 +39,7 @@ int shell_execute_print_macro(int argc, char** argv) { VTR_LOG("\t[%d]: %s\n", iarg, argv[iarg]); } - return 0; + return CMD_EXEC_SUCCESS; } int main(int argc, char** argv) { diff --git a/libopenfpga/libopenfpgautil/src/openfpga_digest.cpp b/libopenfpga/libopenfpgautil/src/openfpga_digest.cpp index 4714700e4..3ae2083df 100644 --- a/libopenfpga/libopenfpgautil/src/openfpga_digest.cpp +++ b/libopenfpga/libopenfpgautil/src/openfpga_digest.cpp @@ -3,6 +3,7 @@ * in OpenFPGA framework *******************************************************************/ #include +#include #include /* Headers from vtrutil library */ @@ -117,37 +118,121 @@ std::string find_path_dir_name(const std::string& file_name) { /******************************************************************** * Create a directory with a given path ********************************************************************/ -bool create_dir_path(const char* dir_path) { - /* Give up if the path is empty */ - if (nullptr == dir_path) { - VTR_LOG_ERROR("dir_path is empty and nothing is created.\n"); - return false; - } +static +bool create_dir_path(const std::string& dir_path, + const bool& verbose) { + /* Give up if the path is empty */ + if (true == dir_path.empty()) { + VTR_LOG_ERROR("Directory path is empty and nothing will be created.\n"); + return false; + } - /* Try to create a directory */ - int ret = mkdir(dir_path, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH); + /* Try to create a directory */ + int ret = mkdir(dir_path.c_str(), S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH); - /* Analyze the return flag and output status */ - switch (ret) { - case 0: - VTR_LOG("Succeed to create directory '%s'\n", - dir_path); - return true; - case -1: - if (EEXIST == errno) { - VTR_LOG_WARN("Directory '%s' already exists. Will overwrite contents\n", - dir_path); - return true; - } - break; - default: - VTR_LOG_ERROR("Create directory '%s'...Failed!\n", - dir_path); - exit(1); - return false; + /* Analyze the return flag and output status */ + switch (ret) { + case 0: + VTR_LOGV(verbose, + "Succeed to create directory '%s'\n", + dir_path.c_str()); + return true; + case -1: + if (EEXIST == errno) { + VTR_LOGV_WARN(verbose, + "Directory '%s' already exists. Will overwrite contents\n", + dir_path.c_str()); + return true; + } + VTR_LOG_ERROR("Create directory '%s'...Failed!\n", + dir_path.c_str()); + exit(1); + break; + default: + VTR_LOG_ERROR("Create directory '%s'...Failed!\n", + dir_path.c_str()); + exit(1); + return false; } return false; } +/******************************************************************** + * Recursively create a directory with a given path + * The create_dir_path() function will only try to create a directory + * in the last level. If any parent directory is not created, it will + * always fail. + * This function will try to create all the parent directory before + * creating the last level. + ********************************************************************/ +static +bool rec_create_dir_path(const std::string& dir_path) { + /* Give up if the path is empty */ + if (true == dir_path.empty()) { + VTR_LOG_ERROR("Directory path is empty and nothing will be created.\n"); + return false; + } + + /* Try to find the positions of all the slashes + * which are the splitter between directories + */ + char back_slash = '/'; + +#ifdef _WIN32 +/* For windows OS, replace any '/' with '\' */ + char back_slash = '\\'; +#endif + + std::vector slash_pos; + + /* Keep searching until we reach the end of the string */ + for (size_t pos = 0; pos < dir_path.size(); ++pos) { + /* Skip the pos = 0, we should avoid creating any root directory */ + if ( (back_slash == dir_path.at(pos)) + && (0 != pos)) { + slash_pos.push_back(pos); + } + } + + /* Create directory by following the position of back slash + * For each back slash, create a sub string from the beginning + * and try to create directory + */ + for (const size_t& pos : slash_pos) { + std::string sub_dir = dir_path.substr(0, pos); + + /* Turn on verbose output only for the last position: the leaf directory */ + if (false == create_dir_path(sub_dir, &pos == &slash_pos.back())) { + return false; + } + } + + return true; +} + +/******************************************************************** + * Top function to create a directory with a given path + * Allow users to select if use the recursive way or not + * + * Strongly recommend to use the recursive way, as it can maximum + * guarantee the success in creation of directories + ********************************************************************/ +void create_directory(const std::string& dir_path, const bool& recursive) { + std::string formatted_dir_path = format_dir_path(dir_path); + bool status = false; + + if (true == recursive) { + status = rec_create_dir_path(formatted_dir_path); + } else { + status = create_dir_path(formatted_dir_path, true); + } + + if (false == status) { + VTR_LOG_ERROR("Fail to create directory '%s'\n", + formatted_dir_path.c_str()); + exit(1); + } +} + } /* namespace openfpga ends */ diff --git a/libopenfpga/libopenfpgautil/src/openfpga_digest.h b/libopenfpga/libopenfpgautil/src/openfpga_digest.h index 90af3dc4e..0e1cd5d76 100644 --- a/libopenfpga/libopenfpgautil/src/openfpga_digest.h +++ b/libopenfpga/libopenfpgautil/src/openfpga_digest.h @@ -23,7 +23,7 @@ std::string find_path_file_name(const std::string& file_name); std::string find_path_dir_name(const std::string& file_name); -bool create_dir_path(const char* dir_path); +void create_directory(const std::string& dir_path, const bool& recursive = true); } /* namespace openfpga ends */ diff --git a/openfpga/src/annotation/check_netlist_naming_conflict.cpp b/openfpga/src/annotation/check_netlist_naming_conflict.cpp index 3470c9f0a..a8ab94384 100644 --- a/openfpga/src/annotation/check_netlist_naming_conflict.cpp +++ b/openfpga/src/annotation/check_netlist_naming_conflict.cpp @@ -11,6 +11,9 @@ #include "vtr_assert.h" #include "vtr_log.h" +/* Headers from openfpgashell library */ +#include "command_exit_codes.h" + /* Headers from archopenfpga library */ #include "write_xml_utils.h" @@ -213,8 +216,8 @@ void print_netlist_naming_fix_report(const std::string& fname, * in the users' BLIF netlist that violates the syntax of OpenFPGA * fabric generator, i.e., Verilog generator and SPICE generator *******************************************************************/ -void check_netlist_naming_conflict(OpenfpgaContext& openfpga_context, - const Command& cmd, const CommandContext& cmd_context) { +int check_netlist_naming_conflict(OpenfpgaContext& openfpga_context, + const Command& cmd, const CommandContext& cmd_context) { vtr::ScopedStartFinishTimer timer("Check naming violations of netlist blocks and nets"); /* By default, we replace all the illegal characters with '_' */ @@ -231,7 +234,15 @@ void check_netlist_naming_conflict(OpenfpgaContext& openfpga_context, num_conflicts); VTR_LOGV(0 == num_conflicts, "Check naming conflicts in the netlist passed.\n"); - return; + + /* If we see conflicts, report minor error */ + if (0 < num_conflicts) { + return CMD_EXEC_MINOR_ERROR; + } + + /* Otherwise, we should see zero conflicts */ + VTR_ASSERT(0 == num_conflicts); + return CMD_EXEC_SUCCESS; } /* If the auto correction is enabled, we apply a fix */ @@ -248,6 +259,9 @@ void check_netlist_naming_conflict(OpenfpgaContext& openfpga_context, cmd_context.option_value(cmd, opt_report).c_str()); } } + + /* TODO: should identify the error code from internal function execution */ + return CMD_EXEC_SUCCESS; } } /* end namespace openfpga */ diff --git a/openfpga/src/annotation/check_netlist_naming_conflict.h b/openfpga/src/annotation/check_netlist_naming_conflict.h index 54d86bca4..cad6c3963 100644 --- a/openfpga/src/annotation/check_netlist_naming_conflict.h +++ b/openfpga/src/annotation/check_netlist_naming_conflict.h @@ -15,8 +15,8 @@ /* begin namespace openfpga */ namespace openfpga { -void check_netlist_naming_conflict(OpenfpgaContext& openfpga_context, - const Command& cmd, const CommandContext& cmd_context); +int check_netlist_naming_conflict(OpenfpgaContext& openfpga_context, + const Command& cmd, const CommandContext& cmd_context); } /* end namespace openfpga */ diff --git a/openfpga/src/annotation/write_xml_device_rr_gsb.cpp b/openfpga/src/annotation/write_xml_device_rr_gsb.cpp index 906c71d70..63c5454a7 100644 --- a/openfpga/src/annotation/write_xml_device_rr_gsb.cpp +++ b/openfpga/src/annotation/write_xml_device_rr_gsb.cpp @@ -182,7 +182,7 @@ void write_device_rr_gsb_to_xml(const char* sb_xml_dir, std::string xml_dir_name = format_dir_path(std::string(sb_xml_dir)); /* Create directories */ - create_dir_path(xml_dir_name.c_str()); + create_directory(xml_dir_name); vtr::Point sb_range = device_rr_gsb.get_gsb_range(); diff --git a/openfpga/src/base/openfpga_bitstream.cpp b/openfpga/src/base/openfpga_bitstream.cpp index e732dee92..7e2a19fc4 100644 --- a/openfpga/src/base/openfpga_bitstream.cpp +++ b/openfpga/src/base/openfpga_bitstream.cpp @@ -5,6 +5,9 @@ #include "vtr_time.h" #include "vtr_log.h" +/* Headers from openfpgashell library */ +#include "command_exit_codes.h" + /* Headers from openfpgautil library */ #include "openfpga_digest.h" @@ -22,8 +25,8 @@ namespace openfpga { /******************************************************************** * A wrapper function to call the build_device_bitstream() in FPGA bitstream *******************************************************************/ -void fpga_bitstream(OpenfpgaContext& openfpga_ctx, - const Command& cmd, const CommandContext& cmd_context) { +int fpga_bitstream(OpenfpgaContext& openfpga_ctx, + const Command& cmd, const CommandContext& cmd_context) { CommandOptionId opt_verbose = cmd.option("verbose"); CommandOptionId opt_file = cmd.option("file"); @@ -36,24 +39,30 @@ void fpga_bitstream(OpenfpgaContext& openfpga_ctx, std::string src_dir_path = find_path_dir_name(cmd_context.option_value(cmd, opt_file)); /* Create directories */ - create_dir_path(src_dir_path.c_str()); + create_directory(src_dir_path); write_arch_independent_bitstream_to_xml_file(openfpga_ctx.bitstream_manager(), cmd_context.option_value(cmd, opt_file)); } + + /* TODO: should identify the error code from internal function execution */ + return CMD_EXEC_SUCCESS; } /******************************************************************** * A wrapper function to call the build_fabric_bitstream() in FPGA bitstream *******************************************************************/ -void build_fabric_bitstream(OpenfpgaContext& openfpga_ctx, - const Command& cmd, const CommandContext& cmd_context) { +int build_fabric_bitstream(OpenfpgaContext& openfpga_ctx, + const Command& cmd, const CommandContext& cmd_context) { CommandOptionId opt_verbose = cmd.option("verbose"); openfpga_ctx.mutable_fabric_bitstream() = build_fabric_dependent_bitstream(openfpga_ctx.bitstream_manager(), openfpga_ctx.module_graph(), cmd_context.option_enable(cmd, opt_verbose)); + + /* TODO: should identify the error code from internal function execution */ + return CMD_EXEC_SUCCESS; } } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_bitstream.h b/openfpga/src/base/openfpga_bitstream.h index 9dc2ad471..58f1c7e86 100644 --- a/openfpga/src/base/openfpga_bitstream.h +++ b/openfpga/src/base/openfpga_bitstream.h @@ -15,11 +15,11 @@ /* begin namespace openfpga */ namespace openfpga { -void fpga_bitstream(OpenfpgaContext& openfpga_ctx, - const Command& cmd, const CommandContext& cmd_context); +int fpga_bitstream(OpenfpgaContext& openfpga_ctx, + const Command& cmd, const CommandContext& cmd_context); -void build_fabric_bitstream(OpenfpgaContext& openfpga_ctx, - const Command& cmd, const CommandContext& cmd_context); +int build_fabric_bitstream(OpenfpgaContext& openfpga_ctx, + const Command& cmd, const CommandContext& cmd_context); } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_build_fabric.cpp b/openfpga/src/base/openfpga_build_fabric.cpp index 4e8b44916..67203216a 100644 --- a/openfpga/src/base/openfpga_build_fabric.cpp +++ b/openfpga/src/base/openfpga_build_fabric.cpp @@ -5,6 +5,9 @@ #include "vtr_time.h" #include "vtr_log.h" +/* Headers from openfpgashell library */ +#include "command_exit_codes.h" + #include "device_rr_gsb.h" #include "device_rr_gsb_utils.h" #include "build_device_module.h" @@ -56,8 +59,8 @@ void compress_routing_hierarchy(OpenfpgaContext& openfpga_ctx, /******************************************************************** * Build the module graph for FPGA device *******************************************************************/ -void build_fabric(OpenfpgaContext& openfpga_ctx, - const Command& cmd, const CommandContext& cmd_context) { +int build_fabric(OpenfpgaContext& openfpga_ctx, + const Command& cmd, const CommandContext& cmd_context) { CommandOptionId opt_compress_routing = cmd.option("compress_routing"); CommandOptionId opt_duplicate_grid_pin = cmd.option("duplicate_grid_pin"); @@ -77,6 +80,9 @@ void build_fabric(OpenfpgaContext& openfpga_ctx, cmd_context.option_enable(cmd, opt_compress_routing), cmd_context.option_enable(cmd, opt_duplicate_grid_pin), cmd_context.option_enable(cmd, opt_verbose)); + + /* TODO: should identify the error code from internal function execution */ + return CMD_EXEC_SUCCESS; } } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_build_fabric.h b/openfpga/src/base/openfpga_build_fabric.h index 824ed63a1..3b63c7ab2 100644 --- a/openfpga/src/base/openfpga_build_fabric.h +++ b/openfpga/src/base/openfpga_build_fabric.h @@ -15,8 +15,8 @@ /* begin namespace openfpga */ namespace openfpga { -void build_fabric(OpenfpgaContext& openfpga_ctx, - const Command& cmd, const CommandContext& cmd_context); +int build_fabric(OpenfpgaContext& openfpga_ctx, + const Command& cmd, const CommandContext& cmd_context); } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_link_arch.cpp b/openfpga/src/base/openfpga_link_arch.cpp index 34c98ee8d..65aef7cf8 100644 --- a/openfpga/src/base/openfpga_link_arch.cpp +++ b/openfpga/src/base/openfpga_link_arch.cpp @@ -8,6 +8,9 @@ #include "vtr_assert.h" #include "vtr_log.h" +/* Headers from openfpgashell library */ +#include "command_exit_codes.h" + /* Headers from vpr library */ #include "read_activity.h" @@ -59,8 +62,8 @@ bool is_vpr_rr_graph_supported(const RRGraph& rr_graph) { * - physical pb_graph nodes and pb_graph pins * - circuit models for global routing architecture *******************************************************************/ -void link_arch(OpenfpgaContext& openfpga_ctx, - const Command& cmd, const CommandContext& cmd_context) { +int link_arch(OpenfpgaContext& openfpga_ctx, + const Command& cmd, const CommandContext& cmd_context) { vtr::ScopedStartFinishTimer timer("Link OpenFPGA architecture to VPR architecture"); @@ -105,7 +108,7 @@ void link_arch(OpenfpgaContext& openfpga_ctx, * - DeviceRRGSB */ if (false == is_vpr_rr_graph_supported(g_vpr_ctx.device().rr_graph)) { - return; + return CMD_EXEC_FATAL_ERROR; } annotate_device_rr_gsb(g_vpr_ctx.device(), @@ -147,6 +150,9 @@ void link_arch(OpenfpgaContext& openfpga_ctx, annotate_simulation_setting(g_vpr_ctx.atom(), openfpga_ctx.net_activity(), openfpga_ctx.mutable_arch().sim_setting); + + /* TODO: should identify the error code from internal function execution */ + return CMD_EXEC_SUCCESS; } } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_link_arch.h b/openfpga/src/base/openfpga_link_arch.h index 742c29541..8eba64386 100644 --- a/openfpga/src/base/openfpga_link_arch.h +++ b/openfpga/src/base/openfpga_link_arch.h @@ -15,8 +15,8 @@ /* begin namespace openfpga */ namespace openfpga { -void link_arch(OpenfpgaContext& openfpga_context, - const Command& cmd, const CommandContext& cmd_context); +int link_arch(OpenfpgaContext& openfpga_context, + const Command& cmd, const CommandContext& cmd_context); } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_lut_truth_table_fixup.cpp b/openfpga/src/base/openfpga_lut_truth_table_fixup.cpp index 45ecbca31..396842dcd 100644 --- a/openfpga/src/base/openfpga_lut_truth_table_fixup.cpp +++ b/openfpga/src/base/openfpga_lut_truth_table_fixup.cpp @@ -7,6 +7,9 @@ #include "vtr_assert.h" #include "vtr_log.h" +/* Headers from openfpgashell library */ +#include "command_exit_codes.h" + /* Headers from vpr library */ #include "vpr_utils.h" @@ -182,7 +185,6 @@ void update_lut_tt_with_post_packing_results(const AtomContext& atom_ctx, } } - /******************************************************************** * Top-level function to fix up the lut truth table results after packing is done * The problem comes from a mismatch between the packing results and @@ -194,8 +196,8 @@ void update_lut_tt_with_post_packing_results(const AtomContext& atom_ctx, * This function aims to fix the mess after packing so that the truth table * can be synchronized *******************************************************************/ -void lut_truth_table_fixup(OpenfpgaContext& openfpga_context, - const Command& cmd, const CommandContext& cmd_context) { +int lut_truth_table_fixup(OpenfpgaContext& openfpga_context, + const Command& cmd, const CommandContext& cmd_context) { vtr::ScopedStartFinishTimer timer("Fix up LUT truth tables after packing optimization"); @@ -206,6 +208,9 @@ void lut_truth_table_fixup(OpenfpgaContext& openfpga_context, g_vpr_ctx.clustering(), openfpga_context.mutable_vpr_clustering_annotation(), cmd_context.option_enable(cmd, opt_verbose)); + + /* TODO: should identify the error code from internal function execution */ + return CMD_EXEC_SUCCESS; } } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_lut_truth_table_fixup.h b/openfpga/src/base/openfpga_lut_truth_table_fixup.h index f11abc7fb..d685a4b44 100644 --- a/openfpga/src/base/openfpga_lut_truth_table_fixup.h +++ b/openfpga/src/base/openfpga_lut_truth_table_fixup.h @@ -15,8 +15,8 @@ /* begin namespace openfpga */ namespace openfpga { -void lut_truth_table_fixup(OpenfpgaContext& openfpga_context, - const Command& cmd, const CommandContext& cmd_context); +int lut_truth_table_fixup(OpenfpgaContext& openfpga_context, + const Command& cmd, const CommandContext& cmd_context); } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_pb_pin_fixup.cpp b/openfpga/src/base/openfpga_pb_pin_fixup.cpp index cc91bdebe..2a8686190 100644 --- a/openfpga/src/base/openfpga_pb_pin_fixup.cpp +++ b/openfpga/src/base/openfpga_pb_pin_fixup.cpp @@ -7,6 +7,9 @@ #include "vtr_assert.h" #include "vtr_log.h" +/* Headers from openfpgashell library */ +#include "command_exit_codes.h" + /* Headers from vpr library */ #include "vpr_utils.h" @@ -254,8 +257,8 @@ void update_pb_pin_with_post_routing_results(const DeviceContext& device_ctx, * This function aims to fix the mess after routing so that the net mapping * can be synchronized *******************************************************************/ -void pb_pin_fixup(OpenfpgaContext& openfpga_context, - const Command& cmd, const CommandContext& cmd_context) { +int pb_pin_fixup(OpenfpgaContext& openfpga_context, + const Command& cmd, const CommandContext& cmd_context) { vtr::ScopedStartFinishTimer timer("Fix up pb pin mapping results after routing optimization"); @@ -268,6 +271,9 @@ void pb_pin_fixup(OpenfpgaContext& openfpga_context, openfpga_context.vpr_routing_annotation(), openfpga_context.mutable_vpr_clustering_annotation(), cmd_context.option_enable(cmd, opt_verbose)); + + /* TODO: should identify the error code from internal function execution */ + return CMD_EXEC_SUCCESS; } } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_pb_pin_fixup.h b/openfpga/src/base/openfpga_pb_pin_fixup.h index e924c6067..bab4e9565 100644 --- a/openfpga/src/base/openfpga_pb_pin_fixup.h +++ b/openfpga/src/base/openfpga_pb_pin_fixup.h @@ -15,8 +15,8 @@ /* begin namespace openfpga */ namespace openfpga { -void pb_pin_fixup(OpenfpgaContext& openfpga_context, - const Command& cmd, const CommandContext& cmd_context); +int pb_pin_fixup(OpenfpgaContext& openfpga_context, + const Command& cmd, const CommandContext& cmd_context); } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_read_arch.cpp b/openfpga/src/base/openfpga_read_arch.cpp index 1a36e85a3..214af1612 100644 --- a/openfpga/src/base/openfpga_read_arch.cpp +++ b/openfpga/src/base/openfpga_read_arch.cpp @@ -5,6 +5,9 @@ /* Headers from vtrutil library */ #include "vtr_log.h" +/* Headers from openfpgashell library */ +#include "command_exit_codes.h" + /* Headers from archopenfpga library */ #include "read_xml_openfpga_arch.h" #include "check_circuit_library.h" @@ -22,8 +25,8 @@ namespace openfpga { * The command will accept an option '--file' which is the architecture * file provided by users *******************************************************************/ -void read_arch(OpenfpgaContext& openfpga_context, - const Command& cmd, const CommandContext& cmd_context) { +int read_arch(OpenfpgaContext& openfpga_context, + const Command& cmd, const CommandContext& cmd_context) { /* Check the option '--file' is enabled or not * Actually, it must be enabled as the shell interface will check * before reaching this fuction @@ -44,6 +47,9 @@ void read_arch(OpenfpgaContext& openfpga_context, * 3. Simulation settings (TODO) */ check_circuit_library(openfpga_context.arch().circuit_lib); + + /* TODO: should identify the error code from internal function execution */ + return CMD_EXEC_SUCCESS; } /******************************************************************** @@ -53,8 +59,8 @@ void read_arch(OpenfpgaContext& openfpga_context, * The command will accept an option '--file' which is the architecture * file provided by users *******************************************************************/ -void write_arch(const OpenfpgaContext& openfpga_context, - const Command& cmd, const CommandContext& cmd_context) { +int write_arch(const OpenfpgaContext& openfpga_context, + const Command& cmd, const CommandContext& cmd_context) { /* Check the option '--file' is enabled or not * Actually, it must be enabled as the shell interface will check * before reaching this fuction @@ -68,6 +74,9 @@ void write_arch(const OpenfpgaContext& openfpga_context, VTR_LOG("Writing XML architecture to '%s'...\n", arch_file_name.c_str()); write_xml_openfpga_arch(arch_file_name.c_str(), openfpga_context.arch()); + + /* TODO: should identify the error code from internal function execution */ + return CMD_EXEC_SUCCESS; } } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_read_arch.h b/openfpga/src/base/openfpga_read_arch.h index dcc04d77a..b664a7b3e 100644 --- a/openfpga/src/base/openfpga_read_arch.h +++ b/openfpga/src/base/openfpga_read_arch.h @@ -15,11 +15,11 @@ /* begin namespace openfpga */ namespace openfpga { -void read_arch(OpenfpgaContext& openfpga_context, - const Command& cmd, const CommandContext& cmd_context); +int read_arch(OpenfpgaContext& openfpga_context, + const Command& cmd, const CommandContext& cmd_context); -void write_arch(const OpenfpgaContext& openfpga_context, - const Command& cmd, const CommandContext& cmd_context); +int write_arch(const OpenfpgaContext& openfpga_context, + const Command& cmd, const CommandContext& cmd_context); } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_repack.cpp b/openfpga/src/base/openfpga_repack.cpp index 91c6b4798..fe0529d04 100644 --- a/openfpga/src/base/openfpga_repack.cpp +++ b/openfpga/src/base/openfpga_repack.cpp @@ -5,6 +5,9 @@ #include "vtr_time.h" #include "vtr_log.h" +/* Headers from openfpgashell library */ +#include "command_exit_codes.h" + #include "build_physical_truth_table.h" #include "repack.h" #include "openfpga_repack.h" @@ -18,8 +21,8 @@ namespace openfpga { /******************************************************************** * A wrapper function to call the fabric_verilog function of FPGA-Verilog *******************************************************************/ -void repack(OpenfpgaContext& openfpga_ctx, - const Command& cmd, const CommandContext& cmd_context) { +int repack(OpenfpgaContext& openfpga_ctx, + const Command& cmd, const CommandContext& cmd_context) { CommandOptionId opt_verbose = cmd.option("verbose"); @@ -35,6 +38,9 @@ void repack(OpenfpgaContext& openfpga_ctx, g_vpr_ctx.clustering(), openfpga_ctx.vpr_device_annotation(), openfpga_ctx.arch().circuit_lib); + + /* TODO: should identify the error code from internal function execution */ + return CMD_EXEC_SUCCESS; } } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_repack.h b/openfpga/src/base/openfpga_repack.h index 0fce62f78..83e4bce63 100644 --- a/openfpga/src/base/openfpga_repack.h +++ b/openfpga/src/base/openfpga_repack.h @@ -15,8 +15,8 @@ /* begin namespace openfpga */ namespace openfpga { -void repack(OpenfpgaContext& openfpga_ctx, - const Command& cmd, const CommandContext& cmd_context); +int repack(OpenfpgaContext& openfpga_ctx, + const Command& cmd, const CommandContext& cmd_context); } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_sdc.cpp b/openfpga/src/base/openfpga_sdc.cpp index cb2e1bf72..21a3ab8fb 100644 --- a/openfpga/src/base/openfpga_sdc.cpp +++ b/openfpga/src/base/openfpga_sdc.cpp @@ -5,6 +5,9 @@ #include "vtr_time.h" #include "vtr_log.h" +/* Headers from openfpgashell library */ +#include "command_exit_codes.h" + /* Headers from openfpgautil library */ #include "openfpga_digest.h" @@ -22,8 +25,8 @@ namespace openfpga { /******************************************************************** * A wrapper function to call the PnR SDC generator of FPGA-SDC *******************************************************************/ -void write_pnr_sdc(OpenfpgaContext& openfpga_ctx, - const Command& cmd, const CommandContext& cmd_context) { +int write_pnr_sdc(OpenfpgaContext& openfpga_ctx, + const Command& cmd, const CommandContext& cmd_context) { CommandOptionId opt_output_dir = cmd.option("file"); CommandOptionId opt_constrain_global_port = cmd.option("constrain_global_port"); @@ -42,7 +45,7 @@ void write_pnr_sdc(OpenfpgaContext& openfpga_ctx, std::string sdc_dir_path = format_dir_path(cmd_context.option_value(cmd, opt_output_dir)); /* Create directories */ - create_dir_path(sdc_dir_path.c_str()); + create_directory(sdc_dir_path); PnrSdcOption options(sdc_dir_path); @@ -80,13 +83,16 @@ void write_pnr_sdc(OpenfpgaContext& openfpga_ctx, global_ports, openfpga_ctx.flow_manager().compress_routing()); } + + /* TODO: should identify the error code from internal function execution */ + return CMD_EXEC_SUCCESS; } /******************************************************************** * A wrapper function to call the analysis SDC generator of FPGA-SDC *******************************************************************/ -void write_analysis_sdc(OpenfpgaContext& openfpga_ctx, - const Command& cmd, const CommandContext& cmd_context) { +int write_analysis_sdc(OpenfpgaContext& openfpga_ctx, + const Command& cmd, const CommandContext& cmd_context) { CommandOptionId opt_output_dir = cmd.option("file"); @@ -96,7 +102,7 @@ void write_analysis_sdc(OpenfpgaContext& openfpga_ctx, std::string sdc_dir_path = format_dir_path(cmd_context.option_value(cmd, opt_output_dir)); /* Create directories */ - create_dir_path(sdc_dir_path.c_str()); + create_directory(sdc_dir_path); AnalysisSdcOption options(sdc_dir_path); options.set_generate_sdc_analysis(true); @@ -114,6 +120,9 @@ void write_analysis_sdc(OpenfpgaContext& openfpga_ctx, global_ports, openfpga_ctx.flow_manager().compress_routing()); } + + /* TODO: should identify the error code from internal function execution */ + return CMD_EXEC_SUCCESS; } } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_sdc.h b/openfpga/src/base/openfpga_sdc.h index 110a8cd72..99a87f899 100644 --- a/openfpga/src/base/openfpga_sdc.h +++ b/openfpga/src/base/openfpga_sdc.h @@ -15,11 +15,11 @@ /* begin namespace openfpga */ namespace openfpga { -void write_pnr_sdc(OpenfpgaContext& openfpga_ctx, - const Command& cmd, const CommandContext& cmd_context); +int write_pnr_sdc(OpenfpgaContext& openfpga_ctx, + const Command& cmd, const CommandContext& cmd_context); -void write_analysis_sdc(OpenfpgaContext& openfpga_ctx, - const Command& cmd, const CommandContext& cmd_context); +int write_analysis_sdc(OpenfpgaContext& openfpga_ctx, + const Command& cmd, const CommandContext& cmd_context); } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_verilog.cpp b/openfpga/src/base/openfpga_verilog.cpp index 1ce23a1d4..c79b68fc2 100644 --- a/openfpga/src/base/openfpga_verilog.cpp +++ b/openfpga/src/base/openfpga_verilog.cpp @@ -5,6 +5,9 @@ #include "vtr_time.h" #include "vtr_log.h" +/* Headers from openfpgashell library */ +#include "command_exit_codes.h" + #include "verilog_api.h" #include "openfpga_verilog.h" @@ -17,8 +20,8 @@ namespace openfpga { /******************************************************************** * A wrapper function to call the fabric Verilog generator of FPGA-Verilog *******************************************************************/ -void write_fabric_verilog(OpenfpgaContext& openfpga_ctx, - const Command& cmd, const CommandContext& cmd_context) { +int write_fabric_verilog(OpenfpgaContext& openfpga_ctx, + const Command& cmd, const CommandContext& cmd_context) { CommandOptionId opt_output_dir = cmd.option("file"); CommandOptionId opt_explicit_port_mapping = cmd.option("explicit_port_mapping"); @@ -48,13 +51,16 @@ void write_fabric_verilog(OpenfpgaContext& openfpga_ctx, openfpga_ctx.vpr_device_annotation(), openfpga_ctx.device_rr_gsb(), options); + + /* TODO: should identify the error code from internal function execution */ + return CMD_EXEC_SUCCESS; } /******************************************************************** * A wrapper function to call the Verilog testbench generator of FPGA-Verilog *******************************************************************/ -void write_verilog_testbench(OpenfpgaContext& openfpga_ctx, - const Command& cmd, const CommandContext& cmd_context) { +int write_verilog_testbench(OpenfpgaContext& openfpga_ctx, + const Command& cmd, const CommandContext& cmd_context) { CommandOptionId opt_output_dir = cmd.option("file"); CommandOptionId opt_reference_benchmark = cmd.option("reference_benchmark_file_path"); @@ -87,6 +93,9 @@ void write_verilog_testbench(OpenfpgaContext& openfpga_ctx, openfpga_ctx.arch().sim_setting, openfpga_ctx.arch().config_protocol.type(), options); + + /* TODO: should identify the error code from internal function execution */ + return CMD_EXEC_SUCCESS; } } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_verilog.h b/openfpga/src/base/openfpga_verilog.h index faf8cf6b0..096039aab 100644 --- a/openfpga/src/base/openfpga_verilog.h +++ b/openfpga/src/base/openfpga_verilog.h @@ -15,11 +15,11 @@ /* begin namespace openfpga */ namespace openfpga { -void write_fabric_verilog(OpenfpgaContext& openfpga_ctx, - const Command& cmd, const CommandContext& cmd_context); +int write_fabric_verilog(OpenfpgaContext& openfpga_ctx, + const Command& cmd, const CommandContext& cmd_context); -void write_verilog_testbench(OpenfpgaContext& openfpga_ctx, - const Command& cmd, const CommandContext& cmd_context); +int write_verilog_testbench(OpenfpgaContext& openfpga_ctx, + const Command& cmd, const CommandContext& cmd_context); } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_write_gsb.cpp b/openfpga/src/base/openfpga_write_gsb.cpp index 9c367ebfb..cdb833c75 100644 --- a/openfpga/src/base/openfpga_write_gsb.cpp +++ b/openfpga/src/base/openfpga_write_gsb.cpp @@ -5,6 +5,9 @@ #include "vtr_time.h" #include "vtr_log.h" +/* Headers from openfpgashell library */ +#include "command_exit_codes.h" + #include "write_xml_device_rr_gsb.h" #include "openfpga_write_gsb.h" @@ -19,8 +22,8 @@ namespace openfpga { * Write internal structrure of all the General Switch Blocks (GSBs) * to an XML file *******************************************************************/ -void write_gsb(const OpenfpgaContext& openfpga_ctx, - const Command& cmd, const CommandContext& cmd_context) { +int write_gsb(const OpenfpgaContext& openfpga_ctx, + const Command& cmd, const CommandContext& cmd_context) { /* Check the option '--file' is enabled or not * Actually, it must be enabled as the shell interface will check @@ -38,6 +41,9 @@ void write_gsb(const OpenfpgaContext& openfpga_ctx, g_vpr_ctx.device().rr_graph, openfpga_ctx.device_rr_gsb(), cmd_context.option_enable(cmd, opt_verbose)); + + /* TODO: should identify the error code from internal function execution */ + return CMD_EXEC_SUCCESS; } } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_write_gsb.h b/openfpga/src/base/openfpga_write_gsb.h index 4f7110717..206e6cd5a 100644 --- a/openfpga/src/base/openfpga_write_gsb.h +++ b/openfpga/src/base/openfpga_write_gsb.h @@ -15,8 +15,8 @@ /* begin namespace openfpga */ namespace openfpga { -void write_gsb(const OpenfpgaContext& openfpga_ctx, - const Command& cmd, const CommandContext& cmd_context); +int write_gsb(const OpenfpgaContext& openfpga_ctx, + const Command& cmd, const CommandContext& cmd_context); } /* end namespace openfpga */ diff --git a/openfpga/src/fabric/build_grid_modules.cpp b/openfpga/src/fabric/build_grid_modules.cpp index 95e435f6f..0b693fcec 100644 --- a/openfpga/src/fabric/build_grid_modules.cpp +++ b/openfpga/src/fabric/build_grid_modules.cpp @@ -306,22 +306,17 @@ void build_primitive_block_module(ModuleManager& module_manager, /* Find the inout ports required by the primitive node, and add them to the module * This is mainly due to the I/O blocks, which have inout ports for the top-level fabric */ - if (CIRCUIT_MODEL_IOPAD == circuit_lib.model_type(primitive_model)) { - std::vector primitive_model_inout_ports = circuit_lib.model_ports_by_type(primitive_model, CIRCUIT_MODEL_PORT_INOUT); - for (auto port : primitive_model_inout_ports) { + for (const auto& port : circuit_lib.model_global_ports(primitive_model, false)) { + if ( (CIRCUIT_MODEL_PORT_INOUT == circuit_lib.port_type(port)) + && (true == circuit_lib.port_is_io(port)) ) { add_primitive_module_fpga_global_io_port(module_manager, primitive_module, logic_module, logic_instance_id, ModuleManager::MODULE_GPIO_PORT, circuit_lib, primitive_model, port); - } - } - - /* Find the other i/o ports required by the primitive node, and add them to the module */ - for (const auto& port : circuit_lib.model_global_ports(primitive_model, false)) { - if ( (CIRCUIT_MODEL_PORT_INPUT == circuit_lib.port_type(port)) - && (true == circuit_lib.port_is_io(port)) ) { + } else if ( (CIRCUIT_MODEL_PORT_INPUT == circuit_lib.port_type(port)) + && (true == circuit_lib.port_is_io(port)) ) { add_primitive_module_fpga_global_io_port(module_manager, primitive_module, logic_module, logic_instance_id, ModuleManager::MODULE_GPIN_PORT, diff --git a/openfpga/src/fpga_sdc/analysis_sdc_writer.cpp b/openfpga/src/fpga_sdc/analysis_sdc_writer.cpp index c188dedd8..584f6e63f 100644 --- a/openfpga/src/fpga_sdc/analysis_sdc_writer.cpp +++ b/openfpga/src/fpga_sdc/analysis_sdc_writer.cpp @@ -203,6 +203,12 @@ void print_analysis_sdc_disable_global_ports(std::fstream& fp, continue; } + /* Skip any gpio port here! */ + if ( (CIRCUIT_MODEL_PORT_INOUT == circuit_lib.port_type(global_port)) + && (true == circuit_lib.port_is_io(global_port)) ) { + continue; + } + ModulePortId module_port = module_manager.find_module_port(top_module, circuit_lib.port_prefix(global_port)); BasicPort port_to_disable = module_manager.module_port(top_module, module_port); diff --git a/openfpga/src/fpga_verilog/verilog_api.cpp b/openfpga/src/fpga_verilog/verilog_api.cpp index dc332db58..c37b68888 100644 --- a/openfpga/src/fpga_verilog/verilog_api.cpp +++ b/openfpga/src/fpga_verilog/verilog_api.cpp @@ -63,19 +63,19 @@ void fpga_fabric_verilog(ModuleManager& module_manager, std::string src_dir_path = format_dir_path(options.output_directory()); /* Create directories */ - create_dir_path(src_dir_path.c_str()); + create_directory(src_dir_path); /* Sub directory under SRC directory to contain all the primitive block netlists */ std::string submodule_dir_path = src_dir_path + std::string(DEFAULT_SUBMODULE_DIR_NAME); - create_dir_path(submodule_dir_path.c_str()); + create_directory(submodule_dir_path); /* Sub directory under SRC directory to contain all the logic block netlists */ std::string lb_dir_path = src_dir_path + std::string(DEFAULT_LB_DIR_NAME); - create_dir_path(lb_dir_path.c_str()); + create_directory(lb_dir_path); /* Sub directory under SRC directory to contain all the routing block netlists */ std::string rr_dir_path = src_dir_path + std::string(DEFAULT_RR_DIR_NAME); - create_dir_path(rr_dir_path.c_str()); + create_directory(rr_dir_path); /* Print Verilog files containing preprocessing flags */ print_verilog_preprocessing_flags_netlist(std::string(src_dir_path), @@ -153,7 +153,7 @@ void fpga_verilog_testbench(const ModuleManager& module_manager, std::string netlist_name = atom_ctx.nlist.netlist_name(); /* Create directories */ - create_dir_path(src_dir_path.c_str()); + create_directory(src_dir_path); /* TODO: check if this works here. This function was in fabric generator */ print_verilog_simulation_preprocessing_flags(std::string(src_dir_path), diff --git a/openfpga/src/utils/module_manager_utils.cpp b/openfpga/src/utils/module_manager_utils.cpp index 64bef2e88..a57e97261 100644 --- a/openfpga/src/utils/module_manager_utils.cpp +++ b/openfpga/src/utils/module_manager_utils.cpp @@ -37,8 +37,9 @@ ModuleId add_circuit_model_to_module_manager(ModuleManager& module_manager, /* Add ports */ /* Find global ports and add one by one - * Global input ports will be considered as global port in the context of module manager - * Global output ports will be considered as spy port in the context of module manager + * Non-I/O Global input ports will be considered as global port to be shorted wired in the context of module manager + * I/O Global output ports will be considered as general purpose output port in the context of module manager + * I/O Global inout ports will be considered as general purpose i/o port in the context of module manager */ for (const auto& port : circuit_lib.model_global_ports(circuit_model, false)) { BasicPort port_info(circuit_lib.port_prefix(port), circuit_lib.port_size(port)); @@ -50,9 +51,12 @@ ModuleId add_circuit_model_to_module_manager(ModuleManager& module_manager, } else if ( (CIRCUIT_MODEL_PORT_INPUT == circuit_lib.port_type(port)) && (true == circuit_lib.port_is_io(port)) ) { module_manager.add_port(module, port_info, ModuleManager::MODULE_GPIN_PORT); - } else { - VTR_ASSERT(CIRCUIT_MODEL_PORT_OUTPUT == circuit_lib.port_type(port)); + } else if (CIRCUIT_MODEL_PORT_OUTPUT == circuit_lib.port_type(port)) { + VTR_ASSERT(true == circuit_lib.port_is_io(port)); module_manager.add_port(module, port_info, ModuleManager::MODULE_GPOUT_PORT); + } else if ( (CIRCUIT_MODEL_PORT_INOUT == circuit_lib.port_type(port)) + && (true == circuit_lib.port_is_io(port)) ) { + module_manager.add_port(module, port_info, ModuleManager::MODULE_GPIO_PORT); } } diff --git a/openfpga/test_openfpga_arch/k6_N10_40nm_openfpga.xml b/openfpga/test_openfpga_arch/k6_N10_40nm_openfpga.xml index 17eb8b550..de0602e1e 100644 --- a/openfpga/test_openfpga_arch/k6_N10_40nm_openfpga.xml +++ b/openfpga/test_openfpga_arch/k6_N10_40nm_openfpga.xml @@ -156,7 +156,7 @@ - + diff --git a/openfpga/test_openfpga_arch/k6_frac_N10_40nm_openfpga.xml b/openfpga/test_openfpga_arch/k6_frac_N10_40nm_openfpga.xml index c43614ae8..51e250a8a 100644 --- a/openfpga/test_openfpga_arch/k6_frac_N10_40nm_openfpga.xml +++ b/openfpga/test_openfpga_arch/k6_frac_N10_40nm_openfpga.xml @@ -173,7 +173,7 @@ - + diff --git a/openfpga/test_openfpga_arch/k6_frac_N10_adder_chain_40nm_openfpga.xml b/openfpga/test_openfpga_arch/k6_frac_N10_adder_chain_40nm_openfpga.xml index cf619cd27..ae08c8250 100644 --- a/openfpga/test_openfpga_arch/k6_frac_N10_adder_chain_40nm_openfpga.xml +++ b/openfpga/test_openfpga_arch/k6_frac_N10_adder_chain_40nm_openfpga.xml @@ -174,7 +174,7 @@ - + diff --git a/openfpga/test_openfpga_arch/k6_frac_N10_adder_chain_mem16K_40nm_openfpga.xml b/openfpga/test_openfpga_arch/k6_frac_N10_adder_chain_mem16K_40nm_openfpga.xml index 4ddf1dd0b..cb145e06d 100644 --- a/openfpga/test_openfpga_arch/k6_frac_N10_adder_chain_mem16K_40nm_openfpga.xml +++ b/openfpga/test_openfpga_arch/k6_frac_N10_adder_chain_mem16K_40nm_openfpga.xml @@ -174,7 +174,7 @@ - + diff --git a/openfpga/test_openfpga_arch/k6_frac_N10_adder_chain_mem16K_aib_40nm_openfpga.xml b/openfpga/test_openfpga_arch/k6_frac_N10_adder_chain_mem16K_aib_40nm_openfpga.xml index f0e84e167..e65851291 100644 --- a/openfpga/test_openfpga_arch/k6_frac_N10_adder_chain_mem16K_aib_40nm_openfpga.xml +++ b/openfpga/test_openfpga_arch/k6_frac_N10_adder_chain_mem16K_aib_40nm_openfpga.xml @@ -174,7 +174,7 @@ - + @@ -209,7 +209,7 @@ - + diff --git a/openfpga/test_openfpga_arch/k6_frac_N10_adder_column_chain_40nm_openfpga.xml b/openfpga/test_openfpga_arch/k6_frac_N10_adder_column_chain_40nm_openfpga.xml index d70ebcb2d..65117d199 100644 --- a/openfpga/test_openfpga_arch/k6_frac_N10_adder_column_chain_40nm_openfpga.xml +++ b/openfpga/test_openfpga_arch/k6_frac_N10_adder_column_chain_40nm_openfpga.xml @@ -174,7 +174,7 @@ - + diff --git a/openfpga/test_openfpga_arch/k6_frac_N10_adder_register_chain_40nm_openfpga.xml b/openfpga/test_openfpga_arch/k6_frac_N10_adder_register_chain_40nm_openfpga.xml index 81a9582dc..779880dea 100644 --- a/openfpga/test_openfpga_arch/k6_frac_N10_adder_register_chain_40nm_openfpga.xml +++ b/openfpga/test_openfpga_arch/k6_frac_N10_adder_register_chain_40nm_openfpga.xml @@ -174,7 +174,7 @@ - + diff --git a/openfpga/test_openfpga_arch/k6_frac_N10_adder_register_scan_chain_40nm_openfpga.xml b/openfpga/test_openfpga_arch/k6_frac_N10_adder_register_scan_chain_40nm_openfpga.xml index 840a2e3bb..621847439 100644 --- a/openfpga/test_openfpga_arch/k6_frac_N10_adder_register_scan_chain_40nm_openfpga.xml +++ b/openfpga/test_openfpga_arch/k6_frac_N10_adder_register_scan_chain_40nm_openfpga.xml @@ -179,7 +179,7 @@ - + diff --git a/openfpga/test_openfpga_arch/k6_frac_N10_spyio_40nm_openfpga.xml b/openfpga/test_openfpga_arch/k6_frac_N10_spyio_40nm_openfpga.xml index 547c742c8..159214507 100644 --- a/openfpga/test_openfpga_arch/k6_frac_N10_spyio_40nm_openfpga.xml +++ b/openfpga/test_openfpga_arch/k6_frac_N10_spyio_40nm_openfpga.xml @@ -173,11 +173,11 @@ - + - - - + + + diff --git a/openfpga/test_openfpga_arch/k6_frac_N10_stdcell_mux_40nm_openfpga.xml b/openfpga/test_openfpga_arch/k6_frac_N10_stdcell_mux_40nm_openfpga.xml index d3e3d1f6c..59f493a13 100644 --- a/openfpga/test_openfpga_arch/k6_frac_N10_stdcell_mux_40nm_openfpga.xml +++ b/openfpga/test_openfpga_arch/k6_frac_N10_stdcell_mux_40nm_openfpga.xml @@ -165,7 +165,7 @@ - + diff --git a/openfpga/test_openfpga_arch/k6_frac_N10_tree_mux_40nm_openfpga.xml b/openfpga/test_openfpga_arch/k6_frac_N10_tree_mux_40nm_openfpga.xml index 8052fb2dc..d04318510 100644 --- a/openfpga/test_openfpga_arch/k6_frac_N10_tree_mux_40nm_openfpga.xml +++ b/openfpga/test_openfpga_arch/k6_frac_N10_tree_mux_40nm_openfpga.xml @@ -164,7 +164,7 @@ - +