/*
 * BLIF Netlist Loader
 * ===================
 *
 * This loader handles loading a post-technology mapping fully flattened (i.e not
 * hierarchical) netlist in Berkely Logic Interchange Format (BLIF) file, and
 * builds a netlist data structure (AtomNetlist) from it.
 *
 * BLIF text parsing is handled by the blifparse library, while this file is responsible
 * for creating the netlist data structure.
 *
 * The main object of interest is the BlifAllocCallback struct, which implements the
 * blifparse callback interface.  The callback methods are then called when basic blif
 * primitives are encountered by the parser.  The callback methods then create the associated
 * netlist data structures.
 *
 */
#include <cstdio>
#include <cstring>
#include <ctime>
#include <sstream>
#include <unordered_set>
#include <cctype> //std::isdigit

#include "blifparse.hpp"
#include "atom_netlist.h"

#include "vtr_assert.h"
#include "vtr_util.h"
#include "vtr_log.h"
#include "vtr_logic.h"
#include "vtr_time.h"
#include "vtr_digest.h"

#include "vpr_types.h"
#include "vpr_error.h"
#include "globals.h"
#include "read_blif.h"
#include "arch_types.h"
#include "echo_files.h"
#include "hash.h"

vtr::LogicValue to_vtr_logic_value(blifparse::LogicValue);

struct BlifAllocCallback : public blifparse::Callback {
  public:
    BlifAllocCallback(e_circuit_format blif_format, AtomNetlist& main_netlist, const std::string netlist_id, const t_model* user_models, const t_model* library_models)
        : main_netlist_(main_netlist)
        , netlist_id_(netlist_id)
        , user_arch_models_(user_models)
        , library_arch_models_(library_models)
        , blif_format_(blif_format) {
        VTR_ASSERT(blif_format_ == e_circuit_format::BLIF
                   || blif_format_ == e_circuit_format::EBLIF);
    }

    static constexpr const char* OUTPAD_NAME_PREFIX = "out:";

  public: //Callback interface
    void start_parse() override {}

    void finish_parse() override {
        //When parsing is finished we *move* the main netlist
        //into the user object. This ensures we never have two copies
        //(consuming twice the memory).
        size_t main_netlist_idx = determine_main_netlist_index();
        main_netlist_ = std::move(blif_models_[main_netlist_idx]);
    }

    void begin_model(std::string model_name) override {
        //Create a new model, and set it's name

        blif_models_.emplace_back(model_name, netlist_id_);
        blif_models_black_box_.emplace_back(false);
        ended_ = false;
        set_curr_block(AtomBlockId::INVALID()); //This statement doesn't define a block, so mark invalid
    }

    void inputs(std::vector<std::string> input_names) override {
        const t_model* blk_model = find_model(MODEL_INPUT);

        VTR_ASSERT_MSG(!blk_model->inputs, "Inpad model has an input port");
        VTR_ASSERT_MSG(blk_model->outputs, "Inpad model has no output port");
        VTR_ASSERT_MSG(blk_model->outputs->size == 1, "Inpad model has non-single-bit output port");
        VTR_ASSERT_MSG(!blk_model->outputs->next, "Inpad model has multiple output ports");

        std::string pin_name = blk_model->outputs->name;
        for (const auto& input : input_names) {
            AtomBlockId blk_id = curr_model().create_block(input, blk_model);
            AtomPortId port_id = curr_model().create_port(blk_id, blk_model->outputs);
            AtomNetId net_id = curr_model().create_net(input);
            curr_model().create_pin(port_id, 0, net_id, PinType::DRIVER);
        }
        set_curr_block(AtomBlockId::INVALID()); //This statement doesn't define a block, so mark invalid
    }

    void outputs(std::vector<std::string> output_names) override {
        const t_model* blk_model = find_model(MODEL_OUTPUT);

        VTR_ASSERT_MSG(!blk_model->outputs, "Outpad model has an output port");
        VTR_ASSERT_MSG(blk_model->inputs, "Outpad model has no input port");
        VTR_ASSERT_MSG(blk_model->inputs->size == 1, "Outpad model has non-single-bit input port");
        VTR_ASSERT_MSG(!blk_model->inputs->next, "Outpad model has multiple input ports");

        std::string pin_name = blk_model->inputs->name;
        for (const auto& output : output_names) {
            //Since we name blocks based on their drivers we need to uniquify outpad names,
            //which we do with a prefix
            AtomBlockId blk_id = curr_model().create_block(OUTPAD_NAME_PREFIX + output, blk_model);
            AtomPortId port_id = curr_model().create_port(blk_id, blk_model->inputs);
            AtomNetId net_id = curr_model().create_net(output);
            curr_model().create_pin(port_id, 0, net_id, PinType::SINK);
        }
        set_curr_block(AtomBlockId::INVALID()); //This statement doesn't define a block, so mark invalid
    }

    void names(std::vector<std::string> nets, std::vector<std::vector<blifparse::LogicValue>> so_cover) override {
        const t_model* blk_model = find_model(MODEL_NAMES);

        VTR_ASSERT_MSG(nets.size() > 0, "BLIF .names has no connections");

        VTR_ASSERT_MSG(blk_model->inputs, ".names model has no input port");
        VTR_ASSERT_MSG(!blk_model->inputs->next, ".names model has multiple input ports");
        if (static_cast<int>(nets.size()) - 1 > blk_model->inputs->size) {
            vpr_throw(VPR_ERROR_BLIF_F, filename_.c_str(), lineno_, "BLIF .names input size (%zu) greater than .names model input size (%d)",
                      nets.size() - 1, blk_model->inputs->size);
        }

        VTR_ASSERT_MSG(blk_model->outputs, ".names has no output port");
        VTR_ASSERT_MSG(!blk_model->outputs->next, ".names model has multiple output ports");
        VTR_ASSERT_MSG(blk_model->outputs->size == 1, ".names model has non-single-bit output");

        //Convert the single-output cover to a netlist truth table
        AtomNetlist::TruthTable truth_table;
        for (const auto& row : so_cover) {
            truth_table.emplace_back();
            for (auto val : row) {
                truth_table[truth_table.size() - 1].push_back(to_vtr_logic_value(val));
            }
        }

        AtomBlockId blk_id = curr_model().create_block(nets[nets.size() - 1], blk_model, truth_table);
        set_curr_block(blk_id);

        //Create inputs
        AtomPortId input_port_id = curr_model().create_port(blk_id, blk_model->inputs);
        for (size_t i = 0; i < nets.size() - 1; ++i) {
            AtomNetId net_id = curr_model().create_net(nets[i]);

            curr_model().create_pin(input_port_id, i, net_id, PinType::SINK);
        }

        //Figure out if the output is a constant generator
        bool output_is_const = false;
        if (truth_table.empty()
            || (truth_table.size() == 1 && truth_table[0].size() == 1 && truth_table[0][0] == vtr::LogicValue::FALSE)) {
            //An empty truth table in BLIF corresponds to a constant-zero
            //  e.g.
            //
            //  #gnd is a constant 0 generator
            //  .names gnd
            //
            //An single entry truth table with value '0' also corresponds to a constant-zero
            //  e.g.
            //
            //  #gnd2 is a constant 0 generator
            //  .names gnd2
            //  0
            //
            output_is_const = true;
            VTR_LOG("Found constant-zero generator '%s'\n", nets[nets.size() - 1].c_str());
        } else if (truth_table.size() == 1 && truth_table[0].size() == 1 && truth_table[0][0] == vtr::LogicValue::TRUE) {
            //A single-entry truth table with value '1' in BLIF corresponds to a constant-one
            //  e.g.
            //
            //  #vcc is a constant 1 generator
            //  .names vcc
            //  1
            //
            output_is_const = true;
            VTR_LOG("Found constant-one generator '%s'\n", nets[nets.size() - 1].c_str());
        }

        //Create output
        AtomNetId net_id = curr_model().create_net(nets[nets.size() - 1]);
        AtomPortId output_port_id = curr_model().create_port(blk_id, blk_model->outputs);
        curr_model().create_pin(output_port_id, 0, net_id, PinType::DRIVER, output_is_const);
    }

    void latch(std::string input, std::string output, blifparse::LatchType type, std::string control, blifparse::LogicValue init) override {
        if (type == blifparse::LatchType::UNSPECIFIED) {
            VTR_LOGF_WARN(filename_.c_str(), lineno_, "Treating latch '%s' of unspecified type as rising edge triggered\n", output.c_str());
        } else if (type != blifparse::LatchType::RISING_EDGE) {
            vpr_throw(VPR_ERROR_BLIF_F, filename_.c_str(), lineno_, "Only rising edge latches supported\n");
        }

        if (control.empty()) {
            vpr_throw(VPR_ERROR_BLIF_F, filename_.c_str(), lineno_, "Latch must have a clock\n");
        }

        const t_model* blk_model = find_model(MODEL_LATCH);

        VTR_ASSERT_MSG(blk_model->inputs, "Has one input port");
        VTR_ASSERT_MSG(blk_model->inputs->next, "Has two input port");
        VTR_ASSERT_MSG(!blk_model->inputs->next->next, "Has no more than two input port");
        VTR_ASSERT_MSG(blk_model->outputs, "Has one output port");
        VTR_ASSERT_MSG(!blk_model->outputs->next, "Has no more than one input port");

        const t_model_ports* d_model_port = blk_model->inputs;
        const t_model_ports* clk_model_port = blk_model->inputs->next;
        const t_model_ports* q_model_port = blk_model->outputs;

        VTR_ASSERT(d_model_port->name == std::string("D"));
        VTR_ASSERT(clk_model_port->name == std::string("clk"));
        VTR_ASSERT(q_model_port->name == std::string("Q"));
        VTR_ASSERT(d_model_port->size == 1);
        VTR_ASSERT(clk_model_port->size == 1);
        VTR_ASSERT(q_model_port->size == 1);
        VTR_ASSERT(clk_model_port->is_clock);

        //We set the initital value as a single entry in the 'truth_table' field
        AtomNetlist::TruthTable truth_table(1);
        truth_table[0].push_back(to_vtr_logic_value(init));

        AtomBlockId blk_id = curr_model().create_block(output, blk_model, truth_table);
        set_curr_block(blk_id);

        //The input
        AtomPortId d_port_id = curr_model().create_port(blk_id, d_model_port);
        AtomNetId d_net_id = curr_model().create_net(input);
        curr_model().create_pin(d_port_id, 0, d_net_id, PinType::SINK);

        //The output
        AtomPortId q_port_id = curr_model().create_port(blk_id, q_model_port);
        AtomNetId q_net_id = curr_model().create_net(output);
        curr_model().create_pin(q_port_id, 0, q_net_id, PinType::DRIVER);

        //The clock
        AtomPortId clk_port_id = curr_model().create_port(blk_id, clk_model_port);
        AtomNetId clk_net_id = curr_model().create_net(control);
        curr_model().create_pin(clk_port_id, 0, clk_net_id, PinType::SINK);
    }

    void subckt(std::string subckt_model, std::vector<std::string> ports, std::vector<std::string> nets) override {
        VTR_ASSERT(ports.size() == nets.size());

        const t_model* blk_model = find_model(subckt_model);

        //We name the subckt based on the net it's first output pin drives
        std::string subckt_name;
        for (size_t i = 0; i < ports.size(); ++i) {
            const t_model_ports* model_port = find_model_port(blk_model, ports[i]);
            VTR_ASSERT(model_port);

            if (model_port->dir == OUT_PORT) {
                subckt_name = nets[i];
                break;
            }
        }

        if (subckt_name.empty()) {
            //We need to name the block uniquely ourselves since there is no connected output
            subckt_name = unique_subckt_name();

            //Since this is unusual, warn the user
            VTR_LOGF_WARN(filename_.c_str(), lineno_,
                          "Subckt of type '%s' at %s:%d has no output pins, and has been named '%s'\n",
                          blk_model->name, filename_.c_str(), lineno_, subckt_name.c_str());
        }

        //The name for every block should be unique, check that there is no name conflict
        AtomBlockId blk_id = curr_model().find_block(subckt_name);
        if (blk_id) {
            const t_model* conflicting_model = curr_model().block_model(blk_id);
            vpr_throw(VPR_ERROR_BLIF_F, filename_.c_str(), lineno_,
                      "Duplicate blocks named '%s' found in netlist."
                      " Existing block of type '%s' conflicts with subckt of type '%s'.",
                      subckt_name.c_str(), conflicting_model->name, subckt_model.c_str());
        }

        //Create the block
        blk_id = curr_model().create_block(subckt_name, blk_model);
        set_curr_block(blk_id);

        for (size_t i = 0; i < ports.size(); ++i) {
            //Check for consistency between model and ports
            const t_model_ports* model_port = find_model_port(blk_model, ports[i]);
            VTR_ASSERT(model_port);

            //Determine the pin type
            PinType pin_type = PinType::SINK;
            if (model_port->dir == OUT_PORT) {
                pin_type = PinType::DRIVER;
            } else {
                VTR_ASSERT_MSG(model_port->dir == IN_PORT, "Unexpected port type");
            }

            //Make the port
            std::string port_base;
            size_t port_bit;
            std::tie(port_base, port_bit) = split_index(ports[i]);

            AtomPortId port_id = curr_model().create_port(blk_id, find_model_port(blk_model, port_base));

            //Make the net
            AtomNetId net_id = curr_model().create_net(nets[i]);

            //Make the pin
            curr_model().create_pin(port_id, port_bit, net_id, pin_type);
        }
    }

    void blackbox() override {
        //We treat black-boxes as netlists during parsing so they should contain
        //only inpads/outpads
        for (const auto& blk_id : curr_model().blocks()) {
            auto blk_type = curr_model().block_type(blk_id);
            if (!(blk_type == AtomBlockType::INPAD || blk_type == AtomBlockType::OUTPAD)) {
                vpr_throw(VPR_ERROR_BLIF_F, filename_.c_str(), lineno_, "Unexpected primitives in blackbox model");
            }
        }
        set_curr_model_blackbox(true);
        set_curr_block(AtomBlockId::INVALID()); //This statement doesn't define a block, so mark invalid
    }

    void end_model() override {
        if (ended_) {
            vpr_throw(VPR_ERROR_BLIF_F, filename_.c_str(), lineno_, "Unexpected .end");
        }

        merge_conn_nets();

        //Mark as ended
        ended_ = true;

        set_curr_block(AtomBlockId::INVALID()); //This statement doesn't define a block, so mark invalid
    }

    //BLIF Extensions
    void conn(std::string src, std::string dst) override {
        if (blif_format_ != e_circuit_format::EBLIF) {
            parse_error(lineno_, ".conn", "Supported only in extended BLIF format");
        }

        //We allow the .conn to create the nets if they don't exist,
        //however typically they will have already been defined.
        AtomNetId driver_net = curr_model().create_net(src);
        AtomNetId sink_net = curr_model().create_net(dst);

        //We eventually need to merge the driver and sink nets,
        //however we must defer that until all the net drivers
        //and sinks have been created (otherwise they may not
        //be properly merged depending on where the .conn is
        //delcared).
        //
        //As a result we record the nets to merge and do the actual merging at
        //the end of the .model
        curr_nets_to_merge_.emplace_back(driver_net, sink_net);

        set_curr_block(AtomBlockId::INVALID());
    }

    void cname(std::string cell_name) override {
        if (blif_format_ != e_circuit_format::EBLIF) {
            parse_error(lineno_, ".cname", "Supported only in extended BLIF format");
        }

        //Re-name the block
        curr_model().set_block_name(curr_block(), cell_name);
    }

    void attr(std::string name, std::string value) override {
        if (blif_format_ != e_circuit_format::EBLIF) {
            parse_error(lineno_, ".attr", "Supported only in extended BLIF format");
        }

        curr_model().set_block_attr(curr_block(), name, value);
    }

    void param(std::string name, std::string value) override {
        if (blif_format_ != e_circuit_format::EBLIF) {
            parse_error(lineno_, ".param", "Supported only in extended BLIF format");
        }

        curr_model().set_block_param(curr_block(), name, value);
    }

    //Utilities
    void filename(std::string fname) override { filename_ = fname; }

    void lineno(int line_num) override { lineno_ = line_num; }

    void parse_error(const int curr_lineno, const std::string& near_text, const std::string& msg) override {
        vpr_throw(VPR_ERROR_BLIF_F, filename_.c_str(), curr_lineno,
                  "Error in blif file near '%s': %s\n", near_text.c_str(), msg.c_str());
    }

  public:
    //Retrieve the netlist
    size_t determine_main_netlist_index() {
        //Look through all the models loaded, to find the one which is non-blackbox (i.e. has real blocks
        //and is not a blackbox).  To check for errors we look at all models, even if we've already
        //found a non-blackbox model.
        int top_model_idx = -1; //Not valid

        for (int i = 0; i < static_cast<int>(blif_models_.size()); ++i) {
            if (!blif_models_black_box_[i]) {
                //A non-blackbox model
                if (top_model_idx == -1) {
                    //This is the top model
                    top_model_idx = i;
                } else {
                    //We already have a top model
                    vpr_throw(VPR_ERROR_BLIF_F, filename_.c_str(), lineno_,
                              "Found multiple models with primitives. "
                              "Only one model can contain primitives, the others must be blackboxes.");
                }
            } else {
                //Verify blackbox models match the architecture
                verify_blackbox_model(blif_models_[i]);
            }
        }

        if (top_model_idx == -1) {
            vpr_throw(VPR_ERROR_BLIF_F, filename_.c_str(), lineno_,
                      "No non-blackbox models found. The main model must not be a blackbox.");
        }

        //Return the main model
        VTR_ASSERT(top_model_idx >= 0);
        return static_cast<size_t>(top_model_idx);
    }

  private:
    const t_model* find_model(std::string name) {
        const t_model* arch_model = nullptr;
        for (const t_model* arch_models : {user_arch_models_, library_arch_models_}) {
            arch_model = arch_models;
            while (arch_model) {
                if (name == arch_model->name) {
                    //Found it
                    break;
                }
                arch_model = arch_model->next;
            }
            if (arch_model) {
                //Found it
                break;
            }
        }
        if (!arch_model) {
            vpr_throw(VPR_ERROR_BLIF_F, filename_.c_str(), lineno_, "Failed to find matching architecture model for '%s'\n",
                      name.c_str());
        }
        return arch_model;
    }

    const t_model_ports* find_model_port(const t_model* blk_model, std::string port_name) {
        //We need to handle both single, and multi-bit port names
        //
        //By convention multi-bit port names have the bit index stored in square brackets
        //at the end of the name. For example:
        //
        //   my_signal_name[2]
        //
        //indicates the 2nd bit of the port 'my_signal_name'.
        std::string trimmed_port_name;
        int bit_index;

        //Extract the index bit
        std::tie(trimmed_port_name, bit_index) = split_index(port_name);

        //We now have the valid bit index and port_name is the name excluding the index info
        VTR_ASSERT(bit_index >= 0);

        //We now look through all the ports on the model looking for the matching port
        for (const t_model_ports* ports : {blk_model->inputs, blk_model->outputs}) {
            const t_model_ports* curr_port = ports;
            while (curr_port) {
                if (trimmed_port_name == curr_port->name) {
                    //Found a matching port, we need to verify the index
                    if (bit_index < curr_port->size) {
                        //Valid port index
                        return curr_port;
                    } else {
                        //Out of range
                        vpr_throw(VPR_ERROR_BLIF_F, filename_.c_str(), lineno_,
                                  "Port '%s' on architecture model '%s' exceeds port width (%d bits)\n",
                                  port_name.c_str(), blk_model->name, curr_port->size);
                    }
                }
                curr_port = curr_port->next;
            }
        }

        //No match
        vpr_throw(VPR_ERROR_BLIF_F, filename_.c_str(), lineno_,
                  "Found no matching port '%s' on architecture model '%s'\n",
                  port_name.c_str(), blk_model->name);
        return nullptr;
    }

    //Splits the index off a signal name and returns the base signal name (excluding
    //the index) and the index as an integer. For example
    //
    //  "my_signal_name[2]"   -> "my_signal_name", 2
    std::pair<std::string, int> split_index(const std::string& signal_name) {
        int bit_index = 0;

        std::string trimmed_signal_name = signal_name;

        auto iter = --signal_name.end(); //Initialized to the last char
        if (*iter == ']') {
            //The name may end in an index
            //
            //To verify, we iterate back through the string until we find
            //an open square brackets, or non digit character
            --iter; //Advance past ']'
            while (iter != signal_name.begin() && std::isdigit(*iter))
                --iter;

            //We are at the first non-digit character from the end (or the beginning of the string)
            if (*iter == '[') {
                //We have a valid index in the open range (iter, --signal_name.end())
                std::string index_str(iter + 1, --signal_name.end());

                //Convert to an integer
                std::stringstream ss(index_str);
                ss >> bit_index;
                VTR_ASSERT_MSG(!ss.fail() && ss.eof(), "Failed to extract signal index");

                //Trim the signal name to exclude the final index
                trimmed_signal_name = std::string(signal_name.begin(), iter);
            }
        }
        return std::make_pair(trimmed_signal_name, bit_index);
    }

    //Retieves a reference to the currently active .model
    AtomNetlist& curr_model() {
        if (blif_models_.empty() || ended_) {
            vpr_throw(VPR_ERROR_BLIF_F, filename_.c_str(), lineno_, "Expected .model");
        }

        return blif_models_[blif_models_.size() - 1];
    }

    void set_curr_model_blackbox(bool val) {
        VTR_ASSERT(blif_models_.size() == blif_models_black_box_.size());
        blif_models_black_box_[blif_models_black_box_.size() - 1] = val;
    }

    bool verify_blackbox_model(AtomNetlist& blif_model) {
        const t_model* arch_model = find_model(blif_model.netlist_name());

        //Verify each port on the model
        //
        // We parse each .model as it's own netlist so the IOs
        // get converted to blocks
        for (auto blk_id : blif_model.blocks()) {
            //Check that the port directions match
            if (blif_model.block_type(blk_id) == AtomBlockType::INPAD) {
                const auto& input_name = blif_model.block_name(blk_id);

                //Find model port already verifies the port widths
                const t_model_ports* arch_model_port = find_model_port(arch_model, input_name);
                VTR_ASSERT(arch_model_port);
                VTR_ASSERT(arch_model_port->dir == IN_PORT);

            } else {
                VTR_ASSERT(blif_model.block_type(blk_id) == AtomBlockType::OUTPAD);

                auto raw_output_name = blif_model.block_name(blk_id);

                std::string output_name = vtr::replace_first(raw_output_name, OUTPAD_NAME_PREFIX, "");

                //Find model port already verifies the port widths
                const t_model_ports* arch_model_port = find_model_port(arch_model, output_name);
                VTR_ASSERT(arch_model_port);

                VTR_ASSERT(arch_model_port->dir == OUT_PORT);
            }
        }
        return true;
    }

    //Returns a different unique subck name each time it is called
    std::string unique_subckt_name() {
        return "unnamed_subckt" + std::to_string(unique_subckt_name_counter_++);
    }

    //Sets the current block which is being processed
    // Used to determine which block a .cname, .param, .attr apply to
    void set_curr_block(AtomBlockId blk) {
        curr_block_ = blk;
    }

    //Gets the current block which is being processed
    AtomBlockId curr_block() const {
        return curr_block_;
    }

    //Merges all the recorded net pairs which need to be merged
    //
    //This should only be called at the end of a .model to ensure that
    //all the associated driver/sink pins have been delcared and connected
    //to their nets
    void merge_conn_nets() {
        for (auto net_pair : curr_nets_to_merge_) {
            curr_model().merge_nets(net_pair.first, net_pair.second);
        }

        curr_nets_to_merge_.clear();
    }

  private:
    bool ended_ = true; //Initially no active .model
    std::string filename_ = "";
    int lineno_ = -1;

    std::vector<AtomNetlist> blif_models_;
    std::vector<bool> blif_models_black_box_;

    AtomNetlist& main_netlist_;    //User object we fill
    const std::string netlist_id_; //Unique identifier based on the contents of the blif file
    const t_model* user_arch_models_ = nullptr;
    const t_model* library_arch_models_ = nullptr;

    size_t unique_subckt_name_counter_ = 0;

    AtomBlockId curr_block_;
    std::vector<std::pair<AtomNetId, AtomNetId>> curr_nets_to_merge_;

    e_circuit_format blif_format_ = e_circuit_format::BLIF;
};

vtr::LogicValue to_vtr_logic_value(blifparse::LogicValue val) {
    vtr::LogicValue new_val = vtr::LogicValue::UNKOWN;
    switch (val) {
        case blifparse::LogicValue::TRUE:
            new_val = vtr::LogicValue::TRUE;
            break;
        case blifparse::LogicValue::FALSE:
            new_val = vtr::LogicValue::FALSE;
            break;
        case blifparse::LogicValue::DONT_CARE:
            new_val = vtr::LogicValue::DONT_CARE;
            break;
        case blifparse::LogicValue::UNKOWN:
            new_val = vtr::LogicValue::UNKOWN;
            break;
        default:
            VTR_ASSERT_OPT_MSG(false, "Unkown logic value");
    }
    return new_val;
}

AtomNetlist read_blif(e_circuit_format circuit_format,
                      const char* blif_file,
                      const t_model* user_models,
                      const t_model* library_models) {
    AtomNetlist netlist;
    std::string netlist_id = vtr::secure_digest_file(blif_file);

    BlifAllocCallback alloc_callback(circuit_format, netlist, netlist_id, user_models, library_models);
    blifparse::blif_parse_filename(blif_file, alloc_callback);

    return netlist;
}
