Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add behavior to handle unmapped muxes without constant inputs better #1869

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/source/manual/arch_lang/circuit_model_examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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``.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions openfpga/src/base/openfpga_bitstream_command_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
7 changes: 5 additions & 2 deletions openfpga/src/base/openfpga_bitstream_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
6 changes: 4 additions & 2 deletions openfpga/src/fpga_bitstream/build_device_bitstream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 '") +
Expand Down Expand Up @@ -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 */
Expand All @@ -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");

Expand Down
1 change: 1 addition & 0 deletions openfpga/src/fpga_bitstream/build_device_bitstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
81 changes: 60 additions & 21 deletions openfpga/src/fpga_bitstream/build_grid_bitstream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
fkosar-ql marked this conversation as resolved.
Show resolved Hide resolved
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 =
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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");
Expand All @@ -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
Expand All @@ -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);
}
}
}
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
}
}
}
Expand Down Expand Up @@ -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);
}

/********************************************************************
Expand All @@ -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));
Expand Down Expand Up @@ -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]);
Expand All @@ -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);
}
}
}
Expand All @@ -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 */
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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");
Expand Down
3 changes: 2 additions & 1 deletion openfpga/src/fpga_bitstream/build_grid_bitstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down
Loading
Loading