mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	Merge remote-tracking branch 'origin/master' into xc7dsp
This commit is contained in:
		
						commit
						f890cfb63b
					
				
					 76 changed files with 840 additions and 568 deletions
				
			
		|  | @ -28,7 +28,7 @@ echo | ||||||
| echo 'Building...' && echo -en 'travis_fold:start:script.build\\r' | echo 'Building...' && echo -en 'travis_fold:start:script.build\\r' | ||||||
| echo | echo | ||||||
| 
 | 
 | ||||||
| make | make CC=$CC CXX=$CC LD=$CC | ||||||
| 
 | 
 | ||||||
| echo | echo | ||||||
| echo -en 'travis_fold:end:script.build\\r' | echo -en 'travis_fold:end:script.build\\r' | ||||||
|  |  | ||||||
							
								
								
									
										68
									
								
								Dockerfile
									
										
									
									
									
								
							
							
						
						
									
										68
									
								
								Dockerfile
									
										
									
									
									
								
							|  | @ -1,33 +1,57 @@ | ||||||
| FROM ubuntu:18.04 as builder | ARG IMAGE="python:3-slim-buster" | ||||||
| LABEL author="Abdelrahman Hosny <abdelrahman.hosny@hotmail.com>" | 
 | ||||||
| ENV DEBIAN_FRONTEND=noninteractive | #--- | ||||||
| RUN apt-get update && apt-get install -y build-essential \ | 
 | ||||||
|  | FROM $IMAGE AS base | ||||||
|  | 
 | ||||||
|  | RUN apt-get update -qq \ | ||||||
|  |  && DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends \ | ||||||
|  |     ca-certificates \ | ||||||
|     clang \ |     clang \ | ||||||
|  |     curl \ | ||||||
|  |     libffi-dev \ | ||||||
|  |     libreadline-dev \ | ||||||
|  |     tcl-dev \ | ||||||
|  |     graphviz \ | ||||||
|  |     xdot \ | ||||||
|  |  && apt-get autoclean && apt-get clean && apt-get -y autoremove \ | ||||||
|  |  && update-ca-certificates \ | ||||||
|  |  && rm -rf /var/lib/apt/lists | ||||||
|  | 
 | ||||||
|  | #--- | ||||||
|  | 
 | ||||||
|  | FROM base AS build | ||||||
|  | 
 | ||||||
|  | RUN apt-get update -qq \ | ||||||
|  |  && DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends \ | ||||||
|     bison \ |     bison \ | ||||||
|     flex \ |     flex \ | ||||||
|     libreadline-dev \ |  | ||||||
|     gawk \ |     gawk \ | ||||||
|     tcl-dev \ |     gcc \ | ||||||
|     libffi-dev \ |  | ||||||
|     git \ |     git \ | ||||||
|  |     iverilog \ | ||||||
|     pkg-config \ |     pkg-config \ | ||||||
|     python3 && \ |  && apt-get autoclean && apt-get clean && apt-get -y autoremove \ | ||||||
|     rm -rf /var/lib/apt/lists |  && rm -rf /var/lib/apt/lists | ||||||
| COPY . / |  | ||||||
| RUN make && \ |  | ||||||
|     make install |  | ||||||
| 
 | 
 | ||||||
| FROM ubuntu:18.04 | COPY . /yosys | ||||||
| ENV DEBIAN_FRONTEND=noninteractive |  | ||||||
| RUN apt-get update && apt-get install -y libreadline-dev tcl-dev |  | ||||||
| 
 | 
 | ||||||
| COPY --from=builder /yosys /build/yosys | ENV PREFIX /opt/yosys | ||||||
| COPY --from=builder /yosys-abc /build/yosys-abc | 
 | ||||||
| COPY --from=builder /yosys-config /build/yosys-config | RUN cd /yosys \ | ||||||
| COPY --from=builder /yosys-filterlib /build/yosys-filterlib |  && make \ | ||||||
| COPY --from=builder /yosys-smtbmc /build/yosys-smtbmc |  && make install \ | ||||||
|  |  && make test | ||||||
|  | 
 | ||||||
|  | #--- | ||||||
|  | 
 | ||||||
|  | FROM base | ||||||
|  | 
 | ||||||
|  | COPY --from=build /opt/yosys /opt/yosys | ||||||
|  | 
 | ||||||
|  | ENV PATH /opt/yosys/bin:$PATH | ||||||
| 
 | 
 | ||||||
| ENV PATH /build:$PATH |  | ||||||
| RUN useradd -m yosys | RUN useradd -m yosys | ||||||
| USER yosys | USER yosys | ||||||
| ENTRYPOINT ["yosys"] | 
 | ||||||
|  | CMD ["yosys"] | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
										
									
									
									
								
							|  | @ -781,7 +781,7 @@ clean: | ||||||
| 	rm -rf kernel/*.pyh | 	rm -rf kernel/*.pyh | ||||||
| 	if test -d manual; then cd manual && sh clean.sh; fi | 	if test -d manual; then cd manual && sh clean.sh; fi | ||||||
| 	rm -f $(OBJS) $(GENFILES) $(TARGETS) $(EXTRA_TARGETS) $(EXTRA_OBJS) $(PY_WRAP_INCLUDES) $(PY_WRAPPER_FILE).cc | 	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 kernel/version_*.o kernel/version_*.cc | ||||||
| 	rm -f libs/*/*.d frontends/*/*.d passes/*/*.d backends/*/*.d kernel/*.d techlibs/*/*.d | 	rm -f libs/*/*.d frontends/*/*.d passes/*/*.d backends/*/*.d kernel/*.d techlibs/*/*.d | ||||||
| 	rm -rf tests/asicworld/*.out tests/asicworld/*.log | 	rm -rf tests/asicworld/*.out tests/asicworld/*.log | ||||||
| 	rm -rf tests/hana/*.out tests/hana/*.log | 	rm -rf tests/hana/*.out tests/hana/*.log | ||||||
|  |  | ||||||
|  | @ -388,11 +388,11 @@ struct XAigerWriter | ||||||
| 						RTLIL::SigSpec rhs; | 						RTLIL::SigSpec rhs; | ||||||
| 						if (it != cell->connections_.end()) { | 						if (it != cell->connections_.end()) { | ||||||
| 							if (GetSize(it->second) < GetSize(w)) | 							if (GetSize(it->second) < GetSize(w)) | ||||||
| 								it->second.append(RTLIL::SigSpec(RTLIL::S0, GetSize(w)-GetSize(it->second))); | 								it->second.append(RTLIL::SigSpec(State::S0, GetSize(w)-GetSize(it->second))); | ||||||
| 							rhs = it->second; | 							rhs = it->second; | ||||||
| 						} | 						} | ||||||
| 						else { | 						else { | ||||||
| 							rhs = RTLIL::SigSpec(RTLIL::S0, GetSize(w)); | 							rhs = RTLIL::SigSpec(State::S0, GetSize(w)); | ||||||
| 							cell->setPort(port_name, rhs); | 							cell->setPort(port_name, rhs); | ||||||
| 						} | 						} | ||||||
| 
 | 
 | ||||||
|  | @ -400,10 +400,10 @@ struct XAigerWriter | ||||||
| 						for (auto b : rhs.bits()) { | 						for (auto b : rhs.bits()) { | ||||||
| 							SigBit I = sigmap(b); | 							SigBit I = sigmap(b); | ||||||
| 							if (b == RTLIL::Sx) | 							if (b == RTLIL::Sx) | ||||||
| 								b = RTLIL::S0; | 								b = State::S0; | ||||||
| 							else if (I != b) { | 							else if (I != b) { | ||||||
| 								if (I == RTLIL::Sx) | 								if (I == RTLIL::Sx) | ||||||
| 									alias_map[b] = RTLIL::S0; | 									alias_map[b] = State::S0; | ||||||
| 								else | 								else | ||||||
| 									alias_map[b] = I; | 									alias_map[b] = I; | ||||||
| 							} | 							} | ||||||
|  | @ -671,7 +671,7 @@ struct XAigerWriter | ||||||
| 							if (holes_cell) | 							if (holes_cell) | ||||||
| 								port_wire.append(holes_wire); | 								port_wire.append(holes_wire); | ||||||
| 							else | 							else | ||||||
| 								holes_module->connect(holes_wire, RTLIL::S0); | 								holes_module->connect(holes_wire, State::S0); | ||||||
| 						} | 						} | ||||||
| 						if (!port_wire.empty()) | 						if (!port_wire.empty()) | ||||||
| 							holes_cell->setPort(w->name, port_wire); | 							holes_cell->setPort(w->name, port_wire); | ||||||
|  |  | ||||||
|  | @ -377,7 +377,7 @@ struct BlifDumper | ||||||
| 				f << stringf("\n"); | 				f << stringf("\n"); | ||||||
| 				RTLIL::SigSpec mask = cell->parameters.at("\\LUT"); | 				RTLIL::SigSpec mask = cell->parameters.at("\\LUT"); | ||||||
| 				for (int i = 0; i < (1 << width); i++) | 				for (int i = 0; i < (1 << width); i++) | ||||||
| 					if (mask[i] == RTLIL::S1) { | 					if (mask[i] == State::S1) { | ||||||
| 						for (int j = width-1; j >= 0; j--) { | 						for (int j = width-1; j >= 0; j--) { | ||||||
| 							f << ((i>>j)&1 ? '1' : '0'); | 							f << ((i>>j)&1 ? '1' : '0'); | ||||||
| 						} | 						} | ||||||
|  |  | ||||||
|  | @ -616,8 +616,8 @@ struct BtorWorker | ||||||
| 			if (initstate_nid < 0) | 			if (initstate_nid < 0) | ||||||
| 			{ | 			{ | ||||||
| 				int sid = get_bv_sid(1); | 				int sid = get_bv_sid(1); | ||||||
| 				int one_nid = get_sig_nid(Const(1, 1)); | 				int one_nid = get_sig_nid(State::S1); | ||||||
| 				int zero_nid = get_sig_nid(Const(0, 1)); | 				int zero_nid = get_sig_nid(State::S0); | ||||||
| 				initstate_nid = next_nid++; | 				initstate_nid = next_nid++; | ||||||
| 				btorf("%d state %d\n", initstate_nid, sid); | 				btorf("%d state %d\n", initstate_nid, sid); | ||||||
| 				btorf("%d init %d %d %d\n", next_nid++, sid, initstate_nid, one_nid); | 				btorf("%d init %d %d %d\n", next_nid++, sid, initstate_nid, one_nid); | ||||||
|  |  | ||||||
|  | @ -122,9 +122,9 @@ struct FirrtlWorker | ||||||
| 			// Current (3/13/2019) conventions:
 | 			// Current (3/13/2019) conventions:
 | ||||||
| 			//  generate a constant 0 for clock and a constant 1 for enable if they are undefined.
 | 			//  generate a constant 0 for clock and a constant 1 for enable if they are undefined.
 | ||||||
| 			if (!clk.is_fully_def()) | 			if (!clk.is_fully_def()) | ||||||
| 				this->clk = SigSpec(RTLIL::Const(0, 1)); | 				this->clk = SigSpec(State::S0); | ||||||
| 			if (!ena.is_fully_def()) | 			if (!ena.is_fully_def()) | ||||||
| 				this->ena = SigSpec(RTLIL::Const(1, 1)); | 				this->ena = SigSpec(State::S1); | ||||||
| 		} | 		} | ||||||
| 		string gen_read(const char * indent) { | 		string gen_read(const char * indent) { | ||||||
| 			string addr_expr = make_expr(addr); | 			string addr_expr = make_expr(addr); | ||||||
|  | @ -297,7 +297,7 @@ struct FirrtlWorker | ||||||
| 		std::string cell_type = fid(cell->type); | 		std::string cell_type = fid(cell->type); | ||||||
| 		std::string instanceOf; | 		std::string instanceOf; | ||||||
| 		// If this is a parameterized module, its parent module is encoded in the cell type
 | 		// If this is a parameterized module, its parent module is encoded in the cell type
 | ||||||
| 		if (cell->type.substr(0, 8) == "$paramod") | 		if (cell->type.begins_with("$paramod")) | ||||||
| 		{ | 		{ | ||||||
| 			std::string::iterator it; | 			std::string::iterator it; | ||||||
| 			for (it = cell_type.begin(); it < cell_type.end(); it++) | 			for (it = cell_type.begin(); it < cell_type.end(); it++) | ||||||
|  | @ -363,7 +363,7 @@ struct FirrtlWorker | ||||||
| 				} | 				} | ||||||
| 				// Check for subfield assignment.
 | 				// Check for subfield assignment.
 | ||||||
| 				std::string bitsString = "bits("; | 				std::string bitsString = "bits("; | ||||||
| 				if (sinkExpr.substr(0, bitsString.length()) == bitsString ) { | 				if (sinkExpr.compare(0, bitsString.length(), bitsString) == 0) { | ||||||
| 					if (sinkSig == nullptr) | 					if (sinkSig == nullptr) | ||||||
| 						log_error("Unknown subfield %s.%s\n", cell_type.c_str(), sinkExpr.c_str()); | 						log_error("Unknown subfield %s.%s\n", cell_type.c_str(), sinkExpr.c_str()); | ||||||
| 					// Don't generate the assignment here.
 | 					// Don't generate the assignment here.
 | ||||||
|  | @ -877,7 +877,7 @@ struct FirrtlWorker | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			// This may be a parameterized module - paramod.
 | 			// This may be a parameterized module - paramod.
 | ||||||
| 			if (cell->type.substr(0, 8) == "$paramod") | 			if (cell->type.begins_with("$paramod")) | ||||||
| 			{ | 			{ | ||||||
| 				process_instance(cell, wire_exprs); | 				process_instance(cell, wire_exprs); | ||||||
| 				continue; | 				continue; | ||||||
|  | @ -943,7 +943,7 @@ struct FirrtlWorker | ||||||
| 				register_reverse_wire_map(y_id, cell->getPort("\\Y")); | 				register_reverse_wire_map(y_id, cell->getPort("\\Y")); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			log_warning("Cell type not supported: %s (%s.%s)\n", log_id(cell->type), log_id(module), log_id(cell)); | 			log_error("Cell type not supported: %s (%s.%s)\n", log_id(cell->type), log_id(module), log_id(cell)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for (auto conn : module->connections()) | 		for (auto conn : module->connections()) | ||||||
|  |  | ||||||
|  | @ -40,8 +40,8 @@ void ILANG_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int wi | ||||||
| 			for (int i = 0; i < width; i++) { | 			for (int i = 0; i < width; i++) { | ||||||
| 				log_assert(offset+i < (int)data.bits.size()); | 				log_assert(offset+i < (int)data.bits.size()); | ||||||
| 				switch (data.bits[offset+i]) { | 				switch (data.bits[offset+i]) { | ||||||
| 				case RTLIL::S0: break; | 				case State::S0: break; | ||||||
| 				case RTLIL::S1: val |= 1 << i; break; | 				case State::S1: val |= 1 << i; break; | ||||||
| 				default: val = -1; break; | 				default: val = -1; break; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | @ -54,8 +54,8 @@ void ILANG_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int wi | ||||||
| 		for (int i = offset+width-1; i >= offset; i--) { | 		for (int i = offset+width-1; i >= offset; i--) { | ||||||
| 			log_assert(i < (int)data.bits.size()); | 			log_assert(i < (int)data.bits.size()); | ||||||
| 			switch (data.bits[i]) { | 			switch (data.bits[i]) { | ||||||
| 			case RTLIL::S0: f << stringf("0"); break; | 			case State::S0: f << stringf("0"); break; | ||||||
| 			case RTLIL::S1: f << stringf("1"); break; | 			case State::S1: f << stringf("1"); break; | ||||||
| 			case RTLIL::Sx: f << stringf("x"); break; | 			case RTLIL::Sx: f << stringf("x"); break; | ||||||
| 			case RTLIL::Sz: f << stringf("z"); break; | 			case RTLIL::Sz: f << stringf("z"); break; | ||||||
| 			case RTLIL::Sa: f << stringf("-"); break; | 			case RTLIL::Sa: f << stringf("-"); break; | ||||||
|  |  | ||||||
|  | @ -108,7 +108,7 @@ struct IntersynthBackend : public Backend { | ||||||
| 			if (f.fail()) | 			if (f.fail()) | ||||||
| 				log_error("Can't open lib file `%s'.\n", filename.c_str()); | 				log_error("Can't open lib file `%s'.\n", filename.c_str()); | ||||||
| 			RTLIL::Design *lib = new RTLIL::Design; | 			RTLIL::Design *lib = new RTLIL::Design; | ||||||
| 			Frontend::frontend_call(lib, &f, filename, (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") ? "ilang" : "verilog"); | 			Frontend::frontend_call(lib, &f, filename, (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "ilang" : "verilog")); | ||||||
| 			libs.push_back(lib); | 			libs.push_back(lib); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -183,7 +183,7 @@ struct IntersynthBackend : public Backend { | ||||||
| 					if (param.second.bits.size() != 32) { | 					if (param.second.bits.size() != 32) { | ||||||
| 						node_code += stringf(" %s '", RTLIL::id2cstr(param.first)); | 						node_code += stringf(" %s '", RTLIL::id2cstr(param.first)); | ||||||
| 						for (int i = param.second.bits.size()-1; i >= 0; i--) | 						for (int i = param.second.bits.size()-1; i >= 0; i--) | ||||||
| 							node_code += param.second.bits[i] == RTLIL::S1 ? "1" : "0"; | 							node_code += param.second.bits[i] == State::S1 ? "1" : "0"; | ||||||
| 					} else | 					} else | ||||||
| 						node_code += stringf(" %s 0x%x", RTLIL::id2cstr(param.first), param.second.as_int()); | 						node_code += stringf(" %s 0x%x", RTLIL::id2cstr(param.first), param.second.as_int()); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|  | @ -601,7 +601,7 @@ struct Smt2Worker | ||||||
| 			if (cell->type == "$logic_and") return export_reduce(cell, "(and (or A) (or B))", false); | 			if (cell->type == "$logic_and") return export_reduce(cell, "(and (or A) (or B))", false); | ||||||
| 			if (cell->type == "$logic_or") return export_reduce(cell, "(or A B)", false); | 			if (cell->type == "$logic_or") return export_reduce(cell, "(or A B)", false); | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$mux" || cell->type == "$pmux") | 			if (cell->type.in("$mux", "$pmux")) | ||||||
| 			{ | 			{ | ||||||
| 				int width = GetSize(cell->getPort("\\Y")); | 				int width = GetSize(cell->getPort("\\Y")); | ||||||
| 				std::string processed_expr = get_bv(cell->getPort("\\A")); | 				std::string processed_expr = get_bv(cell->getPort("\\A")); | ||||||
|  | @ -1476,7 +1476,7 @@ struct Smt2Backend : public Backend { | ||||||
| 				int indent = 0; | 				int indent = 0; | ||||||
| 				while (indent < GetSize(line) && (line[indent] == ' ' || line[indent] == '\t')) | 				while (indent < GetSize(line) && (line[indent] == ' ' || line[indent] == '\t')) | ||||||
| 					indent++; | 					indent++; | ||||||
| 				if (line.substr(indent, 2) == "%%") | 				if (line.compare(indent, 2, "%%") == 0) | ||||||
| 					break; | 					break; | ||||||
| 				*f << line << std::endl; | 				*f << line << std::endl; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | @ -61,7 +61,7 @@ struct SmvWorker | ||||||
| 		{ | 		{ | ||||||
| 			string name = stringf("_%s", id.c_str()); | 			string name = stringf("_%s", id.c_str()); | ||||||
| 
 | 
 | ||||||
| 			if (name.substr(0, 2) == "_\\") | 			if (name.compare(0, 2, "_\\") == 0) | ||||||
| 				name = "_" + name.substr(2); | 				name = "_" + name.substr(2); | ||||||
| 
 | 
 | ||||||
| 			for (auto &c : name) { | 			for (auto &c : name) { | ||||||
|  |  | ||||||
|  | @ -200,9 +200,9 @@ void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int o | ||||||
| 			int32_t val = 0; | 			int32_t val = 0; | ||||||
| 			for (int i = offset+width-1; i >= offset; i--) { | 			for (int i = offset+width-1; i >= offset; i--) { | ||||||
| 				log_assert(i < (int)data.bits.size()); | 				log_assert(i < (int)data.bits.size()); | ||||||
| 				if (data.bits[i] != RTLIL::S0 && data.bits[i] != RTLIL::S1) | 				if (data.bits[i] != State::S0 && data.bits[i] != State::S1) | ||||||
| 					goto dump_hex; | 					goto dump_hex; | ||||||
| 				if (data.bits[i] == RTLIL::S1) | 				if (data.bits[i] == State::S1) | ||||||
| 					val |= 1 << (i - offset); | 					val |= 1 << (i - offset); | ||||||
| 			} | 			} | ||||||
| 			if (decimal) | 			if (decimal) | ||||||
|  | @ -219,8 +219,8 @@ void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int o | ||||||
| 			for (int i = offset; i < offset+width; i++) { | 			for (int i = offset; i < offset+width; i++) { | ||||||
| 				log_assert(i < (int)data.bits.size()); | 				log_assert(i < (int)data.bits.size()); | ||||||
| 				switch (data.bits[i]) { | 				switch (data.bits[i]) { | ||||||
| 				case RTLIL::S0: bin_digits.push_back('0'); break; | 				case State::S0: bin_digits.push_back('0'); break; | ||||||
| 				case RTLIL::S1: bin_digits.push_back('1'); break; | 				case State::S1: bin_digits.push_back('1'); break; | ||||||
| 				case RTLIL::Sx: bin_digits.push_back('x'); break; | 				case RTLIL::Sx: bin_digits.push_back('x'); break; | ||||||
| 				case RTLIL::Sz: bin_digits.push_back('z'); break; | 				case RTLIL::Sz: bin_digits.push_back('z'); break; | ||||||
| 				case RTLIL::Sa: bin_digits.push_back('?'); break; | 				case RTLIL::Sa: bin_digits.push_back('?'); break; | ||||||
|  | @ -273,8 +273,8 @@ void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int o | ||||||
| 			for (int i = offset+width-1; i >= offset; i--) { | 			for (int i = offset+width-1; i >= offset; i--) { | ||||||
| 				log_assert(i < (int)data.bits.size()); | 				log_assert(i < (int)data.bits.size()); | ||||||
| 				switch (data.bits[i]) { | 				switch (data.bits[i]) { | ||||||
| 				case RTLIL::S0: f << stringf("0"); break; | 				case State::S0: f << stringf("0"); break; | ||||||
| 				case RTLIL::S1: f << stringf("1"); break; | 				case State::S1: f << stringf("1"); break; | ||||||
| 				case RTLIL::Sx: f << stringf("x"); break; | 				case RTLIL::Sx: f << stringf("x"); break; | ||||||
| 				case RTLIL::Sz: f << stringf("z"); break; | 				case RTLIL::Sz: f << stringf("z"); break; | ||||||
| 				case RTLIL::Sa: f << stringf("?"); break; | 				case RTLIL::Sa: f << stringf("?"); break; | ||||||
|  | @ -380,9 +380,9 @@ void dump_attributes(std::ostream &f, std::string indent, dict<RTLIL::IdString, | ||||||
| 	for (auto it = attributes.begin(); it != attributes.end(); ++it) { | 	for (auto it = attributes.begin(); it != attributes.end(); ++it) { | ||||||
| 		f << stringf("%s" "%s %s", indent.c_str(), as_comment ? "/*" : "(*", id(it->first).c_str()); | 		f << stringf("%s" "%s %s", indent.c_str(), as_comment ? "/*" : "(*", id(it->first).c_str()); | ||||||
| 		f << stringf(" = "); | 		f << stringf(" = "); | ||||||
| 		if (modattr && (it->second == Const(0, 1) || it->second == Const(0))) | 		if (modattr && (it->second == State::S0 || it->second == Const(0))) | ||||||
| 			f << stringf(" 0 "); | 			f << stringf(" 0 "); | ||||||
| 		else if (modattr && (it->second == Const(1, 1) || it->second == Const(1))) | 		else if (modattr && (it->second == State::S1 || it->second == Const(1))) | ||||||
| 			f << stringf(" 1 "); | 			f << stringf(" 1 "); | ||||||
| 		else | 		else | ||||||
| 			dump_const(f, it->second, -1, 0, false, as_comment); | 			dump_const(f, it->second, -1, 0, false, as_comment); | ||||||
|  | @ -604,7 +604,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type.substr(0, 6) == "$_DFF_") | 	if (cell->type.begins_with("$_DFF_")) | ||||||
| 	{ | 	{ | ||||||
| 		std::string reg_name = cellname(cell); | 		std::string reg_name = cellname(cell); | ||||||
| 		bool out_is_reg_wire = is_reg_wire(cell->getPort("\\Q"), reg_name); | 		bool out_is_reg_wire = is_reg_wire(cell->getPort("\\Q"), reg_name); | ||||||
|  | @ -645,7 +645,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type.substr(0, 8) == "$_DFFSR_") | 	if (cell->type.begins_with("$_DFFSR_")) | ||||||
| 	{ | 	{ | ||||||
| 		char pol_c = cell->type[8], pol_s = cell->type[9], pol_r = cell->type[10]; | 		char pol_c = cell->type[8], pol_s = cell->type[9], pol_r = cell->type[10]; | ||||||
| 
 | 
 | ||||||
|  | @ -949,7 +949,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type == "$dff" || cell->type == "$adff" || cell->type == "$dffe") | 	if (cell->type.in("$dff", "$adff", "$dffe")) | ||||||
| 	{ | 	{ | ||||||
| 		RTLIL::SigSpec sig_clk, sig_arst, sig_en, val_arst; | 		RTLIL::SigSpec sig_clk, sig_arst, sig_en, val_arst; | ||||||
| 		bool pol_clk, pol_arst = false, pol_en = false; | 		bool pol_clk, pol_arst = false, pol_en = false; | ||||||
|  |  | ||||||
|  | @ -30,6 +30,7 @@ | ||||||
| #include <libkern/OSByteOrder.h> | #include <libkern/OSByteOrder.h> | ||||||
| #define __builtin_bswap32 OSSwapInt32 | #define __builtin_bswap32 OSSwapInt32 | ||||||
| #endif | #endif | ||||||
|  | #define __STDC_FORMAT_MACROS | ||||||
| #include <inttypes.h> | #include <inttypes.h> | ||||||
| 
 | 
 | ||||||
| #include "kernel/yosys.h" | #include "kernel/yosys.h" | ||||||
|  | @ -151,12 +152,12 @@ struct ConstEvalAig | ||||||
| 
 | 
 | ||||||
| 		RTLIL::State eval_ret = RTLIL::Sx; | 		RTLIL::State eval_ret = RTLIL::Sx; | ||||||
| 		if (cell->type == "$_NOT_") { | 		if (cell->type == "$_NOT_") { | ||||||
| 			if (sig_a == RTLIL::S0) eval_ret = RTLIL::S1; | 			if (sig_a == State::S0) eval_ret = State::S1; | ||||||
| 			else if (sig_a == RTLIL::S1) eval_ret = RTLIL::S0; | 			else if (sig_a == State::S1) eval_ret = State::S0; | ||||||
| 		} | 		} | ||||||
| 		else if (cell->type == "$_AND_") { | 		else if (cell->type == "$_AND_") { | ||||||
| 			if (sig_a == RTLIL::S0) { | 			if (sig_a == State::S0) { | ||||||
| 				eval_ret = RTLIL::S0; | 				eval_ret = State::S0; | ||||||
| 				goto eval_end; | 				goto eval_end; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | @ -164,15 +165,15 @@ struct ConstEvalAig | ||||||
| 				RTLIL::SigBit sig_b = cell->getPort("\\B"); | 				RTLIL::SigBit sig_b = cell->getPort("\\B"); | ||||||
| 				if (!eval(sig_b)) | 				if (!eval(sig_b)) | ||||||
| 					return false; | 					return false; | ||||||
| 				if (sig_b == RTLIL::S0) { | 				if (sig_b == State::S0) { | ||||||
| 					eval_ret = RTLIL::S0; | 					eval_ret = State::S0; | ||||||
| 					goto eval_end; | 					goto eval_end; | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				if (sig_a != RTLIL::S1 || sig_b != RTLIL::S1) | 				if (sig_a != State::S1 || sig_b != State::S1) | ||||||
| 					goto eval_end; | 					goto eval_end; | ||||||
| 
 | 
 | ||||||
| 				eval_ret = RTLIL::S1; | 				eval_ret = State::S1; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		else log_abort(); | 		else log_abort(); | ||||||
|  | @ -256,7 +257,7 @@ end_of_header: | ||||||
| 
 | 
 | ||||||
| 	RTLIL::Wire* n0 = module->wire("\\__0__"); | 	RTLIL::Wire* n0 = module->wire("\\__0__"); | ||||||
| 	if (n0) | 	if (n0) | ||||||
| 		module->connect(n0, RTLIL::S0); | 		module->connect(n0, State::S0); | ||||||
| 
 | 
 | ||||||
| 	// Parse footer (symbol table, comments, etc.)
 | 	// Parse footer (symbol table, comments, etc.)
 | ||||||
| 	unsigned l1; | 	unsigned l1; | ||||||
|  | @ -371,7 +372,7 @@ void AigerReader::parse_xaiger(const dict<int,IdString> &box_lookup) | ||||||
| 
 | 
 | ||||||
| 	RTLIL::Wire* n0 = module->wire("\\__0__"); | 	RTLIL::Wire* n0 = module->wire("\\__0__"); | ||||||
| 	if (n0) | 	if (n0) | ||||||
| 		module->connect(n0, RTLIL::S0); | 		module->connect(n0, State::S0); | ||||||
| 
 | 
 | ||||||
| 	// Parse footer (symbol table, comments, etc.)
 | 	// Parse footer (symbol table, comments, etc.)
 | ||||||
| 	std::string s; | 	std::string s; | ||||||
|  | @ -520,9 +521,9 @@ void AigerReader::parse_aiger_ascii() | ||||||
| 				log_error("Line %u cannot be interpreted as a latch!\n", line_count); | 				log_error("Line %u cannot be interpreted as a latch!\n", line_count); | ||||||
| 
 | 
 | ||||||
| 			if (l3 == 0) | 			if (l3 == 0) | ||||||
| 				q_wire->attributes["\\init"] = RTLIL::S0; | 				q_wire->attributes["\\init"] = State::S0; | ||||||
| 			else if (l3 == 1) | 			else if (l3 == 1) | ||||||
| 				q_wire->attributes["\\init"] = RTLIL::S1; | 				q_wire->attributes["\\init"] = State::S1; | ||||||
| 			else if (l3 == l1) { | 			else if (l3 == l1) { | ||||||
| 				//q_wire->attributes["\\init"] = RTLIL::Sx;
 | 				//q_wire->attributes["\\init"] = RTLIL::Sx;
 | ||||||
| 			} | 			} | ||||||
|  | @ -531,7 +532,7 @@ void AigerReader::parse_aiger_ascii() | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| 			// AIGER latches are assumed to be initialized to zero
 | 			// AIGER latches are assumed to be initialized to zero
 | ||||||
| 			q_wire->attributes["\\init"] = RTLIL::S0; | 			q_wire->attributes["\\init"] = State::S0; | ||||||
| 		} | 		} | ||||||
| 		latches.push_back(q_wire); | 		latches.push_back(q_wire); | ||||||
| 	} | 	} | ||||||
|  | @ -645,9 +646,9 @@ void AigerReader::parse_aiger_binary() | ||||||
| 				log_error("Line %u cannot be interpreted as a latch!\n", line_count); | 				log_error("Line %u cannot be interpreted as a latch!\n", line_count); | ||||||
| 
 | 
 | ||||||
| 			if (l3 == 0) | 			if (l3 == 0) | ||||||
| 				q_wire->attributes["\\init"] = RTLIL::S0; | 				q_wire->attributes["\\init"] = State::S0; | ||||||
| 			else if (l3 == 1) | 			else if (l3 == 1) | ||||||
| 				q_wire->attributes["\\init"] = RTLIL::S1; | 				q_wire->attributes["\\init"] = State::S1; | ||||||
| 			else if (l3 == l1) { | 			else if (l3 == l1) { | ||||||
| 				//q_wire->attributes["\\init"] = RTLIL::Sx;
 | 				//q_wire->attributes["\\init"] = RTLIL::Sx;
 | ||||||
| 			} | 			} | ||||||
|  | @ -656,7 +657,7 @@ void AigerReader::parse_aiger_binary() | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| 			// AIGER latches are assumed to be initialized to zero
 | 			// AIGER latches are assumed to be initialized to zero
 | ||||||
| 			q_wire->attributes["\\init"] = RTLIL::S0; | 			q_wire->attributes["\\init"] = State::S0; | ||||||
| 		} | 		} | ||||||
| 		latches.push_back(q_wire); | 		latches.push_back(q_wire); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -283,8 +283,8 @@ void AstNode::dumpAst(FILE *f, std::string indent) const | ||||||
| 	if (!bits.empty()) { | 	if (!bits.empty()) { | ||||||
| 		fprintf(f, " bits='"); | 		fprintf(f, " bits='"); | ||||||
| 		for (size_t i = bits.size(); i > 0; i--) | 		for (size_t i = bits.size(); i > 0; i--) | ||||||
| 			fprintf(f, "%c", bits[i-1] == RTLIL::S0 ? '0' : | 			fprintf(f, "%c", bits[i-1] == State::S0 ? '0' : | ||||||
| 					bits[i-1] == RTLIL::S1 ? '1' : | 					bits[i-1] == State::S1 ? '1' : | ||||||
| 					bits[i-1] == RTLIL::Sx ? 'x' : | 					bits[i-1] == RTLIL::Sx ? 'x' : | ||||||
| 					bits[i-1] == RTLIL::Sz ? 'z' : '?'); | 					bits[i-1] == RTLIL::Sz ? 'z' : '?'); | ||||||
| 		fprintf(f, "'(%d)", GetSize(bits)); | 		fprintf(f, "'(%d)", GetSize(bits)); | ||||||
|  | @ -716,7 +716,7 @@ AstNode *AstNode::mkconst_int(uint32_t v, bool is_signed, int width) | ||||||
| 	node->integer = v; | 	node->integer = v; | ||||||
| 	node->is_signed = is_signed; | 	node->is_signed = is_signed; | ||||||
| 	for (int i = 0; i < width; i++) { | 	for (int i = 0; i < width; i++) { | ||||||
| 		node->bits.push_back((v & 1) ? RTLIL::S1 : RTLIL::S0); | 		node->bits.push_back((v & 1) ? State::S1 : State::S0); | ||||||
| 		v = v >> 1; | 		v = v >> 1; | ||||||
| 	} | 	} | ||||||
| 	node->range_valid = true; | 	node->range_valid = true; | ||||||
|  | @ -733,9 +733,9 @@ AstNode *AstNode::mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signe | ||||||
| 	node->bits = v; | 	node->bits = v; | ||||||
| 	for (size_t i = 0; i < 32; i++) { | 	for (size_t i = 0; i < 32; i++) { | ||||||
| 		if (i < node->bits.size()) | 		if (i < node->bits.size()) | ||||||
| 			node->integer |= (node->bits[i] == RTLIL::S1) << i; | 			node->integer |= (node->bits[i] == State::S1) << i; | ||||||
| 		else if (is_signed && !node->bits.empty()) | 		else if (is_signed && !node->bits.empty()) | ||||||
| 			node->integer |= (node->bits.back() == RTLIL::S1) << i; | 			node->integer |= (node->bits.back() == State::S1) << i; | ||||||
| 	} | 	} | ||||||
| 	node->range_valid = true; | 	node->range_valid = true; | ||||||
| 	node->range_left = node->bits.size()-1; | 	node->range_left = node->bits.size()-1; | ||||||
|  | @ -767,7 +767,7 @@ AstNode *AstNode::mkconst_str(const std::string &str) | ||||||
| 	for (size_t i = 0; i < str.size(); i++) { | 	for (size_t i = 0; i < str.size(); i++) { | ||||||
| 		unsigned char ch = str[str.size() - i - 1]; | 		unsigned char ch = str[str.size() - i - 1]; | ||||||
| 		for (int j = 0; j < 8; j++) { | 		for (int j = 0; j < 8; j++) { | ||||||
| 			data.push_back((ch & 1) ? RTLIL::S1 : RTLIL::S0); | 			data.push_back((ch & 1) ? State::S1 : State::S0); | ||||||
| 			ch = ch >> 1; | 			ch = ch >> 1; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -780,7 +780,7 @@ AstNode *AstNode::mkconst_str(const std::string &str) | ||||||
| bool AstNode::bits_only_01() const | bool AstNode::bits_only_01() const | ||||||
| { | { | ||||||
| 	for (auto bit : bits) | 	for (auto bit : bits) | ||||||
| 		if (bit != RTLIL::S0 && bit != RTLIL::S1) | 		if (bit != State::S0 && bit != State::S1) | ||||||
| 			return false; | 			return false; | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
|  | @ -1164,7 +1164,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (flag_icells && (*it)->str.substr(0, 2) == "\\$") | 			if (flag_icells && (*it)->str.compare(0, 2, "\\$") == 0) | ||||||
| 				(*it)->str = (*it)->str.substr(1); | 				(*it)->str = (*it)->str.substr(1); | ||||||
| 
 | 
 | ||||||
| 			if (defer) | 			if (defer) | ||||||
|  | @ -1463,7 +1463,7 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString | ||||||
| { | { | ||||||
| 	std::string stripped_name = name.str(); | 	std::string stripped_name = name.str(); | ||||||
| 
 | 
 | ||||||
| 	if (stripped_name.substr(0, 9) == "$abstract") | 	if (stripped_name.compare(0, 9, "$abstract") == 0) | ||||||
| 		stripped_name = stripped_name.substr(9); | 		stripped_name = stripped_name.substr(9); | ||||||
| 
 | 
 | ||||||
| 	log_header(design, "Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str()); | 	log_header(design, "Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str()); | ||||||
|  |  | ||||||
|  | @ -1516,7 +1516,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) | ||||||
| 				AstNode *child = *it; | 				AstNode *child = *it; | ||||||
| 				if (child->type == AST_CELLTYPE) { | 				if (child->type == AST_CELLTYPE) { | ||||||
| 					cell->type = child->str; | 					cell->type = child->str; | ||||||
| 					if (flag_icells && cell->type.substr(0, 2) == "\\$") | 					if (flag_icells && cell->type.begins_with("\\$")) | ||||||
| 						cell->type = cell->type.substr(1); | 						cell->type = cell->type.substr(1); | ||||||
| 					continue; | 					continue; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|  | @ -2319,7 +2319,7 @@ skip_dynamic_range_lvalue_expansion:; | ||||||
| 				if (attr.first.str().rfind("\\via_celltype_defparam_", 0) == 0) | 				if (attr.first.str().rfind("\\via_celltype_defparam_", 0) == 0) | ||||||
| 				{ | 				{ | ||||||
| 					AstNode *cell_arg = new AstNode(AST_PARASET, attr.second->clone()); | 					AstNode *cell_arg = new AstNode(AST_PARASET, attr.second->clone()); | ||||||
| 					cell_arg->str = RTLIL::escape_id(attr.first.str().substr(strlen("\\via_celltype_defparam_"))); | 					cell_arg->str = RTLIL::escape_id(attr.first.substr(strlen("\\via_celltype_defparam_"))); | ||||||
| 					cell->children.push_back(cell_arg); | 					cell->children.push_back(cell_arg); | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
|  | @ -2793,13 +2793,13 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m | ||||||
| 		std::getline(f, line); | 		std::getline(f, line); | ||||||
| 
 | 
 | ||||||
| 		for (int i = 0; i < GetSize(line); i++) { | 		for (int i = 0; i < GetSize(line); i++) { | ||||||
| 			if (in_comment && line.substr(i, 2) == "*/") { | 			if (in_comment && line.compare(i, 2, "*/") == 0) { | ||||||
| 				line[i] = ' '; | 				line[i] = ' '; | ||||||
| 				line[i+1] = ' '; | 				line[i+1] = ' '; | ||||||
| 				in_comment = false; | 				in_comment = false; | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (!in_comment && line.substr(i, 2) == "/*") | 			if (!in_comment && line.compare(i, 2, "/*") == 0) | ||||||
| 				in_comment = true; | 				in_comment = true; | ||||||
| 			if (in_comment) | 			if (in_comment) | ||||||
| 				line[i] = ' '; | 				line[i] = ' '; | ||||||
|  | @ -2808,7 +2808,7 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m | ||||||
| 		while (1) | 		while (1) | ||||||
| 		{ | 		{ | ||||||
| 			token = next_token(line, " \t\r\n"); | 			token = next_token(line, " \t\r\n"); | ||||||
| 			if (token.empty() || token.substr(0, 2) == "//") | 			if (token.empty() || token.compare(0, 2, "//") == 0) | ||||||
| 				break; | 				break; | ||||||
| 
 | 
 | ||||||
| 			if (token[0] == '@') { | 			if (token[0] == '@') { | ||||||
|  |  | ||||||
|  | @ -19,6 +19,7 @@ | ||||||
| 
 | 
 | ||||||
| #include "kernel/yosys.h" | #include "kernel/yosys.h" | ||||||
| #include "kernel/sigtools.h" | #include "kernel/sigtools.h" | ||||||
|  | #include "kernel/celltypes.h" | ||||||
| #include "kernel/log.h" | #include "kernel/log.h" | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
|  | @ -111,9 +112,10 @@ string get_full_netlist_name(Netlist *nl) | ||||||
| 
 | 
 | ||||||
| // ==================================================================
 | // ==================================================================
 | ||||||
| 
 | 
 | ||||||
| VerificImporter::VerificImporter(bool mode_gates, bool mode_keep, bool mode_nosva, bool mode_names, bool mode_verific, bool mode_autocover) : | VerificImporter::VerificImporter(bool mode_gates, bool mode_keep, bool mode_nosva, bool mode_names, bool mode_verific, bool mode_autocover, bool mode_fullinit) : | ||||||
| 		mode_gates(mode_gates), mode_keep(mode_keep), mode_nosva(mode_nosva), | 		mode_gates(mode_gates), mode_keep(mode_keep), mode_nosva(mode_nosva), | ||||||
| 		mode_names(mode_names), mode_verific(mode_verific), mode_autocover(mode_autocover) | 		mode_names(mode_names), mode_verific(mode_verific), mode_autocover(mode_autocover), | ||||||
|  | 		mode_fullinit(mode_fullinit) | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -1454,6 +1456,50 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se | ||||||
| 
 | 
 | ||||||
| 		merge_past_ffs(past_ffs); | 		merge_past_ffs(past_ffs); | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	if (!mode_fullinit) | ||||||
|  | 	{ | ||||||
|  | 		pool<SigBit> non_ff_bits; | ||||||
|  | 		CellTypes ff_types; | ||||||
|  | 
 | ||||||
|  | 		ff_types.setup_internals_ff(); | ||||||
|  | 		ff_types.setup_stdcells_mem(); | ||||||
|  | 
 | ||||||
|  | 		for (auto cell : module->cells()) | ||||||
|  | 		{ | ||||||
|  | 			if (ff_types.cell_known(cell->type)) | ||||||
|  | 				continue; | ||||||
|  | 
 | ||||||
|  | 			for (auto conn : cell->connections()) | ||||||
|  | 			{ | ||||||
|  | 				if (!cell->output(conn.first)) | ||||||
|  | 					continue; | ||||||
|  | 
 | ||||||
|  | 				for (auto bit : conn.second) | ||||||
|  | 					if (bit.wire != nullptr) | ||||||
|  | 						non_ff_bits.insert(bit); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		for (auto wire : module->wires()) | ||||||
|  | 		{ | ||||||
|  | 			if (!wire->attributes.count("\\init")) | ||||||
|  | 				continue; | ||||||
|  | 
 | ||||||
|  | 			Const &initval = wire->attributes.at("\\init"); | ||||||
|  | 			for (int i = 0; i < GetSize(initval); i++) | ||||||
|  | 			{ | ||||||
|  | 				if (initval[i] != State::S0 && initval[i] != State::S1) | ||||||
|  | 					continue; | ||||||
|  | 
 | ||||||
|  | 				if (non_ff_bits.count(SigBit(wire, i))) | ||||||
|  | 					initval[i] = State::Sx; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (initval.is_fully_undef()) | ||||||
|  | 				wire->attributes.erase("\\init"); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ==================================================================
 | // ==================================================================
 | ||||||
|  | @ -1829,7 +1875,7 @@ void verific_import(Design *design, const std::map<std::string,std::string> &par | ||||||
| 	while (!nl_todo.empty()) { | 	while (!nl_todo.empty()) { | ||||||
| 		Netlist *nl = *nl_todo.begin(); | 		Netlist *nl = *nl_todo.begin(); | ||||||
| 		if (nl_done.count(nl) == 0) { | 		if (nl_done.count(nl) == 0) { | ||||||
| 			VerificImporter importer(false, false, false, false, false, false); | 			VerificImporter importer(false, false, false, false, false, false, false); | ||||||
| 			importer.import_netlist(design, nl, nl_todo); | 			importer.import_netlist(design, nl, nl_todo); | ||||||
| 		} | 		} | ||||||
| 		nl_todo.erase(nl); | 		nl_todo.erase(nl); | ||||||
|  | @ -1952,6 +1998,9 @@ struct VerificPass : public Pass { | ||||||
| 		log("  -autocover\n"); | 		log("  -autocover\n"); | ||||||
| 		log("    Generate automatic cover statements for all asserts\n"); | 		log("    Generate automatic cover statements for all asserts\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
|  | 		log("  -fullinit\n"); | ||||||
|  | 		log("    Keep all register initializations, even those for non-FF registers.\n"); | ||||||
|  | 		log("\n"); | ||||||
| 		log("  -chparam name value \n"); | 		log("  -chparam name value \n"); | ||||||
| 		log("    Elaborate the specified top modules (all modules when -all given) using\n"); | 		log("    Elaborate the specified top modules (all modules when -all given) using\n"); | ||||||
| 		log("    this parameter value. Modules on which this parameter does not exist will\n"); | 		log("    this parameter value. Modules on which this parameter does not exist will\n"); | ||||||
|  | @ -2140,7 +2189,7 @@ struct VerificPass : public Pass { | ||||||
| 			veri_file::DefineMacro("VERIFIC"); | 			veri_file::DefineMacro("VERIFIC"); | ||||||
| 			veri_file::DefineMacro(args[argidx] == "-formal" ? "FORMAL" : "SYNTHESIS"); | 			veri_file::DefineMacro(args[argidx] == "-formal" ? "FORMAL" : "SYNTHESIS"); | ||||||
| 
 | 
 | ||||||
| 			for (argidx++; argidx < GetSize(args) && GetSize(args[argidx]) >= 2 && args[argidx].substr(0, 2) == "-D"; argidx++) { | 			for (argidx++; argidx < GetSize(args) && GetSize(args[argidx]) >= 2 && args[argidx].compare(0, 2, "-D") == 0; argidx++) { | ||||||
| 				std::string name = args[argidx].substr(2); | 				std::string name = args[argidx].substr(2); | ||||||
| 				if (args[argidx] == "-D") { | 				if (args[argidx] == "-D") { | ||||||
| 					if (++argidx >= GetSize(args)) | 					if (++argidx >= GetSize(args)) | ||||||
|  | @ -2213,7 +2262,7 @@ struct VerificPass : public Pass { | ||||||
| 			std::set<Netlist*> nl_todo, nl_done; | 			std::set<Netlist*> nl_todo, nl_done; | ||||||
| 			bool mode_all = false, mode_gates = false, mode_keep = false; | 			bool mode_all = false, mode_gates = false, mode_keep = false; | ||||||
| 			bool mode_nosva = false, mode_names = false, mode_verific = false; | 			bool mode_nosva = false, mode_names = false, mode_verific = false; | ||||||
| 			bool mode_autocover = false; | 			bool mode_autocover = false, mode_fullinit = false; | ||||||
| 			bool flatten = false, extnets = false; | 			bool flatten = false, extnets = false; | ||||||
| 			string dumpfile; | 			string dumpfile; | ||||||
| 			Map parameters(STRING_HASH); | 			Map parameters(STRING_HASH); | ||||||
|  | @ -2255,6 +2304,10 @@ struct VerificPass : public Pass { | ||||||
| 					mode_autocover = true; | 					mode_autocover = true; | ||||||
| 					continue; | 					continue; | ||||||
| 				} | 				} | ||||||
|  | 				if (args[argidx] == "-fullinit") { | ||||||
|  | 					mode_fullinit = true; | ||||||
|  | 					continue; | ||||||
|  | 				} | ||||||
| 				if (args[argidx] == "-chparam"  && argidx+2 < GetSize(args)) { | 				if (args[argidx] == "-chparam"  && argidx+2 < GetSize(args)) { | ||||||
| 					const std::string &key = args[++argidx]; | 					const std::string &key = args[++argidx]; | ||||||
| 					const std::string &value = args[++argidx]; | 					const std::string &value = args[++argidx]; | ||||||
|  | @ -2283,7 +2336,7 @@ struct VerificPass : public Pass { | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (argidx > GetSize(args) && args[argidx].substr(0, 1) == "-") | 			if (argidx > GetSize(args) && args[argidx].compare(0, 1, "-") == 0) | ||||||
| 				cmd_error(args, argidx, "unknown option"); | 				cmd_error(args, argidx, "unknown option"); | ||||||
| 
 | 
 | ||||||
| 			if (mode_all) | 			if (mode_all) | ||||||
|  | @ -2378,7 +2431,7 @@ struct VerificPass : public Pass { | ||||||
| 				Netlist *nl = *nl_todo.begin(); | 				Netlist *nl = *nl_todo.begin(); | ||||||
| 				if (nl_done.count(nl) == 0) { | 				if (nl_done.count(nl) == 0) { | ||||||
| 					VerificImporter importer(mode_gates, mode_keep, mode_nosva, | 					VerificImporter importer(mode_gates, mode_keep, mode_nosva, | ||||||
| 							mode_names, mode_verific, mode_autocover); | 							mode_names, mode_verific, mode_autocover, mode_fullinit); | ||||||
| 					importer.import_netlist(design, nl, nl_todo); | 					importer.import_netlist(design, nl, nl_todo); | ||||||
| 				} | 				} | ||||||
| 				nl_todo.erase(nl); | 				nl_todo.erase(nl); | ||||||
|  |  | ||||||
|  | @ -72,9 +72,9 @@ struct VerificImporter | ||||||
| 	pool<Verific::Net*, hash_ptr_ops> any_all_nets; | 	pool<Verific::Net*, hash_ptr_ops> any_all_nets; | ||||||
| 
 | 
 | ||||||
| 	bool mode_gates, mode_keep, mode_nosva, mode_names, mode_verific; | 	bool mode_gates, mode_keep, mode_nosva, mode_names, mode_verific; | ||||||
| 	bool mode_autocover; | 	bool mode_autocover, mode_fullinit; | ||||||
| 
 | 
 | ||||||
| 	VerificImporter(bool mode_gates, bool mode_keep, bool mode_nosva, bool mode_names, bool mode_verific, bool mode_autocover); | 	VerificImporter(bool mode_gates, bool mode_keep, bool mode_nosva, bool mode_names, bool mode_verific, bool mode_autocover, bool mode_fullinit); | ||||||
| 
 | 
 | ||||||
| 	RTLIL::SigBit net_map_at(Verific::Net *net); | 	RTLIL::SigBit net_map_at(Verific::Net *net); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -357,7 +357,7 @@ struct SvaFsm | ||||||
| 		for (int i = 0; i < GetSize(nodes); i++) | 		for (int i = 0; i < GetSize(nodes); i++) | ||||||
| 		{ | 		{ | ||||||
| 			if (next_state_sig[i] != State::S0) { | 			if (next_state_sig[i] != State::S0) { | ||||||
| 				clocking.addDff(NEW_ID, next_state_sig[i], state_wire[i], Const(0, 1)); | 				clocking.addDff(NEW_ID, next_state_sig[i], state_wire[i], State::S0); | ||||||
| 			} else { | 			} else { | ||||||
| 				module->connect(state_wire[i], State::S0); | 				module->connect(state_wire[i], State::S0); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | @ -99,7 +99,7 @@ static void my_strtobin(std::vector<RTLIL::State> &data, const char *str, int le | ||||||
| 
 | 
 | ||||||
| 	if (base == 10) { | 	if (base == 10) { | ||||||
| 		while (!digits.empty()) | 		while (!digits.empty()) | ||||||
| 			data.push_back(my_decimal_div_by_two(digits) ? RTLIL::S1 : RTLIL::S0); | 			data.push_back(my_decimal_div_by_two(digits) ? State::S1 : State::S0); | ||||||
| 	} else { | 	} else { | ||||||
| 		int bits_per_digit = my_ilog2(base-1); | 		int bits_per_digit = my_ilog2(base-1); | ||||||
| 		for (auto it = digits.rbegin(), e = digits.rend(); it != e; it++) { | 		for (auto it = digits.rbegin(), e = digits.rend(); it != e; it++) { | ||||||
|  | @ -115,17 +115,17 @@ static void my_strtobin(std::vector<RTLIL::State> &data, const char *str, int le | ||||||
| 				else if (*it == 0xf2) | 				else if (*it == 0xf2) | ||||||
| 					data.push_back(RTLIL::Sa); | 					data.push_back(RTLIL::Sa); | ||||||
| 				else | 				else | ||||||
| 					data.push_back((*it & bitmask) ? RTLIL::S1 : RTLIL::S0); | 					data.push_back((*it & bitmask) ? State::S1 : State::S0); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	int len = GetSize(data); | 	int len = GetSize(data); | ||||||
| 	RTLIL::State msb = data.empty() ? RTLIL::S0 : data.back(); | 	RTLIL::State msb = data.empty() ? State::S0 : data.back(); | ||||||
| 
 | 
 | ||||||
| 	if (len_in_bits < 0) { | 	if (len_in_bits < 0) { | ||||||
| 		if (len < 32) | 		if (len < 32) | ||||||
| 			data.resize(32, msb == RTLIL::S0 || msb == RTLIL::S1 ? RTLIL::S0 : msb); | 			data.resize(32, msb == State::S0 || msb == State::S1 ? RTLIL::S0 : msb); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -133,11 +133,11 @@ static void my_strtobin(std::vector<RTLIL::State> &data, const char *str, int le | ||||||
| 		log_file_error(current_filename, get_line_num(), "Unsized constant must have width of 1 bit, but have %d bits!\n", len); | 		log_file_error(current_filename, get_line_num(), "Unsized constant must have width of 1 bit, but have %d bits!\n", len); | ||||||
| 
 | 
 | ||||||
| 	for (len = len - 1; len >= 0; len--) | 	for (len = len - 1; len >= 0; len--) | ||||||
| 		if (data[len] == RTLIL::S1) | 		if (data[len] == State::S1) | ||||||
| 			break; | 			break; | ||||||
| 	if (msb == RTLIL::S0 || msb == RTLIL::S1) { | 	if (msb == State::S0 || msb == State::S1) { | ||||||
| 		len += 1; | 		len += 1; | ||||||
| 		data.resize(len_in_bits, RTLIL::S0); | 		data.resize(len_in_bits, State::S0); | ||||||
| 	} else { | 	} else { | ||||||
| 		len += 2; | 		len += 2; | ||||||
| 		data.resize(len_in_bits, msb); | 		data.resize(len_in_bits, msb); | ||||||
|  | @ -169,7 +169,7 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type, bool warn | ||||||
| 		for (int i = 0; i < len; i++) { | 		for (int i = 0; i < len; i++) { | ||||||
| 			unsigned char ch = str[len - i]; | 			unsigned char ch = str[len - i]; | ||||||
| 			for (int j = 0; j < 8; j++) { | 			for (int j = 0; j < 8; j++) { | ||||||
| 				data.push_back((ch & 1) ? RTLIL::S1 : RTLIL::S0); | 				data.push_back((ch & 1) ? State::S1 : State::S0); | ||||||
| 				ch = ch >> 1; | 				ch = ch >> 1; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | @ -190,8 +190,8 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type, bool warn | ||||||
| 	if (*endptr == 0) { | 	if (*endptr == 0) { | ||||||
| 		std::vector<RTLIL::State> data; | 		std::vector<RTLIL::State> data; | ||||||
| 		my_strtobin(data, str, -1, 10, case_type, false); | 		my_strtobin(data, str, -1, 10, case_type, false); | ||||||
| 		if (data.back() == RTLIL::S1) | 		if (data.back() == State::S1) | ||||||
| 			data.push_back(RTLIL::S0); | 			data.push_back(State::S0); | ||||||
| 		return AstNode::mkconst_bits(data, true); | 		return AstNode::mkconst_bits(data, true); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -237,8 +237,8 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type, bool warn | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		if (len_in_bits < 0) { | 		if (len_in_bits < 0) { | ||||||
| 			if (is_signed && data.back() == RTLIL::S1) | 			if (is_signed && data.back() == State::S1) | ||||||
| 				data.push_back(RTLIL::S0); | 				data.push_back(State::S0); | ||||||
| 		} | 		} | ||||||
| 		return AstNode::mkconst_bits(data, is_signed, is_unsized); | 		return AstNode::mkconst_bits(data, is_signed, is_unsized); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -274,7 +274,7 @@ hierarchical_id: | ||||||
| 		$$ = $1; | 		$$ = $1; | ||||||
| 	} | | 	} | | ||||||
| 	hierarchical_id TOK_PACKAGESEP TOK_ID { | 	hierarchical_id TOK_PACKAGESEP TOK_ID { | ||||||
| 		if ($3->substr(0, 1) == "\\") | 		if ($3->compare(0, 1, "\\") == 0) | ||||||
| 			*$1 += "::" + $3->substr(1); | 			*$1 += "::" + $3->substr(1); | ||||||
| 		else | 		else | ||||||
| 			*$1 += "::" + *$3; | 			*$1 += "::" + *$3; | ||||||
|  | @ -282,7 +282,7 @@ hierarchical_id: | ||||||
| 		$$ = $1; | 		$$ = $1; | ||||||
| 	} | | 	} | | ||||||
| 	hierarchical_id '.' TOK_ID { | 	hierarchical_id '.' TOK_ID { | ||||||
| 		if ($3->substr(0, 1) == "\\") | 		if ($3->compare(0, 1, "\\") == 0) | ||||||
| 			*$1 += "." + $3->substr(1); | 			*$1 += "." + $3->substr(1); | ||||||
| 		else | 		else | ||||||
| 			*$1 += "." + *$3; | 			*$1 += "." + *$3; | ||||||
|  | @ -2184,7 +2184,7 @@ basic_expr: | ||||||
| 		$$ = $1; | 		$$ = $1; | ||||||
| 	} | | 	} | | ||||||
| 	'(' expr ')' TOK_CONSTVAL { | 	'(' expr ')' TOK_CONSTVAL { | ||||||
| 		if ($4->substr(0, 1) != "'") | 		if ($4->compare(0, 1, "'") != 0) | ||||||
| 			frontend_verilog_yyerror("Cast operation must be applied on sized constants e.g. (<expr>)<constval> , while %s is not a sized constant.", $4->c_str()); | 			frontend_verilog_yyerror("Cast operation must be applied on sized constants e.g. (<expr>)<constval> , while %s is not a sized constant.", $4->c_str()); | ||||||
| 		AstNode *bits = $2; | 		AstNode *bits = $2; | ||||||
| 		AstNode *val = const2ast(*$4, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode); | 		AstNode *val = const2ast(*$4, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode); | ||||||
|  | @ -2194,7 +2194,7 @@ basic_expr: | ||||||
| 		delete $4; | 		delete $4; | ||||||
| 	} | | 	} | | ||||||
| 	hierarchical_id TOK_CONSTVAL { | 	hierarchical_id TOK_CONSTVAL { | ||||||
| 		if ($2->substr(0, 1) != "'") | 		if ($2->compare(0, 1, "'") != 0) | ||||||
| 			frontend_verilog_yyerror("Cast operation must be applied on sized constants, e.g. <ID>\'d0, while %s is not a sized constant.", $2->c_str()); | 			frontend_verilog_yyerror("Cast operation must be applied on sized constants, e.g. <ID>\'d0, while %s is not a sized constant.", $2->c_str()); | ||||||
| 		AstNode *bits = new AstNode(AST_IDENTIFIER); | 		AstNode *bits = new AstNode(AST_IDENTIFIER); | ||||||
| 		bits->str = *$1; | 		bits->str = *$1; | ||||||
|  |  | ||||||
|  | @ -139,13 +139,10 @@ struct CellTypes | ||||||
| 		setup_type("$fa", {A, B, C}, {X, Y}, true); | 		setup_type("$fa", {A, B, C}, {X, Y}, true); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void setup_internals_mem() | 	void setup_internals_ff() | ||||||
| 	{ | 	{ | ||||||
| 		IdString SET = "\\SET", CLR = "\\CLR", CLK = "\\CLK", ARST = "\\ARST", EN = "\\EN"; | 		IdString SET = "\\SET", CLR = "\\CLR", CLK = "\\CLK", ARST = "\\ARST", EN = "\\EN"; | ||||||
| 		IdString Q = "\\Q", D = "\\D", ADDR = "\\ADDR", DATA = "\\DATA", RD_EN = "\\RD_EN"; | 		IdString Q = "\\Q", D = "\\D"; | ||||||
| 		IdString RD_CLK = "\\RD_CLK", RD_ADDR = "\\RD_ADDR", WR_CLK = "\\WR_CLK", WR_EN = "\\WR_EN"; |  | ||||||
| 		IdString WR_ADDR = "\\WR_ADDR", WR_DATA = "\\WR_DATA", RD_DATA = "\\RD_DATA"; |  | ||||||
| 		IdString CTRL_IN = "\\CTRL_IN", CTRL_OUT = "\\CTRL_OUT"; |  | ||||||
| 
 | 
 | ||||||
| 		setup_type("$sr", {SET, CLR}, {Q}); | 		setup_type("$sr", {SET, CLR}, {Q}); | ||||||
| 		setup_type("$ff", {D}, {Q}); | 		setup_type("$ff", {D}, {Q}); | ||||||
|  | @ -156,6 +153,18 @@ struct CellTypes | ||||||
| 		setup_type("$dlatch", {EN, D}, {Q}); | 		setup_type("$dlatch", {EN, D}, {Q}); | ||||||
| 		setup_type("$dlatchsr", {EN, SET, CLR, D}, {Q}); | 		setup_type("$dlatchsr", {EN, SET, CLR, D}, {Q}); | ||||||
| 
 | 
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void setup_internals_mem() | ||||||
|  | 	{ | ||||||
|  | 		setup_internals_ff(); | ||||||
|  | 
 | ||||||
|  | 		IdString CLK = "\\CLK", ARST = "\\ARST", EN = "\\EN"; | ||||||
|  | 		IdString ADDR = "\\ADDR", DATA = "\\DATA", RD_EN = "\\RD_EN"; | ||||||
|  | 		IdString RD_CLK = "\\RD_CLK", RD_ADDR = "\\RD_ADDR", WR_CLK = "\\WR_CLK", WR_EN = "\\WR_EN"; | ||||||
|  | 		IdString WR_ADDR = "\\WR_ADDR", WR_DATA = "\\WR_DATA", RD_DATA = "\\RD_DATA"; | ||||||
|  | 		IdString CTRL_IN = "\\CTRL_IN", CTRL_OUT = "\\CTRL_OUT"; | ||||||
|  | 
 | ||||||
| 		setup_type("$memrd", {CLK, EN, ADDR}, {DATA}); | 		setup_type("$memrd", {CLK, EN, ADDR}, {DATA}); | ||||||
| 		setup_type("$memwr", {CLK, EN, ADDR, DATA}, pool<RTLIL::IdString>()); | 		setup_type("$memwr", {CLK, EN, ADDR, DATA}, pool<RTLIL::IdString>()); | ||||||
| 		setup_type("$meminit", {ADDR, DATA}, pool<RTLIL::IdString>()); | 		setup_type("$meminit", {ADDR, DATA}, pool<RTLIL::IdString>()); | ||||||
|  | @ -273,8 +282,8 @@ struct CellTypes | ||||||
| 	static RTLIL::Const eval_not(RTLIL::Const v) | 	static RTLIL::Const eval_not(RTLIL::Const v) | ||||||
| 	{ | 	{ | ||||||
| 		for (auto &bit : v.bits) | 		for (auto &bit : v.bits) | ||||||
| 			if (bit == RTLIL::S0) bit = RTLIL::S1; | 			if (bit == State::S0) bit = State::S1; | ||||||
| 			else if (bit == RTLIL::S1) bit = RTLIL::S0; | 			else if (bit == State::S1) bit = State::S0; | ||||||
| 		return v; | 		return v; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -380,15 +389,15 @@ struct CellTypes | ||||||
| 
 | 
 | ||||||
| 			std::vector<RTLIL::State> t = cell->parameters.at("\\LUT").bits; | 			std::vector<RTLIL::State> t = cell->parameters.at("\\LUT").bits; | ||||||
| 			while (GetSize(t) < (1 << width)) | 			while (GetSize(t) < (1 << width)) | ||||||
| 				t.push_back(RTLIL::S0); | 				t.push_back(State::S0); | ||||||
| 			t.resize(1 << width); | 			t.resize(1 << width); | ||||||
| 
 | 
 | ||||||
| 			for (int i = width-1; i >= 0; i--) { | 			for (int i = width-1; i >= 0; i--) { | ||||||
| 				RTLIL::State sel = arg1.bits.at(i); | 				RTLIL::State sel = arg1.bits.at(i); | ||||||
| 				std::vector<RTLIL::State> new_t; | 				std::vector<RTLIL::State> new_t; | ||||||
| 				if (sel == RTLIL::S0) | 				if (sel == State::S0) | ||||||
| 					new_t = std::vector<RTLIL::State>(t.begin(), t.begin() + GetSize(t)/2); | 					new_t = std::vector<RTLIL::State>(t.begin(), t.begin() + GetSize(t)/2); | ||||||
| 				else if (sel == RTLIL::S1) | 				else if (sel == State::S1) | ||||||
| 					new_t = std::vector<RTLIL::State>(t.begin() + GetSize(t)/2, t.end()); | 					new_t = std::vector<RTLIL::State>(t.begin() + GetSize(t)/2, t.end()); | ||||||
| 				else | 				else | ||||||
| 					for (int j = 0; j < GetSize(t)/2; j++) | 					for (int j = 0; j < GetSize(t)/2; j++) | ||||||
|  | @ -407,7 +416,7 @@ struct CellTypes | ||||||
| 			std::vector<RTLIL::State> t = cell->parameters.at("\\TABLE").bits; | 			std::vector<RTLIL::State> t = cell->parameters.at("\\TABLE").bits; | ||||||
| 
 | 
 | ||||||
| 			while (GetSize(t) < width*depth*2) | 			while (GetSize(t) < width*depth*2) | ||||||
| 				t.push_back(RTLIL::S0); | 				t.push_back(State::S0); | ||||||
| 
 | 
 | ||||||
| 			RTLIL::State default_ret = State::S0; | 			RTLIL::State default_ret = State::S0; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -114,8 +114,8 @@ struct ConstEval | ||||||
| 				bool carry = sig_ci.as_bool(); | 				bool carry = sig_ci.as_bool(); | ||||||
| 
 | 
 | ||||||
| 				for (int i = 0; i < GetSize(coval); i++) { | 				for (int i = 0; i < GetSize(coval); i++) { | ||||||
| 					carry = (sig_g[i] == RTLIL::S1) || (sig_p[i] == RTLIL::S1 && carry); | 					carry = (sig_g[i] == State::S1) || (sig_p[i] == RTLIL::S1 && carry); | ||||||
| 					coval.bits[i] = carry ? RTLIL::S1 : RTLIL::S0; | 					coval.bits[i] = carry ? State::S1 : State::S0; | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				set(sig_co, coval); | 				set(sig_co, coval); | ||||||
|  | @ -254,8 +254,8 @@ struct ConstEval | ||||||
| 			sig_a.extend_u0(GetSize(sig_y), signed_a); | 			sig_a.extend_u0(GetSize(sig_y), signed_a); | ||||||
| 			sig_b.extend_u0(GetSize(sig_y), signed_b); | 			sig_b.extend_u0(GetSize(sig_y), signed_b); | ||||||
| 
 | 
 | ||||||
| 			bool carry = sig_ci[0] == RTLIL::S1; | 			bool carry = sig_ci[0] == State::S1; | ||||||
| 			bool b_inv = sig_bi[0] == RTLIL::S1; | 			bool b_inv = sig_bi[0] == State::S1; | ||||||
| 
 | 
 | ||||||
| 			for (int i = 0; i < GetSize(sig_y); i++) | 			for (int i = 0; i < GetSize(sig_y); i++) | ||||||
| 			{ | 			{ | ||||||
|  | @ -264,22 +264,22 @@ struct ConstEval | ||||||
| 				if (!x_inputs.is_fully_def()) { | 				if (!x_inputs.is_fully_def()) { | ||||||
| 					set(sig_x[i], RTLIL::Sx); | 					set(sig_x[i], RTLIL::Sx); | ||||||
| 				} else { | 				} else { | ||||||
| 					bool bit_a = sig_a[i] == RTLIL::S1; | 					bool bit_a = sig_a[i] == State::S1; | ||||||
| 					bool bit_b = (sig_b[i] == RTLIL::S1) != b_inv; | 					bool bit_b = (sig_b[i] == State::S1) != b_inv; | ||||||
| 					bool bit_x = bit_a != bit_b; | 					bool bit_x = bit_a != bit_b; | ||||||
| 					set(sig_x[i], bit_x ? RTLIL::S1 : RTLIL::S0); | 					set(sig_x[i], bit_x ? State::S1 : State::S0); | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				if (any_input_undef) { | 				if (any_input_undef) { | ||||||
| 					set(sig_y[i], RTLIL::Sx); | 					set(sig_y[i], RTLIL::Sx); | ||||||
| 					set(sig_co[i], RTLIL::Sx); | 					set(sig_co[i], RTLIL::Sx); | ||||||
| 				} else { | 				} else { | ||||||
| 					bool bit_a = sig_a[i] == RTLIL::S1; | 					bool bit_a = sig_a[i] == State::S1; | ||||||
| 					bool bit_b = (sig_b[i] == RTLIL::S1) != b_inv; | 					bool bit_b = (sig_b[i] == State::S1) != b_inv; | ||||||
| 					bool bit_y = (bit_a != bit_b) != carry; | 					bool bit_y = (bit_a != bit_b) != carry; | ||||||
| 					carry = (bit_a && bit_b) || (bit_a && carry) || (bit_b && carry); | 					carry = (bit_a && bit_b) || (bit_a && carry) || (bit_b && carry); | ||||||
| 					set(sig_y[i], bit_y ? RTLIL::S1 : RTLIL::S0); | 					set(sig_y[i], bit_y ? State::S1 : State::S0); | ||||||
| 					set(sig_co[i], carry ? RTLIL::S1 : RTLIL::S0); | 					set(sig_co[i], carry ? State::S1 : State::S0); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -70,9 +70,9 @@ struct Macc | ||||||
| 				while (GetSize(port.in_b) > 1 && port.in_b[GetSize(port.in_b)-1] == port.in_b[GetSize(port.in_b)-2]) | 				while (GetSize(port.in_b) > 1 && port.in_b[GetSize(port.in_b)-1] == port.in_b[GetSize(port.in_b)-2]) | ||||||
| 					port.in_b.remove(GetSize(port.in_b)-1); | 					port.in_b.remove(GetSize(port.in_b)-1); | ||||||
| 			} else { | 			} else { | ||||||
| 				while (GetSize(port.in_a) > 1 && port.in_a[GetSize(port.in_a)-1] == RTLIL::S0) | 				while (GetSize(port.in_a) > 1 && port.in_a[GetSize(port.in_a)-1] == State::S0) | ||||||
| 					port.in_a.remove(GetSize(port.in_a)-1); | 					port.in_a.remove(GetSize(port.in_a)-1); | ||||||
| 				while (GetSize(port.in_b) > 1 && port.in_b[GetSize(port.in_b)-1] == RTLIL::S0) | 				while (GetSize(port.in_b) > 1 && port.in_b[GetSize(port.in_b)-1] == State::S0) | ||||||
| 					port.in_b.remove(GetSize(port.in_b)-1); | 					port.in_b.remove(GetSize(port.in_b)-1); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | @ -80,9 +80,9 @@ struct Macc | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for (auto &bit : bit_ports) | 		for (auto &bit : bit_ports) | ||||||
| 			if (bit == RTLIL::S1) | 			if (bit == State::S1) | ||||||
| 				off = const_add(off, RTLIL::Const(1, width), false, false, width); | 				off = const_add(off, RTLIL::Const(1, width), false, false, width); | ||||||
| 			else if (bit != RTLIL::S0) | 			else if (bit != State::S0) | ||||||
| 				new_bit_ports.append(bit); | 				new_bit_ports.append(bit); | ||||||
| 
 | 
 | ||||||
| 		if (off.as_bool()) { | 		if (off.as_bool()) { | ||||||
|  | @ -113,10 +113,10 @@ struct Macc | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 		int num_bits = 0; | 		int num_bits = 0; | ||||||
| 		if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 1; | 		if (config_bits[config_cursor++] == State::S1) num_bits |= 1; | ||||||
| 		if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 2; | 		if (config_bits[config_cursor++] == State::S1) num_bits |= 2; | ||||||
| 		if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 4; | 		if (config_bits[config_cursor++] == State::S1) num_bits |= 4; | ||||||
| 		if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 8; | 		if (config_bits[config_cursor++] == State::S1) num_bits |= 8; | ||||||
| 
 | 
 | ||||||
| 		int port_a_cursor = 0; | 		int port_a_cursor = 0; | ||||||
| 		while (port_a_cursor < GetSize(port_a)) | 		while (port_a_cursor < GetSize(port_a)) | ||||||
|  | @ -124,12 +124,12 @@ struct Macc | ||||||
| 			log_assert(config_cursor + 2 + 2*num_bits <= config_width); | 			log_assert(config_cursor + 2 + 2*num_bits <= config_width); | ||||||
| 
 | 
 | ||||||
| 			port_t this_port; | 			port_t this_port; | ||||||
| 			this_port.is_signed = config_bits[config_cursor++] == RTLIL::S1; | 			this_port.is_signed = config_bits[config_cursor++] == State::S1; | ||||||
| 			this_port.do_subtract = config_bits[config_cursor++] == RTLIL::S1; | 			this_port.do_subtract = config_bits[config_cursor++] == State::S1; | ||||||
| 
 | 
 | ||||||
| 			int size_a = 0; | 			int size_a = 0; | ||||||
| 			for (int i = 0; i < num_bits; i++) | 			for (int i = 0; i < num_bits; i++) | ||||||
| 				if (config_bits[config_cursor++] == RTLIL::S1) | 				if (config_bits[config_cursor++] == State::S1) | ||||||
| 					size_a |= 1 << i; | 					size_a |= 1 << i; | ||||||
| 
 | 
 | ||||||
| 			this_port.in_a = port_a.extract(port_a_cursor, size_a); | 			this_port.in_a = port_a.extract(port_a_cursor, size_a); | ||||||
|  | @ -137,7 +137,7 @@ struct Macc | ||||||
| 
 | 
 | ||||||
| 			int size_b = 0; | 			int size_b = 0; | ||||||
| 			for (int i = 0; i < num_bits; i++) | 			for (int i = 0; i < num_bits; i++) | ||||||
| 				if (config_bits[config_cursor++] == RTLIL::S1) | 				if (config_bits[config_cursor++] == State::S1) | ||||||
| 					size_b |= 1 << i; | 					size_b |= 1 << i; | ||||||
| 
 | 
 | ||||||
| 			this_port.in_b = port_a.extract(port_a_cursor, size_b); | 			this_port.in_b = port_a.extract(port_a_cursor, size_b); | ||||||
|  | @ -166,26 +166,26 @@ struct Macc | ||||||
| 			num_bits++, max_size /= 2; | 			num_bits++, max_size /= 2; | ||||||
| 
 | 
 | ||||||
| 		log_assert(num_bits < 16); | 		log_assert(num_bits < 16); | ||||||
| 		config_bits.push_back(num_bits & 1 ? RTLIL::S1 : RTLIL::S0); | 		config_bits.push_back(num_bits & 1 ? State::S1 : State::S0); | ||||||
| 		config_bits.push_back(num_bits & 2 ? RTLIL::S1 : RTLIL::S0); | 		config_bits.push_back(num_bits & 2 ? State::S1 : State::S0); | ||||||
| 		config_bits.push_back(num_bits & 4 ? RTLIL::S1 : RTLIL::S0); | 		config_bits.push_back(num_bits & 4 ? State::S1 : State::S0); | ||||||
| 		config_bits.push_back(num_bits & 8 ? RTLIL::S1 : RTLIL::S0); | 		config_bits.push_back(num_bits & 8 ? State::S1 : State::S0); | ||||||
| 
 | 
 | ||||||
| 		for (auto &port : ports) | 		for (auto &port : ports) | ||||||
| 		{ | 		{ | ||||||
| 			if (GetSize(port.in_a) == 0) | 			if (GetSize(port.in_a) == 0) | ||||||
| 				continue; | 				continue; | ||||||
| 
 | 
 | ||||||
| 			config_bits.push_back(port.is_signed ? RTLIL::S1 : RTLIL::S0); | 			config_bits.push_back(port.is_signed ? State::S1 : State::S0); | ||||||
| 			config_bits.push_back(port.do_subtract ? RTLIL::S1 : RTLIL::S0); | 			config_bits.push_back(port.do_subtract ? State::S1 : State::S0); | ||||||
| 
 | 
 | ||||||
| 			int size_a = GetSize(port.in_a); | 			int size_a = GetSize(port.in_a); | ||||||
| 			for (int i = 0; i < num_bits; i++) | 			for (int i = 0; i < num_bits; i++) | ||||||
| 				config_bits.push_back(size_a & (1 << i) ? RTLIL::S1 : RTLIL::S0); | 				config_bits.push_back(size_a & (1 << i) ? State::S1 : State::S0); | ||||||
| 
 | 
 | ||||||
| 			int size_b = GetSize(port.in_b); | 			int size_b = GetSize(port.in_b); | ||||||
| 			for (int i = 0; i < num_bits; i++) | 			for (int i = 0; i < num_bits; i++) | ||||||
| 				config_bits.push_back(size_b & (1 << i) ? RTLIL::S1 : RTLIL::S0); | 				config_bits.push_back(size_b & (1 << i) ? State::S1 : State::S0); | ||||||
| 
 | 
 | ||||||
| 			port_a.append(port.in_a); | 			port_a.append(port.in_a); | ||||||
| 			port_a.append(port.in_b); | 			port_a.append(port.in_b); | ||||||
|  | @ -202,7 +202,7 @@ struct Macc | ||||||
| 	bool eval(RTLIL::Const &result) const | 	bool eval(RTLIL::Const &result) const | ||||||
| 	{ | 	{ | ||||||
| 		for (auto &bit : result.bits) | 		for (auto &bit : result.bits) | ||||||
| 			bit = RTLIL::S0; | 			bit = State::S0; | ||||||
| 
 | 
 | ||||||
| 		for (auto &port : ports) | 		for (auto &port : ports) | ||||||
| 		{ | 		{ | ||||||
|  |  | ||||||
|  | @ -200,7 +200,7 @@ void Pass::extra_args(std::vector<std::string> args, size_t argidx, RTLIL::Desig | ||||||
| 	{ | 	{ | ||||||
| 		std::string arg = args[argidx]; | 		std::string arg = args[argidx]; | ||||||
| 
 | 
 | ||||||
| 		if (arg.substr(0, 1) == "-") | 		if (arg.compare(0, 1, "-") == 0) | ||||||
| 			cmd_error(args, argidx, "Unknown option or option in arguments."); | 			cmd_error(args, argidx, "Unknown option or option in arguments."); | ||||||
| 
 | 
 | ||||||
| 		if (!select) | 		if (!select) | ||||||
|  | @ -449,7 +449,7 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<s | ||||||
| 	{ | 	{ | ||||||
| 		std::string arg = args[argidx]; | 		std::string arg = args[argidx]; | ||||||
| 
 | 
 | ||||||
| 		if (arg.substr(0, 1) == "-") | 		if (arg.compare(0, 1, "-") == 0) | ||||||
| 			cmd_error(args, argidx, "Unknown option or option in arguments."); | 			cmd_error(args, argidx, "Unknown option or option in arguments."); | ||||||
| 		if (f != NULL) | 		if (f != NULL) | ||||||
| 			cmd_error(args, argidx, "Extra filename argument in direct file mode."); | 			cmd_error(args, argidx, "Extra filename argument in direct file mode."); | ||||||
|  | @ -457,7 +457,7 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<s | ||||||
| 		filename = arg; | 		filename = arg; | ||||||
| 		if (filename == "<<" && argidx+1 < args.size()) | 		if (filename == "<<" && argidx+1 < args.size()) | ||||||
| 			filename += args[++argidx]; | 			filename += args[++argidx]; | ||||||
| 		if (filename.substr(0, 2) == "<<") { | 		if (filename.compare(0, 2, "<<") == 0) { | ||||||
| 			if (Frontend::current_script_file == NULL) | 			if (Frontend::current_script_file == NULL) | ||||||
| 				log_error("Unexpected here document '%s' outside of script!\n", filename.c_str()); | 				log_error("Unexpected here document '%s' outside of script!\n", filename.c_str()); | ||||||
| 			if (filename.size() <= 2) | 			if (filename.size() <= 2) | ||||||
|  | @ -475,7 +475,7 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<s | ||||||
| 						break; | 						break; | ||||||
| 				} | 				} | ||||||
| 				size_t indent = buffer.find_first_not_of(" \t\r\n"); | 				size_t indent = buffer.find_first_not_of(" \t\r\n"); | ||||||
| 				if (indent != std::string::npos && buffer.substr(indent, eot_marker.size()) == eot_marker) | 				if (indent != std::string::npos && buffer.compare(indent, eot_marker.size(), eot_marker) == 0) | ||||||
| 					break; | 					break; | ||||||
| 				last_here_document += buffer; | 				last_here_document += buffer; | ||||||
| 			} | 			} | ||||||
|  | @ -522,7 +522,7 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<s | ||||||
| 			log_cmd_error("Can't open input file `%s' for reading: %s\n", filename.c_str(), strerror(errno)); | 			log_cmd_error("Can't open input file `%s' for reading: %s\n", filename.c_str(), strerror(errno)); | ||||||
| 
 | 
 | ||||||
| 		for (size_t i = argidx+1; i < args.size(); i++) | 		for (size_t i = argidx+1; i < args.size(); i++) | ||||||
| 			if (args[i].substr(0, 1) == "-") | 			if (args[i].compare(0, 1, "-") == 0) | ||||||
| 				cmd_error(args, i, "Found option, expected arguments."); | 				cmd_error(args, i, "Found option, expected arguments."); | ||||||
| 
 | 
 | ||||||
| 		if (argidx+1 < args.size()) { | 		if (argidx+1 < args.size()) { | ||||||
|  | @ -612,7 +612,7 @@ void Backend::extra_args(std::ostream *&f, std::string &filename, std::vector<st | ||||||
| 	{ | 	{ | ||||||
| 		std::string arg = args[argidx]; | 		std::string arg = args[argidx]; | ||||||
| 
 | 
 | ||||||
| 		if (arg.substr(0, 1) == "-" && arg != "-") | 		if (arg.compare(0, 1, "-") == 0 && arg != "-") | ||||||
| 			cmd_error(args, argidx, "Unknown option or option in arguments."); | 			cmd_error(args, argidx, "Unknown option or option in arguments."); | ||||||
| 		if (f != NULL) | 		if (f != NULL) | ||||||
| 			cmd_error(args, argidx, "Extra filename argument in direct file mode."); | 			cmd_error(args, argidx, "Extra filename argument in direct file mode."); | ||||||
|  | @ -625,7 +625,7 @@ void Backend::extra_args(std::ostream *&f, std::string &filename, std::vector<st | ||||||
| 
 | 
 | ||||||
| 		filename = arg; | 		filename = arg; | ||||||
| 		rewrite_filename(filename); | 		rewrite_filename(filename); | ||||||
| 		if (filename.size() > 3 && filename.substr(filename.size()-3) == ".gz") { | 		if (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".gz") == 0) { | ||||||
| #ifdef YOSYS_ENABLE_ZLIB | #ifdef YOSYS_ENABLE_ZLIB | ||||||
| 			gzip_ostream *gf = new gzip_ostream; | 			gzip_ostream *gf = new gzip_ostream; | ||||||
| 			if (!gf->open(filename)) { | 			if (!gf->open(filename)) { | ||||||
|  |  | ||||||
|  | @ -47,7 +47,7 @@ RTLIL::Const::Const(std::string str) | ||||||
| 	for (int i = str.size()-1; i >= 0; i--) { | 	for (int i = str.size()-1; i >= 0; i--) { | ||||||
| 		unsigned char ch = str[i]; | 		unsigned char ch = str[i]; | ||||||
| 		for (int j = 0; j < 8; j++) { | 		for (int j = 0; j < 8; j++) { | ||||||
| 			bits.push_back((ch & 1) != 0 ? RTLIL::S1 : RTLIL::S0); | 			bits.push_back((ch & 1) != 0 ? State::S1 : State::S0); | ||||||
| 			ch = ch >> 1; | 			ch = ch >> 1; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -57,7 +57,7 @@ RTLIL::Const::Const(int val, int width) | ||||||
| { | { | ||||||
| 	flags = RTLIL::CONST_FLAG_NONE; | 	flags = RTLIL::CONST_FLAG_NONE; | ||||||
| 	for (int i = 0; i < width; i++) { | 	for (int i = 0; i < width; i++) { | ||||||
| 		bits.push_back((val & 1) != 0 ? RTLIL::S1 : RTLIL::S0); | 		bits.push_back((val & 1) != 0 ? State::S1 : State::S0); | ||||||
| 		val = val >> 1; | 		val = val >> 1; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | @ -73,7 +73,7 @@ RTLIL::Const::Const(const std::vector<bool> &bits) | ||||||
| { | { | ||||||
| 	flags = RTLIL::CONST_FLAG_NONE; | 	flags = RTLIL::CONST_FLAG_NONE; | ||||||
| 	for (auto b : bits) | 	for (auto b : bits) | ||||||
| 		this->bits.push_back(b ? RTLIL::S1 : RTLIL::S0); | 		this->bits.push_back(b ? State::S1 : State::S0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| RTLIL::Const::Const(const RTLIL::Const &c) | RTLIL::Const::Const(const RTLIL::Const &c) | ||||||
|  | @ -106,7 +106,7 @@ bool RTLIL::Const::operator !=(const RTLIL::Const &other) const | ||||||
| bool RTLIL::Const::as_bool() const | bool RTLIL::Const::as_bool() const | ||||||
| { | { | ||||||
| 	for (size_t i = 0; i < bits.size(); i++) | 	for (size_t i = 0; i < bits.size(); i++) | ||||||
| 		if (bits[i] == RTLIL::S1) | 		if (bits[i] == State::S1) | ||||||
| 			return true; | 			return true; | ||||||
| 	return false; | 	return false; | ||||||
| } | } | ||||||
|  | @ -115,9 +115,9 @@ int RTLIL::Const::as_int(bool is_signed) const | ||||||
| { | { | ||||||
| 	int32_t ret = 0; | 	int32_t ret = 0; | ||||||
| 	for (size_t i = 0; i < bits.size() && i < 32; i++) | 	for (size_t i = 0; i < bits.size() && i < 32; i++) | ||||||
| 		if (bits[i] == RTLIL::S1) | 		if (bits[i] == State::S1) | ||||||
| 			ret |= 1 << i; | 			ret |= 1 << i; | ||||||
| 	if (is_signed && bits.back() == RTLIL::S1) | 	if (is_signed && bits.back() == State::S1) | ||||||
| 		for (size_t i = bits.size(); i < 32; i++) | 		for (size_t i = bits.size(); i < 32; i++) | ||||||
| 			ret |= 1 << i; | 			ret |= 1 << i; | ||||||
| 	return ret; | 	return ret; | ||||||
|  | @ -828,8 +828,8 @@ namespace { | ||||||
| 
 | 
 | ||||||
| 		void check() | 		void check() | ||||||
| 		{ | 		{ | ||||||
| 			if (cell->type.substr(0, 1) != "$" || cell->type.substr(0, 3) == "$__" || cell->type.substr(0, 8) == "$paramod" || cell->type.substr(0,10) == "$fmcombine" || | 			if (!cell->type.begins_with("$") || cell->type.begins_with("$__") || cell->type.begins_with("$paramod") || cell->type.begins_with("$fmcombine") || | ||||||
| 					cell->type.substr(0, 9) == "$verific$" || cell->type.substr(0, 7) == "$array:" || cell->type.substr(0, 8) == "$extern:") | 					cell->type.begins_with("$verific$") || cell->type.begins_with("$array:") || cell->type.begins_with("$extern:")) | ||||||
| 				return; | 				return; | ||||||
| 
 | 
 | ||||||
| 			if (cell->type.in("$not", "$pos", "$neg")) { | 			if (cell->type.in("$not", "$pos", "$neg")) { | ||||||
|  | @ -940,7 +940,7 @@ namespace { | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$logic_and" || cell->type == "$logic_or") { | 			if (cell->type.in("$logic_and", "$logic_or")) { | ||||||
| 				param_bool("\\A_SIGNED"); | 				param_bool("\\A_SIGNED"); | ||||||
| 				param_bool("\\B_SIGNED"); | 				param_bool("\\B_SIGNED"); | ||||||
| 				port("\\A", param("\\A_WIDTH")); | 				port("\\A", param("\\A_WIDTH")); | ||||||
|  | @ -2553,8 +2553,8 @@ void RTLIL::Cell::check() | ||||||
| 
 | 
 | ||||||
| void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) | void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) | ||||||
| { | { | ||||||
| 	if (type.substr(0, 1) != "$" || type.substr(0, 2) == "$_" || type.substr(0, 8) == "$paramod" || type.substr(0,10) == "$fmcombine" || | 	if (!type.begins_with("$") || type.begins_with("$_") || type.begins_with("$paramod") || type.begins_with("$fmcombine") || | ||||||
| 			type.substr(0, 9) == "$verific$" || type.substr(0, 7) == "$array:" || type.substr(0, 8) == "$extern:") | 			type.begins_with("$verific$") || type.begins_with("$array:") || type.begins_with("$extern:")) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
| 	if (type == "$mux" || type == "$pmux") { | 	if (type == "$mux" || type == "$pmux") { | ||||||
|  |  | ||||||
|  | @ -276,20 +276,24 @@ namespace RTLIL | ||||||
| 				return std::string(c_str() + pos, len); | 				return std::string(c_str() + pos, len); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		int compare(size_t pos, size_t len, const char* s) const { | ||||||
|  | 			return strncmp(c_str()+pos, s, len); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		bool begins_with(const char* prefix) const { | 		bool begins_with(const char* prefix) const { | ||||||
| 			size_t len = strlen(prefix); | 			size_t len = strlen(prefix); | ||||||
| 			if (size() < len) return false; | 			if (size() < len) return false; | ||||||
| 			return substr(0, len) == prefix; | 			return compare(0, len, prefix) == 0; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		bool ends_with(const char* suffix) const { | 		bool ends_with(const char* suffix) const { | ||||||
| 			size_t len = strlen(suffix); | 			size_t len = strlen(suffix); | ||||||
| 			if (size() < len) return false; | 			if (size() < len) return false; | ||||||
| 			return substr(size()-len) == suffix; | 			return compare(size()-len, len, suffix) == 0; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		size_t size() const { | 		size_t size() const { | ||||||
| 			return str().size(); | 			return strlen(c_str()); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		bool empty() const { | 		bool empty() const { | ||||||
|  | @ -1404,7 +1408,7 @@ struct RTLIL::Process : public RTLIL::AttrObject | ||||||
| 
 | 
 | ||||||
| inline RTLIL::SigBit::SigBit() : wire(NULL), data(RTLIL::State::S0) { } | inline RTLIL::SigBit::SigBit() : wire(NULL), data(RTLIL::State::S0) { } | ||||||
| inline RTLIL::SigBit::SigBit(RTLIL::State bit) : wire(NULL), data(bit) { } | inline RTLIL::SigBit::SigBit(RTLIL::State bit) : wire(NULL), data(bit) { } | ||||||
| inline RTLIL::SigBit::SigBit(bool bit) : wire(NULL), data(bit ? RTLIL::S1 : RTLIL::S0) { } | inline RTLIL::SigBit::SigBit(bool bit) : wire(NULL), data(bit ? State::S1 : State::S0) { } | ||||||
| inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire) : wire(wire), offset(0) { log_assert(wire && wire->width == 1); } | inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire) : wire(wire), offset(0) { log_assert(wire && wire->width == 1); } | ||||||
| inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire != nullptr); } | 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) : wire(chunk.wire) { log_assert(chunk.width == 1); if (wire) offset = chunk.offset; else data = chunk.data[0]; } | ||||||
|  |  | ||||||
|  | @ -1023,7 +1023,7 @@ struct SatGen | ||||||
| 
 | 
 | ||||||
| 			std::vector<int> lut; | 			std::vector<int> lut; | ||||||
| 			for (auto bit : cell->getParam("\\LUT").bits) | 			for (auto bit : cell->getParam("\\LUT").bits) | ||||||
| 				lut.push_back(bit == RTLIL::S1 ? ez->CONST_TRUE : ez->CONST_FALSE); | 				lut.push_back(bit == State::S1 ? ez->CONST_TRUE : ez->CONST_FALSE); | ||||||
| 			while (GetSize(lut) < (1 << GetSize(a))) | 			while (GetSize(lut) < (1 << GetSize(a))) | ||||||
| 				lut.push_back(ez->CONST_FALSE); | 				lut.push_back(ez->CONST_FALSE); | ||||||
| 			lut.resize(1 << GetSize(a)); | 			lut.resize(1 << GetSize(a)); | ||||||
|  |  | ||||||
|  | @ -647,12 +647,12 @@ std::vector<std::string> glob_filename(const std::string &filename_pattern) | ||||||
| 
 | 
 | ||||||
| void rewrite_filename(std::string &filename) | void rewrite_filename(std::string &filename) | ||||||
| { | { | ||||||
| 	if (filename.substr(0, 1) == "\"" && filename.substr(GetSize(filename)-1) == "\"") | 	if (filename.compare(0, 1, "\"") == 0 && filename.compare(GetSize(filename)-1, std::string::npos, "\"") == 0) | ||||||
| 		filename = filename.substr(1, GetSize(filename)-2); | 		filename = filename.substr(1, GetSize(filename)-2); | ||||||
| 	if (filename.substr(0, 2) == "+/") | 	if (filename.compare(0, 2, "+/") == 0) | ||||||
| 		filename = proc_share_dirname() + filename.substr(2); | 		filename = proc_share_dirname() + filename.substr(2); | ||||||
| #ifndef _WIN32 | #ifndef _WIN32 | ||||||
| 	if (filename.substr(0, 2) == "~/") | 	if (filename.compare(0, 2, "~/") == 0) | ||||||
| 		filename = filename.replace(0, 1, getenv("HOME")); | 		filename = filename.replace(0, 1, getenv("HOME")); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  | @ -895,25 +895,25 @@ void run_frontend(std::string filename, std::string command, std::string *backen | ||||||
| 
 | 
 | ||||||
| 	if (command == "auto") { | 	if (command == "auto") { | ||||||
| 		std::string filename_trim = filename; | 		std::string filename_trim = filename; | ||||||
| 		if (filename_trim.size() > 3 && filename_trim.substr(filename_trim.size()-3) == ".gz") | 		if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".gz") == 0) | ||||||
| 			filename_trim.erase(filename_trim.size()-3); | 			filename_trim.erase(filename_trim.size()-3); | ||||||
| 		if (filename_trim.size() > 2 && filename_trim.substr(filename_trim.size()-2) == ".v") | 		if (filename_trim.size() > 2 && filename_trim.compare(filename_trim.size()-2, std::string::npos, ".v") == 0) | ||||||
| 			command = "verilog"; | 			command = "verilog"; | ||||||
| 		else if (filename_trim.size() > 2 && filename_trim.substr(filename_trim.size()-3) == ".sv") | 		else if (filename_trim.size() > 2 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".sv") == 0) | ||||||
| 			command = "verilog -sv"; | 			command = "verilog -sv"; | ||||||
| 		else if (filename_trim.size() > 3 && filename_trim.substr(filename_trim.size()-4) == ".vhd") | 		else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-4, std::string::npos, ".vhd") == 0) | ||||||
| 			command = "vhdl"; | 			command = "vhdl"; | ||||||
| 		else if (filename_trim.size() > 4 && filename_trim.substr(filename_trim.size()-5) == ".blif") | 		else if (filename_trim.size() > 4 && filename_trim.compare(filename_trim.size()-5, std::string::npos, ".blif") == 0) | ||||||
| 			command = "blif"; | 			command = "blif"; | ||||||
| 		else if (filename_trim.size() > 5 && filename_trim.substr(filename_trim.size()-6) == ".eblif") | 		else if (filename_trim.size() > 5 && filename_trim.compare(filename_trim.size()-6, std::string::npos, ".eblif") == 0) | ||||||
| 			command = "blif"; | 			command = "blif"; | ||||||
| 		else if (filename_trim.size() > 4 && filename_trim.substr(filename_trim.size()-5) == ".json") | 		else if (filename_trim.size() > 4 && filename_trim.compare(filename_trim.size()-5, std::string::npos, ".json") == 0) | ||||||
| 			command = "json"; | 			command = "json"; | ||||||
| 		else if (filename_trim.size() > 3 && filename_trim.substr(filename_trim.size()-3) == ".il") | 		else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".il") == 0) | ||||||
| 			command = "ilang"; | 			command = "ilang"; | ||||||
| 		else if (filename_trim.size() > 3 && filename_trim.substr(filename_trim.size()-3) == ".ys") | 		else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".ys") == 0) | ||||||
| 			command = "script"; | 			command = "script"; | ||||||
| 		else if (filename_trim.size() > 3 && filename_trim.substr(filename_trim.size()-4) == ".tcl") | 		else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-4, std::string::npos, ".tcl") == 0) | ||||||
| 			command = "tcl"; | 			command = "tcl"; | ||||||
| 		else if (filename == "-") | 		else if (filename == "-") | ||||||
| 			command = "script"; | 			command = "script"; | ||||||
|  | @ -1028,17 +1028,17 @@ void run_backend(std::string filename, std::string command, RTLIL::Design *desig | ||||||
| 		design = yosys_design; | 		design = yosys_design; | ||||||
| 
 | 
 | ||||||
| 	if (command == "auto") { | 	if (command == "auto") { | ||||||
| 		if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v") | 		if (filename.size() > 2 && filename.compare(filename.size()-2, std::string::npos, ".v") == 0) | ||||||
| 			command = "verilog"; | 			command = "verilog"; | ||||||
| 		else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") | 		else if (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0) | ||||||
| 			command = "ilang"; | 			command = "ilang"; | ||||||
| 		else if (filename.size() > 4 && filename.substr(filename.size()-4) == ".aig") | 		else if (filename.size() > 4 && filename.compare(filename.size()-4, std::string::npos, ".aig") == 0) | ||||||
| 			command = "aiger"; | 			command = "aiger"; | ||||||
| 		else if (filename.size() > 5 && filename.substr(filename.size()-5) == ".blif") | 		else if (filename.size() > 5 && filename.compare(filename.size()-5, std::string::npos, ".blif") == 0) | ||||||
| 			command = "blif"; | 			command = "blif"; | ||||||
| 		else if (filename.size() > 5 && filename.substr(filename.size()-5) == ".edif") | 		else if (filename.size() > 5 && filename.compare(filename.size()-5, std::string::npos, ".edif") == 0) | ||||||
| 			command = "edif"; | 			command = "edif"; | ||||||
| 		else if (filename.size() > 5 && filename.substr(filename.size()-5) == ".json") | 		else if (filename.size() > 5 && filename.compare(filename.size()-5, std::string::npos, ".json") == 0) | ||||||
| 			command = "json"; | 			command = "json"; | ||||||
| 		else if (filename == "-") | 		else if (filename == "-") | ||||||
| 			command = "ilang"; | 			command = "ilang"; | ||||||
|  | @ -1072,7 +1072,7 @@ static char *readline_cmd_generator(const char *text, int state) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for (; it != pass_register.end(); it++) { | 	for (; it != pass_register.end(); it++) { | ||||||
| 		if (it->first.substr(0, len) == text) | 		if (it->first.compare(0, len, text) == 0) | ||||||
| 			return strdup((it++)->first.c_str()); | 			return strdup((it++)->first.c_str()); | ||||||
| 	} | 	} | ||||||
| 	return NULL; | 	return NULL; | ||||||
|  | @ -1094,7 +1094,7 @@ static char *readline_obj_generator(const char *text, int state) | ||||||
| 		if (design->selected_active_module.empty()) | 		if (design->selected_active_module.empty()) | ||||||
| 		{ | 		{ | ||||||
| 			for (auto &it : design->modules_) | 			for (auto &it : design->modules_) | ||||||
| 				if (RTLIL::unescape_id(it.first).substr(0, len) == text) | 				if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0) | ||||||
| 					obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); | 					obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
|  | @ -1103,19 +1103,19 @@ static char *readline_obj_generator(const char *text, int state) | ||||||
| 			RTLIL::Module *module = design->modules_.at(design->selected_active_module); | 			RTLIL::Module *module = design->modules_.at(design->selected_active_module); | ||||||
| 
 | 
 | ||||||
| 			for (auto &it : module->wires_) | 			for (auto &it : module->wires_) | ||||||
| 				if (RTLIL::unescape_id(it.first).substr(0, len) == text) | 				if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0) | ||||||
| 					obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); | 					obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); | ||||||
| 
 | 
 | ||||||
| 			for (auto &it : module->memories) | 			for (auto &it : module->memories) | ||||||
| 				if (RTLIL::unescape_id(it.first).substr(0, len) == text) | 				if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0) | ||||||
| 					obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); | 					obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); | ||||||
| 
 | 
 | ||||||
| 			for (auto &it : module->cells_) | 			for (auto &it : module->cells_) | ||||||
| 				if (RTLIL::unescape_id(it.first).substr(0, len) == text) | 				if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0) | ||||||
| 					obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); | 					obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); | ||||||
| 
 | 
 | ||||||
| 			for (auto &it : module->processes) | 			for (auto &it : module->processes) | ||||||
| 				if (RTLIL::unescape_id(it.first).substr(0, len) == text) | 				if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0) | ||||||
| 					obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); | 					obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -121,7 +121,7 @@ struct CoverPass : public Pass { | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| 		while (argidx < args.size() && args[argidx].substr(0, 1) != "-") | 		while (argidx < args.size() && args[argidx].compare(0, 1, "-") != 0) | ||||||
| 			patterns.push_back(args[argidx++]); | 			patterns.push_back(args[argidx++]); | ||||||
| 		extra_args(args, argidx, design); | 		extra_args(args, argidx, design); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -34,7 +34,7 @@ static bool match_ids(RTLIL::IdString id, std::string pattern) | ||||||
| { | { | ||||||
| 	if (id == pattern) | 	if (id == pattern) | ||||||
| 		return true; | 		return true; | ||||||
| 	if (id.size() > 0 && id[0] == '\\' && id.substr(1) == pattern) | 	if (id.size() > 0 && id[0] == '\\' && id.compare(1, std::string::npos, pattern.c_str()) == 0) | ||||||
| 		return true; | 		return true; | ||||||
| 	if (patmatch(pattern.c_str(), id.c_str())) | 	if (patmatch(pattern.c_str(), id.c_str())) | ||||||
| 		return true; | 		return true; | ||||||
|  | @ -124,11 +124,11 @@ static bool match_attr(const dict<RTLIL::IdString, RTLIL::Const> &attributes, st | ||||||
| 	size_t pos = match_expr.find_first_of("<!=>"); | 	size_t pos = match_expr.find_first_of("<!=>"); | ||||||
| 
 | 
 | ||||||
| 	if (pos != std::string::npos) { | 	if (pos != std::string::npos) { | ||||||
| 		if (match_expr.substr(pos, 2) == "!=") | 		if (match_expr.compare(pos, 2, "!=") == 0) | ||||||
| 			return match_attr(attributes, match_expr.substr(0, pos), match_expr.substr(pos+2), '!'); | 			return match_attr(attributes, match_expr.substr(0, pos), match_expr.substr(pos+2), '!'); | ||||||
| 		if (match_expr.substr(pos, 2) == "<=") | 		if (match_expr.compare(pos, 2, "<=") == 0) | ||||||
| 			return match_attr(attributes, match_expr.substr(0, pos), match_expr.substr(pos+2), '['); | 			return match_attr(attributes, match_expr.substr(0, pos), match_expr.substr(pos+2), '['); | ||||||
| 		if (match_expr.substr(pos, 2) == ">=") | 		if (match_expr.compare(pos, 2, ">=") == 0) | ||||||
| 			return match_attr(attributes, match_expr.substr(0, pos), match_expr.substr(pos+2), ']'); | 			return match_attr(attributes, match_expr.substr(0, pos), match_expr.substr(pos+2), ']'); | ||||||
| 		return match_attr(attributes, match_expr.substr(0, pos), match_expr.substr(pos+1), match_expr[pos]); | 		return match_attr(attributes, match_expr.substr(0, pos), match_expr.substr(pos+1), match_expr[pos]); | ||||||
| 	} | 	} | ||||||
|  | @ -711,32 +711,32 @@ static void select_stmt(RTLIL::Design *design, std::string arg) | ||||||
| 				log_cmd_error("Must have at least one element on the stack for operator %%a.\n"); | 				log_cmd_error("Must have at least one element on the stack for operator %%a.\n"); | ||||||
| 			select_op_alias(design, work_stack[work_stack.size()-1]); | 			select_op_alias(design, work_stack[work_stack.size()-1]); | ||||||
| 		} else | 		} else | ||||||
| 		if (arg == "%x" || (arg.size() > 2 && arg.substr(0, 2) == "%x" && (arg[2] == ':' || arg[2] == '*' || arg[2] == '.' || ('0' <= arg[2] && arg[2] <= '9')))) { | 		if (arg == "%x" || (arg.size() > 2 && arg.compare(0, 2, "%x") == 0 && (arg[2] == ':' || arg[2] == '*' || arg[2] == '.' || ('0' <= arg[2] && arg[2] <= '9')))) { | ||||||
| 			if (work_stack.size() < 1) | 			if (work_stack.size() < 1) | ||||||
| 				log_cmd_error("Must have at least one element on the stack for operator %%x.\n"); | 				log_cmd_error("Must have at least one element on the stack for operator %%x.\n"); | ||||||
| 			select_op_expand(design, arg, 'x', false); | 			select_op_expand(design, arg, 'x', false); | ||||||
| 		} else | 		} else | ||||||
| 		if (arg == "%ci" || (arg.size() > 3 && arg.substr(0, 3) == "%ci" && (arg[3] == ':' || arg[3] == '*' || arg[3] == '.' || ('0' <= arg[3] && arg[3] <= '9')))) { | 		if (arg == "%ci" || (arg.size() > 3 && arg.compare(0, 3, "%ci") == 0 && (arg[3] == ':' || arg[3] == '*' || arg[3] == '.' || ('0' <= arg[3] && arg[3] <= '9')))) { | ||||||
| 			if (work_stack.size() < 1) | 			if (work_stack.size() < 1) | ||||||
| 				log_cmd_error("Must have at least one element on the stack for operator %%ci.\n"); | 				log_cmd_error("Must have at least one element on the stack for operator %%ci.\n"); | ||||||
| 			select_op_expand(design, arg, 'i', false); | 			select_op_expand(design, arg, 'i', false); | ||||||
| 		} else | 		} else | ||||||
| 		if (arg == "%co" || (arg.size() > 3 && arg.substr(0, 3) == "%co" && (arg[3] == ':' || arg[3] == '*' || arg[3] == '.' || ('0' <= arg[3] && arg[3] <= '9')))) { | 		if (arg == "%co" || (arg.size() > 3 && arg.compare(0, 3, "%co") == 0 && (arg[3] == ':' || arg[3] == '*' || arg[3] == '.' || ('0' <= arg[3] && arg[3] <= '9')))) { | ||||||
| 			if (work_stack.size() < 1) | 			if (work_stack.size() < 1) | ||||||
| 				log_cmd_error("Must have at least one element on the stack for operator %%co.\n"); | 				log_cmd_error("Must have at least one element on the stack for operator %%co.\n"); | ||||||
| 			select_op_expand(design, arg, 'o', false); | 			select_op_expand(design, arg, 'o', false); | ||||||
| 		} else | 		} else | ||||||
| 		if (arg == "%xe" || (arg.size() > 3 && arg.substr(0, 3) == "%xe" && (arg[3] == ':' || arg[3] == '*' || arg[3] == '.' || ('0' <= arg[3] && arg[3] <= '9')))) { | 		if (arg == "%xe" || (arg.size() > 3 && arg.compare(0, 3, "%xe") == 0 && (arg[3] == ':' || arg[3] == '*' || arg[3] == '.' || ('0' <= arg[3] && arg[3] <= '9')))) { | ||||||
| 			if (work_stack.size() < 1) | 			if (work_stack.size() < 1) | ||||||
| 				log_cmd_error("Must have at least one element on the stack for operator %%xe.\n"); | 				log_cmd_error("Must have at least one element on the stack for operator %%xe.\n"); | ||||||
| 			select_op_expand(design, arg, 'x', true); | 			select_op_expand(design, arg, 'x', true); | ||||||
| 		} else | 		} else | ||||||
| 		if (arg == "%cie" || (arg.size() > 4 && arg.substr(0, 4) == "%cie" && (arg[4] == ':' || arg[4] == '*' || arg[4] == '.' || ('0' <= arg[4] && arg[4] <= '9')))) { | 		if (arg == "%cie" || (arg.size() > 4 && arg.compare(0, 4, "%cie") == 0 && (arg[4] == ':' || arg[4] == '*' || arg[4] == '.' || ('0' <= arg[4] && arg[4] <= '9')))) { | ||||||
| 			if (work_stack.size() < 1) | 			if (work_stack.size() < 1) | ||||||
| 				log_cmd_error("Must have at least one element on the stack for operator %%cie.\n"); | 				log_cmd_error("Must have at least one element on the stack for operator %%cie.\n"); | ||||||
| 			select_op_expand(design, arg, 'i', true); | 			select_op_expand(design, arg, 'i', true); | ||||||
| 		} else | 		} else | ||||||
| 		if (arg == "%coe" || (arg.size() > 4 && arg.substr(0, 4) == "%coe" && (arg[4] == ':' || arg[4] == '*' || arg[4] == '.' || ('0' <= arg[4] && arg[4] <= '9')))) { | 		if (arg == "%coe" || (arg.size() > 4 && arg.compare(0, 4, "%coe") == 0 && (arg[4] == ':' || arg[4] == '*' || arg[4] == '.' || ('0' <= arg[4] && arg[4] <= '9')))) { | ||||||
| 			if (work_stack.size() < 1) | 			if (work_stack.size() < 1) | ||||||
| 				log_cmd_error("Must have at least one element on the stack for operator %%coe.\n"); | 				log_cmd_error("Must have at least one element on the stack for operator %%coe.\n"); | ||||||
| 			select_op_expand(design, arg, 'o', true); | 			select_op_expand(design, arg, 'o', true); | ||||||
|  | @ -766,7 +766,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg) | ||||||
| 	} else { | 	} else { | ||||||
| 		size_t pos = arg.find('/'); | 		size_t pos = arg.find('/'); | ||||||
| 		if (pos == std::string::npos) { | 		if (pos == std::string::npos) { | ||||||
| 			if (arg.find(':') == std::string::npos || arg.substr(0, 1) == "A") | 			if (arg.find(':') == std::string::npos || arg.compare(0, 1, "A") == 0) | ||||||
| 				arg_mod = arg; | 				arg_mod = arg; | ||||||
| 			else | 			else | ||||||
| 				arg_mod = "*", arg_memb = arg; | 				arg_mod = "*", arg_memb = arg; | ||||||
|  | @ -787,7 +787,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg) | ||||||
| 	sel.full_selection = false; | 	sel.full_selection = false; | ||||||
| 	for (auto &mod_it : design->modules_) | 	for (auto &mod_it : design->modules_) | ||||||
| 	{ | 	{ | ||||||
| 		if (arg_mod.substr(0, 2) == "A:") { | 		if (arg_mod.compare(0, 2, "A:") == 0) { | ||||||
| 			if (!match_attr(mod_it.second->attributes, arg_mod.substr(2))) | 			if (!match_attr(mod_it.second->attributes, arg_mod.substr(2))) | ||||||
| 				continue; | 				continue; | ||||||
| 		} else | 		} else | ||||||
|  | @ -800,27 +800,27 @@ static void select_stmt(RTLIL::Design *design, std::string arg) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		RTLIL::Module *mod = mod_it.second; | 		RTLIL::Module *mod = mod_it.second; | ||||||
| 		if (arg_memb.substr(0, 2) == "w:") { | 		if (arg_memb.compare(0, 2, "w:") == 0) { | ||||||
| 			for (auto &it : mod->wires_) | 			for (auto &it : mod->wires_) | ||||||
| 				if (match_ids(it.first, arg_memb.substr(2))) | 				if (match_ids(it.first, arg_memb.substr(2))) | ||||||
| 					sel.selected_members[mod->name].insert(it.first); | 					sel.selected_members[mod->name].insert(it.first); | ||||||
| 		} else | 		} else | ||||||
| 		if (arg_memb.substr(0, 2) == "i:") { | 		if (arg_memb.compare(0, 2, "i:") == 0) { | ||||||
| 			for (auto &it : mod->wires_) | 			for (auto &it : mod->wires_) | ||||||
| 				if (it.second->port_input && match_ids(it.first, arg_memb.substr(2))) | 				if (it.second->port_input && match_ids(it.first, arg_memb.substr(2))) | ||||||
| 					sel.selected_members[mod->name].insert(it.first); | 					sel.selected_members[mod->name].insert(it.first); | ||||||
| 		} else | 		} else | ||||||
| 		if (arg_memb.substr(0, 2) == "o:") { | 		if (arg_memb.compare(0, 2, "o:") == 0) { | ||||||
| 			for (auto &it : mod->wires_) | 			for (auto &it : mod->wires_) | ||||||
| 				if (it.second->port_output && match_ids(it.first, arg_memb.substr(2))) | 				if (it.second->port_output && match_ids(it.first, arg_memb.substr(2))) | ||||||
| 					sel.selected_members[mod->name].insert(it.first); | 					sel.selected_members[mod->name].insert(it.first); | ||||||
| 		} else | 		} else | ||||||
| 		if (arg_memb.substr(0, 2) == "x:") { | 		if (arg_memb.compare(0, 2, "x:") == 0) { | ||||||
| 			for (auto &it : mod->wires_) | 			for (auto &it : mod->wires_) | ||||||
| 				if ((it.second->port_input || it.second->port_output) && match_ids(it.first, arg_memb.substr(2))) | 				if ((it.second->port_input || it.second->port_output) && match_ids(it.first, arg_memb.substr(2))) | ||||||
| 					sel.selected_members[mod->name].insert(it.first); | 					sel.selected_members[mod->name].insert(it.first); | ||||||
| 		} else | 		} else | ||||||
| 		if (arg_memb.substr(0, 2) == "s:") { | 		if (arg_memb.compare(0, 2, "s:") == 0) { | ||||||
| 			size_t delim = arg_memb.substr(2).find(':'); | 			size_t delim = arg_memb.substr(2).find(':'); | ||||||
| 			if (delim == std::string::npos) { | 			if (delim == std::string::npos) { | ||||||
| 				int width = atoi(arg_memb.substr(2).c_str()); | 				int width = atoi(arg_memb.substr(2).c_str()); | ||||||
|  | @ -837,27 +837,27 @@ static void select_stmt(RTLIL::Design *design, std::string arg) | ||||||
| 						sel.selected_members[mod->name].insert(it.first); | 						sel.selected_members[mod->name].insert(it.first); | ||||||
| 			} | 			} | ||||||
| 		} else | 		} else | ||||||
| 		if (arg_memb.substr(0, 2) == "m:") { | 		if (arg_memb.compare(0, 2, "m:") == 0) { | ||||||
| 			for (auto &it : mod->memories) | 			for (auto &it : mod->memories) | ||||||
| 				if (match_ids(it.first, arg_memb.substr(2))) | 				if (match_ids(it.first, arg_memb.substr(2))) | ||||||
| 					sel.selected_members[mod->name].insert(it.first); | 					sel.selected_members[mod->name].insert(it.first); | ||||||
| 		} else | 		} else | ||||||
| 		if (arg_memb.substr(0, 2) == "c:") { | 		if (arg_memb.compare(0, 2, "c:") ==0) { | ||||||
| 			for (auto &it : mod->cells_) | 			for (auto &it : mod->cells_) | ||||||
| 				if (match_ids(it.first, arg_memb.substr(2))) | 				if (match_ids(it.first, arg_memb.substr(2))) | ||||||
| 					sel.selected_members[mod->name].insert(it.first); | 					sel.selected_members[mod->name].insert(it.first); | ||||||
| 		} else | 		} else | ||||||
| 		if (arg_memb.substr(0, 2) == "t:") { | 		if (arg_memb.compare(0, 2, "t:") == 0) { | ||||||
| 			for (auto &it : mod->cells_) | 			for (auto &it : mod->cells_) | ||||||
| 				if (match_ids(it.second->type, arg_memb.substr(2))) | 				if (match_ids(it.second->type, arg_memb.substr(2))) | ||||||
| 					sel.selected_members[mod->name].insert(it.first); | 					sel.selected_members[mod->name].insert(it.first); | ||||||
| 		} else | 		} else | ||||||
| 		if (arg_memb.substr(0, 2) == "p:") { | 		if (arg_memb.compare(0, 2, "p:") == 0) { | ||||||
| 			for (auto &it : mod->processes) | 			for (auto &it : mod->processes) | ||||||
| 				if (match_ids(it.first, arg_memb.substr(2))) | 				if (match_ids(it.first, arg_memb.substr(2))) | ||||||
| 					sel.selected_members[mod->name].insert(it.first); | 					sel.selected_members[mod->name].insert(it.first); | ||||||
| 		} else | 		} else | ||||||
| 		if (arg_memb.substr(0, 2) == "a:") { | 		if (arg_memb.compare(0, 2, "a:") == 0) { | ||||||
| 			for (auto &it : mod->wires_) | 			for (auto &it : mod->wires_) | ||||||
| 				if (match_attr(it.second->attributes, arg_memb.substr(2))) | 				if (match_attr(it.second->attributes, arg_memb.substr(2))) | ||||||
| 					sel.selected_members[mod->name].insert(it.first); | 					sel.selected_members[mod->name].insert(it.first); | ||||||
|  | @ -871,12 +871,12 @@ static void select_stmt(RTLIL::Design *design, std::string arg) | ||||||
| 				if (match_attr(it.second->attributes, arg_memb.substr(2))) | 				if (match_attr(it.second->attributes, arg_memb.substr(2))) | ||||||
| 					sel.selected_members[mod->name].insert(it.first); | 					sel.selected_members[mod->name].insert(it.first); | ||||||
| 		} else | 		} else | ||||||
| 		if (arg_memb.substr(0, 2) == "r:") { | 		if (arg_memb.compare(0, 2, "r:") == 0) { | ||||||
| 			for (auto &it : mod->cells_) | 			for (auto &it : mod->cells_) | ||||||
| 				if (match_attr(it.second->parameters, arg_memb.substr(2))) | 				if (match_attr(it.second->parameters, arg_memb.substr(2))) | ||||||
| 					sel.selected_members[mod->name].insert(it.first); | 					sel.selected_members[mod->name].insert(it.first); | ||||||
| 		} else { | 		} else { | ||||||
| 			if (arg_memb.substr(0, 2) == "n:") | 			if (arg_memb.compare(0, 2, "n:") == 0) | ||||||
| 				arg_memb = arg_memb.substr(2); | 				arg_memb = arg_memb.substr(2); | ||||||
| 			for (auto &it : mod->wires_) | 			for (auto &it : mod->wires_) | ||||||
| 				if (match_ids(it.first, arg_memb)) | 				if (match_ids(it.first, arg_memb)) | ||||||
|  | @ -927,7 +927,7 @@ void handle_extra_select_args(Pass *pass, vector<string> args, size_t argidx, si | ||||||
| { | { | ||||||
| 	work_stack.clear(); | 	work_stack.clear(); | ||||||
| 	for (; argidx < args_size; argidx++) { | 	for (; argidx < args_size; argidx++) { | ||||||
| 		if (args[argidx].substr(0, 1) == "-") { | 		if (args[argidx].compare(0, 1, "-") == 0) { | ||||||
| 			if (pass != NULL) | 			if (pass != NULL) | ||||||
| 				pass->cmd_error(args, argidx, "Unexpected option in selection arguments."); | 				pass->cmd_error(args, argidx, "Unexpected option in selection arguments."); | ||||||
| 			else | 			else | ||||||
|  |  | ||||||
|  | @ -34,7 +34,7 @@ struct setunset_t | ||||||
| 
 | 
 | ||||||
| 	setunset_t(std::string set_name, std::string set_value) : name(RTLIL::escape_id(set_name)), value(), unset(false) | 	setunset_t(std::string set_name, std::string set_value) : name(RTLIL::escape_id(set_name)), value(), unset(false) | ||||||
| 	{ | 	{ | ||||||
| 		if (set_value.substr(0, 1) == "\"" && set_value.substr(GetSize(set_value)-1) == "\"") { | 		if (set_value.compare(0, 1, "\"") == 0 && set_value.compare(GetSize(set_value)-1, std::string::npos, "\"") == 0) { | ||||||
| 			value = RTLIL::Const(set_value.substr(1, GetSize(set_value)-2)); | 			value = RTLIL::Const(set_value.substr(1, GetSize(set_value)-2)); | ||||||
| 		} else { | 		} else { | ||||||
| 			RTLIL::SigSpec sig_value; | 			RTLIL::SigSpec sig_value; | ||||||
|  |  | ||||||
|  | @ -527,11 +527,11 @@ struct ShowWorker | ||||||
| 		{ | 		{ | ||||||
| 			currentColor = xorshift32(currentColor); | 			currentColor = xorshift32(currentColor); | ||||||
| 			if (wires_on_demand.count(it.first) > 0) { | 			if (wires_on_demand.count(it.first) > 0) { | ||||||
| 				if (it.second.in.size() == 1 && it.second.out.size() > 1 && it.second.in.begin()->substr(0, 1) == "p") | 				if (it.second.in.size() == 1 && it.second.out.size() > 1 && it.second.in.begin()->compare(0, 1, "p") == 0) | ||||||
| 					it.second.out.erase(*it.second.in.begin()); | 					it.second.out.erase(*it.second.in.begin()); | ||||||
| 				if (it.second.in.size() == 1 && it.second.out.size() == 1) { | 				if (it.second.in.size() == 1 && it.second.out.size() == 1) { | ||||||
| 					std::string from = *it.second.in.begin(), to = *it.second.out.begin(); | 					std::string from = *it.second.in.begin(), to = *it.second.out.begin(); | ||||||
| 					if (from != to || from.substr(0, 1) != "p") | 					if (from != to || from.compare(0, 1, "p") != 0) | ||||||
| 						fprintf(f, "%s:e -> %s:w [%s, %s];\n", from.c_str(), to.c_str(), nextColor(it.second.color).c_str(), widthLabel(it.second.bits).c_str()); | 						fprintf(f, "%s:e -> %s:w [%s, %s];\n", from.c_str(), to.c_str(), nextColor(it.second.color).c_str(), widthLabel(it.second.bits).c_str()); | ||||||
| 					continue; | 					continue; | ||||||
| 				} | 				} | ||||||
|  | @ -808,7 +808,7 @@ struct ShowPass : public Pass { | ||||||
| 			if (f.fail()) | 			if (f.fail()) | ||||||
| 				log_error("Can't open lib file `%s'.\n", filename.c_str()); | 				log_error("Can't open lib file `%s'.\n", filename.c_str()); | ||||||
| 			RTLIL::Design *lib = new RTLIL::Design; | 			RTLIL::Design *lib = new RTLIL::Design; | ||||||
| 			Frontend::frontend_call(lib, &f, filename, (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") ? "ilang" : "verilog"); | 			Frontend::frontend_call(lib, &f, filename, (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "ilang" : "verilog")); | ||||||
| 			libs.push_back(lib); | 			libs.push_back(lib); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -97,7 +97,7 @@ struct EquivOptPass:public ScriptPass | ||||||
| 
 | 
 | ||||||
| 		for (; argidx < args.size(); argidx++) { | 		for (; argidx < args.size(); argidx++) { | ||||||
| 			if (command.empty()) { | 			if (command.empty()) { | ||||||
| 				if (args[argidx].substr(0, 1) == "-") | 				if (args[argidx].compare(0, 1, "-") == 0) | ||||||
| 					cmd_error(args, argidx, "Unknown option."); | 					cmd_error(args, argidx, "Unknown option."); | ||||||
| 			} else { | 			} else { | ||||||
| 				command += " "; | 				command += " "; | ||||||
|  |  | ||||||
|  | @ -215,9 +215,9 @@ struct EquivStructWorker | ||||||
| 					if (c != nullptr) { | 					if (c != nullptr) { | ||||||
| 						string n = cell_name.str(); | 						string n = cell_name.str(); | ||||||
| 						cells_type = c->type; | 						cells_type = c->type; | ||||||
| 						if (GetSize(n) > 5 && n.substr(GetSize(n)-5) == "_gold") | 						if (GetSize(n) > 5 && n.compare(GetSize(n)-5, std::string::npos, "_gold") == 0) | ||||||
| 							gold_cells.push_back(c); | 							gold_cells.push_back(c); | ||||||
| 						else if (GetSize(n) > 5 && n.substr(GetSize(n)-5) == "_gate") | 						else if (GetSize(n) > 5 && n.compare(GetSize(n)-5, std::string::npos, "_gate") == 0) | ||||||
| 							gate_cells.push_back(c); | 							gate_cells.push_back(c); | ||||||
| 						else | 						else | ||||||
| 							other_cells.push_back(c); | 							other_cells.push_back(c); | ||||||
|  |  | ||||||
|  | @ -50,7 +50,7 @@ struct FsmExpand | ||||||
| 		if (full_mode || cell->type == "$_MUX_") | 		if (full_mode || cell->type == "$_MUX_") | ||||||
| 			return true; | 			return true; | ||||||
| 
 | 
 | ||||||
| 		if (cell->type == "$mux" || cell->type == "$pmux") | 		if (cell->type.in("$mux", "$pmux")) | ||||||
| 			if (cell->getPort("\\A").size() < 2) | 			if (cell->getPort("\\A").size() < 2) | ||||||
| 				return true; | 				return true; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -168,7 +168,7 @@ undef_bit_in_next_state: | ||||||
| 			ctrl_in_bit_indices[ctrl_in[i]] = i; | 			ctrl_in_bit_indices[ctrl_in[i]] = i; | ||||||
| 
 | 
 | ||||||
| 		for (auto &it : ctrl_in_bit_indices) | 		for (auto &it : ctrl_in_bit_indices) | ||||||
| 			if (tr.ctrl_in.bits.at(it.second) == RTLIL::S1 && exclusive_ctrls.count(it.first) != 0) | 			if (tr.ctrl_in.bits.at(it.second) == State::S1 && exclusive_ctrls.count(it.first) != 0) | ||||||
| 				for (auto &dc_bit : exclusive_ctrls.at(it.first)) | 				for (auto &dc_bit : exclusive_ctrls.at(it.first)) | ||||||
| 					if (ctrl_in_bit_indices.count(dc_bit)) | 					if (ctrl_in_bit_indices.count(dc_bit)) | ||||||
| 						tr.ctrl_in.bits.at(ctrl_in_bit_indices.at(dc_bit)) = RTLIL::State::Sa; | 						tr.ctrl_in.bits.at(ctrl_in_bit_indices.at(dc_bit)) = RTLIL::State::Sa; | ||||||
|  | @ -216,13 +216,13 @@ undef_bit_in_next_state: | ||||||
| 		ce.push(); | 		ce.push(); | ||||||
| 		dont_care.append(undef); | 		dont_care.append(undef); | ||||||
| 		ce.set(undef, constval.as_const()); | 		ce.set(undef, constval.as_const()); | ||||||
| 		if (exclusive_ctrls.count(undef) && constval == RTLIL::S1) | 		if (exclusive_ctrls.count(undef) && constval == State::S1) | ||||||
| 			for (auto &bit : exclusive_ctrls.at(undef)) { | 			for (auto &bit : exclusive_ctrls.at(undef)) { | ||||||
| 				RTLIL::SigSpec bitval = bit; | 				RTLIL::SigSpec bitval = bit; | ||||||
| 				if (ce.eval(bitval) && bitval != RTLIL::S0) | 				if (ce.eval(bitval) && bitval != State::S0) | ||||||
| 					goto found_contradiction_1; | 					goto found_contradiction_1; | ||||||
| 				else | 				else | ||||||
| 					ce.set(bit, RTLIL::S0); | 					ce.set(bit, State::S0); | ||||||
| 			} | 			} | ||||||
| 		find_transitions(ce, ce_nostop, fsm_data, states, state_in, ctrl_in, ctrl_out, dff_in, dont_care); | 		find_transitions(ce, ce_nostop, fsm_data, states, state_in, ctrl_in, ctrl_out, dff_in, dont_care); | ||||||
| 	found_contradiction_1: | 	found_contradiction_1: | ||||||
|  | @ -231,21 +231,21 @@ undef_bit_in_next_state: | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		ce.push(), ce_nostop.push(); | 		ce.push(), ce_nostop.push(); | ||||||
| 		ce.set(undef, RTLIL::S0); | 		ce.set(undef, State::S0); | ||||||
| 		ce_nostop.set(undef, RTLIL::S0); | 		ce_nostop.set(undef, State::S0); | ||||||
| 		find_transitions(ce, ce_nostop, fsm_data, states, state_in, ctrl_in, ctrl_out, dff_in, dont_care); | 		find_transitions(ce, ce_nostop, fsm_data, states, state_in, ctrl_in, ctrl_out, dff_in, dont_care); | ||||||
| 		ce.pop(), ce_nostop.pop(); | 		ce.pop(), ce_nostop.pop(); | ||||||
| 
 | 
 | ||||||
| 		ce.push(), ce_nostop.push(); | 		ce.push(), ce_nostop.push(); | ||||||
| 		ce.set(undef, RTLIL::S1); | 		ce.set(undef, State::S1); | ||||||
| 		ce_nostop.set(undef, RTLIL::S1); | 		ce_nostop.set(undef, State::S1); | ||||||
| 		if (exclusive_ctrls.count(undef)) | 		if (exclusive_ctrls.count(undef)) | ||||||
| 			for (auto &bit : exclusive_ctrls.at(undef)) { | 			for (auto &bit : exclusive_ctrls.at(undef)) { | ||||||
| 				RTLIL::SigSpec bitval = bit; | 				RTLIL::SigSpec bitval = bit; | ||||||
| 				if ((ce.eval(bitval) || ce_nostop.eval(bitval)) && bitval != RTLIL::S0) | 				if ((ce.eval(bitval) || ce_nostop.eval(bitval)) && bitval != State::S0) | ||||||
| 					goto found_contradiction_2; | 					goto found_contradiction_2; | ||||||
| 				else | 				else | ||||||
| 					ce.set(bit, RTLIL::S0), ce_nostop.set(bit, RTLIL::S0); | 					ce.set(bit, State::S0), ce_nostop.set(bit, RTLIL::S0); | ||||||
| 			} | 			} | ||||||
| 		find_transitions(ce, ce_nostop, fsm_data, states, state_in, ctrl_in, ctrl_out, dff_in, dont_care); | 		find_transitions(ce, ce_nostop, fsm_data, states, state_in, ctrl_in, ctrl_out, dff_in, dont_care); | ||||||
| 	found_contradiction_2: | 	found_contradiction_2: | ||||||
|  | @ -263,8 +263,8 @@ static void extract_fsm(RTLIL::Wire *wire) | ||||||
| 	RTLIL::SigSpec dff_in(RTLIL::State::Sm, wire->width); | 	RTLIL::SigSpec dff_in(RTLIL::State::Sm, wire->width); | ||||||
| 	RTLIL::Const reset_state(RTLIL::State::Sx, wire->width); | 	RTLIL::Const reset_state(RTLIL::State::Sx, wire->width); | ||||||
| 
 | 
 | ||||||
| 	RTLIL::SigSpec clk = RTLIL::S0; | 	RTLIL::SigSpec clk = State::S0; | ||||||
| 	RTLIL::SigSpec arst = RTLIL::S0; | 	RTLIL::SigSpec arst = State::S0; | ||||||
| 	bool clk_polarity = true; | 	bool clk_polarity = true; | ||||||
| 	bool arst_polarity = true; | 	bool arst_polarity = true; | ||||||
| 
 | 
 | ||||||
|  | @ -371,8 +371,8 @@ static void extract_fsm(RTLIL::Wire *wire) | ||||||
| 	RTLIL::Cell *fsm_cell = module->addCell(stringf("$fsm$%s$%d", wire->name.c_str(), autoidx++), "$fsm"); | 	RTLIL::Cell *fsm_cell = module->addCell(stringf("$fsm$%s$%d", wire->name.c_str(), autoidx++), "$fsm"); | ||||||
| 	fsm_cell->setPort("\\CLK", clk); | 	fsm_cell->setPort("\\CLK", clk); | ||||||
| 	fsm_cell->setPort("\\ARST", arst); | 	fsm_cell->setPort("\\ARST", arst); | ||||||
| 	fsm_cell->parameters["\\CLK_POLARITY"] = clk_polarity ? RTLIL::S1 : RTLIL::S0; | 	fsm_cell->parameters["\\CLK_POLARITY"] = clk_polarity ? State::S1 : State::S0; | ||||||
| 	fsm_cell->parameters["\\ARST_POLARITY"] = arst_polarity ? RTLIL::S1 : RTLIL::S0; | 	fsm_cell->parameters["\\ARST_POLARITY"] = arst_polarity ? State::S1 : State::S0; | ||||||
| 	fsm_cell->setPort("\\CTRL_IN", ctrl_in); | 	fsm_cell->setPort("\\CTRL_IN", ctrl_in); | ||||||
| 	fsm_cell->setPort("\\CTRL_OUT", ctrl_out); | 	fsm_cell->setPort("\\CTRL_OUT", ctrl_out); | ||||||
| 	fsm_cell->parameters["\\NAME"] = RTLIL::Const(wire->name.str()); | 	fsm_cell->parameters["\\NAME"] = RTLIL::Const(wire->name.str()); | ||||||
|  |  | ||||||
|  | @ -133,7 +133,7 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map<RTLIL::Const | ||||||
| 			cases_vector.append(and_sig); | 			cases_vector.append(and_sig); | ||||||
| 			break; | 			break; | ||||||
| 		case 0: | 		case 0: | ||||||
| 			cases_vector.append(RTLIL::SigSpec(1, 1)); | 			cases_vector.append(State::S1); | ||||||
| 			break; | 			break; | ||||||
| 		default: | 		default: | ||||||
| 			log_abort(); | 			log_abort(); | ||||||
|  | @ -150,7 +150,7 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map<RTLIL::Const | ||||||
| 	} else if (cases_vector.size() == 1) { | 	} else if (cases_vector.size() == 1) { | ||||||
| 		module->connect(RTLIL::SigSig(output, cases_vector)); | 		module->connect(RTLIL::SigSig(output, cases_vector)); | ||||||
| 	} else { | 	} else { | ||||||
| 		module->connect(RTLIL::SigSig(output, RTLIL::SigSpec(0, 1))); | 		module->connect(RTLIL::SigSig(output, State::S0)); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -48,7 +48,7 @@ void generate(RTLIL::Design *design, const std::vector<std::string> &celltypes, | ||||||
| 		RTLIL::Cell *cell = i2.second; | 		RTLIL::Cell *cell = i2.second; | ||||||
| 		if (design->has(cell->type)) | 		if (design->has(cell->type)) | ||||||
| 			continue; | 			continue; | ||||||
| 		if (cell->type.substr(0, 1) == "$" && cell->type.substr(0, 3) != "$__") | 		if (cell->type.begins_with("$__")) | ||||||
| 			continue; | 			continue; | ||||||
| 		for (auto &pattern : celltypes) | 		for (auto &pattern : celltypes) | ||||||
| 			if (patmatch(pattern.c_str(), RTLIL::unescape_id(cell->type).c_str())) | 			if (patmatch(pattern.c_str(), RTLIL::unescape_id(cell->type).c_str())) | ||||||
|  | @ -143,7 +143,7 @@ void generate(RTLIL::Design *design, const std::vector<std::string> &celltypes, | ||||||
| // Return the "basic" type for an array item.
 | // Return the "basic" type for an array item.
 | ||||||
| std::string basic_cell_type(const std::string celltype, int pos[3] = nullptr) { | std::string basic_cell_type(const std::string celltype, int pos[3] = nullptr) { | ||||||
| 	std::string basicType = celltype; | 	std::string basicType = celltype; | ||||||
| 	if (celltype.substr(0, 7) == "$array:") { | 	if (celltype.compare(0, strlen("$array:"), "$array:") == 0) { | ||||||
| 		int pos_idx = celltype.find_first_of(':'); | 		int pos_idx = celltype.find_first_of(':'); | ||||||
| 		int pos_num = celltype.find_first_of(':', pos_idx + 1); | 		int pos_num = celltype.find_first_of(':', pos_idx + 1); | ||||||
| 		int pos_type = celltype.find_first_of(':', pos_num + 1); | 		int pos_type = celltype.find_first_of(':', pos_num + 1); | ||||||
|  | @ -194,16 +194,16 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check | ||||||
| 		std::vector<RTLIL::IdString> connections_to_add_name; | 		std::vector<RTLIL::IdString> connections_to_add_name; | ||||||
| 		std::vector<RTLIL::SigSpec> connections_to_add_signal; | 		std::vector<RTLIL::SigSpec> connections_to_add_signal; | ||||||
| 
 | 
 | ||||||
| 		if (cell->type.substr(0, 7) == "$array:") { | 		if (cell->type.begins_with("$array:")) { | ||||||
| 			int pos[3]; | 			int pos[3]; | ||||||
| 			basic_cell_type(cell->type.str(), pos); | 			basic_cell_type(cell->type.str(), pos); | ||||||
| 			int pos_idx = pos[0]; | 			int pos_idx = pos[0]; | ||||||
| 			int pos_num = pos[1]; | 			int pos_num = pos[1]; | ||||||
| 			int pos_type = pos[2]; | 			int pos_type = pos[2]; | ||||||
| 			int idx = atoi(cell->type.str().substr(pos_idx + 1, pos_num).c_str()); | 			int idx = atoi(cell->type.substr(pos_idx + 1, pos_num).c_str()); | ||||||
| 			int num = atoi(cell->type.str().substr(pos_num + 1, pos_type).c_str()); | 			int num = atoi(cell->type.substr(pos_num + 1, pos_type).c_str()); | ||||||
| 			array_cells[cell] = std::pair<int, int>(idx, num); | 			array_cells[cell] = std::pair<int, int>(idx, num); | ||||||
| 			cell->type = cell->type.str().substr(pos_type + 1); | 			cell->type = cell->type.substr(pos_type + 1); | ||||||
| 		} | 		} | ||||||
| 		dict<RTLIL::IdString, RTLIL::Module*> interfaces_to_add_to_submodule; | 		dict<RTLIL::IdString, RTLIL::Module*> interfaces_to_add_to_submodule; | ||||||
| 		dict<RTLIL::IdString, RTLIL::IdString> modports_used_in_submodule; | 		dict<RTLIL::IdString, RTLIL::IdString> modports_used_in_submodule; | ||||||
|  | @ -422,7 +422,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check | ||||||
| 		for (auto &conn : cell->connections_) { | 		for (auto &conn : cell->connections_) { | ||||||
| 			int conn_size = conn.second.size(); | 			int conn_size = conn.second.size(); | ||||||
| 			RTLIL::IdString portname = conn.first; | 			RTLIL::IdString portname = conn.first; | ||||||
| 			if (portname.substr(0, 1) == "$") { | 			if (portname.begins_with("$")) { | ||||||
| 				int port_id = atoi(portname.substr(1).c_str()); | 				int port_id = atoi(portname.substr(1).c_str()); | ||||||
| 				for (auto &wire_it : mod->wires_) | 				for (auto &wire_it : mod->wires_) | ||||||
| 					if (wire_it.second->port_id == port_id) { | 					if (wire_it.second->port_id == port_id) { | ||||||
|  | @ -457,9 +457,8 @@ void hierarchy_worker(RTLIL::Design *design, std::set<RTLIL::Module*, IdString:: | ||||||
| 
 | 
 | ||||||
| 	for (auto cell : mod->cells()) { | 	for (auto cell : mod->cells()) { | ||||||
| 		std::string celltype = cell->type.str(); | 		std::string celltype = cell->type.str(); | ||||||
| 		if (celltype.substr(0, 7) == "$array:") { | 		if (celltype.compare(0, strlen("$array:"), "$array:") == 0) | ||||||
| 			celltype = basic_cell_type(celltype); | 			celltype = basic_cell_type(celltype); | ||||||
| 		} |  | ||||||
| 		if (design->module(celltype)) | 		if (design->module(celltype)) | ||||||
| 			hierarchy_worker(design, used, design->module(celltype), indent+4); | 			hierarchy_worker(design, used, design->module(celltype), indent+4); | ||||||
| 	} | 	} | ||||||
|  | @ -521,9 +520,8 @@ int find_top_mod_score(Design *design, Module *module, dict<Module*, int> &db) | ||||||
| 		for (auto cell : module->cells()) { | 		for (auto cell : module->cells()) { | ||||||
| 			std::string celltype = cell->type.str(); | 			std::string celltype = cell->type.str(); | ||||||
| 			// Is this an array instance
 | 			// Is this an array instance
 | ||||||
| 			if (celltype.substr(0, 7) == "$array:") { | 			if (celltype.compare(0, strlen("$array:"), "$array:") == 0) | ||||||
| 				celltype = basic_cell_type(celltype); | 				celltype = basic_cell_type(celltype); | ||||||
| 			} |  | ||||||
| 			// Is this cell a module instance?
 | 			// Is this cell a module instance?
 | ||||||
| 			auto instModule = design->module(celltype); | 			auto instModule = design->module(celltype); | ||||||
| 			// If there is no instance for this, issue a warning.
 | 			// If there is no instance for this, issue a warning.
 | ||||||
|  |  | ||||||
|  | @ -194,8 +194,8 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory) | ||||||
| 	log_assert(sig_wr_en.size() == wr_ports * memory->width); | 	log_assert(sig_wr_en.size() == wr_ports * memory->width); | ||||||
| 
 | 
 | ||||||
| 	mem->parameters["\\WR_PORTS"] = Const(wr_ports); | 	mem->parameters["\\WR_PORTS"] = Const(wr_ports); | ||||||
| 	mem->parameters["\\WR_CLK_ENABLE"] = wr_ports ? sig_wr_clk_enable.as_const() : Const(0, 1); | 	mem->parameters["\\WR_CLK_ENABLE"] = wr_ports ? sig_wr_clk_enable.as_const() : State::S0; | ||||||
| 	mem->parameters["\\WR_CLK_POLARITY"] = wr_ports ? sig_wr_clk_polarity.as_const() : Const(0, 1); | 	mem->parameters["\\WR_CLK_POLARITY"] = wr_ports ? sig_wr_clk_polarity.as_const() : State::S0; | ||||||
| 
 | 
 | ||||||
| 	mem->setPort("\\WR_CLK", sig_wr_clk); | 	mem->setPort("\\WR_CLK", sig_wr_clk); | ||||||
| 	mem->setPort("\\WR_ADDR", sig_wr_addr); | 	mem->setPort("\\WR_ADDR", sig_wr_addr); | ||||||
|  | @ -209,9 +209,9 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory) | ||||||
| 	log_assert(sig_rd_data.size() == rd_ports * memory->width); | 	log_assert(sig_rd_data.size() == rd_ports * memory->width); | ||||||
| 
 | 
 | ||||||
| 	mem->parameters["\\RD_PORTS"] = Const(rd_ports); | 	mem->parameters["\\RD_PORTS"] = Const(rd_ports); | ||||||
| 	mem->parameters["\\RD_CLK_ENABLE"] = rd_ports ? sig_rd_clk_enable.as_const() : Const(0, 1); | 	mem->parameters["\\RD_CLK_ENABLE"] = rd_ports ? sig_rd_clk_enable.as_const() : State::S0; | ||||||
| 	mem->parameters["\\RD_CLK_POLARITY"] = rd_ports ? sig_rd_clk_polarity.as_const() : Const(0, 1); | 	mem->parameters["\\RD_CLK_POLARITY"] = rd_ports ? sig_rd_clk_polarity.as_const() : State::S0; | ||||||
| 	mem->parameters["\\RD_TRANSPARENT"] = rd_ports ? sig_rd_transparent.as_const() : Const(0, 1); | 	mem->parameters["\\RD_TRANSPARENT"] = rd_ports ? sig_rd_transparent.as_const() : State::S0; | ||||||
| 
 | 
 | ||||||
| 	mem->setPort("\\RD_CLK", sig_rd_clk); | 	mem->setPort("\\RD_CLK", sig_rd_clk); | ||||||
| 	mem->setPort("\\RD_ADDR", sig_rd_addr); | 	mem->setPort("\\RD_ADDR", sig_rd_addr); | ||||||
|  |  | ||||||
|  | @ -262,7 +262,7 @@ struct MemoryDffWorker | ||||||
| 				mux_cells_a[sigmap(cell->getPort("\\A"))] = cell; | 				mux_cells_a[sigmap(cell->getPort("\\A"))] = cell; | ||||||
| 				mux_cells_b[sigmap(cell->getPort("\\B"))] = cell; | 				mux_cells_b[sigmap(cell->getPort("\\B"))] = cell; | ||||||
| 			} | 			} | ||||||
| 			if (cell->type == "$not" || cell->type == "$_NOT_" || (cell->type == "$logic_not" && GetSize(cell->getPort("\\A")) == 1)) { | 			if (cell->type.in("$not", "$_NOT_") || (cell->type == "$logic_not" && GetSize(cell->getPort("\\A")) == 1)) { | ||||||
| 				SigSpec sig_a = cell->getPort("\\A"); | 				SigSpec sig_a = cell->getPort("\\A"); | ||||||
| 				SigSpec sig_y = cell->getPort("\\Y"); | 				SigSpec sig_y = cell->getPort("\\Y"); | ||||||
| 				if (cell->type == "$not") | 				if (cell->type == "$not") | ||||||
|  |  | ||||||
|  | @ -301,7 +301,7 @@ struct MemoryMapWorker | ||||||
| 
 | 
 | ||||||
| 					RTLIL::Wire *w = w_seladdr; | 					RTLIL::Wire *w = w_seladdr; | ||||||
| 
 | 
 | ||||||
| 					if (wr_bit != RTLIL::SigSpec(1, 1)) | 					if (wr_bit != State::S1) | ||||||
| 					{ | 					{ | ||||||
| 						RTLIL::Cell *c = module->addCell(genid(cell->name, "$wren", i, "", j, "", wr_offset), "$and"); | 						RTLIL::Cell *c = module->addCell(genid(cell->name, "$wren", i, "", j, "", wr_offset), "$and"); | ||||||
| 						c->parameters["\\A_SIGNED"] = RTLIL::Const(0); | 						c->parameters["\\A_SIGNED"] = RTLIL::Const(0); | ||||||
|  |  | ||||||
|  | @ -155,7 +155,7 @@ struct MemoryShareWorker | ||||||
| 		{ | 		{ | ||||||
| 			bool ignore_data_port = false; | 			bool ignore_data_port = false; | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$mux" || cell->type == "$pmux") | 			if (cell->type.in("$mux", "$pmux")) | ||||||
| 			{ | 			{ | ||||||
| 				std::vector<RTLIL::SigBit> sig_a = sigmap(cell->getPort("\\A")); | 				std::vector<RTLIL::SigBit> sig_a = sigmap(cell->getPort("\\A")); | ||||||
| 				std::vector<RTLIL::SigBit> sig_b = sigmap(cell->getPort("\\B")); | 				std::vector<RTLIL::SigBit> sig_b = sigmap(cell->getPort("\\B")); | ||||||
|  | @ -173,7 +173,7 @@ struct MemoryShareWorker | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if ((cell->type == "$memwr" || cell->type == "$memrd") && | 			if (cell->type.in("$memwr", "$memrd") && | ||||||
| 					cell->parameters.at("\\MEMID").decode_string() == memid) | 					cell->parameters.at("\\MEMID").decode_string() == memid) | ||||||
| 				ignore_data_port = true; | 				ignore_data_port = true; | ||||||
| 
 | 
 | ||||||
|  | @ -690,7 +690,7 @@ struct MemoryShareWorker | ||||||
| 					sigmap_xmux.add(cell->getPort("\\Y"), sig_a); | 					sigmap_xmux.add(cell->getPort("\\Y"), sig_a); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$mux" || cell->type == "$pmux") | 			if (cell->type.in("$mux", "$pmux")) | ||||||
| 			{ | 			{ | ||||||
| 				std::vector<RTLIL::SigBit> sig_y = sigmap(cell->getPort("\\Y")); | 				std::vector<RTLIL::SigBit> sig_y = sigmap(cell->getPort("\\Y")); | ||||||
| 				for (int i = 0; i < int(sig_y.size()); i++) | 				for (int i = 0; i < int(sig_y.size()); i++) | ||||||
|  |  | ||||||
|  | @ -49,7 +49,7 @@ struct ExclusiveDatabase | ||||||
| 			} | 			} | ||||||
| 			else if (cell->type == "$logic_not") { | 			else if (cell->type == "$logic_not") { | ||||||
| 				nonconst_sig = sigmap(cell->getPort("\\A")); | 				nonconst_sig = sigmap(cell->getPort("\\A")); | ||||||
| 				const_sig = Const(RTLIL::S0, GetSize(nonconst_sig)); | 				const_sig = Const(State::S0, GetSize(nonconst_sig)); | ||||||
| 				y_port = sigmap(cell->getPort("\\Y")); | 				y_port = sigmap(cell->getPort("\\Y")); | ||||||
| 			} | 			} | ||||||
| 			else if (cell->type == "$reduce_or") { | 			else if (cell->type == "$reduce_or") { | ||||||
|  |  | ||||||
|  | @ -222,10 +222,10 @@ bool compare_signals(RTLIL::SigBit &s1, RTLIL::SigBit &s2, SigPool ®s, SigPoo | ||||||
| 
 | 
 | ||||||
| bool check_public_name(RTLIL::IdString id) | bool check_public_name(RTLIL::IdString id) | ||||||
| { | { | ||||||
| 	const std::string &id_str = id.str(); | 	if (id.begins_with("$")) | ||||||
| 	if (id_str[0] == '$') |  | ||||||
| 		return false; | 		return false; | ||||||
| 	if (id_str.substr(0, 2) == "\\_" && (id_str[id_str.size()-1] == '_' || id_str.find("_[") != std::string::npos)) | 	const std::string &id_str = id.str(); | ||||||
|  | 	if (id.begins_with("\\_") && (id.ends_with("_") || id_str.find("_[") != std::string::npos)) | ||||||
| 		return false; | 		return false; | ||||||
| 	if (id_str.find(".$") != std::string::npos) | 	if (id_str.find(".$") != std::string::npos) | ||||||
| 		return false; | 		return false; | ||||||
|  |  | ||||||
|  | @ -367,10 +367,11 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 
 | 
 | ||||||
| 	for (auto cell : module->cells()) | 	for (auto cell : module->cells()) | ||||||
| 		if (design->selected(module, cell) && cell->type[0] == '$') { | 		if (design->selected(module, cell) && cell->type[0] == '$') { | ||||||
| 			if ((cell->type == "$_NOT_" || cell->type == "$not" || cell->type == "$logic_not") && | 			if (cell->type.in("$_NOT_", "$not", "$logic_not") && | ||||||
| 					cell->getPort("\\A").size() == 1 && cell->getPort("\\Y").size() == 1) | 					cell->getPort("\\A").size() == 1 && cell->getPort("\\Y").size() == 1) | ||||||
| 				invert_map[assign_map(cell->getPort("\\Y"))] = assign_map(cell->getPort("\\A")); | 				invert_map[assign_map(cell->getPort("\\Y"))] = assign_map(cell->getPort("\\A")); | ||||||
| 			if ((cell->type == "$mux" || cell->type == "$_MUX_") && cell->getPort("\\A") == SigSpec(State::S1) && cell->getPort("\\B") == SigSpec(State::S0)) | 			if (cell->type.in("$mux", "$_MUX_") && | ||||||
|  | 					cell->getPort("\\A") == SigSpec(State::S1) && cell->getPort("\\B") == SigSpec(State::S0)) | ||||||
| 				invert_map[assign_map(cell->getPort("\\Y"))] = assign_map(cell->getPort("\\S")); | 				invert_map[assign_map(cell->getPort("\\Y"))] = assign_map(cell->getPort("\\S")); | ||||||
| 			if (ct_combinational.cell_known(cell->type)) | 			if (ct_combinational.cell_known(cell->type)) | ||||||
| 				for (auto &conn : cell->connections()) { | 				for (auto &conn : cell->connections()) { | ||||||
|  | @ -512,13 +513,11 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 
 | 
 | ||||||
| 		if (do_fine) | 		if (do_fine) | ||||||
| 		{ | 		{ | ||||||
| 			if (cell->type == "$not" || cell->type == "$pos" || | 			if (cell->type.in("$not", "$pos", "$and", "$or", "$xor", "$xnor")) | ||||||
| 					cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor") |  | ||||||
| 				if (group_cell_inputs(module, cell, true, assign_map)) | 				if (group_cell_inputs(module, cell, true, assign_map)) | ||||||
| 					goto next_cell; | 					goto next_cell; | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$logic_not" || cell->type == "$logic_and" || cell->type == "$logic_or" || | 			if (cell->type.in("$logic_not", "$logic_and", "$logic_or", "$reduce_or", "$reduce_and", "$reduce_bool")) | ||||||
| 					cell->type == "$reduce_or" || cell->type == "$reduce_and" || cell->type == "$reduce_bool") |  | ||||||
| 			{ | 			{ | ||||||
| 				SigBit neutral_bit = cell->type == "$reduce_and" ? State::S1 : State::S0; | 				SigBit neutral_bit = cell->type == "$reduce_and" ? State::S1 : State::S0; | ||||||
| 
 | 
 | ||||||
|  | @ -541,7 +540,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$logic_and" || cell->type == "$logic_or") | 			if (cell->type.in("$logic_and", "$logic_or")) | ||||||
| 			{ | 			{ | ||||||
| 				SigBit neutral_bit = State::S0; | 				SigBit neutral_bit = State::S0; | ||||||
| 
 | 
 | ||||||
|  | @ -590,7 +589,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$logic_not" || cell->type == "$logic_and" || cell->type == "$logic_or" || cell->type == "$reduce_or" || cell->type == "$reduce_bool") | 			if (cell->type.in("$logic_not", "$logic_and", "$logic_or", "$reduce_or", "$reduce_bool")) | ||||||
| 			{ | 			{ | ||||||
| 				RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); | 				RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); | ||||||
| 
 | 
 | ||||||
|  | @ -616,7 +615,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$logic_and" || cell->type == "$logic_or") | 			if (cell->type.in("$logic_and", "$logic_or")) | ||||||
| 			{ | 			{ | ||||||
| 				RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B")); | 				RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B")); | ||||||
| 
 | 
 | ||||||
|  | @ -642,7 +641,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (cell->type.in("$add", "$sub")) { | 			if (cell->type.in("$add", "$sub")) | ||||||
|  | 			{ | ||||||
| 				RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); | 				RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); | ||||||
| 				RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B")); | 				RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B")); | ||||||
| 				RTLIL::SigSpec sig_y = cell->getPort("\\Y"); | 				RTLIL::SigSpec sig_y = cell->getPort("\\Y"); | ||||||
|  | @ -666,18 +666,62 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 					did_something = true; | 					did_something = true; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | 
 | ||||||
|  | 			if (cell->type == "$alu") | ||||||
|  | 			{ | ||||||
|  | 				RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); | ||||||
|  | 				RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B")); | ||||||
|  | 				RTLIL::SigBit sig_ci = assign_map(cell->getPort("\\CI")); | ||||||
|  | 				RTLIL::SigBit sig_bi = assign_map(cell->getPort("\\BI")); | ||||||
|  | 				RTLIL::SigSpec sig_x = cell->getPort("\\X"); | ||||||
|  | 				RTLIL::SigSpec sig_y = cell->getPort("\\Y"); | ||||||
|  | 				RTLIL::SigSpec sig_co = cell->getPort("\\CO"); | ||||||
|  | 
 | ||||||
|  | 				if (sig_ci.wire || sig_bi.wire) | ||||||
|  | 					goto next_cell; | ||||||
|  | 
 | ||||||
|  | 				bool sub = (sig_ci == State::S1 && sig_bi == State::S1); | ||||||
|  | 
 | ||||||
|  | 				// If not a subtraction, yet there is a carry or B is inverted
 | ||||||
|  | 				//   then no optimisation is possible as carry will not be constant
 | ||||||
|  | 				if (!sub && (sig_ci != State::S0 || sig_bi != State::S0)) | ||||||
|  | 					goto next_cell; | ||||||
|  | 
 | ||||||
|  | 				int i; | ||||||
|  | 				for (i = 0; i < GetSize(sig_y); i++) { | ||||||
|  | 					if (sig_b.at(i, State::Sx) == State::S0 && sig_a.at(i, State::Sx) != State::Sx) { | ||||||
|  | 						module->connect(sig_x[i], sub ? module->Not(NEW_ID, sig_a[i]).as_bit() : sig_a[i]); | ||||||
|  | 						module->connect(sig_y[i], sig_a[i]); | ||||||
|  | 						module->connect(sig_co[i], sub ? State::S1 : State::S0); | ||||||
|  | 					} | ||||||
|  | 					else if (!sub && sig_a.at(i, State::Sx) == State::S0 && sig_b.at(i, State::Sx) != State::Sx) { | ||||||
|  | 						module->connect(sig_x[i], sig_b[i]); | ||||||
|  | 						module->connect(sig_y[i], sig_b[i]); | ||||||
|  | 						module->connect(sig_co[i], State::S0); | ||||||
|  | 					} | ||||||
|  | 					else | ||||||
|  | 						break; | ||||||
|  | 				} | ||||||
|  | 				if (i > 0) { | ||||||
|  | 					cover("opt.opt_expr.fine.$alu"); | ||||||
|  | 					cell->setPort("\\A", sig_a.extract_end(i)); | ||||||
|  | 					cell->setPort("\\B", sig_b.extract_end(i)); | ||||||
|  | 					cell->setPort("\\X", sig_x.extract_end(i)); | ||||||
|  | 					cell->setPort("\\Y", sig_y.extract_end(i)); | ||||||
|  | 					cell->setPort("\\CO", sig_co.extract_end(i)); | ||||||
|  | 					cell->fixup_parameters(); | ||||||
|  | 					did_something = true; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" || cell->type == "$shift" || cell->type == "$shiftx" || | 		if (cell->type.in("$reduce_xor", "$reduce_xnor", "$shift", "$shiftx", "$shl", "$shr", "$sshl", "$sshr", | ||||||
| 				cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" || | 					"$lt", "$le", "$ge", "$gt", "$neg", "$add", "$sub", "$mul", "$div", "$mod", "$pow")) | ||||||
| 				cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt" || |  | ||||||
| 				cell->type == "$neg" || cell->type == "$add" || cell->type == "$sub" || |  | ||||||
| 				cell->type == "$mul" || cell->type == "$div" || cell->type == "$mod" || cell->type == "$pow") |  | ||||||
| 		{ | 		{ | ||||||
| 			RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); | 			RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); | ||||||
| 			RTLIL::SigSpec sig_b = cell->hasPort("\\B") ? assign_map(cell->getPort("\\B")) : RTLIL::SigSpec(); | 			RTLIL::SigSpec sig_b = cell->hasPort("\\B") ? assign_map(cell->getPort("\\B")) : RTLIL::SigSpec(); | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" || cell->type == "$shift" || cell->type == "$shiftx") | 			if (cell->type.in("$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx")) | ||||||
| 				sig_a = RTLIL::SigSpec(); | 				sig_a = RTLIL::SigSpec(); | ||||||
| 
 | 
 | ||||||
| 			for (auto &bit : sig_a.to_sigbit_vector()) | 			for (auto &bit : sig_a.to_sigbit_vector()) | ||||||
|  | @ -692,8 +736,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 		found_the_x_bit: | 		found_the_x_bit: | ||||||
| 				cover_list("opt.opt_expr.xbit", "$reduce_xor", "$reduce_xnor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", | 				cover_list("opt.opt_expr.xbit", "$reduce_xor", "$reduce_xnor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", | ||||||
| 						"$lt", "$le", "$ge", "$gt", "$neg", "$add", "$sub", "$mul", "$div", "$mod", "$pow", cell->type.str()); | 						"$lt", "$le", "$ge", "$gt", "$neg", "$add", "$sub", "$mul", "$div", "$mod", "$pow", cell->type.str()); | ||||||
| 				if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" || | 				if (cell->type.in("$reduce_xor", "$reduce_xnor", "$lt", "$le", "$ge", "$gt")) | ||||||
| 						cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt") |  | ||||||
| 					replace_cell(assign_map, module, cell, "x-bit in input", "\\Y", RTLIL::State::Sx); | 					replace_cell(assign_map, module, cell, "x-bit in input", "\\Y", RTLIL::State::Sx); | ||||||
| 				else | 				else | ||||||
| 					replace_cell(assign_map, module, cell, "x-bit in input", "\\Y", RTLIL::SigSpec(RTLIL::State::Sx, cell->getPort("\\Y").size())); | 					replace_cell(assign_map, module, cell, "x-bit in input", "\\Y", RTLIL::SigSpec(RTLIL::State::Sx, cell->getPort("\\Y").size())); | ||||||
|  | @ -701,14 +744,14 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if ((cell->type == "$_NOT_" || cell->type == "$not" || cell->type == "$logic_not") && cell->getPort("\\Y").size() == 1 && | 		if (cell->type.in("$_NOT_", "$not", "$logic_not") && cell->getPort("\\Y").size() == 1 && | ||||||
| 				invert_map.count(assign_map(cell->getPort("\\A"))) != 0) { | 				invert_map.count(assign_map(cell->getPort("\\A"))) != 0) { | ||||||
| 			cover_list("opt.opt_expr.invert.double", "$_NOT_", "$not", "$logic_not", cell->type.str()); | 			cover_list("opt.opt_expr.invert.double", "$_NOT_", "$not", "$logic_not", cell->type.str()); | ||||||
| 			replace_cell(assign_map, module, cell, "double_invert", "\\Y", invert_map.at(assign_map(cell->getPort("\\A")))); | 			replace_cell(assign_map, module, cell, "double_invert", "\\Y", invert_map.at(assign_map(cell->getPort("\\A")))); | ||||||
| 			goto next_cell; | 			goto next_cell; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if ((cell->type == "$_MUX_" || cell->type == "$mux") && invert_map.count(assign_map(cell->getPort("\\S"))) != 0) { | 		if (cell->type.in("$_MUX_", "$mux") && invert_map.count(assign_map(cell->getPort("\\S"))) != 0) { | ||||||
| 			cover_list("opt.opt_expr.invert.muxsel", "$_MUX_", "$mux", cell->type.str()); | 			cover_list("opt.opt_expr.invert.muxsel", "$_MUX_", "$mux", cell->type.str()); | ||||||
| 			log_debug("Optimizing away select inverter for %s cell `%s' in module `%s'.\n", log_id(cell->type), log_id(cell), log_id(module)); | 			log_debug("Optimizing away select inverter for %s cell `%s' in module `%s'.\n", log_id(cell->type), log_id(cell), log_id(module)); | ||||||
| 			RTLIL::SigSpec tmp = cell->getPort("\\A"); | 			RTLIL::SigSpec tmp = cell->getPort("\\A"); | ||||||
|  | @ -811,7 +854,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (cell->type == "$_TBUF_" || cell->type == "$tribuf") { | 		if (cell->type.in("$_TBUF_", "$tribuf")) { | ||||||
| 			RTLIL::SigSpec input = cell->getPort(cell->type == "$_TBUF_" ? "\\E" : "\\EN"); | 			RTLIL::SigSpec input = cell->getPort(cell->type == "$_TBUF_" ? "\\E" : "\\EN"); | ||||||
| 			RTLIL::SigSpec a = cell->getPort("\\A"); | 			RTLIL::SigSpec a = cell->getPort("\\A"); | ||||||
| 			assign_map.apply(input); | 			assign_map.apply(input); | ||||||
|  | @ -828,7 +871,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (cell->type == "$eq" || cell->type == "$ne" || cell->type == "$eqx" || cell->type == "$nex") | 		if (cell->type.in("$eq", "$ne", "$eqx", "$nex")) | ||||||
| 		{ | 		{ | ||||||
| 			RTLIL::SigSpec a = cell->getPort("\\A"); | 			RTLIL::SigSpec a = cell->getPort("\\A"); | ||||||
| 			RTLIL::SigSpec b = cell->getPort("\\B"); | 			RTLIL::SigSpec b = cell->getPort("\\B"); | ||||||
|  | @ -845,7 +888,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 			for (int i = 0; i < GetSize(a); i++) { | 			for (int i = 0; i < GetSize(a); i++) { | ||||||
| 				if (a[i].wire == NULL && b[i].wire == NULL && a[i] != b[i] && a[i].data <= RTLIL::State::S1 && b[i].data <= RTLIL::State::S1) { | 				if (a[i].wire == NULL && b[i].wire == NULL && a[i] != b[i] && a[i].data <= RTLIL::State::S1 && b[i].data <= RTLIL::State::S1) { | ||||||
| 					cover_list("opt.opt_expr.eqneq.isneq", "$eq", "$ne", "$eqx", "$nex", cell->type.str()); | 					cover_list("opt.opt_expr.eqneq.isneq", "$eq", "$ne", "$eqx", "$nex", cell->type.str()); | ||||||
| 					RTLIL::SigSpec new_y = RTLIL::SigSpec((cell->type == "$eq" || cell->type == "$eqx") ?  RTLIL::State::S0 : RTLIL::State::S1); | 					RTLIL::SigSpec new_y = RTLIL::SigSpec(cell->type.in("$eq", "$eqx") ?  RTLIL::State::S0 : RTLIL::State::S1); | ||||||
| 					new_y.extend_u0(cell->parameters["\\Y_WIDTH"].as_int(), false); | 					new_y.extend_u0(cell->parameters["\\Y_WIDTH"].as_int(), false); | ||||||
| 					replace_cell(assign_map, module, cell, "isneq", "\\Y", new_y); | 					replace_cell(assign_map, module, cell, "isneq", "\\Y", new_y); | ||||||
| 					goto next_cell; | 					goto next_cell; | ||||||
|  | @ -858,7 +901,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 
 | 
 | ||||||
| 			if (new_a.size() == 0) { | 			if (new_a.size() == 0) { | ||||||
| 				cover_list("opt.opt_expr.eqneq.empty", "$eq", "$ne", "$eqx", "$nex", cell->type.str()); | 				cover_list("opt.opt_expr.eqneq.empty", "$eq", "$ne", "$eqx", "$nex", cell->type.str()); | ||||||
| 				RTLIL::SigSpec new_y = RTLIL::SigSpec((cell->type == "$eq" || cell->type == "$eqx") ?  RTLIL::State::S1 : RTLIL::State::S0); | 				RTLIL::SigSpec new_y = RTLIL::SigSpec(cell->type.in("$eq", "$eqx") ?  RTLIL::State::S1 : RTLIL::State::S0); | ||||||
| 				new_y.extend_u0(cell->parameters["\\Y_WIDTH"].as_int(), false); | 				new_y.extend_u0(cell->parameters["\\Y_WIDTH"].as_int(), false); | ||||||
| 				replace_cell(assign_map, module, cell, "empty", "\\Y", new_y); | 				replace_cell(assign_map, module, cell, "empty", "\\Y", new_y); | ||||||
| 				goto next_cell; | 				goto next_cell; | ||||||
|  | @ -873,7 +916,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if ((cell->type == "$eq" || cell->type == "$ne") && cell->parameters["\\Y_WIDTH"].as_int() == 1 && | 		if (cell->type.in("$eq", "$ne") && cell->parameters["\\Y_WIDTH"].as_int() == 1 && | ||||||
| 				cell->parameters["\\A_WIDTH"].as_int() == 1 && cell->parameters["\\B_WIDTH"].as_int() == 1) | 				cell->parameters["\\A_WIDTH"].as_int() == 1 && cell->parameters["\\B_WIDTH"].as_int() == 1) | ||||||
| 		{ | 		{ | ||||||
| 			RTLIL::SigSpec a = assign_map(cell->getPort("\\A")); | 			RTLIL::SigSpec a = assign_map(cell->getPort("\\A")); | ||||||
|  | @ -903,7 +946,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if ((cell->type == "$eq" || cell->type == "$ne") && | 		if (cell->type.in("$eq", "$ne") && | ||||||
| 				(assign_map(cell->getPort("\\A")).is_fully_zero() || assign_map(cell->getPort("\\B")).is_fully_zero())) | 				(assign_map(cell->getPort("\\A")).is_fully_zero() || assign_map(cell->getPort("\\B")).is_fully_zero())) | ||||||
| 		{ | 		{ | ||||||
| 			cover_list("opt.opt_expr.eqneq.cmpzero", "$eq", "$ne", cell->type.str()); | 			cover_list("opt.opt_expr.eqneq.cmpzero", "$eq", "$ne", cell->type.str()); | ||||||
|  | @ -962,7 +1005,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 			bool identity_wrt_b = false; | 			bool identity_wrt_b = false; | ||||||
| 			bool arith_inverse = false; | 			bool arith_inverse = false; | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$add" || cell->type == "$sub" || cell->type == "$or" || cell->type == "$xor") | 			if (cell->type.in("$add", "$sub", "$or", "$xor")) | ||||||
| 			{ | 			{ | ||||||
| 				RTLIL::SigSpec a = assign_map(cell->getPort("\\A")); | 				RTLIL::SigSpec a = assign_map(cell->getPort("\\A")); | ||||||
| 				RTLIL::SigSpec b = assign_map(cell->getPort("\\B")); | 				RTLIL::SigSpec b = assign_map(cell->getPort("\\B")); | ||||||
|  | @ -974,7 +1017,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 					identity_wrt_a = true; | 					identity_wrt_a = true; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" || cell->type == "$shift" || cell->type == "$shiftx") | 			if (cell->type.in("$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx")) | ||||||
| 			{ | 			{ | ||||||
| 				RTLIL::SigSpec b = assign_map(cell->getPort("\\B")); | 				RTLIL::SigSpec b = assign_map(cell->getPort("\\B")); | ||||||
| 
 | 
 | ||||||
|  | @ -1029,15 +1072,15 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && | 		if (mux_bool && cell->type.in("$mux", "$_MUX_") && | ||||||
| 				cell->getPort("\\A") == RTLIL::SigSpec(0, 1) && cell->getPort("\\B") == RTLIL::SigSpec(1, 1)) { | 				cell->getPort("\\A") == State::S0 && cell->getPort("\\B") == State::S1) { | ||||||
| 			cover_list("opt.opt_expr.mux_bool", "$mux", "$_MUX_", cell->type.str()); | 			cover_list("opt.opt_expr.mux_bool", "$mux", "$_MUX_", cell->type.str()); | ||||||
| 			replace_cell(assign_map, module, cell, "mux_bool", "\\Y", cell->getPort("\\S")); | 			replace_cell(assign_map, module, cell, "mux_bool", "\\Y", cell->getPort("\\S")); | ||||||
| 			goto next_cell; | 			goto next_cell; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && | 		if (mux_bool && cell->type.in("$mux", "$_MUX_") && | ||||||
| 				cell->getPort("\\A") == RTLIL::SigSpec(1, 1) && cell->getPort("\\B") == RTLIL::SigSpec(0, 1)) { | 				cell->getPort("\\A") == State::S1 && cell->getPort("\\B") == State::S0) { | ||||||
| 			cover_list("opt.opt_expr.mux_invert", "$mux", "$_MUX_", cell->type.str()); | 			cover_list("opt.opt_expr.mux_invert", "$mux", "$_MUX_", cell->type.str()); | ||||||
| 			log_debug("Replacing %s cell `%s' in module `%s' with inverter.\n", log_id(cell->type), log_id(cell), log_id(module)); | 			log_debug("Replacing %s cell `%s' in module `%s' with inverter.\n", log_id(cell->type), log_id(cell), log_id(module)); | ||||||
| 			cell->setPort("\\A", cell->getPort("\\S")); | 			cell->setPort("\\A", cell->getPort("\\S")); | ||||||
|  | @ -1056,7 +1099,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 			goto next_cell; | 			goto next_cell; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->getPort("\\A") == RTLIL::SigSpec(0, 1)) { | 		if (consume_x && mux_bool && cell->type.in("$mux", "$_MUX_") && cell->getPort("\\A") == State::S0) { | ||||||
| 			cover_list("opt.opt_expr.mux_and", "$mux", "$_MUX_", cell->type.str()); | 			cover_list("opt.opt_expr.mux_and", "$mux", "$_MUX_", cell->type.str()); | ||||||
| 			log_debug("Replacing %s cell `%s' in module `%s' with and-gate.\n", log_id(cell->type), log_id(cell), log_id(module)); | 			log_debug("Replacing %s cell `%s' in module `%s' with and-gate.\n", log_id(cell->type), log_id(cell), log_id(module)); | ||||||
| 			cell->setPort("\\A", cell->getPort("\\S")); | 			cell->setPort("\\A", cell->getPort("\\S")); | ||||||
|  | @ -1076,7 +1119,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 			goto next_cell; | 			goto next_cell; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->getPort("\\B") == RTLIL::SigSpec(1, 1)) { | 		if (consume_x && mux_bool && cell->type.in("$mux", "$_MUX_") && cell->getPort("\\B") == State::S1) { | ||||||
| 			cover_list("opt.opt_expr.mux_or", "$mux", "$_MUX_", cell->type.str()); | 			cover_list("opt.opt_expr.mux_or", "$mux", "$_MUX_", cell->type.str()); | ||||||
| 			log_debug("Replacing %s cell `%s' in module `%s' with or-gate.\n", log_id(cell->type), log_id(cell), log_id(module)); | 			log_debug("Replacing %s cell `%s' in module `%s' with or-gate.\n", log_id(cell->type), log_id(cell), log_id(module)); | ||||||
| 			cell->setPort("\\B", cell->getPort("\\S")); | 			cell->setPort("\\B", cell->getPort("\\S")); | ||||||
|  | @ -1096,7 +1139,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 			goto next_cell; | 			goto next_cell; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (mux_undef && (cell->type == "$mux" || cell->type == "$pmux")) { | 		if (mux_undef && cell->type.in("$mux", "$pmux")) { | ||||||
| 			RTLIL::SigSpec new_a, new_b, new_s; | 			RTLIL::SigSpec new_a, new_b, new_s; | ||||||
| 			int width = cell->getPort("\\A").size(); | 			int width = cell->getPort("\\A").size(); | ||||||
| 			if ((cell->getPort("\\A").is_fully_undef() && cell->getPort("\\B").is_fully_undef()) || | 			if ((cell->getPort("\\A").is_fully_undef() && cell->getPort("\\B").is_fully_undef()) || | ||||||
|  | @ -1438,7 +1481,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// simplify comparisons
 | 		// simplify comparisons
 | ||||||
| 		if (do_fine && (cell->type == "$lt" || cell->type == "$ge" || cell->type == "$gt" || cell->type == "$le")) | 		if (do_fine && cell->type.in("$lt", "$ge", "$gt", "$le")) | ||||||
| 		{ | 		{ | ||||||
| 			IdString cmp_type = cell->type; | 			IdString cmp_type = cell->type; | ||||||
| 			SigSpec var_sig = cell->getPort("\\A"); | 			SigSpec var_sig = cell->getPort("\\A"); | ||||||
|  |  | ||||||
|  | @ -101,6 +101,12 @@ struct OptLutWorker | ||||||
| 		{ | 		{ | ||||||
| 			if (cell->type == "$lut") | 			if (cell->type == "$lut") | ||||||
| 			{ | 			{ | ||||||
|  | 				if (cell->has_keep_attr()) | ||||||
|  | 					continue; | ||||||
|  | 				SigBit lut_output = cell->getPort("\\Y"); | ||||||
|  | 				if (lut_output.wire->get_bool_attribute("\\keep")) | ||||||
|  | 					continue; | ||||||
|  | 
 | ||||||
| 				int lut_width = cell->getParam("\\WIDTH").as_int(); | 				int lut_width = cell->getParam("\\WIDTH").as_int(); | ||||||
| 				SigSpec lut_input = cell->getPort("\\A"); | 				SigSpec lut_input = cell->getPort("\\A"); | ||||||
| 				int lut_arity = 0; | 				int lut_arity = 0; | ||||||
|  |  | ||||||
|  | @ -94,8 +94,8 @@ struct OptMergeWorker | ||||||
| 		const dict<RTLIL::IdString, RTLIL::SigSpec> *conn = &cell->connections(); | 		const dict<RTLIL::IdString, RTLIL::SigSpec> *conn = &cell->connections(); | ||||||
| 		dict<RTLIL::IdString, RTLIL::SigSpec> alt_conn; | 		dict<RTLIL::IdString, RTLIL::SigSpec> alt_conn; | ||||||
| 
 | 
 | ||||||
| 		if (cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor" || cell->type == "$add" || cell->type == "$mul" || | 		if (cell->type.in("$and", "$or", "$xor", "$xnor", "$add", "$mul", | ||||||
| 				cell->type == "$logic_and" || cell->type == "$logic_or" || cell->type == "$_AND_" || cell->type == "$_OR_" || cell->type == "$_XOR_") { | 				"$logic_and", "$logic_or", "$_AND_", "$_OR_", "$_XOR_")) { | ||||||
| 			alt_conn = *conn; | 			alt_conn = *conn; | ||||||
| 			if (assign_map(alt_conn.at("\\A")) < assign_map(alt_conn.at("\\B"))) { | 			if (assign_map(alt_conn.at("\\A")) < assign_map(alt_conn.at("\\B"))) { | ||||||
| 				alt_conn["\\A"] = conn->at("\\B"); | 				alt_conn["\\A"] = conn->at("\\B"); | ||||||
|  | @ -103,13 +103,13 @@ struct OptMergeWorker | ||||||
| 			} | 			} | ||||||
| 			conn = &alt_conn; | 			conn = &alt_conn; | ||||||
| 		} else | 		} else | ||||||
| 		if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor") { | 		if (cell->type.in("$reduce_xor", "$reduce_xnor")) { | ||||||
| 			alt_conn = *conn; | 			alt_conn = *conn; | ||||||
| 			assign_map.apply(alt_conn.at("\\A")); | 			assign_map.apply(alt_conn.at("\\A")); | ||||||
| 			alt_conn.at("\\A").sort(); | 			alt_conn.at("\\A").sort(); | ||||||
| 			conn = &alt_conn; | 			conn = &alt_conn; | ||||||
| 		} else | 		} else | ||||||
| 		if (cell->type == "$reduce_and" || cell->type == "$reduce_or" || cell->type == "$reduce_bool") { | 		if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_bool")) { | ||||||
| 			alt_conn = *conn; | 			alt_conn = *conn; | ||||||
| 			assign_map.apply(alt_conn.at("\\A")); | 			assign_map.apply(alt_conn.at("\\A")); | ||||||
| 			alt_conn.at("\\A").sort_and_unify(); | 			alt_conn.at("\\A").sort_and_unify(); | ||||||
|  | @ -222,7 +222,7 @@ struct OptMergeWorker | ||||||
| 			return true; | 			return true; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (cell1->type.substr(0, 1) == "$" && conn1.count("\\Q") != 0) { | 		if (cell1->type.begins_with("$") && conn1.count("\\Q") != 0) { | ||||||
| 			std::vector<RTLIL::SigBit> q1 = dff_init_map(cell1->getPort("\\Q")).to_sigbit_vector(); | 			std::vector<RTLIL::SigBit> q1 = dff_init_map(cell1->getPort("\\Q")).to_sigbit_vector(); | ||||||
| 			std::vector<RTLIL::SigBit> q2 = dff_init_map(cell2->getPort("\\Q")).to_sigbit_vector(); | 			std::vector<RTLIL::SigBit> q2 = dff_init_map(cell2->getPort("\\Q")).to_sigbit_vector(); | ||||||
| 			for (size_t i = 0; i < q1.size(); i++) | 			for (size_t i = 0; i < q1.size(); i++) | ||||||
|  |  | ||||||
|  | @ -84,7 +84,7 @@ struct OptMuxtreeWorker | ||||||
| 		//	.const_deactivated
 | 		//	.const_deactivated
 | ||||||
| 		for (auto cell : module->cells()) | 		for (auto cell : module->cells()) | ||||||
| 		{ | 		{ | ||||||
| 			if (cell->type == "$mux" || cell->type == "$pmux") | 			if (cell->type.in("$mux", "$pmux")) | ||||||
| 			{ | 			{ | ||||||
| 				RTLIL::SigSpec sig_a = cell->getPort("\\A"); | 				RTLIL::SigSpec sig_a = cell->getPort("\\A"); | ||||||
| 				RTLIL::SigSpec sig_b = cell->getPort("\\B"); | 				RTLIL::SigSpec sig_b = cell->getPort("\\B"); | ||||||
|  |  | ||||||
|  | @ -63,15 +63,15 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell) | ||||||
| 
 | 
 | ||||||
| 	log_assert(GetSize(sig_set) == GetSize(sig_clr)); | 	log_assert(GetSize(sig_set) == GetSize(sig_clr)); | ||||||
| 
 | 
 | ||||||
| 	if (cell->type.substr(0,8) == "$_DFFSR_") { | 	if (cell->type.begins_with("$_DFFSR_")) { | ||||||
| 		pol_set = cell->type[9] == 'P' ? State::S1 : State::S0; | 		pol_set = cell->type[9] == 'P' ? State::S1 : State::S0; | ||||||
| 		pol_clr = cell->type[10] == 'P' ? State::S1 : State::S0; | 		pol_clr = cell->type[10] == 'P' ? State::S1 : State::S0; | ||||||
| 	} else | 	} else | ||||||
| 	if (cell->type.substr(0,11) == "$_DLATCHSR_") { | 	if (cell->type.begins_with("$_DLATCHSR_")) { | ||||||
| 		pol_set = cell->type[12] == 'P' ? State::S1 : State::S0; | 		pol_set = cell->type[12] == 'P' ? State::S1 : State::S0; | ||||||
| 		pol_clr = cell->type[13] == 'P' ? State::S1 : State::S0; | 		pol_clr = cell->type[13] == 'P' ? State::S1 : State::S0; | ||||||
| 	} else | 	} else | ||||||
| 	if (cell->type == "$dffsr" || cell->type == "$dlatchsr") { | 	if (cell->type.in("$dffsr", "$dlatchsr")) { | ||||||
| 		pol_set = cell->parameters["\\SET_POLARITY"].as_bool() ? State::S1 : State::S0; | 		pol_set = cell->parameters["\\SET_POLARITY"].as_bool() ? State::S1 : State::S0; | ||||||
| 		pol_clr = cell->parameters["\\CLR_POLARITY"].as_bool() ? State::S1 : State::S0; | 		pol_clr = cell->parameters["\\CLR_POLARITY"].as_bool() ? State::S1 : State::S0; | ||||||
| 	} else | 	} else | ||||||
|  | @ -137,7 +137,7 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell) | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type == "$dffsr" || cell->type == "$dlatchsr") | 	if (cell->type.in("$dffsr", "$dlatchsr")) | ||||||
| 	{ | 	{ | ||||||
| 		cell->setParam("\\WIDTH", GetSize(sig_d)); | 		cell->setParam("\\WIDTH", GetSize(sig_d)); | ||||||
| 		cell->setPort("\\SET", sig_set); | 		cell->setPort("\\SET", sig_set); | ||||||
|  | @ -198,9 +198,9 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell) | ||||||
| 	{ | 	{ | ||||||
| 		IdString new_type; | 		IdString new_type; | ||||||
| 
 | 
 | ||||||
| 		if (cell->type.substr(0,8) == "$_DFFSR_") | 		if (cell->type.begins_with("$_DFFSR_")) | ||||||
| 			new_type = stringf("$_DFF_%c_", cell->type[8]); | 			new_type = stringf("$_DFF_%c_", cell->type[8]); | ||||||
| 		else if (cell->type.substr(0,11) == "$_DLATCHSR_") | 		else if (cell->type.begins_with("$_DLATCHSR_")) | ||||||
| 			new_type = stringf("$_DLATCH_%c_", cell->type[11]); | 			new_type = stringf("$_DLATCH_%c_", cell->type[11]); | ||||||
| 		else | 		else | ||||||
| 			log_abort(); | 			log_abort(); | ||||||
|  | @ -278,7 +278,7 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) | ||||||
| 		sig_c = dff->getPort("\\C"); | 		sig_c = dff->getPort("\\C"); | ||||||
| 		val_cp = RTLIL::Const(dff->type == "$_DFF_P_", 1); | 		val_cp = RTLIL::Const(dff->type == "$_DFF_P_", 1); | ||||||
| 	} | 	} | ||||||
| 	else if (dff->type.substr(0,6) == "$_DFF_" && dff->type.substr(9) == "_" && | 	else if (dff->type.begins_with("$_DFF_") && dff->type.compare(9, 1, "_") == 0 && | ||||||
| 			(dff->type[6] == 'N' || dff->type[6] == 'P') && | 			(dff->type[6] == 'N' || dff->type[6] == 'P') && | ||||||
| 			(dff->type[7] == 'N' || dff->type[7] == 'P') && | 			(dff->type[7] == 'N' || dff->type[7] == 'P') && | ||||||
| 			(dff->type[8] == '0' || dff->type[8] == '1')) { | 			(dff->type[8] == '0' || dff->type[8] == '1')) { | ||||||
|  | @ -290,7 +290,7 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) | ||||||
| 		val_rp = RTLIL::Const(dff->type[7] == 'P', 1); | 		val_rp = RTLIL::Const(dff->type[7] == 'P', 1); | ||||||
| 		val_rv = RTLIL::Const(dff->type[8] == '1', 1); | 		val_rv = RTLIL::Const(dff->type[8] == '1', 1); | ||||||
| 	} | 	} | ||||||
| 	else if (dff->type.substr(0,7) == "$_DFFE_" && dff->type.substr(9) == "_" && | 	else if (dff->type.begins_with("$_DFFE_") && dff->type.compare(9, 1, "_") == 0 && | ||||||
| 			(dff->type[7] == 'N' || dff->type[7] == 'P') && | 			(dff->type[7] == 'N' || dff->type[7] == 'P') && | ||||||
| 			(dff->type[8] == 'N' || dff->type[8] == 'P')) { | 			(dff->type[8] == 'N' || dff->type[8] == 'P')) { | ||||||
| 		sig_d = dff->getPort("\\D"); | 		sig_d = dff->getPort("\\D"); | ||||||
|  | @ -428,7 +428,7 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) | ||||||
| 			return true; | 			return true; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		log_assert(dff->type.substr(0,6) == "$_DFF_"); | 		log_assert(dff->type.begins_with("$_DFF_")); | ||||||
| 		dff->type = stringf("$_DFF_%c_", + dff->type[6]); | 		dff->type = stringf("$_DFF_%c_", + dff->type[6]); | ||||||
| 		dff->unsetPort("\\R"); | 		dff->unsetPort("\\R"); | ||||||
| 	} | 	} | ||||||
|  | @ -452,7 +452,7 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) | ||||||
| 			return true; | 			return true; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		log_assert(dff->type.substr(0,7) == "$_DFFE_"); | 		log_assert(dff->type.begins_with("$_DFFE_")); | ||||||
| 		dff->type = stringf("$_DFF_%c_", + dff->type[7]); | 		dff->type = stringf("$_DFF_%c_", + dff->type[7]); | ||||||
| 		dff->unsetPort("\\E"); | 		dff->unsetPort("\\E"); | ||||||
| 	} | 	} | ||||||
|  | @ -624,7 +624,7 @@ struct OptRmdffPass : public Pass { | ||||||
| 						} | 						} | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				if (cell->type == "$mux" || cell->type == "$pmux") { | 				if (cell->type.in("$mux", "$pmux")) { | ||||||
| 					if (cell->getPort("\\A").size() == cell->getPort("\\B").size()) | 					if (cell->getPort("\\A").size() == cell->getPort("\\B").size()) | ||||||
| 						mux_drivers.insert(assign_map(cell->getPort("\\Y")), cell); | 						mux_drivers.insert(assign_map(cell->getPort("\\Y")), cell); | ||||||
| 					continue; | 					continue; | ||||||
|  |  | ||||||
|  | @ -376,13 +376,13 @@ struct ShareWorker | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$mul" || cell->type == "$div" || cell->type == "$mod") { | 			if (cell->type.in("$mul", "$div", "$mod")) { | ||||||
| 				if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() >= 4) | 				if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() >= 4) | ||||||
| 					shareable_cells.insert(cell); | 					shareable_cells.insert(cell); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") { | 			if (cell->type.in("$shl", "$shr", "$sshl", "$sshr")) { | ||||||
| 				if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() >= 8) | 				if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() >= 8) | ||||||
| 					shareable_cells.insert(cell); | 					shareable_cells.insert(cell); | ||||||
| 				continue; | 				continue; | ||||||
|  |  | ||||||
|  | @ -55,7 +55,7 @@ bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSpec ref, | ||||||
| 			return check_signal(mod, cell->getPort("\\A"), ref, polarity); | 			return check_signal(mod, cell->getPort("\\A"), ref, polarity); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if ((cell->type == "$eq" || cell->type == "$eqx") && cell->getPort("\\Y") == signal) { | 		if (cell->type.in("$eq", "$eqx") && cell->getPort("\\Y") == signal) { | ||||||
| 			if (cell->getPort("\\A").is_fully_const()) { | 			if (cell->getPort("\\A").is_fully_const()) { | ||||||
| 				if (!cell->getPort("\\A").as_bool()) | 				if (!cell->getPort("\\A").as_bool()) | ||||||
| 					polarity = !polarity; | 					polarity = !polarity; | ||||||
|  | @ -68,7 +68,7 @@ bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSpec ref, | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if ((cell->type == "$ne" || cell->type == "$nex") && cell->getPort("\\Y") == signal) { | 		if (cell->type.in("$ne", "$nex") && cell->getPort("\\Y") == signal) { | ||||||
| 			if (cell->getPort("\\A").is_fully_const()) { | 			if (cell->getPort("\\A").is_fully_const()) { | ||||||
| 				if (cell->getPort("\\A").as_bool()) | 				if (cell->getPort("\\A").as_bool()) | ||||||
| 					polarity = !polarity; | 					polarity = !polarity; | ||||||
|  |  | ||||||
|  | @ -65,8 +65,7 @@ struct PruneWorker | ||||||
| 			pool<RTLIL::SigBit> sw_assigned = do_switch((*it), assigned, affected); | 			pool<RTLIL::SigBit> sw_assigned = do_switch((*it), assigned, affected); | ||||||
| 			assigned.insert(sw_assigned.begin(), sw_assigned.end()); | 			assigned.insert(sw_assigned.begin(), sw_assigned.end()); | ||||||
| 		} | 		} | ||||||
| 		pool<RTLIL::SigSig> remove; | 		for (auto it = cs->actions.rbegin(); it != cs->actions.rend(); ) { | ||||||
| 		for (auto it = cs->actions.rbegin(); it != cs->actions.rend(); ++it) { |  | ||||||
| 			RTLIL::SigSpec lhs = sigmap(it->first); | 			RTLIL::SigSpec lhs = sigmap(it->first); | ||||||
| 			bool redundant = true; | 			bool redundant = true; | ||||||
| 			for (auto &bit : lhs) { | 			for (auto &bit : lhs) { | ||||||
|  | @ -75,9 +74,10 @@ struct PruneWorker | ||||||
| 					break; | 					break; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | 			bool remove = false; | ||||||
| 			if (redundant) { | 			if (redundant) { | ||||||
| 				removed_count++; | 				removed_count++; | ||||||
| 				remove.insert(*it); | 				remove = true; | ||||||
| 			} else { | 			} else { | ||||||
| 				if (root) { | 				if (root) { | ||||||
| 					bool promotable = true; | 					bool promotable = true; | ||||||
|  | @ -99,7 +99,7 @@ struct PruneWorker | ||||||
| 						} | 						} | ||||||
| 						promoted_count++; | 						promoted_count++; | ||||||
| 						module->connect(conn); | 						module->connect(conn); | ||||||
| 						remove.insert(*it); | 						remove = true; | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				for (auto &bit : lhs) | 				for (auto &bit : lhs) | ||||||
|  | @ -109,11 +109,9 @@ struct PruneWorker | ||||||
| 					if (bit.wire) | 					if (bit.wire) | ||||||
| 						affected.insert(bit); | 						affected.insert(bit); | ||||||
| 			} | 			} | ||||||
| 		} | 			if (remove) | ||||||
| 		for (auto it = cs->actions.begin(); it != cs->actions.end(); ) { | 				cs->actions.erase((it++).base() - 1); | ||||||
| 			if (remove[*it]) { | 			else it++; | ||||||
| 				it = cs->actions.erase(it); |  | ||||||
| 			} else it++; |  | ||||||
| 		} | 		} | ||||||
| 		return assigned; | 		return assigned; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -47,8 +47,8 @@ struct BruteForceEquivChecker | ||||||
| 	{ | 	{ | ||||||
| 		if (inputs.size() < mod1_inputs.size()) { | 		if (inputs.size() < mod1_inputs.size()) { | ||||||
| 			RTLIL::SigSpec inputs0 = inputs, inputs1 = inputs; | 			RTLIL::SigSpec inputs0 = inputs, inputs1 = inputs; | ||||||
| 			inputs0.append(RTLIL::Const(0, 1)); | 			inputs0.append(State::S0); | ||||||
| 			inputs1.append(RTLIL::Const(1, 1)); | 			inputs1.append(State::S1); | ||||||
| 			run_checker(inputs0); | 			run_checker(inputs0); | ||||||
| 			run_checker(inputs1); | 			run_checker(inputs1); | ||||||
| 			return; | 			return; | ||||||
|  |  | ||||||
|  | @ -151,7 +151,7 @@ void create_dff_dq_map(std::map<RTLIL::IdString, dff_map_info_t> &map, RTLIL::De | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (info.cell->type.size() == 10 && info.cell->type.substr(0, 6) == "$_DFF_") { | 		if (info.cell->type.size() == 10 && info.cell->type.begins_with("$_DFF_")) { | ||||||
| 			info.bit_clk = sigmap(info.cell->getPort("\\C")).as_bit(); | 			info.bit_clk = sigmap(info.cell->getPort("\\C")).as_bit(); | ||||||
| 			info.bit_arst = sigmap(info.cell->getPort("\\R")).as_bit(); | 			info.bit_arst = sigmap(info.cell->getPort("\\R")).as_bit(); | ||||||
| 			info.clk_polarity = info.cell->type[6] == 'P'; | 			info.clk_polarity = info.cell->type[6] == 'P'; | ||||||
|  |  | ||||||
|  | @ -59,7 +59,7 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL: | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| 	if (argidx+3 != args.size() || args[argidx].substr(0, 1) == "-") | 	if (argidx+3 != args.size() || args[argidx].compare(0, 1, "-") == 0) | ||||||
| 		that->cmd_error(args, argidx, "command argument error"); | 		that->cmd_error(args, argidx, "command argument error"); | ||||||
| 
 | 
 | ||||||
| 	RTLIL::IdString gold_name = RTLIL::escape_id(args[argidx++]); | 	RTLIL::IdString gold_name = RTLIL::escape_id(args[argidx++]); | ||||||
|  | @ -236,7 +236,7 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL: | ||||||
| 	if (flag_make_assert) { | 	if (flag_make_assert) { | ||||||
| 		RTLIL::Cell *assert_cell = miter_module->addCell(NEW_ID, "$assert"); | 		RTLIL::Cell *assert_cell = miter_module->addCell(NEW_ID, "$assert"); | ||||||
| 		assert_cell->setPort("\\A", all_conditions); | 		assert_cell->setPort("\\A", all_conditions); | ||||||
| 		assert_cell->setPort("\\EN", RTLIL::SigSpec(1, 1)); | 		assert_cell->setPort("\\EN", State::S1); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	RTLIL::Wire *w_trigger = miter_module->addWire("\\trigger"); | 	RTLIL::Wire *w_trigger = miter_module->addWire("\\trigger"); | ||||||
|  | @ -279,7 +279,7 @@ void create_miter_assert(struct Pass *that, std::vector<std::string> args, RTLIL | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| 	if ((argidx+1 != args.size() && argidx+2 != args.size()) || args[argidx].substr(0, 1) == "-") | 	if ((argidx+1 != args.size() && argidx+2 != args.size()) || args[argidx].compare(0, 1, "-") == 0) | ||||||
| 		that->cmd_error(args, argidx, "command argument error"); | 		that->cmd_error(args, argidx, "command argument error"); | ||||||
| 
 | 
 | ||||||
| 	IdString module_name = RTLIL::escape_id(args[argidx++]); | 	IdString module_name = RTLIL::escape_id(args[argidx++]); | ||||||
|  |  | ||||||
|  | @ -519,7 +519,7 @@ struct SatHelper | ||||||
| 					for (auto &p : d->connections()) { | 					for (auto &p : d->connections()) { | ||||||
| 						if (d->type == "$dff" && p.first == "\\CLK") | 						if (d->type == "$dff" && p.first == "\\CLK") | ||||||
| 							continue; | 							continue; | ||||||
| 						if (d->type.substr(0, 6) == "$_DFF_" && p.first == "\\C") | 						if (d->type.begins_with("$_DFF_") && p.first == "\\C") | ||||||
| 							continue; | 							continue; | ||||||
| 						queued_signals.add(handled_signals.remove(sigmap(p.second))); | 						queued_signals.add(handled_signals.remove(sigmap(p.second))); | ||||||
| 					} | 					} | ||||||
|  | @ -797,7 +797,7 @@ struct SatHelper | ||||||
| 
 | 
 | ||||||
| 			vector<string> data; | 			vector<string> data; | ||||||
| 			string name = wd.first.c_str(); | 			string name = wd.first.c_str(); | ||||||
| 			while (name.substr(0, 1) == "\\") | 			while (name.compare(0, 1, "\\") == 0) | ||||||
| 				name = name.substr(1); | 				name = name.substr(1); | ||||||
| 
 | 
 | ||||||
| 			fprintf(f, "    { \"name\": \"%s\", \"wave\": \"", name.c_str()); | 			fprintf(f, "    { \"name\": \"%s\", \"wave\": \"", name.c_str()); | ||||||
|  | @ -1353,7 +1353,7 @@ struct SatPass : public Pass { | ||||||
| 		if (show_regs) { | 		if (show_regs) { | ||||||
| 			pool<Wire*> reg_wires; | 			pool<Wire*> reg_wires; | ||||||
| 			for (auto cell : module->cells()) { | 			for (auto cell : module->cells()) { | ||||||
| 				if (cell->type == "$dff" || cell->type.substr(0, 6) == "$_DFF_") | 				if (cell->type == "$dff" || cell->type.begins_with("$_DFF_")) | ||||||
| 					for (auto bit : cell->getPort("\\Q")) | 					for (auto bit : cell->getPort("\\Q")) | ||||||
| 						if (bit.wire) | 						if (bit.wire) | ||||||
| 							reg_wires.insert(bit.wire); | 							reg_wires.insert(bit.wire); | ||||||
|  |  | ||||||
|  | @ -166,7 +166,7 @@ void mark_port(RTLIL::SigSpec sig) | ||||||
| 
 | 
 | ||||||
| void extract_cell(RTLIL::Cell *cell, bool keepff) | void extract_cell(RTLIL::Cell *cell, bool keepff) | ||||||
| { | { | ||||||
| 	if (cell->type == "$_DFF_N_" || cell->type == "$_DFF_P_") | 	if (cell->type.in("$_DFF_N_", "$_DFF_P_")) | ||||||
| 	{ | 	{ | ||||||
| 		if (clk_polarity != (cell->type == "$_DFF_P_")) | 		if (clk_polarity != (cell->type == "$_DFF_P_")) | ||||||
| 			return; | 			return; | ||||||
|  | @ -177,11 +177,11 @@ void extract_cell(RTLIL::Cell *cell, bool keepff) | ||||||
| 		goto matching_dff; | 		goto matching_dff; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type == "$_DFFE_NN_" || cell->type == "$_DFFE_NP_" || cell->type == "$_DFFE_PN_" || cell->type == "$_DFFE_PP_") | 	if (cell->type.in("$_DFFE_NN_", "$_DFFE_NP_", "$_DFFE_PN_", "$_DFFE_PP_")) | ||||||
| 	{ | 	{ | ||||||
| 		if (clk_polarity != (cell->type == "$_DFFE_PN_" || cell->type == "$_DFFE_PP_")) | 		if (clk_polarity != cell->type.in("$_DFFE_PN_", "$_DFFE_PP_")) | ||||||
| 			return; | 			return; | ||||||
| 		if (en_polarity != (cell->type == "$_DFFE_NP_" || cell->type == "$_DFFE_PP_")) | 		if (en_polarity != cell->type.in("$_DFFE_NP_", "$_DFFE_PP_")) | ||||||
| 			return; | 			return; | ||||||
| 		if (clk_sig != assign_map(cell->getPort("\\C"))) | 		if (clk_sig != assign_map(cell->getPort("\\C"))) | ||||||
| 			return; | 			return; | ||||||
|  | @ -333,17 +333,17 @@ std::string remap_name(RTLIL::IdString abc_name, RTLIL::Wire **orig_wire = nullp | ||||||
| { | { | ||||||
| 	std::string abc_sname = abc_name.substr(1); | 	std::string abc_sname = abc_name.substr(1); | ||||||
| 	bool isnew = false; | 	bool isnew = false; | ||||||
| 	if (abc_sname.substr(0, 4) == "new_") | 	if (abc_sname.compare(0, 4, "new_") == 0) | ||||||
| 	{ | 	{ | ||||||
| 		abc_sname.erase(0, 4); | 		abc_sname.erase(0, 4); | ||||||
| 		isnew = true; | 		isnew = true; | ||||||
| 	} | 	} | ||||||
| 	if (abc_sname.substr(0, 5) == "ys__n") | 	if (abc_sname.compare(0, 5, "ys__n") == 0) | ||||||
| 	{ | 	{ | ||||||
| 		abc_sname.erase(0, 5); | 		abc_sname.erase(0, 5); | ||||||
| 		if (std::isdigit(abc_sname.at(0))) | 		if (std::isdigit(abc_sname.at(0))) | ||||||
| 		{ | 		{ | ||||||
| 			int sid = std::stoi(abc_sname); | 			int sid = std::atoi(abc_sname.c_str()); | ||||||
| 			size_t postfix_start = abc_sname.find_first_not_of("0123456789"); | 			size_t postfix_start = abc_sname.find_first_not_of("0123456789"); | ||||||
| 			std::string postfix = postfix_start != std::string::npos ? abc_sname.substr(postfix_start) : ""; | 			std::string postfix = postfix_start != std::string::npos ? abc_sname.substr(postfix_start) : ""; | ||||||
| 
 | 
 | ||||||
|  | @ -941,33 +941,33 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin | ||||||
| 		fprintf(f, "GATE ONE     1 Y=CONST1;\n"); | 		fprintf(f, "GATE ONE     1 Y=CONST1;\n"); | ||||||
| 		fprintf(f, "GATE BUF    %d Y=A;                  PIN * NONINV  1 999 1 0 1 0\n", cell_cost.at("$_BUF_")); | 		fprintf(f, "GATE BUF    %d Y=A;                  PIN * NONINV  1 999 1 0 1 0\n", cell_cost.at("$_BUF_")); | ||||||
| 		fprintf(f, "GATE NOT    %d Y=!A;                 PIN * INV     1 999 1 0 1 0\n", cell_cost.at("$_NOT_")); | 		fprintf(f, "GATE NOT    %d Y=!A;                 PIN * INV     1 999 1 0 1 0\n", cell_cost.at("$_NOT_")); | ||||||
| 		if (enabled_gates.empty() || enabled_gates.count("AND")) | 		if (enabled_gates.count("AND")) | ||||||
| 			fprintf(f, "GATE AND    %d Y=A*B;                PIN * NONINV  1 999 1 0 1 0\n", cell_cost.at("$_AND_")); | 			fprintf(f, "GATE AND    %d Y=A*B;                PIN * NONINV  1 999 1 0 1 0\n", cell_cost.at("$_AND_")); | ||||||
| 		if (enabled_gates.empty() || enabled_gates.count("NAND")) | 		if (enabled_gates.count("NAND")) | ||||||
| 			fprintf(f, "GATE NAND   %d Y=!(A*B);             PIN * INV     1 999 1 0 1 0\n", cell_cost.at("$_NAND_")); | 			fprintf(f, "GATE NAND   %d Y=!(A*B);             PIN * INV     1 999 1 0 1 0\n", cell_cost.at("$_NAND_")); | ||||||
| 		if (enabled_gates.empty() || enabled_gates.count("OR")) | 		if (enabled_gates.count("OR")) | ||||||
| 			fprintf(f, "GATE OR     %d Y=A+B;                PIN * NONINV  1 999 1 0 1 0\n", cell_cost.at("$_OR_")); | 			fprintf(f, "GATE OR     %d Y=A+B;                PIN * NONINV  1 999 1 0 1 0\n", cell_cost.at("$_OR_")); | ||||||
| 		if (enabled_gates.empty() || enabled_gates.count("NOR")) | 		if (enabled_gates.count("NOR")) | ||||||
| 			fprintf(f, "GATE NOR    %d Y=!(A+B);             PIN * INV     1 999 1 0 1 0\n", cell_cost.at("$_NOR_")); | 			fprintf(f, "GATE NOR    %d Y=!(A+B);             PIN * INV     1 999 1 0 1 0\n", cell_cost.at("$_NOR_")); | ||||||
| 		if (enabled_gates.empty() || enabled_gates.count("XOR")) | 		if (enabled_gates.count("XOR")) | ||||||
| 			fprintf(f, "GATE XOR    %d Y=(A*!B)+(!A*B);      PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at("$_XOR_")); | 			fprintf(f, "GATE XOR    %d Y=(A*!B)+(!A*B);      PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at("$_XOR_")); | ||||||
| 		if (enabled_gates.empty() || enabled_gates.count("XNOR")) | 		if (enabled_gates.count("XNOR")) | ||||||
| 			fprintf(f, "GATE XNOR   %d Y=(A*B)+(!A*!B);      PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at("$_XNOR_")); | 			fprintf(f, "GATE XNOR   %d Y=(A*B)+(!A*!B);      PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at("$_XNOR_")); | ||||||
| 		if (enabled_gates.empty() || enabled_gates.count("ANDNOT")) | 		if (enabled_gates.count("ANDNOT")) | ||||||
| 			fprintf(f, "GATE ANDNOT %d Y=A*!B;               PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at("$_ANDNOT_")); | 			fprintf(f, "GATE ANDNOT %d Y=A*!B;               PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at("$_ANDNOT_")); | ||||||
| 		if (enabled_gates.empty() || enabled_gates.count("ORNOT")) | 		if (enabled_gates.count("ORNOT")) | ||||||
| 			fprintf(f, "GATE ORNOT  %d Y=A+!B;               PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at("$_ORNOT_")); | 			fprintf(f, "GATE ORNOT  %d Y=A+!B;               PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at("$_ORNOT_")); | ||||||
| 		if (enabled_gates.empty() || enabled_gates.count("AOI3")) | 		if (enabled_gates.count("AOI3")) | ||||||
| 			fprintf(f, "GATE AOI3   %d Y=!((A*B)+C);         PIN * INV     1 999 1 0 1 0\n", cell_cost.at("$_AOI3_")); | 			fprintf(f, "GATE AOI3   %d Y=!((A*B)+C);         PIN * INV     1 999 1 0 1 0\n", cell_cost.at("$_AOI3_")); | ||||||
| 		if (enabled_gates.empty() || enabled_gates.count("OAI3")) | 		if (enabled_gates.count("OAI3")) | ||||||
| 			fprintf(f, "GATE OAI3   %d Y=!((A+B)*C);         PIN * INV     1 999 1 0 1 0\n", cell_cost.at("$_OAI3_")); | 			fprintf(f, "GATE OAI3   %d Y=!((A+B)*C);         PIN * INV     1 999 1 0 1 0\n", cell_cost.at("$_OAI3_")); | ||||||
| 		if (enabled_gates.empty() || enabled_gates.count("AOI4")) | 		if (enabled_gates.count("AOI4")) | ||||||
| 			fprintf(f, "GATE AOI4   %d Y=!((A*B)+(C*D));     PIN * INV     1 999 1 0 1 0\n", cell_cost.at("$_AOI4_")); | 			fprintf(f, "GATE AOI4   %d Y=!((A*B)+(C*D));     PIN * INV     1 999 1 0 1 0\n", cell_cost.at("$_AOI4_")); | ||||||
| 		if (enabled_gates.empty() || enabled_gates.count("OAI4")) | 		if (enabled_gates.count("OAI4")) | ||||||
| 			fprintf(f, "GATE OAI4   %d Y=!((A+B)*(C+D));     PIN * INV     1 999 1 0 1 0\n", cell_cost.at("$_OAI4_")); | 			fprintf(f, "GATE OAI4   %d Y=!((A+B)*(C+D));     PIN * INV     1 999 1 0 1 0\n", cell_cost.at("$_OAI4_")); | ||||||
| 		if (enabled_gates.empty() || enabled_gates.count("MUX")) | 		if (enabled_gates.count("MUX")) | ||||||
| 			fprintf(f, "GATE MUX    %d Y=(A*B)+(S*B)+(!S*A); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at("$_MUX_")); | 			fprintf(f, "GATE MUX    %d Y=(A*B)+(S*B)+(!S*A); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at("$_MUX_")); | ||||||
| 		if (enabled_gates.empty() || enabled_gates.count("NMUX")) | 		if (enabled_gates.count("NMUX")) | ||||||
| 			fprintf(f, "GATE NMUX   %d Y=!((A*B)+(S*B)+(!S*A)); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at("$_NMUX_")); | 			fprintf(f, "GATE NMUX   %d Y=!((A*B)+(S*B)+(!S*A)); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at("$_NMUX_")); | ||||||
| 		if (map_mux4) | 		if (map_mux4) | ||||||
| 			fprintf(f, "GATE MUX4   %d Y=(!S*!T*A)+(S*!T*B)+(!S*T*C)+(S*T*D); PIN * UNKNOWN 1 999 1 0 1 0\n", 2*cell_cost.at("$_MUX_")); | 			fprintf(f, "GATE MUX4   %d Y=(!S*!T*A)+(S*!T*B)+(!S*T*C)+(S*T*D); PIN * UNKNOWN 1 999 1 0 1 0\n", 2*cell_cost.at("$_MUX_")); | ||||||
|  | @ -1411,7 +1411,9 @@ struct AbcPass : public Pass { | ||||||
| 		// log("\n");
 | 		// log("\n");
 | ||||||
| 		log("    -g type1,type2,...\n"); | 		log("    -g type1,type2,...\n"); | ||||||
| 		log("        Map to the specified list of gate types. Supported gates types are:\n"); | 		log("        Map to the specified list of gate types. Supported gates types are:\n"); | ||||||
| 		log("        AND, NAND, OR, NOR, XOR, XNOR, ANDNOT, ORNOT, MUX, AOI3, OAI3, AOI4, OAI4.\n"); | 		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 | ||||||
|  | 		log("           AND, NAND, OR, NOR, XOR, XNOR, ANDNOT, ORNOT, MUX,\n"); | ||||||
|  | 		log("           NMUX, AOI3, OAI3, AOI4, OAI4.\n"); | ||||||
| 		log("        (The NOT gate is always added to this list automatically.)\n"); | 		log("        (The NOT gate is always added to this list automatically.)\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("        The following aliases can be used to reference common sets of gate types:\n"); | 		log("        The following aliases can be used to reference common sets of gate types:\n"); | ||||||
|  | @ -1423,9 +1425,13 @@ struct AbcPass : public Pass { | ||||||
| 		log("          gates:  AND NAND OR NOR XOR XNOR ANDNOT ORNOT\n"); | 		log("          gates:  AND NAND OR NOR XOR XNOR ANDNOT ORNOT\n"); | ||||||
| 		log("          aig:    AND NAND OR NOR ANDNOT ORNOT\n"); | 		log("          aig:    AND NAND OR NOR ANDNOT ORNOT\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
|  | 		log("        The alias 'all' represent the full set of all gate types.\n"); | ||||||
|  | 		log("\n"); | ||||||
| 		log("        Prefix a gate type with a '-' to remove it from the list. For example\n"); | 		log("        Prefix a gate type with a '-' to remove it from the list. For example\n"); | ||||||
| 		log("        the arguments 'AND,OR,XOR' and 'simple,-MUX' are equivalent.\n"); | 		log("        the arguments 'AND,OR,XOR' and 'simple,-MUX' are equivalent.\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
|  | 		log("        The default is 'all,-NMUX,-AOI3,-OAI3,-AOI4,-OAI4'.\n"); | ||||||
|  | 		log("\n"); | ||||||
| 		log("    -dff\n"); | 		log("    -dff\n"); | ||||||
| 		log("        also pass $_DFF_?_ and $_DFFE_??_ cells through ABC. modules with many\n"); | 		log("        also pass $_DFF_?_ and $_DFFE_??_ cells through ABC. modules with many\n"); | ||||||
| 		log("        clock domains are automatically partitioned in clock domains and each\n"); | 		log("        clock domains are automatically partitioned in clock domains and each\n"); | ||||||
|  | @ -1584,7 +1590,7 @@ struct AbcPass : public Pass { | ||||||
| 					else if (GetSize(parts) == 1) | 					else if (GetSize(parts) == 1) | ||||||
| 						lut_costs.push_back(atoi(parts.at(0).c_str())); | 						lut_costs.push_back(atoi(parts.at(0).c_str())); | ||||||
| 					else if (GetSize(parts) == 2) | 					else if (GetSize(parts) == 2) | ||||||
| 						while (GetSize(lut_costs) < atoi(parts.at(0).c_str())) | 						while (GetSize(lut_costs) < std::atoi(parts.at(0).c_str())) | ||||||
| 							lut_costs.push_back(atoi(parts.at(1).c_str())); | 							lut_costs.push_back(atoi(parts.at(1).c_str())); | ||||||
| 					else | 					else | ||||||
| 						log_cmd_error("Invalid -luts syntax.\n"); | 						log_cmd_error("Invalid -luts syntax.\n"); | ||||||
|  | @ -1701,6 +1707,22 @@ struct AbcPass : public Pass { | ||||||
| 						gate_list.push_back("ORNOT"); | 						gate_list.push_back("ORNOT"); | ||||||
| 						goto ok_alias; | 						goto ok_alias; | ||||||
| 					} | 					} | ||||||
|  | 					if (g == "all") { | ||||||
|  | 						gate_list.push_back("AND"); | ||||||
|  | 						gate_list.push_back("NAND"); | ||||||
|  | 						gate_list.push_back("OR"); | ||||||
|  | 						gate_list.push_back("NOR"); | ||||||
|  | 						gate_list.push_back("XOR"); | ||||||
|  | 						gate_list.push_back("XNOR"); | ||||||
|  | 						gate_list.push_back("ANDNOT"); | ||||||
|  | 						gate_list.push_back("ORNOT"); | ||||||
|  | 						gate_list.push_back("AOI3"); | ||||||
|  | 						gate_list.push_back("OAI3"); | ||||||
|  | 						gate_list.push_back("AOI4"); | ||||||
|  | 						gate_list.push_back("OAI4"); | ||||||
|  | 						gate_list.push_back("MUX"); | ||||||
|  | 						gate_list.push_back("NMUX"); | ||||||
|  | 					} | ||||||
| 					cmd_error(args, argidx, stringf("Unsupported gate type: %s", g.c_str())); | 					cmd_error(args, argidx, stringf("Unsupported gate type: %s", g.c_str())); | ||||||
| 				ok_gate: | 				ok_gate: | ||||||
| 					gate_list.push_back(g); | 					gate_list.push_back(g); | ||||||
|  | @ -1752,6 +1774,23 @@ struct AbcPass : public Pass { | ||||||
| 		if (!constr_file.empty() && liberty_file.empty()) | 		if (!constr_file.empty() && liberty_file.empty()) | ||||||
| 			log_cmd_error("Got -constr but no -liberty!\n"); | 			log_cmd_error("Got -constr but no -liberty!\n"); | ||||||
| 
 | 
 | ||||||
|  | 		if (enabled_gates.empty()) { | ||||||
|  | 			enabled_gates.insert("AND"); | ||||||
|  | 			enabled_gates.insert("NAND"); | ||||||
|  | 			enabled_gates.insert("OR"); | ||||||
|  | 			enabled_gates.insert("NOR"); | ||||||
|  | 			enabled_gates.insert("XOR"); | ||||||
|  | 			enabled_gates.insert("XNOR"); | ||||||
|  | 			enabled_gates.insert("ANDNOT"); | ||||||
|  | 			enabled_gates.insert("ORNOT"); | ||||||
|  | 			// enabled_gates.insert("AOI3");
 | ||||||
|  | 			// enabled_gates.insert("OAI3");
 | ||||||
|  | 			// enabled_gates.insert("AOI4");
 | ||||||
|  | 			// enabled_gates.insert("OAI4");
 | ||||||
|  | 			enabled_gates.insert("MUX"); | ||||||
|  | 			// enabled_gates.insert("NMUX");
 | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		for (auto mod : design->selected_modules()) | 		for (auto mod : design->selected_modules()) | ||||||
| 		{ | 		{ | ||||||
| 			if (mod->processes.size() > 0) { | 			if (mod->processes.size() > 0) { | ||||||
|  | @ -1822,15 +1861,15 @@ struct AbcPass : public Pass { | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				if (cell->type == "$_DFF_N_" || cell->type == "$_DFF_P_") | 				if (cell->type.in("$_DFF_N_", "$_DFF_P_")) | ||||||
| 				{ | 				{ | ||||||
| 					key = clkdomain_t(cell->type == "$_DFF_P_", assign_map(cell->getPort("\\C")), true, RTLIL::SigSpec()); | 					key = clkdomain_t(cell->type == "$_DFF_P_", assign_map(cell->getPort("\\C")), true, RTLIL::SigSpec()); | ||||||
| 				} | 				} | ||||||
| 				else | 				else | ||||||
| 				if (cell->type == "$_DFFE_NN_" || cell->type == "$_DFFE_NP_" || cell->type == "$_DFFE_PN_" || cell->type == "$_DFFE_PP_") | 				if (cell->type.in("$_DFFE_NN_", "$_DFFE_NP_" "$_DFFE_PN_", "$_DFFE_PP_")) | ||||||
| 				{ | 				{ | ||||||
| 					bool this_clk_pol = cell->type == "$_DFFE_PN_" || cell->type == "$_DFFE_PP_"; | 					bool this_clk_pol = cell->type.in("$_DFFE_PN_", "$_DFFE_PP_"); | ||||||
| 					bool this_en_pol = cell->type == "$_DFFE_NP_" || cell->type == "$_DFFE_PP_"; | 					bool this_en_pol = cell->type.in("$_DFFE_NP_", "$_DFFE_PP_"); | ||||||
| 					key = clkdomain_t(this_clk_pol, assign_map(cell->getPort("\\C")), this_en_pol, assign_map(cell->getPort("\\E"))); | 					key = clkdomain_t(this_clk_pol, assign_map(cell->getPort("\\C")), this_en_pol, assign_map(cell->getPort("\\E"))); | ||||||
| 				} | 				} | ||||||
| 				else | 				else | ||||||
|  |  | ||||||
|  | @ -593,7 +593,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri | ||||||
| 					c->setPort("\\Y", module->addWire(NEW_ID)); | 					c->setPort("\\Y", module->addWire(NEW_ID)); | ||||||
| 					RTLIL::Wire *wire = module->wire(remap_name(y_bit.wire->name)); | 					RTLIL::Wire *wire = module->wire(remap_name(y_bit.wire->name)); | ||||||
| 					log_assert(wire); | 					log_assert(wire); | ||||||
| 					module->connect(RTLIL::SigBit(wire, y_bit.offset), RTLIL::S1); | 					module->connect(RTLIL::SigBit(wire, y_bit.offset), State::S1); | ||||||
| 				} | 				} | ||||||
| 				else if (!lut_costs.empty() || !lut_file.empty()) { | 				else if (!lut_costs.empty() || !lut_file.empty()) { | ||||||
| 					RTLIL::Cell* driver_lut = nullptr; | 					RTLIL::Cell* driver_lut = nullptr; | ||||||
|  | @ -1153,15 +1153,15 @@ struct Abc9Pass : public Pass { | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				if (cell->type == "$_DFF_N_" || cell->type == "$_DFF_P_") | 				if (cell->type.in("$_DFF_N_", "$_DFF_P_")) | ||||||
| 				{ | 				{ | ||||||
| 					key = clkdomain_t(cell->type == "$_DFF_P_", assign_map(cell->getPort("\\C")), true, RTLIL::SigSpec()); | 					key = clkdomain_t(cell->type == "$_DFF_P_", assign_map(cell->getPort("\\C")), true, RTLIL::SigSpec()); | ||||||
| 				} | 				} | ||||||
| 				else | 				else | ||||||
| 				if (cell->type == "$_DFFE_NN_" || cell->type == "$_DFFE_NP_" || cell->type == "$_DFFE_PN_" || cell->type == "$_DFFE_PP_") | 				if (cell->type.in("$_DFFE_NN_", "$_DFFE_NP_", "$_DFFE_PN_", "$_DFFE_PP_")) | ||||||
| 				{ | 				{ | ||||||
| 					bool this_clk_pol = cell->type == "$_DFFE_PN_" || cell->type == "$_DFFE_PP_"; | 					bool this_clk_pol = cell->type.in("$_DFFE_PN_", "$_DFFE_PP_"); | ||||||
| 					bool this_en_pol = cell->type == "$_DFFE_NP_" || cell->type == "$_DFFE_PP_"; | 					bool this_en_pol = cell->type.in("$_DFFE_NP_", "$_DFFE_PP_"); | ||||||
| 					key = clkdomain_t(this_clk_pol, assign_map(cell->getPort("\\C")), this_en_pol, assign_map(cell->getPort("\\E"))); | 					key = clkdomain_t(this_clk_pol, assign_map(cell->getPort("\\C")), this_en_pol, assign_map(cell->getPort("\\E"))); | ||||||
| 				} | 				} | ||||||
| 				else | 				else | ||||||
|  |  | ||||||
|  | @ -66,7 +66,7 @@ struct AigmapPass : public Pass { | ||||||
| 			{ | 			{ | ||||||
| 				Aig aig(cell); | 				Aig aig(cell); | ||||||
| 
 | 
 | ||||||
| 				if (cell->type == "$_AND_" || cell->type == "$_NOT_") | 				if (cell->type.in("$_AND_", "$_NOT_")) | ||||||
| 					aig.name.clear(); | 					aig.name.clear(); | ||||||
| 
 | 
 | ||||||
| 				if (nand_mode && cell->type == "$_NAND_") | 				if (nand_mode && cell->type == "$_NAND_") | ||||||
|  |  | ||||||
|  | @ -315,7 +315,7 @@ struct AlumaccWorker | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (subtract_b) | 			if (subtract_b) | ||||||
| 				C.append(RTLIL::S1); | 				C.append(State::S1); | ||||||
| 
 | 
 | ||||||
| 			if (GetSize(C) > 1) | 			if (GetSize(C) > 1) | ||||||
| 				goto next_macc; | 				goto next_macc; | ||||||
|  | @ -402,7 +402,7 @@ struct AlumaccWorker | ||||||
| 			alunode_t *n = nullptr; | 			alunode_t *n = nullptr; | ||||||
| 
 | 
 | ||||||
| 			for (auto node : sig_alu[RTLIL::SigSig(A, B)]) | 			for (auto node : sig_alu[RTLIL::SigSig(A, B)]) | ||||||
| 				if (node->is_signed == is_signed && node->invert_b && node->c == RTLIL::S1) { | 				if (node->is_signed == is_signed && node->invert_b && node->c == State::S1) { | ||||||
| 					n = node; | 					n = node; | ||||||
| 					break; | 					break; | ||||||
| 				} | 				} | ||||||
|  | @ -411,7 +411,7 @@ struct AlumaccWorker | ||||||
| 				n = new alunode_t; | 				n = new alunode_t; | ||||||
| 				n->a = A; | 				n->a = A; | ||||||
| 				n->b = B; | 				n->b = B; | ||||||
| 				n->c = RTLIL::S1; | 				n->c = State::S1; | ||||||
| 				n->y = module->addWire(NEW_ID, max(GetSize(A), GetSize(B))); | 				n->y = module->addWire(NEW_ID, max(GetSize(A), GetSize(B))); | ||||||
| 				n->is_signed = is_signed; | 				n->is_signed = is_signed; | ||||||
| 				n->invert_b = true; | 				n->invert_b = true; | ||||||
|  | @ -440,7 +440,7 @@ struct AlumaccWorker | ||||||
| 			alunode_t *n = nullptr; | 			alunode_t *n = nullptr; | ||||||
| 
 | 
 | ||||||
| 			for (auto node : sig_alu[RTLIL::SigSig(A, B)]) | 			for (auto node : sig_alu[RTLIL::SigSig(A, B)]) | ||||||
| 				if (node->is_signed == is_signed && node->invert_b && node->c == RTLIL::S1) { | 				if (node->is_signed == is_signed && node->invert_b && node->c == State::S1) { | ||||||
| 					n = node; | 					n = node; | ||||||
| 					break; | 					break; | ||||||
| 				} | 				} | ||||||
|  | @ -484,8 +484,8 @@ struct AlumaccWorker | ||||||
| 
 | 
 | ||||||
| 			n->alu_cell->setPort("\\A", n->a); | 			n->alu_cell->setPort("\\A", n->a); | ||||||
| 			n->alu_cell->setPort("\\B", n->b); | 			n->alu_cell->setPort("\\B", n->b); | ||||||
| 			n->alu_cell->setPort("\\CI", GetSize(n->c) ? n->c : RTLIL::S0); | 			n->alu_cell->setPort("\\CI", GetSize(n->c) ? n->c : State::S0); | ||||||
| 			n->alu_cell->setPort("\\BI", n->invert_b ? RTLIL::S1 : RTLIL::S0); | 			n->alu_cell->setPort("\\BI", n->invert_b ? State::S1 : State::S0); | ||||||
| 			n->alu_cell->setPort("\\Y", n->y); | 			n->alu_cell->setPort("\\Y", n->y); | ||||||
| 			n->alu_cell->setPort("\\X", module->addWire(NEW_ID, GetSize(n->y))); | 			n->alu_cell->setPort("\\X", module->addWire(NEW_ID, GetSize(n->y))); | ||||||
| 			n->alu_cell->setPort("\\CO", module->addWire(NEW_ID, GetSize(n->y))); | 			n->alu_cell->setPort("\\CO", module->addWire(NEW_ID, GetSize(n->y))); | ||||||
|  |  | ||||||
|  | @ -85,7 +85,7 @@ struct DeminoutPass : public Pass { | ||||||
| 
 | 
 | ||||||
| 					if (conn.first == "\\Y" && cell->type.in("$mux", "$pmux", "$_MUX_", "$_TBUF_", "$tribuf")) | 					if (conn.first == "\\Y" && cell->type.in("$mux", "$pmux", "$_MUX_", "$_TBUF_", "$tribuf")) | ||||||
| 					{ | 					{ | ||||||
| 						bool tribuf = (cell->type == "$_TBUF_" || cell->type == "$tribuf"); | 						bool tribuf = cell->type.in("$_TBUF_", "$tribuf"); | ||||||
| 
 | 
 | ||||||
| 						if (!tribuf) { | 						if (!tribuf) { | ||||||
| 							for (auto &c : cell->connections()) { | 							for (auto &c : cell->connections()) { | ||||||
|  |  | ||||||
|  | @ -52,13 +52,13 @@ struct Dff2dffeWorker | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for (auto cell : module->cells()) { | 		for (auto cell : module->cells()) { | ||||||
| 			if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$_MUX_") { | 			if (cell->type.in("$mux", "$pmux", "$_MUX_")) { | ||||||
| 				RTLIL::SigSpec sig_y = sigmap(cell->getPort("\\Y")); | 				RTLIL::SigSpec sig_y = sigmap(cell->getPort("\\Y")); | ||||||
| 				for (int i = 0; i < GetSize(sig_y); i++) | 				for (int i = 0; i < GetSize(sig_y); i++) | ||||||
| 					bit2mux[sig_y[i]] = cell_int_t(cell, i); | 					bit2mux[sig_y[i]] = cell_int_t(cell, i); | ||||||
| 			} | 			} | ||||||
| 			if (direct_dict.empty()) { | 			if (direct_dict.empty()) { | ||||||
| 				if (cell->type == "$dff" || cell->type == "$_DFF_N_" || cell->type == "$_DFF_P_") | 				if (cell->type.in("$dff", "$_DFF_N_", "$_DFF_P_")) | ||||||
| 					dff_cells.push_back(cell); | 					dff_cells.push_back(cell); | ||||||
| 			} else { | 			} else { | ||||||
| 				if (direct_dict.count(cell->type)) | 				if (direct_dict.count(cell->type)) | ||||||
|  | @ -167,7 +167,7 @@ struct Dff2dffeWorker | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (GetSize(or_input) == 0) | 		if (GetSize(or_input) == 0) | ||||||
| 			return RTLIL::S1; | 			return State::S1; | ||||||
| 
 | 
 | ||||||
| 		if (GetSize(or_input) == 1) | 		if (GetSize(or_input) == 1) | ||||||
| 			return or_input; | 			return or_input; | ||||||
|  | @ -304,7 +304,7 @@ struct Dff2dffePass : public Pass { | ||||||
| 			} | 			} | ||||||
| 			if (args[argidx] == "-unmap-mince" && argidx + 1 < args.size()) { | 			if (args[argidx] == "-unmap-mince" && argidx + 1 < args.size()) { | ||||||
| 				unmap_mode = true; | 				unmap_mode = true; | ||||||
| 				min_ce_use = std::stoi(args[++argidx]); | 				min_ce_use = atoi(args[++argidx].c_str()); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (args[argidx] == "-direct" && argidx + 2 < args.size()) { | 			if (args[argidx] == "-direct" && argidx + 2 < args.size()) { | ||||||
|  | @ -377,7 +377,7 @@ struct Dff2dffePass : public Pass { | ||||||
| 							mod->remove(cell); | 							mod->remove(cell); | ||||||
| 							continue; | 							continue; | ||||||
| 						} | 						} | ||||||
| 						if (cell->type.substr(0, 7) == "$_DFFE_") { | 						if (cell->type.begins_with("$_DFFE_")) { | ||||||
| 							if (min_ce_use >= 0) { | 							if (min_ce_use >= 0) { | ||||||
| 								int ce_use = 0; | 								int ce_use = 0; | ||||||
| 								for (auto cell_other : mod->selected_cells()) { | 								for (auto cell_other : mod->selected_cells()) { | ||||||
|  | @ -390,8 +390,8 @@ struct Dff2dffePass : public Pass { | ||||||
| 									continue; | 									continue; | ||||||
| 							} | 							} | ||||||
| 
 | 
 | ||||||
| 							bool clk_pol = cell->type.substr(7, 1) == "P"; | 							bool clk_pol = cell->type.compare(7, 1, "P") == 0; | ||||||
| 							bool en_pol = cell->type.substr(8, 1) == "P"; | 							bool en_pol = cell->type.compare(8, 1, "P") == 0; | ||||||
| 							RTLIL::SigSpec tmp = mod->addWire(NEW_ID); | 							RTLIL::SigSpec tmp = mod->addWire(NEW_ID); | ||||||
| 							mod->addDff(NEW_ID, cell->getPort("\\C"), tmp, cell->getPort("\\Q"), clk_pol); | 							mod->addDff(NEW_ID, cell->getPort("\\C"), tmp, cell->getPort("\\Q"), clk_pol); | ||||||
| 							if (en_pol) | 							if (en_pol) | ||||||
|  |  | ||||||
|  | @ -54,7 +54,7 @@ public: | ||||||
| 
 | 
 | ||||||
| 	RTLIL::Const unified_param(RTLIL::IdString cell_type, RTLIL::IdString param, RTLIL::Const value) | 	RTLIL::Const unified_param(RTLIL::IdString cell_type, RTLIL::IdString param, RTLIL::Const value) | ||||||
| 	{ | 	{ | ||||||
| 		if (cell_type.substr(0, 1) != "$" || cell_type.substr(0, 2) == "$_") | 		if (!cell_type.begins_with("$") || cell_type.begins_with("$_")) | ||||||
| 			return value; | 			return value; | ||||||
| 
 | 
 | ||||||
| 	#define param_bool(_n) if (param == _n) return value.as_bool(); | 	#define param_bool(_n) if (param == _n) return value.as_bool(); | ||||||
|  | @ -203,7 +203,7 @@ bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports, | ||||||
| 			continue; | 			continue; | ||||||
| 
 | 
 | ||||||
| 		std::string type = cell->type.str(); | 		std::string type = cell->type.str(); | ||||||
| 		if (sel == NULL && type.substr(0, 2) == "\\$") | 		if (sel == NULL && type.compare(0, 2, "\\$") == 0) | ||||||
| 			type = type.substr(1); | 			type = type.substr(1); | ||||||
| 		graph.createNode(cell->name.str(), type, (void*)cell); | 		graph.createNode(cell->name.str(), type, (void*)cell); | ||||||
| 
 | 
 | ||||||
|  | @ -594,7 +594,7 @@ struct ExtractPass : public Pass { | ||||||
| 			map = new RTLIL::Design; | 			map = new RTLIL::Design; | ||||||
| 			for (auto &filename : map_filenames) | 			for (auto &filename : map_filenames) | ||||||
| 			{ | 			{ | ||||||
| 				if (filename.substr(0, 1) == "%") | 				if (filename.compare(0, 1, "%") == 0) | ||||||
| 				{ | 				{ | ||||||
| 					if (!saved_designs.count(filename.substr(1))) { | 					if (!saved_designs.count(filename.substr(1))) { | ||||||
| 						delete map; | 						delete map; | ||||||
|  | @ -613,10 +613,10 @@ struct ExtractPass : public Pass { | ||||||
| 						delete map; | 						delete map; | ||||||
| 						log_cmd_error("Can't open map file `%s'.\n", filename.c_str()); | 						log_cmd_error("Can't open map file `%s'.\n", filename.c_str()); | ||||||
| 					} | 					} | ||||||
| 					Frontend::frontend_call(map, &f, filename, (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") ? "ilang" : "verilog"); | 					Frontend::frontend_call(map, &f, filename, (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "ilang" : "verilog")); | ||||||
| 					f.close(); | 					f.close(); | ||||||
| 
 | 
 | ||||||
| 					if (filename.size() <= 3 || filename.substr(filename.size()-3) != ".il") { | 					if (filename.size() <= 3 || filename.compare(filename.size()-3, std::string::npos, ".il") != 0) { | ||||||
| 						Pass::call(map, "proc"); | 						Pass::call(map, "proc"); | ||||||
| 						Pass::call(map, "opt_clean"); | 						Pass::call(map, "opt_clean"); | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
|  | @ -36,7 +36,7 @@ struct MaccmapWorker | ||||||
| 
 | 
 | ||||||
| 	void add(RTLIL::SigBit bit, int position) | 	void add(RTLIL::SigBit bit, int position) | ||||||
| 	{ | 	{ | ||||||
| 		if (position >= width || bit == RTLIL::S0) | 		if (position >= width || bit == State::S0) | ||||||
| 			return; | 			return; | ||||||
| 
 | 
 | ||||||
| 		if (bits.at(position).count(bit)) { | 		if (bits.at(position).count(bit)) { | ||||||
|  | @ -53,7 +53,7 @@ struct MaccmapWorker | ||||||
| 
 | 
 | ||||||
| 		if (do_subtract) { | 		if (do_subtract) { | ||||||
| 			a = module->Not(NEW_ID, a); | 			a = module->Not(NEW_ID, a); | ||||||
| 			add(RTLIL::S1, 0); | 			add(State::S1, 0); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for (int i = 0; i < width; i++) | 		for (int i = 0; i < width; i++) | ||||||
|  | @ -80,7 +80,7 @@ struct MaccmapWorker | ||||||
| 			else | 			else | ||||||
| 			{ | 			{ | ||||||
| 				add(module->And(NEW_ID, a, RTLIL::SigSpec(b[i], width)), false, do_subtract); | 				add(module->And(NEW_ID, a, RTLIL::SigSpec(b[i], width)), false, do_subtract); | ||||||
| 				a = {a.extract(0, width-1), RTLIL::S0}; | 				a = {a.extract(0, width-1), State::S0}; | ||||||
| 			} | 			} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -88,10 +88,10 @@ struct MaccmapWorker | ||||||
| 	{ | 	{ | ||||||
| 		int start_index = 0, stop_index = GetSize(in1); | 		int start_index = 0, stop_index = GetSize(in1); | ||||||
| 
 | 
 | ||||||
| 		while (start_index < stop_index && in1[start_index] == RTLIL::S0 && in2[start_index] == RTLIL::S0 && in3[start_index] == RTLIL::S0) | 		while (start_index < stop_index && in1[start_index] == State::S0 && in2[start_index] == RTLIL::S0 && in3[start_index] == RTLIL::S0) | ||||||
| 			start_index++; | 			start_index++; | ||||||
| 
 | 
 | ||||||
| 		while (start_index < stop_index && in1[stop_index-1] == RTLIL::S0 && in2[stop_index-1] == RTLIL::S0 && in3[stop_index-1] == RTLIL::S0) | 		while (start_index < stop_index && in1[stop_index-1] == State::S0 && in2[stop_index-1] == RTLIL::S0 && in3[stop_index-1] == RTLIL::S0) | ||||||
| 			stop_index--; | 			stop_index--; | ||||||
| 
 | 
 | ||||||
| 		if (start_index == stop_index) | 		if (start_index == stop_index) | ||||||
|  | @ -222,7 +222,7 @@ struct MaccmapWorker | ||||||
| 					RTLIL::SigSpec in3 = summands[i+2]; | 					RTLIL::SigSpec in3 = summands[i+2]; | ||||||
| 					RTLIL::SigSpec out1, out2; | 					RTLIL::SigSpec out1, out2; | ||||||
| 					fulladd(in1, in2, in3, out1, out2); | 					fulladd(in1, in2, in3, out1, out2); | ||||||
| 					RTLIL::SigBit extra_bit = RTLIL::S0; | 					RTLIL::SigBit extra_bit = State::S0; | ||||||
| 					if (!tree_sum_bits.empty()) { | 					if (!tree_sum_bits.empty()) { | ||||||
| 						extra_bit = tree_sum_bits.back(); | 						extra_bit = tree_sum_bits.back(); | ||||||
| 						tree_sum_bits.pop_back(); | 						tree_sum_bits.pop_back(); | ||||||
|  | @ -240,8 +240,8 @@ struct MaccmapWorker | ||||||
| 		RTLIL::Cell *c = module->addCell(NEW_ID, "$alu"); | 		RTLIL::Cell *c = module->addCell(NEW_ID, "$alu"); | ||||||
| 		c->setPort("\\A", summands.front()); | 		c->setPort("\\A", summands.front()); | ||||||
| 		c->setPort("\\B", summands.back()); | 		c->setPort("\\B", summands.back()); | ||||||
| 		c->setPort("\\CI", RTLIL::S0); | 		c->setPort("\\CI", State::S0); | ||||||
| 		c->setPort("\\BI", RTLIL::S0); | 		c->setPort("\\BI", State::S0); | ||||||
| 		c->setPort("\\Y", module->addWire(NEW_ID, width)); | 		c->setPort("\\Y", module->addWire(NEW_ID, width)); | ||||||
| 		c->setPort("\\X", module->addWire(NEW_ID, width)); | 		c->setPort("\\X", module->addWire(NEW_ID, width)); | ||||||
| 		c->setPort("\\CO", module->addWire(NEW_ID, width)); | 		c->setPort("\\CO", module->addWire(NEW_ID, width)); | ||||||
|  |  | ||||||
|  | @ -675,36 +675,36 @@ struct MuxcoverPass : public Pass { | ||||||
| 		for (argidx = 1; argidx < args.size(); argidx++) | 		for (argidx = 1; argidx < args.size(); argidx++) | ||||||
| 		{ | 		{ | ||||||
| 			const auto &arg = args[argidx]; | 			const auto &arg = args[argidx]; | ||||||
| 			if (arg.size() >= 6 && arg.substr(0,6) == "-mux2=") { | 			if (arg.size() >= 6 && arg.compare(0,6,"-mux2=") == 0) { | ||||||
| 				cost_mux2 = std::stoi(arg.substr(6)); | 				cost_mux2 = atoi(arg.substr(6).c_str()); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (arg.size() >= 5 && arg.substr(0,5) == "-mux4") { | 			if (arg.size() >= 5 && arg.compare(0,5,"-mux4") == 0) { | ||||||
| 				use_mux4 = true; | 				use_mux4 = true; | ||||||
| 				if (arg.size() > 5) { | 				if (arg.size() > 5) { | ||||||
| 					if (arg[5] != '=') break; | 					if (arg[5] != '=') break; | ||||||
| 					cost_mux4 = std::stoi(arg.substr(6)); | 					cost_mux4 = atoi(arg.substr(6).c_str()); | ||||||
| 				} | 				} | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (arg.size() >= 5 && arg.substr(0,5) == "-mux8") { | 			if (arg.size() >= 5 && arg.compare(0,5,"-mux8") == 0) { | ||||||
| 				use_mux8 = true; | 				use_mux8 = true; | ||||||
| 				if (arg.size() > 5) { | 				if (arg.size() > 5) { | ||||||
| 					if (arg[5] != '=') break; | 					if (arg[5] != '=') break; | ||||||
| 					cost_mux8 = std::stoi(arg.substr(6)); | 					cost_mux8 = atoi(arg.substr(6).c_str()); | ||||||
| 				} | 				} | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (arg.size() >= 6 && arg.substr(0,6) == "-mux16") { | 			if (arg.size() >= 6 && arg.compare(0,6,"-mux16") == 0) { | ||||||
| 				use_mux16 = true; | 				use_mux16 = true; | ||||||
| 				if (arg.size() > 6) { | 				if (arg.size() > 6) { | ||||||
| 					if (arg[6] != '=') break; | 					if (arg[6] != '=') break; | ||||||
| 					cost_mux16 = std::stoi(arg.substr(7)); | 					cost_mux16 = atoi(arg.substr(7).c_str()); | ||||||
| 				} | 				} | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (arg.size() >= 6 && arg.substr(0,6) == "-dmux=") { | 			if (arg.size() >= 6 && arg.compare(0,6,"-dmux=") == 0) { | ||||||
| 				cost_dmux = std::stoi(arg.substr(6)); | 				cost_dmux = atoi(arg.substr(6).c_str()); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (arg == "-nodecode") { | 			if (arg == "-nodecode") { | ||||||
|  |  | ||||||
|  | @ -185,7 +185,7 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLIL::Cell | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (sig.size() == 0) | 	if (sig.size() == 0) | ||||||
| 		sig = RTLIL::SigSpec(0, 1); | 		sig = State::S0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell) | void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell) | ||||||
|  | @ -245,7 +245,7 @@ void simplemap_eqne(RTLIL::Module *module, RTLIL::Cell *cell) | ||||||
| 	RTLIL::SigSpec sig_b = cell->getPort("\\B"); | 	RTLIL::SigSpec sig_b = cell->getPort("\\B"); | ||||||
| 	RTLIL::SigSpec sig_y = cell->getPort("\\Y"); | 	RTLIL::SigSpec sig_y = cell->getPort("\\Y"); | ||||||
| 	bool is_signed = cell->parameters.at("\\A_SIGNED").as_bool(); | 	bool is_signed = cell->parameters.at("\\A_SIGNED").as_bool(); | ||||||
| 	bool is_ne = cell->type == "$ne" || cell->type == "$nex"; | 	bool is_ne = cell->type.in("$ne", "$nex"); | ||||||
| 
 | 
 | ||||||
| 	RTLIL::SigSpec xor_out = module->addWire(NEW_ID, max(GetSize(sig_a), GetSize(sig_b))); | 	RTLIL::SigSpec xor_out = module->addWire(NEW_ID, max(GetSize(sig_a), GetSize(sig_b))); | ||||||
| 	RTLIL::Cell *xor_cell = module->addXor(NEW_ID, sig_a, sig_b, xor_out, is_signed); | 	RTLIL::Cell *xor_cell = module->addXor(NEW_ID, sig_a, sig_b, xor_out, is_signed); | ||||||
|  |  | ||||||
|  | @ -243,7 +243,7 @@ struct TechmapWorker | ||||||
| 			if (positional_ports.count(portname) > 0) | 			if (positional_ports.count(portname) > 0) | ||||||
| 				portname = positional_ports.at(portname); | 				portname = positional_ports.at(portname); | ||||||
| 			if (tpl->wires_.count(portname) == 0 || tpl->wires_.at(portname)->port_id == 0) { | 			if (tpl->wires_.count(portname) == 0 || tpl->wires_.at(portname)->port_id == 0) { | ||||||
| 				if (portname.substr(0, 1) == "$") | 				if (portname.begins_with("$")) | ||||||
| 					log_error("Can't map port `%s' of cell `%s' to template `%s'!\n", portname.c_str(), cell->name.c_str(), tpl->name.c_str()); | 					log_error("Can't map port `%s' of cell `%s' to template `%s'!\n", portname.c_str(), cell->name.c_str(), tpl->name.c_str()); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|  | @ -341,7 +341,7 @@ struct TechmapWorker | ||||||
| 			RTLIL::Cell *c = module->addCell(c_name, it.second); | 			RTLIL::Cell *c = module->addCell(c_name, it.second); | ||||||
| 			design->select(module, c); | 			design->select(module, c); | ||||||
| 
 | 
 | ||||||
| 			if (!flatten_mode && c->type.substr(0, 2) == "\\$") | 			if (!flatten_mode && c->type.begins_with("\\$")) | ||||||
| 				c->type = c->type.substr(1); | 				c->type = c->type.substr(1); | ||||||
| 
 | 
 | ||||||
| 			for (auto &it2 : c->connections_) { | 			for (auto &it2 : c->connections_) { | ||||||
|  | @ -406,7 +406,7 @@ struct TechmapWorker | ||||||
| 				continue; | 				continue; | ||||||
| 
 | 
 | ||||||
| 			std::string cell_type = cell->type.str(); | 			std::string cell_type = cell->type.str(); | ||||||
| 			if (in_recursion && cell_type.substr(0, 2) == "\\$") | 			if (in_recursion && cell->type.begins_with("\\$")) | ||||||
| 				cell_type = cell_type.substr(1); | 				cell_type = cell_type.substr(1); | ||||||
| 
 | 
 | ||||||
| 			if (celltypeMap.count(cell_type) == 0) { | 			if (celltypeMap.count(cell_type) == 0) { | ||||||
|  | @ -468,7 +468,7 @@ struct TechmapWorker | ||||||
| 
 | 
 | ||||||
| 			std::string cell_type = cell->type.str(); | 			std::string cell_type = cell->type.str(); | ||||||
| 
 | 
 | ||||||
| 			if (in_recursion && cell_type.substr(0, 2) == "\\$") | 			if (in_recursion && cell->type.begins_with("\\$")) | ||||||
| 				cell_type = cell_type.substr(1); | 				cell_type = cell_type.substr(1); | ||||||
| 
 | 
 | ||||||
| 			for (auto &tpl_name : celltypeMap.at(cell_type)) | 			for (auto &tpl_name : celltypeMap.at(cell_type)) | ||||||
|  | @ -602,7 +602,7 @@ struct TechmapWorker | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					for (auto conn : cell->connections()) { | 					for (auto conn : cell->connections()) { | ||||||
| 						if (conn.first.substr(0, 1) == "$") | 						if (conn.first.begins_with("$")) | ||||||
| 							continue; | 							continue; | ||||||
| 						if (tpl->wires_.count(conn.first) > 0 && tpl->wires_.at(conn.first)->port_id > 0) | 						if (tpl->wires_.count(conn.first) > 0 && tpl->wires_.at(conn.first)->port_id > 0) | ||||||
| 							continue; | 							continue; | ||||||
|  | @ -725,7 +725,7 @@ struct TechmapWorker | ||||||
| 
 | 
 | ||||||
| 						for (auto &it : twd) | 						for (auto &it : twd) | ||||||
| 						{ | 						{ | ||||||
| 							if (it.first.substr(0, 12) != "_TECHMAP_DO_" || it.second.empty()) | 							if (it.first.compare(0, 12, "_TECHMAP_DO_") != 0 || it.second.empty()) | ||||||
| 								continue; | 								continue; | ||||||
| 
 | 
 | ||||||
| 							auto &data = it.second.front(); | 							auto &data = it.second.front(); | ||||||
|  | @ -874,7 +874,7 @@ struct TechmapWorker | ||||||
| 						tpl->cloneInto(m); | 						tpl->cloneInto(m); | ||||||
| 
 | 
 | ||||||
| 						for (auto cell : m->cells()) { | 						for (auto cell : m->cells()) { | ||||||
| 							if (cell->type.substr(0, 2) == "\\$") | 							if (cell->type.begins_with("\\$")) | ||||||
| 								cell->type = cell->type.substr(1); | 								cell->type = cell->type.substr(1); | ||||||
| 						} | 						} | ||||||
| 
 | 
 | ||||||
|  | @ -1113,7 +1113,7 @@ struct TechmapPass : public Pass { | ||||||
| 			Frontend::frontend_call(map, &f, "<techmap.v>", verilog_frontend); | 			Frontend::frontend_call(map, &f, "<techmap.v>", verilog_frontend); | ||||||
| 		} else { | 		} else { | ||||||
| 			for (auto &fn : map_files) | 			for (auto &fn : map_files) | ||||||
| 				if (fn.substr(0, 1) == "%") { | 				if (fn.compare(0, 1, "%") == 0) { | ||||||
| 					if (!saved_designs.count(fn.substr(1))) { | 					if (!saved_designs.count(fn.substr(1))) { | ||||||
| 						delete map; | 						delete map; | ||||||
| 						log_cmd_error("Can't saved design `%s'.\n", fn.c_str()+1); | 						log_cmd_error("Can't saved design `%s'.\n", fn.c_str()+1); | ||||||
|  | @ -1128,7 +1128,7 @@ struct TechmapPass : public Pass { | ||||||
| 					yosys_input_files.insert(fn); | 					yosys_input_files.insert(fn); | ||||||
| 					if (f.fail()) | 					if (f.fail()) | ||||||
| 						log_cmd_error("Can't open map file `%s'\n", fn.c_str()); | 						log_cmd_error("Can't open map file `%s'\n", fn.c_str()); | ||||||
| 					Frontend::frontend_call(map, &f, fn, (fn.size() > 3 && fn.substr(fn.size()-3) == ".il") ? "ilang" : verilog_frontend); | 					Frontend::frontend_call(map, &f, fn, (fn.size() > 3 && fn.compare(fn.size()-3, std::string::npos, ".il") == 0 ? "ilang" : verilog_frontend)); | ||||||
| 				} | 				} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -1143,7 +1143,7 @@ struct TechmapPass : public Pass { | ||||||
| 				free(p); | 				free(p); | ||||||
| 			} else { | 			} else { | ||||||
| 				string module_name = it.first.str(); | 				string module_name = it.first.str(); | ||||||
| 				if (module_name.substr(0, 2) == "\\$") | 				if (it.first.begins_with("\\$")) | ||||||
| 					module_name = module_name.substr(1); | 					module_name = module_name.substr(1); | ||||||
| 				celltypeMap[module_name].insert(it.first); | 				celltypeMap[module_name].insert(it.first); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | @ -186,7 +186,7 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, | ||||||
| 
 | 
 | ||||||
| 		RTLIL::SigSpec config; | 		RTLIL::SigSpec config; | ||||||
| 		for (int i = 0; i < (1 << width); i++) | 		for (int i = 0; i < (1 << width); i++) | ||||||
| 			config.append(xorshift32(2) ? RTLIL::S1 : RTLIL::S0); | 			config.append(xorshift32(2) ? State::S1 : State::S0); | ||||||
| 
 | 
 | ||||||
| 		cell->setParam("\\LUT", config.as_const()); | 		cell->setParam("\\LUT", config.as_const()); | ||||||
| 	} | 	} | ||||||
|  | @ -209,16 +209,16 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, | ||||||
| 		for (int i = 0; i < width*depth; i++) | 		for (int i = 0; i < width*depth; i++) | ||||||
| 			switch (xorshift32(3)) { | 			switch (xorshift32(3)) { | ||||||
| 				case 0: | 				case 0: | ||||||
| 					config.append(RTLIL::S1); | 					config.append(State::S1); | ||||||
| 					config.append(RTLIL::S0); | 					config.append(State::S0); | ||||||
| 					break; | 					break; | ||||||
| 				case 1: | 				case 1: | ||||||
| 					config.append(RTLIL::S0); | 					config.append(State::S0); | ||||||
| 					config.append(RTLIL::S1); | 					config.append(State::S1); | ||||||
| 					break; | 					break; | ||||||
| 				case 2: | 				case 2: | ||||||
| 					config.append(RTLIL::S0); | 					config.append(State::S0); | ||||||
| 					config.append(RTLIL::S0); | 					config.append(State::S0); | ||||||
| 					break; | 					break; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | @ -308,18 +308,18 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, | ||||||
| 			case 0: | 			case 0: | ||||||
| 				n = xorshift32(GetSize(sig) + 1); | 				n = xorshift32(GetSize(sig) + 1); | ||||||
| 				for (int i = 0; i < n; i++) | 				for (int i = 0; i < n; i++) | ||||||
| 					sig[i] = xorshift32(2) == 1 ? RTLIL::S1 : RTLIL::S0; | 					sig[i] = xorshift32(2) == 1 ? State::S1 : State::S0; | ||||||
| 				break; | 				break; | ||||||
| 			case 1: | 			case 1: | ||||||
| 				n = xorshift32(GetSize(sig) + 1); | 				n = xorshift32(GetSize(sig) + 1); | ||||||
| 				for (int i = n; i < GetSize(sig); i++) | 				for (int i = n; i < GetSize(sig); i++) | ||||||
| 					sig[i] = xorshift32(2) == 1 ? RTLIL::S1 : RTLIL::S0; | 					sig[i] = xorshift32(2) == 1 ? State::S1 : State::S0; | ||||||
| 				break; | 				break; | ||||||
| 			case 2: | 			case 2: | ||||||
| 				n = xorshift32(GetSize(sig)); | 				n = xorshift32(GetSize(sig)); | ||||||
| 				m = xorshift32(GetSize(sig)); | 				m = xorshift32(GetSize(sig)); | ||||||
| 				for (int i = min(n, m); i < max(n, m); i++) | 				for (int i = min(n, m); i < max(n, m); i++) | ||||||
| 					sig[i] = xorshift32(2) == 1 ? RTLIL::S1 : RTLIL::S0; | 					sig[i] = xorshift32(2) == 1 ? State::S1 : State::S0; | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | @ -491,7 +491,7 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: | ||||||
| 
 | 
 | ||||||
| 			RTLIL::Const in_value; | 			RTLIL::Const in_value; | ||||||
| 			for (int i = 0; i < GetSize(gold_wire); i++) | 			for (int i = 0; i < GetSize(gold_wire); i++) | ||||||
| 				in_value.bits.push_back(xorshift32(2) ? RTLIL::S1 : RTLIL::S0); | 				in_value.bits.push_back(xorshift32(2) ? State::S1 : State::S0); | ||||||
| 
 | 
 | ||||||
| 			if (xorshift32(4) == 0) { | 			if (xorshift32(4) == 0) { | ||||||
| 				int inv_chance = 1 + xorshift32(8); | 				int inv_chance = 1 + xorshift32(8); | ||||||
|  | @ -591,11 +591,11 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			for (int i = 0; i < GetSize(out_sig); i++) { | 			for (int i = 0; i < GetSize(out_sig); i++) { | ||||||
| 				if (out_val[i] != RTLIL::S0 && out_val[i] != RTLIL::S1) | 				if (out_val[i] != State::S0 && out_val[i] != State::S1) | ||||||
| 					continue; | 					continue; | ||||||
| 				if (out_val[i] == RTLIL::S0 && sat1_model_value.at(i) == false) | 				if (out_val[i] == State::S0 && sat1_model_value.at(i) == false) | ||||||
| 					continue; | 					continue; | ||||||
| 				if (out_val[i] == RTLIL::S1 && sat1_model_value.at(i) == true) | 				if (out_val[i] == State::S1 && sat1_model_value.at(i) == true) | ||||||
| 					continue; | 					continue; | ||||||
| 				log_error("Mismatch in sat model 1 (no undef modeling) output!\n"); | 				log_error("Mismatch in sat model 1 (no undef modeling) output!\n"); | ||||||
| 			} | 			} | ||||||
|  | @ -627,12 +627,12 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: | ||||||
| 
 | 
 | ||||||
| 			for (int i = 0; i < GetSize(out_sig); i++) { | 			for (int i = 0; i < GetSize(out_sig); i++) { | ||||||
| 				if (sat2_model_value.at(GetSize(out_sig) + i)) { | 				if (sat2_model_value.at(GetSize(out_sig) + i)) { | ||||||
| 					if (out_val[i] != RTLIL::S0 && out_val[i] != RTLIL::S1) | 					if (out_val[i] != State::S0 && out_val[i] != State::S1) | ||||||
| 						continue; | 						continue; | ||||||
| 				} else { | 				} else { | ||||||
| 					if (out_val[i] == RTLIL::S0 && sat2_model_value.at(i) == false) | 					if (out_val[i] == State::S0 && sat2_model_value.at(i) == false) | ||||||
| 						continue; | 						continue; | ||||||
| 					if (out_val[i] == RTLIL::S1 && sat2_model_value.at(i) == true) | 					if (out_val[i] == State::S1 && sat2_model_value.at(i) == true) | ||||||
| 						continue; | 						continue; | ||||||
| 				} | 				} | ||||||
| 				log_error("Mismatch in sat model 2 (undef modeling) output!\n"); | 				log_error("Mismatch in sat model 2 (undef modeling) output!\n"); | ||||||
|  | @ -872,7 +872,7 @@ struct TestCellPass : public Pass { | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (args[argidx].substr(0, 1) == "/") { | 			if (args[argidx].compare(0, 1, "/") == 0) { | ||||||
| 				std::vector<std::string> new_selected_cell_types; | 				std::vector<std::string> new_selected_cell_types; | ||||||
| 				for (auto it : selected_cell_types) | 				for (auto it : selected_cell_types) | ||||||
| 					if (it != args[argidx].substr(1)) | 					if (it != args[argidx].substr(1)) | ||||||
|  |  | ||||||
|  | @ -532,14 +532,26 @@ endmodule | ||||||
| 
 | 
 | ||||||
| // -------------------------------------------------------- | // -------------------------------------------------------- | ||||||
| 
 | 
 | ||||||
|  | //  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| | ||||||
|  | //- | ||||||
|  | //-     $lcu (P, G, CI, CO) | ||||||
|  | //- | ||||||
|  | //- Lookahead carry unit | ||||||
|  | //- A building block dedicated to fast computation of carry-bits used in binary | ||||||
|  | //- arithmetic operations. By replacing the ripple carry structure used in full-adder | ||||||
|  | //- blocks, the more significant  bits of the sum can be expected to be computed more | ||||||
|  | //- quickly. | ||||||
|  | //- Typically created during `techmap` of $alu cells (see the "_90_alu" rule in | ||||||
|  | //- +/techmap.v). | ||||||
| module \$lcu (P, G, CI, CO); | module \$lcu (P, G, CI, CO); | ||||||
| 
 | 
 | ||||||
| parameter WIDTH = 1; | parameter WIDTH = 1; | ||||||
| 
 | 
 | ||||||
| input [WIDTH-1:0] P, G; | input [WIDTH-1:0] P;    // Propagate | ||||||
| input CI; | input [WIDTH-1:0] G;    // Generate | ||||||
|  | input CI;               // Carry-in | ||||||
| 
 | 
 | ||||||
| output reg [WIDTH-1:0] CO; | output reg [WIDTH-1:0] CO; // Carry-out | ||||||
| 
 | 
 | ||||||
| integer i; | integer i; | ||||||
| always @* begin | always @* begin | ||||||
|  | @ -555,6 +567,17 @@ endmodule | ||||||
| 
 | 
 | ||||||
| // -------------------------------------------------------- | // -------------------------------------------------------- | ||||||
| 
 | 
 | ||||||
|  | //  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| | ||||||
|  | //- | ||||||
|  | //-     $alu (A, B, CI, BI, X, Y, CO) | ||||||
|  | //- | ||||||
|  | //- Arithmetic logic unit. | ||||||
|  | //- A building block supporting both binary addition/subtraction operations, and | ||||||
|  | //- indirectly, comparison operations. | ||||||
|  | //- Typically created by the `alumacc` pass, which transforms: | ||||||
|  | //-   $add, $sub, $lt, $le, $ge, $gt, $eq, $eqx, $ne, $nex | ||||||
|  | //- cells into this $alu cell. | ||||||
|  | //- | ||||||
| module \$alu (A, B, CI, BI, X, Y, CO); | module \$alu (A, B, CI, BI, X, Y, CO); | ||||||
| 
 | 
 | ||||||
| parameter A_SIGNED = 0; | parameter A_SIGNED = 0; | ||||||
|  | @ -563,12 +586,16 @@ parameter A_WIDTH = 1; | ||||||
| parameter B_WIDTH = 1; | parameter B_WIDTH = 1; | ||||||
| parameter Y_WIDTH = 1; | parameter Y_WIDTH = 1; | ||||||
| 
 | 
 | ||||||
| input [A_WIDTH-1:0] A; | input [A_WIDTH-1:0] A;      // Input operand | ||||||
| input [B_WIDTH-1:0] B; | input [B_WIDTH-1:0] B;      // Input operand | ||||||
| output [Y_WIDTH-1:0] X, Y; | output [Y_WIDTH-1:0] X;     // A xor B (sign-extended, optional B inversion, | ||||||
|  |                             //          used in combination with | ||||||
|  |                             //          reduction-AND for $eq/$ne ops) | ||||||
|  | output [Y_WIDTH-1:0] Y;     // Sum | ||||||
| 
 | 
 | ||||||
| input CI, BI; | input CI;                   // Carry-in (set for $sub) | ||||||
| output [Y_WIDTH-1:0] CO; | input BI;                   // Invert-B (set for $sub) | ||||||
|  | output [Y_WIDTH-1:0] CO;    // Carry-out | ||||||
| 
 | 
 | ||||||
| wire [Y_WIDTH-1:0] AA, BB; | wire [Y_WIDTH-1:0] AA, BB; | ||||||
| 
 | 
 | ||||||
|  | @ -584,6 +611,7 @@ endgenerate | ||||||
| wire y_co_undef = ^{A, A, B, B, CI, CI, BI, BI}; | wire y_co_undef = ^{A, A, B, B, CI, CI, BI, BI}; | ||||||
| 
 | 
 | ||||||
| assign X = AA ^ BB; | assign X = AA ^ BB; | ||||||
|  | // Full adder | ||||||
| assign Y = (AA + BB + CI) ^ {Y_WIDTH{y_co_undef}}; | assign Y = (AA + BB + CI) ^ {Y_WIDTH{y_co_undef}}; | ||||||
| 
 | 
 | ||||||
| function get_carry; | function get_carry; | ||||||
|  |  | ||||||
|  | @ -60,10 +60,8 @@ struct Coolrunner2SopPass : public Pass { | ||||||
| 			dict<SigBit, pool<tuple<Cell*, std::string>>> special_pterms_inv; | 			dict<SigBit, pool<tuple<Cell*, std::string>>> special_pterms_inv; | ||||||
| 			for (auto cell : module->selected_cells()) | 			for (auto cell : module->selected_cells()) | ||||||
| 			{ | 			{ | ||||||
| 				if (cell->type == "\\FDCP" || cell->type == "\\FDCP_N" || cell->type == "\\FDDCP" || | 				if (cell->type.in("\\FDCP", "\\FDCP_N", "\\FDDCP", "\\FTCP", "\\FTCP_N", "\\FTDCP", | ||||||
| 					cell->type == "\\FTCP" || cell->type == "\\FTCP_N" || cell->type == "\\FTDCP" || | 							"\\FDCPE", "\\FDCPE_N", "\\FDDCPE", "\\LDCP", "\\LDCP_N")) | ||||||
| 					cell->type == "\\FDCPE" || cell->type == "\\FDCPE_N" || cell->type == "\\FDDCPE" || |  | ||||||
| 					cell->type == "\\LDCP" || cell->type == "\\LDCP_N") |  | ||||||
| 				{ | 				{ | ||||||
| 					if (cell->hasPort("\\PRE")) | 					if (cell->hasPort("\\PRE")) | ||||||
| 						special_pterms_no_inv[sigmap(cell->getPort("\\PRE")[0])].insert( | 						special_pterms_no_inv[sigmap(cell->getPort("\\PRE")[0])].insert( | ||||||
|  | @ -257,10 +255,8 @@ struct Coolrunner2SopPass : public Pass { | ||||||
| 			pool<SigBit> sig_fed_by_ff; | 			pool<SigBit> sig_fed_by_ff; | ||||||
| 			for (auto cell : module->selected_cells()) | 			for (auto cell : module->selected_cells()) | ||||||
| 			{ | 			{ | ||||||
| 				if (cell->type == "\\FDCP" || cell->type == "\\FDCP_N" || cell->type == "\\FDDCP" || | 				if (cell->type.in("\\FDCP", "\\FDCP_N", "\\FDDCP", "\\LDCP", "\\LDCP_N", | ||||||
| 					cell->type == "\\LDCP" || cell->type == "\\LDCP_N" || | 							"\\FTCP", "\\FTCP_N", "\\FTDCP", "\\FDCPE", "\\FDCPE_N", "\\FDDCPE")) | ||||||
| 					cell->type == "\\FTCP" || cell->type == "\\FTCP_N" || cell->type == "\\FTDCP" || |  | ||||||
| 					cell->type == "\\FDCPE" || cell->type == "\\FDCPE_N" || cell->type == "\\FDDCPE") |  | ||||||
| 				{ | 				{ | ||||||
| 					auto output = sigmap(cell->getPort("\\Q")[0]); | 					auto output = sigmap(cell->getPort("\\Q")[0]); | ||||||
| 					sig_fed_by_ff.insert(output); | 					sig_fed_by_ff.insert(output); | ||||||
|  | @ -270,13 +266,11 @@ struct Coolrunner2SopPass : public Pass { | ||||||
| 			// Look at all the FF inputs
 | 			// Look at all the FF inputs
 | ||||||
| 			for (auto cell : module->selected_cells()) | 			for (auto cell : module->selected_cells()) | ||||||
| 			{ | 			{ | ||||||
| 				if (cell->type == "\\FDCP" || cell->type == "\\FDCP_N" || cell->type == "\\FDDCP" || | 				if (cell->type.in("\\FDCP", "\\FDCP_N", "\\FDDCP", "\\LDCP", "\\LDCP_N", | ||||||
| 					cell->type == "\\LDCP" || cell->type == "\\LDCP_N" || | 							"\\FTCP", "\\FTCP_N", "\\FTDCP", "\\FDCPE", "\\FDCPE_N", "\\FDDCPE")) | ||||||
| 					cell->type == "\\FTCP" || cell->type == "\\FTCP_N" || cell->type == "\\FTDCP" || |  | ||||||
| 					cell->type == "\\FDCPE" || cell->type == "\\FDCPE_N" || cell->type == "\\FDDCPE") |  | ||||||
| 				{ | 				{ | ||||||
| 					SigBit input; | 					SigBit input; | ||||||
| 					if (cell->type == "\\FTCP" || cell->type == "\\FTCP_N" || cell->type == "\\FTDCP") | 					if (cell->type.in("\\FTCP", "\\FTCP_N", "\\FTDCP")) | ||||||
| 						input = sigmap(cell->getPort("\\T")[0]); | 						input = sigmap(cell->getPort("\\T")[0]); | ||||||
| 					else | 					else | ||||||
| 						input = sigmap(cell->getPort("\\D")[0]); | 						input = sigmap(cell->getPort("\\D")[0]); | ||||||
|  | @ -300,7 +294,7 @@ struct Coolrunner2SopPass : public Pass { | ||||||
| 						xor_cell->setPort("\\IN_PTC", and_to_xor_wire); | 						xor_cell->setPort("\\IN_PTC", and_to_xor_wire); | ||||||
| 						xor_cell->setPort("\\OUT", xor_to_ff_wire); | 						xor_cell->setPort("\\OUT", xor_to_ff_wire); | ||||||
| 
 | 
 | ||||||
| 						if (cell->type == "\\FTCP" || cell->type == "\\FTCP_N" || cell->type == "\\FTDCP") | 						if (cell->type.in("\\FTCP", "\\FTCP_N", "\\FTDCP")) | ||||||
| 							cell->setPort("\\T", xor_to_ff_wire); | 							cell->setPort("\\T", xor_to_ff_wire); | ||||||
| 						else | 						else | ||||||
| 							cell->setPort("\\D", xor_to_ff_wire); | 							cell->setPort("\\D", xor_to_ff_wire); | ||||||
|  |  | ||||||
|  | @ -69,13 +69,13 @@ static void run_ice40_braminit(Module *module) | ||||||
| 
 | 
 | ||||||
| 			for (int i = 0; i < GetSize(line); i++) | 			for (int i = 0; i < GetSize(line); i++) | ||||||
| 			{ | 			{ | ||||||
| 				if (in_comment && line.substr(i, 2) == "*/") { | 				if (in_comment && line.compare(i, 2, "*/") == 0) { | ||||||
| 					line[i] = ' '; | 					line[i] = ' '; | ||||||
| 					line[i+1] = ' '; | 					line[i+1] = ' '; | ||||||
| 					in_comment = false; | 					in_comment = false; | ||||||
| 					continue; | 					continue; | ||||||
| 				} | 				} | ||||||
| 				if (!in_comment && line.substr(i, 2) == "/*") | 				if (!in_comment && line.compare(i, 2, "/*") == 0) | ||||||
| 					in_comment = true; | 					in_comment = true; | ||||||
| 				if (in_comment) | 				if (in_comment) | ||||||
| 					line[i] = ' '; | 					line[i] = ' '; | ||||||
|  | @ -87,7 +87,7 @@ static void run_ice40_braminit(Module *module) | ||||||
| 				long value; | 				long value; | ||||||
| 
 | 
 | ||||||
| 				token = next_token(line, " \t\r\n"); | 				token = next_token(line, " \t\r\n"); | ||||||
| 				if (token.empty() || token.substr(0, 2) == "//") | 				if (token.empty() || token.compare(0, 2, "//") == 0) | ||||||
| 					break; | 					break; | ||||||
| 
 | 
 | ||||||
| 				if (token[0] == '@') { | 				if (token[0] == '@') { | ||||||
|  |  | ||||||
|  | @ -117,7 +117,7 @@ static void run_ice40_opts(Module *module) | ||||||
| 				log("Optimized $__ICE40_FULL_ADDER cell back to logic (without SB_CARRY) %s.%s: CO=%s\n", | 				log("Optimized $__ICE40_FULL_ADDER cell back to logic (without SB_CARRY) %s.%s: CO=%s\n", | ||||||
| 						log_id(module), log_id(cell), log_signal(replacement_output)); | 						log_id(module), log_id(cell), log_signal(replacement_output)); | ||||||
| 				cell->type = "$lut"; | 				cell->type = "$lut"; | ||||||
| 				cell->setPort("\\A", { RTLIL::S0, inbit[0], inbit[1], inbit[2] }); | 				cell->setPort("\\A", { State::S0, inbit[0], inbit[1], inbit[2] }); | ||||||
| 				cell->setPort("\\Y", cell->getPort("\\O")); | 				cell->setPort("\\Y", cell->getPort("\\O")); | ||||||
| 				cell->unsetPort("\\B"); | 				cell->unsetPort("\\B"); | ||||||
| 				cell->unsetPort("\\CI"); | 				cell->unsetPort("\\CI"); | ||||||
|  |  | ||||||
|  | @ -183,7 +183,7 @@ struct SynthIce40Pass : public ScriptPass | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (args[argidx] == "-dffe_min_ce_use" && argidx+1 < args.size()) { | 			if (args[argidx] == "-dffe_min_ce_use" && argidx+1 < args.size()) { | ||||||
| 				min_ce_use = std::stoi(args[++argidx]); | 				min_ce_use = atoi(args[++argidx].c_str()); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (args[argidx] == "-nobram") { | 			if (args[argidx] == "-nobram") { | ||||||
|  |  | ||||||
|  | @ -199,7 +199,7 @@ struct SynthXilinxPass : public ScriptPass | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (args[argidx] == "-widemux" && argidx+1 < args.size()) { | 			if (args[argidx] == "-widemux" && argidx+1 < args.size()) { | ||||||
| 				widemux = std::stoi(args[++argidx]); | 				widemux = atoi(args[++argidx].c_str()); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (args[argidx] == "-abc9") { | 			if (args[argidx] == "-abc9") { | ||||||
|  |  | ||||||
|  | @ -5,144 +5,219 @@ module opt_expr_add_test(input [3:0] i, input [7:0] j, output [8:0] o); | ||||||
| endmodule | endmodule | ||||||
| EOT | EOT | ||||||
| 
 | 
 | ||||||
| hierarchy -auto-top | equiv_opt -assert opt_expr -fine | ||||||
| proc | design -load postopt | ||||||
| design -save gold |  | ||||||
| 
 | 
 | ||||||
| opt_expr -fine | select -assert-count 1 t:$add r:A_WIDTH=5 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i | ||||||
| wreduce |  | ||||||
| 
 |  | ||||||
| select -assert-count 1 t:$add r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i |  | ||||||
| 
 |  | ||||||
| design -stash gate |  | ||||||
| 
 |  | ||||||
| design -import gold -as gold |  | ||||||
| design -import gate -as gate |  | ||||||
| 
 |  | ||||||
| miter -equiv -flatten -make_assert -make_outputs gold gate miter |  | ||||||
| sat -verify -prove-asserts -show-ports miter |  | ||||||
| 
 | 
 | ||||||
| ########## | ########## | ||||||
| 
 | 
 | ||||||
|  | # alumacc version of above | ||||||
|  | design -reset | ||||||
|  | read_verilog <<EOT | ||||||
|  | module opt_expr_add_test(input [3:0] i, input [7:0] j, output [8:0] o); | ||||||
|  |     assign o = (i << 4) + j; | ||||||
|  | endmodule | ||||||
|  | EOT | ||||||
|  | 
 | ||||||
|  | alumacc | ||||||
|  | equiv_opt -assert opt_expr -fine | ||||||
|  | design -load postopt | ||||||
|  | 
 | ||||||
|  | select -assert-count 1 t:$alu r:A_WIDTH=4 r:B_WIDTH=5 r:Y_WIDTH=5 %i %i %i | ||||||
|  | 
 | ||||||
|  | ########## | ||||||
|  | 
 | ||||||
|  | design -reset | ||||||
| read_verilog <<EOT | read_verilog <<EOT | ||||||
| module opt_expr_add_signed_test(input signed [3:0] i, input signed [7:0] j, output signed [8:0] o); | module opt_expr_add_signed_test(input signed [3:0] i, input signed [7:0] j, output signed [8:0] o); | ||||||
|     assign o = (i << 4) + j; |     assign o = (i << 4) + j; | ||||||
| endmodule | endmodule | ||||||
| EOT | EOT | ||||||
| 
 | 
 | ||||||
| hierarchy -auto-top | equiv_opt -assert opt_expr -fine | ||||||
| proc | design -load postopt | ||||||
| design -save gold |  | ||||||
| 
 | 
 | ||||||
| opt_expr -fine | select -assert-count 1 t:$add r:A_WIDTH=5 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i | ||||||
| wreduce |  | ||||||
| 
 |  | ||||||
| select -assert-count 1 t:$add r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i |  | ||||||
| 
 |  | ||||||
| design -stash gate |  | ||||||
| 
 |  | ||||||
| design -import gold -as gold |  | ||||||
| design -import gate -as gate |  | ||||||
| 
 |  | ||||||
| miter -equiv -flatten -make_assert -make_outputs gold gate miter |  | ||||||
| sat -verify -prove-asserts -show-ports miter |  | ||||||
| 
 | 
 | ||||||
| ########## | ########## | ||||||
| 
 | 
 | ||||||
|  | # alumacc version of above | ||||||
|  | design -reset | ||||||
|  | read_verilog <<EOT | ||||||
|  | module opt_expr_add_signed_test(input signed [3:0] i, input signed [7:0] j, output signed [8:0] o); | ||||||
|  |     assign o = (i << 4) + j; | ||||||
|  | endmodule | ||||||
|  | EOT | ||||||
|  | 
 | ||||||
|  | alumacc | ||||||
|  | equiv_opt -assert opt_expr -fine | ||||||
|  | design -load postopt | ||||||
|  | 
 | ||||||
|  | select -assert-count 1 t:$alu r:A_WIDTH=4 r:B_WIDTH=5 r:Y_WIDTH=5 %i %i %i | ||||||
|  | 
 | ||||||
|  | ########## | ||||||
|  | 
 | ||||||
|  | design -reset | ||||||
| read_verilog <<EOT | read_verilog <<EOT | ||||||
| module opt_expr_sub_test1(input [3:0] i, input [7:0] j, output [8:0] o); | module opt_expr_sub_test1(input [3:0] i, input [7:0] j, output [8:0] o); | ||||||
|     assign o = j - (i << 4); |     assign o = j - (i << 4); | ||||||
| endmodule | endmodule | ||||||
| EOT | EOT | ||||||
| 
 | 
 | ||||||
| hierarchy -auto-top | equiv_opt -assert opt_expr -fine | ||||||
| proc | design -load postopt | ||||||
| design -save gold |  | ||||||
| 
 | 
 | ||||||
| opt_expr -fine | select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=5 r:Y_WIDTH=5 %i %i %i | ||||||
| wreduce |  | ||||||
| 
 |  | ||||||
| select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i |  | ||||||
| 
 |  | ||||||
| design -stash gate |  | ||||||
| 
 |  | ||||||
| design -import gold -as gold |  | ||||||
| design -import gate -as gate |  | ||||||
| 
 |  | ||||||
| miter -equiv -flatten -make_assert -make_outputs gold gate miter |  | ||||||
| sat -verify -prove-asserts -show-ports miter |  | ||||||
| 
 | 
 | ||||||
| ########## | ########## | ||||||
| 
 | 
 | ||||||
|  | # alumacc version of above | ||||||
|  | design -reset | ||||||
|  | read_verilog <<EOT | ||||||
|  | module opt_expr_sub_test1(input [3:0] i, input [7:0] j, output [8:0] o); | ||||||
|  |     assign o = j - (i << 4); | ||||||
|  | endmodule | ||||||
|  | EOT | ||||||
|  | 
 | ||||||
|  | alumacc | ||||||
|  | equiv_opt -assert opt_expr -fine | ||||||
|  | design -load postopt | ||||||
|  | 
 | ||||||
|  | dump | ||||||
|  | select -assert-count 1 t:$alu r:A_WIDTH=4 r:B_WIDTH=5 r:Y_WIDTH=5 %i %i %i | ||||||
|  | 
 | ||||||
|  | ########## | ||||||
|  | 
 | ||||||
|  | design -reset | ||||||
| read_verilog <<EOT | read_verilog <<EOT | ||||||
| module opt_expr_sub_signed_test1(input signed [3:0] i, input signed [7:0] j, output signed [8:0] o); | module opt_expr_sub_signed_test1(input signed [3:0] i, input signed [7:0] j, output signed [8:0] o); | ||||||
|     assign o = j - (i << 4); |     assign o = j - (i << 4); | ||||||
| endmodule | endmodule | ||||||
| EOT | EOT | ||||||
| 
 | 
 | ||||||
| hierarchy -auto-top | equiv_opt -assert opt_expr -fine | ||||||
| proc | design -load postopt | ||||||
| design -save gold |  | ||||||
| 
 | 
 | ||||||
| opt_expr -fine | select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=5 r:Y_WIDTH=5 %i %i %i | ||||||
| wreduce |  | ||||||
| 
 |  | ||||||
| select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i |  | ||||||
| 
 |  | ||||||
| design -stash gate |  | ||||||
| 
 |  | ||||||
| design -import gold -as gold |  | ||||||
| design -import gate -as gate |  | ||||||
| 
 |  | ||||||
| miter -equiv -flatten -make_assert -make_outputs gold gate miter |  | ||||||
| sat -verify -prove-asserts -show-ports miter |  | ||||||
| 
 | 
 | ||||||
| ########## | ########## | ||||||
| 
 | 
 | ||||||
|  | # alumacc version of above | ||||||
|  | design -reset | ||||||
|  | read_verilog <<EOT | ||||||
|  | module opt_expr_sub_signed_test1(input signed [3:0] i, input signed [7:0] j, output signed [8:0] o); | ||||||
|  |     assign o = j - (i << 4); | ||||||
|  | endmodule | ||||||
|  | EOT | ||||||
|  | 
 | ||||||
|  | alumacc | ||||||
|  | equiv_opt -assert opt_expr -fine | ||||||
|  | design -load postopt | ||||||
|  | 
 | ||||||
|  | select -assert-count 1 t:$alu r:A_WIDTH=4 r:B_WIDTH=5 r:Y_WIDTH=5 %i %i %i | ||||||
|  | 
 | ||||||
|  | ########## | ||||||
|  | 
 | ||||||
|  | design -reset | ||||||
| read_verilog <<EOT | read_verilog <<EOT | ||||||
| module opt_expr_sub_test2(input [3:0] i, input [7:0] j, output [8:0] o); | module opt_expr_sub_test2(input [3:0] i, input [7:0] j, output [8:0] o); | ||||||
|     assign o = (i << 4) - j; |     assign o = (i << 4) - j; | ||||||
| endmodule | endmodule | ||||||
| EOT | EOT | ||||||
| 
 | 
 | ||||||
| hierarchy -auto-top | equiv_opt -assert opt_expr -fine | ||||||
| proc | design -load postopt | ||||||
| design -save gold |  | ||||||
| 
 | 
 | ||||||
| opt_expr -fine | select -assert-count 1 t:$sub r:A_WIDTH=9 r:B_WIDTH=8 r:Y_WIDTH=9 %i %i %i | ||||||
| wreduce |  | ||||||
| 
 |  | ||||||
| select -assert-count 1 t:$sub r:A_WIDTH=8 r:B_WIDTH=8 r:Y_WIDTH=9 %i %i %i |  | ||||||
| 
 |  | ||||||
| design -stash gate |  | ||||||
| 
 |  | ||||||
| design -import gold -as gold |  | ||||||
| design -import gate -as gate |  | ||||||
| 
 |  | ||||||
| miter -equiv -flatten -make_assert -make_outputs gold gate miter |  | ||||||
| sat -verify -prove-asserts -show-ports miter |  | ||||||
| 
 | 
 | ||||||
| ########## | ########## | ||||||
| 
 | 
 | ||||||
|  | # alumacc version of above | ||||||
|  | design -reset | ||||||
|  | read_verilog <<EOT | ||||||
|  | module opt_expr_sub_test2(input [3:0] i, input [7:0] j, output [8:0] o); | ||||||
|  |     assign o = (i << 4) - j; | ||||||
|  | endmodule | ||||||
|  | EOT | ||||||
|  | 
 | ||||||
|  | alumacc | ||||||
|  | opt_expr -fine | ||||||
|  | equiv_opt -assert opt_expr -fine | ||||||
|  | design -load postopt | ||||||
|  | 
 | ||||||
|  | select -assert-count 1 t:$alu r:A_WIDTH=9 r:B_WIDTH=8 r:Y_WIDTH=9 %i %i %i | ||||||
|  | 
 | ||||||
|  | ########## | ||||||
|  | 
 | ||||||
|  | design -reset | ||||||
| read_verilog <<EOT | read_verilog <<EOT | ||||||
| module opt_expr_sub_test4(input [3:0] i, output [8:0] o); | module opt_expr_sub_test4(input [3:0] i, output [8:0] o); | ||||||
|     assign o = 5'b00010 - i; |     assign o = 5'b00010 - i; | ||||||
| endmodule | endmodule | ||||||
| EOT | EOT | ||||||
| 
 | 
 | ||||||
| hierarchy -auto-top |  | ||||||
| proc |  | ||||||
| design -save gold |  | ||||||
| 
 |  | ||||||
| opt_expr -fine |  | ||||||
| wreduce | wreduce | ||||||
|  | equiv_opt -assert opt_expr -fine | ||||||
|  | design -load postopt | ||||||
| 
 | 
 | ||||||
| select -assert-count 1 t:$sub r:A_WIDTH=2 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i | select -assert-count 1 t:$sub r:A_WIDTH=2 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i | ||||||
| 
 | 
 | ||||||
| design -stash gate | ########## | ||||||
| 
 | 
 | ||||||
| design -import gold -as gold | # alumacc version of above | ||||||
| design -import gate -as gate | design -reset | ||||||
|  | read_verilog <<EOT | ||||||
|  | module opt_expr_sub_test4(input [3:0] i, output [8:0] o); | ||||||
|  |     assign o = 5'b00010 - i; | ||||||
|  | endmodule | ||||||
|  | EOT | ||||||
| 
 | 
 | ||||||
| miter -equiv -flatten -make_assert -make_outputs gold gate miter | wreduce | ||||||
| sat -verify -prove-asserts -show-ports miter | alumacc | ||||||
|  | equiv_opt -assert opt_expr -fine | ||||||
|  | design -load postopt | ||||||
|  | 
 | ||||||
|  | select -assert-count 1 t:$alu r:A_WIDTH=2 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i | ||||||
|  | 
 | ||||||
|  | ########### | ||||||
|  | 
 | ||||||
|  | design -reset | ||||||
|  | read_verilog -icells <<EOT | ||||||
|  | module opt_expr_alu_test_ci0_bi0(input [7:0] a, input [3:0] b, output [8:0] x, y, co); | ||||||
|  |     \$alu #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(8), .B_WIDTH(8), .Y_WIDTH(9)) alu (.A(a), .B({b, 4'b0000}), .CI(1'b0), .BI(1'b0), .X(x), .Y(y), .CO(co)); | ||||||
|  | endmodule | ||||||
|  | EOT | ||||||
|  | check | ||||||
|  | 
 | ||||||
|  | equiv_opt -assert opt_expr -fine | ||||||
|  | design -load postopt | ||||||
|  | select -assert-count 1 t:$alu r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i | ||||||
|  | 
 | ||||||
|  | ########### | ||||||
|  | 
 | ||||||
|  | design -reset | ||||||
|  | read_verilog -icells <<EOT | ||||||
|  | module opt_expr_alu_test_ci1_bi1(input [7:0] a, input [3:0] b, output [8:0] x, y, co); | ||||||
|  |     \$alu #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(8), .B_WIDTH(8), .Y_WIDTH(9)) alu (.A(a), .B({b, 4'b0000}), .CI(1'b1), .BI(1'b1), .X(x), .Y(y), .CO(co)); | ||||||
|  | endmodule | ||||||
|  | EOT | ||||||
|  | check | ||||||
|  | 
 | ||||||
|  | equiv_opt opt_expr -fine | ||||||
|  | design -load postopt | ||||||
|  | select -assert-count 1 t:$alu r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i | ||||||
|  | 
 | ||||||
|  | ########### | ||||||
|  | 
 | ||||||
|  | design -reset | ||||||
|  | read_verilog -icells <<EOT | ||||||
|  | module opt_expr_alu_test_ci0_bi1(input [7:0] a, input [3:0] b, output [8:0] x, y, co); | ||||||
|  |     \$alu #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(8), .B_WIDTH(8), .Y_WIDTH(9)) alu (.A(a), .B({b, 4'b0000}), .CI(1'b0), .BI(1'b1), .X(x), .Y(y), .CO(co)); | ||||||
|  | endmodule | ||||||
|  | EOT | ||||||
|  | check | ||||||
|  | 
 | ||||||
|  | equiv_opt opt_expr -fine | ||||||
|  | design -load postopt | ||||||
|  | select -assert-count 1 t:$alu r:A_WIDTH=8 r:B_WIDTH=8 r:Y_WIDTH=9 %i %i %i | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue