[lib] deprecate libpinconstrain

This commit is contained in:
tangxifan 2022-07-28 14:26:56 -07:00
parent cde7a130d3
commit 1d0cad9f96
21 changed files with 0 additions and 1005 deletions

View File

@ -1,40 +0,0 @@
cmake_minimum_required(VERSION 3.9)
project("libpinconstrain")
file(GLOB_RECURSE EXEC_SOURCES test/*.cpp)
file(GLOB_RECURSE LIB_SOURCES src/*.cpp)
file(GLOB_RECURSE LIB_HEADERS src/*.h)
files_to_dirs(LIB_HEADERS LIB_INCLUDE_DIRS)
file(GLOB_RECURSE BLIF_READ_HEADERS ../../vpr/src/base/*.h)
files_to_dirs(BLIF_READ_HEADERS BLIF_READ_INCLUDE_DIRS)
file(GLOB_RECURSE VTR_UTIL_HEADERS ../../libs/libvtrutil/src/*.h)
files_to_dirs(VTR_UTIL_HEADERS VTR_UTIL_INCLUDE_DIRS)
#Remove test executable from library
list(REMOVE_ITEM LIB_SOURCES ${EXEC_SOURCES})
#Create the library
add_library(libpinconstrain STATIC
${LIB_HEADERS}
${LIB_SOURCES})
target_include_directories(libpinconstrain PUBLIC ${LIB_INCLUDE_DIRS} ${BLIF_READ_INCLUDE_DIRS} ${VTR_UTIL_INCLUDE_DIRS})
set_target_properties(libpinconstrain PROPERTIES PREFIX "") #Avoid extra 'lib' prefix
#Specify link-time dependancies
target_link_libraries(libpinconstrain
libvpr
libvtrutil
libpugixml)
#Create the test executable
foreach(testsourcefile ${EXEC_SOURCES})
# Use a simple string replace, to cut off .cpp.
get_filename_component(testname ${testsourcefile} NAME_WE)
add_executable(${testname} ${testsourcefile})
target_include_directories(${testname} PUBLIC ${LIB_INCLUDE_DIRS} ${BLIF_READ_INCLUDE_DIRS} ${VTR_UTIL_INCLUDE_DIRS})
# Make sure the library is linked to each test executable
target_link_libraries(${testname} libpinconstrain)
endforeach(testsourcefile ${EXEC_SOURCES})

View File

@ -1,3 +0,0 @@
set_io a pad_fpga_io[0]
set_io b pad_fpga_io[4]
set_io c pad_fpga_io[6]

View File

@ -1,17 +0,0 @@
orientation,row,col,pin_num_in_cell,port_name,mapped_pin,GPIO_type,Associated Clock,Clock Edge
TOP,,,,gfpga_pad_IO_A2F[0],pad_fpga_io[0],,,
TOP,,,,gfpga_pad_IO_F2A[0],pad_fpga_io[0],,,
TOP,,,,gfpga_pad_IO_A2F[4],pad_fpga_io[1],,,
TOP,,,,gfpga_pad_IO_F2A[4],pad_fpga_io[1],,,
TOP,,,,gfpga_pad_IO_A2F[8],pad_fpga_io[2],,,
TOP,,,,gfpga_pad_IO_F2A[8],pad_fpga_io[2],,,
TOP,,,,gfpga_pad_IO_A2F[31],pad_fpga_io[3],,,
TOP,,,,gfpga_pad_IO_F2A[31],pad_fpga_io[3],,,
RIGHT,,,,gfpga_pad_IO_A2F[32],pad_fpga_io[4],,,
RIGHT,,,,gfpga_pad_IO_F2A[32],pad_fpga_io[4],,,
RIGHT,,,,gfpga_pad_IO_A2F[40],pad_fpga_io[5],,,
RIGHT,,,,gfpga_pad_IO_F2A[40],pad_fpga_io[5],,,
BOTTOM,,,,gfpga_pad_IO_A2F[64],pad_fpga_io[6],,,
BOTTOM,,,,gfpga_pad_IO_F2A[64],pad_fpga_io[6],,,
LEFT,,,,gfpga_pad_IO_F2A[127],pad_fpga_io[7],,,
LEFT,,,,gfpga_pad_IO_A2F[127],pad_fpga_io[7],,,
1 orientation row col pin_num_in_cell port_name mapped_pin GPIO_type Associated Clock Clock Edge
2 TOP gfpga_pad_IO_A2F[0] pad_fpga_io[0]
3 TOP gfpga_pad_IO_F2A[0] pad_fpga_io[0]
4 TOP gfpga_pad_IO_A2F[4] pad_fpga_io[1]
5 TOP gfpga_pad_IO_F2A[4] pad_fpga_io[1]
6 TOP gfpga_pad_IO_A2F[8] pad_fpga_io[2]
7 TOP gfpga_pad_IO_F2A[8] pad_fpga_io[2]
8 TOP gfpga_pad_IO_A2F[31] pad_fpga_io[3]
9 TOP gfpga_pad_IO_F2A[31] pad_fpga_io[3]
10 RIGHT gfpga_pad_IO_A2F[32] pad_fpga_io[4]
11 RIGHT gfpga_pad_IO_F2A[32] pad_fpga_io[4]
12 RIGHT gfpga_pad_IO_A2F[40] pad_fpga_io[5]
13 RIGHT gfpga_pad_IO_F2A[40] pad_fpga_io[5]
14 BOTTOM gfpga_pad_IO_A2F[64] pad_fpga_io[6]
15 BOTTOM gfpga_pad_IO_F2A[64] pad_fpga_io[6]
16 LEFT gfpga_pad_IO_F2A[127] pad_fpga_io[7]
17 LEFT gfpga_pad_IO_A2F[127] pad_fpga_io[7]

View File

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
XML file specification is primarily to define the mapping of the interface cell ports defined
in vpr_arch xml, to the EFPGA IO interface port names. This mapping is required by OpenFPGA
alongwith architecture definition file i.e. vpr_arch xml file. OpenFPGA will process this
file and use this information for IO placement and then later on use this to map it with the
user-defined pin-mapping file.
-->
<DEVICE name= "k4_N4_tileable_40nm" family="k4n4" width="6" height="6" z="8">
<IO>
<TOP_IO y="5">
<CELL port_name="output" mapped_name="gfpga_pad_IO_F2A[0:31]" startx="1" endx="4"/>
<CELL port_name="input" mapped_name="gfpga_pad_IO_A2F[0:31]" startx="1" endx="4"/>
</TOP_IO>
<RIGHT_IO x="5">
<CELL port_name="output" mapped_name="gfpga_pad_IO_F2A[32:63]" starty="4" endy="1"/>
<CELL port_name="input" mapped_name="gfpga_pad_IO_A2F[32:63]" starty="4" endy="1"/>
</RIGHT_IO>
<BOTTOM_IO y="0">
<CELL port_name="output" mapped_name="gfpga_pad_IO_F2A[64:95]" startx="4" endx="1"/>
<CELL port_name="input" mapped_name="gfpga_pad_IO_A2F[64:95]" startx="4" endx="1"/>
</BOTTOM_IO>
<LEFT_IO x="0">
<CELL port_name="output" mapped_name="gfpga_pad_IO_F2A[96:127]" starty="1" endy="4"/>
<CELL port_name="input" mapped_name="gfpga_pad_IO_A2F[96:127]" starty="1" endy="4"/>
</LEFT_IO>
</IO>
</DEVICE>

View File

@ -1,71 +0,0 @@
#include "vtr_path.h"
#include "read_blif.h"
#include "blifparse.hpp"
#include "blif_reader.h"
#include "vtr_log.h"
// blif parser callback
using namespace blifparse;
class BlifParserCallback : public Callback {
public:
void start_parse() override {}
void filename(std::string /*fname*/) override {}
void lineno(int /*line_num*/) override {}
void begin_model(std::string /*model_name*/) override {}
void inputs(std::vector<std::string> input_ports) override {
for (auto input_port : input_ports) {
inputs_.push_back(input_port);
}
}
void outputs(std::vector<std::string> output_ports) override {
for (auto output_port : output_ports) {
outputs_.push_back(output_port);
}
}
void names(std::vector<std::string> /*nets*/, std::vector<std:: vector<LogicValue>> /*so_cover*/) override {}
void latch(std::string /*input*/, std::string /*output*/, LatchType /* type*/, std::string /*control*/, LogicValue /*init*/) override {}
void subckt(std::string /*model*/, std::vector<std::string> /*ports*/, std:: vector<std::string> /*nets*/) override {}
void blackbox() override {}
void end_model() override {}
void finish_parse() override {}
void parse_error(const int curr_lineno, const std::string& near_text, const std::string& msg) override {
VTR_LOG_ERROR("Custom Error at line %d near '%s': %s\n", curr_lineno, near_text.c_str(), msg.c_str());
had_error_ = true;
}
bool had_error() { return had_error_ == true; }
std::vector<std::string> get_inputs() { return inputs_;}
std::vector<std::string> get_outputs() { return outputs_;}
private:
bool had_error_ = false;
std::vector<std::string> inputs_;
std::vector<std::string> outputs_;
};
// read port info from blif file
bool BlifReader::read_blif(const std::string &blif_file_name)
{
e_circuit_format circuit_format;
auto name_ext = vtr::split_ext(blif_file_name);
if (name_ext[1] == ".blif") {
circuit_format = e_circuit_format::BLIF;
} else if (name_ext[1] == ".eblif") {
circuit_format = e_circuit_format::EBLIF;
} else {
return false;
}
BlifParserCallback callback;
blif_parse_filename(blif_file_name, callback);
if (callback.had_error()) {
return false;
}
inputs = callback.get_inputs();
outputs = callback.get_outputs();
return true;
}

View File

@ -1,37 +0,0 @@
#ifndef BLIF_READER_H
#define BLIF_READER_H
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
#include <unordered_map>
#include <map>
/*
Supported PCF commands:
* set_io <net> <pad> - constrain a given <net> to a given physical <pad> in eFPGA pinout.
* set_clk <pin> <net> - constrain a given global clock <pin> to a given <net>
Every tile where <net> is present will be constrained to use a given global clock.
*/
using namespace std;
class BlifReader
{
vector<string> inputs;
vector<string> outputs;
public:
BlifReader() {}
BlifReader(const std::string &f)
{
read_blif(f);
}
bool read_blif(const std::string &f);
const vector<string>& get_inputs()const { return inputs;}
const vector<string>& get_outputs()const { return outputs;}
};
#endif

View File

@ -1,53 +0,0 @@
#include "csv_reader.h"
#include <algorithm>
#include "vtr_log.h"
bool CvsReader::read_cvs(const std::string &f)
{
std::ifstream infile(f);
if (!infile.is_open())
{
VTR_LOG_ERROR("ERROR: cound not open the file %s.\n", f.c_str());
return false;
}
std::string line;
while (std::getline(infile, line))
{
// cout << line << " - " << endl;
if (!line.size())
continue;
entries.push_back(vector<string>());
entries.back().push_back(string(""));
for (auto c : line)
{
if (isspace(c))
continue;
if (c == ',')
{
entries.back().push_back(string(""));
}
else
entries.back().back().push_back(c);
}
}
std::vector<string> first_v = entries[0];
auto result1 = std::find(first_v.begin(), first_v.end(), "port_name");
vector<string>::iterator result2 = find(first_v.begin(), first_v.end(), "mapped_pin");
int port_name_index = distance(first_v.begin(), result1);
int mapped_pin_index = distance(first_v.begin(), result2);
for (auto &v : entries)
{
string port_name = v[port_name_index];
string mapped_pin = v[mapped_pin_index];
port_map.insert(std::pair<std::string, string>(mapped_pin, port_name));
//for (auto &s : v)
//{
// cout << s << " - ";
//}
}
return true;
}

View File

@ -1,26 +0,0 @@
#ifndef CVS_READER_H
#define CVS_READER_H
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
#include <unordered_map>
#include <ctype.h>
#include <map>
using namespace std;
class CvsReader
{
vector<vector<string>> entries;
map<string, string> port_map;
public:
CvsReader() {}
bool read_cvs(const std::string &f);
const vector<vector<string>>& get_entries()const { return entries;}
const map<string, string>& get_port_map()const { return port_map;}
};
#endif

View File

@ -1,27 +0,0 @@
#include "pcf_reader.h"
#include "vtr_log.h"
bool PcfReader::read_pcf(const std::string &f)
{
std::ifstream infile(f);
if (!infile.is_open())
{
VTR_LOG_ERROR("ERROR: cound not open the file %s.\n", f.c_str());
return false;
}
std::string line;
while (std::getline(infile, line))
{
std::istringstream iss(line);
std::string a, b, c;
if (!(iss >> a >> b >> c))
{
break;
} // error
commands.push_back(std::vector<std::string>());
commands.back().push_back(a);
commands.back().push_back(b);
commands.back().push_back(c);
}
return true;
}

View File

@ -1,34 +0,0 @@
#ifndef PCF_READER_H
#define PCF_READER_H
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
#include <unordered_map>
#include <map>
/*
Supported PCF commands:
* set_io <net> <pad> - constrain a given <net> to a given physical <pad> in eFPGA pinout.
* set_clk <pin> <net> - constrain a given global clock <pin> to a given <net>
Every tile where <net> is present will be constrained to use a given global clock.
*/
class PcfReader
{
std::vector<std::vector<std::string>> commands;
public:
PcfReader() {}
PcfReader(const std::string &f)
{
read_pcf(f);
}
bool read_pcf(const std::string &f);
const std::vector<std::vector<std::string>>& get_commands()const { return commands;}
};
#endif

View File

@ -1,243 +0,0 @@
#include "xml_reader.h"
#include <vector>
#include <fstream>
//======================================================================
std::vector<std::string> XmlReader::vec_to_scalar(std::string str)
{
auto open_bracket_pos = str.find("[");
auto close_bracket_pos = str.find("]");
auto colon_pos = str.find(":");
std::vector<std::string> scalar_ports;
//Parse checks
if (open_bracket_pos == std::string::npos && close_bracket_pos != std::string::npos) {
//Close brace only
std::string msg = "near '" + str + "', missing '['";
std::cerr << " ERROR: " << msg << std::endl;
}
if (open_bracket_pos != std::string::npos && close_bracket_pos == std::string::npos) {
//Open brace only
std::string msg = "near '" + str + "', missing ']'";
std::cerr << " ERROR: " << msg << std::endl;
}
if (open_bracket_pos != std::string::npos && close_bracket_pos != std::string::npos) {
//Have open and close braces, close must be after open
if (open_bracket_pos > close_bracket_pos) {
std::string msg = "near '" + str + "', '[' after ']'";
std::cerr << " ERROR: " << msg << std::endl;
}
}
if (colon_pos != std::string::npos) {
//Have a colon, it must be between open/close braces
if (colon_pos > close_bracket_pos || colon_pos < open_bracket_pos) {
std::string msg = "near '" + str + "', found ':' but not between '[' and ']'";
std::cerr << " ERROR: " << msg << std::endl;
}
}
std::string name = str.substr(0, open_bracket_pos);
std::string first_idx_str;
std::string second_idx_str;
if (colon_pos == std::string::npos && open_bracket_pos == std::string::npos && close_bracket_pos == std::string::npos) {
} else if (colon_pos == std::string::npos) {
first_idx_str = str.substr(open_bracket_pos + 1, close_bracket_pos);
second_idx_str = first_idx_str;
} else {
first_idx_str = str.substr(open_bracket_pos + 1, colon_pos);
second_idx_str = str.substr(colon_pos + 1, close_bracket_pos);
}
int first_idx = std::stoi(first_idx_str);
int second_idx = std::stoi(second_idx_str);
if (first_idx < second_idx)
{
for(int i=first_idx; i < second_idx+1; i++)
{
std::string curr_port_name = name + '[' + std::to_string(i) + ']';
scalar_ports.push_back(curr_port_name);
}
}
else
{
for(int i=first_idx; i >= second_idx ; i--)
{
std::string curr_port_name = name + '[' + std::to_string(i) + ']';
scalar_ports.push_back(curr_port_name);
}
}
return scalar_ports;
}
//======================================================================
bool XmlReader::parse_io_cell (const pugi::xml_node xml_orient_io, const int row_or_col, const int io_per_cell, std::map<std::string, PinMappingData> *port_map)
{
pugi::xpath_node_set cells = xml_orient_io.select_nodes("CELL");
for (pugi::xpath_node_set::const_iterator it = cells.begin(); it != cells.end(); ++it)
{
pugi::xpath_node node = *it;
int startx, starty, endx, endy, i, j, x, y;
std::string port_name = node.node().attribute("port_name").as_string();
std::string mapped_name = node.node().attribute("mapped_name").as_string();
std::vector<std::string> scalar_mapped_pins = vec_to_scalar(mapped_name);
i = 0;
if (node.node().attribute("startx") && node.node().attribute("endx"))
{
startx = node.node().attribute("startx").as_int();
endx = node.node().attribute("endx").as_int();
y = row_or_col;
if (startx < endx)
{
for (x=startx; x < endx+1; x++)
{
for (j=0; j < io_per_cell; j++)
{
std::string mapped_pin = scalar_mapped_pins[i];
PinMappingData pinMapData = PinMappingData(port_name, mapped_pin, x, y, j);
port_map->insert(std::pair<std::string, PinMappingData>(mapped_pin, pinMapData));
i++;
}
}
}
else
{
for (x=startx; x >= endx; x--)
{
for (j=0; j < io_per_cell; j++)
{
std::string mapped_pin = scalar_mapped_pins[i];
PinMappingData pinMapData = PinMappingData(port_name, mapped_pin, x, y, j);
port_map->insert(std::pair<std::string, PinMappingData>(mapped_pin, pinMapData));
i++;
}
}
}
}
if (node.node().attribute("starty") && node.node().attribute("endy").value())
{
starty = node.node().attribute("starty").as_int();
endy = node.node().attribute("endy").as_int();
x = row_or_col;
if (starty < endy)
{
for (y=starty; y < endy+1; y++)
{
for (j=0; j < io_per_cell; j++)
{
std::string mapped_pin = scalar_mapped_pins[i];
PinMappingData pinMapData = PinMappingData(port_name, mapped_pin, x, y, j);
port_map->insert(std::pair<std::string, PinMappingData>(mapped_pin, pinMapData));
i++;
}
}
}
else
{
for (y=starty; y >= endy; y--)
{
for (j=0; j < io_per_cell; j++)
{
std::string mapped_pin = scalar_mapped_pins[i];
PinMappingData pinMapData = PinMappingData(port_name, mapped_pin, x, y, j);
port_map->insert(std::pair<std::string, PinMappingData>(mapped_pin, pinMapData));
i++;
}
}
}
}
}
return true;
}
//======================================================================
bool XmlReader::parse_io (const pugi::xml_node xml_io, const int width, const int height, const int io_per_cell, std::map<std::string, PinMappingData> *port_map)
{
pugi::xml_node xml_top_io = xml_io.child("TOP_IO");
if (!xml_top_io)
{
return false;
}
int io_row_top = height - 1;
if (xml_top_io.attribute("y"))
io_row_top = xml_top_io.attribute("y").as_int();
pugi::xml_node xml_bottom_io = xml_io.child("BOTTOM_IO");
if (!xml_bottom_io)
{
return false;
}
int io_row_bottom = 0;
if (xml_bottom_io.attribute("y"))
io_row_bottom = xml_bottom_io.attribute("y").as_int();
pugi::xml_node xml_left_io = xml_io.child("LEFT_IO");
if (!xml_left_io)
{
return false;
}
int io_col_left = 0;
if (xml_left_io.attribute("x"))
io_col_left = xml_left_io.attribute("x").as_int();
pugi::xml_node xml_right_io = xml_io.child("RIGHT_IO");
if (!xml_right_io)
{
return false;
}
int io_col_right = width - 1;
if (xml_right_io.attribute("x"))
io_col_right = xml_right_io.attribute("x").as_int();
if (!parse_io_cell (xml_top_io, io_row_top, io_per_cell, port_map))
return false;
if (!parse_io_cell (xml_bottom_io, io_row_bottom, io_per_cell, port_map))
return false;
if (!parse_io_cell (xml_right_io, io_col_right, io_per_cell, port_map))
return false;
if (!parse_io_cell (xml_left_io, io_col_left, io_per_cell, port_map))
return false;
return true;
}
//======================================================================
bool XmlReader::read_xml(const std::string &f)
{
pugi::xml_document doc;
std::ifstream infile(f);
if (!infile.is_open())
{
std::cerr << "ERROR: cound not open the file " << f << std::endl;
return false;
}
pugi::xml_parse_result result = doc.load_file(f.c_str());
if (!result)
return false;
pugi::xml_node device = doc.child("DEVICE");
if (!device)
return false;
int width = device.attribute("width").as_int();
int height = device.attribute("height").as_int();
int z = device.attribute("z").as_int();
if (z <= 0)
return false;
pugi::xml_node xml_io = device.child("IO");
if (!xml_io)
return false;
if (!parse_io (xml_io, width, height, z, &port_map_))
return false;
return true;
}

View File

@ -1,41 +0,0 @@
#ifndef XML_READER_H
#define XML_READER_H
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include "pugixml.hpp"
class PinMappingData
{
public:
PinMappingData(std::string p_name, std::string map_pin, int x, int y, int z):port_name_(p_name), mapped_pin_(map_pin), x_(x), y_(y), z_(z){}
std::string get_port_name () { return port_name_; }
std::string get_mapped_pin () { return mapped_pin_; }
int get_x () { return x_; }
int get_y () { return y_; }
int get_z () { return z_; }
private:
std::string port_name_;
std::string mapped_pin_;
int x_;
int y_;
int z_;
};
class XmlReader
{
std::map<std::string, PinMappingData> port_map_;
public:
XmlReader() {}
bool read_xml(const std::string &f);
const std::map<std::string, PinMappingData>& get_port_map()const { return port_map_;}
std::vector<std::string> vec_to_scalar(std::string str);
bool parse_io_cell (const pugi::xml_node xml_orient_io, const int row_or_col, const int io_per_cell, std::map<std::string, PinMappingData> *port_map);
bool parse_io (const pugi::xml_node xml_io, const int width, const int height, const int io_per_cell, std::map<std::string, PinMappingData> *port_map);
};
#endif

View File

@ -1,23 +0,0 @@
#include <iostream>
#include <string>
#include "csv_reader.h"
#include "pcf_reader.h"
#include "xml_reader.h"
#include "cmd_line.h"
// #include "pin_location.h"
#include "pin_constrain_loc.h"
// Convert a PCF file into a VPR io.place file.
// This requires : XML file where we can get (x, y, z) of internal port
// CSV file where we have the maching list (external, internal) ports
// PCF file: constraint file. a design pin can be assigned to an external port
// BLIF file: user design. We need to check the input and output. Special handling for outputs
// The output is a file constraint in VPR format.
// Usage options: --xml PINMAP_XML --pcf PCF --blif BLIF --output OUTPUT --xml PINMAP_XML --csv CSV_FILE
int main(int argc, const char* argv[])
{
cmd_line cmd(argc, argv);
return pin_constrain_location_cmd_line(cmd);
}

View File

@ -1,30 +0,0 @@
#include "pin_location.h"
#include "cmd_line.h"
#include "pin_constrain_loc.h"
#include <vector>
#include <string>
// wraper function to do the real job, it is used by openfpga shell as well
// this gurantees same behavior
int pin_constrain_location (vector<string> args) {
if (args.size() != PIN_C_ARGUMENT_NUMBER ) {
return 1;
}
const char* pin_c_args [PIN_C_ARGUMENT_NUMBER];
for (int i = 0; i < PIN_C_ARGUMENT_NUMBER; i++) {
pin_c_args[i] = const_cast<char*> (args[i].c_str());
}
cmd_line pin_c_cmd (PIN_C_ARGUMENT_NUMBER, pin_c_args);
return pin_constrain_location_cmd_line(pin_c_cmd);
}
// base function for both openfpga wrapper and pin_c executable
int pin_constrain_location_cmd_line (cmd_line& cmd) {
pin_location pl (cmd);
//pl.get_cmd().print_options();
if (!pl.reader_and_writer()) {
return 1;
}
return 0;
}

View File

@ -1,12 +0,0 @@
#include "pin_location.h"
#include "cmd_line.h"
#include <vector>
#include <string>
// wraper function to do the real job, it is used by openfpga shell as well
// this gurantees same behavior
int pin_constrain_location (std::vector<std::string> args);
// base function for both openfpga wrapper and pin_c executable
int pin_constrain_location_cmd_line (cmd_line& cmd);

View File

@ -1,141 +0,0 @@
#include "csv_reader.h"
#include "pcf_reader.h"
#include "xml_reader.h"
#include "blif_reader.h"
#include "cmd_line.h"
#include "pin_location.h"
#include <algorithm>
#include <set>
#include "vtr_log.h"
const string USAGE_MSG = "usage options: --xml PINMAP_XML --pcf PCF --blif BLIF --csv CSV_FILE --output OUTPUT";
const cmd_line & pin_location::get_cmd() const
{
return cl_;
}
bool pin_location::reader_and_writer()
{
cmd_line cmd = cl_;
string xml_name = cmd.get_param("--xml");
string csv_name = cmd.get_param("--csv");
string pcf_name = cmd.get_param("--pcf");
string blif_name = cmd.get_param("--blif");
string output_name = cmd.get_param("--output");
if ((xml_name == "") || (csv_name == "") || (pcf_name == "") || (blif_name == "")|| (output_name == "") )
{
VTR_LOG_ERROR("%s\n %s\n", error_messages[MISSING_IN_OUT_FILES].c_str(), USAGE_MSG.c_str());
return false;
}
XmlReader rd_xml;
if (!rd_xml.read_xml(xml_name))
{
VTR_LOG_ERROR("%s.\n", error_messages[PIN_LOC_XML_PARSE_ERROR].c_str());
return false;
}
std::map<std::string, PinMappingData> xml_port_map = rd_xml.get_port_map();
CvsReader rd_csv;
if (!rd_csv.read_cvs(csv_name))
{
VTR_LOG_ERROR("%s.\n", error_messages[PIN_MAP_CSV_PARSE_ERROR].c_str());
return false;
}
map<string, string> csv_port_map = rd_csv.get_port_map();
PcfReader rd_pcf;
if (!rd_pcf.read_pcf(pcf_name))
{
VTR_LOG_ERROR("%s.\n", error_messages[PIN_CONSTRAINT_PARSE_ERROR].c_str());
return false;
}
// read port info from blif file
BlifReader rd_blif;
if (!rd_blif.read_blif(blif_name)) {
VTR_LOG_ERROR("%s.\n", error_messages[INPUT_DESIGN_PARSE_ERROR].c_str());
return false;
}
std::vector<std::string> inputs = rd_blif.get_inputs();
std::vector<std::string> outputs = rd_blif.get_outputs();
std::ofstream out_file;
out_file.open(output_name);
out_file << "#Block Name x y z\n";
out_file << "#------------ -- -- -\n";
vector<vector<string>> pcf_pin_cstr = rd_pcf.get_commands();
std::set<std::string> constrained_ports, constrained_pins;
for (auto pin_cstr_v : pcf_pin_cstr)
{
if ((pin_cstr_v[0] != "set_io") && (pin_cstr_v[0] != "set_clk"))
continue;
string pin_name = pin_cstr_v[1];
string cstr_name = pin_cstr_v[2];
auto found_in = std::find(inputs.begin(), inputs.end(), pin_name);
bool valid = false, is_out = false;
if (found_in != inputs.end())
valid = true;
else
{
auto found_out = std::find(outputs.begin(), outputs.end(), pin_name);
if (found_out != outputs.end())
{
valid = true;
is_out = true;
}
else
{
VTR_LOG_ERROR("%s: <%s>.\n", error_messages[CONSTRAINED_PORT_NOT_FOUND].c_str(), pin_name.c_str());
out_file.close();
return false;
}
}
if (constrained_ports.find(pin_name) == constrained_ports.end()) {
constrained_ports.insert(pin_name);
} else {
VTR_LOG_ERROR("%s: <%s>.\n", error_messages[RE_CONSTRAINED_PORT].c_str(), pin_name.c_str());
out_file.close();
return false;
}
if (!valid)
continue;
std::string content_to_write;
// Get the the intternal port from the CSV file
auto element_cstr = csv_port_map.find(cstr_name);
if (element_cstr != csv_port_map.end())
{
if (constrained_pins.find(cstr_name) == constrained_pins.end()) {
constrained_pins.insert(cstr_name);
} else {
VTR_LOG_ERROR("%s: <%s>.\n", error_messages[OVERLAP_PIN_IN_CONSTRAINT].c_str(), cstr_name.c_str());
out_file.close();
return false;
}
// Get the (x, y, z) from the XML reader
PinMappingData pinMapData = xml_port_map.at(element_cstr->second);
if (is_out)
{
content_to_write += "out:";
}
content_to_write += pin_name + " " + std::to_string(pinMapData.get_x()) + " " + std::to_string(pinMapData.get_y()) + " " + std::to_string(pinMapData.get_z()) + "\n";
} else {
VTR_LOG_ERROR("%s: <%s>.\n", error_messages[CONSTRAINED_PIN_NOT_FOUND].c_str(), cstr_name.c_str());
out_file.close();
return false;
}
out_file << content_to_write;
}
out_file.close();
return true;
}

View File

@ -1,46 +0,0 @@
#ifndef PIN_LOCATION_H
#define PIN_LOCATION_H
#include "cmd_line.h"
// number of arguments for "pin_c", inlcuding the "pin_c" command itself
#define PIN_C_ARGUMENT_NUMBER 11
class pin_location {
private:
// error messages to be printed out with std::cerr
enum {
MISSING_IN_OUT_FILES = 0,
PIN_LOC_XML_PARSE_ERROR,
PIN_MAP_CSV_PARSE_ERROR,
PIN_CONSTRAINT_PARSE_ERROR,
INPUT_DESIGN_PARSE_ERROR,
CONSTRAINED_PORT_NOT_FOUND,
CONSTRAINED_PIN_NOT_FOUND,
RE_CONSTRAINED_PORT,
OVERLAP_PIN_IN_CONSTRAINT,
MAX_MESSAGE_ID
};
std::string error_messages[MAX_MESSAGE_ID] = {
"Missing input or output file arguments", // MISSING_IN_OUT_FILES
"Pin location file parse error", // PIN_LOC_XML_PARSE_ERROR
"Pin map file parse error", // PIN_MAP_CSV_PARSE_ERROR
"Pin constraint file parse error", // PIN_CONSTRAINT_PARSE_ERROR
"Input design parse error", // INPUT_DESIGN_PARSE_ERROR
"Constrained port not found in design", // CONSTRAINED_PORT_NOT_FOUND
"Constrained pin not found in device", // CONSTRAINED_PIN_NOT_FOUND
"Re-constrained port", // RE_CONSTRAINED_PORT
"Overlap pin found in constraint" // OVERLAP_PIN_IN_CONSTRAINT
};
cmd_line cl_;
public:
pin_location(cmd_line& cl): cl_(cl){
}
const cmd_line& get_cmd()const;
bool reader_and_writer();
};
#endif

View File

@ -1,77 +0,0 @@
#include "cmd_line.h"
cmd_line::cmd_line(int argc, const char *argv[])
{
bool needVal = false;
string key;
for (int i = 1; i < argc; ++i)
{
string s(argv[i]);
if (s.size() < 2)
{
cout << "Warning: Not a valid flag \"" << s << "\" discarding" << endl;
continue;
}
if ('-' == s[0])
{
if ('-' == s[1])
{ // param key
if (needVal)
cout << "Warning: Key " << key << " did not get a value" << endl;
needVal = true;
key = s;
}
else
{ // flag
flags.insert(s);
if (needVal)
cout << "Warning: Key " << key << " did not get a value" << endl;
needVal = false;
}
}
else
{ // param value
if (needVal)
{
params[key] = s;
needVal = false;
}
else
{
cout << "Warning: No key for value " << s << endl;
}
}
}
}
bool cmd_line::is_flag_set(string &fl)
{
return (flags.find(fl) != end(flags));
}
string cmd_line::get_param(const string &key)
{
if (params.find(key) != end(params))
return params[key];
return "";
}
void cmd_line::set_flag(string &fl)
{
flags.insert(fl);
}
void cmd_line::set_param_value(string &key, string &val)
{
params[key] = val;
}
void cmd_line::print_options() const
{
cout << "Flags :\n";
for (auto &f : flags)
cout << "\t" << f << endl;
cout << "Params :\n";
for (auto &p : params)
cout << "\t" << p.first << "\t" << p.second << endl;
}

View File

@ -1,23 +0,0 @@
#ifndef CMD_LINE
#define CMD_LINE
#include <iostream>
#include <unordered_map>
#include <unordered_set>
using namespace std;
class cmd_line
{
unordered_map<string, string> params;
unordered_set<string> flags;
public:
cmd_line(int argc, const char *argv[]);
const unordered_set<string> &get_flag_set() const { return flags; }
const unordered_map<string, string> get_param_map() const { return params; }
bool is_flag_set(string &fl);
string get_param(const string &key);
void set_flag(string &fl);
void set_param_value(string &key, string &val);
void print_options() const;
};
#endif

View File

@ -1,30 +0,0 @@
/********************************************************************
* Unit test functions to validate the correctness of
* 1. parser of data structures
* 2. writer of data structures
*******************************************************************/
/* Headers from vtrutils */
#include "vtr_assert.h"
#include "vtr_log.h"
#include "cmd_line.h"
#include "pin_location.h"
#include "pin_constrain_loc.h"
int main(int argc, const char** argv) {
VTR_ASSERT(argc == PIN_C_ARGUMENT_NUMBER);
string command_line;
for (int i = 0; i < argc; i++) {
if (i > 0) {
command_line += " ";
}
command_line += argv[i];
}
VTR_LOG("Created command line <%s> for test.\n", command_line.c_str());
cmd_line pin_c_cmd (argc, argv);
VTR_LOG("Testing reader and writer.\n");
int status = pin_constrain_location_cmd_line(pin_c_cmd);
VTR_LOG("Test result: %s.\n", status == 0 ? "PASS" : "FAIL");
return status;
}

View File

@ -1,3 +0,0 @@
set_io a pad_fpga_io[0]
set_io b pad_fpga_io[4]
set_io c pad_fpga_io[6]