mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 19:52:31 +00:00 
			
		
		
		
	Merge branch 'master' into clifford/fix1255
This commit is contained in:
		
						commit
						49301b733e
					
				
					 28 changed files with 2506 additions and 2324 deletions
				
			
		
							
								
								
									
										39
									
								
								.travis.yml
									
										
									
									
									
								
							
							
						
						
									
										39
									
								
								.travis.yml
									
										
									
									
									
								
							|  | @ -40,35 +40,6 @@ matrix: | ||||||
|       env: |       env: | ||||||
|         - MATRIX_EVAL="CONFIG=gcc && CC=gcc-4.8 && CXX=g++-4.8" |         - MATRIX_EVAL="CONFIG=gcc && CC=gcc-4.8 && CXX=g++-4.8" | ||||||
| 
 | 
 | ||||||
|     # Latest gcc-6 on Travis Linux |  | ||||||
|     - os: linux |  | ||||||
|       addons: |  | ||||||
|         apt: |  | ||||||
|           sources: |  | ||||||
|             - ubuntu-toolchain-r-test |  | ||||||
|           packages: |  | ||||||
|             - g++-6 |  | ||||||
|             - gperf |  | ||||||
|             - build-essential |  | ||||||
|             - bison |  | ||||||
|             - flex |  | ||||||
|             - libreadline-dev |  | ||||||
|             - gawk |  | ||||||
|             - tcl-dev |  | ||||||
|             - libffi-dev |  | ||||||
|             - git |  | ||||||
|             - graphviz |  | ||||||
|             - xdot |  | ||||||
|             - pkg-config |  | ||||||
|             - python |  | ||||||
|             - python3 |  | ||||||
|             - libboost-system-dev |  | ||||||
|             - libboost-python-dev |  | ||||||
|             - libboost-filesystem-dev |  | ||||||
|             - zlib1g-dev |  | ||||||
|       env: |  | ||||||
|         - MATRIX_EVAL="CONFIG=gcc && CC=gcc-6 && CXX=g++-6" |  | ||||||
| 
 |  | ||||||
|     # Latest gcc supported on Travis Linux |     # Latest gcc supported on Travis Linux | ||||||
|     - os: linux |     - os: linux | ||||||
|       addons: |       addons: | ||||||
|  | @ -76,7 +47,7 @@ matrix: | ||||||
|           sources: |           sources: | ||||||
|             - ubuntu-toolchain-r-test |             - ubuntu-toolchain-r-test | ||||||
|           packages: |           packages: | ||||||
|             - g++-7 |             - g++-9 | ||||||
|             - gperf |             - gperf | ||||||
|             - build-essential |             - build-essential | ||||||
|             - bison |             - bison | ||||||
|  | @ -96,7 +67,7 @@ matrix: | ||||||
|             - libboost-filesystem-dev |             - libboost-filesystem-dev | ||||||
|             - zlib1g-dev |             - zlib1g-dev | ||||||
|       env: |       env: | ||||||
|         - MATRIX_EVAL="CONFIG=gcc && CC=gcc-7 && CXX=g++-7" |         - MATRIX_EVAL="CONFIG=gcc && CC=gcc-9 && CXX=g++-9" | ||||||
| 
 | 
 | ||||||
|     # Clang which ships on Trusty Linux |     # Clang which ships on Trusty Linux | ||||||
|     - os: linux |     - os: linux | ||||||
|  | @ -133,9 +104,9 @@ matrix: | ||||||
|       addons: |       addons: | ||||||
|         apt: |         apt: | ||||||
|           sources: |           sources: | ||||||
|             - llvm-toolchain-trusty-5.0 |             - llvm-toolchain-xenial-8 | ||||||
|           packages: |           packages: | ||||||
|             - clang-5.0 |             - clang-8 | ||||||
|             - gperf |             - gperf | ||||||
|             - build-essential |             - build-essential | ||||||
|             - bison |             - bison | ||||||
|  | @ -155,7 +126,7 @@ matrix: | ||||||
|             - libboost-filesystem-dev |             - libboost-filesystem-dev | ||||||
|             - zlib1g-dev |             - zlib1g-dev | ||||||
|       env: |       env: | ||||||
|         - MATRIX_EVAL="CONFIG=clang && CC=clang-5.0 && CXX=clang++-5.0" |         - MATRIX_EVAL="CONFIG=clang && CC=clang-8 && CXX=clang++-8" | ||||||
| 
 | 
 | ||||||
| #   # Latest clang on Mac OS X | #   # Latest clang on Mac OS X | ||||||
| #   - os: osx | #   - os: osx | ||||||
|  |  | ||||||
|  | @ -51,7 +51,7 @@ fi | ||||||
| 		git clone git://github.com/steveicarus/iverilog.git | 		git clone git://github.com/steveicarus/iverilog.git | ||||||
| 		cd iverilog | 		cd iverilog | ||||||
| 		autoconf | 		autoconf | ||||||
| 		./configure --prefix=$HOME/.local-bin | 		CC=gcc CXX=g++ ./configure --prefix=$HOME/.local-bin | ||||||
| 		make | 		make | ||||||
| 		make install | 		make install | ||||||
| 		echo | 		echo | ||||||
|  |  | ||||||
							
								
								
									
										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"] | ||||||
|  |  | ||||||
|  | @ -268,9 +268,9 @@ Aig::Aig(Cell *cell) | ||||||
| 	cell->parameters.sort(); | 	cell->parameters.sort(); | ||||||
| 	for (auto p : cell->parameters) | 	for (auto p : cell->parameters) | ||||||
| 	{ | 	{ | ||||||
| 		if (p.first == "\\A_WIDTH" && mkname_a_signed) { | 		if (p.first == ID(A_WIDTH) && mkname_a_signed) { | ||||||
| 			name = mkname_last + stringf(":%d%c", p.second.as_int(), mkname_is_signed ? 'S' : 'U'); | 			name = mkname_last + stringf(":%d%c", p.second.as_int(), mkname_is_signed ? 'S' : 'U'); | ||||||
| 		} else if (p.first == "\\B_WIDTH" && mkname_b_signed) { | 		} else if (p.first == ID(B_WIDTH) && mkname_b_signed) { | ||||||
| 			name = mkname_last + stringf(":%d%c", p.second.as_int(), mkname_is_signed ? 'S' : 'U'); | 			name = mkname_last + stringf(":%d%c", p.second.as_int(), mkname_is_signed ? 'S' : 'U'); | ||||||
| 		} else { | 		} else { | ||||||
| 			mkname_last = name; | 			mkname_last = name; | ||||||
|  | @ -280,183 +280,183 @@ Aig::Aig(Cell *cell) | ||||||
| 		mkname_a_signed = false; | 		mkname_a_signed = false; | ||||||
| 		mkname_b_signed = false; | 		mkname_b_signed = false; | ||||||
| 		mkname_is_signed = false; | 		mkname_is_signed = false; | ||||||
| 		if (p.first == "\\A_SIGNED") { | 		if (p.first == ID(A_SIGNED)) { | ||||||
| 			mkname_a_signed = true; | 			mkname_a_signed = true; | ||||||
| 			mkname_is_signed = p.second.as_bool(); | 			mkname_is_signed = p.second.as_bool(); | ||||||
| 		} | 		} | ||||||
| 		if (p.first == "\\B_SIGNED") { | 		if (p.first == ID(B_SIGNED)) { | ||||||
| 			mkname_b_signed = true; | 			mkname_b_signed = true; | ||||||
| 			mkname_is_signed = p.second.as_bool(); | 			mkname_is_signed = p.second.as_bool(); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type.in("$not", "$_NOT_", "$pos", "$_BUF_")) | 	if (cell->type.in(ID($not), ID($_NOT_), ID($pos), ID($_BUF_))) | ||||||
| 	{ | 	{ | ||||||
| 		for (int i = 0; i < GetSize(cell->getPort("\\Y")); i++) { | 		for (int i = 0; i < GetSize(cell->getPort(ID(Y))); i++) { | ||||||
| 			int A = mk.inport("\\A", i); | 			int A = mk.inport(ID(A), i); | ||||||
| 			int Y = cell->type.in("$not", "$_NOT_") ? mk.not_gate(A) : A; | 			int Y = cell->type.in(ID($not), ID($_NOT_)) ? mk.not_gate(A) : A; | ||||||
| 			mk.outport(Y, "\\Y", i); | 			mk.outport(Y, ID(Y), i); | ||||||
| 		} | 		} | ||||||
| 		goto optimize; | 		goto optimize; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type.in("$and", "$_AND_", "$_NAND_", "$or", "$_OR_", "$_NOR_", "$xor", "$xnor", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_")) | 	if (cell->type.in(ID($and), ID($_AND_), ID($_NAND_), ID($or), ID($_OR_), ID($_NOR_), ID($xor), ID($xnor), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_))) | ||||||
| 	{ | 	{ | ||||||
| 		for (int i = 0; i < GetSize(cell->getPort("\\Y")); i++) { | 		for (int i = 0; i < GetSize(cell->getPort(ID(Y))); i++) { | ||||||
| 			int A = mk.inport("\\A", i); | 			int A = mk.inport(ID(A), i); | ||||||
| 			int B = mk.inport("\\B", i); | 			int B = mk.inport(ID(B), i); | ||||||
| 			int Y = cell->type.in("$and", "$_AND_")   ? mk.and_gate(A, B) : | 			int Y = cell->type.in(ID($and), ID($_AND_))   ? mk.and_gate(A, B) : | ||||||
| 			        cell->type.in("$_NAND_")          ? mk.nand_gate(A, B) : | 			        cell->type.in(ID($_NAND_))          ? mk.nand_gate(A, B) : | ||||||
| 			        cell->type.in("$or", "$_OR_")     ? mk.or_gate(A, B) : | 			        cell->type.in(ID($or), ID($_OR_))     ? mk.or_gate(A, B) : | ||||||
| 			        cell->type.in("$_NOR_")           ? mk.nor_gate(A, B) : | 			        cell->type.in(ID($_NOR_))           ? mk.nor_gate(A, B) : | ||||||
| 			        cell->type.in("$xor", "$_XOR_")   ? mk.xor_gate(A, B) : | 			        cell->type.in(ID($xor), ID($_XOR_))   ? mk.xor_gate(A, B) : | ||||||
| 			        cell->type.in("$xnor", "$_XNOR_") ? mk.xnor_gate(A, B) : | 			        cell->type.in(ID($xnor), ID($_XNOR_)) ? mk.xnor_gate(A, B) : | ||||||
| 			        cell->type.in("$_ANDNOT_")        ? mk.andnot_gate(A, B) : | 			        cell->type.in(ID($_ANDNOT_))        ? mk.andnot_gate(A, B) : | ||||||
| 			        cell->type.in("$_ORNOT_")         ? mk.ornot_gate(A, B) : -1; | 			        cell->type.in(ID($_ORNOT_))         ? mk.ornot_gate(A, B) : -1; | ||||||
| 			mk.outport(Y, "\\Y", i); | 			mk.outport(Y, ID(Y), i); | ||||||
| 		} | 		} | ||||||
| 		goto optimize; | 		goto optimize; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type.in("$mux", "$_MUX_")) | 	if (cell->type.in(ID($mux), ID($_MUX_))) | ||||||
| 	{ | 	{ | ||||||
| 		int S = mk.inport("\\S"); | 		int S = mk.inport(ID(S)); | ||||||
| 		for (int i = 0; i < GetSize(cell->getPort("\\Y")); i++) { | 		for (int i = 0; i < GetSize(cell->getPort(ID(Y))); i++) { | ||||||
| 			int A = mk.inport("\\A", i); | 			int A = mk.inport(ID(A), i); | ||||||
| 			int B = mk.inport("\\B", i); | 			int B = mk.inport(ID(B), i); | ||||||
| 			int Y = mk.mux_gate(A, B, S); | 			int Y = mk.mux_gate(A, B, S); | ||||||
| 			if (cell->type == "$_NMUX_") | 			if (cell->type == ID($_NMUX_)) | ||||||
| 				Y = mk.not_gate(Y); | 				Y = mk.not_gate(Y); | ||||||
| 			mk.outport(Y, "\\Y", i); | 			mk.outport(Y, ID(Y), i); | ||||||
| 		} | 		} | ||||||
| 		goto optimize; | 		goto optimize; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool")) | 	if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool))) | ||||||
| 	{ | 	{ | ||||||
| 		int Y = mk.inport("\\A", 0); | 		int Y = mk.inport(ID(A), 0); | ||||||
| 		for (int i = 1; i < GetSize(cell->getPort("\\A")); i++) { | 		for (int i = 1; i < GetSize(cell->getPort(ID(A))); i++) { | ||||||
| 			int A = mk.inport("\\A", i); | 			int A = mk.inport(ID(A), i); | ||||||
| 			if (cell->type == "$reduce_and")  Y = mk.and_gate(A, Y); | 			if (cell->type == ID($reduce_and))  Y = mk.and_gate(A, Y); | ||||||
| 			if (cell->type == "$reduce_or")   Y = mk.or_gate(A, Y); | 			if (cell->type == ID($reduce_or))   Y = mk.or_gate(A, Y); | ||||||
| 			if (cell->type == "$reduce_bool") Y = mk.or_gate(A, Y); | 			if (cell->type == ID($reduce_bool)) Y = mk.or_gate(A, Y); | ||||||
| 			if (cell->type == "$reduce_xor")  Y = mk.xor_gate(A, Y); | 			if (cell->type == ID($reduce_xor))  Y = mk.xor_gate(A, Y); | ||||||
| 			if (cell->type == "$reduce_xnor") Y = mk.xor_gate(A, Y); | 			if (cell->type == ID($reduce_xnor)) Y = mk.xor_gate(A, Y); | ||||||
| 		} | 		} | ||||||
| 		if (cell->type == "$reduce_xnor") | 		if (cell->type == ID($reduce_xnor)) | ||||||
| 			Y = mk.not_gate(Y); | 			Y = mk.not_gate(Y); | ||||||
| 		mk.outport(Y, "\\Y", 0); | 		mk.outport(Y, ID(Y), 0); | ||||||
| 		for (int i = 1; i < GetSize(cell->getPort("\\Y")); i++) | 		for (int i = 1; i < GetSize(cell->getPort(ID(Y))); i++) | ||||||
| 			mk.outport(mk.bool_node(false), "\\Y", i); | 			mk.outport(mk.bool_node(false), ID(Y), i); | ||||||
| 		goto optimize; | 		goto optimize; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type.in("$logic_not", "$logic_and", "$logic_or")) | 	if (cell->type.in(ID($logic_not), ID($logic_and), ID($logic_or))) | ||||||
| 	{ | 	{ | ||||||
| 		int A = mk.inport("\\A", 0), Y = -1; | 		int A = mk.inport(ID(A), 0), Y = -1; | ||||||
| 		for (int i = 1; i < GetSize(cell->getPort("\\A")); i++) | 		for (int i = 1; i < GetSize(cell->getPort(ID(A))); i++) | ||||||
| 			A = mk.or_gate(mk.inport("\\A", i), A); | 			A = mk.or_gate(mk.inport(ID(A), i), A); | ||||||
| 		if (cell->type.in("$logic_and", "$logic_or")) { | 		if (cell->type.in(ID($logic_and), ID($logic_or))) { | ||||||
| 			int B = mk.inport("\\B", 0); | 			int B = mk.inport(ID(B), 0); | ||||||
| 			for (int i = 1; i < GetSize(cell->getPort("\\B")); i++) | 			for (int i = 1; i < GetSize(cell->getPort(ID(B))); i++) | ||||||
| 				B = mk.or_gate(mk.inport("\\B", i), B); | 				B = mk.or_gate(mk.inport(ID(B), i), B); | ||||||
| 			if (cell->type == "$logic_and") Y = mk.and_gate(A, B); | 			if (cell->type == ID($logic_and)) Y = mk.and_gate(A, B); | ||||||
| 			if (cell->type == "$logic_or")  Y = mk.or_gate(A, B); | 			if (cell->type == ID($logic_or))  Y = mk.or_gate(A, B); | ||||||
| 		} else { | 		} else { | ||||||
| 			if (cell->type == "$logic_not") Y = mk.not_gate(A); | 			if (cell->type == ID($logic_not)) Y = mk.not_gate(A); | ||||||
| 		} | 		} | ||||||
| 		mk.outport_bool(Y, "\\Y"); | 		mk.outport_bool(Y, ID(Y)); | ||||||
| 		goto optimize; | 		goto optimize; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type.in("$add", "$sub")) | 	if (cell->type.in(ID($add), ID($sub))) | ||||||
| 	{ | 	{ | ||||||
| 		int width = GetSize(cell->getPort("\\Y")); | 		int width = GetSize(cell->getPort(ID(Y))); | ||||||
| 		vector<int> A = mk.inport_vec("\\A", width); | 		vector<int> A = mk.inport_vec(ID(A), width); | ||||||
| 		vector<int> B = mk.inport_vec("\\B", width); | 		vector<int> B = mk.inport_vec(ID(B), width); | ||||||
| 		int carry = mk.bool_node(false); | 		int carry = mk.bool_node(false); | ||||||
| 		if (cell->type == "$sub") { | 		if (cell->type == ID($sub)) { | ||||||
| 			for (auto &n : B) | 			for (auto &n : B) | ||||||
| 				n = mk.not_gate(n); | 				n = mk.not_gate(n); | ||||||
| 			carry = mk.not_gate(carry); | 			carry = mk.not_gate(carry); | ||||||
| 		} | 		} | ||||||
| 		vector<int> Y = mk.adder(A, B, carry); | 		vector<int> Y = mk.adder(A, B, carry); | ||||||
| 		mk.outport_vec(Y, "\\Y"); | 		mk.outport_vec(Y, ID(Y)); | ||||||
| 		goto optimize; | 		goto optimize; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type == "$alu") | 	if (cell->type == ID($alu)) | ||||||
| 	{ | 	{ | ||||||
| 		int width = GetSize(cell->getPort("\\Y")); | 		int width = GetSize(cell->getPort(ID(Y))); | ||||||
| 		vector<int> A = mk.inport_vec("\\A", width); | 		vector<int> A = mk.inport_vec(ID(A), width); | ||||||
| 		vector<int> B = mk.inport_vec("\\B", width); | 		vector<int> B = mk.inport_vec(ID(B), width); | ||||||
| 		int carry = mk.inport("\\CI"); | 		int carry = mk.inport(ID(CI)); | ||||||
| 		int binv = mk.inport("\\BI"); | 		int binv = mk.inport(ID(BI)); | ||||||
| 		for (auto &n : B) | 		for (auto &n : B) | ||||||
| 			n = mk.xor_gate(n, binv); | 			n = mk.xor_gate(n, binv); | ||||||
| 		vector<int> X(width), CO(width); | 		vector<int> X(width), CO(width); | ||||||
| 		vector<int> Y = mk.adder(A, B, carry, &X, &CO); | 		vector<int> Y = mk.adder(A, B, carry, &X, &CO); | ||||||
| 		for (int i = 0; i < width; i++) | 		for (int i = 0; i < width; i++) | ||||||
| 			X[i] = mk.xor_gate(A[i], B[i]); | 			X[i] = mk.xor_gate(A[i], B[i]); | ||||||
| 		mk.outport_vec(Y, "\\Y"); | 		mk.outport_vec(Y, ID(Y)); | ||||||
| 		mk.outport_vec(X, "\\X"); | 		mk.outport_vec(X, ID(X)); | ||||||
| 		mk.outport_vec(CO, "\\CO"); | 		mk.outport_vec(CO, ID(CO)); | ||||||
| 		goto optimize; | 		goto optimize; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type.in("$eq", "$ne")) | 	if (cell->type.in(ID($eq), ID($ne))) | ||||||
| 	{ | 	{ | ||||||
| 		int width = max(GetSize(cell->getPort("\\A")), GetSize(cell->getPort("\\B"))); | 		int width = max(GetSize(cell->getPort(ID(A))), GetSize(cell->getPort(ID(B)))); | ||||||
| 		vector<int> A = mk.inport_vec("\\A", width); | 		vector<int> A = mk.inport_vec(ID(A), width); | ||||||
| 		vector<int> B = mk.inport_vec("\\B", width); | 		vector<int> B = mk.inport_vec(ID(B), width); | ||||||
| 		int Y = mk.bool_node(false); | 		int Y = mk.bool_node(false); | ||||||
| 		for (int i = 0; i < width; i++) | 		for (int i = 0; i < width; i++) | ||||||
| 			Y = mk.or_gate(Y, mk.xor_gate(A[i], B[i])); | 			Y = mk.or_gate(Y, mk.xor_gate(A[i], B[i])); | ||||||
| 		if (cell->type == "$eq") | 		if (cell->type == ID($eq)) | ||||||
| 			Y = mk.not_gate(Y); | 			Y = mk.not_gate(Y); | ||||||
| 		mk.outport_bool(Y, "\\Y"); | 		mk.outport_bool(Y, ID(Y)); | ||||||
| 		goto optimize; | 		goto optimize; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type == "$_AOI3_") | 	if (cell->type == ID($_AOI3_)) | ||||||
| 	{ | 	{ | ||||||
| 		int A = mk.inport("\\A"); | 		int A = mk.inport(ID(A)); | ||||||
| 		int B = mk.inport("\\B"); | 		int B = mk.inport(ID(B)); | ||||||
| 		int C = mk.inport("\\C"); | 		int C = mk.inport(ID(C)); | ||||||
| 		int Y = mk.nor_gate(mk.and_gate(A, B), C); | 		int Y = mk.nor_gate(mk.and_gate(A, B), C); | ||||||
| 		mk.outport(Y, "\\Y"); | 		mk.outport(Y, ID(Y)); | ||||||
| 		goto optimize; | 		goto optimize; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type == "$_OAI3_") | 	if (cell->type == ID($_OAI3_)) | ||||||
| 	{ | 	{ | ||||||
| 		int A = mk.inport("\\A"); | 		int A = mk.inport(ID(A)); | ||||||
| 		int B = mk.inport("\\B"); | 		int B = mk.inport(ID(B)); | ||||||
| 		int C = mk.inport("\\C"); | 		int C = mk.inport(ID(C)); | ||||||
| 		int Y = mk.nand_gate(mk.or_gate(A, B), C); | 		int Y = mk.nand_gate(mk.or_gate(A, B), C); | ||||||
| 		mk.outport(Y, "\\Y"); | 		mk.outport(Y, ID(Y)); | ||||||
| 		goto optimize; | 		goto optimize; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type == "$_AOI4_") | 	if (cell->type == ID($_AOI4_)) | ||||||
| 	{ | 	{ | ||||||
| 		int A = mk.inport("\\A"); | 		int A = mk.inport(ID(A)); | ||||||
| 		int B = mk.inport("\\B"); | 		int B = mk.inport(ID(B)); | ||||||
| 		int C = mk.inport("\\C"); | 		int C = mk.inport(ID(C)); | ||||||
| 		int D = mk.inport("\\D"); | 		int D = mk.inport(ID(D)); | ||||||
| 		int Y = mk.nor_gate(mk.and_gate(A, B), mk.and_gate(C, D)); | 		int Y = mk.nor_gate(mk.and_gate(A, B), mk.and_gate(C, D)); | ||||||
| 		mk.outport(Y, "\\Y"); | 		mk.outport(Y, ID(Y)); | ||||||
| 		goto optimize; | 		goto optimize; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type == "$_OAI4_") | 	if (cell->type == ID($_OAI4_)) | ||||||
| 	{ | 	{ | ||||||
| 		int A = mk.inport("\\A"); | 		int A = mk.inport(ID(A)); | ||||||
| 		int B = mk.inport("\\B"); | 		int B = mk.inport(ID(B)); | ||||||
| 		int C = mk.inport("\\C"); | 		int C = mk.inport(ID(C)); | ||||||
| 		int D = mk.inport("\\D"); | 		int D = mk.inport(ID(D)); | ||||||
| 		int Y = mk.nand_gate(mk.or_gate(A, B), mk.or_gate(C, D)); | 		int Y = mk.nand_gate(mk.or_gate(A, B), mk.or_gate(C, D)); | ||||||
| 		mk.outport(Y, "\\Y"); | 		mk.outport(Y, ID(Y)); | ||||||
| 		goto optimize; | 		goto optimize; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -24,9 +24,9 @@ PRIVATE_NAMESPACE_BEGIN | ||||||
| 
 | 
 | ||||||
| void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) | void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) | ||||||
| { | { | ||||||
| 	IdString A = "\\A", Y = "\\Y"; | 	IdString A = ID(A), Y = ID(Y); | ||||||
| 
 | 
 | ||||||
| 	bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); | 	bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); | ||||||
| 	int a_width = GetSize(cell->getPort(A)); | 	int a_width = GetSize(cell->getPort(A)); | ||||||
| 	int y_width = GetSize(cell->getPort(Y)); | 	int y_width = GetSize(cell->getPort(Y)); | ||||||
| 
 | 
 | ||||||
|  | @ -41,14 +41,14 @@ void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) | ||||||
| 
 | 
 | ||||||
| void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) | void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) | ||||||
| { | { | ||||||
| 	IdString A = "\\A", B = "\\B", Y = "\\Y"; | 	IdString A = ID(A), B = ID(B), Y = ID(Y); | ||||||
| 
 | 
 | ||||||
| 	bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); | 	bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); | ||||||
| 	int a_width = GetSize(cell->getPort(A)); | 	int a_width = GetSize(cell->getPort(A)); | ||||||
| 	int b_width = GetSize(cell->getPort(B)); | 	int b_width = GetSize(cell->getPort(B)); | ||||||
| 	int y_width = GetSize(cell->getPort(Y)); | 	int y_width = GetSize(cell->getPort(Y)); | ||||||
| 
 | 
 | ||||||
| 	if (cell->type == "$and" && !is_signed) { | 	if (cell->type == ID($and) && !is_signed) { | ||||||
| 		if (a_width > b_width) | 		if (a_width > b_width) | ||||||
| 			a_width = b_width; | 			a_width = b_width; | ||||||
| 		else | 		else | ||||||
|  | @ -71,9 +71,9 @@ void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) | ||||||
| 
 | 
 | ||||||
| void arith_neg_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) | void arith_neg_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) | ||||||
| { | { | ||||||
| 	IdString A = "\\A", Y = "\\Y"; | 	IdString A = ID(A), Y = ID(Y); | ||||||
| 
 | 
 | ||||||
| 	bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); | 	bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); | ||||||
| 	int a_width = GetSize(cell->getPort(A)); | 	int a_width = GetSize(cell->getPort(A)); | ||||||
| 	int y_width = GetSize(cell->getPort(Y)); | 	int y_width = GetSize(cell->getPort(Y)); | ||||||
| 
 | 
 | ||||||
|  | @ -87,14 +87,14 @@ void arith_neg_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) | ||||||
| 
 | 
 | ||||||
| void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) | void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) | ||||||
| { | { | ||||||
| 	IdString A = "\\A", B = "\\B", Y = "\\Y"; | 	IdString A = ID(A), B = ID(B), Y = ID(Y); | ||||||
| 
 | 
 | ||||||
| 	bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); | 	bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); | ||||||
| 	int a_width = GetSize(cell->getPort(A)); | 	int a_width = GetSize(cell->getPort(A)); | ||||||
| 	int b_width = GetSize(cell->getPort(B)); | 	int b_width = GetSize(cell->getPort(B)); | ||||||
| 	int y_width = GetSize(cell->getPort(Y)); | 	int y_width = GetSize(cell->getPort(Y)); | ||||||
| 
 | 
 | ||||||
| 	if (!is_signed && cell->type != "$sub") { | 	if (!is_signed && cell->type != ID($sub)) { | ||||||
| 		int ab_width = std::max(a_width, b_width); | 		int ab_width = std::max(a_width, b_width); | ||||||
| 		y_width = std::min(y_width, ab_width+1); | 		y_width = std::min(y_width, ab_width+1); | ||||||
| 	} | 	} | ||||||
|  | @ -114,7 +114,7 @@ void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) | ||||||
| 
 | 
 | ||||||
| void reduce_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) | void reduce_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) | ||||||
| { | { | ||||||
| 	IdString A = "\\A", Y = "\\Y"; | 	IdString A = ID(A), Y = ID(Y); | ||||||
| 
 | 
 | ||||||
| 	int a_width = GetSize(cell->getPort(A)); | 	int a_width = GetSize(cell->getPort(A)); | ||||||
| 
 | 
 | ||||||
|  | @ -124,7 +124,7 @@ void reduce_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) | ||||||
| 
 | 
 | ||||||
| void compare_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) | void compare_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) | ||||||
| { | { | ||||||
| 	IdString A = "\\A", B = "\\B", Y = "\\Y"; | 	IdString A = ID(A), B = ID(B), Y = ID(Y); | ||||||
| 
 | 
 | ||||||
| 	int a_width = GetSize(cell->getPort(A)); | 	int a_width = GetSize(cell->getPort(A)); | ||||||
| 	int b_width = GetSize(cell->getPort(B)); | 	int b_width = GetSize(cell->getPort(B)); | ||||||
|  | @ -138,7 +138,7 @@ void compare_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) | ||||||
| 
 | 
 | ||||||
| void mux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) | void mux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) | ||||||
| { | { | ||||||
| 	IdString A = "\\A", B = "\\B", S = "\\S", Y = "\\Y"; | 	IdString A = ID(A), B = ID(B), S = ID(S), Y = ID(Y); | ||||||
| 
 | 
 | ||||||
| 	int a_width = GetSize(cell->getPort(A)); | 	int a_width = GetSize(cell->getPort(A)); | ||||||
| 	int b_width = GetSize(cell->getPort(B)); | 	int b_width = GetSize(cell->getPort(B)); | ||||||
|  | @ -160,43 +160,43 @@ PRIVATE_NAMESPACE_END | ||||||
| 
 | 
 | ||||||
| bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL::Cell *cell) | bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL::Cell *cell) | ||||||
| { | { | ||||||
| 	if (cell->type.in("$not", "$pos")) { | 	if (cell->type.in(ID($not), ID($pos))) { | ||||||
| 		bitwise_unary_op(this, cell); | 		bitwise_unary_op(this, cell); | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type.in("$and", "$or", "$xor", "$xnor")) { | 	if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor))) { | ||||||
| 		bitwise_binary_op(this, cell); | 		bitwise_binary_op(this, cell); | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type == "$neg") { | 	if (cell->type == ID($neg)) { | ||||||
| 		arith_neg_op(this, cell); | 		arith_neg_op(this, cell); | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type.in("$add", "$sub")) { | 	if (cell->type.in(ID($add), ID($sub))) { | ||||||
| 		arith_binary_op(this, cell); | 		arith_binary_op(this, cell); | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool", "$logic_not")) { | 	if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($logic_not))) { | ||||||
| 		reduce_op(this, cell); | 		reduce_op(this, cell); | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// FIXME:
 | 	// FIXME:
 | ||||||
| 	// if (cell->type.in("$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx")) {
 | 	// if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) {
 | ||||||
| 	// 	shift_op(this, cell);
 | 	// 	shift_op(this, cell);
 | ||||||
| 	// 	return true;
 | 	// 	return true;
 | ||||||
| 	// }
 | 	// }
 | ||||||
| 
 | 
 | ||||||
| 	if (cell->type.in("$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt")) { | 	if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt))) { | ||||||
| 		compare_op(this, cell); | 		compare_op(this, cell); | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type.in("$mux", "$pmux")) { | 	if (cell->type.in(ID($mux), ID($pmux))) { | ||||||
| 		mux_op(this, cell); | 		mux_op(this, cell); | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -84,46 +84,46 @@ struct CellTypes | ||||||
| 	{ | 	{ | ||||||
| 		setup_internals_eval(); | 		setup_internals_eval(); | ||||||
| 
 | 
 | ||||||
| 		IdString A = "\\A", B = "\\B", EN = "\\EN", Y = "\\Y"; | 		IdString A = ID(A), B = ID(B), EN = ID(EN), Y = ID(Y); | ||||||
| 		IdString SRC = "\\SRC", DST = "\\DST", DAT = "\\DAT"; | 		IdString SRC = ID(SRC), DST = ID(DST), DAT = ID(DAT); | ||||||
| 		IdString EN_SRC = "\\EN_SRC", EN_DST = "\\EN_DST"; | 		IdString EN_SRC = ID(EN_SRC), EN_DST = ID(EN_DST); | ||||||
| 
 | 
 | ||||||
| 		setup_type("$tribuf", {A, EN}, {Y}, true); | 		setup_type(ID($tribuf), {A, EN}, {Y}, true); | ||||||
| 
 | 
 | ||||||
| 		setup_type("$assert", {A, EN}, pool<RTLIL::IdString>(), true); | 		setup_type(ID($assert), {A, EN}, pool<RTLIL::IdString>(), true); | ||||||
| 		setup_type("$assume", {A, EN}, pool<RTLIL::IdString>(), true); | 		setup_type(ID($assume), {A, EN}, pool<RTLIL::IdString>(), true); | ||||||
| 		setup_type("$live", {A, EN}, pool<RTLIL::IdString>(), true); | 		setup_type(ID($live), {A, EN}, pool<RTLIL::IdString>(), true); | ||||||
| 		setup_type("$fair", {A, EN}, pool<RTLIL::IdString>(), true); | 		setup_type(ID($fair), {A, EN}, pool<RTLIL::IdString>(), true); | ||||||
| 		setup_type("$cover", {A, EN}, pool<RTLIL::IdString>(), true); | 		setup_type(ID($cover), {A, EN}, pool<RTLIL::IdString>(), true); | ||||||
| 		setup_type("$initstate", pool<RTLIL::IdString>(), {Y}, true); | 		setup_type(ID($initstate), pool<RTLIL::IdString>(), {Y}, true); | ||||||
| 		setup_type("$anyconst", pool<RTLIL::IdString>(), {Y}, true); | 		setup_type(ID($anyconst), pool<RTLIL::IdString>(), {Y}, true); | ||||||
| 		setup_type("$anyseq", pool<RTLIL::IdString>(), {Y}, true); | 		setup_type(ID($anyseq), pool<RTLIL::IdString>(), {Y}, true); | ||||||
| 		setup_type("$allconst", pool<RTLIL::IdString>(), {Y}, true); | 		setup_type(ID($allconst), pool<RTLIL::IdString>(), {Y}, true); | ||||||
| 		setup_type("$allseq", pool<RTLIL::IdString>(), {Y}, true); | 		setup_type(ID($allseq), pool<RTLIL::IdString>(), {Y}, true); | ||||||
| 		setup_type("$equiv", {A, B}, {Y}, true); | 		setup_type(ID($equiv), {A, B}, {Y}, true); | ||||||
| 		setup_type("$specify2", {EN, SRC, DST}, pool<RTLIL::IdString>(), true); | 		setup_type(ID($specify2), {EN, SRC, DST}, pool<RTLIL::IdString>(), true); | ||||||
| 		setup_type("$specify3", {EN, SRC, DST, DAT}, pool<RTLIL::IdString>(), true); | 		setup_type(ID($specify3), {EN, SRC, DST, DAT}, pool<RTLIL::IdString>(), true); | ||||||
| 		setup_type("$specrule", {EN_SRC, EN_DST, SRC, DST}, pool<RTLIL::IdString>(), true); | 		setup_type(ID($specrule), {EN_SRC, EN_DST, SRC, DST}, pool<RTLIL::IdString>(), true); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void setup_internals_eval() | 	void setup_internals_eval() | ||||||
| 	{ | 	{ | ||||||
| 		std::vector<RTLIL::IdString> unary_ops = { | 		std::vector<RTLIL::IdString> unary_ops = { | ||||||
| 			"$not", "$pos", "$neg", | 			ID($not), ID($pos), ID($neg), | ||||||
| 			"$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool", | 			ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), | ||||||
| 			"$logic_not", "$slice", "$lut", "$sop" | 			ID($logic_not), ID($slice), ID($lut), ID($sop) | ||||||
| 		}; | 		}; | ||||||
| 
 | 
 | ||||||
| 		std::vector<RTLIL::IdString> binary_ops = { | 		std::vector<RTLIL::IdString> binary_ops = { | ||||||
| 			"$and", "$or", "$xor", "$xnor", | 			ID($and), ID($or), ID($xor), ID($xnor), | ||||||
| 			"$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", | 			ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx), | ||||||
| 			"$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt", | 			ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt), | ||||||
| 			"$add", "$sub", "$mul", "$div", "$mod", "$pow", | 			ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow), | ||||||
| 			"$logic_and", "$logic_or", "$concat", "$macc" | 			ID($logic_and), ID($logic_or), ID($concat), ID($macc) | ||||||
| 		}; | 		}; | ||||||
| 		IdString A = "\\A", B = "\\B", S = "\\S", Y = "\\Y"; | 		IdString A = ID(A), B = ID(B), S = ID(S), Y = ID(Y); | ||||||
| 		IdString P = "\\P", G = "\\G", C = "\\C", X = "\\X"; | 		IdString P = ID(P), G = ID(G), C = ID(C), X = ID(X); | ||||||
| 		IdString BI = "\\BI", CI = "\\CI", CO = "\\CO", EN = "\\EN"; | 		IdString BI = ID(BI), CI = ID(CI), CO = ID(CO), EN = ID(EN); | ||||||
| 
 | 
 | ||||||
| 		for (auto type : unary_ops) | 		for (auto type : unary_ops) | ||||||
| 			setup_type(type, {A}, {Y}, true); | 			setup_type(type, {A}, {Y}, true); | ||||||
|  | @ -131,27 +131,27 @@ struct CellTypes | ||||||
| 		for (auto type : binary_ops) | 		for (auto type : binary_ops) | ||||||
| 			setup_type(type, {A, B}, {Y}, true); | 			setup_type(type, {A, B}, {Y}, true); | ||||||
| 
 | 
 | ||||||
| 		for (auto type : std::vector<RTLIL::IdString>({"$mux", "$pmux"})) | 		for (auto type : std::vector<RTLIL::IdString>({ID($mux), ID($pmux)})) | ||||||
| 			setup_type(type, {A, B, S}, {Y}, true); | 			setup_type(type, {A, B, S}, {Y}, true); | ||||||
| 
 | 
 | ||||||
| 		setup_type("$lcu", {P, G, CI}, {CO}, true); | 		setup_type(ID($lcu), {P, G, CI}, {CO}, true); | ||||||
| 		setup_type("$alu", {A, B, CI, BI}, {X, Y, CO}, true); | 		setup_type(ID($alu), {A, B, CI, BI}, {X, Y, CO}, true); | ||||||
| 		setup_type("$fa", {A, B, C}, {X, Y}, true); | 		setup_type(ID($fa), {A, B, C}, {X, Y}, true); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void setup_internals_ff() | 	void setup_internals_ff() | ||||||
| 	{ | 	{ | ||||||
| 		IdString SET = "\\SET", CLR = "\\CLR", CLK = "\\CLK", ARST = "\\ARST", EN = "\\EN"; | 		IdString SET = ID(SET), CLR = ID(CLR), CLK = ID(CLK), ARST = ID(ARST), EN = ID(EN); | ||||||
| 		IdString Q = "\\Q", D = "\\D"; | 		IdString Q = ID(Q), D = ID(D); | ||||||
| 
 | 
 | ||||||
| 		setup_type("$sr", {SET, CLR}, {Q}); | 		setup_type(ID($sr), {SET, CLR}, {Q}); | ||||||
| 		setup_type("$ff", {D}, {Q}); | 		setup_type(ID($ff), {D}, {Q}); | ||||||
| 		setup_type("$dff", {CLK, D}, {Q}); | 		setup_type(ID($dff), {CLK, D}, {Q}); | ||||||
| 		setup_type("$dffe", {CLK, EN, D}, {Q}); | 		setup_type(ID($dffe), {CLK, EN, D}, {Q}); | ||||||
| 		setup_type("$dffsr", {CLK, SET, CLR, D}, {Q}); | 		setup_type(ID($dffsr), {CLK, SET, CLR, D}, {Q}); | ||||||
| 		setup_type("$adff", {CLK, ARST, D}, {Q}); | 		setup_type(ID($adff), {CLK, ARST, D}, {Q}); | ||||||
| 		setup_type("$dlatch", {EN, D}, {Q}); | 		setup_type(ID($dlatch), {EN, D}, {Q}); | ||||||
| 		setup_type("$dlatchsr", {EN, SET, CLR, D}, {Q}); | 		setup_type(ID($dlatchsr), {EN, SET, CLR, D}, {Q}); | ||||||
| 
 | 
 | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -159,63 +159,63 @@ struct CellTypes | ||||||
| 	{ | 	{ | ||||||
| 		setup_internals_ff(); | 		setup_internals_ff(); | ||||||
| 
 | 
 | ||||||
| 		IdString CLK = "\\CLK", ARST = "\\ARST", EN = "\\EN"; | 		IdString CLK = ID(CLK), ARST = ID(ARST), EN = ID(EN); | ||||||
| 		IdString ADDR = "\\ADDR", DATA = "\\DATA", RD_EN = "\\RD_EN"; | 		IdString ADDR = ID(ADDR), DATA = ID(DATA), RD_EN = ID(RD_EN); | ||||||
| 		IdString RD_CLK = "\\RD_CLK", RD_ADDR = "\\RD_ADDR", WR_CLK = "\\WR_CLK", WR_EN = "\\WR_EN"; | 		IdString RD_CLK = ID(RD_CLK), RD_ADDR = ID(RD_ADDR), WR_CLK = ID(WR_CLK), WR_EN = ID(WR_EN); | ||||||
| 		IdString WR_ADDR = "\\WR_ADDR", WR_DATA = "\\WR_DATA", RD_DATA = "\\RD_DATA"; | 		IdString WR_ADDR = ID(WR_ADDR), WR_DATA = ID(WR_DATA), RD_DATA = ID(RD_DATA); | ||||||
| 		IdString CTRL_IN = "\\CTRL_IN", CTRL_OUT = "\\CTRL_OUT"; | 		IdString CTRL_IN = ID(CTRL_IN), CTRL_OUT = ID(CTRL_OUT); | ||||||
| 
 | 
 | ||||||
| 		setup_type("$memrd", {CLK, EN, ADDR}, {DATA}); | 		setup_type(ID($memrd), {CLK, EN, ADDR}, {DATA}); | ||||||
| 		setup_type("$memwr", {CLK, EN, ADDR, DATA}, pool<RTLIL::IdString>()); | 		setup_type(ID($memwr), {CLK, EN, ADDR, DATA}, pool<RTLIL::IdString>()); | ||||||
| 		setup_type("$meminit", {ADDR, DATA}, pool<RTLIL::IdString>()); | 		setup_type(ID($meminit), {ADDR, DATA}, pool<RTLIL::IdString>()); | ||||||
| 		setup_type("$mem", {RD_CLK, RD_EN, RD_ADDR, WR_CLK, WR_EN, WR_ADDR, WR_DATA}, {RD_DATA}); | 		setup_type(ID($mem), {RD_CLK, RD_EN, RD_ADDR, WR_CLK, WR_EN, WR_ADDR, WR_DATA}, {RD_DATA}); | ||||||
| 
 | 
 | ||||||
| 		setup_type("$fsm", {CLK, ARST, CTRL_IN}, {CTRL_OUT}); | 		setup_type(ID($fsm), {CLK, ARST, CTRL_IN}, {CTRL_OUT}); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void setup_stdcells() | 	void setup_stdcells() | ||||||
| 	{ | 	{ | ||||||
| 		setup_stdcells_eval(); | 		setup_stdcells_eval(); | ||||||
| 
 | 
 | ||||||
| 		IdString A = "\\A", E = "\\E", Y = "\\Y"; | 		IdString A = ID(A), E = ID(E), Y = ID(Y); | ||||||
| 
 | 
 | ||||||
| 		setup_type("$_TBUF_", {A, E}, {Y}, true); | 		setup_type(ID($_TBUF_), {A, E}, {Y}, true); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void setup_stdcells_eval() | 	void setup_stdcells_eval() | ||||||
| 	{ | 	{ | ||||||
| 		IdString A = "\\A", B = "\\B", C = "\\C", D = "\\D"; | 		IdString A = ID(A), B = ID(B), C = ID(C), D = ID(D); | ||||||
| 		IdString E = "\\E", F = "\\F", G = "\\G", H = "\\H"; | 		IdString E = ID(E), F = ID(F), G = ID(G), H = ID(H); | ||||||
| 		IdString I = "\\I", J = "\\J", K = "\\K", L = "\\L"; | 		IdString I = ID(I), J = ID(J), K = ID(K), L = ID(L); | ||||||
| 		IdString M = "\\M", N = "\\N", O = "\\O", P = "\\P"; | 		IdString M = ID(M), N = ID(N), O = ID(O), P = ID(P); | ||||||
| 		IdString S = "\\S", T = "\\T", U = "\\U", V = "\\V"; | 		IdString S = ID(S), T = ID(T), U = ID(U), V = ID(V); | ||||||
| 		IdString Y = "\\Y"; | 		IdString Y = ID(Y); | ||||||
| 
 | 
 | ||||||
| 		setup_type("$_BUF_", {A}, {Y}, true); | 		setup_type(ID($_BUF_), {A}, {Y}, true); | ||||||
| 		setup_type("$_NOT_", {A}, {Y}, true); | 		setup_type(ID($_NOT_), {A}, {Y}, true); | ||||||
| 		setup_type("$_AND_", {A, B}, {Y}, true); | 		setup_type(ID($_AND_), {A, B}, {Y}, true); | ||||||
| 		setup_type("$_NAND_", {A, B}, {Y}, true); | 		setup_type(ID($_NAND_), {A, B}, {Y}, true); | ||||||
| 		setup_type("$_OR_",  {A, B}, {Y}, true); | 		setup_type(ID($_OR_),  {A, B}, {Y}, true); | ||||||
| 		setup_type("$_NOR_",  {A, B}, {Y}, true); | 		setup_type(ID($_NOR_),  {A, B}, {Y}, true); | ||||||
| 		setup_type("$_XOR_", {A, B}, {Y}, true); | 		setup_type(ID($_XOR_), {A, B}, {Y}, true); | ||||||
| 		setup_type("$_XNOR_", {A, B}, {Y}, true); | 		setup_type(ID($_XNOR_), {A, B}, {Y}, true); | ||||||
| 		setup_type("$_ANDNOT_", {A, B}, {Y}, true); | 		setup_type(ID($_ANDNOT_), {A, B}, {Y}, true); | ||||||
| 		setup_type("$_ORNOT_", {A, B}, {Y}, true); | 		setup_type(ID($_ORNOT_), {A, B}, {Y}, true); | ||||||
| 		setup_type("$_MUX_", {A, B, S}, {Y}, true); | 		setup_type(ID($_MUX_), {A, B, S}, {Y}, true); | ||||||
| 		setup_type("$_NMUX_", {A, B, S}, {Y}, true); | 		setup_type(ID($_NMUX_), {A, B, S}, {Y}, true); | ||||||
| 		setup_type("$_MUX4_", {A, B, C, D, S, T}, {Y}, true); | 		setup_type(ID($_MUX4_), {A, B, C, D, S, T}, {Y}, true); | ||||||
| 		setup_type("$_MUX8_", {A, B, C, D, E, F, G, H, S, T, U}, {Y}, true); | 		setup_type(ID($_MUX8_), {A, B, C, D, E, F, G, H, S, T, U}, {Y}, true); | ||||||
| 		setup_type("$_MUX16_", {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V}, {Y}, true); | 		setup_type(ID($_MUX16_), {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V}, {Y}, true); | ||||||
| 		setup_type("$_AOI3_", {A, B, C}, {Y}, true); | 		setup_type(ID($_AOI3_), {A, B, C}, {Y}, true); | ||||||
| 		setup_type("$_OAI3_", {A, B, C}, {Y}, true); | 		setup_type(ID($_OAI3_), {A, B, C}, {Y}, true); | ||||||
| 		setup_type("$_AOI4_", {A, B, C, D}, {Y}, true); | 		setup_type(ID($_AOI4_), {A, B, C, D}, {Y}, true); | ||||||
| 		setup_type("$_OAI4_", {A, B, C, D}, {Y}, true); | 		setup_type(ID($_OAI4_), {A, B, C, D}, {Y}, true); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void setup_stdcells_mem() | 	void setup_stdcells_mem() | ||||||
| 	{ | 	{ | ||||||
| 		IdString S = "\\S", R = "\\R", C = "\\C"; | 		IdString S = ID(S), R = ID(R), C = ID(C); | ||||||
| 		IdString D = "\\D", Q = "\\Q", E = "\\E"; | 		IdString D = ID(D), Q = ID(Q), E = ID(E); | ||||||
| 
 | 
 | ||||||
| 		std::vector<char> list_np = {'N', 'P'}, list_01 = {'0', '1'}; | 		std::vector<char> list_np = {'N', 'P'}, list_01 = {'0', '1'}; | ||||||
| 
 | 
 | ||||||
|  | @ -223,7 +223,7 @@ struct CellTypes | ||||||
| 		for (auto c2 : list_np) | 		for (auto c2 : list_np) | ||||||
| 			setup_type(stringf("$_SR_%c%c_", c1, c2), {S, R}, {Q}); | 			setup_type(stringf("$_SR_%c%c_", c1, c2), {S, R}, {Q}); | ||||||
| 
 | 
 | ||||||
| 		setup_type("$_FF_", {D}, {Q}); | 		setup_type(ID($_FF_), {D}, {Q}); | ||||||
| 
 | 
 | ||||||
| 		for (auto c1 : list_np) | 		for (auto c1 : list_np) | ||||||
| 			setup_type(stringf("$_DFF_%c_", c1), {C, D}, {Q}); | 			setup_type(stringf("$_DFF_%c_", c1), {C, D}, {Q}); | ||||||
|  | @ -289,13 +289,13 @@ struct CellTypes | ||||||
| 
 | 
 | ||||||
| 	static RTLIL::Const eval(RTLIL::IdString type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len, bool *errp = nullptr) | 	static RTLIL::Const eval(RTLIL::IdString type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len, bool *errp = nullptr) | ||||||
| 	{ | 	{ | ||||||
| 		if (type == "$sshr" && !signed1) | 		if (type == ID($sshr) && !signed1) | ||||||
| 			type = "$shr"; | 			type = ID($shr); | ||||||
| 		if (type == "$sshl" && !signed1) | 		if (type == ID($sshl) && !signed1) | ||||||
| 			type = "$shl"; | 			type = ID($shl); | ||||||
| 
 | 
 | ||||||
| 		if (type != "$sshr" && type != "$sshl" && type != "$shr" && type != "$shl" && type != "$shift" && type != "$shiftx" && | 		if (type != ID($sshr) && type != ID($sshl) && type != ID($shr) && type != ID($shl) && type != ID($shift) && type != ID($shiftx) && | ||||||
| 				type != "$pos" && type != "$neg" && type != "$not") { | 				type != ID($pos) && type != ID($neg) && type != ID($not)) { | ||||||
| 			if (!signed1 || !signed2) | 			if (!signed1 || !signed2) | ||||||
| 				signed1 = false, signed2 = false; | 				signed1 = false, signed2 = false; | ||||||
| 		} | 		} | ||||||
|  | @ -338,25 +338,25 @@ struct CellTypes | ||||||
| 		HANDLE_CELL_TYPE(neg) | 		HANDLE_CELL_TYPE(neg) | ||||||
| #undef HANDLE_CELL_TYPE | #undef HANDLE_CELL_TYPE | ||||||
| 
 | 
 | ||||||
| 		if (type == "$_BUF_") | 		if (type == ID($_BUF_)) | ||||||
| 			return arg1; | 			return arg1; | ||||||
| 		if (type == "$_NOT_") | 		if (type == ID($_NOT_)) | ||||||
| 			return eval_not(arg1); | 			return eval_not(arg1); | ||||||
| 		if (type == "$_AND_") | 		if (type == ID($_AND_)) | ||||||
| 			return const_and(arg1, arg2, false, false, 1); | 			return const_and(arg1, arg2, false, false, 1); | ||||||
| 		if (type == "$_NAND_") | 		if (type == ID($_NAND_)) | ||||||
| 			return eval_not(const_and(arg1, arg2, false, false, 1)); | 			return eval_not(const_and(arg1, arg2, false, false, 1)); | ||||||
| 		if (type == "$_OR_") | 		if (type == ID($_OR_)) | ||||||
| 			return const_or(arg1, arg2, false, false, 1); | 			return const_or(arg1, arg2, false, false, 1); | ||||||
| 		if (type == "$_NOR_") | 		if (type == ID($_NOR_)) | ||||||
| 			return eval_not(const_or(arg1, arg2, false, false, 1)); | 			return eval_not(const_or(arg1, arg2, false, false, 1)); | ||||||
| 		if (type == "$_XOR_") | 		if (type == ID($_XOR_)) | ||||||
| 			return const_xor(arg1, arg2, false, false, 1); | 			return const_xor(arg1, arg2, false, false, 1); | ||||||
| 		if (type == "$_XNOR_") | 		if (type == ID($_XNOR_)) | ||||||
| 			return const_xnor(arg1, arg2, false, false, 1); | 			return const_xnor(arg1, arg2, false, false, 1); | ||||||
| 		if (type == "$_ANDNOT_") | 		if (type == ID($_ANDNOT_)) | ||||||
| 			return const_and(arg1, eval_not(arg2), false, false, 1); | 			return const_and(arg1, eval_not(arg2), false, false, 1); | ||||||
| 		if (type == "$_ORNOT_") | 		if (type == ID($_ORNOT_)) | ||||||
| 			return const_or(arg1, eval_not(arg2), false, false, 1); | 			return const_or(arg1, eval_not(arg2), false, false, 1); | ||||||
| 
 | 
 | ||||||
| 		if (errp != nullptr) { | 		if (errp != nullptr) { | ||||||
|  | @ -369,25 +369,25 @@ struct CellTypes | ||||||
| 
 | 
 | ||||||
| 	static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool *errp = nullptr) | 	static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool *errp = nullptr) | ||||||
| 	{ | 	{ | ||||||
| 		if (cell->type == "$slice") { | 		if (cell->type == ID($slice)) { | ||||||
| 			RTLIL::Const ret; | 			RTLIL::Const ret; | ||||||
| 			int width = cell->parameters.at("\\Y_WIDTH").as_int(); | 			int width = cell->parameters.at(ID(Y_WIDTH)).as_int(); | ||||||
| 			int offset = cell->parameters.at("\\OFFSET").as_int(); | 			int offset = cell->parameters.at(ID(OFFSET)).as_int(); | ||||||
| 			ret.bits.insert(ret.bits.end(), arg1.bits.begin()+offset, arg1.bits.begin()+offset+width); | 			ret.bits.insert(ret.bits.end(), arg1.bits.begin()+offset, arg1.bits.begin()+offset+width); | ||||||
| 			return ret; | 			return ret; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (cell->type == "$concat") { | 		if (cell->type == ID($concat)) { | ||||||
| 			RTLIL::Const ret = arg1; | 			RTLIL::Const ret = arg1; | ||||||
| 			ret.bits.insert(ret.bits.end(), arg2.bits.begin(), arg2.bits.end()); | 			ret.bits.insert(ret.bits.end(), arg2.bits.begin(), arg2.bits.end()); | ||||||
| 			return ret; | 			return ret; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (cell->type == "$lut") | 		if (cell->type == ID($lut)) | ||||||
| 		{ | 		{ | ||||||
| 			int width = cell->parameters.at("\\WIDTH").as_int(); | 			int width = cell->parameters.at(ID(WIDTH)).as_int(); | ||||||
| 
 | 
 | ||||||
| 			std::vector<RTLIL::State> t = cell->parameters.at("\\LUT").bits; | 			std::vector<RTLIL::State> t = cell->parameters.at(ID(LUT)).bits; | ||||||
| 			while (GetSize(t) < (1 << width)) | 			while (GetSize(t) < (1 << width)) | ||||||
| 				t.push_back(State::S0); | 				t.push_back(State::S0); | ||||||
| 			t.resize(1 << width); | 			t.resize(1 << width); | ||||||
|  | @ -409,11 +409,11 @@ struct CellTypes | ||||||
| 			return t; | 			return t; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (cell->type == "$sop") | 		if (cell->type == ID($sop)) | ||||||
| 		{ | 		{ | ||||||
| 			int width = cell->parameters.at("\\WIDTH").as_int(); | 			int width = cell->parameters.at(ID(WIDTH)).as_int(); | ||||||
| 			int depth = cell->parameters.at("\\DEPTH").as_int(); | 			int depth = cell->parameters.at(ID(DEPTH)).as_int(); | ||||||
| 			std::vector<RTLIL::State> t = cell->parameters.at("\\TABLE").bits; | 			std::vector<RTLIL::State> t = cell->parameters.at(ID(TABLE)).bits; | ||||||
| 
 | 
 | ||||||
| 			while (GetSize(t) < width*depth*2) | 			while (GetSize(t) < width*depth*2) | ||||||
| 				t.push_back(State::S0); | 				t.push_back(State::S0); | ||||||
|  | @ -447,15 +447,15 @@ struct CellTypes | ||||||
| 			return default_ret; | 			return default_ret; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		bool signed_a = cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters["\\A_SIGNED"].as_bool(); | 		bool signed_a = cell->parameters.count(ID(A_SIGNED)) > 0 && cell->parameters[ID(A_SIGNED)].as_bool(); | ||||||
| 		bool signed_b = cell->parameters.count("\\B_SIGNED") > 0 && cell->parameters["\\B_SIGNED"].as_bool(); | 		bool signed_b = cell->parameters.count(ID(B_SIGNED)) > 0 && cell->parameters[ID(B_SIGNED)].as_bool(); | ||||||
| 		int result_len = cell->parameters.count("\\Y_WIDTH") > 0 ? cell->parameters["\\Y_WIDTH"].as_int() : -1; | 		int result_len = cell->parameters.count(ID(Y_WIDTH)) > 0 ? cell->parameters[ID(Y_WIDTH)].as_int() : -1; | ||||||
| 		return eval(cell->type, arg1, arg2, signed_a, signed_b, result_len, errp); | 		return eval(cell->type, arg1, arg2, signed_a, signed_b, result_len, errp); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, bool *errp = nullptr) | 	static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, bool *errp = nullptr) | ||||||
| 	{ | 	{ | ||||||
| 		if (cell->type.in("$mux", "$pmux", "$_MUX_")) { | 		if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_))) { | ||||||
| 			RTLIL::Const ret = arg1; | 			RTLIL::Const ret = arg1; | ||||||
| 			for (size_t i = 0; i < arg3.bits.size(); i++) | 			for (size_t i = 0; i < arg3.bits.size(); i++) | ||||||
| 				if (arg3.bits[i] == RTLIL::State::S1) { | 				if (arg3.bits[i] == RTLIL::State::S1) { | ||||||
|  | @ -465,9 +465,9 @@ struct CellTypes | ||||||
| 			return ret; | 			return ret; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (cell->type == "$_AOI3_") | 		if (cell->type == ID($_AOI3_)) | ||||||
| 			return eval_not(const_or(const_and(arg1, arg2, false, false, 1), arg3, false, false, 1)); | 			return eval_not(const_or(const_and(arg1, arg2, false, false, 1), arg3, false, false, 1)); | ||||||
| 		if (cell->type == "$_OAI3_") | 		if (cell->type == ID($_OAI3_)) | ||||||
| 			return eval_not(const_and(const_or(arg1, arg2, false, false, 1), arg3, false, false, 1)); | 			return eval_not(const_and(const_or(arg1, arg2, false, false, 1), arg3, false, false, 1)); | ||||||
| 
 | 
 | ||||||
| 		log_assert(arg3.bits.size() == 0); | 		log_assert(arg3.bits.size() == 0); | ||||||
|  | @ -476,9 +476,9 @@ struct CellTypes | ||||||
| 
 | 
 | ||||||
| 	static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, const RTLIL::Const &arg4, bool *errp = nullptr) | 	static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, const RTLIL::Const &arg4, bool *errp = nullptr) | ||||||
| 	{ | 	{ | ||||||
| 		if (cell->type == "$_AOI4_") | 		if (cell->type == ID($_AOI4_)) | ||||||
| 			return eval_not(const_or(const_and(arg1, arg2, false, false, 1), const_and(arg3, arg4, false, false, 1), false, false, 1)); | 			return eval_not(const_or(const_and(arg1, arg2, false, false, 1), const_and(arg3, arg4, false, false, 1), false, false, 1)); | ||||||
| 		if (cell->type == "$_OAI4_") | 		if (cell->type == ID($_OAI4_)) | ||||||
| 			return eval_not(const_and(const_or(arg1, arg2, false, false, 1), const_or(arg3, arg4, false, false, 1), false, false, 1)); | 			return eval_not(const_and(const_or(arg1, arg2, false, false, 1), const_or(arg3, arg4, false, false, 1), false, false, 1)); | ||||||
| 
 | 
 | ||||||
| 		log_assert(arg4.bits.size() == 0); | 		log_assert(arg4.bits.size() == 0); | ||||||
|  |  | ||||||
|  | @ -89,12 +89,12 @@ struct ConstEval | ||||||
| 
 | 
 | ||||||
| 	bool eval(RTLIL::Cell *cell, RTLIL::SigSpec &undef) | 	bool eval(RTLIL::Cell *cell, RTLIL::SigSpec &undef) | ||||||
| 	{ | 	{ | ||||||
| 		if (cell->type == "$lcu") | 		if (cell->type == ID($lcu)) | ||||||
| 		{ | 		{ | ||||||
| 			RTLIL::SigSpec sig_p = cell->getPort("\\P"); | 			RTLIL::SigSpec sig_p = cell->getPort(ID(P)); | ||||||
| 			RTLIL::SigSpec sig_g = cell->getPort("\\G"); | 			RTLIL::SigSpec sig_g = cell->getPort(ID(G)); | ||||||
| 			RTLIL::SigSpec sig_ci = cell->getPort("\\CI"); | 			RTLIL::SigSpec sig_ci = cell->getPort(ID(CI)); | ||||||
| 			RTLIL::SigSpec sig_co = values_map(assign_map(cell->getPort("\\CO"))); | 			RTLIL::SigSpec sig_co = values_map(assign_map(cell->getPort(ID(CO)))); | ||||||
| 
 | 
 | ||||||
| 			if (sig_co.is_fully_const()) | 			if (sig_co.is_fully_const()) | ||||||
| 				return true; | 				return true; | ||||||
|  | @ -128,24 +128,24 @@ struct ConstEval | ||||||
| 
 | 
 | ||||||
| 		RTLIL::SigSpec sig_a, sig_b, sig_s, sig_y; | 		RTLIL::SigSpec sig_a, sig_b, sig_s, sig_y; | ||||||
| 
 | 
 | ||||||
| 		log_assert(cell->hasPort("\\Y")); | 		log_assert(cell->hasPort(ID(Y))); | ||||||
| 		sig_y = values_map(assign_map(cell->getPort("\\Y"))); | 		sig_y = values_map(assign_map(cell->getPort(ID(Y)))); | ||||||
| 		if (sig_y.is_fully_const()) | 		if (sig_y.is_fully_const()) | ||||||
| 			return true; | 			return true; | ||||||
| 
 | 
 | ||||||
| 		if (cell->hasPort("\\S")) { | 		if (cell->hasPort(ID(S))) { | ||||||
| 			sig_s = cell->getPort("\\S"); | 			sig_s = cell->getPort(ID(S)); | ||||||
| 			if (!eval(sig_s, undef, cell)) | 			if (!eval(sig_s, undef, cell)) | ||||||
| 				return false; | 				return false; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (cell->hasPort("\\A")) | 		if (cell->hasPort(ID(A))) | ||||||
| 			sig_a = cell->getPort("\\A"); | 			sig_a = cell->getPort(ID(A)); | ||||||
| 
 | 
 | ||||||
| 		if (cell->hasPort("\\B")) | 		if (cell->hasPort(ID(B))) | ||||||
| 			sig_b = cell->getPort("\\B"); | 			sig_b = cell->getPort(ID(B)); | ||||||
| 
 | 
 | ||||||
| 		if (cell->type.in("$mux", "$pmux", "$_MUX_", "$_NMUX_")) | 		if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_), ID($_NMUX_))) | ||||||
| 		{ | 		{ | ||||||
| 			std::vector<RTLIL::SigSpec> y_candidates; | 			std::vector<RTLIL::SigSpec> y_candidates; | ||||||
| 			int count_maybe_set_s_bits = 0; | 			int count_maybe_set_s_bits = 0; | ||||||
|  | @ -175,7 +175,7 @@ struct ConstEval | ||||||
| 			for (auto &yc : y_candidates) { | 			for (auto &yc : y_candidates) { | ||||||
| 				if (!eval(yc, undef, cell)) | 				if (!eval(yc, undef, cell)) | ||||||
| 					return false; | 					return false; | ||||||
| 				if (cell->type == "$_NMUX_") | 				if (cell->type == ID($_NMUX_)) | ||||||
| 					y_values.push_back(RTLIL::const_not(yc.as_const(), Const(), false, false, GetSize(yc))); | 					y_values.push_back(RTLIL::const_not(yc.as_const(), Const(), false, false, GetSize(yc))); | ||||||
| 				else | 				else | ||||||
| 					y_values.push_back(yc.as_const()); | 					y_values.push_back(yc.as_const()); | ||||||
|  | @ -198,10 +198,10 @@ struct ConstEval | ||||||
| 			else | 			else | ||||||
| 				set(sig_y, y_values.front()); | 				set(sig_y, y_values.front()); | ||||||
| 		} | 		} | ||||||
| 		else if (cell->type == "$fa") | 		else if (cell->type == ID($fa)) | ||||||
| 		{ | 		{ | ||||||
| 			RTLIL::SigSpec sig_c = cell->getPort("\\C"); | 			RTLIL::SigSpec sig_c = cell->getPort(ID(C)); | ||||||
| 			RTLIL::SigSpec sig_x = cell->getPort("\\X"); | 			RTLIL::SigSpec sig_x = cell->getPort(ID(X)); | ||||||
| 			int width = GetSize(sig_c); | 			int width = GetSize(sig_c); | ||||||
| 
 | 
 | ||||||
| 			if (!eval(sig_a, undef, cell)) | 			if (!eval(sig_a, undef, cell)) | ||||||
|  | @ -227,13 +227,13 @@ struct ConstEval | ||||||
| 			set(sig_y, val_y); | 			set(sig_y, val_y); | ||||||
| 			set(sig_x, val_x); | 			set(sig_x, val_x); | ||||||
| 		} | 		} | ||||||
| 		else if (cell->type == "$alu") | 		else if (cell->type == ID($alu)) | ||||||
| 		{ | 		{ | ||||||
| 			bool signed_a = cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters["\\A_SIGNED"].as_bool(); | 			bool signed_a = cell->parameters.count(ID(A_SIGNED)) > 0 && cell->parameters[ID(A_SIGNED)].as_bool(); | ||||||
| 			bool signed_b = cell->parameters.count("\\B_SIGNED") > 0 && cell->parameters["\\B_SIGNED"].as_bool(); | 			bool signed_b = cell->parameters.count(ID(B_SIGNED)) > 0 && cell->parameters[ID(B_SIGNED)].as_bool(); | ||||||
| 
 | 
 | ||||||
| 			RTLIL::SigSpec sig_ci = cell->getPort("\\CI"); | 			RTLIL::SigSpec sig_ci = cell->getPort(ID(CI)); | ||||||
| 			RTLIL::SigSpec sig_bi = cell->getPort("\\BI"); | 			RTLIL::SigSpec sig_bi = cell->getPort(ID(BI)); | ||||||
| 
 | 
 | ||||||
| 			if (!eval(sig_a, undef, cell)) | 			if (!eval(sig_a, undef, cell)) | ||||||
| 				return false; | 				return false; | ||||||
|  | @ -247,8 +247,8 @@ struct ConstEval | ||||||
| 			if (!eval(sig_bi, undef, cell)) | 			if (!eval(sig_bi, undef, cell)) | ||||||
| 				return false; | 				return false; | ||||||
| 
 | 
 | ||||||
| 			RTLIL::SigSpec sig_x = cell->getPort("\\X"); | 			RTLIL::SigSpec sig_x = cell->getPort(ID(X)); | ||||||
| 			RTLIL::SigSpec sig_co = cell->getPort("\\CO"); | 			RTLIL::SigSpec sig_co = cell->getPort(ID(CO)); | ||||||
| 
 | 
 | ||||||
| 			bool any_input_undef = !(sig_a.is_fully_def() && sig_b.is_fully_def() && sig_ci.is_fully_def() && sig_bi.is_fully_def()); | 			bool any_input_undef = !(sig_a.is_fully_def() && sig_b.is_fully_def() && sig_ci.is_fully_def() && sig_bi.is_fully_def()); | ||||||
| 			sig_a.extend_u0(GetSize(sig_y), signed_a); | 			sig_a.extend_u0(GetSize(sig_y), signed_a); | ||||||
|  | @ -283,7 +283,7 @@ struct ConstEval | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		else if (cell->type == "$macc") | 		else if (cell->type == ID($macc)) | ||||||
| 		{ | 		{ | ||||||
| 			Macc macc; | 			Macc macc; | ||||||
| 			macc.from_cell(cell); | 			macc.from_cell(cell); | ||||||
|  | @ -298,21 +298,21 @@ struct ConstEval | ||||||
| 					return false; | 					return false; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			RTLIL::Const result(0, GetSize(cell->getPort("\\Y"))); | 			RTLIL::Const result(0, GetSize(cell->getPort(ID(Y)))); | ||||||
| 			if (!macc.eval(result)) | 			if (!macc.eval(result)) | ||||||
| 				log_abort(); | 				log_abort(); | ||||||
| 
 | 
 | ||||||
| 			set(cell->getPort("\\Y"), result); | 			set(cell->getPort(ID(Y)), result); | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			RTLIL::SigSpec sig_c, sig_d; | 			RTLIL::SigSpec sig_c, sig_d; | ||||||
| 
 | 
 | ||||||
| 			if (cell->type.in("$_AOI3_", "$_OAI3_", "$_AOI4_", "$_OAI4_")) { | 			if (cell->type.in(ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_))) { | ||||||
| 				if (cell->hasPort("\\C")) | 				if (cell->hasPort(ID(C))) | ||||||
| 					sig_c = cell->getPort("\\C"); | 					sig_c = cell->getPort(ID(C)); | ||||||
| 				if (cell->hasPort("\\D")) | 				if (cell->hasPort(ID(D))) | ||||||
| 					sig_d = cell->getPort("\\D"); | 					sig_d = cell->getPort(ID(D)); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (sig_a.size() > 0 && !eval(sig_a, undef, cell)) | 			if (sig_a.size() > 0 && !eval(sig_a, undef, cell)) | ||||||
|  |  | ||||||
|  | @ -28,44 +28,44 @@ struct CellCosts | ||||||
| { | { | ||||||
| 	static const dict<RTLIL::IdString, int>& default_gate_cost() { | 	static const dict<RTLIL::IdString, int>& default_gate_cost() { | ||||||
| 		static const dict<RTLIL::IdString, int> db = { | 		static const dict<RTLIL::IdString, int> db = { | ||||||
| 			{ "$_BUF_",    1 }, | 			{ ID($_BUF_),    1 }, | ||||||
| 			{ "$_NOT_",    2 }, | 			{ ID($_NOT_),    2 }, | ||||||
| 			{ "$_AND_",    4 }, | 			{ ID($_AND_),    4 }, | ||||||
| 			{ "$_NAND_",   4 }, | 			{ ID($_NAND_),   4 }, | ||||||
| 			{ "$_OR_",     4 }, | 			{ ID($_OR_),     4 }, | ||||||
| 			{ "$_NOR_",    4 }, | 			{ ID($_NOR_),    4 }, | ||||||
| 			{ "$_ANDNOT_", 4 }, | 			{ ID($_ANDNOT_), 4 }, | ||||||
| 			{ "$_ORNOT_",  4 }, | 			{ ID($_ORNOT_),  4 }, | ||||||
| 			{ "$_XOR_",    5 }, | 			{ ID($_XOR_),    5 }, | ||||||
| 			{ "$_XNOR_",   5 }, | 			{ ID($_XNOR_),   5 }, | ||||||
| 			{ "$_AOI3_",   6 }, | 			{ ID($_AOI3_),   6 }, | ||||||
| 			{ "$_OAI3_",   6 }, | 			{ ID($_OAI3_),   6 }, | ||||||
| 			{ "$_AOI4_",   7 }, | 			{ ID($_AOI4_),   7 }, | ||||||
| 			{ "$_OAI4_",   7 }, | 			{ ID($_OAI4_),   7 }, | ||||||
| 			{ "$_MUX_",    4 }, | 			{ ID($_MUX_),    4 }, | ||||||
| 			{ "$_NMUX_",   4 } | 			{ ID($_NMUX_),   4 } | ||||||
| 		}; | 		}; | ||||||
| 		return db; | 		return db; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	static const dict<RTLIL::IdString, int>& cmos_gate_cost() { | 	static const dict<RTLIL::IdString, int>& cmos_gate_cost() { | ||||||
| 		static const dict<RTLIL::IdString, int> db = { | 		static const dict<RTLIL::IdString, int> db = { | ||||||
| 			{ "$_BUF_",     1 }, | 			{ ID($_BUF_),     1 }, | ||||||
| 			{ "$_NOT_",     2 }, | 			{ ID($_NOT_),     2 }, | ||||||
| 			{ "$_AND_",     6 }, | 			{ ID($_AND_),     6 }, | ||||||
| 			{ "$_NAND_",    4 }, | 			{ ID($_NAND_),    4 }, | ||||||
| 			{ "$_OR_",      6 }, | 			{ ID($_OR_),      6 }, | ||||||
| 			{ "$_NOR_",     4 }, | 			{ ID($_NOR_),     4 }, | ||||||
| 			{ "$_ANDNOT_",  6 }, | 			{ ID($_ANDNOT_),  6 }, | ||||||
| 			{ "$_ORNOT_",   6 }, | 			{ ID($_ORNOT_),   6 }, | ||||||
| 			{ "$_XOR_",    12 }, | 			{ ID($_XOR_),    12 }, | ||||||
| 			{ "$_XNOR_",   12 }, | 			{ ID($_XNOR_),   12 }, | ||||||
| 			{ "$_AOI3_",    6 }, | 			{ ID($_AOI3_),    6 }, | ||||||
| 			{ "$_OAI3_",    6 }, | 			{ ID($_OAI3_),    6 }, | ||||||
| 			{ "$_AOI4_",    8 }, | 			{ ID($_AOI4_),    8 }, | ||||||
| 			{ "$_OAI4_",    8 }, | 			{ ID($_OAI4_),    8 }, | ||||||
| 			{ "$_MUX_",    12 }, | 			{ ID($_MUX_),    12 }, | ||||||
| 			{ "$_NMUX_",   10 } | 			{ ID($_NMUX_),   10 } | ||||||
| 		}; | 		}; | ||||||
| 		return db; | 		return db; | ||||||
| 	} | 	} | ||||||
|  | @ -92,8 +92,8 @@ struct CellCosts | ||||||
| 		{ | 		{ | ||||||
| 			RTLIL::Module *mod = design->module(cell->type); | 			RTLIL::Module *mod = design->module(cell->type); | ||||||
| 
 | 
 | ||||||
| 			if (mod->attributes.count("\\cost")) | 			if (mod->attributes.count(ID(cost))) | ||||||
| 				return mod->attributes.at("\\cost").as_int(); | 				return mod->attributes.at(ID(cost)).as_int(); | ||||||
| 
 | 
 | ||||||
| 			if (mod_cost_cache.count(mod->name)) | 			if (mod_cost_cache.count(mod->name)) | ||||||
| 				return mod_cost_cache.at(mod->name); | 				return mod_cost_cache.at(mod->name); | ||||||
|  |  | ||||||
|  | @ -99,16 +99,16 @@ struct Macc | ||||||
| 
 | 
 | ||||||
| 	void from_cell(RTLIL::Cell *cell) | 	void from_cell(RTLIL::Cell *cell) | ||||||
| 	{ | 	{ | ||||||
| 		RTLIL::SigSpec port_a = cell->getPort("\\A"); | 		RTLIL::SigSpec port_a = cell->getPort(ID(A)); | ||||||
| 
 | 
 | ||||||
| 		ports.clear(); | 		ports.clear(); | ||||||
| 		bit_ports = cell->getPort("\\B"); | 		bit_ports = cell->getPort(ID(B)); | ||||||
| 
 | 
 | ||||||
| 		std::vector<RTLIL::State> config_bits = cell->getParam("\\CONFIG").bits; | 		std::vector<RTLIL::State> config_bits = cell->getParam(ID(CONFIG)).bits; | ||||||
| 		int config_cursor = 0; | 		int config_cursor = 0; | ||||||
| 
 | 
 | ||||||
| #ifndef NDEBUG | #ifndef NDEBUG | ||||||
| 		int config_width = cell->getParam("\\CONFIG_WIDTH").as_int(); | 		int config_width = cell->getParam(ID(CONFIG_WIDTH)).as_int(); | ||||||
| 		log_assert(GetSize(config_bits) >= config_width); | 		log_assert(GetSize(config_bits) >= config_width); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | @ -191,12 +191,12 @@ struct Macc | ||||||
| 			port_a.append(port.in_b); | 			port_a.append(port.in_b); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		cell->setPort("\\A", port_a); | 		cell->setPort(ID(A), port_a); | ||||||
| 		cell->setPort("\\B", bit_ports); | 		cell->setPort(ID(B), bit_ports); | ||||||
| 		cell->setParam("\\CONFIG", config_bits); | 		cell->setParam(ID(CONFIG), config_bits); | ||||||
| 		cell->setParam("\\CONFIG_WIDTH", GetSize(config_bits)); | 		cell->setParam(ID(CONFIG_WIDTH), GetSize(config_bits)); | ||||||
| 		cell->setParam("\\A_WIDTH", GetSize(port_a)); | 		cell->setParam(ID(A_WIDTH), GetSize(port_a)); | ||||||
| 		cell->setParam("\\B_WIDTH", GetSize(bit_ports)); | 		cell->setParam(ID(B_WIDTH), GetSize(bit_ports)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	bool eval(RTLIL::Const &result) const | 	bool eval(RTLIL::Const &result) const | ||||||
|  |  | ||||||
							
								
								
									
										1151
									
								
								kernel/rtlil.cc
									
										
									
									
									
								
							
							
						
						
									
										1151
									
								
								kernel/rtlil.cc
									
										
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										125
									
								
								kernel/rtlil.h
									
										
									
									
									
								
							
							
						
						
									
										125
									
								
								kernel/rtlil.h
									
										
									
									
									
								
							|  | @ -78,6 +78,8 @@ namespace RTLIL | ||||||
| 	{ | 	{ | ||||||
| 		#undef YOSYS_XTRACE_GET_PUT | 		#undef YOSYS_XTRACE_GET_PUT | ||||||
| 		#undef YOSYS_SORT_ID_FREE_LIST | 		#undef YOSYS_SORT_ID_FREE_LIST | ||||||
|  | 		#undef YOSYS_USE_STICKY_IDS | ||||||
|  | 		#undef YOSYS_NO_IDS_REFCNT | ||||||
| 
 | 
 | ||||||
| 		// the global id string cache
 | 		// the global id string cache
 | ||||||
| 
 | 
 | ||||||
|  | @ -87,13 +89,17 @@ namespace RTLIL | ||||||
| 			~destruct_guard_t() { ok = false; } | 			~destruct_guard_t() { ok = false; } | ||||||
| 		} destruct_guard; | 		} destruct_guard; | ||||||
| 
 | 
 | ||||||
| 		static std::vector<int> global_refcount_storage_; |  | ||||||
| 		static std::vector<char*> global_id_storage_; | 		static std::vector<char*> global_id_storage_; | ||||||
| 		static dict<char*, int, hash_cstr_ops> global_id_index_; | 		static dict<char*, int, hash_cstr_ops> global_id_index_; | ||||||
|  | 	#ifndef YOSYS_NO_IDS_REFCNT | ||||||
|  | 		static std::vector<int> global_refcount_storage_; | ||||||
| 		static std::vector<int> global_free_idx_list_; | 		static std::vector<int> global_free_idx_list_; | ||||||
|  | 	#endif | ||||||
| 
 | 
 | ||||||
|  | 	#ifdef YOSYS_USE_STICKY_IDS | ||||||
| 		static int last_created_idx_ptr_; | 		static int last_created_idx_ptr_; | ||||||
| 		static int last_created_idx_[8]; | 		static int last_created_idx_[8]; | ||||||
|  | 	#endif | ||||||
| 
 | 
 | ||||||
| 		static inline void xtrace_db_dump() | 		static inline void xtrace_db_dump() | ||||||
| 		{ | 		{ | ||||||
|  | @ -110,12 +116,14 @@ namespace RTLIL | ||||||
| 
 | 
 | ||||||
| 		static inline void checkpoint() | 		static inline void checkpoint() | ||||||
| 		{ | 		{ | ||||||
|  | 		#ifdef YOSYS_USE_STICKY_IDS | ||||||
| 			last_created_idx_ptr_ = 0; | 			last_created_idx_ptr_ = 0; | ||||||
| 			for (int i = 0; i < 8; i++) { | 			for (int i = 0; i < 8; i++) { | ||||||
| 				if (last_created_idx_[i]) | 				if (last_created_idx_[i]) | ||||||
| 					put_reference(last_created_idx_[i]); | 					put_reference(last_created_idx_[i]); | ||||||
| 				last_created_idx_[i] = 0; | 				last_created_idx_[i] = 0; | ||||||
| 			} | 			} | ||||||
|  | 		#endif | ||||||
| 		#ifdef YOSYS_SORT_ID_FREE_LIST | 		#ifdef YOSYS_SORT_ID_FREE_LIST | ||||||
| 			std::sort(global_free_idx_list_.begin(), global_free_idx_list_.end(), std::greater<int>()); | 			std::sort(global_free_idx_list_.begin(), global_free_idx_list_.end(), std::greater<int>()); | ||||||
| 		#endif | 		#endif | ||||||
|  | @ -123,36 +131,47 @@ namespace RTLIL | ||||||
| 
 | 
 | ||||||
| 		static inline int get_reference(int idx) | 		static inline int get_reference(int idx) | ||||||
| 		{ | 		{ | ||||||
| 			global_refcount_storage_.at(idx)++; | 			if (idx) { | ||||||
| 		#ifdef YOSYS_XTRACE_GET_PUT | 		#ifndef YOSYS_NO_IDS_REFCNT | ||||||
| 			if (yosys_xtrace) { | 				global_refcount_storage_[idx]++; | ||||||
| 				log("#X# GET-BY-INDEX '%s' (index %d, refcount %d)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx)); |  | ||||||
| 			} |  | ||||||
| 		#endif | 		#endif | ||||||
|  | 		#ifdef YOSYS_XTRACE_GET_PUT | ||||||
|  | 				if (yosys_xtrace) | ||||||
|  | 					log("#X# GET-BY-INDEX '%s' (index %d, refcount %d)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx)); | ||||||
|  | 		#endif | ||||||
|  | 			} | ||||||
| 			return idx; | 			return idx; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		static inline int get_reference(const char *p) | 		static int get_reference(const char *p) | ||||||
| 		{ | 		{ | ||||||
| 			log_assert(destruct_guard.ok); | 			log_assert(destruct_guard.ok); | ||||||
| 
 | 
 | ||||||
| 			if (p[0]) { | 			if (!p[0]) | ||||||
| 				log_assert(p[1] != 0); | 				return 0; | ||||||
|  | 
 | ||||||
| 			log_assert(p[0] == '$' || p[0] == '\\'); | 			log_assert(p[0] == '$' || p[0] == '\\'); | ||||||
| 			} | 			log_assert(p[1] != 0); | ||||||
| 
 | 
 | ||||||
| 			auto it = global_id_index_.find((char*)p); | 			auto it = global_id_index_.find((char*)p); | ||||||
| 			if (it != global_id_index_.end()) { | 			if (it != global_id_index_.end()) { | ||||||
|  | 		#ifndef YOSYS_NO_IDS_REFCNT | ||||||
| 				global_refcount_storage_.at(it->second)++; | 				global_refcount_storage_.at(it->second)++; | ||||||
|  | 		#endif | ||||||
| 		#ifdef YOSYS_XTRACE_GET_PUT | 		#ifdef YOSYS_XTRACE_GET_PUT | ||||||
| 				if (yosys_xtrace) { | 				if (yosys_xtrace) | ||||||
| 					log("#X# GET-BY-NAME '%s' (index %d, refcount %d)\n", global_id_storage_.at(it->second), it->second, global_refcount_storage_.at(it->second)); | 					log("#X# GET-BY-NAME '%s' (index %d, refcount %d)\n", global_id_storage_.at(it->second), it->second, global_refcount_storage_.at(it->second)); | ||||||
| 				} |  | ||||||
| 		#endif | 		#endif | ||||||
| 				return it->second; | 				return it->second; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | 		#ifndef YOSYS_NO_IDS_REFCNT | ||||||
| 			if (global_free_idx_list_.empty()) { | 			if (global_free_idx_list_.empty()) { | ||||||
|  | 				if (global_id_storage_.empty()) { | ||||||
|  | 					global_refcount_storage_.push_back(0); | ||||||
|  | 					global_id_storage_.push_back((char*)""); | ||||||
|  | 					global_id_index_[global_id_storage_.back()] = 0; | ||||||
|  | 				} | ||||||
| 				log_assert(global_id_storage_.size() < 0x40000000); | 				log_assert(global_id_storage_.size() < 0x40000000); | ||||||
| 				global_free_idx_list_.push_back(global_id_storage_.size()); | 				global_free_idx_list_.push_back(global_id_storage_.size()); | ||||||
| 				global_id_storage_.push_back(nullptr); | 				global_id_storage_.push_back(nullptr); | ||||||
|  | @ -164,13 +183,15 @@ namespace RTLIL | ||||||
| 			global_id_storage_.at(idx) = strdup(p); | 			global_id_storage_.at(idx) = strdup(p); | ||||||
| 			global_id_index_[global_id_storage_.at(idx)] = idx; | 			global_id_index_[global_id_storage_.at(idx)] = idx; | ||||||
| 			global_refcount_storage_.at(idx)++; | 			global_refcount_storage_.at(idx)++; | ||||||
| 
 | 		#else | ||||||
| 			// Avoid Create->Delete->Create pattern
 | 			if (global_id_storage_.empty()) { | ||||||
| 			if (last_created_idx_[last_created_idx_ptr_]) | 				global_id_storage_.push_back((char*)""); | ||||||
| 				put_reference(last_created_idx_[last_created_idx_ptr_]); | 				global_id_index_[global_id_storage_.back()] = 0; | ||||||
| 			last_created_idx_[last_created_idx_ptr_] = idx; | 			} | ||||||
| 			get_reference(last_created_idx_[last_created_idx_ptr_]); | 			int idx = global_id_storage_.size(); | ||||||
| 			last_created_idx_ptr_ = (last_created_idx_ptr_ + 1) & 7; | 			global_id_storage_.push_back(strdup(p)); | ||||||
|  | 			global_id_index_[global_id_storage_.back()] = idx; | ||||||
|  | 		#endif | ||||||
| 
 | 
 | ||||||
| 			if (yosys_xtrace) { | 			if (yosys_xtrace) { | ||||||
| 				log("#X# New IdString '%s' with index %d.\n", p, idx); | 				log("#X# New IdString '%s' with index %d.\n", p, idx); | ||||||
|  | @ -178,18 +199,28 @@ namespace RTLIL | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 		#ifdef YOSYS_XTRACE_GET_PUT | 		#ifdef YOSYS_XTRACE_GET_PUT | ||||||
| 			if (yosys_xtrace) { | 			if (yosys_xtrace) | ||||||
| 				log("#X# GET-BY-NAME '%s' (index %d, refcount %d)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx)); | 				log("#X# GET-BY-NAME '%s' (index %d, refcount %d)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx)); | ||||||
| 			} |  | ||||||
| 		#endif | 		#endif | ||||||
|  | 
 | ||||||
|  | 		#ifdef YOSYS_USE_STICKY_IDS | ||||||
|  | 			// Avoid Create->Delete->Create pattern
 | ||||||
|  | 			if (last_created_idx_[last_created_idx_ptr_]) | ||||||
|  | 				put_reference(last_created_idx_[last_created_idx_ptr_]); | ||||||
|  | 			last_created_idx_[last_created_idx_ptr_] = idx; | ||||||
|  | 			get_reference(last_created_idx_[last_created_idx_ptr_]); | ||||||
|  | 			last_created_idx_ptr_ = (last_created_idx_ptr_ + 1) & 7; | ||||||
|  | 		#endif | ||||||
|  | 
 | ||||||
| 			return idx; | 			return idx; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 	#ifndef YOSYS_NO_IDS_REFCNT | ||||||
| 		static inline void put_reference(int idx) | 		static inline void put_reference(int idx) | ||||||
| 		{ | 		{ | ||||||
| 			// put_reference() may be called from destructors after the destructor of
 | 			// put_reference() may be called from destructors after the destructor of
 | ||||||
| 			// global_refcount_storage_ has been run. in this case we simply do nothing.
 | 			// global_refcount_storage_ has been run. in this case we simply do nothing.
 | ||||||
| 			if (!destruct_guard.ok) | 			if (!destruct_guard.ok || !idx) | ||||||
| 				return; | 				return; | ||||||
| 
 | 
 | ||||||
| 		#ifdef YOSYS_XTRACE_GET_PUT | 		#ifdef YOSYS_XTRACE_GET_PUT | ||||||
|  | @ -198,11 +229,13 @@ namespace RTLIL | ||||||
| 			} | 			} | ||||||
| 		#endif | 		#endif | ||||||
| 
 | 
 | ||||||
| 			log_assert(global_refcount_storage_.at(idx) > 0); | 			int &refcount = global_refcount_storage_[idx]; | ||||||
| 
 | 
 | ||||||
| 			if (--global_refcount_storage_.at(idx) != 0) | 			if (--refcount > 0) | ||||||
| 				return; | 				return; | ||||||
| 
 | 
 | ||||||
|  | 			log_assert(refcount == 0); | ||||||
|  | 
 | ||||||
| 			if (yosys_xtrace) { | 			if (yosys_xtrace) { | ||||||
| 				log("#X# Removed IdString '%s' with index %d.\n", global_id_storage_.at(idx), idx); | 				log("#X# Removed IdString '%s' with index %d.\n", global_id_storage_.at(idx), idx); | ||||||
| 				log_backtrace("-X- ", yosys_xtrace-1); | 				log_backtrace("-X- ", yosys_xtrace-1); | ||||||
|  | @ -213,46 +246,50 @@ namespace RTLIL | ||||||
| 			global_id_storage_.at(idx) = nullptr; | 			global_id_storage_.at(idx) = nullptr; | ||||||
| 			global_free_idx_list_.push_back(idx); | 			global_free_idx_list_.push_back(idx); | ||||||
| 		} | 		} | ||||||
|  | 	#else | ||||||
|  | 		static inline void put_reference(int) { } | ||||||
|  | 	#endif | ||||||
| 
 | 
 | ||||||
| 		// the actual IdString object is just is a single int
 | 		// the actual IdString object is just is a single int
 | ||||||
| 
 | 
 | ||||||
| 		int index_; | 		int index_; | ||||||
| 
 | 
 | ||||||
| 		IdString() : index_(get_reference("")) { } | 		inline IdString() : index_(0) { } | ||||||
| 		IdString(const char *str) : index_(get_reference(str)) { } | 		inline IdString(const char *str) : index_(get_reference(str)) { } | ||||||
| 		IdString(const IdString &str) : index_(get_reference(str.index_)) { } | 		inline IdString(const IdString &str) : index_(get_reference(str.index_)) { } | ||||||
| 		IdString(const std::string &str) : index_(get_reference(str.c_str())) { } | 		inline IdString(IdString &&str) : index_(str.index_) { str.index_ = 0; } | ||||||
| 		~IdString() { put_reference(index_); } | 		inline IdString(const std::string &str) : index_(get_reference(str.c_str())) { } | ||||||
|  | 		inline ~IdString() { put_reference(index_); } | ||||||
| 
 | 
 | ||||||
| 		void operator=(const IdString &rhs) { | 		inline void operator=(const IdString &rhs) { | ||||||
| 			put_reference(index_); | 			put_reference(index_); | ||||||
| 			index_ = get_reference(rhs.index_); | 			index_ = get_reference(rhs.index_); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		void operator=(const char *rhs) { | 		inline void operator=(const char *rhs) { | ||||||
| 			IdString id(rhs); | 			IdString id(rhs); | ||||||
| 			*this = id; | 			*this = id; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		void operator=(const std::string &rhs) { | 		inline void operator=(const std::string &rhs) { | ||||||
| 			IdString id(rhs); | 			IdString id(rhs); | ||||||
| 			*this = id; | 			*this = id; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		const char *c_str() const { | 		inline const char *c_str() const { | ||||||
| 			return global_id_storage_.at(index_); | 			return global_id_storage_.at(index_); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		std::string str() const { | 		inline std::string str() const { | ||||||
| 			return std::string(global_id_storage_.at(index_)); | 			return std::string(global_id_storage_.at(index_)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		bool operator<(const IdString &rhs) const { | 		inline bool operator<(const IdString &rhs) const { | ||||||
| 			return index_ < rhs.index_; | 			return index_ < rhs.index_; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		bool operator==(const IdString &rhs) const { return index_ == rhs.index_; } | 		inline bool operator==(const IdString &rhs) const { return index_ == rhs.index_; } | ||||||
| 		bool operator!=(const IdString &rhs) const { return index_ != rhs.index_; } | 		inline bool operator!=(const IdString &rhs) const { return index_ != rhs.index_; } | ||||||
| 
 | 
 | ||||||
| 		// The methods below are just convenience functions for better compatibility with std::string.
 | 		// The methods below are just convenience functions for better compatibility with std::string.
 | ||||||
| 
 | 
 | ||||||
|  | @ -332,6 +369,14 @@ namespace RTLIL | ||||||
| 		bool in(const pool<IdString> &rhs) const { return rhs.count(*this) != 0; } | 		bool in(const pool<IdString> &rhs) const { return rhs.count(*this) != 0; } | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
|  | 	namespace ID { | ||||||
|  | 		// defined in rtlil.cc, initialized in yosys.cc
 | ||||||
|  | 		extern IdString A, B, Y; | ||||||
|  | 		extern IdString keep; | ||||||
|  | 		extern IdString whitebox; | ||||||
|  | 		extern IdString blackbox; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
| 	static inline std::string escape_id(std::string str) { | 	static inline std::string escape_id(std::string str) { | ||||||
| 		if (str.size() > 0 && str[0] != '\\' && str[0] != '$') | 		if (str.size() > 0 && str[0] != '\\' && str[0] != '$') | ||||||
| 			return "\\" + str; | 			return "\\" + str; | ||||||
|  | @ -604,7 +649,7 @@ struct RTLIL::AttrObject | ||||||
| 	bool get_bool_attribute(RTLIL::IdString id) const; | 	bool get_bool_attribute(RTLIL::IdString id) const; | ||||||
| 
 | 
 | ||||||
| 	bool get_blackbox_attribute(bool ignore_wb=false) const { | 	bool get_blackbox_attribute(bool ignore_wb=false) const { | ||||||
| 		return get_bool_attribute("\\blackbox") || (!ignore_wb && get_bool_attribute("\\whitebox")); | 		return get_bool_attribute(ID::blackbox) || (!ignore_wb && get_bool_attribute(ID::whitebox)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void set_strpool_attribute(RTLIL::IdString id, const pool<string> &data); | 	void set_strpool_attribute(RTLIL::IdString id, const pool<string> &data); | ||||||
|  | @ -1339,8 +1384,8 @@ public: | ||||||
| 	void fixup_parameters(bool set_a_signed = false, bool set_b_signed = false); | 	void fixup_parameters(bool set_a_signed = false, bool set_b_signed = false); | ||||||
| 
 | 
 | ||||||
| 	bool has_keep_attr() const { | 	bool has_keep_attr() const { | ||||||
| 		return get_bool_attribute("\\keep") || (module && module->design && module->design->module(type) && | 		return get_bool_attribute(ID::keep) || (module && module->design && module->design->module(type) && | ||||||
| 				module->design->module(type)->get_bool_attribute("\\keep")); | 				module->design->module(type)->get_bool_attribute(ID::keep)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	template<typename T> void rewrite_sigspecs(T &functor); | 	template<typename T> void rewrite_sigspecs(T &functor); | ||||||
|  |  | ||||||
							
								
								
									
										520
									
								
								kernel/satgen.h
									
										
									
									
									
								
							
							
						
						
									
										520
									
								
								kernel/satgen.h
									
										
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -510,10 +510,13 @@ void yosys_setup() | ||||||
| 	if(already_setup) | 	if(already_setup) | ||||||
| 		return; | 		return; | ||||||
| 	already_setup = true; | 	already_setup = true; | ||||||
| 	// if there are already IdString objects then we have a global initialization order bug
 | 
 | ||||||
| 	IdString empty_id; | 	RTLIL::ID::A = "\\A"; | ||||||
| 	log_assert(empty_id.index_ == 0); | 	RTLIL::ID::B = "\\B"; | ||||||
| 	IdString::get_reference(empty_id.index_); | 	RTLIL::ID::Y = "\\Y"; | ||||||
|  | 	RTLIL::ID::keep = "\\keep"; | ||||||
|  | 	RTLIL::ID::whitebox = "\\whitebox"; | ||||||
|  | 	RTLIL::ID::blackbox = "\\blackbox"; | ||||||
| 
 | 
 | ||||||
| 	#ifdef WITH_PYTHON | 	#ifdef WITH_PYTHON | ||||||
| 		PyImport_AppendInittab((char*)"libyosys", INIT_MODULE); | 		PyImport_AppendInittab((char*)"libyosys", INIT_MODULE); | ||||||
|  | @ -575,9 +578,6 @@ void yosys_shutdown() | ||||||
| #ifdef WITH_PYTHON | #ifdef WITH_PYTHON | ||||||
| 	Py_Finalize(); | 	Py_Finalize(); | ||||||
| #endif | #endif | ||||||
| 
 |  | ||||||
| 	IdString empty_id; |  | ||||||
| 	IdString::put_reference(empty_id.index_); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| RTLIL::IdString new_id(std::string file, int line, std::string func) | RTLIL::IdString new_id(std::string file, int line, std::string func) | ||||||
|  |  | ||||||
|  | @ -305,8 +305,16 @@ RTLIL::IdString new_id(std::string file, int line, std::string func); | ||||||
| #define NEW_ID \ | #define NEW_ID \ | ||||||
| 	YOSYS_NAMESPACE_PREFIX new_id(__FILE__, __LINE__, __FUNCTION__) | 	YOSYS_NAMESPACE_PREFIX new_id(__FILE__, __LINE__, __FUNCTION__) | ||||||
| 
 | 
 | ||||||
| #define ID(_str) \ | // Create a statically allocated IdString object, using for example ID(A) or ID($add).
 | ||||||
| 	([]() { static YOSYS_NAMESPACE_PREFIX RTLIL::IdString _id(_str); return _id; })() | //
 | ||||||
|  | // Recipe for Converting old code that is using conversion of strings like "\\A" and
 | ||||||
|  | // "$add" for creating IdStrings: Run below SED command on the .cc file and then use for
 | ||||||
|  | // example "meld foo.cc foo.cc.orig" to manually compile errors, if necessary.
 | ||||||
|  | //
 | ||||||
|  | //  sed -i.orig -r 's/"\\\\([a-zA-Z0-9_]+)"/ID(\1)/g; s/"(\$[a-zA-Z0-9_]+)"/ID(\1)/g;' <filename>
 | ||||||
|  | //
 | ||||||
|  | #define ID(_id) ([]() { const char *p = "\\" #_id, *q = p[1] == '$' ? p+1 : p; \ | ||||||
|  |         static const YOSYS_NAMESPACE_PREFIX RTLIL::IdString id(q); return id; })() | ||||||
| 
 | 
 | ||||||
| RTLIL::Design *yosys_get_design(); | RTLIL::Design *yosys_get_design(); | ||||||
| std::string proc_self_dirname(); | std::string proc_self_dirname(); | ||||||
|  |  | ||||||
|  | @ -37,22 +37,22 @@ struct ExclusiveDatabase | ||||||
| 		SigBit y_port; | 		SigBit y_port; | ||||||
| 		pool<Cell*> reduce_or; | 		pool<Cell*> reduce_or; | ||||||
| 		for (auto cell : module->cells()) { | 		for (auto cell : module->cells()) { | ||||||
| 			if (cell->type == "$eq") { | 			if (cell->type == ID($eq)) { | ||||||
| 				nonconst_sig = sigmap(cell->getPort("\\A")); | 				nonconst_sig = sigmap(cell->getPort(ID(A))); | ||||||
| 				const_sig = sigmap(cell->getPort("\\B")); | 				const_sig = sigmap(cell->getPort(ID(B))); | ||||||
| 				if (!const_sig.is_fully_const()) { | 				if (!const_sig.is_fully_const()) { | ||||||
| 					if (!nonconst_sig.is_fully_const()) | 					if (!nonconst_sig.is_fully_const()) | ||||||
| 						continue; | 						continue; | ||||||
| 					std::swap(nonconst_sig, const_sig); | 					std::swap(nonconst_sig, const_sig); | ||||||
| 				} | 				} | ||||||
| 				y_port = sigmap(cell->getPort("\\Y")); | 				y_port = sigmap(cell->getPort(ID(Y))); | ||||||
| 			} | 			} | ||||||
| 			else if (cell->type == "$logic_not") { | 			else if (cell->type == ID($logic_not)) { | ||||||
| 				nonconst_sig = sigmap(cell->getPort("\\A")); | 				nonconst_sig = sigmap(cell->getPort(ID(A))); | ||||||
| 				const_sig = Const(State::S0, GetSize(nonconst_sig)); | 				const_sig = Const(State::S0, GetSize(nonconst_sig)); | ||||||
| 				y_port = sigmap(cell->getPort("\\Y")); | 				y_port = sigmap(cell->getPort(ID(Y))); | ||||||
| 			} | 			} | ||||||
| 			else if (cell->type == "$reduce_or") { | 			else if (cell->type == ID($reduce_or)) { | ||||||
| 				reduce_or.insert(cell); | 				reduce_or.insert(cell); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|  | @ -66,7 +66,7 @@ struct ExclusiveDatabase | ||||||
| 		for (auto cell : reduce_or) { | 		for (auto cell : reduce_or) { | ||||||
| 			nonconst_sig = SigSpec(); | 			nonconst_sig = SigSpec(); | ||||||
| 			std::vector<Const> values; | 			std::vector<Const> values; | ||||||
| 			SigSpec a_port = sigmap(cell->getPort("\\A")); | 			SigSpec a_port = sigmap(cell->getPort(ID(A))); | ||||||
| 			for (auto bit : a_port) { | 			for (auto bit : a_port) { | ||||||
| 				auto it = sig_cmp_prev.find(bit); | 				auto it = sig_cmp_prev.find(bit); | ||||||
| 				if (it == sig_cmp_prev.end()) { | 				if (it == sig_cmp_prev.end()) { | ||||||
|  | @ -84,7 +84,7 @@ struct ExclusiveDatabase | ||||||
| 			} | 			} | ||||||
| 			if (nonconst_sig.empty()) | 			if (nonconst_sig.empty()) | ||||||
| 				continue; | 				continue; | ||||||
| 			y_port = sigmap(cell->getPort("\\Y")); | 			y_port = sigmap(cell->getPort(ID(Y))); | ||||||
| 			sig_cmp_prev[y_port] = std::make_pair(nonconst_sig,std::move(values)); | 			sig_cmp_prev[y_port] = std::make_pair(nonconst_sig,std::move(values)); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -135,7 +135,7 @@ struct MuxpackWorker | ||||||
| 	{ | 	{ | ||||||
| 		for (auto wire : module->wires()) | 		for (auto wire : module->wires()) | ||||||
| 		{ | 		{ | ||||||
| 			if (wire->port_output || wire->get_bool_attribute("\\keep")) { | 			if (wire->port_output || wire->get_bool_attribute(ID(keep))) { | ||||||
| 				for (auto bit : sigmap(wire)) | 				for (auto bit : sigmap(wire)) | ||||||
| 					sigbit_with_non_chain_users.insert(bit); | 					sigbit_with_non_chain_users.insert(bit); | ||||||
| 			} | 			} | ||||||
|  | @ -143,13 +143,13 @@ struct MuxpackWorker | ||||||
| 
 | 
 | ||||||
| 		for (auto cell : module->cells()) | 		for (auto cell : module->cells()) | ||||||
| 		{ | 		{ | ||||||
| 			if (cell->type.in("$mux", "$pmux") && !cell->get_bool_attribute("\\keep")) | 			if (cell->type.in(ID($mux), ID($pmux)) && !cell->get_bool_attribute(ID(keep))) | ||||||
| 			{ | 			{ | ||||||
| 				SigSpec a_sig = sigmap(cell->getPort("\\A")); | 				SigSpec a_sig = sigmap(cell->getPort(ID(A))); | ||||||
| 				SigSpec b_sig; | 				SigSpec b_sig; | ||||||
| 				if (cell->type == "$mux") | 				if (cell->type == ID($mux)) | ||||||
| 					b_sig = sigmap(cell->getPort("\\B")); | 					b_sig = sigmap(cell->getPort(ID(B))); | ||||||
| 				SigSpec y_sig = sigmap(cell->getPort("\\Y")); | 				SigSpec y_sig = sigmap(cell->getPort(ID(Y))); | ||||||
|     |     | ||||||
| 				if (sig_chain_next.count(a_sig)) | 				if (sig_chain_next.count(a_sig)) | ||||||
| 					for (auto a_bit : a_sig.bits()) | 					for (auto a_bit : a_sig.bits()) | ||||||
|  | @ -186,16 +186,16 @@ struct MuxpackWorker | ||||||
| 		{ | 		{ | ||||||
| 			log_debug("Considering %s (%s)\n", log_id(cell), log_id(cell->type)); | 			log_debug("Considering %s (%s)\n", log_id(cell), log_id(cell->type)); | ||||||
| 
 | 
 | ||||||
| 			SigSpec a_sig = sigmap(cell->getPort("\\A")); | 			SigSpec a_sig = sigmap(cell->getPort(ID(A))); | ||||||
| 			if (cell->type == "$mux") { | 			if (cell->type == ID($mux)) { | ||||||
| 				SigSpec b_sig = sigmap(cell->getPort("\\B")); | 				SigSpec b_sig = sigmap(cell->getPort(ID(B))); | ||||||
| 				if (sig_chain_prev.count(a_sig) + sig_chain_prev.count(b_sig) != 1) | 				if (sig_chain_prev.count(a_sig) + sig_chain_prev.count(b_sig) != 1) | ||||||
| 					goto start_cell; | 					goto start_cell; | ||||||
| 
 | 
 | ||||||
| 				if (!sig_chain_prev.count(a_sig)) | 				if (!sig_chain_prev.count(a_sig)) | ||||||
| 					a_sig = b_sig; | 					a_sig = b_sig; | ||||||
| 			} | 			} | ||||||
| 			else if (cell->type == "$pmux") { | 			else if (cell->type == ID($pmux)) { | ||||||
| 				if (!sig_chain_prev.count(a_sig)) | 				if (!sig_chain_prev.count(a_sig)) | ||||||
| 					goto start_cell; | 					goto start_cell; | ||||||
| 			} | 			} | ||||||
|  | @ -208,8 +208,8 @@ struct MuxpackWorker | ||||||
| 			{ | 			{ | ||||||
| 				Cell *prev_cell = sig_chain_prev.at(a_sig); | 				Cell *prev_cell = sig_chain_prev.at(a_sig); | ||||||
| 				log_assert(prev_cell); | 				log_assert(prev_cell); | ||||||
| 				SigSpec s_sig = sigmap(cell->getPort("\\S")); | 				SigSpec s_sig = sigmap(cell->getPort(ID(S))); | ||||||
| 				s_sig.append(sigmap(prev_cell->getPort("\\S"))); | 				s_sig.append(sigmap(prev_cell->getPort(ID(S)))); | ||||||
| 				if (!excl_db.query(s_sig)) | 				if (!excl_db.query(s_sig)) | ||||||
| 					goto start_cell; | 					goto start_cell; | ||||||
| 			} | 			} | ||||||
|  | @ -230,7 +230,7 @@ struct MuxpackWorker | ||||||
| 		{ | 		{ | ||||||
| 			chain.push_back(c); | 			chain.push_back(c); | ||||||
| 
 | 
 | ||||||
| 			SigSpec y_sig = sigmap(c->getPort("\\Y")); | 			SigSpec y_sig = sigmap(c->getPort(ID(Y))); | ||||||
| 
 | 
 | ||||||
| 			if (sig_chain_next.count(y_sig) == 0) | 			if (sig_chain_next.count(y_sig) == 0) | ||||||
| 				break; | 				break; | ||||||
|  | @ -269,29 +269,29 @@ struct MuxpackWorker | ||||||
| 			mux_count += cases; | 			mux_count += cases; | ||||||
| 			pmux_count += 1; | 			pmux_count += 1; | ||||||
| 
 | 
 | ||||||
| 			first_cell->type = "$pmux"; | 			first_cell->type = ID($pmux); | ||||||
| 			SigSpec b_sig = first_cell->getPort("\\B"); | 			SigSpec b_sig = first_cell->getPort(ID(B)); | ||||||
| 			SigSpec s_sig = first_cell->getPort("\\S"); | 			SigSpec s_sig = first_cell->getPort(ID(S)); | ||||||
| 
 | 
 | ||||||
| 			for (int i = 1; i < cases; i++) { | 			for (int i = 1; i < cases; i++) { | ||||||
| 				Cell* prev_cell = chain[cursor+i-1]; | 				Cell* prev_cell = chain[cursor+i-1]; | ||||||
| 				Cell* cursor_cell = chain[cursor+i]; | 				Cell* cursor_cell = chain[cursor+i]; | ||||||
| 				if (sigmap(prev_cell->getPort("\\Y")) == sigmap(cursor_cell->getPort("\\A"))) { | 				if (sigmap(prev_cell->getPort(ID(Y))) == sigmap(cursor_cell->getPort(ID(A)))) { | ||||||
| 					b_sig.append(cursor_cell->getPort("\\B")); | 					b_sig.append(cursor_cell->getPort(ID(B))); | ||||||
| 					s_sig.append(cursor_cell->getPort("\\S")); | 					s_sig.append(cursor_cell->getPort(ID(S))); | ||||||
| 				} | 				} | ||||||
| 				else { | 				else { | ||||||
| 					log_assert(cursor_cell->type == "$mux"); | 					log_assert(cursor_cell->type == ID($mux)); | ||||||
| 					b_sig.append(cursor_cell->getPort("\\A")); | 					b_sig.append(cursor_cell->getPort(ID(A))); | ||||||
| 					s_sig.append(module->LogicNot(NEW_ID, cursor_cell->getPort("\\S"))); | 					s_sig.append(module->LogicNot(NEW_ID, cursor_cell->getPort(ID(S)))); | ||||||
| 				} | 				} | ||||||
| 				remove_cells.insert(cursor_cell); | 				remove_cells.insert(cursor_cell); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			first_cell->setPort("\\B", b_sig); | 			first_cell->setPort(ID(B), b_sig); | ||||||
| 			first_cell->setPort("\\S", s_sig); | 			first_cell->setPort(ID(S), s_sig); | ||||||
| 			first_cell->setParam("\\S_WIDTH", GetSize(s_sig)); | 			first_cell->setParam(ID(S_WIDTH), GetSize(s_sig)); | ||||||
| 			first_cell->setPort("\\Y", last_cell->getPort("\\Y")); | 			first_cell->setPort(ID(Y), last_cell->getPort(ID(Y))); | ||||||
| 
 | 
 | ||||||
| 			cursor += cases; | 			cursor += cases; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -52,7 +52,7 @@ struct keep_cache_t | ||||||
| 			return cache.at(module); | 			return cache.at(module); | ||||||
| 
 | 
 | ||||||
| 		cache[module] = true; | 		cache[module] = true; | ||||||
| 		if (!module->get_bool_attribute("\\keep")) { | 		if (!module->get_bool_attribute(ID(keep))) { | ||||||
| 			bool found_keep = false; | 			bool found_keep = false; | ||||||
| 			for (auto cell : module->cells()) | 			for (auto cell : module->cells()) | ||||||
| 				if (query(cell)) found_keep = true; | 				if (query(cell)) found_keep = true; | ||||||
|  | @ -64,7 +64,7 @@ struct keep_cache_t | ||||||
| 
 | 
 | ||||||
| 	bool query(Cell *cell) | 	bool query(Cell *cell) | ||||||
| 	{ | 	{ | ||||||
| 		if (cell->type.in("$memwr", "$meminit", "$assert", "$assume", "$live", "$fair", "$cover", "$specify2", "$specify3", "$specrule")) | 		if (cell->type.in(ID($memwr), ID($meminit), ID($assert), ID($assume), ID($live), ID($fair), ID($cover), ID($specify2), ID($specify3), ID($specrule))) | ||||||
| 			return true; | 			return true; | ||||||
| 
 | 
 | ||||||
| 		if (cell->has_keep_attr()) | 		if (cell->has_keep_attr()) | ||||||
|  | @ -122,7 +122,7 @@ void rmunused_module_cells(Module *module, bool verbose) | ||||||
| 
 | 
 | ||||||
| 	for (auto &it : module->wires_) { | 	for (auto &it : module->wires_) { | ||||||
| 		Wire *wire = it.second; | 		Wire *wire = it.second; | ||||||
| 		if (wire->port_output || wire->get_bool_attribute("\\keep")) { | 		if (wire->port_output || wire->get_bool_attribute(ID(keep))) { | ||||||
| 			for (auto bit : sigmap(wire)) | 			for (auto bit : sigmap(wire)) | ||||||
| 			for (auto c : wire2driver[bit]) | 			for (auto c : wire2driver[bit]) | ||||||
| 				queue.insert(c), unused.erase(c); | 				queue.insert(c), unused.erase(c); | ||||||
|  | @ -177,8 +177,8 @@ void rmunused_module_cells(Module *module, bool verbose) | ||||||
| int count_nontrivial_wire_attrs(RTLIL::Wire *w) | int count_nontrivial_wire_attrs(RTLIL::Wire *w) | ||||||
| { | { | ||||||
| 	int count = w->attributes.size(); | 	int count = w->attributes.size(); | ||||||
| 	count -= w->attributes.count("\\src"); | 	count -= w->attributes.count(ID(src)); | ||||||
| 	count -= w->attributes.count("\\unused_bits"); | 	count -= w->attributes.count(ID(unused_bits)); | ||||||
| 	return count; | 	return count; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -297,7 +297,7 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos | ||||||
| 			if (!wire->port_input) | 			if (!wire->port_input) | ||||||
| 				used_signals_nodrivers.add(sig); | 				used_signals_nodrivers.add(sig); | ||||||
| 		} | 		} | ||||||
| 		if (wire->get_bool_attribute("\\keep")) { | 		if (wire->get_bool_attribute(ID(keep))) { | ||||||
| 			RTLIL::SigSpec sig = RTLIL::SigSpec(wire); | 			RTLIL::SigSpec sig = RTLIL::SigSpec(wire); | ||||||
| 			assign_map.apply(sig); | 			assign_map.apply(sig); | ||||||
| 			used_signals.add(sig); | 			used_signals.add(sig); | ||||||
|  | @ -311,19 +311,19 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos | ||||||
| 		log_assert(GetSize(s1) == GetSize(s2)); | 		log_assert(GetSize(s1) == GetSize(s2)); | ||||||
| 
 | 
 | ||||||
| 		Const initval; | 		Const initval; | ||||||
| 		if (wire->attributes.count("\\init")) | 		if (wire->attributes.count(ID(init))) | ||||||
| 			initval = wire->attributes.at("\\init"); | 			initval = wire->attributes.at(ID(init)); | ||||||
| 		if (GetSize(initval) != GetSize(wire)) | 		if (GetSize(initval) != GetSize(wire)) | ||||||
| 			initval.bits.resize(GetSize(wire), State::Sx); | 			initval.bits.resize(GetSize(wire), State::Sx); | ||||||
| 		if (initval.is_fully_undef()) | 		if (initval.is_fully_undef()) | ||||||
| 			wire->attributes.erase("\\init"); | 			wire->attributes.erase(ID(init)); | ||||||
| 
 | 
 | ||||||
| 		if (GetSize(wire) == 0) { | 		if (GetSize(wire) == 0) { | ||||||
| 			// delete zero-width wires, unless they are module ports
 | 			// delete zero-width wires, unless they are module ports
 | ||||||
| 			if (wire->port_id == 0) | 			if (wire->port_id == 0) | ||||||
| 				goto delete_this_wire; | 				goto delete_this_wire; | ||||||
| 		} else | 		} else | ||||||
| 		if (wire->port_id != 0 || wire->get_bool_attribute("\\keep") || !initval.is_fully_undef()) { | 		if (wire->port_id != 0 || wire->get_bool_attribute(ID(keep)) || !initval.is_fully_undef()) { | ||||||
| 			// do not delete anything with "keep" or module ports or initialized wires
 | 			// do not delete anything with "keep" or module ports or initialized wires
 | ||||||
| 		} else | 		} else | ||||||
| 		if (!purge_mode && check_public_name(wire->name) && (raw_used_signals.check_any(s1) || used_signals.check_any(s2) || s1 != s2)) { | 		if (!purge_mode && check_public_name(wire->name) && (raw_used_signals.check_any(s1) || used_signals.check_any(s2) || s1 != s2)) { | ||||||
|  | @ -357,9 +357,9 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos | ||||||
| 				} | 				} | ||||||
| 			if (new_conn.first.size() > 0) { | 			if (new_conn.first.size() > 0) { | ||||||
| 				if (initval.is_fully_undef()) | 				if (initval.is_fully_undef()) | ||||||
| 					wire->attributes.erase("\\init"); | 					wire->attributes.erase(ID(init)); | ||||||
| 				else | 				else | ||||||
| 					wire->attributes.at("\\init") = initval; | 					wire->attributes.at(ID(init)) = initval; | ||||||
| 				used_signals.add(new_conn.first); | 				used_signals.add(new_conn.first); | ||||||
| 				used_signals.add(new_conn.second); | 				used_signals.add(new_conn.second); | ||||||
| 				module->connect(new_conn); | 				module->connect(new_conn); | ||||||
|  | @ -377,11 +377,11 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				if (unused_bits.empty() || wire->port_id != 0) | 				if (unused_bits.empty() || wire->port_id != 0) | ||||||
| 					wire->attributes.erase("\\unused_bits"); | 					wire->attributes.erase(ID(unused_bits)); | ||||||
| 				else | 				else | ||||||
| 					wire->attributes["\\unused_bits"] = RTLIL::Const(unused_bits); | 					wire->attributes[ID(unused_bits)] = RTLIL::Const(unused_bits); | ||||||
| 			} else { | 			} else { | ||||||
| 				wire->attributes.erase("\\unused_bits"); | 				wire->attributes.erase(ID(unused_bits)); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -413,18 +413,18 @@ bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose) | ||||||
| 	dict<SigBit, State> qbits; | 	dict<SigBit, State> qbits; | ||||||
| 
 | 
 | ||||||
| 	for (auto cell : module->cells()) | 	for (auto cell : module->cells()) | ||||||
| 		if (fftypes.cell_known(cell->type) && cell->hasPort("\\Q")) | 		if (fftypes.cell_known(cell->type) && cell->hasPort(ID(Q))) | ||||||
| 		{ | 		{ | ||||||
| 			SigSpec sig = cell->getPort("\\Q"); | 			SigSpec sig = cell->getPort(ID(Q)); | ||||||
| 
 | 
 | ||||||
| 			for (int i = 0; i < GetSize(sig); i++) | 			for (int i = 0; i < GetSize(sig); i++) | ||||||
| 			{ | 			{ | ||||||
| 				SigBit bit = sig[i]; | 				SigBit bit = sig[i]; | ||||||
| 
 | 
 | ||||||
| 				if (bit.wire == nullptr || bit.wire->attributes.count("\\init") == 0) | 				if (bit.wire == nullptr || bit.wire->attributes.count(ID(init)) == 0) | ||||||
| 					continue; | 					continue; | ||||||
| 
 | 
 | ||||||
| 				Const init = bit.wire->attributes.at("\\init"); | 				Const init = bit.wire->attributes.at(ID(init)); | ||||||
| 
 | 
 | ||||||
| 				if (i >= GetSize(init) || init[i] == State::Sx || init[i] == State::Sz) | 				if (i >= GetSize(init) || init[i] == State::Sx || init[i] == State::Sz) | ||||||
| 					continue; | 					continue; | ||||||
|  | @ -439,10 +439,10 @@ bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose) | ||||||
| 		if (!purge_mode && wire->name[0] == '\\') | 		if (!purge_mode && wire->name[0] == '\\') | ||||||
| 			continue; | 			continue; | ||||||
| 
 | 
 | ||||||
| 		if (wire->attributes.count("\\init") == 0) | 		if (wire->attributes.count(ID(init)) == 0) | ||||||
| 			continue; | 			continue; | ||||||
| 
 | 
 | ||||||
| 		Const init = wire->attributes.at("\\init"); | 		Const init = wire->attributes.at(ID(init)); | ||||||
| 
 | 
 | ||||||
| 		for (int i = 0; i < GetSize(wire) && i < GetSize(init); i++) | 		for (int i = 0; i < GetSize(wire) && i < GetSize(init); i++) | ||||||
| 		{ | 		{ | ||||||
|  | @ -465,7 +465,7 @@ bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose) | ||||||
| 		if (verbose) | 		if (verbose) | ||||||
| 			log_debug("  removing redundant init attribute on %s.\n", log_id(wire)); | 			log_debug("  removing redundant init attribute on %s.\n", log_id(wire)); | ||||||
| 
 | 
 | ||||||
| 		wire->attributes.erase("\\init"); | 		wire->attributes.erase(ID(init)); | ||||||
| 		did_something = true; | 		did_something = true; | ||||||
| 	next_wire:; | 	next_wire:; | ||||||
| 	} | 	} | ||||||
|  | @ -480,10 +480,10 @@ void rmunused_module(RTLIL::Module *module, bool purge_mode, bool verbose, bool | ||||||
| 
 | 
 | ||||||
| 	std::vector<RTLIL::Cell*> delcells; | 	std::vector<RTLIL::Cell*> delcells; | ||||||
| 	for (auto cell : module->cells()) | 	for (auto cell : module->cells()) | ||||||
| 		if (cell->type.in("$pos", "$_BUF_") && !cell->has_keep_attr()) { | 		if (cell->type.in(ID($pos), ID($_BUF_)) && !cell->has_keep_attr()) { | ||||||
| 			bool is_signed = cell->type == "$pos" && cell->getParam("\\A_SIGNED").as_bool(); | 			bool is_signed = cell->type == ID($pos) && cell->getParam(ID(A_SIGNED)).as_bool(); | ||||||
| 			RTLIL::SigSpec a = cell->getPort("\\A"); | 			RTLIL::SigSpec a = cell->getPort(ID(A)); | ||||||
| 			RTLIL::SigSpec y = cell->getPort("\\Y"); | 			RTLIL::SigSpec y = cell->getPort(ID(Y)); | ||||||
| 			a.extend_u0(GetSize(y), is_signed); | 			a.extend_u0(GetSize(y), is_signed); | ||||||
| 			module->connect(y, a); | 			module->connect(y, a); | ||||||
| 			delcells.push_back(cell); | 			delcells.push_back(cell); | ||||||
|  | @ -491,7 +491,7 @@ void rmunused_module(RTLIL::Module *module, bool purge_mode, bool verbose, bool | ||||||
| 	for (auto cell : delcells) { | 	for (auto cell : delcells) { | ||||||
| 		if (verbose) | 		if (verbose) | ||||||
| 			log_debug("  removing buffer cell `%s': %s = %s\n", cell->name.c_str(), | 			log_debug("  removing buffer cell `%s': %s = %s\n", cell->name.c_str(), | ||||||
| 					log_signal(cell->getPort("\\Y")), log_signal(cell->getPort("\\A"))); | 					log_signal(cell->getPort(ID(Y))), log_signal(cell->getPort(ID(A)))); | ||||||
| 		module->remove(cell); | 		module->remove(cell); | ||||||
| 	} | 	} | ||||||
| 	if (!delcells.empty()) | 	if (!delcells.empty()) | ||||||
|  |  | ||||||
|  | @ -35,10 +35,10 @@ void demorgan_worker( | ||||||
| 	//TODO: Add support for reduce_xor
 | 	//TODO: Add support for reduce_xor
 | ||||||
| 	//DeMorgan of XOR is either XOR (if even number of inputs) or XNOR (if odd number)
 | 	//DeMorgan of XOR is either XOR (if even number of inputs) or XNOR (if odd number)
 | ||||||
| 
 | 
 | ||||||
| 	if( (cell->type != "$reduce_and") && (cell->type != "$reduce_or") ) | 	if( (cell->type != ID($reduce_and)) && (cell->type != ID($reduce_or)) ) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
| 	auto insig = sigmap(cell->getPort("\\A")); | 	auto insig = sigmap(cell->getPort(ID(A))); | ||||||
| 	log("Inspecting %s cell %s (%d inputs)\n", log_id(cell->type), log_id(cell->name), GetSize(insig)); | 	log("Inspecting %s cell %s (%d inputs)\n", log_id(cell->type), log_id(cell->name), GetSize(insig)); | ||||||
| 	int num_inverted = 0; | 	int num_inverted = 0; | ||||||
| 	for(int i=0; i<GetSize(insig); i++) | 	for(int i=0; i<GetSize(insig); i++) | ||||||
|  | @ -51,7 +51,7 @@ void demorgan_worker( | ||||||
| 		bool inverted = false; | 		bool inverted = false; | ||||||
| 		for(auto x : ports) | 		for(auto x : ports) | ||||||
| 		{ | 		{ | ||||||
| 			if(x.port == "\\Y" && x.cell->type == "$_NOT_") | 			if(x.port == ID(Y) && x.cell->type == ID($_NOT_)) | ||||||
| 			{ | 			{ | ||||||
| 				inverted = true; | 				inverted = true; | ||||||
| 				break; | 				break; | ||||||
|  | @ -85,7 +85,7 @@ void demorgan_worker( | ||||||
| 		RTLIL::Cell* srcinv = NULL; | 		RTLIL::Cell* srcinv = NULL; | ||||||
| 		for(auto x : ports) | 		for(auto x : ports) | ||||||
| 		{ | 		{ | ||||||
| 			if(x.port == "\\Y" && x.cell->type == "$_NOT_") | 			if(x.port == ID(Y) && x.cell->type == ID($_NOT_)) | ||||||
| 			{ | 			{ | ||||||
| 				srcinv = x.cell; | 				srcinv = x.cell; | ||||||
| 				break; | 				break; | ||||||
|  | @ -103,7 +103,7 @@ void demorgan_worker( | ||||||
| 		//We ARE inverted - bypass it
 | 		//We ARE inverted - bypass it
 | ||||||
| 		//Don't automatically delete the inverter since other stuff might still use it
 | 		//Don't automatically delete the inverter since other stuff might still use it
 | ||||||
| 		else | 		else | ||||||
| 			insig[i] = srcinv->getPort("\\A"); | 			insig[i] = srcinv->getPort(ID(A)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	//Cosmetic fixup: If our input is just a scrambled version of one bus, rearrange it
 | 	//Cosmetic fixup: If our input is just a scrambled version of one bus, rearrange it
 | ||||||
|  | @ -151,20 +151,20 @@ void demorgan_worker( | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	//Push the new input signal back to the reduction (after bypassing/adding inverters)
 | 	//Push the new input signal back to the reduction (after bypassing/adding inverters)
 | ||||||
| 	cell->setPort("\\A", insig); | 	cell->setPort(ID(A), insig); | ||||||
| 
 | 
 | ||||||
| 	//Change the cell type
 | 	//Change the cell type
 | ||||||
| 	if(cell->type == "$reduce_and") | 	if(cell->type == ID($reduce_and)) | ||||||
| 		cell->type = "$reduce_or"; | 		cell->type = ID($reduce_or); | ||||||
| 	else if(cell->type == "$reduce_or") | 	else if(cell->type == ID($reduce_or)) | ||||||
| 		cell->type = "$reduce_and"; | 		cell->type = ID($reduce_and); | ||||||
| 	//don't change XOR
 | 	//don't change XOR
 | ||||||
| 
 | 
 | ||||||
| 	//Add an inverter to the output
 | 	//Add an inverter to the output
 | ||||||
| 	auto inverted_output = cell->getPort("\\Y"); | 	auto inverted_output = cell->getPort(ID(Y)); | ||||||
| 	auto uninverted_output = m->addWire(NEW_ID); | 	auto uninverted_output = m->addWire(NEW_ID); | ||||||
| 	m->addNot(NEW_ID, RTLIL::SigSpec(uninverted_output), inverted_output); | 	m->addNot(NEW_ID, RTLIL::SigSpec(uninverted_output), inverted_output); | ||||||
| 	cell->setPort("\\Y", uninverted_output); | 	cell->setPort(ID(Y), uninverted_output); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct OptDemorganPass : public Pass { | struct OptDemorganPass : public Pass { | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -40,9 +40,9 @@ struct OptLutWorker | ||||||
| 
 | 
 | ||||||
| 	bool evaluate_lut(RTLIL::Cell *lut, dict<SigBit, bool> inputs) | 	bool evaluate_lut(RTLIL::Cell *lut, dict<SigBit, bool> inputs) | ||||||
| 	{ | 	{ | ||||||
| 		SigSpec lut_input = sigmap(lut->getPort("\\A")); | 		SigSpec lut_input = sigmap(lut->getPort(ID(A))); | ||||||
| 		int lut_width = lut->getParam("\\WIDTH").as_int(); | 		int lut_width = lut->getParam(ID(WIDTH)).as_int(); | ||||||
| 		Const lut_table = lut->getParam("\\LUT"); | 		Const lut_table = lut->getParam(ID(LUT)); | ||||||
| 		int lut_index = 0; | 		int lut_index = 0; | ||||||
| 
 | 
 | ||||||
| 		for (int i = 0; i < lut_width; i++) | 		for (int i = 0; i < lut_width; i++) | ||||||
|  | @ -99,16 +99,16 @@ struct OptLutWorker | ||||||
| 		log("Discovering LUTs.\n"); | 		log("Discovering LUTs.\n"); | ||||||
| 		for (auto cell : module->selected_cells()) | 		for (auto cell : module->selected_cells()) | ||||||
| 		{ | 		{ | ||||||
| 			if (cell->type == "$lut") | 			if (cell->type == ID($lut)) | ||||||
| 			{ | 			{ | ||||||
| 				if (cell->has_keep_attr()) | 				if (cell->has_keep_attr()) | ||||||
| 					continue; | 					continue; | ||||||
| 				SigBit lut_output = cell->getPort("\\Y"); | 				SigBit lut_output = cell->getPort(ID(Y)); | ||||||
| 				if (lut_output.wire->get_bool_attribute("\\keep")) | 				if (lut_output.wire->get_bool_attribute(ID(keep))) | ||||||
| 					continue; | 					continue; | ||||||
| 
 | 
 | ||||||
| 				int lut_width = cell->getParam("\\WIDTH").as_int(); | 				int lut_width = cell->getParam(ID(WIDTH)).as_int(); | ||||||
| 				SigSpec lut_input = cell->getPort("\\A"); | 				SigSpec lut_input = cell->getPort(ID(A)); | ||||||
| 				int lut_arity = 0; | 				int lut_arity = 0; | ||||||
| 
 | 
 | ||||||
| 				log_debug("Found $lut\\WIDTH=%d cell %s.%s.\n", lut_width, log_id(module), log_id(cell)); | 				log_debug("Found $lut\\WIDTH=%d cell %s.%s.\n", lut_width, log_id(module), log_id(cell)); | ||||||
|  | @ -205,7 +205,7 @@ struct OptLutWorker | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			auto lut = worklist.pop(); | 			auto lut = worklist.pop(); | ||||||
| 			SigSpec lut_input = sigmap(lut->getPort("\\A")); | 			SigSpec lut_input = sigmap(lut->getPort(ID(A))); | ||||||
| 			pool<int> &lut_dlogic_inputs = luts_dlogic_inputs[lut]; | 			pool<int> &lut_dlogic_inputs = luts_dlogic_inputs[lut]; | ||||||
| 
 | 
 | ||||||
| 			vector<SigBit> lut_inputs; | 			vector<SigBit> lut_inputs; | ||||||
|  | @ -267,7 +267,7 @@ struct OptLutWorker | ||||||
| 					log_debug("  Not eliminating cell (connected to dedicated logic).\n"); | 					log_debug("  Not eliminating cell (connected to dedicated logic).\n"); | ||||||
| 				else | 				else | ||||||
| 				{ | 				{ | ||||||
| 					SigSpec lut_output = lut->getPort("\\Y"); | 					SigSpec lut_output = lut->getPort(ID(Y)); | ||||||
| 					for (auto &port : index.query_ports(lut_output)) | 					for (auto &port : index.query_ports(lut_output)) | ||||||
| 					{ | 					{ | ||||||
| 						if (port.cell != lut && luts.count(port.cell)) | 						if (port.cell != lut && luts.count(port.cell)) | ||||||
|  | @ -303,13 +303,13 @@ struct OptLutWorker | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			auto lutA = worklist.pop(); | 			auto lutA = worklist.pop(); | ||||||
| 			SigSpec lutA_input = sigmap(lutA->getPort("\\A")); | 			SigSpec lutA_input = sigmap(lutA->getPort(ID(A))); | ||||||
| 			SigSpec lutA_output = sigmap(lutA->getPort("\\Y")[0]); | 			SigSpec lutA_output = sigmap(lutA->getPort(ID(Y))[0]); | ||||||
| 			int lutA_width = lutA->getParam("\\WIDTH").as_int(); | 			int lutA_width = lutA->getParam(ID(WIDTH)).as_int(); | ||||||
| 			int lutA_arity = luts_arity[lutA]; | 			int lutA_arity = luts_arity[lutA]; | ||||||
| 			pool<int> &lutA_dlogic_inputs = luts_dlogic_inputs[lutA]; | 			pool<int> &lutA_dlogic_inputs = luts_dlogic_inputs[lutA]; | ||||||
| 
 | 
 | ||||||
| 			auto lutA_output_ports = index.query_ports(lutA->getPort("\\Y")); | 			auto lutA_output_ports = index.query_ports(lutA->getPort(ID(Y))); | ||||||
| 			if (lutA_output_ports.size() != 2) | 			if (lutA_output_ports.size() != 2) | ||||||
| 				continue; | 				continue; | ||||||
| 
 | 
 | ||||||
|  | @ -321,15 +321,15 @@ struct OptLutWorker | ||||||
| 				if (luts.count(port.cell)) | 				if (luts.count(port.cell)) | ||||||
| 				{ | 				{ | ||||||
| 					auto lutB = port.cell; | 					auto lutB = port.cell; | ||||||
| 					SigSpec lutB_input = sigmap(lutB->getPort("\\A")); | 					SigSpec lutB_input = sigmap(lutB->getPort(ID(A))); | ||||||
| 					SigSpec lutB_output = sigmap(lutB->getPort("\\Y")[0]); | 					SigSpec lutB_output = sigmap(lutB->getPort(ID(Y))[0]); | ||||||
| 					int lutB_width = lutB->getParam("\\WIDTH").as_int(); | 					int lutB_width = lutB->getParam(ID(WIDTH)).as_int(); | ||||||
| 					int lutB_arity = luts_arity[lutB]; | 					int lutB_arity = luts_arity[lutB]; | ||||||
| 					pool<int> &lutB_dlogic_inputs = luts_dlogic_inputs[lutB]; | 					pool<int> &lutB_dlogic_inputs = luts_dlogic_inputs[lutB]; | ||||||
| 
 | 
 | ||||||
| 					log_debug("Found %s.%s (cell A) feeding %s.%s (cell B).\n", log_id(module), log_id(lutA), log_id(module), log_id(lutB)); | 					log_debug("Found %s.%s (cell A) feeding %s.%s (cell B).\n", log_id(module), log_id(lutA), log_id(module), log_id(lutB)); | ||||||
| 
 | 
 | ||||||
| 					if (index.query_is_output(lutA->getPort("\\Y"))) | 					if (index.query_is_output(lutA->getPort(ID(Y)))) | ||||||
| 					{ | 					{ | ||||||
| 						log_debug("  Not combining LUTs (cascade connection feeds module output).\n"); | 						log_debug("  Not combining LUTs (cascade connection feeds module output).\n"); | ||||||
| 						continue; | 						continue; | ||||||
|  | @ -372,7 +372,7 @@ struct OptLutWorker | ||||||
| 						log_debug("  Not combining LUTs into cell A (combined LUT wider than cell A).\n"); | 						log_debug("  Not combining LUTs into cell A (combined LUT wider than cell A).\n"); | ||||||
| 					else if (lutB_dlogic_inputs.size() > 0) | 					else if (lutB_dlogic_inputs.size() > 0) | ||||||
| 						log_debug("  Not combining LUTs into cell A (cell B is connected to dedicated logic).\n"); | 						log_debug("  Not combining LUTs into cell A (cell B is connected to dedicated logic).\n"); | ||||||
| 					else if (lutB->get_bool_attribute("\\lut_keep")) | 					else if (lutB->get_bool_attribute(ID(lut_keep))) | ||||||
| 						log_debug("  Not combining LUTs into cell A (cell B has attribute \\lut_keep).\n"); | 						log_debug("  Not combining LUTs into cell A (cell B has attribute \\lut_keep).\n"); | ||||||
| 					else | 					else | ||||||
| 						combine_mask |= COMBINE_A; | 						combine_mask |= COMBINE_A; | ||||||
|  | @ -380,7 +380,7 @@ struct OptLutWorker | ||||||
| 						log_debug("  Not combining LUTs into cell B (combined LUT wider than cell B).\n"); | 						log_debug("  Not combining LUTs into cell B (combined LUT wider than cell B).\n"); | ||||||
| 					else if (lutA_dlogic_inputs.size() > 0) | 					else if (lutA_dlogic_inputs.size() > 0) | ||||||
| 						log_debug("  Not combining LUTs into cell B (cell A is connected to dedicated logic).\n"); | 						log_debug("  Not combining LUTs into cell B (cell A is connected to dedicated logic).\n"); | ||||||
| 					else if (lutA->get_bool_attribute("\\lut_keep")) | 					else if (lutA->get_bool_attribute(ID(lut_keep))) | ||||||
| 						log_debug("  Not combining LUTs into cell B (cell A has attribute \\lut_keep).\n"); | 						log_debug("  Not combining LUTs into cell B (cell A has attribute \\lut_keep).\n"); | ||||||
| 					else | 					else | ||||||
| 						combine_mask |= COMBINE_B; | 						combine_mask |= COMBINE_B; | ||||||
|  | @ -440,8 +440,8 @@ struct OptLutWorker | ||||||
| 							lutR_unique.insert(bit); | 							lutR_unique.insert(bit); | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					int lutM_width = lutM->getParam("\\WIDTH").as_int(); | 					int lutM_width = lutM->getParam(ID(WIDTH)).as_int(); | ||||||
| 					SigSpec lutM_input = sigmap(lutM->getPort("\\A")); | 					SigSpec lutM_input = sigmap(lutM->getPort(ID(A))); | ||||||
| 					std::vector<SigBit> lutM_new_inputs; | 					std::vector<SigBit> lutM_new_inputs; | ||||||
| 					for (int i = 0; i < lutM_width; i++) | 					for (int i = 0; i < lutM_width; i++) | ||||||
| 					{ | 					{ | ||||||
|  | @ -482,13 +482,13 @@ struct OptLutWorker | ||||||
| 						lutM_new_table[eval] = (RTLIL::State) evaluate_lut(lutB, eval_inputs); | 						lutM_new_table[eval] = (RTLIL::State) evaluate_lut(lutB, eval_inputs); | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					log_debug("  Cell A truth table: %s.\n", lutA->getParam("\\LUT").as_string().c_str()); | 					log_debug("  Cell A truth table: %s.\n", lutA->getParam(ID(LUT)).as_string().c_str()); | ||||||
| 					log_debug("  Cell B truth table: %s.\n", lutB->getParam("\\LUT").as_string().c_str()); | 					log_debug("  Cell B truth table: %s.\n", lutB->getParam(ID(LUT)).as_string().c_str()); | ||||||
| 					log_debug("  Merged truth table: %s.\n", lutM_new_table.as_string().c_str()); | 					log_debug("  Merged truth table: %s.\n", lutM_new_table.as_string().c_str()); | ||||||
| 
 | 
 | ||||||
| 					lutM->setParam("\\LUT", lutM_new_table); | 					lutM->setParam(ID(LUT), lutM_new_table); | ||||||
| 					lutM->setPort("\\A", lutM_new_inputs); | 					lutM->setPort(ID(A), lutM_new_inputs); | ||||||
| 					lutM->setPort("\\Y", lutB_output); | 					lutM->setPort(ID(Y), lutB_output); | ||||||
| 
 | 
 | ||||||
| 					luts_arity[lutM] = lutM_arity; | 					luts_arity[lutM] = lutM_arity; | ||||||
| 					luts.erase(lutR); | 					luts.erase(lutR); | ||||||
|  |  | ||||||
|  | @ -47,8 +47,8 @@ struct OptMergeWorker | ||||||
| 
 | 
 | ||||||
| 	static void sort_pmux_conn(dict<RTLIL::IdString, RTLIL::SigSpec> &conn) | 	static void sort_pmux_conn(dict<RTLIL::IdString, RTLIL::SigSpec> &conn) | ||||||
| 	{ | 	{ | ||||||
| 		SigSpec sig_s = conn.at("\\S"); | 		SigSpec sig_s = conn.at(ID(S)); | ||||||
| 		SigSpec sig_b = conn.at("\\B"); | 		SigSpec sig_b = conn.at(ID(B)); | ||||||
| 
 | 
 | ||||||
| 		int s_width = GetSize(sig_s); | 		int s_width = GetSize(sig_s); | ||||||
| 		int width = GetSize(sig_b) / s_width; | 		int width = GetSize(sig_b) / s_width; | ||||||
|  | @ -59,12 +59,12 @@ struct OptMergeWorker | ||||||
| 
 | 
 | ||||||
| 		std::sort(sb_pairs.begin(), sb_pairs.end()); | 		std::sort(sb_pairs.begin(), sb_pairs.end()); | ||||||
| 
 | 
 | ||||||
| 		conn["\\S"] = SigSpec(); | 		conn[ID(S)] = SigSpec(); | ||||||
| 		conn["\\B"] = SigSpec(); | 		conn[ID(B)] = SigSpec(); | ||||||
| 
 | 
 | ||||||
| 		for (auto &it : sb_pairs) { | 		for (auto &it : sb_pairs) { | ||||||
| 			conn["\\S"].append(it.first); | 			conn[ID(S)].append(it.first); | ||||||
| 			conn["\\B"].append(it.second); | 			conn[ID(B)].append(it.second); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -94,32 +94,32 @@ 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.in("$and", "$or", "$xor", "$xnor", "$add", "$mul", | 		if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor), ID($add), ID($mul), | ||||||
| 				"$logic_and", "$logic_or", "$_AND_", "$_OR_", "$_XOR_")) { | 				ID($logic_and), ID($logic_or), ID($_AND_), ID($_OR_), ID($_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(ID(A))) < assign_map(alt_conn.at(ID(B)))) { | ||||||
| 				alt_conn["\\A"] = conn->at("\\B"); | 				alt_conn[ID(A)] = conn->at(ID(B)); | ||||||
| 				alt_conn["\\B"] = conn->at("\\A"); | 				alt_conn[ID(B)] = conn->at(ID(A)); | ||||||
| 			} | 			} | ||||||
| 			conn = &alt_conn; | 			conn = &alt_conn; | ||||||
| 		} else | 		} else | ||||||
| 		if (cell->type.in("$reduce_xor", "$reduce_xnor")) { | 		if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) { | ||||||
| 			alt_conn = *conn; | 			alt_conn = *conn; | ||||||
| 			assign_map.apply(alt_conn.at("\\A")); | 			assign_map.apply(alt_conn.at(ID(A))); | ||||||
| 			alt_conn.at("\\A").sort(); | 			alt_conn.at(ID(A)).sort(); | ||||||
| 			conn = &alt_conn; | 			conn = &alt_conn; | ||||||
| 		} else | 		} else | ||||||
| 		if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_bool")) { | 		if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool))) { | ||||||
| 			alt_conn = *conn; | 			alt_conn = *conn; | ||||||
| 			assign_map.apply(alt_conn.at("\\A")); | 			assign_map.apply(alt_conn.at(ID(A))); | ||||||
| 			alt_conn.at("\\A").sort_and_unify(); | 			alt_conn.at(ID(A)).sort_and_unify(); | ||||||
| 			conn = &alt_conn; | 			conn = &alt_conn; | ||||||
| 		} else | 		} else | ||||||
| 		if (cell->type == "$pmux") { | 		if (cell->type == ID($pmux)) { | ||||||
| 			alt_conn = *conn; | 			alt_conn = *conn; | ||||||
| 			assign_map.apply(alt_conn.at("\\A")); | 			assign_map.apply(alt_conn.at(ID(A))); | ||||||
| 			assign_map.apply(alt_conn.at("\\B")); | 			assign_map.apply(alt_conn.at(ID(B))); | ||||||
| 			assign_map.apply(alt_conn.at("\\S")); | 			assign_map.apply(alt_conn.at(ID(S))); | ||||||
| 			sort_pmux_conn(alt_conn); | 			sort_pmux_conn(alt_conn); | ||||||
| 			conn = &alt_conn; | 			conn = &alt_conn; | ||||||
| 		} | 		} | ||||||
|  | @ -189,28 +189,28 @@ struct OptMergeWorker | ||||||
| 				assign_map.apply(it.second); | 				assign_map.apply(it.second); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (cell1->type == "$and" || cell1->type == "$or" || cell1->type == "$xor" || cell1->type == "$xnor" || cell1->type == "$add" || cell1->type == "$mul" || | 		if (cell1->type == ID($and) || cell1->type == ID($or) || cell1->type == ID($xor) || cell1->type == ID($xnor) || cell1->type == ID($add) || cell1->type == ID($mul) || | ||||||
| 				cell1->type == "$logic_and" || cell1->type == "$logic_or" || cell1->type == "$_AND_" || cell1->type == "$_OR_" || cell1->type == "$_XOR_") { | 				cell1->type == ID($logic_and) || cell1->type == ID($logic_or) || cell1->type == ID($_AND_) || cell1->type == ID($_OR_) || cell1->type == ID($_XOR_)) { | ||||||
| 			if (conn1.at("\\A") < conn1.at("\\B")) { | 			if (conn1.at(ID(A)) < conn1.at(ID(B))) { | ||||||
| 				RTLIL::SigSpec tmp = conn1["\\A"]; | 				RTLIL::SigSpec tmp = conn1[ID(A)]; | ||||||
| 				conn1["\\A"] = conn1["\\B"]; | 				conn1[ID(A)] = conn1[ID(B)]; | ||||||
| 				conn1["\\B"] = tmp; | 				conn1[ID(B)] = tmp; | ||||||
| 			} | 			} | ||||||
| 			if (conn2.at("\\A") < conn2.at("\\B")) { | 			if (conn2.at(ID(A)) < conn2.at(ID(B))) { | ||||||
| 				RTLIL::SigSpec tmp = conn2["\\A"]; | 				RTLIL::SigSpec tmp = conn2[ID(A)]; | ||||||
| 				conn2["\\A"] = conn2["\\B"]; | 				conn2[ID(A)] = conn2[ID(B)]; | ||||||
| 				conn2["\\B"] = tmp; | 				conn2[ID(B)] = tmp; | ||||||
| 			} | 			} | ||||||
| 		} else | 		} else | ||||||
| 		if (cell1->type == "$reduce_xor" || cell1->type == "$reduce_xnor") { | 		if (cell1->type == ID($reduce_xor) || cell1->type == ID($reduce_xnor)) { | ||||||
| 			conn1["\\A"].sort(); | 			conn1[ID(A)].sort(); | ||||||
| 			conn2["\\A"].sort(); | 			conn2[ID(A)].sort(); | ||||||
| 		} else | 		} else | ||||||
| 		if (cell1->type == "$reduce_and" || cell1->type == "$reduce_or" || cell1->type == "$reduce_bool") { | 		if (cell1->type == ID($reduce_and) || cell1->type == ID($reduce_or) || cell1->type == ID($reduce_bool)) { | ||||||
| 			conn1["\\A"].sort_and_unify(); | 			conn1[ID(A)].sort_and_unify(); | ||||||
| 			conn2["\\A"].sort_and_unify(); | 			conn2[ID(A)].sort_and_unify(); | ||||||
| 		} else | 		} else | ||||||
| 		if (cell1->type == "$pmux") { | 		if (cell1->type == ID($pmux)) { | ||||||
| 			sort_pmux_conn(conn1); | 			sort_pmux_conn(conn1); | ||||||
| 			sort_pmux_conn(conn2); | 			sort_pmux_conn(conn2); | ||||||
| 		} | 		} | ||||||
|  | @ -222,9 +222,9 @@ struct OptMergeWorker | ||||||
| 			return true; | 			return true; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (cell1->type.begins_with("$") && conn1.count("\\Q") != 0) { | 		if (cell1->type.begins_with("$") && conn1.count(ID(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(ID(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(ID(Q))).to_sigbit_vector(); | ||||||
| 			for (size_t i = 0; i < q1.size(); i++) | 			for (size_t i = 0; i < q1.size(); i++) | ||||||
| 				if ((q1.at(i).wire == NULL || q2.at(i).wire == NULL) && q1.at(i) != q2.at(i)) { | 				if ((q1.at(i).wire == NULL || q2.at(i).wire == NULL) && q1.at(i) != q2.at(i)) { | ||||||
| 					lt = q1.at(i) < q2.at(i); | 					lt = q1.at(i) < q2.at(i); | ||||||
|  | @ -271,24 +271,24 @@ struct OptMergeWorker | ||||||
| 		ct.setup_stdcells_mem(); | 		ct.setup_stdcells_mem(); | ||||||
| 
 | 
 | ||||||
| 		if (mode_nomux) { | 		if (mode_nomux) { | ||||||
| 			ct.cell_types.erase("$mux"); | 			ct.cell_types.erase(ID($mux)); | ||||||
| 			ct.cell_types.erase("$pmux"); | 			ct.cell_types.erase(ID($pmux)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		ct.cell_types.erase("$tribuf"); | 		ct.cell_types.erase(ID($tribuf)); | ||||||
| 		ct.cell_types.erase("$_TBUF_"); | 		ct.cell_types.erase(ID($_TBUF_)); | ||||||
| 		ct.cell_types.erase("$anyseq"); | 		ct.cell_types.erase(ID($anyseq)); | ||||||
| 		ct.cell_types.erase("$anyconst"); | 		ct.cell_types.erase(ID($anyconst)); | ||||||
| 		ct.cell_types.erase("$allseq"); | 		ct.cell_types.erase(ID($allseq)); | ||||||
| 		ct.cell_types.erase("$allconst"); | 		ct.cell_types.erase(ID($allconst)); | ||||||
| 
 | 
 | ||||||
| 		log("Finding identical cells in module `%s'.\n", module->name.c_str()); | 		log("Finding identical cells in module `%s'.\n", module->name.c_str()); | ||||||
| 		assign_map.set(module); | 		assign_map.set(module); | ||||||
| 
 | 
 | ||||||
| 		dff_init_map.set(module); | 		dff_init_map.set(module); | ||||||
| 		for (auto &it : module->wires_) | 		for (auto &it : module->wires_) | ||||||
| 			if (it.second->attributes.count("\\init") != 0) { | 			if (it.second->attributes.count(ID(init)) != 0) { | ||||||
| 				Const initval = it.second->attributes.at("\\init"); | 				Const initval = it.second->attributes.at(ID(init)); | ||||||
| 				for (int i = 0; i < GetSize(initval) && i < GetSize(it.second); i++) | 				for (int i = 0; i < GetSize(initval) && i < GetSize(it.second); i++) | ||||||
| 					if (initval[i] == State::S0 || initval[i] == State::S1) | 					if (initval[i] == State::S0 || initval[i] == State::S1) | ||||||
| 						dff_init_map.add(SigBit(it.second, i), initval[i]); | 						dff_init_map.add(SigBit(it.second, i), initval[i]); | ||||||
|  |  | ||||||
|  | @ -84,12 +84,12 @@ struct OptMuxtreeWorker | ||||||
| 		//	.const_deactivated
 | 		//	.const_deactivated
 | ||||||
| 		for (auto cell : module->cells()) | 		for (auto cell : module->cells()) | ||||||
| 		{ | 		{ | ||||||
| 			if (cell->type.in("$mux", "$pmux")) | 			if (cell->type.in(ID($mux), ID($pmux))) | ||||||
| 			{ | 			{ | ||||||
| 				RTLIL::SigSpec sig_a = cell->getPort("\\A"); | 				RTLIL::SigSpec sig_a = cell->getPort(ID(A)); | ||||||
| 				RTLIL::SigSpec sig_b = cell->getPort("\\B"); | 				RTLIL::SigSpec sig_b = cell->getPort(ID(B)); | ||||||
| 				RTLIL::SigSpec sig_s = cell->getPort("\\S"); | 				RTLIL::SigSpec sig_s = cell->getPort(ID(S)); | ||||||
| 				RTLIL::SigSpec sig_y = cell->getPort("\\Y"); | 				RTLIL::SigSpec sig_y = cell->getPort(ID(Y)); | ||||||
| 
 | 
 | ||||||
| 				muxinfo_t muxinfo; | 				muxinfo_t muxinfo; | ||||||
| 				muxinfo.cell = cell; | 				muxinfo.cell = cell; | ||||||
|  | @ -137,7 +137,7 @@ struct OptMuxtreeWorker | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		for (auto wire : module->wires()) { | 		for (auto wire : module->wires()) { | ||||||
| 			if (wire->port_output || wire->get_bool_attribute("\\keep")) | 			if (wire->port_output || wire->get_bool_attribute(ID(keep))) | ||||||
| 				for (int idx : sig2bits(RTLIL::SigSpec(wire))) | 				for (int idx : sig2bits(RTLIL::SigSpec(wire))) | ||||||
| 					bit2info[idx].seen_non_mux = true; | 					bit2info[idx].seen_non_mux = true; | ||||||
| 		} | 		} | ||||||
|  | @ -227,10 +227,10 @@ struct OptMuxtreeWorker | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			RTLIL::SigSpec sig_a = mi.cell->getPort("\\A"); | 			RTLIL::SigSpec sig_a = mi.cell->getPort(ID(A)); | ||||||
| 			RTLIL::SigSpec sig_b = mi.cell->getPort("\\B"); | 			RTLIL::SigSpec sig_b = mi.cell->getPort(ID(B)); | ||||||
| 			RTLIL::SigSpec sig_s = mi.cell->getPort("\\S"); | 			RTLIL::SigSpec sig_s = mi.cell->getPort(ID(S)); | ||||||
| 			RTLIL::SigSpec sig_y = mi.cell->getPort("\\Y"); | 			RTLIL::SigSpec sig_y = mi.cell->getPort(ID(Y)); | ||||||
| 
 | 
 | ||||||
| 			RTLIL::SigSpec sig_ports = sig_b; | 			RTLIL::SigSpec sig_ports = sig_b; | ||||||
| 			sig_ports.append(sig_a); | 			sig_ports.append(sig_a); | ||||||
|  | @ -255,14 +255,14 @@ struct OptMuxtreeWorker | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				mi.cell->setPort("\\A", new_sig_a); | 				mi.cell->setPort(ID(A), new_sig_a); | ||||||
| 				mi.cell->setPort("\\B", new_sig_b); | 				mi.cell->setPort(ID(B), new_sig_b); | ||||||
| 				mi.cell->setPort("\\S", new_sig_s); | 				mi.cell->setPort(ID(S), new_sig_s); | ||||||
| 				if (GetSize(new_sig_s) == 1) { | 				if (GetSize(new_sig_s) == 1) { | ||||||
| 					mi.cell->type = "$mux"; | 					mi.cell->type = ID($mux); | ||||||
| 					mi.cell->parameters.erase("\\S_WIDTH"); | 					mi.cell->parameters.erase(ID(S_WIDTH)); | ||||||
| 				} else { | 				} else { | ||||||
| 					mi.cell->parameters["\\S_WIDTH"] = RTLIL::Const(GetSize(new_sig_s)); | 					mi.cell->parameters[ID(S_WIDTH)] = RTLIL::Const(GetSize(new_sig_s)); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | @ -364,9 +364,9 @@ struct OptMuxtreeWorker | ||||||
| 
 | 
 | ||||||
| 		int width = 0; | 		int width = 0; | ||||||
| 		idict<int> ctrl_bits; | 		idict<int> ctrl_bits; | ||||||
| 		if (portname == "\\B") | 		if (portname == ID(B)) | ||||||
| 			width = GetSize(muxinfo.cell->getPort("\\A")); | 			width = GetSize(muxinfo.cell->getPort(ID(A))); | ||||||
| 		for (int bit : sig2bits(muxinfo.cell->getPort("\\S"), false)) | 		for (int bit : sig2bits(muxinfo.cell->getPort(ID(S)), false)) | ||||||
| 			ctrl_bits(bit); | 			ctrl_bits(bit); | ||||||
| 
 | 
 | ||||||
| 		int port_idx = 0, port_off = 0; | 		int port_idx = 0, port_off = 0; | ||||||
|  | @ -414,8 +414,8 @@ struct OptMuxtreeWorker | ||||||
| 
 | 
 | ||||||
| 		// set input ports to constants if we find known active or inactive signals
 | 		// set input ports to constants if we find known active or inactive signals
 | ||||||
| 		if (do_replace_known) { | 		if (do_replace_known) { | ||||||
| 			replace_known(knowledge, muxinfo, "\\A"); | 			replace_known(knowledge, muxinfo, ID(A)); | ||||||
| 			replace_known(knowledge, muxinfo, "\\B"); | 			replace_known(knowledge, muxinfo, ID(B)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// if there is a constant activated port we just use it
 | 		// if there is a constant activated port we just use it
 | ||||||
|  |  | ||||||
|  | @ -43,13 +43,13 @@ struct OptReduceWorker | ||||||
| 			return; | 			return; | ||||||
| 		cells.erase(cell); | 		cells.erase(cell); | ||||||
| 
 | 
 | ||||||
| 		RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); | 		RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A))); | ||||||
| 		pool<RTLIL::SigBit> new_sig_a_bits; | 		pool<RTLIL::SigBit> new_sig_a_bits; | ||||||
| 
 | 
 | ||||||
| 		for (auto &bit : sig_a.to_sigbit_set()) | 		for (auto &bit : sig_a.to_sigbit_set()) | ||||||
| 		{ | 		{ | ||||||
| 			if (bit == RTLIL::State::S0) { | 			if (bit == RTLIL::State::S0) { | ||||||
| 				if (cell->type == "$reduce_and") { | 				if (cell->type == ID($reduce_and)) { | ||||||
| 					new_sig_a_bits.clear(); | 					new_sig_a_bits.clear(); | ||||||
| 					new_sig_a_bits.insert(RTLIL::State::S0); | 					new_sig_a_bits.insert(RTLIL::State::S0); | ||||||
| 					break; | 					break; | ||||||
|  | @ -57,7 +57,7 @@ struct OptReduceWorker | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (bit == RTLIL::State::S1) { | 			if (bit == RTLIL::State::S1) { | ||||||
| 				if (cell->type == "$reduce_or") { | 				if (cell->type == ID($reduce_or)) { | ||||||
| 					new_sig_a_bits.clear(); | 					new_sig_a_bits.clear(); | ||||||
| 					new_sig_a_bits.insert(RTLIL::State::S1); | 					new_sig_a_bits.insert(RTLIL::State::S1); | ||||||
| 					break; | 					break; | ||||||
|  | @ -73,8 +73,8 @@ struct OptReduceWorker | ||||||
| 			for (auto child_cell : drivers.find(bit)) { | 			for (auto child_cell : drivers.find(bit)) { | ||||||
| 				if (child_cell->type == cell->type) { | 				if (child_cell->type == cell->type) { | ||||||
| 					opt_reduce(cells, drivers, child_cell); | 					opt_reduce(cells, drivers, child_cell); | ||||||
| 					if (child_cell->getPort("\\Y")[0] == bit) { | 					if (child_cell->getPort(ID(Y))[0] == bit) { | ||||||
| 						pool<RTLIL::SigBit> child_sig_a_bits = assign_map(child_cell->getPort("\\A")).to_sigbit_pool(); | 						pool<RTLIL::SigBit> child_sig_a_bits = assign_map(child_cell->getPort(ID(A))).to_sigbit_pool(); | ||||||
| 						new_sig_a_bits.insert(child_sig_a_bits.begin(), child_sig_a_bits.end()); | 						new_sig_a_bits.insert(child_sig_a_bits.begin(), child_sig_a_bits.end()); | ||||||
| 					} else | 					} else | ||||||
| 						new_sig_a_bits.insert(RTLIL::State::S0); | 						new_sig_a_bits.insert(RTLIL::State::S0); | ||||||
|  | @ -87,22 +87,22 @@ struct OptReduceWorker | ||||||
| 
 | 
 | ||||||
| 		RTLIL::SigSpec new_sig_a(new_sig_a_bits); | 		RTLIL::SigSpec new_sig_a(new_sig_a_bits); | ||||||
| 
 | 
 | ||||||
| 		if (new_sig_a != sig_a || sig_a.size() != cell->getPort("\\A").size()) { | 		if (new_sig_a != sig_a || sig_a.size() != cell->getPort(ID(A)).size()) { | ||||||
| 			log("    New input vector for %s cell %s: %s\n", cell->type.c_str(), cell->name.c_str(), log_signal(new_sig_a)); | 			log("    New input vector for %s cell %s: %s\n", cell->type.c_str(), cell->name.c_str(), log_signal(new_sig_a)); | ||||||
| 			did_something = true; | 			did_something = true; | ||||||
| 			total_count++; | 			total_count++; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		cell->setPort("\\A", new_sig_a); | 		cell->setPort(ID(A), new_sig_a); | ||||||
| 		cell->parameters["\\A_WIDTH"] = RTLIL::Const(new_sig_a.size()); | 		cell->parameters[ID(A_WIDTH)] = RTLIL::Const(new_sig_a.size()); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void opt_mux(RTLIL::Cell *cell) | 	void opt_mux(RTLIL::Cell *cell) | ||||||
| 	{ | 	{ | ||||||
| 		RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); | 		RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A))); | ||||||
| 		RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B")); | 		RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID(B))); | ||||||
| 		RTLIL::SigSpec sig_s = assign_map(cell->getPort("\\S")); | 		RTLIL::SigSpec sig_s = assign_map(cell->getPort(ID(S))); | ||||||
| 
 | 
 | ||||||
| 		RTLIL::SigSpec new_sig_b, new_sig_s; | 		RTLIL::SigSpec new_sig_b, new_sig_s; | ||||||
| 		pool<RTLIL::SigSpec> handled_sig; | 		pool<RTLIL::SigSpec> handled_sig; | ||||||
|  | @ -123,15 +123,15 @@ struct OptReduceWorker | ||||||
| 
 | 
 | ||||||
| 			if (this_s.size() > 1) | 			if (this_s.size() > 1) | ||||||
| 			{ | 			{ | ||||||
| 				RTLIL::Cell *reduce_or_cell = module->addCell(NEW_ID, "$reduce_or"); | 				RTLIL::Cell *reduce_or_cell = module->addCell(NEW_ID, ID($reduce_or)); | ||||||
| 				reduce_or_cell->setPort("\\A", this_s); | 				reduce_or_cell->setPort(ID(A), this_s); | ||||||
| 				reduce_or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); | 				reduce_or_cell->parameters[ID(A_SIGNED)] = RTLIL::Const(0); | ||||||
| 				reduce_or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(this_s.size()); | 				reduce_or_cell->parameters[ID(A_WIDTH)] = RTLIL::Const(this_s.size()); | ||||||
| 				reduce_or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); | 				reduce_or_cell->parameters[ID(Y_WIDTH)] = RTLIL::Const(1); | ||||||
| 
 | 
 | ||||||
| 				RTLIL::Wire *reduce_or_wire = module->addWire(NEW_ID); | 				RTLIL::Wire *reduce_or_wire = module->addWire(NEW_ID); | ||||||
| 				this_s = RTLIL::SigSpec(reduce_or_wire); | 				this_s = RTLIL::SigSpec(reduce_or_wire); | ||||||
| 				reduce_or_cell->setPort("\\Y", this_s); | 				reduce_or_cell->setPort(ID(Y), this_s); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			new_sig_b.append(this_b); | 			new_sig_b.append(this_b); | ||||||
|  | @ -147,28 +147,28 @@ struct OptReduceWorker | ||||||
| 
 | 
 | ||||||
| 		if (new_sig_s.size() == 0) | 		if (new_sig_s.size() == 0) | ||||||
| 		{ | 		{ | ||||||
| 			module->connect(RTLIL::SigSig(cell->getPort("\\Y"), cell->getPort("\\A"))); | 			module->connect(RTLIL::SigSig(cell->getPort(ID(Y)), cell->getPort(ID(A)))); | ||||||
| 			assign_map.add(cell->getPort("\\Y"), cell->getPort("\\A")); | 			assign_map.add(cell->getPort(ID(Y)), cell->getPort(ID(A))); | ||||||
| 			module->remove(cell); | 			module->remove(cell); | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			cell->setPort("\\B", new_sig_b); | 			cell->setPort(ID(B), new_sig_b); | ||||||
| 			cell->setPort("\\S", new_sig_s); | 			cell->setPort(ID(S), new_sig_s); | ||||||
| 			if (new_sig_s.size() > 1) { | 			if (new_sig_s.size() > 1) { | ||||||
| 				cell->parameters["\\S_WIDTH"] = RTLIL::Const(new_sig_s.size()); | 				cell->parameters[ID(S_WIDTH)] = RTLIL::Const(new_sig_s.size()); | ||||||
| 			} else { | 			} else { | ||||||
| 				cell->type = "$mux"; | 				cell->type = ID($mux); | ||||||
| 				cell->parameters.erase("\\S_WIDTH"); | 				cell->parameters.erase(ID(S_WIDTH)); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void opt_mux_bits(RTLIL::Cell *cell) | 	void opt_mux_bits(RTLIL::Cell *cell) | ||||||
| 	{ | 	{ | ||||||
| 		std::vector<RTLIL::SigBit> sig_a = assign_map(cell->getPort("\\A")).to_sigbit_vector(); | 		std::vector<RTLIL::SigBit> sig_a = assign_map(cell->getPort(ID(A))).to_sigbit_vector(); | ||||||
| 		std::vector<RTLIL::SigBit> sig_b = assign_map(cell->getPort("\\B")).to_sigbit_vector(); | 		std::vector<RTLIL::SigBit> sig_b = assign_map(cell->getPort(ID(B))).to_sigbit_vector(); | ||||||
| 		std::vector<RTLIL::SigBit> sig_y = assign_map(cell->getPort("\\Y")).to_sigbit_vector(); | 		std::vector<RTLIL::SigBit> sig_y = assign_map(cell->getPort(ID(Y))).to_sigbit_vector(); | ||||||
| 
 | 
 | ||||||
| 		std::vector<RTLIL::SigBit> new_sig_y; | 		std::vector<RTLIL::SigBit> new_sig_y; | ||||||
| 		RTLIL::SigSig old_sig_conn; | 		RTLIL::SigSig old_sig_conn; | ||||||
|  | @ -209,29 +209,29 @@ struct OptReduceWorker | ||||||
| 		if (new_sig_y.size() != sig_y.size()) | 		if (new_sig_y.size() != sig_y.size()) | ||||||
| 		{ | 		{ | ||||||
| 			log("    Consolidated identical input bits for %s cell %s:\n", cell->type.c_str(), cell->name.c_str()); | 			log("    Consolidated identical input bits for %s cell %s:\n", cell->type.c_str(), cell->name.c_str()); | ||||||
| 			log("      Old ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort("\\A")), | 			log("      Old ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort(ID(A))), | ||||||
| 					log_signal(cell->getPort("\\B")), log_signal(cell->getPort("\\Y"))); | 					log_signal(cell->getPort(ID(B))), log_signal(cell->getPort(ID(Y)))); | ||||||
| 
 | 
 | ||||||
| 			cell->setPort("\\A", RTLIL::SigSpec()); | 			cell->setPort(ID(A), RTLIL::SigSpec()); | ||||||
| 			for (auto &in_tuple : consolidated_in_tuples) { | 			for (auto &in_tuple : consolidated_in_tuples) { | ||||||
| 				RTLIL::SigSpec new_a = cell->getPort("\\A"); | 				RTLIL::SigSpec new_a = cell->getPort(ID(A)); | ||||||
| 				new_a.append(in_tuple.at(0)); | 				new_a.append(in_tuple.at(0)); | ||||||
| 				cell->setPort("\\A", new_a); | 				cell->setPort(ID(A), new_a); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			cell->setPort("\\B", RTLIL::SigSpec()); | 			cell->setPort(ID(B), RTLIL::SigSpec()); | ||||||
| 			for (int i = 1; i <= cell->getPort("\\S").size(); i++) | 			for (int i = 1; i <= cell->getPort(ID(S)).size(); i++) | ||||||
| 				for (auto &in_tuple : consolidated_in_tuples) { | 				for (auto &in_tuple : consolidated_in_tuples) { | ||||||
| 					RTLIL::SigSpec new_b = cell->getPort("\\B"); | 					RTLIL::SigSpec new_b = cell->getPort(ID(B)); | ||||||
| 					new_b.append(in_tuple.at(i)); | 					new_b.append(in_tuple.at(i)); | ||||||
| 					cell->setPort("\\B", new_b); | 					cell->setPort(ID(B), new_b); | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 			cell->parameters["\\WIDTH"] = RTLIL::Const(new_sig_y.size()); | 			cell->parameters[ID(WIDTH)] = RTLIL::Const(new_sig_y.size()); | ||||||
| 			cell->setPort("\\Y", new_sig_y); | 			cell->setPort(ID(Y), new_sig_y); | ||||||
| 
 | 
 | ||||||
| 			log("      New ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort("\\A")), | 			log("      New ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort(ID(A))), | ||||||
| 					log_signal(cell->getPort("\\B")), log_signal(cell->getPort("\\Y"))); | 					log_signal(cell->getPort(ID(B))), log_signal(cell->getPort(ID(Y)))); | ||||||
| 			log("      New connections: %s = %s\n", log_signal(old_sig_conn.first), log_signal(old_sig_conn.second)); | 			log("      New connections: %s = %s\n", log_signal(old_sig_conn.first), log_signal(old_sig_conn.second)); | ||||||
| 
 | 
 | ||||||
| 			module->connect(old_sig_conn); | 			module->connect(old_sig_conn); | ||||||
|  | @ -253,15 +253,15 @@ struct OptReduceWorker | ||||||
| 		SigPool mem_wren_sigs; | 		SigPool mem_wren_sigs; | ||||||
| 		for (auto &cell_it : module->cells_) { | 		for (auto &cell_it : module->cells_) { | ||||||
| 			RTLIL::Cell *cell = cell_it.second; | 			RTLIL::Cell *cell = cell_it.second; | ||||||
| 			if (cell->type == "$mem") | 			if (cell->type == ID($mem)) | ||||||
| 				mem_wren_sigs.add(assign_map(cell->getPort("\\WR_EN"))); | 				mem_wren_sigs.add(assign_map(cell->getPort(ID(WR_EN)))); | ||||||
| 			if (cell->type == "$memwr") | 			if (cell->type == ID($memwr)) | ||||||
| 				mem_wren_sigs.add(assign_map(cell->getPort("\\EN"))); | 				mem_wren_sigs.add(assign_map(cell->getPort(ID(EN)))); | ||||||
| 		} | 		} | ||||||
| 		for (auto &cell_it : module->cells_) { | 		for (auto &cell_it : module->cells_) { | ||||||
| 			RTLIL::Cell *cell = cell_it.second; | 			RTLIL::Cell *cell = cell_it.second; | ||||||
| 			if (cell->type == "$dff" && mem_wren_sigs.check_any(assign_map(cell->getPort("\\Q")))) | 			if (cell->type == ID($dff) && mem_wren_sigs.check_any(assign_map(cell->getPort(ID(Q))))) | ||||||
| 				mem_wren_sigs.add(assign_map(cell->getPort("\\D"))); | 				mem_wren_sigs.add(assign_map(cell->getPort(ID(D)))); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		bool keep_expanding_mem_wren_sigs = true; | 		bool keep_expanding_mem_wren_sigs = true; | ||||||
|  | @ -269,12 +269,12 @@ struct OptReduceWorker | ||||||
| 			keep_expanding_mem_wren_sigs = false; | 			keep_expanding_mem_wren_sigs = false; | ||||||
| 			for (auto &cell_it : module->cells_) { | 			for (auto &cell_it : module->cells_) { | ||||||
| 				RTLIL::Cell *cell = cell_it.second; | 				RTLIL::Cell *cell = cell_it.second; | ||||||
| 				if (cell->type == "$mux" && mem_wren_sigs.check_any(assign_map(cell->getPort("\\Y")))) { | 				if (cell->type == ID($mux) && mem_wren_sigs.check_any(assign_map(cell->getPort(ID(Y))))) { | ||||||
| 					if (!mem_wren_sigs.check_all(assign_map(cell->getPort("\\A"))) || | 					if (!mem_wren_sigs.check_all(assign_map(cell->getPort(ID(A)))) || | ||||||
| 							!mem_wren_sigs.check_all(assign_map(cell->getPort("\\B")))) | 							!mem_wren_sigs.check_all(assign_map(cell->getPort(ID(B))))) | ||||||
| 						keep_expanding_mem_wren_sigs = true; | 						keep_expanding_mem_wren_sigs = true; | ||||||
| 					mem_wren_sigs.add(assign_map(cell->getPort("\\A"))); | 					mem_wren_sigs.add(assign_map(cell->getPort(ID(A)))); | ||||||
| 					mem_wren_sigs.add(assign_map(cell->getPort("\\B"))); | 					mem_wren_sigs.add(assign_map(cell->getPort(ID(B)))); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | @ -286,7 +286,7 @@ struct OptReduceWorker | ||||||
| 			// merge trees of reduce_* cells to one single cell and unify input vectors
 | 			// merge trees of reduce_* cells to one single cell and unify input vectors
 | ||||||
| 			// (only handle reduce_and and reduce_or for various reasons)
 | 			// (only handle reduce_and and reduce_or for various reasons)
 | ||||||
| 
 | 
 | ||||||
| 			const char *type_list[] = { "$reduce_or", "$reduce_and" }; | 			const IdString type_list[] = { ID($reduce_or), ID($reduce_and) }; | ||||||
| 			for (auto type : type_list) | 			for (auto type : type_list) | ||||||
| 			{ | 			{ | ||||||
| 				SigSet<RTLIL::Cell*> drivers; | 				SigSet<RTLIL::Cell*> drivers; | ||||||
|  | @ -296,7 +296,7 @@ struct OptReduceWorker | ||||||
| 					RTLIL::Cell *cell = cell_it.second; | 					RTLIL::Cell *cell = cell_it.second; | ||||||
| 					if (cell->type != type || !design->selected(module, cell)) | 					if (cell->type != type || !design->selected(module, cell)) | ||||||
| 						continue; | 						continue; | ||||||
| 					drivers.insert(assign_map(cell->getPort("\\Y")), cell); | 					drivers.insert(assign_map(cell->getPort(ID(Y))), cell); | ||||||
| 					cells.insert(cell); | 					cells.insert(cell); | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
|  | @ -311,14 +311,14 @@ struct OptReduceWorker | ||||||
| 			std::vector<RTLIL::Cell*> cells; | 			std::vector<RTLIL::Cell*> cells; | ||||||
| 
 | 
 | ||||||
| 			for (auto &it : module->cells_) | 			for (auto &it : module->cells_) | ||||||
| 				if ((it.second->type == "$mux" || it.second->type == "$pmux") && design->selected(module, it.second)) | 				if ((it.second->type == ID($mux) || it.second->type == ID($pmux)) && design->selected(module, it.second)) | ||||||
| 					cells.push_back(it.second); | 					cells.push_back(it.second); | ||||||
| 
 | 
 | ||||||
| 			for (auto cell : cells) | 			for (auto cell : cells) | ||||||
| 			{ | 			{ | ||||||
| 				// this optimization is to aggressive for most coarse-grain applications.
 | 				// this optimization is to aggressive for most coarse-grain applications.
 | ||||||
| 				// but we always want it for multiplexers driving write enable ports.
 | 				// but we always want it for multiplexers driving write enable ports.
 | ||||||
| 				if (do_fine || mem_wren_sigs.check_any(assign_map(cell->getPort("\\Y")))) | 				if (do_fine || mem_wren_sigs.check_any(assign_map(cell->getPort(ID(Y))))) | ||||||
| 					opt_mux_bits(cell); | 					opt_mux_bits(cell); | ||||||
| 
 | 
 | ||||||
| 				opt_mux(cell); | 				opt_mux(cell); | ||||||
|  |  | ||||||
|  | @ -41,7 +41,7 @@ void remove_init_attr(SigSpec sig) | ||||||
| 	for (auto bit : assign_map(sig)) | 	for (auto bit : assign_map(sig)) | ||||||
| 		if (init_attributes.count(bit)) | 		if (init_attributes.count(bit)) | ||||||
| 			for (auto wbit : init_attributes.at(bit)) | 			for (auto wbit : init_attributes.at(bit)) | ||||||
| 				wbit.wire->attributes.at("\\init")[wbit.offset] = State::Sx; | 				wbit.wire->attributes.at(ID(init))[wbit.offset] = State::Sx; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell) | bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell) | ||||||
|  | @ -49,17 +49,17 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell) | ||||||
| 	SigSpec sig_set, sig_clr; | 	SigSpec sig_set, sig_clr; | ||||||
| 	State pol_set, pol_clr; | 	State pol_set, pol_clr; | ||||||
| 
 | 
 | ||||||
| 	if (cell->hasPort("\\S")) | 	if (cell->hasPort(ID(S))) | ||||||
| 		sig_set = cell->getPort("\\S"); | 		sig_set = cell->getPort(ID(S)); | ||||||
| 
 | 
 | ||||||
| 	if (cell->hasPort("\\R")) | 	if (cell->hasPort(ID(R))) | ||||||
| 		sig_clr = cell->getPort("\\R"); | 		sig_clr = cell->getPort(ID(R)); | ||||||
| 
 | 
 | ||||||
| 	if (cell->hasPort("\\SET")) | 	if (cell->hasPort(ID(SET))) | ||||||
| 		sig_set = cell->getPort("\\SET"); | 		sig_set = cell->getPort(ID(SET)); | ||||||
| 
 | 
 | ||||||
| 	if (cell->hasPort("\\CLR")) | 	if (cell->hasPort(ID(CLR))) | ||||||
| 		sig_clr = cell->getPort("\\CLR"); | 		sig_clr = cell->getPort(ID(CLR)); | ||||||
| 
 | 
 | ||||||
| 	log_assert(GetSize(sig_set) == GetSize(sig_clr)); | 	log_assert(GetSize(sig_set) == GetSize(sig_clr)); | ||||||
| 
 | 
 | ||||||
|  | @ -71,17 +71,17 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell) | ||||||
| 		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.in("$dffsr", "$dlatchsr")) { | 	if (cell->type.in(ID($dffsr), ID($dlatchsr))) { | ||||||
| 		pol_set = cell->parameters["\\SET_POLARITY"].as_bool() ? State::S1 : State::S0; | 		pol_set = cell->parameters[ID(SET_POLARITY)].as_bool() ? State::S1 : State::S0; | ||||||
| 		pol_clr = cell->parameters["\\CLR_POLARITY"].as_bool() ? State::S1 : State::S0; | 		pol_clr = cell->parameters[ID(CLR_POLARITY)].as_bool() ? State::S1 : State::S0; | ||||||
| 	} else | 	} else | ||||||
| 		log_abort(); | 		log_abort(); | ||||||
| 
 | 
 | ||||||
| 	State npol_set = pol_set == State::S0 ? State::S1 : State::S0; | 	State npol_set = pol_set == State::S0 ? State::S1 : State::S0; | ||||||
| 	State npol_clr = pol_clr == State::S0 ? State::S1 : State::S0; | 	State npol_clr = pol_clr == State::S0 ? State::S1 : State::S0; | ||||||
| 
 | 
 | ||||||
| 	SigSpec sig_d = cell->getPort("\\D"); | 	SigSpec sig_d = cell->getPort(ID(D)); | ||||||
| 	SigSpec sig_q = cell->getPort("\\Q"); | 	SigSpec sig_q = cell->getPort(ID(Q)); | ||||||
| 
 | 
 | ||||||
| 	bool did_something = false; | 	bool did_something = false; | ||||||
| 	bool proper_sr = false; | 	bool proper_sr = false; | ||||||
|  | @ -137,20 +137,20 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell) | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (cell->type.in("$dffsr", "$dlatchsr")) | 	if (cell->type.in(ID($dffsr), ID($dlatchsr))) | ||||||
| 	{ | 	{ | ||||||
| 		cell->setParam("\\WIDTH", GetSize(sig_d)); | 		cell->setParam(ID(WIDTH), GetSize(sig_d)); | ||||||
| 		cell->setPort("\\SET", sig_set); | 		cell->setPort(ID(SET), sig_set); | ||||||
| 		cell->setPort("\\CLR", sig_clr); | 		cell->setPort(ID(CLR), sig_clr); | ||||||
| 		cell->setPort("\\D", sig_d); | 		cell->setPort(ID(D), sig_d); | ||||||
| 		cell->setPort("\\Q", sig_q); | 		cell->setPort(ID(Q), sig_q); | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		cell->setPort("\\S", sig_set); | 		cell->setPort(ID(S), sig_set); | ||||||
| 		cell->setPort("\\R", sig_clr); | 		cell->setPort(ID(R), sig_clr); | ||||||
| 		cell->setPort("\\D", sig_d); | 		cell->setPort(ID(D), sig_d); | ||||||
| 		cell->setPort("\\Q", sig_q); | 		cell->setPort(ID(Q), sig_q); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (proper_sr) | 	if (proper_sr) | ||||||
|  | @ -159,36 +159,36 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell) | ||||||
| 	if (used_pol_set && used_pol_clr && pol_set != pol_clr) | 	if (used_pol_set && used_pol_clr && pol_set != pol_clr) | ||||||
| 		return did_something; | 		return did_something; | ||||||
| 
 | 
 | ||||||
| 	if (cell->type == "$dlatchsr") | 	if (cell->type == ID($dlatchsr)) | ||||||
| 		return did_something; | 		return did_something; | ||||||
| 
 | 
 | ||||||
| 	State unified_pol = used_pol_set ? pol_set : pol_clr; | 	State unified_pol = used_pol_set ? pol_set : pol_clr; | ||||||
| 
 | 
 | ||||||
| 	if (cell->type == "$dffsr") | 	if (cell->type == ID($dffsr)) | ||||||
| 	{ | 	{ | ||||||
| 		if (hasreset) | 		if (hasreset) | ||||||
| 		{ | 		{ | ||||||
| 			log("Converting %s (%s) to %s in module %s.\n", log_id(cell), log_id(cell->type), "$adff", log_id(mod)); | 			log("Converting %s (%s) to %s in module %s.\n", log_id(cell), log_id(cell->type), "$adff", log_id(mod)); | ||||||
| 
 | 
 | ||||||
| 			cell->type = "$adff"; | 			cell->type = ID($adff); | ||||||
| 			cell->setParam("\\ARST_POLARITY", unified_pol); | 			cell->setParam(ID(ARST_POLARITY), unified_pol); | ||||||
| 			cell->setParam("\\ARST_VALUE", reset_val); | 			cell->setParam(ID(ARST_VALUE), reset_val); | ||||||
| 			cell->setPort("\\ARST", sig_reset); | 			cell->setPort(ID(ARST), sig_reset); | ||||||
| 
 | 
 | ||||||
| 			cell->unsetParam("\\SET_POLARITY"); | 			cell->unsetParam(ID(SET_POLARITY)); | ||||||
| 			cell->unsetParam("\\CLR_POLARITY"); | 			cell->unsetParam(ID(CLR_POLARITY)); | ||||||
| 			cell->unsetPort("\\SET"); | 			cell->unsetPort(ID(SET)); | ||||||
| 			cell->unsetPort("\\CLR"); | 			cell->unsetPort(ID(CLR)); | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			log("Converting %s (%s) to %s in module %s.\n", log_id(cell), log_id(cell->type), "$dff", log_id(mod)); | 			log("Converting %s (%s) to %s in module %s.\n", log_id(cell), log_id(cell->type), "$dff", log_id(mod)); | ||||||
| 
 | 
 | ||||||
| 			cell->type = "$dff"; | 			cell->type = ID($dff); | ||||||
| 			cell->unsetParam("\\SET_POLARITY"); | 			cell->unsetParam(ID(SET_POLARITY)); | ||||||
| 			cell->unsetParam("\\CLR_POLARITY"); | 			cell->unsetParam(ID(CLR_POLARITY)); | ||||||
| 			cell->unsetPort("\\SET"); | 			cell->unsetPort(ID(SET)); | ||||||
| 			cell->unsetPort("\\CLR"); | 			cell->unsetPort(ID(CLR)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return true; | 		return true; | ||||||
|  | @ -208,8 +208,8 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell) | ||||||
| 		log("Converting %s (%s) to %s in module %s.\n", log_id(cell), log_id(cell->type), log_id(new_type), log_id(mod)); | 		log("Converting %s (%s) to %s in module %s.\n", log_id(cell), log_id(cell->type), log_id(new_type), log_id(mod)); | ||||||
| 
 | 
 | ||||||
| 		cell->type = new_type; | 		cell->type = new_type; | ||||||
| 		cell->unsetPort("\\S"); | 		cell->unsetPort(ID(S)); | ||||||
| 		cell->unsetPort("\\R"); | 		cell->unsetPort(ID(R)); | ||||||
| 
 | 
 | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
|  | @ -222,18 +222,18 @@ bool handle_dlatch(RTLIL::Module *mod, RTLIL::Cell *dlatch) | ||||||
| 	SigSpec sig_e; | 	SigSpec sig_e; | ||||||
| 	State on_state, off_state; | 	State on_state, off_state; | ||||||
| 
 | 
 | ||||||
| 	if (dlatch->type == "$dlatch") { | 	if (dlatch->type == ID($dlatch)) { | ||||||
| 		sig_e = assign_map(dlatch->getPort("\\EN")); | 		sig_e = assign_map(dlatch->getPort(ID(EN))); | ||||||
| 		on_state = dlatch->getParam("\\EN_POLARITY").as_bool() ? State::S1 : State::S0; | 		on_state = dlatch->getParam(ID(EN_POLARITY)).as_bool() ? State::S1 : State::S0; | ||||||
| 		off_state = dlatch->getParam("\\EN_POLARITY").as_bool() ? State::S0 : State::S1; | 		off_state = dlatch->getParam(ID(EN_POLARITY)).as_bool() ? State::S0 : State::S1; | ||||||
| 	} else | 	} else | ||||||
| 	if (dlatch->type == "$_DLATCH_P_") { | 	if (dlatch->type == ID($_DLATCH_P_)) { | ||||||
| 		sig_e = assign_map(dlatch->getPort("\\E")); | 		sig_e = assign_map(dlatch->getPort(ID(E))); | ||||||
| 		on_state = State::S1; | 		on_state = State::S1; | ||||||
| 		off_state = State::S0; | 		off_state = State::S0; | ||||||
| 	} else | 	} else | ||||||
| 	if (dlatch->type == "$_DLATCH_N_") { | 	if (dlatch->type == ID($_DLATCH_N_)) { | ||||||
| 		sig_e = assign_map(dlatch->getPort("\\E")); | 		sig_e = assign_map(dlatch->getPort(ID(E))); | ||||||
| 		on_state = State::S0; | 		on_state = State::S0; | ||||||
| 		off_state = State::S1; | 		off_state = State::S1; | ||||||
| 	} else | 	} else | ||||||
|  | @ -242,15 +242,15 @@ bool handle_dlatch(RTLIL::Module *mod, RTLIL::Cell *dlatch) | ||||||
| 	if (sig_e == off_state) | 	if (sig_e == off_state) | ||||||
| 	{ | 	{ | ||||||
| 		RTLIL::Const val_init; | 		RTLIL::Const val_init; | ||||||
| 		for (auto bit : dff_init_map(dlatch->getPort("\\Q"))) | 		for (auto bit : dff_init_map(dlatch->getPort(ID(Q)))) | ||||||
| 			val_init.bits.push_back(bit.wire == NULL ? bit.data : State::Sx); | 			val_init.bits.push_back(bit.wire == NULL ? bit.data : State::Sx); | ||||||
| 		mod->connect(dlatch->getPort("\\Q"), val_init); | 		mod->connect(dlatch->getPort(ID(Q)), val_init); | ||||||
| 		goto delete_dlatch; | 		goto delete_dlatch; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (sig_e == on_state) | 	if (sig_e == on_state) | ||||||
| 	{ | 	{ | ||||||
| 		mod->connect(dlatch->getPort("\\Q"), dlatch->getPort("\\D")); | 		mod->connect(dlatch->getPort(ID(Q)), dlatch->getPort(ID(D))); | ||||||
| 		goto delete_dlatch; | 		goto delete_dlatch; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -258,7 +258,7 @@ bool handle_dlatch(RTLIL::Module *mod, RTLIL::Cell *dlatch) | ||||||
| 
 | 
 | ||||||
| delete_dlatch: | delete_dlatch: | ||||||
| 	log("Removing %s (%s) from module %s.\n", log_id(dlatch), log_id(dlatch->type), log_id(mod)); | 	log("Removing %s (%s) from module %s.\n", log_id(dlatch), log_id(dlatch->type), log_id(mod)); | ||||||
| 	remove_init_attr(dlatch->getPort("\\Q")); | 	remove_init_attr(dlatch->getPort(ID(Q))); | ||||||
| 	mod->remove(dlatch); | 	mod->remove(dlatch); | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
|  | @ -268,24 +268,24 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) | ||||||
| 	RTLIL::SigSpec sig_d, sig_q, sig_c, sig_r, sig_e; | 	RTLIL::SigSpec sig_d, sig_q, sig_c, sig_r, sig_e; | ||||||
| 	RTLIL::Const val_cp, val_rp, val_rv, val_ep; | 	RTLIL::Const val_cp, val_rp, val_rv, val_ep; | ||||||
| 
 | 
 | ||||||
| 	if (dff->type == "$_FF_") { | 	if (dff->type == ID($_FF_)) { | ||||||
| 		sig_d = dff->getPort("\\D"); | 		sig_d = dff->getPort(ID(D)); | ||||||
| 		sig_q = dff->getPort("\\Q"); | 		sig_q = dff->getPort(ID(Q)); | ||||||
| 	} | 	} | ||||||
| 	else if (dff->type == "$_DFF_N_" || dff->type == "$_DFF_P_") { | 	else if (dff->type == ID($_DFF_N_) || dff->type == ID($_DFF_P_)) { | ||||||
| 		sig_d = dff->getPort("\\D"); | 		sig_d = dff->getPort(ID(D)); | ||||||
| 		sig_q = dff->getPort("\\Q"); | 		sig_q = dff->getPort(ID(Q)); | ||||||
| 		sig_c = dff->getPort("\\C"); | 		sig_c = dff->getPort(ID(C)); | ||||||
| 		val_cp = RTLIL::Const(dff->type == "$_DFF_P_", 1); | 		val_cp = RTLIL::Const(dff->type == ID($_DFF_P_), 1); | ||||||
| 	} | 	} | ||||||
| 	else if (dff->type.begins_with("$_DFF_") && dff->type.compare(9, 1, "_") == 0 && | 	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')) { | ||||||
| 		sig_d = dff->getPort("\\D"); | 		sig_d = dff->getPort(ID(D)); | ||||||
| 		sig_q = dff->getPort("\\Q"); | 		sig_q = dff->getPort(ID(Q)); | ||||||
| 		sig_c = dff->getPort("\\C"); | 		sig_c = dff->getPort(ID(C)); | ||||||
| 		sig_r = dff->getPort("\\R"); | 		sig_r = dff->getPort(ID(R)); | ||||||
| 		val_cp = RTLIL::Const(dff->type[6] == 'P', 1); | 		val_cp = RTLIL::Const(dff->type[6] == 'P', 1); | ||||||
| 		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); | ||||||
|  | @ -293,39 +293,39 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) | ||||||
| 	else if (dff->type.begins_with("$_DFFE_") && dff->type.compare(9, 1, "_") == 0 && | 	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(ID(D)); | ||||||
| 		sig_q = dff->getPort("\\Q"); | 		sig_q = dff->getPort(ID(Q)); | ||||||
| 		sig_c = dff->getPort("\\C"); | 		sig_c = dff->getPort(ID(C)); | ||||||
| 		sig_e = dff->getPort("\\E"); | 		sig_e = dff->getPort(ID(E)); | ||||||
| 		val_cp = RTLIL::Const(dff->type[7] == 'P', 1); | 		val_cp = RTLIL::Const(dff->type[7] == 'P', 1); | ||||||
| 		val_ep = RTLIL::Const(dff->type[8] == 'P', 1); | 		val_ep = RTLIL::Const(dff->type[8] == 'P', 1); | ||||||
| 	} | 	} | ||||||
| 	else if (dff->type == "$ff") { | 	else if (dff->type == ID($ff)) { | ||||||
| 		sig_d = dff->getPort("\\D"); | 		sig_d = dff->getPort(ID(D)); | ||||||
| 		sig_q = dff->getPort("\\Q"); | 		sig_q = dff->getPort(ID(Q)); | ||||||
| 	} | 	} | ||||||
| 	else if (dff->type == "$dff") { | 	else if (dff->type == ID($dff)) { | ||||||
| 		sig_d = dff->getPort("\\D"); | 		sig_d = dff->getPort(ID(D)); | ||||||
| 		sig_q = dff->getPort("\\Q"); | 		sig_q = dff->getPort(ID(Q)); | ||||||
| 		sig_c = dff->getPort("\\CLK"); | 		sig_c = dff->getPort(ID(CLK)); | ||||||
| 		val_cp = RTLIL::Const(dff->parameters["\\CLK_POLARITY"].as_bool(), 1); | 		val_cp = RTLIL::Const(dff->parameters[ID(CLK_POLARITY)].as_bool(), 1); | ||||||
| 	} | 	} | ||||||
| 	else if (dff->type == "$dffe") { | 	else if (dff->type == ID($dffe)) { | ||||||
| 		sig_e = dff->getPort("\\EN"); | 		sig_e = dff->getPort(ID(EN)); | ||||||
| 		sig_d = dff->getPort("\\D"); | 		sig_d = dff->getPort(ID(D)); | ||||||
| 		sig_q = dff->getPort("\\Q"); | 		sig_q = dff->getPort(ID(Q)); | ||||||
| 		sig_c = dff->getPort("\\CLK"); | 		sig_c = dff->getPort(ID(CLK)); | ||||||
| 		val_cp = RTLIL::Const(dff->parameters["\\CLK_POLARITY"].as_bool(), 1); | 		val_cp = RTLIL::Const(dff->parameters[ID(CLK_POLARITY)].as_bool(), 1); | ||||||
| 		val_ep = RTLIL::Const(dff->parameters["\\EN_POLARITY"].as_bool(), 1); | 		val_ep = RTLIL::Const(dff->parameters[ID(EN_POLARITY)].as_bool(), 1); | ||||||
| 	} | 	} | ||||||
| 	else if (dff->type == "$adff") { | 	else if (dff->type == ID($adff)) { | ||||||
| 		sig_d = dff->getPort("\\D"); | 		sig_d = dff->getPort(ID(D)); | ||||||
| 		sig_q = dff->getPort("\\Q"); | 		sig_q = dff->getPort(ID(Q)); | ||||||
| 		sig_c = dff->getPort("\\CLK"); | 		sig_c = dff->getPort(ID(CLK)); | ||||||
| 		sig_r = dff->getPort("\\ARST"); | 		sig_r = dff->getPort(ID(ARST)); | ||||||
| 		val_cp = RTLIL::Const(dff->parameters["\\CLK_POLARITY"].as_bool(), 1); | 		val_cp = RTLIL::Const(dff->parameters[ID(CLK_POLARITY)].as_bool(), 1); | ||||||
| 		val_rp = RTLIL::Const(dff->parameters["\\ARST_POLARITY"].as_bool(), 1); | 		val_rp = RTLIL::Const(dff->parameters[ID(ARST_POLARITY)].as_bool(), 1); | ||||||
| 		val_rv = dff->parameters["\\ARST_VALUE"]; | 		val_rv = dff->parameters[ID(ARST_VALUE)]; | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 		log_abort(); | 		log_abort(); | ||||||
|  | @ -343,12 +343,12 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) | ||||||
| 		val_init.bits.push_back(bit.wire == NULL ? bit.data : RTLIL::State::Sx); | 		val_init.bits.push_back(bit.wire == NULL ? bit.data : RTLIL::State::Sx); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (dff->type.in("$ff", "$dff") && mux_drivers.has(sig_d)) { | 	if (dff->type.in(ID($ff), ID($dff)) && mux_drivers.has(sig_d)) { | ||||||
| 		std::set<RTLIL::Cell*> muxes; | 		std::set<RTLIL::Cell*> muxes; | ||||||
| 		mux_drivers.find(sig_d, muxes); | 		mux_drivers.find(sig_d, muxes); | ||||||
| 		for (auto mux : muxes) { | 		for (auto mux : muxes) { | ||||||
| 			RTLIL::SigSpec sig_a = assign_map(mux->getPort("\\A")); | 			RTLIL::SigSpec sig_a = assign_map(mux->getPort(ID(A))); | ||||||
| 			RTLIL::SigSpec sig_b = assign_map(mux->getPort("\\B")); | 			RTLIL::SigSpec sig_b = assign_map(mux->getPort(ID(B))); | ||||||
| 			if (sig_a == sig_q && sig_b.is_fully_const() && (!has_init || val_init == sig_b.as_const())) { | 			if (sig_a == sig_q && sig_b.is_fully_const() && (!has_init || val_init == sig_b.as_const())) { | ||||||
| 				mod->connect(sig_q, sig_b); | 				mod->connect(sig_q, sig_b); | ||||||
| 				goto delete_dff; | 				goto delete_dff; | ||||||
|  | @ -420,17 +420,17 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) | ||||||
| 
 | 
 | ||||||
| 		log("Removing unused reset from %s (%s) from module %s.\n", log_id(dff), log_id(dff->type), log_id(mod)); | 		log("Removing unused reset from %s (%s) from module %s.\n", log_id(dff), log_id(dff->type), log_id(mod)); | ||||||
| 
 | 
 | ||||||
| 		if (dff->type == "$adff") { | 		if (dff->type == ID($adff)) { | ||||||
| 			dff->type = "$dff"; | 			dff->type = ID($dff); | ||||||
| 			dff->unsetPort("\\ARST"); | 			dff->unsetPort(ID(ARST)); | ||||||
| 			dff->unsetParam("\\ARST_POLARITY"); | 			dff->unsetParam(ID(ARST_POLARITY)); | ||||||
| 			dff->unsetParam("\\ARST_VALUE"); | 			dff->unsetParam(ID(ARST_VALUE)); | ||||||
| 			return true; | 			return true; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		log_assert(dff->type.begins_with("$_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(ID(R)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// If enable signal is present, and is fully constant
 | 	// If enable signal is present, and is fully constant
 | ||||||
|  | @ -445,16 +445,16 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) | ||||||
| 
 | 
 | ||||||
| 		log("Removing unused enable from %s (%s) from module %s.\n", log_id(dff), log_id(dff->type), log_id(mod)); | 		log("Removing unused enable from %s (%s) from module %s.\n", log_id(dff), log_id(dff->type), log_id(mod)); | ||||||
| 
 | 
 | ||||||
| 		if (dff->type == "$dffe") { | 		if (dff->type == ID($dffe)) { | ||||||
| 			dff->type = "$dff"; | 			dff->type = ID($dff); | ||||||
| 			dff->unsetPort("\\EN"); | 			dff->unsetPort(ID(EN)); | ||||||
| 			dff->unsetParam("\\EN_POLARITY"); | 			dff->unsetParam(ID(EN_POLARITY)); | ||||||
| 			return true; | 			return true; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		log_assert(dff->type.begins_with("$_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(ID(E)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (sat && has_init && (!sig_r.size() || val_init == val_rv)) | 	if (sat && has_init && (!sig_r.size() || val_init == val_rv)) | ||||||
|  | @ -509,9 +509,9 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) | ||||||
| 				log("Setting constant %d-bit at position %d on %s (%s) from module %s.\n", sigbit_init_val ? 1 : 0, | 				log("Setting constant %d-bit at position %d on %s (%s) from module %s.\n", sigbit_init_val ? 1 : 0, | ||||||
| 						position, log_id(dff), log_id(dff->type), log_id(mod)); | 						position, log_id(dff), log_id(dff->type), log_id(mod)); | ||||||
| 
 | 
 | ||||||
| 				SigSpec tmp = dff->getPort("\\D"); | 				SigSpec tmp = dff->getPort(ID(D)); | ||||||
| 				tmp[position] = sigbit_init_val; | 				tmp[position] = sigbit_init_val; | ||||||
| 				dff->setPort("\\D", tmp); | 				dff->setPort(ID(D), tmp); | ||||||
| 
 | 
 | ||||||
| 				removed_sigbits = true; | 				removed_sigbits = true; | ||||||
| 			} | 			} | ||||||
|  | @ -528,7 +528,7 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) | ||||||
| 
 | 
 | ||||||
| delete_dff: | delete_dff: | ||||||
| 	log("Removing %s (%s) from module %s.\n", log_id(dff), log_id(dff->type), log_id(mod)); | 	log("Removing %s (%s) from module %s.\n", log_id(dff), log_id(dff->type), log_id(mod)); | ||||||
| 	remove_init_attr(dff->getPort("\\Q")); | 	remove_init_attr(dff->getPort(ID(Q))); | ||||||
| 	mod->remove(dff); | 	mod->remove(dff); | ||||||
| 
 | 
 | ||||||
| 	for (auto &entry : bit2driver) | 	for (auto &entry : bit2driver) | ||||||
|  | @ -588,8 +588,8 @@ struct OptRmdffPass : public Pass { | ||||||
| 
 | 
 | ||||||
| 			for (auto wire : module->wires()) | 			for (auto wire : module->wires()) | ||||||
| 			{ | 			{ | ||||||
| 				if (wire->attributes.count("\\init") != 0) { | 				if (wire->attributes.count(ID(init)) != 0) { | ||||||
| 					Const initval = wire->attributes.at("\\init"); | 					Const initval = wire->attributes.at(ID(init)); | ||||||
| 					for (int i = 0; i < GetSize(initval) && i < GetSize(wire); i++) | 					for (int i = 0; i < GetSize(initval) && i < GetSize(wire); i++) | ||||||
| 						if (initval[i] == State::S0 || initval[i] == State::S1) | 						if (initval[i] == State::S0 || initval[i] == State::S1) | ||||||
| 							dff_init_map.add(SigBit(wire, i), initval[i]); | 							dff_init_map.add(SigBit(wire, i), initval[i]); | ||||||
|  | @ -624,29 +624,29 @@ struct OptRmdffPass : public Pass { | ||||||
| 						} | 						} | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				if (cell->type.in("$mux", "$pmux")) { | 				if (cell->type.in(ID($mux), ID($pmux))) { | ||||||
| 					if (cell->getPort("\\A").size() == cell->getPort("\\B").size()) | 					if (cell->getPort(ID(A)).size() == cell->getPort(ID(B)).size()) | ||||||
| 						mux_drivers.insert(assign_map(cell->getPort("\\Y")), cell); | 						mux_drivers.insert(assign_map(cell->getPort(ID(Y))), cell); | ||||||
| 					continue; | 					continue; | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				if (!design->selected(module, cell)) | 				if (!design->selected(module, cell)) | ||||||
| 					continue; | 					continue; | ||||||
| 
 | 
 | ||||||
| 				if (cell->type.in("$_DFFSR_NNN_", "$_DFFSR_NNP_", "$_DFFSR_NPN_", "$_DFFSR_NPP_", | 				if (cell->type.in(ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_), | ||||||
| 						"$_DFFSR_PNN_", "$_DFFSR_PNP_", "$_DFFSR_PPN_", "$_DFFSR_PPP_", "$dffsr", | 						ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_), ID($dffsr), | ||||||
| 						"$_DLATCHSR_NNN_", "$_DLATCHSR_NNP_", "$_DLATCHSR_NPN_", "$_DLATCHSR_NPP_", | 						ID($_DLATCHSR_NNN_), ID($_DLATCHSR_NNP_), ID($_DLATCHSR_NPN_), ID($_DLATCHSR_NPP_), | ||||||
| 						"$_DLATCHSR_PNN_", "$_DLATCHSR_PNP_", "$_DLATCHSR_PPN_", "$_DLATCHSR_PPP_", "$dlatchsr")) | 						ID($_DLATCHSR_PNN_), ID($_DLATCHSR_PNP_), ID($_DLATCHSR_PPN_), ID($_DLATCHSR_PPP_), ID($dlatchsr))) | ||||||
| 					dffsr_list.push_back(cell->name); | 					dffsr_list.push_back(cell->name); | ||||||
| 
 | 
 | ||||||
| 				if (cell->type.in("$_FF_", "$_DFF_N_", "$_DFF_P_", | 				if (cell->type.in(ID($_FF_), ID($_DFF_N_), ID($_DFF_P_), | ||||||
| 						"$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_", | 						ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), | ||||||
| 						"$_DFF_PN0_", "$_DFF_PN1_", "$_DFF_PP0_", "$_DFF_PP1_", | 						ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_), | ||||||
| 						"$_DFFE_NN_", "$_DFFE_NP_", "$_DFFE_PN_", "$_DFFE_PP_", | 						ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_), | ||||||
| 						"$ff", "$dff", "$dffe", "$adff")) | 						ID($ff), ID($dff), ID($dffe), ID($adff))) | ||||||
| 					dff_list.push_back(cell->name); | 					dff_list.push_back(cell->name); | ||||||
| 
 | 
 | ||||||
| 				if (cell->type.in("$dlatch", "$_DLATCH_P_", "$_DLATCH_N_")) | 				if (cell->type.in(ID($dlatch), ID($_DLATCH_P_), ID($_DLATCH_N_))) | ||||||
| 					dlatch_list.push_back(cell->name); | 					dlatch_list.push_back(cell->name); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -46,7 +46,7 @@ struct OnehotDatabase | ||||||
| 
 | 
 | ||||||
| 		for (auto wire : module->wires()) | 		for (auto wire : module->wires()) | ||||||
| 		{ | 		{ | ||||||
| 			auto it = wire->attributes.find("\\init"); | 			auto it = wire->attributes.find(ID(init)); | ||||||
| 			if (it == wire->attributes.end()) | 			if (it == wire->attributes.end()) | ||||||
| 				continue; | 				continue; | ||||||
| 
 | 
 | ||||||
|  | @ -63,19 +63,19 @@ struct OnehotDatabase | ||||||
| 			vector<SigSpec> inputs; | 			vector<SigSpec> inputs; | ||||||
| 			SigSpec output; | 			SigSpec output; | ||||||
| 
 | 
 | ||||||
| 			if (cell->type.in("$adff", "$dff", "$dffe", "$dlatch", "$ff")) | 			if (cell->type.in(ID($adff), ID($dff), ID($dffe), ID($dlatch), ID($ff))) | ||||||
| 			{ | 			{ | ||||||
| 				output = cell->getPort("\\Q"); | 				output = cell->getPort(ID(Q)); | ||||||
| 				if (cell->type == "$adff") | 				if (cell->type == ID($adff)) | ||||||
| 					inputs.push_back(cell->getParam("\\ARST_VALUE")); | 					inputs.push_back(cell->getParam(ID(ARST_VALUE))); | ||||||
| 				inputs.push_back(cell->getPort("\\D")); | 				inputs.push_back(cell->getPort(ID(D))); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (cell->type.in("$mux", "$pmux")) | 			if (cell->type.in(ID($mux), ID($pmux))) | ||||||
| 			{ | 			{ | ||||||
| 				output = cell->getPort("\\Y"); | 				output = cell->getPort(ID(Y)); | ||||||
| 				inputs.push_back(cell->getPort("\\A")); | 				inputs.push_back(cell->getPort(ID(A))); | ||||||
| 				SigSpec B = cell->getPort("\\B"); | 				SigSpec B = cell->getPort(ID(B)); | ||||||
| 				for (int i = 0; i < GetSize(B); i += GetSize(output)) | 				for (int i = 0; i < GetSize(B); i += GetSize(output)) | ||||||
| 					inputs.push_back(B.extract(i, GetSize(output))); | 					inputs.push_back(B.extract(i, GetSize(output))); | ||||||
| 			} | 			} | ||||||
|  | @ -292,23 +292,23 @@ struct Pmux2ShiftxPass : public Pass { | ||||||
| 
 | 
 | ||||||
| 			for (auto cell : module->cells()) | 			for (auto cell : module->cells()) | ||||||
| 			{ | 			{ | ||||||
| 				if (cell->type == "$eq") | 				if (cell->type == ID($eq)) | ||||||
| 				{ | 				{ | ||||||
| 					dict<SigBit, State> bits; | 					dict<SigBit, State> bits; | ||||||
| 
 | 
 | ||||||
| 					SigSpec A = sigmap(cell->getPort("\\A")); | 					SigSpec A = sigmap(cell->getPort(ID(A))); | ||||||
| 					SigSpec B = sigmap(cell->getPort("\\B")); | 					SigSpec B = sigmap(cell->getPort(ID(B))); | ||||||
| 
 | 
 | ||||||
| 					int a_width = cell->getParam("\\A_WIDTH").as_int(); | 					int a_width = cell->getParam(ID(A_WIDTH)).as_int(); | ||||||
| 					int b_width = cell->getParam("\\B_WIDTH").as_int(); | 					int b_width = cell->getParam(ID(B_WIDTH)).as_int(); | ||||||
| 
 | 
 | ||||||
| 					if (a_width < b_width) { | 					if (a_width < b_width) { | ||||||
| 						bool a_signed = cell->getParam("\\A_SIGNED").as_int(); | 						bool a_signed = cell->getParam(ID(A_SIGNED)).as_int(); | ||||||
| 						A.extend_u0(b_width, a_signed); | 						A.extend_u0(b_width, a_signed); | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					if (b_width < a_width) { | 					if (b_width < a_width) { | ||||||
| 						bool b_signed = cell->getParam("\\B_SIGNED").as_int(); | 						bool b_signed = cell->getParam(ID(B_SIGNED)).as_int(); | ||||||
| 						B.extend_u0(a_width, b_signed); | 						B.extend_u0(a_width, b_signed); | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
|  | @ -335,15 +335,15 @@ struct Pmux2ShiftxPass : public Pass { | ||||||
| 						entry.second.bits.push_back(it.second); | 						entry.second.bits.push_back(it.second); | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					eqdb[sigmap(cell->getPort("\\Y")[0])] = entry; | 					eqdb[sigmap(cell->getPort(ID(Y))[0])] = entry; | ||||||
| 					goto next_cell; | 					goto next_cell; | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				if (cell->type == "$logic_not") | 				if (cell->type == ID($logic_not)) | ||||||
| 				{ | 				{ | ||||||
| 					dict<SigBit, State> bits; | 					dict<SigBit, State> bits; | ||||||
| 
 | 
 | ||||||
| 					SigSpec A = sigmap(cell->getPort("\\A")); | 					SigSpec A = sigmap(cell->getPort(ID(A))); | ||||||
| 
 | 
 | ||||||
| 					for (int i = 0; i < GetSize(A); i++) | 					for (int i = 0; i < GetSize(A); i++) | ||||||
| 						bits[A[i]] = State::S0; | 						bits[A[i]] = State::S0; | ||||||
|  | @ -356,7 +356,7 @@ struct Pmux2ShiftxPass : public Pass { | ||||||
| 						entry.second.bits.push_back(it.second); | 						entry.second.bits.push_back(it.second); | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					eqdb[sigmap(cell->getPort("\\Y")[0])] = entry; | 					eqdb[sigmap(cell->getPort(ID(Y))[0])] = entry; | ||||||
| 					goto next_cell; | 					goto next_cell; | ||||||
| 				} | 				} | ||||||
| 		next_cell:; | 		next_cell:; | ||||||
|  | @ -364,11 +364,11 @@ struct Pmux2ShiftxPass : public Pass { | ||||||
| 
 | 
 | ||||||
| 			for (auto cell : module->selected_cells()) | 			for (auto cell : module->selected_cells()) | ||||||
| 			{ | 			{ | ||||||
| 				if (cell->type != "$pmux") | 				if (cell->type != ID($pmux)) | ||||||
| 					continue; | 					continue; | ||||||
| 
 | 
 | ||||||
| 				string src = cell->get_src_attribute(); | 				string src = cell->get_src_attribute(); | ||||||
| 				int width = cell->getParam("\\WIDTH").as_int(); | 				int width = cell->getParam(ID(WIDTH)).as_int(); | ||||||
| 				int width_bits = ceil_log2(width); | 				int width_bits = ceil_log2(width); | ||||||
| 				int extwidth = width; | 				int extwidth = width; | ||||||
| 
 | 
 | ||||||
|  | @ -377,9 +377,9 @@ struct Pmux2ShiftxPass : public Pass { | ||||||
| 
 | 
 | ||||||
| 				dict<SigSpec, pool<int>> seldb; | 				dict<SigSpec, pool<int>> seldb; | ||||||
| 
 | 
 | ||||||
| 				SigSpec A = cell->getPort("\\A"); | 				SigSpec A = cell->getPort(ID(A)); | ||||||
| 				SigSpec B = cell->getPort("\\B"); | 				SigSpec B = cell->getPort(ID(B)); | ||||||
| 				SigSpec S = sigmap(cell->getPort("\\S")); | 				SigSpec S = sigmap(cell->getPort(ID(S))); | ||||||
| 				for (int i = 0; i < GetSize(S); i++) | 				for (int i = 0; i < GetSize(S); i++) | ||||||
| 				{ | 				{ | ||||||
| 					if (!eqdb.count(S[i])) | 					if (!eqdb.count(S[i])) | ||||||
|  | @ -400,8 +400,8 @@ struct Pmux2ShiftxPass : public Pass { | ||||||
| 					log("  data width: %d (next power-of-2 = %d, log2 = %d)\n", width, extwidth, width_bits); | 					log("  data width: %d (next power-of-2 = %d, log2 = %d)\n", width, extwidth, width_bits); | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				SigSpec updated_S = cell->getPort("\\S"); | 				SigSpec updated_S = cell->getPort(ID(S)); | ||||||
| 				SigSpec updated_B = cell->getPort("\\B"); | 				SigSpec updated_B = cell->getPort(ID(B)); | ||||||
| 
 | 
 | ||||||
| 				while (!seldb.empty()) | 				while (!seldb.empty()) | ||||||
| 				{ | 				{ | ||||||
|  | @ -727,9 +727,9 @@ struct Pmux2ShiftxPass : public Pass { | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				// update $pmux cell
 | 				// update $pmux cell
 | ||||||
| 				cell->setPort("\\S", updated_S); | 				cell->setPort(ID(S), updated_S); | ||||||
| 				cell->setPort("\\B", updated_B); | 				cell->setPort(ID(B), updated_B); | ||||||
| 				cell->setParam("\\S_WIDTH", GetSize(updated_S)); | 				cell->setParam(ID(S_WIDTH), GetSize(updated_S)); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -779,22 +779,22 @@ struct OnehotPass : public Pass { | ||||||
| 
 | 
 | ||||||
| 			for (auto cell : module->selected_cells()) | 			for (auto cell : module->selected_cells()) | ||||||
| 			{ | 			{ | ||||||
| 				if (cell->type != "$eq") | 				if (cell->type != ID($eq)) | ||||||
| 					continue; | 					continue; | ||||||
| 
 | 
 | ||||||
| 				SigSpec A = sigmap(cell->getPort("\\A")); | 				SigSpec A = sigmap(cell->getPort(ID(A))); | ||||||
| 				SigSpec B = sigmap(cell->getPort("\\B")); | 				SigSpec B = sigmap(cell->getPort(ID(B))); | ||||||
| 
 | 
 | ||||||
| 				int a_width = cell->getParam("\\A_WIDTH").as_int(); | 				int a_width = cell->getParam(ID(A_WIDTH)).as_int(); | ||||||
| 				int b_width = cell->getParam("\\B_WIDTH").as_int(); | 				int b_width = cell->getParam(ID(B_WIDTH)).as_int(); | ||||||
| 
 | 
 | ||||||
| 				if (a_width < b_width) { | 				if (a_width < b_width) { | ||||||
| 					bool a_signed = cell->getParam("\\A_SIGNED").as_int(); | 					bool a_signed = cell->getParam(ID(A_SIGNED)).as_int(); | ||||||
| 					A.extend_u0(b_width, a_signed); | 					A.extend_u0(b_width, a_signed); | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				if (b_width < a_width) { | 				if (b_width < a_width) { | ||||||
| 					bool b_signed = cell->getParam("\\B_SIGNED").as_int(); | 					bool b_signed = cell->getParam(ID(B_SIGNED)).as_int(); | ||||||
| 					B.extend_u0(a_width, b_signed); | 					B.extend_u0(a_width, b_signed); | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
|  | @ -830,7 +830,7 @@ struct OnehotPass : public Pass { | ||||||
| 					continue; | 					continue; | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				SigSpec Y = cell->getPort("\\Y"); | 				SigSpec Y = cell->getPort(ID(Y)); | ||||||
| 
 | 
 | ||||||
| 				if (not_onehot) | 				if (not_onehot) | ||||||
| 				{ | 				{ | ||||||
|  |  | ||||||
|  | @ -89,8 +89,8 @@ struct ShareWorker | ||||||
| 			queue_bits.clear(); | 			queue_bits.clear(); | ||||||
| 
 | 
 | ||||||
| 			for (auto &pbit : portbits) { | 			for (auto &pbit : portbits) { | ||||||
| 				if (pbit.cell->type == "$mux" || pbit.cell->type == "$pmux") { | 				if (pbit.cell->type == ID($mux) || pbit.cell->type == ID($pmux)) { | ||||||
| 					pool<RTLIL::SigBit> bits = modwalker.sigmap(pbit.cell->getPort("\\S")).to_sigbit_pool(); | 					pool<RTLIL::SigBit> bits = modwalker.sigmap(pbit.cell->getPort(ID(S))).to_sigbit_pool(); | ||||||
| 					terminal_bits.insert(bits.begin(), bits.end()); | 					terminal_bits.insert(bits.begin(), bits.end()); | ||||||
| 					queue_bits.insert(bits.begin(), bits.end()); | 					queue_bits.insert(bits.begin(), bits.end()); | ||||||
| 					visited_cells.insert(pbit.cell); | 					visited_cells.insert(pbit.cell); | ||||||
|  | @ -128,7 +128,7 @@ struct ShareWorker | ||||||
| 	static int bits_macc(RTLIL::Cell *c) | 	static int bits_macc(RTLIL::Cell *c) | ||||||
| 	{ | 	{ | ||||||
| 		Macc m(c); | 		Macc m(c); | ||||||
| 		int width = GetSize(c->getPort("\\Y")); | 		int width = GetSize(c->getPort(ID(Y))); | ||||||
| 		return bits_macc(m, width); | 		return bits_macc(m, width); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -242,7 +242,7 @@ struct ShareWorker | ||||||
| 	{ | 	{ | ||||||
| 		Macc m1(c1), m2(c2), supermacc; | 		Macc m1(c1), m2(c2), supermacc; | ||||||
| 
 | 
 | ||||||
| 		int w1 = GetSize(c1->getPort("\\Y")), w2 = GetSize(c2->getPort("\\Y")); | 		int w1 = GetSize(c1->getPort(ID(Y))), w2 = GetSize(c2->getPort(ID(Y))); | ||||||
| 		int width = max(w1, w2); | 		int width = max(w1, w2); | ||||||
| 
 | 
 | ||||||
| 		m1.optimize(w1); | 		m1.optimize(w1); | ||||||
|  | @ -328,11 +328,11 @@ struct ShareWorker | ||||||
| 		{ | 		{ | ||||||
| 			RTLIL::SigSpec sig_y = module->addWire(NEW_ID, width); | 			RTLIL::SigSpec sig_y = module->addWire(NEW_ID, width); | ||||||
| 
 | 
 | ||||||
| 			supercell_aux->insert(module->addPos(NEW_ID, sig_y, c1->getPort("\\Y"))); | 			supercell_aux->insert(module->addPos(NEW_ID, sig_y, c1->getPort(ID(Y)))); | ||||||
| 			supercell_aux->insert(module->addPos(NEW_ID, sig_y, c2->getPort("\\Y"))); | 			supercell_aux->insert(module->addPos(NEW_ID, sig_y, c2->getPort(ID(Y)))); | ||||||
| 
 | 
 | ||||||
| 			supercell->setParam("\\Y_WIDTH", width); | 			supercell->setParam(ID(Y_WIDTH), width); | ||||||
| 			supercell->setPort("\\Y", sig_y); | 			supercell->setPort(ID(Y), sig_y); | ||||||
| 
 | 
 | ||||||
| 			supermacc.optimize(width); | 			supermacc.optimize(width); | ||||||
| 			supermacc.to_cell(supercell); | 			supermacc.to_cell(supercell); | ||||||
|  | @ -368,22 +368,22 @@ struct ShareWorker | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$memrd") { | 			if (cell->type == ID($memrd)) { | ||||||
| 				if (cell->parameters.at("\\CLK_ENABLE").as_bool()) | 				if (cell->parameters.at(ID(CLK_ENABLE)).as_bool()) | ||||||
| 					continue; | 					continue; | ||||||
| 				if (config.opt_aggressive || !modwalker.sigmap(cell->getPort("\\ADDR")).is_fully_const()) | 				if (config.opt_aggressive || !modwalker.sigmap(cell->getPort(ID(ADDR))).is_fully_const()) | ||||||
| 					shareable_cells.insert(cell); | 					shareable_cells.insert(cell); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (cell->type.in("$mul", "$div", "$mod")) { | 			if (cell->type.in(ID($mul), ID($div), ID($mod))) { | ||||||
| 				if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() >= 4) | 				if (config.opt_aggressive || cell->parameters.at(ID(Y_WIDTH)).as_int() >= 4) | ||||||
| 					shareable_cells.insert(cell); | 					shareable_cells.insert(cell); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (cell->type.in("$shl", "$shr", "$sshl", "$sshr")) { | 			if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr))) { | ||||||
| 				if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() >= 8) | 				if (config.opt_aggressive || cell->parameters.at(ID(Y_WIDTH)).as_int() >= 8) | ||||||
| 					shareable_cells.insert(cell); | 					shareable_cells.insert(cell); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|  | @ -401,9 +401,9 @@ struct ShareWorker | ||||||
| 		if (c1->type != c2->type) | 		if (c1->type != c2->type) | ||||||
| 			return false; | 			return false; | ||||||
| 
 | 
 | ||||||
| 		if (c1->type == "$memrd") | 		if (c1->type == ID($memrd)) | ||||||
| 		{ | 		{ | ||||||
| 			if (c1->parameters.at("\\MEMID").decode_string() != c2->parameters.at("\\MEMID").decode_string()) | 			if (c1->parameters.at(ID(MEMID)).decode_string() != c2->parameters.at(ID(MEMID)).decode_string()) | ||||||
| 				return false; | 				return false; | ||||||
| 
 | 
 | ||||||
| 			return true; | 			return true; | ||||||
|  | @ -413,11 +413,11 @@ struct ShareWorker | ||||||
| 		{ | 		{ | ||||||
| 			if (!config.opt_aggressive) | 			if (!config.opt_aggressive) | ||||||
| 			{ | 			{ | ||||||
| 				int a1_width = c1->parameters.at("\\A_WIDTH").as_int(); | 				int a1_width = c1->parameters.at(ID(A_WIDTH)).as_int(); | ||||||
| 				int y1_width = c1->parameters.at("\\Y_WIDTH").as_int(); | 				int y1_width = c1->parameters.at(ID(Y_WIDTH)).as_int(); | ||||||
| 
 | 
 | ||||||
| 				int a2_width = c2->parameters.at("\\A_WIDTH").as_int(); | 				int a2_width = c2->parameters.at(ID(A_WIDTH)).as_int(); | ||||||
| 				int y2_width = c2->parameters.at("\\Y_WIDTH").as_int(); | 				int y2_width = c2->parameters.at(ID(Y_WIDTH)).as_int(); | ||||||
| 
 | 
 | ||||||
| 				if (max(a1_width, a2_width) > 2 * min(a1_width, a2_width)) return false; | 				if (max(a1_width, a2_width) > 2 * min(a1_width, a2_width)) return false; | ||||||
| 				if (max(y1_width, y2_width) > 2 * min(y1_width, y2_width)) return false; | 				if (max(y1_width, y2_width) > 2 * min(y1_width, y2_width)) return false; | ||||||
|  | @ -426,17 +426,17 @@ struct ShareWorker | ||||||
| 			return true; | 			return true; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (config.generic_bin_ops.count(c1->type) || c1->type == "$alu") | 		if (config.generic_bin_ops.count(c1->type) || c1->type == ID($alu)) | ||||||
| 		{ | 		{ | ||||||
| 			if (!config.opt_aggressive) | 			if (!config.opt_aggressive) | ||||||
| 			{ | 			{ | ||||||
| 				int a1_width = c1->parameters.at("\\A_WIDTH").as_int(); | 				int a1_width = c1->parameters.at(ID(A_WIDTH)).as_int(); | ||||||
| 				int b1_width = c1->parameters.at("\\B_WIDTH").as_int(); | 				int b1_width = c1->parameters.at(ID(B_WIDTH)).as_int(); | ||||||
| 				int y1_width = c1->parameters.at("\\Y_WIDTH").as_int(); | 				int y1_width = c1->parameters.at(ID(Y_WIDTH)).as_int(); | ||||||
| 
 | 
 | ||||||
| 				int a2_width = c2->parameters.at("\\A_WIDTH").as_int(); | 				int a2_width = c2->parameters.at(ID(A_WIDTH)).as_int(); | ||||||
| 				int b2_width = c2->parameters.at("\\B_WIDTH").as_int(); | 				int b2_width = c2->parameters.at(ID(B_WIDTH)).as_int(); | ||||||
| 				int y2_width = c2->parameters.at("\\Y_WIDTH").as_int(); | 				int y2_width = c2->parameters.at(ID(Y_WIDTH)).as_int(); | ||||||
| 
 | 
 | ||||||
| 				if (max(a1_width, a2_width) > 2 * min(a1_width, a2_width)) return false; | 				if (max(a1_width, a2_width) > 2 * min(a1_width, a2_width)) return false; | ||||||
| 				if (max(b1_width, b2_width) > 2 * min(b1_width, b2_width)) return false; | 				if (max(b1_width, b2_width) > 2 * min(b1_width, b2_width)) return false; | ||||||
|  | @ -450,13 +450,13 @@ struct ShareWorker | ||||||
| 		{ | 		{ | ||||||
| 			if (!config.opt_aggressive) | 			if (!config.opt_aggressive) | ||||||
| 			{ | 			{ | ||||||
| 				int a1_width = c1->parameters.at("\\A_WIDTH").as_int(); | 				int a1_width = c1->parameters.at(ID(A_WIDTH)).as_int(); | ||||||
| 				int b1_width = c1->parameters.at("\\B_WIDTH").as_int(); | 				int b1_width = c1->parameters.at(ID(B_WIDTH)).as_int(); | ||||||
| 				int y1_width = c1->parameters.at("\\Y_WIDTH").as_int(); | 				int y1_width = c1->parameters.at(ID(Y_WIDTH)).as_int(); | ||||||
| 
 | 
 | ||||||
| 				int a2_width = c2->parameters.at("\\A_WIDTH").as_int(); | 				int a2_width = c2->parameters.at(ID(A_WIDTH)).as_int(); | ||||||
| 				int b2_width = c2->parameters.at("\\B_WIDTH").as_int(); | 				int b2_width = c2->parameters.at(ID(B_WIDTH)).as_int(); | ||||||
| 				int y2_width = c2->parameters.at("\\Y_WIDTH").as_int(); | 				int y2_width = c2->parameters.at(ID(Y_WIDTH)).as_int(); | ||||||
| 
 | 
 | ||||||
| 				int min1_width = min(a1_width, b1_width); | 				int min1_width = min(a1_width, b1_width); | ||||||
| 				int max1_width = max(a1_width, b1_width); | 				int max1_width = max(a1_width, b1_width); | ||||||
|  | @ -472,7 +472,7 @@ struct ShareWorker | ||||||
| 			return true; | 			return true; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (c1->type == "$macc") | 		if (c1->type == ID($macc)) | ||||||
| 		{ | 		{ | ||||||
| 			if (!config.opt_aggressive) | 			if (!config.opt_aggressive) | ||||||
| 				if (share_macc(c1, c2) > 2 * min(bits_macc(c1), bits_macc(c2))) return false; | 				if (share_macc(c1, c2) > 2 * min(bits_macc(c1), bits_macc(c2))) return false; | ||||||
|  | @ -510,27 +510,27 @@ struct ShareWorker | ||||||
| 
 | 
 | ||||||
| 		if (config.generic_uni_ops.count(c1->type)) | 		if (config.generic_uni_ops.count(c1->type)) | ||||||
| 		{ | 		{ | ||||||
| 			if (c1->parameters.at("\\A_SIGNED").as_bool() != c2->parameters.at("\\A_SIGNED").as_bool()) | 			if (c1->parameters.at(ID(A_SIGNED)).as_bool() != c2->parameters.at(ID(A_SIGNED)).as_bool()) | ||||||
| 			{ | 			{ | ||||||
| 				RTLIL::Cell *unsigned_cell = c1->parameters.at("\\A_SIGNED").as_bool() ? c2 : c1; | 				RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(A_SIGNED)).as_bool() ? c2 : c1; | ||||||
| 				if (unsigned_cell->getPort("\\A").to_sigbit_vector().back() != RTLIL::State::S0) { | 				if (unsigned_cell->getPort(ID(A)).to_sigbit_vector().back() != RTLIL::State::S0) { | ||||||
| 					unsigned_cell->parameters.at("\\A_WIDTH") = unsigned_cell->parameters.at("\\A_WIDTH").as_int() + 1; | 					unsigned_cell->parameters.at(ID(A_WIDTH)) = unsigned_cell->parameters.at(ID(A_WIDTH)).as_int() + 1; | ||||||
| 					RTLIL::SigSpec new_a = unsigned_cell->getPort("\\A"); | 					RTLIL::SigSpec new_a = unsigned_cell->getPort(ID(A)); | ||||||
| 					new_a.append_bit(RTLIL::State::S0); | 					new_a.append_bit(RTLIL::State::S0); | ||||||
| 					unsigned_cell->setPort("\\A", new_a); | 					unsigned_cell->setPort(ID(A), new_a); | ||||||
| 				} | 				} | ||||||
| 				unsigned_cell->parameters.at("\\A_SIGNED") = true; | 				unsigned_cell->parameters.at(ID(A_SIGNED)) = true; | ||||||
| 				unsigned_cell->check(); | 				unsigned_cell->check(); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			bool a_signed = c1->parameters.at("\\A_SIGNED").as_bool(); | 			bool a_signed = c1->parameters.at(ID(A_SIGNED)).as_bool(); | ||||||
| 			log_assert(a_signed == c2->parameters.at("\\A_SIGNED").as_bool()); | 			log_assert(a_signed == c2->parameters.at(ID(A_SIGNED)).as_bool()); | ||||||
| 
 | 
 | ||||||
| 			RTLIL::SigSpec a1 = c1->getPort("\\A"); | 			RTLIL::SigSpec a1 = c1->getPort(ID(A)); | ||||||
| 			RTLIL::SigSpec y1 = c1->getPort("\\Y"); | 			RTLIL::SigSpec y1 = c1->getPort(ID(Y)); | ||||||
| 
 | 
 | ||||||
| 			RTLIL::SigSpec a2 = c2->getPort("\\A"); | 			RTLIL::SigSpec a2 = c2->getPort(ID(A)); | ||||||
| 			RTLIL::SigSpec y2 = c2->getPort("\\Y"); | 			RTLIL::SigSpec y2 = c2->getPort(ID(Y)); | ||||||
| 
 | 
 | ||||||
| 			int a_width = max(a1.size(), a2.size()); | 			int a_width = max(a1.size(), a2.size()); | ||||||
| 			int y_width = max(y1.size(), y2.size()); | 			int y_width = max(y1.size(), y2.size()); | ||||||
|  | @ -544,11 +544,11 @@ struct ShareWorker | ||||||
| 			RTLIL::Wire *y = module->addWire(NEW_ID, y_width); | 			RTLIL::Wire *y = module->addWire(NEW_ID, y_width); | ||||||
| 
 | 
 | ||||||
| 			RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type); | 			RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type); | ||||||
| 			supercell->parameters["\\A_SIGNED"] = a_signed; | 			supercell->parameters[ID(A_SIGNED)] = a_signed; | ||||||
| 			supercell->parameters["\\A_WIDTH"] = a_width; | 			supercell->parameters[ID(A_WIDTH)] = a_width; | ||||||
| 			supercell->parameters["\\Y_WIDTH"] = y_width; | 			supercell->parameters[ID(Y_WIDTH)] = y_width; | ||||||
| 			supercell->setPort("\\A", a); | 			supercell->setPort(ID(A), a); | ||||||
| 			supercell->setPort("\\Y", y); | 			supercell->setPort(ID(Y), y); | ||||||
| 
 | 
 | ||||||
| 			supercell_aux.insert(module->addPos(NEW_ID, y, y1)); | 			supercell_aux.insert(module->addPos(NEW_ID, y, y1)); | ||||||
| 			supercell_aux.insert(module->addPos(NEW_ID, y, y2)); | 			supercell_aux.insert(module->addPos(NEW_ID, y, y2)); | ||||||
|  | @ -557,54 +557,54 @@ struct ShareWorker | ||||||
| 			return supercell; | 			return supercell; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (config.generic_bin_ops.count(c1->type) || config.generic_cbin_ops.count(c1->type) || c1->type == "$alu") | 		if (config.generic_bin_ops.count(c1->type) || config.generic_cbin_ops.count(c1->type) || c1->type == ID($alu)) | ||||||
| 		{ | 		{ | ||||||
| 			bool modified_src_cells = false; | 			bool modified_src_cells = false; | ||||||
| 
 | 
 | ||||||
| 			if (config.generic_cbin_ops.count(c1->type)) | 			if (config.generic_cbin_ops.count(c1->type)) | ||||||
| 			{ | 			{ | ||||||
| 				int score_unflipped = max(c1->parameters.at("\\A_WIDTH").as_int(), c2->parameters.at("\\A_WIDTH").as_int()) + | 				int score_unflipped = max(c1->parameters.at(ID(A_WIDTH)).as_int(), c2->parameters.at(ID(A_WIDTH)).as_int()) + | ||||||
| 						max(c1->parameters.at("\\B_WIDTH").as_int(), c2->parameters.at("\\B_WIDTH").as_int()); | 						max(c1->parameters.at(ID(B_WIDTH)).as_int(), c2->parameters.at(ID(B_WIDTH)).as_int()); | ||||||
| 
 | 
 | ||||||
| 				int score_flipped = max(c1->parameters.at("\\A_WIDTH").as_int(), c2->parameters.at("\\B_WIDTH").as_int()) + | 				int score_flipped = max(c1->parameters.at(ID(A_WIDTH)).as_int(), c2->parameters.at(ID(B_WIDTH)).as_int()) + | ||||||
| 						max(c1->parameters.at("\\B_WIDTH").as_int(), c2->parameters.at("\\A_WIDTH").as_int()); | 						max(c1->parameters.at(ID(B_WIDTH)).as_int(), c2->parameters.at(ID(A_WIDTH)).as_int()); | ||||||
| 
 | 
 | ||||||
| 				if (score_flipped < score_unflipped) | 				if (score_flipped < score_unflipped) | ||||||
| 				{ | 				{ | ||||||
| 					RTLIL::SigSpec tmp = c2->getPort("\\A"); | 					RTLIL::SigSpec tmp = c2->getPort(ID(A)); | ||||||
| 					c2->setPort("\\A", c2->getPort("\\B")); | 					c2->setPort(ID(A), c2->getPort(ID(B))); | ||||||
| 					c2->setPort("\\B", tmp); | 					c2->setPort(ID(B), tmp); | ||||||
| 
 | 
 | ||||||
| 					std::swap(c2->parameters.at("\\A_WIDTH"), c2->parameters.at("\\B_WIDTH")); | 					std::swap(c2->parameters.at(ID(A_WIDTH)), c2->parameters.at(ID(B_WIDTH))); | ||||||
| 					std::swap(c2->parameters.at("\\A_SIGNED"), c2->parameters.at("\\B_SIGNED")); | 					std::swap(c2->parameters.at(ID(A_SIGNED)), c2->parameters.at(ID(B_SIGNED))); | ||||||
| 					modified_src_cells = true; | 					modified_src_cells = true; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (c1->parameters.at("\\A_SIGNED").as_bool() != c2->parameters.at("\\A_SIGNED").as_bool()) | 			if (c1->parameters.at(ID(A_SIGNED)).as_bool() != c2->parameters.at(ID(A_SIGNED)).as_bool()) | ||||||
| 
 | 
 | ||||||
| 			{ | 			{ | ||||||
| 				RTLIL::Cell *unsigned_cell = c1->parameters.at("\\A_SIGNED").as_bool() ? c2 : c1; | 				RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(A_SIGNED)).as_bool() ? c2 : c1; | ||||||
| 				if (unsigned_cell->getPort("\\A").to_sigbit_vector().back() != RTLIL::State::S0) { | 				if (unsigned_cell->getPort(ID(A)).to_sigbit_vector().back() != RTLIL::State::S0) { | ||||||
| 					unsigned_cell->parameters.at("\\A_WIDTH") = unsigned_cell->parameters.at("\\A_WIDTH").as_int() + 1; | 					unsigned_cell->parameters.at(ID(A_WIDTH)) = unsigned_cell->parameters.at(ID(A_WIDTH)).as_int() + 1; | ||||||
| 					RTLIL::SigSpec new_a = unsigned_cell->getPort("\\A"); | 					RTLIL::SigSpec new_a = unsigned_cell->getPort(ID(A)); | ||||||
| 					new_a.append_bit(RTLIL::State::S0); | 					new_a.append_bit(RTLIL::State::S0); | ||||||
| 					unsigned_cell->setPort("\\A", new_a); | 					unsigned_cell->setPort(ID(A), new_a); | ||||||
| 				} | 				} | ||||||
| 				unsigned_cell->parameters.at("\\A_SIGNED") = true; | 				unsigned_cell->parameters.at(ID(A_SIGNED)) = true; | ||||||
| 				modified_src_cells = true; | 				modified_src_cells = true; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (c1->parameters.at("\\B_SIGNED").as_bool() != c2->parameters.at("\\B_SIGNED").as_bool()) | 			if (c1->parameters.at(ID(B_SIGNED)).as_bool() != c2->parameters.at(ID(B_SIGNED)).as_bool()) | ||||||
| 			{ | 			{ | ||||||
| 				RTLIL::Cell *unsigned_cell = c1->parameters.at("\\B_SIGNED").as_bool() ? c2 : c1; | 				RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(B_SIGNED)).as_bool() ? c2 : c1; | ||||||
| 				if (unsigned_cell->getPort("\\B").to_sigbit_vector().back() != RTLIL::State::S0) { | 				if (unsigned_cell->getPort(ID(B)).to_sigbit_vector().back() != RTLIL::State::S0) { | ||||||
| 					unsigned_cell->parameters.at("\\B_WIDTH") = unsigned_cell->parameters.at("\\B_WIDTH").as_int() + 1; | 					unsigned_cell->parameters.at(ID(B_WIDTH)) = unsigned_cell->parameters.at(ID(B_WIDTH)).as_int() + 1; | ||||||
| 					RTLIL::SigSpec new_b = unsigned_cell->getPort("\\B"); | 					RTLIL::SigSpec new_b = unsigned_cell->getPort(ID(B)); | ||||||
| 					new_b.append_bit(RTLIL::State::S0); | 					new_b.append_bit(RTLIL::State::S0); | ||||||
| 					unsigned_cell->setPort("\\B", new_b); | 					unsigned_cell->setPort(ID(B), new_b); | ||||||
| 				} | 				} | ||||||
| 				unsigned_cell->parameters.at("\\B_SIGNED") = true; | 				unsigned_cell->parameters.at(ID(B_SIGNED)) = true; | ||||||
| 				modified_src_cells = true; | 				modified_src_cells = true; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | @ -613,28 +613,28 @@ struct ShareWorker | ||||||
| 				c2->check(); | 				c2->check(); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			bool a_signed = c1->parameters.at("\\A_SIGNED").as_bool(); | 			bool a_signed = c1->parameters.at(ID(A_SIGNED)).as_bool(); | ||||||
| 			bool b_signed = c1->parameters.at("\\B_SIGNED").as_bool(); | 			bool b_signed = c1->parameters.at(ID(B_SIGNED)).as_bool(); | ||||||
| 
 | 
 | ||||||
| 			log_assert(a_signed == c2->parameters.at("\\A_SIGNED").as_bool()); | 			log_assert(a_signed == c2->parameters.at(ID(A_SIGNED)).as_bool()); | ||||||
| 			log_assert(b_signed == c2->parameters.at("\\B_SIGNED").as_bool()); | 			log_assert(b_signed == c2->parameters.at(ID(B_SIGNED)).as_bool()); | ||||||
| 
 | 
 | ||||||
| 			if (c1->type == "$shl" || c1->type == "$shr" || c1->type == "$sshl" || c1->type == "$sshr") | 			if (c1->type == ID($shl) || c1->type == ID($shr) || c1->type == ID($sshl) || c1->type == ID($sshr)) | ||||||
| 				b_signed = false; | 				b_signed = false; | ||||||
| 
 | 
 | ||||||
| 			RTLIL::SigSpec a1 = c1->getPort("\\A"); | 			RTLIL::SigSpec a1 = c1->getPort(ID(A)); | ||||||
| 			RTLIL::SigSpec b1 = c1->getPort("\\B"); | 			RTLIL::SigSpec b1 = c1->getPort(ID(B)); | ||||||
| 			RTLIL::SigSpec y1 = c1->getPort("\\Y"); | 			RTLIL::SigSpec y1 = c1->getPort(ID(Y)); | ||||||
| 
 | 
 | ||||||
| 			RTLIL::SigSpec a2 = c2->getPort("\\A"); | 			RTLIL::SigSpec a2 = c2->getPort(ID(A)); | ||||||
| 			RTLIL::SigSpec b2 = c2->getPort("\\B"); | 			RTLIL::SigSpec b2 = c2->getPort(ID(B)); | ||||||
| 			RTLIL::SigSpec y2 = c2->getPort("\\Y"); | 			RTLIL::SigSpec y2 = c2->getPort(ID(Y)); | ||||||
| 
 | 
 | ||||||
| 			int a_width = max(a1.size(), a2.size()); | 			int a_width = max(a1.size(), a2.size()); | ||||||
| 			int b_width = max(b1.size(), b2.size()); | 			int b_width = max(b1.size(), b2.size()); | ||||||
| 			int y_width = max(y1.size(), y2.size()); | 			int y_width = max(y1.size(), y2.size()); | ||||||
| 
 | 
 | ||||||
| 			if (c1->type == "$shr" && a_signed) | 			if (c1->type == ID($shr) && a_signed) | ||||||
| 			{ | 			{ | ||||||
| 				a_width = max(y_width, a_width); | 				a_width = max(y_width, a_width); | ||||||
| 
 | 
 | ||||||
|  | @ -660,43 +660,43 @@ struct ShareWorker | ||||||
| 			supercell_aux.insert(module->addMux(NEW_ID, b2, b1, act, b)); | 			supercell_aux.insert(module->addMux(NEW_ID, b2, b1, act, b)); | ||||||
| 
 | 
 | ||||||
| 			RTLIL::Wire *y = module->addWire(NEW_ID, y_width); | 			RTLIL::Wire *y = module->addWire(NEW_ID, y_width); | ||||||
| 			RTLIL::Wire *x = c1->type == "$alu" ? module->addWire(NEW_ID, y_width) : nullptr; | 			RTLIL::Wire *x = c1->type == ID($alu) ? module->addWire(NEW_ID, y_width) : nullptr; | ||||||
| 			RTLIL::Wire *co = c1->type == "$alu" ? module->addWire(NEW_ID, y_width) : nullptr; | 			RTLIL::Wire *co = c1->type == ID($alu) ? module->addWire(NEW_ID, y_width) : nullptr; | ||||||
| 
 | 
 | ||||||
| 			RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type); | 			RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type); | ||||||
| 			supercell->parameters["\\A_SIGNED"] = a_signed; | 			supercell->parameters[ID(A_SIGNED)] = a_signed; | ||||||
| 			supercell->parameters["\\B_SIGNED"] = b_signed; | 			supercell->parameters[ID(B_SIGNED)] = b_signed; | ||||||
| 			supercell->parameters["\\A_WIDTH"] = a_width; | 			supercell->parameters[ID(A_WIDTH)] = a_width; | ||||||
| 			supercell->parameters["\\B_WIDTH"] = b_width; | 			supercell->parameters[ID(B_WIDTH)] = b_width; | ||||||
| 			supercell->parameters["\\Y_WIDTH"] = y_width; | 			supercell->parameters[ID(Y_WIDTH)] = y_width; | ||||||
| 			supercell->setPort("\\A", a); | 			supercell->setPort(ID(A), a); | ||||||
| 			supercell->setPort("\\B", b); | 			supercell->setPort(ID(B), b); | ||||||
| 			supercell->setPort("\\Y", y); | 			supercell->setPort(ID(Y), y); | ||||||
| 			if (c1->type == "$alu") { | 			if (c1->type == ID($alu)) { | ||||||
| 				RTLIL::Wire *ci = module->addWire(NEW_ID), *bi = module->addWire(NEW_ID); | 				RTLIL::Wire *ci = module->addWire(NEW_ID), *bi = module->addWire(NEW_ID); | ||||||
| 				supercell_aux.insert(module->addMux(NEW_ID, c2->getPort("\\CI"), c1->getPort("\\CI"), act, ci)); | 				supercell_aux.insert(module->addMux(NEW_ID, c2->getPort(ID(CI)), c1->getPort(ID(CI)), act, ci)); | ||||||
| 				supercell_aux.insert(module->addMux(NEW_ID, c2->getPort("\\BI"), c1->getPort("\\BI"), act, bi)); | 				supercell_aux.insert(module->addMux(NEW_ID, c2->getPort(ID(BI)), c1->getPort(ID(BI)), act, bi)); | ||||||
| 				supercell->setPort("\\CI", ci); | 				supercell->setPort(ID(CI), ci); | ||||||
| 				supercell->setPort("\\BI", bi); | 				supercell->setPort(ID(BI), bi); | ||||||
| 				supercell->setPort("\\CO", co); | 				supercell->setPort(ID(CO), co); | ||||||
| 				supercell->setPort("\\X", x); | 				supercell->setPort(ID(X), x); | ||||||
| 			} | 			} | ||||||
| 			supercell->check(); | 			supercell->check(); | ||||||
| 
 | 
 | ||||||
| 			supercell_aux.insert(module->addPos(NEW_ID, y, y1)); | 			supercell_aux.insert(module->addPos(NEW_ID, y, y1)); | ||||||
| 			supercell_aux.insert(module->addPos(NEW_ID, y, y2)); | 			supercell_aux.insert(module->addPos(NEW_ID, y, y2)); | ||||||
| 			if (c1->type == "$alu") { | 			if (c1->type == ID($alu)) { | ||||||
| 				supercell_aux.insert(module->addPos(NEW_ID, co, c1->getPort("\\CO"))); | 				supercell_aux.insert(module->addPos(NEW_ID, co, c1->getPort(ID(CO)))); | ||||||
| 				supercell_aux.insert(module->addPos(NEW_ID, co, c2->getPort("\\CO"))); | 				supercell_aux.insert(module->addPos(NEW_ID, co, c2->getPort(ID(CO)))); | ||||||
| 				supercell_aux.insert(module->addPos(NEW_ID, x, c1->getPort("\\X"))); | 				supercell_aux.insert(module->addPos(NEW_ID, x, c1->getPort(ID(X)))); | ||||||
| 				supercell_aux.insert(module->addPos(NEW_ID, x, c2->getPort("\\X"))); | 				supercell_aux.insert(module->addPos(NEW_ID, x, c2->getPort(ID(X)))); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			supercell_aux.insert(supercell); | 			supercell_aux.insert(supercell); | ||||||
| 			return supercell; | 			return supercell; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (c1->type == "$macc") | 		if (c1->type == ID($macc)) | ||||||
| 		{ | 		{ | ||||||
| 			RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type); | 			RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type); | ||||||
| 			supercell_aux.insert(supercell); | 			supercell_aux.insert(supercell); | ||||||
|  | @ -705,18 +705,18 @@ struct ShareWorker | ||||||
| 			return supercell; | 			return supercell; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (c1->type == "$memrd") | 		if (c1->type == ID($memrd)) | ||||||
| 		{ | 		{ | ||||||
| 			RTLIL::Cell *supercell = module->addCell(NEW_ID, c1); | 			RTLIL::Cell *supercell = module->addCell(NEW_ID, c1); | ||||||
| 			RTLIL::SigSpec addr1 = c1->getPort("\\ADDR"); | 			RTLIL::SigSpec addr1 = c1->getPort(ID(ADDR)); | ||||||
| 			RTLIL::SigSpec addr2 = c2->getPort("\\ADDR"); | 			RTLIL::SigSpec addr2 = c2->getPort(ID(ADDR)); | ||||||
| 			if (GetSize(addr1) < GetSize(addr2)) | 			if (GetSize(addr1) < GetSize(addr2)) | ||||||
| 				addr1.extend_u0(GetSize(addr2)); | 				addr1.extend_u0(GetSize(addr2)); | ||||||
| 			else | 			else | ||||||
| 				addr2.extend_u0(GetSize(addr1)); | 				addr2.extend_u0(GetSize(addr1)); | ||||||
| 			supercell->setPort("\\ADDR", addr1 != addr2 ? module->Mux(NEW_ID, addr2, addr1, act) : addr1); | 			supercell->setPort(ID(ADDR), addr1 != addr2 ? module->Mux(NEW_ID, addr2, addr1, act) : addr1); | ||||||
| 			supercell->parameters["\\ABITS"] = RTLIL::Const(GetSize(addr1)); | 			supercell->parameters[ID(ABITS)] = RTLIL::Const(GetSize(addr1)); | ||||||
| 			supercell_aux.insert(module->addPos(NEW_ID, supercell->getPort("\\DATA"), c2->getPort("\\DATA"))); | 			supercell_aux.insert(module->addPos(NEW_ID, supercell->getPort(ID(DATA)), c2->getPort(ID(DATA)))); | ||||||
| 			supercell_aux.insert(supercell); | 			supercell_aux.insert(supercell); | ||||||
| 			return supercell; | 			return supercell; | ||||||
| 		} | 		} | ||||||
|  | @ -747,8 +747,8 @@ struct ShareWorker | ||||||
| 		modwalker.get_consumers(pbits, modwalker.cell_outputs[cell]); | 		modwalker.get_consumers(pbits, modwalker.cell_outputs[cell]); | ||||||
| 
 | 
 | ||||||
| 		for (auto &bit : pbits) { | 		for (auto &bit : pbits) { | ||||||
| 			if ((bit.cell->type == "$mux" || bit.cell->type == "$pmux") && bit.port == "\\S") | 			if ((bit.cell->type == ID($mux) || bit.cell->type == ID($pmux)) && bit.port == ID(S)) | ||||||
| 				forbidden_controls_cache[cell].insert(bit.cell->getPort("\\S").extract(bit.offset, 1)); | 				forbidden_controls_cache[cell].insert(bit.cell->getPort(ID(S)).extract(bit.offset, 1)); | ||||||
| 			consumer_cells.insert(bit.cell); | 			consumer_cells.insert(bit.cell); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -874,7 +874,7 @@ struct ShareWorker | ||||||
| 			} | 			} | ||||||
| 			for (auto &pbit : modwalker.signal_consumers[bit]) { | 			for (auto &pbit : modwalker.signal_consumers[bit]) { | ||||||
| 				log_assert(fwd_ct.cell_known(pbit.cell->type)); | 				log_assert(fwd_ct.cell_known(pbit.cell->type)); | ||||||
| 				if ((pbit.cell->type == "$mux" || pbit.cell->type == "$pmux") && (pbit.port == "\\A" || pbit.port == "\\B")) | 				if ((pbit.cell->type == ID($mux) || pbit.cell->type == ID($pmux)) && (pbit.port == ID(A) || pbit.port == ID(B))) | ||||||
| 					driven_data_muxes.insert(pbit.cell); | 					driven_data_muxes.insert(pbit.cell); | ||||||
| 				else | 				else | ||||||
| 					driven_cells.insert(pbit.cell); | 					driven_cells.insert(pbit.cell); | ||||||
|  | @ -890,10 +890,10 @@ struct ShareWorker | ||||||
| 			bool used_in_a = false; | 			bool used_in_a = false; | ||||||
| 			std::set<int> used_in_b_parts; | 			std::set<int> used_in_b_parts; | ||||||
| 
 | 
 | ||||||
| 			int width = c->parameters.at("\\WIDTH").as_int(); | 			int width = c->parameters.at(ID(WIDTH)).as_int(); | ||||||
| 			std::vector<RTLIL::SigBit> sig_a = modwalker.sigmap(c->getPort("\\A")); | 			std::vector<RTLIL::SigBit> sig_a = modwalker.sigmap(c->getPort(ID(A))); | ||||||
| 			std::vector<RTLIL::SigBit> sig_b = modwalker.sigmap(c->getPort("\\B")); | 			std::vector<RTLIL::SigBit> sig_b = modwalker.sigmap(c->getPort(ID(B))); | ||||||
| 			std::vector<RTLIL::SigBit> sig_s = modwalker.sigmap(c->getPort("\\S")); | 			std::vector<RTLIL::SigBit> sig_s = modwalker.sigmap(c->getPort(ID(S))); | ||||||
| 
 | 
 | ||||||
| 			for (auto &bit : sig_a) | 			for (auto &bit : sig_a) | ||||||
| 				if (cell_out_bits.count(bit)) | 				if (cell_out_bits.count(bit)) | ||||||
|  | @ -1132,14 +1132,14 @@ struct ShareWorker | ||||||
| 		fwd_ct.setup_internals(); | 		fwd_ct.setup_internals(); | ||||||
| 
 | 
 | ||||||
| 		cone_ct.setup_internals(); | 		cone_ct.setup_internals(); | ||||||
| 		cone_ct.cell_types.erase("$mul"); | 		cone_ct.cell_types.erase(ID($mul)); | ||||||
| 		cone_ct.cell_types.erase("$mod"); | 		cone_ct.cell_types.erase(ID($mod)); | ||||||
| 		cone_ct.cell_types.erase("$div"); | 		cone_ct.cell_types.erase(ID($div)); | ||||||
| 		cone_ct.cell_types.erase("$pow"); | 		cone_ct.cell_types.erase(ID($pow)); | ||||||
| 		cone_ct.cell_types.erase("$shl"); | 		cone_ct.cell_types.erase(ID($shl)); | ||||||
| 		cone_ct.cell_types.erase("$shr"); | 		cone_ct.cell_types.erase(ID($shr)); | ||||||
| 		cone_ct.cell_types.erase("$sshl"); | 		cone_ct.cell_types.erase(ID($sshl)); | ||||||
| 		cone_ct.cell_types.erase("$sshr"); | 		cone_ct.cell_types.erase(ID($sshr)); | ||||||
| 
 | 
 | ||||||
| 		modwalker.setup(design, module); | 		modwalker.setup(design, module); | ||||||
| 
 | 
 | ||||||
|  | @ -1153,9 +1153,9 @@ struct ShareWorker | ||||||
| 				GetSize(shareable_cells), log_id(module)); | 				GetSize(shareable_cells), log_id(module)); | ||||||
| 
 | 
 | ||||||
| 		for (auto cell : module->cells()) | 		for (auto cell : module->cells()) | ||||||
| 			if (cell->type == "$pmux") | 			if (cell->type == ID($pmux)) | ||||||
| 				for (auto bit : cell->getPort("\\S")) | 				for (auto bit : cell->getPort(ID(S))) | ||||||
| 				for (auto other_bit : cell->getPort("\\S")) | 				for (auto other_bit : cell->getPort(ID(S))) | ||||||
| 					if (bit < other_bit) | 					if (bit < other_bit) | ||||||
| 						exclusive_ctrls.push_back(std::pair<RTLIL::SigBit, RTLIL::SigBit>(bit, other_bit)); | 						exclusive_ctrls.push_back(std::pair<RTLIL::SigBit, RTLIL::SigBit>(bit, other_bit)); | ||||||
| 
 | 
 | ||||||
|  | @ -1466,43 +1466,43 @@ struct SharePass : public Pass { | ||||||
| 		config.opt_aggressive = false; | 		config.opt_aggressive = false; | ||||||
| 		config.opt_fast = false; | 		config.opt_fast = false; | ||||||
| 
 | 
 | ||||||
| 		config.generic_uni_ops.insert("$not"); | 		config.generic_uni_ops.insert(ID($not)); | ||||||
| 		// config.generic_uni_ops.insert("$pos");
 | 		// config.generic_uni_ops.insert(ID($pos));
 | ||||||
| 		config.generic_uni_ops.insert("$neg"); | 		config.generic_uni_ops.insert(ID($neg)); | ||||||
| 
 | 
 | ||||||
| 		config.generic_cbin_ops.insert("$and"); | 		config.generic_cbin_ops.insert(ID($and)); | ||||||
| 		config.generic_cbin_ops.insert("$or"); | 		config.generic_cbin_ops.insert(ID($or)); | ||||||
| 		config.generic_cbin_ops.insert("$xor"); | 		config.generic_cbin_ops.insert(ID($xor)); | ||||||
| 		config.generic_cbin_ops.insert("$xnor"); | 		config.generic_cbin_ops.insert(ID($xnor)); | ||||||
| 
 | 
 | ||||||
| 		config.generic_bin_ops.insert("$shl"); | 		config.generic_bin_ops.insert(ID($shl)); | ||||||
| 		config.generic_bin_ops.insert("$shr"); | 		config.generic_bin_ops.insert(ID($shr)); | ||||||
| 		config.generic_bin_ops.insert("$sshl"); | 		config.generic_bin_ops.insert(ID($sshl)); | ||||||
| 		config.generic_bin_ops.insert("$sshr"); | 		config.generic_bin_ops.insert(ID($sshr)); | ||||||
| 
 | 
 | ||||||
| 		config.generic_bin_ops.insert("$lt"); | 		config.generic_bin_ops.insert(ID($lt)); | ||||||
| 		config.generic_bin_ops.insert("$le"); | 		config.generic_bin_ops.insert(ID($le)); | ||||||
| 		config.generic_bin_ops.insert("$eq"); | 		config.generic_bin_ops.insert(ID($eq)); | ||||||
| 		config.generic_bin_ops.insert("$ne"); | 		config.generic_bin_ops.insert(ID($ne)); | ||||||
| 		config.generic_bin_ops.insert("$eqx"); | 		config.generic_bin_ops.insert(ID($eqx)); | ||||||
| 		config.generic_bin_ops.insert("$nex"); | 		config.generic_bin_ops.insert(ID($nex)); | ||||||
| 		config.generic_bin_ops.insert("$ge"); | 		config.generic_bin_ops.insert(ID($ge)); | ||||||
| 		config.generic_bin_ops.insert("$gt"); | 		config.generic_bin_ops.insert(ID($gt)); | ||||||
| 
 | 
 | ||||||
| 		config.generic_cbin_ops.insert("$add"); | 		config.generic_cbin_ops.insert(ID($add)); | ||||||
| 		config.generic_cbin_ops.insert("$mul"); | 		config.generic_cbin_ops.insert(ID($mul)); | ||||||
| 
 | 
 | ||||||
| 		config.generic_bin_ops.insert("$sub"); | 		config.generic_bin_ops.insert(ID($sub)); | ||||||
| 		config.generic_bin_ops.insert("$div"); | 		config.generic_bin_ops.insert(ID($div)); | ||||||
| 		config.generic_bin_ops.insert("$mod"); | 		config.generic_bin_ops.insert(ID($mod)); | ||||||
| 		// config.generic_bin_ops.insert("$pow");
 | 		// config.generic_bin_ops.insert(ID($pow));
 | ||||||
| 
 | 
 | ||||||
| 		config.generic_uni_ops.insert("$logic_not"); | 		config.generic_uni_ops.insert(ID($logic_not)); | ||||||
| 		config.generic_cbin_ops.insert("$logic_and"); | 		config.generic_cbin_ops.insert(ID($logic_and)); | ||||||
| 		config.generic_cbin_ops.insert("$logic_or"); | 		config.generic_cbin_ops.insert(ID($logic_or)); | ||||||
| 
 | 
 | ||||||
| 		config.generic_other_ops.insert("$alu"); | 		config.generic_other_ops.insert(ID($alu)); | ||||||
| 		config.generic_other_ops.insert("$macc"); | 		config.generic_other_ops.insert(ID($macc)); | ||||||
| 
 | 
 | ||||||
| 		log_header(design, "Executing SHARE pass (SAT-based resource sharing).\n"); | 		log_header(design, "Executing SHARE pass (SAT-based resource sharing).\n"); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -34,13 +34,13 @@ struct WreduceConfig | ||||||
| 	WreduceConfig() | 	WreduceConfig() | ||||||
| 	{ | 	{ | ||||||
| 		supported_cell_types = pool<IdString>({ | 		supported_cell_types = pool<IdString>({ | ||||||
| 			"$not", "$pos", "$neg", | 			ID($not), ID($pos), ID($neg), | ||||||
| 			"$and", "$or", "$xor", "$xnor", | 			ID($and), ID($or), ID($xor), ID($xnor), | ||||||
| 			"$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", | 			ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx), | ||||||
| 			"$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt", | 			ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt), | ||||||
| 			"$add", "$sub", "$mul", // "$div", "$mod", "$pow",
 | 			ID($add), ID($sub), ID($mul), // ID($div), ID($mod), ID($pow),
 | ||||||
| 			"$mux", "$pmux", | 			ID($mux), ID($pmux), | ||||||
| 			"$dff", "$adff" | 			ID($dff), ID($adff) | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
|  | @ -64,10 +64,10 @@ struct WreduceWorker | ||||||
| 	{ | 	{ | ||||||
| 		// Reduce size of MUX if inputs agree on a value for a bit or a output bit is unused
 | 		// Reduce size of MUX if inputs agree on a value for a bit or a output bit is unused
 | ||||||
| 
 | 
 | ||||||
| 		SigSpec sig_a = mi.sigmap(cell->getPort("\\A")); | 		SigSpec sig_a = mi.sigmap(cell->getPort(ID(A))); | ||||||
| 		SigSpec sig_b = mi.sigmap(cell->getPort("\\B")); | 		SigSpec sig_b = mi.sigmap(cell->getPort(ID(B))); | ||||||
| 		SigSpec sig_s = mi.sigmap(cell->getPort("\\S")); | 		SigSpec sig_s = mi.sigmap(cell->getPort(ID(S))); | ||||||
| 		SigSpec sig_y = mi.sigmap(cell->getPort("\\Y")); | 		SigSpec sig_y = mi.sigmap(cell->getPort(ID(Y))); | ||||||
| 		std::vector<SigBit> bits_removed; | 		std::vector<SigBit> bits_removed; | ||||||
| 
 | 
 | ||||||
| 		if (sig_y.has_const()) | 		if (sig_y.has_const()) | ||||||
|  | @ -130,9 +130,9 @@ struct WreduceWorker | ||||||
| 		for (auto bit : new_work_queue_bits) | 		for (auto bit : new_work_queue_bits) | ||||||
| 			work_queue_bits.insert(bit); | 			work_queue_bits.insert(bit); | ||||||
| 
 | 
 | ||||||
| 		cell->setPort("\\A", new_sig_a); | 		cell->setPort(ID(A), new_sig_a); | ||||||
| 		cell->setPort("\\B", new_sig_b); | 		cell->setPort(ID(B), new_sig_b); | ||||||
| 		cell->setPort("\\Y", new_sig_y); | 		cell->setPort(ID(Y), new_sig_y); | ||||||
| 		cell->fixup_parameters(); | 		cell->fixup_parameters(); | ||||||
| 
 | 
 | ||||||
| 		module->connect(sig_y.extract(n_kept, n_removed), sig_removed); | 		module->connect(sig_y.extract(n_kept, n_removed), sig_removed); | ||||||
|  | @ -142,8 +142,8 @@ struct WreduceWorker | ||||||
| 	{ | 	{ | ||||||
| 		// Reduce size of FF if inputs are just sign/zero extended or output bit is not used
 | 		// Reduce size of FF if inputs are just sign/zero extended or output bit is not used
 | ||||||
| 
 | 
 | ||||||
| 		SigSpec sig_d = mi.sigmap(cell->getPort("\\D")); | 		SigSpec sig_d = mi.sigmap(cell->getPort(ID(D))); | ||||||
| 		SigSpec sig_q = mi.sigmap(cell->getPort("\\Q")); | 		SigSpec sig_q = mi.sigmap(cell->getPort(ID(Q))); | ||||||
| 		Const initval; | 		Const initval; | ||||||
| 
 | 
 | ||||||
| 		int width_before = GetSize(sig_q); | 		int width_before = GetSize(sig_q); | ||||||
|  | @ -214,14 +214,14 @@ struct WreduceWorker | ||||||
| 			work_queue_bits.insert(bit); | 			work_queue_bits.insert(bit); | ||||||
| 
 | 
 | ||||||
| 		// Narrow ARST_VALUE parameter to new size.
 | 		// Narrow ARST_VALUE parameter to new size.
 | ||||||
| 		if (cell->parameters.count("\\ARST_VALUE")) { | 		if (cell->parameters.count(ID(ARST_VALUE))) { | ||||||
| 			Const arst_value = cell->getParam("\\ARST_VALUE"); | 			Const arst_value = cell->getParam(ID(ARST_VALUE)); | ||||||
| 			arst_value.bits.resize(GetSize(sig_q)); | 			arst_value.bits.resize(GetSize(sig_q)); | ||||||
| 			cell->setParam("\\ARST_VALUE", arst_value); | 			cell->setParam(ID(ARST_VALUE), arst_value); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		cell->setPort("\\D", sig_d); | 		cell->setPort(ID(D), sig_d); | ||||||
| 		cell->setPort("\\Q", sig_q); | 		cell->setPort(ID(Q), sig_q); | ||||||
| 		cell->fixup_parameters(); | 		cell->fixup_parameters(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -230,7 +230,7 @@ struct WreduceWorker | ||||||
| 		port_signed = cell->getParam(stringf("\\%c_SIGNED", port)).as_bool(); | 		port_signed = cell->getParam(stringf("\\%c_SIGNED", port)).as_bool(); | ||||||
| 		SigSpec sig = mi.sigmap(cell->getPort(stringf("\\%c", port))); | 		SigSpec sig = mi.sigmap(cell->getPort(stringf("\\%c", port))); | ||||||
| 
 | 
 | ||||||
| 		if (port == 'B' && cell->type.in("$shl", "$shr", "$sshl", "$sshr")) | 		if (port == 'B' && cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr))) | ||||||
| 			port_signed = false; | 			port_signed = false; | ||||||
| 
 | 
 | ||||||
| 		int bits_removed = 0; | 		int bits_removed = 0; | ||||||
|  | @ -264,13 +264,13 @@ struct WreduceWorker | ||||||
| 		if (!cell->type.in(config->supported_cell_types)) | 		if (!cell->type.in(config->supported_cell_types)) | ||||||
| 			return; | 			return; | ||||||
| 
 | 
 | ||||||
| 		if (cell->type.in("$mux", "$pmux")) | 		if (cell->type.in(ID($mux), ID($pmux))) | ||||||
| 			return run_cell_mux(cell); | 			return run_cell_mux(cell); | ||||||
| 
 | 
 | ||||||
| 		if (cell->type.in("$dff", "$adff")) | 		if (cell->type.in(ID($dff), ID($adff))) | ||||||
| 			return run_cell_dff(cell); | 			return run_cell_dff(cell); | ||||||
| 
 | 
 | ||||||
| 		SigSpec sig = mi.sigmap(cell->getPort("\\Y")); | 		SigSpec sig = mi.sigmap(cell->getPort(ID(Y))); | ||||||
| 
 | 
 | ||||||
| 		if (sig.has_const()) | 		if (sig.has_const()) | ||||||
| 			return; | 			return; | ||||||
|  | @ -278,10 +278,10 @@ struct WreduceWorker | ||||||
| 
 | 
 | ||||||
| 		// Reduce size of ports A and B based on constant input bits and size of output port
 | 		// Reduce size of ports A and B based on constant input bits and size of output port
 | ||||||
| 
 | 
 | ||||||
| 		int max_port_a_size = cell->hasPort("\\A") ? GetSize(cell->getPort("\\A")) : -1; | 		int max_port_a_size = cell->hasPort(ID(A)) ? GetSize(cell->getPort(ID(A))) : -1; | ||||||
| 		int max_port_b_size = cell->hasPort("\\B") ? GetSize(cell->getPort("\\B")) : -1; | 		int max_port_b_size = cell->hasPort(ID(B)) ? GetSize(cell->getPort(ID(B))) : -1; | ||||||
| 
 | 
 | ||||||
| 		if (cell->type.in("$not", "$pos", "$neg", "$and", "$or", "$xor", "$add", "$sub")) { | 		if (cell->type.in(ID($not), ID($pos), ID($neg), ID($and), ID($or), ID($xor), ID($add), ID($sub))) { | ||||||
| 			max_port_a_size = min(max_port_a_size, GetSize(sig)); | 			max_port_a_size = min(max_port_a_size, GetSize(sig)); | ||||||
| 			max_port_b_size = min(max_port_b_size, GetSize(sig)); | 			max_port_b_size = min(max_port_b_size, GetSize(sig)); | ||||||
| 		} | 		} | ||||||
|  | @ -289,32 +289,32 @@ struct WreduceWorker | ||||||
| 		bool port_a_signed = false; | 		bool port_a_signed = false; | ||||||
| 		bool port_b_signed = false; | 		bool port_b_signed = false; | ||||||
| 
 | 
 | ||||||
| 		if (max_port_a_size >= 0 && cell->type != "$shiftx") | 		if (max_port_a_size >= 0 && cell->type != ID($shiftx)) | ||||||
| 			run_reduce_inport(cell, 'A', max_port_a_size, port_a_signed, did_something); | 			run_reduce_inport(cell, 'A', max_port_a_size, port_a_signed, did_something); | ||||||
| 
 | 
 | ||||||
| 		if (max_port_b_size >= 0) | 		if (max_port_b_size >= 0) | ||||||
| 			run_reduce_inport(cell, 'B', max_port_b_size, port_b_signed, did_something); | 			run_reduce_inport(cell, 'B', max_port_b_size, port_b_signed, did_something); | ||||||
| 
 | 
 | ||||||
| 		if (cell->hasPort("\\A") && cell->hasPort("\\B") && port_a_signed && port_b_signed) { | 		if (cell->hasPort(ID(A)) && cell->hasPort(ID(B)) && port_a_signed && port_b_signed) { | ||||||
| 			SigSpec sig_a = mi.sigmap(cell->getPort("\\A")), sig_b = mi.sigmap(cell->getPort("\\B")); | 			SigSpec sig_a = mi.sigmap(cell->getPort(ID(A))), sig_b = mi.sigmap(cell->getPort(ID(B))); | ||||||
| 			if (GetSize(sig_a) > 0 && sig_a[GetSize(sig_a)-1] == State::S0 && | 			if (GetSize(sig_a) > 0 && sig_a[GetSize(sig_a)-1] == State::S0 && | ||||||
| 					GetSize(sig_b) > 0 && sig_b[GetSize(sig_b)-1] == State::S0) { | 					GetSize(sig_b) > 0 && sig_b[GetSize(sig_b)-1] == State::S0) { | ||||||
| 				log("Converting cell %s.%s (%s) from signed to unsigned.\n", | 				log("Converting cell %s.%s (%s) from signed to unsigned.\n", | ||||||
| 						log_id(module), log_id(cell), log_id(cell->type)); | 						log_id(module), log_id(cell), log_id(cell->type)); | ||||||
| 				cell->setParam("\\A_SIGNED", 0); | 				cell->setParam(ID(A_SIGNED), 0); | ||||||
| 				cell->setParam("\\B_SIGNED", 0); | 				cell->setParam(ID(B_SIGNED), 0); | ||||||
| 				port_a_signed = false; | 				port_a_signed = false; | ||||||
| 				port_b_signed = false; | 				port_b_signed = false; | ||||||
| 				did_something = true; | 				did_something = true; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (cell->hasPort("\\A") && !cell->hasPort("\\B") && port_a_signed) { | 		if (cell->hasPort(ID(A)) && !cell->hasPort(ID(B)) && port_a_signed) { | ||||||
| 			SigSpec sig_a = mi.sigmap(cell->getPort("\\A")); | 			SigSpec sig_a = mi.sigmap(cell->getPort(ID(A))); | ||||||
| 			if (GetSize(sig_a) > 0 && sig_a[GetSize(sig_a)-1] == State::S0) { | 			if (GetSize(sig_a) > 0 && sig_a[GetSize(sig_a)-1] == State::S0) { | ||||||
| 				log("Converting cell %s.%s (%s) from signed to unsigned.\n", | 				log("Converting cell %s.%s (%s) from signed to unsigned.\n", | ||||||
| 						log_id(module), log_id(cell), log_id(cell->type)); | 						log_id(module), log_id(cell), log_id(cell->type)); | ||||||
| 				cell->setParam("\\A_SIGNED", 0); | 				cell->setParam(ID(A_SIGNED), 0); | ||||||
| 				port_a_signed = false; | 				port_a_signed = false; | ||||||
| 				did_something = true; | 				did_something = true; | ||||||
| 			} | 			} | ||||||
|  | @ -324,7 +324,7 @@ struct WreduceWorker | ||||||
| 		// Reduce size of port Y based on sizes for A and B and unused bits in Y
 | 		// Reduce size of port Y based on sizes for A and B and unused bits in Y
 | ||||||
| 
 | 
 | ||||||
| 		int bits_removed = 0; | 		int bits_removed = 0; | ||||||
| 		if (port_a_signed && cell->type == "$shr") { | 		if (port_a_signed && cell->type == ID($shr)) { | ||||||
| 			// do not reduce size of output on $shr cells with signed A inputs
 | 			// do not reduce size of output on $shr cells with signed A inputs
 | ||||||
| 		} else { | 		} else { | ||||||
| 			while (GetSize(sig) > 0) | 			while (GetSize(sig) > 0) | ||||||
|  | @ -342,20 +342,20 @@ struct WreduceWorker | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (cell->type.in("$pos", "$add", "$mul", "$and", "$or", "$xor", "$sub")) | 		if (cell->type.in(ID($pos), ID($add), ID($mul), ID($and), ID($or), ID($xor), ID($sub))) | ||||||
| 		{ | 		{ | ||||||
| 			bool is_signed = cell->getParam("\\A_SIGNED").as_bool() || cell->type == "$sub"; | 			bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool() || cell->type == ID($sub); | ||||||
| 
 | 
 | ||||||
| 			int a_size = 0, b_size = 0; | 			int a_size = 0, b_size = 0; | ||||||
| 			if (cell->hasPort("\\A")) a_size = GetSize(cell->getPort("\\A")); | 			if (cell->hasPort(ID(A))) a_size = GetSize(cell->getPort(ID(A))); | ||||||
| 			if (cell->hasPort("\\B")) b_size = GetSize(cell->getPort("\\B")); | 			if (cell->hasPort(ID(B))) b_size = GetSize(cell->getPort(ID(B))); | ||||||
| 
 | 
 | ||||||
| 			int max_y_size = max(a_size, b_size); | 			int max_y_size = max(a_size, b_size); | ||||||
| 
 | 
 | ||||||
| 			if (cell->type.in("$add", "$sub")) | 			if (cell->type.in(ID($add), ID($sub))) | ||||||
| 				max_y_size++; | 				max_y_size++; | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$mul") | 			if (cell->type == ID($mul)) | ||||||
| 				max_y_size = a_size + b_size; | 				max_y_size = a_size + b_size; | ||||||
| 
 | 
 | ||||||
| 			while (GetSize(sig) > 1 && GetSize(sig) > max_y_size) { | 			while (GetSize(sig) > 1 && GetSize(sig) > max_y_size) { | ||||||
|  | @ -374,7 +374,7 @@ struct WreduceWorker | ||||||
| 		if (bits_removed) { | 		if (bits_removed) { | ||||||
| 			log("Removed top %d bits (of %d) from port Y of cell %s.%s (%s).\n", | 			log("Removed top %d bits (of %d) from port Y of cell %s.%s (%s).\n", | ||||||
| 					bits_removed, GetSize(sig) + bits_removed, log_id(module), log_id(cell), log_id(cell->type)); | 					bits_removed, GetSize(sig) + bits_removed, log_id(module), log_id(cell), log_id(cell->type)); | ||||||
| 			cell->setPort("\\Y", sig); | 			cell->setPort(ID(Y), sig); | ||||||
| 			did_something = true; | 			did_something = true; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -387,8 +387,8 @@ struct WreduceWorker | ||||||
| 	static int count_nontrivial_wire_attrs(RTLIL::Wire *w) | 	static int count_nontrivial_wire_attrs(RTLIL::Wire *w) | ||||||
| 	{ | 	{ | ||||||
| 		int count = w->attributes.size(); | 		int count = w->attributes.size(); | ||||||
| 		count -= w->attributes.count("\\src"); | 		count -= w->attributes.count(ID(src)); | ||||||
| 		count -= w->attributes.count("\\unused_bits"); | 		count -= w->attributes.count(ID(unused_bits)); | ||||||
| 		return count; | 		return count; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -398,11 +398,11 @@ struct WreduceWorker | ||||||
| 		SigMap init_attr_sigmap = mi.sigmap; | 		SigMap init_attr_sigmap = mi.sigmap; | ||||||
| 
 | 
 | ||||||
| 		for (auto w : module->wires()) { | 		for (auto w : module->wires()) { | ||||||
| 			if (w->get_bool_attribute("\\keep")) | 			if (w->get_bool_attribute(ID(keep))) | ||||||
| 				for (auto bit : mi.sigmap(w)) | 				for (auto bit : mi.sigmap(w)) | ||||||
| 					keep_bits.insert(bit); | 					keep_bits.insert(bit); | ||||||
| 			if (w->attributes.count("\\init")) { | 			if (w->attributes.count(ID(init))) { | ||||||
| 				Const initval = w->attributes.at("\\init"); | 				Const initval = w->attributes.at(ID(init)); | ||||||
| 				SigSpec initsig = init_attr_sigmap(w); | 				SigSpec initsig = init_attr_sigmap(w); | ||||||
| 				int width = std::min(GetSize(initval), GetSize(initsig)); | 				int width = std::min(GetSize(initval), GetSize(initsig)); | ||||||
| 				for (int i = 0; i < width; i++) | 				for (int i = 0; i < width; i++) | ||||||
|  | @ -459,8 +459,8 @@ struct WreduceWorker | ||||||
| 
 | 
 | ||||||
| 		if (!remove_init_bits.empty()) { | 		if (!remove_init_bits.empty()) { | ||||||
| 			for (auto w : module->wires()) { | 			for (auto w : module->wires()) { | ||||||
| 				if (w->attributes.count("\\init")) { | 				if (w->attributes.count(ID(init))) { | ||||||
| 					Const initval = w->attributes.at("\\init"); | 					Const initval = w->attributes.at(ID(init)); | ||||||
| 					Const new_initval(State::Sx, GetSize(w)); | 					Const new_initval(State::Sx, GetSize(w)); | ||||||
| 					SigSpec initsig = init_attr_sigmap(w); | 					SigSpec initsig = init_attr_sigmap(w); | ||||||
| 					int width = std::min(GetSize(initval), GetSize(initsig)); | 					int width = std::min(GetSize(initval), GetSize(initsig)); | ||||||
|  | @ -468,7 +468,7 @@ struct WreduceWorker | ||||||
| 						if (!remove_init_bits.count(initsig[i])) | 						if (!remove_init_bits.count(initsig[i])) | ||||||
| 							new_initval[i] = initval[i]; | 							new_initval[i] = initval[i]; | ||||||
| 					} | 					} | ||||||
| 					w->attributes.at("\\init") = new_initval; | 					w->attributes.at(ID(init)) = new_initval; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | @ -528,23 +528,23 @@ struct WreducePass : public Pass { | ||||||
| 
 | 
 | ||||||
| 			for (auto c : module->selected_cells()) | 			for (auto c : module->selected_cells()) | ||||||
| 			{ | 			{ | ||||||
| 				if (c->type.in("$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool", | 				if (c->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), | ||||||
| 						"$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt", | 						ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt), | ||||||
| 						"$logic_not", "$logic_and", "$logic_or") && GetSize(c->getPort("\\Y")) > 1) { | 						ID($logic_not), ID($logic_and), ID($logic_or)) && GetSize(c->getPort(ID(Y))) > 1) { | ||||||
| 					SigSpec sig = c->getPort("\\Y"); | 					SigSpec sig = c->getPort(ID(Y)); | ||||||
| 					if (!sig.has_const()) { | 					if (!sig.has_const()) { | ||||||
| 						c->setPort("\\Y", sig[0]); | 						c->setPort(ID(Y), sig[0]); | ||||||
| 						c->setParam("\\Y_WIDTH", 1); | 						c->setParam(ID(Y_WIDTH), 1); | ||||||
| 						sig.remove(0); | 						sig.remove(0); | ||||||
| 						module->connect(sig, Const(0, GetSize(sig))); | 						module->connect(sig, Const(0, GetSize(sig))); | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				if (c->type.in("$div", "$mod", "$pow")) | 				if (c->type.in(ID($div), ID($mod), ID($pow))) | ||||||
| 				{ | 				{ | ||||||
| 					SigSpec A = c->getPort("\\A"); | 					SigSpec A = c->getPort(ID(A)); | ||||||
| 					int original_a_width = GetSize(A); | 					int original_a_width = GetSize(A); | ||||||
| 					if (c->getParam("\\A_SIGNED").as_bool()) { | 					if (c->getParam(ID(A_SIGNED)).as_bool()) { | ||||||
| 						while (GetSize(A) > 1 && A[GetSize(A)-1] == State::S0 && A[GetSize(A)-2] == State::S0) | 						while (GetSize(A) > 1 && A[GetSize(A)-1] == State::S0 && A[GetSize(A)-2] == State::S0) | ||||||
| 							A.remove(GetSize(A)-1, 1); | 							A.remove(GetSize(A)-1, 1); | ||||||
| 					} else { | 					} else { | ||||||
|  | @ -554,13 +554,13 @@ struct WreducePass : public Pass { | ||||||
| 					if (original_a_width != GetSize(A)) { | 					if (original_a_width != GetSize(A)) { | ||||||
| 						log("Removed top %d bits (of %d) from port A of cell %s.%s (%s).\n", | 						log("Removed top %d bits (of %d) from port A of cell %s.%s (%s).\n", | ||||||
| 								original_a_width-GetSize(A), original_a_width, log_id(module), log_id(c), log_id(c->type)); | 								original_a_width-GetSize(A), original_a_width, log_id(module), log_id(c), log_id(c->type)); | ||||||
| 						c->setPort("\\A", A); | 						c->setPort(ID(A), A); | ||||||
| 						c->setParam("\\A_WIDTH", GetSize(A)); | 						c->setParam(ID(A_WIDTH), GetSize(A)); | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					SigSpec B = c->getPort("\\B"); | 					SigSpec B = c->getPort(ID(B)); | ||||||
| 					int original_b_width = GetSize(B); | 					int original_b_width = GetSize(B); | ||||||
| 					if (c->getParam("\\B_SIGNED").as_bool()) { | 					if (c->getParam(ID(B_SIGNED)).as_bool()) { | ||||||
| 						while (GetSize(B) > 1 && B[GetSize(B)-1] == State::S0 && B[GetSize(B)-2] == State::S0) | 						while (GetSize(B) > 1 && B[GetSize(B)-1] == State::S0 && B[GetSize(B)-2] == State::S0) | ||||||
| 							B.remove(GetSize(B)-1, 1); | 							B.remove(GetSize(B)-1, 1); | ||||||
| 					} else { | 					} else { | ||||||
|  | @ -570,24 +570,24 @@ struct WreducePass : public Pass { | ||||||
| 					if (original_b_width != GetSize(B)) { | 					if (original_b_width != GetSize(B)) { | ||||||
| 						log("Removed top %d bits (of %d) from port B of cell %s.%s (%s).\n", | 						log("Removed top %d bits (of %d) from port B of cell %s.%s (%s).\n", | ||||||
| 								original_b_width-GetSize(B), original_b_width, log_id(module), log_id(c), log_id(c->type)); | 								original_b_width-GetSize(B), original_b_width, log_id(module), log_id(c), log_id(c->type)); | ||||||
| 						c->setPort("\\B", B); | 						c->setPort(ID(B), B); | ||||||
| 						c->setParam("\\B_WIDTH", GetSize(B)); | 						c->setParam(ID(B_WIDTH), GetSize(B)); | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				if (!opt_memx && c->type.in("$memrd", "$memwr", "$meminit")) { | 				if (!opt_memx && c->type.in(ID($memrd), ID($memwr), ID($meminit))) { | ||||||
| 					IdString memid = c->getParam("\\MEMID").decode_string(); | 					IdString memid = c->getParam(ID(MEMID)).decode_string(); | ||||||
| 					RTLIL::Memory *mem = module->memories.at(memid); | 					RTLIL::Memory *mem = module->memories.at(memid); | ||||||
| 					if (mem->start_offset >= 0) { | 					if (mem->start_offset >= 0) { | ||||||
| 						int cur_addrbits = c->getParam("\\ABITS").as_int(); | 						int cur_addrbits = c->getParam(ID(ABITS)).as_int(); | ||||||
| 						int max_addrbits = ceil_log2(mem->start_offset + mem->size); | 						int max_addrbits = ceil_log2(mem->start_offset + mem->size); | ||||||
| 						if (cur_addrbits > max_addrbits) { | 						if (cur_addrbits > max_addrbits) { | ||||||
| 							log("Removed top %d address bits (of %d) from memory %s port %s.%s (%s).\n", | 							log("Removed top %d address bits (of %d) from memory %s port %s.%s (%s).\n", | ||||||
| 									cur_addrbits-max_addrbits, cur_addrbits, | 									cur_addrbits-max_addrbits, cur_addrbits, | ||||||
| 									c->type == "$memrd" ? "read" : c->type == "$memwr" ? "write" : "init", | 									c->type == ID($memrd) ? "read" : c->type == ID($memwr) ? "write" : "init", | ||||||
| 									log_id(module), log_id(c), log_id(memid)); | 									log_id(module), log_id(c), log_id(memid)); | ||||||
| 							c->setParam("\\ABITS", max_addrbits); | 							c->setParam(ID(ABITS), max_addrbits); | ||||||
| 							c->setPort("\\ADDR", c->getPort("\\ADDR").extract(0, max_addrbits)); | 							c->setPort(ID(ADDR), c->getPort(ID(ADDR)).extract(0, max_addrbits)); | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|  | @ -513,13 +513,13 @@ struct ExtractFaWorker | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				if (func2.at(key).count(xor2_func)) { | 				if (func2.at(key).count(xor2_func)) { | ||||||
| 					SigBit YY = invert_xy ? module->NotGate(NEW_ID, Y) : Y; | 					SigBit YY = invert_xy || (f2i.inv_a && !f2i.inv_b) || (!f2i.inv_a && f2i.inv_b) ? module->NotGate(NEW_ID, Y) : Y; | ||||||
| 					for (auto bit : func2.at(key).at(xor2_func)) | 					for (auto bit : func2.at(key).at(xor2_func)) | ||||||
| 						assign_new_driver(bit, YY); | 						assign_new_driver(bit, YY); | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				if (func2.at(key).count(xnor2_func)) { | 				if (func2.at(key).count(xnor2_func)) { | ||||||
| 					SigBit YY = invert_xy ? Y : module->NotGate(NEW_ID, Y); | 					SigBit YY = invert_xy || (f2i.inv_a && !f2i.inv_b) || (!f2i.inv_a && f2i.inv_b) ? Y : module->NotGate(NEW_ID, Y); | ||||||
| 					for (auto bit : func2.at(key).at(xnor2_func)) | 					for (auto bit : func2.at(key).at(xnor2_func)) | ||||||
| 						assign_new_driver(bit, YY); | 						assign_new_driver(bit, YY); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|  | @ -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