Skip to content

Commit

Permalink
Merge pull request #62 from LNIS-Projects/dev
Browse files Browse the repository at this point in the history
Simplify fabric key where users just need to provide alias; start porting FPGA-SPICE
  • Loading branch information
tangxifan authored Jul 7, 2020
2 parents 1ef32c5 + 7615db2 commit f246da6
Show file tree
Hide file tree
Showing 46 changed files with 1,158 additions and 134 deletions.
1 change: 0 additions & 1 deletion docs/source/manual/arch_lang/fabric_key.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,4 @@ The following is an example of a fabric key generate by OpenFPGA for a 2 :math:`
<key id="30" name="cbx_1__1_" value="0" alias="cbx_1__1_"/>
<key id="31" name="grid_io_top" value="0" alias="grid_io_top_1_3"/>
<key id="32" name="grid_io_left" value="1" alias="grid_io_left_0_2"/>
<key id="33" name="decoder6to33" value="0"/>
</fabric_key>
21 changes: 15 additions & 6 deletions libopenfpga/libfabrickey/src/read_xml_fabric_key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ void read_xml_component_key(pugi::xml_node& xml_component_key,

/* Find the id of component key */
const size_t& id = get_attribute(xml_component_key, "id", loc_data).as_int();
const std::string& name = get_attribute(xml_component_key, "name", loc_data).as_string();
const size_t& value = get_attribute(xml_component_key, "value", loc_data).as_int();


if (false == fabric_key.valid_key_id(FabricKeyId(id))) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_component_key),
"Invalid 'id' attribute '%d'\n",
Expand All @@ -40,14 +38,25 @@ void read_xml_component_key(pugi::xml_node& xml_component_key,

VTR_ASSERT_SAFE(true == fabric_key.valid_key_id(FabricKeyId(id)));

fabric_key.set_key_name(FabricKeyId(id), name);
fabric_key.set_key_value(FabricKeyId(id), value);

/* If we have an alias, set the value as well */
const std::string& alias = get_attribute(xml_component_key, "alias", loc_data, pugiutil::ReqOpt::OPTIONAL).as_string();
if (!alias.empty()) {
fabric_key.set_key_alias(FabricKeyId(id), alias);
}

/* If we have the alias set, name and valus are optional then
* Otherwise, they are mandatory attributes
*/
pugiutil::ReqOpt required_name_value = pugiutil::ReqOpt::OPTIONAL;
if (true == alias.empty()) {
required_name_value = pugiutil::ReqOpt::REQUIRED;
}

const std::string& name = get_attribute(xml_component_key, "name", loc_data, required_name_value).as_string();
const size_t& value = get_attribute(xml_component_key, "value", loc_data, required_name_value).as_int();

fabric_key.set_key_name(FabricKeyId(id), name);
fabric_key.set_key_value(FabricKeyId(id), value);
}

/********************************************************************
Expand Down
4 changes: 3 additions & 1 deletion libopenfpga/libfabrickey/src/write_xml_fabric_key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ int write_xml_fabric_component_key(std::fstream& fp,
}

write_xml_attribute(fp, "id", size_t(component_key));
write_xml_attribute(fp, "name", fabric_key.key_name(component_key).c_str());
if (!fabric_key.key_name(component_key).empty()) {
write_xml_attribute(fp, "name", fabric_key.key_name(component_key).c_str());
}
write_xml_attribute(fp, "value", fabric_key.key_value(component_key));

if (!fabric_key.key_alias(component_key).empty()) {
Expand Down
4 changes: 4 additions & 0 deletions libopenfpga/libopenfpgautil/src/openfpga_reserved_words.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ constexpr char* INV_PORT_POSTFIX = "_inv";
/* Bitstream file strings */
constexpr char* BITSTREAM_XML_FILE_NAME_POSTFIX = "_bitstream.xml";

constexpr char* DEFAULT_LB_DIR_NAME = "lb/";
constexpr char* DEFAULT_RR_DIR_NAME = "routing/";
constexpr char* DEFAULT_SUBMODULE_DIR_NAME = "sub_module/";

} /* end namespace openfpga */

#endif
47 changes: 31 additions & 16 deletions openfpga/src/base/openfpga_build_fabric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ int build_fabric(OpenfpgaContext& openfpga_ctx,

VTR_LOG("\n");

/* Record the execution status in curr_status for each command
* and summarize them in the final status
*/
int curr_status = CMD_EXEC_SUCCESS;
int final_status = CMD_EXEC_SUCCESS;

/* Load fabric key from file */
FabricKey predefined_fabric_key;
if (true == cmd_context.option_enable(cmd, opt_load_fabric_key)) {
Expand All @@ -93,29 +99,38 @@ int build_fabric(OpenfpgaContext& openfpga_ctx,

VTR_LOG("\n");

openfpga_ctx.mutable_module_graph() = build_device_module_graph(openfpga_ctx.mutable_io_location_map(),
openfpga_ctx.mutable_decoder_lib(),
const_cast<const OpenfpgaContext&>(openfpga_ctx),
g_vpr_ctx.device(),
cmd_context.option_enable(cmd, opt_frame_view),
cmd_context.option_enable(cmd, opt_compress_routing),
cmd_context.option_enable(cmd, opt_duplicate_grid_pin),
predefined_fabric_key,
cmd_context.option_enable(cmd, opt_gen_random_fabric_key),
cmd_context.option_enable(cmd, opt_verbose));
curr_status = build_device_module_graph(openfpga_ctx.mutable_module_graph(),
openfpga_ctx.mutable_io_location_map(),
openfpga_ctx.mutable_decoder_lib(),
const_cast<const OpenfpgaContext&>(openfpga_ctx),
g_vpr_ctx.device(),
cmd_context.option_enable(cmd, opt_frame_view),
cmd_context.option_enable(cmd, opt_compress_routing),
cmd_context.option_enable(cmd, opt_duplicate_grid_pin),
predefined_fabric_key,
cmd_context.option_enable(cmd, opt_gen_random_fabric_key),
cmd_context.option_enable(cmd, opt_verbose));

/* If there is any error, final status cannot be overwritten by a success flag */
if (CMD_EXEC_SUCCESS != curr_status) {
final_status = curr_status;
}

/* Output fabric key if user requested */
if (true == cmd_context.option_enable(cmd, opt_write_fabric_key)) {
std::string fkey_fname = cmd_context.option_value(cmd, opt_write_fabric_key);
VTR_ASSERT(false == fkey_fname.empty());
write_fabric_key_to_xml_file(openfpga_ctx.module_graph(),
fkey_fname,
cmd_context.option_enable(cmd, opt_verbose));

curr_status = write_fabric_key_to_xml_file(openfpga_ctx.module_graph(),
fkey_fname,
openfpga_ctx.arch().config_protocol.type(),
cmd_context.option_enable(cmd, opt_verbose));
/* If there is any error, final status cannot be overwritten by a success flag */
if (CMD_EXEC_SUCCESS != curr_status) {
final_status = curr_status;
}
}

/* TODO: should identify the error code from internal function execution */
return CMD_EXEC_SUCCESS;
return final_status;
}

/********************************************************************
Expand Down
3 changes: 3 additions & 0 deletions openfpga/src/base/openfpga_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class OpenfpgaContext : public Context {
const openfpga::IoLocationMap& io_location_map() const { return io_location_map_; }
const std::unordered_map<AtomNetId, t_net_power>& net_activity() const { return net_activity_; }
const openfpga::NetlistManager& verilog_netlists() const { return verilog_netlists_; }
const openfpga::NetlistManager& spice_netlists() const { return spice_netlists_; }
public: /* Public mutators */
openfpga::Arch& mutable_arch() { return arch_; }
openfpga::SimulationSetting& mutable_simulation_setting() { return sim_setting_; }
Expand All @@ -86,6 +87,7 @@ class OpenfpgaContext : public Context {
openfpga::IoLocationMap& mutable_io_location_map() { return io_location_map_; }
std::unordered_map<AtomNetId, t_net_power>& mutable_net_activity() { return net_activity_; }
openfpga::NetlistManager& mutable_verilog_netlists() { return verilog_netlists_; }
openfpga::NetlistManager& mutable_spice_netlists() { return spice_netlists_; }
private: /* Internal data */
/* Data structure to store information from read_openfpga_arch library */
openfpga::Arch arch_;
Expand Down Expand Up @@ -130,6 +132,7 @@ class OpenfpgaContext : public Context {
* TODO: Each format should have an independent entry
*/
openfpga::NetlistManager verilog_netlists_;
openfpga::NetlistManager spice_netlists_;

/* Net activities of users' implementation */
std::unordered_map<AtomNetId, t_net_power> net_activity_;
Expand Down
48 changes: 48 additions & 0 deletions openfpga/src/base/openfpga_spice.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/********************************************************************
* This file includes functions to compress the hierachy of routing architecture
*******************************************************************/
/* Headers from vtrutil library */
#include "vtr_time.h"
#include "vtr_log.h"

/* Headers from openfpgashell library */
#include "command_exit_codes.h"

#include "spice_api.h"
#include "openfpga_spice.h"

/* Include global variables of VPR */
#include "globals.h"

/* begin namespace openfpga */
namespace openfpga {

/********************************************************************
* A wrapper function to call the fabric SPICE generator of FPGA-SPICE
*******************************************************************/
int write_fabric_spice(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context) {

CommandOptionId opt_output_dir = cmd.option("file");
CommandOptionId opt_explicit_port_mapping = cmd.option("explicit_port_mapping");
CommandOptionId opt_verbose = cmd.option("verbose");

/* This is an intermediate data structure which is designed to modularize the FPGA-SPICE
* Keep it independent from any other outside data structures
*/
FabricSpiceOption options;
options.set_output_directory(cmd_context.option_value(cmd, opt_output_dir));
options.set_explicit_port_mapping(cmd_context.option_enable(cmd, opt_explicit_port_mapping));
options.set_verbose_output(cmd_context.option_enable(cmd, opt_verbose));
options.set_compress_routing(openfpga_ctx.flow_manager().compress_routing());

int status = CMD_EXEC_SUCCESS;
status = fpga_fabric_spice(openfpga_ctx.module_graph(),
openfpga_ctx.mutable_spice_netlists(),
openfpga_ctx.arch().tech_lib,
options);

return status;
}

} /* end namespace openfpga */
23 changes: 23 additions & 0 deletions openfpga/src/base/openfpga_spice.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef OPENFPGA_SPICE_H
#define OPENFPGA_SPICE_H

/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include "command.h"
#include "command_context.h"
#include "openfpga_context.h"

/********************************************************************
* Function declaration
*******************************************************************/

/* begin namespace openfpga */
namespace openfpga {

int write_fabric_spice(OpenfpgaContext& openfpga_ctx,
const Command& cmd, const CommandContext& cmd_context);

} /* end namespace openfpga */

#endif
78 changes: 78 additions & 0 deletions openfpga/src/base/openfpga_spice_command.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/********************************************************************
* Add commands to the OpenFPGA shell interface,
* in purpose of generate SPICE netlists modeling the full FPGA fabric
* This is one of the core engine of openfpga, including:
* - generate_fabric_spice : generate Verilog netlists about FPGA fabric
* - TODO: generate_spice_top_testbench : generate SPICE testbenches for top-level module
* - TODO: generate_spice_grid_testbench : generate SPICE testbenches for grids
* - TODO: generate_spice_cb_testbench : generate SPICE testbenches for connection blocks
* - TODO: generate_spice_sb_testbench : generate SPICE testbenches for switch blocks
* - TODO: generate_spice_lut_testbench : generate SPICE testbenches for Look-Up Tables
* - TODO: generate_spice_hard_logic_testbench : generate SPICE testbenches for all the hard logics
* - TODO: generate_spice_local_routing_testbench : generate SPICE testbenches for local routing
* - TODO: generate_spice_cb_routing_testbench : generate SPICE testbenches for routing circuit inside connection blocks
* - TODO: generate_spice_sb_routing_testbench : generate SPICE testbenches for routing circuit inside switch blocks
*******************************************************************/
#include "openfpga_spice.h"
#include "openfpga_spice_command.h"

/* begin namespace openfpga */
namespace openfpga {

/********************************************************************
* - Add a command to Shell environment: generate fabric Verilog
* - Add associated options
* - Add command dependency
*******************************************************************/
static
ShellCommandId add_openfpga_write_fabric_spice_command(openfpga::Shell<OpenfpgaContext>& shell,
const ShellCommandClassId& cmd_class_id,
const std::vector<ShellCommandId>& dependent_cmds) {
Command shell_cmd("write_fabric_spice");

/* Add an option '--file' in short '-f'*/
CommandOptionId output_opt = shell_cmd.add_option("file", true, "Specify the output directory for SPICE netlists");
shell_cmd.set_option_short_name(output_opt, "f");
shell_cmd.set_option_require_value(output_opt, openfpga::OPT_STRING);

/* Add an option '--explicit_port_mapping' */
shell_cmd.add_option("explicit_port_mapping", false, "Use explicit port mapping in Verilog netlists");

/* Add an option '--verbose' */
shell_cmd.add_option("verbose", false, "Enable verbose output");

/* Add command 'write_fabric_spice' to the Shell */
ShellCommandId shell_cmd_id = shell.add_command(shell_cmd, "generate SPICE netlists modeling full FPGA fabric");
shell.set_command_class(shell_cmd_id, cmd_class_id);
shell.set_command_execute_function(shell_cmd_id, write_fabric_spice);

/* Add command dependency to the Shell */
shell.set_command_dependency(shell_cmd_id, dependent_cmds);

return shell_cmd_id;
}

void add_openfpga_spice_commands(openfpga::Shell<OpenfpgaContext>& shell) {
/* Get the unique id of 'build_fabric' command which is to be used in creating the dependency graph */
const ShellCommandId& build_fabric_cmd_id = shell.command(std::string("build_fabric"));

/* Add a new class of commands */
ShellCommandClassId openfpga_spice_cmd_class = shell.add_command_class("FPGA-SPICE");

/********************************
* Command 'write_fabric_spice'
*/
/* The 'write_fabric_spice' command should NOT be executed before 'build_fabric' */
std::vector<ShellCommandId> fabric_spice_dependent_cmds;
fabric_spice_dependent_cmds.push_back(build_fabric_cmd_id);
add_openfpga_write_fabric_spice_command(shell,
openfpga_spice_cmd_class,
fabric_spice_dependent_cmds);

/********************************
* TODO: Command 'write_spice_top_testbench'
*/
/* The command 'write_spice_top_testbench' should NOT be executed before 'build_fabric' */
}

} /* end namespace openfpga */
21 changes: 21 additions & 0 deletions openfpga/src/base/openfpga_spice_command.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef OPENFPGA_SPICE_COMMAND_H
#define OPENFPGA_SPICE_COMMAND_H

/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include "shell.h"
#include "openfpga_context.h"

/********************************************************************
* Function declaration
*******************************************************************/

/* begin namespace openfpga */
namespace openfpga {

void add_openfpga_spice_commands(openfpga::Shell<OpenfpgaContext>& shell);

} /* end namespace openfpga */

#endif
4 changes: 4 additions & 0 deletions openfpga/src/fabric/build_decoder_modules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,10 @@ void build_mux_local_decoder_module(ModuleManager& module_manager,
/* Create a Verilog Module based on the circuit model, and add to module manager */
ModuleId module_id = module_manager.add_module(module_name);
VTR_ASSERT(true == module_manager.valid_module_id(module_id));

/* Label module usage */
module_manager.set_module_usage(module_id, ModuleManager::MODULE_CONFIG);

/* Add module ports */
/* Add each input port */
BasicPort addr_port(generate_mux_local_decoder_addr_port_name(), addr_size);
Expand Down
Loading

0 comments on commit f246da6

Please sign in to comment.