From 21e38bed98d3d6bc4ae5833f6f609ac8f12d6361 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 19 Jun 2013 09:30:37 +0200 Subject: Added "eval" pass --- kernel/rtlil.cc | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/rtlil.h | 1 + 2 files changed, 86 insertions(+) (limited to 'kernel') diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index dacefa21..a1091286 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 #include @@ -1062,6 +1063,90 @@ bool RTLIL::SigSpec::match(std::string pattern) const return true; } +static void sigspec_parse_split(std::vector &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 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 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 5ababa7e..6dde475d 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 { -- cgit v1.2.3