[engine] developing pcf2place integration to openfpga

This commit is contained in:
tangxifan 2022-07-28 10:30:43 -07:00
parent 72ce2c29c2
commit 2a5bffa6b9
8 changed files with 143 additions and 174 deletions

View File

@ -28,8 +28,7 @@ target_link_libraries(libopenfpga
libpcf
libvtrutil
libbusgroup
libvpr
libpinconstrain)
libvpr)
#Create the test executable
add_executable(openfpga ${EXEC_SOURCE})

View File

@ -1,96 +0,0 @@
/********************************************************************
* This file includes functions to build bitstream database
*******************************************************************/
/* Headers from vtrutil library */
#include "vtr_time.h"
#include "vtr_log.h"
/* Headers from openfpgashell library */
#include "command_exit_codes.h"
/* Headers from openfpgautil library */
#include "openfpga_digest.h"
#include "openfpga_reserved_words.h"
#include "openfpga_naming.h"
#include "openfpga_constrain_pin_location.h"
/* Include global variables of VPR */
#include "globals.h"
/* begin namespace openfpga */
extern int pin_constrain_location (std::vector<std::string> args);
namespace openfpga {
/********************************************************************
* Top-level function to read an OpenFPGA architecture file
* we use the APIs from the libarchopenfpga library
*
* The command will accept an option '--file' which is the architecture
* file provided by users
*******************************************************************/
int constrain_pin_location(OpenfpgaContext& openfpga_context, const Command& cmd, const CommandContext& cmd_context) {
/* initialize arguments with sanity check*/
std::vector<std::string> pin_constrain_args;
pin_constrain_args.push_back("pin_c");
/* todo: create a factory to produce this in the future*/
std::string pcf_option_name = "pcf";
CommandOptionId opt_pcf_file = cmd.option(pcf_option_name);
VTR_ASSERT(true == cmd_context.option_enable(cmd, opt_pcf_file));
VTR_ASSERT(false == cmd_context.option_value(cmd, opt_pcf_file).empty());
std::string pcf_file_name = cmd_context.option_value(cmd, opt_pcf_file);
pin_constrain_args.push_back(std::string("--") + pcf_option_name);
pin_constrain_args.push_back(pcf_file_name.c_str());
std::string blif_option_name = "blif";
CommandOptionId opt_blif_file = cmd.option(blif_option_name);
VTR_ASSERT(true == cmd_context.option_enable(cmd, opt_blif_file));
VTR_ASSERT(false == cmd_context.option_value(cmd, opt_blif_file).empty());
std::string blif_file_name = cmd_context.option_value(cmd, opt_blif_file);
pin_constrain_args.push_back(std::string("--") + blif_option_name);
pin_constrain_args.push_back(blif_file_name);
#if 0
// --net is not supported by pin_c yet
std::string net_option_name = "net";
CommandOptionId opt_net_file = cmd.option(net_option_name);
VTR_ASSERT(true == cmd_context.option_enable(cmd, opt_net_file));
VTR_ASSERT(false == cmd_context.option_value(cmd, opt_net_file).empty());
std::string net_file_name = cmd_context.option_value(cmd, opt_net_file);
pin_constrain_args.push_back(std::string("--") + net_option_name);
pin_constrain_args.push_back(net_file_name);
#endif
std::string pinmap_xml_option_name = "pinmap_xml";
CommandOptionId opt_pinmap_xml_file = cmd.option(pinmap_xml_option_name);
VTR_ASSERT(true == cmd_context.option_enable(cmd, opt_pinmap_xml_file));
VTR_ASSERT(false == cmd_context.option_value(cmd, opt_pinmap_xml_file).empty());
std::string pinmap_xml_file_name = cmd_context.option_value(cmd, opt_pinmap_xml_file);
pin_constrain_args.push_back(std::string("--xml"));
pin_constrain_args.push_back(pinmap_xml_file_name);
std::string csv_file_option_name = "csv_file";
CommandOptionId opt_csv_file = cmd.option(csv_file_option_name);
VTR_ASSERT(true == cmd_context.option_enable(cmd, opt_csv_file));
VTR_ASSERT(false == cmd_context.option_value(cmd, opt_csv_file).empty());
std::string csv_file_name = cmd_context.option_value(cmd, opt_csv_file);
pin_constrain_args.push_back(std::string("--csv"));
pin_constrain_args.push_back(csv_file_name);
std::string output_option_name = "output";
CommandOptionId opt_output_file = cmd.option(output_option_name);
VTR_ASSERT(true == cmd_context.option_enable(cmd, opt_output_file));
VTR_ASSERT(false == cmd_context.option_value(cmd, opt_output_file).empty());
std::string output_file_name = cmd_context.option_value(cmd, opt_output_file);
pin_constrain_args.push_back(std::string("--") + output_option_name);
pin_constrain_args.push_back(output_file_name);
if (pin_constrain_location(pin_constrain_args)) {
return CMD_EXEC_FATAL_ERROR;
}
return CMD_EXEC_SUCCESS;
}
} /* end namespace openfpga */

View File

@ -1,49 +0,0 @@
/********************************************************************
* Add commands to the OpenFPGA shell interface,
* in purpose of setting up OpenFPGA core engine, including:
* - read_openfpga_arch : read OpenFPGA architecture file
*******************************************************************/
#include "openfpga_constrain_pin_location_command.h"
#include "openfpga_constrain_pin_location.h"
/* begin namespace openfpga */
namespace openfpga {
/********************************************************************
* - Add a command to Shell environment: constrain_pin_location
* - Add associated options
* - Add command dependency
*******************************************************************/
void add_openfpga_constrain_pin_location_command(openfpga::Shell<OpenfpgaContext>& shell) {
Command shell_cmd("constrain_pin_location");
/* Options are created by following the python script crafted by QL, since that has been used for a while:
python3 create_ioplace.py --pcf pcf_file --blif blif_file --net net_file --pinmap_xml pinmap_xml_file --csv_file csv_file --output outputplace_file
*/
/* Add an option '--pcf'*/
CommandOptionId opt_pcf_file = shell_cmd.add_option("pcf", true, "file path to the user pin constraint");
shell_cmd.set_option_require_value(opt_pcf_file, openfpga::OPT_STRING);
/* Add an option '--blif'*/
CommandOptionId opt_blif_file = shell_cmd.add_option("blif", true, "file path to the synthesized blif");
shell_cmd.set_option_require_value(opt_blif_file, openfpga::OPT_STRING);
/* Add an option '--pinmap_xml'*/
CommandOptionId opt_pinmap_file = shell_cmd.add_option("pinmap_xml", true, "file path to the pin location XML");
shell_cmd.set_option_require_value(opt_pinmap_file, openfpga::OPT_STRING);
/* Add an option '--csv_file'*/
CommandOptionId opt_csv_file = shell_cmd.add_option("csv_file", true, "file path to the pin map csv");
shell_cmd.set_option_require_value(opt_csv_file, openfpga::OPT_STRING);
/* Add an option '--output'*/
CommandOptionId opt_output_file = shell_cmd.add_option("output", true, "file path to the output");
shell_cmd.set_option_require_value(opt_output_file, openfpga::OPT_STRING);
/* Add command 'constrain_pin_location' to the Shell */
ShellCommandId shell_cmd_id = shell.add_command(shell_cmd, "constrain pin location by generating a place file");
shell.set_command_execute_function(shell_cmd_id, constrain_pin_location);
}
} /* end namespace openfpga */

View File

@ -1,21 +0,0 @@
#ifndef OPENFPGA_CONSTRAIN_PIN_LOCATION_COMMAND_H
#define OPENFPGA_CONSTRAIN_PIN_LOCATION_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_constrain_pin_location_command(openfpga::Shell<OpenfpgaContext>& shell);
} /* end namespace openfpga */
#endif

View File

@ -0,0 +1,86 @@
/********************************************************************
* This file includes functions to build bitstream database
*******************************************************************/
/* Headers from vtrutil library */
#include "vtr_time.h"
#include "vtr_log.h"
/* Headers from openfpgashell library */
#include "command_exit_codes.h"
/* Headers from openfpgautil library */
#include "openfpga_digest.h"
/* Headers from pcf library */
#include "pcf_reader.h"
#include "blif_head_reader.h"
#include "read_csv_io_pin_table.h"
#include "read_xml_io_location_map.h"
#include "io_net_place.h"
#include "pcf2place.h"
/* begin namespace openfpga */
namespace openfpga {
/********************************************************************
* Top-level function to convert a .pcf file to a .place file which
* which VPR can force I/O placement
*******************************************************************/
int pcf2place_wrapper(const OpenfpgaContext& openfpga_context,
const Command& cmd, const CommandContext& cmd_context) {
/* todo: create a factory to produce this in the future*/
CommandOptionId opt_pcf = cmd.option("pcf");
CommandOptionId opt_blif = cmd.option("blif");
CommandOptionId opt_fpga_io_map = cmd.option("fpga_io_map");
CommandOptionId opt_pin_table = cmd.option("pin_table");
CommandOptionId opt_fpga_fix_pins = cmd.option("fpga_fix_pins");
CommandOptionId opt_no_time_stamp = cmd.option("no_time_stamp");
CommandOptionId opt_verbose = cmd.option("verbose");
std::string pcf_fname = cmd_context.option_value(cmd, opt_pcf);
std::string blif_fname = cmd_context.option_value(cmd, opt_blif);
std::string fpga_io_map_fname = cmd_context.option_value(cmd, opt_fpga_io_map);
/* Parse the input files */
openfpga::PcfData pcf_data;
openfpga::read_pcf(pcf_fname, pcf_data);
VTR_LOG("Read the design constraints from a pcf file: %s.\n",
pcf_fname.c_str());
blifparse::BlifHeadReader callback;
blifparse::blif_parse_filename(argv[2], callback);
VTR_LOG("Read the blif from a file: %s.\n",
argv[2]);
if (callback.had_error()) {
VTR_LOG("Read the blif ends with errors\n",
argv[2]);
return 1;
}
openfpga::IoLocationMap io_location_map = openfpga::read_xml_io_location_map(argv[3]);
VTR_LOG("Read the I/O location map from an XML file: %s.\n",
argv[3]);
openfpga::IoPinTable io_pin_table = openfpga::read_csv_io_pin_table(argv[4]);
VTR_LOG("Read the I/O pin table from a csv file: %s.\n",
argv[4]);
/* Convert */
openfpga::IoNetPlace io_net_place;
int status = pcf2place(pcf_data, callback.input_pins(), callback.output_pins(), io_pin_table, io_location_map, io_net_place);
if (status) {
return status;
}
/* Output */
status = io_net_place.write_to_place_file(argv[5], true, true);
return CMD_EXEC_FATAL_ERROR;
}
return CMD_EXEC_SUCCESS;
}
} /* end namespace openfpga */

View File

@ -1,5 +1,5 @@
#ifndef OPENFPGA_BITSTREAM_H
#define OPENFPGA_BITSTREAM_H
#ifndef OPENFPGA_PCF2PLACE_H
#define OPENFPGA_PCF2PLACE_H
/********************************************************************
* Include header files that are required by function declaration
@ -14,7 +14,10 @@
/* begin namespace openfpga */
namespace openfpga {
int constrain_pin_location(OpenfpgaContext& openfpga_context, const Command& cmd, const CommandContext& cmd_context);
int pcf2place_wrapper(const OpenfpgaContext& openfpga_context,
const Command& cmd, const CommandContext& cmd_context);
} /* end namespace openfpga */
#endif

View File

@ -421,6 +421,50 @@ ShellCommandId add_openfpga_write_fabric_io_info_command(openfpga::Shell<Openfpg
return shell_cmd_id;
}
/********************************************************************
* - Add a command to Shell environment: pcf2place
* - Add associated options
* - Add command dependency
*******************************************************************/
static
ShellCommandId add_openfpga_pcf2place_command(openfpga::Shell<OpenfpgaContext>& shell,
const ShellCommandClassId& cmd_class_id) {
Command shell_cmd("pcf2place");
/* Add an option '--pcf'*/
CommandOptionId opt_pcf_file = shell_cmd.add_option("pcf", true, "file path to the user pin constraint");
shell_cmd.set_option_require_value(opt_pcf_file, openfpga::OPT_STRING);
/* Add an option '--blif'*/
CommandOptionId opt_blif_file = shell_cmd.add_option("blif", true, "file path to the synthesized netlist (.blif)");
shell_cmd.set_option_require_value(opt_blif_file, openfpga::OPT_STRING);
/* Add an option '--fpga_io_map'*/
CommandOptionId opt_fpga_io_map_file = shell_cmd.add_option("fpga_io_map", true, "file path to FPGA I/O location map (.xml)");
shell_cmd.set_option_require_value(opt_fpga_io_map_file, openfpga::OPT_STRING);
/* Add an option '--pin_table'*/
CommandOptionId opt_pin_table_file = shell_cmd.add_option("pin_table", true, "file path to the pin table (.csv)");
shell_cmd.set_option_require_value(opt_pin_table_file, openfpga::OPT_STRING);
/* Add an option '--fpga_fix_pins'*/
CommandOptionId opt_fpga_fix_pins_file = shell_cmd.add_option("fpga_fix_pins", true, "file path to the output fix-pin placement file (.place)");
shell_cmd.set_option_require_value(opt_fpga_fix_pins_file, openfpga::OPT_STRING);
/* Add an option '--no_time_stamp' */
shell_cmd.add_option("no_time_stamp", false, "Do not print time stamp in output files");
/* Add an option '--verbose' */
shell_cmd.add_option("verbose", false, "Enable verbose output");
/* Add command to the Shell */
ShellCommandId shell_cmd_id = shell.add_command(shell_cmd, "Convert user Pin Constraint File (.pcf) to an placement file");
shell.set_command_class(shell_cmd_id, cmd_class_id);
shell.set_command_execute_function(shell_cmd_id, pcf2place_wrapper);
return shell_cmd_id;
}
void add_openfpga_setup_commands(openfpga::Shell<OpenfpgaContext>& shell) {
/* Get the unique id of 'vpr' command which is to be used in creating the dependency graph */
const ShellCommandId& vpr_cmd_id = shell.command(std::string("vpr"));
@ -428,6 +472,12 @@ void add_openfpga_setup_commands(openfpga::Shell<OpenfpgaContext>& shell) {
/* Add a new class of commands */
ShellCommandClassId openfpga_setup_cmd_class = shell.add_command_class("OpenFPGA setup");
/********************************
* Command 'pcf2place'
*/
ShellCommandId pcf2place_cmd_id = add_openfpga_pcf2place_command(shell,
openfpga_setup_cmd_class);
/********************************
* Command 'read_openfpga_arch'
*/

View File

@ -81,9 +81,6 @@ int main(int argc, char** argv) {
/* Add openfpga sdc commands */
openfpga::add_openfpga_sdc_commands(shell);
/* Add constrain pin location command */
openfpga::add_openfpga_constrain_pin_location_command(shell);
/* Add basic commands: exit, help, etc.
* Note:
* This MUST be the last command group to be added!