diff options
author | Clifford Wolf <clifford@clifford.at> | 2013-03-31 11:51:12 +0200 |
---|---|---|
committer | Clifford Wolf <clifford@clifford.at> | 2013-03-31 11:51:12 +0200 |
commit | f1a2fd966f62df072d2c43573fb71a1369857523 (patch) | |
tree | a86a810fe0b12f862b3d4b721f5a3e198bd8247b /frontends/ast/genrtlil.cc | |
parent | 161565be104fd0c7b7c4224bd23e9502625e041a (diff) | |
download | yosys-f1a2fd966f62df072d2c43573fb71a1369857523.tar.gz yosys-f1a2fd966f62df072d2c43573fb71a1369857523.tar.bz2 yosys-f1a2fd966f62df072d2c43573fb71a1369857523.zip |
Now only use value from "initial" when no matching "always" block is found
Diffstat (limited to 'frontends/ast/genrtlil.cc')
-rw-r--r-- | frontends/ast/genrtlil.cc | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 2f5370fe8..36074be34 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -183,7 +183,9 @@ struct AST_INTERNAL::ProcessGenerator { // input and output structures AstNode *always; + RTLIL::SigSpec skipSyncSignals; RTLIL::Process *proc; + const RTLIL::SigSpec &outputSignals; // This always points to the RTLIL::CaseRule beeing filled at the moment RTLIL::CaseRule *current_case; @@ -205,7 +207,7 @@ struct AST_INTERNAL::ProcessGenerator // map helps generating nice numbered names for all this temporary signals. std::map<RTLIL::Wire*, int> new_temp_count; - ProcessGenerator(AstNode *always) : always(always) + ProcessGenerator(AstNode *always, RTLIL::SigSpec skipSyncSignalsArg = RTLIL::SigSpec()) : always(always), skipSyncSignals(skipSyncSignalsArg), outputSignals(subst_lvalue_from) { // generate process and simple root case proc = new RTLIL::Process; @@ -351,8 +353,10 @@ struct AST_INTERNAL::ProcessGenerator // add an assignment (aka "action") but split it up in chunks. this way huge assignments // are avoided and the generated $mux cells have a more "natural" size. - void addChunkActions(std::vector<RTLIL::SigSig> &actions, RTLIL::SigSpec lvalue, RTLIL::SigSpec rvalue, bool noSyncToUndef = false) + void addChunkActions(std::vector<RTLIL::SigSig> &actions, RTLIL::SigSpec lvalue, RTLIL::SigSpec rvalue, bool inSyncRule = false) { + if (inSyncRule) + lvalue.remove2(skipSyncSignals, &rvalue); assert(lvalue.width == rvalue.width); lvalue.optimize(); rvalue.optimize(); @@ -361,7 +365,7 @@ struct AST_INTERNAL::ProcessGenerator for (size_t i = 0; i < lvalue.chunks.size(); i++) { RTLIL::SigSpec lhs = lvalue.chunks[i]; RTLIL::SigSpec rhs = rvalue.extract(offset, lvalue.chunks[i].width); - if (noSyncToUndef && lvalue.chunks[i].wire && lvalue.chunks[i].wire->attributes.count("\\nosync")) + if (inSyncRule && lvalue.chunks[i].wire && lvalue.chunks[i].wire->attributes.count("\\nosync")) rhs = RTLIL::SigSpec(RTLIL::State::Sx, rhs.width); actions.push_back(RTLIL::SigSig(lhs, rhs)); offset += lhs.width; @@ -1014,10 +1018,16 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint) break; // use ProcessGenerator for always blocks - case AST_ALWAYS: - case AST_INITIAL: { + case AST_ALWAYS: { AstNode *always = this->clone(); ProcessGenerator generator(always); + ignoreThisSignalsInInitial.append(generator.outputSignals); + delete always; + } break; + + case AST_INITIAL: { + AstNode *always = this->clone(); + ProcessGenerator generator(always, ignoreThisSignalsInInitial); delete always; } break; |