Skip to content

Commit

Permalink
Merge pull request #4537 from povik/libparse-cleanup
Browse files Browse the repository at this point in the history
Liberty parsing cleanup
  • Loading branch information
povik authored Aug 14, 2024
2 parents 4b9f452 + ab5d6b0 commit a854903
Show file tree
Hide file tree
Showing 22 changed files with 643 additions and 125 deletions.
69 changes: 17 additions & 52 deletions frontends/liberty/liberty.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,55 +53,20 @@ static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *&
return module->wires_.at(id);
}

static RTLIL::SigSpec create_inv_cell(RTLIL::Module *module, RTLIL::SigSpec A)
{
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($_NOT_));
cell->setPort(ID::A, A);
cell->setPort(ID::Y, module->addWire(NEW_ID));
return cell->getPort(ID::Y);
}

static RTLIL::SigSpec create_xor_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B)
{
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($_XOR_));
cell->setPort(ID::A, A);
cell->setPort(ID::B, B);
cell->setPort(ID::Y, module->addWire(NEW_ID));
return cell->getPort(ID::Y);
}

static RTLIL::SigSpec create_and_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B)
{
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($_AND_));
cell->setPort(ID::A, A);
cell->setPort(ID::B, B);
cell->setPort(ID::Y, module->addWire(NEW_ID));
return cell->getPort(ID::Y);
}

static RTLIL::SigSpec create_or_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B)
{
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($_OR_));
cell->setPort(ID::A, A);
cell->setPort(ID::B, B);
cell->setPort(ID::Y, module->addWire(NEW_ID));
return cell->getPort(ID::Y);
}

static bool parse_func_reduce(RTLIL::Module *module, std::vector<token_t> &stack, token_t next_token)
{
int top = int(stack.size())-1;

if (0 <= top-1 && stack[top].type == 0 && stack[top-1].type == '!') {
token_t t = token_t(0, create_inv_cell(module, stack[top].sig));
token_t t = token_t(0, module->NotGate(NEW_ID, stack[top].sig));
stack.pop_back();
stack.pop_back();
stack.push_back(t);
return true;
}

if (0 <= top-1 && stack[top].type == '\'' && stack[top-1].type == 0) {
token_t t = token_t(0, create_inv_cell(module, stack[top-1].sig));
token_t t = token_t(0, module->NotGate(NEW_ID, stack[top-1].sig));
stack.pop_back();
stack.pop_back();
stack.push_back(t);
Expand All @@ -116,7 +81,7 @@ static bool parse_func_reduce(RTLIL::Module *module, std::vector<token_t> &stack
}

if (0 <= top-2 && stack[top-2].type == 1 && stack[top-1].type == '^' && stack[top].type == 1) {
token_t t = token_t(1, create_xor_cell(module, stack[top-2].sig, stack[top].sig));
token_t t = token_t(1, module->XorGate(NEW_ID, stack[top-2].sig, stack[top].sig));
stack.pop_back();
stack.pop_back();
stack.pop_back();
Expand All @@ -132,15 +97,15 @@ static bool parse_func_reduce(RTLIL::Module *module, std::vector<token_t> &stack
}

if (0 <= top-1 && stack[top-1].type == 2 && stack[top].type == 2) {
token_t t = token_t(2, create_and_cell(module, stack[top-1].sig, stack[top].sig));
token_t t = token_t(2, module->AndGate(NEW_ID, stack[top-1].sig, stack[top].sig));
stack.pop_back();
stack.pop_back();
stack.push_back(t);
return true;
}

if (0 <= top-2 && stack[top-2].type == 2 && (stack[top-1].type == '*' || stack[top-1].type == '&') && stack[top].type == 2) {
token_t t = token_t(2, create_and_cell(module, stack[top-2].sig, stack[top].sig));
token_t t = token_t(2, module->AndGate(NEW_ID, stack[top-2].sig, stack[top].sig));
stack.pop_back();
stack.pop_back();
stack.pop_back();
Expand All @@ -156,7 +121,7 @@ static bool parse_func_reduce(RTLIL::Module *module, std::vector<token_t> &stack
}

if (0 <= top-2 && stack[top-2].type == 3 && (stack[top-1].type == '+' || stack[top-1].type == '|') && stack[top].type == 3) {
token_t t = token_t(3, create_or_cell(module, stack[top-2].sig, stack[top].sig));
token_t t = token_t(3, module->OrGate(NEW_ID, stack[top-2].sig, stack[top].sig));
stack.pop_back();
stack.pop_back();
stack.pop_back();
Expand Down Expand Up @@ -221,12 +186,12 @@ static RTLIL::SigSpec create_tristate(RTLIL::Module *module, RTLIL::SigSpec func
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($tribuf));
cell->setParam(ID::WIDTH, GetSize(func));
cell->setPort(ID::A, func);
cell->setPort(ID::EN, create_inv_cell(module, three_state));
cell->setPort(ID::EN, module->NotGate(NEW_ID, three_state));
cell->setPort(ID::Y, module->addWire(NEW_ID));
return cell->getPort(ID::Y);
}

static void create_ff(RTLIL::Module *module, LibertyAst *node)
static void create_ff(RTLIL::Module *module, const LibertyAst *node)
{
RTLIL::SigSpec iq_sig(module->addWire(RTLIL::escape_id(node->args.at(0))));
RTLIL::SigSpec iqn_sig(module->addWire(RTLIL::escape_id(node->args.at(1))));
Expand Down Expand Up @@ -303,7 +268,7 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node)
log_assert(!cell->type.empty());
}

static bool create_latch(RTLIL::Module *module, LibertyAst *node, bool flag_ignore_miss_data_latch)
static bool create_latch(RTLIL::Module *module, const LibertyAst *node, bool flag_ignore_miss_data_latch)
{
RTLIL::SigSpec iq_sig(module->addWire(RTLIL::escape_id(node->args.at(0))));
RTLIL::SigSpec iqn_sig(module->addWire(RTLIL::escape_id(node->args.at(1))));
Expand Down Expand Up @@ -422,7 +387,7 @@ static bool create_latch(RTLIL::Module *module, LibertyAst *node, bool flag_igno
return true;
}

void parse_type_map(std::map<std::string, std::tuple<int, int, bool>> &type_map, LibertyAst *ast)
void parse_type_map(std::map<std::string, std::tuple<int, int, bool>> &type_map, const LibertyAst *ast)
{
for (auto type_node : ast->children)
{
Expand Down Expand Up @@ -604,7 +569,7 @@ struct LibertyFrontend : public Frontend {
for (auto node : cell->children)
{
if (node->id == "pin" && node->args.size() == 1) {
LibertyAst *dir = node->find("direction");
const LibertyAst *dir = node->find("direction");
if (!dir || (dir->value != "input" && dir->value != "output" && dir->value != "inout" && dir->value != "internal"))
{
if (!flag_ignore_miss_dir)
Expand All @@ -625,10 +590,10 @@ struct LibertyFrontend : public Frontend {
if (!flag_lib)
log_error("Error in cell %s: bus interfaces are only supported in -lib mode.\n", log_id(cell_name));

LibertyAst *dir = node->find("direction");
const LibertyAst *dir = node->find("direction");

if (dir == nullptr) {
LibertyAst *pin = node->find("pin");
const LibertyAst *pin = node->find("pin");
if (pin != nullptr)
dir = pin->find("direction");
}
Expand All @@ -639,7 +604,7 @@ struct LibertyFrontend : public Frontend {
if (dir->value == "internal")
continue;

LibertyAst *bus_type_node = node->find("bus_type");
const LibertyAst *bus_type_node = node->find("bus_type");

if (!bus_type_node || !type_map.count(bus_type_node->value))
log_error("Unknown or unsupported type for bus interface %s on cell %s.\n",
Expand Down Expand Up @@ -681,7 +646,7 @@ struct LibertyFrontend : public Frontend {
{
if (node->id == "pin" && node->args.size() == 1)
{
LibertyAst *dir = node->find("direction");
const LibertyAst *dir = node->find("direction");

if (flag_lib && dir->value == "internal")
continue;
Expand All @@ -704,7 +669,7 @@ struct LibertyFrontend : public Frontend {
if (flag_lib)
continue;

LibertyAst *func = node->find("function");
const LibertyAst *func = node->find("function");
if (func == NULL)
{
if (dir->value != "inout") { // allow inout with missing function, can be used for power pins
Expand All @@ -719,7 +684,7 @@ struct LibertyFrontend : public Frontend {
}
} else {
RTLIL::SigSpec out_sig = parse_func_expr(module, func->value.c_str());
LibertyAst *three_state = node->find("three_state");
const LibertyAst *three_state = node->find("three_state");
if (three_state) {
out_sig = create_tristate(module, out_sig, three_state->value.c_str());
}
Expand Down
2 changes: 1 addition & 1 deletion passes/cmds/stat.cc
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ void read_liberty_cellarea(dict<IdString, cell_area_t> &cell_area, string libert
if (cell->id != "cell" || cell->args.size() != 1)
continue;

LibertyAst *ar = cell->find("area");
const LibertyAst *ar = cell->find("area");
bool is_flip_flop = cell->find("ff") != nullptr;
if (ar != nullptr && !ar->value.empty())
cell_area["\\" + cell->args[0]] = {/*area=*/atof(ar->value.c_str()), is_flip_flop};
Expand Down
30 changes: 15 additions & 15 deletions passes/techmap/dfflibmap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ static void logmap_all()
logmap(ID($_DFFSR_PPP_));
}

static bool parse_pin(LibertyAst *cell, LibertyAst *attr, std::string &pin_name, bool &pin_pol)
static bool parse_pin(const LibertyAst *cell, const LibertyAst *attr, std::string &pin_name, bool &pin_pol)
{
if (cell == nullptr || attr == nullptr || attr->value.empty())
return false;
Expand Down Expand Up @@ -115,9 +115,9 @@ static bool parse_pin(LibertyAst *cell, LibertyAst *attr, std::string &pin_name,
return false;
}

static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has_reset, bool rstpol, bool rstval, std::vector<std::string> &dont_use_cells)
static void find_cell(const LibertyAst *ast, IdString cell_type, bool clkpol, bool has_reset, bool rstpol, bool rstval, std::vector<std::string> &dont_use_cells)
{
LibertyAst *best_cell = nullptr;
const LibertyAst *best_cell = nullptr;
std::map<std::string, char> best_cell_ports;
int best_cell_pins = 0;
bool best_cell_noninv = false;
Expand All @@ -131,7 +131,7 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
if (cell->id != "cell" || cell->args.size() != 1)
continue;

LibertyAst *dn = cell->find("dont_use");
const LibertyAst *dn = cell->find("dont_use");
if (dn != nullptr && dn->value == "true")
continue;

Expand All @@ -147,7 +147,7 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
if (dont_use)
continue;

LibertyAst *ff = cell->find("ff");
const LibertyAst *ff = cell->find("ff");
if (ff == nullptr)
continue;

Expand All @@ -174,7 +174,7 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
this_cell_ports[cell_next_pin] = 'D';

double area = 0;
LibertyAst *ar = cell->find("area");
const LibertyAst *ar = cell->find("area");
if (ar != nullptr && !ar->value.empty())
area = atof(ar->value.c_str());

Expand All @@ -186,15 +186,15 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
if (pin->id != "pin" || pin->args.size() != 1)
continue;

LibertyAst *dir = pin->find("direction");
const LibertyAst *dir = pin->find("direction");
if (dir == nullptr || dir->value == "internal")
continue;
num_pins++;

if (dir->value == "input" && this_cell_ports.count(pin->args[0]) == 0)
goto continue_cell_loop;

LibertyAst *func = pin->find("function");
const LibertyAst *func = pin->find("function");
if (dir->value == "output" && func != nullptr) {
std::string value = func->value;
for (size_t pos = value.find_first_of("\" \t"); pos != std::string::npos; pos = value.find_first_of("\" \t"))
Expand Down Expand Up @@ -239,9 +239,9 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
}
}

static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool setpol, bool clrpol, std::vector<std::string> &dont_use_cells)
static void find_cell_sr(const LibertyAst *ast, IdString cell_type, bool clkpol, bool setpol, bool clrpol, std::vector<std::string> &dont_use_cells)
{
LibertyAst *best_cell = nullptr;
const LibertyAst *best_cell = nullptr;
std::map<std::string, char> best_cell_ports;
int best_cell_pins = 0;
bool best_cell_noninv = false;
Expand All @@ -255,7 +255,7 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
if (cell->id != "cell" || cell->args.size() != 1)
continue;

LibertyAst *dn = cell->find("dont_use");
const LibertyAst *dn = cell->find("dont_use");
if (dn != nullptr && dn->value == "true")
continue;

Expand All @@ -271,7 +271,7 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
if (dont_use)
continue;

LibertyAst *ff = cell->find("ff");
const LibertyAst *ff = cell->find("ff");
if (ff == nullptr)
continue;

Expand All @@ -294,7 +294,7 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
this_cell_ports[cell_next_pin] = 'D';

double area = 0;
LibertyAst *ar = cell->find("area");
const LibertyAst *ar = cell->find("area");
if (ar != nullptr && !ar->value.empty())
area = atof(ar->value.c_str());

Expand All @@ -306,15 +306,15 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
if (pin->id != "pin" || pin->args.size() != 1)
continue;

LibertyAst *dir = pin->find("direction");
const LibertyAst *dir = pin->find("direction");
if (dir == nullptr || dir->value == "internal")
continue;
num_pins++;

if (dir->value == "input" && this_cell_ports.count(pin->args[0]) == 0)
goto continue_cell_loop;

LibertyAst *func = pin->find("function");
const LibertyAst *func = pin->find("function");
if (dir->value == "output" && func != nullptr) {
std::string value = func->value;
for (size_t pos = value.find_first_of("\" \t"); pos != std::string::npos; pos = value.find_first_of("\" \t"))
Expand Down
Loading

0 comments on commit a854903

Please sign in to comment.