Skip to content

Commit

Permalink
add cli commands for reading and writing
Browse files Browse the repository at this point in the history
  • Loading branch information
simon1hofmann committed Oct 6, 2023
1 parent 7f294c3 commit 5fcdd7b
Show file tree
Hide file tree
Showing 3 changed files with 225 additions and 2 deletions.
114 changes: 114 additions & 0 deletions cli/cmd/io/fgl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
//
// Created by simon on 06.10.2023
//

#ifndef FICTION_CMD_FGL_HPP
#define FICTION_CMD_FGL_HPP

#include <fiction/io/write_fgl_layout.hpp>
#include <fiction/traits.hpp>
#include <fiction/types.hpp>
#include <fiction/utils/name_utils.hpp>

#include <alice/alice.hpp>

#include <filesystem>
#include <ostream>
#include <string>
#include <variant>

namespace alice
{
/**
* Generates a FGL file for the current gate-level layout in store and writes it to the given path.
*/
class fgl_command : public command
{
public:
/**
* Standard constructor. Adds descriptive information, options, and flags.
*
* @param e alice::environment that specifies stores etc.
*/
explicit fgl_command(const environment::ptr& e) :
command(e, "Generates a FGL file for the current gate-level layout in store.")
{
add_option("filename", filename, "FGL file name");
}

protected:
/**
* Function to perform the output call. Generates a FGL file.
*/
void execute() override
{
auto& s = store<fiction::gate_layout_t>();

// error case: empty gate-level layout store
if (s.empty())
{
env->out() << "[w] no gate-level layout in store" << std::endl;
return;
}

const auto get_name = [](auto&& lyt_ptr) -> std::string { return fiction::get_name(*lyt_ptr); };

const auto write_fgl = [this, &get_name](auto&& lyt_ptr)
{
using Lyt = typename std::decay_t<decltype(lyt_ptr)>::element_type;

if constexpr (fiction::is_gate_level_layout_v<Lyt>)
{
fiction::write_fgl_layout(*lyt_ptr, filename);
}
else
{
env->out() << fmt::format("[e] {} is not a gate-level layout", get_name(lyt_ptr)) << std::endl;
}
};

const auto& lyt = s.current();

// error case: do not override directories
if (std::filesystem::is_directory(filename))
{
env->out() << "[e] cannot override a directory" << std::endl;
return;
}
// if filename was not given, use stored layout name
if (filename.empty())
{
filename = std::visit(get_name, lyt);
}
// add .fgl file extension if necessary
if (std::filesystem::path(filename).extension() != ".fgl")
{
filename += ".fgl";
}

try
{
std::visit(write_fgl, lyt);
}
catch (const std::ofstream::failure& e)
{
env->out() << fmt::format("[e] {}", e.what()) << std::endl;
}
catch (...)
{
env->out() << "[e] an error occurred while the file was being written; it could be corrupted" << std::endl;
}
}

private:
/**
* File name to write the FGL file into.
*/
std::string filename;
};

ALICE_ADD_COMMAND(fgl, "I/O")

} // namespace alice

#endif // FICTION_CMD_FGL_HPP
112 changes: 110 additions & 2 deletions cli/cmd/io/read.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define FICTION_CMD_READ_HPP

#include <fiction/io/network_reader.hpp>
#include <fiction/io/read_fgl_layout.hpp>
#include <fiction/io/read_fqca_layout.hpp>
#include <fiction/types.hpp>

Expand All @@ -22,7 +23,7 @@ namespace alice
*
* Currently parses Verilog, AIGER, and BLIF using the lorina parsers.
*
* Parses FQCA via a custom reader function.
* Parses FGL and FQCA via custom reader functions.
*
* For more information see: https://github.com/hriener/lorina
*/
Expand All @@ -38,14 +39,17 @@ class read_command : public command
command(e, "Reads a file or a directory of files and creates logic network or FCN layout objects "
"which will be put into the respective store. Current supported file types are:\n"
"Logic networks: Verilog, AIGER, BLIF.\n"
"Gate-level layouts: FGL.\n"
"Cell-level layouts: FQCA.\n"
"In a directory, only files with extension '.v', '.aig', '.blif' are considered.")
{
add_option("filename", filename, "Filename or directory")->required();
add_option("topology", topology, "Topology for gate-level layouts");
add_flag("--aig,-a", "Parse file as AIG");
add_flag("--xag,-x", "Parse file as XAG");
add_flag("--mig,-m", "Parse file as MIG");
add_flag("--tec,-t", "Parse file as technology network");
add_flag("--fgl,-f", "Parse file as fiction gate-level layout");
add_flag("--qca,-q", "Parse file as QCA cell-level layout");
add_flag("--sort,-s", sort, "Sort networks in given directory by vertex count prior to storing them");
}
Expand All @@ -64,14 +68,22 @@ class read_command : public command
}
};

if (!is_set("aig") && !is_set("xag") && !is_set("mig") && !is_set("tec") && !is_set("qca"))
if (!is_set("aig") && !is_set("xag") && !is_set("mig") && !is_set("tec") && !is_set("fgl") && !is_set("qca"))
{
env->out() << "[e] at least one network or layout type must be specified" << std::endl;
}
else if ((is_set("aig") || is_set("xag") || is_set("mig") || is_set("tec")) && is_set("fql"))
{
env->out() << "[e] cannot parse files as both logic networks and gate-level layouts" << std::endl;
}
else if ((is_set("aig") || is_set("xag") || is_set("mig") || is_set("tec")) && is_set("qca"))
{
env->out() << "[e] cannot parse files as both logic networks and cell-level layouts" << std::endl;
}
else if (is_set("fql") && is_set("qca"))
{
env->out() << "[e] cannot parse files as both gate-level and cell-level layouts" << std::endl;
}
else
{
try
Expand Down Expand Up @@ -100,6 +112,98 @@ class read_command : public command

store_ntks(reader);
}
if (is_set("fgl"))
{
if (!topology.empty())
{
if (std::filesystem::exists(filename))
{
if (std::filesystem::is_regular_file(filename))
{
try
{
if (topology == "cartesian")
{
store<fiction::gate_layout_t>().extend() =
std::make_shared<fiction::cart_gate_clk_lyt>(
fiction::read_fgl_layout<fiction::cart_gate_clk_lyt>(filename));
}
else if (topology == "odd_row_cartesian")
{
store<fiction::gate_layout_t>().extend() =
std::make_shared<fiction::cart_odd_row_gate_clk_lyt>(
fiction::read_fgl_layout<fiction::cart_odd_row_gate_clk_lyt>(filename));
}
else if (topology == "even_row_cartesian")
{
store<fiction::gate_layout_t>().extend() =
std::make_shared<fiction::cart_even_row_gate_clk_lyt>(
fiction::read_fgl_layout<fiction::cart_even_row_gate_clk_lyt>(
filename));
}
else if (topology == "odd_column_cartesian")
{
store<fiction::gate_layout_t>().extend() =
std::make_shared<fiction::cart_odd_col_gate_clk_lyt>(
fiction::read_fgl_layout<fiction::cart_odd_col_gate_clk_lyt>(filename));
}
else if (topology == "even_column_cartesian")
{
store<fiction::gate_layout_t>().extend() =
std::make_shared<fiction::cart_even_col_gate_clk_lyt>(
fiction::read_fgl_layout<fiction::cart_even_col_gate_clk_lyt>(
filename));
}
else if (topology == "odd_row_hex")
{
store<fiction::gate_layout_t>().extend() =
std::make_shared<fiction::hex_odd_row_gate_clk_lyt>(
fiction::read_fgl_layout<fiction::hex_odd_row_gate_clk_lyt>(filename));
}
else if (topology == "even_row_hex")
{
store<fiction::gate_layout_t>().extend() =
std::make_shared<fiction::hex_even_row_gate_clk_lyt>(
fiction::read_fgl_layout<fiction::hex_even_row_gate_clk_lyt>(filename));
}
else if (topology == "odd_column_hex")
{
store<fiction::gate_layout_t>().extend() =
std::make_shared<fiction::hex_odd_col_gate_clk_lyt>(
fiction::read_fgl_layout<fiction::hex_odd_col_gate_clk_lyt>(filename));
}
else if (topology == "even_column_hex")
{
store<fiction::gate_layout_t>().extend() =
std::make_shared<fiction::hex_even_col_gate_clk_lyt>(
fiction::read_fgl_layout<fiction::hex_even_col_gate_clk_lyt>(filename));
}
else
{
env->out() << fmt::format("[e] given topology does not exist: {}", topology)
<< std::endl;
}
}
catch (const fiction::fgl_parsing_error& e)
{
env->out() << e.what() << std::endl;
}
}
else
{
env->out() << "[e] given file name does not point to a regular file" << std::endl;
}
}
else
{
env->out() << "[e] given file name does not exist" << std::endl;
}
}
else
{
env->out() << "[e] for reading gate-level layouts, the topology has to be set" << std::endl;
}
}
if (is_set("qca"))
{
if (std::filesystem::exists(filename))
Expand Down Expand Up @@ -160,6 +264,10 @@ class read_command : public command
* Verilog filename.
*/
std::string filename;
/**
* Gate-level layout topology.
*/
std::string topology;
/**
* Flag to indicate that files should be sorted by file size.
*/
Expand Down
1 change: 1 addition & 0 deletions cli/commands.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "cmd/general/clear.hpp"
#include "cmd/general/version.hpp"
#include "cmd/io/blif.hpp"
#include "cmd/io/fgl.hpp"
#include "cmd/io/fqca.hpp"
#include "cmd/io/qca.hpp"
#include "cmd/io/qcc.hpp"
Expand Down

0 comments on commit 5fcdd7b

Please sign in to comment.