Add behavior to handle unmapped muxes without constant inputs better

This commit is contained in:
Duck Deux 2024-10-31 00:01:59 -07:00
parent 0714ccf608
commit 1877779a99
10 changed files with 180 additions and 62 deletions

View File

@ -525,6 +525,8 @@ Template
- ``structure="tree|multi_level|one_level"`` Specify the multiplexer structure for a multiplexer. The structure option is only valid for SRAM-based multiplexers. For RRAM-based multiplexers, currently we only support the one_level structure
.. _mux_const_input_option:
- ``num_level="<int>"`` Specify the number of levels when ``multi_level`` structure is selected.
- ``add_const_input="true|false"`` Specify if an extra input should be added to the multiplexer circuits. For example, an 4-input multiplexer will be turned to a 5-input multiplexer. The extra input will be wired to a constant value, which can be specified through the XML syntax ``const_input_val``.

View File

@ -51,6 +51,10 @@ build_architecture_bitstream
Output the fabric-independent bitstream to an XML file. See details at :ref:`file_formats_architecture_bitstream`.
.. option:: --prefer_unused_mux_input
Try to connect unmapped mux outputs to unmapped inputs. Only effective if there is no constant input to muxes (see :ref:`mux_const_input_option`). This option aims to reduce power consumption by preventing unnecessary switching of unmapped mux outputs.
.. option:: --no_time_stamp
Do not print time stamp in bitstream files

View File

@ -74,6 +74,11 @@ ShellCommandId add_build_arch_bitstream_command_template(
"read_file", false, "file path to read the bitstream database");
shell_cmd.set_option_require_value(opt_read_file, openfpga::OPT_STRING);
/* Add an option '--prefer_unused_mux_input' */
shell_cmd.add_option(
"prefer_unused_mux_input", false,
"Try to connect unmapped mux outputs to unmapped inputs");
/* Add an option '--no_time_stamp' */
shell_cmd.add_option("no_time_stamp", false,
"Do not print time stamp in output files");

View File

@ -39,13 +39,16 @@ int fpga_bitstream_template(T& openfpga_ctx, const Command& cmd,
CommandOptionId opt_no_time_stamp = cmd.option("no_time_stamp");
CommandOptionId opt_write_file = cmd.option("write_file");
CommandOptionId opt_read_file = cmd.option("read_file");
CommandOptionId opt_prefer_unused = cmd.option("prefer_unused_mux_input");
if (true == cmd_context.option_enable(cmd, opt_read_file)) {
openfpga_ctx.mutable_bitstream_manager() = read_xml_architecture_bitstream(
cmd_context.option_value(cmd, opt_read_file).c_str());
} else {
openfpga_ctx.mutable_bitstream_manager() = build_device_bitstream(
g_vpr_ctx, openfpga_ctx, cmd_context.option_enable(cmd, opt_verbose));
openfpga_ctx.mutable_bitstream_manager() =
build_device_bitstream(g_vpr_ctx, openfpga_ctx,
cmd_context.option_enable(cmd, opt_prefer_unused),
cmd_context.option_enable(cmd, opt_verbose));
}
overwrite_bitstream(openfpga_ctx.mutable_bitstream_manager(),

View File

@ -149,6 +149,7 @@ static size_t rec_estimate_device_bitstream_num_bits(
*******************************************************************/
BitstreamManager build_device_bitstream(const VprContext& vpr_ctx,
const OpenfpgaContext& openfpga_ctx,
const bool& prefer_unused_mux_input,
const bool& verbose) {
std::string timer_message =
std::string("\nBuild fabric-independent bitstream for implementation '") +
@ -218,7 +219,7 @@ BitstreamManager build_device_bitstream(const VprContext& vpr_ctx,
openfpga_ctx.vpr_device_annotation(),
openfpga_ctx.vpr_clustering_annotation(),
openfpga_ctx.vpr_placement_annotation(),
openfpga_ctx.vpr_bitstream_annotation(), verbose);
openfpga_ctx.vpr_bitstream_annotation(), prefer_unused_mux_input, verbose);
VTR_LOGV(verbose, "Done\n");
/* Create bitstream from routing architectures */
@ -229,7 +230,8 @@ BitstreamManager build_device_bitstream(const VprContext& vpr_ctx,
openfpga_ctx.arch().circuit_lib, openfpga_ctx.mux_lib(), vpr_ctx.atom(),
openfpga_ctx.vpr_device_annotation(), openfpga_ctx.vpr_routing_annotation(),
vpr_ctx.device().rr_graph, openfpga_ctx.device_rr_gsb(),
openfpga_ctx.flow_manager().compress_routing(), verbose);
openfpga_ctx.flow_manager().compress_routing(), prefer_unused_mux_input,
verbose);
VTR_LOGV(verbose, "Done\n");

View File

@ -18,6 +18,7 @@ namespace openfpga {
BitstreamManager build_device_bitstream(const VprContext& vpr_ctx,
const OpenfpgaContext& openfpga_ctx,
const bool& prefer_unused_mux_input,
const bool& verbose);
} /* end namespace openfpga */

View File

@ -185,7 +185,8 @@ static void build_physical_block_pin_interc_bitstream(
const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation,
const VprBitstreamAnnotation& bitstream_annotation,
const PhysicalPb& physical_pb, t_pb_graph_pin* des_pb_graph_pin,
t_mode* physical_mode, const bool& verbose) {
t_mode* physical_mode, const bool& prefer_unused_mux_input,
const bool& verbose) {
/* Identify the number of fan-in (Consider interconnection edges of only
* selected mode) */
t_interconnect* cur_interc =
@ -225,16 +226,47 @@ static void build_physical_block_pin_interc_bitstream(
* - if des pb is not valid, this is an unmapped pb, we can set a default
* path_id
* - There is no net mapped to des_pb_graph_pin we use default path id
* - There is a net mapped to des_pin_graph_pin: we find the path id
* - There is a net mapped to des_pb_graph_pin: we find the path id
*/
const PhysicalPbId& des_pb_id =
physical_pb.find_pb(des_pb_graph_pin->parent_node);
size_t mux_input_pin_id = 0;
if (true != physical_pb.valid_pb_id(des_pb_id)) {
if (true != physical_pb.valid_pb_id(des_pb_id)) { /* Unmapped pb */
mux_input_pin_id = DEFAULT_PATH_ID;
} else if (AtomNetId::INVALID() == physical_pb.pb_graph_pin_atom_net(
des_pb_id, des_pb_graph_pin)) {
mux_input_pin_id = DEFAULT_PATH_ID;
/* Unmapped output */
if (false == circuit_lib.mux_add_const_input(mux_model) &&
prefer_unused_mux_input) {
/* No constant input and fix flag is set
* Select the first unmapped input */
auto pin_inputs = pb_graph_pin_inputs(des_pb_graph_pin, cur_interc);
size_t pin_id;
for (pin_id = 0; pin_id < pin_inputs.size(); pin_id++) {
auto src_pb_graph_pin = pin_inputs[pin_id];
const PhysicalPbId& src_pb_id =
physical_pb.find_pb(src_pb_graph_pin->parent_node);
if (!physical_pb.valid_pb_id(src_pb_id)) {
mux_input_pin_id = pin_id;
break;
}
}
/* Couldn't find an unmapped input, use default path ID */
if (pin_id == pin_inputs.size()) {
VTR_LOGV_WARN(verbose,
"At PhysicalPbId=%d: output is unmapped but all"
" inputs are mapped\n",
des_pb_id);
mux_input_pin_id = DEFAULT_PATH_ID;
}
/* or the first input was already unmapped, use default path ID */
if (mux_input_pin_id == 0) {
mux_input_pin_id = DEFAULT_PATH_ID;
}
} else {
/* We have constant input, use the default path ID */
mux_input_pin_id = DEFAULT_PATH_ID;
}
} else {
output_net =
physical_pb.pb_graph_pin_atom_net(des_pb_id, des_pb_graph_pin);
@ -385,7 +417,7 @@ static void build_physical_block_interc_port_bitstream(
const VprBitstreamAnnotation& bitstream_annotation,
t_pb_graph_node* physical_pb_graph_node, const PhysicalPb& physical_pb,
const e_circuit_pb_port_type& pb_port_type, t_mode* physical_mode,
const bool& verbose) {
const bool& prefer_unused_mux_input, const bool& verbose) {
switch (pb_port_type) {
case CIRCUIT_PB_PORT_INPUT:
for (int iport = 0; iport < physical_pb_graph_node->num_input_ports;
@ -398,7 +430,7 @@ static void build_physical_block_interc_port_bitstream(
circuit_lib, mux_lib, atom_ctx, device_annotation,
bitstream_annotation, physical_pb,
&(physical_pb_graph_node->input_pins[iport][ipin]), physical_mode,
verbose);
prefer_unused_mux_input, verbose);
}
}
break;
@ -413,7 +445,7 @@ static void build_physical_block_interc_port_bitstream(
circuit_lib, mux_lib, atom_ctx, device_annotation,
bitstream_annotation, physical_pb,
&(physical_pb_graph_node->output_pins[iport][ipin]), physical_mode,
verbose);
prefer_unused_mux_input, verbose);
}
}
break;
@ -428,7 +460,7 @@ static void build_physical_block_interc_port_bitstream(
circuit_lib, mux_lib, atom_ctx, device_annotation,
bitstream_annotation, physical_pb,
&(physical_pb_graph_node->clock_pins[iport][ipin]), physical_mode,
verbose);
prefer_unused_mux_input, verbose);
}
}
break;
@ -451,7 +483,8 @@ static void build_physical_block_interc_bitstream(
const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation,
const VprBitstreamAnnotation& bitstream_annotation,
t_pb_graph_node* physical_pb_graph_node, const PhysicalPb& physical_pb,
t_mode* physical_mode, const bool& verbose) {
t_mode* physical_mode, const bool& prefer_unused_mux_input,
const bool& verbose) {
/* Check if the pb_graph node is valid or not */
if (nullptr == physical_pb_graph_node) {
VTR_LOGF_ERROR(__FILE__, __LINE__, "Invalid physical_pb_graph_node.\n");
@ -472,7 +505,8 @@ static void build_physical_block_interc_bitstream(
bitstream_manager, grouped_mem_inst_scoreboard, parent_configurable_block,
module_manager, module_name_map, circuit_lib, mux_lib, atom_ctx,
device_annotation, bitstream_annotation, physical_pb_graph_node,
physical_pb, CIRCUIT_PB_PORT_OUTPUT, physical_mode, verbose);
physical_pb, CIRCUIT_PB_PORT_OUTPUT, physical_mode, prefer_unused_mux_input,
verbose);
/* We check input_pins of child_pb_graph_node and its the input_edges
* Iterate over the interconnections between inputs of physical_pb_graph_node
@ -496,14 +530,14 @@ static void build_physical_block_interc_bitstream(
parent_configurable_block, module_manager, module_name_map, circuit_lib,
mux_lib, atom_ctx, device_annotation, bitstream_annotation,
child_pb_graph_node, physical_pb, CIRCUIT_PB_PORT_INPUT, physical_mode,
verbose);
prefer_unused_mux_input, verbose);
/* For clock pins, we should do the same work */
build_physical_block_interc_port_bitstream(
bitstream_manager, grouped_mem_inst_scoreboard,
parent_configurable_block, module_manager, module_name_map, circuit_lib,
mux_lib, atom_ctx, device_annotation, bitstream_annotation,
child_pb_graph_node, physical_pb, CIRCUIT_PB_PORT_CLOCK, physical_mode,
verbose);
prefer_unused_mux_input, verbose);
}
}
}
@ -712,7 +746,7 @@ static void rec_build_physical_block_bitstream(
const VprBitstreamAnnotation& bitstream_annotation, const e_side& border_side,
const PhysicalPb& physical_pb, const PhysicalPbId& pb_id,
t_pb_graph_node* physical_pb_graph_node, const size_t& pb_graph_node_index,
const bool& verbose) {
const bool& prefer_unused_mux_input, const bool& verbose) {
/* Get the physical pb_type that is linked to the pb_graph node */
t_pb_type* physical_pb_type = physical_pb_graph_node->pb_type;
@ -773,7 +807,7 @@ static void rec_build_physical_block_bitstream(
child_pb,
&(physical_pb_graph_node
->child_pb_graph_nodes[physical_mode->index][ipb][jpb]),
jpb, verbose);
jpb, prefer_unused_mux_input, verbose);
}
}
}
@ -817,7 +851,7 @@ static void rec_build_physical_block_bitstream(
bitstream_manager, grouped_mem_inst_scoreboard, pb_configurable_block,
module_manager, module_name_map, circuit_lib, mux_lib, atom_ctx,
device_annotation, bitstream_annotation, physical_pb_graph_node,
physical_pb, physical_mode, verbose);
physical_pb, physical_mode, prefer_unused_mux_input, verbose);
}
/********************************************************************
@ -836,7 +870,8 @@ static void build_physical_block_bitstream(
const VprPlacementAnnotation& place_annotation,
const VprBitstreamAnnotation& bitstream_annotation, const DeviceGrid& grids,
const size_t& layer, const vtr::Point<size_t>& grid_coord,
const e_side& border_side, const bool& verbose) {
const e_side& border_side, const bool& prefer_unused_mux_input,
const bool& verbose) {
/* Create a block for the grid in bitstream manager */
t_physical_tile_type_ptr grid_type = grids.get_physical_type(
t_physical_tile_loc(grid_coord.x(), grid_coord.y(), layer));
@ -931,7 +966,7 @@ static void build_physical_block_bitstream(
grid_configurable_block, module_manager, module_name_map, circuit_lib,
mux_lib, atom_ctx, device_annotation, bitstream_annotation,
border_side, PhysicalPb(), PhysicalPbId::INVALID(),
lb_type->pb_graph_head, z, verbose);
lb_type->pb_graph_head, z, prefer_unused_mux_input, verbose);
} else {
const PhysicalPb& phy_pb = cluster_annotation.physical_pb(
place_annotation.grid_blocks(grid_coord)[z]);
@ -946,7 +981,8 @@ static void build_physical_block_bitstream(
bitstream_manager, grouped_mem_inst_scoreboard,
grid_configurable_block, module_manager, module_name_map, circuit_lib,
mux_lib, atom_ctx, device_annotation, bitstream_annotation,
border_side, phy_pb, top_pb_id, pb_graph_head, z, verbose);
border_side, phy_pb, top_pb_id, pb_graph_head, z,
prefer_unused_mux_input, verbose);
}
}
}
@ -966,7 +1002,8 @@ void build_grid_bitstream(
const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation,
const VprClusteringAnnotation& cluster_annotation,
const VprPlacementAnnotation& place_annotation,
const VprBitstreamAnnotation& bitstream_annotation, const bool& verbose) {
const VprBitstreamAnnotation& bitstream_annotation,
const bool& prefer_unused_mux_input, const bool& verbose) {
VTR_LOGV(verbose, "Generating bitstream for core grids...");
/* Generate bitstream for the core logic block one by one */
@ -1007,7 +1044,8 @@ void build_grid_bitstream(
bitstream_manager, parent_block, module_manager, module_name_map,
fabric_tile, curr_tile, circuit_lib, mux_lib, atom_ctx,
device_annotation, cluster_annotation, place_annotation,
bitstream_annotation, grids, layer, grid_coord, NUM_2D_SIDES, verbose);
bitstream_annotation, grids, layer, grid_coord, NUM_2D_SIDES,
prefer_unused_mux_input, verbose);
}
}
VTR_LOGV(verbose, "Done\n");
@ -1055,7 +1093,8 @@ void build_grid_bitstream(
bitstream_manager, parent_block, module_manager, module_name_map,
fabric_tile, curr_tile, circuit_lib, mux_lib, atom_ctx,
device_annotation, cluster_annotation, place_annotation,
bitstream_annotation, grids, layer, io_coordinate, io_side, verbose);
bitstream_annotation, grids, layer, io_coordinate, io_side,
prefer_unused_mux_input, verbose);
}
}
VTR_LOGV(verbose, "Done\n");

View File

@ -34,7 +34,8 @@ void build_grid_bitstream(
const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation,
const VprClusteringAnnotation& cluster_annotation,
const VprPlacementAnnotation& place_annotation,
const VprBitstreamAnnotation& bitstream_annotation, const bool& verbose);
const VprBitstreamAnnotation& bitstream_annotation,
const bool& prefer_unused_mux_input, const bool& verbose);
} /* end namespace openfpga */

View File

@ -38,7 +38,8 @@ static void build_switch_block_mux_bitstream(
const RRGraphView& rr_graph, const RRNodeId& cur_rr_node,
const std::vector<RRNodeId>& drive_rr_nodes, const AtomContext& atom_ctx,
const VprDeviceAnnotation& device_annotation,
const VprRoutingAnnotation& routing_annotation, const bool& verbose) {
const VprRoutingAnnotation& routing_annotation,
const bool& prefer_unused_mux_input, const bool& verbose) {
/* Check current rr_node is CHANX or CHANY*/
VTR_ASSERT((CHANX == rr_graph.node_type(cur_rr_node)) ||
(CHANY == rr_graph.node_type(cur_rr_node)));
@ -46,6 +47,14 @@ static void build_switch_block_mux_bitstream(
/* Find the input size of the implementation of a routing multiplexer */
size_t datapath_mux_size = drive_rr_nodes.size();
/* Find the circuit model id of the mux, we need its design technology which
* matters the bitstream generation */
std::vector<RRSwitchId> driver_switches =
get_rr_graph_driver_switches(rr_graph, cur_rr_node);
VTR_ASSERT(1 == driver_switches.size());
CircuitModelId mux_model =
device_annotation.rr_switch_circuit_model(driver_switches[0]);
/* Cache input and output nets */
std::vector<ClusterNetId> input_nets;
ClusterNetId output_net = routing_annotation.rr_node_net(cur_rr_node);
@ -78,21 +87,37 @@ static void build_switch_block_mux_bitstream(
break;
}
}
}
} else if (false == circuit_lib.mux_add_const_input(mux_model) && prefer_unused_mux_input) {
/* If
* 1. output net is INVALID (unmapped)
* 2. and we don't have a constant input,
* 3. and the prefer_unused_mux_input flag is on,
* then find an unmapped input and connect it to the output net */
for (size_t inode = 0; inode < drive_rr_nodes.size(); inode++) {
if (input_nets[inode] == ClusterNetId::INVALID()) {
path_id = inode;
break;
}
}
/* Warn if all inputs were mapped */
if (path_id == DEFAULT_PATH_ID) {
VTR_LOGV_WARN(
verbose,
"At RRNodeId = %d: output is unmapped but all inputs are mapped?",
cur_rr_node);
}
/* If the first input was already unmapped, set path id to default
* (for compatibility purposes) */
if (path_id == 0) {
path_id = DEFAULT_PATH_ID;
}
} /* Keep default path id if output is unmapped but all inputs are mapped */
/* Ensure that our path id makes sense! */
VTR_ASSERT(
(DEFAULT_PATH_ID == path_id) ||
((DEFAULT_PATH_ID < path_id) && (path_id < (int)datapath_mux_size)));
/* Find the circuit model id of the mux, we need its design technology which
* matters the bitstream generation */
std::vector<RRSwitchId> driver_switches =
get_rr_graph_driver_switches(rr_graph, cur_rr_node);
VTR_ASSERT(1 == driver_switches.size());
CircuitModelId mux_model =
device_annotation.rr_switch_circuit_model(driver_switches[0]);
/* Generate bitstream depend on both technology and structure of this MUX */
std::vector<bool> mux_bitstream = build_mux_bitstream(
circuit_lib, mux_model, mux_lib, datapath_mux_size, path_id);
@ -164,7 +189,8 @@ static void build_switch_block_interc_bitstream(
const RRGraphView& rr_graph, const AtomContext& atom_ctx,
const VprDeviceAnnotation& device_annotation,
const VprRoutingAnnotation& routing_annotation, const RRGSB& rr_gsb,
const e_side& chan_side, const size_t& chan_node_id, const bool& verbose) {
const e_side& chan_side, const size_t& chan_node_id,
const bool& prefer_unused_mux_input, const bool& verbose) {
std::vector<RRNodeId> driver_rr_nodes;
/* Get the node */
@ -200,7 +226,7 @@ static void build_switch_block_interc_bitstream(
build_switch_block_mux_bitstream(
bitstream_manager, mux_mem_block, module_manager, module_name_map,
circuit_lib, mux_lib, rr_graph, cur_rr_node, driver_rr_nodes, atom_ctx,
device_annotation, routing_annotation, verbose);
device_annotation, routing_annotation, prefer_unused_mux_input, verbose);
} /*Nothing should be done else*/
}
@ -221,7 +247,8 @@ static void build_switch_block_bitstream(
const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib,
const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation,
const VprRoutingAnnotation& routing_annotation, const RRGraphView& rr_graph,
const RRGSB& rr_gsb, const bool& verbose) {
const RRGSB& rr_gsb, const bool& prefer_unused_mux_input,
const bool& verbose) {
/* Iterate over all the multiplexers */
for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) {
SideManager side_manager(side);
@ -239,7 +266,8 @@ static void build_switch_block_bitstream(
build_switch_block_interc_bitstream(
bitstream_manager, sb_config_block, module_manager, module_name_map,
circuit_lib, mux_lib, rr_graph, atom_ctx, device_annotation,
routing_annotation, rr_gsb, side_manager.get_side(), itrack, verbose);
routing_annotation, rr_gsb, side_manager.get_side(), itrack,
prefer_unused_mux_input, verbose);
}
}
}
@ -258,13 +286,21 @@ static void build_connection_block_mux_bitstream(
const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation,
const VprRoutingAnnotation& routing_annotation, const RRGraphView& rr_graph,
const RRGSB& rr_gsb, const e_side& cb_ipin_side, const size_t& ipin_index,
const bool& verbose) {
const bool& prefer_unused_mux_input, const bool& verbose) {
RRNodeId src_rr_node = rr_gsb.get_ipin_node(cb_ipin_side, ipin_index);
/* Find drive_rr_nodes*/
std::vector<RREdgeId> driver_rr_edges =
rr_gsb.get_ipin_node_in_edges(rr_graph, cb_ipin_side, ipin_index);
size_t datapath_mux_size = driver_rr_edges.size();
/* Find the circuit model id of the mux, we need its design technology which
* matters the bitstream generation */
std::vector<RRSwitchId> driver_switches =
get_rr_graph_driver_switches(rr_graph, src_rr_node);
VTR_ASSERT(1 == driver_switches.size());
CircuitModelId mux_model =
device_annotation.rr_switch_circuit_model(driver_switches[0]);
/* Cache input and output nets */
std::vector<ClusterNetId> input_nets;
ClusterNetId output_net = routing_annotation.rr_node_net(src_rr_node);
@ -295,21 +331,41 @@ static void build_connection_block_mux_bitstream(
}
edge_index++;
}
}
} else if (false == circuit_lib.mux_add_const_input(mux_model) &&
prefer_unused_mux_input) {
/* If
* 1. output net is INVALID (unmapped)
* 2. and we don't have a constant input,
* 3. and the prefer_unused_mux_input flag is on,
* then find an unmapped input and connect it to the output net */
for (size_t iedge = 0; iedge < driver_rr_edges.size(); iedge++) {
RREdgeId edge = driver_rr_edges[iedge];
RRNodeId driver_node = rr_graph.edge_src_node(edge);
if (routing_annotation.rr_node_net(driver_node) ==
ClusterNetId::INVALID()){
path_id = iedge;
break;
}
}
/* Warn if all inputs are mapped */
if (path_id == int(driver_rr_edges.size())) {
VTR_LOGV_WARN(
verbose,
"At RRNodeId = %d: output is unmapped but all inputs are mapped?",
src_rr_node);
}
/* If the first input was already unmapped, set path id to default
* (for compatibility purposes) */
if (path_id == 0) {
path_id = DEFAULT_PATH_ID;
}
} /* Keep default path id if output is unmapped but all inputs are mapped */
/* Ensure that our path id makes sense! */
VTR_ASSERT(
(DEFAULT_PATH_ID == path_id) ||
((DEFAULT_PATH_ID < path_id) && (path_id < (int)datapath_mux_size)));
/* Find the circuit model id of the mux, we need its design technology which
* matters the bitstream generation */
std::vector<RRSwitchId> driver_switches =
get_rr_graph_driver_switches(rr_graph, src_rr_node);
VTR_ASSERT(1 == driver_switches.size());
CircuitModelId mux_model =
device_annotation.rr_switch_circuit_model(driver_switches[0]);
/* Generate bitstream depend on both technology and structure of this MUX */
std::vector<bool> mux_bitstream = build_mux_bitstream(
circuit_lib, mux_model, mux_lib, datapath_mux_size, path_id);
@ -382,7 +438,7 @@ static void build_connection_block_interc_bitstream(
const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation,
const VprRoutingAnnotation& routing_annotation, const RRGraphView& rr_graph,
const RRGSB& rr_gsb, const e_side& cb_ipin_side, const size_t& ipin_index,
const bool& verbose) {
const bool& prefer_unused_mux_input, const bool& verbose) {
RRNodeId src_rr_node = rr_gsb.get_ipin_node(cb_ipin_side, ipin_index);
VTR_LOGV(verbose, "\tGenerating bitstream for IPIN '%lu'. Details: %s\n",
@ -414,7 +470,8 @@ static void build_connection_block_interc_bitstream(
build_connection_block_mux_bitstream(
bitstream_manager, mux_mem_block, module_manager, module_name_map,
circuit_lib, mux_lib, atom_ctx, device_annotation, routing_annotation,
rr_graph, rr_gsb, cb_ipin_side, ipin_index, verbose);
rr_graph, rr_gsb, cb_ipin_side, ipin_index, prefer_unused_mux_input,
verbose);
} /*Nothing should be done else*/
}
@ -436,7 +493,8 @@ static void build_connection_block_bitstream(
const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib,
const AtomContext& atom_ctx, const VprDeviceAnnotation& device_annotation,
const VprRoutingAnnotation& routing_annotation, const RRGraphView& rr_graph,
const RRGSB& rr_gsb, const t_rr_type& cb_type, const bool& verbose) {
const RRGSB& rr_gsb, const t_rr_type& cb_type,
const bool& prefer_unused_mux_input, const bool& verbose) {
/* Find routing multiplexers on the sides of a Connection block where IPIN
* nodes locate */
std::vector<enum e_side> cb_sides = rr_gsb.get_cb_ipin_sides(cb_type);
@ -451,7 +509,8 @@ static void build_connection_block_bitstream(
build_connection_block_interc_bitstream(
bitstream_manager, cb_configurable_block, module_manager,
module_name_map, circuit_lib, mux_lib, atom_ctx, device_annotation,
routing_annotation, rr_graph, rr_gsb, cb_ipin_side, inode, verbose);
routing_annotation, rr_graph, rr_gsb, cb_ipin_side, inode,
prefer_unused_mux_input, verbose);
}
}
}
@ -467,8 +526,9 @@ static void build_connection_block_bitstreams(
const MuxLibrary& mux_lib, const AtomContext& atom_ctx,
const VprDeviceAnnotation& device_annotation,
const VprRoutingAnnotation& routing_annotation, const RRGraphView& rr_graph,
const DeviceRRGSB& device_rr_gsb, const bool& compact_routing_hierarchy,
const t_rr_type& cb_type, const bool& verbose) {
const DeviceRRGSB& device_rr_gsb, bool compact_routing_hierarchy,
const t_rr_type& cb_type, const bool& prefer_unused_mux_input,
const bool& verbose) {
vtr::Point<size_t> cb_range = device_rr_gsb.get_gsb_range();
for (size_t ix = 0; ix < cb_range.x(); ++ix) {
@ -592,7 +652,8 @@ static void build_connection_block_bitstreams(
build_connection_block_bitstream(
bitstream_manager, cb_configurable_block, module_manager,
module_name_map, circuit_lib, mux_lib, atom_ctx, device_annotation,
routing_annotation, rr_graph, rr_gsb, cb_type, verbose);
routing_annotation, rr_graph, rr_gsb, cb_type, prefer_unused_mux_input,
verbose);
VTR_LOGV(verbose, "\tDone\n");
}
@ -614,7 +675,7 @@ void build_routing_bitstream(
const VprDeviceAnnotation& device_annotation,
const VprRoutingAnnotation& routing_annotation, const RRGraphView& rr_graph,
const DeviceRRGSB& device_rr_gsb, const bool& compact_routing_hierarchy,
const bool& verbose) {
const bool& prefer_unused_mux_input, const bool& verbose) {
/* Generate bitstream for each switch blocks
* To organize the bitstream in blocks, we create a block for each switch
* block and give names which are same as they are in top-level module
@ -724,7 +785,7 @@ void build_routing_bitstream(
build_switch_block_bitstream(
bitstream_manager, sb_configurable_block, module_manager,
module_name_map, circuit_lib, mux_lib, atom_ctx, device_annotation,
routing_annotation, rr_graph, rr_gsb, verbose);
routing_annotation, rr_graph, rr_gsb, prefer_unused_mux_input, verbose);
VTR_LOGV(verbose, "\tDone\n");
}
@ -742,7 +803,7 @@ void build_routing_bitstream(
bitstream_manager, top_configurable_block, module_manager, module_name_map,
fabric_tile, circuit_lib, mux_lib, atom_ctx, device_annotation,
routing_annotation, rr_graph, device_rr_gsb, compact_routing_hierarchy,
CHANX, verbose);
CHANX, prefer_unused_mux_input, verbose);
VTR_LOG("Done\n");
VTR_LOG("Generating bitstream for Y-direction Connection blocks ...");
@ -751,7 +812,7 @@ void build_routing_bitstream(
bitstream_manager, top_configurable_block, module_manager, module_name_map,
fabric_tile, circuit_lib, mux_lib, atom_ctx, device_annotation,
routing_annotation, rr_graph, device_rr_gsb, compact_routing_hierarchy,
CHANY, verbose);
CHANY, prefer_unused_mux_input, verbose);
VTR_LOG("Done\n");
}

View File

@ -36,7 +36,7 @@ void build_routing_bitstream(
const VprDeviceAnnotation& device_annotation,
const VprRoutingAnnotation& routing_annotation, const RRGraphView& rr_graph,
const DeviceRRGSB& device_rr_gsb, const bool& compact_routing_hierarchy,
const bool& verbose);
const bool& prefer_unused_mux_input, const bool& verbose);
} /* end namespace openfpga */