Skip to content

Commit

Permalink
Add behavior to handle unmapped muxes without constant inputs better
Browse files Browse the repository at this point in the history
  • Loading branch information
duck2 committed Oct 31, 2024
1 parent 0714ccf commit cc18704
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 60 deletions.
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
4 changes: 3 additions & 1 deletion openfpga/src/base/openfpga_bitstream_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@ 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));
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
8 changes: 6 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,9 @@ 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 +232,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,9 @@ 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 =
Expand Down Expand Up @@ -225,16 +227,46 @@ 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,7 @@ 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 +1001,9 @@ 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
4 changes: 3 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,9 @@ 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

0 comments on commit cc18704

Please sign in to comment.