diff options
author | Clifford Wolf <clifford@clifford.at> | 2013-06-19 09:30:37 +0200 |
---|---|---|
committer | Clifford Wolf <clifford@clifford.at> | 2013-06-19 09:30:37 +0200 |
commit | 21e38bed98d3d6bc4ae5833f6f609ac8f12d6361 (patch) | |
tree | 059c694e9a587cfe77f30297e7a7fcc7ba11b6c8 /kernel | |
parent | a046a302f0d258dccc4fd22cb341f41bacf0aaba (diff) | |
download | yosys-21e38bed98d3d6bc4ae5833f6f609ac8f12d6361.tar.gz yosys-21e38bed98d3d6bc4ae5833f6f609ac8f12d6361.tar.bz2 yosys-21e38bed98d3d6bc4ae5833f6f609ac8f12d6361.zip |
Added "eval" pass
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/rtlil.cc | 85 | ||||
-rw-r--r-- | kernel/rtlil.h | 1 |
2 files changed, 86 insertions, 0 deletions
diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index dacefa215..a10912868 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -19,6 +19,7 @@ #include "kernel/rtlil.h" #include "kernel/log.h" +#include "frontends/verilog/verilog_frontend.h" #include <assert.h> #include <algorithm> @@ -1062,6 +1063,90 @@ bool RTLIL::SigSpec::match(std::string pattern) const return true; } +static void sigspec_parse_split(std::vector<std::string> &tokens, const std::string &text, char sep) +{ + size_t start = 0, end = 0; + while ((end = text.find(sep, start)) != std::string::npos) { + tokens.push_back(text.substr(start, end - start)); + start = end + 1; + } + tokens.push_back(text.substr(start)); +} + +static int sigspec_parse_get_dummy_line_num() +{ + return 0; +} + +bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str) +{ + std::vector<std::string> tokens; + sigspec_parse_split(tokens, str, ','); + + sig = RTLIL::SigSpec(); + for (auto &tok : tokens) + { + std::string netname = tok; + std::string indices; + + if (netname.size() == 0) + continue; + + if ('0' <= netname[0] && netname[0] <= '9') { + AST::get_line_num = sigspec_parse_get_dummy_line_num; + AST::AstNode *ast = VERILOG_FRONTEND::const2ast(netname); + if (ast == NULL) + return false; + sig.append(RTLIL::Const(ast->bits)); + delete ast; + continue; + } + + if (netname[0] != '$' && netname[0] != '\\') + netname = "\\" + netname; + + if (module->wires.count(netname) == 0) { + size_t indices_pos = netname.size()-1; + if (indices_pos > 2 && netname[indices_pos] == ']') + { + indices_pos--; + while (indices_pos > 0 && ('0' <= netname[indices_pos] && netname[indices_pos] <= '9')) indices_pos--; + if (indices_pos > 0 && netname[indices_pos] == ':') { + indices_pos--; + while (indices_pos > 0 && ('0' <= netname[indices_pos] && netname[indices_pos] <= '9')) indices_pos--; + } + if (indices_pos > 0 && netname[indices_pos] == '[') { + indices = netname.substr(indices_pos); + netname = netname.substr(0, indices_pos); + } + } + } + + if (module->wires.count(netname) == 0) + return false; + + RTLIL::Wire *wire = module->wires.at(netname); + if (!indices.empty()) { + std::vector<std::string> index_tokens; + sigspec_parse_split(index_tokens, indices.substr(1, indices.size()-2), ':'); + if (index_tokens.size() == 1) + sig.append(RTLIL::SigSpec(wire, 1, atoi(index_tokens.at(0).c_str()))); + else { + int a = atoi(index_tokens.at(0).c_str()); + int b = atoi(index_tokens.at(1).c_str()); + if (a > b) { + int tmp = a; + a = b, b = tmp; + } + sig.append(RTLIL::SigSpec(wire, b-a+1, a)); + } + } else + sig.append(wire); + } + + return true; +} + RTLIL::CaseRule::~CaseRule() { for (auto it = switches.begin(); it != switches.end(); it++) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 5ababa7ec..6dde475d1 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -327,6 +327,7 @@ struct RTLIL::SigSpec { std::string as_string() const; RTLIL::Const as_const() const; bool match(std::string pattern) const; + static bool parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str); }; struct RTLIL::CaseRule { |