mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 19:52:31 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			140 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  *  yosys -- Yosys Open SYnthesis Suite
 | |
|  *
 | |
|  *  Copyright (C) 2020  Marcelina Kościelnicka <mwk@0x04.net>
 | |
|  *
 | |
|  *  Permission to use, copy, modify, and/or distribute this software for any
 | |
|  *  purpose with or without fee is hereby granted, provided that the above
 | |
|  *  copyright notice and this permission notice appear in all copies.
 | |
|  *
 | |
|  *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | |
|  *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | |
|  *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | |
|  *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | |
|  *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | |
|  *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | |
|  *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #ifndef FFINIT_H
 | |
| #define FFINIT_H
 | |
| 
 | |
| #include "kernel/yosys.h"
 | |
| #include "kernel/sigtools.h"
 | |
| 
 | |
| YOSYS_NAMESPACE_BEGIN
 | |
| 
 | |
| struct FfInitVals
 | |
| {
 | |
| 	const SigMapView *sigmap;
 | |
| 	dict<SigBit, std::pair<State,SigBit>> initbits;
 | |
| 
 | |
| 	void set(const SigMapView *sigmap_, RTLIL::Module *module)
 | |
| 	{
 | |
| 		sigmap = sigmap_;
 | |
| 		initbits.clear();
 | |
| 		for (auto wire : module->wires())
 | |
| 		{
 | |
| 			if (wire->attributes.count(ID::init) == 0)
 | |
| 				continue;
 | |
| 
 | |
| 			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));
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	RTLIL::State operator()(RTLIL::SigBit bit) const
 | |
| 	{
 | |
| 		auto it = initbits.find((*sigmap)(bit));
 | |
| 		if (it != initbits.end())
 | |
| 			return it->second.first;
 | |
| 		else
 | |
| 			return State::Sx;
 | |
| 	}
 | |
| 
 | |
| 	RTLIL::Const operator()(const RTLIL::SigSpec &sig) const
 | |
| 	{
 | |
| 		RTLIL::Const::Builder res_bits(GetSize(sig));
 | |
| 		for (auto bit : sig)
 | |
| 			res_bits.push_back((*this)(bit));
 | |
| 		return res_bits.build();
 | |
| 	}
 | |
| 
 | |
| 	void set_init(RTLIL::SigBit bit, RTLIL::State val)
 | |
| 	{
 | |
| 		SigBit mbit = (*sigmap)(bit);
 | |
| 		SigBit abit = bit;
 | |
| 		auto it = initbits.find(mbit);
 | |
| 		if (it != initbits.end())
 | |
| 			abit = it->second.second;
 | |
| 		else if (val == State::Sx)
 | |
| 			return;
 | |
| 		log_assert(abit.wire);
 | |
| 		initbits[mbit] = std::make_pair(val,abit);
 | |
| 		auto it2 = abit.wire->attributes.find(ID::init);
 | |
| 		if (it2 != abit.wire->attributes.end()) {
 | |
| 			it2->second.set(abit.offset, val);
 | |
| 			if (it2->second.is_fully_undef())
 | |
| 				abit.wire->attributes.erase(it2);
 | |
| 		} else if (val != State::Sx) {
 | |
| 			Const cval(State::Sx, GetSize(abit.wire));
 | |
| 			cval.set(abit.offset, val);
 | |
| 			abit.wire->attributes[ID::init] = cval;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	void set_init(const RTLIL::SigSpec &sig, RTLIL::Const val)
 | |
| 	{
 | |
| 		log_assert(GetSize(sig) == GetSize(val));
 | |
| 		for (int i = 0; i < GetSize(sig); i++)
 | |
| 			set_init(sig[i], val[i]);
 | |
| 	}
 | |
| 
 | |
| 	void remove_init(RTLIL::SigBit bit)
 | |
| 	{
 | |
| 		set_init(bit, State::Sx);
 | |
| 	}
 | |
| 
 | |
| 	void remove_init(const RTLIL::SigSpec &sig)
 | |
| 	{
 | |
| 		for (auto bit : sig)
 | |
| 			remove_init(bit);
 | |
| 	}
 | |
| 
 | |
| 	void clear()
 | |
| 	{
 | |
| 		initbits.clear();
 | |
| 	}
 | |
| 
 | |
| 	FfInitVals (const SigMapView *sigmap, RTLIL::Module *module)
 | |
| 	{
 | |
| 		set(sigmap, module);
 | |
| 	}
 | |
| 
 | |
| 	FfInitVals () {}
 | |
| };
 | |
| 
 | |
| 
 | |
| YOSYS_NAMESPACE_END
 | |
| 
 | |
| #endif
 |