2025-05-02 14:18:01 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
#include <optional>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <unordered_map>
|
|
|
|
|
#include <variant>
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
#include "EnumNameMap.h"
|
|
|
|
|
#include "Helper.h"
|
|
|
|
|
#include "tokenizer.h"
|
|
|
|
|
#include "unit.h"
|
|
|
|
|
|
2025-06-26 16:21:37 +08:00
|
|
|
#include "Lut.h"
|
|
|
|
|
|
2025-05-02 14:18:01 +08:00
|
|
|
using std::optional;
|
|
|
|
|
using std::string;
|
|
|
|
|
using std::unordered_map;
|
|
|
|
|
using std::variant;
|
|
|
|
|
using std::vector;
|
|
|
|
|
|
|
|
|
|
namespace db {
|
|
|
|
|
class Database;
|
|
|
|
|
class CellType;
|
|
|
|
|
}; // namespace db
|
|
|
|
|
|
|
|
|
|
namespace gt {
|
|
|
|
|
|
|
|
|
|
class CellLib;
|
|
|
|
|
class LibertyCell;
|
|
|
|
|
class LibertyPort;
|
|
|
|
|
class TimingArc;
|
|
|
|
|
struct LutTemplate;
|
|
|
|
|
class Lut;
|
2025-06-26 16:21:37 +08:00
|
|
|
class BusType;
|
|
|
|
|
class InternalArc;
|
|
|
|
|
// class LutVar;
|
2025-05-02 14:18:01 +08:00
|
|
|
|
|
|
|
|
enum class DelayModel { generic_cmos, table_lookup, cmos2, piecewise_cmos, dcm, polynomial, unknown };
|
|
|
|
|
enum class CellPortDirection { input, output, inout, internal, unknown };
|
|
|
|
|
DelayModel findDelayModel(const std::string model_name);
|
|
|
|
|
CellPortDirection findPortDirection(const std::string dir_name);
|
|
|
|
|
|
|
|
|
|
class CellLib {
|
|
|
|
|
public:
|
|
|
|
|
~CellLib() { logger.info("Destruct celllib"); }
|
|
|
|
|
CellLib() = default;
|
|
|
|
|
CellLib(db::Database *rawdb_) : rawdb(rawdb_) {}
|
|
|
|
|
db::Database *rawdb = nullptr;
|
|
|
|
|
db::CellType *cell_type_ = nullptr;
|
|
|
|
|
|
|
|
|
|
using token_iterator = std::vector<std::string_view>::iterator;
|
|
|
|
|
DelayModel delay_model;
|
|
|
|
|
string name;
|
|
|
|
|
|
|
|
|
|
optional<second_t> time_unit_;
|
|
|
|
|
optional<watt_t> power_unit_;
|
|
|
|
|
optional<ohm_t> resistance_unit_;
|
|
|
|
|
optional<farad_t> capacitance_unit_;
|
|
|
|
|
optional<ampere_t> current_unit_;
|
|
|
|
|
optional<volt_t> voltage_unit_;
|
2025-06-26 16:21:37 +08:00
|
|
|
optional<float> energy_unit_;
|
2025-05-02 14:18:01 +08:00
|
|
|
|
|
|
|
|
unordered_map<string, optional<float>> default_values = {
|
|
|
|
|
{"default_cell_leakage_power", optional<float>{}},
|
|
|
|
|
{"default_inout_pin_cap", optional<float>{}},
|
|
|
|
|
{"default_input_pin_cap", optional<float>{}},
|
|
|
|
|
{"default_output_pin_cap", optional<float>{}},
|
|
|
|
|
{"default_fanout_load", optional<float>{}},
|
|
|
|
|
{"default_max_fanout", optional<float>{}},
|
|
|
|
|
{"default_max_transition", optional<float>{}},
|
|
|
|
|
{"voltage", optional<float>{}},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
unordered_map<string, float> scale_factors = {
|
|
|
|
|
{"time", 1.0},
|
|
|
|
|
{"resistance", 1.0},
|
|
|
|
|
{"power", 1.0},
|
|
|
|
|
{"capacitance", 1.0},
|
|
|
|
|
{"current", 1.0},
|
|
|
|
|
{"voltage", 1.0},
|
2025-06-26 16:21:37 +08:00
|
|
|
{"energy", 1.0}
|
2025-05-02 14:18:01 +08:00
|
|
|
};
|
|
|
|
|
|
2025-06-26 16:21:37 +08:00
|
|
|
unordered_map<string, BusType *> Bus_types_;
|
2025-05-02 14:18:01 +08:00
|
|
|
unordered_map<string, LutTemplate *> lut_templates_;
|
|
|
|
|
unordered_map<string, LibertyCell *> lib_cells_;
|
2025-06-26 16:21:37 +08:00
|
|
|
unordered_map<string, vector<LibertyCell *>> func2libcell_map;
|
2025-05-02 14:18:01 +08:00
|
|
|
|
|
|
|
|
LutTemplate *get_lut_template(const string &);
|
|
|
|
|
LibertyCell *get_cell(const std::string &name);
|
|
|
|
|
void read(const string &file);
|
|
|
|
|
void finish_read();
|
|
|
|
|
void finish_port_read(LibertyPort *liberty_port);
|
|
|
|
|
|
2025-06-26 16:21:37 +08:00
|
|
|
float lut_index_to_scale_factor(LutVar var) {
|
|
|
|
|
switch (var) {
|
|
|
|
|
case LutVar::CONSTRAINED_PIN_TRANSITION:
|
|
|
|
|
case LutVar::INPUT_NET_TRANSITION:
|
|
|
|
|
case LutVar::RELATED_PIN_TRANSITION:
|
|
|
|
|
case LutVar::INPUT_TRANSITION_TIME:
|
|
|
|
|
return scale_factors["time"];
|
|
|
|
|
case LutVar::TOTAL_OUTPUT_NET_CAPACITANCE:
|
|
|
|
|
return scale_factors["capacitance"];
|
|
|
|
|
case LutVar::NORMALIZED_VOLTAGE:
|
|
|
|
|
return scale_factors["voltage"];
|
|
|
|
|
default:
|
|
|
|
|
throw std::invalid_argument("Invalid LutVar value");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-02 14:18:01 +08:00
|
|
|
public:
|
|
|
|
|
LibertyCell *extractLibertyCell(token_iterator &, const token_iterator);
|
|
|
|
|
LibertyPort *extractLibertyPort(token_iterator &, const token_iterator, LibertyCell *);
|
2025-06-26 16:21:37 +08:00
|
|
|
void extractLibertyBus(token_iterator &, const token_iterator, LibertyCell *, LibertyPort *);
|
2025-05-02 14:18:01 +08:00
|
|
|
TimingArc *extractTimingArc(token_iterator &, const token_iterator, LibertyPort *);
|
2025-06-26 16:21:37 +08:00
|
|
|
InternalArc *extractInternalArc(token_iterator &, const token_iterator, LibertyPort *);
|
2025-05-02 14:18:01 +08:00
|
|
|
std::optional<float> extract_operating_conditions(token_iterator &itr, const token_iterator end);
|
|
|
|
|
LutTemplate *extract_lut_template(token_iterator &, const token_iterator);
|
2025-06-26 16:21:37 +08:00
|
|
|
Lut *extract_lut(token_iterator &, const token_iterator, float value_scale);
|
|
|
|
|
BusType *extract_bus_type(token_iterator &, const token_iterator);
|
2025-05-02 14:18:01 +08:00
|
|
|
|
|
|
|
|
void apply_default_values();
|
|
|
|
|
void uncomment(std::vector<char> &);
|
|
|
|
|
void tokenize(const std::vector<char> &, std::vector<std::string_view> &);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class LibertyCell {
|
|
|
|
|
public:
|
|
|
|
|
LibertyCell() = default;
|
|
|
|
|
string name;
|
|
|
|
|
db:: CellType *cell_type_ = nullptr;
|
|
|
|
|
vector<LibertyPort *> ports_;
|
2025-06-26 16:21:37 +08:00
|
|
|
vector<LibertyPort *> buses_;
|
2025-05-02 14:18:01 +08:00
|
|
|
// map<string, LibertyPort *> ports_map_;
|
|
|
|
|
map<string, int> ports_map_;
|
|
|
|
|
|
|
|
|
|
vector<float> leakage_powers_;
|
|
|
|
|
optional<float> leakage_power_;
|
|
|
|
|
optional<float> area_;
|
|
|
|
|
|
|
|
|
|
bool is_seq_ = false;
|
|
|
|
|
int num_bits_ = 0;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
int get_port(const std::string &name);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class LibertyPort {
|
|
|
|
|
public:
|
|
|
|
|
LibertyPort() = default;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
string name;
|
|
|
|
|
LibertyCell *cell_;
|
|
|
|
|
CellPortDirection direction_;
|
|
|
|
|
optional<float> port_capacitance_[3];
|
|
|
|
|
|
|
|
|
|
bool is_clock_ = false;
|
|
|
|
|
bool is_bundle_ = false;
|
2025-06-26 16:21:37 +08:00
|
|
|
// bool is_bus_ = false;
|
2025-05-02 14:18:01 +08:00
|
|
|
vector<LibertyPort *> member_ports_;
|
|
|
|
|
|
|
|
|
|
vector<TimingArc *> timing_arcs_;
|
2025-06-26 16:21:37 +08:00
|
|
|
vector<InternalArc *> internal_arcs_;
|
2025-05-02 14:18:01 +08:00
|
|
|
map<string, TimingArc *> timing_arcs_map_;
|
|
|
|
|
vector<TimingArc *> timing_arcs_non_cond_non_bundle_;
|
2025-06-26 16:21:37 +08:00
|
|
|
map<string, InternalArc *> internal_arcs_map_;
|
|
|
|
|
vector<InternalArc *> internal_arcs_non_cond_non_bundle_;
|
2025-05-02 14:18:01 +08:00
|
|
|
|
|
|
|
|
|
2025-06-26 16:21:37 +08:00
|
|
|
optional<string> function;
|
2025-05-02 14:18:01 +08:00
|
|
|
|
|
|
|
|
// optional<float> capacitance;
|
|
|
|
|
// optional<float> fall_capacitance;
|
|
|
|
|
// optional<float> rise_capacitance;
|
|
|
|
|
|
|
|
|
|
optional<float> fanout_load;
|
|
|
|
|
optional<float> max_fanout;
|
|
|
|
|
optional<float> min_fanout;
|
|
|
|
|
optional<float> max_capacitance;
|
|
|
|
|
optional<float> min_capacitance;
|
|
|
|
|
optional<float> max_transition;
|
|
|
|
|
optional<float> min_transition;
|
|
|
|
|
};
|
|
|
|
|
|
2025-06-26 16:21:37 +08:00
|
|
|
class BusType {
|
|
|
|
|
public:
|
|
|
|
|
BusType() = default;
|
|
|
|
|
std::string name;
|
|
|
|
|
optional<int> bit_from;
|
|
|
|
|
optional<int> bit_to;
|
|
|
|
|
optional<int> bit_width;
|
|
|
|
|
optional<bool> downto;
|
|
|
|
|
};
|
|
|
|
|
|
2025-05-02 14:18:01 +08:00
|
|
|
}; // namespace gt
|