diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/celltypes.h | 5 | ||||
| -rw-r--r-- | kernel/rtlil.cc | 81 | ||||
| -rw-r--r-- | kernel/rtlil.h | 65 | ||||
| -rw-r--r-- | kernel/yosys.cc | 6 | ||||
| -rw-r--r-- | kernel/yosys.h | 2 | 
5 files changed, 144 insertions, 15 deletions
diff --git a/kernel/celltypes.h b/kernel/celltypes.h index ae88f4aaf..89df36222 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -85,6 +85,8 @@ struct CellTypes  		setup_internals_eval();  		IdString A = "\\A", B = "\\B", EN = "\\EN", Y = "\\Y"; +		IdString SRC = "\\SRC", DST = "\\DST", DAT = "\\DAT"; +		IdString EN_SRC = "\\EN_SRC", EN_DST = "\\EN_DST";  		setup_type("$tribuf", {A, EN}, {Y}, true); @@ -99,6 +101,9 @@ struct CellTypes  		setup_type("$allconst", pool<RTLIL::IdString>(), {Y}, true);  		setup_type("$allseq", pool<RTLIL::IdString>(), {Y}, true);  		setup_type("$equiv", {A, B}, {Y}, true); +		setup_type("$specify2", {EN, SRC, DST}, pool<RTLIL::IdString>(), true); +		setup_type("$specify3", {EN, SRC, DST, DAT}, pool<RTLIL::IdString>(), true); +		setup_type("$specrule", {EN_SRC, EN_DST, SRC, DST}, pool<RTLIL::IdString>(), true);  	}  	void setup_internals_eval() diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index dd6817873..790ba52a3 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -218,15 +218,19 @@ void RTLIL::AttrObject::set_bool_attribute(RTLIL::IdString id, bool value)  {  	if (value)  		attributes[id] = RTLIL::Const(1); -	else if (attributes.count(id)) -		attributes.erase(id); +	else { +                const auto it = attributes.find(id); +                if (it != attributes.end()) +			attributes.erase(it); +	}  }  bool RTLIL::AttrObject::get_bool_attribute(RTLIL::IdString id) const  { -	if (attributes.count(id) == 0) +	const auto it = attributes.find(id); +	if (it == attributes.end())  		return false; -	return attributes.at(id).as_bool(); +	return it->second.as_bool();  }  void RTLIL::AttrObject::set_strpool_attribute(RTLIL::IdString id, const pool<string> &data) @@ -1194,6 +1198,46 @@ namespace {  				return;  			} +			if (cell->type.in("$specify2", "$specify3")) { +				param_bool("\\FULL"); +				param_bool("\\SRC_DST_PEN"); +				param_bool("\\SRC_DST_POL"); +				param("\\T_RISE_MIN"); +				param("\\T_RISE_TYP"); +				param("\\T_RISE_MAX"); +				param("\\T_FALL_MIN"); +				param("\\T_FALL_TYP"); +				param("\\T_FALL_MAX"); +				port("\\EN", 1); +				port("\\SRC", param("\\SRC_WIDTH")); +				port("\\DST", param("\\DST_WIDTH")); +				if (cell->type == "$specify3") { +					param_bool("\\EDGE_EN"); +					param_bool("\\EDGE_POL"); +					param_bool("\\DAT_DST_PEN"); +					param_bool("\\DAT_DST_POL"); +					port("\\DAT", param("\\DST_WIDTH")); +				} +				check_expected(); +				return; +			} + +			if (cell->type == "$specrule") { +				param("\\TYPE"); +				param_bool("\\SRC_PEN"); +				param_bool("\\SRC_POL"); +				param_bool("\\DST_PEN"); +				param_bool("\\DST_POL"); +				param("\\T_LIMIT"); +				param("\\T_LIMIT2"); +				port("\\SRC_EN", 1); +				port("\\DST_EN", 1); +				port("\\SRC", param("\\SRC_WIDTH")); +				port("\\DST", param("\\DST_WIDTH")); +				check_expected(); +				return; +			} +  			if (cell->type == "$_BUF_")    { check_gate("AY"); return; }  			if (cell->type == "$_NOT_")    { check_gate("AY"); return; }  			if (cell->type == "$_AND_")    { check_gate("ABY"); return; } @@ -1470,7 +1514,10 @@ void RTLIL::Module::add(RTLIL::Cell *cell)  	cell->module = this;  } -namespace { +void RTLIL::Module::remove(const pool<RTLIL::Wire*> &wires) +{ +	log_assert(refcount_wires_ == 0); +  	struct DeleteWireWorker  	{  		RTLIL::Module *module; @@ -1485,17 +1532,29 @@ namespace {  				}  			sig = chunks;  		} -	}; -} -void RTLIL::Module::remove(const pool<RTLIL::Wire*> &wires) -{ -	log_assert(refcount_wires_ == 0); +		void operator()(RTLIL::SigSpec &lhs, RTLIL::SigSpec &rhs) { +			log_assert(GetSize(lhs) == GetSize(rhs)); +			RTLIL::SigSpec new_lhs, new_rhs; +			for (int i = 0; i < GetSize(lhs); i++) { +				RTLIL::SigBit lhs_bit = lhs[i]; +				if (lhs_bit.wire != nullptr && wires_p->count(lhs_bit.wire)) +					continue; +				RTLIL::SigBit rhs_bit = rhs[i]; +				if (rhs_bit.wire != nullptr && wires_p->count(rhs_bit.wire)) +					continue; +				new_lhs.append(lhs_bit); +				new_rhs.append(rhs_bit); +			} +			lhs = new_lhs; +			rhs = new_rhs; +		} +	};  	DeleteWireWorker delete_wire_worker;  	delete_wire_worker.module = this;  	delete_wire_worker.wires_p = &wires; -	rewrite_sigspecs(delete_wire_worker); +	rewrite_sigspecs2(delete_wire_worker);  	for (auto &it : wires) {  		log_assert(wires_.count(it->name) != 0); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 757e0dfa4..6c860f36c 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -50,7 +50,7 @@ namespace RTLIL  		CONST_FLAG_NONE   = 0,  		CONST_FLAG_STRING = 1,  		CONST_FLAG_SIGNED = 2,  // only used for parameters -		CONST_FLAG_REAL   = 4   // unused -- to be used for parameters +		CONST_FLAG_REAL   = 4   // only used for parameters  	};  	struct Const; @@ -524,6 +524,7 @@ struct RTLIL::Const  	Const(const std::vector<RTLIL::State> &bits) : bits(bits) { flags = CONST_FLAG_NONE; }  	Const(const std::vector<bool> &bits);  	Const(const RTLIL::Const &c); +	RTLIL::Const &operator =(const RTLIL::Const &other) = default;  	bool operator <(const RTLIL::Const &other) const;  	bool operator ==(const RTLIL::Const &other) const; @@ -603,6 +604,7 @@ struct RTLIL::SigChunk  	SigChunk(RTLIL::State bit, int width = 1);  	SigChunk(RTLIL::SigBit bit);  	SigChunk(const RTLIL::SigChunk &sigchunk); +	RTLIL::SigChunk &operator =(const RTLIL::SigChunk &other) = default;  	RTLIL::SigChunk extract(int offset, int length) const; @@ -628,6 +630,7 @@ struct RTLIL::SigBit  	SigBit(const RTLIL::SigChunk &chunk, int index);  	SigBit(const RTLIL::SigSpec &sig);  	SigBit(const RTLIL::SigBit &sigbit); +	RTLIL::SigBit &operator =(const RTLIL::SigBit &other) = default;  	bool operator <(const RTLIL::SigBit &other) const;  	bool operator ==(const RTLIL::SigBit &other) const; @@ -1004,6 +1007,7 @@ public:  	void fixup_ports();  	template<typename T> void rewrite_sigspecs(T &functor); +	template<typename T> void rewrite_sigspecs2(T &functor);  	void cloneInto(RTLIL::Module *new_mod) const;  	virtual RTLIL::Module *clone() const; @@ -1309,6 +1313,7 @@ public:  	}  	template<typename T> void rewrite_sigspecs(T &functor); +	template<typename T> void rewrite_sigspecs2(T &functor);  #ifdef WITH_PYTHON  	static std::map<unsigned int, RTLIL::Cell*> *get_all_cells(void); @@ -1327,6 +1332,7 @@ struct RTLIL::CaseRule  	bool empty() const;  	template<typename T> void rewrite_sigspecs(T &functor); +	template<typename T> void rewrite_sigspecs2(T &functor);  	RTLIL::CaseRule *clone() const;  }; @@ -1340,6 +1346,7 @@ struct RTLIL::SwitchRule : public RTLIL::AttrObject  	bool empty() const;  	template<typename T> void rewrite_sigspecs(T &functor); +	template<typename T> void rewrite_sigspecs2(T &functor);  	RTLIL::SwitchRule *clone() const;  }; @@ -1350,6 +1357,7 @@ struct RTLIL::SyncRule  	std::vector<RTLIL::SigSig> actions;  	template<typename T> void rewrite_sigspecs(T &functor); +	template<typename T> void rewrite_sigspecs2(T &functor);  	RTLIL::SyncRule *clone() const;  }; @@ -1362,6 +1370,7 @@ struct RTLIL::Process : public RTLIL::AttrObject  	~Process();  	template<typename T> void rewrite_sigspecs(T &functor); +	template<typename T> void rewrite_sigspecs2(T &functor);  	RTLIL::Process *clone() const;  }; @@ -1424,12 +1433,30 @@ void RTLIL::Module::rewrite_sigspecs(T &functor)  }  template<typename T> +void RTLIL::Module::rewrite_sigspecs2(T &functor) +{ +	for (auto &it : cells_) +		it.second->rewrite_sigspecs2(functor); +	for (auto &it : processes) +		it.second->rewrite_sigspecs2(functor); +	for (auto &it : connections_) { +		functor(it.first, it.second); +	} +} + +template<typename T>  void RTLIL::Cell::rewrite_sigspecs(T &functor) {  	for (auto &it : connections_)  		functor(it.second);  }  template<typename T> +void RTLIL::Cell::rewrite_sigspecs2(T &functor) { +	for (auto &it : connections_) +		functor(it.second); +} + +template<typename T>  void RTLIL::CaseRule::rewrite_sigspecs(T &functor) {  	for (auto &it : compare)  		functor(it); @@ -1442,6 +1469,17 @@ void RTLIL::CaseRule::rewrite_sigspecs(T &functor) {  }  template<typename T> +void RTLIL::CaseRule::rewrite_sigspecs2(T &functor) { +	for (auto &it : compare) +		functor(it); +	for (auto &it : actions) { +		functor(it.first, it.second); +	} +	for (auto it : switches) +		it->rewrite_sigspecs2(functor); +} + +template<typename T>  void RTLIL::SwitchRule::rewrite_sigspecs(T &functor)  {  	functor(signal); @@ -1450,6 +1488,14 @@ void RTLIL::SwitchRule::rewrite_sigspecs(T &functor)  }  template<typename T> +void RTLIL::SwitchRule::rewrite_sigspecs2(T &functor) +{ +	functor(signal); +	for (auto it : cases) +		it->rewrite_sigspecs2(functor); +} + +template<typename T>  void RTLIL::SyncRule::rewrite_sigspecs(T &functor)  {  	functor(signal); @@ -1460,6 +1506,15 @@ void RTLIL::SyncRule::rewrite_sigspecs(T &functor)  }  template<typename T> +void RTLIL::SyncRule::rewrite_sigspecs2(T &functor) +{ +	functor(signal); +	for (auto &it : actions) { +		functor(it.first, it.second); +	} +} + +template<typename T>  void RTLIL::Process::rewrite_sigspecs(T &functor)  {  	root_case.rewrite_sigspecs(functor); @@ -1467,6 +1522,14 @@ void RTLIL::Process::rewrite_sigspecs(T &functor)  		it->rewrite_sigspecs(functor);  } +template<typename T> +void RTLIL::Process::rewrite_sigspecs2(T &functor) +{ +	root_case.rewrite_sigspecs2(functor); +	for (auto it : syncs) +		it->rewrite_sigspecs2(functor); +} +  YOSYS_NAMESPACE_END  #endif diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 20d972150..377572fc2 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -151,14 +151,16 @@ void yosys_banner()  int ceil_log2(int x)  { +#if defined(__GNUC__) +        return x > 1 ? (8*sizeof(int)) - __builtin_clz(x-1) : 0; +#else  	if (x <= 0)  		return 0; -  	for (int i = 0; i < 32; i++)  		if (((x-1) >> i) == 0)  			return i; -  	log_abort(); +#endif  }  std::string stringf(const char *fmt, ...) diff --git a/kernel/yosys.h b/kernel/yosys.h index 82eb069ab..c7b671724 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -244,7 +244,7 @@ extern bool memhasher_active;  inline void memhasher() { if (memhasher_active) memhasher_do(); }  void yosys_banner(); -int ceil_log2(int x); +int ceil_log2(int x) YS_ATTRIBUTE(const);  std::string stringf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 1, 2));  std::string vstringf(const char *fmt, va_list ap);  int readsome(std::istream &f, char *s, int n);  | 
