[Tool] Support superLUT circuit model in core engine
This commit is contained in:
parent
7dcc14d73f
commit
6a0f4f354f
|
@ -45,8 +45,13 @@ void build_lut_module(ModuleManager& module_manager,
|
|||
std::vector<CircuitPortId> lut_global_ports = circuit_lib.model_global_ports_by_type(lut_model, CIRCUIT_MODEL_PORT_INPUT, false, true);
|
||||
/* 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);
|
||||
/* Find the inputs that drive the internal LUT MUX */
|
||||
std::vector<CircuitPortId> lut_mux_input_ports = find_lut_circuit_model_input_port(circuit_lib, lut_model, false);
|
||||
|
||||
/* 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, false);
|
||||
/* Find the outputs that are driven the internal LUT MUX */
|
||||
std::vector<CircuitPortId> lut_mux_output_ports = find_lut_circuit_model_output_port(circuit_lib, lut_model, false);
|
||||
|
||||
/* 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);
|
||||
|
@ -60,8 +65,8 @@ void build_lut_module(ModuleManager& module_manager,
|
|||
/* Single-output LUTs:
|
||||
* We should have only 1 input port, 1 output port and 1 SRAM port
|
||||
*/
|
||||
VTR_ASSERT (1 == lut_input_ports.size());
|
||||
VTR_ASSERT (1 == lut_output_ports.size());
|
||||
VTR_ASSERT (1 == lut_mux_input_ports.size());
|
||||
VTR_ASSERT (1 == lut_mux_output_ports.size());
|
||||
VTR_ASSERT (1 == lut_regular_sram_ports.size());
|
||||
VTR_ASSERT (0 == lut_mode_select_sram_ports.size());
|
||||
} else {
|
||||
|
@ -70,8 +75,8 @@ void build_lut_module(ModuleManager& module_manager,
|
|||
* We should have only 1 input port, a few output ports (fracturable outputs)
|
||||
* and two SRAM ports
|
||||
*/
|
||||
VTR_ASSERT (1 == lut_input_ports.size());
|
||||
VTR_ASSERT (1 <= lut_output_ports.size());
|
||||
VTR_ASSERT (1 == lut_mux_input_ports.size());
|
||||
VTR_ASSERT (1 <= lut_mux_output_ports.size());
|
||||
VTR_ASSERT (1 == lut_regular_sram_ports.size());
|
||||
VTR_ASSERT ( (0 == lut_mode_select_sram_ports.size())
|
||||
|| (1 == lut_mode_select_sram_ports.size()));
|
||||
|
@ -155,10 +160,10 @@ void build_lut_module(ModuleManager& module_manager,
|
|||
* +--------------------------------------+
|
||||
*/
|
||||
/* Get the tri-state port map for the input ports*/
|
||||
std::string tri_state_map = circuit_lib.port_tri_state_map(lut_input_ports[0]);
|
||||
std::string tri_state_map = circuit_lib.port_tri_state_map(lut_mux_input_ports[0]);
|
||||
size_t mode_select_port_lsb = 0;
|
||||
for (const auto& pin : circuit_lib.pins(lut_input_ports[0])) {
|
||||
ModulePortId lut_module_input_port_id = module_manager.find_module_port(lut_module, circuit_lib.port_prefix(lut_input_ports[0]));
|
||||
for (const auto& pin : circuit_lib.pins(lut_mux_input_ports[0])) {
|
||||
ModulePortId lut_module_input_port_id = module_manager.find_module_port(lut_module, circuit_lib.port_prefix(lut_mux_input_ports[0]));
|
||||
VTR_ASSERT(true == module_manager.valid_module_port_id(lut_module, lut_module_input_port_id));
|
||||
|
||||
/* Create a module net for the connection */
|
||||
|
@ -200,7 +205,7 @@ void build_lut_module(ModuleManager& module_manager,
|
|||
required_gate_type = CIRCUIT_MODEL_GATE_OR;
|
||||
}
|
||||
/* Get the circuit model of the gate */
|
||||
CircuitModelId gate_model = circuit_lib.port_tri_state_model(lut_input_ports[0]);
|
||||
CircuitModelId gate_model = circuit_lib.port_tri_state_model(lut_mux_input_ports[0]);
|
||||
/* Check this is the gate we want ! */
|
||||
VTR_ASSERT (required_gate_type == circuit_lib.gate_type(gate_model));
|
||||
|
||||
|
@ -290,7 +295,7 @@ void build_lut_module(ModuleManager& module_manager,
|
|||
|
||||
std::vector<ModuleNetId> lut_mux_sram_inv_nets;
|
||||
/* Now we need to add inverters by instanciating the modules */
|
||||
for (size_t pin = 0; pin < circuit_lib.port_size(lut_input_ports[0]); ++pin) {
|
||||
for (size_t pin = 0; pin < circuit_lib.port_size(lut_mux_input_ports[0]); ++pin) {
|
||||
ModuleNetId lut_mux_sram_inv_net = add_inverter_buffer_child_module_and_nets(module_manager, lut_module,
|
||||
circuit_lib, input_inverter_model,
|
||||
mode_selected_nets[pin]);
|
||||
|
@ -308,7 +313,7 @@ void build_lut_module(ModuleManager& module_manager,
|
|||
|
||||
std::vector<ModuleNetId> lut_mux_sram_nets;
|
||||
/* Now we need to add inverters by instanciating the modules and add module nets */
|
||||
for (size_t pin = 0; pin < circuit_lib.port_size(lut_input_ports[0]); ++pin) {
|
||||
for (size_t pin = 0; pin < circuit_lib.port_size(lut_mux_input_ports[0]); ++pin) {
|
||||
ModuleNetId lut_mux_sram_net = add_inverter_buffer_child_module_and_nets(module_manager, lut_module,
|
||||
circuit_lib, input_buffer_model,
|
||||
mode_selected_nets[pin]);
|
||||
|
@ -362,7 +367,7 @@ void build_lut_module(ModuleManager& module_manager,
|
|||
*/
|
||||
ModulePortId lut_sram_port_id = module_manager.find_module_port(lut_module, circuit_lib.port_prefix(lut_regular_sram_ports[0]));
|
||||
BasicPort lut_sram_port = module_manager.module_port(lut_module, lut_sram_port_id);
|
||||
ModulePortId lut_mux_input_port_id = module_manager.find_module_port(lut_mux_module, circuit_lib.port_prefix(lut_input_ports[0]));
|
||||
ModulePortId lut_mux_input_port_id = module_manager.find_module_port(lut_mux_module, circuit_lib.port_prefix(lut_mux_input_ports[0]));
|
||||
BasicPort lut_mux_input_port = module_manager.module_port(lut_mux_module, lut_mux_input_port_id);
|
||||
VTR_ASSERT(lut_mux_input_port.get_width() == lut_sram_port.get_width());
|
||||
/* Wire the port to lut_mux_sram_net */
|
||||
|
@ -372,7 +377,7 @@ void build_lut_module(ModuleManager& module_manager,
|
|||
module_manager.add_module_net_sink(lut_module, net, lut_mux_module, lut_mux_instance, lut_mux_input_port_id, lut_mux_input_port.pins()[pin_id]);
|
||||
}
|
||||
|
||||
for (const auto& port : lut_output_ports) {
|
||||
for (const auto& port : lut_mux_output_ports) {
|
||||
ModulePortId lut_output_port_id = module_manager.find_module_port(lut_module, circuit_lib.port_prefix(port));
|
||||
BasicPort lut_output_port = module_manager.module_port(lut_module, lut_output_port_id);
|
||||
ModulePortId lut_mux_output_port_id = module_manager.find_module_port(lut_mux_module, circuit_lib.port_prefix(port));
|
||||
|
@ -407,6 +412,11 @@ void build_lut_modules(ModuleManager& module_manager,
|
|||
if (CIRCUIT_MODEL_LUT != circuit_lib.model_type(lut_model)) {
|
||||
continue;
|
||||
}
|
||||
/* We skip user-defined models */
|
||||
if ( (false == circuit_lib.model_verilog_netlist(lut_model).empty())
|
||||
|| (false == circuit_lib.model_spice_netlist(lut_model).empty()) ) {
|
||||
continue;
|
||||
}
|
||||
build_lut_module(module_manager, circuit_lib, lut_model);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -734,8 +734,18 @@ vtr::vector<MuxInputId, ModuleNetId> build_mux_module_input_buffers(ModuleManage
|
|||
const MuxGraph& mux_graph) {
|
||||
vtr::vector<MuxInputId, ModuleNetId> mux_input_nets(mux_graph.num_inputs(), ModuleNetId::INVALID());
|
||||
|
||||
/* 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);
|
||||
/* Get the input ports from the mux:
|
||||
* - LUT may have ports that are driven by harden logic,
|
||||
* which should not be included when building the mux graph
|
||||
*/
|
||||
std::vector<CircuitPortId> mux_input_ports;
|
||||
if (CIRCUIT_MODEL_LUT == circuit_lib.model_type(mux_model)) {
|
||||
mux_input_ports = find_lut_circuit_model_input_port(circuit_lib, mux_model, false);
|
||||
} else {
|
||||
VTR_ASSERT(CIRCUIT_MODEL_MUX == circuit_lib.model_type(mux_model));
|
||||
mux_input_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_INPUT, true);
|
||||
}
|
||||
|
||||
/* We should have only 1 input port! */
|
||||
VTR_ASSERT(1 == mux_input_ports.size());
|
||||
|
||||
|
@ -849,8 +859,18 @@ vtr::vector<MuxOutputId, ModuleNetId> build_mux_module_output_buffers(ModuleMana
|
|||
/* Create module nets for output ports */
|
||||
vtr::vector<MuxOutputId, ModuleNetId> mux_output_nets(mux_graph.num_outputs(), ModuleNetId::INVALID());
|
||||
|
||||
/* 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, false);
|
||||
/* Get the output ports from the mux:
|
||||
* - LUT may have ports that are driven by harden logic,
|
||||
* which should not be included when building the mux graph
|
||||
* - LUT may have global output ports that are wired directly to top-level module
|
||||
*/
|
||||
std::vector<CircuitPortId> mux_output_ports;
|
||||
if (CIRCUIT_MODEL_LUT == circuit_lib.model_type(mux_model)) {
|
||||
mux_output_ports = find_lut_circuit_model_output_port(circuit_lib, mux_model, false, false);
|
||||
} else {
|
||||
VTR_ASSERT(CIRCUIT_MODEL_MUX == circuit_lib.model_type(mux_model));
|
||||
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 */
|
||||
for (const auto& output_port : mux_output_ports) {
|
||||
|
@ -1096,10 +1116,32 @@ void build_cmos_mux_module(ModuleManager& module_manager,
|
|||
const MuxGraph& mux_graph) {
|
||||
/* Get the global ports required by MUX (and any submodules) */
|
||||
std::vector<CircuitPortId> mux_global_ports = circuit_lib.model_global_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_INPUT, true, true);
|
||||
/* 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);
|
||||
/* 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, false);
|
||||
|
||||
/* Get the input ports from the mux:
|
||||
* - LUT may have ports that are driven by harden logic,
|
||||
* which should not be included when building the mux graph
|
||||
*/
|
||||
std::vector<CircuitPortId> mux_input_ports;
|
||||
if (CIRCUIT_MODEL_LUT == circuit_lib.model_type(mux_model)) {
|
||||
mux_input_ports = find_lut_circuit_model_input_port(circuit_lib, mux_model, false);
|
||||
} else {
|
||||
VTR_ASSERT(CIRCUIT_MODEL_MUX == circuit_lib.model_type(mux_model));
|
||||
mux_input_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_INPUT, true);
|
||||
}
|
||||
|
||||
/* Get the output ports from the mux:
|
||||
* - LUT may have ports that are driven by harden logic,
|
||||
* which should not be included when building the mux graph
|
||||
* - LUT may have global output ports that are wired directly to top-level module
|
||||
*/
|
||||
std::vector<CircuitPortId> mux_output_ports;
|
||||
if (CIRCUIT_MODEL_LUT == circuit_lib.model_type(mux_model)) {
|
||||
mux_output_ports = find_lut_circuit_model_output_port(circuit_lib, mux_model, false, false);
|
||||
} else {
|
||||
VTR_ASSERT(CIRCUIT_MODEL_MUX == circuit_lib.model_type(mux_model));
|
||||
mux_output_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_OUTPUT, false);
|
||||
}
|
||||
|
||||
/* Get the sram ports from the mux
|
||||
* Multiplexing structure does not mode_sram_ports, they are handled in LUT modules
|
||||
* Here we just bypass it.
|
||||
|
|
|
@ -407,7 +407,7 @@ void build_lut_bitstream(BitstreamManager& bitstream_manager,
|
|||
VTR_ASSERT(CIRCUIT_MODEL_LUT == circuit_lib.model_type(lut_model));
|
||||
|
||||
/* Find the input ports for LUT size, this is used to decode the LUT memory bits! */
|
||||
std::vector<CircuitPortId> model_input_ports = circuit_lib.model_ports_by_type(lut_model, CIRCUIT_MODEL_PORT_INPUT, true);
|
||||
std::vector<CircuitPortId> model_input_ports = find_lut_circuit_model_input_port(circuit_lib, lut_model, false);
|
||||
VTR_ASSERT(1 == model_input_ports.size());
|
||||
size_t lut_size = circuit_lib.port_size(model_input_ports[0]);
|
||||
|
||||
|
|
|
@ -89,7 +89,9 @@ int print_sdc_disable_lut_configure_ports(std::fstream& fp,
|
|||
}
|
||||
|
||||
const std::string& sram_inv_port_name = circuit_lib.port_lib_name(sram_port) + INV_PORT_POSTFIX;
|
||||
VTR_ASSERT(true == module_manager.valid_module_port_id(programmable_module, module_manager.find_module_port(programmable_module, sram_inv_port_name)));
|
||||
if (false == module_manager.valid_module_port_id(programmable_module, module_manager.find_module_port(programmable_module, sram_inv_port_name))) {
|
||||
continue;
|
||||
}
|
||||
if (CMD_EXEC_FATAL_ERROR ==
|
||||
rec_print_sdc_disable_timing_for_module_ports(fp,
|
||||
flatten_names,
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
/* Headers from readarchopenfpga library */
|
||||
#include "circuit_types.h"
|
||||
#include "circuit_library.h"
|
||||
#include "circuit_library_utils.h"
|
||||
|
||||
#include "mux_utils.h"
|
||||
#include "pb_type_utils.h"
|
||||
|
@ -182,7 +183,7 @@ void build_lut_mux_library(MuxLibrary& mux_lib,
|
|||
}
|
||||
/* Find the MUX size required by the LUT */
|
||||
/* Get input ports which are not global ports! */
|
||||
std::vector<CircuitPortId> input_ports = circuit_lib.model_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_INPUT, true);
|
||||
std::vector<CircuitPortId> input_ports = find_lut_circuit_model_input_port(circuit_lib, circuit_model, false);
|
||||
VTR_ASSERT(1 == input_ports.size());
|
||||
/* MUX size = 2^lut_size */
|
||||
size_t lut_mux_size = (size_t)pow(2., (double)(circuit_lib.port_size(input_ports[0])));
|
||||
|
|
|
@ -50,39 +50,47 @@ static
|
|||
std::vector<int> generate_lut_rotated_input_pin_map(const std::vector<AtomNetId>& input_nets,
|
||||
const AtomContext& atom_ctx,
|
||||
const AtomBlockId& atom_blk,
|
||||
const VprDeviceAnnotation& device_annotation,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const t_pb_graph_node* pb_graph_node) {
|
||||
/* Find the pin rotation status and record it ,
|
||||
* Note that some LUT inputs may not be used, we set them to be open by default
|
||||
*/
|
||||
std::vector<int> rotated_pin_map(input_nets.size(), -1);
|
||||
|
||||
VTR_ASSERT(1 == pb_graph_node->num_input_ports);
|
||||
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) {
|
||||
/* Skip the input pin that do not drive by LUT MUXes */
|
||||
CircuitPortId circuit_port = device_annotation.pb_circuit_port(pb_graph_node->input_pins[iport][ipin].port);
|
||||
if (true == circuit_lib.port_is_harden_lut_port(circuit_port)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int ipin = 0; ipin < pb_graph_node->num_input_pins[0]; ++ipin) {
|
||||
/* The lut pb_graph_node may not be the primitive node
|
||||
* because VPR adds two default modes to its LUT pb_type
|
||||
* If so, we will use the LUT mode of the pb_graph node
|
||||
*/
|
||||
t_port* lut_pb_type_in_port = pb_graph_node->input_pins[0][ipin].port;
|
||||
if (0 != pb_graph_node->pb_type->num_modes) {
|
||||
VTR_ASSERT(2 == pb_graph_node->pb_type->num_modes);
|
||||
VTR_ASSERT(1 == pb_graph_node->pb_type->modes[VPR_PB_TYPE_LUT_MODE].num_pb_type_children);
|
||||
lut_pb_type_in_port = &(pb_graph_node->pb_type->modes[VPR_PB_TYPE_LUT_MODE].pb_type_children[0].ports[0]);
|
||||
VTR_ASSERT(std::string(lut_pb_type_in_port->name) == std::string(pb_graph_node->input_pins[0][ipin].port->name));
|
||||
VTR_ASSERT(lut_pb_type_in_port->num_pins == pb_graph_node->input_pins[0][ipin].port->num_pins);
|
||||
}
|
||||
/* The lut pb_graph_node may not be the primitive node
|
||||
* because VPR adds two default modes to its LUT pb_type
|
||||
* If so, we will use the LUT mode of the pb_graph node
|
||||
*/
|
||||
t_port* lut_pb_type_in_port = pb_graph_node->input_pins[iport][ipin].port;
|
||||
if (0 != pb_graph_node->pb_type->num_modes) {
|
||||
VTR_ASSERT(2 == pb_graph_node->pb_type->num_modes);
|
||||
VTR_ASSERT(1 == pb_graph_node->pb_type->modes[VPR_PB_TYPE_LUT_MODE].num_pb_type_children);
|
||||
lut_pb_type_in_port = &(pb_graph_node->pb_type->modes[VPR_PB_TYPE_LUT_MODE].pb_type_children[0].ports[iport]);
|
||||
VTR_ASSERT(std::string(lut_pb_type_in_port->name) == std::string(pb_graph_node->input_pins[iport][ipin].port->name));
|
||||
VTR_ASSERT(lut_pb_type_in_port->num_pins == pb_graph_node->input_pins[iport][ipin].port->num_pins);
|
||||
}
|
||||
|
||||
/* Port exists (some LUTs may have no input and hence no port in the atom netlist) */
|
||||
AtomPortId atom_port = atom_ctx.nlist.find_atom_port(atom_blk, lut_pb_type_in_port->model_port);
|
||||
if (!atom_port) {
|
||||
continue;
|
||||
}
|
||||
/* Port exists (some LUTs may have no input and hence no port in the atom netlist) */
|
||||
AtomPortId atom_port = atom_ctx.nlist.find_atom_port(atom_blk, lut_pb_type_in_port->model_port);
|
||||
if (!atom_port) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (AtomPinId atom_pin : atom_ctx.nlist.port_pins(atom_port)) {
|
||||
AtomNetId atom_pin_net = atom_ctx.nlist.pin_net(atom_pin);
|
||||
if (atom_pin_net == input_nets[ipin]) {
|
||||
rotated_pin_map[ipin] = atom_ctx.nlist.pin_port_bit(atom_pin);
|
||||
break;
|
||||
for (AtomPinId atom_pin : atom_ctx.nlist.port_pins(atom_port)) {
|
||||
AtomNetId atom_pin_net = atom_ctx.nlist.pin_net(atom_pin);
|
||||
if (atom_pin_net == input_nets[ipin]) {
|
||||
rotated_pin_map[ipin] = atom_ctx.nlist.pin_port_bit(atom_pin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -109,15 +117,27 @@ void build_physical_pb_lut_truth_tables(PhysicalPb& physical_pb,
|
|||
|
||||
/* Find all the nets mapped to each inputs */
|
||||
std::vector<AtomNetId> input_nets;
|
||||
VTR_ASSERT(1 == pb_graph_node->num_input_ports);
|
||||
for (int ipin = 0; ipin < pb_graph_node->num_input_pins[0]; ++ipin) {
|
||||
input_nets.push_back(physical_pb.pb_graph_pin_atom_net(lut_pb_id, &(pb_graph_node->input_pins[0][ipin])));
|
||||
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) {
|
||||
/* Skip the input pin that do not drive by LUT MUXes */
|
||||
CircuitPortId circuit_port = device_annotation.pb_circuit_port(pb_graph_node->input_pins[iport][ipin].port);
|
||||
if (true == circuit_lib.port_is_harden_lut_port(circuit_port)) {
|
||||
continue;
|
||||
}
|
||||
input_nets.push_back(physical_pb.pb_graph_pin_atom_net(lut_pb_id, &(pb_graph_node->input_pins[iport][ipin])));
|
||||
}
|
||||
}
|
||||
|
||||
/* Find all the nets mapped to each outputs */
|
||||
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) {
|
||||
const t_pb_graph_pin* output_pin = &(pb_graph_node->output_pins[iport][ipin]);
|
||||
/* Skip the output ports that are not driven by LUT MUXes */
|
||||
CircuitPortId circuit_port = device_annotation.pb_circuit_port(output_pin->port);
|
||||
if (true == circuit_lib.port_is_harden_lut_port(circuit_port)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AtomNetId output_net = physical_pb.pb_graph_pin_atom_net(lut_pb_id, output_pin);
|
||||
/* Bypass unmapped pins */
|
||||
if (AtomNetId::INVALID() == output_net) {
|
||||
|
@ -135,7 +155,7 @@ void build_physical_pb_lut_truth_tables(PhysicalPb& physical_pb,
|
|||
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);
|
||||
std::vector<int> rotated_pin_map = generate_lut_rotated_input_pin_map(input_nets, atom_ctx, atom_blk, device_annotation, circuit_lib, pb_graph_node);
|
||||
adapt_tt = lut_truth_table_adaption(orig_tt, rotated_pin_map);
|
||||
}
|
||||
|
||||
|
|
|
@ -368,4 +368,54 @@ CircuitPortId find_circuit_model_power_gate_enb_port(const CircuitLibrary& circu
|
|||
return enb_port;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Try to find the input ports for a LUT circuit model (EXCLUDE the global ports)
|
||||
* which can optionally include those ports drives or is driven by hard logic
|
||||
***********************************************************************/
|
||||
std::vector<CircuitPortId> find_lut_circuit_model_input_port(const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model,
|
||||
const bool& include_harden_port,
|
||||
const bool& include_global_port) {
|
||||
VTR_ASSERT(CIRCUIT_MODEL_LUT == circuit_lib.model_type(circuit_model));
|
||||
|
||||
std::vector<CircuitPortId> input_ports;
|
||||
|
||||
/* Find all the non-global input ports */
|
||||
for (const auto& port : circuit_lib.model_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_INPUT, !include_global_port)) {
|
||||
/* Skip harden ports if specified */
|
||||
if ( (true == circuit_lib.port_is_harden_lut_port(port))
|
||||
&& (false == include_harden_port)) {
|
||||
continue;
|
||||
}
|
||||
input_ports.push_back(port);
|
||||
}
|
||||
|
||||
return input_ports;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Try to find the output ports for a LUT circuit model (EXCLUDE the global ports)
|
||||
* which can optionally include those ports drives or is driven by hard logic
|
||||
***********************************************************************/
|
||||
std::vector<CircuitPortId> find_lut_circuit_model_output_port(const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model,
|
||||
const bool& include_harden_port,
|
||||
const bool& include_global_port) {
|
||||
VTR_ASSERT(CIRCUIT_MODEL_LUT == circuit_lib.model_type(circuit_model));
|
||||
|
||||
std::vector<CircuitPortId> output_ports;
|
||||
|
||||
/* Find all the non-global input ports */
|
||||
for (const auto& port : circuit_lib.model_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_OUTPUT, !include_global_port)) {
|
||||
/* Skip harden ports if specified */
|
||||
if ( (true == circuit_lib.port_is_harden_lut_port(port))
|
||||
&& (false == include_harden_port)) {
|
||||
continue;
|
||||
}
|
||||
output_ports.push_back(port);
|
||||
}
|
||||
|
||||
return output_ports;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -51,6 +51,16 @@ CircuitPortId find_circuit_model_power_gate_en_port(const CircuitLibrary& circui
|
|||
CircuitPortId find_circuit_model_power_gate_enb_port(const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model);
|
||||
|
||||
std::vector<CircuitPortId> find_lut_circuit_model_input_port(const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model,
|
||||
const bool& include_harden_port,
|
||||
const bool& include_global_port = true);
|
||||
|
||||
std::vector<CircuitPortId> find_lut_circuit_model_output_port(const CircuitLibrary& circuit_lib,
|
||||
const CircuitModelId& circuit_model,
|
||||
const bool& include_harden_port,
|
||||
const bool& include_global_port = true);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue