Merge pull request #72 from LNIS-Projects/dev

Fabric Bitstream file writer
This commit is contained in:
tangxifan 2020-07-26 23:05:32 -06:00 committed by GitHub
commit 03dc0ee7ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 1338 additions and 138 deletions

View File

@ -44,4 +44,7 @@ python3 openfpga_flow/scripts/run_fpga_task.py fixed_simulation_settings --debug
echo -e "Testing SDC generation with time units";
python3 openfpga_flow/scripts/run_fpga_task.py sdc_time_unit --debug --show_thread_logs
echo -e "Testing FPGA-SPICE with netlist generation";
python3 openfpga_flow/scripts/run_fpga_task.py generate_spice --debug --show_thread_logs
end_section "OpenFPGA.TaskTun"

View File

@ -78,6 +78,9 @@ python3 openfpga_flow/scripts/run_fpga_task.py fabric_key/load_external_key --de
echo -e "Testing Power-gating designs";
python3 openfpga_flow/scripts/run_fpga_task.py power_gated_design/power_gated_inverter --show_thread_logs --debug
echo -e "Testing Depopulated crossbar in local routing";
python3 openfpga_flow/scripts/run_fpga_task.py depopulate_crossbar --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

View File

@ -13,8 +13,8 @@ General organization is as follows.
<device_model name="<string>" type="<string>">
<lib type="<string>" corner="<string>" ref="<string>" path="<string>"/>
<design vdd="<float>" pn_ratio="<float>"/>
<pmos name="<string>" chan_length="<float>" min_width="<float>" variation="<string>"/>
<nmos name="<string>" chan_length="<float>" min_width="<float>" variation="<string>"/>
<pmos name="<string>" chan_length="<float>" min_width="<float>" max_width="<float>" variation="<string>"/>
<nmos name="<string>" chan_length="<float>" min_width="<float>" max_width="<float>" variation="<string>"/>
<rram rlrs="<float>" rhrs="<float>" variation="<string>"/>
</device_model>
</device_library>
@ -71,15 +71,19 @@ A device model represents a transistor/RRAM model available in users' technology
- ``pn_ratio="<float>"`` specify the ratio between *p*-type and *n*-type transistors. The ratio will be used when building circuit structures such as inverters, buffers, etc.
.. option:: <pmos|nmos name="<string>" chan_length="<float>" min_width="<float>" variation="<string>"/>
.. option:: <pmos|nmos name="<string>" chan_length="<float>" min_width="<float>" max_width="<float>" variation="<string>"/>
Specify device-level parameters for transistors
- ``name="<string>"`` specify the name of the p/n type transistor, which can be found in the manual of the technology provider.
- ``chan_length="<float>"`` specify the channel length of *p/n* type transistor.
- ``chan_length="<float>"`` specify the channel length of a *p/n* type transistor.
- ``min_width="<float>"`` specify the minimum width of *p/n* type transistor. This parameter will be used in building inverter, buffer, *etc*. as a base number for transistor sizing.
- ``min_width="<float>"`` specify the minimum width of a *p/n* type transistor. This parameter will be used in building inverter, buffer, *etc*. as a base number for transistor sizing.
- ``max_width="<float>"`` specify the maximum width of a *p/n* type transistor. This parameter will be used in building inverter, buffer, *etc*. as a base number for transistor sizing. If the required transistor width exceeds the maximum width, multiple transistors will be instanciated. Note that for FinFET technology, your ``max_width`` should be the same as your ``min_width``.
.. note:: The ``max_width`` is optional. By default, it will be set to be same as the ``min_width``.
- ``variation="<string>"`` specify the variation name defined in the ``<variation_library>``

View File

@ -1,7 +1,131 @@
Fabric-dependent Bitstream
~~~~~~~~~~~~~~~~~~~~~~~~~~
Usage
`````
Fabric-dependent bitstream is design to be loadable to the configuration protocols of FPGAs.
The bitstream just sets an order to the configuration bits in the database, without duplicating the database.
OpenFPGA framework provides a fabric-dependent bitstream generator which is aligned to our Verilog netlists.
The fabric-dependent bitstream can be found in autogenerated Verilog testbenches.
The fabric-dependent bitstream can be found in the pre-configured Verilog testbenches.
The fabric bitsteam can be outputted in different file format in terms of usage.
Plain Text File Format
```````````````````````
This file format is designed to be directly loaded to an FPGA fabric.
It does not include any comments but only bitstream.
The information depends on the type of configuration procotol.
.. option:: vanilla
A line consisting of ``0`` | ``1``
.. option:: scan_chain
A line consisting of ``0`` | ``1``
.. option:: memory_bank
Multiple lines will be included, each of which is organized as <address><space><bit>.
Note that due to the use of Bit-Line and Word-Line decoders, every two lines are paired.
The first line represents the Bit-Line address and configuration bit.
The second line represents the Word-Line address and configuration bit.
For example
.. code-block:: xml
<bitline_address> <bit_value>
<wordline_address> <bit_value>
<bitline_address> <bit_value>
<wordline_address> <bit_value>
...
<bitline_address> <bit_value>
<wordline_address> <bit_value>
.. option:: frame_based
Multiple lines will be included, each of which is organized as <address><space><bit>.
For example
.. code-block:: xml
<frame_address> <bit_value>
<frame_address> <bit_value>
...
<frame_address> <bit_value>
XML File Format
```````````````
This file format is designed to generate testbenches using external tools, e.g., CocoTB.
In principle, the file consist a number of XML node ``<bit>``, each bit contains the following attributes:
- ``id``: The unique id of the configuration bit in the fabric bitstream.
- ``value``: The configuration bit value.
- ``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
A quick example:
.. code-block:: xml
<bit id="0" value="1">
<hierarchy>
<instance level="0" name="fpga_top"/>
<instance level="1" name="grid_clb_1__2_"/>
<instance level="2" name="logical_tile_clb_mode_clb__0"/>
<instance level="3" name="mem_fle_9_in_5"/>
</hierarchy>
</bit>
Other information may depend on the type of configuration procotol.
.. option:: memory_bank
- ``bl``: Bit line address information
- ``wl``: Word line address information
A quick example:
.. code-block:: xml
<bit id="0" value="1">
<hierarchy>
<instance level="0" name="fpga_top"/>
<instance level="1" name="grid_io_bottom_1__0_"/>
<instance level="2" name="logical_tile_io_mode_io__0"/>
<instance level="3" name="logical_tile_io_mode_physical__iopad_0"/>
<instance level="4" name="iopad_sram_blwl_mem"/>
</hierarchy>
<bl address="000000"/>
<wl address="000000"/>
</bit>
.. option:: frame_based
- ``frame``: frame address information
A quick example:
.. code-block:: xml
<bit id="0" value="1">
<hierarchy>
<instance level="0" name="fpga_top"/>
<instance level="1" name="grid_io_bottom_1__0_"/>
<instance level="2" name="logical_tile_io_mode_io__0"/>
<instance level="3" name="logical_tile_io_mode_physical__iopad_0"/>
<instance level="4" name="iopad_config_latch_mem"/>
</hierarchy>
<frame address="0000000000000000"/>
</bit>

View File

@ -30,4 +30,6 @@ build_fabric_bitstream
- ``--file`` or ``-f`` Output the fabric bitstream to an plain text file (only 0 or 1)
- ``--format`` Specify the file format [``plain_text``|``xml``]. By default is ``plain_text``.
- ``--verbose`` Show verbose log

View File

@ -109,6 +109,10 @@ build_fabric
- ``--write_fabric_key <xml_file>`` Output current fabric key to an XML file
- ``--frame_view`` Create only frame views of the module graph. When enabled, top-level module will not include any nets. This option is made for save runtime and memory.
.. warning:: Recommend to turn the option on when bitstream generation is the only purpose of the flow. Do not use it when you need generate netlists!
- ``--verbose`` Show verbose log
.. note:: This is a must-run command before launching FPGA-Verilog, FPGA-Bitstream, FPGA-SDC and FPGA-SPICE

View File

@ -122,6 +122,14 @@ void read_xml_device_transistor(pugi::xml_node& xml_device_transistor,
tech_lib.set_transistor_model_min_width(device_model, transistor_type,
get_attribute(xml_device_transistor, "min_width", loc_data).as_float(0.));
/* Parse the transistor maximum width, by default we consider the same as minimum width */
tech_lib.set_transistor_model_max_width(device_model, transistor_type,
get_attribute(xml_device_transistor, "max_width", loc_data, pugiutil::ReqOpt::OPTIONAL).as_float(0.));
/* If the max_width is default value, we set it to be the same as min_width */
if (0. == tech_lib.transistor_model_max_width(device_model, transistor_type)) {
tech_lib.set_transistor_model_max_width(device_model, transistor_type, tech_lib.transistor_model_min_width(device_model, transistor_type));
}
/* Parse the transistor variation name */
tech_lib.set_transistor_model_variation_name(device_model, transistor_type,
get_attribute(xml_device_transistor, "variation", loc_data).as_string());

View File

@ -157,6 +157,18 @@ float TechnologyLibrary::transistor_model_min_width(const TechnologyModelId& mod
return transistor_model_min_widths_[model_id][transistor_type];
}
/* Access the maximum width of a transistor (either PMOS or NMOS) for a technology model
* Note: This is ONLY applicable to transistor model
*/
float TechnologyLibrary::transistor_model_max_width(const TechnologyModelId& model_id,
const e_tech_lib_transistor_type& transistor_type) const {
/* validate the model_id */
VTR_ASSERT(valid_model_id(model_id));
/* This is only applicable to transistor model */
VTR_ASSERT(TECH_LIB_MODEL_TRANSISTOR == model_type(model_id));
return transistor_model_max_widths_[model_id][transistor_type];
}
/* Access the minimum width of a transistor (either PMOS or NMOS) for a technology model
* Note: This is ONLY applicable to transistor model
*/
@ -270,6 +282,7 @@ TechnologyModelId TechnologyLibrary::add_model(const std::string& name) {
transistor_model_names_.emplace_back();
transistor_model_chan_lengths_.emplace_back();
transistor_model_min_widths_.emplace_back();
transistor_model_max_widths_.emplace_back();
transistor_model_variation_names_.emplace_back();
transistor_model_variation_ids_.push_back(std::array<TechnologyVariationId, 2>{TechnologyVariationId::INVALID(), TechnologyVariationId::INVALID()});
@ -394,6 +407,19 @@ void TechnologyLibrary::set_transistor_model_min_width(const TechnologyModelId&
return;
}
/* Set the maximum width for either PMOS or NMOS of a model in the library
* This is ONLY applicable to transistors
*/
void TechnologyLibrary::set_transistor_model_max_width(const TechnologyModelId& model_id,
const e_tech_lib_transistor_type& transistor_type,
const float& max_width) {
/* validate the model_id */
VTR_ASSERT(valid_model_id(model_id));
VTR_ASSERT(TECH_LIB_MODEL_TRANSISTOR == model_type(model_id));
transistor_model_max_widths_[model_id][transistor_type] = max_width;
return;
}
/* Set the variation name for either PMOS or NMOS of a model in the library
* This is ONLY applicable to transistors
*/

View File

@ -101,6 +101,8 @@ class TechnologyLibrary {
const e_tech_lib_transistor_type& transistor_type) const;
float transistor_model_min_width(const TechnologyModelId& model_id,
const e_tech_lib_transistor_type& transistor_type) const;
float transistor_model_max_width(const TechnologyModelId& model_id,
const e_tech_lib_transistor_type& transistor_type) const;
TechnologyVariationId transistor_model_variation(const TechnologyModelId& model_id,
const e_tech_lib_transistor_type& transistor_type) const;
public: /* Public Accessors: Basic data query on RRAM models */
@ -138,6 +140,9 @@ class TechnologyLibrary {
void set_transistor_model_min_width(const TechnologyModelId& model_id,
const e_tech_lib_transistor_type& transistor_type,
const float& min_width);
void set_transistor_model_max_width(const TechnologyModelId& model_id,
const e_tech_lib_transistor_type& transistor_type,
const float& max_width);
void set_transistor_model_variation_name(const TechnologyModelId& model_id,
const e_tech_lib_transistor_type& transistor_type,
const std::string& variation_name);
@ -231,6 +236,15 @@ class TechnologyLibrary {
*/
vtr::vector<TechnologyModelId, std::array<float, 2>> transistor_model_min_widths_;
/* The maximum width of a transistor.
* This should be defined by your technology vendor
* The maximum width of a transistor will be used to size your transistors
* If the required width in circuit models in larger then the max width,
* multiple transistor bin will be instanciated.
* For FinFET, the maximum width should be the same as min_width
*/
vtr::vector<TechnologyModelId, std::array<float, 2>> transistor_model_max_widths_;
/* The variation name and id binded to PMOS and NMOS transistor
* We expect users to provide the exact name of variation defined in this technology library
* the name and id will be automatically matched by using function link_model_to_variation()

View File

@ -92,6 +92,25 @@ void write_xml_design_technology(std::fstream& fp,
fp << "/>" << "\n";
}
/********************************************************************
* A writer to output the device technology of a circuit model to XML format
*******************************************************************/
static
void write_xml_device_technology(std::fstream& fp,
const char* fname,
const CircuitLibrary& circuit_lib,
const CircuitModelId& model) {
/* Validate the file stream */
openfpga::check_file_stream(fname, fp);
if (!circuit_lib.device_model_name(model).empty()) {
fp << "\t\t\t" << "<device_technology";
write_xml_attribute(fp, "device_model_name", circuit_lib.device_model_name(model).c_str());
/* Finish all the attributes, we can return here */
fp << "/>" << "\n";
}
}
/********************************************************************
* A writer to output a circuit port to XML format
*******************************************************************/
@ -401,6 +420,9 @@ void write_xml_circuit_model(std::fstream& fp,
/* Write the design technology of circuit model */
write_xml_design_technology(fp, fname, circuit_lib, model);
/* Write the device technology of circuit model */
write_xml_device_technology(fp, fname, circuit_lib, model);
/* Write the input buffer information of circuit model,
* only applicable when this circuit model is neither inverter nor buffer
*/

View File

@ -60,6 +60,7 @@ void write_xml_device_model(std::fstream& fp,
write_xml_attribute(fp, "name", tech_lib.transistor_model_name(device_model, TECH_LIB_TRANSISTOR_PMOS).c_str());
write_xml_attribute(fp, "chan_length", tech_lib.transistor_model_chan_length(device_model, TECH_LIB_TRANSISTOR_PMOS));
write_xml_attribute(fp, "min_width", tech_lib.transistor_model_min_width(device_model, TECH_LIB_TRANSISTOR_PMOS));
write_xml_attribute(fp, "max_width", tech_lib.transistor_model_max_width(device_model, TECH_LIB_TRANSISTOR_PMOS));
if (TechnologyVariationId::INVALID() != tech_lib.transistor_model_variation(device_model, TECH_LIB_TRANSISTOR_PMOS)) {
write_xml_attribute(fp, "variation", tech_lib.variation_name(tech_lib.transistor_model_variation(device_model, TECH_LIB_TRANSISTOR_PMOS)).c_str());
}

View File

@ -52,6 +52,13 @@ bool BitstreamManager::bit_value(const ConfigBitId& bit_id) const {
return '1' == bit_values_[bit_id];
}
ConfigBlockId BitstreamManager::bit_parent_block(const ConfigBitId& bit_id) const {
/* Ensure a valid id */
VTR_ASSERT(true == valid_bit_id(bit_id));
return bit_parent_blocks_[bit_id];
}
std::string BitstreamManager::block_name(const ConfigBlockId& block_id) const {
/* Ensure the input ids are valid */
VTR_ASSERT(true == valid_block_id(block_id));
@ -140,7 +147,7 @@ std::string BitstreamManager::block_output_net_ids(const ConfigBlockId& block_id
/******************************************************************************
* Public Mutators
******************************************************************************/
ConfigBitId BitstreamManager::add_bit(const bool& bit_value) {
ConfigBitId BitstreamManager::add_bit(const ConfigBlockId& parent_block, const bool& bit_value) {
ConfigBitId bit = ConfigBitId(num_bits_);
/* Add a new bit, and allocate associated data structures */
num_bits_++;
@ -150,6 +157,8 @@ ConfigBitId BitstreamManager::add_bit(const bool& bit_value) {
bit_values_.push_back('0');
}
bit_parent_blocks_.push_back(parent_block);
return bit;
}
@ -234,7 +243,7 @@ void BitstreamManager::add_block_bits(const ConfigBlockId& block,
block_bit_id_lsbs_[block] = num_bits_;
block_bit_lengths_[block] = block_bitstream.size();
for (const bool& bit : block_bitstream) {
add_bit(bit);
add_bit(block, bit);
}
}

View File

@ -119,6 +119,9 @@ class BitstreamManager {
/* Find the value of bitstream */
bool bit_value(const ConfigBitId& bit_id) const;
/* Find the parent block of a configuration bit */
ConfigBlockId bit_parent_block(const ConfigBitId& bit_id) const;
/* Find a name of a block */
std::string block_name(const ConfigBlockId& block_id) const;
@ -145,7 +148,7 @@ class BitstreamManager {
public: /* Public Mutators */
/* Add a new configuration bit to the bitstream manager */
ConfigBitId add_bit(const bool& bit_value);
ConfigBitId add_bit(const ConfigBlockId& parent_block, const bool& bit_value);
/* Reserve memory for a number of clocks */
void reserve_blocks(const size_t& num_blocks);
@ -235,6 +238,7 @@ class BitstreamManager {
std::unordered_set<ConfigBitId> invalid_bit_ids_;
/* value of a bit in the Bitstream */
vtr::vector<ConfigBitId, char> bit_values_;
vtr::vector<ConfigBitId, ConfigBlockId> bit_parent_blocks_;
};
} /* end namespace openfpga */

View File

@ -16,7 +16,8 @@
#include "write_xml_arch_bitstream.h"
#include "build_device_bitstream.h"
#include "fabric_bitstream_writer.h"
#include "write_text_fabric_bitstream.h"
#include "write_xml_fabric_bitstream.h"
#include "build_fabric_bitstream.h"
#include "openfpga_bitstream.h"
@ -66,6 +67,7 @@ int build_fabric_bitstream(OpenfpgaContext& openfpga_ctx,
CommandOptionId opt_verbose = cmd.option("verbose");
CommandOptionId opt_file = cmd.option("file");
CommandOptionId opt_file_format = cmd.option("format");
/* Build fabric bitstream here */
openfpga_ctx.mutable_fabric_bitstream() = build_fabric_dependent_bitstream(openfpga_ctx.bitstream_manager(),
@ -81,10 +83,24 @@ int build_fabric_bitstream(OpenfpgaContext& openfpga_ctx,
/* Create directories */
create_directory(src_dir_path);
status = write_fabric_bitstream_to_text_file(openfpga_ctx.bitstream_manager(),
openfpga_ctx.fabric_bitstream(),
openfpga_ctx.arch().config_protocol,
cmd_context.option_value(cmd, opt_file));
/* Check file format requirements */
std::string file_format("plain_text");
if (true == cmd_context.option_enable(cmd, opt_file_format)) {
file_format = cmd_context.option_value(cmd, opt_file_format);
}
if (std::string("xml") == file_format) {
status = write_fabric_bitstream_to_xml_file(openfpga_ctx.bitstream_manager(),
openfpga_ctx.fabric_bitstream(),
openfpga_ctx.arch().config_protocol,
cmd_context.option_value(cmd, opt_file));
} else {
/* By default, output in plain text format */
status = write_fabric_bitstream_to_text_file(openfpga_ctx.bitstream_manager(),
openfpga_ctx.fabric_bitstream(),
openfpga_ctx.arch().config_protocol,
cmd_context.option_value(cmd, opt_file));
}
}
/* TODO: should identify the error code from internal function execution */

View File

@ -85,6 +85,10 @@ ShellCommandId add_openfpga_fabric_bitstream_command(openfpga::Shell<OpenfpgaCon
shell_cmd.set_option_short_name(opt_file, "f");
shell_cmd.set_option_require_value(opt_file, openfpga::OPT_STRING);
/* Add an option '--file_format'*/
CommandOptionId opt_file_format = shell_cmd.add_option("format", false, "file format of fabric bitstream [plain_text|xml]. Default: plain_text");
shell_cmd.set_option_require_value(opt_file_format, openfpga::OPT_STRING);
/* Add an option '--verbose' */
shell_cmd.add_option("verbose", false, "Enable verbose output");

View File

@ -1,6 +1,6 @@
/********************************************************************
* This file includes functions that output a fabric-dependent
* bitstream database to files in different formats
* bitstream database to files in plain text
*******************************************************************/
#include <chrono>
#include <ctime>
@ -17,7 +17,7 @@
#include "openfpga_naming.h"
#include "bitstream_manager_utils.h"
#include "fabric_bitstream_writer.h"
#include "write_text_fabric_bitstream.h"
/* begin namespace openfpga */
namespace openfpga {

View File

@ -1,5 +1,5 @@
#ifndef FABRIC_BITSTREAM_WRITER_H
#define FABRIC_BITSTREAM_WRITER_H
#ifndef WRITE_TEXT_FABRIC_BITSTREAM_H
#define WRITE_TEXT_FABRIC_BITSTREAM_H
/********************************************************************
* Include header files that are required by function declaration

View File

@ -0,0 +1,194 @@
/********************************************************************
* This file includes functions that output a fabric-dependent
* bitstream database to files in XML format
*******************************************************************/
#include <chrono>
#include <ctime>
#include <fstream>
/* Headers from vtrutil library */
#include "vtr_assert.h"
#include "vtr_log.h"
#include "vtr_time.h"
/* Headers from openfpgautil library */
#include "openfpga_digest.h"
/* Headers from archopenfpga library */
#include "openfpga_naming.h"
#include "bitstream_manager_utils.h"
#include "write_xml_fabric_bitstream.h"
/* begin namespace openfpga */
namespace openfpga {
/********************************************************************
* This function write header information to a bitstream file
*******************************************************************/
static
void write_fabric_bitstream_xml_file_head(std::fstream& fp) {
valid_file_stream(fp);
auto end = std::chrono::system_clock::now();
std::time_t end_time = std::chrono::system_clock::to_time_t(end);
fp << "<!--" << std::endl;
fp << "\t- Fabric bitstream" << std::endl;
fp << "\t- Author: Xifan TANG" << std::endl;
fp << "\t- Organization: University of Utah" << std::endl;
fp << "\t- Date: " << std::ctime(&end_time) ;
fp << "-->" << std::endl;
fp << std::endl;
}
/********************************************************************
* Write a configuration bit into a plain text file
* General format
* <bit id="<fabric_bit>" value="<config_bit_value>">
* <hierarchy>
* <!-- configurable memory hierarchy -->
* </hierarchy>
* <!-- address information -->
* ...
* </bit>
* The format depends on the type of configuration protocol
* - Vanilla (standalone): No more information to be included
* - Configuration chain: No more information to be included
* - Memory bank :
* <bl address="<bl_address_value>"/>
* <wl address="<wl_address_value>"/>
* - Frame-based configuration protocol :
* <frame address="<frame_address_value>"/>
*
* Return:
* - 0 if succeed
* - 1 if critical errors occured
*******************************************************************/
static
int write_fabric_config_bit_to_xml_file(std::fstream& fp,
const BitstreamManager& bitstream_manager,
const FabricBitstream& fabric_bitstream,
const FabricBitId& fabric_bit,
const e_config_protocol_type& config_type) {
if (false == valid_file_stream(fp)) {
return 1;
}
fp << "<bit id=\"" << size_t(fabric_bit) << "\" ";
fp << "value=\"";
fp << bitstream_manager.bit_value(fabric_bitstream.config_bit(fabric_bit));
fp << "\">\n";
/* Output hierarchy of this parent*/
const ConfigBitId& config_bit = fabric_bitstream.config_bit(fabric_bit);
const ConfigBlockId& config_block = bitstream_manager.bit_parent_block(config_bit);
std::vector<ConfigBlockId> block_hierarchy = find_bitstream_manager_block_hierarchy(bitstream_manager, config_block);
write_tab_to_file(fp, 1);
fp << "<hierarchy>\n";
size_t hierarchy_counter = 0;
for (const ConfigBlockId& temp_block : block_hierarchy) {
write_tab_to_file(fp, 2);
fp << "<instance level=\"" << hierarchy_counter << "\"";
fp << " name=\"" << bitstream_manager.block_name(temp_block) << "\"";
fp << "/>\n";
hierarchy_counter++;
}
write_tab_to_file(fp, 1);
fp << "</hierarchy>\n";
switch (config_type) {
case CONFIG_MEM_STANDALONE:
case CONFIG_MEM_SCAN_CHAIN:
break;
case CONFIG_MEM_MEMORY_BANK: {
/* Bit line address */
write_tab_to_file(fp, 1);
fp << "<bl address=\"";
for (const char& addr_bit : fabric_bitstream.bit_bl_address(fabric_bit)) {
fp << addr_bit;
}
fp << "\"/>\n";
write_tab_to_file(fp, 1);
fp << "<wl address=\"";
for (const char& addr_bit : fabric_bitstream.bit_wl_address(fabric_bit)) {
fp << addr_bit;
}
fp << "\"/>\n";
break;
}
case CONFIG_MEM_FRAME_BASED: {
write_tab_to_file(fp, 1);
fp << "<frame address=\"";
for (const char& addr_bit : fabric_bitstream.bit_address(fabric_bit)) {
fp << addr_bit;
}
fp << "\"/>\n";
break;
}
default:
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Invalid configuration protocol type!\n");
return 1;
}
fp << "</bit>\n";
return 0;
}
/********************************************************************
* Write the fabric bitstream to an XML file
* Notes:
* - This file is designed to be reused by testbench generators, e.g., CocoTB
* - It can NOT be directly loaded to the FPGA fabric
* - It include configurable memory paths in full hierarchy
*
* Return:
* - 0 if succeed
* - 1 if critical errors occured
*******************************************************************/
int write_fabric_bitstream_to_xml_file(const BitstreamManager& bitstream_manager,
const FabricBitstream& fabric_bitstream,
const ConfigProtocol& config_protocol,
const std::string& fname) {
/* Ensure that we have a valid file name */
if (true == fname.empty()) {
VTR_LOG_ERROR("Received empty file name to output bitstream!\n\tPlease specify a valid file name.\n");
}
std::string timer_message = std::string("Write ") + std::to_string(fabric_bitstream.num_bits()) + std::string(" fabric bitstream into xml file '") + fname + std::string("'");
vtr::ScopedStartFinishTimer timer(timer_message);
/* Create the file stream */
std::fstream fp;
fp.open(fname, std::fstream::out | std::fstream::trunc);
check_file_stream(fname.c_str(), fp);
/* Write XML head */
write_fabric_bitstream_xml_file_head(fp);
/* Output fabric bitstream to the file */
int status = 0;
for (const FabricBitId& fabric_bit : fabric_bitstream.bits()) {
status = write_fabric_config_bit_to_xml_file(fp, bitstream_manager,
fabric_bitstream,
fabric_bit,
config_protocol.type());
if (1 == status) {
break;
}
}
/* Print an end to the file here */
fp << std::endl;
/* Close file handler */
fp.close();
return status;
}
} /* end namespace openfpga */

View File

@ -0,0 +1,27 @@
#ifndef WRITE_XML_FABRIC_BITSTREAM_H
#define WRITE_XML_FABRIC_BITSTREAM_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include <string>
#include <vector>
#include "bitstream_manager.h"
#include "fabric_bitstream.h"
#include "config_protocol.h"
/********************************************************************
* Function declaration
*******************************************************************/
/* begin namespace openfpga */
namespace openfpga {
int write_fabric_bitstream_to_xml_file(const BitstreamManager& bitstream_manager,
const FabricBitstream& fabric_bitstream,
const ConfigProtocol& config_protocol,
const std::string& fname);
} /* end namespace openfpga */
#endif

View File

@ -5,6 +5,7 @@
* logic gates etc.
***********************************************/
#include <fstream>
#include <cmath>
#include <iomanip>
/* Headers from vtrutil library */
@ -26,9 +27,9 @@
/* begin namespace openfpga */
namespace openfpga {
/************************************************
/********************************************************************
* Print a SPICE model wrapper for a transistor model
***********************************************/
*******************************************************************/
static
int print_spice_transistor_model_wrapper(std::fstream& fp,
const TechnologyLibrary& tech_lib,
@ -69,9 +70,9 @@ int print_spice_transistor_model_wrapper(std::fstream& fp,
return CMD_EXEC_SUCCESS;
}
/************************************************
/********************************************************************
* Generate the SPICE netlist for transistors
***********************************************/
*******************************************************************/
int print_spice_transistor_wrapper(NetlistManager& netlist_manager,
const TechnologyLibrary& tech_lib,
const std::string& submodule_dir) {
@ -85,9 +86,11 @@ int print_spice_transistor_wrapper(NetlistManager& netlist_manager,
check_file_stream(spice_fname.c_str(), fp);
/* Create file */
VTR_LOG("Generating SPICE netlist '%s' for essential gates...",
VTR_LOG("Generating SPICE netlist '%s' for transistors...",
spice_fname.c_str());
print_spice_file_header(fp, std::string("Transistor wrappers"));
/* Iterate over the transistor models */
for (const TechnologyModelId& model : tech_lib.models()) {
/* Focus on transistor model */
@ -113,9 +116,147 @@ int print_spice_transistor_wrapper(NetlistManager& netlist_manager,
return CMD_EXEC_SUCCESS;
}
/************************************************
/********************************************************************
* Generate the SPICE modeling for a power-gated inverter
*
* This function is created to be shared by inverter and buffer SPICE netlist writer
*
* Note:
* - This function does NOT create a file
* but requires a file stream created
* - This function only output SPICE modeling for
* an inverter. Any preprocessing or subckt definition should not be included!
*******************************************************************/
static
int print_spice_powergated_inverter_pmos_modeling(std::fstream& fp,
const std::string& trans_name_postfix,
const std::string& input_port_name,
const std::string& output_port_name,
const CircuitLibrary& circuit_lib,
const CircuitPortId& enb_port,
const TechnologyLibrary& tech_lib,
const TechnologyModelId& tech_model,
const float& trans_width) {
if (false == valid_file_stream(fp)) {
return CMD_EXEC_FATAL_ERROR;
}
/* Write power-gating transistor pairs using the technology model
* Note that for a mulit-bit power gating port, we should cascade the transistors
*/
bool first_enb_pin = true;
size_t last_enb_pin;
for (const auto& power_gate_pin : circuit_lib.pins(enb_port)) {
BasicPort enb_pin(circuit_lib.port_prefix(enb_port), power_gate_pin, power_gate_pin);
fp << "Xpmos_powergate_" << trans_name_postfix << "_pin_" << power_gate_pin << " ";
/* For the first pin, we should connect it to local VDD*/
if (true == first_enb_pin) {
fp << output_port_name << "_pmos_pg_" << power_gate_pin << " ";
fp << generate_spice_port(enb_pin) << " ";
fp << "LVDD ";
fp << "LVDD ";
first_enb_pin = false;
} else {
VTR_ASSERT_SAFE(false == first_enb_pin);
fp << output_port_name << "_pmos_pg_" << last_enb_pin << " ";
fp << generate_spice_port(enb_pin) << " ";
fp << output_port_name << "_pmos_pg_" << power_gate_pin << " ";
fp << "LVDD ";
}
fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_PMOS) << TRANSISTOR_WRAPPER_POSTFIX;
fp << " W=" << std::setprecision(10) << trans_width;
fp << "\n";
/* Cache the last pin*/
last_enb_pin = power_gate_pin;
}
/* Write transistor pairs using the technology model */
fp << "Xpmos_" << trans_name_postfix << " ";
fp << output_port_name << " ";
fp << input_port_name << " ";
fp << output_port_name << "_pmos_pg_" << circuit_lib.pins(enb_port).back() << " ";
fp << "LVDD ";
fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_PMOS) << TRANSISTOR_WRAPPER_POSTFIX;
fp << " W=" << std::setprecision(10) << trans_width;
fp << "\n";
return CMD_EXEC_SUCCESS;
}
/********************************************************************
* Generate the SPICE modeling for the NMOS part of a power-gated inverter
*
* This function is created to be shared by inverter and buffer SPICE netlist writer
*
* Note:
* - This function does NOT create a file
* but requires a file stream created
* - This function only output SPICE modeling for
* an inverter. Any preprocessing or subckt definition should not be included!
*******************************************************************/
static
int print_spice_powergated_inverter_nmos_modeling(std::fstream& fp,
const std::string& trans_name_postfix,
const std::string& input_port_name,
const std::string& output_port_name,
const CircuitLibrary& circuit_lib,
const CircuitPortId& en_port,
const TechnologyLibrary& tech_lib,
const TechnologyModelId& tech_model,
const float& trans_width) {
if (false == valid_file_stream(fp)) {
return CMD_EXEC_FATAL_ERROR;
}
bool first_en_pin = true;
size_t last_en_pin;
for (const auto& power_gate_pin : circuit_lib.pins(en_port)) {
BasicPort en_pin(circuit_lib.port_prefix(en_port), power_gate_pin, power_gate_pin);
fp << "Xnmos_powergate_" << trans_name_postfix << "_pin_" << power_gate_pin << " ";
/* For the first pin, we should connect it to local VDD*/
if (true == first_en_pin) {
fp << output_port_name << "_nmos_pg_" << power_gate_pin << " ";
fp << generate_spice_port(en_pin) << " ";
fp << "LGND ";
fp << "LGND ";
first_en_pin = false;
} else {
VTR_ASSERT_SAFE(false == first_en_pin);
fp << output_port_name << "_nmos_pg_" << last_en_pin << " ";
fp << circuit_lib.port_prefix(en_port) << " ";
fp << output_port_name << "_nmos_pg_" << power_gate_pin << " ";
fp << "LGND ";
}
fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_NMOS) << TRANSISTOR_WRAPPER_POSTFIX;
fp << " W=" << std::setprecision(10) << trans_width;
fp << "\n";
/* Cache the last pin*/
last_en_pin = power_gate_pin;
}
fp << "Xnmos_" << trans_name_postfix << " ";
fp << output_port_name << " ";
fp << input_port_name << " ";
fp << output_port_name << " _nmos_pg_" << circuit_lib.pins(en_port).back() << " ";
fp << "LGND ";
fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_NMOS) << TRANSISTOR_WRAPPER_POSTFIX;
fp << " W=" << std::setprecision(10) << trans_width;
fp << "\n";
return CMD_EXEC_SUCCESS;
}
/********************************************************************
* Generate the SPICE subckt for a power gated inverter
* The Enable signal controlled the power gating
*
* Note:
* - This function supports multi-bit power gating
*
* Schematic
* LVDD
* |
@ -127,7 +268,9 @@ int print_spice_transistor_wrapper(NetlistManager& netlist_manager,
* ENb[1] -o||
* -
* |
* ...
*
* ... <More control signals if available in the port>
*
* |
* -
* +-o||
@ -138,7 +281,9 @@ int print_spice_transistor_wrapper(NetlistManager& netlist_manager,
* | -
* +--||
* -
* ...
*
* ... <More control signals if available in the port>
*
* |
* -
* EN[1] -||
@ -150,7 +295,7 @@ int print_spice_transistor_wrapper(NetlistManager& netlist_manager,
* |
* LGND
*
***********************************************/
*******************************************************************/
static
int print_spice_powergated_inverter_subckt(std::fstream& fp,
const ModuleManager& module_manager,
@ -187,75 +332,68 @@ int print_spice_powergated_inverter_subckt(std::fstream& fp,
VTR_ASSERT(true == circuit_lib.valid_circuit_port_id(en_port));
VTR_ASSERT(true == circuit_lib.valid_circuit_port_id(enb_port));
/* TODO: may consider use size/bin to compact layout etc. */
for (size_t i = 0; i < circuit_lib.buffer_size(circuit_model); ++i) {
/* Write power-gating transistor pairs using the technology model
* Note that for a mulit-bit power gating port, we should cascade the transistors
*/
bool first_enb_pin = true;
size_t last_enb_pin;
for (const auto& power_gate_pin : circuit_lib.pins(enb_port)) {
BasicPort enb_pin(circuit_lib.port_prefix(enb_port), power_gate_pin, power_gate_pin);
fp << "Xpmos_powergate_" << i << "_pin_" << power_gate_pin << " ";
/* For the first pin, we should connect it to local VDD*/
if (true == first_enb_pin) {
fp << circuit_lib.port_prefix(output_ports[0]) << "_pmos_pg_" << power_gate_pin << " ";
fp << generate_spice_port(enb_pin) << " ";
fp << "LVDD ";
fp << "LVDD ";
first_enb_pin = false;
} else {
VTR_ASSERT_SAFE(false == first_enb_pin);
fp << circuit_lib.port_prefix(output_ports[0]) << "_pmos_pg_" << last_enb_pin << " ";
fp << generate_spice_port(enb_pin) << " ";
fp << circuit_lib.port_prefix(output_ports[0]) << "_pmos_pg_" << power_gate_pin << " ";
fp << "LVDD ";
}
fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_PMOS) << TRANSISTOR_WRAPPER_POSTFIX;
int status = CMD_EXEC_SUCCESS;
/* Cache the last pin*/
last_enb_pin = power_gate_pin;
/* Consider use size/bin to compact layout:
* Try to size transistors to the max width for each bin
* The last bin may not reach the max width
*/
float regular_pmos_bin_width = tech_lib.transistor_model_max_width(tech_model, TECH_LIB_TRANSISTOR_PMOS);
float total_pmos_width = circuit_lib.buffer_size(circuit_model)
* tech_lib.model_pn_ratio(tech_model)
* tech_lib.transistor_model_min_width(tech_model, TECH_LIB_TRANSISTOR_PMOS);
int num_pmos_bins = std::ceil(total_pmos_width / regular_pmos_bin_width);
float last_pmos_bin_width = std::fmod(total_pmos_width, regular_pmos_bin_width);
for (int ibin = 0; ibin < num_pmos_bins; ++ibin) {
float curr_bin_width = regular_pmos_bin_width;
/* For last bin, we need an irregular width */
if ((ibin == num_pmos_bins - 1)
&& (0. != last_pmos_bin_width)) {
curr_bin_width = last_pmos_bin_width;
}
status = print_spice_powergated_inverter_pmos_modeling(fp,
std::to_string(ibin),
circuit_lib.port_prefix(input_ports[0]),
circuit_lib.port_prefix(output_ports[0]),
circuit_lib,
enb_port,
tech_lib,
tech_model,
curr_bin_width);
if (CMD_EXEC_FATAL_ERROR == status) {
return status;
}
}
/* Consider use size/bin to compact layout:
* Try to size transistors to the max width for each bin
* The last bin may not reach the max width
*/
float regular_nmos_bin_width = tech_lib.transistor_model_max_width(tech_model, TECH_LIB_TRANSISTOR_NMOS);
float total_nmos_width = circuit_lib.buffer_size(circuit_model)
* tech_lib.transistor_model_min_width(tech_model, TECH_LIB_TRANSISTOR_NMOS);
int num_nmos_bins = std::ceil(total_nmos_width / regular_nmos_bin_width);
float last_nmos_bin_width = std::fmod(total_nmos_width, regular_nmos_bin_width);
for (int ibin = 0; ibin < num_nmos_bins; ++ibin) {
float curr_bin_width = regular_nmos_bin_width;
/* For last bin, we need an irregular width */
if ((ibin == num_nmos_bins - 1)
&& (0. != last_nmos_bin_width)) {
curr_bin_width = last_nmos_bin_width;
}
bool first_en_pin = true;
size_t last_en_pin;
for (const auto& power_gate_pin : circuit_lib.pins(en_port)) {
BasicPort en_pin(circuit_lib.port_prefix(en_port), power_gate_pin, power_gate_pin);
fp << "Xnmos_powergate_" << i << "_pin_" << power_gate_pin << " ";
/* For the first pin, we should connect it to local VDD*/
if (true == first_en_pin) {
fp << circuit_lib.port_prefix(output_ports[0]) << "_nmos_pg_" << power_gate_pin << " ";
fp << generate_spice_port(en_pin) << " ";
fp << "LGND ";
fp << "LGND ";
first_en_pin = false;
} else {
VTR_ASSERT_SAFE(false == first_enb_pin);
fp << circuit_lib.port_prefix(output_ports[0]) << "_nmos_pg_" << last_en_pin << " ";
fp << circuit_lib.port_prefix(en_port) << " ";
fp << circuit_lib.port_prefix(output_ports[0]) << "_nmos_pg_" << power_gate_pin << " ";
fp << "LGND ";
}
fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_NMOS) << TRANSISTOR_WRAPPER_POSTFIX;
/* Cache the last pin*/
last_enb_pin = power_gate_pin;
status = print_spice_powergated_inverter_nmos_modeling(fp,
std::to_string(ibin),
circuit_lib.port_prefix(input_ports[0]),
circuit_lib.port_prefix(output_ports[0]),
circuit_lib,
en_port,
tech_lib,
tech_model,
curr_bin_width);
if (CMD_EXEC_FATAL_ERROR == status) {
return status;
}
/* Write transistor pairs using the technology model */
fp << "Xpmos_" << i << " ";
fp << circuit_lib.port_prefix(output_ports[0]) << " ";
fp << circuit_lib.port_prefix(input_ports[0]) << " ";
fp << circuit_lib.port_prefix(output_ports[0]) << "_pmos_pg_" << circuit_lib.pins(enb_port).back() << " ";
fp << "LVDD ";
fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_PMOS) << TRANSISTOR_WRAPPER_POSTFIX;
fp << "Xnmos_" << i << " ";
fp << circuit_lib.port_prefix(output_ports[0]) << " ";
fp << circuit_lib.port_prefix(input_ports[0]) << " ";
fp << circuit_lib.port_prefix(output_ports[0]) << " _nmos_pg_" << circuit_lib.pins(en_port).back() << " ";
fp << "LGND ";
fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_NMOS) << TRANSISTOR_WRAPPER_POSTFIX;
}
print_spice_subckt_end(fp, module_manager.module_name(module_id));
@ -263,8 +401,86 @@ int print_spice_powergated_inverter_subckt(std::fstream& fp,
return CMD_EXEC_SUCCESS;
}
/************************************************
/********************************************************************
* Generate the SPICE modeling for the PMOS part of a regular inverter
*
* This function is created to be shared by inverter and buffer SPICE netlist writer
*
* Note:
* - This function does NOT create a file
* but requires a file stream created
* - This function only output SPICE modeling for
* an inverter. Any preprocessing or subckt definition should not be included!
*******************************************************************/
static
int print_spice_regular_inverter_pmos_modeling(std::fstream& fp,
const std::string& trans_name_postfix,
const std::string& input_port_name,
const std::string& output_port_name,
const TechnologyLibrary& tech_lib,
const TechnologyModelId& tech_model,
const float& trans_width) {
if (false == valid_file_stream(fp)) {
return CMD_EXEC_FATAL_ERROR;
}
/* Write transistor pairs using the technology model */
fp << "Xpmos_" << trans_name_postfix << " ";
fp << output_port_name << " ";
fp << input_port_name << " ";
fp << "LVDD ";
fp << "LVDD ";
fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_PMOS) << TRANSISTOR_WRAPPER_POSTFIX;
fp << " W=" << std::setprecision(10) << trans_width;
fp << "\n";
return CMD_EXEC_SUCCESS;
}
/********************************************************************
* Generate the SPICE modeling for the NMOS part of a regular inverter
*
* This function is created to be shared by inverter and buffer SPICE netlist writer
*
* Note:
* - This function does NOT create a file
* but requires a file stream created
* - This function only output SPICE modeling for
* an inverter. Any preprocessing or subckt definition should not be included!
*******************************************************************/
static
int print_spice_regular_inverter_nmos_modeling(std::fstream& fp,
const std::string& trans_name_postfix,
const std::string& input_port_name,
const std::string& output_port_name,
const TechnologyLibrary& tech_lib,
const TechnologyModelId& tech_model,
const float& trans_width) {
if (false == valid_file_stream(fp)) {
return CMD_EXEC_FATAL_ERROR;
}
fp << "Xnmos_" << trans_name_postfix << " ";
fp << output_port_name << " ";
fp << input_port_name << " ";
fp << "LGND ";
fp << "LGND ";
fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_NMOS) << TRANSISTOR_WRAPPER_POSTFIX;
fp << " W=" << std::setprecision(10) << trans_width;
fp << "\n";
return CMD_EXEC_SUCCESS;
}
/********************************************************************
* Generate the SPICE subckt for a regular inverter
*
* Note:
* - This function does NOT support power-gating
* It should be managed in a separated function
*
* Schematic
* LVDD
* |
@ -280,7 +496,7 @@ int print_spice_powergated_inverter_subckt(std::fstream& fp,
* |
* LGND
*
***********************************************/
*******************************************************************/
static
int print_spice_regular_inverter_subckt(std::fstream& fp,
const ModuleManager& module_manager,
@ -310,33 +526,77 @@ int print_spice_regular_inverter_subckt(std::fstream& fp,
VTR_ASSERT( (1 == input_ports.size()) && (1 == circuit_lib.port_size(input_ports[0])) );
VTR_ASSERT( (1 == output_ports.size()) && (1 == circuit_lib.port_size(output_ports[0])) );
/* TODO: may consider use size/bin to compact layout etc. */
for (size_t i = 0; i < circuit_lib.buffer_size(circuit_model); ++i) {
/* Write transistor pairs using the technology model */
fp << "Xpmos_" << i << " ";
fp << circuit_lib.port_prefix(output_ports[0]) << " ";
fp << circuit_lib.port_prefix(input_ports[0]) << " ";
fp << "LVDD ";
fp << "LVDD ";
fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_PMOS) << TRANSISTOR_WRAPPER_POSTFIX;
int status = CMD_EXEC_SUCCESS;
fp << "Xnmos_" << i << " ";
fp << circuit_lib.port_prefix(output_ports[0]) << " ";
fp << circuit_lib.port_prefix(input_ports[0]) << " ";
fp << "LGND ";
fp << "LGND ";
fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_NMOS) << TRANSISTOR_WRAPPER_POSTFIX;
/* Consider use size/bin to compact layout:
* Try to size transistors to the max width for each bin
* The last bin may not reach the max width
*/
float regular_pmos_bin_width = tech_lib.transistor_model_max_width(tech_model, TECH_LIB_TRANSISTOR_PMOS);
float total_pmos_width = circuit_lib.buffer_size(circuit_model)
* tech_lib.model_pn_ratio(tech_model)
* tech_lib.transistor_model_min_width(tech_model, TECH_LIB_TRANSISTOR_PMOS);
int num_pmos_bins = std::ceil(total_pmos_width / regular_pmos_bin_width);
float last_pmos_bin_width = std::fmod(total_pmos_width, regular_pmos_bin_width);
for (int ibin = 0; ibin < num_pmos_bins; ++ibin) {
float curr_bin_width = regular_pmos_bin_width;
/* For last bin, we need an irregular width */
if ((ibin == num_pmos_bins - 1)
&& (0. != last_pmos_bin_width)) {
curr_bin_width = last_pmos_bin_width;
}
status = print_spice_regular_inverter_pmos_modeling(fp,
std::to_string(ibin),
circuit_lib.port_prefix(input_ports[0]),
circuit_lib.port_prefix(output_ports[0]),
tech_lib,
tech_model,
curr_bin_width);
if (CMD_EXEC_FATAL_ERROR == status) {
return status;
}
}
/* Consider use size/bin to compact layout:
* Try to size transistors to the max width for each bin
* The last bin may not reach the max width
*/
float regular_nmos_bin_width = tech_lib.transistor_model_max_width(tech_model, TECH_LIB_TRANSISTOR_NMOS);
float total_nmos_width = circuit_lib.buffer_size(circuit_model)
* tech_lib.transistor_model_min_width(tech_model, TECH_LIB_TRANSISTOR_NMOS);
int num_nmos_bins = std::ceil(total_nmos_width / regular_nmos_bin_width);
float last_nmos_bin_width = std::fmod(total_nmos_width, regular_nmos_bin_width);
for (int ibin = 0; ibin < num_nmos_bins; ++ibin) {
float curr_bin_width = regular_nmos_bin_width;
/* For last bin, we need an irregular width */
if ((ibin == num_nmos_bins - 1)
&& (0. != last_nmos_bin_width)) {
curr_bin_width = last_nmos_bin_width;
}
status = print_spice_regular_inverter_nmos_modeling(fp,
std::to_string(ibin),
circuit_lib.port_prefix(input_ports[0]),
circuit_lib.port_prefix(output_ports[0]),
tech_lib,
tech_model,
curr_bin_width);
if (CMD_EXEC_FATAL_ERROR == status) {
return status;
}
}
print_spice_subckt_end(fp, module_manager.module_name(module_id));
return CMD_EXEC_SUCCESS;
return status;
}
/************************************************
/********************************************************************
* Generate the SPICE subckt for an inverter
* Branch on the different circuit topologies
***********************************************/
*******************************************************************/
static
int print_spice_inverter_subckt(std::fstream& fp,
const ModuleManager& module_manager,
@ -362,13 +622,378 @@ int print_spice_inverter_subckt(std::fstream& fp,
return status;
}
/************************************************
/********************************************************************
* Generate the SPICE subckt for a power-gated buffer
* which contains at least 2 stages
*
* Schematic of a multi-stage buffer
*
* LVDD LVDD
* | |
* - -
* ENb[0] -o|| ENb[0] -o||
* - -
* | |
* - -
* ENb[1] -o|| ENb[1] -o||
* - -
* | |
*
* ... <More control signals if available in the port>
*
* | |
* - -
* +-o|| +-o||
* | - | -
* | | | |
* in-->+ +-- ... ---+---->+---> out
* | | | |
* | - | -
* +--|| +--||
* - -
* | |
*
* ... <More control signals if available in the port>
*
* | |
* - -
* EN[0] -|| EN[0] -||
* - -
* | |
* - -
* EN[1] -|| EN[1] -||
* - -
* | |
* | |
* LGND LGND
*
*******************************************************************/
static
int print_spice_powergated_buffer_subckt(std::fstream& fp,
const ModuleManager& module_manager,
const ModuleId& module_id,
const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model,
const TechnologyLibrary& tech_lib,
const TechnologyModelId& tech_model) {
if (false == valid_file_stream(fp)) {
return CMD_EXEC_FATAL_ERROR;
}
/* Print the inverter subckt definition */
print_spice_subckt_definition(fp, module_manager, module_id);
/* Find the input and output ports:
* we do NOT support global ports here,
* it should be handled in another type of inverter subckt (power-gated)
*/
std::vector<CircuitPortId> input_ports = circuit_lib.model_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_INPUT, true);
std::vector<CircuitPortId> output_ports = circuit_lib.model_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_OUTPUT, true);
/* Make sure:
* There is only 1 input port and 1 output port,
* each size of which is 1
*/
VTR_ASSERT( (1 == input_ports.size()) && (1 == circuit_lib.port_size(input_ports[0])) );
VTR_ASSERT( (1 == output_ports.size()) && (1 == circuit_lib.port_size(output_ports[0])) );
/* If the circuit model is power-gated, we need to find at least one global config_enable signals */
VTR_ASSERT(true == circuit_lib.is_power_gated(circuit_model));
CircuitPortId en_port = find_circuit_model_power_gate_en_port(circuit_lib, circuit_model);
CircuitPortId enb_port = find_circuit_model_power_gate_enb_port(circuit_lib, circuit_model);
VTR_ASSERT(true == circuit_lib.valid_circuit_port_id(en_port));
VTR_ASSERT(true == circuit_lib.valid_circuit_port_id(enb_port));
int status = CMD_EXEC_SUCCESS;
/* Buffers must have >= 2 stages */
VTR_ASSERT(2 <= circuit_lib.buffer_num_levels(circuit_model));
/* Build the array denoting width of inverters per stage */
std::vector<float> buffer_widths(circuit_lib.buffer_num_levels(circuit_model), 1);
for (size_t level = 0; level < circuit_lib.buffer_num_levels(circuit_model); ++level) {
buffer_widths[level] = circuit_lib.buffer_size(circuit_model)
* std::pow(circuit_lib.buffer_f_per_stage(circuit_model), level);
}
for (size_t level = 0; level < circuit_lib.buffer_num_levels(circuit_model); ++level) {
std::string input_port_name = circuit_lib.port_prefix(input_ports[0]);
std::string output_port_name = circuit_lib.port_prefix(output_ports[0]);
/* Special for first stage: output port should be an intermediate node
* Special for rest of stages: input port should be the output of previous stage
*/
if (0 == level) {
output_port_name += std::string("_level") + std::to_string(level);
} else {
VTR_ASSERT(0 < level);
input_port_name += std::string("_level") + std::to_string(level - 1);
}
/* Consider use size/bin to compact layout:
* Try to size transistors to the max width for each bin
* The last bin may not reach the max width
*/
float regular_pmos_bin_width = tech_lib.transistor_model_max_width(tech_model, TECH_LIB_TRANSISTOR_PMOS);
float total_pmos_width = buffer_widths[level]
* tech_lib.model_pn_ratio(tech_model)
* tech_lib.transistor_model_min_width(tech_model, TECH_LIB_TRANSISTOR_PMOS);
int num_pmos_bins = std::ceil(total_pmos_width / regular_pmos_bin_width);
float last_pmos_bin_width = std::fmod(total_pmos_width, regular_pmos_bin_width);
for (int ibin = 0; ibin < num_pmos_bins; ++ibin) {
float curr_bin_width = regular_pmos_bin_width;
/* For last bin, we need an irregular width */
if ((ibin == num_pmos_bins - 1)
&& (0. != last_pmos_bin_width)) {
curr_bin_width = last_pmos_bin_width;
}
std::string name_postfix = std::string("level") + std::to_string(level) + std::string("_bin") + std::to_string(ibin);
status = print_spice_powergated_inverter_pmos_modeling(fp,
name_postfix,
circuit_lib.port_prefix(input_ports[0]),
circuit_lib.port_prefix(output_ports[0]),
circuit_lib,
enb_port,
tech_lib,
tech_model,
curr_bin_width);
if (CMD_EXEC_FATAL_ERROR == status) {
return status;
}
}
/* Consider use size/bin to compact layout:
* Try to size transistors to the max width for each bin
* The last bin may not reach the max width
*/
float regular_nmos_bin_width = tech_lib.transistor_model_max_width(tech_model, TECH_LIB_TRANSISTOR_NMOS);
float total_nmos_width = buffer_widths[level]
* tech_lib.transistor_model_min_width(tech_model, TECH_LIB_TRANSISTOR_NMOS);
int num_nmos_bins = std::ceil(total_nmos_width / regular_nmos_bin_width);
float last_nmos_bin_width = std::fmod(total_nmos_width, regular_nmos_bin_width);
for (int ibin = 0; ibin < num_nmos_bins; ++ibin) {
float curr_bin_width = regular_nmos_bin_width;
/* For last bin, we need an irregular width */
if ((ibin == num_nmos_bins - 1)
&& (0. != last_nmos_bin_width)) {
curr_bin_width = last_nmos_bin_width;
}
std::string name_postfix = std::string("level") + std::to_string(level) + std::string("_bin") + std::to_string(ibin);
status = print_spice_powergated_inverter_nmos_modeling(fp,
name_postfix,
circuit_lib.port_prefix(input_ports[0]),
circuit_lib.port_prefix(output_ports[0]),
circuit_lib,
en_port,
tech_lib,
tech_model,
curr_bin_width);
if (CMD_EXEC_FATAL_ERROR == status) {
return status;
}
}
}
print_spice_subckt_end(fp, module_manager.module_name(module_id));
return CMD_EXEC_SUCCESS;
}
/********************************************************************
* Generate the SPICE subckt for a regular buffer
* which contains at least 2 stages
*
* Note:
* - This function does NOT support power-gating
* It should be managed in a separated function
*
* Schematic of a multi-stage buffer
*
* LVDD LVDD
* | |
* - -
* +-o|| +-o||
* | - | -
* | | | |
* in-->+ +-- ... ---+---->+---> out
* | | | |
* | - | -
* +--|| +--||
* - -
* | |
* LGND LGND
*
*******************************************************************/
static
int print_spice_regular_buffer_subckt(std::fstream& fp,
const ModuleManager& module_manager,
const ModuleId& module_id,
const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model,
const TechnologyLibrary& tech_lib,
const TechnologyModelId& tech_model) {
if (false == valid_file_stream(fp)) {
return CMD_EXEC_FATAL_ERROR;
}
/* Print the inverter subckt definition */
print_spice_subckt_definition(fp, module_manager, module_id);
/* Find the input and output ports:
* we do NOT support global ports here,
* it should be handled in another type of inverter subckt (power-gated)
*/
std::vector<CircuitPortId> input_ports = circuit_lib.model_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_INPUT, true);
std::vector<CircuitPortId> output_ports = circuit_lib.model_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_OUTPUT, true);
/* Make sure:
* There is only 1 input port and 1 output port,
* each size of which is 1
*/
VTR_ASSERT( (1 == input_ports.size()) && (1 == circuit_lib.port_size(input_ports[0])) );
VTR_ASSERT( (1 == output_ports.size()) && (1 == circuit_lib.port_size(output_ports[0])) );
int status = CMD_EXEC_SUCCESS;
/* Buffers must have >= 2 stages */
VTR_ASSERT(2 <= circuit_lib.buffer_num_levels(circuit_model));
/* Build the array denoting width of inverters per stage */
std::vector<float> buffer_widths(circuit_lib.buffer_num_levels(circuit_model), 1);
for (size_t level = 0; level < circuit_lib.buffer_num_levels(circuit_model); ++level) {
buffer_widths[level] = circuit_lib.buffer_size(circuit_model)
* std::pow(circuit_lib.buffer_f_per_stage(circuit_model), level);
}
for (size_t level = 0; level < circuit_lib.buffer_num_levels(circuit_model); ++level) {
std::string input_port_name = circuit_lib.port_prefix(input_ports[0]);
std::string output_port_name = circuit_lib.port_prefix(output_ports[0]);
/* Special for first stage: output port should be an intermediate node
* Special for rest of stages: input port should be the output of previous stage
*/
if (0 == level) {
output_port_name += std::string("_level") + std::to_string(level);
} else {
VTR_ASSERT(0 < level);
input_port_name += std::string("_level") + std::to_string(level - 1);
}
/* Consider use size/bin to compact layout:
* Try to size transistors to the max width for each bin
* The last bin may not reach the max width
*/
float regular_pmos_bin_width = tech_lib.transistor_model_max_width(tech_model, TECH_LIB_TRANSISTOR_PMOS);
float total_pmos_width = buffer_widths[level]
* tech_lib.model_pn_ratio(tech_model)
* tech_lib.transistor_model_min_width(tech_model, TECH_LIB_TRANSISTOR_PMOS);
int num_pmos_bins = std::ceil(total_pmos_width / regular_pmos_bin_width);
float last_pmos_bin_width = std::fmod(total_pmos_width, regular_pmos_bin_width);
for (int ibin = 0; ibin < num_pmos_bins; ++ibin) {
float curr_bin_width = regular_pmos_bin_width;
/* For last bin, we need an irregular width */
if ((ibin == num_pmos_bins - 1)
&& (0. != last_pmos_bin_width)) {
curr_bin_width = last_pmos_bin_width;
}
std::string name_postfix = std::string("level") + std::to_string(level) + std::string("_bin") + std::to_string(ibin);
status = print_spice_regular_inverter_pmos_modeling(fp,
name_postfix,
circuit_lib.port_prefix(input_ports[0]),
circuit_lib.port_prefix(output_ports[0]),
tech_lib,
tech_model,
curr_bin_width);
if (CMD_EXEC_FATAL_ERROR == status) {
return status;
}
}
/* Consider use size/bin to compact layout:
* Try to size transistors to the max width for each bin
* The last bin may not reach the max width
*/
float regular_nmos_bin_width = tech_lib.transistor_model_max_width(tech_model, TECH_LIB_TRANSISTOR_NMOS);
float total_nmos_width = buffer_widths[level]
* tech_lib.transistor_model_min_width(tech_model, TECH_LIB_TRANSISTOR_NMOS);
int num_nmos_bins = std::ceil(total_nmos_width / regular_nmos_bin_width);
float last_nmos_bin_width = std::fmod(total_nmos_width, regular_nmos_bin_width);
for (int ibin = 0; ibin < num_nmos_bins; ++ibin) {
float curr_bin_width = regular_nmos_bin_width;
/* For last bin, we need an irregular width */
if ((ibin == num_nmos_bins - 1)
&& (0. != last_nmos_bin_width)) {
curr_bin_width = last_nmos_bin_width;
}
std::string name_postfix = std::string("level") + std::to_string(level) + std::string("_bin") + std::to_string(ibin);
status = print_spice_regular_inverter_nmos_modeling(fp,
name_postfix,
circuit_lib.port_prefix(input_ports[0]),
circuit_lib.port_prefix(output_ports[0]),
tech_lib,
tech_model,
curr_bin_width);
if (CMD_EXEC_FATAL_ERROR == status) {
return status;
}
}
}
print_spice_subckt_end(fp, module_manager.module_name(module_id));
return status;
}
/********************************************************************
* Generate the SPICE subckt for an buffer
* which consists of multiple stage of inverters
*******************************************************************/
static
int print_spice_buffer_subckt(std::fstream& fp,
const ModuleManager& module_manager,
const ModuleId& module_id,
const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model,
const TechnologyLibrary& tech_lib,
const TechnologyModelId& tech_model) {
int status = CMD_EXEC_SUCCESS;
if (true == circuit_lib.is_power_gated(circuit_model)) {
status = print_spice_powergated_buffer_subckt(fp,
module_manager, module_id,
circuit_lib, circuit_model,
tech_lib, tech_model);
} else {
VTR_ASSERT_SAFE(false == circuit_lib.is_power_gated(circuit_model));
status = print_spice_regular_buffer_subckt(fp,
module_manager, module_id,
circuit_lib, circuit_model,
tech_lib, tech_model);
}
return status;
}
/********************************************************************
* Generate the SPICE netlist for essential gates:
* - inverters and their templates
* - buffers and their templates
* - pass-transistor or transmission gates
* - logic gates
***********************************************/
*******************************************************************/
int print_spice_essential_gates(NetlistManager& netlist_manager,
const ModuleManager& module_manager,
const CircuitLibrary& circuit_lib,
@ -385,15 +1010,17 @@ int print_spice_essential_gates(NetlistManager& netlist_manager,
check_file_stream(spice_fname.c_str(), fp);
/* Create file */
VTR_LOG("Generating SPICE netlist '%s' for transistor wrappers...",
VTR_LOG("Generating SPICE netlist '%s' for essential gates...",
spice_fname.c_str());
print_spice_file_header(fp, std::string("Essential gates"));
int status = CMD_EXEC_SUCCESS;
/* Iterate over the circuit models */
for (const CircuitModelId& circuit_model : circuit_lib.models()) {
/* Bypass models require extern netlists */
if (true == circuit_lib.model_circuit_netlist(circuit_model).empty()) {
if (!circuit_lib.model_circuit_netlist(circuit_model).empty()) {
continue;
}
@ -429,6 +1056,10 @@ int print_spice_essential_gates(NetlistManager& netlist_manager,
tech_lib, tech_model);
} else {
VTR_ASSERT(CIRCUIT_MODEL_BUF_BUF == circuit_lib.buffer_type(circuit_model));
status = print_spice_buffer_subckt(fp,
module_manager, module_id,
circuit_lib, circuit_model,
tech_lib, tech_model);
}
if (CMD_EXEC_FATAL_ERROR == status) {

View File

@ -37,10 +37,10 @@ repack #--verbose
# Build the bitstream
# - Output the fabric-independent bitstream to a file
build_architecture_bitstream --verbose --write_file fabric_indepenent_bitstream.xml
build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml
# Build fabric-dependent bitstream
build_fabric_bitstream --verbose
build_fabric_bitstream --verbose --file fabric_bitstream.xml --format xml
# Write the Verilog netlist for FPGA fabric
# - Enable the use of explicit port mapping in Verilog netlist

View File

@ -37,10 +37,10 @@ repack #--verbose
# Build the bitstream
# - Output the fabric-independent bitstream to a file
build_architecture_bitstream --verbose --write_file fabric_indepenent_bitstream.xml
build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml
# Build fabric-dependent bitstream
build_fabric_bitstream --verbose
build_fabric_bitstream --verbose --file fabric_bitstream.xml --format xml
# Write the Verilog netlist for FPGA fabric
# - Enable the use of explicit port mapping in Verilog netlist

View File

@ -37,10 +37,10 @@ repack #--verbose
# Build the bitstream
# - Output the fabric-independent bitstream to a file
build_architecture_bitstream --verbose --write_file fabric_indepenent_bitstream.xml
build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml
# Build fabric-dependent bitstream
build_fabric_bitstream --verbose
build_fabric_bitstream --verbose --file fabric_bitstream.xml --format xml
# Write the Verilog netlist for FPGA fabric
# - Enable the use of explicit port mapping in Verilog netlist

View File

@ -37,10 +37,10 @@ repack #--verbose
# Build the bitstream
# - Output the fabric-independent bitstream to a file
build_architecture_bitstream --verbose --write_file fabric_indepenent_bitstream.xml
build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml
# Build fabric-dependent bitstream
build_fabric_bitstream --verbose
build_fabric_bitstream --verbose --file fabric_bitstream.xml --format xml
# Write the Verilog netlist for FPGA fabric
# - Enable the use of explicit port mapping in Verilog netlist

View File

@ -37,10 +37,10 @@ repack #--verbose
# Build the bitstream
# - Output the fabric-independent bitstream to a file
build_architecture_bitstream --verbose --write_file fabric_indepenent_bitstream.xml
build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml
# Build fabric-dependent bitstream
build_fabric_bitstream --verbose
build_fabric_bitstream --verbose --file fabric_bitstream.xml --format xml
# Write the Verilog netlist for FPGA fabric
# - Enable the use of explicit port mapping in Verilog netlist

View File

@ -37,10 +37,10 @@ repack #--verbose
# Build the bitstream
# - Output the fabric-independent bitstream to a file
build_architecture_bitstream --verbose --write_file fabric_indepenent_bitstream.xml
build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml
# Build fabric-dependent bitstream
build_fabric_bitstream --verbose
build_fabric_bitstream --verbose --file fabric_bitstream.xml --format xml
# Write the Verilog netlist for FPGA fabric
# - Enable the use of explicit port mapping in Verilog netlist

View File

@ -35,10 +35,10 @@ repack #--verbose
# Build the bitstream
# - Output the fabric-independent bitstream to a file
build_architecture_bitstream --verbose --write_file fabric_indepenent_bitstream.xml
build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml
# Build fabric-dependent bitstream
build_fabric_bitstream --verbose
build_fabric_bitstream --verbose --file fabric_bitstream.txt
# Finish and exit OpenFPGA
exit

View File

@ -40,10 +40,10 @@ repack #--verbose
# Build the bitstream
# - Output the fabric-independent bitstream to a file
build_architecture_bitstream --verbose --write_file fabric_indepenent_bitstream.xml
build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml
# Build fabric-dependent bitstream
build_fabric_bitstream --verbose
build_fabric_bitstream --verbose --file fabric_bitstream.xml --format xml
# Write the Verilog netlist for FPGA fabric
# - Enable the use of explicit port mapping in Verilog netlist

View File

@ -40,10 +40,10 @@ repack #--verbose
# Build the bitstream
# - Output the fabric-independent bitstream to a file
build_architecture_bitstream --verbose --write_file fabric_indepenent_bitstream.xml
build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml
# Build fabric-dependent bitstream
build_fabric_bitstream --verbose
build_fabric_bitstream --verbose --file fabric_bitstream.xml --format xml
# Write the Verilog netlist for FPGA fabric
# - Enable the use of explicit port mapping in Verilog netlist

View File

@ -0,0 +1,35 @@
# Run VPR for the 'and' design
#--write_rr_graph example_rr_graph.xml
vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling route
# Read OpenFPGA architecture definition
read_openfpga_arch -f ${OPENFPGA_ARCH_FILE}
# Read OpenFPGA simulation settings
read_openfpga_simulation_setting -f ${OPENFPGA_SIM_SETTING_FILE}
# Annotate the OpenFPGA architecture to VPR data base
# to debug use --verbose options
link_openfpga_arch --activity_file ${ACTIVITY_FILE} --sort_gsb_chan_node_in_edges
# Check and correct any naming conflicts in the BLIF netlist
check_netlist_naming_conflict --fix --report ./netlist_renaming.xml
# Build the module graph
# - Enabled compression on routing architecture modules
# - Enable pin duplication on grid modules
build_fabric --compress_routing #--verbose
# Write the fabric hierarchy of module graph to a file
# This is used by hierarchical PnR flows
write_fabric_hierarchy --file ./fabric_hierarchy.txt
# Write the Verilog netlist for FPGA fabric
# - Enable the use of explicit port mapping in Verilog netlist
write_fabric_spice --file ./SPICE --verbose
# Finish and exit OpenFPGA
exit
# Note :
# To run verification at the end of the flow maintain source in ./SRC directory

View File

@ -37,10 +37,10 @@ repack #--verbose
# Build the bitstream
# - Output the fabric-independent bitstream to a file
build_architecture_bitstream --verbose --write_file fabric_indepenent_bitstream.xml
build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml
# Build fabric-dependent bitstream
build_fabric_bitstream --verbose
build_fabric_bitstream --verbose --file fabric_bitstream --format xml
# Write the Verilog testbench for FPGA fabric
# - We suggest the use of same output directory as fabric Verilog netlists

View File

@ -37,10 +37,10 @@ repack #--verbose
# Build the bitstream
# - Output the fabric-independent bitstream to a file
build_architecture_bitstream --verbose --write_file fabric_indepenent_bitstream.xml
build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml
# Build fabric-dependent bitstream
build_fabric_bitstream --verbose
build_fabric_bitstream --verbose --file fabric_bitstream.xml --format xml
# Write the Verilog netlist for FPGA fabric
# - Enable the use of explicit port mapping in Verilog netlist

View File

@ -0,0 +1,36 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Configuration file for running experiments
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
# Each job execute fpga_flow script on combination of architecture & benchmark
# timeout_each_job is timeout for each job
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
[GENERAL]
run_engine=openfpga_shell
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/OpenFPGAShellScripts/example_script.openfpga
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
power_analysis = true
spice_output=false
verilog_output=true
timeout_each_job = 20*60
fpga_flow=vpr_blif
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10_adder_register_scan_chain_depop50_40nm_openfpga.xml
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml
external_fabric_key_file=
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_register_scan_chain_depop50_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
[SYNTHESIS_PARAM]
bench0_top = and2
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
bench0_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test=
vpr_fpga_verilog_formal_verification_top_netlist=

View File

@ -0,0 +1,33 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Configuration file for running experiments
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
# Each job execute fpga_flow script on combination of architecture & benchmark
# timeout_each_job is timeout for each job
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
[GENERAL]
run_engine=openfpga_shell
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/OpenFPGAShellScripts/generate_spice_example_script.openfpga
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
power_analysis = true
spice_output=false
verilog_output=true
timeout_each_job = 20*60
fpga_flow=vpr_blif
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10_40nm_openfpga.xml
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml
external_fabric_key_file=
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileable_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
[SYNTHESIS_PARAM]
bench0_top = and2
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]