diff options
Diffstat (limited to 'passes/proc')
| -rw-r--r-- | passes/proc/proc_dlatch.cc | 33 | 
1 files changed, 33 insertions, 0 deletions
diff --git a/passes/proc/proc_dlatch.cc b/passes/proc/proc_dlatch.cc index e7c8a80dd..3ed158f37 100644 --- a/passes/proc/proc_dlatch.cc +++ b/passes/proc/proc_dlatch.cc @@ -37,6 +37,7 @@ struct proc_dlatch_db_t  	dict<Cell*, vector<SigBit>> mux_srcbits;  	dict<SigBit, pair<Cell*, int>> mux_drivers;  	dict<SigBit, int> sigusers; +	dict<SigBit, std::pair<State,SigBit>> initbits;  	proc_dlatch_db_t(Module *module) : module(module), sigmap(module)  	{ @@ -69,9 +70,34 @@ struct proc_dlatch_db_t  		}  		for (auto wire : module->wires()) +		{  			if (wire->port_input)  				for (auto bit : sigmap(wire))  					sigusers[bit]++; +			if (wire->attributes.count(ID::init)) { +				SigSpec wirebits = sigmap(wire); +				Const initval = wire->attributes.at(ID::init); + +				for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++) +				{ +					SigBit bit = wirebits[i]; +					State val = initval[i]; + +					if (val != State::S0 && val != State::S1 && bit.wire != nullptr) +						continue; + +					if (initbits.count(bit)) { +						if (initbits.at(bit).first != val) +							log_error("Conflicting init values for signal %s (%s = %s != %s).\n", +									log_signal(bit), log_signal(SigBit(wire, i)), +									log_signal(val), log_signal(initbits.at(bit).first)); +						continue; +					} + +					initbits[bit] = std::make_pair(val,SigBit(wire,i)); +				} +			} +		}  	}  	bool quickcheck(const SigSpec &haystack, const SigSpec &needle) @@ -393,6 +419,13 @@ void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc)  		else  			log("No latch inferred for signal `%s.%s' from process `%s.%s'.\n",  					db.module->name.c_str(), log_signal(lhs), db.module->name.c_str(), proc->name.c_str()); +		for (auto &bit : lhs) { +			auto it = db.initbits.find(bit); +			if (it != db.initbits.end()) { +				log("Removing init bit %s for non-memory siginal `%s.%s` in process `%s.%s`.\n", log_signal(it->second.first), db.module->name.c_str(), log_signal(bit), db.module->name.c_str(), proc->name.c_str()); +				it->second.second.wire->attributes.at(ID::init)[it->second.second.offset] = State::Sx; +			} +		}  		db.module->connect(lhs, rhs);  		offset += chunk.width;  	}  | 
