Merge pull request #1186 from lnis-uofu/xt_mock_wrapper
Support mock FPGA wrapper generation
This commit is contained in:
commit
2e3625aa7c
Binary file not shown.
After Width: | Height: | Size: 74 KiB |
|
@ -10,3 +10,5 @@ FPGA-Verilog
|
|||
fabric_netlist
|
||||
|
||||
testbench
|
||||
|
||||
mock_fpga_wrapper
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
.. _fpga_verilog_mock_fpga_wrapper:
|
||||
|
||||
Mock FPGA Wrapper
|
||||
-----------------
|
||||
|
||||
OpenFPGA can generates HDL netlists that model a complete eFPGA fabric (see details in :ref:`fabric_netlists`).
|
||||
Through bitstream forcing, users can verify the eFPGAs that are mapped by various applications in the context of SoC (see details in :numref:`fig_preconfig_module`).
|
||||
However, the complete eFPGA fabric is very costly in design verification runtime.
|
||||
To reduce runtime, a mock eFPGA wrapper is required to bridge the application HDL and other components in the SoC.
|
||||
As illustrated in :numref:`fig_mock_fpga_wrapper`, a 3-bit counter application is mapped to an FPGA, while a mock wrapper is interfacing the signals between the counter module and the SoC.
|
||||
The mock wrapper consists of the same ports as the FPGA fabric, which is generated by the OpenFPGA command ``write_fabric_verilog``. See :ref:`openfpga_verilog_commands` for its detailed usage.
|
||||
The only difference lies in that the mock wrapper contains an instance of the application HDL design which is implemented on the FPGA, while the FPGA fabric contains a complete structure of programmable resources.
|
||||
|
||||
.. note:: The mock wrapper is useful for connectivity checks on FPGA datapaths. It does not cover any configuration protocols (see details in :ref:`config_protocol`)
|
||||
|
||||
|
||||
.. _fig_mock_fpga_wrapper:
|
||||
|
||||
.. figure:: figures/mock_fpga_wrapper.png
|
||||
:width: 100%
|
||||
:alt: Illustraion of a mock FPGA wrapper
|
||||
|
||||
Principles of a mock FPGA wrapper: ease SoC-level design verification
|
||||
|
||||
|
|
@ -22,7 +22,7 @@ To enable self-testing, the FPGA and user's RTL design (simulate using an HDL si
|
|||
.. _fig_verilog_testbench_organization:
|
||||
|
||||
.. figure:: figures/full_testbench_block_diagram.svg
|
||||
:scale: 50%
|
||||
:width: 100%
|
||||
:alt: Verilog testbench principles
|
||||
|
||||
Principles of Verilog testbenches: (1) using common input stimuli; (2) applying bitstream; (3) checking output vectors.
|
||||
|
@ -30,7 +30,7 @@ To enable self-testing, the FPGA and user's RTL design (simulate using an HDL si
|
|||
.. _fig_verilog_full_testbench_waveform:
|
||||
|
||||
.. figure:: figures/full_testbench_waveform.svg
|
||||
:scale: 50%
|
||||
:width: 100%
|
||||
:alt: Full testbench waveform
|
||||
|
||||
Illustration on the waveforms in full testbench
|
||||
|
@ -48,7 +48,7 @@ Formal-oriented Testbench
|
|||
The formal-oriented testbench aims to test a programmed FPGA is instantiated with the user's bitstream.
|
||||
The module of the programmed FPGA is encapsulated with the same port mapping as the user's RTL design and thus can be fed to a formal tool for a 100% coverage formal verification. Compared to the full testbench, this skips the time-consuming configuration phase, reducing the simulation time, potentially also significantly accelerating the functional verification, especially for large FPGAs.
|
||||
|
||||
.. warning:: Formal-oriented testbenches do not validate the configuration protocol of FPGAs. It is used to validate FPGA with a wide range of benchmarks.
|
||||
.. warning:: Formal-oriented testbenches do not validate the configuration protocol of FPGAs. It is used to validate FPGA with a wide range of benchmarks.
|
||||
|
||||
General Usage
|
||||
~~~~~~~~~~~~~
|
||||
|
@ -59,7 +59,7 @@ Inside the directory, the Verilog testbenches are organized as illustrated in :n
|
|||
.. _fig_verilog_testbench_hierarchy:
|
||||
|
||||
.. figure:: ./figures/verilog_testbench_hierarchy.svg
|
||||
:scale: 100%
|
||||
:width: 100%
|
||||
|
||||
Hierarchy of Verilog testbenches for a FPGA fabric implemented with an application
|
||||
|
||||
|
@ -91,7 +91,7 @@ Inside the directory, the Verilog testbenches are organized as illustrated in :n
|
|||
.. _fig_preconfig_module:
|
||||
|
||||
.. figure:: ./figures/preconfig_module.png
|
||||
:scale: 25%
|
||||
:width: 100%
|
||||
|
||||
Internal structure of a pre-configured FPGA module
|
||||
|
||||
|
|
|
@ -166,6 +166,45 @@ __ iverilog_website_
|
|||
|
||||
Show verbose log
|
||||
|
||||
write_mock_fpga_wrapper
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Write the Verilog wrapper which mockes a mapped FPGA fabric. See details in :ref:`fpga_verilog_mock_fpga_wrapper`.
|
||||
|
||||
.. option:: --file <string> or -f <string>
|
||||
|
||||
The output directory for the netlists. We suggest the use of same output directory as fabric Verilog netlists. For example, ``--file /temp/testbench``
|
||||
|
||||
.. option:: --pin_constraints_file <string> or -pcf <string>
|
||||
|
||||
Specify the *Pin Constraints File* (PCF) if you want to custom stimulus in testbenches. For example, ``-pin_constraints_file pin_constraints.xml``
|
||||
Strongly recommend for multi-clock simulations. See detailed file format about :ref:`file_format_pin_constraints_file`.
|
||||
|
||||
.. option:: --bus_group_file <string> or -bgf <string>
|
||||
|
||||
Specify the *Bus Group File* (BGF) if you want to group pins to buses. For example, ``-bgf bus_group.xml``
|
||||
Strongly recommend when input HDL contains bus ports. See detailed file format about :ref:`file_format_bus_group_file`.
|
||||
|
||||
.. option:: --explicit_port_mapping
|
||||
|
||||
Use explicit port mapping when writing the Verilog netlists
|
||||
|
||||
.. option:: --use_relative_path
|
||||
|
||||
Force to use relative path in netlists when including other netlists. By default, this is off, which means that netlists use absolute paths when including other netlists
|
||||
|
||||
.. option:: --default_net_type <string>
|
||||
|
||||
Specify the default net type for the Verilog netlists. Currently, supported types are ``none`` and ``wire``. Default value: ``none``.
|
||||
|
||||
.. option:: --no_time_stamp
|
||||
|
||||
Do not print time stamp in Verilog netlists
|
||||
|
||||
.. option:: --verbose
|
||||
|
||||
Show verbose log
|
||||
|
||||
write_preconfigured_testbench
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -251,6 +251,78 @@ ShellCommandId add_write_preconfigured_fabric_wrapper_command_template(
|
|||
return shell_cmd_id;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* - add a command to shell environment: write mock fpga wrapper
|
||||
* - add associated options
|
||||
* - add command dependency
|
||||
*******************************************************************/
|
||||
template <class T>
|
||||
ShellCommandId add_write_mock_fpga_wrapper_command_template(
|
||||
openfpga::Shell<T>& shell, const ShellCommandClassId& cmd_class_id,
|
||||
const std::vector<ShellCommandId>& dependent_cmds, const bool& hidden) {
|
||||
Command shell_cmd("write_mock_fpga_wrapper");
|
||||
|
||||
/* add an option '--file' in short '-f'*/
|
||||
CommandOptionId output_opt = shell_cmd.add_option(
|
||||
"file", true, "specify the output directory for hdl netlists");
|
||||
shell_cmd.set_option_short_name(output_opt, "f");
|
||||
shell_cmd.set_option_require_value(output_opt, openfpga::OPT_STRING);
|
||||
|
||||
/* add an option '--pin_constraints_file in short '-pcf' */
|
||||
CommandOptionId pcf_opt =
|
||||
shell_cmd.add_option("pin_constraints_file", false,
|
||||
"specify the file path to the pin constraints");
|
||||
shell_cmd.set_option_short_name(pcf_opt, "pcf");
|
||||
shell_cmd.set_option_require_value(pcf_opt, openfpga::OPT_STRING);
|
||||
|
||||
/* add an option '--bus_group_file in short '-bgf' */
|
||||
CommandOptionId bgf_opt = shell_cmd.add_option(
|
||||
"bus_group_file", false, "specify the file path to the group pins to bus");
|
||||
shell_cmd.set_option_short_name(bgf_opt, "bgf");
|
||||
shell_cmd.set_option_require_value(bgf_opt, openfpga::OPT_STRING);
|
||||
|
||||
/* Add an option '--use_relative_path' */
|
||||
shell_cmd.add_option(
|
||||
"use_relative_path", false,
|
||||
"Force to use relative path in netlists when including other netlists");
|
||||
|
||||
/* add an option '--explicit_port_mapping' */
|
||||
shell_cmd.add_option("explicit_port_mapping", false,
|
||||
"use explicit port mapping in verilog netlists");
|
||||
|
||||
/* Add an option '--default_net_type' */
|
||||
CommandOptionId default_net_type_opt = shell_cmd.add_option(
|
||||
"default_net_type", false,
|
||||
"Set the default net type for Verilog netlists. Default value is 'none'");
|
||||
shell_cmd.set_option_require_value(default_net_type_opt,
|
||||
openfpga::OPT_STRING);
|
||||
|
||||
/* add an option '--explicit_port_mapping' */
|
||||
shell_cmd.add_option("explicit_port_mapping", false,
|
||||
"use explicit port mapping in verilog netlists");
|
||||
|
||||
/* Add an option '--no_time_stamp' */
|
||||
shell_cmd.add_option("no_time_stamp", false,
|
||||
"Do not print a time stamp in the output files");
|
||||
|
||||
/* add an option '--verbose' */
|
||||
shell_cmd.add_option("verbose", false, "enable verbose output");
|
||||
|
||||
/* add command to the shell */
|
||||
ShellCommandId shell_cmd_id = shell.add_command(
|
||||
shell_cmd,
|
||||
"generate a wrapper of a mock fpga fabric mapped with applications",
|
||||
hidden);
|
||||
shell.set_command_class(shell_cmd_id, cmd_class_id);
|
||||
shell.set_command_execute_function(shell_cmd_id,
|
||||
write_mock_fpga_wrapper_template<T>);
|
||||
|
||||
/* add command dependency to the shell */
|
||||
shell.set_command_dependency(shell_cmd_id, dependent_cmds);
|
||||
|
||||
return shell_cmd_id;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* - Add a command to Shell environment: write preconfigured testbench
|
||||
* - Add associated options
|
||||
|
@ -435,6 +507,17 @@ void add_verilog_command_templates(openfpga::Shell<T>& shell,
|
|||
shell, openfpga_verilog_cmd_class, preconfig_wrapper_dependent_cmds,
|
||||
hidden);
|
||||
|
||||
/********************************
|
||||
* Command 'write_mock_fpga_wrapper'
|
||||
*/
|
||||
/* The command 'write_mock_fpga_wrapper' should NOT be executed
|
||||
* before 'build_fabric' */
|
||||
std::vector<ShellCommandId> write_mock_fpga_wrapper_dependent_cmds;
|
||||
write_mock_fpga_wrapper_dependent_cmds.push_back(build_fabric_cmd_id);
|
||||
add_write_mock_fpga_wrapper_command_template<T>(
|
||||
shell, openfpga_verilog_cmd_class, write_mock_fpga_wrapper_dependent_cmds,
|
||||
hidden);
|
||||
|
||||
/********************************
|
||||
* Command 'write_preconfigured_testbench'
|
||||
*/
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "read_xml_bus_group.h"
|
||||
#include "read_xml_pin_constraints.h"
|
||||
#include "verilog_api.h"
|
||||
#include "verilog_mock_fpga_wrapper.h"
|
||||
#include "vtr_log.h"
|
||||
#include "vtr_time.h"
|
||||
|
||||
|
@ -207,6 +208,61 @@ int write_preconfigured_fabric_wrapper_template(
|
|||
openfpga_ctx.arch().config_protocol, options);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* A wrapper function to call the mock fpga wrapper generator of
|
||||
*FPGA-Verilog
|
||||
*******************************************************************/
|
||||
template <class T>
|
||||
int write_mock_fpga_wrapper_template(const T& openfpga_ctx, const Command& cmd,
|
||||
const CommandContext& cmd_context) {
|
||||
CommandOptionId opt_output_dir = cmd.option("file");
|
||||
CommandOptionId opt_pcf = cmd.option("pin_constraints_file");
|
||||
CommandOptionId opt_bgf = cmd.option("bus_group_file");
|
||||
CommandOptionId opt_explicit_port_mapping =
|
||||
cmd.option("explicit_port_mapping");
|
||||
CommandOptionId opt_use_relative_path = cmd.option("use_relative_path");
|
||||
CommandOptionId opt_default_net_type = cmd.option("default_net_type");
|
||||
CommandOptionId opt_no_time_stamp = cmd.option("no_time_stamp");
|
||||
CommandOptionId opt_verbose = cmd.option("verbose");
|
||||
|
||||
/* This is an intermediate data structure which is designed to modularize the
|
||||
* FPGA-Verilog Keep it independent from any other outside data structures
|
||||
*/
|
||||
VerilogTestbenchOption options;
|
||||
options.set_output_directory(cmd_context.option_value(cmd, opt_output_dir));
|
||||
options.set_explicit_port_mapping(
|
||||
cmd_context.option_enable(cmd, opt_explicit_port_mapping));
|
||||
options.set_use_relative_path(
|
||||
cmd_context.option_enable(cmd, opt_use_relative_path));
|
||||
options.set_time_stamp(!cmd_context.option_enable(cmd, opt_no_time_stamp));
|
||||
options.set_verbose_output(cmd_context.option_enable(cmd, opt_verbose));
|
||||
|
||||
if (true == cmd_context.option_enable(cmd, opt_default_net_type)) {
|
||||
options.set_default_net_type(
|
||||
cmd_context.option_value(cmd, opt_default_net_type));
|
||||
}
|
||||
|
||||
/* If pin constraints are enabled by command options, read the file */
|
||||
PinConstraints pin_constraints;
|
||||
if (true == cmd_context.option_enable(cmd, opt_pcf)) {
|
||||
pin_constraints =
|
||||
read_xml_pin_constraints(cmd_context.option_value(cmd, opt_pcf).c_str());
|
||||
}
|
||||
|
||||
/* If bug group file are enabled by command options, read the file */
|
||||
BusGroup bus_group;
|
||||
if (true == cmd_context.option_enable(cmd, opt_bgf)) {
|
||||
bus_group =
|
||||
read_xml_bus_group(cmd_context.option_value(cmd, opt_bgf).c_str());
|
||||
}
|
||||
|
||||
return fpga_verilog_mock_fpga_wrapper(
|
||||
openfpga_ctx.module_graph(), g_vpr_ctx.atom(), g_vpr_ctx.placement(),
|
||||
pin_constraints, bus_group, openfpga_ctx.io_location_map(),
|
||||
openfpga_ctx.fabric_global_port_info(),
|
||||
openfpga_ctx.vpr_netlist_annotation(), options);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* A wrapper function to call the preconfigured testbench generator of
|
||||
*FPGA-Verilog
|
||||
|
|
|
@ -12,11 +12,13 @@
|
|||
/* Headers from openfpgautil library */
|
||||
#include "device_rr_gsb.h"
|
||||
#include "openfpga_digest.h"
|
||||
#include "openfpga_naming.h"
|
||||
#include "openfpga_reserved_words.h"
|
||||
#include "verilog_auxiliary_netlists.h"
|
||||
#include "verilog_constants.h"
|
||||
#include "verilog_formal_random_top_testbench.h"
|
||||
#include "verilog_grid.h"
|
||||
#include "verilog_mock_fpga_wrapper.h"
|
||||
#include "verilog_preconfig_top_module.h"
|
||||
#include "verilog_routing.h"
|
||||
#include "verilog_simulation_info_writer.h"
|
||||
|
@ -222,6 +224,60 @@ int fpga_verilog_preconfigured_fabric_wrapper(
|
|||
return status;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* A top-level function of FPGA-Verilog which focuses on a wrapper module,
|
||||
* which encapsulate the application HDL into a mock FPGA module
|
||||
********************************************************************/
|
||||
int fpga_verilog_mock_fpga_wrapper(
|
||||
const ModuleManager &module_manager, const AtomContext &atom_ctx,
|
||||
const PlacementContext &place_ctx, const PinConstraints &pin_constraints,
|
||||
const BusGroup &bus_group, const IoLocationMap &io_location_map,
|
||||
const FabricGlobalPortInfo &fabric_global_port_info,
|
||||
const VprNetlistAnnotation &netlist_annotation,
|
||||
const VerilogTestbenchOption &options) {
|
||||
vtr::ScopedStartFinishTimer timer(
|
||||
"Write a wrapper module to mock a mapped FPGA fabric\n");
|
||||
|
||||
std::string src_dir_path = format_dir_path(options.output_directory());
|
||||
|
||||
std::string netlist_name = atom_ctx.nlist.netlist_name();
|
||||
|
||||
int status = CMD_EXEC_SUCCESS;
|
||||
|
||||
NetlistManager netlist_manager;
|
||||
|
||||
/* Create directories */
|
||||
create_directory(src_dir_path);
|
||||
|
||||
/* Generate wrapper module for FPGA fabric (mapped by the input benchmark and
|
||||
* pre-configured testbench for verification */
|
||||
std::string netlist_file_name =
|
||||
generate_fpga_top_netlist_name(std::string(VERILOG_NETLIST_FILE_POSTFIX));
|
||||
std::string netlist_file_path = src_dir_path + netlist_file_name;
|
||||
status = print_verilog_mock_fpga_wrapper(
|
||||
module_manager, fabric_global_port_info, atom_ctx, place_ctx,
|
||||
pin_constraints, bus_group, io_location_map, netlist_annotation,
|
||||
netlist_name, netlist_file_path, options);
|
||||
|
||||
/* Add fname to the netlist name list */
|
||||
NetlistId nlist_id = NetlistId::INVALID();
|
||||
if (options.use_relative_path()) {
|
||||
nlist_id = netlist_manager.add_netlist(netlist_file_name);
|
||||
} else {
|
||||
nlist_id = netlist_manager.add_netlist(netlist_file_path);
|
||||
}
|
||||
VTR_ASSERT(nlist_id);
|
||||
netlist_manager.set_netlist_type(nlist_id,
|
||||
NetlistManager::TOP_MODULE_NETLIST);
|
||||
|
||||
/* Generate an netlist including all the fabric-related netlists */
|
||||
print_verilog_mock_fabric_include_netlist(netlist_manager, src_dir_path,
|
||||
options.use_relative_path(),
|
||||
options.time_stamp());
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* A top-level function of FPGA-Verilog which focuses on fabric Verilog
|
||||
*generation This function will generate
|
||||
|
|
|
@ -68,6 +68,14 @@ int fpga_verilog_preconfigured_fabric_wrapper(
|
|||
const CircuitLibrary& circuit_lib, const ConfigProtocol& config_protocol,
|
||||
const VerilogTestbenchOption& options);
|
||||
|
||||
int fpga_verilog_mock_fpga_wrapper(
|
||||
const ModuleManager& module_manager, const AtomContext& atom_ctx,
|
||||
const PlacementContext& place_ctx, const PinConstraints& pin_constraints,
|
||||
const BusGroup& bus_group, const IoLocationMap& io_location_map,
|
||||
const FabricGlobalPortInfo& fabric_global_port_info,
|
||||
const VprNetlistAnnotation& netlist_annotation,
|
||||
const VerilogTestbenchOption& options);
|
||||
|
||||
int fpga_verilog_preconfigured_testbench(
|
||||
const ModuleManager& module_manager, const AtomContext& atom_ctx,
|
||||
const PinConstraints& pin_constraints, const BusGroup& bus_group,
|
||||
|
|
|
@ -23,6 +23,48 @@ namespace openfpga {
|
|||
* Local constant variables
|
||||
*******************************************************************/
|
||||
|
||||
/********************************************************************
|
||||
* Print a file that includes all the fabric netlists
|
||||
* that have been generated and user-defined.
|
||||
* This does NOT include any testbenches!
|
||||
* Some netlists are open to compile under specific preprocessing flags
|
||||
*******************************************************************/
|
||||
void print_verilog_mock_fabric_include_netlist(
|
||||
const NetlistManager& netlist_manager, const std::string& src_dir_path,
|
||||
const bool& use_relative_path, const bool& include_time_stamp) {
|
||||
/* If we force the use of relative path, the src dir path should NOT be
|
||||
* included in any output */
|
||||
std::string src_dir = src_dir_path;
|
||||
if (use_relative_path) {
|
||||
src_dir.clear();
|
||||
}
|
||||
std::string verilog_fpath =
|
||||
src_dir_path + std::string(FABRIC_INCLUDE_VERILOG_NETLIST_FILE_NAME);
|
||||
|
||||
/* Create the file stream */
|
||||
std::fstream fp;
|
||||
fp.open(verilog_fpath, std::fstream::out | std::fstream::trunc);
|
||||
|
||||
/* Validate the file stream */
|
||||
check_file_stream(verilog_fpath.c_str(), fp);
|
||||
|
||||
/* Print the title */
|
||||
print_verilog_file_header(fp, std::string("Mock Fabric Netlist Summary"),
|
||||
include_time_stamp);
|
||||
|
||||
/* Include FPGA top module */
|
||||
print_verilog_comment(
|
||||
fp, std::string("------ Include fabric top-level netlists -----"));
|
||||
for (const NetlistId& nlist_id :
|
||||
netlist_manager.netlists_by_type(NetlistManager::TOP_MODULE_NETLIST)) {
|
||||
print_verilog_include_netlist(fp, netlist_manager.netlist_name(nlist_id));
|
||||
}
|
||||
fp << std::endl;
|
||||
|
||||
/* Close the file stream */
|
||||
fp.close();
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Print a file that includes all the fabric netlists
|
||||
* that have been generated and user-defined.
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void print_verilog_mock_fabric_include_netlist(
|
||||
const NetlistManager& netlist_manager, const std::string& src_dir_path,
|
||||
const bool& use_relative_path, const bool& include_time_stamp);
|
||||
|
||||
void print_verilog_fabric_include_netlist(const NetlistManager& netlist_manager,
|
||||
const std::string& src_dir_path,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
|
|
|
@ -116,8 +116,9 @@ static void print_verilog_top_random_testbench_benchmark_instance(
|
|||
print_verilog_testbench_benchmark_instance(
|
||||
fp, reference_verilog_top_name, std::string(BENCHMARK_INSTANCE_NAME),
|
||||
std::string(), std::string(), std::string(),
|
||||
std::string(BENCHMARK_PORT_POSTFIX), std::vector<std::string>(), atom_ctx,
|
||||
netlist_annotation, pin_constraints, bus_group, explicit_port_mapping);
|
||||
std::string(BENCHMARK_PORT_POSTFIX), std::vector<std::string>(), false,
|
||||
atom_ctx, netlist_annotation, pin_constraints, bus_group,
|
||||
explicit_port_mapping);
|
||||
|
||||
print_verilog_comment(
|
||||
fp, std::string("----- End reference Benchmark Instanication -------"));
|
||||
|
@ -147,7 +148,7 @@ static void print_verilog_random_testbench_fpga_instance(
|
|||
std::string(FORMAL_VERIFICATION_TOP_MODULE_POSTFIX)),
|
||||
std::string(FPGA_INSTANCE_NAME), std::string(), std::string(),
|
||||
std::string(), std::string(FPGA_PORT_POSTFIX), std::vector<std::string>(),
|
||||
atom_ctx, netlist_annotation, pin_constraints, bus_group,
|
||||
false, atom_ctx, netlist_annotation, pin_constraints, bus_group,
|
||||
explicit_port_mapping);
|
||||
|
||||
print_verilog_comment(
|
||||
|
|
|
@ -0,0 +1,491 @@
|
|||
/********************************************************************
|
||||
* This file includes functions that are used to generate
|
||||
* a Verilog module of a pre-configured FPGA fabric
|
||||
*******************************************************************/
|
||||
#include <fstream>
|
||||
|
||||
/* Headers from vtrutil library */
|
||||
#include "command_exit_codes.h"
|
||||
#include "vtr_assert.h"
|
||||
#include "vtr_log.h"
|
||||
#include "vtr_time.h"
|
||||
|
||||
/* Headers from openfpgautil library */
|
||||
#include "bitstream_manager_utils.h"
|
||||
#include "fabric_global_port_info_utils.h"
|
||||
#include "module_manager_utils.h"
|
||||
#include "openfpga_atom_netlist_utils.h"
|
||||
#include "openfpga_digest.h"
|
||||
#include "openfpga_naming.h"
|
||||
#include "openfpga_port.h"
|
||||
#include "openfpga_reserved_words.h"
|
||||
#include "verilog_constants.h"
|
||||
#include "verilog_mock_fpga_wrapper.h"
|
||||
#include "verilog_testbench_utils.h"
|
||||
#include "verilog_writer_utils.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* Local variables used only in this file
|
||||
*******************************************************************/
|
||||
constexpr const char* APPINST_PORT_POSTFIX = "_bench";
|
||||
constexpr const char* APP_INSTANCE_NAME = "MAPPED_DESIGN";
|
||||
|
||||
/********************************************************************
|
||||
* This function adds stimuli to I/Os of FPGA fabric
|
||||
* 1. For mapped I/Os, this function will wire them to the input ports
|
||||
* of the pre-configured FPGA top module
|
||||
* 2. For unmapped I/Os, this function will assign a constant value
|
||||
* by default
|
||||
*******************************************************************/
|
||||
static void print_verilog_mock_fpga_wrapper_connect_ios(
|
||||
std::fstream& fp, const ModuleManager& module_manager,
|
||||
const ModuleId& top_module, const AtomContext& atom_ctx,
|
||||
const PlacementContext& place_ctx, const IoLocationMap& io_location_map,
|
||||
const PinConstraints& pin_constraints,
|
||||
const FabricGlobalPortInfo& global_ports,
|
||||
const VprNetlistAnnotation& netlist_annotation,
|
||||
const std::string& net_name_postfix,
|
||||
const std::string& io_input_port_name_postfix,
|
||||
const std::string& io_output_port_name_postfix,
|
||||
const std::vector<std::string>& clock_port_names,
|
||||
const size_t& unused_io_value) {
|
||||
/* Validate the file stream */
|
||||
valid_file_stream(fp);
|
||||
|
||||
/* Only mappable i/o ports can be considered */
|
||||
std::vector<ModulePortId> module_io_ports;
|
||||
for (const ModuleManager::e_module_port_type& module_io_port_type :
|
||||
MODULE_IO_PORT_TYPES) {
|
||||
for (const ModulePortId& gpio_port_id :
|
||||
module_manager.module_port_ids_by_type(top_module,
|
||||
module_io_port_type)) {
|
||||
/* Only care mappable I/O */
|
||||
if (false ==
|
||||
module_manager.port_is_mappable_io(top_module, gpio_port_id)) {
|
||||
continue;
|
||||
}
|
||||
module_io_ports.push_back(gpio_port_id);
|
||||
}
|
||||
}
|
||||
|
||||
/* Keep tracking which I/Os have been used */
|
||||
std::map<ModulePortId, std::vector<bool>> io_used;
|
||||
for (const ModulePortId& module_io_port_id : module_io_ports) {
|
||||
const BasicPort& module_io_port =
|
||||
module_manager.module_port(top_module, module_io_port_id);
|
||||
io_used[module_io_port_id] =
|
||||
std::vector<bool>(module_io_port.get_width(), false);
|
||||
}
|
||||
|
||||
/* Type mapping between VPR block and Module port */
|
||||
std::map<AtomBlockType, ModuleManager::e_module_port_type>
|
||||
atom_block_type_to_module_port_type;
|
||||
atom_block_type_to_module_port_type[AtomBlockType::INPAD] =
|
||||
ModuleManager::MODULE_GPIN_PORT;
|
||||
atom_block_type_to_module_port_type[AtomBlockType::OUTPAD] =
|
||||
ModuleManager::MODULE_GPOUT_PORT;
|
||||
|
||||
/* See if this I/O should be wired to a benchmark input/output */
|
||||
/* Add signals from blif benchmark and short-wire them to FPGA I/O PADs
|
||||
* This brings convenience to checking functionality
|
||||
*/
|
||||
print_verilog_comment(
|
||||
fp, std::string("----- Link FPGA I/Os to Benchmark I/Os -----"));
|
||||
|
||||
for (const AtomBlockId& atom_blk : atom_ctx.nlist.blocks()) {
|
||||
/* Bypass non-I/O atom blocks ! */
|
||||
if ((AtomBlockType::INPAD != atom_ctx.nlist.block_type(atom_blk)) &&
|
||||
(AtomBlockType::OUTPAD != atom_ctx.nlist.block_type(atom_blk))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If there is a GPIO port, use it directly
|
||||
* Otherwise, should find a GPIN for INPAD
|
||||
* or should find a GPOUT for OUTPAD
|
||||
*/
|
||||
std::pair<ModulePortId, size_t> mapped_module_io_info =
|
||||
std::make_pair(ModulePortId::INVALID(), -1);
|
||||
for (const ModulePortId& module_io_port_id : module_io_ports) {
|
||||
const BasicPort& module_io_port =
|
||||
module_manager.module_port(top_module, module_io_port_id);
|
||||
|
||||
/* Find the index of the mapped GPIO in top-level FPGA fabric */
|
||||
size_t temp_io_index = io_location_map.io_index(
|
||||
place_ctx.block_locs[atom_ctx.lookup.atom_clb(atom_blk)].loc.x,
|
||||
place_ctx.block_locs[atom_ctx.lookup.atom_clb(atom_blk)].loc.y,
|
||||
place_ctx.block_locs[atom_ctx.lookup.atom_clb(atom_blk)].loc.sub_tile,
|
||||
module_io_port.get_name());
|
||||
|
||||
/* Bypass invalid index (not mapped to this GPIO port) */
|
||||
if (size_t(-1) == temp_io_index) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If the port is an GPIO port, just use it */
|
||||
if (ModuleManager::MODULE_GPIO_PORT ==
|
||||
module_manager.port_type(top_module, module_io_port_id)) {
|
||||
mapped_module_io_info =
|
||||
std::make_pair(module_io_port_id, temp_io_index);
|
||||
break;
|
||||
}
|
||||
|
||||
/* If this is an INPAD, we can use an GPIN port (if available) */
|
||||
if (atom_block_type_to_module_port_type[atom_ctx.nlist.block_type(
|
||||
atom_blk)] ==
|
||||
module_manager.port_type(top_module, module_io_port_id)) {
|
||||
mapped_module_io_info =
|
||||
std::make_pair(module_io_port_id, temp_io_index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* We must find a valid one */
|
||||
VTR_ASSERT(true == module_manager.valid_module_port_id(
|
||||
top_module, mapped_module_io_info.first));
|
||||
VTR_ASSERT(size_t(-1) != mapped_module_io_info.second);
|
||||
|
||||
/* Ensure that IO index is in range */
|
||||
BasicPort module_mapped_io_port =
|
||||
module_manager.module_port(top_module, mapped_module_io_info.first);
|
||||
size_t io_index = mapped_module_io_info.second;
|
||||
|
||||
/* Set the port pin index */
|
||||
VTR_ASSERT(io_index < module_mapped_io_port.get_width());
|
||||
module_mapped_io_port.set_name(module_mapped_io_port.get_name() +
|
||||
net_name_postfix);
|
||||
module_mapped_io_port.set_width(io_index, io_index);
|
||||
|
||||
/* The block may be renamed as it contains special characters which violate
|
||||
* Verilog syntax */
|
||||
std::string block_name = atom_ctx.nlist.block_name(atom_blk);
|
||||
if (true == netlist_annotation.is_block_renamed(atom_blk)) {
|
||||
block_name = netlist_annotation.block_name(atom_blk);
|
||||
}
|
||||
/* Note that VPR added a prefix to the name of output blocks
|
||||
* We can remove this when specified through input argument
|
||||
*/
|
||||
if (AtomBlockType::OUTPAD == atom_ctx.nlist.block_type(atom_blk)) {
|
||||
block_name = remove_atom_block_name_prefix(block_name);
|
||||
}
|
||||
|
||||
/* Create the port for benchmark I/O, due to BLIF benchmark, each I/O always
|
||||
* has a size of 1 In addition, the input and output ports may have
|
||||
* different postfix in naming due to verification context! Here, we give
|
||||
* full customization on naming
|
||||
*/
|
||||
BasicPort benchmark_io_port;
|
||||
|
||||
benchmark_io_port.set_width(1);
|
||||
|
||||
if (AtomBlockType::INPAD == atom_ctx.nlist.block_type(atom_blk)) {
|
||||
/* If the port is a clock, skip it */
|
||||
if (clock_port_names.end() != std::find(clock_port_names.begin(),
|
||||
clock_port_names.end(),
|
||||
block_name)) {
|
||||
continue;
|
||||
}
|
||||
/* For global ports, use wires; otherwise, use registers*/
|
||||
if (true == port_is_fabric_global_reset_port(
|
||||
global_ports, module_manager,
|
||||
pin_constraints.net_pin(block_name))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
benchmark_io_port.set_name(
|
||||
std::string(block_name + io_input_port_name_postfix));
|
||||
print_verilog_comment(
|
||||
fp, std::string("----- Blif Benchmark input " + block_name +
|
||||
" is mapped to FPGA IOPAD " +
|
||||
module_mapped_io_port.get_name() + "[" +
|
||||
std::to_string(io_index) + "] -----"));
|
||||
print_verilog_wire_connection(fp, benchmark_io_port,
|
||||
module_mapped_io_port, false);
|
||||
} else {
|
||||
VTR_ASSERT(AtomBlockType::OUTPAD == atom_ctx.nlist.block_type(atom_blk));
|
||||
benchmark_io_port.set_name(
|
||||
std::string(block_name + io_output_port_name_postfix));
|
||||
print_verilog_comment(
|
||||
fp, std::string("----- Blif Benchmark output " + block_name +
|
||||
" is mapped to FPGA IOPAD " +
|
||||
module_mapped_io_port.get_name() + "[" +
|
||||
std::to_string(io_index) + "] -----"));
|
||||
print_verilog_wire_connection(fp, module_mapped_io_port,
|
||||
benchmark_io_port, false);
|
||||
}
|
||||
|
||||
/* Mark this I/O has been used/wired */
|
||||
io_used[mapped_module_io_info.first][io_index] = true;
|
||||
|
||||
/* Add an empty line as a splitter */
|
||||
fp << std::endl;
|
||||
}
|
||||
|
||||
/* Wire the unused iopads to a constant */
|
||||
print_verilog_comment(
|
||||
fp, std::string("----- Wire unused FPGA I/Os to constants -----"));
|
||||
for (const ModulePortId& module_io_port_id : module_io_ports) {
|
||||
for (size_t io_index = 0; io_index < io_used[module_io_port_id].size();
|
||||
++io_index) {
|
||||
/* Bypass used iopads */
|
||||
if (true == io_used[module_io_port_id][io_index]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Bypass unused output pads */
|
||||
if (ModuleManager::MODULE_GPOUT_PORT !=
|
||||
module_manager.port_type(top_module, module_io_port_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Wire to a contant */
|
||||
BasicPort module_unused_io_port =
|
||||
module_manager.module_port(top_module, module_io_port_id);
|
||||
/* Set the port pin index */
|
||||
module_unused_io_port.set_name(module_unused_io_port.get_name() +
|
||||
net_name_postfix);
|
||||
module_unused_io_port.set_width(io_index, io_index);
|
||||
|
||||
std::vector<size_t> default_values(module_unused_io_port.get_width(),
|
||||
unused_io_value);
|
||||
print_verilog_wire_constant_values(fp, module_unused_io_port,
|
||||
default_values);
|
||||
}
|
||||
|
||||
/* Add an empty line as a splitter */
|
||||
fp << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Connect global ports of FPGA top module to constants except:
|
||||
* 1. operating clock, which should be wired to the clock port of
|
||||
* this pre-configured FPGA top module
|
||||
*******************************************************************/
|
||||
static int print_verilog_mock_fpga_wrapper_connect_global_ports(
|
||||
std::fstream& fp, const ModuleManager& module_manager,
|
||||
const ModuleId& top_module, const PinConstraints& pin_constraints,
|
||||
const FabricGlobalPortInfo& fabric_global_ports,
|
||||
const std::vector<std::string>& benchmark_clock_port_names) {
|
||||
/* Validate the file stream */
|
||||
valid_file_stream(fp);
|
||||
|
||||
print_verilog_comment(
|
||||
fp,
|
||||
std::string(
|
||||
"----- Begin Connect Global ports to FPGA top-level interface -----"));
|
||||
|
||||
for (const FabricGlobalPortId& global_port_id :
|
||||
fabric_global_ports.global_ports()) {
|
||||
ModulePortId module_global_port_id =
|
||||
fabric_global_ports.global_module_port(global_port_id);
|
||||
VTR_ASSERT(ModuleManager::MODULE_GLOBAL_PORT ==
|
||||
module_manager.port_type(top_module, module_global_port_id));
|
||||
BasicPort module_global_port =
|
||||
module_manager.module_port(top_module, module_global_port_id);
|
||||
/* Now, for operating clock port, we should wire it to the clock of
|
||||
* benchmark! */
|
||||
if ((true == fabric_global_ports.global_port_is_clock(global_port_id)) &&
|
||||
(false == fabric_global_ports.global_port_is_prog(global_port_id))) {
|
||||
/* Wiring to each pin of the global port: benchmark clock is always 1-bit
|
||||
*/
|
||||
for (size_t pin_id = 0; pin_id < module_global_port.pins().size();
|
||||
++pin_id) {
|
||||
BasicPort module_clock_pin(module_global_port.get_name(),
|
||||
module_global_port.pins()[pin_id],
|
||||
module_global_port.pins()[pin_id]);
|
||||
|
||||
/* If the clock port name is in the pin constraints, we should wire it
|
||||
* to the constrained pin */
|
||||
std::string constrained_net_name = pin_constraints.pin_net(BasicPort(
|
||||
module_global_port.get_name(), module_global_port.pins()[pin_id],
|
||||
module_global_port.pins()[pin_id]));
|
||||
|
||||
/* If constrained to an open net or there is no clock in the benchmark,
|
||||
* we assign it to a default value */
|
||||
if ((true == pin_constraints.unmapped_net(constrained_net_name)) ||
|
||||
(true == benchmark_clock_port_names.empty())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string clock_name_to_connect;
|
||||
if (!pin_constraints.unconstrained_net(constrained_net_name)) {
|
||||
clock_name_to_connect = constrained_net_name;
|
||||
} else {
|
||||
/* Otherwise, we must have a clear one-to-one clock net
|
||||
* corresponding!!! */
|
||||
if (benchmark_clock_port_names.size() !=
|
||||
module_global_port.get_width()) {
|
||||
VTR_LOG_ERROR(
|
||||
"Unable to map %lu benchmark clocks to %lu clock pins of "
|
||||
"FPGA!\nRequire clear pin constraints!\n",
|
||||
benchmark_clock_port_names.size(),
|
||||
module_global_port.get_width());
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
clock_name_to_connect = benchmark_clock_port_names[pin_id];
|
||||
}
|
||||
clock_name_to_connect += std::string(APPINST_PORT_POSTFIX);
|
||||
|
||||
BasicPort benchmark_clock_pin(clock_name_to_connect, 1);
|
||||
print_verilog_wire_connection(fp, benchmark_clock_pin, module_clock_pin,
|
||||
false);
|
||||
}
|
||||
/* Finish, go to the next */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* For other ports, give an default value */
|
||||
for (size_t pin_id = 0; pin_id < module_global_port.pins().size();
|
||||
++pin_id) {
|
||||
BasicPort module_global_pin(module_global_port.get_name(),
|
||||
module_global_port.pins()[pin_id],
|
||||
module_global_port.pins()[pin_id]);
|
||||
|
||||
/* If the global port name is in the pin constraints, we should wire it to
|
||||
* the constrained pin */
|
||||
std::string constrained_net_name =
|
||||
pin_constraints.pin_net(module_global_pin);
|
||||
if (constrained_net_name.empty()) {
|
||||
continue;
|
||||
}
|
||||
constrained_net_name += std::string(APPINST_PORT_POSTFIX);
|
||||
|
||||
module_global_pin.set_name(module_global_port.get_name());
|
||||
|
||||
/* - If constrained to a given net in the benchmark, we connect the global
|
||||
* pin to the net
|
||||
* - If constrained to an open net in the benchmark, we assign it to a
|
||||
* default value
|
||||
*/
|
||||
if ((false == pin_constraints.unconstrained_net(constrained_net_name)) &&
|
||||
(false == pin_constraints.unmapped_net(constrained_net_name))) {
|
||||
BasicPort benchmark_pin(constrained_net_name, 1);
|
||||
print_verilog_wire_connection(fp, benchmark_pin, module_global_pin,
|
||||
false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print_verilog_comment(
|
||||
fp, std::string(
|
||||
"----- End Connect Global ports to FPGA top-level interface -----"));
|
||||
|
||||
/* Add an empty line as a splitter */
|
||||
fp << std::endl;
|
||||
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Top-level function to generate a Verilog module of
|
||||
* a mock FPGA wrapper which contains an benchmark instance.
|
||||
*
|
||||
* Mock FPGA wrapper
|
||||
* +--------------------------------------------
|
||||
* |
|
||||
* | Benchmark instance
|
||||
* | +-------------------------------+
|
||||
* | | |
|
||||
* fpga_clock----->|--------->|benchmark_clock |
|
||||
* | | |
|
||||
* fpga_inputs---->|--------->|benchmark_inputs |
|
||||
* | | |
|
||||
* fpga_outputs<---|<---------|benchmark_output |
|
||||
* | | |
|
||||
* | +-------------------------------+
|
||||
* |
|
||||
* +-------------------------------------------
|
||||
*
|
||||
* Note: we do NOT put this module in the module manager.
|
||||
* Because, it is not a standard module, where we just wrap an instance of
|
||||
*application HDL (supposed to be implemented on FPGA).
|
||||
*******************************************************************/
|
||||
int print_verilog_mock_fpga_wrapper(
|
||||
const ModuleManager& module_manager, const FabricGlobalPortInfo& global_ports,
|
||||
const AtomContext& atom_ctx, const PlacementContext& place_ctx,
|
||||
const PinConstraints& pin_constraints, const BusGroup& bus_group,
|
||||
const IoLocationMap& io_location_map,
|
||||
const VprNetlistAnnotation& netlist_annotation,
|
||||
const std::string& circuit_name, const std::string& verilog_fname,
|
||||
const VerilogTestbenchOption& options) {
|
||||
std::string timer_message =
|
||||
std::string("Write mock FPGA wrapper in Verilog format for design '") +
|
||||
circuit_name + std::string("'");
|
||||
|
||||
int status = CMD_EXEC_SUCCESS;
|
||||
|
||||
/* Start time count */
|
||||
vtr::ScopedStartFinishTimer timer(timer_message);
|
||||
|
||||
/* Create the file stream */
|
||||
std::fstream fp;
|
||||
fp.open(verilog_fname, std::fstream::out | std::fstream::trunc);
|
||||
|
||||
/* Validate the file stream */
|
||||
check_file_stream(verilog_fname.c_str(), fp);
|
||||
|
||||
/* Generate a brief description on the Verilog file*/
|
||||
std::string title =
|
||||
std::string("Verilog netlist for mock FPGA fabric by design: ") +
|
||||
circuit_name;
|
||||
print_verilog_file_header(fp, title, options.time_stamp());
|
||||
|
||||
/* Find the top_module */
|
||||
ModuleId top_module =
|
||||
module_manager.find_module(generate_fpga_top_module_name());
|
||||
VTR_ASSERT(true == module_manager.valid_module_id(top_module));
|
||||
|
||||
/* Print module declaration */
|
||||
print_verilog_module_declaration(fp, module_manager, top_module,
|
||||
options.default_net_type());
|
||||
|
||||
/* Find clock ports in benchmark */
|
||||
std::vector<std::string> benchmark_clock_port_names =
|
||||
find_atom_netlist_clock_port_names(atom_ctx.nlist, netlist_annotation);
|
||||
|
||||
/* Print local wires */
|
||||
print_verilog_testbench_shared_input_ports(
|
||||
fp, module_manager, global_ports, pin_constraints, atom_ctx,
|
||||
netlist_annotation, benchmark_clock_port_names, true,
|
||||
std::string(APPINST_PORT_POSTFIX), false);
|
||||
|
||||
print_verilog_testbench_shared_benchmark_output_ports(
|
||||
fp, atom_ctx, netlist_annotation, std::string(APPINST_PORT_POSTFIX));
|
||||
|
||||
/* Instanciate application HDL module */
|
||||
print_verilog_testbench_benchmark_instance(
|
||||
fp, circuit_name, std::string(APP_INSTANCE_NAME), std::string(),
|
||||
std::string(), std::string(APPINST_PORT_POSTFIX),
|
||||
std::string(APPINST_PORT_POSTFIX), benchmark_clock_port_names, true,
|
||||
atom_ctx, netlist_annotation, pin_constraints, bus_group,
|
||||
options.explicit_port_mapping());
|
||||
|
||||
/* Connect FPGA top module global ports to constant or benchmark global
|
||||
* signals! */
|
||||
status = print_verilog_mock_fpga_wrapper_connect_global_ports(
|
||||
fp, module_manager, top_module, pin_constraints, global_ports,
|
||||
benchmark_clock_port_names);
|
||||
if (CMD_EXEC_FATAL_ERROR == status) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Connect I/Os to benchmark I/Os or constant driver */
|
||||
print_verilog_mock_fpga_wrapper_connect_ios(
|
||||
fp, module_manager, top_module, atom_ctx, place_ctx, io_location_map,
|
||||
pin_constraints, global_ports, netlist_annotation, std::string(),
|
||||
std::string(APPINST_PORT_POSTFIX), std::string(APPINST_PORT_POSTFIX),
|
||||
benchmark_clock_port_names, (size_t)VERILOG_DEFAULT_SIGNAL_INIT_VALUE);
|
||||
|
||||
/* Testbench ends*/
|
||||
print_verilog_module_end(fp, title);
|
||||
|
||||
/* Close the file stream */
|
||||
fp.close();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef VERILOG_MOCK_FPGA_WRAPPER_H
|
||||
#define VERILOG_MOCK_FPGA_WRAPPER_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "bitstream_manager.h"
|
||||
#include "bus_group.h"
|
||||
#include "circuit_library.h"
|
||||
#include "config_protocol.h"
|
||||
#include "fabric_global_port_info.h"
|
||||
#include "io_location_map.h"
|
||||
#include "module_manager.h"
|
||||
#include "pin_constraints.h"
|
||||
#include "verilog_testbench_options.h"
|
||||
#include "vpr_context.h"
|
||||
#include "vpr_netlist_annotation.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
int print_verilog_mock_fpga_wrapper(
|
||||
const ModuleManager& module_manager, const FabricGlobalPortInfo& global_ports,
|
||||
const AtomContext& atom_ctx, const PlacementContext& place_ctx,
|
||||
const PinConstraints& pin_constraints, const BusGroup& bus_group,
|
||||
const IoLocationMap& io_location_map,
|
||||
const VprNetlistAnnotation& netlist_annotation,
|
||||
const std::string& circuit_name, const std::string& verilog_fname,
|
||||
const VerilogTestbenchOption& options);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -78,7 +78,8 @@ void print_verilog_testbench_benchmark_instance(
|
|||
const std::string& module_input_port_postfix,
|
||||
const std::string& module_output_port_postfix,
|
||||
const std::string& input_port_postfix, const std::string& output_port_postfix,
|
||||
const std::vector<std::string>& clock_port_names, const AtomContext& atom_ctx,
|
||||
const std::vector<std::string>& clock_port_names,
|
||||
const bool& include_clock_port_postfix, const AtomContext& atom_ctx,
|
||||
const VprNetlistAnnotation& netlist_annotation,
|
||||
const PinConstraints& pin_constraints, const BusGroup& bus_group,
|
||||
const bool& use_explicit_port_map) {
|
||||
|
@ -183,6 +184,8 @@ void print_verilog_testbench_benchmark_instance(
|
|||
clock_port_names.end(),
|
||||
port_names[iport])) {
|
||||
fp << input_port_postfix;
|
||||
} else if (include_clock_port_postfix) {
|
||||
fp << input_port_postfix;
|
||||
}
|
||||
|
||||
pin_counter++;
|
||||
|
@ -206,6 +209,8 @@ void print_verilog_testbench_benchmark_instance(
|
|||
clock_port_names.end(),
|
||||
port_names[iport])) {
|
||||
fp << input_port_postfix;
|
||||
} else if (include_clock_port_postfix) {
|
||||
fp << input_port_postfix;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -914,20 +919,16 @@ void print_verilog_testbench_random_stimuli(
|
|||
* which are
|
||||
* 1. the shared input ports (registers) to drive both
|
||||
* FPGA fabric and benchmark instance
|
||||
* 2. the output ports (wires) for both FPGA fabric and benchmark instance
|
||||
* 3. the checking flag ports to evaluate if outputs matches under the
|
||||
* same input vectors
|
||||
*******************************************************************/
|
||||
void print_verilog_testbench_shared_ports(
|
||||
void print_verilog_testbench_shared_input_ports(
|
||||
std::fstream& fp, const ModuleManager& module_manager,
|
||||
const FabricGlobalPortInfo& global_ports,
|
||||
const PinConstraints& pin_constraints, const AtomContext& atom_ctx,
|
||||
const VprNetlistAnnotation& netlist_annotation,
|
||||
const std::vector<std::string>& clock_port_names,
|
||||
const std::string& shared_input_port_postfix,
|
||||
const std::string& benchmark_output_port_postfix,
|
||||
const std::string& fpga_output_port_postfix,
|
||||
const std::string& check_flag_port_postfix, const bool& no_self_checking) {
|
||||
const bool& include_clock_ports, const std::string& shared_input_port_postfix,
|
||||
const bool& use_reg_port) {
|
||||
/* Validate the file stream */
|
||||
valid_file_stream(fp);
|
||||
|
||||
|
@ -950,7 +951,9 @@ void print_verilog_testbench_shared_ports(
|
|||
if (clock_port_names.end() != std::find(clock_port_names.begin(),
|
||||
clock_port_names.end(),
|
||||
block_name)) {
|
||||
continue;
|
||||
if (!include_clock_ports) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Each logical block assumes a single-width port */
|
||||
|
@ -959,8 +962,13 @@ void print_verilog_testbench_shared_ports(
|
|||
if (false ==
|
||||
port_is_fabric_global_reset_port(global_ports, module_manager,
|
||||
pin_constraints.net_pin(block_name))) {
|
||||
fp << "\t" << generate_verilog_port(VERILOG_PORT_REG, input_port) << ";"
|
||||
<< std::endl;
|
||||
if (use_reg_port) {
|
||||
fp << "\t" << generate_verilog_port(VERILOG_PORT_REG, input_port) << ";"
|
||||
<< std::endl;
|
||||
} else {
|
||||
fp << "\t" << generate_verilog_port(VERILOG_PORT_WIRE, input_port)
|
||||
<< ";" << std::endl;
|
||||
}
|
||||
} else {
|
||||
fp << "\t" << generate_verilog_port(VERILOG_PORT_WIRE, input_port) << ";"
|
||||
<< std::endl;
|
||||
|
@ -969,6 +977,19 @@ void print_verilog_testbench_shared_ports(
|
|||
|
||||
/* Add an empty line as splitter */
|
||||
fp << std::endl;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Print Verilog declaration of shared ports appear in testbenches
|
||||
* which are
|
||||
* 2. the output ports (wires) for FPGA fabric
|
||||
*******************************************************************/
|
||||
void print_verilog_testbench_shared_fpga_output_ports(
|
||||
std::fstream& fp, const AtomContext& atom_ctx,
|
||||
const VprNetlistAnnotation& netlist_annotation,
|
||||
const std::string& fpga_output_port_postfix) {
|
||||
/* Validate the file stream */
|
||||
valid_file_stream(fp);
|
||||
|
||||
/* Instantiate wires for FPGA fabric outputs */
|
||||
print_verilog_comment(fp, std::string("----- FPGA fabric outputs -------"));
|
||||
|
@ -996,10 +1017,19 @@ void print_verilog_testbench_shared_ports(
|
|||
|
||||
/* Add an empty line as splitter */
|
||||
fp << std::endl;
|
||||
}
|
||||
|
||||
if (no_self_checking) {
|
||||
return;
|
||||
}
|
||||
/********************************************************************
|
||||
* Print Verilog declaration of shared ports appear in testbenches
|
||||
* which are
|
||||
* 2. the output ports (wires) for benchmark instance
|
||||
*******************************************************************/
|
||||
void print_verilog_testbench_shared_benchmark_output_ports(
|
||||
std::fstream& fp, const AtomContext& atom_ctx,
|
||||
const VprNetlistAnnotation& netlist_annotation,
|
||||
const std::string& benchmark_output_port_postfix) {
|
||||
/* Validate the file stream */
|
||||
valid_file_stream(fp);
|
||||
|
||||
/* Instantiate wire for benchmark output */
|
||||
print_verilog_comment(fp, std::string("----- Benchmark outputs -------"));
|
||||
|
@ -1026,6 +1056,23 @@ void print_verilog_testbench_shared_ports(
|
|||
|
||||
/* Add an empty line as splitter */
|
||||
fp << std::endl;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Print Verilog declaration of shared ports appear in testbenches
|
||||
* which are
|
||||
* 1. the shared input ports (registers) to drive both
|
||||
* FPGA fabric and benchmark instance
|
||||
* 2. the output ports (wires) for both FPGA fabric and benchmark instance
|
||||
* 3. the checking flag ports to evaluate if outputs matches under the
|
||||
* same input vectors
|
||||
*******************************************************************/
|
||||
void print_verilog_testbench_shared_check_flags(
|
||||
std::fstream& fp, const AtomContext& atom_ctx,
|
||||
const VprNetlistAnnotation& netlist_annotation,
|
||||
const std::string& check_flag_port_postfix) {
|
||||
/* Validate the file stream */
|
||||
valid_file_stream(fp);
|
||||
|
||||
/* Instantiate register for output comparison */
|
||||
print_verilog_comment(
|
||||
|
@ -1054,6 +1101,44 @@ void print_verilog_testbench_shared_ports(
|
|||
fp << std::endl;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Print Verilog declaration of shared ports appear in testbenches
|
||||
* which are
|
||||
* 1. the shared input ports (registers) to drive both
|
||||
* FPGA fabric and benchmark instance
|
||||
* 2. the output ports (wires) for both FPGA fabric and benchmark instance
|
||||
* 3. the checking flag ports to evaluate if outputs matches under the
|
||||
* same input vectors
|
||||
*******************************************************************/
|
||||
void print_verilog_testbench_shared_ports(
|
||||
std::fstream& fp, const ModuleManager& module_manager,
|
||||
const FabricGlobalPortInfo& global_ports,
|
||||
const PinConstraints& pin_constraints, const AtomContext& atom_ctx,
|
||||
const VprNetlistAnnotation& netlist_annotation,
|
||||
const std::vector<std::string>& clock_port_names,
|
||||
const std::string& shared_input_port_postfix,
|
||||
const std::string& benchmark_output_port_postfix,
|
||||
const std::string& fpga_output_port_postfix,
|
||||
const std::string& check_flag_port_postfix, const bool& no_self_checking) {
|
||||
print_verilog_testbench_shared_input_ports(
|
||||
fp, module_manager, global_ports, pin_constraints, atom_ctx,
|
||||
netlist_annotation, clock_port_names, false, shared_input_port_postfix,
|
||||
true);
|
||||
|
||||
print_verilog_testbench_shared_fpga_output_ports(
|
||||
fp, atom_ctx, netlist_annotation, fpga_output_port_postfix);
|
||||
|
||||
if (no_self_checking) {
|
||||
return;
|
||||
}
|
||||
|
||||
print_verilog_testbench_shared_benchmark_output_ports(
|
||||
fp, atom_ctx, netlist_annotation, benchmark_output_port_postfix);
|
||||
|
||||
print_verilog_testbench_shared_check_flags(fp, atom_ctx, netlist_annotation,
|
||||
check_flag_port_postfix);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Print signal initialization which
|
||||
* deposit initial values for the input ports of primitive circuit models
|
||||
|
|
|
@ -38,7 +38,8 @@ void print_verilog_testbench_benchmark_instance(
|
|||
const std::string& module_input_port_postfix,
|
||||
const std::string& module_output_port_postfix,
|
||||
const std::string& input_port_postfix, const std::string& output_port_postfix,
|
||||
const std::vector<std::string>& clock_port_names, const AtomContext& atom_ctx,
|
||||
const std::vector<std::string>& clock_port_names,
|
||||
const bool& include_clock_port_postfix, const AtomContext& atom_ctx,
|
||||
const VprNetlistAnnotation& netlist_annotation,
|
||||
const PinConstraints& pin_constraints, const BusGroup& bus_group,
|
||||
const bool& use_explicit_port_map);
|
||||
|
@ -90,6 +91,30 @@ void print_verilog_testbench_random_stimuli(
|
|||
const std::string& check_flag_port_postfix,
|
||||
const std::vector<BasicPort>& clock_ports, const bool& no_self_checking);
|
||||
|
||||
void print_verilog_testbench_shared_input_ports(
|
||||
std::fstream& fp, const ModuleManager& module_manager,
|
||||
const FabricGlobalPortInfo& global_ports,
|
||||
const PinConstraints& pin_constraints, const AtomContext& atom_ctx,
|
||||
const VprNetlistAnnotation& netlist_annotation,
|
||||
const std::vector<std::string>& clock_port_names,
|
||||
const bool& include_clock_ports, const std::string& shared_input_port_postfix,
|
||||
const bool& use_reg_port);
|
||||
|
||||
void print_verilog_testbench_shared_fpga_output_ports(
|
||||
std::fstream& fp, const AtomContext& atom_ctx,
|
||||
const VprNetlistAnnotation& netlist_annotation,
|
||||
const std::string& fpga_output_port_postfix);
|
||||
|
||||
void print_verilog_testbench_shared_benchmark_output_ports(
|
||||
std::fstream& fp, const AtomContext& atom_ctx,
|
||||
const VprNetlistAnnotation& netlist_annotation,
|
||||
const std::string& benchmark_output_port_postfix);
|
||||
|
||||
void print_verilog_testbench_shared_check_flags(
|
||||
std::fstream& fp, const AtomContext& atom_ctx,
|
||||
const VprNetlistAnnotation& netlist_annotation,
|
||||
const std::string& check_flag_port_postfix);
|
||||
|
||||
void print_verilog_testbench_shared_ports(
|
||||
std::fstream& fp, const ModuleManager& module_manager,
|
||||
const FabricGlobalPortInfo& global_ports,
|
||||
|
|
|
@ -1146,7 +1146,7 @@ static void print_verilog_top_testbench_benchmark_instance(
|
|||
std::string(TOP_TESTBENCH_REFERENCE_INSTANCE_NAME), std::string(),
|
||||
std::string(), std::string(TOP_TESTBENCH_SHARED_INPUT_POSTFIX),
|
||||
std::string(TOP_TESTBENCH_REFERENCE_OUTPUT_POSTFIX), clock_port_names,
|
||||
atom_ctx, netlist_annotation, pin_constraints, bus_group,
|
||||
false, atom_ctx, netlist_annotation, pin_constraints, bus_group,
|
||||
explicit_port_mapping);
|
||||
|
||||
print_verilog_comment(
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
# Run VPR for the 'and' design
|
||||
#--write_rr_graph example_rr_graph.xml
|
||||
vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling ideal
|
||||
|
||||
# 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 --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
|
||||
|
||||
# Apply fix-up to Look-Up Table truth tables based on packing results
|
||||
lut_truth_table_fixup
|
||||
|
||||
# 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
|
||||
|
||||
# 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
|
||||
repack ${OPENFPGA_REPACK_DESIGN_CONSTRAINTS} #--verbose
|
||||
|
||||
# Build the bitstream
|
||||
# - Output the fabric-independent bitstream to a file
|
||||
build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml
|
||||
|
||||
# Build fabric-dependent bitstream
|
||||
build_fabric_bitstream --verbose
|
||||
|
||||
# Write fabric-dependent bitstream
|
||||
write_fabric_bitstream --file fabric_bitstream.bit --format plain_text
|
||||
|
||||
# Write the Verilog netlist for FPGA fabric
|
||||
# - Enable the use of explicit port mapping in Verilog netlist
|
||||
write_mock_fpga_wrapper --file ./SRC ${OPENFPGA_MOCK_WRAPPER_OPTIONS} ${OPENFPGA_MOCK_WRAPPER_BGF} ${OPENFPGA_MOCK_WRAPPER_PCF}
|
||||
|
||||
# Write the Verilog testbench for FPGA fabric
|
||||
# - We suggest the use of same output directory as fabric Verilog netlists
|
||||
# - Must specify the reference benchmark file if you want to output any testbenches
|
||||
# - Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA
|
||||
# - Enable pre-configured top-level testbench which is a fast verification skipping programming phase
|
||||
# - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts
|
||||
write_preconfigured_fabric_wrapper --embed_bitstream none --file ./SRC --explicit_port_mapping ${OPENFPGA_MOCK_WRAPPER_BGF} ${OPENFPGA_MOCK_WRAPPER_PCF}
|
||||
write_preconfigured_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --explicit_port_mapping ${OPENFPGA_MOCK_WRAPPER_BGF} ${OPENFPGA_MOCK_WRAPPER_PCF}
|
||||
|
||||
# Write the SDC files for PnR backend
|
||||
# - Turn on every options here
|
||||
write_pnr_sdc --file ./SDC
|
||||
|
||||
# Write SDC to disable timing for configure ports
|
||||
write_sdc_disable_timing_configure_ports --file ./SDC/disable_configure_ports.sdc
|
||||
|
||||
# Write the SDC to run timing analysis for a mapped FPGA fabric
|
||||
write_analysis_sdc --file ./SDC_analysis
|
||||
|
||||
# Finish and exit OpenFPGA
|
||||
exit
|
||||
|
||||
# Note :
|
||||
# To run verification at the end of the flow maintain source in ./SRC directory
|
|
@ -115,6 +115,12 @@ run-task basic_tests/fabric_key/load_external_key_qlbanksr_multi_chain_fpga $@
|
|||
# TODO: This feature is temporarily out of test due to the emergency in delivering netlists for multi-chain shift-register memory bank
|
||||
#run-task basic_tests/fabric_key/load_external_key_multi_region_qlbanksr_fpga $@
|
||||
|
||||
echo -e "Testing mock wrapper"
|
||||
run-task basic_tests/mock_wrapper/mock_wrapper_explicit_port_mapping $@
|
||||
run-task basic_tests/mock_wrapper/mock_wrapper_implicit_port_mapping $@
|
||||
run-task basic_tests/mock_wrapper/mock_wrapper_pcf $@
|
||||
run-task basic_tests/mock_wrapper/mock_wrapper_bgf $@
|
||||
|
||||
echo -e "Testing K4 series FPGA";
|
||||
echo -e "Testing K4N4 with facturable LUTs";
|
||||
run-task basic_tests/k4_series/k4n4_frac_lut $@
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<bus_group>
|
||||
<bus name="result[7:0]" big_endian="false">
|
||||
<pin id="0" name="result_0_"/>
|
||||
<pin id="1" name="result_1_"/>
|
||||
<pin id="2" name="result_2_"/>
|
||||
<pin id="3" name="result_3_"/>
|
||||
<pin id="4" name="result_4_"/>
|
||||
<pin id="5" name="result_5_"/>
|
||||
<pin id="6" name="result_6_"/>
|
||||
<pin id="7" name="result_7_"/>
|
||||
</bus>
|
||||
</bus_group>
|
|
@ -0,0 +1,7 @@
|
|||
<pin_constraints>
|
||||
<!-- For a given .blif file, we want to assign
|
||||
- the reset signal to the op_reset[0] port of the FPGA fabric
|
||||
-->
|
||||
<set_io pin="op_reset[0]" net="reset"/>
|
||||
</pin_constraints>
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
||||
# 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
|
||||
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
|
||||
power_analysis = false
|
||||
spice_output=false
|
||||
verilog_output=true
|
||||
timeout_each_job = 20*60
|
||||
fpga_flow=yosys_vpr
|
||||
|
||||
[OpenFPGA_SHELL]
|
||||
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/mock_wrapper_example_script.openfpga
|
||||
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_dpram8K_dsp36_fracff_40nm_openfpga.xml
|
||||
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml
|
||||
openfpga_repack_design_constraints=
|
||||
openfpga_mock_wrapper_options=--explicit_port_mapping
|
||||
openfpga_mock_wrapper_bgf=
|
||||
openfpga_mock_wrapper_pcf=
|
||||
|
||||
[ARCHITECTURES]
|
||||
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm.xml
|
||||
|
||||
[BENCHMARKS]
|
||||
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counters/counter_8bit_async_reset/counter.v
|
||||
|
||||
[SYNTHESIS_PARAM]
|
||||
# Yosys script parameters
|
||||
bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm_cell_sim.v
|
||||
bench_yosys_dff_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm_dff_map.v
|
||||
bench_yosys_bram_map_rules_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_bram.txt
|
||||
bench_yosys_bram_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_bram_map.v
|
||||
bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_dsp_map.v
|
||||
bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=36 -D DSP_B_MAXWIDTH=36 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_36x36
|
||||
bench_read_verilog_options_common = -nolatches
|
||||
bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dff_flow.ys
|
||||
bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys
|
||||
|
||||
bench0_top = counter
|
||||
bench0_openfpga_mock_wrapper_pcf=-pcf ${PATH:TASK_DIR}/config/pin_constraints_reset.xml
|
||||
bench0_openfpga_mock_wrapper_bgf=-bgf ${PATH:TASK_DIR}/config/counter8_bus_group.xml
|
||||
|
||||
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
|
||||
end_flow_with_test=
|
||||
vpr_fpga_verilog_formal_verification_top_netlist=
|
|
@ -0,0 +1,45 @@
|
|||
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
||||
# 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
|
||||
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
|
||||
power_analysis = false
|
||||
spice_output=false
|
||||
verilog_output=true
|
||||
timeout_each_job = 20*60
|
||||
fpga_flow=yosys_vpr
|
||||
|
||||
[OpenFPGA_SHELL]
|
||||
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/mock_wrapper_example_script.openfpga
|
||||
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_cc_openfpga.xml
|
||||
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml
|
||||
openfpga_repack_design_constraints=
|
||||
openfpga_mock_wrapper_options=--explicit_port_mapping
|
||||
openfpga_mock_wrapper_bgf=
|
||||
openfpga_mock_wrapper_pcf=
|
||||
|
||||
[ARCHITECTURES]
|
||||
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml
|
||||
|
||||
[BENCHMARKS]
|
||||
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
|
||||
bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/or2/or2.v
|
||||
bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_latch/and2_latch.v
|
||||
|
||||
[SYNTHESIS_PARAM]
|
||||
bench_read_verilog_options_common = -nolatches
|
||||
bench0_top = and2
|
||||
|
||||
bench1_top = or2
|
||||
|
||||
bench2_top = and2_latch
|
||||
|
||||
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
|
||||
end_flow_with_test=
|
||||
vpr_fpga_verilog_formal_verification_top_netlist=
|
|
@ -0,0 +1,45 @@
|
|||
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
||||
# 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
|
||||
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
|
||||
power_analysis = false
|
||||
spice_output=false
|
||||
verilog_output=true
|
||||
timeout_each_job = 20*60
|
||||
fpga_flow=yosys_vpr
|
||||
|
||||
[OpenFPGA_SHELL]
|
||||
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/mock_wrapper_example_script.openfpga
|
||||
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_cc_openfpga.xml
|
||||
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml
|
||||
openfpga_repack_design_constraints=
|
||||
openfpga_mock_wrapper_options=
|
||||
openfpga_mock_wrapper_bgf=
|
||||
openfpga_mock_wrapper_pcf=
|
||||
|
||||
[ARCHITECTURES]
|
||||
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml
|
||||
|
||||
[BENCHMARKS]
|
||||
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
|
||||
bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/or2/or2.v
|
||||
bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_latch/and2_latch.v
|
||||
|
||||
[SYNTHESIS_PARAM]
|
||||
bench_read_verilog_options_common = -nolatches
|
||||
bench0_top = and2
|
||||
|
||||
bench1_top = or2
|
||||
|
||||
bench2_top = and2_latch
|
||||
|
||||
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
|
||||
end_flow_with_test=
|
||||
vpr_fpga_verilog_formal_verification_top_netlist=
|
|
@ -0,0 +1,11 @@
|
|||
<pin_constraints>
|
||||
<!-- For a given .blif file, we want to assign
|
||||
- the clk0 signal to the clk[0] port of the FPGA fabric
|
||||
- the clk1 signal to the clk[1] port of the FPGA fabric
|
||||
-->
|
||||
<set_io pin="clk[0]" net="clk0"/>
|
||||
<set_io pin="clk[1]" net="clk1"/>
|
||||
<set_io pin="clk[2]" net="OPEN"/>
|
||||
<set_io pin="clk[3]" net="OPEN"/>
|
||||
</pin_constraints>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<repack_design_constraints>
|
||||
<!-- For a given .blif file, we want to assign
|
||||
- the clk0 signal to the clk[0] port of all the clb tiles available in the FPGA fabric
|
||||
- the clk1 signal to the clk[1] port of all the clb tiles available in the FPGA fabric
|
||||
and ensure no signals could be mapped to
|
||||
- the clk[2] port of all the clb tiles available in the FPGA fabric
|
||||
- the clk[3] port of all the clb tiles available in the FPGA fabric
|
||||
-->
|
||||
<pin_constraint pb_type="clb" pin="clk[0]" net="clk0"/>
|
||||
<pin_constraint pb_type="clb" pin="clk[1]" net="clk1"/>
|
||||
<pin_constraint pb_type="clb" pin="clk[2]" net="OPEN"/>
|
||||
<pin_constraint pb_type="clb" pin="clk[3]" net="OPEN"/>
|
||||
</repack_design_constraints>
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
||||
# 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
|
||||
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
|
||||
power_analysis = false
|
||||
spice_output=false
|
||||
verilog_output=true
|
||||
timeout_each_job = 20*60
|
||||
fpga_flow=yosys_vpr
|
||||
|
||||
[OpenFPGA_SHELL]
|
||||
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/mock_wrapper_example_script.openfpga
|
||||
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTile4Clk_cc_openfpga.xml
|
||||
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_4clock_sim_openfpga.xml
|
||||
openfpga_repack_design_constraints=--design_constraints ${PATH:TASK_DIR}/config/repack_pin_constraints.xml
|
||||
openfpga_mock_wrapper_options=
|
||||
openfpga_mock_wrapper_bgf=
|
||||
openfpga_mock_wrapper_pcf=
|
||||
|
||||
[ARCHITECTURES]
|
||||
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_GlobalTile4Clk_40nm.xml
|
||||
|
||||
[BENCHMARKS]
|
||||
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_latch_2clock/and2_latch_2clock.v
|
||||
|
||||
[SYNTHESIS_PARAM]
|
||||
bench_read_verilog_options_common = -nolatches
|
||||
|
||||
bench0_top = and2_latch_2clock
|
||||
bench0_openfpga_pin_constraints=--design_constraints ${PATH:TASK_DIR}/config/and2_latch_pin_constraints.xml
|
||||
bench0_openfpga_mock_wrapper_pcf=-pcf ${PATH:TASK_DIR}/config/and2_latch_pin_constraints.xml
|
||||
bench0_openfpga_mock_wrapper_bgf=
|
||||
|
||||
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
|
||||
end_flow_with_test=
|
||||
vpr_fpga_verilog_formal_verification_top_netlist=
|
Loading…
Reference in New Issue