Merge remote-tracking branch 'lnis_origin/dev' into ganesh_dev
This commit is contained in:
commit
8267d78b01
|
@ -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 |
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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];
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"/>
|
||||||
|
|
|
@ -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"/>
|
||||||
|
|
|
@ -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"/>
|
||||||
|
|
|
@ -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"/>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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"/>
|
||||||
|
|
|
@ -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"/>
|
||||||
|
|
|
@ -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"/>
|
||||||
|
|
|
@ -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"/>
|
||||||
|
|
|
@ -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"/>
|
||||||
|
|
|
@ -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"/>
|
||||||
|
|
Loading…
Reference in New Issue