mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +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
 |