mirror of https://github.com/YosysHQ/yosys.git
Add "read_blif -wideports"
This commit is contained in:
parent
aab58045a8
commit
7e0b776a79
|
@ -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<RTLIL::IdString, int> 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<RTLIL::IdString, int>("\\" + name.substr(0, pos), atoi(name.c_str() + pos+1)+1);
|
||||
|
||||
failed:
|
||||
return std::pair<RTLIL::IdString, int>("\\" + 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<RTLIL::IdString, RTLIL::Const> *obj_attributes = nullptr;
|
||||
dict<RTLIL::IdString, RTLIL::Const> *obj_parameters = nullptr;
|
||||
|
||||
dict<RTLIL::IdString, std::pair<int, bool>> 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<RTLIL::IdString, int> 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<std::string> 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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue