From 7e0b776a793f648bed3338dfbc6b25bc1c24e873 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 6 Feb 2017 14:48:03 +0100 Subject: [PATCH] Add "read_blif -wideports" --- frontends/blif/blifparse.cc | 79 +++++++++++++++++++++++++++++++++++-- frontends/blif/blifparse.h | 3 +- 2 files changed, 77 insertions(+), 5 deletions(-) diff --git a/frontends/blif/blifparse.cc b/frontends/blif/blifparse.cc index 6d4d60870..f610a25c3 100644 --- a/frontends/blif/blifparse.cc +++ b/frontends/blif/blifparse.cc @@ -55,7 +55,30 @@ static bool read_next_line(char *&buffer, size_t &buffer_size, int &line_count, } } -void parse_blif(RTLIL::Design *design, std::istream &f, std::string dff_name, bool run_clean, bool sop_mode) +static std::pair wideports_split(std::string name) +{ + int pos = -1; + + if (name.empty() || name.back() != ']') + goto failed; + + for (int i = 0; i+1 < GetSize(name); i++) { + if (name[i] == '[') + pos = i; + else if (name[i] < '0' || name[i] > '9') + pos = -1; + else if (i == pos+1 && name[i] == '0') + pos = -1; + } + + if (pos >= 0) + return std::pair("\\" + name.substr(0, pos), atoi(name.c_str() + pos+1)+1); + +failed: + return std::pair("\\" + name, 0); +} + +void parse_blif(RTLIL::Design *design, std::istream &f, std::string dff_name, bool run_clean, bool sop_mode, bool wideports) { RTLIL::Module *module = nullptr; RTLIL::Const *lutptr = NULL; @@ -96,6 +119,8 @@ void parse_blif(RTLIL::Design *design, std::istream &f, std::string dff_name, bo dict *obj_attributes = nullptr; dict *obj_parameters = nullptr; + dict> wideports_cache; + size_t buffer_size = 4096; char *buffer = (char*)malloc(buffer_size); int line_count = 0; @@ -148,7 +173,32 @@ void parse_blif(RTLIL::Design *design, std::istream &f, std::string dff_name, bo if (!strcmp(cmd, ".end")) { + for (auto &wp : wideports_cache) + { + auto name = wp.first; + int width = wp.second.first; + bool isinput = wp.second.second; + + RTLIL::Wire *wire = module->addWire(name, width); + wire->port_input = isinput; + wire->port_output = !isinput; + + for (int i = 0; i < width; i++) { + RTLIL::IdString other_name = name.str() + stringf("[%d]", i); + RTLIL::Wire *other_wire = module->wire(other_name); + if (other_wire) { + other_wire->port_input = false; + other_wire->port_output = false; + if (isinput) + module->connect(other_wire, SigSpec(wire, i)); + else + module->connect(SigSpec(wire, i), other_wire); + } + } + } + module->fixup_ports(); + wideports_cache.clear(); if (run_clean) { @@ -187,9 +237,11 @@ void parse_blif(RTLIL::Design *design, std::istream &f, std::string dff_name, bo continue; } - if (!strcmp(cmd, ".inputs") || !strcmp(cmd, ".outputs")) { + if (!strcmp(cmd, ".inputs") || !strcmp(cmd, ".outputs")) + { char *p; - while ((p = strtok(NULL, " \t\r\n")) != NULL) { + while ((p = strtok(NULL, " \t\r\n")) != NULL) + { RTLIL::IdString wire_name(stringf("\\%s", p)); RTLIL::Wire *wire = module->wire(wire_name); if (wire == nullptr) @@ -198,6 +250,14 @@ void parse_blif(RTLIL::Design *design, std::istream &f, std::string dff_name, bo wire->port_input = true; else wire->port_output = true; + + if (wideports) { + std::pair wp = wideports_split(p); + if (wp.second > 0) { + wideports_cache[wp.first].first = std::max(wideports_cache[wp.first].first, wp.second); + wideports_cache[wp.first].second = !strcmp(cmd, ".inputs"); + } + } } obj_attributes = nullptr; obj_parameters = nullptr; @@ -452,6 +512,8 @@ void parse_blif(RTLIL::Design *design, std::istream &f, std::string dff_name, bo } } + return; + error: log_error("Syntax error in line %d!\n", line_count); } @@ -469,10 +531,15 @@ struct BlifFrontend : public Frontend { log(" -sop\n"); log(" Create $sop cells instead of $lut cells\n"); log("\n"); + log(" -wideports\n"); + log(" Merge ports that match the pattern 'name[int]' into a single\n"); + log(" multi-bit port 'name'.\n"); + log("\n"); } virtual void execute(std::istream *&f, std::string filename, std::vector args, RTLIL::Design *design) { bool sop_mode = false; + bool wideports = false; log_header(design, "Executing BLIF frontend.\n"); @@ -483,11 +550,15 @@ struct BlifFrontend : public Frontend { sop_mode = true; continue; } + if (arg == "-wideports") { + wideports = true; + continue; + } break; } extra_args(f, filename, args, argidx); - parse_blif(design, *f, "", true, sop_mode); + parse_blif(design, *f, "", true, sop_mode, wideports); } } BlifFrontend; diff --git a/frontends/blif/blifparse.h b/frontends/blif/blifparse.h index 058087d81..955b6aacf 100644 --- a/frontends/blif/blifparse.h +++ b/frontends/blif/blifparse.h @@ -24,7 +24,8 @@ YOSYS_NAMESPACE_BEGIN -extern void parse_blif(RTLIL::Design *design, std::istream &f, std::string dff_name, bool run_clean = false, bool sop_mode = false); +extern void parse_blif(RTLIL::Design *design, std::istream &f, std::string dff_name, + bool run_clean = false, bool sop_mode = false, bool wideports = false); YOSYS_NAMESPACE_END -- 2.30.2