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

This commit is contained in:
ganeshgore 2020-04-23 12:18:24 -06:00
commit ca793285ca
71 changed files with 4744 additions and 189 deletions

View File

@ -51,6 +51,9 @@ echo -e "Testing OpenFPGA Shell";
echo -e "Testing configuration chain of a K4N4 FPGA"; echo -e "Testing configuration chain of a K4N4 FPGA";
python3 openfpga_flow/scripts/run_fpga_task.py openfpga_shell/configuration_chain --debug --show_thread_logs python3 openfpga_flow/scripts/run_fpga_task.py openfpga_shell/configuration_chain --debug --show_thread_logs
echo -e "Testing Verilog generation for a single mode LUT6 FPGA using micro benchmarks";
python3 openfpga_flow/scripts/run_fpga_task.py openfpga_shell/single_mode --debug --show_thread_logs
echo -e "Testing Verilog generation with simple fracturable LUT6 "; echo -e "Testing Verilog generation with simple fracturable LUT6 ";
python3 openfpga_flow/scripts/run_fpga_task.py openfpga_shell/frac_lut --debug --show_thread_logs python3 openfpga_flow/scripts/run_fpga_task.py openfpga_shell/frac_lut --debug --show_thread_logs
@ -99,4 +102,7 @@ python3 openfpga_flow/scripts/run_fpga_task.py openfpga_shell/flatten_routing --
echo -e "Testing Verilog generation with duplicated grid output pins"; echo -e "Testing Verilog generation with duplicated grid output pins";
python3 openfpga_flow/scripts/run_fpga_task.py openfpga_shell/duplicated_grid_pin --debug --show_thread_logs python3 openfpga_flow/scripts/run_fpga_task.py openfpga_shell/duplicated_grid_pin --debug --show_thread_logs
echo -e "Testing Verilog generation with spy output pads";
python3 openfpga_flow/scripts/run_fpga_task.py openfpga_shell/spypad --debug --show_thread_logs
end_section "OpenFPGA.TaskTun" end_section "OpenFPGA.TaskTun"

View File

@ -124,7 +124,9 @@ FPGA-Bitstream
.. option:: build_fabric_bitstream .. option:: build_fabric_bitstream
Reorganize the bitstream database for a specific FPGA fabric Build a sequence for every configuration bits in the bitstream database for a specific FPGA fabric
- ``--file`` or ``-f`` Output the fabric bitstream to an plain text file (only 0 or 1)
- ``--verbose`` Show verbose log - ``--verbose`` Show verbose log

View File

@ -777,7 +777,7 @@ std::vector<CircuitPortId> CircuitLibrary::model_ports_by_type(const CircuitMode
if ( type != port_type(port_id) ) { if ( type != port_type(port_id) ) {
continue; continue;
} }
/* We skip global ports if specified */ /* We skip global ports if specified. Note: I/O port should be kept */
if ( (true == ignore_global_port) if ( (true == ignore_global_port)
&& (true == port_is_global(port_id)) ) { && (true == port_is_global(port_id)) ) {
continue; continue;

View File

@ -36,9 +36,10 @@ void VprRoutingAnnotation::set_rr_node_net(const RRNodeId& rr_node,
/* Ensure that the node_id is in the list */ /* Ensure that the node_id is in the list */
VTR_ASSERT(size_t(rr_node) < rr_node_nets_.size()); VTR_ASSERT(size_t(rr_node) < rr_node_nets_.size());
/* Warn any override attempt */ /* Warn any override attempt */
if (ClusterNetId::INVALID() != rr_node_nets_[rr_node]) { if ( (ClusterNetId::INVALID() != rr_node_nets_[rr_node])
VTR_LOG_WARN("Override the net '%ld' for node '%ld' with in routing context annotation!\n", && (net_id != rr_node_nets_[rr_node])) {
size_t(net_id), size_t(rr_node)); VTR_LOG_WARN("Override the net '%ld' by net '%ld' for node '%ld' with in routing context annotation!\n",
size_t(rr_node_nets_[rr_node]), size_t(net_id), size_t(rr_node));
} }
rr_node_nets_[rr_node] = net_id; rr_node_nets_[rr_node] = net_id;

View File

@ -12,7 +12,8 @@
#include "openfpga_digest.h" #include "openfpga_digest.h"
#include "build_device_bitstream.h" #include "build_device_bitstream.h"
#include "bitstream_writer.h" #include "arch_bitstream_writer.h"
#include "fabric_bitstream_writer.h"
#include "build_fabric_bitstream.h" #include "build_fabric_bitstream.h"
#include "openfpga_bitstream.h" #include "openfpga_bitstream.h"
@ -56,10 +57,24 @@ int build_fabric_bitstream(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context) { const Command& cmd, const CommandContext& cmd_context) {
CommandOptionId opt_verbose = cmd.option("verbose"); CommandOptionId opt_verbose = cmd.option("verbose");
CommandOptionId opt_file = cmd.option("file");
/* Build fabric bitstream here */
openfpga_ctx.mutable_fabric_bitstream() = build_fabric_dependent_bitstream(openfpga_ctx.bitstream_manager(), openfpga_ctx.mutable_fabric_bitstream() = build_fabric_dependent_bitstream(openfpga_ctx.bitstream_manager(),
openfpga_ctx.module_graph(), openfpga_ctx.module_graph(),
cmd_context.option_enable(cmd, opt_verbose)); cmd_context.option_enable(cmd, opt_verbose));
/* Write fabric bitstream if required */
if (true == cmd_context.option_enable(cmd, opt_file)) {
std::string src_dir_path = find_path_dir_name(cmd_context.option_value(cmd, opt_file));
/* Create directories */
create_directory(src_dir_path);
write_fabric_bitstream_to_text_file(openfpga_ctx.bitstream_manager(),
openfpga_ctx.fabric_bitstream(),
cmd_context.option_value(cmd, opt_file));
}
/* TODO: should identify the error code from internal function execution */ /* TODO: should identify the error code from internal function execution */
return CMD_EXEC_SUCCESS; return CMD_EXEC_SUCCESS;

View File

@ -76,6 +76,11 @@ ShellCommandId add_openfpga_fabric_bitstream_command(openfpga::Shell<OpenfpgaCon
const std::vector<ShellCommandId>& dependent_cmds) { const std::vector<ShellCommandId>& dependent_cmds) {
Command shell_cmd("build_fabric_bitstream"); Command shell_cmd("build_fabric_bitstream");
/* Add an option '--file' in short '-f'*/
CommandOptionId opt_file = shell_cmd.add_option("file", false, "file path to output the fabric bitstream to plain text file");
shell_cmd.set_option_short_name(opt_file, "f");
shell_cmd.set_option_require_value(opt_file, openfpga::OPT_STRING);
/* Add an option '--verbose' */ /* Add an option '--verbose' */
shell_cmd.add_option("verbose", false, "Enable verbose output"); shell_cmd.add_option("verbose", false, "Enable verbose output");

View File

@ -1325,14 +1325,28 @@ bool is_core_grid_on_given_border_side(const vtr::Point<size_t>& device_size,
* The name convention is * The name convention is
* <pb_type_name>_<port_name> * <pb_type_name>_<port_name>
********************************************************************/ ********************************************************************/
std::string generate_pb_type_port_name(t_port* pb_type_port) { std::string generate_pb_type_port_name(t_pb_type* pb_type,
t_port* pb_type_port) {
std::string port_name; std::string port_name;
port_name = std::string(pb_type_port->parent_pb_type->name) + std::string("_") + std::string(pb_type_port->name); port_name = std::string(pb_type->name) + std::string("_") + std::string(pb_type_port->name);
return port_name; return port_name;
} }
/*********************************************************************
* Generate the port name of a Verilog module describing a pb_type
* The name convention is
* <pb_type_name>_<port_name>
*
* This is a wrapper on the generate_pb_type_port_name() function
* which can infer the parent_pb_type
********************************************************************/
std::string generate_pb_type_port_name(t_port* pb_type_port) {
return generate_pb_type_port_name(pb_type_port->parent_pb_type, pb_type_port);
}
/********************************************************************* /*********************************************************************
* Generate the global I/O port name of a Verilog module * Generate the global I/O port name of a Verilog module
* This is mainly used by I/O circuit models * This is mainly used by I/O circuit models

View File

@ -238,6 +238,9 @@ bool is_core_grid_on_given_border_side(const vtr::Point<size_t>& device_size,
const vtr::Point<size_t>& grid_coordinate, const vtr::Point<size_t>& grid_coordinate,
const e_side& border_side); const e_side& border_side);
std::string generate_pb_type_port_name(t_pb_type* pb_type,
t_port* pb_type_port);
std::string generate_pb_type_port_name(t_port* pb_type_port); std::string generate_pb_type_port_name(t_port* pb_type_port);
std::string generate_fpga_global_io_port_name(const std::string& prefix, std::string generate_fpga_global_io_port_name(const std::string& prefix,

View File

@ -37,7 +37,8 @@ int repack(OpenfpgaContext& openfpga_ctx,
g_vpr_ctx.atom(), g_vpr_ctx.atom(),
g_vpr_ctx.clustering(), g_vpr_ctx.clustering(),
openfpga_ctx.vpr_device_annotation(), openfpga_ctx.vpr_device_annotation(),
openfpga_ctx.arch().circuit_lib); openfpga_ctx.arch().circuit_lib,
cmd_context.option_enable(cmd, opt_verbose));
/* TODO: should identify the error code from internal function execution */ /* TODO: should identify the error code from internal function execution */
return CMD_EXEC_SUCCESS; return CMD_EXEC_SUCCESS;

View File

@ -163,16 +163,36 @@ void add_primitive_module_fpga_global_io_port(ModuleManager& module_manager,
BasicPort logic_io_port = module_manager.module_port(logic_module, logic_io_port_id); BasicPort logic_io_port = module_manager.module_port(logic_module, logic_io_port_id);
VTR_ASSERT(logic_io_port.get_width() == module_port.get_width()); VTR_ASSERT(logic_io_port.get_width() == module_port.get_width());
/* Wire the GPIO port form primitive_module to the logic module!*/ /* Wire the GPIO port from primitive_module to the logic module!*/
for (size_t pin_id = 0; pin_id < module_port.pins().size(); ++pin_id) { for (size_t pin_id = 0; pin_id < module_port.pins().size(); ++pin_id) {
ModuleNetId net = module_manager.create_module_net(primitive_module);
if ( (ModuleManager::MODULE_GPIO_PORT == module_io_port_type) if ( (ModuleManager::MODULE_GPIO_PORT == module_io_port_type)
|| (ModuleManager::MODULE_GPIN_PORT == module_io_port_type) ) { || (ModuleManager::MODULE_GPIN_PORT == module_io_port_type) ) {
module_manager.add_module_net_source(primitive_module, net, primitive_module, 0, primitive_io_port_id, module_port.pins()[pin_id]); bool net_exist = true;
/* If the source port has already a net to drive, we just update the net sinks */
ModuleNetId net = module_manager.module_instance_port_net(primitive_module, primitive_module, 0, primitive_io_port_id, module_port.pins()[pin_id]);
if (net == ModuleNetId::INVALID()) {
net_exist = false;
net = module_manager.create_module_net(primitive_module);
}
if (false == net_exist) {
module_manager.add_module_net_source(primitive_module, net, primitive_module, 0, primitive_io_port_id, module_port.pins()[pin_id]);
}
module_manager.add_module_net_sink(primitive_module, net, logic_module, logic_instance_id, logic_io_port_id, logic_io_port.pins()[pin_id]); module_manager.add_module_net_sink(primitive_module, net, logic_module, logic_instance_id, logic_io_port_id, logic_io_port.pins()[pin_id]);
} else { } else {
bool net_exist = true;
/* If the source port has already a net to drive, we just update the net sinks */
ModuleNetId net = module_manager.module_instance_port_net(primitive_module, logic_module, logic_instance_id, logic_io_port_id, logic_io_port.pins()[pin_id]);
if (net == ModuleNetId::INVALID()) {
net_exist = false;
net = module_manager.create_module_net(primitive_module);
}
VTR_ASSERT(ModuleManager::MODULE_GPOUT_PORT == module_io_port_type); VTR_ASSERT(ModuleManager::MODULE_GPOUT_PORT == module_io_port_type);
module_manager.add_module_net_source(primitive_module, net, logic_module, logic_instance_id, logic_io_port_id, logic_io_port.pins()[pin_id]);
if (false == net_exist) {
module_manager.add_module_net_source(primitive_module, net, logic_module, logic_instance_id, logic_io_port_id, logic_io_port.pins()[pin_id]);
}
module_manager.add_module_net_sink(primitive_module, net, primitive_module, 0, primitive_io_port_id, module_port.pins()[pin_id]); module_manager.add_module_net_sink(primitive_module, net, primitive_module, 0, primitive_io_port_id, module_port.pins()[pin_id]);
} }
} }

View File

@ -45,7 +45,7 @@ void build_lut_module(ModuleManager& module_manager,
/* Get the input ports from the mux */ /* Get the input ports from the mux */
std::vector<CircuitPortId> lut_input_ports = circuit_lib.model_ports_by_type(lut_model, CIRCUIT_MODEL_PORT_INPUT, true); std::vector<CircuitPortId> lut_input_ports = circuit_lib.model_ports_by_type(lut_model, CIRCUIT_MODEL_PORT_INPUT, true);
/* Get the output ports from the mux */ /* Get the output ports from the mux */
std::vector<CircuitPortId> lut_output_ports = circuit_lib.model_ports_by_type(lut_model, CIRCUIT_MODEL_PORT_OUTPUT, true); std::vector<CircuitPortId> lut_output_ports = circuit_lib.model_ports_by_type(lut_model, CIRCUIT_MODEL_PORT_OUTPUT, false);
/* Classify SRAM ports into two categories: regular (not for mode select) and mode-select */ /* Classify SRAM ports into two categories: regular (not for mode select) and mode-select */
std::vector<CircuitPortId> lut_regular_sram_ports = find_circuit_regular_sram_ports(circuit_lib, lut_model); std::vector<CircuitPortId> lut_regular_sram_ports = find_circuit_regular_sram_ports(circuit_lib, lut_model);

View File

@ -849,7 +849,7 @@ vtr::vector<MuxOutputId, ModuleNetId> build_mux_module_output_buffers(ModuleMana
vtr::vector<MuxOutputId, ModuleNetId> mux_output_nets(mux_graph.num_outputs(), ModuleNetId::INVALID()); vtr::vector<MuxOutputId, ModuleNetId> mux_output_nets(mux_graph.num_outputs(), ModuleNetId::INVALID());
/* Get the output ports from the mux */ /* Get the output ports from the mux */
std::vector<CircuitPortId> mux_output_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_OUTPUT, true); std::vector<CircuitPortId> mux_output_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_OUTPUT, false);
/* Iterate over all the outputs in the MUX module */ /* Iterate over all the outputs in the MUX module */
for (const auto& output_port : mux_output_ports) { for (const auto& output_port : mux_output_ports) {
@ -1098,7 +1098,7 @@ void build_cmos_mux_module(ModuleManager& module_manager,
/* Get the input ports from the mux */ /* Get the input ports from the mux */
std::vector<CircuitPortId> mux_input_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_INPUT, true); std::vector<CircuitPortId> mux_input_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_INPUT, true);
/* Get the output ports from the mux */ /* Get the output ports from the mux */
std::vector<CircuitPortId> mux_output_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_OUTPUT, true); std::vector<CircuitPortId> mux_output_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_OUTPUT, false);
/* Get the sram ports from the mux /* Get the sram ports from the mux
* Multiplexing structure does not mode_sram_ports, they are handled in LUT modules * Multiplexing structure does not mode_sram_ports, they are handled in LUT modules
* Here we just bypass it. * Here we just bypass it.

View File

@ -17,7 +17,7 @@
#include "openfpga_naming.h" #include "openfpga_naming.h"
#include "bitstream_manager_utils.h" #include "bitstream_manager_utils.h"
#include "bitstream_writer.h" #include "arch_bitstream_writer.h"
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {

View File

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

View File

@ -0,0 +1,61 @@
/********************************************************************
* This file includes functions that output a fabric-dependent
* bitstream database to files in different formats
*******************************************************************/
#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"
#include "openfpga_naming.h"
#include "bitstream_manager_utils.h"
#include "fabric_bitstream_writer.h"
/* begin namespace openfpga */
namespace openfpga {
/********************************************************************
* Write the fabric bitstream to a plain text file
* Notes:
* - This is the final bitstream which is loadable to the FPGA fabric
* (Verilog netlists etc.)
* - Do NOT include any comments or other characters that the 0|1 bitstream content
* in this file
*******************************************************************/
void write_fabric_bitstream_to_text_file(const BitstreamManager& bitstream_manager,
const std::vector<ConfigBitId>& fabric_bitstream,
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.size()) + std::string(" fabric bitstream into plain text 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);
/* Put down pure 0|1 bitstream here */
for (const ConfigBitId& fabric_bit : fabric_bitstream) {
fp << bitstream_manager.bit_value(fabric_bit);
}
/* Print an end to the file here */
fp << std::endl;
/* Close file handler */
fp.close();
}
} /* end namespace openfpga */

View File

@ -0,0 +1,24 @@
#ifndef FABRIC_BITSTREAM_WRITER_H
#define FABRIC_BITSTREAM_WRITER_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include <string>
#include <vector>
#include "bitstream_manager.h"
/********************************************************************
* Function declaration
*******************************************************************/
/* begin namespace openfpga */
namespace openfpga {
void write_fabric_bitstream_to_text_file(const BitstreamManager& bitstream_manager,
const std::vector<ConfigBitId>& fabric_bitstream,
const std::string& fname);
} /* end namespace openfpga */
#endif

View File

@ -281,6 +281,135 @@ void print_pnr_sdc_constrain_pb_graph_node_timing(const std::string& sdc_dir,
fp.close(); fp.close();
} }
/********************************************************************
* Print SDC timing constraints for a primitive pb_type
* This function will generate SDC to constrain pin-to-pin timing
* if it is defined in XML
*
* This is designed for LUT, adder or other hard IPs
* When PnR the modules, we want to minimize the interconnect delay
*******************************************************************/
static
void print_pnr_sdc_constrain_primitive_pb_graph_node(const std::string& sdc_dir,
const ModuleManager& module_manager,
t_pb_graph_node* primitive_pb_graph_node,
const bool& constrain_zero_delay_paths) {
/* Validate pb_graph node */
if (nullptr == primitive_pb_graph_node) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Invalid primitive_pb_graph_node.\n");
exit(1);
}
t_pb_graph_node* logical_primitive_pb_graph_node = primitive_pb_graph_node;
/* Get the pb_type where the timing annotations are stored
* Note that some primitive pb_type has child modes
* - Look-Up Table
* - Memory
* For those pb_type, timing annotations are stored in the child pb_type
*/
t_pb_type* primitive_pb_type = primitive_pb_graph_node->pb_type;
if (LUT_CLASS == primitive_pb_type->class_type) {
VTR_ASSERT(VPR_PB_TYPE_LUT_MODE < primitive_pb_type->num_modes);
VTR_ASSERT(1 == primitive_pb_type->modes[VPR_PB_TYPE_LUT_MODE].num_pb_type_children);
primitive_pb_type = &(primitive_pb_type->modes[VPR_PB_TYPE_LUT_MODE].pb_type_children[0]);
logical_primitive_pb_graph_node = primitive_pb_graph_node->child_pb_graph_nodes[VPR_PB_TYPE_LUT_MODE][0];
VTR_ASSERT(nullptr != logical_primitive_pb_graph_node);
} else if (MEMORY_CLASS == primitive_pb_type->class_type) {
VTR_ASSERT(1 == primitive_pb_type->num_modes);
VTR_ASSERT(1 == primitive_pb_type->modes[0].num_pb_type_children);
primitive_pb_type = &(primitive_pb_type->modes[0].pb_type_children[0]);
logical_primitive_pb_graph_node = primitive_pb_graph_node->child_pb_graph_nodes[0][0];
}
VTR_ASSERT(nullptr != primitive_pb_type);
VTR_ASSERT(nullptr != logical_primitive_pb_graph_node);
/* We can directly return if there is no timing annotation defined */
if (0 == primitive_pb_type->num_annotations) {
return;
}
/* Get the pb_type definition related to the node */
t_pb_type* physical_pb_type = primitive_pb_graph_node->pb_type;
std::string pb_module_name = generate_physical_block_module_name(physical_pb_type);
/* Find the pb module in module manager */
ModuleId pb_module = module_manager.find_module(pb_module_name);
VTR_ASSERT(true == module_manager.valid_module_id(pb_module));
/* Create the file name for SDC */
std::string sdc_fname(sdc_dir + pb_module_name + std::string(SDC_FILE_NAME_POSTFIX));
/* Create the file stream */
std::fstream fp;
fp.open(sdc_fname, std::fstream::out | std::fstream::trunc);
check_file_stream(sdc_fname.c_str(), fp);
/* Generate the descriptions*/
print_sdc_file_header(fp, std::string("Timing constraints for Grid " + pb_module_name + " in PnR"));
/* We traverse the pb_graph pins where we can find pin-to-pin timing annotation
* We walk through output pins here, build timing constraints by pair each output to input
* Clock pins are not walked through because they will be handled by clock tree synthesis
*/
for (int iport = 0; iport < logical_primitive_pb_graph_node->num_output_ports; ++iport) {
for (int ipin = 0; ipin < logical_primitive_pb_graph_node->num_output_pins[iport]; ++ipin) {
t_pb_graph_pin* sink_pin = &(logical_primitive_pb_graph_node->output_pins[iport][ipin]);
/* Port must exist in the module graph */
ModulePortId sink_module_port_id = module_manager.find_module_port(pb_module, generate_pb_type_port_name(physical_pb_type, sink_pin->port));
VTR_ASSERT(true == module_manager.valid_module_port_id(pb_module, sink_module_port_id));
BasicPort sink_port = module_manager.module_port(pb_module, sink_module_port_id);
/* Set the correct pin number of the port */
sink_port.set_width(sink_pin->pin_number, sink_pin->pin_number);
/* Find all the sink pin from this source pb_graph_pin */
for (int iedge = 0; iedge < sink_pin->num_input_edges; ++iedge) {
VTR_ASSERT(1 == sink_pin->input_edges[iedge]->num_input_pins);
t_pb_graph_pin* src_pin = sink_pin->input_edges[iedge]->input_pins[0];
/* Port must exist in the module graph */
ModulePortId src_module_port_id = module_manager.find_module_port(pb_module, generate_pb_type_port_name(physical_pb_type, src_pin->port));
VTR_ASSERT(true == module_manager.valid_module_port_id(pb_module, src_module_port_id));
BasicPort src_port = module_manager.module_port(pb_module, src_module_port_id);
/* Set the correct pin number of the port */
src_port.set_width(src_pin->pin_number, src_pin->pin_number);
/* Find max delay between src and sink pin */
float tmax = sink_pin->input_edges[iedge]->delay_max;
/* If the delay is zero, constrain only when user wants it */
if ( (true == constrain_zero_delay_paths)
|| (0. == tmax) ) {
print_pnr_sdc_constrain_max_delay(fp,
pb_module_name,
generate_sdc_port(src_port),
pb_module_name,
generate_sdc_port(sink_port),
tmax);
}
/* Find min delay between src and sink pin */
float tmin = sink_pin->input_edges[iedge]->delay_min;
/* If the delay is zero, constrain only when user wants it */
if ( (true == constrain_zero_delay_paths)
|| (0. == tmin) ) {
print_pnr_sdc_constrain_min_delay(fp,
pb_module_name,
generate_sdc_port(src_port),
pb_module_name,
generate_sdc_port(sink_port),
tmin);
}
}
}
}
/* Close file handler */
fp.close();
}
/******************************************************************** /********************************************************************
* Recursively print SDC timing constraints for a pb_type * Recursively print SDC timing constraints for a pb_type
* This function will generate a SDC file for each pb_type, * This function will generate a SDC file for each pb_type,
@ -302,8 +431,11 @@ void rec_print_pnr_sdc_constrain_pb_graph_timing(const std::string& sdc_dir,
/* Get the pb_type */ /* Get the pb_type */
t_pb_type* parent_pb_type = parent_pb_graph_node->pb_type; t_pb_type* parent_pb_type = parent_pb_graph_node->pb_type;
/* No need to constrain the primitive node */ /* Constrain the primitive node if a timing matrix is defined */
if (true == is_primitive_pb_type(parent_pb_type)) { if (true == is_primitive_pb_type(parent_pb_type)) {
print_pnr_sdc_constrain_primitive_pb_graph_node(sdc_dir, module_manager,
parent_pb_graph_node,
constrain_zero_delay_paths);
return; return;
} }

View File

@ -334,6 +334,52 @@ void print_pnr_sdc_constrain_cb_timing(const std::string& sdc_dir,
/* Generate the descriptions*/ /* Generate the descriptions*/
print_sdc_file_header(fp, std::string("Constrain timing of Connection Block " + cb_module_name + " for PnR")); print_sdc_file_header(fp, std::string("Constrain timing of Connection Block " + cb_module_name + " for PnR"));
/* Contrain each routing track inside the connection block */
for (size_t itrack = 0; itrack < rr_gsb.get_cb_chan_width(cb_type); ++itrack) {
/* Create a port description for the input */
std::string input_port_name = generate_cb_module_track_port_name(cb_type,
itrack,
IN_PORT);
ModulePortId input_port_id = module_manager.find_module_port(cb_module, input_port_name);
BasicPort input_port = module_manager.module_port(cb_module, input_port_id);
/* Create a port description for the output */
std::string output_port_name = generate_cb_module_track_port_name(cb_type,
itrack,
OUT_PORT);
ModulePortId output_port_id = module_manager.find_module_port(cb_module, output_port_name);
BasicPort output_port = module_manager.module_port(cb_module, output_port_id);
/* Ensure port size matching */
VTR_ASSERT(1 == input_port.get_width());
VTR_ASSERT(input_port.get_width() == output_port.get_width());
/* Connection block routing segment ids for each track */
RRSegmentId segment_id = rr_gsb.get_chan_node_segment(rr_gsb.get_cb_chan_side(cb_type), itrack);
/* Computing the delay of the routing segment
* Here we just assume a simple 1-level RC delay model
* TODO: Should consider multi-level RC delay models
* where the number of levels are defined by users
*/
float routing_segment_delay = rr_graph.get_segment(segment_id).Rmetal
* rr_graph.get_segment(segment_id).Cmetal;
/* If we have a zero-delay path to contrain, we will skip unless users want so */
if ( (false == constrain_zero_delay_paths)
&& (0. == routing_segment_delay) ) {
continue;
}
/* Constrain a path with routing segment delay */
print_pnr_sdc_constrain_port2port_timing(fp,
module_manager,
cb_module, input_port_id,
cb_module, output_port_id,
routing_segment_delay);
}
/* Contrain each multiplexers inside the connection block */
std::vector<enum e_side> cb_sides = rr_gsb.get_cb_ipin_sides(cb_type); std::vector<enum e_side> cb_sides = rr_gsb.get_cb_ipin_sides(cb_type);
for (size_t side = 0; side < cb_sides.size(); ++side) { for (size_t side = 0; side < cb_sides.size(); ++side) {

View File

@ -87,6 +87,38 @@ void print_pnr_sdc_constrain_max_delay(std::fstream& fp,
fp << std::endl; fp << std::endl;
} }
/********************************************************************
* Constrain a path between two ports of a module with a given minimum timing value
*******************************************************************/
void print_pnr_sdc_constrain_min_delay(std::fstream& fp,
const std::string& src_instance_name,
const std::string& src_port_name,
const std::string& des_instance_name,
const std::string& des_port_name,
const float& delay) {
/* Validate file stream */
valid_file_stream(fp);
fp << "set_min_delay";
fp << " -from ";
if (!src_instance_name.empty()) {
fp << src_instance_name << "/";
}
fp << src_port_name;
fp << " -to ";
if (!des_instance_name.empty()) {
fp << des_instance_name << "/";
}
fp << des_port_name;
fp << " " << std::setprecision(10) << delay;
fp << std::endl;
}
/******************************************************************** /********************************************************************
* Constrain a path between two ports of a module with a given timing value * Constrain a path between two ports of a module with a given timing value
* Note: this function uses set_max_delay !!! * Note: this function uses set_max_delay !!!

View File

@ -28,6 +28,13 @@ void print_pnr_sdc_constrain_max_delay(std::fstream& fp,
const std::string& des_port_name, const std::string& des_port_name,
const float& delay); const float& delay);
void print_pnr_sdc_constrain_min_delay(std::fstream& fp,
const std::string& src_instance_name,
const std::string& src_port_name,
const std::string& des_instance_name,
const std::string& des_port_name,
const float& delay);
void print_pnr_sdc_constrain_module_port2port_timing(std::fstream& fp, void print_pnr_sdc_constrain_module_port2port_timing(std::fstream& fp,
const ModuleManager& module_manager, const ModuleManager& module_manager,
const ModuleId& input_parent_module_id, const ModuleId& input_parent_module_id,

View File

@ -12,6 +12,9 @@
#include "vtr_assert.h" #include "vtr_assert.h"
#include "vtr_time.h" #include "vtr_time.h"
/* Headers from openfpgautil library */
#include "openfpga_digest.h"
#include "simulation_utils.h" #include "simulation_utils.h"
#include "verilog_constants.h" #include "verilog_constants.h"
@ -34,6 +37,11 @@ void print_verilog_simulation_info(const std::string& ini_fname,
std::string timer_message = std::string("Write exchangeable file containing simulation information '") + ini_fname + std::string("'"); std::string timer_message = std::string("Write exchangeable file containing simulation information '") + ini_fname + std::string("'");
std::string ini_dir_path = format_dir_path(find_path_dir_name(ini_fname));
/* Create directories */
create_directory(ini_dir_path);
/* Start time count */ /* Start time count */
vtr::ScopedStartFinishTimer timer(timer_message); vtr::ScopedStartFinishTimer timer(timer_message);

View File

@ -1001,7 +1001,7 @@ void MuxGraph::build_onelevel_mux_graph(const size_t& mux_size,
void MuxGraph::add_fracturable_outputs(const CircuitLibrary& circuit_lib, void MuxGraph::add_fracturable_outputs(const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model) { const CircuitModelId& circuit_model) {
/* Iterate over output ports */ /* Iterate over output ports */
for (const auto& port : circuit_lib.model_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_OUTPUT, true)) { for (const auto& port : circuit_lib.model_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_OUTPUT, false)) {
/* Get the fracturable_level */ /* Get the fracturable_level */
size_t frac_level = circuit_lib.port_lut_frac_level(port); size_t frac_level = circuit_lib.port_lut_frac_level(port);
/* Bypass invalid frac_level */ /* Bypass invalid frac_level */

View File

@ -11,15 +11,13 @@
#include "openfpga_naming.h" #include "openfpga_naming.h"
#include "lut_utils.h" #include "lut_utils.h"
#include "pb_type_utils.h"
#include "physical_pb.h" #include "physical_pb.h"
#include "build_physical_truth_table.h" #include "build_physical_truth_table.h"
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
/* Mode 1 is the lut mode while mode 0 is the wire mode */
constexpr int VPR_PB_TYPE_LUT_MODE = 1;
/*************************************************************************************** /***************************************************************************************
* Identify if LUT is used as wiring * Identify if LUT is used as wiring
* In this case, LUT functions as a buffer * In this case, LUT functions as a buffer
@ -102,7 +100,8 @@ void build_physical_pb_lut_truth_tables(PhysicalPb& physical_pb,
const PhysicalPbId& lut_pb_id, const PhysicalPbId& lut_pb_id,
const AtomContext& atom_ctx, const AtomContext& atom_ctx,
const VprDeviceAnnotation& device_annotation, const VprDeviceAnnotation& device_annotation,
const CircuitLibrary& circuit_lib) { const CircuitLibrary& circuit_lib,
const bool& verbose) {
const t_pb_graph_node* pb_graph_node = physical_pb.pb_graph_node(lut_pb_id); const t_pb_graph_node* pb_graph_node = physical_pb.pb_graph_node(lut_pb_id);
CircuitModelId lut_model = device_annotation.pb_type_circuit_model(physical_pb.pb_graph_node(lut_pb_id)->pb_type); CircuitModelId lut_model = device_annotation.pb_type_circuit_model(physical_pb.pb_graph_node(lut_pb_id)->pb_type);
@ -125,20 +124,21 @@ void build_physical_pb_lut_truth_tables(PhysicalPb& physical_pb,
continue; continue;
} }
/* Check if this is a LUT used as wiring */ /* Check if this is a LUT used as wiring */
if (true == is_wired_lut(input_nets, output_net)) { AtomNetlist::TruthTable adapt_tt;
AtomNetlist::TruthTable wire_tt = build_wired_lut_truth_table(input_nets.size(), std::find(input_nets.begin(), input_nets.end(), output_net) - input_nets.begin()); if (true == physical_pb.is_wire_lut_output(lut_pb_id, output_pin)) {
physical_pb.set_truth_table(lut_pb_id, output_pin, wire_tt); /* Double check: ensure that the output nets appear in the input net !!! */
continue; VTR_ASSERT(true == is_wired_lut(input_nets, output_net));
adapt_tt = build_wired_lut_truth_table(input_nets.size(), std::find(input_nets.begin(), input_nets.end(), output_net) - input_nets.begin());
} else {
/* Find the truth table from atom block which drives the atom net */
const AtomBlockId& atom_blk = atom_ctx.nlist.net_driver_block(output_net);
VTR_ASSERT(true == atom_ctx.nlist.valid_block_id(atom_blk));
const AtomNetlist::TruthTable& orig_tt = atom_ctx.nlist.block_truth_table(atom_blk);
std::vector<int> rotated_pin_map = generate_lut_rotated_input_pin_map(input_nets, atom_ctx, atom_blk, pb_graph_node);
adapt_tt = lut_truth_table_adaption(orig_tt, rotated_pin_map);
} }
/* Find the truth table from atom block which drives the atom net */
const AtomBlockId& atom_blk = atom_ctx.nlist.net_driver_block(output_net);
VTR_ASSERT(true == atom_ctx.nlist.valid_block_id(atom_blk));
const AtomNetlist::TruthTable& orig_tt = atom_ctx.nlist.block_truth_table(atom_blk);
std::vector<int> rotated_pin_map = generate_lut_rotated_input_pin_map(input_nets, atom_ctx, atom_blk, pb_graph_node);
const AtomNetlist::TruthTable& adapt_tt = lut_truth_table_adaption(orig_tt, rotated_pin_map);
/* Adapt the truth table for fracturable lut implementation and add to physical pb */ /* Adapt the truth table for fracturable lut implementation and add to physical pb */
CircuitPortId lut_model_output_port = device_annotation.pb_circuit_port(output_pin->port); CircuitPortId lut_model_output_port = device_annotation.pb_circuit_port(output_pin->port);
size_t lut_frac_level = circuit_lib.port_lut_frac_level(lut_model_output_port); size_t lut_frac_level = circuit_lib.port_lut_frac_level(lut_model_output_port);
@ -148,6 +148,29 @@ void build_physical_pb_lut_truth_tables(PhysicalPb& physical_pb,
size_t lut_output_mask = circuit_lib.port_lut_output_mask(lut_model_output_port)[output_pin->pin_number]; size_t lut_output_mask = circuit_lib.port_lut_output_mask(lut_model_output_port)[output_pin->pin_number];
const AtomNetlist::TruthTable& frac_lut_tt = adapt_truth_table_for_frac_lut(lut_frac_level, lut_output_mask, adapt_tt); const AtomNetlist::TruthTable& frac_lut_tt = adapt_truth_table_for_frac_lut(lut_frac_level, lut_output_mask, adapt_tt);
physical_pb.set_truth_table(lut_pb_id, output_pin, frac_lut_tt); physical_pb.set_truth_table(lut_pb_id, output_pin, frac_lut_tt);
/* Print debug information */
VTR_LOGV(verbose, "Input nets: ");
for (const AtomNetId& net : input_nets) {
if (AtomNetId::INVALID() == net) {
VTR_LOGV(verbose, "unconn ");
} else {
VTR_ASSERT(AtomNetId::INVALID() != net);
VTR_LOGV(verbose, "%s ", atom_ctx.nlist.net_name(net).c_str());
}
}
VTR_LOGV(verbose, "\n");
VTR_ASSERT(AtomNetId::INVALID() != output_net);
VTR_LOGV(verbose, "Output net: %s\n", atom_ctx.nlist.net_name(output_net).c_str());
VTR_LOGV(verbose,
"Add following truth table to pb_graph_pin '%s[%d]'\n",
output_pin->port->name, output_pin->pin_number);
for (const std::string& tt_line : truth_table_to_string(frac_lut_tt)) {
VTR_LOGV(verbose, "\t%s\n", tt_line.c_str());
}
VTR_LOGV(verbose, "\n");
} }
} }
} }
@ -164,7 +187,8 @@ void build_physical_lut_truth_tables(VprClusteringAnnotation& cluster_annotation
const AtomContext& atom_ctx, const AtomContext& atom_ctx,
const ClusteringContext& cluster_ctx, const ClusteringContext& cluster_ctx,
const VprDeviceAnnotation& device_annotation, const VprDeviceAnnotation& device_annotation,
const CircuitLibrary& circuit_lib) { const CircuitLibrary& circuit_lib,
const bool& verbose) {
vtr::ScopedStartFinishTimer timer("Build truth tables for physical LUTs"); vtr::ScopedStartFinishTimer timer("Build truth tables for physical LUTs");
for (auto blk_id : cluster_ctx.clb_nlist.blocks()) { for (auto blk_id : cluster_ctx.clb_nlist.blocks()) {
@ -178,7 +202,7 @@ void build_physical_lut_truth_tables(VprClusteringAnnotation& cluster_annotation
} }
/* Reach here, we have a LUT to deal with. Find the truth tables that mapped to the LUT */ /* Reach here, we have a LUT to deal with. Find the truth tables that mapped to the LUT */
build_physical_pb_lut_truth_tables(physical_pb, primitive_pb, atom_ctx, device_annotation, circuit_lib); build_physical_pb_lut_truth_tables(physical_pb, primitive_pb, atom_ctx, device_annotation, circuit_lib, verbose);
} }
} }
} }

View File

@ -20,7 +20,8 @@ void build_physical_lut_truth_tables(VprClusteringAnnotation& cluster_annotation
const AtomContext& atom_ctx, const AtomContext& atom_ctx,
const ClusteringContext& cluster_ctx, const ClusteringContext& cluster_ctx,
const VprDeviceAnnotation& device_annotation, const VprDeviceAnnotation& device_annotation,
const CircuitLibrary& circuit_lib); const CircuitLibrary& circuit_lib,
const bool& verbose);
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -86,6 +86,16 @@ void save_lb_router_results_to_physical_pb(PhysicalPb& phy_pb,
VTR_ASSERT(true == phy_pb.valid_pb_id(pb_id)); VTR_ASSERT(true == phy_pb.valid_pb_id(pb_id));
const AtomNetId& atom_net = lb_router.net_atom_net_id(net); const AtomNetId& atom_net = lb_router.net_atom_net_id(net);
/* Print info to help debug
bool verbose = true;
VTR_LOGV(verbose,
"\nSave net '%lu' to physical pb_graph_pin '%s.%s[%d]'\n",
size_t(atom_net),
pb_graph_pin->parent_node->pb_type->name,
pb_graph_pin->port->name,
pb_graph_pin->pin_number);
*/
if (AtomNetId::INVALID() == phy_pb.pb_graph_pin_atom_net(pb_id, pb_graph_pin)) { if (AtomNetId::INVALID() == phy_pb.pb_graph_pin_atom_net(pb_id, pb_graph_pin)) {
phy_pb.set_pb_graph_pin_atom_net(pb_id, pb_graph_pin, atom_net); phy_pb.set_pb_graph_pin_atom_net(pb_id, pb_graph_pin, atom_net);

View File

@ -81,6 +81,17 @@ AtomNetId PhysicalPb::pb_graph_pin_atom_net(const PhysicalPbId& pb,
return AtomNetId::INVALID(); return AtomNetId::INVALID();
} }
bool PhysicalPb::is_wire_lut_output(const PhysicalPbId& pb,
const t_pb_graph_pin* pb_graph_pin) const {
VTR_ASSERT(true == valid_pb_id(pb));
if (wire_lut_outputs_[pb].find(pb_graph_pin) != wire_lut_outputs_[pb].end()) {
/* Find it, return the status */
return wire_lut_outputs_[pb].at(pb_graph_pin);
}
/* Not found, return false */
return false;
}
std::map<const t_pb_graph_pin*, AtomNetlist::TruthTable> PhysicalPb::truth_tables(const PhysicalPbId& pb) const { std::map<const t_pb_graph_pin*, AtomNetlist::TruthTable> PhysicalPb::truth_tables(const PhysicalPbId& pb) const {
VTR_ASSERT(true == valid_pb_id(pb)); VTR_ASSERT(true == valid_pb_id(pb));
return truth_tables_[pb]; return truth_tables_[pb];
@ -110,6 +121,7 @@ PhysicalPbId PhysicalPb::create_pb(const t_pb_graph_node* pb_graph_node) {
pb_graph_nodes_.push_back(pb_graph_node); pb_graph_nodes_.push_back(pb_graph_node);
atom_blocks_.emplace_back(); atom_blocks_.emplace_back();
pin_atom_nets_.emplace_back(); pin_atom_nets_.emplace_back();
wire_lut_outputs_.emplace_back();
child_pbs_.emplace_back(); child_pbs_.emplace_back();
parent_pbs_.emplace_back(); parent_pbs_.emplace_back();
@ -182,6 +194,18 @@ void PhysicalPb::set_pb_graph_pin_atom_net(const PhysicalPbId& pb,
pin_atom_nets_[pb][pb_graph_pin] = atom_net; pin_atom_nets_[pb][pb_graph_pin] = atom_net;
} }
void PhysicalPb::set_wire_lut_output(const PhysicalPbId& pb,
const t_pb_graph_pin* pb_graph_pin,
const bool& wire_lut_output) {
VTR_ASSERT(true == valid_pb_id(pb));
if (wire_lut_outputs_[pb].end() != wire_lut_outputs_[pb].find(pb_graph_pin)) {
VTR_LOG_WARN("Overwrite pb_graph_pin '%s[%d]' status on wire LUT output\n",
pb_graph_pin->port->name, pb_graph_pin->pin_number);
}
wire_lut_outputs_[pb][pb_graph_pin] = wire_lut_output;
}
/****************************************************************************** /******************************************************************************
* Private validators/invalidators * Private validators/invalidators
******************************************************************************/ ******************************************************************************/

View File

@ -50,6 +50,8 @@ class PhysicalPb {
std::vector<AtomBlockId> atom_blocks(const PhysicalPbId& pb) const; std::vector<AtomBlockId> atom_blocks(const PhysicalPbId& pb) const;
AtomNetId pb_graph_pin_atom_net(const PhysicalPbId& pb, AtomNetId pb_graph_pin_atom_net(const PhysicalPbId& pb,
const t_pb_graph_pin* pb_graph_pin) const; const t_pb_graph_pin* pb_graph_pin) const;
bool is_wire_lut_output(const PhysicalPbId& pb,
const t_pb_graph_pin* pb_graph_pin) const;
std::map<const t_pb_graph_pin*, AtomNetlist::TruthTable> truth_tables(const PhysicalPbId& pb) const; std::map<const t_pb_graph_pin*, AtomNetlist::TruthTable> truth_tables(const PhysicalPbId& pb) const;
std::vector<size_t> mode_bits(const PhysicalPbId& pb) const; std::vector<size_t> mode_bits(const PhysicalPbId& pb) const;
public: /* Public mutators */ public: /* Public mutators */
@ -67,6 +69,9 @@ class PhysicalPb {
void set_pb_graph_pin_atom_net(const PhysicalPbId& pb, void set_pb_graph_pin_atom_net(const PhysicalPbId& pb,
const t_pb_graph_pin* pb_graph_pin, const t_pb_graph_pin* pb_graph_pin,
const AtomNetId& atom_net); const AtomNetId& atom_net);
void set_wire_lut_output(const PhysicalPbId& pb,
const t_pb_graph_pin* pb_graph_pin,
const bool& wire_lut_output);
public: /* Public validators/invalidators */ public: /* Public validators/invalidators */
bool valid_pb_id(const PhysicalPbId& pb_id) const; bool valid_pb_id(const PhysicalPbId& pb_id) const;
bool empty() const; bool empty() const;
@ -76,6 +81,7 @@ class PhysicalPb {
vtr::vector<PhysicalPbId, std::string> names_; vtr::vector<PhysicalPbId, std::string> names_;
vtr::vector<PhysicalPbId, std::vector<AtomBlockId>> atom_blocks_; vtr::vector<PhysicalPbId, std::vector<AtomBlockId>> atom_blocks_;
vtr::vector<PhysicalPbId, std::map<const t_pb_graph_pin*, AtomNetId>> pin_atom_nets_; vtr::vector<PhysicalPbId, std::map<const t_pb_graph_pin*, AtomNetId>> pin_atom_nets_;
vtr::vector<PhysicalPbId, std::map<const t_pb_graph_pin*, bool>> wire_lut_outputs_;
/* Child pbs are organized as [0..num_child_pb_types-1][0..child_pb_type->num_pb-1] */ /* Child pbs are organized as [0..num_child_pb_types-1][0..child_pb_type->num_pb-1] */
vtr::vector<PhysicalPbId, std::map<const t_pb_type*, std::vector<PhysicalPbId>>> child_pbs_; vtr::vector<PhysicalPbId, std::map<const t_pb_type*, std::vector<PhysicalPbId>>> child_pbs_;

View File

@ -117,15 +117,21 @@ int find_pb_route_remapped_source_pb_pin(const t_pb* pb,
for (int pin = 0; pin < pb->pb_graph_node->total_pb_pins; ++pin) { for (int pin = 0; pin < pb->pb_graph_node->total_pb_pins; ++pin) {
/* Bypass unused pins */ /* Bypass unused pins */
if ((0 == pb->pb_route.count(pin)) || (AtomNetId::INVALID() == pb->pb_route[pin].atom_net_id)) { if ((0 == pb->pb_route.count(pin)) || (AtomNetId::INVALID() == pb->pb_route.at(pin).atom_net_id)) {
continue; continue;
} }
/* Get the driver pb pin id, it must be valid */ /* Get the driver pb pin id, it must be valid */
if (atom_net_id != pb->pb_route[pin].atom_net_id) { if (atom_net_id != pb->pb_route.at(pin).atom_net_id) {
continue; continue;
} }
/* Only care the pin that shares the same parent_node as source_pb_pin */ /* Only care the pin has the same parent port as source_pb_pin
if (source_pb_pin->parent_node == pb->pb_route[pin].pb_graph_pin->parent_node) { * Due to that the source_pb_pin may be swapped during routing
* the pb_route is out-of-date
* TODO: should update pb_route by post routing results
* On the other side, the swapping can only happen between equivalent pins
* in a port. So the port must match here!
*/
if (source_pb_pin->port == pb->pb_route.at(pin).pb_graph_pin->port) {
pb_route_indices.push_back(pin); pb_route_indices.push_back(pin);
} }
} }
@ -272,17 +278,20 @@ void add_lb_router_nets(LbRouter& lb_router,
VTR_ASSERT(sink_lb_rr_nodes.size() == sink_pb_graph_pins.size()); VTR_ASSERT(sink_lb_rr_nodes.size() == sink_pb_graph_pins.size());
/* Printf for debugging only, may be enabled if verbose is enabled /* Printf for debugging only, may be enabled if verbose is enabled
VTR_LOG("Pb route for Net %s:\n",
atom_ctx.nlist.net_name(atom_net_id).c_str());
VTR_LOG("Source node:\n\t%s -> %s\n",
source_pb_pin->to_string().c_str(),
source_pb_pin->to_string().c_str());
VTR_LOG("Sink nodes:\n");
for (t_pb_graph_pin* sink_pb_pin : sink_pb_graph_pins) {
VTR_LOG("\t%s\n",
sink_pb_pin->to_string().c_str());
}
*/ */
VTR_LOGV(verbose,
"Pb route for Net %s:\n",
atom_ctx.nlist.net_name(atom_net_id).c_str());
VTR_LOGV(verbose,
"Source node:\n\t%s -> %s\n",
source_pb_pin->to_string().c_str(),
source_pb_pin->to_string().c_str());
VTR_LOGV(verbose, "Sink nodes:\n");
for (t_pb_graph_pin* sink_pb_pin : sink_pb_graph_pins) {
VTR_LOGV(verbose,
"\t%s\n",
sink_pb_pin->to_string().c_str());
}
/* Add the net */ /* Add the net */
add_lb_router_net_to_route(lb_router, lb_rr_graph, add_lb_router_net_to_route(lb_router, lb_rr_graph,
@ -335,17 +344,20 @@ void add_lb_router_nets(LbRouter& lb_router,
VTR_ASSERT(sink_lb_rr_nodes.size() == sink_pb_graph_pins.size()); VTR_ASSERT(sink_lb_rr_nodes.size() == sink_pb_graph_pins.size());
/* Printf for debugging only, may be enabled if verbose is enabled /* Printf for debugging only, may be enabled if verbose is enabled
VTR_LOG("Pb route for Net %s:\n",
atom_ctx.nlist.net_name(atom_net_id).c_str());
VTR_LOG("Source node:\n\t%s -> %s\n",
source_pb_pin->to_string().c_str(),
physical_source_pb_pin->to_string().c_str());
VTR_LOG("Sink nodes:\n");
for (t_pb_graph_pin* sink_pb_pin : sink_pb_graph_pins) {
VTR_LOG("\t%s\n",
sink_pb_pin->to_string().c_str());
}
*/ */
VTR_LOGV(verbose,
"Pb route for Net %s:\n",
atom_ctx.nlist.net_name(atom_net_id).c_str());
VTR_LOGV(verbose,
"Source node:\n\t%s -> %s\n",
source_pb_pin->to_string().c_str(),
physical_source_pb_pin->to_string().c_str());
VTR_LOGV(verbose, "Sink nodes:\n");
for (t_pb_graph_pin* sink_pb_pin : sink_pb_graph_pins) {
VTR_LOGV(verbose,
"\t%s\n",
sink_pb_pin->to_string().c_str());
}
/* Add the net */ /* Add the net */
add_lb_router_net_to_route(lb_router, lb_rr_graph, add_lb_router_net_to_route(lb_router, lb_rr_graph,
@ -423,7 +435,8 @@ void repack_cluster(const AtomContext& atom_ctx,
clustering_ctx.clb_nlist.block_pb(block_id), clustering_ctx.clb_nlist.block_pb(block_id),
clustering_ctx.clb_nlist.block_pb(block_id)->pb_route, clustering_ctx.clb_nlist.block_pb(block_id)->pb_route,
atom_ctx, atom_ctx,
device_annotation); device_annotation,
verbose);
/* Save routing results */ /* Save routing results */
save_lb_router_results_to_physical_pb(phy_pb, lb_router, lb_rr_graph); save_lb_router_results_to_physical_pb(phy_pb, lb_router, lb_rr_graph);
VTR_LOGV(verbose, "Saved results in physical pb\n"); VTR_LOGV(verbose, "Saved results in physical pb\n");

View File

@ -473,6 +473,29 @@ std::vector<bool> build_frac_lut_bitstream(const CircuitLibrary& circuit_lib,
VTR_ASSERT(bitstream_offset < lut_bitstream.size()); VTR_ASSERT(bitstream_offset < lut_bitstream.size());
VTR_ASSERT(bitstream_offset + length_of_temp_bitstream_to_copy <= lut_bitstream.size()); VTR_ASSERT(bitstream_offset + length_of_temp_bitstream_to_copy <= lut_bitstream.size());
/* Print debug information
bool verbose = true;
VTR_LOGV(verbose, "Full truth table\n");
for (const std::string& tt_line : truth_table_to_string(element.second)) {
VTR_LOGV(verbose, "\t%s\n", tt_line.c_str());
}
VTR_LOGV(verbose, "\n");
VTR_LOGV(verbose, "Bitstream (size = %ld)\n", temp_bitstream.size());
for (const bool& bit : temp_bitstream) {
if (true == bit) {
VTR_LOGV(verbose, "1");
} else {
VTR_ASSERT(false == bit);
VTR_LOGV(verbose, "0");
}
}
VTR_LOGV(verbose, "\n");
VTR_LOGV(verbose, "Bitstream offset = %d\n", bitstream_offset);
VTR_LOGV(verbose, "Bitstream length to be used = %d\n", length_of_temp_bitstream_to_copy);
*/
/* Copy to the segment of bitstream */ /* Copy to the segment of bitstream */
for (size_t bit = bitstream_offset; bit < bitstream_offset + length_of_temp_bitstream_to_copy; ++bit) { for (size_t bit = bitstream_offset; bit < bitstream_offset + length_of_temp_bitstream_to_copy; ++bit) {
lut_bitstream[bit] = temp_bitstream[bit]; lut_bitstream[bit] = temp_bitstream[bit];

View File

@ -17,6 +17,15 @@
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
/* Constants */
/* Mode index of a LUT pb_type
* Mode 0 is the wire mode
* Mode 1 is the lut mode
*/
constexpr int VPR_PB_TYPE_WIRE_MODE = 0;
constexpr int VPR_PB_TYPE_LUT_MODE = 1;
bool is_primitive_pb_type(t_pb_type* pb_type); bool is_primitive_pb_type(t_pb_type* pb_type);
bool is_root_pb_type(t_pb_type* pb_type); bool is_root_pb_type(t_pb_type* pb_type);

View File

@ -132,6 +132,16 @@ void update_primitive_physical_pb_pin_atom_net(PhysicalPb& phy_pb,
t_pb_graph_pin* physical_pb_graph_pin = device_annotation.physical_pb_graph_pin(pb_graph_pin); t_pb_graph_pin* physical_pb_graph_pin = device_annotation.physical_pb_graph_pin(pb_graph_pin);
VTR_ASSERT(nullptr != physical_pb_graph_pin); VTR_ASSERT(nullptr != physical_pb_graph_pin);
/* Print info to help debug
bool verbose = true;
VTR_LOGV(verbose,
"\nSynchronize net '%lu' to physical pb_graph_pin '%s.%s[%d]'\n",
size_t(atom_net),
pb_graph_pin->parent_node->pb_type->name,
pb_graph_pin->port->name,
pb_graph_pin->pin_number);
*/
/* Check if the pin has been mapped to a net. /* Check if the pin has been mapped to a net.
* If yes, the atom net must be the same * If yes, the atom net must be the same
*/ */
@ -155,6 +165,7 @@ void synchronize_primitive_physical_pb_atom_nets(PhysicalPb& phy_pb,
const AtomBlockId& atom_blk, const AtomBlockId& atom_blk,
const VprDeviceAnnotation& device_annotation) { const VprDeviceAnnotation& device_annotation) {
/* Iterate over all the ports: input, output and clock */ /* Iterate over all the ports: input, output and clock */
for (int iport = 0; iport < pb_graph_node->num_input_ports; ++iport) { for (int iport = 0; iport < pb_graph_node->num_input_ports; ++iport) {
for (int ipin = 0; ipin < pb_graph_node->num_input_pins[iport]; ++ipin) { for (int ipin = 0; ipin < pb_graph_node->num_input_pins[iport]; ++ipin) {
/* Port exists (some LUTs may have no input and hence no port in the atom netlist) */ /* Port exists (some LUTs may have no input and hence no port in the atom netlist) */
@ -219,6 +230,46 @@ void synchronize_primitive_physical_pb_atom_nets(PhysicalPb& phy_pb,
} }
} }
/************************************************************************
* Reach this function, the primitive pb should be
* - linked to a LUT pb_type
* - operating in the wire mode of a LUT
*
* Note: this function will not check the prequistics here
* Users must be responsible for this!!!
*
* This function will find the physical pb_graph_pin for each output
* of the pb_graph node and mark in the physical_pb database
* as driven by an wired LUT
***********************************************************************/
static
void mark_physical_pb_wired_lut_outputs(PhysicalPb& phy_pb,
const PhysicalPbId& primitive_pb,
const t_pb_graph_node* pb_graph_node,
const VprDeviceAnnotation& device_annotation,
const bool& verbose) {
for (int iport = 0; iport < pb_graph_node->num_output_ports; ++iport) {
for (int ipin = 0; ipin < pb_graph_node->num_output_pins[iport]; ++ipin) {
t_pb_graph_pin* pb_graph_pin = &(pb_graph_node->output_pins[iport][ipin]);
/* Find the physical pb_graph_pin */
t_pb_graph_pin* physical_pb_graph_pin = device_annotation.physical_pb_graph_pin(pb_graph_pin);
VTR_ASSERT(nullptr != physical_pb_graph_pin);
/* Print debug info */
VTR_LOGV(verbose,
"Mark physical pb_graph pin '%s.%s[%d]' as wire LUT output\n",
physical_pb_graph_pin->parent_node->pb_type->name,
physical_pb_graph_pin->port->name,
physical_pb_graph_pin->pin_number);
/* Label the pins in physical_pb as driven by wired LUT*/
phy_pb.set_wire_lut_output(primitive_pb, physical_pb_graph_pin, true);
}
}
}
/************************************************************************ /************************************************************************
* Synchronize mapping results from an operating pb to a physical pb * Synchronize mapping results from an operating pb to a physical pb
***********************************************************************/ ***********************************************************************/
@ -226,7 +277,8 @@ void rec_update_physical_pb_from_operating_pb(PhysicalPb& phy_pb,
const t_pb* op_pb, const t_pb* op_pb,
const t_pb_routes& pb_route, const t_pb_routes& pb_route,
const AtomContext& atom_ctx, const AtomContext& atom_ctx,
const VprDeviceAnnotation& device_annotation) { const VprDeviceAnnotation& device_annotation,
const bool& verbose) {
t_pb_graph_node* pb_graph_node = op_pb->pb_graph_node; t_pb_graph_node* pb_graph_node = op_pb->pb_graph_node;
t_pb_type* pb_type = pb_graph_node->pb_type; t_pb_type* pb_type = pb_graph_node->pb_type;
@ -265,7 +317,55 @@ void rec_update_physical_pb_from_operating_pb(PhysicalPb& phy_pb,
&(op_pb->child_pbs[ipb][jpb]), &(op_pb->child_pbs[ipb][jpb]),
pb_route, pb_route,
atom_ctx, atom_ctx,
device_annotation); device_annotation,
verbose);
} else {
/* Some pb may be used just in routing purpose, find out the output nets */
/* The following code is inspired by output_cluster.cpp */
bool is_used = false;
t_pb_type* child_pb_type = &(mapped_mode->pb_type_children[ipb]);
/* Bypass non-primitive pb_type, we care only the LUT pb_type */
if (false == is_primitive_pb_type(child_pb_type)) {
continue;
}
int port_index = 0;
t_pb_graph_node* child_pb_graph_node = &(pb_graph_node->child_pb_graph_nodes[op_pb->mode][ipb][jpb]);
for (int k = 0; k < child_pb_type->num_ports && !is_used; k++) {
if (OUT_PORT == child_pb_type->ports[k].type) {
for (int m = 0; m < child_pb_type->ports[k].num_pins; m++) {
int node_index = child_pb_graph_node->output_pins[port_index][m].pin_count_in_cluster;
if (pb_route.count(node_index) && pb_route[node_index].atom_net_id) {
is_used = true;
break;
}
}
port_index++;
}
}
/* Identify output pb_graph_pin that is driven by a wired LUT
* Without this function, physical Look-Up Table build-up will cause errors
* and bitstream will be incorrect!!!
*/
if (true == is_used) {
VTR_ASSERT(LUT_CLASS == child_pb_type->class_type);
t_pb_graph_node* physical_pb_graph_node = device_annotation.physical_pb_graph_node(child_pb_graph_node);
VTR_ASSERT(nullptr != physical_pb_graph_node);
/* Find the physical pb */
const PhysicalPbId& physical_pb = phy_pb.find_pb(physical_pb_graph_node);
VTR_ASSERT(true == phy_pb.valid_pb_id(physical_pb));
/* Set the mode bits */
phy_pb.set_mode_bits(physical_pb, device_annotation.pb_type_mode_bits(child_pb_type));
mark_physical_pb_wired_lut_outputs(phy_pb, physical_pb,
child_pb_graph_node,
device_annotation,
verbose);
}
} }
} }
} }

View File

@ -28,7 +28,8 @@ void rec_update_physical_pb_from_operating_pb(PhysicalPb& phy_pb,
const t_pb* op_pb, const t_pb* op_pb,
const t_pb_routes& pb_route, const t_pb_routes& pb_route,
const AtomContext& atom_ctx, const AtomContext& atom_ctx,
const VprDeviceAnnotation& device_annotation); const VprDeviceAnnotation& device_annotation,
const bool& verbose);
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -34,7 +34,7 @@ repack #--verbose
build_architecture_bitstream --verbose --file /var/tmp/xtang/openfpga_test_src/fabric_indepenent_bitstream.xml build_architecture_bitstream --verbose --file /var/tmp/xtang/openfpga_test_src/fabric_indepenent_bitstream.xml
# Build fabric-dependent bitstream # Build fabric-dependent bitstream
build_fabric_bitstream --verbose build_fabric_bitstream --verbose --file /var/tmp/xtang/openfpga_test_src/and.bitstream
# Write the Verilog netlist for FPGA fabric # Write the Verilog netlist for FPGA fabric
# - Enable the use of explicit port mapping in Verilog netlist # - Enable the use of explicit port mapping in Verilog netlist

View File

@ -0,0 +1,61 @@
# Run VPR for the 'and' design
#--write_rr_graph example_rr_graph.xml
vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling route --absorb_buffer_luts off
# Read OpenFPGA architecture definition
read_openfpga_arch -f ${OPENFPGA_ARCH_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
# Apply fix-up to clustering nets based on routing results
pb_pin_fixup --verbose
# 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
# 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 #--verbose
# Build the bitstream
# - Output the fabric-independent bitstream to a file
build_architecture_bitstream --verbose --file fabric_indepenent_bitstream.xml
# Build fabric-dependent bitstream
build_fabric_bitstream --verbose
# Write the Verilog netlist for FPGA fabric
# - Enable the use of explicit port mapping in Verilog netlist
write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --include_signal_init --support_icarus_simulator --print_user_defined_template --verbose
# 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_verilog_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --print_top_testbench --print_preconfig_top_testbench --print_simulation_ini ./simulation_deck_info.ini
# Write the SDC files for PnR backend
# - Turn on every options here
write_pnr_sdc --file ./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

View File

@ -54,7 +54,7 @@
<site pb_type="clb"/> <site pb_type="clb"/>
</equivalent_sites> </equivalent_sites>
<input name="I" num_pins="40" equivalent="full"/> <input name="I" num_pins="40" equivalent="full"/>
<output name="O" num_pins="10" equivalent="instance"/> <output name="O" num_pins="10" equivalent="none"/>
<clock name="clk" num_pins="1"/> <clock name="clk" num_pins="1"/>
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10"/> <fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10"/>
<pinlocations pattern="spread"/> <pinlocations pattern="spread"/>
@ -137,7 +137,7 @@
<!-- A mode denotes the physical implementation of an I/O <!-- A mode denotes the physical implementation of an I/O
This mode will be not packable but is mainly used for fabric verilog generation This mode will be not packable but is mainly used for fabric verilog generation
--> -->
<mode name="physical" disabled_in_pack="true"> <mode name="physical" packable="false">
<pb_type name="iopad" blif_model=".subckt io" num_pb="1"> <pb_type name="iopad" blif_model=".subckt io" num_pb="1">
<input name="outpad" num_pins="1"/> <input name="outpad" num_pins="1"/>
<output name="inpad" num_pins="1"/> <output name="inpad" num_pins="1"/>
@ -197,7 +197,7 @@
--> -->
<pb_type name="clb"> <pb_type name="clb">
<input name="I" num_pins="40" equivalent="full"/> <input name="I" num_pins="40" equivalent="full"/>
<output name="O" num_pins="10" equivalent="instance"/> <output name="O" num_pins="10" equivalent="none"/>
<clock name="clk" num_pins="1"/> <clock name="clk" num_pins="1"/>
<!-- Describe basic logic element. <!-- Describe basic logic element.
Each basic logic element has a 6-LUT that can be optionally registered Each basic logic element has a 6-LUT that can be optionally registered

View File

@ -0,0 +1,680 @@
<!-- Homogeneous FPGA Architecture with Carry Chain for VPR8
- The chip layout is organized with a 2x2 array of Configurable Logic Blocks (CLBs)
surrounded by a ring of I/Os
- [TODO] Delay numbers are extracted from a 12 nm technology
Author: Xifan Tang, Aurelien Alacchi and Ganesh Gore
-->
<architecture>
<!--
ODIN II specific config begins
Describes the types of user-specified netlist blocks (in blif, this corresponds to
".model [type_of_block]") that this architecture supports.
Note: Basic LUTs, I/Os, and flip-flops are not included here as there are
already special structures in blif (.names, .input, .output, and .latch)
that describe them.
-->
<models>
<model name="adder">
<input_ports>
<port name="a" combinational_sink_ports="sumout cout"/>
<port name="b" combinational_sink_ports="sumout cout"/>
<port name="cin" combinational_sink_ports="sumout cout"/>
</input_ports>
<output_ports>
<port name="cout"/>
<port name="sumout"/>
</output_ports>
</model>
<!-- A virtual model for I/O to be used in the physical mode of io block -->
<model name="io">
<input_ports>
<port name="outpad"/>
</input_ports>
<output_ports>
<port name="inpad"/>
</output_ports>
</model>
<!-- A virtual model for I/O to be used in the physical mode of io block -->
<model name="frac_lut6">
<input_ports>
<port name="in"/>
</input_ports>
<output_ports>
<port name="lut4_out"/>
<port name="lut5_out"/>
<port name="lut6_out"/>
</output_ports>
</model>
<model name="shift">
<input_ports>
<port name="D" clock="clk"/>
<port name="clk" is_clock="1"/>
</input_ports>
<output_ports>
<port name="Q" clock="clk"/>
</output_ports>
</model>
<model name="scff">
<input_ports>
<port name="D" clock="clk"/>
<port name="D_chain" clock="clk"/>
<port name="clk" is_clock="1"/>
</input_ports>
<output_ports>
<port name="Q" clock="clk"/>
</output_ports>
</model>
</models>
<tiles>
<!-- Each I/O tile includes a GPIO -->
<!-- IOs go on the periphery of the FPGA, for consistency,
make it physically equivalent on all sides so that only one definition of I/Os is needed.
If I do not make a physically equivalent definition, then I need to define 4 different I/Os, one for each side of the FPGA
-->
<tile name="io" capacity="8" area="0">
<equivalent_sites>
<site pb_type="io"/>
</equivalent_sites>
<input name="outpad" num_pins="1"/>
<output name="inpad" num_pins="1"/>
<!-- Each input of the tile can be driven by 15% of routing tracks
Each output of the tile can drive 10% of routing tracks
-->
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10"/>
<pinlocations pattern="custom">
<loc side="left">io.outpad io.inpad</loc>
<loc side="top">io.outpad io.inpad</loc>
<loc side="right">io.outpad io.inpad</loc>
<loc side="bottom">io.outpad io.inpad</loc>
</pinlocations>
</tile>
<!-- Each CLB tile includes a Configurable Logic Block (CLB)
Each input of the tile can be driven by 15% of routing tracks
Each output of the tile can drive 10% of routing tracks
-->
<tile name="clb" area="53894">
<equivalent_sites>
<site pb_type="clb"/>
</equivalent_sites>
<input name="I0" num_pins="10" equivalent="full"/>
<input name="I1" num_pins="10" equivalent="full"/>
<input name="I2" num_pins="10" equivalent="full"/>
<input name="I3" num_pins="10" equivalent="full"/>
<input name="sc_in" num_pins="1"/>
<input name="cin" num_pins="1"/>
<input name="cin_trick" num_pins="1"/>
<input name="regin" num_pins="1"/>
<output name="O" num_pins="20" equivalent="none"/>
<output name="sc_out" num_pins="1"/>
<output name="cout" num_pins="1"/>
<output name="cout_copy" num_pins="1"/>
<output name="regout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- Each input of the tile can be driven by 15% of routing tracks
Each output of the tile can drive 10% of routing tracks
There are four pins (cin, cout, sc_in, sc_out) has not connection
to routing tracks. There are directed wired from/to adjacent CLBs
-->
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10">
<fc_override port_name="cin" fc_type="frac" fc_val="0"/>
<fc_override port_name="cout" fc_type="frac" fc_val="0"/>
<fc_override port_name="sc_in" fc_type="frac" fc_val="0"/>
<fc_override port_name="sc_out" fc_type="frac" fc_val="0"/>
</fc>
<!-- Highly recommand to customize pin location when direct connection is used!!! -->
<!-- To ensure best tileable routing architecture (minimize the number of unique SBs
We keep all the pins that touch routing architecture on the right and bottom sides of the tile
Top side pins are mainly for direct connections
-->
<pinlocations pattern="custom">
<loc side="left"></loc>
<loc side="top">clb.sc_in clb.cin clb.cin_trick clb.regin clb.clk</loc>
<loc side="right">clb.I0[9:0] clb.I1[9:0] clb.O[9:0]</loc>
<loc side="bottom">clb.cout clb.cout_copy clb.sc_out clb.regout clb.I2[9:0] clb.I3[9:0] clb.O[19:10]</loc>
</pinlocations>
</tile>
</tiles>
<!-- ODIN II specific config ends -->
<!-- Physical descriptions begin -->
<!-- Apply tileable routing architecture.
This is strongly recommended if you want to PnR large FPGA fabric
-->
<layout tileable="true">
<auto_layout aspect_ratio="1.0">
<!-- Apply a fixed layout of 2x2 core array.
VPR8 considers the I/O ring in the array size
Therefore the height and width are both 4
-->
<!-- fixed_layout name="32x32" width="34" height="34" -->
<!--Perimeter of 'io' blocks with 'EMPTY' blocks at corners-->
<perimeter type="io" priority="100"/>
<corners type="EMPTY" priority="101"/>
<!--Fill with 'clb'-->
<fill type="clb" priority="10"/>
<!-- /fixed_layout -->
</auto_layout>
</layout>
<device>
<sizing R_minW_nmos="8926" R_minW_pmos="16067"/>
<!-- The grid_logic_tile_area below will be used for all blocks that do not explicitly set their own (non-routing)
area; set to 0 since we explicitly set the area of all blocks currently in this architecture file.
-->
<area grid_logic_tile_area="0"/>
<chan_width_distr>
<x distr="uniform" peak="1.000000"/>
<y distr="uniform" peak="1.000000"/>
</chan_width_distr>
<!-- Use Wilton-style connecting pattern in switch block
Each routing track has access to only three other routing tracks
(one per each side of the switch block except the side where the routing track locates)
-->
<switch_block type="wilton" fs="3"/>
<connection_block input_switch_name="ipin_cblock"/>
</device>
<switchlist>
<switch type="mux" name="0" R="551" Cin=".77e-15" Cout="4e-15" Tdel="58e-12" mux_trans_size="2.630740" buf_size="27.645901"/>
<switch type="mux" name="ipin_cblock" R="2231.5" Cout="0." Cin="1.47e-15" Tdel="7.247000e-11" mux_trans_size="1.222260" buf_size="auto"/>
</switchlist>
<segmentlist>
<!-- GIVE a specific name for the segment! OpenFPGA appreciate that! -->
<!-- Uni-directional routing architecture using only length-4 wires in routing channels -->
<segment name="L4" freq="1.000000" length="4" type="unidir" Rmetal="101" Cmetal="22.5e-15">
<mux name="0"/>
<sb type="pattern">1 1 1 1 1</sb>
<cb type="pattern">1 1 1 1</cb>
</segment>
</segmentlist>
<directlist>
<!-- Hard adder chain inside CLB is directly connected between adjacent CLBs -->
<direct name="adder_carry" from_pin="clb.cout" to_pin="clb.cin" x_offset="0" y_offset="-1" z_offset="0"/>
<!-- Scan chain inside CLB is directly connected between adjacent CLBs -->
<direct name="scff_chain" from_pin="clb.sc_out" to_pin="clb.sc_in" x_offset="0" y_offset="-1" z_offset="0"/>
</directlist>
<complexblocklist>
<!-- Define I/O pads begin -->
<!-- Capacity is a unique property of I/Os, it is the maximum number of I/Os that can be placed at the same (X,Y) location on the FPGA -->
<!-- Not sure of the area of an I/O (varies widely), and it's not relevant to the design of the FPGA core, so we're setting it to 0. -->
<pb_type name="io">
<input name="outpad" num_pins="1"/>
<output name="inpad" num_pins="1"/>
<!-- Do NOT add clock pins to I/O here!!! VPR does not build clock network in the way that OpenFPGA can support
If you need to register the I/O, define clocks in the circuit models
These clocks can be handled in back-end
-->
<!-- A mode denotes the physical implementation of an I/O
This mode will be not packable but is mainly used for fabric verilog generation
-->
<mode name="physical" packable="false">
<pb_type name="iopad" blif_model=".subckt io" num_pb="1">
<input name="outpad" num_pins="1"/>
<output name="inpad" num_pins="1"/>
</pb_type>
<interconnect>
<direct name="outpad" input="io.outpad" output="iopad.outpad">
<delay_constant max="1.394e-11" in_port="io.outpad" out_port="iopad.outpad"/>
</direct>
<direct name="inpad" input="iopad.inpad" output="io.inpad">
<delay_constant max="4.243e-11" in_port="iopad.inpad" out_port="io.inpad"/>
</direct>
</interconnect>
</mode>
<!-- IOs can operate as either inputs or outputs.
Delays below come from Ian Kuon. They are small, so they should be interpreted as
the delays to and from registers in the I/O (and generally I/Os are registered
today and that is when you timing analyze them.
-->
<mode name="inpad">
<pb_type name="inpad" blif_model=".input" num_pb="1">
<output name="inpad" num_pins="1"/>
</pb_type>
<interconnect>
<direct name="inpad" input="inpad.inpad" output="io.inpad">
<delay_constant max="4.243e-11" in_port="inpad.inpad" out_port="io.inpad"/>
</direct>
</interconnect>
</mode>
<mode name="outpad">
<pb_type name="outpad" blif_model=".output" num_pb="1">
<input name="outpad" num_pins="1"/>
</pb_type>
<interconnect>
<direct name="outpad" input="io.outpad" output="outpad.outpad">
<delay_constant max="1.394e-11" in_port="io.outpad" out_port="outpad.outpad"/>
</direct>
</interconnect>
</mode>
<power method="ignore"/>
</pb_type>
<!-- Define I/O pads ends -->
<!-- Define multi-mode Configurable Logic Block (CLB) begin -->
<!-- Technical highlight:
K6_frac_N10_I40_chain_shiftreg_depop50
- K6_frac: Each Logic Element (LE) contains a fracturable 6 LUT,
which can operate as one 6-LUT or two 5-LUTs or four 4-LUTs
In addition to 6-LUT, each LE also includes two Flip-Flops
- N10: every CLB consists of 10 LEs and a local routing architecture
- I40: every CLB has 40 inputs
- chain: a hard adder chain across all the LEs in a CLB
The inputs of adder are driven by 4-LUTs.
The sumout of adder can optional drive an LE output or a Flip-Flop
The carry-out of adder will drive the carry-in of the next adder in the chain
- shiftreg: Flip-flops inside CLB can be configured as shift registers.
The organization is similar the hard adder chain except it is programmable
- depop50: every local routing multiplexer accesses to 50% of the CLB inputs
-->
<pb_type name="clb">
<input name="I0" num_pins="10" equivalent="full"/>
<input name="I1" num_pins="10" equivalent="full"/>
<input name="I2" num_pins="10" equivalent="full"/>
<input name="I3" num_pins="10" equivalent="full"/>
<input name="sc_in" num_pins="1"/>
<input name="cin" num_pins="1"/>
<input name="cin_trick" num_pins="1"/>
<input name="regin" num_pins="1"/>
<output name="O" num_pins="20" equivalent="none"/>
<output name="sc_out" num_pins="1"/>
<output name="cout" num_pins="1"/>
<output name="cout_copy" num_pins="1"/>
<output name="regout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- Describe fracturable logic element -->
<pb_type name="fle" num_pb="10">
<input name="in" num_pins="6"/>
<input name="cin" num_pins="1"/>
<input name="sc_in" num_pins="1"/>
<input name="regin" num_pins="1"/>
<output name="out" num_pins="2"/>
<output name="cout" num_pins="1"/>
<output name="sc_out" num_pins="1"/>
<output name="regout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- Describe physical mode begins -->
<mode name="physical" packable="false">
<pb_type name="frac_logic" num_pb="1">
<input name="in" num_pins="6"/>
<input name="cin" num_pins="1"/>
<input name="regin" num_pins="1"/>
<input name="regchain" num_pins="1"/>
<output name="out" num_pins="2"/>
<output name="cout" num_pins="1"/>
<pb_type name="frac_lut6" blif_model=".subckt frac_lut6" num_pb="1">
<input name="in" num_pins="6"/>
<output name="lut4_out" num_pins="4"/>
<output name="lut5_out" num_pins="2"/>
<output name="lut6_out" num_pins="1"/>
</pb_type>
<pb_type name="adder_phy" blif_model=".subckt adder" num_pb="2">
<input name="a" num_pins="1"/>
<input name="b" num_pins="1"/>
<input name="cin" num_pins="1"/>
<output name="cout" num_pins="1"/>
<output name="sumout" num_pins="1"/>
<delay_constant max="0.3e-9" in_port="adder_phy.a" out_port="adder_phy.sumout"/>
<delay_constant max="0.3e-9" in_port="adder_phy.b" out_port="adder_phy.sumout"/>
<delay_constant max="0.3e-9" in_port="adder_phy.cin" out_port="adder_phy.sumout"/>
<delay_constant max="0.3e-9" in_port="adder_phy.a" out_port="adder_phy.cout"/>
<delay_constant max="0.3e-9" in_port="adder_phy.b" out_port="adder_phy.cout"/>
<delay_constant max="0.3e-9" in_port="adder_phy.cin" out_port="adder_phy.cout"/>
</pb_type>
<interconnect>
<direct name="direct_fraclut_in" input="frac_logic.in[5:0]" output="frac_lut6.in[5:0]"/>
<direct name="direct_cin" input="frac_logic.cin" output="adder_phy[0].cin"/>
<direct name="direct_carry" input="adder_phy[0].cout" output="adder_phy[1].cin"/>
<direct name="direct_cout" input="adder_phy[1].cout" output="frac_logic.cout"/>
<direct name="direct_lut4carry0" input="frac_lut6.lut4_out[0]" output="adder_phy[0].a"/>
<direct name="direct_lut4carry1" input="frac_lut6.lut4_out[1]" output="adder_phy[0].b"/>
<direct name="direct_lut4carry2" input="frac_lut6.lut4_out[2]" output="adder_phy[1].a"/>
<direct name="direct_lut4carry3" input="frac_lut6.lut4_out[3]" output="adder_phy[1].b"/>
<mux name="mux1" input="adder_phy[0].sumout frac_lut6.lut5_out[0] frac_logic.regin" output="frac_logic.out[0]">
</mux>
<mux name="mux2" input="adder_phy[1].sumout frac_lut6.lut5_out[1] frac_lut6.lut6_out[0] frac_logic.regchain[0]" output="frac_logic.out[1]">
</mux>
</interconnect>
</pb_type>
<pb_type name="ff_phy" blif_model=".subckt scff" num_pb="2">
<input name="D" num_pins="1"/>
<input name="D_chain" num_pins="1"/>
<output name="Q" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<T_setup value="66e-12" port="ff_phy.D" clock="clk"/>
<T_setup value="66e-12" port="ff_phy.D_chain" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff_phy.Q" clock="clk"/>
</pb_type>
<interconnect>
<complete name="direct_clk" input="fle.clk" output="ff_phy[1:0].clk"/>
<direct name="direct_in" input="fle.in[5:0]" output="frac_logic.in[5:0]"/>
<direct name="direct_regin" input="fle.regin" output="frac_logic.regin"/>
<direct name="direct_regchain" input="ff_phy[0].Q" output="frac_logic.regchain"/>
<direct name="direct_regout" input="ff_phy[1].Q" output="fle.regout"/>
<direct name="direct_cin" input="fle.cin" output="frac_logic.cin"/>
<direct name="direct_cout" input="frac_logic.cout" output="fle.cout"/>
<direct name="direct_frac_out1" input="frac_logic.out[0]" output="ff_phy[0].D"/>
<direct name="direct_frac_out2" input="frac_logic.out[1]" output="ff_phy[1].D"/>
<direct name="direct_fle_scin" input="fle.sc_in" output="ff_phy[0].D_chain"/>
<direct name="direct_fle_sc_chain" input="ff_phy[0].Q" output="ff_phy[1].D_chain"/>
<direct name="direct_fle_scout" input="ff_phy[1].Q" output="fle.sc_out"/>
<mux name="mux1" input="ff_phy[0].Q frac_logic.out[0]" output="fle.out[0]">
</mux>
<mux name="mux2" input="ff_phy[1].Q frac_logic.out[1]" output="fle.out[1]">
</mux>
</interconnect>
</mode>
<!-- Define physical mode begins -->
<!-- Define n2_lut5 mode begins -->
<mode name="n2_lut5" packable="true">
<pb_type name="lut5inter" num_pb="1">
<input name="in" num_pins="5"/>
<input name="cin" num_pins="1"/>
<output name="out" num_pins="2"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<pb_type name="ble5" num_pb="2">
<input name="in" num_pins="5"/>
<input name="cin" num_pins="1"/>
<output name="out" num_pins="1"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<mode name="blut5">
<pb_type name="flut5" num_pb="1">
<input name="in" num_pins="5"/>
<output name="out" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- Regular LUT mode -->
<pb_type name="lut5" blif_model=".names" num_pb="1" class="lut">
<input name="in" num_pins="5" port_class="lut_in"/>
<output name="out" num_pins="1" port_class="lut_out"/>
<!-- LUT timing using delay matrix -->
<delay_matrix type="max" in_port="lut5.in" out_port="lut5.out">
202e-12
202e-12
202e-12
202e-12
202e-12
</delay_matrix>
</pb_type>
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="direct1" input="flut5.in" output="lut5.in"/>
<direct name="direct2" input="lut5.out" output="ff.D">
<pack_pattern name="ble5" in_port="lut5.out" out_port="ff.D"/>
</direct>
<direct name="direct3" input="flut5.clk" output="ff.clk"/>
<mux name="mux1" input="ff.Q lut5.out" output="flut5.out">
<delay_constant max="25e-12" in_port="lut5.out" out_port="flut5.out" />
<delay_constant max="45e-12" in_port="ff.Q" out_port="flut5.out" />
</mux>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="ble5.in" output="flut5.in"/>
<direct name="direct2" input="ble5.clk" output="flut5.clk"/>
<direct name="direct3" input="flut5.out" output="ble5.out"/>
</interconnect>
</mode>
<mode name="arithmetic">
<pb_type name="arithmetic" num_pb="1">
<input name="in" num_pins="4"/>
<input name="cin" num_pins="1"/>
<output name="out" num_pins="1"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- Special dual-LUT mode that drives adder only -->
<pb_type name="lut4" blif_model=".names" num_pb="2" class="lut">
<input name="in" num_pins="4" port_class="lut_in"/>
<output name="out" num_pins="1" port_class="lut_out"/>
<!-- LUT timing using delay matrix -->
<delay_matrix type="max" in_port="lut4.in" out_port="lut4.out">
180e-12
180e-12
180e-12
180e-12
</delay_matrix>
</pb_type>
<pb_type name="adder" blif_model=".subckt adder" num_pb="1">
<input name="a" num_pins="1"/>
<input name="b" num_pins="1"/>
<input name="cin" num_pins="1"/>
<output name="cout" num_pins="1"/>
<output name="sumout" num_pins="1"/>
<delay_constant max="0.3e-9" in_port="adder.a" out_port="adder.sumout"/>
<delay_constant max="0.3e-9" in_port="adder.b" out_port="adder.sumout"/>
<delay_constant max="0.3e-9" in_port="adder.cin" out_port="adder.sumout"/>
<delay_constant max="0.3e-9" in_port="adder.a" out_port="adder.cout"/>
<delay_constant max="0.3e-9" in_port="adder.b" out_port="adder.cout"/>
<delay_constant max="0.3e-9" in_port="adder.cin" out_port="adder.cout"/>
</pb_type>
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="clock" input="arithmetic.clk" output="ff.clk"/>
<direct name="lut_in1" input="arithmetic.in[3:0]" output="lut4[0:0].in[3:0]"/>
<direct name="lut_in2" input="arithmetic.in[3:0]" output="lut4[1:1].in[3:0]"/>
<direct name="lut_to_add1" input="lut4[0:0].out" output="adder.a">
</direct>
<direct name="lut_to_add2" input="lut4[1:1].out" output="adder.b">
</direct>
<direct name="add_to_ff" input="adder.sumout" output="ff.D">
<pack_pattern name="chain" in_port="adder.sumout" out_port="ff.D"/>
</direct>
<direct name="carry_in" input="arithmetic.cin" output="adder.cin">
<pack_pattern name="chain" in_port="arithmetic.cin" out_port="adder.cin"/>
</direct>
<direct name="carry_out" input="adder.cout" output="arithmetic.cout">
<pack_pattern name="chain" in_port="adder.cout" out_port="arithmetic.cout"/>
</direct>
<mux name="sumout" input="ff.Q adder.sumout" output="arithmetic.out">
<delay_constant max="25e-12" in_port="adder.sumout" out_port="arithmetic.out"/>
<delay_constant max="45e-12" in_port="ff.Q" out_port="arithmetic.out" />
</mux>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="ble5.in[3:0]" output="arithmetic.in"/>
<direct name="carry_in" input="ble5.cin" output="arithmetic.cin">
<!--pack_pattern name="chain" in_port="ble5.cin" out_port="arithmetic.cin"/-->
</direct>
<direct name="carry_out" input="arithmetic.cout" output="ble5.cout">
<!--pack_pattern name="chain" in_port="arithmetic.cout" out_port="ble5.cout"/-->
</direct>
<direct name="direct2" input="ble5.clk" output="arithmetic.clk"/>
<direct name="direct3" input="arithmetic.out" output="ble5.out"/>
</interconnect>
</mode>
</pb_type>
<interconnect>
<direct name="direct1" input="lut5inter.in" output="ble5[0:0].in"/>
<direct name="direct2" input="lut5inter.in" output="ble5[1:1].in"/>
<direct name="direct3" input="ble5[1:0].out" output="lut5inter.out"/>
<direct name="carry_in" input="lut5inter.cin" output="ble5[0:0].cin">
<!--pack_pattern name="chain" in_port="lut5inter.cin" out_port="ble5[0:0].cin"/-->
</direct>
<direct name="carry_out" input="ble5[1:1].cout" output="lut5inter.cout">
<!--pack_pattern name="chain" in_port="ble5[1:1].cout" out_port="lut5inter.cout"/-->
</direct>
<direct name="carry_link" input="ble5[0:0].cout" output="ble5[1:1].cin">
<!--pack_pattern name="chain" in_port="ble5[0:0].cout" out_port="ble5[1:1].cout"/-->
</direct>
<complete name="complete1" input="lut5inter.clk" output="ble5[1:0].clk"/>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="fle.in[4:0]" output="lut5inter.in"/>
<direct name="direct2" input="lut5inter.out" output="fle.out"/>
<direct name="direct3" input="fle.clk" output="lut5inter.clk"/>
<direct name="carry_in" input="fle.cin" output="lut5inter.cin">
<!--pack_pattern name="chain" in_port="fle.cin" out_port="lut5inter.cin"/-->
</direct>
<direct name="carry_out" input="lut5inter.cout" output="fle.cout">
<!--pack_pattern name="chain" in_port="lut5inter.cout" out_port="fle.cout"/-->
</direct>
</interconnect>
</mode>
<!-- Define n2_lut5 mode ends -->
<mode name="n1_lut6">
<pb_type name="ble6" num_pb="1">
<input name="in" num_pins="6"/>
<output name="out" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<pb_type name="lut6" blif_model=".names" num_pb="1" class="lut">
<input name="in" num_pins="6" port_class="lut_in"/>
<output name="out" num_pins="1" port_class="lut_out"/>
<!-- LUT timing using delay matrix -->
<delay_matrix type="max" in_port="lut6.in" out_port="lut6.out">
229e-12
229e-12
229e-12
229e-12
229e-12
229e-12
</delay_matrix>
</pb_type>
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="direct1" input="ble6.in" output="lut6[0:0].in"/>
<direct name="direct2" input="lut6.out" output="ff.D">
<pack_pattern name="ble6" in_port="lut6.out" out_port="ff.D"/>
</direct>
<direct name="direct3" input="ble6.clk" output="ff.clk"/>
<mux name="mux1" input="ff.Q lut6.out" output="ble6.out">
<delay_constant max="25e-12" in_port="lut6.out" out_port="ble6.out" />
<delay_constant max="45e-12" in_port="ff.Q" out_port="ble6.out" />
</mux>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="fle.in" output="ble6.in"/>
<direct name="direct2" input="ble6.out" output="fle.out[1:1]"/>
<direct name="direct3" input="fle.clk" output="ble6.clk"/>
</interconnect>
</mode>
<!-- Define n1_lut6 mode ends -->
<!-- Define shift register mode begins -->
<mode name="shift_register">
<pb_type name="ble_shift" num_pb="1">
<input name="in" num_pins="1"/>
<output name="out" num_pins="2"/>
<output name="regout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<pb_type name="ff" blif_model=".subckt shift" num_pb="2" class="flipflop">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="direct1" input="ble_shift.in" output="ff[0].D"/>
<direct name="direct2" input="ff[0].Q" output="ff[1].D">
<!--pack_pattern name="ble_shift" in_port="ff[0].Q" out_port="ff[1].D"/-->
</direct>
<direct name="out1" input="ff[0].Q" output="ble_shift.out[0]"/>
<direct name="out2" input="ff[1].Q" output="ble_shift.out[1]"/>
<direct name="direct_regout" input="ff[1].Q" output="ble_shift.regout"/>
<complete name="direct3" input="ble_shift.clk" output="ff[1:0].clk"/>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="fle.regin" output="ble_shift.in"/>
<direct name="direct2" input="ble_shift.out" output="fle.out"/>
<direct name="direct3" input="fle.clk" output="ble_shift.clk"/>
<direct name="direct4" input="ble_shift.regout" output="fle.regout"/>
</interconnect>
</mode>
<!-- Define shift_register mode end -->
</pb_type>
<interconnect>
<complete name="crossbar0" input="clb.I2 clb.I3 fle[9:0].out" output="fle[9:0].in[0]">
<delay_constant max="190e-12" in_port="clb.I2 clb.I3" out_port="fle[9:0].in[0]" />
<delay_constant max="190e-12" in_port="fle[9:0].out" out_port="fle[9:0].in[0]" />
</complete>
<complete name="crossbar1" input="clb.I1 clb.I2 fle[9:0].out" output="fle[9:0].in[1]">
<delay_constant max="190e-12" in_port="clb.I1 clb.I2" out_port="fle[9:0].in[1]" />
<delay_constant max="190e-12" in_port="fle[9:0].out" out_port="fle[9:0].in[1]" />
</complete>
<complete name="crossbar2" input="clb.I0 clb.I1 fle[9:0].out" output="fle[9:0].in[2]">
<delay_constant max="190e-12" in_port="clb.I0 clb.I1" out_port="fle[9:0].in[2]" />
<delay_constant max="190e-12" in_port="fle[9:0].out" out_port="fle[9:0].in[2]" />
</complete>
<complete name="crossbar3" input="clb.I1 clb.I3 fle[9:0].out" output="fle[9:0].in[3]">
<delay_constant max="190e-12" in_port="clb.I1 clb.I3" out_port="fle[9:0].in[3]" />
<delay_constant max="190e-12" in_port="fle[9:0].out" out_port="fle[9:0].in[3]" />
</complete>
<complete name="crossbar4" input="clb.I0 clb.I2 fle[9:0].out" output="fle[9:0].in[4]">
<delay_constant max="190e-12" in_port="clb.I0 clb.I2" out_port="fle[9:0].in[4]" />
<delay_constant max="190e-12" in_port="fle[9:0].out" out_port="fle[9:0].in[4]" />
</complete>
<complete name="crossbar5" input="clb.I0 clb.I3 fle[9:0].out" output="fle[9:0].in[5]">
</complete>
<complete name="clks" input="clb.clk" output="fle[9:0].clk">
</complete>
<complete name="carry_in" input="clb.cin clb.cin_trick fle[9:0].out" output="fle[0:0].cin">
<!-- Put all inter-block carry chain delay on this one edge -->
<!--delay_constant max="0.15e-9" in_port="clb.cin clb.cin_trick" out_port="fle[0:0].cin"/-->
<pack_pattern name="chain" in_port="clb.cin" out_port="fle[0:0].cin"/>
<!--pack_pattern name="chain" in_port="clb.cin_trick" out_port="fle[0:0].cin"/-->
</complete>
<!--direct name="carry_in" input="clb.cin" output="fle[0:0].cin">
<pack_pattern name="chain" in_port="clb.cin" out_port="fle[0:0].cin"/>
</direct-->
<direct name="clbouts1" input="fle[9:0].out[0:0]" output="clb.O[9:0]"/>
<direct name="clbouts2" input="fle[9:0].out[1:1]" output="clb.O[19:10]"/>
<direct name="cout_copy" input="fle[9:9].cout" output="clb.cout_copy"/>
<!-- Shift register links -->
<direct name="regin" input="clb.regin" output="fle[0:0].regin">
<!-- Put all inter-block carry chain delay on this one edge -->
<delay_constant max="0.15e-9" in_port="clb.regin" out_port="fle[0:0].regin"/>
<pack_pattern name="chain" in_port="clb.regin" out_port="fle[0:0].regin"/>
</direct>
<direct name="regout" input="fle[9:9].regout" output="clb.regout">
<pack_pattern name="chain" in_port="fle[9:9].regout" out_port="clb.regout"/>
</direct>
<direct name="reg_link" input="fle[8:0].regout" output="fle[9:1].regin">
<pack_pattern name="chain" in_port="fle[8:0].regout" out_port="fle[9:1].regin"/>
</direct>
<!-- Carry chain links -->
<direct name="carry_out" input="fle[9:9].cout" output="clb.cout">
<pack_pattern name="chain" in_port="fle[9:9].cout" out_port="clb.cout"/>
</direct>
<direct name="carry_link" input="fle[8:0].cout" output="fle[9:1].cin">
<pack_pattern name="chain" in_port="fle[8:0].cout" out_port="fle[9:1].cin"/>
</direct>
<!-- Scan chain links -->
<direct name="sc_in" input="clb.sc_in" output="fle[0:0].sc_in">
</direct>
<direct name="sc_out" input="fle[9:9].sc_out" output="clb.sc_out">
</direct>
<direct name="sc_link" input="fle[8:0].sc_out" output="fle[9:1].sc_in">
</direct>
</interconnect>
</pb_type>
<!-- Define general purpose logic block (CLB) ends -->
</complexblocklist>
</architecture>

View File

@ -0,0 +1,802 @@
<!-- Heterogeneous FPGA Architecture with Carry Chain for VPR8
- The chip layout is organized with a 32x32 array of Configurable Logic Blocks (CLBs)
surrounded by a ring of I/Os
- A column of BRAM locates at the 16th column of the 32x32 array
- Delay numbers are extracted from a 12 nm technology
Process corner: TT 0.8V
Author: Xifan Tang, Aurelien Alacchi and Ganesh Gore
-->
<architecture>
<!--
ODIN II specific config begins
Describes the types of user-specified netlist blocks (in blif, this corresponds to
".model [type_of_block]") that this architecture supports.
Note: Basic LUTs, I/Os, and flip-flops are not included here as there are
already special structures in blif (.names, .input, .output, and .latch)
that describe them.
-->
<models>
<model name="adder">
<input_ports>
<port name="a" combinational_sink_ports="sumout cout"/>
<port name="b" combinational_sink_ports="sumout cout"/>
<port name="cin" combinational_sink_ports="sumout cout"/>
</input_ports>
<output_ports>
<port name="cout"/>
<port name="sumout"/>
</output_ports>
</model>
<!-- A virtual model for I/O to be used in the physical mode of io block -->
<model name="io">
<input_ports>
<port name="outpad"/>
</input_ports>
<output_ports>
<port name="inpad"/>
</output_ports>
</model>
<!-- A virtual model for I/O to be used in the physical mode of io block -->
<model name="frac_lut6">
<input_ports>
<port name="in"/>
</input_ports>
<output_ports>
<port name="lut4_out"/>
<port name="lut5_out"/>
<port name="lut6_out"/>
</output_ports>
</model>
<model name="shift">
<input_ports>
<port name="D" clock="clk"/>
<port name="clk" is_clock="1"/>
</input_ports>
<output_ports>
<port name="Q" clock="clk"/>
</output_ports>
</model>
<model name="scff">
<input_ports>
<port name="D" clock="clk"/>
<port name="D_chain" clock="clk"/>
<port name="clk" is_clock="1"/>
</input_ports>
<output_ports>
<port name="Q" clock="clk"/>
</output_ports>
</model>
<model name="dual_port_ram">
<input_ports>
<!-- write address lines -->
<port name="waddr" clock="clk"/>
<!-- read address lines -->
<port name="raddr" clock="clk"/>
<!-- data lines can be broken down into smaller bit widths minimum size 1 -->
<port name="d_in" clock="clk"/>
<!-- write enable -->
<port name="wen" clock="clk"/>
<!-- read enable -->
<port name="ren" clock="clk"/>
<!-- memories are often clocked -->
<port name="clk" is_clock="1"/>
</input_ports>
<output_ports>
<!-- output can be broken down into smaller bit widths minimum size 1 -->
<port name="d_out" clock="clk"/>
</output_ports>
</model>
</models>
<tiles>
<!-- Each I/O tile includes a GPIO -->
<!-- IOs go on the periphery of the FPGA, for consistency,
make it physically equivalent on all sides so that only one definition of I/Os is needed.
If I do not make a physically equivalent definition, then I need to define 4 different I/Os, one for each side of the FPGA
-->
<tile name="io" capacity="1" area="0">
<equivalent_sites>
<site pb_type="io"/>
</equivalent_sites>
<input name="outpad" num_pins="1"/>
<output name="inpad" num_pins="1"/>
<!-- Each input of the tile can be driven by 15% of routing tracks
Each output of the tile can drive 10% of routing tracks
-->
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10"/>
<pinlocations pattern="custom">
<loc side="left">io.outpad io.inpad</loc>
<loc side="top">io.outpad io.inpad</loc>
<loc side="right">io.outpad io.inpad</loc>
<loc side="bottom">io.outpad io.inpad</loc>
</pinlocations>
</tile>
<!-- Each CLB tile includes a Configurable Logic Block (CLB)
Each input of the tile can be driven by 15% of routing tracks
Each output of the tile can drive 10% of routing tracks
-->
<tile name="clb" area="53894">
<equivalent_sites>
<site pb_type="clb"/>
</equivalent_sites>
<input name="I0" num_pins="10" equivalent="full"/>
<input name="I1" num_pins="10" equivalent="full"/>
<input name="I2" num_pins="10" equivalent="full"/>
<input name="I3" num_pins="10" equivalent="full"/>
<input name="sc_in" num_pins="1"/>
<input name="cin" num_pins="1"/>
<input name="cin_trick" num_pins="1"/>
<input name="regin" num_pins="1"/>
<output name="O" num_pins="20" equivalent="none"/>
<output name="sc_out" num_pins="1"/>
<output name="cout" num_pins="1"/>
<output name="cout_copy" num_pins="1"/>
<output name="regout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- Each input of the tile can be driven by 15% of routing tracks
Each output of the tile can drive 10% of routing tracks
There are four pins (cin, cout, sc_in, sc_out) has not connection
to routing tracks. There are directed wired from/to adjacent CLBs
-->
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10">
<fc_override port_name="cin" fc_type="frac" fc_val="0"/>
<fc_override port_name="cout" fc_type="frac" fc_val="0"/>
<fc_override port_name="sc_in" fc_type="frac" fc_val="0"/>
<fc_override port_name="sc_out" fc_type="frac" fc_val="0"/>
</fc>
<!-- Highly recommand to customize pin location when direct connection is used!!! -->
<!-- To ensure best tileable routing architecture (minimize the number of unique SBs
We keep all the pins that touch routing architecture on the right and bottom sides of the tile
Top side pins are mainly for direct connections
-->
<pinlocations pattern="custom">
<loc side="left"></loc>
<loc side="top">clb.sc_in clb.cin clb.cin_trick clb.regin clb.clk</loc>
<loc side="right">clb.I0[9:0] clb.I1[9:0] clb.O[9:0]</loc>
<loc side="bottom">clb.cout clb.cout_copy clb.sc_out clb.regout clb.I2[9:0] clb.I3[9:0] clb.O[19:10]</loc>
</pinlocations>
</tile>
<tile name="memory" height="2" area="548000">
<equivalent_sites>
<site pb_type="memory"/>
</equivalent_sites>
<input name="waddr" num_pins="10"/>
<input name="raddr" num_pins="10"/>
<input name="d_in" num_pins="32"/>
<input name="wen" num_pins="1"/>
<input name="ren" num_pins="1"/>
<output name="d_out" num_pins="32"/>
<clock name="clk" num_pins="1"/>
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10"/>
<pinlocations pattern="custom">
<loc side="left"></loc>
<loc side="top">memory.clk</loc>
<loc side="right">memory.waddr memory.d_in[15:0] memory.wen memory.d_out[15:0]</loc>
<loc side="bottom">memory.raddr memory.d_in[31:16] memory.ren memory.d_out[31:16]</loc>
</pinlocations>
</tile>
</tiles>
<!-- ODIN II specific config ends -->
<!-- Physical descriptions begin -->
<!-- Apply tileable routing architecture.
This is strongly recommended if you want to PnR large FPGA fabric
-->
<layout tileable="true">
<!-- auto_layout aspect_ratio="1.0" -->
<!-- Apply a fixed layout of 2x2 core array.
VPR8 considers the I/O ring in the array size
Therefore the height and width are both 4
-->
<fixed_layout name="32x32" width="34" height="34">
<!--Perimeter of 'io' blocks with 'EMPTY' blocks at corners-->
<perimeter type="io" priority="100"/>
<corners type="EMPTY" priority="101"/>
<!--Fill with 'clb'-->
<fill type="clb" priority="10"/>
<!--Column of 'memory' with 'EMPTY' blocks wherever a 'memory' does not fit. Vertical offset by 1 for perimeter.-->
<col type="memory" startx="16" starty="1" repeatx="16" priority="20"/>
<col type="EMPTY" startx="16" repeatx="16" starty="1" priority="19"/>
</fixed_layout>
<!--/auto_layout-->
</layout>
<device>
<sizing R_minW_nmos="8926" R_minW_pmos="16067"/>
<!-- The grid_logic_tile_area below will be used for all blocks that do not explicitly set their own (non-routing)
area; set to 0 since we explicitly set the area of all blocks currently in this architecture file.
-->
<area grid_logic_tile_area="0"/>
<chan_width_distr>
<x distr="uniform" peak="1.000000"/>
<y distr="uniform" peak="1.000000"/>
</chan_width_distr>
<!-- Use Wilton-style connecting pattern in switch block
Each routing track has access to only three other routing tracks
(one per each side of the switch block except the side where the routing track locates)
-->
<switch_block type="wilton" fs="3"/>
<connection_block input_switch_name="ipin_cblock"/>
</device>
<switchlist>
<switch type="mux" name="0" R="0" Cin="0" Cout="0" Tdel="200e-12" mux_trans_size="2.630740" buf_size="27.645901"/>
<switch type="mux" name="ipin_cblock" R="0." Cout="0." Cin="0" Tdel="210e-12" mux_trans_size="1.222260" buf_size="auto"/>
</switchlist>
<segmentlist>
<!-- GIVE a specific name for the segment! OpenFPGA appreciate that! -->
<!-- Uni-directional routing architecture using only length-4 wires in routing channels -->
<segment name="L4" freq="1.000000" length="4" type="unidir" Rmetal="0" Cmetal="0">
<mux name="0"/>
<sb type="pattern">1 1 1 1 1</sb>
<cb type="pattern">1 1 1 1</cb>
</segment>
</segmentlist>
<directlist>
<!-- Hard adder chain inside CLB is directly connected between adjacent CLBs -->
<direct name="adder_carry" from_pin="clb.cout" to_pin="clb.cin" x_offset="0" y_offset="-1" z_offset="0"/>
<!-- Scan chain inside CLB is directly connected between adjacent CLBs -->
<direct name="scff_chain" from_pin="clb.sc_out" to_pin="clb.sc_in" x_offset="0" y_offset="-1" z_offset="0"/>
</directlist>
<complexblocklist>
<!-- Define I/O pads begin -->
<!-- Capacity is a unique property of I/Os, it is the maximum number of I/Os that can be placed at the same (X,Y) location on the FPGA -->
<!-- Not sure of the area of an I/O (varies widely), and it's not relevant to the design of the FPGA core, so we're setting it to 0. -->
<pb_type name="io">
<input name="outpad" num_pins="1"/>
<output name="inpad" num_pins="1"/>
<!-- Do NOT add clock pins to I/O here!!! VPR does not build clock network in the way that OpenFPGA can support
If you need to register the I/O, define clocks in the circuit models
These clocks can be handled in back-end
-->
<!-- A mode denotes the physical implementation of an I/O
This mode will be not packable but is mainly used for fabric verilog generation
-->
<mode name="physical" packable="false">
<pb_type name="iopad" blif_model=".subckt io" num_pb="1">
<input name="outpad" num_pins="1"/>
<output name="inpad" num_pins="1"/>
</pb_type>
<interconnect>
<direct name="outpad" input="io.outpad" output="iopad.outpad">
<delay_constant max="0" in_port="io.outpad" out_port="iopad.outpad"/>
</direct>
<direct name="inpad" input="iopad.inpad" output="io.inpad">
<delay_constant max="0" in_port="iopad.inpad" out_port="io.inpad"/>
</direct>
</interconnect>
</mode>
<!-- IOs can operate as either inputs or outputs.
Delays below come from Ian Kuon. They are small, so they should be interpreted as
the delays to and from registers in the I/O (and generally I/Os are registered
today and that is when you timing analyze them.
-->
<mode name="inpad">
<pb_type name="inpad" blif_model=".input" num_pb="1">
<output name="inpad" num_pins="1"/>
</pb_type>
<interconnect>
<direct name="inpad" input="inpad.inpad" output="io.inpad">
<delay_constant max="0" in_port="inpad.inpad" out_port="io.inpad"/>
</direct>
</interconnect>
</mode>
<mode name="outpad">
<pb_type name="outpad" blif_model=".output" num_pb="1">
<input name="outpad" num_pins="1"/>
</pb_type>
<interconnect>
<direct name="outpad" input="io.outpad" output="outpad.outpad">
<delay_constant max="0" in_port="io.outpad" out_port="outpad.outpad"/>
</direct>
</interconnect>
</mode>
<power method="ignore"/>
</pb_type>
<!-- Define I/O pads ends -->
<!-- Define multi-mode Configurable Logic Block (CLB) begin -->
<!-- Technical highlight:
K6_frac_N10_I40_chain_shiftreg_depop50
- K6_frac: Each Logic Element (LE) contains a fracturable 6 LUT,
which can operate as one 6-LUT or two 5-LUTs or four 4-LUTs
In addition to 6-LUT, each LE also includes two Flip-Flops
- N10: every CLB consists of 10 LEs and a local routing architecture
- I40: every CLB has 40 inputs
- chain: a hard adder chain across all the LEs in a CLB
The inputs of adder are driven by 4-LUTs.
The sumout of adder can optional drive an LE output or a Flip-Flop
The carry-out of adder will drive the carry-in of the next adder in the chain
- shiftreg: Flip-flops inside CLB can be configured as shift registers.
The organization is similar the hard adder chain except it is programmable
- depop50: every local routing multiplexer accesses to 50% of the CLB inputs
-->
<pb_type name="clb">
<input name="I0" num_pins="10" equivalent="full"/>
<input name="I1" num_pins="10" equivalent="full"/>
<input name="I2" num_pins="10" equivalent="full"/>
<input name="I3" num_pins="10" equivalent="full"/>
<input name="sc_in" num_pins="1"/>
<input name="cin" num_pins="1"/>
<input name="cin_trick" num_pins="1"/>
<input name="regin" num_pins="1"/>
<output name="O" num_pins="20" equivalent="none"/>
<output name="sc_out" num_pins="1"/>
<output name="cout" num_pins="1"/>
<output name="cout_copy" num_pins="1"/>
<output name="regout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- Describe fracturable logic element -->
<pb_type name="fle" num_pb="10">
<input name="in" num_pins="6"/>
<input name="cin" num_pins="1"/>
<input name="sc_in" num_pins="1"/>
<input name="regin" num_pins="1"/>
<output name="out" num_pins="2"/>
<output name="cout" num_pins="1"/>
<output name="sc_out" num_pins="1"/>
<output name="regout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- Describe physical mode begins -->
<!-- Timing annotation is not require for unpackable mode
It will not be used by timing analyzer
-->
<mode name="physical" packable="false">
<pb_type name="frac_logic" num_pb="1">
<input name="in" num_pins="6"/>
<input name="cin" num_pins="1"/>
<input name="regin" num_pins="1"/>
<input name="regchain" num_pins="1"/>
<output name="out" num_pins="2"/>
<output name="cout" num_pins="1"/>
<pb_type name="frac_lut6" blif_model=".subckt frac_lut6" num_pb="1">
<input name="in" num_pins="6"/>
<output name="lut4_out" num_pins="4"/>
<output name="lut5_out" num_pins="2"/>
<output name="lut6_out" num_pins="1"/>
</pb_type>
<pb_type name="adder_phy" blif_model=".subckt adder" num_pb="2">
<input name="a" num_pins="1"/>
<input name="b" num_pins="1"/>
<input name="cin" num_pins="1"/>
<output name="cout" num_pins="1"/>
<output name="sumout" num_pins="1"/>
<delay_constant max="0.3e-9" in_port="adder_phy.a" out_port="adder_phy.sumout"/>
<delay_constant max="0.3e-9" in_port="adder_phy.b" out_port="adder_phy.sumout"/>
<delay_constant max="0.3e-9" in_port="adder_phy.cin" out_port="adder_phy.sumout"/>
<delay_constant max="0.3e-9" in_port="adder_phy.a" out_port="adder_phy.cout"/>
<delay_constant max="0.3e-9" in_port="adder_phy.b" out_port="adder_phy.cout"/>
<delay_constant max="0.3e-9" in_port="adder_phy.cin" out_port="adder_phy.cout"/>
</pb_type>
<interconnect>
<direct name="direct_fraclut_in" input="frac_logic.in[5:0]" output="frac_lut6.in[5:0]"/>
<direct name="direct_cin" input="frac_logic.cin" output="adder_phy[0].cin"/>
<direct name="direct_carry" input="adder_phy[0].cout" output="adder_phy[1].cin"/>
<direct name="direct_cout" input="adder_phy[1].cout" output="frac_logic.cout"/>
<direct name="direct_lut4carry0" input="frac_lut6.lut4_out[0]" output="adder_phy[0].a"/>
<direct name="direct_lut4carry1" input="frac_lut6.lut4_out[1]" output="adder_phy[0].b"/>
<direct name="direct_lut4carry2" input="frac_lut6.lut4_out[2]" output="adder_phy[1].a"/>
<direct name="direct_lut4carry3" input="frac_lut6.lut4_out[3]" output="adder_phy[1].b"/>
<mux name="mux1" input="adder_phy[0].sumout frac_lut6.lut5_out[0] frac_logic.regin" output="frac_logic.out[0]">
</mux>
<mux name="mux2" input="adder_phy[1].sumout frac_lut6.lut5_out[1] frac_lut6.lut6_out[0] frac_logic.regchain[0]" output="frac_logic.out[1]">
</mux>
</interconnect>
</pb_type>
<pb_type name="ff_phy" blif_model=".subckt scff" num_pb="2">
<input name="D" num_pins="1"/>
<input name="D_chain" num_pins="1"/>
<output name="Q" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<T_setup value="66e-12" port="ff_phy.D" clock="clk"/>
<T_setup value="66e-12" port="ff_phy.D_chain" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff_phy.Q" clock="clk"/>
</pb_type>
<interconnect>
<complete name="direct_clk" input="fle.clk" output="ff_phy[1:0].clk"/>
<direct name="direct_in" input="fle.in[5:0]" output="frac_logic.in[5:0]"/>
<direct name="direct_regin" input="fle.regin" output="frac_logic.regin"/>
<direct name="direct_regchain" input="ff_phy[0].Q" output="frac_logic.regchain"/>
<direct name="direct_regout" input="ff_phy[1].Q" output="fle.regout"/>
<direct name="direct_cin" input="fle.cin" output="frac_logic.cin"/>
<direct name="direct_cout" input="frac_logic.cout" output="fle.cout"/>
<direct name="direct_frac_out1" input="frac_logic.out[0]" output="ff_phy[0].D"/>
<direct name="direct_frac_out2" input="frac_logic.out[1]" output="ff_phy[1].D"/>
<direct name="direct_fle_scin" input="fle.sc_in" output="ff_phy[0].D_chain"/>
<direct name="direct_fle_sc_chain" input="ff_phy[0].Q" output="ff_phy[1].D_chain"/>
<direct name="direct_fle_scout" input="ff_phy[1].Q" output="fle.sc_out"/>
<mux name="mux1" input="ff_phy[0].Q frac_logic.out[0]" output="fle.out[0]">
</mux>
<mux name="mux2" input="ff_phy[1].Q frac_logic.out[1]" output="fle.out[1]">
</mux>
</interconnect>
</mode>
<!-- Define physical mode begins -->
<!-- Define n2_lut5 mode begins -->
<mode name="n2_lut5" packable="true">
<pb_type name="lut5inter" num_pb="1">
<input name="in" num_pins="5"/>
<input name="cin" num_pins="1"/>
<output name="out" num_pins="2"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<pb_type name="ble5" num_pb="2">
<input name="in" num_pins="5"/>
<input name="cin" num_pins="1"/>
<output name="out" num_pins="1"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<mode name="blut5">
<pb_type name="flut5" num_pb="1">
<input name="in" num_pins="5"/>
<output name="out" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- Regular LUT mode -->
<pb_type name="lut5" blif_model=".names" num_pb="1" class="lut">
<input name="in" num_pins="5" port_class="lut_in"/>
<output name="out" num_pins="1" port_class="lut_out"/>
<!-- LUT timing using delay matrix -->
<delay_matrix type="max" in_port="lut5.in" out_port="lut5.out">
193e-12
193e-12
193e-12
193e-12
193e-12
</delay_matrix>
</pb_type>
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="26e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="46e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="direct1" input="flut5.in" output="lut5.in"/>
<direct name="direct2" input="lut5.out" output="ff.D">
<pack_pattern name="ble5" in_port="lut5.out" out_port="ff.D"/>
</direct>
<direct name="direct3" input="flut5.clk" output="ff.clk"/>
<mux name="mux1" input="ff.Q lut5.out" output="flut5.out">
<delay_constant max="112e-12" in_port="lut5.out" out_port="flut5.out" />
<delay_constant max="48e-12" in_port="ff.Q" out_port="flut5.out" />
</mux>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="ble5.in" output="flut5.in"/>
<direct name="direct2" input="ble5.clk" output="flut5.clk"/>
<direct name="direct3" input="flut5.out" output="ble5.out"/>
</interconnect>
</mode>
<mode name="arithmetic">
<pb_type name="arithmetic" num_pb="1">
<input name="in" num_pins="4"/>
<input name="cin" num_pins="1"/>
<output name="out" num_pins="1"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- Special dual-LUT mode that drives adder only -->
<pb_type name="lut4" blif_model=".names" num_pb="2" class="lut">
<input name="in" num_pins="4" port_class="lut_in"/>
<output name="out" num_pins="1" port_class="lut_out"/>
<!-- LUT timing using delay matrix -->
<delay_matrix type="max" in_port="lut4.in" out_port="lut4.out">
161e-12
161e-12
161e-12
161e-12
</delay_matrix>
</pb_type>
<!-- Delay extracted from standard cell lib file
Consider the minimum slew and minimum load
-->
<pb_type name="adder" blif_model=".subckt adder" num_pb="1">
<input name="a" num_pins="1"/>
<input name="b" num_pins="1"/>
<input name="cin" num_pins="1"/>
<output name="cout" num_pins="1"/>
<output name="sumout" num_pins="1"/>
<delay_constant max="26e-12" in_port="adder.a" out_port="adder.sumout"/>
<delay_constant max="26e-12" in_port="adder.b" out_port="adder.sumout"/>
<delay_constant max="26e-12" in_port="adder.cin" out_port="adder.sumout"/>
<delay_constant max="26e-12" in_port="adder.a" out_port="adder.cout"/>
<delay_constant max="26e-12" in_port="adder.b" out_port="adder.cout"/>
<delay_constant max="26e-12" in_port="adder.cin" out_port="adder.cout"/>
</pb_type>
<!-- Delay extracted from standard cell lib file
Consider the minimum slew and minimum load
-->
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="26e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="46e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="clock" input="arithmetic.clk" output="ff.clk"/>
<direct name="lut_in1" input="arithmetic.in[3:0]" output="lut4[0:0].in[3:0]"/>
<direct name="lut_in2" input="arithmetic.in[3:0]" output="lut4[1:1].in[3:0]"/>
<direct name="lut_to_add1" input="lut4[0:0].out" output="adder.a">
</direct>
<direct name="lut_to_add2" input="lut4[1:1].out" output="adder.b">
</direct>
<direct name="add_to_ff" input="adder.sumout" output="ff.D">
<pack_pattern name="chain" in_port="adder.sumout" out_port="ff.D"/>
</direct>
<direct name="carry_in" input="arithmetic.cin" output="adder.cin">
<pack_pattern name="chain" in_port="arithmetic.cin" out_port="adder.cin"/>
</direct>
<direct name="carry_out" input="adder.cout" output="arithmetic.cout">
<pack_pattern name="chain" in_port="adder.cout" out_port="arithmetic.cout"/>
</direct>
<!-- Timing is extracted from the physical implementation
The path from ff.Q to arithmetic.out consists of a routing multiplexer
The path from adder.sumout to arithmetic.out consists of two routing multiplexers
One multiplexer connects from adder to ff.D
Another connects from the ff.D to arithmetic.out
-->
<mux name="sumout" input="ff.Q adder.sumout" output="arithmetic.out">
<delay_constant max="112e-12" in_port="adder.sumout" out_port="arithmetic.out"/>
<delay_constant max="48e-12" in_port="ff.Q" out_port="arithmetic.out" />
</mux>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="ble5.in[3:0]" output="arithmetic.in"/>
<direct name="carry_in" input="ble5.cin" output="arithmetic.cin">
</direct>
<direct name="carry_out" input="arithmetic.cout" output="ble5.cout">
</direct>
<direct name="direct2" input="ble5.clk" output="arithmetic.clk"/>
<direct name="direct3" input="arithmetic.out" output="ble5.out"/>
</interconnect>
</mode>
</pb_type>
<interconnect>
<direct name="direct1" input="lut5inter.in" output="ble5[0:0].in"/>
<direct name="direct2" input="lut5inter.in" output="ble5[1:1].in"/>
<direct name="direct3" input="ble5[1:0].out" output="lut5inter.out"/>
<direct name="carry_in" input="lut5inter.cin" output="ble5[0:0].cin">
</direct>
<direct name="carry_out" input="ble5[1:1].cout" output="lut5inter.cout">
</direct>
<direct name="carry_link" input="ble5[0:0].cout" output="ble5[1:1].cin">
</direct>
<complete name="complete1" input="lut5inter.clk" output="ble5[1:0].clk"/>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="fle.in[4:0]" output="lut5inter.in"/>
<direct name="direct2" input="lut5inter.out" output="fle.out"/>
<direct name="direct3" input="fle.clk" output="lut5inter.clk"/>
<direct name="carry_in" input="fle.cin" output="lut5inter.cin">
</direct>
<direct name="carry_out" input="lut5inter.cout" output="fle.cout">
</direct>
</interconnect>
</mode>
<!-- Define n2_lut5 mode ends -->
<mode name="n1_lut6">
<pb_type name="ble6" num_pb="1">
<input name="in" num_pins="6"/>
<output name="out" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<pb_type name="lut6" blif_model=".names" num_pb="1" class="lut">
<input name="in" num_pins="6" port_class="lut_in"/>
<output name="out" num_pins="1" port_class="lut_out"/>
<!-- LUT timing using delay matrix -->
<delay_matrix type="max" in_port="lut6.in" out_port="lut6.out">
230e-12
230e-12
230e-12
230e-12
230e-12
230e-12
</delay_matrix>
</pb_type>
<!-- Delay extracted from standard cell lib file
Consider the minimum slew and minimum load
-->
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="26e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="46e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="direct1" input="ble6.in" output="lut6[0:0].in"/>
<direct name="direct2" input="lut6.out" output="ff.D">
<pack_pattern name="ble6" in_port="lut6.out" out_port="ff.D"/>
</direct>
<direct name="direct3" input="ble6.clk" output="ff.clk"/>
<mux name="mux1" input="ff.Q lut6.out" output="ble6.out">
<delay_constant max="112e-12" in_port="lut6.out" out_port="ble6.out" />
<delay_constant max="48e-12" in_port="ff.Q" out_port="ble6.out" />
</mux>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="fle.in" output="ble6.in"/>
<direct name="direct2" input="ble6.out" output="fle.out[1:1]"/>
<direct name="direct3" input="fle.clk" output="ble6.clk"/>
</interconnect>
</mode>
<!-- Define n1_lut6 mode ends -->
<!-- Define shift register mode begins -->
<mode name="shift_register">
<pb_type name="ble_shift" num_pb="1">
<input name="in" num_pins="1"/>
<output name="out" num_pins="2"/>
<output name="regout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<pb_type name="ff" blif_model=".subckt shift" num_pb="2" class="flipflop">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="26e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="46e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="direct1" input="ble_shift.in" output="ff[0].D"/>
<direct name="direct2" input="ff[0].Q" output="ff[1].D">
<!--pack_pattern name="ble_shift" in_port="ff[0].Q" out_port="ff[1].D"/-->
</direct>
<direct name="out1" input="ff[0].Q" output="ble_shift.out[0]"/>
<direct name="out2" input="ff[1].Q" output="ble_shift.out[1]"/>
<direct name="direct_regout" input="ff[1].Q" output="ble_shift.regout"/>
<complete name="direct3" input="ble_shift.clk" output="ff[1:0].clk"/>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="fle.regin" output="ble_shift.in"/>
<direct name="direct2" input="ble_shift.out" output="fle.out"/>
<direct name="direct3" input="fle.clk" output="ble_shift.clk"/>
<direct name="direct4" input="ble_shift.regout" output="fle.regout"/>
</interconnect>
</mode>
<!-- Define shift_register mode end -->
</pb_type>
<interconnect>
<complete name="crossbar0" input="clb.I2 clb.I3 fle[9:0].out" output="fle[9:0].in[0]">
<delay_constant max="230e-12" in_port="clb.I2 clb.I3" out_port="fle[9:0].in[0]" />
<delay_constant max="230e-12" in_port="fle[9:0].out" out_port="fle[9:0].in[0]" />
</complete>
<complete name="crossbar1" input="clb.I1 clb.I2 fle[9:0].out" output="fle[9:0].in[1]">
<delay_constant max="230e-12" in_port="clb.I1 clb.I2" out_port="fle[9:0].in[1]" />
<delay_constant max="230e-12" in_port="fle[9:0].out" out_port="fle[9:0].in[1]" />
</complete>
<complete name="crossbar2" input="clb.I0 clb.I1 fle[9:0].out" output="fle[9:0].in[2]">
<delay_constant max="230e-12" in_port="clb.I0 clb.I1" out_port="fle[9:0].in[2]" />
<delay_constant max="230e-12" in_port="fle[9:0].out" out_port="fle[9:0].in[2]" />
</complete>
<complete name="crossbar3" input="clb.I1 clb.I3 fle[9:0].out" output="fle[9:0].in[3]">
<delay_constant max="230e-12" in_port="clb.I1 clb.I3" out_port="fle[9:0].in[3]" />
<delay_constant max="230e-12" in_port="fle[9:0].out" out_port="fle[9:0].in[3]" />
</complete>
<complete name="crossbar4" input="clb.I0 clb.I2 fle[9:0].out" output="fle[9:0].in[4]">
<delay_constant max="230e-12" in_port="clb.I0 clb.I2" out_port="fle[9:0].in[4]" />
<delay_constant max="230e-12" in_port="fle[9:0].out" out_port="fle[9:0].in[4]" />
</complete>
<complete name="crossbar5" input="clb.I0 clb.I3 fle[9:0].out" output="fle[9:0].in[5]">
<delay_constant max="230e-12" in_port="clb.I0 clb.I3" out_port="fle[9:0].in[5]" />
<delay_constant max="230e-12" in_port="fle[9:0].out" out_port="fle[9:0].in[5]" />
</complete>
<complete name="clks" input="clb.clk" output="fle[9:0].clk">
</complete>
<complete name="carry_in" input="clb.cin clb.cin_trick fle[9:0].out" output="fle[0:0].cin">
<!-- Put all inter-block carry chain delay on this one edge -->
<!--delay_constant max="0.15e-9" in_port="clb.cin clb.cin_trick" out_port="fle[0:0].cin"/-->
<pack_pattern name="chain" in_port="clb.cin" out_port="fle[0:0].cin"/>
<!--pack_pattern name="chain" in_port="clb.cin_trick" out_port="fle[0:0].cin"/-->
</complete>
<!--direct name="carry_in" input="clb.cin" output="fle[0:0].cin">
<pack_pattern name="chain" in_port="clb.cin" out_port="fle[0:0].cin"/>
</direct-->
<direct name="clbouts1" input="fle[9:0].out[0:0]" output="clb.O[9:0]">
<delay_constant max="172e-12" in_port="fle[9:0].out[0:0]" out_port="clb.O[9:0]"/>
</direct>
<direct name="clbouts2" input="fle[9:0].out[1:1]" output="clb.O[19:10]">
<delay_constant max="172e-12" in_port="fle[9:0].out[1:1]" out_port="clb.O[19:10]"/>
</direct>
<direct name="cout_copy" input="fle[9:9].cout" output="clb.cout_copy"/>
<!-- Shift register links -->
<direct name="regin" input="clb.regin" output="fle[0:0].regin">
<!-- Put all inter-block carry chain delay on this one edge -->
<delay_constant max="0e-9" in_port="clb.regin" out_port="fle[0:0].regin"/>
<pack_pattern name="chain" in_port="clb.regin" out_port="fle[0:0].regin"/>
</direct>
<direct name="regout" input="fle[9:9].regout" output="clb.regout">
<pack_pattern name="chain" in_port="fle[9:9].regout" out_port="clb.regout"/>
</direct>
<direct name="reg_link" input="fle[8:0].regout" output="fle[9:1].regin">
<pack_pattern name="chain" in_port="fle[8:0].regout" out_port="fle[9:1].regin"/>
</direct>
<!-- Carry chain links -->
<direct name="carry_out" input="fle[9:9].cout" output="clb.cout">
<pack_pattern name="chain" in_port="fle[9:9].cout" out_port="clb.cout"/>
</direct>
<direct name="carry_link" input="fle[8:0].cout" output="fle[9:1].cin">
<pack_pattern name="chain" in_port="fle[8:0].cout" out_port="fle[9:1].cin"/>
</direct>
<!-- Scan chain links -->
<direct name="sc_in" input="clb.sc_in" output="fle[0:0].sc_in">
</direct>
<direct name="sc_out" input="fle[9:9].sc_out" output="clb.sc_out">
</direct>
<direct name="sc_link" input="fle[8:0].sc_out" output="fle[9:1].sc_in">
</direct>
</interconnect>
</pb_type>
<!-- Define general purpose logic block (CLB) ends -->
<!-- Define single-mode dual-port memory begin -->
<pb_type name="memory">
<input name="waddr" num_pins="10"/>
<input name="raddr" num_pins="10"/>
<input name="d_in" num_pins="32"/>
<input name="wen" num_pins="1"/>
<input name="ren" num_pins="1"/>
<output name="d_out" num_pins="32"/>
<clock name="clk" num_pins="1"/>
<!-- Specify the 512x32=16Kbit memory block
Note: the delay numbers are extracted from VPR flagship XML without modification
Should align to the process technology we using to create the 16K dual-port RAM
-->
<mode name="mem_512x32_dp">
<pb_type name="mem_512x32_dp" blif_model=".subckt dual_port_ram" class="memory" num_pb="1">
<input name="waddr" num_pins="10" port_class="address"/>
<input name="raddr" num_pins="10" port_class="address"/>
<input name="d_in" num_pins="32" port_class="data_in"/>
<input name="wen" num_pins="1" port_class="write_en"/>
<input name="ren" num_pins="1" port_class="write_en"/>
<output name="d_out" num_pins="32" port_class="data_out"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<!-- TODO the setup time and clk2Q delay should be extracted from BRAM LIB -->
<T_setup value="509e-12" port="mem_512x32_dp.waddr" clock="clk"/>
<T_setup value="509e-12" port="mem_512x32_dp.raddr" clock="clk"/>
<T_setup value="509e-12" port="mem_512x32_dp.d_in" clock="clk"/>
<T_setup value="509e-12" port="mem_512x32_dp.wen" clock="clk"/>
<T_setup value="509e-12" port="mem_512x32_dp.ren" clock="clk"/>
<T_clock_to_Q max="1.234e-9" port="mem_512x32_dp.d_out" clock="clk"/>
<power method="pin-toggle">
<port name="clk" energy_per_toggle="17.9e-12"/>
<static_power power_per_instance="0.0"/>
</power>
</pb_type>
<interconnect>
<direct name="waddress" input="memory.waddr" output="mem_512x32_dp.waddr">
<delay_constant max="132e-12" in_port="memory.waddr" out_port="mem_512x32_dp.waddr"/>
</direct>
<direct name="raddress" input="memory.raddr" output="mem_512x32_dp.raddr">
<delay_constant max="132e-12" in_port="memory.raddr" out_port="mem_512x32_dp.raddr"/>
</direct>
<direct name="data_input" input="memory.d_in" output="mem_512x32_dp.d_in">
<delay_constant max="132e-12" in_port="memory.d_in" out_port="mem_512x32_dp.d_in"/>
</direct>
<direct name="writeen" input="memory.wen" output="mem_512x32_dp.wen">
<delay_constant max="132e-12" in_port="memory.wen" out_port="mem_512x32_dp.wen"/>
</direct>
<direct name="readen" input="memory.ren" output="mem_512x32_dp.ren">
<delay_constant max="132e-12" in_port="memory.ren" out_port="mem_512x32_dp.ren"/>
</direct>
<direct name="dataout" input="mem_512x32_dp.d_out" output="memory.d_out">
<delay_constant max="40e-12" in_port="mem_512x32_dp.d_out" out_port="memory.d_out"/>
</direct>
<direct name="clk" input="memory.clk" output="mem_512x32_dp.clk">
</direct>
</interconnect>
</mode>
</pb_type>
<!-- Define single-mode dual-port memory end -->
</complexblocklist>
</architecture>

View File

@ -1,14 +0,0 @@
`timescale 1ns / 1ps
module top(
a,
b,
c);
input wire a;
input wire b;
output wire c;
assign c = a & b;
endmodule

View File

@ -1,4 +1,4 @@
.model top .model and2
.inputs a b .inputs a b
.outputs c .outputs c

View File

@ -0,0 +1,18 @@
/////////////////////////////////////////
// Functionality: 2-input AND
// Author: Xifan Tang
////////////////////////////////////////
`timescale 1ns / 1ps
module and2(
a,
b,
c);
input wire a;
input wire b;
output wire c;
assign c = a & b;
endmodule

View File

@ -1,5 +1,5 @@
# Benchmark "top" written by ABC on Wed Mar 11 10:36:28 2020 # Benchmark "and2_latch" written by ABC on Wed Mar 11 10:36:28 2020
.model top .model and2_latch
.inputs a b clk .inputs a b clk
.outputs c d .outputs c d

View File

@ -0,0 +1,29 @@
/////////////////////////////////////////
// Functionality: 2-input AND with clocked
// and combinational outputs
// Author: Xifan Tang
////////////////////////////////////////
`timescale 1ns / 1ps
module and2_latch(
a,
b,
clk,
c,
d);
input wire clk;
input wire a;
input wire b;
output wire c;
output reg d;
assign c = a & b;
always @(posedge clk) begin
d <= c;
end
endmodule

View File

@ -1,23 +0,0 @@
`timescale 1ns / 1ps
module top(
clk,
a,
b,
c,
d);
input wire clk;
input wire a;
input wire b;
output wire c;
output reg d;
assign c = a & b;
always @(posedge clk) begin
d <= c;
end
endmodule

View File

@ -146,11 +146,11 @@
<design_technology type="cmos"/> <design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/> <input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/> <output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="input" prefix="pReset" size="1" is_global="true" default_val="0" is_reset="true" is_prog="true"/> <port type="input" prefix="pReset" lib_name="reset" size="1" is_global="true" default_val="0" is_reset="true" is_prog="true"/>
<port type="input" prefix="D" size="1"/> <port type="input" prefix="D" size="1"/>
<port type="output" prefix="Q" size="1"/> <port type="output" prefix="Q" size="1"/>
<port type="output" prefix="Qb" size="1"/> <port type="output" prefix="Qb" size="1"/>
<port type="clock" prefix="prog_clk" size="1" is_global="true" default_val="0" is_prog="true"/> <port type="clock" prefix="prog_clk" lib_name="clk" size="1" is_global="true" default_val="0" is_prog="true"/>
</circuit_model> </circuit_model>
<circuit_model type="iopad" name="iopad" prefix="iopad" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/SpiceNetlists/io.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/VerilogNetlists/io.v"> <circuit_model type="iopad" name="iopad" prefix="iopad" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/SpiceNetlists/io.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/VerilogNetlists/io.v">
<design_technology type="cmos"/> <design_technology type="cmos"/>

View File

@ -0,0 +1,289 @@
<!-- Architecture annotation for OpenFPGA framework
This annotation supports the k6_N10_40nm.xml
- General purpose logic block
- K = 6, N = 10, I = 40
- Single mode
- Routing architecture
- L = 4, fc_in = 0.15, fc_out = 0.1
-->
<openfpga_architecture>
<technology_library>
<device_library>
<device_model name="logic" type="transistor">
<lib type="industry" corner="TOP_TT" ref="M" path="${OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.pm"/>
<design vdd="0.9" pn_ratio="2"/>
<pmos name="pch" chan_length="40e-9" min_width="140e-9" variation="logic_transistor_var"/>
<nmos name="nch" chan_length="40e-9" min_width="140e-9" variation="logic_transistor_var"/>
</device_model>
<device_model name="io" type="transistor">
<lib type="academia" ref="M" path="${OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.pm"/>
<design vdd="2.5" pn_ratio="3"/>
<pmos name="pch_25" chan_length="270e-9" min_width="320e-9" variation="io_transistor_var"/>
<nmos name="nch_25" chan_length="270e-9" min_width="320e-9" variation="io_transistor_var"/>
</device_model>
</device_library>
<variation_library>
<variation name="logic_transistor_var" abs_deviation="0.1" num_sigma="3"/>
<variation name="io_transistor_var" abs_deviation="0.1" num_sigma="3"/>
</variation_library>
</technology_library>
<circuit_library>
<circuit_model type="inv_buf" name="INVTX1" prefix="INVTX1" is_default="true">
<design_technology type="cmos" topology="inverter" size="1"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="in" out_port="out">
10e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in" out_port="out">
10e-12
</delay_matrix>
</circuit_model>
<circuit_model type="inv_buf" name="buf4" prefix="buf4" is_default="false">
<design_technology type="cmos" topology="buffer" size="1" num_level="2" f_per_stage="4"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="in" out_port="out">
10e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in" out_port="out">
10e-12
</delay_matrix>
</circuit_model>
<circuit_model type="inv_buf" name="tap_buf4" prefix="tap_buf4" is_default="false">
<design_technology type="cmos" topology="buffer" size="1" num_level="3" f_per_stage="4"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="in" out_port="out">
10e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in" out_port="out">
10e-12
</delay_matrix>
</circuit_model>
<circuit_model type="gate" name="OR2" prefix="OR2" is_default="true">
<design_technology type="cmos" topology="OR"/>
<input_buffer exist="false"/>
<output_buffer exist="false"/>
<port type="input" prefix="a" size="1"/>
<port type="input" prefix="b" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="a b" out_port="out">
10e-12 5e-12
</delay_matrix>
<delay_matrix type="fall" in_port="a b" out_port="out">
10e-12 5e-12
</delay_matrix>
</circuit_model>
<circuit_model type="pass_gate" name="TGATE" prefix="TGATE" is_default="true">
<design_technology type="cmos" topology="transmission_gate" nmos_size="1" pmos_size="2"/>
<input_buffer exist="false"/>
<output_buffer exist="false"/>
<port type="input" prefix="in" size="1"/>
<port type="input" prefix="sel" size="1"/>
<port type="input" prefix="selb" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="in sel selb" out_port="out">
10e-12 5e-12 5e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in sel selb" out_port="out">
10e-12 5e-12 5e-12
</delay_matrix>
</circuit_model>
<circuit_model type="chan_wire" name="chan_segment" prefix="track_seg" is_default="true">
<design_technology type="cmos"/>
<input_buffer exist="false"/>
<output_buffer exist="false"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<wire_param model_type="pi" R="101" C="22.5e-15" num_level="1"/> <!-- model_type could be T, res_val and cap_val DON'T CARE -->
</circuit_model>
<circuit_model type="wire" name="direct_interc" prefix="direct_interc" is_default="true">
<design_technology type="cmos"/>
<input_buffer exist="false"/>
<output_buffer exist="false"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<wire_param model_type="pi" R="0" C="0" num_level="1"/> <!-- model_type could be T, res_val cap_val should be defined -->
</circuit_model>
<circuit_model type="mux" name="mux_2level" prefix="mux_2level" dump_structural_verilog="true">
<design_technology type="cmos" structure="multi_level" num_level="2" add_const_input="true" const_input_val="1"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="1"/>
</circuit_model>
<circuit_model type="mux" name="mux_2level_tapbuf" prefix="mux_2level_tapbuf" dump_structural_verilog="true">
<design_technology type="cmos" structure="multi_level" num_level="2" add_const_input="true" const_input_val="1"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="tap_buf4"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="1"/>
</circuit_model>
<circuit_model type="mux" name="mux_1level_tapbuf" prefix="mux_1level_tapbuf" is_default="true" dump_structural_verilog="true">
<design_technology type="cmos" structure="one_level" add_const_input="true" const_input_val="1"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="tap_buf4"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="1"/>
</circuit_model>
<!--DFF subckt ports should be defined as <D> <Q> <CLK> <RESET> <SET>
This is flip-flop with scan-chain feature.
When the TESTEN is enabled, the data will be propagated form DI instead of D
-->
<circuit_model type="ff" name="scan_chain_ff" prefix="scan_chain_ff" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/SpiceNetlists/ff.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/VerilogNetlists/ff.v">
<design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="input" prefix="D" size="1"/>
<port type="input" prefix="D_chain" lib_name="DI" size="1"/>
<port type="input" prefix="TESTEN" size="1" is_global="true" default_val="0"/>
<port type="input" prefix="set" size="1" is_global="true" default_val="0" is_set="true"/>
<port type="input" prefix="reset" size="1" is_global="true" default_val="0" is_reset="true"/>
<port type="output" prefix="Q" size="1"/>
<port type="clock" prefix="clk" size="1" is_global="true" default_val="0" />
</circuit_model>
<circuit_model type="lut" name="frac_lut6" prefix="frac_lut6" dump_structural_verilog="true">
<design_technology type="cmos" fracturable_lut="true"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<lut_input_inverter exist="true" circuit_model_name="INVTX1"/>
<lut_input_buffer exist="true" circuit_model_name="buf4"/>
<lut_intermediate_buffer exist="true" circuit_model_name="buf4" location_map="-1-1-"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="6" tri_state_map="----11" circuit_model_name="OR2"/>
<port type="output" prefix="lut4_out" size="4" lut_frac_level="4" lut_output_mask="0,1,2,3"/>
<port type="output" prefix="lut5_out" size="2" lut_frac_level="5" lut_output_mask="0,1"/>
<port type="output" prefix="lut6_out" size="1" lut_output_mask="0"/>
<port type="sram" prefix="sram" size="64"/>
<port type="sram" prefix="mode" size="2" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/>
</circuit_model>
<!--Scan-chain DFF subckt ports should be defined as <D> <Q> <Qb> <CLK> <RESET> <SET> -->
<circuit_model type="ccff" name="sc_dff_compact" prefix="scff" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/SpiceNetlists/ff.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/VerilogNetlists/ff.v">
<design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="input" prefix="pReset" lib_name="reset" size="1" is_global="true" default_val="0" is_reset="true" is_prog="true"/>
<port type="input" prefix="D" size="1"/>
<port type="output" prefix="Q" size="1"/>
<port type="output" prefix="Qb" size="1"/>
<port type="clock" prefix="prog_clk" lib_name="clk" size="1" is_global="true" default_val="0" is_prog="true"/>
</circuit_model>
<circuit_model type="iopad" name="iopad" prefix="iopad" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/SpiceNetlists/io.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/VerilogNetlists/io.v">
<design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="inout" prefix="pad" size="1" is_global="true" is_io="true"/>
<port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/>
<port type="input" prefix="outpad" size="1"/>
<port type="output" prefix="inpad" size="1"/>
</circuit_model>
<circuit_model type="hard_logic" name="adder" prefix="adder" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/SpiceNetlists/adder.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/VerilogNetlists/adder.v">
<design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="input" prefix="a" size="1"/>
<port type="input" prefix="b" size="1"/>
<port type="input" prefix="cin" size="1"/>
<port type="output" prefix="sumout" size="1"/>
<port type="output" prefix="cout" size="1"/>
</circuit_model>
</circuit_library>
<configuration_protocol>
<organization type="scan_chain" circuit_model_name="sc_dff_compact"/>
</configuration_protocol>
<connection_block>
<switch name="ipin_cblock" circuit_model_name="mux_2level_tapbuf"/>
</connection_block>
<switch_block>
<switch name="0" circuit_model_name="mux_2level_tapbuf"/>
</switch_block>
<routing_segment>
<segment name="L4" circuit_model_name="chan_segment"/>
</routing_segment>
<direct_connection>
<direct name="adder_carry" circuit_model_name="direct_interc"/>
<direct name="scff_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
</direct_connection>
<pb_type_annotations>
<!-- physical pb_type binding in complex block IO -->
<pb_type name="io" physical_mode_name="physical" idle_mode_name="inpad"/>
<pb_type name="io[physical].iopad" circuit_model_name="iopad" mode_bits="1"/>
<pb_type name="io[inpad].inpad" physical_pb_type_name="io[physical].iopad" mode_bits="1"/>
<pb_type name="io[outpad].outpad" physical_pb_type_name="io[physical].iopad" mode_bits="0"/>
<!-- End physical pb_type binding in complex block IO -->
<!-- physical pb_type binding in complex block CLB -->
<!-- physical mode will be the default mode if not specified -->
<pb_type name="clb.fle" physical_mode_name="physical"/>
<pb_type name="clb.fle[physical].frac_logic.frac_lut6" circuit_model_name="frac_lut6" mode_bits="11"/>
<pb_type name="clb.fle[physical].ff_phy" circuit_model_name="scan_chain_ff"/>
<pb_type name="clb.fle[physical].frac_logic.adder_phy" circuit_model_name="adder"/>
<!-- Binding operating pb_type to physical pb_type -->
<!-- Binding operating pb_types in mode 'n2_lut5' -->
<pb_type name="clb.fle[n2_lut5].lut5inter.ble5[blut5].flut5.lut5" physical_pb_type_name="clb.fle[physical].frac_logic.frac_lut6" mode_bits="01" physical_pb_type_index_factor="0.5">
<!-- Binding the lut5 to the first 5 inputs of fracturable lut6 -->
<port name="in" physical_mode_port="in[0:4]"/>
<port name="out" physical_mode_port="lut5_out[0:0]" physical_mode_pin_rotate_offset="1"/>
</pb_type>
<pb_type name="clb.fle[n2_lut5].lut5inter.ble5[blut5].flut5.ff" physical_pb_type_name="clb.fle[physical].ff_phy"/>
<!-- Binding operating pb_types in mode 'arithmetic' -->
<pb_type name="clb.fle[n2_lut5].lut5inter.ble5[arithmetic].arithmetic.lut4" physical_pb_type_name="clb.fle[physical].frac_logic.frac_lut6" mode_bits="11" physical_pb_type_index_factor="0.25">
<!-- Binding the lut4 to the first 4 inputs of fracturable lut6 -->
<port name="in" physical_mode_port="in[0:3]"/>
<port name="out" physical_mode_port="lut4_out[0:0]" physical_mode_pin_rotate_offset="1"/>
</pb_type>
<pb_type name="clb.fle[n2_lut5].lut5inter.ble5[arithmetic].arithmetic.adder" physical_pb_type_name="clb.fle[physical].frac_logic.adder_phy"/>
<pb_type name="clb.fle[n2_lut5].lut5inter.ble5[arithmetic].arithmetic.ff" physical_pb_type_name="clb.fle[physical].ff_phy"/>
<!-- Binding operating pb_types in mode 'ble6' -->
<pb_type name="clb.fle[n1_lut6].ble6.lut6" physical_pb_type_name="clb.fle[physical].frac_logic.frac_lut6" mode_bits="00">
<!-- Binding the lut6 to the first 6 inputs of fracturable lut6 -->
<port name="in" physical_mode_port="in[0:5]"/>
<port name="out" physical_mode_port="lut6_out"/>
</pb_type>
<pb_type name="clb.fle[n1_lut6].ble6.ff" physical_pb_type_name="clb.fle[physical].ff_phy" physical_pb_type_index_factor="2" physical_pb_type_index_offset="1"/>
<!-- Binding operating pb_types in mode 'shift_register' -->
<pb_type name="clb.fle[shift_register].ble_shift.ff" physical_pb_type_name="clb.fle[physical].ff_phy"/>
<!-- End physical pb_type binding in complex block CLB -->
</pb_type_annotations>
</openfpga_architecture>
<openfpga_simulation_setting>
<clock_setting>
<!--operating frequency="auto" num_cycles="auto" slack="0.2"/-->
<operating frequency="200e6" num_cycles="auto" slack="0.2"/>
<programming frequency="10e6"/>
</clock_setting>
<simulator_option>
<operating_condition temperature="25"/>
<output_log verbose="false" captab="false"/>
<accuracy type="abs" value="1e-13"/>
<runtime fast_simulation="true"/>
</simulator_option>
<monte_carlo num_simulation_points="2"/>
<measurement_setting>
<slew>
<rise upper_thres_pct="0.95" lower_thres_pct="0.05"/>
<fall upper_thres_pct="0.05" lower_thres_pct="0.95"/>
</slew>
<delay>
<rise input_thres_pct="0.5" output_thres_pct="0.5"/>
<fall input_thres_pct="0.5" output_thres_pct="0.5"/>
</delay>
</measurement_setting>
<stimulus>
<clock>
<rise slew_type="abs" slew_time="20e-12" />
<fall slew_type="abs" slew_time="20e-12" />
</clock>
<input>
<rise slew_type="abs" slew_time="25e-12" />
<fall slew_type="abs" slew_time="25e-12" />
</input>
</stimulus>
</openfpga_simulation_setting>

View File

@ -0,0 +1,373 @@
<!-- Architecture annotation for OpenFPGA framework
This annotation supports the k6_N10_40nm.xml
- General purpose logic block
- K = 6, N = 10, I = 40
- Single mode
- Routing architecture
- L = 4, fc_in = 0.15, fc_out = 0.1
-->
<openfpga_architecture>
<technology_library>
<device_library>
<device_model name="logic" type="transistor">
<lib type="industry" corner="TOP_TT" ref="M" path="${OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.pm"/>
<design vdd="0.9" pn_ratio="2"/>
<pmos name="pch" chan_length="40e-9" min_width="140e-9" variation="logic_transistor_var"/>
<nmos name="nch" chan_length="40e-9" min_width="140e-9" variation="logic_transistor_var"/>
</device_model>
<device_model name="io" type="transistor">
<lib type="academia" ref="M" path="${OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.pm"/>
<design vdd="2.5" pn_ratio="3"/>
<pmos name="pch_25" chan_length="270e-9" min_width="320e-9" variation="io_transistor_var"/>
<nmos name="nch_25" chan_length="270e-9" min_width="320e-9" variation="io_transistor_var"/>
</device_model>
</device_library>
<variation_library>
<variation name="logic_transistor_var" abs_deviation="0.1" num_sigma="3"/>
<variation name="io_transistor_var" abs_deviation="0.1" num_sigma="3"/>
</variation_library>
</technology_library>
<circuit_library>
<circuit_model type="inv_buf" name="INVTX1" prefix="INVTX1" is_default="true">
<design_technology type="cmos" topology="inverter" size="1"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="in" out_port="out">
10e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in" out_port="out">
10e-12
</delay_matrix>
</circuit_model>
<circuit_model type="inv_buf" name="buf4" prefix="buf4" is_default="false">
<design_technology type="cmos" topology="buffer" size="1" num_level="2" f_per_stage="4"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="in" out_port="out">
10e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in" out_port="out">
10e-12
</delay_matrix>
</circuit_model>
<circuit_model type="inv_buf" name="tap_buf4" prefix="tap_buf4" is_default="false">
<design_technology type="cmos" topology="buffer" size="1" num_level="3" f_per_stage="4"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="in" out_port="out">
10e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in" out_port="out">
10e-12
</delay_matrix>
</circuit_model>
<circuit_model type="gate" name="OR2" prefix="OR2" is_default="true">
<design_technology type="cmos" topology="OR"/>
<input_buffer exist="false"/>
<output_buffer exist="false"/>
<port type="input" prefix="a" size="1"/>
<port type="input" prefix="b" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="a b" out_port="out">
10e-12 5e-12
</delay_matrix>
<delay_matrix type="fall" in_port="a b" out_port="out">
10e-12 5e-12
</delay_matrix>
</circuit_model>
<circuit_model type="pass_gate" name="TGATE" prefix="TGATE" is_default="true">
<design_technology type="cmos" topology="transmission_gate" nmos_size="1" pmos_size="2"/>
<input_buffer exist="false"/>
<output_buffer exist="false"/>
<port type="input" prefix="in" size="1"/>
<port type="input" prefix="sel" size="1"/>
<port type="input" prefix="selb" size="1"/>
<port type="output" prefix="out" size="1"/>
<delay_matrix type="rise" in_port="in sel selb" out_port="out">
10e-12 5e-12 5e-12
</delay_matrix>
<delay_matrix type="fall" in_port="in sel selb" out_port="out">
10e-12 5e-12 5e-12
</delay_matrix>
</circuit_model>
<circuit_model type="chan_wire" name="chan_segment" prefix="track_seg" is_default="true">
<design_technology type="cmos"/>
<input_buffer exist="false"/>
<output_buffer exist="false"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<wire_param model_type="pi" R="101" C="22.5e-15" num_level="1"/> <!-- model_type could be T, res_val and cap_val DON'T CARE -->
</circuit_model>
<circuit_model type="wire" name="direct_interc" prefix="direct_interc" is_default="true">
<design_technology type="cmos"/>
<input_buffer exist="false"/>
<output_buffer exist="false"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<wire_param model_type="pi" R="0" C="0" num_level="1"/> <!-- model_type could be T, res_val cap_val should be defined -->
</circuit_model>
<circuit_model type="mux" name="mux_2level" prefix="mux_2level" dump_structural_verilog="true">
<design_technology type="cmos" structure="multi_level" num_level="2" add_const_input="true" const_input_val="1"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="1"/>
</circuit_model>
<circuit_model type="mux" name="mux_2level_tapbuf" prefix="mux_2level_tapbuf" dump_structural_verilog="true">
<design_technology type="cmos" structure="multi_level" num_level="2" add_const_input="true" const_input_val="1"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="tap_buf4"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="1"/>
</circuit_model>
<circuit_model type="mux" name="mux_1level_tapbuf" prefix="mux_1level_tapbuf" is_default="true" dump_structural_verilog="true">
<design_technology type="cmos" structure="one_level" add_const_input="true" const_input_val="1"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="tap_buf4"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="1"/>
<port type="output" prefix="out" size="1"/>
<port type="sram" prefix="sram" size="1"/>
</circuit_model>
<!--DFF subckt ports should be defined as <D> <Q> <CLK> <RESET> <SET>
This is flip-flop with scan-chain feature.
When the TESTEN is enabled, the data will be propagated form DI instead of D
-->
<circuit_model type="ff" name="scan_chain_ff" prefix="scan_chain_ff" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/SpiceNetlists/ff.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/VerilogNetlists/ff.v">
<design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="input" prefix="D" size="1"/>
<port type="input" prefix="D_chain" lib_name="DI" size="1"/>
<port type="input" prefix="TESTEN" size="1" is_global="true" default_val="0"/>
<port type="input" prefix="set" size="1" is_global="true" default_val="0" is_set="true"/>
<port type="input" prefix="reset" size="1" is_global="true" default_val="0" is_reset="true"/>
<port type="output" prefix="Q" size="1"/>
<port type="clock" prefix="clk" size="1" is_global="true" default_val="0" />
</circuit_model>
<circuit_model type="lut" name="frac_lut6" prefix="frac_lut6" dump_structural_verilog="true">
<design_technology type="cmos" fracturable_lut="true"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<lut_input_inverter exist="true" circuit_model_name="INVTX1"/>
<lut_input_buffer exist="true" circuit_model_name="buf4"/>
<lut_intermediate_buffer exist="true" circuit_model_name="buf4" location_map="-1-1-"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="6" tri_state_map="----11" circuit_model_name="OR2"/>
<port type="output" prefix="lut4_out" size="4" lut_frac_level="4" lut_output_mask="0,1,2,3"/>
<port type="output" prefix="lut5_out" size="2" lut_frac_level="5" lut_output_mask="0,1"/>
<port type="output" prefix="lut6_out" size="1" lut_output_mask="0"/>
<port type="sram" prefix="sram" size="64"/>
<port type="sram" prefix="mode" size="2" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/>
</circuit_model>
<circuit_model type="lut" name="frac_lut6_spypad" prefix="frac_lut6_spypad" dump_structural_verilog="true">
<design_technology type="cmos" fracturable_lut="true"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<lut_input_inverter exist="true" circuit_model_name="INVTX1"/>
<lut_input_buffer exist="true" circuit_model_name="buf4"/>
<lut_intermediate_buffer exist="true" circuit_model_name="buf4" location_map="-1-1-"/>
<pass_gate_logic circuit_model_name="TGATE"/>
<port type="input" prefix="in" size="6" tri_state_map="----11" circuit_model_name="OR2"/>
<port type="output" prefix="lut4_out" size="4" lut_frac_level="4" lut_output_mask="0,1,2,3" is_global="true" is_io="true"/>
<port type="output" prefix="lut5_out" size="2" lut_frac_level="5" lut_output_mask="0,1" is_global="true" is_io="true"/>
<port type="output" prefix="lut6_out" size="1" lut_output_mask="0" is_global="true" is_io="true"/>
<port type="sram" prefix="sram" size="64"/>
<port type="sram" prefix="mode" size="2" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/>
</circuit_model>
<!--Scan-chain DFF subckt ports should be defined as <D> <Q> <Qb> <CLK> <RESET> <SET> -->
<circuit_model type="ccff" name="sc_dff_compact" prefix="scff" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/SpiceNetlists/ff.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/VerilogNetlists/ff.v">
<design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="input" prefix="pReset" lib_name="reset" size="1" is_global="true" default_val="0" is_reset="true" is_prog="true"/>
<port type="input" prefix="D" size="1"/>
<port type="output" prefix="Q" size="1"/>
<port type="output" prefix="Qb" size="1"/>
<port type="clock" prefix="prog_clk" lib_name="clk" size="1" is_global="true" default_val="0" is_prog="true"/>
</circuit_model>
<circuit_model type="iopad" name="iopad" prefix="iopad" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/SpiceNetlists/io.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/VerilogNetlists/io.v">
<design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="inout" prefix="pad" size="1" is_global="true" is_io="true"/>
<port type="sram" prefix="en" size="1" mode_select="true" circuit_model_name="sc_dff_compact" default_val="1"/>
<port type="input" prefix="outpad" size="1"/>
<port type="output" prefix="inpad" size="1"/>
</circuit_model>
<circuit_model type="hard_logic" name="adder" prefix="adder" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/SpiceNetlists/adder.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/VerilogNetlists/adder.v">
<design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="INVTX1"/>
<output_buffer exist="true" circuit_model_name="INVTX1"/>
<port type="input" prefix="a" size="1"/>
<port type="input" prefix="b" size="1"/>
<port type="input" prefix="cin" size="1"/>
<port type="output" prefix="sumout" size="1"/>
<port type="output" prefix="cout" size="1"/>
</circuit_model>
</circuit_library>
<configuration_protocol>
<organization type="scan_chain" circuit_model_name="sc_dff_compact"/>
</configuration_protocol>
<connection_block>
<switch name="ipin_cblock" circuit_model_name="mux_2level_tapbuf"/>
</connection_block>
<switch_block>
<switch name="0" circuit_model_name="mux_2level_tapbuf"/>
</switch_block>
<routing_segment>
<segment name="L4" circuit_model_name="chan_segment"/>
</routing_segment>
<direct_connection>
<direct name="adder_carry" circuit_model_name="direct_interc"/>
<direct name="scff_chain" circuit_model_name="direct_interc" type="column" x_dir="positive" y_dir="positive"/>
</direct_connection>
<pb_type_annotations>
<!-- physical pb_type binding in complex block IO -->
<pb_type name="io" physical_mode_name="physical" idle_mode_name="inpad"/>
<pb_type name="io[physical].iopad" circuit_model_name="iopad" mode_bits="1"/>
<pb_type name="io[inpad].inpad" physical_pb_type_name="io[physical].iopad" mode_bits="1"/>
<pb_type name="io[outpad].outpad" physical_pb_type_name="io[physical].iopad" mode_bits="0"/>
<!-- End physical pb_type binding in complex block IO -->
<!-- physical pb_type binding in complex block CLB -->
<!-- physical mode will be the default mode if not specified -->
<pb_type name="clb.fle" physical_mode_name="physical"/>
<pb_type name="clb.fle[physical].frac_logic.frac_lut6" circuit_model_name="frac_lut6" mode_bits="11"/>
<pb_type name="clb.fle[physical].ff_phy" circuit_model_name="scan_chain_ff"/>
<pb_type name="clb.fle[physical].frac_logic.adder_phy" circuit_model_name="adder"/>
<!-- Binding operating pb_type to physical pb_type -->
<!-- Binding operating pb_types in mode 'n2_lut5' -->
<pb_type name="clb.fle[n2_lut5].lut5inter.ble5[blut5].flut5.lut5" physical_pb_type_name="clb.fle[physical].frac_logic.frac_lut6" mode_bits="01" physical_pb_type_index_factor="0.5">
<!-- Binding the lut5 to the first 5 inputs of fracturable lut6 -->
<port name="in" physical_mode_port="in[0:4]"/>
<port name="out" physical_mode_port="lut5_out[0:0]" physical_mode_pin_rotate_offset="1"/>
</pb_type>
<pb_type name="clb.fle[n2_lut5].lut5inter.ble5[blut5].flut5.ff" physical_pb_type_name="clb.fle[physical].ff_phy"/>
<!-- Binding operating pb_types in mode 'arithmetic' -->
<pb_type name="clb.fle[n2_lut5].lut5inter.ble5[arithmetic].arithmetic.lut4" physical_pb_type_name="clb.fle[physical].frac_logic.frac_lut6" mode_bits="11" physical_pb_type_index_factor="0.25">
<!-- Binding the lut4 to the first 4 inputs of fracturable lut6 -->
<port name="in" physical_mode_port="in[0:3]"/>
<port name="out" physical_mode_port="lut4_out[0:0]" physical_mode_pin_rotate_offset="1"/>
</pb_type>
<pb_type name="clb.fle[n2_lut5].lut5inter.ble5[arithmetic].arithmetic.adder" physical_pb_type_name="clb.fle[physical].frac_logic.adder_phy"/>
<pb_type name="clb.fle[n2_lut5].lut5inter.ble5[arithmetic].arithmetic.ff" physical_pb_type_name="clb.fle[physical].ff_phy"/>
<!-- Binding operating pb_types in mode 'ble6' -->
<pb_type name="clb.fle[n1_lut6].ble6.lut6" physical_pb_type_name="clb.fle[physical].frac_logic.frac_lut6" mode_bits="00">
<!-- Binding the lut6 to the first 6 inputs of fracturable lut6 -->
<port name="in" physical_mode_port="in[0:5]"/>
<port name="out" physical_mode_port="lut6_out"/>
</pb_type>
<pb_type name="clb.fle[n1_lut6].ble6.ff" physical_pb_type_name="clb.fle[physical].ff_phy" physical_pb_type_index_factor="2" physical_pb_type_index_offset="1"/>
<!-- Binding operating pb_types in mode 'shift_register' -->
<pb_type name="clb.fle[shift_register].ble_shift.ff" physical_pb_type_name="clb.fle[physical].ff_phy"/>
<!-- End physical pb_type binding in complex block CLB -->
<!-- physical pb_type binding in complex block CLB with spypads-->
<!-- physical mode will be the default mode if not specified -->
<pb_type name="clb_spypad.fle" physical_mode_name="physical"/>
<!-- Binding regular FLEs -->
<pb_type name="clb_spypad.fle[physical].frac_logic.frac_lut6" circuit_model_name="frac_lut6" mode_bits="11"/>
<pb_type name="clb_spypad.fle[physical].ff_phy" circuit_model_name="scan_chain_ff"/>
<pb_type name="clb_spypad.fle[physical].frac_logic.adder_phy" circuit_model_name="adder"/>
<!-- Binding operating pb_type to physical pb_type -->
<!-- Binding operating pb_types in mode 'n2_lut5' -->
<pb_type name="clb_spypad.fle[n2_lut5].lut5inter.ble5[blut5].flut5.lut5" physical_pb_type_name="clb_spypad.fle[physical].frac_logic.frac_lut6" mode_bits="01" physical_pb_type_index_factor="0.5">
<!-- Binding the lut5 to the first 5 inputs of fracturable lut6 -->
<port name="in" physical_mode_port="in[0:4]"/>
<port name="out" physical_mode_port="lut5_out[0:0]" physical_mode_pin_rotate_offset="1"/>
</pb_type>
<pb_type name="clb_spypad.fle[n2_lut5].lut5inter.ble5[blut5].flut5.ff" physical_pb_type_name="clb_spypad.fle[physical].ff_phy"/>
<!-- Binding operating pb_types in mode 'arithmetic' -->
<pb_type name="clb_spypad.fle[n2_lut5].lut5inter.ble5[arithmetic].arithmetic.lut4" physical_pb_type_name="clb_spypad.fle[physical].frac_logic.frac_lut6" mode_bits="11" physical_pb_type_index_factor="0.25">
<!-- Binding the lut4 to the first 4 inputs of fracturable lut6 -->
<port name="in" physical_mode_port="in[0:3]"/>
<port name="out" physical_mode_port="lut4_out[0:0]" physical_mode_pin_rotate_offset="1"/>
</pb_type>
<pb_type name="clb_spypad.fle[n2_lut5].lut5inter.ble5[arithmetic].arithmetic.adder" physical_pb_type_name="clb_spypad.fle[physical].frac_logic.adder_phy"/>
<pb_type name="clb_spypad.fle[n2_lut5].lut5inter.ble5[arithmetic].arithmetic.ff" physical_pb_type_name="clb_spypad.fle[physical].ff_phy"/>
<!-- Binding operating pb_types in mode 'ble6' -->
<pb_type name="clb_spypad.fle[n1_lut6].ble6.lut6" physical_pb_type_name="clb_spypad.fle[physical].frac_logic.frac_lut6" mode_bits="00">
<!-- Binding the lut6 to the first 6 inputs of fracturable lut6 -->
<port name="in" physical_mode_port="in[0:5]"/>
<port name="out" physical_mode_port="lut6_out"/>
</pb_type>
<pb_type name="clb_spypad.fle[n1_lut6].ble6.ff" physical_pb_type_name="clb_spypad.fle[physical].ff_phy" physical_pb_type_index_factor="2" physical_pb_type_index_offset="1"/>
<!-- Binding operating pb_types in mode 'shift_register' -->
<pb_type name="clb_spypad.fle[shift_register].ble_shift.ff" physical_pb_type_name="clb_spypad.fle[physical].ff_phy"/>
<!-- Binding FLE with spy pads -->
<!-- physical mode will be the default mode if not specified -->
<pb_type name="clb_spypad.fle_spypad" physical_mode_name="physical"/>
<pb_type name="clb_spypad.fle_spypad[physical].frac_logic.frac_lut6" circuit_model_name="frac_lut6_spypad" mode_bits="11"/>
<pb_type name="clb_spypad.fle_spypad[physical].ff_phy" circuit_model_name="scan_chain_ff"/>
<pb_type name="clb_spypad.fle_spypad[physical].frac_logic.adder_phy" circuit_model_name="adder"/>
<!-- Binding operating pb_type to physical pb_type -->
<!-- Binding operating pb_types in mode 'n2_lut5' -->
<pb_type name="clb_spypad.fle_spypad[n2_lut5].lut5inter.ble5[blut5].flut5.lut5" physical_pb_type_name="clb_spypad.fle_spypad[physical].frac_logic.frac_lut6" mode_bits="01" physical_pb_type_index_factor="0.5">
<!-- Binding the lut5 to the first 5 inputs of fracturable lut6 -->
<port name="in" physical_mode_port="in[0:4]"/>
<port name="out" physical_mode_port="lut5_out[0:0]" physical_mode_pin_rotate_offset="1"/>
</pb_type>
<pb_type name="clb_spypad.fle_spypad[n2_lut5].lut5inter.ble5[blut5].flut5.ff" physical_pb_type_name="clb_spypad.fle_spypad[physical].ff_phy"/>
<!-- Binding operating pb_types in mode 'arithmetic' -->
<pb_type name="clb_spypad.fle_spypad[n2_lut5].lut5inter.ble5[arithmetic].arithmetic.lut4" physical_pb_type_name="clb_spypad.fle_spypad[physical].frac_logic.frac_lut6" mode_bits="11" physical_pb_type_index_factor="0.25">
<!-- Binding the lut4 to the first 4 inputs of fracturable lut6 -->
<port name="in" physical_mode_port="in[0:3]"/>
<port name="out" physical_mode_port="lut4_out[0:0]" physical_mode_pin_rotate_offset="1"/>
</pb_type>
<pb_type name="clb_spypad.fle_spypad[n2_lut5].lut5inter.ble5[arithmetic].arithmetic.adder" physical_pb_type_name="clb_spypad.fle_spypad[physical].frac_logic.adder_phy"/>
<pb_type name="clb_spypad.fle_spypad[n2_lut5].lut5inter.ble5[arithmetic].arithmetic.ff" physical_pb_type_name="clb_spypad.fle_spypad[physical].ff_phy"/>
<!-- Binding operating pb_types in mode 'ble6' -->
<pb_type name="clb_spypad.fle_spypad[n1_lut6].ble6.lut6" physical_pb_type_name="clb_spypad.fle_spypad[physical].frac_logic.frac_lut6" mode_bits="00">
<!-- Binding the lut6 to the first 6 inputs of fracturable lut6 -->
<port name="in" physical_mode_port="in[0:5]"/>
<port name="out" physical_mode_port="lut6_out"/>
</pb_type>
<pb_type name="clb_spypad.fle_spypad[n1_lut6].ble6.ff" physical_pb_type_name="clb_spypad.fle_spypad[physical].ff_phy" physical_pb_type_index_factor="2" physical_pb_type_index_offset="1"/>
<!-- Binding operating pb_types in mode 'shift_register' -->
<pb_type name="clb_spypad.fle_spypad[shift_register].ble_shift.ff" physical_pb_type_name="clb_spypad.fle_spypad[physical].ff_phy"/>
<!-- End physical pb_type binding in complex block CLB with spypads-->
</pb_type_annotations>
</openfpga_architecture>
<openfpga_simulation_setting>
<clock_setting>
<!--operating frequency="auto" num_cycles="auto" slack="0.2"/-->
<operating frequency="200e6" num_cycles="auto" slack="0.2"/>
<programming frequency="10e6"/>
</clock_setting>
<simulator_option>
<operating_condition temperature="25"/>
<output_log verbose="false" captab="false"/>
<accuracy type="abs" value="1e-13"/>
<runtime fast_simulation="true"/>
</simulator_option>
<monte_carlo num_simulation_points="2"/>
<measurement_setting>
<slew>
<rise upper_thres_pct="0.95" lower_thres_pct="0.05"/>
<fall upper_thres_pct="0.05" lower_thres_pct="0.95"/>
</slew>
<delay>
<rise input_thres_pct="0.5" output_thres_pct="0.5"/>
<fall input_thres_pct="0.5" output_thres_pct="0.5"/>
</delay>
</measurement_setting>
<stimulus>
<clock>
<rise slew_type="abs" slew_time="20e-12" />
<fall slew_type="abs" slew_time="20e-12" />
</clock>
<input>
<rise slew_type="abs" slew_time="25e-12" />
<fall slew_type="abs" slew_time="25e-12" />
</input>
</stimulus>
</openfpga_simulation_setting>

View File

@ -21,12 +21,12 @@ openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_40nm.xml arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_40nm.xml
[BENCHMARKS] [BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.blif bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
[SYNTHESIS_PARAM] [SYNTHESIS_PARAM]
bench0_top = top bench0_top = and2
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.act bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.v bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
bench0_chan_width = 300 bench0_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]

View File

@ -21,12 +21,12 @@ openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_adder_chain_mem16K_40nm.xml arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_adder_chain_mem16K_40nm.xml
[BENCHMARKS] [BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.blif bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
[SYNTHESIS_PARAM] [SYNTHESIS_PARAM]
bench0_top = top bench0_top = and2
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.act bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.v bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
bench0_chan_width = 300 bench0_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]

View File

@ -22,12 +22,12 @@ openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_adder_chain_wide_mem16K_40nm.xml arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_adder_chain_wide_mem16K_40nm.xml
[BENCHMARKS] [BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.blif bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
[SYNTHESIS_PARAM] [SYNTHESIS_PARAM]
bench0_top = top bench0_top = and2
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.act bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.v bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
bench0_chan_width = 300 bench0_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]

View File

@ -21,12 +21,12 @@ openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k4_N4_tileable_40nm.xml arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k4_N4_tileable_40nm.xml
[BENCHMARKS] [BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.blif bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
[SYNTHESIS_PARAM] [SYNTHESIS_PARAM]
bench0_top = top bench0_top = and2
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.act bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.v bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
bench0_chan_width = 300 bench0_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]

View File

@ -21,12 +21,12 @@ openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_40nm.xml arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_40nm.xml
[BENCHMARKS] [BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.blif bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
[SYNTHESIS_PARAM] [SYNTHESIS_PARAM]
bench0_top = top bench0_top = and2
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.act bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.v bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
bench0_chan_width = 300 bench0_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]

View File

@ -21,12 +21,12 @@ openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_adder_chain_40nm.xml arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_adder_chain_40nm.xml
[BENCHMARKS] [BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.blif bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
[SYNTHESIS_PARAM] [SYNTHESIS_PARAM]
bench0_top = top bench0_top = and2
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.act bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.v bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
bench0_chan_width = 300 bench0_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]

View File

@ -21,12 +21,12 @@ openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_adder_register_chain_40nm.xml arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_adder_register_chain_40nm.xml
[BENCHMARKS] [BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.blif bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
[SYNTHESIS_PARAM] [SYNTHESIS_PARAM]
bench0_top = top bench0_top = and2
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.act bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.v bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
bench0_chan_width = 300 bench0_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]

View File

@ -21,12 +21,12 @@ openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_adder_register_scan_chain_40nm.xml arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_adder_register_scan_chain_40nm.xml
[BENCHMARKS] [BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.blif bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
[SYNTHESIS_PARAM] [SYNTHESIS_PARAM]
bench0_top = top bench0_top = and2
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.act bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.v bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
bench0_chan_width = 300 bench0_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]

View File

@ -21,12 +21,12 @@ openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_40nm.xml arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_40nm.xml
[BENCHMARKS] [BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.blif bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
[SYNTHESIS_PARAM] [SYNTHESIS_PARAM]
bench0_top = top bench0_top = and2
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.act bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.v bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
bench0_chan_width = 300 bench0_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]

View File

@ -21,13 +21,18 @@ openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_40nm.xml arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_40nm.xml
[BENCHMARKS] [BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.blif bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
# Modelsim is ok with this but icarus fails due to poor support on timing and looping
#bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_latch/and2_latch.blif
[SYNTHESIS_PARAM] [SYNTHESIS_PARAM]
bench0_top = top bench0_top = and2
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.act bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.v bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
bench0_chan_width = 300
bench1_top = and2_latch
bench1_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_latch/and2_latch.act
bench1_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_latch/and2_latch.v
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test= end_flow_with_test=

View File

@ -21,12 +21,12 @@ openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_adder_chain_40nm.xml arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_adder_chain_40nm.xml
[BENCHMARKS] [BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.blif bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
[SYNTHESIS_PARAM] [SYNTHESIS_PARAM]
bench0_top = top bench0_top = and2
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.act bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.v bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
bench0_chan_width = 300 bench0_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]

View File

@ -21,12 +21,12 @@ openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_40nm.xml arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_40nm.xml
[BENCHMARKS] [BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.blif bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
[SYNTHESIS_PARAM] [SYNTHESIS_PARAM]
bench0_top = top bench0_top = and2
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.act bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.v bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
bench0_chan_width = 300 bench0_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]

View File

@ -32,12 +32,12 @@ openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_adder_chain_mem16K_aib_40nm.xml arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_adder_chain_mem16K_aib_40nm.xml
[BENCHMARKS] [BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.blif bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
[SYNTHESIS_PARAM] [SYNTHESIS_PARAM]
bench0_top = top bench0_top = and2
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.act bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.v bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
bench0_chan_width = 300 bench0_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]

View File

@ -21,12 +21,12 @@ openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_adder_chain_mem16K_multi_io_capacity_40nm.xml arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_adder_chain_mem16K_multi_io_capacity_40nm.xml
[BENCHMARKS] [BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.blif bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
[SYNTHESIS_PARAM] [SYNTHESIS_PARAM]
bench0_top = top bench0_top = and2
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.act bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.v bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
bench0_chan_width = 300 bench0_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]

View File

@ -21,12 +21,12 @@ openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_adder_chain_mem16K_reduced_io_40nm.xml arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_adder_chain_mem16K_reduced_io_40nm.xml
[BENCHMARKS] [BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.blif bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
[SYNTHESIS_PARAM] [SYNTHESIS_PARAM]
bench0_top = top bench0_top = and2
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.act bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.v bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
bench0_chan_width = 300 bench0_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]

View File

@ -0,0 +1,133 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# 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/mcnc_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
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_adder_register_scan_chain_depop50_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/alu4/alu4.blif
bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/apex2/apex2.blif
bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/apex4/apex4.blif
# VPR remove buffers which are in act file and create a new net. Then VPR errors out by saying the new net does not exist in act file
bench3=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/bigkey/bigkey.blif
# VPR remove buffers which are in act file and create a new net. Then VPR errors out by saying the new net does not exist in act file
bench4=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/clma/clma.blif
bench5=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/des/des.blif
bench6=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/diffeq/diffeq.blif
# VPR remove buffers which are in act file and create a new net. Then VPR errors out by saying the new net does not exist in act file
bench7=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/dsip/dsip.blif
bench8=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/elliptic/elliptic.blif
bench9=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/ex1010/ex1010.blif
bench10=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/ex5p/ex5p.blif
bench11=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/frisc/frisc.blif
bench12=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/misex3/misex3.blif
bench13=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/pdc/pdc.blif
# Passed
#bench14=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/s298/s298.blif
bench15=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/s38417/s38417.blif
bench16=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/s38584/s38584.blif
bench17=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/seq/seq.blif
bench18=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/spla/spla.blif
bench19=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/tseng/tseng.blif
[SYNTHESIS_PARAM]
# Benchmark alu4
bench0_top = alu4
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/alu4/alu4.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/alu4/alu4.v
# Benchmark apex2
bench1_top = apex2
bench1_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/apex2/apex2.act
bench1_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/apex2/apex2.v
# Benchmark apex4
bench2_top = apex4
bench2_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/apex4/apex4.act
bench2_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/apex4/apex4.v
# Benchmark bigkey
bench3_top = bigkey
bench3_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/bigkey/bigkey.act
bench3_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/bigkey/bigkey.v
# Benchmark clma
bench4_top = clma
bench4_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/clma/clma.act
bench4_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/clma/clma.v
# Benchmark des
bench5_top = des
bench5_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/des/des.act
bench5_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/des/des.v
# Benchmark diffeq
bench6_top = diffeq
bench6_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/diffeq/diffeq.act
bench6_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/diffeq/diffeq.v
# Benchmark dsip
bench7_top = dsip
bench7_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/dsip/dsip.act
bench7_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/dsip/dsip.v
# Benchmark elliptic
bench8_top = elliptic
bench8_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/elliptic/elliptic.act
bench8_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/elliptic/elliptic.v
# Benchmark ex1010
bench9_top = ex1010
bench9_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/ex1010/ex1010.act
bench9_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/ex1010/ex1010.v
# Benchmark ex5p
bench10_top = ex5p
bench10_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/ex5p/ex5p.act
bench10_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/ex5p/ex5p.v
# Benchmark frisc
bench11_top = frisc
bench11_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/frisc/frisc.act
bench11_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/frisc/frisc.v
# Benchmark misex3
bench12_top = misex3
bench12_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/misex3/misex3.act
bench12_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/misex3/misex3.v
# Benchmark pdc
bench13_top = pdc
bench13_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/pdc/pdc.act
bench13_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/pdc/pdc.v
# Benchmark s298
bench14_top = s298
bench14_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/s298/s298.act
bench14_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/s298/s298.v
# Benchmark s38417
bench15_top = s38417
bench15_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/s38417/s38417.act
bench15_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/s38417/s38417.v
# Benchmark s38584
bench16_top = s38584
bench16_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/s38584/s38584.act
bench16_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/s38584/s38584.v
# Benchmark seq
bench17_top = seq
bench17_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/seq/seq.act
bench17_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/seq/seq.v
# Benchmark spla
bench18_top = spla
bench18_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/spla/spla.act
bench18_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/spla/spla.v
# Benchmark tseng
bench19_top = tseng
bench19_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/tseng/tseng.act
bench19_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/mcnc_big20/tseng/tseng.v
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
#end_flow_with_test=
vpr_fpga_verilog_formal_verification_top_netlist=

View File

@ -21,12 +21,12 @@ openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_40nm.xml arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_40nm.xml
[BENCHMARKS] [BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.blif bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
[SYNTHESIS_PARAM] [SYNTHESIS_PARAM]
bench0_top = top bench0_top = and2
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.act bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.v bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
bench0_chan_width = 300 bench0_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]

View File

@ -21,12 +21,12 @@ openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_40nm.xml arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_40nm.xml
[BENCHMARKS] [BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.blif bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
[SYNTHESIS_PARAM] [SYNTHESIS_PARAM]
bench0_top = top bench0_top = and2
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.act bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.v bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
bench0_chan_width = 300 bench0_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]

View File

@ -0,0 +1,38 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# 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_N10_40nm_openfpga.xml
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_N10_tileable_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_latch/and2_latch.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
bench1_top = and2_latch
bench1_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_latch/and2_latch.act
bench1_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_latch/and2_latch.v
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test=
vpr_fpga_verilog_formal_verification_top_netlist=

View File

@ -0,0 +1,34 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# 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_spypad_40nm_openfpga.xml
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_tileable_adder_register_scan_chain_depop50_spypad_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

@ -21,12 +21,12 @@ openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_40nm.xml arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/vpr_only_templates/k6_frac_N10_40nm.xml
[BENCHMARKS] [BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.blif bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
[SYNTHESIS_PARAM] [SYNTHESIS_PARAM]
bench0_top = top bench0_top = and2
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.act bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and.v bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
bench0_chan_width = 300 bench0_chan_width = 300
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]

View File

@ -19,8 +19,8 @@ static bool add_activity_to_net(const AtomNetlist& netlist, std::unordered_map<A
return false; return false;
} }
VTR_LOG( VTR_LOG_WARN(
"Error: net %s found in activity file, but it does not exist in the .blif file.\n", "net %s found in activity file, but it does not exist in the .blif file.\n",
net_name); net_name);
return true; return true;
} }