Merge remote-tracking branch 'lnis_origin/dev' into ganesh_dev

This commit is contained in:
ganeshgore 2020-04-08 18:40:39 -06:00
commit 8267d78b01
55 changed files with 607 additions and 185 deletions

View File

@ -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. - ``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. - ``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:: 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``. .. 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
<port type="input" is_global="true" is_io="false"/>
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
<port type="inout" is_global="true" is_io="false"/>
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
<port type="input" is_global="true" is_io="true"/>
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
<port type="inout" is_global="true" is_io="true"/>
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
<port type="output" is_global="true" is_io="true"/>
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -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 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 .. option:: --file or -f
Launch OpenFPGA in script mode where users write commands in scripts and FPGA will execute them Launch OpenFPGA in script mode where users write commands in scripts and FPGA will execute them

View File

@ -194,7 +194,7 @@ FPGA-SDC
- ``--constrain_zero_delay_paths`` Constrain all the zero-delay paths in FPGA fabric - ``--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 - ``--verbose`` Enable verbose output

View File

@ -4,8 +4,20 @@ OpenFPGA Script Format
---------------------- ----------------------
OpenFPGA accepts a simplified tcl-like 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. The following is an example.
@ -21,7 +33,8 @@ The following is an example.
#write_openfpga_arch -f ./arch_echo.xml #write_openfpga_arch -f ./arch_echo.xml
# Annotate the OpenFPGA architecture to VPR data base # 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 and correct any naming conflicts in the BLIF netlist
check_netlist_naming_conflict --fix --report ./netlist_renaming.xml check_netlist_naming_conflict --fix --report ./netlist_renaming.xml
@ -35,7 +48,8 @@ The following is an example.
# Build the module graph # Build the module graph
# - Enabled compression on routing architecture modules # - Enabled compression on routing architecture modules
# - Enable pin duplication on grid 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 # Repack the netlist to physical pbs
# This must be done before bitstream generator and testbench generation # This must be done before bitstream generator and testbench generation
@ -44,14 +58,21 @@ The following is an example.
# Build the bitstream # Build the bitstream
# - Output the fabric-independent bitstream to a file # - 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-dependent bitstream
build_fabric_bitstream --verbose build_fabric_bitstream --verbose
# Write the Verilog netlist for FPGA fabric # Write the Verilog netlist for FPGA fabric
# - Enable the use of explicit port mapping in Verilog netlist # - 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 # Write the Verilog testbench for FPGA fabric
# - We suggest the use of same output directory as fabric Verilog netlists # - 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 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 # - 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 # - 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 # Write the SDC files for PnR backend
# - Turn on every options here # - Turn on every options here

View File

@ -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 */ /* Check set/reset/config_enable ports: make sure they are all global ports */
for (const auto& port : circuit_lib.ports()) { for (const auto& port : circuit_lib.ports()) {
if ( ( (circuit_lib.port_is_set(port)) if ( ( (circuit_lib.port_is_set(port))

View File

@ -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. /* Identify if the port is for io, this is only applicable to INPUT ports.
* By default, it will NOT be a mode selection port * 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, "is_io", loc_data, pugiutil::ReqOpt::OPTIONAL).as_bool(false));
circuit_lib.set_port_is_io(port, get_attribute(xml_port, "io", loc_data, pugiutil::ReqOpt::OPTIONAL).as_bool(false));
}
/* Identify if the port is for mode selection, this is only applicable to SRAM ports. /* 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 * By default, it will NOT be a mode selection port

View File

@ -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

View File

@ -10,6 +10,7 @@
#include "vtr_range.h" #include "vtr_range.h"
#include "command.h" #include "command.h"
#include "command_context.h" #include "command_context.h"
#include "command_exit_codes.h"
#include "shell_fwd.h" #include "shell_fwd.h"
/* Begin namespace openfpga */ /* Begin namespace openfpga */
@ -88,25 +89,49 @@ class Shell {
ShellCommandId add_command(const Command& cmd, const char* descr); ShellCommandId add_command(const Command& cmd, const char* descr);
void set_command_class(const ShellCommandId& cmd_id, const ShellCommandClassId& cmd_class_id); void set_command_class(const ShellCommandId& cmd_id, const ShellCommandClassId& cmd_class_id);
/* Link the execute function to a command /* Link the execute function to a command
* We support here three types of functions to be executed in the shell * We support here different types of functions to be executed in the shell
* 1. Standard function, including the data exchange <T> and commands
* 2. Short function, including only the data exchange <T>
* 3. Built-in function, including only the shell envoriment variables
* 4. Marco function, which directly call a macro function without command parsing
* Users just need to specify the function object and its type will be automatically inferred * 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 <T> and commands
* This function requires the data exchange <T> to be constant
* This is designed for outputting functions requiring external data than the <T>
*/ */
void set_command_const_execute_function(const ShellCommandId& cmd_id, void set_command_const_execute_function(const ShellCommandId& cmd_id,
std::function<void(const T&, const Command&, const CommandContext&)> exec_func); std::function<int(const T&, const Command&, const CommandContext&)> exec_func);
/* Standard function, including the data exchange <T> and commands
* This function allows modification to the data exchange <T>
* This is designed for implementing functions requiring external data than the <T>
*/
void set_command_execute_function(const ShellCommandId& cmd_id, void set_command_execute_function(const ShellCommandId& cmd_id,
std::function<void(T&, const Command&, const CommandContext&)> exec_func); std::function<int(T&, const Command&, const CommandContext&)> exec_func);
/* Short function, including only the data exchange <T>
* This function requires the data exchange <T> to be constant
* This is designed for outputting functions without external data than the <T>
*/
void set_command_const_execute_function(const ShellCommandId& cmd_id, void set_command_const_execute_function(const ShellCommandId& cmd_id,
std::function<void(const T&)> exec_func); std::function<int(const T&)> exec_func);
/* Short function, including only the data exchange <T>
* This function allows modification to the data exchange <T>
* This is designed for internal implementing functions without external data than the <T>
*/
void set_command_execute_function(const ShellCommandId& cmd_id, void set_command_execute_function(const ShellCommandId& cmd_id,
std::function<void(T&)> exec_func); std::function<int(T&)> exec_func);
/* Built-in function, including only the shell envoriment variables */
void set_command_execute_function(const ShellCommandId& cmd_id, void set_command_execute_function(const ShellCommandId& cmd_id,
std::function<void()> exec_func); std::function<void()> exec_func);
/* Marco function, which directly call a macro function without command parsing */
void set_command_execute_function(const ShellCommandId& cmd_id, void set_command_execute_function(const ShellCommandId& cmd_id,
std::function<int(int, char**)> exec_func); std::function<int(int, char**)> exec_func);
void set_command_dependency(const ShellCommandId& cmd_id, void set_command_dependency(const ShellCommandId& cmd_id,
const std::vector<ShellCommandId>& cmd_dependency); const std::vector<ShellCommandId>& cmd_dependency);
ShellCommandClassId add_command_class(const char* name); 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 /* 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 * 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 */ private: /* Internal data */
/* Name of the shell, this will appear in the interactive mode */ /* Name of the shell, this will appear in the interactive mode */
std::string name_; std::string name_;
@ -162,10 +187,10 @@ class Shell {
* 3. Built-in function, including only the shell envoriment variables * 3. Built-in function, including only the shell envoriment variables
* 4. Marco function, which directly call a macro function without command parsing * 4. Marco function, which directly call a macro function without command parsing
*/ */
vtr::vector<ShellCommandId, std::function<void(const T&, const Command&, const CommandContext&)>> command_const_execute_functions_; vtr::vector<ShellCommandId, std::function<int(const T&, const Command&, const CommandContext&)>> command_const_execute_functions_;
vtr::vector<ShellCommandId, std::function<void(T&, const Command&, const CommandContext&)>> command_standard_execute_functions_; vtr::vector<ShellCommandId, std::function<int(T&, const Command&, const CommandContext&)>> command_standard_execute_functions_;
vtr::vector<ShellCommandId, std::function<void(const T&)>> command_short_const_execute_functions_; vtr::vector<ShellCommandId, std::function<int(const T&)>> command_short_const_execute_functions_;
vtr::vector<ShellCommandId, std::function<void(T&)>> command_short_execute_functions_; vtr::vector<ShellCommandId, std::function<int(T&)>> command_short_execute_functions_;
vtr::vector<ShellCommandId, std::function<void()>> command_builtin_execute_functions_; vtr::vector<ShellCommandId, std::function<void()>> command_builtin_execute_functions_;
vtr::vector<ShellCommandId, std::function<int(int, char**)>> command_macro_execute_functions_; vtr::vector<ShellCommandId, std::function<int(int, char**)>> command_macro_execute_functions_;
@ -175,7 +200,7 @@ class Shell {
vtr::vector<ShellCommandId, e_exec_func_type> command_execute_function_types_; vtr::vector<ShellCommandId, e_exec_func_type> command_execute_function_types_;
/* A flag to indicate if the command has been executed */ /* A flag to indicate if the command has been executed */
vtr::vector<ShellCommandId, bool> command_status_; vtr::vector<ShellCommandId, int> command_status_;
/* Dependency graph for different commands, /* Dependency graph for different commands,
* This helps the shell interface to check if a command need other commands to be run before its execution * This helps the shell interface to check if a command need other commands to be run before its execution

View File

@ -131,7 +131,7 @@ ShellCommandId Shell<T>::add_command(const Command& cmd, const char* descr) {
command_short_execute_functions_.emplace_back(); command_short_execute_functions_.emplace_back();
command_builtin_execute_functions_.emplace_back(); command_builtin_execute_functions_.emplace_back();
command_macro_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(); command_dependencies_.emplace_back();
/* Register the name in the name2id map */ /* Register the name in the name2id map */
@ -155,7 +155,7 @@ void Shell<T>::set_command_class(const ShellCommandId& cmd_id, const ShellComman
template<class T> template<class T>
void Shell<T>::set_command_const_execute_function(const ShellCommandId& cmd_id, void Shell<T>::set_command_const_execute_function(const ShellCommandId& cmd_id,
std::function<void(const T&, const Command&, const CommandContext&)> exec_func) { std::function<int(const T&, const Command&, const CommandContext&)> exec_func) {
VTR_ASSERT(true == valid_command_id(cmd_id)); VTR_ASSERT(true == valid_command_id(cmd_id));
command_execute_function_types_[cmd_id] = CONST_STANDARD; command_execute_function_types_[cmd_id] = CONST_STANDARD;
command_const_execute_functions_[cmd_id] = exec_func; command_const_execute_functions_[cmd_id] = exec_func;
@ -163,7 +163,7 @@ void Shell<T>::set_command_const_execute_function(const ShellCommandId& cmd_id,
template<class T> template<class T>
void Shell<T>::set_command_execute_function(const ShellCommandId& cmd_id, void Shell<T>::set_command_execute_function(const ShellCommandId& cmd_id,
std::function<void(T&, const Command&, const CommandContext&)> exec_func) { std::function<int(T&, const Command&, const CommandContext&)> exec_func) {
VTR_ASSERT(true == valid_command_id(cmd_id)); VTR_ASSERT(true == valid_command_id(cmd_id));
command_execute_function_types_[cmd_id] = STANDARD; command_execute_function_types_[cmd_id] = STANDARD;
command_standard_execute_functions_[cmd_id] = exec_func; command_standard_execute_functions_[cmd_id] = exec_func;
@ -171,7 +171,7 @@ void Shell<T>::set_command_execute_function(const ShellCommandId& cmd_id,
template<class T> template<class T>
void Shell<T>::set_command_const_execute_function(const ShellCommandId& cmd_id, void Shell<T>::set_command_const_execute_function(const ShellCommandId& cmd_id,
std::function<void(const T&)> exec_func) { std::function<int(const T&)> exec_func) {
VTR_ASSERT(true == valid_command_id(cmd_id)); VTR_ASSERT(true == valid_command_id(cmd_id));
command_execute_function_types_[cmd_id] = CONST_SHORT; command_execute_function_types_[cmd_id] = CONST_SHORT;
command_short_const_execute_functions_[cmd_id] = exec_func; command_short_const_execute_functions_[cmd_id] = exec_func;
@ -179,7 +179,7 @@ void Shell<T>::set_command_const_execute_function(const ShellCommandId& cmd_id,
template<class T> template<class T>
void Shell<T>::set_command_execute_function(const ShellCommandId& cmd_id, void Shell<T>::set_command_execute_function(const ShellCommandId& cmd_id,
std::function<void(T&)> exec_func) { std::function<int(T&)> exec_func) {
VTR_ASSERT(true == valid_command_id(cmd_id)); VTR_ASSERT(true == valid_command_id(cmd_id));
command_execute_function_types_[cmd_id] = SHORT; command_execute_function_types_[cmd_id] = SHORT;
command_short_execute_functions_[cmd_id] = exec_func; command_short_execute_functions_[cmd_id] = exec_func;
@ -341,9 +341,15 @@ void Shell<T>::run_script_mode(const char* script_file_name, T& context) {
/* Process the command only when the full command line in ended */ /* Process the command only when the full command line in ended */
if (!cmd_line.empty()) { if (!cmd_line.empty()) {
VTR_LOG("\nCommand line to execute: %s\n", cmd_line.c_str()); 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 */ /* Empty the line ready to start a new line */
cmd_line.clear(); 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(); fp.close();
@ -376,16 +382,49 @@ void Shell<T>::print_commands() const {
template <class T> template <class T>
void Shell<T>::exit() const { void Shell<T>::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", VTR_LOG("\nThank you for using %s!\n",
name().c_str()); name().c_str());
std::exit(0);
std::exit(exit_code);
} }
/************************************************************************ /************************************************************************
* Private executors * Private executors
***********************************************************************/ ***********************************************************************/
template <class T> template <class T>
void Shell<T>::execute_command(const char* cmd_line, int Shell<T>::execute_command(const char* cmd_line,
T& common_context) { T& common_context) {
/* Tokenize the line */ /* Tokenize the line */
openfpga::StringToken tokenizer(cmd_line); openfpga::StringToken tokenizer(cmd_line);
@ -396,17 +435,18 @@ void Shell<T>::execute_command(const char* cmd_line,
if (ShellCommandId::INVALID() == cmd_id) { if (ShellCommandId::INVALID() == cmd_id) {
VTR_LOG("Try to call a command '%s' which is not defined!\n", VTR_LOG("Try to call a command '%s' which is not defined!\n",
tokens[0].c_str()); tokens[0].c_str());
return; return CMD_EXEC_FATAL_ERROR;
} }
/* Check the dependency graph to see if all the prequistics have been met */ /* Check the dependency graph to see if all the prequistics have been met */
for (const ShellCommandId& dep_cmd : command_dependencies_[cmd_id]) { 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", 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()); commands_[dep_cmd].name().c_str(), commands_[cmd_id].name().c_str());
/* Echo the command help desk */ /* Echo the command help desk */
print_command_options(commands_[cmd_id]); print_command_options(commands_[cmd_id]);
return; return CMD_EXEC_FATAL_ERROR;
} }
} }
@ -421,25 +461,22 @@ void Shell<T>::execute_command(const char* cmd_line,
argv[itok] = (char*)malloc((tokens[itok].length() + 1) * sizeof(char)); argv[itok] = (char*)malloc((tokens[itok].length() + 1) * sizeof(char));
strcpy(argv[itok], tokens[itok].c_str()); strcpy(argv[itok], tokens[itok].c_str());
} }
/* Execute the marco function */ /* Execute the marco function and record the execution status */
command_macro_execute_functions_[cmd_id](tokens.size(), argv); command_status_[cmd_id] = command_macro_execute_functions_[cmd_id](tokens.size(), argv);
/* Free the argv */ /* Free the argv */
for (size_t itok = 0; itok < tokens.size(); ++itok) { for (size_t itok = 0; itok < tokens.size(); ++itok) {
free(argv[itok]); free(argv[itok]);
} }
free(argv); free(argv);
/* Change the status of the command */
command_status_[cmd_id] = true;
/* Finish for macro command, return */ /* Finish for macro command, return */
return; return command_status_[cmd_id];
} }
if (false == parse_command(tokens, commands_[cmd_id], command_contexts_[cmd_id])) { if (false == parse_command(tokens, commands_[cmd_id], command_contexts_[cmd_id])) {
/* Echo the command */ /* Echo the command */
print_command_options(commands_[cmd_id]); print_command_options(commands_[cmd_id]);
return; return CMD_EXEC_FATAL_ERROR;
} }
/* Parse succeed. Let user to confirm selected options */ /* Parse succeed. Let user to confirm selected options */
@ -448,31 +485,38 @@ void Shell<T>::execute_command(const char* cmd_line,
/* Execute the command depending on the type of function ! */ /* Execute the command depending on the type of function ! */
switch (command_execute_function_types_[cmd_id]) { switch (command_execute_function_types_[cmd_id]) {
case CONST_STANDARD: 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; break;
case STANDARD: 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; break;
case CONST_SHORT: 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; break;
case SHORT: case SHORT:
command_short_execute_functions_[cmd_id](common_context); command_status_[cmd_id] = command_short_execute_functions_[cmd_id](common_context);
break; break;
case BUILTIN: case BUILTIN:
command_builtin_execute_functions_[cmd_id](); command_builtin_execute_functions_[cmd_id]();
/* Built-in execution is always correct */
command_status_[cmd_id] = CMD_EXEC_SUCCESS;
break; break;
/* MACRO should be executed eariler in this function. It should not appear here */ /* MACRO should be executed eariler in this function. It should not appear here */
default: default:
/* This is not allowed! Error out */ /* This is not allowed! Error out */
VTR_LOG("Invalid type of execute function for command '%s'!\n", VTR_LOG_ERROR("Invalid type of execute function for command '%s'!\n",
commands_[cmd_id].name().c_str()); commands_[cmd_id].name().c_str());
/* Exit the shell using the exit() function inside this class! */ /* Exit the shell using the exit() function inside this class! */
exit(); return CMD_EXEC_FATAL_ERROR;
} }
/* Change the status of the command */ /* Forbid users to return the status CMD_EXEC_NONE */
command_status_[cmd_id] = true; 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];
} }
/************************************************************************ /************************************************************************

View File

@ -15,16 +15,20 @@ class ShellContext {
}; };
static static
void shell_execute_set(ShellContext& context, int shell_execute_set(ShellContext& context,
const Command& cmd, const CommandContext& cmd_context) { const Command& cmd, const CommandContext& cmd_context) {
CommandOptionId opt_id = cmd.option("value"); CommandOptionId opt_id = cmd.option("value");
/* Get the value of a in the command context */ /* Get the value of a in the command context */
context.a = std::atoi(cmd_context.option_value(cmd, opt_id).c_str()); context.a = std::atoi(cmd_context.option_value(cmd, opt_id).c_str());
return CMD_EXEC_SUCCESS;
} }
static static
void shell_execute_print(ShellContext& context) { int shell_execute_print(ShellContext& context) {
VTR_LOG("a=%d\n", context.a); VTR_LOG("a=%d\n", context.a);
return CMD_EXEC_SUCCESS;
} }
static static
@ -35,7 +39,7 @@ int shell_execute_print_macro(int argc, char** argv) {
VTR_LOG("\t[%d]: %s\n", iarg, argv[iarg]); VTR_LOG("\t[%d]: %s\n", iarg, argv[iarg]);
} }
return 0; return CMD_EXEC_SUCCESS;
} }
int main(int argc, char** argv) { int main(int argc, char** argv) {

View File

@ -3,6 +3,7 @@
* in OpenFPGA framework * in OpenFPGA framework
*******************************************************************/ *******************************************************************/
#include <sys/stat.h> #include <sys/stat.h>
#include <vector>
#include <algorithm> #include <algorithm>
/* Headers from vtrutil library */ /* 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 * Create a directory with a given path
********************************************************************/ ********************************************************************/
bool create_dir_path(const char* dir_path) { static
/* Give up if the path is empty */ bool create_dir_path(const std::string& dir_path,
if (nullptr == dir_path) { const bool& verbose) {
VTR_LOG_ERROR("dir_path is empty and nothing is created.\n"); /* Give up if the path is empty */
return false; 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 */ /* Try to create a directory */
int ret = mkdir(dir_path, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH); int ret = mkdir(dir_path.c_str(), S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH);
/* Analyze the return flag and output status */ /* Analyze the return flag and output status */
switch (ret) { switch (ret) {
case 0: case 0:
VTR_LOG("Succeed to create directory '%s'\n", VTR_LOGV(verbose,
dir_path); "Succeed to create directory '%s'\n",
return true; dir_path.c_str());
case -1: return true;
if (EEXIST == errno) { case -1:
VTR_LOG_WARN("Directory '%s' already exists. Will overwrite contents\n", if (EEXIST == errno) {
dir_path); VTR_LOGV_WARN(verbose,
return true; "Directory '%s' already exists. Will overwrite contents\n",
} dir_path.c_str());
break; return true;
default: }
VTR_LOG_ERROR("Create directory '%s'...Failed!\n", VTR_LOG_ERROR("Create directory '%s'...Failed!\n",
dir_path); dir_path.c_str());
exit(1); exit(1);
return false; break;
default:
VTR_LOG_ERROR("Create directory '%s'...Failed!\n",
dir_path.c_str());
exit(1);
return false;
} }
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<size_t> 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 */ } /* namespace openfpga ends */

View File

@ -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); 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 */ } /* namespace openfpga ends */

View File

@ -11,6 +11,9 @@
#include "vtr_assert.h" #include "vtr_assert.h"
#include "vtr_log.h" #include "vtr_log.h"
/* Headers from openfpgashell library */
#include "command_exit_codes.h"
/* Headers from archopenfpga library */ /* Headers from archopenfpga library */
#include "write_xml_utils.h" #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 * in the users' BLIF netlist that violates the syntax of OpenFPGA
* fabric generator, i.e., Verilog generator and SPICE generator * fabric generator, i.e., Verilog generator and SPICE generator
*******************************************************************/ *******************************************************************/
void check_netlist_naming_conflict(OpenfpgaContext& openfpga_context, int check_netlist_naming_conflict(OpenfpgaContext& openfpga_context,
const Command& cmd, const CommandContext& cmd_context) { const Command& cmd, const CommandContext& cmd_context) {
vtr::ScopedStartFinishTimer timer("Check naming violations of netlist blocks and nets"); vtr::ScopedStartFinishTimer timer("Check naming violations of netlist blocks and nets");
/* By default, we replace all the illegal characters with '_' */ /* By default, we replace all the illegal characters with '_' */
@ -231,7 +234,15 @@ void check_netlist_naming_conflict(OpenfpgaContext& openfpga_context,
num_conflicts); num_conflicts);
VTR_LOGV(0 == num_conflicts, VTR_LOGV(0 == num_conflicts,
"Check naming conflicts in the netlist passed.\n"); "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 */ /* 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()); 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 */ } /* end namespace openfpga */

View File

@ -15,8 +15,8 @@
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
void check_netlist_naming_conflict(OpenfpgaContext& openfpga_context, int check_netlist_naming_conflict(OpenfpgaContext& openfpga_context,
const Command& cmd, const CommandContext& cmd_context); const Command& cmd, const CommandContext& cmd_context);
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -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)); std::string xml_dir_name = format_dir_path(std::string(sb_xml_dir));
/* Create directories */ /* Create directories */
create_dir_path(xml_dir_name.c_str()); create_directory(xml_dir_name);
vtr::Point<size_t> sb_range = device_rr_gsb.get_gsb_range(); vtr::Point<size_t> sb_range = device_rr_gsb.get_gsb_range();

View File

@ -5,6 +5,9 @@
#include "vtr_time.h" #include "vtr_time.h"
#include "vtr_log.h" #include "vtr_log.h"
/* Headers from openfpgashell library */
#include "command_exit_codes.h"
/* Headers from openfpgautil library */ /* Headers from openfpgautil library */
#include "openfpga_digest.h" #include "openfpga_digest.h"
@ -22,8 +25,8 @@ namespace openfpga {
/******************************************************************** /********************************************************************
* A wrapper function to call the build_device_bitstream() in FPGA bitstream * A wrapper function to call the build_device_bitstream() in FPGA bitstream
*******************************************************************/ *******************************************************************/
void fpga_bitstream(OpenfpgaContext& openfpga_ctx, int fpga_bitstream(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context) { const Command& cmd, const CommandContext& cmd_context) {
CommandOptionId opt_verbose = cmd.option("verbose"); CommandOptionId opt_verbose = cmd.option("verbose");
CommandOptionId opt_file = cmd.option("file"); 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)); std::string src_dir_path = find_path_dir_name(cmd_context.option_value(cmd, opt_file));
/* Create directories */ /* 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(), write_arch_independent_bitstream_to_xml_file(openfpga_ctx.bitstream_manager(),
cmd_context.option_value(cmd, opt_file)); 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 * A wrapper function to call the build_fabric_bitstream() in FPGA bitstream
*******************************************************************/ *******************************************************************/
void build_fabric_bitstream(OpenfpgaContext& openfpga_ctx, int build_fabric_bitstream(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context) { const Command& cmd, const CommandContext& cmd_context) {
CommandOptionId opt_verbose = cmd.option("verbose"); CommandOptionId opt_verbose = cmd.option("verbose");
openfpga_ctx.mutable_fabric_bitstream() = build_fabric_dependent_bitstream(openfpga_ctx.bitstream_manager(), openfpga_ctx.mutable_fabric_bitstream() = build_fabric_dependent_bitstream(openfpga_ctx.bitstream_manager(),
openfpga_ctx.module_graph(), openfpga_ctx.module_graph(),
cmd_context.option_enable(cmd, opt_verbose)); cmd_context.option_enable(cmd, opt_verbose));
/* TODO: should identify the error code from internal function execution */
return CMD_EXEC_SUCCESS;
} }
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -15,11 +15,11 @@
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
void fpga_bitstream(OpenfpgaContext& openfpga_ctx, int fpga_bitstream(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context); const Command& cmd, const CommandContext& cmd_context);
void build_fabric_bitstream(OpenfpgaContext& openfpga_ctx, int build_fabric_bitstream(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context); const Command& cmd, const CommandContext& cmd_context);
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -5,6 +5,9 @@
#include "vtr_time.h" #include "vtr_time.h"
#include "vtr_log.h" #include "vtr_log.h"
/* Headers from openfpgashell library */
#include "command_exit_codes.h"
#include "device_rr_gsb.h" #include "device_rr_gsb.h"
#include "device_rr_gsb_utils.h" #include "device_rr_gsb_utils.h"
#include "build_device_module.h" #include "build_device_module.h"
@ -56,8 +59,8 @@ void compress_routing_hierarchy(OpenfpgaContext& openfpga_ctx,
/******************************************************************** /********************************************************************
* Build the module graph for FPGA device * Build the module graph for FPGA device
*******************************************************************/ *******************************************************************/
void build_fabric(OpenfpgaContext& openfpga_ctx, int build_fabric(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context) { const Command& cmd, const CommandContext& cmd_context) {
CommandOptionId opt_compress_routing = cmd.option("compress_routing"); CommandOptionId opt_compress_routing = cmd.option("compress_routing");
CommandOptionId opt_duplicate_grid_pin = cmd.option("duplicate_grid_pin"); 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_compress_routing),
cmd_context.option_enable(cmd, opt_duplicate_grid_pin), cmd_context.option_enable(cmd, opt_duplicate_grid_pin),
cmd_context.option_enable(cmd, opt_verbose)); cmd_context.option_enable(cmd, opt_verbose));
/* TODO: should identify the error code from internal function execution */
return CMD_EXEC_SUCCESS;
} }
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -15,8 +15,8 @@
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
void build_fabric(OpenfpgaContext& openfpga_ctx, int build_fabric(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context); const Command& cmd, const CommandContext& cmd_context);
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -8,6 +8,9 @@
#include "vtr_assert.h" #include "vtr_assert.h"
#include "vtr_log.h" #include "vtr_log.h"
/* Headers from openfpgashell library */
#include "command_exit_codes.h"
/* Headers from vpr library */ /* Headers from vpr library */
#include "read_activity.h" #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 * - physical pb_graph nodes and pb_graph pins
* - circuit models for global routing architecture * - circuit models for global routing architecture
*******************************************************************/ *******************************************************************/
void link_arch(OpenfpgaContext& openfpga_ctx, int link_arch(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context) { const Command& cmd, const CommandContext& cmd_context) {
vtr::ScopedStartFinishTimer timer("Link OpenFPGA architecture to VPR architecture"); vtr::ScopedStartFinishTimer timer("Link OpenFPGA architecture to VPR architecture");
@ -105,7 +108,7 @@ void link_arch(OpenfpgaContext& openfpga_ctx,
* - DeviceRRGSB * - DeviceRRGSB
*/ */
if (false == is_vpr_rr_graph_supported(g_vpr_ctx.device().rr_graph)) { 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(), 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(), annotate_simulation_setting(g_vpr_ctx.atom(),
openfpga_ctx.net_activity(), openfpga_ctx.net_activity(),
openfpga_ctx.mutable_arch().sim_setting); openfpga_ctx.mutable_arch().sim_setting);
/* TODO: should identify the error code from internal function execution */
return CMD_EXEC_SUCCESS;
} }
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -15,8 +15,8 @@
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
void link_arch(OpenfpgaContext& openfpga_context, int link_arch(OpenfpgaContext& openfpga_context,
const Command& cmd, const CommandContext& cmd_context); const Command& cmd, const CommandContext& cmd_context);
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -7,6 +7,9 @@
#include "vtr_assert.h" #include "vtr_assert.h"
#include "vtr_log.h" #include "vtr_log.h"
/* Headers from openfpgashell library */
#include "command_exit_codes.h"
/* Headers from vpr library */ /* Headers from vpr library */
#include "vpr_utils.h" #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 * 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 * 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 * This function aims to fix the mess after packing so that the truth table
* can be synchronized * can be synchronized
*******************************************************************/ *******************************************************************/
void lut_truth_table_fixup(OpenfpgaContext& openfpga_context, int lut_truth_table_fixup(OpenfpgaContext& openfpga_context,
const Command& cmd, const CommandContext& cmd_context) { const Command& cmd, const CommandContext& cmd_context) {
vtr::ScopedStartFinishTimer timer("Fix up LUT truth tables after packing optimization"); 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(), g_vpr_ctx.clustering(),
openfpga_context.mutable_vpr_clustering_annotation(), openfpga_context.mutable_vpr_clustering_annotation(),
cmd_context.option_enable(cmd, opt_verbose)); cmd_context.option_enable(cmd, opt_verbose));
/* TODO: should identify the error code from internal function execution */
return CMD_EXEC_SUCCESS;
} }
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -15,8 +15,8 @@
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
void lut_truth_table_fixup(OpenfpgaContext& openfpga_context, int lut_truth_table_fixup(OpenfpgaContext& openfpga_context,
const Command& cmd, const CommandContext& cmd_context); const Command& cmd, const CommandContext& cmd_context);
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -7,6 +7,9 @@
#include "vtr_assert.h" #include "vtr_assert.h"
#include "vtr_log.h" #include "vtr_log.h"
/* Headers from openfpgashell library */
#include "command_exit_codes.h"
/* Headers from vpr library */ /* Headers from vpr library */
#include "vpr_utils.h" #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 * This function aims to fix the mess after routing so that the net mapping
* can be synchronized * can be synchronized
*******************************************************************/ *******************************************************************/
void pb_pin_fixup(OpenfpgaContext& openfpga_context, int pb_pin_fixup(OpenfpgaContext& openfpga_context,
const Command& cmd, const CommandContext& cmd_context) { const Command& cmd, const CommandContext& cmd_context) {
vtr::ScopedStartFinishTimer timer("Fix up pb pin mapping results after routing optimization"); 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.vpr_routing_annotation(),
openfpga_context.mutable_vpr_clustering_annotation(), openfpga_context.mutable_vpr_clustering_annotation(),
cmd_context.option_enable(cmd, opt_verbose)); cmd_context.option_enable(cmd, opt_verbose));
/* TODO: should identify the error code from internal function execution */
return CMD_EXEC_SUCCESS;
} }
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -15,8 +15,8 @@
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
void pb_pin_fixup(OpenfpgaContext& openfpga_context, int pb_pin_fixup(OpenfpgaContext& openfpga_context,
const Command& cmd, const CommandContext& cmd_context); const Command& cmd, const CommandContext& cmd_context);
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -5,6 +5,9 @@
/* Headers from vtrutil library */ /* Headers from vtrutil library */
#include "vtr_log.h" #include "vtr_log.h"
/* Headers from openfpgashell library */
#include "command_exit_codes.h"
/* Headers from archopenfpga library */ /* Headers from archopenfpga library */
#include "read_xml_openfpga_arch.h" #include "read_xml_openfpga_arch.h"
#include "check_circuit_library.h" #include "check_circuit_library.h"
@ -22,8 +25,8 @@ namespace openfpga {
* The command will accept an option '--file' which is the architecture * The command will accept an option '--file' which is the architecture
* file provided by users * file provided by users
*******************************************************************/ *******************************************************************/
void read_arch(OpenfpgaContext& openfpga_context, int read_arch(OpenfpgaContext& openfpga_context,
const Command& cmd, const CommandContext& cmd_context) { const Command& cmd, const CommandContext& cmd_context) {
/* Check the option '--file' is enabled or not /* Check the option '--file' is enabled or not
* Actually, it must be enabled as the shell interface will check * Actually, it must be enabled as the shell interface will check
* before reaching this fuction * before reaching this fuction
@ -44,6 +47,9 @@ void read_arch(OpenfpgaContext& openfpga_context,
* 3. Simulation settings (TODO) * 3. Simulation settings (TODO)
*/ */
check_circuit_library(openfpga_context.arch().circuit_lib); 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 * The command will accept an option '--file' which is the architecture
* file provided by users * file provided by users
*******************************************************************/ *******************************************************************/
void write_arch(const OpenfpgaContext& openfpga_context, int write_arch(const OpenfpgaContext& openfpga_context,
const Command& cmd, const CommandContext& cmd_context) { const Command& cmd, const CommandContext& cmd_context) {
/* Check the option '--file' is enabled or not /* Check the option '--file' is enabled or not
* Actually, it must be enabled as the shell interface will check * Actually, it must be enabled as the shell interface will check
* before reaching this fuction * before reaching this fuction
@ -68,6 +74,9 @@ void write_arch(const OpenfpgaContext& openfpga_context,
VTR_LOG("Writing XML architecture to '%s'...\n", VTR_LOG("Writing XML architecture to '%s'...\n",
arch_file_name.c_str()); arch_file_name.c_str());
write_xml_openfpga_arch(arch_file_name.c_str(), openfpga_context.arch()); 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 */ } /* end namespace openfpga */

View File

@ -15,11 +15,11 @@
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
void read_arch(OpenfpgaContext& openfpga_context, int read_arch(OpenfpgaContext& openfpga_context,
const Command& cmd, const CommandContext& cmd_context); const Command& cmd, const CommandContext& cmd_context);
void write_arch(const OpenfpgaContext& openfpga_context, int write_arch(const OpenfpgaContext& openfpga_context,
const Command& cmd, const CommandContext& cmd_context); const Command& cmd, const CommandContext& cmd_context);
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -5,6 +5,9 @@
#include "vtr_time.h" #include "vtr_time.h"
#include "vtr_log.h" #include "vtr_log.h"
/* Headers from openfpgashell library */
#include "command_exit_codes.h"
#include "build_physical_truth_table.h" #include "build_physical_truth_table.h"
#include "repack.h" #include "repack.h"
#include "openfpga_repack.h" #include "openfpga_repack.h"
@ -18,8 +21,8 @@ namespace openfpga {
/******************************************************************** /********************************************************************
* A wrapper function to call the fabric_verilog function of FPGA-Verilog * A wrapper function to call the fabric_verilog function of FPGA-Verilog
*******************************************************************/ *******************************************************************/
void repack(OpenfpgaContext& openfpga_ctx, int repack(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context) { const Command& cmd, const CommandContext& cmd_context) {
CommandOptionId opt_verbose = cmd.option("verbose"); CommandOptionId opt_verbose = cmd.option("verbose");
@ -35,6 +38,9 @@ void repack(OpenfpgaContext& openfpga_ctx,
g_vpr_ctx.clustering(), g_vpr_ctx.clustering(),
openfpga_ctx.vpr_device_annotation(), openfpga_ctx.vpr_device_annotation(),
openfpga_ctx.arch().circuit_lib); openfpga_ctx.arch().circuit_lib);
/* TODO: should identify the error code from internal function execution */
return CMD_EXEC_SUCCESS;
} }
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -15,8 +15,8 @@
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
void repack(OpenfpgaContext& openfpga_ctx, int repack(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context); const Command& cmd, const CommandContext& cmd_context);
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -5,6 +5,9 @@
#include "vtr_time.h" #include "vtr_time.h"
#include "vtr_log.h" #include "vtr_log.h"
/* Headers from openfpgashell library */
#include "command_exit_codes.h"
/* Headers from openfpgautil library */ /* Headers from openfpgautil library */
#include "openfpga_digest.h" #include "openfpga_digest.h"
@ -22,8 +25,8 @@ namespace openfpga {
/******************************************************************** /********************************************************************
* A wrapper function to call the PnR SDC generator of FPGA-SDC * A wrapper function to call the PnR SDC generator of FPGA-SDC
*******************************************************************/ *******************************************************************/
void write_pnr_sdc(OpenfpgaContext& openfpga_ctx, int write_pnr_sdc(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context) { const Command& cmd, const CommandContext& cmd_context) {
CommandOptionId opt_output_dir = cmd.option("file"); CommandOptionId opt_output_dir = cmd.option("file");
CommandOptionId opt_constrain_global_port = cmd.option("constrain_global_port"); 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)); std::string sdc_dir_path = format_dir_path(cmd_context.option_value(cmd, opt_output_dir));
/* Create directories */ /* Create directories */
create_dir_path(sdc_dir_path.c_str()); create_directory(sdc_dir_path);
PnrSdcOption options(sdc_dir_path); PnrSdcOption options(sdc_dir_path);
@ -80,13 +83,16 @@ void write_pnr_sdc(OpenfpgaContext& openfpga_ctx,
global_ports, global_ports,
openfpga_ctx.flow_manager().compress_routing()); 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 * A wrapper function to call the analysis SDC generator of FPGA-SDC
*******************************************************************/ *******************************************************************/
void write_analysis_sdc(OpenfpgaContext& openfpga_ctx, int write_analysis_sdc(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context) { const Command& cmd, const CommandContext& cmd_context) {
CommandOptionId opt_output_dir = cmd.option("file"); 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)); std::string sdc_dir_path = format_dir_path(cmd_context.option_value(cmd, opt_output_dir));
/* Create directories */ /* Create directories */
create_dir_path(sdc_dir_path.c_str()); create_directory(sdc_dir_path);
AnalysisSdcOption options(sdc_dir_path); AnalysisSdcOption options(sdc_dir_path);
options.set_generate_sdc_analysis(true); options.set_generate_sdc_analysis(true);
@ -114,6 +120,9 @@ void write_analysis_sdc(OpenfpgaContext& openfpga_ctx,
global_ports, global_ports,
openfpga_ctx.flow_manager().compress_routing()); openfpga_ctx.flow_manager().compress_routing());
} }
/* TODO: should identify the error code from internal function execution */
return CMD_EXEC_SUCCESS;
} }
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -15,11 +15,11 @@
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
void write_pnr_sdc(OpenfpgaContext& openfpga_ctx, int write_pnr_sdc(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context); const Command& cmd, const CommandContext& cmd_context);
void write_analysis_sdc(OpenfpgaContext& openfpga_ctx, int write_analysis_sdc(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context); const Command& cmd, const CommandContext& cmd_context);
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -5,6 +5,9 @@
#include "vtr_time.h" #include "vtr_time.h"
#include "vtr_log.h" #include "vtr_log.h"
/* Headers from openfpgashell library */
#include "command_exit_codes.h"
#include "verilog_api.h" #include "verilog_api.h"
#include "openfpga_verilog.h" #include "openfpga_verilog.h"
@ -17,8 +20,8 @@ namespace openfpga {
/******************************************************************** /********************************************************************
* A wrapper function to call the fabric Verilog generator of FPGA-Verilog * A wrapper function to call the fabric Verilog generator of FPGA-Verilog
*******************************************************************/ *******************************************************************/
void write_fabric_verilog(OpenfpgaContext& openfpga_ctx, int write_fabric_verilog(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context) { const Command& cmd, const CommandContext& cmd_context) {
CommandOptionId opt_output_dir = cmd.option("file"); CommandOptionId opt_output_dir = cmd.option("file");
CommandOptionId opt_explicit_port_mapping = cmd.option("explicit_port_mapping"); 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.vpr_device_annotation(),
openfpga_ctx.device_rr_gsb(), openfpga_ctx.device_rr_gsb(),
options); 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 * A wrapper function to call the Verilog testbench generator of FPGA-Verilog
*******************************************************************/ *******************************************************************/
void write_verilog_testbench(OpenfpgaContext& openfpga_ctx, int write_verilog_testbench(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context) { const Command& cmd, const CommandContext& cmd_context) {
CommandOptionId opt_output_dir = cmd.option("file"); CommandOptionId opt_output_dir = cmd.option("file");
CommandOptionId opt_reference_benchmark = cmd.option("reference_benchmark_file_path"); 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().sim_setting,
openfpga_ctx.arch().config_protocol.type(), openfpga_ctx.arch().config_protocol.type(),
options); options);
/* TODO: should identify the error code from internal function execution */
return CMD_EXEC_SUCCESS;
} }
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -15,11 +15,11 @@
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
void write_fabric_verilog(OpenfpgaContext& openfpga_ctx, int write_fabric_verilog(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context); const Command& cmd, const CommandContext& cmd_context);
void write_verilog_testbench(OpenfpgaContext& openfpga_ctx, int write_verilog_testbench(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context); const Command& cmd, const CommandContext& cmd_context);
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -5,6 +5,9 @@
#include "vtr_time.h" #include "vtr_time.h"
#include "vtr_log.h" #include "vtr_log.h"
/* Headers from openfpgashell library */
#include "command_exit_codes.h"
#include "write_xml_device_rr_gsb.h" #include "write_xml_device_rr_gsb.h"
#include "openfpga_write_gsb.h" #include "openfpga_write_gsb.h"
@ -19,8 +22,8 @@ namespace openfpga {
* Write internal structrure of all the General Switch Blocks (GSBs) * Write internal structrure of all the General Switch Blocks (GSBs)
* to an XML file * to an XML file
*******************************************************************/ *******************************************************************/
void write_gsb(const OpenfpgaContext& openfpga_ctx, int write_gsb(const OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context) { const Command& cmd, const CommandContext& cmd_context) {
/* Check the option '--file' is enabled or not /* Check the option '--file' is enabled or not
* Actually, it must be enabled as the shell interface will check * 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, g_vpr_ctx.device().rr_graph,
openfpga_ctx.device_rr_gsb(), openfpga_ctx.device_rr_gsb(),
cmd_context.option_enable(cmd, opt_verbose)); cmd_context.option_enable(cmd, opt_verbose));
/* TODO: should identify the error code from internal function execution */
return CMD_EXEC_SUCCESS;
} }
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -15,8 +15,8 @@
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
void write_gsb(const OpenfpgaContext& openfpga_ctx, int write_gsb(const OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context); const Command& cmd, const CommandContext& cmd_context);
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -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 /* 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 * 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)) { for (const auto& port : circuit_lib.model_global_ports(primitive_model, false)) {
std::vector<CircuitPortId> primitive_model_inout_ports = circuit_lib.model_ports_by_type(primitive_model, CIRCUIT_MODEL_PORT_INOUT); if ( (CIRCUIT_MODEL_PORT_INOUT == circuit_lib.port_type(port))
for (auto port : primitive_model_inout_ports) { && (true == circuit_lib.port_is_io(port)) ) {
add_primitive_module_fpga_global_io_port(module_manager, primitive_module, add_primitive_module_fpga_global_io_port(module_manager, primitive_module,
logic_module, logic_instance_id, logic_module, logic_instance_id,
ModuleManager::MODULE_GPIO_PORT, ModuleManager::MODULE_GPIO_PORT,
circuit_lib, circuit_lib,
primitive_model, primitive_model,
port); port);
} } else if ( (CIRCUIT_MODEL_PORT_INPUT == circuit_lib.port_type(port))
} && (true == circuit_lib.port_is_io(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)) ) {
add_primitive_module_fpga_global_io_port(module_manager, primitive_module, add_primitive_module_fpga_global_io_port(module_manager, primitive_module,
logic_module, logic_instance_id, logic_module, logic_instance_id,
ModuleManager::MODULE_GPIN_PORT, ModuleManager::MODULE_GPIN_PORT,

View File

@ -203,6 +203,12 @@ void print_analysis_sdc_disable_global_ports(std::fstream& fp,
continue; 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)); 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); BasicPort port_to_disable = module_manager.module_port(top_module, module_port);

View File

@ -63,19 +63,19 @@ void fpga_fabric_verilog(ModuleManager& module_manager,
std::string src_dir_path = format_dir_path(options.output_directory()); std::string src_dir_path = format_dir_path(options.output_directory());
/* Create directories */ /* 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 */ /* 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); 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 */ /* 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); 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 */ /* 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); 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 files containing preprocessing flags */
print_verilog_preprocessing_flags_netlist(std::string(src_dir_path), 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(); std::string netlist_name = atom_ctx.nlist.netlist_name();
/* Create directories */ /* 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 */ /* TODO: check if this works here. This function was in fabric generator */
print_verilog_simulation_preprocessing_flags(std::string(src_dir_path), print_verilog_simulation_preprocessing_flags(std::string(src_dir_path),

View File

@ -37,8 +37,9 @@ ModuleId add_circuit_model_to_module_manager(ModuleManager& module_manager,
/* Add ports */ /* Add ports */
/* Find global ports and add one by one /* Find global ports and add one by one
* Global input ports will be considered as global 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
* Global output ports will be considered as spy port 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)) { 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)); 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)) } else if ( (CIRCUIT_MODEL_PORT_INPUT == circuit_lib.port_type(port))
&& (true == circuit_lib.port_is_io(port)) ) { && (true == circuit_lib.port_is_io(port)) ) {
module_manager.add_port(module, port_info, ModuleManager::MODULE_GPIN_PORT); module_manager.add_port(module, port_info, ModuleManager::MODULE_GPIN_PORT);
} else { } else if (CIRCUIT_MODEL_PORT_OUTPUT == circuit_lib.port_type(port)) {
VTR_ASSERT(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); 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);
} }
} }

View File

@ -156,7 +156,7 @@
<design_technology type="cmos"/> <design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/> <input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/> <output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="inout" prefix="pad" size="1"/> <port type="inout" prefix="pad" size="1" is_global="true" is_io="true"/>
<port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/> <port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/>
<port type="input" prefix="outpad" size="1"/> <port type="input" prefix="outpad" size="1"/>
<port type="output" prefix="inpad" size="1"/> <port type="output" prefix="inpad" size="1"/>

View File

@ -173,7 +173,7 @@
<design_technology type="cmos"/> <design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/> <input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/> <output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="inout" prefix="pad" size="1"/> <port type="inout" prefix="pad" size="1" is_global="true" is_io="true"/>
<port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/> <port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/>
<port type="input" prefix="outpad" size="1"/> <port type="input" prefix="outpad" size="1"/>
<port type="output" prefix="inpad" size="1"/> <port type="output" prefix="inpad" size="1"/>

View File

@ -174,7 +174,7 @@
<design_technology type="cmos"/> <design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/> <input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/> <output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="inout" prefix="pad" size="1"/> <port type="inout" prefix="pad" size="1" is_global="true" is_io="true"/>
<port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/> <port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/>
<port type="input" prefix="outpad" size="1"/> <port type="input" prefix="outpad" size="1"/>
<port type="output" prefix="inpad" size="1"/> <port type="output" prefix="inpad" size="1"/>

View File

@ -174,7 +174,7 @@
<design_technology type="cmos"/> <design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/> <input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/> <output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="inout" prefix="pad" size="1"/> <port type="inout" prefix="pad" size="1" is_global="true" is_io="true"/>
<port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/> <port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/>
<port type="input" prefix="outpad" size="1"/> <port type="input" prefix="outpad" size="1"/>
<port type="output" prefix="inpad" size="1"/> <port type="output" prefix="inpad" size="1"/>

View File

@ -174,7 +174,7 @@
<design_technology type="cmos"/> <design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/> <input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/> <output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="inout" prefix="pad" size="1"/> <port type="inout" prefix="pad" size="1" is_global="true" is_io="true"/>
<port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/> <port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/>
<port type="input" prefix="outpad" size="1"/> <port type="input" prefix="outpad" size="1"/>
<port type="output" prefix="inpad" size="1"/> <port type="output" prefix="inpad" size="1"/>
@ -209,7 +209,7 @@
<port type="output" prefix="rx_data" size="80"/> <port type="output" prefix="rx_data" size="80"/>
<port type="clock" prefix="tx_clk" size="1" default_val="0"/> <port type="clock" prefix="tx_clk" size="1" default_val="0"/>
<port type="clock" prefix="rx_clk" size="1" default_val="0"/> <port type="clock" prefix="rx_clk" size="1" default_val="0"/>
<port type="inout" prefix="pad" size="80"/> <port type="inout" prefix="pad" size="80" is_global="true" is_io="true"/>
</circuit_model> </circuit_model>
</circuit_library> </circuit_library>
<configuration_protocol> <configuration_protocol>

View File

@ -174,7 +174,7 @@
<design_technology type="cmos"/> <design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/> <input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/> <output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="inout" prefix="pad" size="1"/> <port type="inout" prefix="pad" size="1" is_global="true" is_io="true"/>
<port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/> <port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/>
<port type="input" prefix="outpad" size="1"/> <port type="input" prefix="outpad" size="1"/>
<port type="output" prefix="inpad" size="1"/> <port type="output" prefix="inpad" size="1"/>

View File

@ -174,7 +174,7 @@
<design_technology type="cmos"/> <design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/> <input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/> <output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="inout" prefix="pad" size="1"/> <port type="inout" prefix="pad" size="1" is_global="true" is_io="true"/>
<port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/> <port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/>
<port type="input" prefix="outpad" size="1"/> <port type="input" prefix="outpad" size="1"/>
<port type="output" prefix="inpad" size="1"/> <port type="output" prefix="inpad" size="1"/>

View File

@ -179,7 +179,7 @@
<design_technology type="cmos"/> <design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/> <input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/> <output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="inout" prefix="pad" size="1"/> <port type="inout" prefix="pad" size="1" is_global="true" is_io="true"/>
<port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/> <port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/>
<port type="input" prefix="outpad" size="1"/> <port type="input" prefix="outpad" size="1"/>
<port type="output" prefix="inpad" size="1"/> <port type="output" prefix="inpad" size="1"/>

View File

@ -173,11 +173,11 @@
<design_technology type="cmos"/> <design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/> <input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/> <output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="inout" prefix="pad" size="1"/> <port type="inout" prefix="pad" size="1" is_global="true" is_io="true" />
<!-- A spypad for the direction port of the I/O pad, which can be visible in the fpga_top --> <!-- A spypad for the direction port of the I/O pad, which can be visible in the fpga_top -->
<port type="input" prefix="din" size="1" is_global="true" io="true" default_value="0"/> <port type="input" prefix="din" size="1" is_global="true" is_io="true" default_value="0"/>
<port type="output" prefix="dout" size="1" is_global="true"/> <port type="output" prefix="dout" size="1" is_global="true" is_io="true"/>
<port type="output" prefix="dir" size="1" is_global="true"/> <port type="output" prefix="dir" size="1" is_global="true" is_io="true"/>
<port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/> <port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/>
<port type="input" prefix="outpad" size="1"/> <port type="input" prefix="outpad" size="1"/>
<port type="output" prefix="inpad" size="1"/> <port type="output" prefix="inpad" size="1"/>

View File

@ -165,7 +165,7 @@
<design_technology type="cmos"/> <design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/> <input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/> <output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="inout" prefix="pad" size="1"/> <port type="inout" prefix="pad" size="1" is_global="true" is_io="true"/>
<port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/> <port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/>
<port type="input" prefix="outpad" size="1"/> <port type="input" prefix="outpad" size="1"/>
<port type="output" prefix="inpad" size="1"/> <port type="output" prefix="inpad" size="1"/>

View File

@ -164,7 +164,7 @@
<design_technology type="cmos"/> <design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/> <input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/> <output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="inout" prefix="pad" size="1"/> <port type="inout" prefix="pad" size="1" is_global="true" is_io="true"/>
<port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/> <port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/>
<port type="input" prefix="outpad" size="1"/> <port type="input" prefix="outpad" size="1"/>
<port type="output" prefix="inpad" size="1"/> <port type="output" prefix="inpad" size="1"/>