Skip to content

Commit

Permalink
Merge pull request #1781 from lnis-uofu/xt_rpt_ref
Browse files Browse the repository at this point in the history
Rework the option ``constant_undriven_wire``
  • Loading branch information
tangxifan authored Aug 7, 2024
2 parents 41160bb + 1026df4 commit 1e6e044
Show file tree
Hide file tree
Showing 25 changed files with 517 additions and 115 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ write_fabric_verilog

Specify the output directory for the Verilog netlists. For example, ``--file /temp/fabric_netlist/``

.. option:: --constant_undriven_inputs
.. option:: --constant_undriven_inputs <string>

.. note:: This option is automatically enabled when the option ``perimeter_cb`` of tileable routing resource graph is enabled (see details in :ref`addon_vpr_syntax`).
.. note:: This option is automatically enabled and set to ``bus0`` when the option ``perimeter_cb`` of tileable routing resource graph is enabled (see details in :ref`addon_vpr_syntax`).

.. note:: Enable this option may shadow issues in your FPGA architecture, which causes them difficult to be found in design verification.

Use constant gnd for undriven wires in Verilog netlists. Recommand to enable when there are boundary routing tracks in FPGA fabric.
Can be [``none`` | ``bus0`` | ``bus1`` | ``bit0`` | ``bit1`` ]. Use constant 0 or 1 for undriven wires in Verilog netlists. Recommand to enable when there are boundary routing tracks in FPGA fabric. When ``bus0`` or ``bus1`` are set, the constant wiring will be done in a bus format. When ``bit0`` or ``bit1`` are set, the constant wiring will be done in a bit-blast style. Suggest to use bit-blast style only when downstream Verilog parsers do not support bus format. By default, it is ``none``.

.. option:: --default_net_type <string>

Expand Down
7 changes: 5 additions & 2 deletions openfpga/src/base/openfpga_verilog_command_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,13 @@ ShellCommandId add_write_fabric_verilog_command_template(
shell_cmd.set_option_require_value(output_opt, openfpga::OPT_STRING);

/* Add an option '--constant_undriven_inputs' */
shell_cmd.add_option(
CommandOptionId const_undriven_inputs_opt = shell_cmd.add_option(
"constant_undriven_inputs", false,
"Use constant gnd for undriven wires in Verilog netlists. Recommand to "
"Can be [none|bus0|bus1|bit0|bit1]. Use constant vdd/gnd for undriven "
"wires in Verilog netlists. Recommand to "
"enable when there are boundary routing tracks in FPGA fabric");
shell_cmd.set_option_require_value(const_undriven_inputs_opt,
openfpga::OPT_STRING);

/* Add an option '--explicit_port_mapping' */
shell_cmd.add_option("explicit_port_mapping", false,
Expand Down
23 changes: 14 additions & 9 deletions openfpga/src/base/openfpga_verilog_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,21 @@ int write_fabric_verilog_template(T& openfpga_ctx, const Command& cmd,
}
options.set_verbose_output(cmd_context.option_enable(cmd, opt_verbose));
options.set_compress_routing(openfpga_ctx.flow_manager().compress_routing());
/* For perimeter cb, enable the constant undriven inputs, unless it is off by
* user */
if (g_vpr_ctx.device().arch->perimeter_cb) {
options.set_constant_undriven_inputs(true);
VTR_LOG(
"Automatically enable the constant_undriven_input option as perimeter "
"connection blocks are seen in FPGA fabric\n");
} else {
/* For perimeter cb, enable the constant-zero undriven inputs, unless it is
* defined by user. Throw error if the constant inputs are not selected! */
if (cmd_context.option_enable(cmd, opt_constant_undriven_inputs)) {
options.set_constant_undriven_inputs(
cmd_context.option_enable(cmd, opt_constant_undriven_inputs));
cmd_context.option_value(cmd, opt_constant_undriven_inputs));
}
if (g_vpr_ctx.device().arch->perimeter_cb) {
if (FabricVerilogOption::e_undriven_input_type::NONE ==
options.constant_undriven_inputs()) {
options.set_constant_undriven_inputs(
FabricVerilogOption::e_undriven_input_type::BUS0);
VTR_LOG(
"Automatically enable the constant_undriven_input option as perimeter "
"connection blocks are seen in FPGA fabric\n");
}
}

return fpga_fabric_verilog(
Expand Down
64 changes: 60 additions & 4 deletions openfpga/src/fpga_verilog/fabric_verilog_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ FabricVerilogOption::FabricVerilogOption() {
default_net_type_ = VERILOG_DEFAULT_NET_TYPE_NONE;
time_stamp_ = true;
use_relative_path_ = false;
constant_undriven_inputs_ = false;
constant_undriven_inputs_ = FabricVerilogOption::e_undriven_input_type::NONE;
CONSTANT_UNDRIVEN_INPUT_TYPE_STRING_ = {"none", "bus0", "bus1", "bit0",
"bit1"};
verbose_output_ = false;
}

Expand Down Expand Up @@ -54,10 +56,41 @@ e_verilog_default_net_type FabricVerilogOption::default_net_type() const {
return default_net_type_;
}

bool FabricVerilogOption::constant_undriven_inputs() const {
FabricVerilogOption::e_undriven_input_type
FabricVerilogOption::constant_undriven_inputs() const {
return constant_undriven_inputs_;
}

bool FabricVerilogOption::constant_undriven_inputs_use_bus() const {
return constant_undriven_inputs_ ==
FabricVerilogOption::e_undriven_input_type::BUS0 ||
constant_undriven_inputs_ ==
FabricVerilogOption::e_undriven_input_type::BUS1;
}

size_t FabricVerilogOption::constant_undriven_inputs_value() const {
if (constant_undriven_inputs_ ==
FabricVerilogOption::e_undriven_input_type::BUS1 ||
constant_undriven_inputs_ ==
FabricVerilogOption::e_undriven_input_type::BIT1) {
return 1;
}
return 0;
}

std::string FabricVerilogOption::full_constant_undriven_input_type_str() const {
std::string full_type_str("[");
for (size_t itype = 0;
itype < size_t(FabricVerilogOption::e_undriven_input_type::NUM_TYPES);
++itype) {
full_type_str += std::string(CONSTANT_UNDRIVEN_INPUT_TYPE_STRING_[itype]) +
std::string("|");
}
full_type_str.pop_back();
full_type_str += std::string("]");
return full_type_str;
}

bool FabricVerilogOption::verbose_output() const { return verbose_output_; }

/******************************************************************************
Expand Down Expand Up @@ -111,8 +144,31 @@ void FabricVerilogOption::set_default_net_type(
}
}

void FabricVerilogOption::set_constant_undriven_inputs(const bool& enabled) {
constant_undriven_inputs_ = enabled;
bool FabricVerilogOption::set_constant_undriven_inputs(
const std::string& type_str) {
bool valid_type = false;
for (size_t itype = 0;
itype < size_t(FabricVerilogOption::e_undriven_input_type::NUM_TYPES);
++itype) {
if (std::string(CONSTANT_UNDRIVEN_INPUT_TYPE_STRING_[itype]) == type_str) {
constant_undriven_inputs_ =
static_cast<FabricVerilogOption::e_undriven_input_type>(itype);
valid_type = true;
break;
}
}
if (!valid_type) {
VTR_LOG_ERROR("Invalid types for undriven inputs: %s. Expect %s\n",
type_str.c_str(),
full_constant_undriven_input_type_str().c_str());
}
return valid_type;
}

bool FabricVerilogOption::set_constant_undriven_inputs(
const FabricVerilogOption::e_undriven_input_type& type) {
constant_undriven_inputs_ = type;
return type != FabricVerilogOption::e_undriven_input_type::NUM_TYPES;
}

void FabricVerilogOption::set_verbose_output(const bool& enabled) {
Expand Down
33 changes: 30 additions & 3 deletions openfpga/src/fpga_verilog/fabric_verilog_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ namespace openfpga {
* Options for Fabric Verilog generator
*******************************************************************/
class FabricVerilogOption {
public: /* Types */
enum class e_undriven_input_type {
NONE = 0, /* Leave undriven input to be dangling */
BUS0, /* Wire to a bus format of constant 0 */
BUS1, /* Wire to a bus format of constant 1 */
BIT0, /* Wire to a blast-bit format of constant 0 */
BIT1, /* Wire to a blast-bit format of constant 1 */
NUM_TYPES
};

public: /* Public constructor */
/* Set default options */
FabricVerilogOption();
Expand All @@ -28,7 +38,14 @@ class FabricVerilogOption {
bool compress_routing() const;
e_verilog_default_net_type default_net_type() const;
bool print_user_defined_template() const;
bool constant_undriven_inputs() const;
e_undriven_input_type constant_undriven_inputs() const;
/* Identify if a bus format should be applied when wiring undriven inputs to
* constants */
bool constant_undriven_inputs_use_bus() const;
/* Identify the logic value should be applied when wiring undriven inputs to
* constants */
size_t constant_undriven_inputs_value() const;
std::string full_constant_undriven_input_type_str() const;
bool verbose_output() const;

public: /* Public mutators */
Expand All @@ -40,7 +57,13 @@ class FabricVerilogOption {
void set_compress_routing(const bool& enabled);
void set_print_user_defined_template(const bool& enabled);
void set_default_net_type(const std::string& default_net_type);
void set_constant_undriven_inputs(const bool& enabled);
/** Decode the type from string to enumeration
* "none" -> NONE, "bus0" -> BUS0, "bus1" -> BUS1, "bit0" -> BIT0, "bit1" ->
* BIT1 For invalid types, error out
*/
bool set_constant_undriven_inputs(const std::string& type_str);
/** For invalid types, error out */
bool set_constant_undriven_inputs(const e_undriven_input_type& type);
void set_verbose_output(const bool& enabled);

private: /* Internal Data */
Expand All @@ -52,7 +75,11 @@ class FabricVerilogOption {
e_verilog_default_net_type default_net_type_;
bool time_stamp_;
bool use_relative_path_;
bool constant_undriven_inputs_;
e_undriven_input_type constant_undriven_inputs_;
std::array<const char*,
size_t(FabricVerilogOption::e_undriven_input_type::NUM_TYPES)>
CONSTANT_UNDRIVEN_INPUT_TYPE_STRING_; // String versions of constant
// undriven input types
bool verbose_output_;
};

Expand Down
15 changes: 6 additions & 9 deletions openfpga/src/fpga_verilog/verilog_grid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,10 @@ static void print_verilog_primitive_block(
module_manager.module_name(primitive_module).c_str());

/* Write the verilog module */
write_verilog_module_to_file(fp, module_manager, primitive_module, true,
options.constant_undriven_inputs(),
options.default_net_type());
FabricVerilogOption curr_options = options;
curr_options.set_explicit_port_mapping(true);
write_verilog_module_to_file(fp, module_manager, primitive_module,
curr_options);

/* Close file handler */
fp.close();
Expand Down Expand Up @@ -233,9 +234,7 @@ static void rec_print_verilog_logical_tile(
std::string(physical_pb_type->name) + " -----"));

/* Write the verilog module */
write_verilog_module_to_file(
fp, module_manager, pb_module, options.explicit_port_mapping(),
options.constant_undriven_inputs(), options.default_net_type());
write_verilog_module_to_file(fp, module_manager, pb_module, options);

print_verilog_comment(
fp,
Expand Down Expand Up @@ -347,9 +346,7 @@ static void print_verilog_physical_tile_netlist(
print_verilog_comment(
fp, std::string("----- BEGIN Grid Verilog module: " +
module_manager.module_name(grid_module) + " -----"));
write_verilog_module_to_file(
fp, module_manager, grid_module, options.explicit_port_mapping(),
options.constant_undriven_inputs(), options.default_net_type());
write_verilog_module_to_file(fp, module_manager, grid_module, options);

print_verilog_comment(
fp, std::string("----- END Grid Verilog module: " +
Expand Down
8 changes: 4 additions & 4 deletions openfpga/src/fpga_verilog/verilog_lut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@ void print_verilog_submodule_luts(const ModuleManager& module_manager,
ModuleId lut_module = module_manager.find_module(
module_name_map.name(circuit_lib.model_name(lut_model)));
VTR_ASSERT(true == module_manager.valid_module_id(lut_module));
write_verilog_module_to_file(
fp, module_manager, lut_module,
FabricVerilogOption curr_options = options;
curr_options.set_explicit_port_mapping(
options.explicit_port_mapping() ||
circuit_lib.dump_explicit_port_map(lut_model),
options.constant_undriven_inputs(), options.default_net_type());
circuit_lib.dump_explicit_port_map(lut_model));
write_verilog_module_to_file(fp, module_manager, lut_module, curr_options);
}

/* Close the file handler */
Expand Down
35 changes: 14 additions & 21 deletions openfpga/src/fpga_verilog/verilog_memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,12 @@ static void print_verilog_mux_memory_module(
ModuleId mem_module = module_manager.find_module(module_name);
VTR_ASSERT(true == module_manager.valid_module_id(mem_module));
/* Write the module content in Verilog format */
write_verilog_module_to_file(
fp, module_manager, mem_module,
FabricVerilogOption curr_options = options;
curr_options.set_explicit_port_mapping(
options.explicit_port_mapping() ||
circuit_lib.dump_explicit_port_map(mux_model),
options.constant_undriven_inputs(), options.default_net_type());
circuit_lib.dump_explicit_port_map(mux_model));
write_verilog_module_to_file(fp, module_manager, mem_module,
curr_options);

/* Add an empty line as a splitter */
fp << std::endl;
Expand All @@ -80,11 +81,8 @@ static void print_verilog_mux_memory_module(
if (module_manager.valid_module_id(feedthru_mem_module)) {
VTR_ASSERT(true == module_manager.valid_module_id(feedthru_mem_module));
/* Write the module content in Verilog format */
write_verilog_module_to_file(
fp, module_manager, feedthru_mem_module,
options.explicit_port_mapping() ||
circuit_lib.dump_explicit_port_map(mux_model),
options.constant_undriven_inputs(), options.default_net_type());
write_verilog_module_to_file(fp, module_manager, feedthru_mem_module,
curr_options);

/* Add an empty line as a splitter */
fp << std::endl;
Expand Down Expand Up @@ -205,11 +203,11 @@ void print_verilog_submodule_memories(
ModuleId mem_module = module_manager.find_module(module_name);
VTR_ASSERT(true == module_manager.valid_module_id(mem_module));
/* Write the module content in Verilog format */
write_verilog_module_to_file(fp, module_manager, mem_module,
options.explicit_port_mapping() ||
circuit_lib.dump_explicit_port_map(model),
options.constant_undriven_inputs(),
options.default_net_type());
FabricVerilogOption curr_options = options;
curr_options.set_explicit_port_mapping(
options.explicit_port_mapping() ||
circuit_lib.dump_explicit_port_map(model));
write_verilog_module_to_file(fp, module_manager, mem_module, curr_options);

/* Add an empty line as a splitter */
fp << std::endl;
Expand All @@ -227,10 +225,7 @@ void print_verilog_submodule_memories(
if (module_manager.valid_module_id(feedthru_mem_module)) {
/* Write the module content in Verilog format */
write_verilog_module_to_file(fp, module_manager, feedthru_mem_module,
options.explicit_port_mapping() ||
circuit_lib.dump_explicit_port_map(model),
options.constant_undriven_inputs(),
options.default_net_type());
curr_options);

/* Add an empty line as a splitter */
fp << std::endl;
Expand All @@ -241,9 +236,7 @@ void print_verilog_submodule_memories(
for (ModuleId mem_group_module : module_manager.modules_by_usage(
ModuleManager::e_module_usage_type::MODULE_CONFIG_GROUP)) {
/* Write the module content in Verilog format */
write_verilog_module_to_file(
fp, module_manager, mem_group_module, options.explicit_port_mapping(),
options.constant_undriven_inputs(), options.default_net_type());
write_verilog_module_to_file(fp, module_manager, mem_group_module, options);

/* Add an empty line as a splitter */
fp << std::endl;
Expand Down
Loading

0 comments on commit 1e6e044

Please sign in to comment.