mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	Merge remote-tracking branch 'origin/master' into xaig_dff
This commit is contained in:
		
						commit
						a46a7e8a67
					
				
					 19 changed files with 1771 additions and 969 deletions
				
			
		|  | @ -430,10 +430,14 @@ sigspec: | ||||||
| 		free($1); | 		free($1); | ||||||
| 	} | | 	} | | ||||||
| 	sigspec '[' TOK_INT ']' { | 	sigspec '[' TOK_INT ']' { | ||||||
|  | 		if ($3 >= $1->size() || $3 < 0) | ||||||
|  | 			rtlil_frontend_ilang_yyerror("bit index out of range"); | ||||||
| 		$$ = new RTLIL::SigSpec($1->extract($3)); | 		$$ = new RTLIL::SigSpec($1->extract($3)); | ||||||
| 		delete $1; | 		delete $1; | ||||||
| 	} | | 	} | | ||||||
| 	sigspec '[' TOK_INT ':' TOK_INT ']' { | 	sigspec '[' TOK_INT ':' TOK_INT ']' { | ||||||
|  | 		if ($3 >= $1->size() || $3 < 0 || $3 < $5) | ||||||
|  | 			rtlil_frontend_ilang_yyerror("invalid slice"); | ||||||
| 		$$ = new RTLIL::SigSpec($1->extract($5, $3 - $5 + 1)); | 		$$ = new RTLIL::SigSpec($1->extract($5, $3 - $5 + 1)); | ||||||
| 		delete $1; | 		delete $1; | ||||||
| 	} | | 	} | | ||||||
|  |  | ||||||
|  | @ -2413,19 +2413,19 @@ basic_expr: | ||||||
| 		append_attr($$, $2); | 		append_attr($$, $2); | ||||||
| 	} | | 	} | | ||||||
| 	basic_expr OP_SHL attr basic_expr { | 	basic_expr OP_SHL attr basic_expr { | ||||||
| 		$$ = new AstNode(AST_SHIFT_LEFT, $1, $4); | 		$$ = new AstNode(AST_SHIFT_LEFT, $1, new AstNode(AST_TO_UNSIGNED, $4)); | ||||||
| 		append_attr($$, $3); | 		append_attr($$, $3); | ||||||
| 	} | | 	} | | ||||||
| 	basic_expr OP_SHR attr basic_expr { | 	basic_expr OP_SHR attr basic_expr { | ||||||
| 		$$ = new AstNode(AST_SHIFT_RIGHT, $1, $4); | 		$$ = new AstNode(AST_SHIFT_RIGHT, $1, new AstNode(AST_TO_UNSIGNED, $4)); | ||||||
| 		append_attr($$, $3); | 		append_attr($$, $3); | ||||||
| 	} | | 	} | | ||||||
| 	basic_expr OP_SSHL attr basic_expr { | 	basic_expr OP_SSHL attr basic_expr { | ||||||
| 		$$ = new AstNode(AST_SHIFT_SLEFT, $1, $4); | 		$$ = new AstNode(AST_SHIFT_SLEFT, $1, new AstNode(AST_TO_UNSIGNED, $4)); | ||||||
| 		append_attr($$, $3); | 		append_attr($$, $3); | ||||||
| 	} | | 	} | | ||||||
| 	basic_expr OP_SSHR attr basic_expr { | 	basic_expr OP_SSHR attr basic_expr { | ||||||
| 		$$ = new AstNode(AST_SHIFT_SRIGHT, $1, $4); | 		$$ = new AstNode(AST_SHIFT_SRIGHT, $1, new AstNode(AST_TO_UNSIGNED, $4)); | ||||||
| 		append_attr($$, $3); | 		append_attr($$, $3); | ||||||
| 	} | | 	} | | ||||||
| 	basic_expr '<' attr basic_expr { | 	basic_expr '<' attr basic_expr { | ||||||
|  |  | ||||||
|  | @ -783,6 +783,14 @@ namespace { | ||||||
| 			return v; | 			return v; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		int param_bool(RTLIL::IdString name, bool expected) | ||||||
|  | 		{ | ||||||
|  | 			int v = param_bool(name); | ||||||
|  | 			if (v != expected) | ||||||
|  | 				error(__LINE__); | ||||||
|  | 			return v; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		void param_bits(RTLIL::IdString name, int width) | 		void param_bits(RTLIL::IdString name, int width) | ||||||
| 		{ | 		{ | ||||||
| 			param(name); | 			param(name); | ||||||
|  | @ -869,13 +877,23 @@ namespace { | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) { | 			if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr))) { | ||||||
|  | 				param_bool(ID(A_SIGNED)); | ||||||
|  | 				param_bool(ID(B_SIGNED), /*expected=*/false); | ||||||
|  | 				port(ID::A, param(ID(A_WIDTH))); | ||||||
|  | 				port(ID::B, param(ID(B_WIDTH))); | ||||||
|  | 				port(ID::Y, param(ID(Y_WIDTH))); | ||||||
|  | 				check_expected(/*check_matched_sign=*/false); | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (cell->type.in(ID($shift), ID($shiftx))) { | ||||||
| 				param_bool(ID(A_SIGNED)); | 				param_bool(ID(A_SIGNED)); | ||||||
| 				param_bool(ID(B_SIGNED)); | 				param_bool(ID(B_SIGNED)); | ||||||
| 				port(ID::A, param(ID(A_WIDTH))); | 				port(ID::A, param(ID(A_WIDTH))); | ||||||
| 				port(ID::B, param(ID(B_WIDTH))); | 				port(ID::B, param(ID(B_WIDTH))); | ||||||
| 				port(ID::Y, param(ID(Y_WIDTH))); | 				port(ID::Y, param(ID(Y_WIDTH))); | ||||||
| 				check_expected(false); | 				check_expected(/*check_matched_sign=*/false); | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | @ -957,7 +975,7 @@ namespace { | ||||||
| 				port(ID::A, param(ID(A_WIDTH))); | 				port(ID::A, param(ID(A_WIDTH))); | ||||||
| 				port(ID::B, param(ID(B_WIDTH))); | 				port(ID::B, param(ID(B_WIDTH))); | ||||||
| 				port(ID::Y, param(ID(Y_WIDTH))); | 				port(ID::Y, param(ID(Y_WIDTH))); | ||||||
| 				check_expected(false); | 				check_expected(/*check_matched_sign=*/false); | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -65,6 +65,11 @@ Verilog & Cell Type \\ | ||||||
| \label{tab:CellLib_unary} | \label{tab:CellLib_unary} | ||||||
| \end{table} | \end{table} | ||||||
| 
 | 
 | ||||||
|  | For the unary cells that output a logical value ({\tt \$reduce\_and}, {\tt \$reduce\_or}, | ||||||
|  | {\tt \$reduce\_xor}, {\tt \$reduce\_xnor}, {\tt \$reduce\_bool}, {\tt \$logic\_not}), | ||||||
|  | when the \B{Y\_WIDTH} parameter is greater than 1, the output is zero-extended, | ||||||
|  | and only the least significant bit varies. | ||||||
|  | 
 | ||||||
| Note that {\tt \$reduce\_or} and {\tt \$reduce\_bool} actually represent the same | Note that {\tt \$reduce\_or} and {\tt \$reduce\_bool} actually represent the same | ||||||
| logic function. But the HDL frontends generate them in different situations. A | logic function. But the HDL frontends generate them in different situations. A | ||||||
| {\tt \$reduce\_or} cell is generated when the prefix {\tt |} operator is being used. A | {\tt \$reduce\_or} cell is generated when the prefix {\tt |} operator is being used. A | ||||||
|  | @ -97,41 +102,6 @@ The width of the output port \B{Y}. | ||||||
| 
 | 
 | ||||||
| Table~\ref{tab:CellLib_binary} lists all cells for binary RTL operators. | Table~\ref{tab:CellLib_binary} lists all cells for binary RTL operators. | ||||||
| 
 | 
 | ||||||
| \subsection{Multiplexers} |  | ||||||
| 
 |  | ||||||
| Multiplexers are generated by the Verilog HDL frontend for {\tt |  | ||||||
| ?:}-expressions. Multiplexers are also generated by the {\tt proc} pass to map the decision trees |  | ||||||
| from RTLIL::Process objects to logic. |  | ||||||
| 
 |  | ||||||
| The simplest multiplexer cell type is {\tt \$mux}. Cells of this type have a \B{WIDTH} parameter |  | ||||||
| and data inputs \B{A} and \B{B} and a data output \B{Y}, all of the specified width. This cell also |  | ||||||
| has a single bit control input \B{S}. If \B{S} is 0 the value from the \B{A} input is sent to |  | ||||||
| the output, if it is 1 the value from the \B{B} input is sent to the output. So the {\tt \$mux} |  | ||||||
| cell implements the function \lstinline[language=Verilog]; Y = S ? B : A;. |  | ||||||
| 
 |  | ||||||
| The {\tt \$pmux} cell is used to multiplex between many inputs using a one-hot select signal. Cells |  | ||||||
| of this type have a \B{WIDTH} and a \B{S\_WIDTH} parameter and inputs \B{A}, \B{B}, and \B{S} and |  | ||||||
| an output \B{Y}. The \B{S} input is \B{S\_WIDTH} bits wide. The \B{A} input and the output are both |  | ||||||
| \B{WIDTH} bits wide and the \B{B} input is \B{WIDTH}*\B{S\_WIDTH} bits wide. When all bits of |  | ||||||
| \B{S} are zero, the value from \B{A} input is sent to the output. If the $n$'th bit from \B{S} is |  | ||||||
| set, the value $n$'th \B{WIDTH} bits wide slice of the \B{B} input is sent to the output. When more |  | ||||||
| than one bit from \B{S} is set the output is undefined. Cells of this type are used to model |  | ||||||
| ``parallel cases'' (defined by using the {\tt parallel\_case} attribute or detected by |  | ||||||
| an optimization). |  | ||||||
| 
 |  | ||||||
| The {\tt \$tribuf} cell is used to implement tristate logic. Cells of this type have a \B{WIDTH} |  | ||||||
| parameter and inputs \B{A} and \B{EN} and an output \B{Y}. The \B{A} input and \B{Y} output are |  | ||||||
| \B{WIDTH} bits wide, and the \B{EN} input is one bit wide. When \B{EN} is 0, the output \B{Y} |  | ||||||
| is not driven. When \B{EN} is 1, the value from \B{A} input is sent to the \B{Y} output. Therefore, |  | ||||||
| the {\tt \$tribuf} cell implements the function \lstinline[language=Verilog]; Y = EN ? A : 'bz;. |  | ||||||
| 
 |  | ||||||
| Behavioural code with cascaded {\tt if-then-else}- and {\tt case}-statements |  | ||||||
| usually results in trees of multiplexer cells. Many passes (from various |  | ||||||
| optimizations to FSM extraction) heavily depend on these multiplexer trees to |  | ||||||
| understand dependencies between signals. Therefore optimizations should not |  | ||||||
| break these multiplexer trees (e.g.~by replacing a multiplexer between a |  | ||||||
| calculated signal and a constant zero with an {\tt \$and} gate). |  | ||||||
| 
 |  | ||||||
| \begin{table}[t!] | \begin{table}[t!] | ||||||
| \hfil | \hfil | ||||||
| \begin{tabular}[t]{ll} | \begin{tabular}[t]{ll} | ||||||
|  | @ -175,6 +145,57 @@ Verilog & Cell Type \\ | ||||||
| \label{tab:CellLib_binary} | \label{tab:CellLib_binary} | ||||||
| \end{table} | \end{table} | ||||||
| 
 | 
 | ||||||
|  | The {\tt \$shl} and {\tt \$shr} cells implement logical shifts, whereas the {\tt \$sshl} and | ||||||
|  | {\tt \$sshr} cells implement arithmetic shifts. The {\tt \$shl} and {\tt \$sshl} cells implement | ||||||
|  | the same operation. All four of these cells interpret the second operand as unsigned, and require | ||||||
|  | \B{B\_SIGNED} to be zero. | ||||||
|  | 
 | ||||||
|  | Two additional shift operator cells are available that do not directly correspond to any operator | ||||||
|  | in Verilog, {\tt \$shift} and {\tt \$shiftx}. The {\tt \$shift} cell performs a right logical shift | ||||||
|  | if the second operand is positive (or unsigned), and a left logical shift if it is negative. | ||||||
|  | The {\tt \$shiftx} cell performs the same operation as the {\tt \$shift} cell, but the vacated bit | ||||||
|  | positions are filled with undef (x) bits, and corresponds to the Verilog indexed part-select expression. | ||||||
|  | 
 | ||||||
|  | For the binary cells that output a logical value ({\tt \$logic\_and}, {\tt \$logic\_or}, | ||||||
|  | {\tt \$eqx}, {\tt \$nex}, {\tt \$lt}, {\tt \$le}, {\tt \$eq}, {\tt \$ne}, {\tt \$ge}, | ||||||
|  | {\tt \$gt}), when the \B{Y\_WIDTH} parameter is greater than 1, the output is zero-extended, | ||||||
|  | and only the least significant bit varies. | ||||||
|  | 
 | ||||||
|  | \subsection{Multiplexers} | ||||||
|  | 
 | ||||||
|  | Multiplexers are generated by the Verilog HDL frontend for {\tt | ||||||
|  | ?:}-expressions. Multiplexers are also generated by the {\tt proc} pass to map the decision trees | ||||||
|  | from RTLIL::Process objects to logic. | ||||||
|  | 
 | ||||||
|  | The simplest multiplexer cell type is {\tt \$mux}. Cells of this type have a \B{WIDTH} parameter | ||||||
|  | and data inputs \B{A} and \B{B} and a data output \B{Y}, all of the specified width. This cell also | ||||||
|  | has a single bit control input \B{S}. If \B{S} is 0 the value from the \B{A} input is sent to | ||||||
|  | the output, if it is 1 the value from the \B{B} input is sent to the output. So the {\tt \$mux} | ||||||
|  | cell implements the function \lstinline[language=Verilog]; Y = S ? B : A;. | ||||||
|  | 
 | ||||||
|  | The {\tt \$pmux} cell is used to multiplex between many inputs using a one-hot select signal. Cells | ||||||
|  | of this type have a \B{WIDTH} and a \B{S\_WIDTH} parameter and inputs \B{A}, \B{B}, and \B{S} and | ||||||
|  | an output \B{Y}. The \B{S} input is \B{S\_WIDTH} bits wide. The \B{A} input and the output are both | ||||||
|  | \B{WIDTH} bits wide and the \B{B} input is \B{WIDTH}*\B{S\_WIDTH} bits wide. When all bits of | ||||||
|  | \B{S} are zero, the value from \B{A} input is sent to the output. If the $n$'th bit from \B{S} is | ||||||
|  | set, the value $n$'th \B{WIDTH} bits wide slice of the \B{B} input is sent to the output. When more | ||||||
|  | than one bit from \B{S} is set the output is undefined. Cells of this type are used to model | ||||||
|  | ``parallel cases'' (defined by using the {\tt parallel\_case} attribute or detected by | ||||||
|  | an optimization). | ||||||
|  | 
 | ||||||
|  | The {\tt \$tribuf} cell is used to implement tristate logic. Cells of this type have a \B{WIDTH} | ||||||
|  | parameter and inputs \B{A} and \B{EN} and an output \B{Y}. The \B{A} input and \B{Y} output are | ||||||
|  | \B{WIDTH} bits wide, and the \B{EN} input is one bit wide. When \B{EN} is 0, the output \B{Y} | ||||||
|  | is not driven. When \B{EN} is 1, the value from \B{A} input is sent to the \B{Y} output. Therefore, | ||||||
|  | the {\tt \$tribuf} cell implements the function \lstinline[language=Verilog]; Y = EN ? A : 'bz;. | ||||||
|  | 
 | ||||||
|  | Behavioural code with cascaded {\tt if-then-else}- and {\tt case}-statements | ||||||
|  | usually results in trees of multiplexer cells. Many passes (from various | ||||||
|  | optimizations to FSM extraction) heavily depend on these multiplexer trees to | ||||||
|  | understand dependencies between signals. Therefore optimizations should not | ||||||
|  | break these multiplexer trees (e.g.~by replacing a multiplexer between a | ||||||
|  | calculated signal and a constant zero with an {\tt \$and} gate). | ||||||
|  | 
 | ||||||
| \subsection{Registers} | \subsection{Registers} | ||||||
| 
 | 
 | ||||||
| D-Type Flip-Flops are represented by {\tt \$dff} cells. These cells have a clock port \B{CLK}, | D-Type Flip-Flops are represented by {\tt \$dff} cells. These cells have a clock port \B{CLK}, | ||||||
|  |  | ||||||
|  | @ -89,20 +89,30 @@ void handle_loops(RTLIL::Design *design, RTLIL::Module *module) | ||||||
| 					if (cell->output(c.first)) { | 					if (cell->output(c.first)) { | ||||||
| 						SigBit b = c.second.as_bit(); | 						SigBit b = c.second.as_bit(); | ||||||
| 						Wire *w = b.wire; | 						Wire *w = b.wire; | ||||||
| 						log_assert(!w->port_input); | 						if (w->port_input) { | ||||||
| 						w->port_input = true; | 							// In this case, hopefully the loop break has been already created
 | ||||||
| 						w = module->wire(stringf("%s.abci", w->name.c_str())); | 							// Get the non-prefixed wire
 | ||||||
| 						if (!w) { | 							Wire *wo = module->wire(stringf("%s.abco", b.wire->name.c_str())); | ||||||
| 							w = module->addWire(stringf("%s.abci", b.wire->name.c_str()), GetSize(b.wire)); | 							log_assert(wo != nullptr); | ||||||
| 							w->port_output = true; | 							log_assert(wo->port_output); | ||||||
|  | 							log_assert(b.offset < GetSize(wo)); | ||||||
|  | 							c.second = RTLIL::SigBit(wo, b.offset); | ||||||
| 						} | 						} | ||||||
| 						else { | 						else { | ||||||
| 							log_assert(w->port_input); | 							// Create a new output/input loop break
 | ||||||
| 							log_assert(b.offset < GetSize(w)); | 							w->port_input = true; | ||||||
|  | 							w = module->wire(stringf("%s.abco", w->name.c_str())); | ||||||
|  | 							if (!w) { | ||||||
|  | 								w = module->addWire(stringf("%s.abco", b.wire->name.c_str()), GetSize(b.wire)); | ||||||
|  | 								w->port_output = true; | ||||||
|  | 							} | ||||||
|  | 							else { | ||||||
|  | 								log_assert(w->port_input); | ||||||
|  | 								log_assert(b.offset < GetSize(w)); | ||||||
|  | 							} | ||||||
|  | 							w->set_bool_attribute(ID(abc9_scc_break)); | ||||||
|  | 							c.second = RTLIL::SigBit(w, b.offset); | ||||||
| 						} | 						} | ||||||
| 						w->set_bool_attribute(ID(abc9_scc_break)); |  | ||||||
| 						module->swap_names(b.wire, w); |  | ||||||
| 						c.second = RTLIL::SigBit(w, b.offset); |  | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | @ -354,24 +364,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip | ||||||
| 		design->remove(design->module(ID($__abc9__))); | 		design->remove(design->module(ID($__abc9__))); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 		// Now 'unexpose' those wires by undoing
 |  | ||||||
| 		// the expose operation -- remove them from PO/PI
 |  | ||||||
| 		// and re-connecting them back together
 |  | ||||||
| 		for (auto wire : module->wires()) { |  | ||||||
| 			auto it = wire->attributes.find(ID(abc9_scc_break)); |  | ||||||
| 			if (it != wire->attributes.end()) { |  | ||||||
| 				wire->attributes.erase(it); |  | ||||||
| 				log_assert(wire->port_output); |  | ||||||
| 				wire->port_output = false; |  | ||||||
| 				RTLIL::Wire *i_wire = module->wire(wire->name.str() + ".abci"); |  | ||||||
| 				log_assert(i_wire); |  | ||||||
| 				log_assert(i_wire->port_input); |  | ||||||
| 				i_wire->port_input = false; |  | ||||||
| 				module->connect(i_wire, wire); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		module->fixup_ports(); |  | ||||||
| 
 |  | ||||||
| 		log_header(design, "Executing ABC9.\n"); | 		log_header(design, "Executing ABC9.\n"); | ||||||
| 
 | 
 | ||||||
| 		if (!lut_costs.empty()) { | 		if (!lut_costs.empty()) { | ||||||
|  | @ -705,6 +697,25 @@ clone_lut: | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		// Now 'unexpose' those wires by undoing
 | ||||||
|  | 		// the expose operation -- remove them from PO/PI
 | ||||||
|  | 		// and re-connecting them back together
 | ||||||
|  | 		for (auto wire : module->wires()) { | ||||||
|  | 			auto it = wire->attributes.find(ID(abc9_scc_break)); | ||||||
|  | 			if (it != wire->attributes.end()) { | ||||||
|  | 				wire->attributes.erase(it); | ||||||
|  | 				log_assert(wire->port_output); | ||||||
|  | 				wire->port_output = false; | ||||||
|  | 				std::string name = wire->name.str(); | ||||||
|  | 				RTLIL::Wire *i_wire = module->wire(name.substr(0, GetSize(name) - 5)); | ||||||
|  | 				log_assert(i_wire); | ||||||
|  | 				log_assert(i_wire->port_input); | ||||||
|  | 				i_wire->port_input = false; | ||||||
|  | 				module->connect(i_wire, wire); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		module->fixup_ports(); | ||||||
|  | 
 | ||||||
| 		//log("ABC RESULTS:        internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires);
 | 		//log("ABC RESULTS:        internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires);
 | ||||||
| 		log("ABC RESULTS:           input signals: %8d\n", in_wires); | 		log("ABC RESULTS:           input signals: %8d\n", in_wires); | ||||||
| 		log("ABC RESULTS:          output signals: %8d\n", out_wires); | 		log("ABC RESULTS:          output signals: %8d\n", out_wires); | ||||||
|  |  | ||||||
|  | @ -87,11 +87,11 @@ struct IopadmapPass : public Pass { | ||||||
| 	{ | 	{ | ||||||
| 		log_header(design, "Executing IOPADMAP pass (mapping inputs/outputs to IO-PAD cells).\n"); | 		log_header(design, "Executing IOPADMAP pass (mapping inputs/outputs to IO-PAD cells).\n"); | ||||||
| 
 | 
 | ||||||
| 		std::string inpad_celltype, inpad_portname, inpad_portname2; | 		std::string inpad_celltype, inpad_portname_o, inpad_portname_pad; | ||||||
| 		std::string outpad_celltype, outpad_portname, outpad_portname2; | 		std::string outpad_celltype, outpad_portname_i, outpad_portname_pad; | ||||||
| 		std::string inoutpad_celltype, inoutpad_portname, inoutpad_portname2; | 		std::string inoutpad_celltype, inoutpad_portname_io, inoutpad_portname_pad; | ||||||
| 		std::string toutpad_celltype, toutpad_portname, toutpad_portname2, toutpad_portname3; | 		std::string toutpad_celltype, toutpad_portname_oe, toutpad_portname_i, toutpad_portname_pad; | ||||||
| 		std::string tinoutpad_celltype, tinoutpad_portname, tinoutpad_portname2, tinoutpad_portname3, tinoutpad_portname4; | 		std::string tinoutpad_celltype, tinoutpad_portname_oe, tinoutpad_portname_o, tinoutpad_portname_i, tinoutpad_portname_pad; | ||||||
| 		std::string widthparam, nameparam; | 		std::string widthparam, nameparam; | ||||||
| 		pool<pair<IdString, IdString>> ignore; | 		pool<pair<IdString, IdString>> ignore; | ||||||
| 		bool flag_bits = false; | 		bool flag_bits = false; | ||||||
|  | @ -102,35 +102,35 @@ struct IopadmapPass : public Pass { | ||||||
| 			std::string arg = args[argidx]; | 			std::string arg = args[argidx]; | ||||||
| 			if (arg == "-inpad" && argidx+2 < args.size()) { | 			if (arg == "-inpad" && argidx+2 < args.size()) { | ||||||
| 				inpad_celltype = args[++argidx]; | 				inpad_celltype = args[++argidx]; | ||||||
| 				inpad_portname = args[++argidx]; | 				inpad_portname_o = args[++argidx]; | ||||||
| 				split_portname_pair(inpad_portname, inpad_portname2); | 				split_portname_pair(inpad_portname_o, inpad_portname_pad); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (arg == "-outpad" && argidx+2 < args.size()) { | 			if (arg == "-outpad" && argidx+2 < args.size()) { | ||||||
| 				outpad_celltype = args[++argidx]; | 				outpad_celltype = args[++argidx]; | ||||||
| 				outpad_portname = args[++argidx]; | 				outpad_portname_i = args[++argidx]; | ||||||
| 				split_portname_pair(outpad_portname, outpad_portname2); | 				split_portname_pair(outpad_portname_i, outpad_portname_pad); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (arg == "-inoutpad" && argidx+2 < args.size()) { | 			if (arg == "-inoutpad" && argidx+2 < args.size()) { | ||||||
| 				inoutpad_celltype = args[++argidx]; | 				inoutpad_celltype = args[++argidx]; | ||||||
| 				inoutpad_portname = args[++argidx]; | 				inoutpad_portname_io = args[++argidx]; | ||||||
| 				split_portname_pair(inoutpad_portname, inoutpad_portname2); | 				split_portname_pair(inoutpad_portname_io, inoutpad_portname_pad); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (arg == "-toutpad" && argidx+2 < args.size()) { | 			if (arg == "-toutpad" && argidx+2 < args.size()) { | ||||||
| 				toutpad_celltype = args[++argidx]; | 				toutpad_celltype = args[++argidx]; | ||||||
| 				toutpad_portname = args[++argidx]; | 				toutpad_portname_oe = args[++argidx]; | ||||||
| 				split_portname_pair(toutpad_portname, toutpad_portname2); | 				split_portname_pair(toutpad_portname_oe, toutpad_portname_i); | ||||||
| 				split_portname_pair(toutpad_portname2, toutpad_portname3); | 				split_portname_pair(toutpad_portname_i, toutpad_portname_pad); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (arg == "-tinoutpad" && argidx+2 < args.size()) { | 			if (arg == "-tinoutpad" && argidx+2 < args.size()) { | ||||||
| 				tinoutpad_celltype = args[++argidx]; | 				tinoutpad_celltype = args[++argidx]; | ||||||
| 				tinoutpad_portname = args[++argidx]; | 				tinoutpad_portname_oe = args[++argidx]; | ||||||
| 				split_portname_pair(tinoutpad_portname, tinoutpad_portname2); | 				split_portname_pair(tinoutpad_portname_oe, tinoutpad_portname_o); | ||||||
| 				split_portname_pair(tinoutpad_portname2, tinoutpad_portname3); | 				split_portname_pair(tinoutpad_portname_o, tinoutpad_portname_i); | ||||||
| 				split_portname_pair(tinoutpad_portname3, tinoutpad_portname4); | 				split_portname_pair(tinoutpad_portname_i, tinoutpad_portname_pad); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (arg == "-ignore" && argidx+2 < args.size()) { | 			if (arg == "-ignore" && argidx+2 < args.size()) { | ||||||
|  | @ -161,16 +161,16 @@ struct IopadmapPass : public Pass { | ||||||
| 		} | 		} | ||||||
| 		extra_args(args, argidx, design); | 		extra_args(args, argidx, design); | ||||||
| 
 | 
 | ||||||
| 		if (!inpad_portname2.empty()) | 		if (!inpad_portname_pad.empty()) | ||||||
| 			ignore.insert(make_pair(RTLIL::escape_id(inpad_celltype), RTLIL::escape_id(inpad_portname2))); | 			ignore.insert(make_pair(RTLIL::escape_id(inpad_celltype), RTLIL::escape_id(inpad_portname_pad))); | ||||||
| 		if (!outpad_portname2.empty()) | 		if (!outpad_portname_pad.empty()) | ||||||
| 			ignore.insert(make_pair(RTLIL::escape_id(outpad_celltype), RTLIL::escape_id(outpad_portname2))); | 			ignore.insert(make_pair(RTLIL::escape_id(outpad_celltype), RTLIL::escape_id(outpad_portname_pad))); | ||||||
| 		if (!inoutpad_portname2.empty()) | 		if (!inoutpad_portname_pad.empty()) | ||||||
| 			ignore.insert(make_pair(RTLIL::escape_id(inoutpad_celltype), RTLIL::escape_id(inoutpad_portname2))); | 			ignore.insert(make_pair(RTLIL::escape_id(inoutpad_celltype), RTLIL::escape_id(inoutpad_portname_pad))); | ||||||
| 		if (!toutpad_portname3.empty()) | 		if (!toutpad_portname_pad.empty()) | ||||||
| 			ignore.insert(make_pair(RTLIL::escape_id(toutpad_celltype), RTLIL::escape_id(toutpad_portname3))); | 			ignore.insert(make_pair(RTLIL::escape_id(toutpad_celltype), RTLIL::escape_id(toutpad_portname_pad))); | ||||||
| 		if (!tinoutpad_portname4.empty()) | 		if (!tinoutpad_portname_pad.empty()) | ||||||
| 			ignore.insert(make_pair(RTLIL::escape_id(tinoutpad_celltype), RTLIL::escape_id(tinoutpad_portname4))); | 			ignore.insert(make_pair(RTLIL::escape_id(tinoutpad_celltype), RTLIL::escape_id(tinoutpad_portname_pad))); | ||||||
| 
 | 
 | ||||||
| 		for (auto module : design->modules()) | 		for (auto module : design->modules()) | ||||||
| 			if (module->get_blackbox_attribute()) | 			if (module->get_blackbox_attribute()) | ||||||
|  | @ -180,34 +180,25 @@ struct IopadmapPass : public Pass { | ||||||
| 
 | 
 | ||||||
| 		for (auto module : design->selected_modules()) | 		for (auto module : design->selected_modules()) | ||||||
| 		{ | 		{ | ||||||
| 			dict<IdString, pool<int>> skip_wires; |  | ||||||
| 			pool<SigBit> skip_wire_bits; | 			pool<SigBit> skip_wire_bits; | ||||||
| 			SigMap sigmap(module); | 			dict<Wire *, dict<int, pair<Cell *, IdString>>> rewrite_bits; | ||||||
| 
 | 
 | ||||||
| 			for (auto cell : module->cells()) | 			for (auto cell : module->cells()) | ||||||
| 			for (auto port : cell->connections()) | 			for (auto port : cell->connections()) | ||||||
| 				if (ignore.count(make_pair(cell->type, port.first))) | 				if (ignore.count(make_pair(cell->type, port.first))) | ||||||
| 					for (auto bit : sigmap(port.second)) | 					for (auto bit : port.second) | ||||||
| 						skip_wire_bits.insert(bit); | 						skip_wire_bits.insert(bit); | ||||||
| 
 | 
 | ||||||
| 			if (!toutpad_celltype.empty() || !tinoutpad_celltype.empty()) | 			if (!toutpad_celltype.empty() || !tinoutpad_celltype.empty()) | ||||||
| 			{ | 			{ | ||||||
| 				dict<SigBit, pair<IdString, pool<IdString>>> tbuf_bits; | 				dict<SigBit, Cell *> tbuf_bits; | ||||||
| 				pool<pair<IdString, IdString>> norewrites; |  | ||||||
| 				SigMap rewrites; |  | ||||||
| 
 | 
 | ||||||
| 				for (auto cell : module->cells()) | 				for (auto cell : module->cells()) | ||||||
| 					if (cell->type == ID($_TBUF_)) { | 					if (cell->type == ID($_TBUF_)) { | ||||||
| 						SigBit bit = sigmap(cell->getPort(ID::Y).as_bit()); | 						SigBit bit = cell->getPort(ID::Y).as_bit(); | ||||||
| 						tbuf_bits[bit].first = cell->name; | 						tbuf_bits[bit] = cell; | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 				for (auto cell : module->cells()) |  | ||||||
| 				for (auto port : cell->connections()) |  | ||||||
| 				for (auto bit : sigmap(port.second)) |  | ||||||
| 					if (tbuf_bits.count(bit)) |  | ||||||
| 						tbuf_bits.at(bit).second.insert(cell->name); |  | ||||||
| 
 |  | ||||||
| 				for (auto wire : module->selected_wires()) | 				for (auto wire : module->selected_wires()) | ||||||
| 				{ | 				{ | ||||||
| 					if (!wire->port_output) | 					if (!wire->port_output) | ||||||
|  | @ -216,16 +207,11 @@ struct IopadmapPass : public Pass { | ||||||
| 					for (int i = 0; i < GetSize(wire); i++) | 					for (int i = 0; i < GetSize(wire); i++) | ||||||
| 					{ | 					{ | ||||||
| 						SigBit wire_bit(wire, i); | 						SigBit wire_bit(wire, i); | ||||||
| 						SigBit mapped_wire_bit = sigmap(wire_bit); |  | ||||||
| 
 | 
 | ||||||
| 						if (tbuf_bits.count(mapped_wire_bit) == 0) | 						if (tbuf_bits.count(wire_bit) == 0) | ||||||
| 							continue; | 							continue; | ||||||
| 
 | 
 | ||||||
| 						if (skip_wire_bits.count(mapped_wire_bit)) | 						Cell *tbuf_cell = tbuf_bits.at(wire_bit); | ||||||
| 							continue; |  | ||||||
| 
 |  | ||||||
| 						auto &tbuf_cache = tbuf_bits.at(mapped_wire_bit); |  | ||||||
| 						Cell *tbuf_cell = module->cell(tbuf_cache.first); |  | ||||||
| 
 | 
 | ||||||
| 						if (tbuf_cell == nullptr) | 						if (tbuf_cell == nullptr) | ||||||
| 							continue; | 							continue; | ||||||
|  | @ -238,37 +224,16 @@ struct IopadmapPass : public Pass { | ||||||
| 							log("Mapping port %s.%s[%d] using %s.\n", log_id(module), log_id(wire), i, tinoutpad_celltype.c_str()); | 							log("Mapping port %s.%s[%d] using %s.\n", log_id(module), log_id(wire), i, tinoutpad_celltype.c_str()); | ||||||
| 
 | 
 | ||||||
| 							Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(tinoutpad_celltype)); | 							Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(tinoutpad_celltype)); | ||||||
| 							Wire *owire = module->addWire(NEW_ID); |  | ||||||
| 
 | 
 | ||||||
| 							cell->setPort(RTLIL::escape_id(tinoutpad_portname), en_sig); | 							cell->setPort(RTLIL::escape_id(tinoutpad_portname_oe), en_sig); | ||||||
| 							cell->setPort(RTLIL::escape_id(tinoutpad_portname2), owire); | 							cell->setPort(RTLIL::escape_id(tinoutpad_portname_o), wire_bit); | ||||||
| 							cell->setPort(RTLIL::escape_id(tinoutpad_portname3), data_sig); | 							cell->setPort(RTLIL::escape_id(tinoutpad_portname_i), data_sig); | ||||||
| 							cell->setPort(RTLIL::escape_id(tinoutpad_portname4), wire_bit); |  | ||||||
| 							cell->attributes[ID::keep] = RTLIL::Const(1); | 							cell->attributes[ID::keep] = RTLIL::Const(1); | ||||||
| 
 | 
 | ||||||
| 							for (auto cn : tbuf_cache.second) { |  | ||||||
| 								auto c = module->cell(cn); |  | ||||||
| 								if (c == nullptr) |  | ||||||
| 									continue; |  | ||||||
| 								for (auto port : c->connections()) { |  | ||||||
| 									SigSpec sig = port.second; |  | ||||||
| 									bool newsig = false; |  | ||||||
| 									for (auto &bit : sig) |  | ||||||
| 										if (sigmap(bit) == mapped_wire_bit) { |  | ||||||
| 											bit = owire; |  | ||||||
| 											newsig = true; |  | ||||||
| 										} |  | ||||||
| 									if (newsig) |  | ||||||
| 										c->setPort(port.first, sig); |  | ||||||
| 								} |  | ||||||
| 							} |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 							module->remove(tbuf_cell); | 							module->remove(tbuf_cell); | ||||||
| 							skip_wires[wire->name].insert(i); | 							skip_wire_bits.insert(wire_bit); | ||||||
| 
 | 							if (!tinoutpad_portname_pad.empty()) | ||||||
| 							norewrites.insert(make_pair(cell->name, RTLIL::escape_id(tinoutpad_portname4))); | 								rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(tinoutpad_portname_pad)); | ||||||
| 							rewrites.add(sigmap(wire_bit), owire); |  | ||||||
| 							continue; | 							continue; | ||||||
| 						} | 						} | ||||||
| 
 | 
 | ||||||
|  | @ -278,50 +243,19 @@ struct IopadmapPass : public Pass { | ||||||
| 
 | 
 | ||||||
| 							Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(toutpad_celltype)); | 							Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(toutpad_celltype)); | ||||||
| 
 | 
 | ||||||
| 							cell->setPort(RTLIL::escape_id(toutpad_portname), en_sig); | 							cell->setPort(RTLIL::escape_id(toutpad_portname_oe), en_sig); | ||||||
| 							cell->setPort(RTLIL::escape_id(toutpad_portname2), data_sig); | 							cell->setPort(RTLIL::escape_id(toutpad_portname_i), data_sig); | ||||||
| 							cell->setPort(RTLIL::escape_id(toutpad_portname3), wire_bit); |  | ||||||
| 							cell->attributes[ID::keep] = RTLIL::Const(1); | 							cell->attributes[ID::keep] = RTLIL::Const(1); | ||||||
| 
 | 
 | ||||||
| 							for (auto cn : tbuf_cache.second) { |  | ||||||
| 								auto c = module->cell(cn); |  | ||||||
| 								if (c == nullptr) |  | ||||||
| 									continue; |  | ||||||
| 								for (auto port : c->connections()) { |  | ||||||
| 									SigSpec sig = port.second; |  | ||||||
| 									bool newsig = false; |  | ||||||
| 									for (auto &bit : sig) |  | ||||||
| 										if (sigmap(bit) == mapped_wire_bit) { |  | ||||||
| 											bit = data_sig; |  | ||||||
| 											newsig = true; |  | ||||||
| 										} |  | ||||||
| 									if (newsig) |  | ||||||
| 										c->setPort(port.first, sig); |  | ||||||
| 								} |  | ||||||
| 							} |  | ||||||
| 
 |  | ||||||
| 							module->remove(tbuf_cell); | 							module->remove(tbuf_cell); | ||||||
| 							skip_wires[wire->name].insert(i); | 							module->connect(wire_bit, data_sig); | ||||||
|  | 							skip_wire_bits.insert(wire_bit); | ||||||
|  | 							if (!toutpad_portname_pad.empty()) | ||||||
|  | 								rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(toutpad_portname_pad)); | ||||||
| 							continue; | 							continue; | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 
 |  | ||||||
| 				if (GetSize(norewrites)) |  | ||||||
| 				{ |  | ||||||
| 					for (auto cell : module->cells()) |  | ||||||
| 					for (auto port : cell->connections()) |  | ||||||
| 					{ |  | ||||||
| 						if (norewrites.count(make_pair(cell->name, port.first))) |  | ||||||
| 							continue; |  | ||||||
| 
 |  | ||||||
| 						SigSpec orig_sig = sigmap(port.second); |  | ||||||
| 						SigSpec new_sig = rewrites(orig_sig); |  | ||||||
| 
 |  | ||||||
| 						if (orig_sig != new_sig) |  | ||||||
| 							cell->setPort(port.first, new_sig); |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			for (auto wire : module->selected_wires()) | 			for (auto wire : module->selected_wires()) | ||||||
|  | @ -329,17 +263,11 @@ struct IopadmapPass : public Pass { | ||||||
| 				if (!wire->port_id) | 				if (!wire->port_id) | ||||||
| 					continue; | 					continue; | ||||||
| 
 | 
 | ||||||
| 				std::string celltype, portname, portname2; | 				std::string celltype, portname_int, portname_pad; | ||||||
| 				pool<int> skip_bit_indices; | 				pool<int> skip_bit_indices; | ||||||
| 
 | 
 | ||||||
| 				if (skip_wires.count(wire->name)) { |  | ||||||
| 					if (!flag_bits) |  | ||||||
| 						continue; |  | ||||||
| 					skip_bit_indices = skip_wires.at(wire->name); |  | ||||||
| 				} |  | ||||||
| 
 |  | ||||||
| 				for (int i = 0; i < GetSize(wire); i++) | 				for (int i = 0; i < GetSize(wire); i++) | ||||||
| 					if (skip_wire_bits.count(sigmap(SigBit(wire, i)))) | 					if (skip_wire_bits.count(SigBit(wire, i))) | ||||||
| 						skip_bit_indices.insert(i); | 						skip_bit_indices.insert(i); | ||||||
| 
 | 
 | ||||||
| 				if (GetSize(wire) == GetSize(skip_bit_indices)) | 				if (GetSize(wire) == GetSize(skip_bit_indices)) | ||||||
|  | @ -351,8 +279,8 @@ struct IopadmapPass : public Pass { | ||||||
| 						continue; | 						continue; | ||||||
| 					} | 					} | ||||||
| 					celltype = inpad_celltype; | 					celltype = inpad_celltype; | ||||||
| 					portname = inpad_portname; | 					portname_int = inpad_portname_o; | ||||||
| 					portname2 = inpad_portname2; | 					portname_pad = inpad_portname_pad; | ||||||
| 				} else | 				} else | ||||||
| 				if (!wire->port_input && wire->port_output) { | 				if (!wire->port_input && wire->port_output) { | ||||||
| 					if (outpad_celltype.empty()) { | 					if (outpad_celltype.empty()) { | ||||||
|  | @ -360,8 +288,8 @@ struct IopadmapPass : public Pass { | ||||||
| 						continue; | 						continue; | ||||||
| 					} | 					} | ||||||
| 					celltype = outpad_celltype; | 					celltype = outpad_celltype; | ||||||
| 					portname = outpad_portname; | 					portname_int = outpad_portname_i; | ||||||
| 					portname2 = outpad_portname2; | 					portname_pad = outpad_portname_pad; | ||||||
| 				} else | 				} else | ||||||
| 				if (wire->port_input && wire->port_output) { | 				if (wire->port_input && wire->port_output) { | ||||||
| 					if (inoutpad_celltype.empty()) { | 					if (inoutpad_celltype.empty()) { | ||||||
|  | @ -369,8 +297,8 @@ struct IopadmapPass : public Pass { | ||||||
| 						continue; | 						continue; | ||||||
| 					} | 					} | ||||||
| 					celltype = inoutpad_celltype; | 					celltype = inoutpad_celltype; | ||||||
| 					portname = inoutpad_portname; | 					portname_int = inoutpad_portname_io; | ||||||
| 					portname2 = inoutpad_portname2; | 					portname_pad = inoutpad_portname_pad; | ||||||
| 				} else | 				} else | ||||||
| 					log_abort(); | 					log_abort(); | ||||||
| 
 | 
 | ||||||
|  | @ -381,29 +309,20 @@ struct IopadmapPass : public Pass { | ||||||
| 
 | 
 | ||||||
| 				log("Mapping port %s.%s using %s.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name), celltype.c_str()); | 				log("Mapping port %s.%s using %s.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name), celltype.c_str()); | ||||||
| 
 | 
 | ||||||
| 				RTLIL::Wire *new_wire = NULL; |  | ||||||
| 				if (!portname2.empty()) { |  | ||||||
| 					new_wire = module->addWire(NEW_ID, wire); |  | ||||||
| 					module->swap_names(new_wire, wire); |  | ||||||
| 					wire->attributes.clear(); |  | ||||||
| 				} |  | ||||||
| 
 |  | ||||||
| 				if (flag_bits) | 				if (flag_bits) | ||||||
| 				{ | 				{ | ||||||
| 					for (int i = 0; i < wire->width; i++) | 					for (int i = 0; i < wire->width; i++) | ||||||
| 					{ | 					{ | ||||||
| 						if (skip_bit_indices.count(i)) { | 						if (skip_bit_indices.count(i)) | ||||||
| 							if (wire->port_output) |  | ||||||
| 								module->connect(SigSpec(new_wire, i), SigSpec(wire, i)); |  | ||||||
| 							else |  | ||||||
| 								module->connect(SigSpec(wire, i), SigSpec(new_wire, i)); |  | ||||||
| 							continue; | 							continue; | ||||||
| 						} | 
 | ||||||
|  | 						SigBit wire_bit(wire, i); | ||||||
| 
 | 
 | ||||||
| 						RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); | 						RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); | ||||||
| 						cell->setPort(RTLIL::escape_id(portname), RTLIL::SigSpec(wire, i)); | 						cell->setPort(RTLIL::escape_id(portname_int), wire_bit); | ||||||
| 						if (!portname2.empty()) | 
 | ||||||
| 							cell->setPort(RTLIL::escape_id(portname2), RTLIL::SigSpec(new_wire, i)); | 						if (!portname_pad.empty()) | ||||||
|  | 							rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(portname_pad)); | ||||||
| 						if (!widthparam.empty()) | 						if (!widthparam.empty()) | ||||||
| 							cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(1); | 							cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(1); | ||||||
| 						if (!nameparam.empty()) | 						if (!nameparam.empty()) | ||||||
|  | @ -414,9 +333,15 @@ struct IopadmapPass : public Pass { | ||||||
| 				else | 				else | ||||||
| 				{ | 				{ | ||||||
| 					RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); | 					RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); | ||||||
| 					cell->setPort(RTLIL::escape_id(portname), RTLIL::SigSpec(wire)); | 					cell->setPort(RTLIL::escape_id(portname_int), RTLIL::SigSpec(wire)); | ||||||
| 					if (!portname2.empty()) | 
 | ||||||
| 						cell->setPort(RTLIL::escape_id(portname2), RTLIL::SigSpec(new_wire)); | 					if (!portname_pad.empty()) { | ||||||
|  | 						RTLIL::Wire *new_wire = NULL; | ||||||
|  | 						new_wire = module->addWire(NEW_ID, wire); | ||||||
|  | 						module->swap_names(new_wire, wire); | ||||||
|  | 						wire->attributes.clear(); | ||||||
|  | 						cell->setPort(RTLIL::escape_id(portname_pad), RTLIL::SigSpec(new_wire)); | ||||||
|  | 					} | ||||||
| 					if (!widthparam.empty()) | 					if (!widthparam.empty()) | ||||||
| 						cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(wire->width); | 						cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(wire->width); | ||||||
| 					if (!nameparam.empty()) | 					if (!nameparam.empty()) | ||||||
|  | @ -424,6 +349,32 @@ struct IopadmapPass : public Pass { | ||||||
| 					cell->attributes[ID::keep] = RTLIL::Const(1); | 					cell->attributes[ID::keep] = RTLIL::Const(1); | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
|  | 				if (!rewrite_bits.count(wire)) { | ||||||
|  | 					wire->port_id = 0; | ||||||
|  | 					wire->port_input = false; | ||||||
|  | 					wire->port_output = false; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			for (auto &it : rewrite_bits) { | ||||||
|  | 				RTLIL::Wire *wire = it.first; | ||||||
|  | 				RTLIL::Wire *new_wire = module->addWire(NEW_ID, wire); | ||||||
|  | 				module->swap_names(new_wire, wire); | ||||||
|  | 				wire->attributes.clear(); | ||||||
|  | 				for (int i = 0; i < wire->width; i++) | ||||||
|  | 				{ | ||||||
|  | 					SigBit wire_bit(wire, i); | ||||||
|  | 					if (!it.second.count(i)) { | ||||||
|  | 						if (wire->port_output) | ||||||
|  | 							module->connect(SigSpec(new_wire, i), SigSpec(wire, i)); | ||||||
|  | 						else | ||||||
|  | 							module->connect(SigSpec(wire, i), SigSpec(new_wire, i)); | ||||||
|  | 					} else { | ||||||
|  | 						auto &new_conn = it.second.at(i); | ||||||
|  | 						new_conn.first->setPort(new_conn.second, RTLIL::SigSpec(new_wire, i)); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
| 				wire->port_id = 0; | 				wire->port_id = 0; | ||||||
| 				wire->port_input = false; | 				wire->port_input = false; | ||||||
| 				wire->port_output = false; | 				wire->port_output = false; | ||||||
|  |  | ||||||
|  | @ -1,133 +1,282 @@ | ||||||
|  | `default_nettype none | ||||||
| //All DFF* have INIT, but the hardware is always initialised to the reset | //All DFF* have INIT, but the hardware is always initialised to the reset | ||||||
| //value regardless. The parameter is ignored. | //value regardless. The parameter is ignored. | ||||||
| 
 | 
 | ||||||
| // DFFN      D Flip-Flop with Negative-Edge Clock | // DFFN			 D Flip-Flop with Negative-Edge Clock | ||||||
| module  \$_DFF_N_ (input D, C, output Q); DFFN _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); endmodule | module	\$_DFF_N_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, output Q); | ||||||
| // DFF       D Flip-Flop | 	generate | ||||||
| module  \$_DFF_P_ (input D, C, output Q); DFF _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); endmodule | 		if (_TECHMAP_WIREINIT_Q_ === 1'b1) | ||||||
|  | 			DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(1'b0)); | ||||||
|  | 		else | ||||||
|  | 			DFFN _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); | ||||||
|  | 	endgenerate | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = 1; | ||||||
|  | endmodule | ||||||
| 
 | 
 | ||||||
| // DFFE      D Flip-Flop with Clock Enable | // DFF			 D Flip-Flop | ||||||
| module  \$_DFFE_PP_ (input D, C, E, output Q); DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E)); endmodule | module	\$_DFF_P_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, output Q); | ||||||
| module  \$_DFFE_PN_ (input D, C, E, output Q); DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(!E)); endmodule | 	generate | ||||||
|  | 		if (_TECHMAP_WIREINIT_Q_ === 1'b1) | ||||||
|  | 			DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(1'b0)); | ||||||
|  | 		else | ||||||
|  | 			DFF _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); | ||||||
|  | 	endgenerate | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = 1; | ||||||
|  | endmodule | ||||||
| 
 | 
 | ||||||
| // DFFNE     D Flip-Flop with Negative-Edge Clock and Clock Enable | // DFFE			 D Flip-Flop with Clock Enable | ||||||
| module  \$_DFFE_NP_ (input D, C, E, output Q); DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E)); endmodule | module	\$_DFFE_PP_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, E, output Q); | ||||||
| module  \$_DFFE_NN_ (input D, C, E, output Q); DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(!E)); endmodule | 	generate | ||||||
|  | 		if (_TECHMAP_WIREINIT_Q_ === 1'b1) | ||||||
|  | 			DFFSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E), .SET(1'b0)); | ||||||
|  | 		else | ||||||
|  | 			DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E)); | ||||||
|  | 	endgenerate | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = 1; | ||||||
|  | endmodule | ||||||
| 
 | 
 | ||||||
| // DFFR      D Flip-Flop with Synchronous Reset | module	\$_DFFE_PN_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, E, output Q); | ||||||
| module  \$__DFFS_PN0_ (input D, C, R, output Q); DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R)); endmodule | 	generate | ||||||
| module  \$__DFFS_PP0_ (input D, C, R, output Q); DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R)); endmodule | 		if (_TECHMAP_WIREINIT_Q_ === 1'b1) | ||||||
|  | 			DFFSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(!E), .SET(1'b0)); | ||||||
|  | 		else | ||||||
|  | 			DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(!E)); | ||||||
|  | 	endgenerate | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = 1; | ||||||
|  | endmodule | ||||||
| 
 | 
 | ||||||
| // DFFNR     D Flip-Flop with Negative-Edge Clock and Synchronous Reset | // DFFNE		 D Flip-Flop with Negative-Edge Clock and Clock Enable | ||||||
| module  \$__DFFS_NN0_ (input D, C, R, output Q); DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R)); endmodule | module	\$_DFFE_NP_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, E, output Q); | ||||||
| module  \$__DFFS_NP0_ (input D, C, R, output Q); DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R)); endmodule | 	generate | ||||||
|  | 		if (_TECHMAP_WIREINIT_Q_ === 1'b1) | ||||||
|  | 			DFFNSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E), .SET(1'b0)); | ||||||
|  | 		else | ||||||
|  | 			DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E)); | ||||||
|  | 	endgenerate | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = 1; | ||||||
|  | endmodule | ||||||
| 
 | 
 | ||||||
| // DFFRE     D Flip-Flop with Clock Enable and Synchronous Reset | module	\$_DFFE_NN_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, E, output Q); | ||||||
| module  \$__DFFSE_PN0 (input D, C, R, E, output Q); DFFRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R), .CE(E)); endmodule | 	generate | ||||||
| module  \$__DFFSE_PP0 (input D, C, R, E, output Q); DFFRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R), .CE(E)); endmodule | 		if (_TECHMAP_WIREINIT_Q_ === 1'b1) | ||||||
|  | 			DFFNSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(!E), .SET(1'b0)); | ||||||
|  | 		else | ||||||
|  | 			DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(!E)); | ||||||
|  | 	endgenerate | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = 1; | ||||||
|  | endmodule | ||||||
| 
 | 
 | ||||||
| // DFFNRE    D Flip-Flop with Negative-Edge Clock,Clock Enable, and Synchronous Reset | // DFFR			 D Flip-Flop with Synchronous Reset | ||||||
| module  \$__DFFNSE_PN0 (input D, C, R, E, output Q); DFFNRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R), .CE(E)); endmodule | module	\$__DFFS_PN0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); | ||||||
| module  \$__DFFNSE_PP0 (input D, C, R, E, output Q); DFFNRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R), .CE(E)); endmodule | 	DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; | ||||||
|  | endmodule | ||||||
| 
 | 
 | ||||||
| // DFFS      D Flip-Flop with Synchronous Set | module	\$__DFFS_PP0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); | ||||||
| module  \$__DFFS_PN1_ (input D, C, R, output Q); DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R)); endmodule | 	DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R)); | ||||||
| module  \$__DFFS_PP1_ (input D, C, R, output Q); DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R)); endmodule | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; | ||||||
|  | endmodule | ||||||
| 
 | 
 | ||||||
| // DFFNS     D Flip-Flop with Negative-Edge Clock and Synchronous Set | // DFFNR		 D Flip-Flop with Negative-Edge Clock and Synchronous Reset | ||||||
| module  \$__DFFS_NN1_ (input D, C, R, output Q); DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R)); endmodule | module	\$__DFFS_NN0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); | ||||||
| module  \$__DFFS_NP1_ (input D, C, R, output Q); DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R)); endmodule | 	DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; | ||||||
|  | endmodule | ||||||
|  | module	\$__DFFS_NP0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); | ||||||
|  | 	DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; | ||||||
|  | endmodule | ||||||
| 
 | 
 | ||||||
| // DFFSE     D Flip-Flop with Clock Enable and Synchronous Set | // DFFRE		 D Flip-Flop with Clock Enable and Synchronous Reset | ||||||
| module  \$__DFFSE_PN1 (input D, C, R, E, output Q); DFFSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R), .CE(E)); endmodule | module	\$__DFFSE_PN0 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); | ||||||
| module  \$__DFFSE_PP1 (input D, C, R, E, output Q); DFFSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R), .CE(E)); endmodule | 	DFFRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R), .CE(E)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; | ||||||
|  | endmodule | ||||||
|  | module	\$__DFFSE_PP0 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); | ||||||
|  | 	DFFRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R), .CE(E)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; | ||||||
|  | endmodule | ||||||
| 
 | 
 | ||||||
| // DFFNSE    D Flip-Flop with Negative-Edge Clock,Clock Enable,and Synchronous Set | // DFFNRE		 D Flip-Flop with Negative-Edge Clock,Clock Enable, and Synchronous Reset | ||||||
| module  \$__DFFSE_NN1 (input D, C, R, E, output Q); DFFNSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R), .CE(E)); endmodule | module	\$__DFFSE_NN0 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); | ||||||
| module  \$__DFFSE_NP1 (input D, C, R, E, output Q); DFFNSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R), .CE(E)); endmodule | 	DFFNRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R), .CE(E)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; | ||||||
|  | endmodule | ||||||
|  | module	\$__DFFSE_NP0 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); | ||||||
|  | 	DFFNRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R), .CE(E)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; | ||||||
|  | endmodule | ||||||
| 
 | 
 | ||||||
| // DFFP      D Flip-Flop with Asynchronous Preset | // DFFS			 D Flip-Flop with Synchronous Set | ||||||
| module  \$_DFF_PP1_ (input D, C, R, output Q); DFFP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R)); endmodule | module	\$__DFFS_PN1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); | ||||||
| module  \$_DFF_PN1_ (input D, C, R, output Q); DFFP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R)); endmodule | 	DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; | ||||||
|  | endmodule | ||||||
|  | module	\$__DFFS_PP1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); | ||||||
|  | 	DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; | ||||||
|  | endmodule | ||||||
| 
 | 
 | ||||||
| // DFFNP     D Flip-Flop with Negative-Edge Clock and Asynchronous Preset | // DFFNS		 D Flip-Flop with Negative-Edge Clock and Synchronous Set | ||||||
| module  \$_DFF_NP1_ (input D, C, R, output Q); DFFNP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R)); endmodule | module	\$__DFFS_NN1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); | ||||||
| module  \$_DFF_NN1_ (input D, C, R, output Q); DFFNP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R)); endmodule | 	DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; | ||||||
|  | endmodule | ||||||
|  | module	\$__DFFS_NP1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); | ||||||
|  | 	DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; | ||||||
|  | endmodule | ||||||
| 
 | 
 | ||||||
| // DFFC      D Flip-Flop with Asynchronous Clear | // DFFSE		 D Flip-Flop with Clock Enable and Synchronous Set | ||||||
| module  \$_DFF_PP0_ (input D, C, R, output Q); DFFC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R)); endmodule | module	\$__DFFSE_PN1 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); | ||||||
| module  \$_DFF_PN0_ (input D, C, R, output Q); DFFC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R)); endmodule | 	DFFSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R), .CE(E)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; | ||||||
|  | endmodule | ||||||
|  | module	\$__DFFSE_PP1 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); | ||||||
|  | 	DFFSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R), .CE(E)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; | ||||||
|  | endmodule | ||||||
| 
 | 
 | ||||||
| // DFFNC     D Flip-Flop with Negative-Edge Clock and Asynchronous Clear | // DFFNSE		 D Flip-Flop with Negative-Edge Clock,Clock Enable,and Synchronous Set | ||||||
| module  \$_DFF_NP0_ (input D, C, R, output Q); DFFNC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R)); endmodule | module	\$__DFFSE_NN1 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); | ||||||
| module  \$_DFF_NN0_ (input D, C, R, output Q); DFFNC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R)); endmodule | 	DFFNSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R), .CE(E)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; | ||||||
|  | endmodule | ||||||
|  | module	\$__DFFSE_NP1 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); | ||||||
|  | 	DFFNSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R), .CE(E)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; | ||||||
|  | endmodule | ||||||
| 
 | 
 | ||||||
| // DFFPE     D Flip-Flop with Clock Enable and Asynchronous Preset | // DFFP			 D Flip-Flop with Asynchronous Preset | ||||||
| module  \$__DFFE_PP1 (input D, C, R, E, output Q); DFFPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R), .CE(E)); endmodule | module	\$_DFF_PP1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); | ||||||
| module  \$__DFFE_PN1 (input D, C, R, E, output Q); DFFPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R), .CE(E)); endmodule | 	DFFP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; | ||||||
|  | endmodule | ||||||
|  | module	\$_DFF_PN1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); | ||||||
|  | 	DFFP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; | ||||||
|  | endmodule | ||||||
| 
 | 
 | ||||||
| // DFFNPE    D Flip-Flop with Negative-Edge Clock,Clock Enable, and Asynchronous Preset | // DFFNP		 D Flip-Flop with Negative-Edge Clock and Asynchronous Preset | ||||||
| module  \$__DFFE_NP1 (input D, C, R, E, output Q); DFFNPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R), .CE(E)); endmodule | module	\$_DFF_NP1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); | ||||||
| module  \$__DFFE_NN1 (input D, C, R, E, output Q); DFFNPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R), .CE(E)); endmodule | 	DFFNP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; | ||||||
|  | endmodule | ||||||
|  | module	\$_DFF_NN1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); | ||||||
|  | 	DFFNP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; | ||||||
|  | endmodule | ||||||
| 
 | 
 | ||||||
| // DFFCE     D Flip-Flop with Clock Enable and Asynchronous Clear | // DFFC			 D Flip-Flop with Asynchronous Clear | ||||||
| module  \$__DFFE_PP0 (input D, C, R, E, output Q); DFFCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R), .CE(E)); endmodule | module	\$_DFF_PP0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); | ||||||
| module  \$__DFFE_PN0 (input D, C, R, E, output Q); DFFCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R), .CE(E)); endmodule | 	DFFC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; | ||||||
|  | endmodule | ||||||
|  | module	\$_DFF_PN0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); | ||||||
|  | 	DFFC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; | ||||||
|  | endmodule | ||||||
| 
 | 
 | ||||||
| // DFFNCE    D Flip-Flop with Negative-Edge Clock,Clock Enable and Asynchronous Clear | // DFFNC		 D Flip-Flop with Negative-Edge Clock and Asynchronous Clear | ||||||
| module  \$__DFFE_NP0 (input D, C, R, E, output Q); DFFNCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R), .CE(E)); endmodule | module	\$_DFF_NP0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); | ||||||
| module  \$__DFFE_NN0 (input D, C, R, E, output Q); DFFNCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R), .CE(E)); endmodule | 	DFFNC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; | ||||||
|  | endmodule | ||||||
|  | module	\$_DFF_NN0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); | ||||||
|  | 	DFFNC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | // DFFPE		 D Flip-Flop with Clock Enable and Asynchronous Preset | ||||||
|  | module	\$__DFFE_PP1 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); | ||||||
|  | 	DFFPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R), .CE(E)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; | ||||||
|  | endmodule | ||||||
|  | module	\$__DFFE_PN1 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); | ||||||
|  | 	DFFPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R), .CE(E)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | // DFFNPE		 D Flip-Flop with Negative-Edge Clock,Clock Enable, and Asynchronous Preset | ||||||
|  | module	\$__DFFE_NP1 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); | ||||||
|  | 	DFFNPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R), .CE(E)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; | ||||||
|  | endmodule | ||||||
|  | module	\$__DFFE_NN1 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); | ||||||
|  | 	DFFNPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R), .CE(E)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | // DFFCE		 D Flip-Flop with Clock Enable and Asynchronous Clear | ||||||
|  | module	\$__DFFE_PP0 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); | ||||||
|  | 	DFFCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R), .CE(E)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; | ||||||
|  | endmodule | ||||||
|  | module	\$__DFFE_PN0 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); | ||||||
|  | 	DFFCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R), .CE(E)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | // DFFNCE		 D Flip-Flop with Negative-Edge Clock,Clock Enable and Asynchronous Clear | ||||||
|  | module	\$__DFFE_NP0 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); | ||||||
|  | 	DFFNCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R), .CE(E)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; | ||||||
|  | endmodule | ||||||
|  | module	\$__DFFE_NN0 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); | ||||||
|  | 	DFFNCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R), .CE(E)); | ||||||
|  | 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; | ||||||
|  | endmodule | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| module \$lut (A, Y); | module \$lut (A, Y); | ||||||
|   parameter WIDTH = 0; | 	parameter WIDTH = 0; | ||||||
|   parameter LUT = 0; | 	parameter LUT = 0; | ||||||
| 
 | 
 | ||||||
|   input [WIDTH-1:0] A; | 	input [WIDTH-1:0] A; | ||||||
|   output Y; | 	output Y; | ||||||
| 
 | 
 | ||||||
|   generate | 	generate | ||||||
|     if (WIDTH == 1) begin | 		if (WIDTH == 1) begin | ||||||
|       LUT1 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.F(Y), | 			LUT1 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.F(Y), | ||||||
|         .I0(A[0])); | 				.I0(A[0])); | ||||||
|     end else | 		end else | ||||||
|     if (WIDTH == 2) begin | 		if (WIDTH == 2) begin | ||||||
|       LUT2 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.F(Y), | 			LUT2 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.F(Y), | ||||||
|         .I0(A[0]), .I1(A[1])); | 				.I0(A[0]), .I1(A[1])); | ||||||
|     end else | 		end else | ||||||
|     if (WIDTH == 3) begin | 		if (WIDTH == 3) begin | ||||||
|       LUT3 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.F(Y), | 			LUT3 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.F(Y), | ||||||
|         .I0(A[0]), .I1(A[1]), .I2(A[2])); | 				.I0(A[0]), .I1(A[1]), .I2(A[2])); | ||||||
|     end else | 		end else | ||||||
|     if (WIDTH == 4) begin | 		if (WIDTH == 4) begin | ||||||
|       LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.F(Y), | 			LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.F(Y), | ||||||
|         .I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(A[3])); | 				.I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(A[3])); | ||||||
|     end else | 		end else | ||||||
|     if (WIDTH == 5) begin | 		if (WIDTH == 5) begin | ||||||
|       wire f0, f1; | 			wire f0, f1; | ||||||
|       \$lut #(.LUT(LUT[15: 0]), .WIDTH(4)) lut0 (.A(A[3:0]), .Y(f0)); | 			\$lut #(.LUT(LUT[15: 0]), .WIDTH(4)) lut0 (.A(A[3:0]), .Y(f0)); | ||||||
|       \$lut #(.LUT(LUT[31:16]), .WIDTH(4)) lut1 (.A(A[3:0]), .Y(f1)); | 			\$lut #(.LUT(LUT[31:16]), .WIDTH(4)) lut1 (.A(A[3:0]), .Y(f1)); | ||||||
|       MUX2_LUT5 mux5(.I0(f0), .I1(f1), .S0(A[4]), .O(Y)); | 			MUX2_LUT5 mux5(.I0(f0), .I1(f1), .S0(A[4]), .O(Y)); | ||||||
|     end else | 		end else | ||||||
|     if (WIDTH == 6) begin | 		if (WIDTH == 6) begin | ||||||
|       wire f0, f1; | 			wire f0, f1; | ||||||
|       \$lut #(.LUT(LUT[31: 0]), .WIDTH(5)) lut0 (.A(A[4:0]), .Y(f0)); | 			\$lut #(.LUT(LUT[31: 0]), .WIDTH(5)) lut0 (.A(A[4:0]), .Y(f0)); | ||||||
|       \$lut #(.LUT(LUT[63:32]), .WIDTH(5)) lut1 (.A(A[4:0]), .Y(f1)); | 			\$lut #(.LUT(LUT[63:32]), .WIDTH(5)) lut1 (.A(A[4:0]), .Y(f1)); | ||||||
|       MUX2_LUT6 mux6(.I0(f0), .I1(f1), .S0(A[5]), .O(Y)); | 			MUX2_LUT6 mux6(.I0(f0), .I1(f1), .S0(A[5]), .O(Y)); | ||||||
|     end else | 		end else | ||||||
|     if (WIDTH == 7) begin | 		if (WIDTH == 7) begin | ||||||
|       wire f0, f1; | 			wire f0, f1; | ||||||
|       \$lut #(.LUT(LUT[63: 0]), .WIDTH(6)) lut0 (.A(A[5:0]), .Y(f0)); | 			\$lut #(.LUT(LUT[63: 0]), .WIDTH(6)) lut0 (.A(A[5:0]), .Y(f0)); | ||||||
|       \$lut #(.LUT(LUT[127:64]), .WIDTH(6)) lut1 (.A(A[5:0]), .Y(f1)); | 			\$lut #(.LUT(LUT[127:64]), .WIDTH(6)) lut1 (.A(A[5:0]), .Y(f1)); | ||||||
|       MUX2_LUT7 mux7(.I0(f0), .I1(f1), .S0(A[6]), .O(Y)); | 			MUX2_LUT7 mux7(.I0(f0), .I1(f1), .S0(A[6]), .O(Y)); | ||||||
|     end else | 		end else | ||||||
|     if (WIDTH == 8) begin | 		if (WIDTH == 8) begin | ||||||
|       wire f0, f1; | 			wire f0, f1; | ||||||
|       \$lut #(.LUT(LUT[127: 0]), .WIDTH(7)) lut0 (.A(A[6:0]), .Y(f0)); | 			\$lut #(.LUT(LUT[127: 0]), .WIDTH(7)) lut0 (.A(A[6:0]), .Y(f0)); | ||||||
|       \$lut #(.LUT(LUT[255:128]), .WIDTH(7)) lut1 (.A(A[6:0]), .Y(f1)); | 			\$lut #(.LUT(LUT[255:128]), .WIDTH(7)) lut1 (.A(A[6:0]), .Y(f1)); | ||||||
|       MUX2_LUT8 mux8(.I0(f0), .I1(f1), .S0(A[7]), .O(Y)); | 			MUX2_LUT8 mux8(.I0(f0), .I1(f1), .S0(A[7]), .O(Y)); | ||||||
|     end else begin | 		end else begin | ||||||
|       wire _TECHMAP_FAIL_ = 1; | 			wire _TECHMAP_FAIL_ = 1; | ||||||
|     end | 		end | ||||||
|   endgenerate | 	endgenerate | ||||||
| endmodule | endmodule | ||||||
|  |  | ||||||
|  | @ -67,6 +67,9 @@ struct SynthGowinPass : public ScriptPass | ||||||
| 		log("    -nowidelut\n"); | 		log("    -nowidelut\n"); | ||||||
| 		log("        do not use muxes to implement LUTs larger than LUT4s\n"); | 		log("        do not use muxes to implement LUTs larger than LUT4s\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
|  | 		log("    -noiopads\n"); | ||||||
|  | 		log("        do not emit IOB at top level ports\n"); | ||||||
|  | 		log("\n"); | ||||||
| 		log("    -abc9\n"); | 		log("    -abc9\n"); | ||||||
| 		log("        use new ABC9 flow (EXPERIMENTAL)\n"); | 		log("        use new ABC9 flow (EXPERIMENTAL)\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
|  | @ -77,7 +80,7 @@ struct SynthGowinPass : public ScriptPass | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	string top_opt, vout_file; | 	string top_opt, vout_file; | ||||||
| 	bool retime, nobram, nodram, flatten, nodffe, nowidelut, abc9; | 	bool retime, nobram, nodram, flatten, nodffe, nowidelut, abc9, noiopads; | ||||||
| 
 | 
 | ||||||
| 	void clear_flags() YS_OVERRIDE | 	void clear_flags() YS_OVERRIDE | ||||||
| 	{ | 	{ | ||||||
|  | @ -90,6 +93,7 @@ struct SynthGowinPass : public ScriptPass | ||||||
| 		nodram = false; | 		nodram = false; | ||||||
| 		nowidelut = false; | 		nowidelut = false; | ||||||
| 		abc9 = false; | 		abc9 = false; | ||||||
|  | 		noiopads = false; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE | 	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE | ||||||
|  | @ -144,6 +148,10 @@ struct SynthGowinPass : public ScriptPass | ||||||
| 				abc9 = true; | 				abc9 = true; | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|  | 			if (args[argidx] == "-noiopads") { | ||||||
|  | 				noiopads = true; | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| 		extra_args(args, argidx, design); | 		extra_args(args, argidx, design); | ||||||
|  | @ -208,7 +216,7 @@ struct SynthGowinPass : public ScriptPass | ||||||
| 		if (check_label("map_ffs")) | 		if (check_label("map_ffs")) | ||||||
| 		{ | 		{ | ||||||
| 			run("dffsr2dff"); | 			run("dffsr2dff"); | ||||||
| 			run("dff2dffs"); | 			run("dff2dffs -match-init"); | ||||||
| 			run("opt_clean"); | 			run("opt_clean"); | ||||||
| 			if (!nodffe) | 			if (!nodffe) | ||||||
| 				run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*"); | 				run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*"); | ||||||
|  | @ -236,8 +244,9 @@ struct SynthGowinPass : public ScriptPass | ||||||
| 			run("techmap -map +/gowin/cells_map.v"); | 			run("techmap -map +/gowin/cells_map.v"); | ||||||
| 			run("setundef -undriven -params -zero"); | 			run("setundef -undriven -params -zero"); | ||||||
| 			run("hilomap -singleton -hicell VCC V -locell GND G"); | 			run("hilomap -singleton -hicell VCC V -locell GND G"); | ||||||
| 			run("iopadmap -bits -inpad IBUF O:I -outpad OBUF I:O " | 			if (!noiopads || help_mode) | ||||||
| 				"-toutpad TBUF OEN:I:O -tinoutpad IOBUF OEN:O:I:IO", "(unless -noiopads)"); | 				run("iopadmap -bits -inpad IBUF O:I -outpad OBUF I:O " | ||||||
|  | 					"-toutpad TBUF OEN:I:O -tinoutpad IOBUF OEN:O:I:IO", "(unless -noiopads)"); | ||||||
| 			run("clean"); | 			run("clean"); | ||||||
| 
 | 
 | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -363,3 +363,11 @@ module \$__XILINX_MUXF78 (O, I0, I1, I2, I3, S0, S1); | ||||||
|   else |   else | ||||||
|     MUXF8 mux8 (.I0(T0), .I1(T1), .S(S1), .O(O)); |     MUXF8 mux8 (.I0(T0), .I1(T1), .S(S1), .O(O)); | ||||||
| endmodule | endmodule | ||||||
|  | 
 | ||||||
|  | module \$__XILINX_TINOUTPAD (input I, OE, output O, inout IO); | ||||||
|  |   IOBUF _TECHMAP_REPLACE_ (.I(I), .O(O), .T(~OE), .IO(IO)); | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module \$__XILINX_TOUTPAD (input I, OE, output O); | ||||||
|  |   OBUFT _TECHMAP_REPLACE_ (.I(I), .O(O), .T(~OE)); | ||||||
|  | endmodule | ||||||
|  |  | ||||||
|  | @ -479,6 +479,473 @@ module LDPE ( | ||||||
|     else if (GE && g) Q = D; |     else if (GE && g) Q = D; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
|  | // LUTRAM. | ||||||
|  | 
 | ||||||
|  | // Single port. | ||||||
|  | 
 | ||||||
|  | module RAM16X1S ( | ||||||
|  |   output O, | ||||||
|  |   input A0, A1, A2, A3, | ||||||
|  |   input D, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input WCLK, | ||||||
|  |   input WE | ||||||
|  | ); | ||||||
|  |   parameter [15:0] INIT = 16'h0000; | ||||||
|  |   parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   wire [3:0] a = {A3, A2, A1, A0}; | ||||||
|  |   reg [15:0] mem = INIT; | ||||||
|  |   assign O = mem[a]; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   always @(posedge clk) if (WE) mem[a] <= D; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module RAM16X1S_1 ( | ||||||
|  |   output O, | ||||||
|  |   input A0, A1, A2, A3, | ||||||
|  |   input D, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input WCLK, | ||||||
|  |   input WE | ||||||
|  | ); | ||||||
|  |   parameter [15:0] INIT = 16'h0000; | ||||||
|  |   parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   wire [3:0] a = {A3, A2, A1, A0}; | ||||||
|  |   reg [15:0] mem = INIT; | ||||||
|  |   assign O = mem[a]; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   always @(negedge clk) if (WE) mem[a] <= D; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module RAM32X1S ( | ||||||
|  |   output O, | ||||||
|  |   input A0, A1, A2, A3, A4, | ||||||
|  |   input D, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input WCLK, | ||||||
|  |   input WE | ||||||
|  | ); | ||||||
|  |   parameter [31:0] INIT = 32'h00000000; | ||||||
|  |   parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   wire [4:0] a = {A4, A3, A2, A1, A0}; | ||||||
|  |   reg [31:0] mem = INIT; | ||||||
|  |   assign O = mem[a]; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   always @(posedge clk) if (WE) mem[a] <= D; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module RAM32X1S_1 ( | ||||||
|  |   output O, | ||||||
|  |   input A0, A1, A2, A3, A4, | ||||||
|  |   input D, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input WCLK, | ||||||
|  |   input WE | ||||||
|  | ); | ||||||
|  |   parameter [31:0] INIT = 32'h00000000; | ||||||
|  |   parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   wire [4:0] a = {A4, A3, A2, A1, A0}; | ||||||
|  |   reg [31:0] mem = INIT; | ||||||
|  |   assign O = mem[a]; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   always @(negedge clk) if (WE) mem[a] <= D; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module RAM64X1S ( | ||||||
|  |   output O, | ||||||
|  |   input A0, A1, A2, A3, A4, A5, | ||||||
|  |   input D, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input WCLK, | ||||||
|  |   input WE | ||||||
|  | ); | ||||||
|  |   parameter [63:0] INIT = 64'h0000000000000000; | ||||||
|  |   parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   wire [5:0] a = {A5, A4, A3, A2, A1, A0}; | ||||||
|  |   reg [63:0] mem = INIT; | ||||||
|  |   assign O = mem[a]; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   always @(posedge clk) if (WE) mem[a] <= D; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module RAM64X1S_1 ( | ||||||
|  |   output O, | ||||||
|  |   input A0, A1, A2, A3, A4, A5, | ||||||
|  |   input D, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input WCLK, | ||||||
|  |   input WE | ||||||
|  | ); | ||||||
|  |   parameter [63:0] INIT = 64'h0000000000000000; | ||||||
|  |   parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   wire [5:0] a = {A5, A4, A3, A2, A1, A0}; | ||||||
|  |   reg [63:0] mem = INIT; | ||||||
|  |   assign O = mem[a]; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   always @(negedge clk) if (WE) mem[a] <= D; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module RAM128X1S ( | ||||||
|  |   output O, | ||||||
|  |   input A0, A1, A2, A3, A4, A5, A6, | ||||||
|  |   input D, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input WCLK, | ||||||
|  |   input WE | ||||||
|  | ); | ||||||
|  |   parameter [127:0] INIT = 128'h00000000000000000000000000000000; | ||||||
|  |   parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   wire [6:0] a = {A6, A5, A4, A3, A2, A1, A0}; | ||||||
|  |   reg [127:0] mem = INIT; | ||||||
|  |   assign O = mem[a]; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   always @(posedge clk) if (WE) mem[a] <= D; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module RAM128X1S_1 ( | ||||||
|  |   output O, | ||||||
|  |   input A0, A1, A2, A3, A4, A5, A6, | ||||||
|  |   input D, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input WCLK, | ||||||
|  |   input WE | ||||||
|  | ); | ||||||
|  |   parameter [127:0] INIT = 128'h00000000000000000000000000000000; | ||||||
|  |   parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   wire [6:0] a = {A6, A5, A4, A3, A2, A1, A0}; | ||||||
|  |   reg [127:0] mem = INIT; | ||||||
|  |   assign O = mem[a]; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   always @(negedge clk) if (WE) mem[a] <= D; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module RAM256X1S ( | ||||||
|  |   output O, | ||||||
|  |   input [7:0] A, | ||||||
|  |   input D, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input WCLK, | ||||||
|  |   input WE | ||||||
|  | ); | ||||||
|  |   parameter [255:0] INIT = 256'h0; | ||||||
|  |   parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   reg [255:0] mem = INIT; | ||||||
|  |   assign O = mem[A]; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   always @(posedge clk) if (WE) mem[A] <= D; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module RAM512X1S ( | ||||||
|  |   output O, | ||||||
|  |   input [8:0] A, | ||||||
|  |   input D, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input WCLK, | ||||||
|  |   input WE | ||||||
|  | ); | ||||||
|  |   parameter [511:0] INIT = 512'h0; | ||||||
|  |   parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   reg [511:0] mem = INIT; | ||||||
|  |   assign O = mem[A]; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   always @(posedge clk) if (WE) mem[A] <= D; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | // Single port, wide. | ||||||
|  | 
 | ||||||
|  | module RAM16X2S ( | ||||||
|  |   output O0, O1, | ||||||
|  |   input A0, A1, A2, A3, | ||||||
|  |   input D0, D1, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input WCLK, | ||||||
|  |   input WE | ||||||
|  | ); | ||||||
|  |   parameter [15:0] INIT_00 = 16'h0000; | ||||||
|  |   parameter [15:0] INIT_01 = 16'h0000; | ||||||
|  |   parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   wire [3:0] a = {A3, A2, A1, A0}; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   reg [15:0] mem0 = INIT_00; | ||||||
|  |   reg [15:0] mem1 = INIT_01; | ||||||
|  |   assign O0 = mem0[a]; | ||||||
|  |   assign O1 = mem1[a]; | ||||||
|  |   always @(posedge clk) | ||||||
|  |     if (WE) begin | ||||||
|  |       mem0[a] <= D0; | ||||||
|  |       mem1[a] <= D1; | ||||||
|  |     end | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module RAM32X2S ( | ||||||
|  |   output O0, O1, | ||||||
|  |   input A0, A1, A2, A3, A4, | ||||||
|  |   input D0, D1, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input WCLK, | ||||||
|  |   input WE | ||||||
|  | ); | ||||||
|  |   parameter [31:0] INIT_00 = 32'h00000000; | ||||||
|  |   parameter [31:0] INIT_01 = 32'h00000000; | ||||||
|  |   parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   wire [4:0] a = {A4, A3, A2, A1, A0}; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   reg [31:0] mem0 = INIT_00; | ||||||
|  |   reg [31:0] mem1 = INIT_01; | ||||||
|  |   assign O0 = mem0[a]; | ||||||
|  |   assign O1 = mem1[a]; | ||||||
|  |   always @(posedge clk) | ||||||
|  |     if (WE) begin | ||||||
|  |       mem0[a] <= D0; | ||||||
|  |       mem1[a] <= D1; | ||||||
|  |     end | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module RAM64X2S ( | ||||||
|  |   output O0, O1, | ||||||
|  |   input A0, A1, A2, A3, A4, A5, | ||||||
|  |   input D0, D1, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input WCLK, | ||||||
|  |   input WE | ||||||
|  | ); | ||||||
|  |   parameter [63:0] INIT_00 = 64'h0000000000000000; | ||||||
|  |   parameter [63:0] INIT_01 = 64'h0000000000000000; | ||||||
|  |   parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   wire [5:0] a = {A5, A3, A2, A1, A0}; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   reg [63:0] mem0 = INIT_00; | ||||||
|  |   reg [63:0] mem1 = INIT_01; | ||||||
|  |   assign O0 = mem0[a]; | ||||||
|  |   assign O1 = mem1[a]; | ||||||
|  |   always @(posedge clk) | ||||||
|  |     if (WE) begin | ||||||
|  |       mem0[a] <= D0; | ||||||
|  |       mem1[a] <= D1; | ||||||
|  |     end | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module RAM16X4S ( | ||||||
|  |   output O0, O1, O2, O3, | ||||||
|  |   input A0, A1, A2, A3, | ||||||
|  |   input D0, D1, D2, D3, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input WCLK, | ||||||
|  |   input WE | ||||||
|  | ); | ||||||
|  |   parameter [15:0] INIT_00 = 16'h0000; | ||||||
|  |   parameter [15:0] INIT_01 = 16'h0000; | ||||||
|  |   parameter [15:0] INIT_02 = 16'h0000; | ||||||
|  |   parameter [15:0] INIT_03 = 16'h0000; | ||||||
|  |   parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   wire [3:0] a = {A3, A2, A1, A0}; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   reg [15:0] mem0 = INIT_00; | ||||||
|  |   reg [15:0] mem1 = INIT_01; | ||||||
|  |   reg [15:0] mem2 = INIT_02; | ||||||
|  |   reg [15:0] mem3 = INIT_03; | ||||||
|  |   assign O0 = mem0[a]; | ||||||
|  |   assign O1 = mem1[a]; | ||||||
|  |   assign O2 = mem2[a]; | ||||||
|  |   assign O3 = mem3[a]; | ||||||
|  |   always @(posedge clk) | ||||||
|  |     if (WE) begin | ||||||
|  |       mem0[a] <= D0; | ||||||
|  |       mem1[a] <= D1; | ||||||
|  |       mem2[a] <= D2; | ||||||
|  |       mem3[a] <= D3; | ||||||
|  |     end | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module RAM32X4S ( | ||||||
|  |   output O0, O1, O2, O3, | ||||||
|  |   input A0, A1, A2, A3, A4, | ||||||
|  |   input D0, D1, D2, D3, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input WCLK, | ||||||
|  |   input WE | ||||||
|  | ); | ||||||
|  |   parameter [31:0] INIT_00 = 32'h00000000; | ||||||
|  |   parameter [31:0] INIT_01 = 32'h00000000; | ||||||
|  |   parameter [31:0] INIT_02 = 32'h00000000; | ||||||
|  |   parameter [31:0] INIT_03 = 32'h00000000; | ||||||
|  |   parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   wire [4:0] a = {A4, A3, A2, A1, A0}; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   reg [31:0] mem0 = INIT_00; | ||||||
|  |   reg [31:0] mem1 = INIT_01; | ||||||
|  |   reg [31:0] mem2 = INIT_02; | ||||||
|  |   reg [31:0] mem3 = INIT_03; | ||||||
|  |   assign O0 = mem0[a]; | ||||||
|  |   assign O1 = mem1[a]; | ||||||
|  |   assign O2 = mem2[a]; | ||||||
|  |   assign O3 = mem3[a]; | ||||||
|  |   always @(posedge clk) | ||||||
|  |     if (WE) begin | ||||||
|  |       mem0[a] <= D0; | ||||||
|  |       mem1[a] <= D1; | ||||||
|  |       mem2[a] <= D2; | ||||||
|  |       mem3[a] <= D3; | ||||||
|  |     end | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module RAM16X8S ( | ||||||
|  |   output [7:0] O, | ||||||
|  |   input A0, A1, A2, A3, | ||||||
|  |   input [7:0] D, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input WCLK, | ||||||
|  |   input WE | ||||||
|  | ); | ||||||
|  |   parameter [15:0] INIT_00 = 16'h0000; | ||||||
|  |   parameter [15:0] INIT_01 = 16'h0000; | ||||||
|  |   parameter [15:0] INIT_02 = 16'h0000; | ||||||
|  |   parameter [15:0] INIT_03 = 16'h0000; | ||||||
|  |   parameter [15:0] INIT_04 = 16'h0000; | ||||||
|  |   parameter [15:0] INIT_05 = 16'h0000; | ||||||
|  |   parameter [15:0] INIT_06 = 16'h0000; | ||||||
|  |   parameter [15:0] INIT_07 = 16'h0000; | ||||||
|  |   parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   wire [3:0] a = {A3, A2, A1, A0}; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   reg [15:0] mem0 = INIT_00; | ||||||
|  |   reg [15:0] mem1 = INIT_01; | ||||||
|  |   reg [15:0] mem2 = INIT_02; | ||||||
|  |   reg [15:0] mem3 = INIT_03; | ||||||
|  |   reg [15:0] mem4 = INIT_04; | ||||||
|  |   reg [15:0] mem5 = INIT_05; | ||||||
|  |   reg [15:0] mem6 = INIT_06; | ||||||
|  |   reg [15:0] mem7 = INIT_07; | ||||||
|  |   assign O[0] = mem0[a]; | ||||||
|  |   assign O[1] = mem1[a]; | ||||||
|  |   assign O[2] = mem2[a]; | ||||||
|  |   assign O[3] = mem3[a]; | ||||||
|  |   assign O[4] = mem4[a]; | ||||||
|  |   assign O[5] = mem5[a]; | ||||||
|  |   assign O[6] = mem6[a]; | ||||||
|  |   assign O[7] = mem7[a]; | ||||||
|  |   always @(posedge clk) | ||||||
|  |     if (WE) begin | ||||||
|  |       mem0[a] <= D[0]; | ||||||
|  |       mem1[a] <= D[1]; | ||||||
|  |       mem2[a] <= D[2]; | ||||||
|  |       mem3[a] <= D[3]; | ||||||
|  |       mem4[a] <= D[4]; | ||||||
|  |       mem5[a] <= D[5]; | ||||||
|  |       mem6[a] <= D[6]; | ||||||
|  |       mem7[a] <= D[7]; | ||||||
|  |     end | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module RAM32X8S ( | ||||||
|  |   output [7:0] O, | ||||||
|  |   input A0, A1, A2, A3, A4, | ||||||
|  |   input [7:0] D, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input WCLK, | ||||||
|  |   input WE | ||||||
|  | ); | ||||||
|  |   parameter [31:0] INIT_00 = 32'h00000000; | ||||||
|  |   parameter [31:0] INIT_01 = 32'h00000000; | ||||||
|  |   parameter [31:0] INIT_02 = 32'h00000000; | ||||||
|  |   parameter [31:0] INIT_03 = 32'h00000000; | ||||||
|  |   parameter [31:0] INIT_04 = 32'h00000000; | ||||||
|  |   parameter [31:0] INIT_05 = 32'h00000000; | ||||||
|  |   parameter [31:0] INIT_06 = 32'h00000000; | ||||||
|  |   parameter [31:0] INIT_07 = 32'h00000000; | ||||||
|  |   parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   wire [4:0] a = {A4, A3, A2, A1, A0}; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   reg [31:0] mem0 = INIT_00; | ||||||
|  |   reg [31:0] mem1 = INIT_01; | ||||||
|  |   reg [31:0] mem2 = INIT_02; | ||||||
|  |   reg [31:0] mem3 = INIT_03; | ||||||
|  |   reg [31:0] mem4 = INIT_04; | ||||||
|  |   reg [31:0] mem5 = INIT_05; | ||||||
|  |   reg [31:0] mem6 = INIT_06; | ||||||
|  |   reg [31:0] mem7 = INIT_07; | ||||||
|  |   assign O[0] = mem0[a]; | ||||||
|  |   assign O[1] = mem1[a]; | ||||||
|  |   assign O[2] = mem2[a]; | ||||||
|  |   assign O[3] = mem3[a]; | ||||||
|  |   assign O[4] = mem4[a]; | ||||||
|  |   assign O[5] = mem5[a]; | ||||||
|  |   assign O[6] = mem6[a]; | ||||||
|  |   assign O[7] = mem7[a]; | ||||||
|  |   always @(posedge clk) | ||||||
|  |     if (WE) begin | ||||||
|  |       mem0[a] <= D[0]; | ||||||
|  |       mem1[a] <= D[1]; | ||||||
|  |       mem2[a] <= D[2]; | ||||||
|  |       mem3[a] <= D[3]; | ||||||
|  |       mem4[a] <= D[4]; | ||||||
|  |       mem5[a] <= D[5]; | ||||||
|  |       mem6[a] <= D[6]; | ||||||
|  |       mem7[a] <= D[7]; | ||||||
|  |     end | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | // Dual port. | ||||||
|  | 
 | ||||||
|  | module RAM16X1D ( | ||||||
|  |   output DPO, SPO, | ||||||
|  |   input  D, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input  WCLK, | ||||||
|  |   input  WE, | ||||||
|  |   input  A0, A1, A2, A3, | ||||||
|  |   input  DPRA0, DPRA1, DPRA2, DPRA3 | ||||||
|  | ); | ||||||
|  |   parameter INIT = 16'h0; | ||||||
|  |   parameter IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   wire [3:0] a = {A3, A2, A1, A0}; | ||||||
|  |   wire [3:0] dpra = {DPRA3, DPRA2, DPRA1, DPRA0}; | ||||||
|  |   reg [15:0] mem = INIT; | ||||||
|  |   assign SPO = mem[a]; | ||||||
|  |   assign DPO = mem[dpra]; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   always @(posedge clk) if (WE) mem[a] <= D; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module RAM16X1D_1 ( | ||||||
|  |   output DPO, SPO, | ||||||
|  |   input  D, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input  WCLK, | ||||||
|  |   input  WE, | ||||||
|  |   input  A0, A1, A2, A3, | ||||||
|  |   input  DPRA0, DPRA1, DPRA2, DPRA3 | ||||||
|  | ); | ||||||
|  |   parameter INIT = 16'h0; | ||||||
|  |   parameter IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   wire [3:0] a = {A3, A2, A1, A0}; | ||||||
|  |   wire [3:0] dpra = {DPRA3, DPRA2, DPRA1, DPRA0}; | ||||||
|  |   reg [15:0] mem = INIT; | ||||||
|  |   assign SPO = mem[a]; | ||||||
|  |   assign DPO = mem[dpra]; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   always @(negedge clk) if (WE) mem[a] <= D; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
| module RAM32X1D ( | module RAM32X1D ( | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 |   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 | ||||||
|   (* abc9_arrival=1153 *) |   (* abc9_arrival=1153 *) | ||||||
|  | @ -502,6 +969,29 @@ module RAM32X1D ( | ||||||
|   always @(posedge clk) if (WE) mem[a] <= D; |   always @(posedge clk) if (WE) mem[a] <= D; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
|  | module RAM32X1D_1 ( | ||||||
|  |   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 | ||||||
|  |   (* abc9_arrival=1153 *) | ||||||
|  |   output DPO, SPO, | ||||||
|  |   input  D, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input  WCLK, | ||||||
|  |   input  WE, | ||||||
|  |   input  A0, A1, A2, A3, A4, | ||||||
|  |   input  DPRA0, DPRA1, DPRA2, DPRA3, DPRA4 | ||||||
|  | ); | ||||||
|  |   parameter INIT = 32'h0; | ||||||
|  |   parameter IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   wire [4:0] a = {A4, A3, A2, A1, A0}; | ||||||
|  |   wire [4:0] dpra = {DPRA4, DPRA3, DPRA2, DPRA1, DPRA0}; | ||||||
|  |   reg [31:0] mem = INIT; | ||||||
|  |   assign SPO = mem[a]; | ||||||
|  |   assign DPO = mem[dpra]; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   always @(negedge clk) if (WE) mem[a] <= D; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
| module RAM64X1D ( | module RAM64X1D ( | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 |   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 | ||||||
|   (* abc9_arrival=1153 *) |   (* abc9_arrival=1153 *) | ||||||
|  | @ -525,6 +1015,29 @@ module RAM64X1D ( | ||||||
|   always @(posedge clk) if (WE) mem[a] <= D; |   always @(posedge clk) if (WE) mem[a] <= D; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
|  | module RAM64X1D_1 ( | ||||||
|  |   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 | ||||||
|  |   (* abc9_arrival=1153 *) | ||||||
|  |   output DPO, SPO, | ||||||
|  |   input  D, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input  WCLK, | ||||||
|  |   input  WE, | ||||||
|  |   input  A0, A1, A2, A3, A4, A5, | ||||||
|  |   input  DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5 | ||||||
|  | ); | ||||||
|  |   parameter INIT = 64'h0; | ||||||
|  |   parameter IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   wire [5:0] a = {A5, A4, A3, A2, A1, A0}; | ||||||
|  |   wire [5:0] dpra = {DPRA5, DPRA4, DPRA3, DPRA2, DPRA1, DPRA0}; | ||||||
|  |   reg [63:0] mem = INIT; | ||||||
|  |   assign SPO = mem[a]; | ||||||
|  |   assign DPO = mem[dpra]; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   always @(negedge clk) if (WE) mem[a] <= D; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
| module RAM128X1D ( | module RAM128X1D ( | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 |   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 | ||||||
|   (* abc9_arrival=1153 *) |   (* abc9_arrival=1153 *) | ||||||
|  | @ -545,6 +1058,290 @@ module RAM128X1D ( | ||||||
|   always @(posedge clk) if (WE) mem[A] <= D; |   always @(posedge clk) if (WE) mem[A] <= D; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
|  | module RAM256X1D ( | ||||||
|  |   output DPO, SPO, | ||||||
|  |   input        D, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input        WCLK, | ||||||
|  |   input        WE, | ||||||
|  |   input  [7:0] A, DPRA | ||||||
|  | ); | ||||||
|  |   parameter INIT = 256'h0; | ||||||
|  |   parameter IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   reg [255:0] mem = INIT; | ||||||
|  |   assign SPO = mem[A]; | ||||||
|  |   assign DPO = mem[DPRA]; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   always @(posedge clk) if (WE) mem[A] <= D; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | // Multi port. | ||||||
|  | 
 | ||||||
|  | module RAM32M ( | ||||||
|  |   output [1:0] DOA, | ||||||
|  |   output [1:0] DOB, | ||||||
|  |   output [1:0] DOC, | ||||||
|  |   output [1:0] DOD, | ||||||
|  |   input [4:0] ADDRA, | ||||||
|  |   input [4:0] ADDRB, | ||||||
|  |   input [4:0] ADDRC, | ||||||
|  |   input [4:0] ADDRD, | ||||||
|  |   input [1:0] DIA, | ||||||
|  |   input [1:0] DIB, | ||||||
|  |   input [1:0] DIC, | ||||||
|  |   input [1:0] DID, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input WCLK, | ||||||
|  |   input WE | ||||||
|  | ); | ||||||
|  |   parameter [63:0] INIT_A = 64'h0000000000000000; | ||||||
|  |   parameter [63:0] INIT_B = 64'h0000000000000000; | ||||||
|  |   parameter [63:0] INIT_C = 64'h0000000000000000; | ||||||
|  |   parameter [63:0] INIT_D = 64'h0000000000000000; | ||||||
|  |   parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   reg [63:0] mem_a = INIT_A; | ||||||
|  |   reg [63:0] mem_b = INIT_B; | ||||||
|  |   reg [63:0] mem_c = INIT_C; | ||||||
|  |   reg [63:0] mem_d = INIT_D; | ||||||
|  |   assign DOA = mem_a[2*ADDRA+:2]; | ||||||
|  |   assign DOB = mem_b[2*ADDRB+:2]; | ||||||
|  |   assign DOC = mem_c[2*ADDRC+:2]; | ||||||
|  |   assign DOD = mem_d[2*ADDRD+:2]; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   always @(posedge clk) | ||||||
|  |     if (WE) begin | ||||||
|  |       mem_a[2*ADDRD+:2] <= DIA; | ||||||
|  |       mem_b[2*ADDRD+:2] <= DIB; | ||||||
|  |       mem_c[2*ADDRD+:2] <= DIC; | ||||||
|  |       mem_d[2*ADDRD+:2] <= DID; | ||||||
|  |     end | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module RAM32M16 ( | ||||||
|  |   output [1:0] DOA, | ||||||
|  |   output [1:0] DOB, | ||||||
|  |   output [1:0] DOC, | ||||||
|  |   output [1:0] DOD, | ||||||
|  |   output [1:0] DOE, | ||||||
|  |   output [1:0] DOF, | ||||||
|  |   output [1:0] DOG, | ||||||
|  |   output [1:0] DOH, | ||||||
|  |   input [4:0] ADDRA, | ||||||
|  |   input [4:0] ADDRB, | ||||||
|  |   input [4:0] ADDRC, | ||||||
|  |   input [4:0] ADDRD, | ||||||
|  |   input [4:0] ADDRE, | ||||||
|  |   input [4:0] ADDRF, | ||||||
|  |   input [4:0] ADDRG, | ||||||
|  |   input [4:0] ADDRH, | ||||||
|  |   input [1:0] DIA, | ||||||
|  |   input [1:0] DIB, | ||||||
|  |   input [1:0] DIC, | ||||||
|  |   input [1:0] DID, | ||||||
|  |   input [1:0] DIE, | ||||||
|  |   input [1:0] DIF, | ||||||
|  |   input [1:0] DIG, | ||||||
|  |   input [1:0] DIH, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input WCLK, | ||||||
|  |   input WE | ||||||
|  | ); | ||||||
|  |   parameter [63:0] INIT_A = 64'h0000000000000000; | ||||||
|  |   parameter [63:0] INIT_B = 64'h0000000000000000; | ||||||
|  |   parameter [63:0] INIT_C = 64'h0000000000000000; | ||||||
|  |   parameter [63:0] INIT_D = 64'h0000000000000000; | ||||||
|  |   parameter [63:0] INIT_E = 64'h0000000000000000; | ||||||
|  |   parameter [63:0] INIT_F = 64'h0000000000000000; | ||||||
|  |   parameter [63:0] INIT_G = 64'h0000000000000000; | ||||||
|  |   parameter [63:0] INIT_H = 64'h0000000000000000; | ||||||
|  |   parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   reg [63:0] mem_a = INIT_A; | ||||||
|  |   reg [63:0] mem_b = INIT_B; | ||||||
|  |   reg [63:0] mem_c = INIT_C; | ||||||
|  |   reg [63:0] mem_d = INIT_D; | ||||||
|  |   reg [63:0] mem_e = INIT_E; | ||||||
|  |   reg [63:0] mem_f = INIT_F; | ||||||
|  |   reg [63:0] mem_g = INIT_G; | ||||||
|  |   reg [63:0] mem_h = INIT_H; | ||||||
|  |   assign DOA = mem_a[2*ADDRA+:2]; | ||||||
|  |   assign DOB = mem_b[2*ADDRB+:2]; | ||||||
|  |   assign DOC = mem_c[2*ADDRC+:2]; | ||||||
|  |   assign DOD = mem_d[2*ADDRD+:2]; | ||||||
|  |   assign DOE = mem_e[2*ADDRE+:2]; | ||||||
|  |   assign DOF = mem_f[2*ADDRF+:2]; | ||||||
|  |   assign DOG = mem_g[2*ADDRG+:2]; | ||||||
|  |   assign DOH = mem_h[2*ADDRH+:2]; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   always @(posedge clk) | ||||||
|  |     if (WE) begin | ||||||
|  |       mem_a[2*ADDRH+:2] <= DIA; | ||||||
|  |       mem_b[2*ADDRH+:2] <= DIB; | ||||||
|  |       mem_c[2*ADDRH+:2] <= DIC; | ||||||
|  |       mem_d[2*ADDRH+:2] <= DID; | ||||||
|  |       mem_e[2*ADDRH+:2] <= DIE; | ||||||
|  |       mem_f[2*ADDRH+:2] <= DIF; | ||||||
|  |       mem_g[2*ADDRH+:2] <= DIG; | ||||||
|  |       mem_h[2*ADDRH+:2] <= DIH; | ||||||
|  |     end | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module RAM64M ( | ||||||
|  |   output DOA, | ||||||
|  |   output DOB, | ||||||
|  |   output DOC, | ||||||
|  |   output DOD, | ||||||
|  |   input [4:0] ADDRA, | ||||||
|  |   input [4:0] ADDRB, | ||||||
|  |   input [4:0] ADDRC, | ||||||
|  |   input [4:0] ADDRD, | ||||||
|  |   input DIA, | ||||||
|  |   input DIB, | ||||||
|  |   input DIC, | ||||||
|  |   input DID, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input WCLK, | ||||||
|  |   input WE | ||||||
|  | ); | ||||||
|  |   parameter [63:0] INIT_A = 64'h0000000000000000; | ||||||
|  |   parameter [63:0] INIT_B = 64'h0000000000000000; | ||||||
|  |   parameter [63:0] INIT_C = 64'h0000000000000000; | ||||||
|  |   parameter [63:0] INIT_D = 64'h0000000000000000; | ||||||
|  |   parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   reg [63:0] mem_a = INIT_A; | ||||||
|  |   reg [63:0] mem_b = INIT_B; | ||||||
|  |   reg [63:0] mem_c = INIT_C; | ||||||
|  |   reg [63:0] mem_d = INIT_D; | ||||||
|  |   assign DOA = mem_a[ADDRA]; | ||||||
|  |   assign DOB = mem_b[ADDRB]; | ||||||
|  |   assign DOC = mem_c[ADDRC]; | ||||||
|  |   assign DOD = mem_d[ADDRD]; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   always @(posedge clk) | ||||||
|  |     if (WE) begin | ||||||
|  |       mem_a[ADDRD] <= DIA; | ||||||
|  |       mem_b[ADDRD] <= DIB; | ||||||
|  |       mem_c[ADDRD] <= DIC; | ||||||
|  |       mem_d[ADDRD] <= DID; | ||||||
|  |     end | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module RAM64M8 ( | ||||||
|  |   output DOA, | ||||||
|  |   output DOB, | ||||||
|  |   output DOC, | ||||||
|  |   output DOD, | ||||||
|  |   output DOE, | ||||||
|  |   output DOF, | ||||||
|  |   output DOG, | ||||||
|  |   output DOH, | ||||||
|  |   input [4:0] ADDRA, | ||||||
|  |   input [4:0] ADDRB, | ||||||
|  |   input [4:0] ADDRC, | ||||||
|  |   input [4:0] ADDRD, | ||||||
|  |   input [4:0] ADDRE, | ||||||
|  |   input [4:0] ADDRF, | ||||||
|  |   input [4:0] ADDRG, | ||||||
|  |   input [4:0] ADDRH, | ||||||
|  |   input DIA, | ||||||
|  |   input DIB, | ||||||
|  |   input DIC, | ||||||
|  |   input DID, | ||||||
|  |   input DIE, | ||||||
|  |   input DIF, | ||||||
|  |   input DIG, | ||||||
|  |   input DIH, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|  |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|  |   input WCLK, | ||||||
|  |   input WE | ||||||
|  | ); | ||||||
|  |   parameter [63:0] INIT_A = 64'h0000000000000000; | ||||||
|  |   parameter [63:0] INIT_B = 64'h0000000000000000; | ||||||
|  |   parameter [63:0] INIT_C = 64'h0000000000000000; | ||||||
|  |   parameter [63:0] INIT_D = 64'h0000000000000000; | ||||||
|  |   parameter [63:0] INIT_E = 64'h0000000000000000; | ||||||
|  |   parameter [63:0] INIT_F = 64'h0000000000000000; | ||||||
|  |   parameter [63:0] INIT_G = 64'h0000000000000000; | ||||||
|  |   parameter [63:0] INIT_H = 64'h0000000000000000; | ||||||
|  |   parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|  |   reg [63:0] mem_a = INIT_A; | ||||||
|  |   reg [63:0] mem_b = INIT_B; | ||||||
|  |   reg [63:0] mem_c = INIT_C; | ||||||
|  |   reg [63:0] mem_d = INIT_D; | ||||||
|  |   reg [63:0] mem_e = INIT_E; | ||||||
|  |   reg [63:0] mem_f = INIT_F; | ||||||
|  |   reg [63:0] mem_g = INIT_G; | ||||||
|  |   reg [63:0] mem_h = INIT_H; | ||||||
|  |   assign DOA = mem_a[ADDRA]; | ||||||
|  |   assign DOB = mem_b[ADDRB]; | ||||||
|  |   assign DOC = mem_c[ADDRC]; | ||||||
|  |   assign DOD = mem_d[ADDRD]; | ||||||
|  |   assign DOE = mem_e[ADDRE]; | ||||||
|  |   assign DOF = mem_f[ADDRF]; | ||||||
|  |   assign DOG = mem_g[ADDRG]; | ||||||
|  |   assign DOH = mem_h[ADDRH]; | ||||||
|  |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|  |   always @(posedge clk) | ||||||
|  |     if (WE) begin | ||||||
|  |       mem_a[ADDRH] <= DIA; | ||||||
|  |       mem_b[ADDRH] <= DIB; | ||||||
|  |       mem_c[ADDRH] <= DIC; | ||||||
|  |       mem_d[ADDRH] <= DID; | ||||||
|  |       mem_e[ADDRH] <= DIE; | ||||||
|  |       mem_f[ADDRH] <= DIF; | ||||||
|  |       mem_g[ADDRH] <= DIG; | ||||||
|  |       mem_h[ADDRH] <= DIH; | ||||||
|  |     end | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | // ROM. | ||||||
|  | 
 | ||||||
|  | module ROM16X1 ( | ||||||
|  |   output O, | ||||||
|  |   input A0, A1, A2, A3 | ||||||
|  | ); | ||||||
|  |   parameter [15:0] INIT = 16'h0; | ||||||
|  |   assign O = INIT[{A3, A2, A1, A0}]; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module ROM32X1 ( | ||||||
|  |   output O, | ||||||
|  |   input A0, A1, A2, A3, A4 | ||||||
|  | ); | ||||||
|  |   parameter [31:0] INIT = 32'h0; | ||||||
|  |   assign O = INIT[{A4, A3, A2, A1, A0}]; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module ROM64X1 ( | ||||||
|  |   output O, | ||||||
|  |   input A0, A1, A2, A3, A4, A5 | ||||||
|  | ); | ||||||
|  |   parameter [63:0] INIT = 64'h0; | ||||||
|  |   assign O = INIT[{A5, A4, A3, A2, A1, A0}]; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module ROM128X1 ( | ||||||
|  |   output O, | ||||||
|  |   input A0, A1, A2, A3, A4, A5, A6 | ||||||
|  | ); | ||||||
|  |   parameter [127:0] INIT = 128'h0; | ||||||
|  |   assign O = INIT[{A6, A5, A4, A3, A2, A1, A0}]; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module ROM256X1 ( | ||||||
|  |   output O, | ||||||
|  |   input A0, A1, A2, A3, A4, A5, A6, A7 | ||||||
|  | ); | ||||||
|  |   parameter [255:0] INIT = 256'h0; | ||||||
|  |   assign O = INIT[{A7, A6, A5, A4, A3, A2, A1, A0}]; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | // Shift registers. | ||||||
|  | 
 | ||||||
| module SRL16E ( | module SRL16E ( | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 |   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 | ||||||
|   (* abc9_arrival=1472 *) |   (* abc9_arrival=1472 *) | ||||||
|  |  | ||||||
|  | @ -28,40 +28,40 @@ CELLS = [ | ||||||
|     # - UG974 (Ultrascale) |     # - UG974 (Ultrascale) | ||||||
| 
 | 
 | ||||||
|     # CLB -- RAM/ROM. |     # CLB -- RAM/ROM. | ||||||
|     Cell('RAM16X1S', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM16X1S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM16X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM16X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM32X1S', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM32X1S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM32X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM32X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM64X1S', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM64X1S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM64X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM64X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM128X1S', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM128X1S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM128X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM128X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM256X1S', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM256X1S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM512X1S', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM512X1S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM16X2S', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM16X2S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM32X2S', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM32X2S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM64X2S', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM64X2S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM16X4S', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM16X4S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM32X4S', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM32X4S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM16X8S', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM16X8S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM32X8S', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM32X8S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM16X1D', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM16X1D', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM16X1D_1', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM16X1D_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     #Cell('RAM32X1D', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM32X1D', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM32X1D_1', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM32X1D_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     #Cell('RAM64X1D', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM64X1D', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM64X1D_1', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM64X1D_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     #Cell('RAM128X1D', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM128X1D', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM256X1D', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM256X1D', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM32M', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM32M', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM32M16', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM32M16', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM64M', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM64M', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('RAM64M8', port_attrs={'WCLK': ['clkbuf_sink']}), |     # Cell('RAM64M8', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|     Cell('ROM16X1'), |     # Cell('ROM16X1'), | ||||||
|     Cell('ROM32X1'), |     # Cell('ROM32X1'), | ||||||
|     Cell('ROM64X1'), |     # Cell('ROM64X1'), | ||||||
|     Cell('ROM128X1'), |     # Cell('ROM128X1'), | ||||||
|     Cell('ROM256X1'), |     # Cell('ROM256X1'), | ||||||
| 
 | 
 | ||||||
|     # CLB -- registers/latches. |     # CLB -- registers/latches. | ||||||
|     # Virtex 1/2/4/5, Spartan 3. |     # Virtex 1/2/4/5, Spartan 3. | ||||||
|  | @ -372,6 +372,7 @@ CELLS = [ | ||||||
|     Cell('BUFIO2', port_attrs={'IOCLK': ['clkbuf_driver'], 'DIVCLK': ['clkbuf_driver']}), |     Cell('BUFIO2', port_attrs={'IOCLK': ['clkbuf_driver'], 'DIVCLK': ['clkbuf_driver']}), | ||||||
|     Cell('BUFIO2_2CLK', port_attrs={'IOCLK': ['clkbuf_driver'], 'DIVCLK': ['clkbuf_driver']}), |     Cell('BUFIO2_2CLK', port_attrs={'IOCLK': ['clkbuf_driver'], 'DIVCLK': ['clkbuf_driver']}), | ||||||
|     Cell('BUFIO2FB', port_attrs={'O': ['clkbuf_driver']}), |     Cell('BUFIO2FB', port_attrs={'O': ['clkbuf_driver']}), | ||||||
|  |     Cell('BUFPLL', port_attrs={'IOCLK': ['clkbuf_driver']}), | ||||||
|     Cell('BUFPLL_MCB', port_attrs={'IOCLK0': ['clkbuf_driver'], 'IOCLK1': ['clkbuf_driver']}), |     Cell('BUFPLL_MCB', port_attrs={'IOCLK0': ['clkbuf_driver'], 'IOCLK1': ['clkbuf_driver']}), | ||||||
| 
 | 
 | ||||||
|     # Clock buffers (IO and regional) -- Virtex. |     # Clock buffers (IO and regional) -- Virtex. | ||||||
|  |  | ||||||
|  | @ -1,595 +1,5 @@ | ||||||
| // Created by cells_xtra.py from Xilinx models | // Created by cells_xtra.py from Xilinx models | ||||||
| 
 | 
 | ||||||
| module RAM16X1S (...); |  | ||||||
|     parameter [15:0] INIT = 16'h0000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output O; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     input D; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM16X1S_1 (...); |  | ||||||
|     parameter [15:0] INIT = 16'h0000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output O; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     input D; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM32X1S (...); |  | ||||||
|     parameter [31:0] INIT = 32'h00000000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output O; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     input A4; |  | ||||||
|     input D; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM32X1S_1 (...); |  | ||||||
|     parameter [31:0] INIT = 32'h00000000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output O; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     input A4; |  | ||||||
|     input D; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM64X1S (...); |  | ||||||
|     parameter [63:0] INIT = 64'h0000000000000000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output O; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     input A4; |  | ||||||
|     input A5; |  | ||||||
|     input D; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM64X1S_1 (...); |  | ||||||
|     parameter [63:0] INIT = 64'h0000000000000000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output O; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     input A4; |  | ||||||
|     input A5; |  | ||||||
|     input D; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM128X1S (...); |  | ||||||
|     parameter [127:0] INIT = 128'h00000000000000000000000000000000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output O; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     input A4; |  | ||||||
|     input A5; |  | ||||||
|     input A6; |  | ||||||
|     input D; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM128X1S_1 (...); |  | ||||||
|     parameter [127:0] INIT = 128'h00000000000000000000000000000000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output O; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     input A4; |  | ||||||
|     input A5; |  | ||||||
|     input A6; |  | ||||||
|     input D; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM256X1S (...); |  | ||||||
|     parameter [255:0] INIT = 256'h0; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output O; |  | ||||||
|     input [7:0] A; |  | ||||||
|     input D; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM512X1S (...); |  | ||||||
|     parameter [511:0] INIT = 512'h0; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output O; |  | ||||||
|     input [8:0] A; |  | ||||||
|     input D; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM16X2S (...); |  | ||||||
|     parameter [15:0] INIT_00 = 16'h0000; |  | ||||||
|     parameter [15:0] INIT_01 = 16'h0000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output O0; |  | ||||||
|     output O1; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     input D0; |  | ||||||
|     input D1; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM32X2S (...); |  | ||||||
|     parameter [31:0] INIT_00 = 32'h00000000; |  | ||||||
|     parameter [31:0] INIT_01 = 32'h00000000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output O0; |  | ||||||
|     output O1; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     input A4; |  | ||||||
|     input D0; |  | ||||||
|     input D1; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM64X2S (...); |  | ||||||
|     parameter [63:0] INIT_00 = 64'h0000000000000000; |  | ||||||
|     parameter [63:0] INIT_01 = 64'h0000000000000000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output O0; |  | ||||||
|     output O1; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     input A4; |  | ||||||
|     input A5; |  | ||||||
|     input D0; |  | ||||||
|     input D1; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM16X4S (...); |  | ||||||
|     parameter [15:0] INIT_00 = 16'h0000; |  | ||||||
|     parameter [15:0] INIT_01 = 16'h0000; |  | ||||||
|     parameter [15:0] INIT_02 = 16'h0000; |  | ||||||
|     parameter [15:0] INIT_03 = 16'h0000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output O0; |  | ||||||
|     output O1; |  | ||||||
|     output O2; |  | ||||||
|     output O3; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     input D0; |  | ||||||
|     input D1; |  | ||||||
|     input D2; |  | ||||||
|     input D3; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM32X4S (...); |  | ||||||
|     parameter [31:0] INIT_00 = 32'h00000000; |  | ||||||
|     parameter [31:0] INIT_01 = 32'h00000000; |  | ||||||
|     parameter [31:0] INIT_02 = 32'h00000000; |  | ||||||
|     parameter [31:0] INIT_03 = 32'h00000000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output O0; |  | ||||||
|     output O1; |  | ||||||
|     output O2; |  | ||||||
|     output O3; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     input A4; |  | ||||||
|     input D0; |  | ||||||
|     input D1; |  | ||||||
|     input D2; |  | ||||||
|     input D3; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM16X8S (...); |  | ||||||
|     parameter [15:0] INIT_00 = 16'h0000; |  | ||||||
|     parameter [15:0] INIT_01 = 16'h0000; |  | ||||||
|     parameter [15:0] INIT_02 = 16'h0000; |  | ||||||
|     parameter [15:0] INIT_03 = 16'h0000; |  | ||||||
|     parameter [15:0] INIT_04 = 16'h0000; |  | ||||||
|     parameter [15:0] INIT_05 = 16'h0000; |  | ||||||
|     parameter [15:0] INIT_06 = 16'h0000; |  | ||||||
|     parameter [15:0] INIT_07 = 16'h0000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output [7:0] O; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
|     input [7:0] D; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM32X8S (...); |  | ||||||
|     parameter [31:0] INIT_00 = 32'h00000000; |  | ||||||
|     parameter [31:0] INIT_01 = 32'h00000000; |  | ||||||
|     parameter [31:0] INIT_02 = 32'h00000000; |  | ||||||
|     parameter [31:0] INIT_03 = 32'h00000000; |  | ||||||
|     parameter [31:0] INIT_04 = 32'h00000000; |  | ||||||
|     parameter [31:0] INIT_05 = 32'h00000000; |  | ||||||
|     parameter [31:0] INIT_06 = 32'h00000000; |  | ||||||
|     parameter [31:0] INIT_07 = 32'h00000000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output [7:0] O; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     input A4; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
|     input [7:0] D; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM16X1D (...); |  | ||||||
|     parameter [15:0] INIT = 16'h0000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output DPO; |  | ||||||
|     output SPO; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     input D; |  | ||||||
|     input DPRA0; |  | ||||||
|     input DPRA1; |  | ||||||
|     input DPRA2; |  | ||||||
|     input DPRA3; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM16X1D_1 (...); |  | ||||||
|     parameter [15:0] INIT = 16'h0000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output DPO; |  | ||||||
|     output SPO; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     input D; |  | ||||||
|     input DPRA0; |  | ||||||
|     input DPRA1; |  | ||||||
|     input DPRA2; |  | ||||||
|     input DPRA3; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM32X1D_1 (...); |  | ||||||
|     parameter [31:0] INIT = 32'h00000000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output DPO; |  | ||||||
|     output SPO; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     input A4; |  | ||||||
|     input D; |  | ||||||
|     input DPRA0; |  | ||||||
|     input DPRA1; |  | ||||||
|     input DPRA2; |  | ||||||
|     input DPRA3; |  | ||||||
|     input DPRA4; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM64X1D_1 (...); |  | ||||||
|     parameter [63:0] INIT = 64'h0000000000000000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output DPO; |  | ||||||
|     output SPO; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     input A4; |  | ||||||
|     input A5; |  | ||||||
|     input D; |  | ||||||
|     input DPRA0; |  | ||||||
|     input DPRA1; |  | ||||||
|     input DPRA2; |  | ||||||
|     input DPRA3; |  | ||||||
|     input DPRA4; |  | ||||||
|     input DPRA5; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM256X1D (...); |  | ||||||
|     parameter [255:0] INIT = 256'h0000000000000000000000000000000000000000000000000000000000000000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output DPO; |  | ||||||
|     output SPO; |  | ||||||
|     input [7:0] A; |  | ||||||
|     input D; |  | ||||||
|     input [7:0] DPRA; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM32M (...); |  | ||||||
|     parameter [63:0] INIT_A = 64'h0000000000000000; |  | ||||||
|     parameter [63:0] INIT_B = 64'h0000000000000000; |  | ||||||
|     parameter [63:0] INIT_C = 64'h0000000000000000; |  | ||||||
|     parameter [63:0] INIT_D = 64'h0000000000000000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output [1:0] DOA; |  | ||||||
|     output [1:0] DOB; |  | ||||||
|     output [1:0] DOC; |  | ||||||
|     output [1:0] DOD; |  | ||||||
|     input [4:0] ADDRA; |  | ||||||
|     input [4:0] ADDRB; |  | ||||||
|     input [4:0] ADDRC; |  | ||||||
|     input [4:0] ADDRD; |  | ||||||
|     input [1:0] DIA; |  | ||||||
|     input [1:0] DIB; |  | ||||||
|     input [1:0] DIC; |  | ||||||
|     input [1:0] DID; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM32M16 (...); |  | ||||||
|     parameter [63:0] INIT_A = 64'h0000000000000000; |  | ||||||
|     parameter [63:0] INIT_B = 64'h0000000000000000; |  | ||||||
|     parameter [63:0] INIT_C = 64'h0000000000000000; |  | ||||||
|     parameter [63:0] INIT_D = 64'h0000000000000000; |  | ||||||
|     parameter [63:0] INIT_E = 64'h0000000000000000; |  | ||||||
|     parameter [63:0] INIT_F = 64'h0000000000000000; |  | ||||||
|     parameter [63:0] INIT_G = 64'h0000000000000000; |  | ||||||
|     parameter [63:0] INIT_H = 64'h0000000000000000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output [1:0] DOA; |  | ||||||
|     output [1:0] DOB; |  | ||||||
|     output [1:0] DOC; |  | ||||||
|     output [1:0] DOD; |  | ||||||
|     output [1:0] DOE; |  | ||||||
|     output [1:0] DOF; |  | ||||||
|     output [1:0] DOG; |  | ||||||
|     output [1:0] DOH; |  | ||||||
|     input [4:0] ADDRA; |  | ||||||
|     input [4:0] ADDRB; |  | ||||||
|     input [4:0] ADDRC; |  | ||||||
|     input [4:0] ADDRD; |  | ||||||
|     input [4:0] ADDRE; |  | ||||||
|     input [4:0] ADDRF; |  | ||||||
|     input [4:0] ADDRG; |  | ||||||
|     input [4:0] ADDRH; |  | ||||||
|     input [1:0] DIA; |  | ||||||
|     input [1:0] DIB; |  | ||||||
|     input [1:0] DIC; |  | ||||||
|     input [1:0] DID; |  | ||||||
|     input [1:0] DIE; |  | ||||||
|     input [1:0] DIF; |  | ||||||
|     input [1:0] DIG; |  | ||||||
|     input [1:0] DIH; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM64M (...); |  | ||||||
|     parameter [63:0] INIT_A = 64'h0000000000000000; |  | ||||||
|     parameter [63:0] INIT_B = 64'h0000000000000000; |  | ||||||
|     parameter [63:0] INIT_C = 64'h0000000000000000; |  | ||||||
|     parameter [63:0] INIT_D = 64'h0000000000000000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output DOA; |  | ||||||
|     output DOB; |  | ||||||
|     output DOC; |  | ||||||
|     output DOD; |  | ||||||
|     input [5:0] ADDRA; |  | ||||||
|     input [5:0] ADDRB; |  | ||||||
|     input [5:0] ADDRC; |  | ||||||
|     input [5:0] ADDRD; |  | ||||||
|     input DIA; |  | ||||||
|     input DIB; |  | ||||||
|     input DIC; |  | ||||||
|     input DID; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM64M8 (...); |  | ||||||
|     parameter [63:0] INIT_A = 64'h0000000000000000; |  | ||||||
|     parameter [63:0] INIT_B = 64'h0000000000000000; |  | ||||||
|     parameter [63:0] INIT_C = 64'h0000000000000000; |  | ||||||
|     parameter [63:0] INIT_D = 64'h0000000000000000; |  | ||||||
|     parameter [63:0] INIT_E = 64'h0000000000000000; |  | ||||||
|     parameter [63:0] INIT_F = 64'h0000000000000000; |  | ||||||
|     parameter [63:0] INIT_G = 64'h0000000000000000; |  | ||||||
|     parameter [63:0] INIT_H = 64'h0000000000000000; |  | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |  | ||||||
|     output DOA; |  | ||||||
|     output DOB; |  | ||||||
|     output DOC; |  | ||||||
|     output DOD; |  | ||||||
|     output DOE; |  | ||||||
|     output DOF; |  | ||||||
|     output DOG; |  | ||||||
|     output DOH; |  | ||||||
|     input [5:0] ADDRA; |  | ||||||
|     input [5:0] ADDRB; |  | ||||||
|     input [5:0] ADDRC; |  | ||||||
|     input [5:0] ADDRD; |  | ||||||
|     input [5:0] ADDRE; |  | ||||||
|     input [5:0] ADDRF; |  | ||||||
|     input [5:0] ADDRG; |  | ||||||
|     input [5:0] ADDRH; |  | ||||||
|     input DIA; |  | ||||||
|     input DIB; |  | ||||||
|     input DIC; |  | ||||||
|     input DID; |  | ||||||
|     input DIE; |  | ||||||
|     input DIF; |  | ||||||
|     input DIG; |  | ||||||
|     input DIH; |  | ||||||
|     (* clkbuf_sink *) |  | ||||||
|     (* invertible_pin = "IS_WCLK_INVERTED" *) |  | ||||||
|     input WCLK; |  | ||||||
|     input WE; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module ROM16X1 (...); |  | ||||||
|     parameter [127:0] INIT = 16'h0000; |  | ||||||
|     output O; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module ROM32X1 (...); |  | ||||||
|     parameter [31:0] INIT = 32'h00000000; |  | ||||||
|     output O; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     input A4; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module ROM64X1 (...); |  | ||||||
|     parameter [63:0] INIT = 64'h0000000000000000; |  | ||||||
|     output O; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     input A4; |  | ||||||
|     input A5; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module ROM128X1 (...); |  | ||||||
|     parameter [127:0] INIT = 128'h00000000000000000000000000000000; |  | ||||||
|     output O; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     input A4; |  | ||||||
|     input A5; |  | ||||||
|     input A6; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module ROM256X1 (...); |  | ||||||
|     parameter [255:0] INIT = 256'h0000000000000000000000000000000000000000000000000000000000000000; |  | ||||||
|     output O; |  | ||||||
|     input A0; |  | ||||||
|     input A1; |  | ||||||
|     input A2; |  | ||||||
|     input A3; |  | ||||||
|     input A4; |  | ||||||
|     input A5; |  | ||||||
|     input A6; |  | ||||||
|     input A7; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module FDCPE (...); | module FDCPE (...); | ||||||
|     parameter [0:0] INIT = 1'b0; |     parameter [0:0] INIT = 1'b0; | ||||||
|     parameter [0:0] IS_C_INVERTED = 1'b0; |     parameter [0:0] IS_C_INVERTED = 1'b0; | ||||||
|  | @ -5240,9 +4650,13 @@ module RAMB18E1 (...); | ||||||
|     parameter IS_RSTRAMB_INVERTED = 1'b0; |     parameter IS_RSTRAMB_INVERTED = 1'b0; | ||||||
|     parameter IS_RSTREGARSTREG_INVERTED = 1'b0; |     parameter IS_RSTREGARSTREG_INVERTED = 1'b0; | ||||||
|     parameter IS_RSTREGB_INVERTED = 1'b0; |     parameter IS_RSTREGB_INVERTED = 1'b0; | ||||||
|  |     (* abc9_arrival=2454 *) | ||||||
|     output [15:0] DOADO; |     output [15:0] DOADO; | ||||||
|  |     (* abc9_arrival=2454 *) | ||||||
|     output [15:0] DOBDO; |     output [15:0] DOBDO; | ||||||
|  |     (* abc9_arrival=2454 *) | ||||||
|     output [1:0] DOPADOP; |     output [1:0] DOPADOP; | ||||||
|  |     (* abc9_arrival=2454 *) | ||||||
|     output [1:0] DOPBDOP; |     output [1:0] DOPBDOP; | ||||||
|     (* clkbuf_sink *) |     (* clkbuf_sink *) | ||||||
|     (* invertible_pin = "IS_CLKARDCLK_INVERTED" *) |     (* invertible_pin = "IS_CLKARDCLK_INVERTED" *) | ||||||
|  | @ -5452,9 +4866,13 @@ module RAMB36E1 (...); | ||||||
|     parameter IS_RSTREGB_INVERTED = 1'b0; |     parameter IS_RSTREGB_INVERTED = 1'b0; | ||||||
|     output CASCADEOUTA; |     output CASCADEOUTA; | ||||||
|     output CASCADEOUTB; |     output CASCADEOUTB; | ||||||
|  |     (* abc9_arrival=2454 *) | ||||||
|     output [31:0] DOADO; |     output [31:0] DOADO; | ||||||
|  |     (* abc9_arrival=2454 *) | ||||||
|     output [31:0] DOBDO; |     output [31:0] DOBDO; | ||||||
|  |     (* abc9_arrival=2454 *) | ||||||
|     output [3:0] DOPADOP; |     output [3:0] DOPADOP; | ||||||
|  |     (* abc9_arrival=2454 *) | ||||||
|     output [3:0] DOPBDOP; |     output [3:0] DOPBDOP; | ||||||
|     output [7:0] ECCPARITY; |     output [7:0] ECCPARITY; | ||||||
|     output [8:0] RDADDRECC; |     output [8:0] RDADDRECC; | ||||||
|  | @ -8527,6 +7945,18 @@ module BUFIO2FB (...); | ||||||
|     input I; |     input I; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
|  | module BUFPLL (...); | ||||||
|  |     parameter integer DIVIDE = 1; | ||||||
|  |     parameter ENABLE_SYNC = "TRUE"; | ||||||
|  |     (* clkbuf_driver *) | ||||||
|  |     output IOCLK; | ||||||
|  |     output LOCK; | ||||||
|  |     output SERDESSTROBE; | ||||||
|  |     input GCLK; | ||||||
|  |     input LOCKED; | ||||||
|  |     input PLLIN; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
| module BUFPLL_MCB (...); | module BUFPLL_MCB (...); | ||||||
|     parameter integer DIVIDE = 2; |     parameter integer DIVIDE = 2; | ||||||
|     parameter LOCK_SRC = "LOCK_TO_0"; |     parameter LOCK_SRC = "LOCK_TO_0"; | ||||||
|  |  | ||||||
|  | @ -282,6 +282,7 @@ struct SynthXilinxPass : public ScriptPass | ||||||
| 
 | 
 | ||||||
| 	void script() YS_OVERRIDE | 	void script() YS_OVERRIDE | ||||||
| 	{ | 	{ | ||||||
|  | 		bool do_iopad = iopad || (ise && !noiopad); | ||||||
| 		std::string ff_map_file; | 		std::string ff_map_file; | ||||||
| 		if (help_mode) | 		if (help_mode) | ||||||
| 			ff_map_file = "+/xilinx/{family}_ff_map.v"; | 			ff_map_file = "+/xilinx/{family}_ff_map.v"; | ||||||
|  | @ -306,6 +307,8 @@ struct SynthXilinxPass : public ScriptPass | ||||||
| 			run("proc"); | 			run("proc"); | ||||||
| 			if (flatten || help_mode) | 			if (flatten || help_mode) | ||||||
| 				run("flatten", "(with '-flatten')"); | 				run("flatten", "(with '-flatten')"); | ||||||
|  | 			run("tribuf -logic"); | ||||||
|  | 			run("deminout"); | ||||||
| 			run("opt_expr"); | 			run("opt_expr"); | ||||||
| 			run("opt_clean"); | 			run("opt_clean"); | ||||||
| 			run("check"); | 			run("check"); | ||||||
|  | @ -504,6 +507,9 @@ struct SynthXilinxPass : public ScriptPass | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (check_label("map_cells")) { | 		if (check_label("map_cells")) { | ||||||
|  | 			// Needs to be done before logic optimization, so that inverters (OE vs T) are handled.
 | ||||||
|  | 			if (help_mode || do_iopad) | ||||||
|  | 				run("iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I -toutpad $__XILINX_TOUTPAD OE:I:O -tinoutpad $__XILINX_TINOUTPAD OE:O:I:IO A:top", "(only if '-iopad' or '-ise' and not '-noiopad')"); | ||||||
| 			std::string techmap_args = "-map +/techmap.v -map +/xilinx/cells_map.v"; | 			std::string techmap_args = "-map +/techmap.v -map +/xilinx/cells_map.v"; | ||||||
| 			if (widemux > 0) | 			if (widemux > 0) | ||||||
| 				techmap_args += stringf(" -D MIN_MUX_INPUTS=%d", widemux); | 				techmap_args += stringf(" -D MIN_MUX_INPUTS=%d", widemux); | ||||||
|  | @ -560,15 +566,8 @@ struct SynthXilinxPass : public ScriptPass | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (check_label("finalize")) { | 		if (check_label("finalize")) { | ||||||
| 			bool do_iopad = iopad || (ise && !noiopad); | 			if (help_mode || !noclkbuf) | ||||||
| 			if (help_mode || !noclkbuf) { | 				run("clkbufmap -buf BUFG O:I ", "(skip if '-noclkbuf')"); | ||||||
| 				if (help_mode || do_iopad) |  | ||||||
| 					run("clkbufmap -buf BUFG O:I -inpad IBUFG O:I", "(skip if '-noclkbuf', '-inpad' passed if '-iopad' or '-ise' and not '-noiopad')"); |  | ||||||
| 				else |  | ||||||
| 					run("clkbufmap -buf BUFG O:I"); |  | ||||||
| 			} |  | ||||||
| 			if (help_mode || do_iopad) |  | ||||||
| 				run("iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I A:top", "(only if '-iopad' or '-ise' and not '-noiopad')"); |  | ||||||
| 			if (help_mode || ise) | 			if (help_mode || ise) | ||||||
| 				run("extractinv -inv INV O:I", "(only if '-ise')"); | 				run("extractinv -inv INV O:I", "(only if '-ise')"); | ||||||
| 			run("clean"); | 			run("clean"); | ||||||
|  |  | ||||||
|  | @ -34,11 +34,12 @@ proc | ||||||
| equiv_opt -async2sync -assert -map +/gowin/cells_sim.v synth_gowin # equivalency check | equiv_opt -async2sync -assert -map +/gowin/cells_sim.v synth_gowin # equivalency check | ||||||
| design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) | design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) | ||||||
| cd dffs # Constrain all select calls below inside the top module | cd dffs # Constrain all select calls below inside the top module | ||||||
| select -assert-count 1 t:DFFS | select -assert-count 1 t:DFF | ||||||
|  | select -assert-count 1 t:LUT2 | ||||||
| select -assert-count 4 t:IBUF | select -assert-count 4 t:IBUF | ||||||
| select -assert-count 1 t:OBUF | select -assert-count 1 t:OBUF | ||||||
| 
 | 
 | ||||||
| select -assert-none t:DFFS t:IBUF t:OBUF %% t:* %D | select -assert-none t:DFF t:LUT2 t:IBUF t:OBUF %% t:* %D | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| design -load read | design -load read | ||||||
|  |  | ||||||
							
								
								
									
										224
									
								
								tests/arch/gowin/init.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								tests/arch/gowin/init.v
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,224 @@ | ||||||
|  | module myDFF (output reg Q, input CLK, D); | ||||||
|  | 	parameter [0:0] INIT = 1'b0; | ||||||
|  | 	initial Q = INIT; | ||||||
|  | 	always @(posedge CLK) | ||||||
|  | 		Q <= D; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module myDFFE (output reg Q, input D, CLK, CE); | ||||||
|  | 	parameter [0:0] INIT = 1'b0; | ||||||
|  | 	initial Q = INIT; | ||||||
|  | 	always @(posedge CLK) begin | ||||||
|  | 		if (CE) | ||||||
|  | 			Q <= D; | ||||||
|  | 	end | ||||||
|  | endmodule // DFFE (positive clock edge; clock enable) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | module myDFFS (output reg Q, input D, CLK, SET); | ||||||
|  | 	parameter [0:0] INIT = 1'b1; | ||||||
|  | 	initial Q = INIT; | ||||||
|  | 	always @(posedge CLK) begin | ||||||
|  | 		if (SET) | ||||||
|  | 			Q <= 1'b1; | ||||||
|  | 		else | ||||||
|  | 			Q <= D; | ||||||
|  | 	end | ||||||
|  | endmodule // DFFS (positive clock edge; synchronous set) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | module myDFFSE (output reg Q, input D, CLK, CE, SET); | ||||||
|  | 	parameter [0:0] INIT = 1'b1; | ||||||
|  | 	initial Q = INIT; | ||||||
|  | 	always @(posedge CLK) begin | ||||||
|  | 		if (SET) | ||||||
|  | 			Q <= 1'b1; | ||||||
|  | 		else if (CE) | ||||||
|  | 			Q <= D; | ||||||
|  | end | ||||||
|  | endmodule // DFFSE (positive clock edge; synchronous set takes precedence over clock enable) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | module myDFFR (output reg Q, input D, CLK, RESET); | ||||||
|  | 	parameter [0:0] INIT = 1'b0; | ||||||
|  | 	initial Q = INIT; | ||||||
|  | 	always @(posedge CLK) begin | ||||||
|  | 		if (RESET) | ||||||
|  | 			Q <= 1'b0; | ||||||
|  | 		else | ||||||
|  | 			Q <= D; | ||||||
|  | 	end | ||||||
|  | endmodule // DFFR (positive clock edge; synchronous reset) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | module myDFFRE (output reg Q, input D, CLK, CE, RESET); | ||||||
|  | 	parameter [0:0] INIT = 1'b0; | ||||||
|  | 	initial Q = INIT; | ||||||
|  | 	always @(posedge CLK) begin | ||||||
|  | 		if (RESET) | ||||||
|  | 			Q <= 1'b0; | ||||||
|  | 		else if (CE) | ||||||
|  | 			Q <= D; | ||||||
|  | 	end | ||||||
|  | endmodule // DFFRE (positive clock edge; synchronous reset takes precedence over clock enable) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | module myDFFP (output reg Q, input D, CLK, PRESET); | ||||||
|  | 	parameter [0:0] INIT = 1'b1; | ||||||
|  | 	initial Q = INIT; | ||||||
|  | 	always @(posedge CLK or posedge PRESET) begin | ||||||
|  | 		if(PRESET) | ||||||
|  | 			Q <= 1'b1; | ||||||
|  | 		else | ||||||
|  | 			Q <= D; | ||||||
|  | 	end | ||||||
|  | endmodule // DFFP (positive clock edge; asynchronous preset) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | module myDFFPE (output reg Q, input D, CLK, CE, PRESET); | ||||||
|  | 	parameter [0:0] INIT = 1'b1; | ||||||
|  | 	initial Q = INIT; | ||||||
|  | 	always @(posedge CLK or posedge PRESET) begin | ||||||
|  | 		if(PRESET) | ||||||
|  | 			Q <= 1'b1; | ||||||
|  | 		else if (CE) | ||||||
|  | 			Q <= D; | ||||||
|  | 	end | ||||||
|  | endmodule // DFFPE (positive clock edge; asynchronous preset; clock enable) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | module myDFFC (output reg Q, input D, CLK, CLEAR); | ||||||
|  | 	parameter [0:0] INIT = 1'b0; | ||||||
|  | 	initial Q = INIT; | ||||||
|  | 	always @(posedge CLK or posedge CLEAR) begin | ||||||
|  | 		if(CLEAR) | ||||||
|  | 			Q <= 1'b0; | ||||||
|  | 		else | ||||||
|  | 			Q <= D; | ||||||
|  | 	end | ||||||
|  | endmodule // DFFC (positive clock edge; asynchronous clear) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | module myDFFCE (output reg Q, input D, CLK, CE, CLEAR); | ||||||
|  | 	parameter [0:0] INIT = 1'b0; | ||||||
|  | 	initial Q = INIT; | ||||||
|  | 	always @(posedge CLK or posedge CLEAR) begin | ||||||
|  | 		if(CLEAR) | ||||||
|  | 			Q <= 1'b0; | ||||||
|  | 		else if (CE) | ||||||
|  | 			Q <= D; | ||||||
|  | 	end | ||||||
|  | endmodule // DFFCE (positive clock edge; asynchronous clear; clock enable) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | module myDFFN (output reg Q, input CLK, D); | ||||||
|  | 	parameter [0:0] INIT = 1'b0; | ||||||
|  | 	initial Q = INIT; | ||||||
|  | 	always @(negedge CLK) | ||||||
|  | 		Q <= D; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module myDFFNE (output reg Q, input D, CLK, CE); | ||||||
|  | 	parameter [0:0] INIT = 1'b0; | ||||||
|  | 	initial Q = INIT; | ||||||
|  | 	always @(negedge CLK) begin | ||||||
|  | 		if (CE) | ||||||
|  | 			Q <= D; | ||||||
|  | 	end | ||||||
|  | endmodule // DFFNE (negative clock edge; clock enable) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | module myDFFNS (output reg Q, input D, CLK, SET); | ||||||
|  | 	parameter [0:0] INIT = 1'b1; | ||||||
|  | 	initial Q = INIT; | ||||||
|  | 	always @(negedge CLK) begin | ||||||
|  | 		if (SET) | ||||||
|  | 			Q <= 1'b1; | ||||||
|  | 		else | ||||||
|  | 			Q <= D; | ||||||
|  | 	end | ||||||
|  | endmodule // DFFNS (negative clock edge; synchronous set) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | module myDFFNSE (output reg Q, input D, CLK, CE, SET); | ||||||
|  | 	parameter [0:0] INIT = 1'b1; | ||||||
|  | 	initial Q = INIT; | ||||||
|  | 	always @(negedge CLK) begin | ||||||
|  | 		if (SET) | ||||||
|  | 			Q <= 1'b1; | ||||||
|  | 		else if (CE) | ||||||
|  | 			Q <= D; | ||||||
|  | end | ||||||
|  | endmodule // DFFNSE (negative clock edge; synchronous set takes precedence over clock enable) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | module myDFFNR (output reg Q, input D, CLK, RESET); | ||||||
|  | 	parameter [0:0] INIT = 1'b0; | ||||||
|  | 	initial Q = INIT; | ||||||
|  | 	always @(negedge CLK) begin | ||||||
|  | 		if (RESET) | ||||||
|  | 			Q <= 1'b0; | ||||||
|  | 		else | ||||||
|  | 			Q <= D; | ||||||
|  | 	end | ||||||
|  | endmodule // DFFNR (negative clock edge; synchronous reset) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | module myDFFNRE (output reg Q, input D, CLK, CE, RESET); | ||||||
|  | 	parameter [0:0] INIT = 1'b0; | ||||||
|  | 	initial Q = INIT; | ||||||
|  | 	always @(negedge CLK) begin | ||||||
|  | 		if (RESET) | ||||||
|  | 			Q <= 1'b0; | ||||||
|  | 		else if (CE) | ||||||
|  | 			Q <= D; | ||||||
|  | 	end | ||||||
|  | endmodule // DFFNRE (negative clock edge; synchronous reset takes precedence over clock enable) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | module myDFFNP (output reg Q, input D, CLK, PRESET); | ||||||
|  | 	parameter [0:0] INIT = 1'b1; | ||||||
|  | 	initial Q = INIT; | ||||||
|  | 	always @(negedge CLK or posedge PRESET) begin | ||||||
|  | 		if(PRESET) | ||||||
|  | 			Q <= 1'b1; | ||||||
|  | 		else | ||||||
|  | 			Q <= D; | ||||||
|  | 	end | ||||||
|  | endmodule // DFFNP (negative clock edge; asynchronous preset) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | module myDFFNPE (output reg Q, input D, CLK, CE, PRESET); | ||||||
|  | 	parameter [0:0] INIT = 1'b1; | ||||||
|  | 	initial Q = INIT; | ||||||
|  | 	always @(negedge CLK or posedge PRESET) begin | ||||||
|  | 		if(PRESET) | ||||||
|  | 			Q <= 1'b1; | ||||||
|  | 		else if (CE) | ||||||
|  | 			Q <= D; | ||||||
|  | 	end | ||||||
|  | endmodule // DFFNPE (negative clock edge; asynchronous preset; clock enable) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | module myDFFNC (output reg Q, input D, CLK, CLEAR); | ||||||
|  | 	parameter [0:0] INIT = 1'b0; | ||||||
|  | 	initial Q = INIT; | ||||||
|  | 	always @(negedge CLK or posedge CLEAR) begin | ||||||
|  | 		if(CLEAR) | ||||||
|  | 			Q <= 1'b0; | ||||||
|  | 		else | ||||||
|  | 			Q <= D; | ||||||
|  | 	end | ||||||
|  | endmodule // DFFNC (negative clock edge; asynchronous clear) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | module myDFFNCE (output reg Q, input D, CLK, CE, CLEAR); | ||||||
|  | 	parameter [0:0] INIT = 1'b0; | ||||||
|  | 	initial Q = INIT; | ||||||
|  | 	always @(negedge CLK or posedge CLEAR) begin | ||||||
|  | 		if(CLEAR) | ||||||
|  | 			Q <= 1'b0; | ||||||
|  | 		else if (CE) | ||||||
|  | 			Q <= D; | ||||||
|  | 	end | ||||||
|  | endmodule // DFFNCE (negative clock edge; asynchronous clear; clock enable) | ||||||
							
								
								
									
										74
									
								
								tests/arch/gowin/init.ys
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								tests/arch/gowin/init.ys
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,74 @@ | ||||||
|  | read_verilog init.v | ||||||
|  | read_verilog -lib +/gowin/cells_sim.v | ||||||
|  | design -save read | ||||||
|  | 
 | ||||||
|  | proc | ||||||
|  | flatten | ||||||
|  | synth_gowin -run coarse: | ||||||
|  | 
 | ||||||
|  | # check if all init values are handled | ||||||
|  | check -assert -noinit | ||||||
|  | # check if every flop mapped correctly | ||||||
|  | select -assert-count 1 t:DFF | ||||||
|  | select -assert-count 1 t:DFFC | ||||||
|  | select -assert-count 1 t:DFFCE | ||||||
|  | select -assert-count 1 t:DFFE | ||||||
|  | select -assert-count 1 t:DFFN | ||||||
|  | select -assert-count 1 t:DFFNC | ||||||
|  | select -assert-count 1 t:DFFNCE | ||||||
|  | select -assert-count 1 t:DFFNE | ||||||
|  | select -assert-count 1 t:DFFNP | ||||||
|  | select -assert-count 1 t:DFFNPE | ||||||
|  | select -assert-count 1 t:DFFNR | ||||||
|  | select -assert-count 1 t:DFFNRE | ||||||
|  | select -assert-count 1 t:DFFNS | ||||||
|  | select -assert-count 1 t:DFFNSE | ||||||
|  | select -assert-count 1 t:DFFP | ||||||
|  | select -assert-count 1 t:DFFPE | ||||||
|  | select -assert-count 1 t:DFFR | ||||||
|  | select -assert-count 1 t:DFFRE | ||||||
|  | select -assert-count 1 t:DFFS | ||||||
|  | select -assert-count 1 t:DFFSE | ||||||
|  | 
 | ||||||
|  | delete | ||||||
|  | design -load read | ||||||
|  | 
 | ||||||
|  | # these should synth to a flop with reset | ||||||
|  | chparam -set INIT 1 myDFF myDFFN myDFFE myDFFNE | ||||||
|  | 
 | ||||||
|  | # async should give a warning | ||||||
|  | # sync should synth to a mux | ||||||
|  | chparam -set INIT 0 myDFF*S* myDFF*P* | ||||||
|  | chparam -set INIT 1 myDFF*R* myDFF*C* | ||||||
|  | 
 | ||||||
|  | proc | ||||||
|  | flatten | ||||||
|  | synth_gowin -run coarse: | ||||||
|  | 
 | ||||||
|  | # check the flops mapped as expected | ||||||
|  | select -assert-count 1 t:DFF | ||||||
|  | select -assert-count 1 t:DFFC | ||||||
|  | select -assert-count 1 t:DFFCE | ||||||
|  | select -assert-count 1 t:DFFE | ||||||
|  | select -assert-count 1 t:DFFN | ||||||
|  | select -assert-count 1 t:DFFNC | ||||||
|  | select -assert-count 1 t:DFFNCE | ||||||
|  | select -assert-count 1 t:DFFNE | ||||||
|  | select -assert-count 1 t:DFFNP | ||||||
|  | select -assert-count 1 t:DFFNPE | ||||||
|  | select -assert-count 0 t:DFFNR | ||||||
|  | select -assert-count 0 t:DFFNRE | ||||||
|  | select -assert-count 2 t:DFFNS | ||||||
|  | select -assert-count 2 t:DFFNSE | ||||||
|  | select -assert-count 1 t:DFFP | ||||||
|  | select -assert-count 1 t:DFFPE | ||||||
|  | select -assert-count 0 t:DFFR | ||||||
|  | select -assert-count 0 t:DFFRE | ||||||
|  | select -assert-count 2 t:DFFS | ||||||
|  | select -assert-count 2 t:DFFSE | ||||||
|  | select -assert-count 12 t:LUT2 | ||||||
|  | 
 | ||||||
|  | # check the expected leftover init values | ||||||
|  | # this would happen if your reset value is not the initial value | ||||||
|  | # which would be weird | ||||||
|  | select -assert-count 8 a:init | ||||||
|  | @ -1,3 +1,3 @@ | ||||||
| ../../../yosys -qp "synth_xilinx -top macc2; rename -top macc2_uut" macc.v -o macc_uut.v | ../../../yosys -qp "synth_xilinx -top macc2; rename -top macc2_uut" -o macc_uut.v macc.v | ||||||
| iverilog -o test_macc macc_tb.v macc_uut.v macc.v ../../../techlibs/xilinx/cells_sim.v | iverilog -o test_macc macc_tb.v macc_uut.v macc.v ../../../techlibs/xilinx/cells_sim.v | ||||||
| vvp -N ./test_macc | vvp -N ./test_macc | ||||||
|  |  | ||||||
|  | @ -259,29 +259,35 @@ assign o = { 1'b1, 1'bx }; | ||||||
| assign p = { 1'b1, 1'bx, 1'b0 }; | assign p = { 1'b1, 1'bx, 1'b0 }; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module abc9_test029(input clk1, clk2, d, output reg q1, q2); | module abc9_test030(input [3:0] d, input en, output reg [3:0] q); | ||||||
|  | always @* | ||||||
|  |   if (en) | ||||||
|  |     q <= d; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module abc9_test031(input clk1, clk2, d, output reg q1, q2); | ||||||
| always @(posedge clk1) q1 <= d; | always @(posedge clk1) q1 <= d; | ||||||
| always @(negedge clk2) q2 <= q1; | always @(negedge clk2) q2 <= q1; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module abc9_test030(input clk, d, r, output reg q); | module abc9_test032(input clk, d, r, output reg q); | ||||||
| always @(posedge clk or posedge r) | always @(posedge clk or posedge r) | ||||||
|     if (r) q <= 1'b0; |     if (r) q <= 1'b0; | ||||||
|     else q <= d; |     else q <= d; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module abc9_test031(input clk, d, r, output reg q); | module abc9_test033(input clk, d, r, output reg q); | ||||||
| always @(negedge clk or posedge r) | always @(negedge clk or posedge r) | ||||||
|     if (r) q <= 1'b1; |     if (r) q <= 1'b1; | ||||||
|     else q <= d; |     else q <= d; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module abc9_test033(input clk, d, output reg q1, q2); | module abc9_test034(input clk, d, output reg q1, q2); | ||||||
| always @(posedge clk) q1 <= d; | always @(posedge clk) q1 <= d; | ||||||
| always @(posedge clk) q2 <= q1; | always @(posedge clk) q2 <= q1; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module abc9_test034(input clk, d, output reg [1:0] q); | module abc9_test035(input clk, d, output reg [1:0] q); | ||||||
| always @(posedge clk) q[0] <= d; | always @(posedge clk) q[0] <= d; | ||||||
| always @(negedge clk) q[1] <= q[0]; | always @(negedge clk) q[1] <= q[0]; | ||||||
| endmodule | endmodule | ||||||
|  |  | ||||||
							
								
								
									
										99
									
								
								tests/techmap/iopadmap.ys
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								tests/techmap/iopadmap.ys
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,99 @@ | ||||||
|  | read_verilog << EOT | ||||||
|  | module ibuf ((* iopad_external_pin *) input i, output o); endmodule | ||||||
|  | module obuf (input i, (* iopad_external_pin *) output o); endmodule | ||||||
|  | module obuft (input i, input oe, (* iopad_external_pin *) output o); endmodule | ||||||
|  | module iobuf (input i, input oe, output o, (* iopad_external_pin *) inout io); endmodule | ||||||
|  | 
 | ||||||
|  | module a(input i, output o); | ||||||
|  | assign o = i; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module b(input i, output o); | ||||||
|  | assign o = i; | ||||||
|  | ibuf b (.i(i), .o(o)); | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module c(input i, output o); | ||||||
|  | obuf b (.i(i), .o(o)); | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module d(input i, oe, output o, o2, o3); | ||||||
|  | assign o = oe ? i : 1'bz; | ||||||
|  | assign o2 = o; | ||||||
|  | assign o3 = ~o; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module e(input i, oe, inout io, output o2, o3); | ||||||
|  | assign io = oe ? i : 1'bz; | ||||||
|  | assign o2 = io; | ||||||
|  | assign o3 = ~io; | ||||||
|  | endmodule | ||||||
|  | EOT | ||||||
|  | 
 | ||||||
|  | opt_clean | ||||||
|  | tribuf | ||||||
|  | simplemap | ||||||
|  | iopadmap -bits -inpad ibuf o:i -outpad obuf i:o -toutpad obuft oe:i:o -tinoutpad iobuf oe:o:i:io | ||||||
|  | opt_clean | ||||||
|  | 
 | ||||||
|  | select -assert-count 1 a/t:ibuf | ||||||
|  | select -assert-count 1 a/t:obuf | ||||||
|  | select -set ib w:i %a %co a/t:ibuf %i | ||||||
|  | select -set ob w:o %a %ci a/t:obuf %i | ||||||
|  | select -assert-count 1 @ib | ||||||
|  | select -assert-count 1 @ob | ||||||
|  | select -assert-count 1 @ib %co %co @ob %i | ||||||
|  | 
 | ||||||
|  | select -assert-count 1 b/t:ibuf | ||||||
|  | select -assert-count 1 b/t:obuf | ||||||
|  | select -set ib w:i %a %co b/t:ibuf %i | ||||||
|  | select -set ob w:o %a %ci b/t:obuf %i | ||||||
|  | select -assert-count 1 @ib | ||||||
|  | select -assert-count 1 @ob | ||||||
|  | select -assert-count 1 @ib %co %co @ob %i | ||||||
|  | 
 | ||||||
|  | select -assert-count 1 c/t:ibuf | ||||||
|  | select -assert-count 1 c/t:obuf | ||||||
|  | select -set ib w:i %a %co c/t:ibuf %i | ||||||
|  | select -set ob w:o %a %ci c/t:obuf %i | ||||||
|  | select -assert-count 1 @ib | ||||||
|  | select -assert-count 1 @ob | ||||||
|  | select -assert-count 1 @ib %co %co @ob %i | ||||||
|  | 
 | ||||||
|  | select -assert-count 2 d/t:ibuf | ||||||
|  | select -assert-count 2 d/t:obuf | ||||||
|  | select -assert-count 1 d/t:obuft | ||||||
|  | select -set ib w:i %a %co d/t:ibuf %i | ||||||
|  | select -set oeb w:oe %a %co d/t:ibuf %i | ||||||
|  | select -set ob w:o %a %ci d/t:obuft %i | ||||||
|  | select -set o2b w:o2 %a %ci d/t:obuf %i | ||||||
|  | select -set o3b w:o3 %a %ci d/t:obuf %i | ||||||
|  | select -assert-count 1 @ib | ||||||
|  | select -assert-count 1 @oeb | ||||||
|  | select -assert-count 1 @ob | ||||||
|  | select -assert-count 1 @o2b | ||||||
|  | select -assert-count 1 @o3b | ||||||
|  | select -assert-count 1 @ib %co %co @ob %i | ||||||
|  | select -assert-count 1 @oeb %co %co @ob %i | ||||||
|  | select -assert-count 1 @ib %co %co @o2b %i | ||||||
|  | select -assert-count 1 @ib %co %co t:$_NOT_ %i | ||||||
|  | select -assert-count 1 @o3b %ci %ci t:$_NOT_ %i | ||||||
|  | 
 | ||||||
|  | select -assert-count 2 e/t:ibuf | ||||||
|  | select -assert-count 2 e/t:obuf | ||||||
|  | select -assert-count 1 e/t:iobuf | ||||||
|  | select -set ib w:i %a %co e/t:ibuf %i | ||||||
|  | select -set oeb w:oe %a %co e/t:ibuf %i | ||||||
|  | select -set iob w:io %a %ci e/t:iobuf %i | ||||||
|  | select -set o2b w:o2 %a %ci e/t:obuf %i | ||||||
|  | select -set o3b w:o3 %a %ci e/t:obuf %i | ||||||
|  | select -assert-count 1 @ib | ||||||
|  | select -assert-count 1 @oeb | ||||||
|  | select -assert-count 1 @iob | ||||||
|  | select -assert-count 1 @o2b | ||||||
|  | select -assert-count 1 @o3b | ||||||
|  | select -assert-count 1 @ib %co %co @iob %i | ||||||
|  | select -assert-count 1 @oeb %co %co @iob %i | ||||||
|  | select -assert-count 1 @iob %co %co @o2b %i | ||||||
|  | select -assert-count 1 @iob %co %co t:$_NOT_ %i | ||||||
|  | select -assert-count 1 @o3b %ci %ci t:$_NOT_ %i | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue