mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	Merge pull request #905 from christian-krieg/feature/python_bindings
Feature/python bindings
This commit is contained in:
		
						commit
						99d5435650
					
				
					 15 changed files with 2472 additions and 10 deletions
				
			
		
							
								
								
									
										20
									
								
								.travis.yml
									
										
									
									
									
								
							
							
						
						
									
										20
									
								
								.travis.yml
									
										
									
									
									
								
							|  | @ -32,6 +32,10 @@ matrix: | |||
|             - xdot | ||||
|             - pkg-config | ||||
|             - python | ||||
|             - python3 | ||||
|             - libboost-system-dev | ||||
|             - libboost-python-dev | ||||
|             - libboost-filesystem-dev | ||||
|       env: | ||||
|         - MATRIX_EVAL="CONFIG=gcc && CC=gcc-4.8 && CXX=g++-4.8" | ||||
| 
 | ||||
|  | @ -56,6 +60,10 @@ matrix: | |||
|             - xdot | ||||
|             - pkg-config | ||||
|             - python | ||||
|             - python3 | ||||
|             - libboost-system-dev | ||||
|             - libboost-python-dev | ||||
|             - libboost-filesystem-dev | ||||
|       env: | ||||
|         - MATRIX_EVAL="CONFIG=gcc && CC=gcc-6 && CXX=g++-6" | ||||
| 
 | ||||
|  | @ -80,6 +88,10 @@ matrix: | |||
|             - xdot | ||||
|             - pkg-config | ||||
|             - python | ||||
|             - python3 | ||||
|             - libboost-system-dev | ||||
|             - libboost-python-dev | ||||
|             - libboost-filesystem-dev | ||||
|       env: | ||||
|         - MATRIX_EVAL="CONFIG=gcc && CC=gcc-7 && CXX=g++-7" | ||||
| 
 | ||||
|  | @ -105,6 +117,10 @@ matrix: | |||
|             - xdot | ||||
|             - pkg-config | ||||
|             - python | ||||
|             - python3 | ||||
|             - libboost-system-dev | ||||
|             - libboost-python-dev | ||||
|             - libboost-filesystem-dev | ||||
|       env: | ||||
|         - MATRIX_EVAL="CONFIG=clang && CC=clang-3.8 && CXX=clang++-3.8" | ||||
| 
 | ||||
|  | @ -129,6 +145,10 @@ matrix: | |||
|             - xdot | ||||
|             - pkg-config | ||||
|             - python | ||||
|             - python3 | ||||
|             - libboost-system-dev | ||||
|             - libboost-python-dev | ||||
|             - libboost-filesystem-dev | ||||
|       env: | ||||
|         - MATRIX_EVAL="CONFIG=clang && CC=clang-5.0 && CXX=clang++-5.0" | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										59
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										59
									
								
								Makefile
									
										
									
									
									
								
							|  | @ -16,9 +16,17 @@ ENABLE_READLINE := 1 | |||
| ENABLE_EDITLINE := 0 | ||||
| ENABLE_VERIFIC := 0 | ||||
| ENABLE_COVER := 1 | ||||
| ENABLE_LIBYOSYS := 0 | ||||
| ENABLE_LIBYOSYS := 1 | ||||
| ENABLE_PROTOBUF := 0 | ||||
| 
 | ||||
| # python wrappers
 | ||||
| ENABLE_PYOSYS := 1 | ||||
| PYTHON_VERSION_TESTCODE := "import sys;t='{v[0]}.{v[1]}'.format(v=list(sys.version_info[:2]));print(t)" | ||||
| PYTHON_EXECUTABLE := $(shell if python3 -c ""; then echo "python3"; else echo "python"; fi) | ||||
| PYTHON_VERSION := $(shell $(PYTHON_EXECUTABLE) -c ""$(PYTHON_VERSION_TESTCODE)"") | ||||
| PYTHON_MAJOR_VERSION := $(shell echo $(PYTHON_VERSION) | cut -f1 -d.) | ||||
| PYTHON_DESTDIR := `$(PYTHON_EXECUTABLE)-config --prefix`/lib/python$(PYTHON_VERSION)/dist-packages | ||||
| 
 | ||||
| # other configuration flags
 | ||||
| ENABLE_GCOV := 0 | ||||
| ENABLE_GPROF := 0 | ||||
|  | @ -261,6 +269,34 @@ ifeq ($(ENABLE_LIBYOSYS),1) | |||
| TARGETS += libyosys.so | ||||
| endif | ||||
| 
 | ||||
| ifeq ($(ENABLE_PYOSYS),1) | ||||
| 
 | ||||
| #Detect name of boost_python library. Some distros usbe boost_python-py<version>, other boost_python<version>, some only use the major version number, some a concatenation of major and minor version numbers
 | ||||
| BOOST_PYTHON_LIB ?= $(shell \
 | ||||
| 	if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null `$(PYTHON_EXECUTABLE)-config --libs` -lboost_python-py$(subst .,,$(PYTHON_VERSION)) - > /dev/null 2>&1;        then echo "-lboost_python-py$(subst .,,$(PYTHON_VERSION))";       else \
 | ||||
| 	if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null `$(PYTHON_EXECUTABLE)-config --libs` -lboost_python-py$(subst .,,$(PYTHON_MAJOR_VERSION)) - > /dev/null 2>&1;  then echo "-lboost_python-py$(subst .,,$(PYTHON_MAJOR_VERSION))"; else \
 | ||||
| 	if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null `$(PYTHON_EXECUTABLE)-config --libs` -lboost_python$(subst .,,$(PYTHON_VERSION)) - > /dev/null 2>&1;           then echo "-lboost_python$(subst .,,$(PYTHON_VERSION))";          else \
 | ||||
| 	if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null `$(PYTHON_EXECUTABLE)-config --libs` -lboost_python$(subst .,,$(PYTHON_MAJOR_VERSION)) - > /dev/null 2>&1;     then echo "-lboost_python$(subst .,,$(PYTHON_MAJOR_VERSION))";    else \
 | ||||
|                                                                                                                                                                                         echo ""; fi; fi; fi; fi;) | ||||
| 
 | ||||
| ifeq ($(BOOST_PYTHON_LIB),) | ||||
| $(error BOOST_PYTHON_LIB could not be detected. Please define manualy) | ||||
| endif | ||||
| 
 | ||||
| ifeq ($(PYTHON_MAJOR_VERSION),3) | ||||
| LDLIBS += `$(PYTHON_EXECUTABLE)-config --libs` $(BOOST_PYTHON_LIB) -lboost_system -lboost_filesystem | ||||
| CXXFLAGS += `$(PYTHON_EXECUTABLE)-config --includes` -D WITH_PYTHON | ||||
| else | ||||
| LDLIBS += `$(PYTHON_EXECUTABLE)-config --libs` $(BOOST_PYTHON_LIB) -lboost_system -lboost_filesystem | ||||
| CXXFLAGS += `$(PYTHON_EXECUTABLE)-config --includes` -D WITH_PYTHON | ||||
| endif | ||||
| 
 | ||||
| PY_WRAPPER_FILE = kernel/python_wrappers | ||||
| OBJS += $(PY_WRAPPER_FILE).o | ||||
| PY_GEN_SCRIPT= py_wrap_generator | ||||
| PY_WRAP_INCLUDES := $(shell python$(PYTHON_VERSION) -c "import $(PY_GEN_SCRIPT); $(PY_GEN_SCRIPT).print_includes()") | ||||
| endif | ||||
| 
 | ||||
| ifeq ($(ENABLE_READLINE),1) | ||||
| CXXFLAGS += -DYOSYS_ENABLE_READLINE | ||||
| ifeq ($(OS), FreeBSD) | ||||
|  | @ -510,6 +546,14 @@ libyosys.so: $(filter-out kernel/driver.o,$(OBJS)) | |||
| 	$(Q) mkdir -p $(dir $@) | ||||
| 	$(P) $(CXX) -o $@ -c $(CPPFLAGS) $(CXXFLAGS) $< | ||||
| 
 | ||||
| %.pyh: %.h | ||||
| 	$(Q) mkdir -p $(dir $@) | ||||
| 	$(P) cat $< | grep -E -v "#[ ]*(include|error)" | $(LD) -x c++ -o $@ -E -P - | ||||
| 
 | ||||
| $(PY_WRAPPER_FILE).cc: $(PY_GEN_SCRIPT).py $(PY_WRAP_INCLUDES) | ||||
| 	$(Q) mkdir -p $(dir $@) | ||||
| 	$(P) python$(PYTHON_VERSION) -c "import $(PY_GEN_SCRIPT); $(PY_GEN_SCRIPT).gen_wrappers(\"$(PY_WRAPPER_FILE).cc\")" | ||||
| 
 | ||||
| %.o: %.cpp | ||||
| 	$(Q) mkdir -p $(dir $@) | ||||
| 	$(P) $(CXX) -o $@ -c $(CPPFLAGS) $(CXXFLAGS) $< | ||||
|  | @ -638,6 +682,11 @@ ifeq ($(ENABLE_LIBYOSYS),1) | |||
| 	$(INSTALL_SUDO) cp libyosys.so $(DESTDIR)$(LIBDIR) | ||||
| 	$(INSTALL_SUDO) $(STRIP) -S $(DESTDIR)$(LIBDIR)/libyosys.so | ||||
| 	$(INSTALL_SUDO) ldconfig | ||||
| ifeq ($(ENABLE_PYOSYS),1) | ||||
| 	$(INSTALL_SUDO) mkdir -p $(PYTHON_DESTDIR)/pyosys | ||||
| 	$(INSTALL_SUDO) cp libyosys.so $(PYTHON_DESTDIR)/pyosys | ||||
| 	$(INSTALL_SUDO) cp __init__.py $(PYTHON_DESTDIR)/pyosys | ||||
| endif | ||||
| endif | ||||
| 
 | ||||
| uninstall: | ||||
|  | @ -645,6 +694,11 @@ uninstall: | |||
| 	$(INSTALL_SUDO) rm -rvf $(DESTDIR)$(DATDIR) | ||||
| ifeq ($(ENABLE_LIBYOSYS),1) | ||||
| 	$(INSTALL_SUDO) rm -vf $(DESTDIR)$(LIBDIR)/libyosys.so | ||||
| ifeq ($(ENABLE_PYOSYS),1) | ||||
| 	$(INSTALL_SUDO) rm -vf $(PYTHON_DESTDIR)/pyosys/libyosys.so | ||||
| 	$(INSTALL_SUDO) rm -vf $(PYTHON_DESTDIR)/pyosys/__init__.py | ||||
| 	$(INSTALL_SUDO) rmdir $(PYTHON_DESTDIR)/pyosys | ||||
| endif | ||||
| endif | ||||
| 
 | ||||
| update-manual: $(TARGETS) $(EXTRA_TARGETS) | ||||
|  | @ -657,8 +711,9 @@ manual: $(TARGETS) $(EXTRA_TARGETS) | |||
| 
 | ||||
| clean: | ||||
| 	rm -rf share | ||||
| 	rm -rf kernel/*.pyh | ||||
| 	if test -d manual; then cd manual && sh clean.sh; fi | ||||
| 	rm -f $(OBJS) $(GENFILES) $(TARGETS) $(EXTRA_TARGETS) $(EXTRA_OBJS) | ||||
| 	rm -f $(OBJS) $(GENFILES) $(TARGETS) $(EXTRA_TARGETS) $(EXTRA_OBJS) $(PY_WRAP_INCLUDES) $(PY_WRAPPER_FILE).cc | ||||
| 	rm -f kernel/version_*.o kernel/version_*.cc abc/abc-[0-9a-f]* abc/libabc-[0-9a-f]*.a | ||||
| 	rm -f libs/*/*.d frontends/*/*.d passes/*/*.d backends/*/*.d kernel/*.d techlibs/*/*.d | ||||
| 	rm -rf tests/asicworld/*.out tests/asicworld/*.log | ||||
|  |  | |||
|  | @ -66,25 +66,26 @@ prerequisites for building yosys: | |||
| 
 | ||||
| 	$ sudo apt-get install build-essential clang bison flex \ | ||||
| 		libreadline-dev gawk tcl-dev libffi-dev git \ | ||||
| 		graphviz xdot pkg-config python3 | ||||
| 		graphviz xdot pkg-config python3 libboost-system-dev \ | ||||
| 		libboost-python-dev libboost-filesystem-dev | ||||
| 
 | ||||
| Similarily, on Mac OS X MacPorts or Homebrew can be used to install dependencies: | ||||
| 
 | ||||
| 	$ brew tap Homebrew/bundle && brew bundle | ||||
| 	$ sudo port install bison flex readline gawk libffi \ | ||||
| 		git graphviz pkgconfig python36 | ||||
| 		git graphviz pkgconfig python36 boost | ||||
| 
 | ||||
| On FreeBSD use the following command to install all prerequisites: | ||||
| 
 | ||||
| 	# pkg install bison flex readline gawk libffi\ | ||||
| 		git graphviz pkgconfig python3 python36 tcl-wrapper | ||||
| 		git graphviz pkgconfig python3 python36 tcl-wrapper boost-libs | ||||
| 
 | ||||
| On FreeBSD system use gmake instead of make. To run tests use: | ||||
|     % MAKE=gmake CC=cc gmake test | ||||
| 
 | ||||
| For Cygwin use the following command to install all prerequisites, or select these additional packages: | ||||
| 
 | ||||
| 	setup-x86_64.exe -q --packages=bison,flex,gcc-core,gcc-g++,git,libffi-devel,libreadline-devel,make,pkg-config,python3,tcl-devel | ||||
| 	setup-x86_64.exe -q --packages=bison,flex,gcc-core,gcc-g++,git,libffi-devel,libreadline-devel,make,pkg-config,python3,tcl-devel,boost-build | ||||
| 
 | ||||
| There are also pre-compiled Yosys binary packages for Ubuntu and Win32 as well | ||||
| as a source distribution for Visual Studio. Visit the Yosys download page for | ||||
|  |  | |||
							
								
								
									
										5
									
								
								__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								__init__.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | |||
| import os | ||||
| import sys | ||||
| sys.setdlopenflags(os.RTLD_NOW | os.RTLD_GLOBAL) | ||||
| 
 | ||||
| __all__ = ["libyosys"] | ||||
							
								
								
									
										1
									
								
								examples/python-api/.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								examples/python-api/.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| out/** | ||||
							
								
								
									
										32
									
								
								examples/python-api/pass.py
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										32
									
								
								examples/python-api/pass.py
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,32 @@ | |||
| #!/usr/bin/python3 | ||||
| 
 | ||||
| from pyosys import libyosys as ys | ||||
| 
 | ||||
| import matplotlib.pyplot as plt | ||||
| import numpy as np | ||||
| 
 | ||||
| class CellStatsPass(ys.Pass): | ||||
| 
 | ||||
|     def __init__(self): | ||||
|         super().__init__("cell_stats", "Shows cell stats as plot") | ||||
| 
 | ||||
|     def py_help(self): | ||||
|         ys.log("This pass uses the matplotlib library to display cell stats\n") | ||||
| 
 | ||||
|     def py_execute(self, args, design): | ||||
|         ys.log_header(design, "Plotting cell stats\n") | ||||
|         cell_stats = {} | ||||
|         for module in design.selected_whole_modules_warn(): | ||||
|             for cell in module.selected_cells(): | ||||
|                 if cell.type.str() in cell_stats: | ||||
|                     cell_stats[cell.type.str()] += 1 | ||||
|                 else: | ||||
|                     cell_stats[cell.type.str()] = 1 | ||||
|         plt.bar(range(len(cell_stats)), height = list(cell_stats.values()),align='center') | ||||
|         plt.xticks(range(len(cell_stats)), list(cell_stats.keys())) | ||||
|         plt.show() | ||||
| 
 | ||||
|     def py_clear_flags(self): | ||||
|         ys.log("Clear Flags - CellStatsPass\n") | ||||
| 
 | ||||
| p = CellStatsPass() | ||||
							
								
								
									
										22
									
								
								examples/python-api/script.py
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										22
									
								
								examples/python-api/script.py
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,22 @@ | |||
| #!/usr/bin/python3 | ||||
| 
 | ||||
| from pyosys import libyosys as ys | ||||
| 
 | ||||
| import matplotlib.pyplot as plt | ||||
| import numpy as np | ||||
| 
 | ||||
| design = ys.Design() | ||||
| ys.run_pass("read_verilog ../../tests/simple/fiedler-cooley.v", design); | ||||
| ys.run_pass("prep", design) | ||||
| ys.run_pass("opt -full", design) | ||||
| 
 | ||||
| cell_stats = {} | ||||
| for module in design.selected_whole_modules_warn(): | ||||
|   for cell in module.selected_cells(): | ||||
|     if cell.type.str() in cell_stats: | ||||
|       cell_stats[cell.type.str()] += 1 | ||||
|     else: | ||||
|       cell_stats[cell.type.str()] = 1 | ||||
| plt.bar(range(len(cell_stats)), height = list(cell_stats.values()),align='center') | ||||
| plt.xticks(range(len(cell_stats)), list(cell_stats.keys())) | ||||
| plt.show() | ||||
|  | @ -26,7 +26,7 @@ YOSYS_NAMESPACE_BEGIN | |||
| 
 | ||||
| int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr); | ||||
| 
 | ||||
| int get_cell_cost(RTLIL::IdString type, const dict<RTLIL::IdString, RTLIL::Const> ¶meters = dict<RTLIL::IdString, RTLIL::Const>(), | ||||
| inline int get_cell_cost(RTLIL::IdString type, const dict<RTLIL::IdString, RTLIL::Const> ¶meters = dict<RTLIL::IdString, RTLIL::Const>(), | ||||
| 		RTLIL::Design *design = nullptr, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr) | ||||
| { | ||||
| 	static dict<RTLIL::IdString, int> gate_cost = { | ||||
|  | @ -76,7 +76,7 @@ int get_cell_cost(RTLIL::IdString type, const dict<RTLIL::IdString, RTLIL::Const | |||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache) | ||||
| inline int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache) | ||||
| { | ||||
| 	return get_cell_cost(cell->type, cell->parameters, cell->module->design, mod_cost_cache); | ||||
| } | ||||
|  |  | |||
|  | @ -110,6 +110,10 @@ int main(int argc, char **argv) | |||
| 	log_error_stderr = true; | ||||
| 	yosys_banner(); | ||||
| 	yosys_setup(); | ||||
| #ifdef WITH_PYTHON | ||||
| 	PyRun_SimpleString(("sys.path.append(\""+proc_self_dirname()+"\")").c_str()); | ||||
| 	PyRun_SimpleString(("sys.path.append(\""+proc_share_dirname()+"plugins\")").c_str()); | ||||
| #endif | ||||
| 
 | ||||
| 	if (argc == 2) | ||||
| 	{ | ||||
|  | @ -469,6 +473,10 @@ int main(int argc, char **argv) | |||
| #endif | ||||
| 
 | ||||
| 	yosys_setup(); | ||||
| #ifdef WITH_PYTHON | ||||
| 	PyRun_SimpleString(("sys.path.append(\""+proc_self_dirname()+"\")").c_str()); | ||||
| 	PyRun_SimpleString(("sys.path.append(\""+proc_share_dirname()+"plugins\")").c_str()); | ||||
| #endif | ||||
| 	log_error_atexit = yosys_atexit; | ||||
| 
 | ||||
| 	for (auto &fn : plugin_filenames) | ||||
|  |  | |||
|  | @ -76,6 +76,13 @@ RTLIL::Const::Const(const std::vector<bool> &bits) | |||
| 		this->bits.push_back(b ? RTLIL::S1 : RTLIL::S0); | ||||
| } | ||||
| 
 | ||||
| RTLIL::Const::Const(const RTLIL::Const &c) | ||||
| { | ||||
| 	flags = c.flags; | ||||
| 	for (auto b : c.bits) | ||||
| 		this->bits.push_back(b); | ||||
| } | ||||
| 
 | ||||
| bool RTLIL::Const::operator <(const RTLIL::Const &other) const | ||||
| { | ||||
| 	if (bits.size() != other.bits.size()) | ||||
|  | @ -363,6 +370,10 @@ RTLIL::Design::Design() | |||
| 
 | ||||
| 	refcount_modules_ = 0; | ||||
| 	selection_stack.push_back(RTLIL::Selection()); | ||||
| 
 | ||||
| #ifdef WITH_PYTHON | ||||
| 	RTLIL::Design::get_all_designs()->insert(std::pair<unsigned int, RTLIL::Design*>(hashidx_, this)); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| RTLIL::Design::~Design() | ||||
|  | @ -373,8 +384,19 @@ RTLIL::Design::~Design() | |||
| 		delete n; | ||||
| 	for (auto n : verilog_globals) | ||||
| 		delete n; | ||||
| #ifdef WITH_PYTHON | ||||
| 	RTLIL::Design::get_all_designs()->erase(hashidx_); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| #ifdef WITH_PYTHON | ||||
| static std::map<unsigned int, RTLIL::Design*> all_designs; | ||||
| std::map<unsigned int, RTLIL::Design*> *RTLIL::Design::get_all_designs(void) | ||||
| { | ||||
| 	return &all_designs; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| RTLIL::ObjRange<RTLIL::Module*> RTLIL::Design::modules() | ||||
| { | ||||
| 	return RTLIL::ObjRange<RTLIL::Module*>(&modules_, &refcount_modules_); | ||||
|  | @ -630,6 +652,10 @@ RTLIL::Module::Module() | |||
| 	design = nullptr; | ||||
| 	refcount_wires_ = 0; | ||||
| 	refcount_cells_ = 0; | ||||
| 
 | ||||
| #ifdef WITH_PYTHON | ||||
| 	RTLIL::Module::get_all_modules()->insert(std::pair<unsigned int, RTLIL::Module*>(hashidx_, this)); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| RTLIL::Module::~Module() | ||||
|  | @ -642,8 +668,19 @@ RTLIL::Module::~Module() | |||
| 		delete it->second; | ||||
| 	for (auto it = processes.begin(); it != processes.end(); ++it) | ||||
| 		delete it->second; | ||||
| #ifdef WITH_PYTHON | ||||
| 	RTLIL::Module::get_all_modules()->erase(hashidx_); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| #ifdef WITH_PYTHON | ||||
| static std::map<unsigned int, RTLIL::Module*> all_modules; | ||||
| std::map<unsigned int, RTLIL::Module*> *RTLIL::Module::get_all_modules(void) | ||||
| { | ||||
| 	return &all_modules; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| void RTLIL::Module::makeblackbox() | ||||
| { | ||||
| 	pool<RTLIL::Wire*> delwires; | ||||
|  | @ -2229,8 +2266,27 @@ RTLIL::Wire::Wire() | |||
| 	port_input = false; | ||||
| 	port_output = false; | ||||
| 	upto = false; | ||||
| 
 | ||||
| #ifdef WITH_PYTHON | ||||
| 	RTLIL::Wire::get_all_wires()->insert(std::pair<unsigned int, RTLIL::Wire*>(hashidx_, this)); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| RTLIL::Wire::~Wire() | ||||
| { | ||||
| #ifdef WITH_PYTHON | ||||
| 	RTLIL::Wire::get_all_wires()->erase(hashidx_); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| #ifdef WITH_PYTHON | ||||
| static std::map<unsigned int, RTLIL::Wire*> all_wires; | ||||
| std::map<unsigned int, RTLIL::Wire*> *RTLIL::Wire::get_all_wires(void) | ||||
| { | ||||
| 	return &all_wires; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| RTLIL::Memory::Memory() | ||||
| { | ||||
| 	static unsigned int hashidx_count = 123456789; | ||||
|  | @ -2240,6 +2296,9 @@ RTLIL::Memory::Memory() | |||
| 	width = 1; | ||||
| 	start_offset = 0; | ||||
| 	size = 0; | ||||
| #ifdef WITH_PYTHON | ||||
| 	RTLIL::Memory::get_all_memorys()->insert(std::pair<unsigned int, RTLIL::Memory*>(hashidx_, this)); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| RTLIL::Cell::Cell() : module(nullptr) | ||||
|  | @ -2250,8 +2309,27 @@ RTLIL::Cell::Cell() : module(nullptr) | |||
| 
 | ||||
| 	// log("#memtrace# %p\n", this);
 | ||||
| 	memhasher(); | ||||
| 
 | ||||
| #ifdef WITH_PYTHON | ||||
| 	RTLIL::Cell::get_all_cells()->insert(std::pair<unsigned int, RTLIL::Cell*>(hashidx_, this)); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| RTLIL::Cell::~Cell() | ||||
| { | ||||
| #ifdef WITH_PYTHON | ||||
| 	RTLIL::Cell::get_all_cells()->erase(hashidx_); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| #ifdef WITH_PYTHON | ||||
| static std::map<unsigned int, RTLIL::Cell*> all_cells; | ||||
| std::map<unsigned int, RTLIL::Cell*> *RTLIL::Cell::get_all_cells(void) | ||||
| { | ||||
| 	return &all_cells; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| bool RTLIL::Cell::hasPort(RTLIL::IdString portname) const | ||||
| { | ||||
| 	return connections_.count(portname) != 0; | ||||
|  | @ -2511,6 +2589,14 @@ RTLIL::SigChunk::SigChunk(RTLIL::SigBit bit) | |||
| 	width = 1; | ||||
| } | ||||
| 
 | ||||
| RTLIL::SigChunk::SigChunk(const RTLIL::SigChunk &sigchunk) : data(sigchunk.data) | ||||
| { | ||||
| 	wire = sigchunk.wire; | ||||
| 	data = sigchunk.data; | ||||
| 	width = sigchunk.width; | ||||
| 	offset = sigchunk.offset; | ||||
| } | ||||
| 
 | ||||
| RTLIL::SigChunk RTLIL::SigChunk::extract(int offset, int length) const | ||||
| { | ||||
| 	RTLIL::SigChunk ret; | ||||
|  | @ -3895,5 +3981,15 @@ RTLIL::Process *RTLIL::Process::clone() const | |||
| 	return new_proc; | ||||
| } | ||||
| 
 | ||||
| #ifdef WITH_PYTHON | ||||
| RTLIL::Memory::~Memory() | ||||
| { | ||||
| 	RTLIL::Memory::get_all_memorys()->erase(hashidx_); | ||||
| } | ||||
| static std::map<unsigned int, RTLIL::Memory*> all_memorys; | ||||
| std::map<unsigned int, RTLIL::Memory*> *RTLIL::Memory::get_all_memorys(void) | ||||
| { | ||||
| 	return &all_memorys; | ||||
| } | ||||
| #endif | ||||
| YOSYS_NAMESPACE_END | ||||
| 
 | ||||
|  |  | |||
|  | @ -517,6 +517,7 @@ struct RTLIL::Const | |||
| 	Const(RTLIL::State bit, int width = 1); | ||||
| 	Const(const std::vector<RTLIL::State> &bits) : bits(bits) { flags = CONST_FLAG_NONE; } | ||||
| 	Const(const std::vector<bool> &bits); | ||||
| 	Const(const RTLIL::Const &c); | ||||
| 
 | ||||
| 	bool operator <(const RTLIL::Const &other) const; | ||||
| 	bool operator ==(const RTLIL::Const &other) const; | ||||
|  | @ -595,6 +596,7 @@ struct RTLIL::SigChunk | |||
| 	SigChunk(int val, int width = 32); | ||||
| 	SigChunk(RTLIL::State bit, int width = 1); | ||||
| 	SigChunk(RTLIL::SigBit bit); | ||||
| 	SigChunk(const RTLIL::SigChunk &sigchunk); | ||||
| 
 | ||||
| 	RTLIL::SigChunk extract(int offset, int length) const; | ||||
| 
 | ||||
|  | @ -619,6 +621,7 @@ struct RTLIL::SigBit | |||
| 	SigBit(const RTLIL::SigChunk &chunk); | ||||
| 	SigBit(const RTLIL::SigChunk &chunk, int index); | ||||
| 	SigBit(const RTLIL::SigSpec &sig); | ||||
| 	SigBit(const RTLIL::SigBit &sigbit); | ||||
| 
 | ||||
| 	bool operator <(const RTLIL::SigBit &other) const; | ||||
| 	bool operator ==(const RTLIL::SigBit &other) const; | ||||
|  | @ -940,9 +943,13 @@ struct RTLIL::Design | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	std::vector<RTLIL::Module*> selected_modules() const; | ||||
| 	std::vector<RTLIL::Module*> selected_whole_modules() const; | ||||
| 	std::vector<RTLIL::Module*> selected_whole_modules_warn() const; | ||||
| #ifdef WITH_PYTHON | ||||
| 	static std::map<unsigned int, RTLIL::Design*> *get_all_designs(void); | ||||
| #endif | ||||
| }; | ||||
| 
 | ||||
| struct RTLIL::Module : public RTLIL::AttrObject | ||||
|  | @ -1199,6 +1206,10 @@ public: | |||
| 	RTLIL::SigSpec Allconst  (RTLIL::IdString name, int width = 1, const std::string &src = ""); | ||||
| 	RTLIL::SigSpec Allseq    (RTLIL::IdString name, int width = 1, const std::string &src = ""); | ||||
| 	RTLIL::SigSpec Initstate (RTLIL::IdString name, const std::string &src = ""); | ||||
| 
 | ||||
| #ifdef WITH_PYTHON | ||||
| 	static std::map<unsigned int, RTLIL::Module*> *get_all_modules(void); | ||||
| #endif | ||||
| }; | ||||
| 
 | ||||
| struct RTLIL::Wire : public RTLIL::AttrObject | ||||
|  | @ -1210,7 +1221,7 @@ protected: | |||
| 	// use module->addWire() and module->remove() to create or destroy wires
 | ||||
| 	friend struct RTLIL::Module; | ||||
| 	Wire(); | ||||
| 	~Wire() { }; | ||||
| 	~Wire(); | ||||
| 
 | ||||
| public: | ||||
| 	// do not simply copy wires
 | ||||
|  | @ -1221,6 +1232,10 @@ public: | |||
| 	RTLIL::IdString name; | ||||
| 	int width, start_offset, port_id; | ||||
| 	bool port_input, port_output, upto; | ||||
| 
 | ||||
| #ifdef WITH_PYTHON | ||||
| 	static std::map<unsigned int, RTLIL::Wire*> *get_all_wires(void); | ||||
| #endif | ||||
| }; | ||||
| 
 | ||||
| struct RTLIL::Memory : public RTLIL::AttrObject | ||||
|  | @ -1232,6 +1247,10 @@ struct RTLIL::Memory : public RTLIL::AttrObject | |||
| 
 | ||||
| 	RTLIL::IdString name; | ||||
| 	int width, start_offset, size; | ||||
| #ifdef WITH_PYTHON | ||||
| 	~Memory(); | ||||
| 	static std::map<unsigned int, RTLIL::Memory*> *get_all_memorys(void); | ||||
| #endif | ||||
| }; | ||||
| 
 | ||||
| struct RTLIL::Cell : public RTLIL::AttrObject | ||||
|  | @ -1243,6 +1262,7 @@ protected: | |||
| 	// use module->addCell() and module->remove() to create or destroy cells
 | ||||
| 	friend struct RTLIL::Module; | ||||
| 	Cell(); | ||||
| 	~Cell(); | ||||
| 
 | ||||
| public: | ||||
| 	// do not simply copy cells
 | ||||
|  | @ -1283,6 +1303,10 @@ public: | |||
| 	} | ||||
| 
 | ||||
| 	template<typename T> void rewrite_sigspecs(T &functor); | ||||
| 
 | ||||
| #ifdef WITH_PYTHON | ||||
| 	static std::map<unsigned int, RTLIL::Cell*> *get_all_cells(void); | ||||
| #endif | ||||
| }; | ||||
| 
 | ||||
| struct RTLIL::CaseRule | ||||
|  | @ -1343,6 +1367,7 @@ inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire) : wire(wire), offset(0) { log_as | |||
| inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire != nullptr); } | ||||
| inline RTLIL::SigBit::SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { log_assert(chunk.width == 1); if (wire) offset = chunk.offset; else data = chunk.data[0]; } | ||||
| inline RTLIL::SigBit::SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire) { if (wire) offset = chunk.offset + index; else data = chunk.data[index]; } | ||||
| inline RTLIL::SigBit::SigBit(const RTLIL::SigBit &sigbit) : wire(sigbit.wire), data(sigbit.data){if(wire) offset = sigbit.offset;} | ||||
| 
 | ||||
| inline bool RTLIL::SigBit::operator<(const RTLIL::SigBit &other) const { | ||||
| 	if (wire == other.wire) | ||||
|  |  | |||
|  | @ -57,6 +57,16 @@ | |||
| #  include <sys/sysctl.h> | ||||
| #endif | ||||
| 
 | ||||
| #ifdef WITH_PYTHON | ||||
| #if PY_MAJOR_VERSION >= 3 | ||||
| #   define INIT_MODULE PyInit_libyosys | ||||
|     extern "C" PyObject* INIT_MODULE(); | ||||
| #else | ||||
| #   define INIT_MODULE initlibyosys | ||||
| 	extern "C" void INIT_MODULE(); | ||||
| #endif | ||||
| #endif | ||||
| 
 | ||||
| #include <limits.h> | ||||
| #include <errno.h> | ||||
| 
 | ||||
|  | @ -477,21 +487,42 @@ int GetSize(RTLIL::Wire *wire) | |||
| 	return wire->width; | ||||
| } | ||||
| 
 | ||||
| bool already_setup = false; | ||||
| 
 | ||||
| void yosys_setup() | ||||
| { | ||||
| 	if(already_setup) | ||||
| 		return; | ||||
| 	already_setup = true; | ||||
| 	// if there are already IdString objects then we have a global initialization order bug
 | ||||
| 	IdString empty_id; | ||||
| 	log_assert(empty_id.index_ == 0); | ||||
| 	IdString::get_reference(empty_id.index_); | ||||
| 
 | ||||
| 	#ifdef WITH_PYTHON | ||||
| 		PyImport_AppendInittab((char*)"libyosys", INIT_MODULE); | ||||
| 		Py_Initialize(); | ||||
| 		PyRun_SimpleString("import sys"); | ||||
| 	#endif | ||||
| 
 | ||||
| 	Pass::init_register(); | ||||
| 	yosys_design = new RTLIL::Design; | ||||
| 	yosys_celltypes.setup(); | ||||
| 	log_push(); | ||||
| } | ||||
| 
 | ||||
| bool yosys_already_setup() | ||||
| { | ||||
| 	return already_setup; | ||||
| } | ||||
| 
 | ||||
| bool already_shutdown = false; | ||||
| 
 | ||||
| void yosys_shutdown() | ||||
| { | ||||
| 	if(already_shutdown) | ||||
| 		return; | ||||
| 	already_shutdown = true; | ||||
| 	log_pop(); | ||||
| 
 | ||||
| 	delete yosys_design; | ||||
|  | @ -519,9 +550,16 @@ void yosys_shutdown() | |||
| 		dlclose(it.second); | ||||
| 
 | ||||
| 	loaded_plugins.clear(); | ||||
| #ifdef WITH_PYTHON | ||||
| 	loaded_python_plugins.clear(); | ||||
| #endif | ||||
| 	loaded_plugin_aliases.clear(); | ||||
| #endif | ||||
| 
 | ||||
| #ifdef WITH_PYTHON | ||||
| 	Py_Finalize(); | ||||
| #endif | ||||
| 
 | ||||
| 	IdString empty_id; | ||||
| 	IdString::put_reference(empty_id.index_); | ||||
| } | ||||
|  |  | |||
|  | @ -66,6 +66,10 @@ | |||
| #include <stdio.h> | ||||
| #include <limits.h> | ||||
| 
 | ||||
| #ifdef WITH_PYTHON | ||||
| #include <Python.h> | ||||
| #endif | ||||
| 
 | ||||
| #ifndef _YOSYS_ | ||||
| #  error It looks like you are trying to build Yosys without the config defines set. \ | ||||
|          When building Yosys with a custom make system, make sure you set all the \ | ||||
|  | @ -115,6 +119,7 @@ extern const char *Tcl_GetStringResult(Tcl_Interp *interp); | |||
| #  define PATH_MAX 4096 | ||||
| #endif | ||||
| 
 | ||||
| #define YOSYS_NAMESPACE          Yosys | ||||
| #define PRIVATE_NAMESPACE_BEGIN  namespace { | ||||
| #define PRIVATE_NAMESPACE_END    } | ||||
| #define YOSYS_NAMESPACE_BEGIN    namespace Yosys { | ||||
|  | @ -276,6 +281,11 @@ namespace hashlib { | |||
| } | ||||
| 
 | ||||
| void yosys_setup(); | ||||
| 
 | ||||
| #ifdef WITH_PYTHON | ||||
| bool yosys_already_setup(); | ||||
| #endif | ||||
| 
 | ||||
| void yosys_shutdown(); | ||||
| 
 | ||||
| #ifdef YOSYS_ENABLE_TCL | ||||
|  | @ -317,6 +327,9 @@ extern std::vector<RTLIL::Design*> pushed_designs; | |||
| 
 | ||||
| // from passes/cmds/pluginc.cc
 | ||||
| extern std::map<std::string, void*> loaded_plugins; | ||||
| #ifdef WITH_PYTHON | ||||
| extern std::map<std::string, void*> loaded_python_plugins; | ||||
| #endif | ||||
| extern std::map<std::string, std::string> loaded_plugin_aliases; | ||||
| void load_plugin(std::string filename, std::vector<std::string> aliases); | ||||
| 
 | ||||
|  |  | |||
|  | @ -23,9 +23,18 @@ | |||
| #  include <dlfcn.h> | ||||
| #endif | ||||
| 
 | ||||
| #ifdef WITH_PYTHON | ||||
| #  include <boost/algorithm/string/predicate.hpp> | ||||
| #  include <Python.h> | ||||
| #  include <boost/filesystem.hpp> | ||||
| #endif | ||||
| 
 | ||||
| YOSYS_NAMESPACE_BEGIN | ||||
| 
 | ||||
| std::map<std::string, void*> loaded_plugins; | ||||
| #ifdef WITH_PYTHON | ||||
| std::map<std::string, void*> loaded_python_plugins; | ||||
| #endif | ||||
| std::map<std::string, std::string> loaded_plugin_aliases; | ||||
| 
 | ||||
| #ifdef YOSYS_ENABLE_PLUGINS | ||||
|  | @ -36,7 +45,35 @@ void load_plugin(std::string filename, std::vector<std::string> aliases) | |||
| 	if (filename.find('/') == std::string::npos) | ||||
| 		filename = "./" + filename; | ||||
| 
 | ||||
| 	#ifdef WITH_PYTHON | ||||
| 	if (!loaded_plugins.count(filename) && !loaded_python_plugins.count(filename)) { | ||||
| 	#else | ||||
| 	if (!loaded_plugins.count(filename)) { | ||||
| 	#endif | ||||
| 
 | ||||
| 		#ifdef WITH_PYTHON | ||||
| 
 | ||||
| 		boost::filesystem::path full_path(filename); | ||||
| 
 | ||||
| 		if(strcmp(full_path.extension().c_str(), ".py") == 0) | ||||
| 		{ | ||||
| 			std::string path(full_path.parent_path().c_str()); | ||||
| 			filename = full_path.filename().c_str(); | ||||
| 			filename = filename.substr(0,filename.size()-3); | ||||
| 			PyRun_SimpleString(("sys.path.insert(0,\""+path+"\")").c_str()); | ||||
| 			PyErr_Print(); | ||||
| 			PyObject *module_p = PyImport_ImportModule(filename.c_str()); | ||||
| 			if(module_p == NULL) | ||||
| 			{ | ||||
| 				PyErr_Print(); | ||||
| 				log_cmd_error("Can't load python module `%s'\n", full_path.filename().c_str()); | ||||
| 				return; | ||||
| 			} | ||||
| 			loaded_python_plugins[orig_filename] = module_p; | ||||
| 			Pass::init_register(); | ||||
| 		} else { | ||||
| 		#endif | ||||
| 
 | ||||
| 		void *hdl = dlopen(filename.c_str(), RTLD_LAZY|RTLD_LOCAL); | ||||
| 		if (hdl == NULL && orig_filename.find('/') == std::string::npos) | ||||
| 			hdl = dlopen((proc_share_dirname() + "plugins/" + orig_filename + ".so").c_str(), RTLD_LAZY|RTLD_LOCAL); | ||||
|  | @ -44,6 +81,10 @@ void load_plugin(std::string filename, std::vector<std::string> aliases) | |||
| 			log_cmd_error("Can't load module `%s': %s\n", filename.c_str(), dlerror()); | ||||
| 		loaded_plugins[orig_filename] = hdl; | ||||
| 		Pass::init_register(); | ||||
| 
 | ||||
| 		#ifdef WITH_PYTHON | ||||
| 		} | ||||
| 		#endif | ||||
| 	} | ||||
| 
 | ||||
| 	for (auto &alias : aliases) | ||||
|  | @ -107,7 +148,11 @@ struct PluginPass : public Pass { | |||
| 		if (list_mode) | ||||
| 		{ | ||||
| 			log("\n"); | ||||
| #ifdef WITH_PYTHON | ||||
| 			if (loaded_plugins.empty() and loaded_python_plugins.empty()) | ||||
| #else | ||||
| 			if (loaded_plugins.empty()) | ||||
| #endif | ||||
| 				log("No plugins loaded.\n"); | ||||
| 			else | ||||
| 				log("Loaded plugins:\n"); | ||||
|  | @ -115,6 +160,11 @@ struct PluginPass : public Pass { | |||
| 			for (auto &it : loaded_plugins) | ||||
| 				log("  %s\n", it.first.c_str()); | ||||
| 
 | ||||
| #ifdef WITH_PYTHON | ||||
| 			for (auto &it : loaded_python_plugins) | ||||
| 				log("  %s\n", it.first.c_str()); | ||||
| #endif | ||||
| 
 | ||||
| 			if (!loaded_plugin_aliases.empty()) { | ||||
| 				log("\n"); | ||||
| 				int max_alias_len = 1; | ||||
|  |  | |||
							
								
								
									
										2096
									
								
								py_wrap_generator.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2096
									
								
								py_wrap_generator.py
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue