aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ginput
Commit message (Expand)AuthorAgeFilesLines
* Replace all inline definitions with GFXINLINEinmarket2015-10-235-16/+16
* Adding first version of STM32F7 discovery touch driverJoel Bodenmann2015-07-221-35/+21
* Adding FT5336 touch driver. Not tested yet.Joel Bodenmann2015-07-214-0/+422
* Fix in FT5x06 touch driverJoel Bodenmann2015-07-101-1/+1
* Revert "Fix in FT5x06 touch driver"Joel Bodenmann2015-07-101-1/+1
* Fix in FT5x06 touch driverJoel Bodenmann2015-07-101-1/+1
* Fix compiler warningsinmarket2015-02-283-0/+3
* Fix self calibration for touch devices FT5x06 and STMPE610inmarket2015-02-282-7/+23
* Replace missing breaks.inmarket2015-02-251-0/+2
* Fix to STMPE811 touch driver to fix self-calibration in other orientationsinmarket2015-02-231-2/+15
* Add touch driver STMPE610 by lliypukinmarket2015-02-235-0/+411
* Big file rename to reduce problems with brain-dead IDE's that don't handle pr...inmarket2015-01-217-7/+7
* Fixing wrong define in ADS7843 driverJoel Bodenmann2015-01-021-1/+1
* Spacing, comments and spelling mistakesinmarket2014-11-151-12/+4
* Fixing MAX11802 driver (by user steved)Joel Bodenmann2014-11-143-20/+32
* Some MAX11802 fixes.inmarket2014-11-102-11/+18
* MCU touch template fixinmarket2014-11-101-1/+1
* Update default settings in the board file for the ADS7843 touchinmarket2014-11-101-6/+6
* Update to MAX11802 touch driver. To be tested.inmarket2014-11-102-67/+75
* Added MAX11802 driver - NOT WORKING YET - read_xyz() not ported yetJoel Bodenmann2014-11-094-0/+276
* Fix the newmouse STMPE811 driver.inmarket2014-11-074-79/+178
* Allow a mouse driver to not return any results when it is polled.inmarket2014-11-072-2/+4
* small fixJoel Bodenmann2014-10-281-2/+2
* Bug fix newmouse SMTPE811 touch driverinmarket2014-10-281-1/+1
* STMPE811 fixes - still not workingJoel Bodenmann2014-10-131-3/+0
* Fixing STMPE811 driverJoel Bodenmann2014-10-131-5/+5
* Port SMTPE811 mouse driver to newmouse (and supported boards)inmarket2014-10-136-188/+223
* Remove unnecessary fileinmarket2014-10-131-18/+0
* Update newmouse driver makefilesinmarket2014-10-132-7/+1
* Convert FT5x06 mouse driver to newmouse (untested)inmarket2014-10-135-136/+166
* Add GMouse parameter to ADS7843 mouse driver to enable multiple drivers.inmarket2014-10-132-22/+19
* Tidy up MCU mouse definesinmarket2014-10-132-30/+19
* fixing ADS7843 driver - testedJoel Bodenmann2014-10-111-5/+14
* Added missing defines to board template of ADS7843Joel Bodenmann2014-10-111-0/+7
* ADS7843 porting - not tested yet!Joel Bodenmann2014-10-115-117/+79
* Board File can now request extra data bytes in the GMouse structure.inmarket2014-10-121-1/+6
* New newmouse driver for MCU touchinmarket2014-10-077-146/+107
* Rename all driver makefiles to driver.mkinmarket2014-08-226-20/+20
* Removed the doxygen inside of every driver as doxygen is only meant for highl...Joel Bodenmann2014-03-2820-464/+1
* Integrate the include files with each module. Simplifies structure of code.inmarket2014-02-196-12/+10
* Update template files for the MCU touch driver.inmarket2013-11-252-14/+43
* Rewrite of the MCU driver. This is now much more reliable.inmarket2013-11-241-40/+40
* Clean up the driver directory structure by moving all board specific files in...inmarket2013-10-288-819/+1
* Create uGFX board directories which include example Makefiles.inmarket2013-10-285-108/+51
* fixed license headersJoel Bodenmann2013-07-2128-28/+28
* doxygen updatesJoel Bodenmann2013-07-211-1/+1
* cleaned up board file messJoel Bodenmann2013-07-2111-288/+208
* doxygen fixJoel Bodenmann2013-06-282-2/+2
* quick board file fixJoel Bodenmann2013-06-241-1/+1
* one more typo fix...Joel Bodenmann2013-06-221-1/+1
Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *  
 *  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 RTLIL_H
#define RTLIL_H

#include <map>
#include <set>
#include <vector>
#include <string>
#include <assert.h>

std::string stringf(const char *fmt, ...);

namespace RTLIL
{
	enum State {
		S0 = 0,
		S1 = 1,
		Sx = 2, // undefined value or conflict
		Sz = 3, // high-impedance / not-connected
		Sa = 4, // don't care (used only in cases)
		Sm = 5  // marker (used internally by some passes)
	};
	enum SyncType {
		ST0 = 0, // level sensitive: 0
		ST1 = 1, // level sensitive: 1
		STp = 2, // edge sensitive: posedge
		STn = 3, // edge sensitive: negedge
		STe = 4, // edge sensitive: both edges
		STa = 5, // always active
		STi = 6  // init
	};

	extern int autoidx;

	struct Const;
	struct Selection;
	struct Design;
	struct Module;
	struct Wire;
	struct Memory;
	struct Cell;
	struct SigChunk;
	struct SigBit;
	struct SigSpec;
	struct CaseRule;
	struct SwitchRule;
	struct SyncRule;
	struct Process;

	typedef std::pair<SigSpec, SigSpec> SigSig;

#ifdef NDEBUG
	typedef std::string IdString;
#else
	struct IdString : public std::string {
		IdString() { }
		IdString(std::string str) : std::string(str) {
			check();
		}
		IdString(const char *s) : std::string(s) {
			check();
		}
		IdString &operator=(const std::string &str) {
			std::string::operator=(str);
			check();
			return *this;
		}
		IdString &operator=(const char *s) {
			std::string::operator=(s);
			check();
			return *this;
		}
		bool operator<(const IdString &rhs) {
			check(), rhs.check();
			return std::string(*this) < std::string(rhs);
		}
		void check() const {
			assert(empty() || (size() >= 2 && (at(0) == '$' || at(0) == '\\')));
		}
	};
#endif

	static IdString escape_id(std::string str) __attribute__((unused));
	static IdString escape_id(std::string str) {
		if (str.size() > 0 && str[0] != '\\' && str[0] != '$')
			return "\\" + str;
		return str;
	}

	static std::string unescape_id(std::string str) __attribute__((unused));
	static std::string unescape_id(std::string str) {
		if (str.size() > 1 && str[0] == '\\' && str[1] != '$')
			return str.substr(1);
		return str;
	}

	static const char *id2cstr(std::string str) __attribute__((unused));
	static const char *id2cstr(std::string str) {
		if (str.size() > 1 && str[0] == '\\' && str[1] != '$')
			return str.c_str() + 1;
		return str.c_str();
	}

	static IdString new_id(std::string file, int line, std::string func) __attribute__((unused));
	static IdString new_id(std::string file, int line, std::string func) {
		std::string str = "$auto$";
		size_t pos = file.find_last_of('/');
		str += pos != std::string::npos ? file.substr(pos+1) : file;
		str += stringf(":%d:%s$%d", line, func.c_str(), autoidx++);
		return str;
	}

#define NEW_ID \
	RTLIL::new_id(__FILE__, __LINE__, __FUNCTION__)

#define NEW_WIRE(_mod, _width) \
	(_mod)->new_wire(_width, NEW_ID)

	template <typename T> struct sort_by_name {
		bool operator()(T *a, T *b) const {
			return a->name < b->name;
		}
	};

	// see calc.cc for the implementation of this functions
	RTLIL::Const const_not         (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_and         (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_or          (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_xor         (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_xnor        (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);

	RTLIL::Const const_reduce_and  (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_reduce_or   (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_reduce_xor  (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_reduce_xnor (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_reduce_bool (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);

	RTLIL::Const const_logic_not   (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_logic_and   (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_logic_or    (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);

	RTLIL::Const const_shl         (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_shr         (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_sshl        (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_sshr        (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);

	RTLIL::Const const_lt          (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_le          (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_eq          (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_ne          (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_ge          (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_gt          (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);

	RTLIL::Const const_add         (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_sub         (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_mul         (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_div         (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_mod         (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_pow         (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);

	RTLIL::Const const_pos         (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
	RTLIL::Const const_neg         (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
};

struct RTLIL::Const {
	std::string str;
	std::vector<RTLIL::State> bits;
	Const(std::string str = std::string());
	Const(int val, int width = 32);
	Const(RTLIL::State bit, int width = 1);
	Const(std::vector<RTLIL::State> bits) : bits(bits) { };
	bool operator <(const RTLIL::Const &other) const;
	bool operator ==(const RTLIL::Const &other) const;
	bool operator !=(const RTLIL::Const &other) const;
	bool as_bool() const;
	int as_int() const;
	std::string as_string() const;
};

struct RTLIL::Selection {
	bool full_selection;
	std::set<RTLIL::IdString> selected_modules;
	std::map<RTLIL::IdString, std::set<RTLIL::IdString>> selected_members;
	Selection(bool full = true) : full_selection(full) { }
	bool selected_module(RTLIL::IdString mod_name) const;
	bool selected_whole_module(RTLIL::IdString mod_name) const;
	bool selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name) const;
	void optimize(RTLIL::Design *design);
	template<typename T1, typename T2> void select(T1 *module, T2 *member) {
		if (!full_selection && selected_modules.count(module->name) == 0)
			selected_members[module->name].insert(member->name);
	}
};

struct RTLIL::Design {
	std::map<RTLIL::IdString, RTLIL::Module*> modules;
	std::vector<RTLIL::Selection> selection_stack;
	std::map<RTLIL::IdString, RTLIL::Selection> selection_vars;
	std::string selected_active_module;
	~Design();
	void check();
	void optimize();
	bool selected_module(RTLIL::IdString mod_name) const;
	bool selected_whole_module(RTLIL::IdString mod_name) const;
	bool selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name) const;
	bool full_selection() const {
		return selection_stack.back().full_selection;
	}
	template<typename T1> bool selected(T1 *module) const {
		return selected_module(module->name);
	}
	template<typename T1, typename T2> bool selected(T1 *module, T2 *member) const {
		return selected_member(module->name, member->name);
	}
	template<typename T1, typename T2> void select(T1 *module, T2 *member) {
		if (selection_stack.size() > 0) {
			RTLIL::Selection &sel = selection_stack.back();
			sel.select(module, member);
		}
	}
};

#define RTLIL_ATTRIBUTE_MEMBERS                                \
	std::map<RTLIL::IdString, RTLIL::Const> attributes;    \
	void set_bool_attribute(RTLIL::IdString id) {          \
		attributes[id] = RTLIL::Const(1);              \
	}                                                      \
	bool get_bool_attribute(RTLIL::IdString id) const {    \
		if (attributes.count(id) == 0)                 \
			return false;                          \
		return attributes.at(id).as_bool();            \
	}

struct RTLIL::Module {
	RTLIL::IdString name;
	std::map<RTLIL::IdString, RTLIL::Wire*> wires;
	std::map<RTLIL::IdString, RTLIL::Memory*> memories;
	std::map<RTLIL::IdString, RTLIL::Cell*> cells;
	std::map<RTLIL::IdString, RTLIL::Process*> processes;
	std::vector<RTLIL::SigSig> connections;
	RTLIL_ATTRIBUTE_MEMBERS
	virtual ~Module();
	virtual RTLIL::IdString derive(RTLIL::Design *design, std::map<RTLIL::IdString, RTLIL::Const> parameters);
	virtual void update_auto_wires(std::map<RTLIL::IdString, int> auto_sizes);
	virtual size_t count_id(RTLIL::IdString id);
	virtual void check();
	virtual void optimize();
	RTLIL::Wire *new_wire(int width, RTLIL::IdString name);
	void add(RTLIL::Wire *wire);
	void add(RTLIL::Cell *cell);
	void fixup_ports();

	template<typename T> void rewrite_sigspecs(T functor);
	void cloneInto(RTLIL::Module *new_mod) const;
	virtual RTLIL::Module *clone() const;

};

struct RTLIL::Wire {
	RTLIL::IdString name;
	int width, start_offset, port_id;
	bool port_input, port_output, auto_width;
	RTLIL_ATTRIBUTE_MEMBERS
	Wire();
};

struct RTLIL::Memory {
	RTLIL::IdString name;
	int width, start_offset, size;
	RTLIL_ATTRIBUTE_MEMBERS
	Memory();
};

struct RTLIL::Cell {
	RTLIL::IdString name;
	RTLIL::IdString type;
	std::map<RTLIL::IdString, RTLIL::SigSpec> connections;
	std::map<RTLIL::IdString, RTLIL::Const> parameters;
	RTLIL_ATTRIBUTE_MEMBERS
	void optimize();

	template<typename T> void rewrite_sigspecs(T functor);
};

struct RTLIL::SigChunk {
	RTLIL::Wire *wire;
	RTLIL::Const data; // only used if wire == NULL, LSB at index 0
	int width, offset;
	SigChunk();
	SigChunk(const RTLIL::Const &data);
	SigChunk(RTLIL::Wire *wire, int width, int offset);
	SigChunk(const std::string &str);
	SigChunk(int val, int width = 32);
	SigChunk(RTLIL::State bit, int width = 1);
	SigChunk(RTLIL::SigBit bit);
	RTLIL::SigChunk extract(int offset, int length) const;
	bool operator <(const RTLIL::SigChunk &other) const;
	bool operator ==(const RTLIL::SigChunk &other) const;
	bool operator !=(const RTLIL::SigChunk &other) const;
	static bool compare(const RTLIL::SigChunk &a, const RTLIL::SigChunk &b);
};

struct RTLIL::SigBit {
	RTLIL::Wire *wire;
	RTLIL::State data;
	int offset;
	SigBit() : wire(NULL), data(RTLIL::State::S0), offset(0) { }
	SigBit(RTLIL::State bit) : wire(NULL), data(bit), offset(0) { }
	SigBit(RTLIL::Wire *wire) : wire(wire), data(RTLIL::State::S0), offset(0) { assert(!wire || wire->width == 1); }
	SigBit(RTLIL::Wire *wire, int offset) : wire(wire), data(RTLIL::State::S0), offset(offset) { }
	SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire), data(chunk.wire ? RTLIL::State::S0 : chunk.data.bits[0]), offset(chunk.offset) { assert(chunk.width == 1); }
	SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire), data(chunk.wire ? RTLIL::State::S0 : chunk.data.bits[index]), offset(chunk.wire ? chunk.offset + index : 0) { }
	SigBit(const RTLIL::SigSpec &sig);
	bool operator <(const RTLIL::SigBit &other) const {
		return (wire != other.wire) ? (wire < other.wire) : wire ? (offset < other.offset) : (data < other.data);
	}
	bool operator ==(const RTLIL::SigBit &other) const {
		return (wire == other.wire) && (wire ? (offset == other.offset) : (data == other.data));
	}
	bool operator !=(const RTLIL::SigBit &other) const {
		return (wire != other.wire) || (wire ? (offset != other.offset) : (data != other.data));
	}
};

struct RTLIL::SigSpec {
	std::vector<RTLIL::SigChunk> chunks; // LSB at index 0
	int width;
	SigSpec();
	SigSpec(const RTLIL::Const &data);
	SigSpec(const RTLIL::SigChunk &chunk);
	SigSpec(RTLIL::Wire *wire, int width = -1, int offset = 0);
	SigSpec(const std::string &str);
	SigSpec(int val, int width = 32);
	SigSpec(RTLIL::State bit, int width = 1);
	SigSpec(RTLIL::SigBit bit, int width = 1);
	SigSpec(std::vector<RTLIL::SigBit> bits);
	void expand();
	void optimize();
	void sort();
	void sort_and_unify();
	void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with);
	void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const;
	void remove(const RTLIL::SigSpec &pattern);
	void remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) const;
	void remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other);
	RTLIL::SigSpec extract(RTLIL::SigSpec pattern, RTLIL::SigSpec *other = NULL) const;
	void replace(int offset, const RTLIL::SigSpec &with);
	void remove_const();
	void remove(int offset, int length);
	RTLIL::SigSpec extract(int offset, int length) const;
	void append(const RTLIL::SigSpec &signal);
	void append_bit(const RTLIL::SigBit &bit);
	bool combine(RTLIL::SigSpec signal, RTLIL::State freeState = RTLIL::State::Sz, bool override = false);
	void extend(int width, bool is_signed = false);
	void extend_u0(int width, bool is_signed = false);
	void check() const;
	bool operator <(const RTLIL::SigSpec &other) const;
	bool operator ==(const RTLIL::SigSpec &other) const;
	bool operator !=(const RTLIL::SigSpec &other) const;
	bool is_fully_const() const;
	bool is_fully_def() const;
	bool is_fully_undef() const;
	bool has_marked_bits() const;
	bool as_bool() const;
	int as_int() const;
	std::string as_string() const;
	RTLIL::Const as_const() const;
	bool match(std::string pattern) const;
	std::set<RTLIL::SigBit> to_sigbit_set() const;
	std::vector<RTLIL::SigBit> to_sigbit_vector() const;
	static bool parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str);
	static bool parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str);
};

inline RTLIL::SigBit::SigBit(const RTLIL::SigSpec &sig) {
	assert(sig.width == 1 && sig.chunks.size() == 1);
	*this = SigBit(sig.chunks[0]);
}

struct RTLIL::CaseRule {
	std::vector<RTLIL::SigSpec> compare;
	std::vector<RTLIL::SigSig> actions;
	std::vector<RTLIL::SwitchRule*> switches;
	~CaseRule();
	void optimize();

	template<typename T> void rewrite_sigspecs(T functor);
	RTLIL::CaseRule *clone() const;
};

struct RTLIL::SwitchRule {
	RTLIL::SigSpec signal;
	RTLIL_ATTRIBUTE_MEMBERS
	std::vector<RTLIL::CaseRule*> cases;
	~SwitchRule();
	void optimize();

	template<typename T> void rewrite_sigspecs(T functor);
	RTLIL::SwitchRule *clone() const;
};

struct RTLIL::SyncRule {
	RTLIL::SyncType type;
	RTLIL::SigSpec signal;
	std::vector<RTLIL::SigSig> actions;
	void optimize();

	template<typename T> void rewrite_sigspecs(T functor);
	RTLIL::SyncRule *clone() const;
};

struct RTLIL::Process {
	RTLIL::IdString name;
	RTLIL_ATTRIBUTE_MEMBERS
	RTLIL::CaseRule root_case;
	std::vector<RTLIL::SyncRule*> syncs;
	~Process();
	void optimize();

	template<typename T> void rewrite_sigspecs(T functor);
	RTLIL::Process *clone() const;
};

template<typename T>
void RTLIL::Module::rewrite_sigspecs(T functor)
{
	for (auto &it : cells)
		it.second->rewrite_sigspecs(functor);
	for (auto &it : processes)
		it.second->rewrite_sigspecs(functor);
	for (auto &it : connections) {
		functor(it.first);
		functor(it.second);
	}
}

template<typename T>
void RTLIL::Cell::rewrite_sigspecs(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);
	for (auto &it : actions) {
		functor(it.first);
		functor(it.second);
	}
	for (auto it : switches)
		it->rewrite_sigspecs(functor);
}

template<typename T>
void RTLIL::SwitchRule::rewrite_sigspecs(T functor)
{
	functor(signal);
	for (auto it : cases)
		it->rewrite_sigspecs(functor);
}

template<typename T>
void RTLIL::SyncRule::rewrite_sigspecs(T functor)
{
	functor(signal);
	for (auto &it : actions) {
		functor(it.first);
		functor(it.second);
	}
}

template<typename T>
void RTLIL::Process::rewrite_sigspecs(T functor)
{
	root_case.rewrite_sigspecs(functor);
	for (auto it : syncs)
		it->rewrite_sigspecs(functor);
}

#endif