diff --git a/.travis/openfpga_vpr8_reg_test.sh b/.travis/openfpga_vpr8_reg_test.sh
index 046f8210f..8c07480cd 100755
--- a/.travis/openfpga_vpr8_reg_test.sh
+++ b/.travis/openfpga_vpr8_reg_test.sh
@@ -102,6 +102,11 @@ python3 openfpga_flow/scripts/run_fpga_task.py openfpga_shell/generate_testbench
echo -e "Testing SDC generation with time units";
python3 openfpga_flow/scripts/run_fpga_task.py openfpga_shell/sdc_time_unit --debug --show_thread_logs
+echo -e "Testing Secured FPGA fabrics";
+python3 openfpga_flow/scripts/run_fpga_task.py openfpga_shell/fabric_key/generate_vanilla_key --debug --show_thread_logs
+python3 openfpga_flow/scripts/run_fpga_task.py openfpga_shell/fabric_key/generate_random_key --debug --show_thread_logs
+python3 openfpga_flow/scripts/run_fpga_task.py openfpga_shell/fabric_key/load_external_key --debug --show_thread_logs
+
# Verify MCNC big20 benchmark suite with ModelSim
# Please make sure you have ModelSim installed in the environment
# Otherwise, it will fail
diff --git a/docs/source/manual/arch_lang/fabric_key.rst b/docs/source/manual/arch_lang/fabric_key.rst
new file mode 100644
index 000000000..1739551b7
--- /dev/null
+++ b/docs/source/manual/arch_lang/fabric_key.rst
@@ -0,0 +1,69 @@
+Fabric Key
+~~~~~~~~~~
+
+Fabric key is a secure key for users to generate bitstream for a specific FPGA fabric.
+With this key, OpenFPGA can generate correct bitstreams for the FPGA.
+Using a wrong key, OpenFPGA may error out or generate wrong bitstreams.
+The fabric key support allows users to build secured/classified FPGA chips even with an open-source tool.
+
+.. note:: Users are the only owner of the key. OpenFPGA will not store or replicate the key.
+
+Key Generation
+``````````````
+A fabric key can be achieved in the following ways:
+
+- OpenFPGA can auto-generate a fabric key using random algorithms (see detail in :ref:`cmd_build_fabric`)
+
+- Users can craft a fabric key based on auto-generated file by following the file format description.
+
+File Format
+```````````
+
+A fabric key follows an XML format. As shown in the following XML code, the key file includes the organization of configurable memory blocks in the top-level FPGA fabric:
+
+ - ``id`` indicates the sequence of the configurable memory block in the top-level FPGA fabric.
+
+ - ``name`` indicates the module name of the configurable memory block.
+
+ - ``value`` indicates the instance id of the configurable memory block in the top-level FPGA fabric.
+
+The following is an example of a fabric key generate by OpenFPGA for a 2 :math:`\times` 2 FPGA.
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/source/manual/arch_lang/index.rst b/docs/source/manual/arch_lang/index.rst
index f2fd146fb..bcd6287e3 100644
--- a/docs/source/manual/arch_lang/index.rst
+++ b/docs/source/manual/arch_lang/index.rst
@@ -25,4 +25,4 @@ OpenFPGA Architecture Description
annotate_vpr_arch
-
+ fabric_key
diff --git a/docs/source/manual/fpga_bitstream/generic_bitstream.rst b/docs/source/manual/fpga_bitstream/generic_bitstream.rst
index 78fbd3de4..a434096bc 100644
--- a/docs/source/manual/fpga_bitstream/generic_bitstream.rst
+++ b/docs/source/manual/fpga_bitstream/generic_bitstream.rst
@@ -6,46 +6,109 @@ Usage
Generic bitstream is a fabric-independent bitstream where configuration bits are organized out-of-order in a database.
This can be regarded as a raw bitstream used for
- - ``debugging``: Hardware engineers can validate if their configuration memories across the FPGA fabric are assigned to expected values
- - ``an exchangeable file format for bitstream assembler``: Software engineers can use the raw bitstream to build a bitstream assembler which organize the bitstream in the loadable formate to FPGA chips.
- - ``creation of artificial bitstream``: Test engineers can craft artificial bitstreams to test each element of the FPGA fabric, which is typically not synthesizable by VPR.
-.. note:: The fabric-independent bitstream cannot be directly loaded to FPGA fabrics
+ - ``debugging``: Hardware engineers can validate if their configuration memories across the FPGA fabric are assigned to expected values
+
+ - ``an exchangeable file format for bitstream assembler``: Software engineers can use the raw bitstream to build a bitstream assembler which organize the bitstream in the loadable formate to FPGA chips.
+
+ - ``creation of artificial bitstream``: Test engineers can craft artificial bitstreams to test each element of the FPGA fabric, which is typically not synthesizable by VPR. Use the ``--read_file`` option to load the artifical bitsteam to OpenFPGA (see details in :ref:`openfpga_bitstream_commands`).
+
+.. warning:: The fabric-independent bitstream cannot be directly loaded to FPGA fabrics
File Format
```````````
-OpenFPGA can output the generic bitstream to an XML format, which is easy to debug. As shown in the following XML code, configuration bits are organized block by block, where each block could be a LUT, a routing multiplexer `etc`. Each ``bitstream_block`` includes two sets of information:
+OpenFPGA can output the generic bitstream to an XML format, which is easy to debug. As shown in the following XML code, configuration bits are organized block by block, where each block could be a LUT, a routing multiplexer `etc`. Each ``bitstream_block`` includes the following information:
+ - ``name`` represents the instance name which you can find in the fabric netlists
+
+ - ``hierarchy_level`` represents the depth of this block in the hierarchy of the FPGA fabric. It always starts from 0 as the root.
- ``hierarchy`` represents the location of this block in FPGA fabric.
+ The hierachy includes the full hierarchy of this block
+
+ - ``instance`` denotes the instance name which you can find in the fabric netlists
+
+ - ``level`` denotes the depth of the block in the hierarchy
+
+ - ``input_nets`` represents the path ids and net names that are mapped to the inputs of block. Unused inputs will be tagged as ``unmapped`` which is a reserved word of OpenFPGA. Path id corresponds the selected ``path_id`` in the ```` node.
+
+ - ``output_nets`` represents the path ids and net names that are mapped to the outputs of block. Unused outputs will be tagged as ``unmapped`` which is a reserved word OpenFPGA.
- ``bitstream`` represents the configuration bits affiliated to this block.
+ - ``path_id`` denotes the index of inputs which is propagated to the output. Note that smallest valid index starts from zero. Only routing multiplexers have the path index. Unused routing multiplexer will not have a ``path_id`` of ``-1``, which allows bitstream assembler to freely find the best path in terms of Quality of Results (QoR). A used routing multiplexer should have a zero or positive ``path_id``.
+
+ - ``bit`` denotes a single configuration bit under this block. It contains \
+
+ - ``memory_port`` the memory port name which you can find in the fabric netlists by following the hierarchy.
+
+ - ``value`` a binary value which is the configuration bit assigned to the memory port.
+
.. code-block:: xml
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
diff --git a/docs/source/manual/openfpga_shell/index.rst b/docs/source/manual/openfpga_shell/index.rst
index 24512f67d..406fc0ddf 100644
--- a/docs/source/manual/openfpga_shell/index.rst
+++ b/docs/source/manual/openfpga_shell/index.rst
@@ -11,4 +11,4 @@ OpenFPGA Shell
openfpga_script
- openfpga_commands
+ openfpga_commands/index
diff --git a/docs/source/manual/openfpga_shell/openfpga_commands.rst b/docs/source/manual/openfpga_shell/openfpga_commands.rst
deleted file mode 100644
index eb5929861..000000000
--- a/docs/source/manual/openfpga_shell/openfpga_commands.rst
+++ /dev/null
@@ -1,280 +0,0 @@
-.. _openfpga_commands:
-
-Commands
---------
-
-As OpenFPGA integrates various tools, the commands are categorized into different classes:
-
-Basic Commands
-~~~~~~~~~~~~~~
-
-.. option:: help
-
- Show help desk to list all the available commands
-
-.. option:: exit
-
- Exit OpenFPGA shell
-
-VPR
-~~~
-
-.. option:: vpr
-
- OpenFPGA allows users to call ``vpr`` in the standard way as documented in vtr project.
-
-Setup OpenFPGA
-~~~~~~~~~~~~~~
-
-.. option:: read_openfpga_arch
-
- Read the XML file about architecture description (see details in :ref:`arch_generality`)
-
- - ``--file`` or ``-f`` Specify the file name
-
- - ``--verbose`` Show verbose log
-
-.. option:: write_openfpga_arch
-
- Write the OpenFPGA XML architecture file to a file
-
- - ``--file`` or ``-f`` Specify the file name
-
- - ``--verbose`` Show verbose log
-
-.. option:: read_openfpga_simulation_setting
-
- Read the XML file about simulation settings (see details in :ref:`simulation_setting`)
-
- - ``--file`` or ``-f`` Specify the file name
-
- - ``--verbose`` Show verbose log
-
-.. option:: write_openfpga_simulation_setting
-
- Write the OpenFPGA XML simulation settings to a file
-
- - ``--file`` or ``-f`` Specify the file name
-
- - ``--verbose`` Show verbose log
-
-.. option:: link_openfpga_arch
-
- Annotate the OpenFPGA architecture to VPR data base
-
- - ``--activity_file`` Specify the signal activity file
-
- - ``--sort_gsb_chan_node_in_edges`` Sort the edges for the routing tracks in General Switch Blocks (GSBs). Strongly recommand to turn this on for uniquifying the routing modules
-
- - ``--verbose`` Show verbose log
-
-.. option:: write_gsb_to_xml
-
- Write the internal structure of General Switch Blocks (GSBs) across a FPGA fabric, including the interconnection between the nodes and node-level details, to XML files
-
- - ``--file`` or ``-f`` Specify the output directory of the XML files. Each GSB will be written to an indepedent XML file
-
- - ``--verbose`` Show verbose log
-
- .. note:: This command is used to help users to study the difference between GSBs
-
-.. option:: check_netlist_naming_conflict
-
- Check and correct any naming conflicts in the BLIF netlist
- This is strongly recommended. Otherwise, the outputted Verilog netlists may not be compiled successfully.
-
- .. warning:: This command may be deprecated in future when it is merged to VPR upstream
-
- - ``--fix`` Apply fix-up to the names that violate the syntax
-
- - ``--report <.xml>`` Report the naming fix-up to a log file
-
-.. option:: pb_pin_fixup
-
- Apply fix-up to clustering nets based on routing results
- This is strongly recommended. Otherwise, the bitstream generation may be wrong
-
- .. warning:: This command may be deprecated in future when it is merged to VPR upstream
-
- - ``--verbose`` Show verbose log
-
-.. option:: lut_truth_table_fixup
-
- Apply fix-up to Look-Up Table truth tables based on packing results
-
- .. warning:: This command may be deprecated in future when it is merged to VPR upstream
-
- - ``--verbose`` Show verbose log
-
-.. option:: build_fabric
-
- Build the module graph.
-
- - ``--compress_routing`` Enable compression on routing architecture modules. Strongly recommend this as it will minimize the number of routing modules to be outputted. It can reduce the netlist size significantly.
-
- - ``--duplicate_grid_pin`` Enable pin duplication on grid modules. This is optional unless ultra-dense layout generation is needed
-
- - ``--verbose`` Show verbose log
-
- .. note:: This is a must-run command before launching FPGA-Verilog, FPGA-Bitstream, FPGA-SDC and FPGA-SPICE
-
-.. option:: write_fabric_hierarchy
-
- Write the hierarchy of FPGA fabric graph to a plain-text file
-
- - ``--file`` or ``-f`` Specify the file name to write the hierarchy.
-
- - ``--depth`` Specify at which depth of the fabric module graph should the writer stop outputting. The root module start from depth 0. For example, if you want a two-level hierarchy, you should specify depth as 1.
-
- - ``--verbose`` Show verbose log
-
- .. note:: This file is designed for hierarchical PnR flow, which requires the tree of Multiple-Instanced-Blocks (MIBs).
-
-FPGA-Bitstream
-~~~~~~~~~~~~~~
-
-.. option:: repack
-
- Repack the netlist to physical pbs
- This must be done before bitstream generator and testbench generation
- Strongly recommend it is done after all the fix-up have been applied
-
- - ``--verbose`` Show verbose log
-
-.. option:: build_architecture_bitstream
-
- Decode VPR implementing results to an fabric-independent bitstream database
-
- - ``--file`` or ``-f`` Output the fabric-independent bitstream to an XML file
-
- - ``--verbose`` Show verbose log
-
-.. option:: build_fabric_bitstream
-
- Build a sequence for every configuration bits in the bitstream database for a specific FPGA fabric
-
- - ``--file`` or ``-f`` Output the fabric bitstream to an plain text file (only 0 or 1)
-
- - ``--verbose`` Show verbose log
-
-.. _openfpga_verilog_commands:
-
-FPGA-Verilog
-~~~~~~~~~~~~
-
-.. option:: write_fabric_verilog
-
- Write the Verilog netlist for FPGA fabric based on module graph
-
- - ``--file`` or ``-f`` Specify the output directory for the Verilog netlists
-
- - ``--explicit_port_mapping`` Use explicit port mapping when writing the Verilog netlists
-
- - ``--include_timing`` Output timing information to Verilog netlists for primitive modules
-
- - ``--include_signal_init`` Output signal initialization to Verilog netlists for primitive modules
-
- - ``--support_icarus_simulator`` Output Verilog netlists with syntax that iVerilog simulatorcan accept
-
- - ``--print_user_defined_template`` Output a template Verilog netlist for all the user-defined ``circuit models`` in :ref:`circuit_library`. This aims to help engineers to check what is the port sequence required by top-level Verilog netlists
-
- - ``--verbose`` Show verbose log
-
-.. option:: write_verilog_testbench
-
- Write the Verilog testbench for FPGA fabric
-
- - ``--file`` or ``-f`` The output directory for all the testbench netlists. We suggest the use of same output directory as fabric Verilog netlists
-
- - ``--reference_benchmark_file_path`` Must specify the reference benchmark Verilog file if you want to output any testbenches
-
- - ``--fast_configuration`` Enable fast configuration phase for the top-level testbench in order to reduce runtime of simulations. It is applicable to memory bank and frame-based configuration protocols. When enabled, all the zero configuration bits will be skipped. So ensure that your memory cells can be correctly reset to zero with a reset signal.
-
- - ``--print_top_testbench`` Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA
-
- - ``--print_formal_verification_top_netlist`` Generate a top-level module which can be used in formal verification
-
- - ``--print_preconfig_top_testbench`` Enable pre-configured top-level testbench which is a fast verification skipping programming phase
-
- - ``--print_simulation_ini`` Output an exchangeable simulation ini file, which is needed only when you need to interface different HDL simulators using openfpga flow-run scripts
-
- - ``--explicit_port_mapping`` Use explicit port mapping when writing the Verilog netlists
-
-FPGA-SDC
-~~~~~~~~
-
-.. option:: write_pnr_sdc
-
- Write the SDC files for PnR backend
-
- - ``--file`` or ``-f`` Specify the output directory for SDC files
-
- - ``--hierarchical`` Output SDC files without full path in hierarchy
-
- - ``--flatten_names`` Use flatten names (no wildcards) in SDC files
-
- - ``--time_unit`` Specify a time unit to be used in SDC files. Acceptable values are string: ``as`` | ``fs`` | ``ps`` | ``ns`` | ``us`` | ``ms`` | ``ks`` | ``Ms``. By default, we will consider second (``s``).
-
- - ``--output_hierarchy`` Output hierarchy of Multiple-Instance-Blocks(MIBs) to plain text file. This is applied to constrain timing for grids, Switch Blocks and Connection Blocks.
-
- .. note:: Valid only when ``compress_routing`` is enabled in ``build_fabric``
-
- - ``--constrain_global_port`` Constrain all the global ports of FPGA fabric.
-
- - ``--constrain_non_clock_global_port`` Constrain all the non-clock global ports as clocks ports of FPGA fabric
-
- .. note:: ``constrain_global_port`` will treat these global ports in Clock Tree Synthesis (CTS), in purpose of balancing the delay to each sink. Be carefull to enable ``constrain_non_clock_global_port``, this may significanly increase the runtime of CTS as it is supposed to be routed before any other nets. This may cause routing congestion as well.
-
- - ``--constrain_grid`` Constrain all the grids of FPGA fabric
-
- - ``--constrain_sb`` Constrain all the switch blocks of FPGA fabric
-
- - ``--constrain_cb`` Constrain all the connection blocks of FPGA fabric
-
- - ``--constrain_configurable_memory_outputs`` Constrain all the outputs of configurable memories of FPGA fabric
-
- - ``--constrain_routing_multiplexer_outputs`` Constrain all the outputs of routing multiplexer of FPGA fabric
-
- - ``--constrain_switch_block_outputs`` Constrain all the outputs of switch blocks of 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
-
- - ``--verbose`` Enable verbose output
-
-.. option:: write_configuration_chain_sdc
-
- Write the SDC file to constrain the timing for configuration chain. The timing constraints will always start from the first output (Q) of a Configuration Chain Flip-flop (CCFF) and ends at the inputs of the next CCFF in the chain. Note that Qb of CCFF will not be constrained!
-
- - ``--file`` or ``-f`` Specify the output SDC file
-
- - ``--time_unit`` Specify a time unit to be used in SDC files. Acceptable values are string: ``as`` | ``fs`` | ``ps`` | ``ns`` | ``us`` | ``ms`` | ``ks`` | ``Ms``. By default, we will consider second (``s``).
-
-
- - ``--max_delay`` Specify the maximum delay to be used. The timing value should follow the time unit defined in this command.
-
- - ``--min_delay`` Specify the minimum delay to be used. The timing value should follow the time unit defined in this command.
-
- .. note::
- Only applicable when configuration chain is used as configuration protocol
-
-.. option:: write_sdc_disable_timing_configure_ports
-
- Write the SDC file to disable timing for configure ports of programmable modules. The SDC aims to break the combinational loops across FPGAs and avoid false path timing to be visible to timing analyzers
-
- - ``--file`` or ``-f`` Specify the output SDC file
-
- - ``--flatten_names`` Use flatten names (no wildcards) in SDC files
-
- - ``--verbose`` Show verbose log
-
-.. option:: write_analysis_sdc
-
- Write the SDC to run timing analysis for a mapped FPGA fabric
-
- - ``--file`` or ``-f`` Specify the output directory for SDC files
-
- - ``--flatten_names`` Use flatten names (no wildcards) in SDC files
-
- - ``--time_unit`` Specify a time unit to be used in SDC files. Acceptable values are string: ``as`` | ``fs`` | ``ps`` | ``ns`` | ``us`` | ``ms`` | ``ks`` | ``Ms``. By default, we will consider second (``s``).
diff --git a/docs/source/manual/openfpga_shell/openfpga_commands/basic_commands.rst b/docs/source/manual/openfpga_shell/openfpga_commands/basic_commands.rst
new file mode 100644
index 000000000..727448a61
--- /dev/null
+++ b/docs/source/manual/openfpga_shell/openfpga_commands/basic_commands.rst
@@ -0,0 +1,15 @@
+.. _openfpga_basic_commands:
+
+Basic Commands
+--------------
+
+help
+~~~~
+
+ Show help desk to list all the available commands
+
+exit
+~~~~
+
+ Exit OpenFPGA shell
+
diff --git a/docs/source/manual/openfpga_shell/openfpga_commands/fpga_bitstream_commands.rst b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_bitstream_commands.rst
new file mode 100644
index 000000000..731f99f94
--- /dev/null
+++ b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_bitstream_commands.rst
@@ -0,0 +1,33 @@
+.. _openfpga_bitstream_commands:
+
+FPGA-Bitstream
+--------------
+
+repack
+~~~~~~
+
+ Repack the netlist to physical pbs
+ This must be done before bitstream generator and testbench generation
+ Strongly recommend it is done after all the fix-up have been applied
+
+ - ``--verbose`` Show verbose log
+
+build_architecture_bitstream
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Decode VPR implementing results to an fabric-independent bitstream database
+
+ - ``--read_file`` Read the fabric-independent bitstream from an XML file. When this is enabled, bitstream generation will NOT consider VPR results.
+
+ - ``--write_file`` Output the fabric-independent bitstream to an XML file
+
+ - ``--verbose`` Show verbose log
+
+build_fabric_bitstream
+~~~~~~~~~~~~~~~~~~~~~~
+
+ Build a sequence for every configuration bits in the bitstream database for a specific FPGA fabric
+
+ - ``--file`` or ``-f`` Output the fabric bitstream to an plain text file (only 0 or 1)
+
+ - ``--verbose`` Show verbose log
diff --git a/docs/source/manual/openfpga_shell/openfpga_commands/fpga_sdc_commands.rst b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_sdc_commands.rst
new file mode 100644
index 000000000..f5f0b83af
--- /dev/null
+++ b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_sdc_commands.rst
@@ -0,0 +1,84 @@
+.. _openfpga_sdc_commands:
+
+FPGA-SDC
+--------
+
+write_pnr_sdc
+~~~~~~~~~~~~~
+
+ Write the SDC files for PnR backend
+
+ - ``--file`` or ``-f`` Specify the output directory for SDC files
+
+ - ``--hierarchical`` Output SDC files without full path in hierarchy
+
+ - ``--flatten_names`` Use flatten names (no wildcards) in SDC files
+
+ - ``--time_unit`` Specify a time unit to be used in SDC files. Acceptable values are string: ``as`` | ``fs`` | ``ps`` | ``ns`` | ``us`` | ``ms`` | ``ks`` | ``Ms``. By default, we will consider second (``s``).
+
+ - ``--output_hierarchy`` Output hierarchy of Multiple-Instance-Blocks(MIBs) to plain text file. This is applied to constrain timing for grids, Switch Blocks and Connection Blocks.
+
+ .. note:: Valid only when ``compress_routing`` is enabled in ``build_fabric``
+
+ - ``--constrain_global_port`` Constrain all the global ports of FPGA fabric.
+
+ - ``--constrain_non_clock_global_port`` Constrain all the non-clock global ports as clocks ports of FPGA fabric
+
+ .. note:: ``constrain_global_port`` will treat these global ports in Clock Tree Synthesis (CTS), in purpose of balancing the delay to each sink. Be carefull to enable ``constrain_non_clock_global_port``, this may significanly increase the runtime of CTS as it is supposed to be routed before any other nets. This may cause routing congestion as well.
+
+ - ``--constrain_grid`` Constrain all the grids of FPGA fabric
+
+ - ``--constrain_sb`` Constrain all the switch blocks of FPGA fabric
+
+ - ``--constrain_cb`` Constrain all the connection blocks of FPGA fabric
+
+ - ``--constrain_configurable_memory_outputs`` Constrain all the outputs of configurable memories of FPGA fabric
+
+ - ``--constrain_routing_multiplexer_outputs`` Constrain all the outputs of routing multiplexer of FPGA fabric
+
+ - ``--constrain_switch_block_outputs`` Constrain all the outputs of switch blocks of 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
+
+ - ``--verbose`` Enable verbose output
+
+write_configuration_chain_sdc
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Write the SDC file to constrain the timing for configuration chain. The timing constraints will always start from the first output (Q) of a Configuration Chain Flip-flop (CCFF) and ends at the inputs of the next CCFF in the chain. Note that Qb of CCFF will not be constrained!
+
+ - ``--file`` or ``-f`` Specify the output SDC file
+
+ - ``--time_unit`` Specify a time unit to be used in SDC files. Acceptable values are string: ``as`` | ``fs`` | ``ps`` | ``ns`` | ``us`` | ``ms`` | ``ks`` | ``Ms``. By default, we will consider second (``s``).
+
+
+ - ``--max_delay`` Specify the maximum delay to be used. The timing value should follow the time unit defined in this command.
+
+ - ``--min_delay`` Specify the minimum delay to be used. The timing value should follow the time unit defined in this command.
+
+ .. note::
+ Only applicable when configuration chain is used as configuration protocol
+
+write_sdc_disable_timing_configure_ports
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Write the SDC file to disable timing for configure ports of programmable modules. The SDC aims to break the combinational loops across FPGAs and avoid false path timing to be visible to timing analyzers
+
+ - ``--file`` or ``-f`` Specify the output SDC file
+
+ - ``--flatten_names`` Use flatten names (no wildcards) in SDC files
+
+ - ``--verbose`` Show verbose log
+
+write_analysis_sdc
+~~~~~~~~~~~~~~~~~~
+
+ Write the SDC to run timing analysis for a mapped FPGA fabric
+
+ - ``--file`` or ``-f`` Specify the output directory for SDC files
+
+ - ``--flatten_names`` Use flatten names (no wildcards) in SDC files
+
+ - ``--time_unit`` Specify a time unit to be used in SDC files. Acceptable values are string: ``as`` | ``fs`` | ``ps`` | ``ns`` | ``us`` | ``ms`` | ``ks`` | ``Ms``. By default, we will consider second (``s``).
diff --git a/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst
new file mode 100644
index 000000000..de4aecad8
--- /dev/null
+++ b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst
@@ -0,0 +1,44 @@
+.. _openfpga_verilog_commands:
+
+FPGA-Verilog
+------------
+
+write_fabric_verilog
+~~~~~~~~~~~~~~~~~~~~
+
+ Write the Verilog netlist for FPGA fabric based on module graph
+
+ - ``--file`` or ``-f`` Specify the output directory for the Verilog netlists
+
+ - ``--explicit_port_mapping`` Use explicit port mapping when writing the Verilog netlists
+
+ - ``--include_timing`` Output timing information to Verilog netlists for primitive modules
+
+ - ``--include_signal_init`` Output signal initialization to Verilog netlists for primitive modules
+
+ - ``--support_icarus_simulator`` Output Verilog netlists with syntax that iVerilog simulatorcan accept
+
+ - ``--print_user_defined_template`` Output a template Verilog netlist for all the user-defined ``circuit models`` in :ref:`circuit_library`. This aims to help engineers to check what is the port sequence required by top-level Verilog netlists
+
+ - ``--verbose`` Show verbose log
+
+write_verilog_testbench
+~~~~~~~~~~~~~~~~~~~~~~~
+
+ Write the Verilog testbench for FPGA fabric
+
+ - ``--file`` or ``-f`` The output directory for all the testbench netlists. We suggest the use of same output directory as fabric Verilog netlists
+
+ - ``--reference_benchmark_file_path`` Must specify the reference benchmark Verilog file if you want to output any testbenches
+
+ - ``--fast_configuration`` Enable fast configuration phase for the top-level testbench in order to reduce runtime of simulations. It is applicable to memory bank and frame-based configuration protocols. When enabled, all the zero configuration bits will be skipped. So ensure that your memory cells can be correctly reset to zero with a reset signal.
+
+ - ``--print_top_testbench`` Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA
+
+ - ``--print_formal_verification_top_netlist`` Generate a top-level module which can be used in formal verification
+
+ - ``--print_preconfig_top_testbench`` Enable pre-configured top-level testbench which is a fast verification skipping programming phase
+
+ - ``--print_simulation_ini`` Output an exchangeable simulation ini file, which is needed only when you need to interface different HDL simulators using openfpga flow-run scripts
+
+ - ``--explicit_port_mapping`` Use explicit port mapping when writing the Verilog netlists
diff --git a/docs/source/manual/openfpga_shell/openfpga_commands/index.rst b/docs/source/manual/openfpga_shell/openfpga_commands/index.rst
new file mode 100644
index 000000000..2a9f871b6
--- /dev/null
+++ b/docs/source/manual/openfpga_shell/openfpga_commands/index.rst
@@ -0,0 +1,21 @@
+Commands
+--------
+
+As OpenFPGA integrates various tools, the commands are categorized into different classes:
+
+.. _openfpga_commands:
+
+.. toctree::
+ :maxdepth: 2
+
+ basic_commands
+
+ vpr_commands
+
+ setup_commands
+
+ fpga_bitstream_commands
+
+ fpga_verilog_commands
+
+ fpga_sdc_commands
diff --git a/docs/source/manual/openfpga_shell/openfpga_commands/setup_commands.rst b/docs/source/manual/openfpga_shell/openfpga_commands/setup_commands.rst
new file mode 100644
index 000000000..aa0018476
--- /dev/null
+++ b/docs/source/manual/openfpga_shell/openfpga_commands/setup_commands.rst
@@ -0,0 +1,127 @@
+.. _openfpga_setup_commands:
+
+Setup OpenFPGA
+--------------
+
+read_openfpga_arch
+~~~~~~~~~~~~~~~~~~
+
+ Read the XML file about architecture description (see details in :ref:`arch_generality`)
+
+ - ``--file`` or ``-f`` Specify the file name
+
+ - ``--verbose`` Show verbose log
+
+write_openfpga_arch
+~~~~~~~~~~~~~~~~~~~
+
+ Write the OpenFPGA XML architecture file to a file
+
+ - ``--file`` or ``-f`` Specify the file name
+
+ - ``--verbose`` Show verbose log
+
+read_openfpga_simulation_setting
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Read the XML file about simulation settings (see details in :ref:`simulation_setting`)
+
+ - ``--file`` or ``-f`` Specify the file name
+
+ - ``--verbose`` Show verbose log
+
+write_openfpga_simulation_setting
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Write the OpenFPGA XML simulation settings to a file
+
+ - ``--file`` or ``-f`` Specify the file name
+
+ - ``--verbose`` Show verbose log
+
+link_openfpga_arch
+~~~~~~~~~~~~~~~~~~
+
+ Annotate the OpenFPGA architecture to VPR data base
+
+ - ``--activity_file`` Specify the signal activity file
+
+ - ``--sort_gsb_chan_node_in_edges`` Sort the edges for the routing tracks in General Switch Blocks (GSBs). Strongly recommand to turn this on for uniquifying the routing modules
+
+ - ``--verbose`` Show verbose log
+
+write_gsb_to_xml
+~~~~~~~~~~~~~~~~
+
+ Write the internal structure of General Switch Blocks (GSBs) across a FPGA fabric, including the interconnection between the nodes and node-level details, to XML files
+
+ - ``--file`` or ``-f`` Specify the output directory of the XML files. Each GSB will be written to an indepedent XML file
+
+ - ``--verbose`` Show verbose log
+
+ .. note:: This command is used to help users to study the difference between GSBs
+
+check_netlist_naming_conflict
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Check and correct any naming conflicts in the BLIF netlist
+ This is strongly recommended. Otherwise, the outputted Verilog netlists may not be compiled successfully.
+
+ .. warning:: This command may be deprecated in future when it is merged to VPR upstream
+
+ - ``--fix`` Apply fix-up to the names that violate the syntax
+
+ - ``--report <.xml>`` Report the naming fix-up to a log file
+
+pb_pin_fixup
+~~~~~~~~~~~~
+
+ Apply fix-up to clustering nets based on routing results
+ This is strongly recommended. Otherwise, the bitstream generation may be wrong
+
+ .. warning:: This command may be deprecated in future when it is merged to VPR upstream
+
+ - ``--verbose`` Show verbose log
+
+lut_truth_table_fixup
+~~~~~~~~~~~~~~~~~~~~~
+
+ Apply fix-up to Look-Up Table truth tables based on packing results
+
+ .. warning:: This command may be deprecated in future when it is merged to VPR upstream
+
+ - ``--verbose`` Show verbose log
+
+.. _cmd_build_fabric:
+
+build_fabric
+~~~~~~~~~~~~
+
+ Build the module graph.
+
+ - ``--compress_routing`` Enable compression on routing architecture modules. Strongly recommend this as it will minimize the number of routing modules to be outputted. It can reduce the netlist size significantly.
+
+ - ``--duplicate_grid_pin`` Enable pin duplication on grid modules. This is optional unless ultra-dense layout generation is needed
+
+ - ``--load_fabric_key `` Load an external fabric key from an XML file.
+
+ - ``--generate_fabric_key`` Generate a fabric key in a random way
+
+ - ``--write_fabric_key `` Output current fabric key to an XML file
+
+ - ``--verbose`` Show verbose log
+
+ .. note:: This is a must-run command before launching FPGA-Verilog, FPGA-Bitstream, FPGA-SDC and FPGA-SPICE
+
+write_fabric_hierarchy
+~~~~~~~~~~~~~~~~~~~~~~
+
+ Write the hierarchy of FPGA fabric graph to a plain-text file
+
+ - ``--file`` or ``-f`` Specify the file name to write the hierarchy.
+
+ - ``--depth`` Specify at which depth of the fabric module graph should the writer stop outputting. The root module start from depth 0. For example, if you want a two-level hierarchy, you should specify depth as 1.
+
+ - ``--verbose`` Show verbose log
+
+ .. note:: This file is designed for hierarchical PnR flow, which requires the tree of Multiple-Instanced-Blocks (MIBs).
diff --git a/docs/source/manual/openfpga_shell/openfpga_commands/vpr_commands.rst b/docs/source/manual/openfpga_shell/openfpga_commands/vpr_commands.rst
new file mode 100644
index 000000000..cbdad4a53
--- /dev/null
+++ b/docs/source/manual/openfpga_shell/openfpga_commands/vpr_commands.rst
@@ -0,0 +1,11 @@
+.. _openfpga_vpr_commands:
+
+VPR Commands
+------------
+
+vpr
+~~~
+
+ OpenFPGA allows users to call ``vpr`` in the standard way as documented in the vtr_project_.
+
+.. _vtr_project: https://github.com/verilog-to-routing/vtr-verilog-to-routing
diff --git a/docs/source/tutorials/arch_modeling/quick_start.rst b/docs/source/tutorials/arch_modeling/quick_start.rst
index 0efbddf0d..1b31300d1 100644
--- a/docs/source/tutorials/arch_modeling/quick_start.rst
+++ b/docs/source/tutorials/arch_modeling/quick_start.rst
@@ -4,8 +4,9 @@ A Quick Start
-------------
In this tutorial, we will consider a simple but representative FPGA architecture to show you how to
- - Adapt the VPR architecture XML file to OpenFPGA acceptable format
- - Create the OpenFPGA architecture XMl file to customize the primitive circuits
+ - Adapt a VPR architecture XML file to OpenFPGA acceptable format
+ - Create an OpenFPGA architecture XML file to customize the primitive circuits
+ - Create a simulation setting XML file to specify the simulation settings
Through this quick example, we will introduce the key steps to build your own FPGA based on a VPR architecture template.
@@ -128,6 +129,7 @@ Craft OpenFPGA Architecture
OpenFPGA needs another XML file which contains detailed modeling on the physical design of FPGA architecture.
This is designed to minimize the modification on the original VPR architecture file, so that it can be reused.
+You may create an XML file `k4_n4_openfpga_arch.xml` and then add contents shown as follows.
Overview on the Structure
^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -136,7 +138,6 @@ An OpenFPGA architecture including the following parts.
- Architecture modeling with a focus on circuit-level description
- Configuration protocol definition
- Annotation on the VPR architecture modules
- - Simulation settings
These parts are organized as follows in the XML file.
@@ -173,10 +174,6 @@ These parts are organized as follows in the XML file.
-
- ...
-
-
Technology Library Definition
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Technology information are all stored under the ```` node, which contains transistor-level information to build the FPGA.
@@ -474,10 +471,13 @@ The complete annotation is shown as follows:
See details in :ref:`annotate_vpr_arch`.
Simulation Settings
-^^^^^^^^^^^^^^^^^^^
+~~~~~~~~~~~~~~~~~~~
+OpenFPGA needs an XML file where detailed simulation settings are defined.
The simulation settings contain critical parameters to build testbenches for verify the FPGA fabric.
+You may create an XML file `k4_n4_openfpga_simulation.xml` and then add contents shown as follows.
+
The complete annotation is shown as follows:
.. code-block:: xml
diff --git a/docs/source/tutorials/design_flow/blif_to_verification.rst b/docs/source/tutorials/design_flow/blif_to_verification.rst
index d3b27a43f..26a0b87cf 100644
--- a/docs/source/tutorials/design_flow/blif_to_verification.rst
+++ b/docs/source/tutorials/design_flow/blif_to_verification.rst
@@ -18,9 +18,9 @@ We will simply execute the following openfpga task-run by
.. code-block:: shell
- python3 openfpga_flow/scripts/run_fpga_task.py openfpga_shell/configuration_chain
+ python3 openfpga_flow/scripts/run_fpga_task.py openfpga_shell/full_testbench/configuration_chain
-Detailed settings, such as architecture XML files and RTL designs, can be found at ``${OPENFPGA_PATH}/openfpga_flow/tasks/openfpga_shell/configuration_chain/config/task.conf``.
+Detailed settings, such as architecture XML files and RTL designs, can be found at ``${OPENFPGA_PATH}/openfpga_flow/tasks/openfpga_shell/full_testbench/configuration_chain/config/task.conf``.
.. note:: ``${OPENFPGA_PATH}`` is the root directory of OpenFPGA
@@ -28,7 +28,7 @@ After this task-run, you can find all the generated netlists and testbenches at
.. code-block:: shell
- ${OPENFPGA_PATH}/openfpga_flow/tasks/openfpga_shell/configuration_chain/latest/k4_N4_tileable_40nm/and2/MIN_ROUTE_CHAN_WIDTH/SRC/
+ ${OPENFPGA_PATH}/openfpga_flow/tasks/openfpga_shell/full_testbench/configuration_chain/latest/k4_N4_tileable_40nm/and2/MIN_ROUTE_CHAN_WIDTH/SRC/
.. note:: See :ref:`fabric_netlists` and :ref:`fpga_verilog_testbench` for the netlist details.
@@ -43,7 +43,7 @@ The simulation results are logged in
.. code-block:: shell
- ${OPENFPGA_PATH}/openfpga_flow/tasks/openfpga_shell/configuration_chain/latest/k4_N4_tileable_40nm/and2/MIN_ROUTE_CHAN_WIDTH/vvp_sim_output.txt
+ ${OPENFPGA_PATH}/openfpga_flow/tasks/openfpga_shell/full_testbench/configuration_chain/latest/k4_N4_tileable_40nm/and2/MIN_ROUTE_CHAN_WIDTH/vvp_sim_output.txt
If the verification passed, you should be able to see ``Simulation Succeed`` in the log file.
@@ -53,7 +53,7 @@ To visualize the waveforms, you can use the `GTKWave
.. code-block:: shell
- gtkwave ${OPENFPGA_PATH}/openfpga_flow/tasks/openfpga_shell/configuration_chain/latest/k4_N4_tileable_40nm/and2/MIN_ROUTE_CHAN_WIDTH/and2_formal.vcd &
+ gtkwave ${OPENFPGA_PATH}/openfpga_flow/tasks/openfpga_shell/full_testbench/configuration_chain/latest/k4_N4_tileable_40nm/and2/MIN_ROUTE_CHAN_WIDTH/and2_formal.vcd &
Manual Method
^^^^^^^^^^^^^
@@ -62,7 +62,7 @@ If you want to run iVerilog simulation manually, you can follow these steps:
.. code-block:: shell
- cd ${OPENFPGA_PATH}/openfpga_flow/tasks/openfpga_shell/configuration_chain/latest/k4_N4_tileable_40nm/and2/MIN_ROUTE_CHAN_WIDTH
+ cd ${OPENFPGA_PATH}/openfpga_flow/tasks/openfpga_shell/full_testbench/configuration_chain/latest/k4_N4_tileable_40nm/and2/MIN_ROUTE_CHAN_WIDTH
source iverilog_output.txt
@@ -73,9 +73,9 @@ Debugging Tips
If you want to apply full visibility to the signals, you need to change the following line in
- .. code-block:: shell
+.. code-block:: shell
- ${OPENFPGA_PATH}/openfpga_flow/tasks/openfpga_shell/configuration_chain/latest/k4_N4_tileable_40nm/and2/MIN_ROUTE_CHAN_WIDTH/SRC/and2_autocheck_top_tb.v
+ ${OPENFPGA_PATH}/openfpga_flow/tasks/openfpga_shell/full_testbench/configuration_chain/latest/k4_N4_tileable_40nm/and2/MIN_ROUTE_CHAN_WIDTH/SRC/and2_autocheck_top_tb.v
from
@@ -100,13 +100,13 @@ You can simply call the python script in the following line:
.. code-block:: shell
- python3 openfpga_flow/scripts/run_modelsim.py openfpga_shell/configuration_chain --run_sim
+ python3 openfpga_flow/scripts/run_modelsim.py openfpga_shell/full_testbench/configuration_chain --run_sim
The script will automatically create a Modelsim project at
.. code-block:: shell
- ${OPENFPGA_PATH}/openfpga_flow/tasks/openfpga_shell/configuration_chain/latest/k4_N4_tileable_40nm/and2/MIN_ROUTE_CHAN_WIDTH/MSIM2/
+ ${OPENFPGA_PATH}/openfpga_flow/tasks/openfpga_shell/full_testbench/configuration_chain/latest/k4_N4_tileable_40nm/and2/MIN_ROUTE_CHAN_WIDTH/MSIM2/
and run the simulation.
@@ -119,7 +119,7 @@ Modify the ``fpga_defines.v`` (see details in :ref:`fabric_netlists`) at
.. code-block:: shell
- ${OPENFPGA_PATH}/openfpga_flow/tasks/openfpga_shell/configuration_chain/latest/k4_N4_tileable_40nm/and2/MIN_ROUTE_CHAN_WIDTH/SRC/
+ ${OPENFPGA_PATH}/openfpga_flow/tasks/openfpga_shellfull_testbench//configuration_chain/latest/k4_N4_tileable_40nm/and2/MIN_ROUTE_CHAN_WIDTH/SRC/
by **deleting** the line
@@ -131,7 +131,7 @@ Create a folder ``MSIM`` under
.. code-block:: shell
- ${OPENFPGA_PATH}/openfpga_flow/tasks/openfpga_shell/configuration_chain/latest/k4_N4_tileable_40nm/and2/MIN_ROUTE_CHAN_WIDTH/
+ ${OPENFPGA_PATH}/openfpga_flow/tasks/openfpga_shell/full_testbench/configuration_chain/latest/k4_N4_tileable_40nm/and2/MIN_ROUTE_CHAN_WIDTH/
Under the ``MSIM`` folder, create symbolic links to ``SRC`` folder and reference benchmarks by
@@ -149,7 +149,7 @@ Add the following file to your project:
.. code-block:: shell
- ${OPENFPGA_PATH}/openfpga_flow/tasks/openfpga_shell/configuration_chain/latest/k4_N4_tileable_40nm/and2/MIN_ROUTE_CHAN_WIDTH/SRC/and2_include_netlists.v
+ ${OPENFPGA_PATH}/openfpga_flow/tasks/openfpga_shell/full_testbench/configuration_chain/latest/k4_N4_tileable_40nm/and2/MIN_ROUTE_CHAN_WIDTH/SRC/and2_include_netlists.v
Compile the netlists, create a simulation configuration and specify ``and2_autocheck_top_tb`` at the top unit.
diff --git a/libopenfpga/CMakeLists.txt b/libopenfpga/CMakeLists.txt
index 00cf0acf0..92d25522a 100644
--- a/libopenfpga/CMakeLists.txt
+++ b/libopenfpga/CMakeLists.txt
@@ -3,3 +3,5 @@ add_subdirectory(libini)
add_subdirectory(libopenfpgashell)
add_subdirectory(libarchopenfpga)
add_subdirectory(libopenfpgautil)
+add_subdirectory(libfabrickey)
+add_subdirectory(libfpgabitstream)
diff --git a/libopenfpga/libarchopenfpga/src/write_xml_utils.cpp b/libopenfpga/libarchopenfpga/src/write_xml_utils.cpp
index e4d32e720..a416203ee 100644
--- a/libopenfpga/libarchopenfpga/src/write_xml_utils.cpp
+++ b/libopenfpga/libarchopenfpga/src/write_xml_utils.cpp
@@ -61,6 +61,21 @@ void write_xml_attribute(std::fstream& fp,
fp << "\"";
}
+/********************************************************************
+ * A most utilized function to write an XML attribute to file
+ * This accepts the value as a size_t
+ *******************************************************************/
+void write_xml_attribute(std::fstream& fp,
+ const char* attr,
+ const size_t& value) {
+ /* Validate the file stream */
+ openfpga::valid_file_stream(fp);
+
+ fp << " " << attr << "=\"";
+ fp << value;
+ fp << "\"";
+}
+
/********************************************************************
* A most utilized function to write an XML attribute to file
* This accepts the value as a float
diff --git a/libopenfpga/libarchopenfpga/src/write_xml_utils.h b/libopenfpga/libarchopenfpga/src/write_xml_utils.h
index 3976d78b9..b54caf6db 100644
--- a/libopenfpga/libarchopenfpga/src/write_xml_utils.h
+++ b/libopenfpga/libarchopenfpga/src/write_xml_utils.h
@@ -26,4 +26,8 @@ void write_xml_attribute(std::fstream& fp,
const char* attr,
const float& value);
+void write_xml_attribute(std::fstream& fp,
+ const char* attr,
+ const size_t& value);
+
#endif
diff --git a/libopenfpga/libfabrickey/CMakeLists.txt b/libopenfpga/libfabrickey/CMakeLists.txt
new file mode 100644
index 000000000..db52b510e
--- /dev/null
+++ b/libopenfpga/libfabrickey/CMakeLists.txt
@@ -0,0 +1,35 @@
+cmake_minimum_required(VERSION 3.9)
+
+project("libfabrickey")
+
+file(GLOB_RECURSE EXEC_SOURCES test/*.cpp)
+file(GLOB_RECURSE LIB_SOURCES src/*.cpp)
+file(GLOB_RECURSE LIB_HEADERS src/*.h)
+files_to_dirs(LIB_HEADERS LIB_INCLUDE_DIRS)
+
+#Remove test executable from library
+list(REMOVE_ITEM LIB_SOURCES ${EXEC_SOURCES})
+
+#Create the library
+add_library(libfabrickey STATIC
+ ${LIB_HEADERS}
+ ${LIB_SOURCES})
+target_include_directories(libfabrickey PUBLIC ${LIB_INCLUDE_DIRS})
+set_target_properties(libfabrickey PROPERTIES PREFIX "") #Avoid extra 'lib' prefix
+
+#Specify link-time dependancies
+target_link_libraries(libfabrickey
+ libopenfpgautil
+ libarchopenfpga
+ libvtrutil
+ libpugixml
+ libpugiutil)
+
+#Create the test executable
+foreach(testsourcefile ${EXEC_SOURCES})
+ # Use a simple string replace, to cut off .cpp.
+ get_filename_component(testname ${testsourcefile} NAME_WE)
+ add_executable(${testname} ${testsourcefile})
+ # Make sure the library is linked to each test executable
+ target_link_libraries(${testname} libfabrickey)
+endforeach(testsourcefile ${EXEC_SOURCES})
diff --git a/libopenfpga/libfabrickey/key_examples/key_example.xml b/libopenfpga/libfabrickey/key_examples/key_example.xml
new file mode 100644
index 000000000..49140b6e0
--- /dev/null
+++ b/libopenfpga/libfabrickey/key_examples/key_example.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/libopenfpga/libfabrickey/src/fabric_key.cpp b/libopenfpga/libfabrickey/src/fabric_key.cpp
new file mode 100644
index 000000000..0c2c508bd
--- /dev/null
+++ b/libopenfpga/libfabrickey/src/fabric_key.cpp
@@ -0,0 +1,86 @@
+#include "vtr_assert.h"
+
+#include "fabric_key.h"
+
+/************************************************************************
+ * Member functions for class FabricKey
+ ***********************************************************************/
+
+/************************************************************************
+ * Constructors
+ ***********************************************************************/
+FabricKey::FabricKey() {
+ return;
+}
+
+/************************************************************************
+ * Public Accessors : aggregates
+ ***********************************************************************/
+FabricKey::fabric_key_range FabricKey::keys() const {
+ return vtr::make_range(key_ids_.begin(), key_ids_.end());
+}
+
+/************************************************************************
+ * Public Accessors : Basic data query
+ ***********************************************************************/
+/* Access the name of a key */
+std::string FabricKey::key_name(const FabricKeyId& key_id) const {
+ /* validate the key_id */
+ VTR_ASSERT(valid_key_id(key_id));
+ return key_names_[key_id];
+}
+
+/* Access the value of a key */
+size_t FabricKey::key_value(const FabricKeyId& key_id) const {
+ /* validate the key_id */
+ VTR_ASSERT(valid_key_id(key_id));
+ return key_values_[key_id];
+}
+
+bool FabricKey::empty() const {
+ return 0 == key_ids_.size();
+}
+
+/************************************************************************
+ * Public Mutators
+ ***********************************************************************/
+void FabricKey::reserve_keys(const size_t& num_keys) {
+ key_ids_.reserve(num_keys);
+ key_names_.reserve(num_keys);
+ key_values_.reserve(num_keys);
+}
+
+/* Create a new key and add it to the library, return an id */
+FabricKeyId FabricKey::create_key() {
+ /* Create a new id */
+ FabricKeyId key = FabricKeyId(key_ids_.size());
+ key_ids_.push_back(key);
+ key_names_.emplace_back();
+ key_values_.emplace_back();
+
+ return key;
+}
+
+void FabricKey::set_key_name(const FabricKeyId& key_id,
+ const std::string& name) {
+ /* validate the key_id */
+ VTR_ASSERT(valid_key_id(key_id));
+
+ key_names_[key_id] = name;
+}
+
+void FabricKey::set_key_value(const FabricKeyId& key_id,
+ const size_t& value) {
+ /* validate the key_id */
+ VTR_ASSERT(valid_key_id(key_id));
+
+ key_values_[key_id] = value;
+}
+
+/************************************************************************
+ * Internal invalidators/validators
+ ***********************************************************************/
+/* Validators */
+bool FabricKey::valid_key_id(const FabricKeyId& key_id) const {
+ return ( size_t(key_id) < key_ids_.size() ) && ( key_id == key_ids_[key_id] );
+}
diff --git a/libopenfpga/libfabrickey/src/fabric_key.h b/libopenfpga/libfabrickey/src/fabric_key.h
new file mode 100644
index 000000000..053e32e56
--- /dev/null
+++ b/libopenfpga/libfabrickey/src/fabric_key.h
@@ -0,0 +1,60 @@
+#ifndef FABRIC_KEY_H
+#define FABRIC_KEY_H
+
+/********************************************************************
+ * This file include the declaration of fabric key
+ *******************************************************************/
+#include
+#include