/*
 * 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
using namespace std;

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

#include "vtr_assert.h"
#include "vtr_util.h"
#include "vtr_list.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::printf("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::printf("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::printf_warning(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::printf_warning(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");
            }

            //We can not determine if a .subckt is a constant generator until all
            //it's inputs have been created. So we identify them now, once the full
            //model has been defined
            mark_constant_generator_subckts();

            //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);

            curr_model().merge_nets(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;
        }

        //Marks all constant subckt generator output pins as constants
        void mark_constant_generator_subckts() {
            size_t num_blocks_marked;

            //It is possible that by marking one constant generator
            //it may 'reveal' another constant generator downstream.
            //As a result we iteratively mark constant generators until
            //no additional ones are identified.
            std::unordered_set<AtomBlockId> marked_blocks;
            do {
                num_blocks_marked = 0;

                //Look through all the blocks marking those that are
                //constant generataors
                for(auto blk_id : curr_model().blocks()) {
                    if(marked_blocks.count(blk_id)) continue; //Don't mark multiple times

                    if(curr_model().block_type(blk_id) != AtomBlockType::BLOCK) continue; //Don't mark I/Os as constants

                    if(identify_candidate_constant_generator_subckt(blk_id)) {
                        //This block is a constant generator
                        marked_blocks.insert(blk_id);

                        vtr::printf("Inferred black-box constant generator '%s'\n",
                                    curr_model().block_name(blk_id).c_str());

                        //Mark all the output pins as constants
                        for(auto pin_id : curr_model().block_output_pins(blk_id)) {
                            curr_model().set_pin_is_constant(pin_id, true);
                        }

                        ++num_blocks_marked;
                    }
                }
            } while(num_blocks_marked != 0);
        }

        //Determines if a particular block satisfies all the criteria of a constant
        //generator.
        //
        //Returns true, if the block is a constant generator and should be marked
        bool identify_candidate_constant_generator_subckt(AtomBlockId blk_id) {
            const t_model* arch_model = curr_model().block_model(blk_id);

            //We look for combinational blocks which are not .names (i.e.
            //combinational .subckts)
            if(curr_model().block_is_combinational(blk_id)
               && arch_model->name != std::string(MODEL_NAMES)) {

                //A subckt is a constant generator if all its input nets are either:
                //  1) Constant nets (i.e. driven by constant pins), or
                //  2) Disconnected
                for(auto pin_id : curr_model().block_input_pins(blk_id)) {
                    auto net_id = curr_model().pin_net(pin_id);

                    if(net_id && !curr_model().net_is_constant(net_id)) {
                        return false;
                    } else {
                        VTR_ASSERT(!net_id || curr_model().net_is_constant(net_id));
                    }
                }
                //This subckt is a constant generator
                return true;
            }
            return false;
        }

        //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_;
        }

    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_;

        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(const 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;
}

