/*
 * 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,
                          const e_const_gen_inference const_gen_inference,
                          int verbosity)
            : main_netlist_(main_netlist)
            , netlist_id_(netlist_id)
            , user_arch_models_(user_models)
            , library_arch_models_(library_models)
            , blif_format_(blif_format) 
            , const_gen_inference_(const_gen_inference)
            , verbosity_(verbosity) {
            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 {
            VTR_LOGV(verbosity_ > 0, "Inferred %zu constant generator blocks\n", num_constant_generators_inferred_);

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

            //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 = 0;

            //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(identify_candidate_constant_generator(blk_id)) {
                        //This block is a constant generator
                        marked_blocks.insert(blk_id);

                        //We may infer constant generators which have already been identified (e.g. vcc/gnd).
                        //Check if the output pins are already all marked as constants
                        bool all_pins_constant = true;
                        for(auto pin_id : curr_model().block_output_pins(blk_id)) {
                            if (!curr_model().pin_is_constant(pin_id)) {
                                all_pins_constant = false;
                                break;
                            }
                        }

                        if (!all_pins_constant) { //New constant generator
                            VTR_LOGV(verbosity_ > 1, "Inferred black-box constant generator '%s' (%s)\n",
                                        curr_model().block_name(blk_id).c_str(),
                                        curr_model().block_model(blk_id)->name);

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

                        ++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(AtomBlockId blk_id) {

            //Constant generator inference disabled. Nothing is a constant generator.
            if (const_gen_inference_ == e_const_gen_inference::NONE) return false;

            //Never mark I/Os as constants
            if (curr_model().block_type(blk_id) != AtomBlockType::BLOCK) return false;

            VTR_ASSERT(const_gen_inference_ == e_const_gen_inference::COMB
                       || const_gen_inference_ == e_const_gen_inference::COMB_SEQ);

            if (!curr_model().block_is_combinational(blk_id) 
                && const_gen_inference_ != e_const_gen_inference::COMB_SEQ) {
                //This is a sequential block, and sequential constant generator 
                //inference is disabled.
                //Therefore not a constant generator
                return false;
            }

            //A block 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)) {
                    //Non-constant input.
                    //This block can not be a constant generator.
                    return false; 
                } else {
                    VTR_ASSERT(!net_id || curr_model().net_is_constant(net_id));
                }
            }

            VTR_ASSERT_SAFE((const_gen_inference_ == e_const_gen_inference::COMB && curr_model().block_is_combinational(blk_id))
                            || (const_gen_inference_ == e_const_gen_inference::COMB_SEQ));

            //This subckt is a constant generator
            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_;
        }

    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;
        size_t num_constant_generators_inferred_ = 0;

        AtomBlockId curr_block_;

        e_circuit_format blif_format_ = e_circuit_format::BLIF;
        e_const_gen_inference const_gen_inference_ = e_const_gen_inference::COMB;
        int verbosity_ = 1;

};


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,
                      const e_const_gen_inference const_gen_inference,
                      const int verbosity) {


    AtomNetlist netlist;
    std::string netlist_id = vtr::secure_digest_file(blif_file);

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

    return netlist;
}

