mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +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); | ||||
| 	} | | ||||
| 	sigspec '[' TOK_INT ']' { | ||||
| 		if ($3 >= $1->size() || $3 < 0) | ||||
| 			rtlil_frontend_ilang_yyerror("bit index out of range"); | ||||
| 		$$ = new RTLIL::SigSpec($1->extract($3)); | ||||
| 		delete $1; | ||||
| 	} | | ||||
| 	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)); | ||||
| 		delete $1; | ||||
| 	} | | ||||
|  |  | |||
|  | @ -2242,7 +2242,7 @@ gen_stmt: | |||
| 		ast_stack.back()->children.push_back(node); | ||||
| 		ast_stack.push_back(node); | ||||
| 	} opt_arg_list ';'{ | ||||
| 		ast_stack.pop_back();		 | ||||
| 		ast_stack.pop_back(); | ||||
| 	}; | ||||
| 
 | ||||
| gen_stmt_block: | ||||
|  | @ -2413,19 +2413,19 @@ basic_expr: | |||
| 		append_attr($$, $2); | ||||
| 	} | | ||||
| 	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); | ||||
| 	} | | ||||
| 	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); | ||||
| 	} | | ||||
| 	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); | ||||
| 	} | | ||||
| 	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); | ||||
| 	} | | ||||
| 	basic_expr '<' attr basic_expr { | ||||
|  |  | |||
|  | @ -783,6 +783,14 @@ namespace { | |||
| 			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) | ||||
| 		{ | ||||
| 			param(name); | ||||
|  | @ -869,13 +877,23 @@ namespace { | |||
| 				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(B_SIGNED)); | ||||
| 				port(ID::A, param(ID(A_WIDTH))); | ||||
| 				port(ID::B, param(ID(B_WIDTH))); | ||||
| 				port(ID::Y, param(ID(Y_WIDTH))); | ||||
| 				check_expected(false); | ||||
| 				check_expected(/*check_matched_sign=*/false); | ||||
| 				return; | ||||
| 			} | ||||
| 
 | ||||
|  | @ -957,7 +975,7 @@ namespace { | |||
| 				port(ID::A, param(ID(A_WIDTH))); | ||||
| 				port(ID::B, param(ID(B_WIDTH))); | ||||
| 				port(ID::Y, param(ID(Y_WIDTH))); | ||||
| 				check_expected(false); | ||||
| 				check_expected(/*check_matched_sign=*/false); | ||||
| 				return; | ||||
| 			} | ||||
| 
 | ||||
|  |  | |||
|  | @ -65,6 +65,11 @@ Verilog & Cell Type \\ | |||
| \label{tab:CellLib_unary} | ||||
| \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 | ||||
| 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 | ||||
|  | @ -97,41 +102,6 @@ The width of the output port \B{Y}. | |||
| 
 | ||||
| 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!] | ||||
| \hfil | ||||
| \begin{tabular}[t]{ll} | ||||
|  | @ -175,6 +145,57 @@ Verilog & Cell Type \\ | |||
| \label{tab:CellLib_binary} | ||||
| \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} | ||||
| 
 | ||||
| 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)) { | ||||
| 						SigBit b = c.second.as_bit(); | ||||
| 						Wire *w = b.wire; | ||||
| 						log_assert(!w->port_input); | ||||
| 						w->port_input = true; | ||||
| 						w = module->wire(stringf("%s.abci", w->name.c_str())); | ||||
| 						if (!w) { | ||||
| 							w = module->addWire(stringf("%s.abci", b.wire->name.c_str()), GetSize(b.wire)); | ||||
| 							w->port_output = true; | ||||
| 						if (w->port_input) { | ||||
| 							// In this case, hopefully the loop break has been already created
 | ||||
| 							// Get the non-prefixed wire
 | ||||
| 							Wire *wo = module->wire(stringf("%s.abco", b.wire->name.c_str())); | ||||
| 							log_assert(wo != nullptr); | ||||
| 							log_assert(wo->port_output); | ||||
| 							log_assert(b.offset < GetSize(wo)); | ||||
| 							c.second = RTLIL::SigBit(wo, b.offset); | ||||
| 						} | ||||
| 						else { | ||||
| 							log_assert(w->port_input); | ||||
| 							log_assert(b.offset < GetSize(w)); | ||||
| 							// Create a new output/input loop break
 | ||||
| 							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__))); | ||||
| #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"); | ||||
| 
 | ||||
| 		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:           input signals: %8d\n", in_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"); | ||||
| 
 | ||||
| 		std::string inpad_celltype, inpad_portname, inpad_portname2; | ||||
| 		std::string outpad_celltype, outpad_portname, outpad_portname2; | ||||
| 		std::string inoutpad_celltype, inoutpad_portname, inoutpad_portname2; | ||||
| 		std::string toutpad_celltype, toutpad_portname, toutpad_portname2, toutpad_portname3; | ||||
| 		std::string tinoutpad_celltype, tinoutpad_portname, tinoutpad_portname2, tinoutpad_portname3, tinoutpad_portname4; | ||||
| 		std::string inpad_celltype, inpad_portname_o, inpad_portname_pad; | ||||
| 		std::string outpad_celltype, outpad_portname_i, outpad_portname_pad; | ||||
| 		std::string inoutpad_celltype, inoutpad_portname_io, inoutpad_portname_pad; | ||||
| 		std::string toutpad_celltype, toutpad_portname_oe, toutpad_portname_i, toutpad_portname_pad; | ||||
| 		std::string tinoutpad_celltype, tinoutpad_portname_oe, tinoutpad_portname_o, tinoutpad_portname_i, tinoutpad_portname_pad; | ||||
| 		std::string widthparam, nameparam; | ||||
| 		pool<pair<IdString, IdString>> ignore; | ||||
| 		bool flag_bits = false; | ||||
|  | @ -102,35 +102,35 @@ struct IopadmapPass : public Pass { | |||
| 			std::string arg = args[argidx]; | ||||
| 			if (arg == "-inpad" && argidx+2 < args.size()) { | ||||
| 				inpad_celltype = args[++argidx]; | ||||
| 				inpad_portname = args[++argidx]; | ||||
| 				split_portname_pair(inpad_portname, inpad_portname2); | ||||
| 				inpad_portname_o = args[++argidx]; | ||||
| 				split_portname_pair(inpad_portname_o, inpad_portname_pad); | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-outpad" && argidx+2 < args.size()) { | ||||
| 				outpad_celltype = args[++argidx]; | ||||
| 				outpad_portname = args[++argidx]; | ||||
| 				split_portname_pair(outpad_portname, outpad_portname2); | ||||
| 				outpad_portname_i = args[++argidx]; | ||||
| 				split_portname_pair(outpad_portname_i, outpad_portname_pad); | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-inoutpad" && argidx+2 < args.size()) { | ||||
| 				inoutpad_celltype = args[++argidx]; | ||||
| 				inoutpad_portname = args[++argidx]; | ||||
| 				split_portname_pair(inoutpad_portname, inoutpad_portname2); | ||||
| 				inoutpad_portname_io = args[++argidx]; | ||||
| 				split_portname_pair(inoutpad_portname_io, inoutpad_portname_pad); | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-toutpad" && argidx+2 < args.size()) { | ||||
| 				toutpad_celltype = args[++argidx]; | ||||
| 				toutpad_portname = args[++argidx]; | ||||
| 				split_portname_pair(toutpad_portname, toutpad_portname2); | ||||
| 				split_portname_pair(toutpad_portname2, toutpad_portname3); | ||||
| 				toutpad_portname_oe = args[++argidx]; | ||||
| 				split_portname_pair(toutpad_portname_oe, toutpad_portname_i); | ||||
| 				split_portname_pair(toutpad_portname_i, toutpad_portname_pad); | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-tinoutpad" && argidx+2 < args.size()) { | ||||
| 				tinoutpad_celltype = args[++argidx]; | ||||
| 				tinoutpad_portname = args[++argidx]; | ||||
| 				split_portname_pair(tinoutpad_portname, tinoutpad_portname2); | ||||
| 				split_portname_pair(tinoutpad_portname2, tinoutpad_portname3); | ||||
| 				split_portname_pair(tinoutpad_portname3, tinoutpad_portname4); | ||||
| 				tinoutpad_portname_oe = args[++argidx]; | ||||
| 				split_portname_pair(tinoutpad_portname_oe, tinoutpad_portname_o); | ||||
| 				split_portname_pair(tinoutpad_portname_o, tinoutpad_portname_i); | ||||
| 				split_portname_pair(tinoutpad_portname_i, tinoutpad_portname_pad); | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-ignore" && argidx+2 < args.size()) { | ||||
|  | @ -161,16 +161,16 @@ struct IopadmapPass : public Pass { | |||
| 		} | ||||
| 		extra_args(args, argidx, design); | ||||
| 
 | ||||
| 		if (!inpad_portname2.empty()) | ||||
| 			ignore.insert(make_pair(RTLIL::escape_id(inpad_celltype), RTLIL::escape_id(inpad_portname2))); | ||||
| 		if (!outpad_portname2.empty()) | ||||
| 			ignore.insert(make_pair(RTLIL::escape_id(outpad_celltype), RTLIL::escape_id(outpad_portname2))); | ||||
| 		if (!inoutpad_portname2.empty()) | ||||
| 			ignore.insert(make_pair(RTLIL::escape_id(inoutpad_celltype), RTLIL::escape_id(inoutpad_portname2))); | ||||
| 		if (!toutpad_portname3.empty()) | ||||
| 			ignore.insert(make_pair(RTLIL::escape_id(toutpad_celltype), RTLIL::escape_id(toutpad_portname3))); | ||||
| 		if (!tinoutpad_portname4.empty()) | ||||
| 			ignore.insert(make_pair(RTLIL::escape_id(tinoutpad_celltype), RTLIL::escape_id(tinoutpad_portname4))); | ||||
| 		if (!inpad_portname_pad.empty()) | ||||
| 			ignore.insert(make_pair(RTLIL::escape_id(inpad_celltype), RTLIL::escape_id(inpad_portname_pad))); | ||||
| 		if (!outpad_portname_pad.empty()) | ||||
| 			ignore.insert(make_pair(RTLIL::escape_id(outpad_celltype), RTLIL::escape_id(outpad_portname_pad))); | ||||
| 		if (!inoutpad_portname_pad.empty()) | ||||
| 			ignore.insert(make_pair(RTLIL::escape_id(inoutpad_celltype), RTLIL::escape_id(inoutpad_portname_pad))); | ||||
| 		if (!toutpad_portname_pad.empty()) | ||||
| 			ignore.insert(make_pair(RTLIL::escape_id(toutpad_celltype), RTLIL::escape_id(toutpad_portname_pad))); | ||||
| 		if (!tinoutpad_portname_pad.empty()) | ||||
| 			ignore.insert(make_pair(RTLIL::escape_id(tinoutpad_celltype), RTLIL::escape_id(tinoutpad_portname_pad))); | ||||
| 
 | ||||
| 		for (auto module : design->modules()) | ||||
| 			if (module->get_blackbox_attribute()) | ||||
|  | @ -180,34 +180,25 @@ struct IopadmapPass : public Pass { | |||
| 
 | ||||
| 		for (auto module : design->selected_modules()) | ||||
| 		{ | ||||
| 			dict<IdString, pool<int>> skip_wires; | ||||
| 			pool<SigBit> skip_wire_bits; | ||||
| 			SigMap sigmap(module); | ||||
| 			dict<Wire *, dict<int, pair<Cell *, IdString>>> rewrite_bits; | ||||
| 
 | ||||
| 			for (auto cell : module->cells()) | ||||
| 			for (auto port : cell->connections()) | ||||
| 				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); | ||||
| 
 | ||||
| 			if (!toutpad_celltype.empty() || !tinoutpad_celltype.empty()) | ||||
| 			{ | ||||
| 				dict<SigBit, pair<IdString, pool<IdString>>> tbuf_bits; | ||||
| 				pool<pair<IdString, IdString>> norewrites; | ||||
| 				SigMap rewrites; | ||||
| 				dict<SigBit, Cell *> tbuf_bits; | ||||
| 
 | ||||
| 				for (auto cell : module->cells()) | ||||
| 					if (cell->type == ID($_TBUF_)) { | ||||
| 						SigBit bit = sigmap(cell->getPort(ID::Y).as_bit()); | ||||
| 						tbuf_bits[bit].first = cell->name; | ||||
| 						SigBit bit = cell->getPort(ID::Y).as_bit(); | ||||
| 						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()) | ||||
| 				{ | ||||
| 					if (!wire->port_output) | ||||
|  | @ -216,16 +207,11 @@ struct IopadmapPass : public Pass { | |||
| 					for (int i = 0; i < GetSize(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; | ||||
| 
 | ||||
| 						if (skip_wire_bits.count(mapped_wire_bit)) | ||||
| 							continue; | ||||
| 
 | ||||
| 						auto &tbuf_cache = tbuf_bits.at(mapped_wire_bit); | ||||
| 						Cell *tbuf_cell = module->cell(tbuf_cache.first); | ||||
| 						Cell *tbuf_cell = tbuf_bits.at(wire_bit); | ||||
| 
 | ||||
| 						if (tbuf_cell == nullptr) | ||||
| 							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()); | ||||
| 
 | ||||
| 							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_portname2), owire); | ||||
| 							cell->setPort(RTLIL::escape_id(tinoutpad_portname3), data_sig); | ||||
| 							cell->setPort(RTLIL::escape_id(tinoutpad_portname4), wire_bit); | ||||
| 							cell->setPort(RTLIL::escape_id(tinoutpad_portname_oe), en_sig); | ||||
| 							cell->setPort(RTLIL::escape_id(tinoutpad_portname_o), wire_bit); | ||||
| 							cell->setPort(RTLIL::escape_id(tinoutpad_portname_i), data_sig); | ||||
| 							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); | ||||
| 							skip_wires[wire->name].insert(i); | ||||
| 
 | ||||
| 							norewrites.insert(make_pair(cell->name, RTLIL::escape_id(tinoutpad_portname4))); | ||||
| 							rewrites.add(sigmap(wire_bit), owire); | ||||
| 							skip_wire_bits.insert(wire_bit); | ||||
| 							if (!tinoutpad_portname_pad.empty()) | ||||
| 								rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(tinoutpad_portname_pad)); | ||||
| 							continue; | ||||
| 						} | ||||
| 
 | ||||
|  | @ -278,50 +243,19 @@ struct IopadmapPass : public Pass { | |||
| 
 | ||||
| 							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_portname2), data_sig); | ||||
| 							cell->setPort(RTLIL::escape_id(toutpad_portname3), wire_bit); | ||||
| 							cell->setPort(RTLIL::escape_id(toutpad_portname_oe), en_sig); | ||||
| 							cell->setPort(RTLIL::escape_id(toutpad_portname_i), data_sig); | ||||
| 							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); | ||||
| 							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; | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				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()) | ||||
|  | @ -329,17 +263,11 @@ struct IopadmapPass : public Pass { | |||
| 				if (!wire->port_id) | ||||
| 					continue; | ||||
| 
 | ||||
| 				std::string celltype, portname, portname2; | ||||
| 				std::string celltype, portname_int, portname_pad; | ||||
| 				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++) | ||||
| 					if (skip_wire_bits.count(sigmap(SigBit(wire, i)))) | ||||
| 					if (skip_wire_bits.count(SigBit(wire, i))) | ||||
| 						skip_bit_indices.insert(i); | ||||
| 
 | ||||
| 				if (GetSize(wire) == GetSize(skip_bit_indices)) | ||||
|  | @ -351,8 +279,8 @@ struct IopadmapPass : public Pass { | |||
| 						continue; | ||||
| 					} | ||||
| 					celltype = inpad_celltype; | ||||
| 					portname = inpad_portname; | ||||
| 					portname2 = inpad_portname2; | ||||
| 					portname_int = inpad_portname_o; | ||||
| 					portname_pad = inpad_portname_pad; | ||||
| 				} else | ||||
| 				if (!wire->port_input && wire->port_output) { | ||||
| 					if (outpad_celltype.empty()) { | ||||
|  | @ -360,8 +288,8 @@ struct IopadmapPass : public Pass { | |||
| 						continue; | ||||
| 					} | ||||
| 					celltype = outpad_celltype; | ||||
| 					portname = outpad_portname; | ||||
| 					portname2 = outpad_portname2; | ||||
| 					portname_int = outpad_portname_i; | ||||
| 					portname_pad = outpad_portname_pad; | ||||
| 				} else | ||||
| 				if (wire->port_input && wire->port_output) { | ||||
| 					if (inoutpad_celltype.empty()) { | ||||
|  | @ -369,8 +297,8 @@ struct IopadmapPass : public Pass { | |||
| 						continue; | ||||
| 					} | ||||
| 					celltype = inoutpad_celltype; | ||||
| 					portname = inoutpad_portname; | ||||
| 					portname2 = inoutpad_portname2; | ||||
| 					portname_int = inoutpad_portname_io; | ||||
| 					portname_pad = inoutpad_portname_pad; | ||||
| 				} else | ||||
| 					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()); | ||||
| 
 | ||||
| 				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) | ||||
| 				{ | ||||
| 					for (int i = 0; i < wire->width; 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)); | ||||
| 						if (skip_bit_indices.count(i)) | ||||
| 							continue; | ||||
| 						} | ||||
| 
 | ||||
| 						SigBit wire_bit(wire, i); | ||||
| 
 | ||||
| 						RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); | ||||
| 						cell->setPort(RTLIL::escape_id(portname), RTLIL::SigSpec(wire, i)); | ||||
| 						if (!portname2.empty()) | ||||
| 							cell->setPort(RTLIL::escape_id(portname2), RTLIL::SigSpec(new_wire, i)); | ||||
| 						cell->setPort(RTLIL::escape_id(portname_int), wire_bit); | ||||
| 
 | ||||
| 						if (!portname_pad.empty()) | ||||
| 							rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(portname_pad)); | ||||
| 						if (!widthparam.empty()) | ||||
| 							cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(1); | ||||
| 						if (!nameparam.empty()) | ||||
|  | @ -414,9 +333,15 @@ struct IopadmapPass : public Pass { | |||
| 				else | ||||
| 				{ | ||||
| 					RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); | ||||
| 					cell->setPort(RTLIL::escape_id(portname), RTLIL::SigSpec(wire)); | ||||
| 					if (!portname2.empty()) | ||||
| 						cell->setPort(RTLIL::escape_id(portname2), RTLIL::SigSpec(new_wire)); | ||||
| 					cell->setPort(RTLIL::escape_id(portname_int), RTLIL::SigSpec(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()) | ||||
| 						cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(wire->width); | ||||
| 					if (!nameparam.empty()) | ||||
|  | @ -424,6 +349,32 @@ struct IopadmapPass : public Pass { | |||
| 					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_input = 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 | ||||
| //value regardless. The parameter is ignored. | ||||
| 
 | ||||
| // 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 | ||||
| // DFF       D Flip-Flop | ||||
| module  \$_DFF_P_ (input D, C, output Q); DFF _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); endmodule | ||||
| // DFFN			 D Flip-Flop with Negative-Edge Clock | ||||
| module	\$_DFF_N_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, output Q); | ||||
| 	generate | ||||
| 		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 | ||||
| module  \$_DFFE_PP_ (input D, C, E, output Q); DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E)); endmodule | ||||
| module  \$_DFFE_PN_ (input D, C, E, output Q); DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(!E)); endmodule | ||||
| // DFF			 D Flip-Flop | ||||
| module	\$_DFF_P_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, output Q); | ||||
| 	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 | ||||
| module  \$_DFFE_NP_ (input D, C, E, output Q); DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E)); endmodule | ||||
| module  \$_DFFE_NN_ (input D, C, E, output Q); DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(!E)); endmodule | ||||
| // DFFE			 D Flip-Flop with Clock Enable | ||||
| module	\$_DFFE_PP_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, E, output Q); | ||||
| 	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  \$__DFFS_PN0_ (input D, C, R, output Q); DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R)); endmodule | ||||
| module  \$__DFFS_PP0_ (input D, C, R, output Q); DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R)); endmodule | ||||
| module	\$_DFFE_PN_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, E, output Q); | ||||
| 	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 | ||||
| 
 | ||||
| // DFFNR     D Flip-Flop with Negative-Edge Clock and Synchronous Reset | ||||
| module  \$__DFFS_NN0_ (input D, C, R, output Q); DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R)); endmodule | ||||
| module  \$__DFFS_NP0_ (input D, C, R, output Q); DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R)); endmodule | ||||
| // DFFNE		 D Flip-Flop with Negative-Edge Clock and Clock Enable | ||||
| module	\$_DFFE_NP_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, E, output Q); | ||||
| 	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  \$__DFFSE_PN0 (input D, C, R, E, output Q); DFFRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R), .CE(E)); endmodule | ||||
| module  \$__DFFSE_PP0 (input D, C, R, E, output Q); DFFRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R), .CE(E)); endmodule | ||||
| module	\$_DFFE_NN_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, E, output Q); | ||||
| 	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 | ||||
| 
 | ||||
| // DFFNRE    D Flip-Flop with Negative-Edge Clock,Clock Enable, and 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  \$__DFFNSE_PP0 (input D, C, R, E, output Q); DFFNRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R), .CE(E)); endmodule | ||||
| // DFFR			 D Flip-Flop with Synchronous Reset | ||||
| module	\$__DFFS_PN0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); | ||||
| 	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_PN1_ (input D, C, R, output Q); DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R)); endmodule | ||||
| module  \$__DFFS_PP1_ (input D, C, R, output Q); DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R)); endmodule | ||||
| module	\$__DFFS_PP0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); | ||||
| 	DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R)); | ||||
| 	wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; | ||||
| endmodule | ||||
| 
 | ||||
| // DFFNS     D Flip-Flop with Negative-Edge Clock and Synchronous Set | ||||
| module  \$__DFFS_NN1_ (input D, C, R, output Q); DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R)); endmodule | ||||
| module  \$__DFFS_NP1_ (input D, C, R, output Q); DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R)); endmodule | ||||
| // DFFNR		 D Flip-Flop with Negative-Edge Clock and Synchronous Reset | ||||
| module	\$__DFFS_NN0_ #(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 | ||||
| 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 | ||||
| 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_PP1 (input D, C, R, E, output Q); DFFSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R), .CE(E)); endmodule | ||||
| // DFFRE		 D Flip-Flop with Clock Enable and Synchronous Reset | ||||
| module	\$__DFFSE_PN0 #(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 | ||||
| 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 | ||||
| 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_NP1 (input D, C, R, E, output Q); DFFNSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R), .CE(E)); endmodule | ||||
| // DFFNRE		 D Flip-Flop with Negative-Edge Clock,Clock Enable, and Synchronous Reset | ||||
| module	\$__DFFSE_NN0 #(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 | ||||
| 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 | ||||
| module  \$_DFF_PP1_ (input D, C, R, output Q); DFFP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R)); endmodule | ||||
| module  \$_DFF_PN1_ (input D, C, R, output Q); DFFP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R)); endmodule | ||||
| // DFFS			 D Flip-Flop with Synchronous Set | ||||
| module	\$__DFFS_PN1_ #(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 | ||||
| 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 | ||||
| module  \$_DFF_NP1_ (input D, C, R, output Q); DFFNP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R)); endmodule | ||||
| module  \$_DFF_NN1_ (input D, C, R, output Q); DFFNP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R)); endmodule | ||||
| // DFFNS		 D Flip-Flop with Negative-Edge Clock and Synchronous Set | ||||
| module	\$__DFFS_NN1_ #(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 | ||||
| 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 | ||||
| module  \$_DFF_PP0_ (input D, C, R, output Q); DFFC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R)); endmodule | ||||
| module  \$_DFF_PN0_ (input D, C, R, output Q); DFFC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R)); endmodule | ||||
| // DFFSE		 D Flip-Flop with Clock Enable and Synchronous Set | ||||
| module	\$__DFFSE_PN1 #(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 | ||||
| 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 | ||||
| module  \$_DFF_NP0_ (input D, C, R, output Q); DFFNC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R)); endmodule | ||||
| module  \$_DFF_NN0_ (input D, C, R, output Q); DFFNC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R)); endmodule | ||||
| // DFFNSE		 D Flip-Flop with Negative-Edge Clock,Clock Enable,and Synchronous Set | ||||
| module	\$__DFFSE_NN1 #(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 | ||||
| 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 | ||||
| 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  \$__DFFE_PN1 (input D, C, R, E, output Q); DFFPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R), .CE(E)); endmodule | ||||
| // DFFP			 D Flip-Flop with Asynchronous Preset | ||||
| module	\$_DFF_PP1_ #(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 | ||||
| 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 | ||||
| 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  \$__DFFE_NN1 (input D, C, R, E, output Q); DFFNPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R), .CE(E)); endmodule | ||||
| // DFFNP		 D Flip-Flop with Negative-Edge Clock and Asynchronous Preset | ||||
| module	\$_DFF_NP1_ #(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 | ||||
| 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 | ||||
| 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  \$__DFFE_PN0 (input D, C, R, E, output Q); DFFCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R), .CE(E)); endmodule | ||||
| // DFFC			 D Flip-Flop with Asynchronous Clear | ||||
| module	\$_DFF_PP0_ #(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 | ||||
| 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 | ||||
| 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  \$__DFFE_NN0 (input D, C, R, E, output Q); DFFNCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R), .CE(E)); endmodule | ||||
| // DFFNC		 D Flip-Flop with Negative-Edge Clock and Asynchronous Clear | ||||
| module	\$_DFF_NP0_ #(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 | ||||
| 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); | ||||
|   parameter WIDTH = 0; | ||||
|   parameter LUT = 0; | ||||
| 	parameter WIDTH = 0; | ||||
| 	parameter LUT = 0; | ||||
| 
 | ||||
|   input [WIDTH-1:0] A; | ||||
|   output Y; | ||||
| 	input [WIDTH-1:0] A; | ||||
| 	output Y; | ||||
| 
 | ||||
|   generate | ||||
|     if (WIDTH == 1) begin | ||||
|       LUT1 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.F(Y), | ||||
|         .I0(A[0])); | ||||
|     end else | ||||
|     if (WIDTH == 2) begin | ||||
|       LUT2 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.F(Y), | ||||
|         .I0(A[0]), .I1(A[1])); | ||||
|     end else | ||||
|     if (WIDTH == 3) begin | ||||
|       LUT3 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.F(Y), | ||||
|         .I0(A[0]), .I1(A[1]), .I2(A[2])); | ||||
|     end else | ||||
|     if (WIDTH == 4) begin | ||||
|       LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.F(Y), | ||||
|         .I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(A[3])); | ||||
|     end else | ||||
|     if (WIDTH == 5) begin | ||||
|       wire f0, f1; | ||||
|       \$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)); | ||||
|       MUX2_LUT5 mux5(.I0(f0), .I1(f1), .S0(A[4]), .O(Y)); | ||||
|     end else | ||||
|     if (WIDTH == 6) begin | ||||
|       wire f0, f1; | ||||
|       \$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)); | ||||
|       MUX2_LUT6 mux6(.I0(f0), .I1(f1), .S0(A[5]), .O(Y)); | ||||
|     end else | ||||
|     if (WIDTH == 7) begin | ||||
|       wire f0, f1; | ||||
|       \$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)); | ||||
|       MUX2_LUT7 mux7(.I0(f0), .I1(f1), .S0(A[6]), .O(Y)); | ||||
|     end else | ||||
|     if (WIDTH == 8) begin | ||||
|       wire f0, f1; | ||||
|       \$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)); | ||||
|       MUX2_LUT8 mux8(.I0(f0), .I1(f1), .S0(A[7]), .O(Y)); | ||||
|     end else begin | ||||
|       wire _TECHMAP_FAIL_ = 1; | ||||
|     end | ||||
|   endgenerate | ||||
| 	generate | ||||
| 		if (WIDTH == 1) begin | ||||
| 			LUT1 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.F(Y), | ||||
| 				.I0(A[0])); | ||||
| 		end else | ||||
| 		if (WIDTH == 2) begin | ||||
| 			LUT2 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.F(Y), | ||||
| 				.I0(A[0]), .I1(A[1])); | ||||
| 		end else | ||||
| 		if (WIDTH == 3) begin | ||||
| 			LUT3 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.F(Y), | ||||
| 				.I0(A[0]), .I1(A[1]), .I2(A[2])); | ||||
| 		end else | ||||
| 		if (WIDTH == 4) begin | ||||
| 			LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.F(Y), | ||||
| 				.I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(A[3])); | ||||
| 		end else | ||||
| 		if (WIDTH == 5) begin | ||||
| 			wire f0, f1; | ||||
| 			\$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)); | ||||
| 			MUX2_LUT5 mux5(.I0(f0), .I1(f1), .S0(A[4]), .O(Y)); | ||||
| 		end else | ||||
| 		if (WIDTH == 6) begin | ||||
| 			wire f0, f1; | ||||
| 			\$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)); | ||||
| 			MUX2_LUT6 mux6(.I0(f0), .I1(f1), .S0(A[5]), .O(Y)); | ||||
| 		end else | ||||
| 		if (WIDTH == 7) begin | ||||
| 			wire f0, f1; | ||||
| 			\$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)); | ||||
| 			MUX2_LUT7 mux7(.I0(f0), .I1(f1), .S0(A[6]), .O(Y)); | ||||
| 		end else | ||||
| 		if (WIDTH == 8) begin | ||||
| 			wire f0, f1; | ||||
| 			\$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)); | ||||
| 			MUX2_LUT8 mux8(.I0(f0), .I1(f1), .S0(A[7]), .O(Y)); | ||||
| 		end else begin | ||||
| 			wire _TECHMAP_FAIL_ = 1; | ||||
| 		end | ||||
| 	endgenerate | ||||
| endmodule | ||||
|  |  | |||
|  | @ -67,6 +67,9 @@ struct SynthGowinPass : public ScriptPass | |||
| 		log("    -nowidelut\n"); | ||||
| 		log("        do not use muxes to implement LUTs larger than LUT4s\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -noiopads\n"); | ||||
| 		log("        do not emit IOB at top level ports\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -abc9\n"); | ||||
| 		log("        use new ABC9 flow (EXPERIMENTAL)\n"); | ||||
| 		log("\n"); | ||||
|  | @ -77,7 +80,7 @@ struct SynthGowinPass : public ScriptPass | |||
| 	} | ||||
| 
 | ||||
| 	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 | ||||
| 	{ | ||||
|  | @ -90,6 +93,7 @@ struct SynthGowinPass : public ScriptPass | |||
| 		nodram = false; | ||||
| 		nowidelut = false; | ||||
| 		abc9 = false; | ||||
| 		noiopads = false; | ||||
| 	} | ||||
| 
 | ||||
| 	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE | ||||
|  | @ -144,6 +148,10 @@ struct SynthGowinPass : public ScriptPass | |||
| 				abc9 = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (args[argidx] == "-noiopads") { | ||||
| 				noiopads = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
| 		extra_args(args, argidx, design); | ||||
|  | @ -208,7 +216,7 @@ struct SynthGowinPass : public ScriptPass | |||
| 		if (check_label("map_ffs")) | ||||
| 		{ | ||||
| 			run("dffsr2dff"); | ||||
| 			run("dff2dffs"); | ||||
| 			run("dff2dffs -match-init"); | ||||
| 			run("opt_clean"); | ||||
| 			if (!nodffe) | ||||
| 				run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*"); | ||||
|  | @ -236,8 +244,9 @@ struct SynthGowinPass : public ScriptPass | |||
| 			run("techmap -map +/gowin/cells_map.v"); | ||||
| 			run("setundef -undriven -params -zero"); | ||||
| 			run("hilomap -singleton -hicell VCC V -locell GND G"); | ||||
| 			run("iopadmap -bits -inpad IBUF O:I -outpad OBUF I:O " | ||||
| 				"-toutpad TBUF OEN:I:O -tinoutpad IOBUF OEN:O:I:IO", "(unless -noiopads)"); | ||||
| 			if (!noiopads || help_mode) | ||||
| 				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"); | ||||
| 
 | ||||
| 		} | ||||
|  |  | |||
|  | @ -363,3 +363,11 @@ module \$__XILINX_MUXF78 (O, I0, I1, I2, I3, S0, S1); | |||
|   else | ||||
|     MUXF8 mux8 (.I0(T0), .I1(T1), .S(S1), .O(O)); | ||||
| 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; | ||||
| 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 ( | ||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 | ||||
|   (* abc9_arrival=1153 *) | ||||
|  | @ -502,6 +969,29 @@ module RAM32X1D ( | |||
|   always @(posedge clk) if (WE) mem[a] <= D; | ||||
| 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 ( | ||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 | ||||
|   (* abc9_arrival=1153 *) | ||||
|  | @ -525,6 +1015,29 @@ module RAM64X1D ( | |||
|   always @(posedge clk) if (WE) mem[a] <= D; | ||||
| 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 ( | ||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 | ||||
|   (* abc9_arrival=1153 *) | ||||
|  | @ -545,6 +1058,290 @@ module RAM128X1D ( | |||
|   always @(posedge clk) if (WE) mem[A] <= D; | ||||
| 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 ( | ||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905 | ||||
|   (* abc9_arrival=1472 *) | ||||
|  |  | |||
|  | @ -28,40 +28,40 @@ CELLS = [ | |||
|     # - UG974 (Ultrascale) | ||||
| 
 | ||||
|     # CLB -- RAM/ROM. | ||||
|     Cell('RAM16X1S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM16X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM32X1S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM32X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM64X1S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM64X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM128X1S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM128X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM256X1S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM512X1S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM16X2S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM32X2S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM64X2S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM16X4S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM32X4S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM16X8S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM32X8S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM16X1D', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM16X1D_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     #Cell('RAM32X1D', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM32X1D_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     #Cell('RAM64X1D', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM64X1D_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     #Cell('RAM128X1D', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM256X1D', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM32M', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM32M16', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM64M', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('RAM64M8', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     Cell('ROM16X1'), | ||||
|     Cell('ROM32X1'), | ||||
|     Cell('ROM64X1'), | ||||
|     Cell('ROM128X1'), | ||||
|     Cell('ROM256X1'), | ||||
|     # Cell('RAM16X1S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM16X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM32X1S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM32X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM64X1S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM64X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM128X1S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM128X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM256X1S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM512X1S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM16X2S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM32X2S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM64X2S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM16X4S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM32X4S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM16X8S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM32X8S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM16X1D', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM16X1D_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM32X1D', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM32X1D_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM64X1D', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM64X1D_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM128X1D', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM256X1D', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM32M', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM32M16', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM64M', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('RAM64M8', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||
|     # Cell('ROM16X1'), | ||||
|     # Cell('ROM32X1'), | ||||
|     # Cell('ROM64X1'), | ||||
|     # Cell('ROM128X1'), | ||||
|     # Cell('ROM256X1'), | ||||
| 
 | ||||
|     # CLB -- registers/latches. | ||||
|     # Virtex 1/2/4/5, Spartan 3. | ||||
|  | @ -372,6 +372,7 @@ CELLS = [ | |||
|     Cell('BUFIO2', 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('BUFPLL', port_attrs={'IOCLK': ['clkbuf_driver']}), | ||||
|     Cell('BUFPLL_MCB', port_attrs={'IOCLK0': ['clkbuf_driver'], 'IOCLK1': ['clkbuf_driver']}), | ||||
| 
 | ||||
|     # Clock buffers (IO and regional) -- Virtex. | ||||
|  |  | |||
|  | @ -1,595 +1,5 @@ | |||
| // 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 (...); | ||||
|     parameter [0:0] INIT = 1'b0; | ||||
|     parameter [0:0] IS_C_INVERTED = 1'b0; | ||||
|  | @ -5240,9 +4650,13 @@ module RAMB18E1 (...); | |||
|     parameter IS_RSTRAMB_INVERTED = 1'b0; | ||||
|     parameter IS_RSTREGARSTREG_INVERTED = 1'b0; | ||||
|     parameter IS_RSTREGB_INVERTED = 1'b0; | ||||
|     (* abc9_arrival=2454 *) | ||||
|     output [15:0] DOADO; | ||||
|     (* abc9_arrival=2454 *) | ||||
|     output [15:0] DOBDO; | ||||
|     (* abc9_arrival=2454 *) | ||||
|     output [1:0] DOPADOP; | ||||
|     (* abc9_arrival=2454 *) | ||||
|     output [1:0] DOPBDOP; | ||||
|     (* clkbuf_sink *) | ||||
|     (* invertible_pin = "IS_CLKARDCLK_INVERTED" *) | ||||
|  | @ -5452,9 +4866,13 @@ module RAMB36E1 (...); | |||
|     parameter IS_RSTREGB_INVERTED = 1'b0; | ||||
|     output CASCADEOUTA; | ||||
|     output CASCADEOUTB; | ||||
|     (* abc9_arrival=2454 *) | ||||
|     output [31:0] DOADO; | ||||
|     (* abc9_arrival=2454 *) | ||||
|     output [31:0] DOBDO; | ||||
|     (* abc9_arrival=2454 *) | ||||
|     output [3:0] DOPADOP; | ||||
|     (* abc9_arrival=2454 *) | ||||
|     output [3:0] DOPBDOP; | ||||
|     output [7:0] ECCPARITY; | ||||
|     output [8:0] RDADDRECC; | ||||
|  | @ -8527,6 +7945,18 @@ module BUFIO2FB (...); | |||
|     input I; | ||||
| 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 (...); | ||||
|     parameter integer DIVIDE = 2; | ||||
|     parameter LOCK_SRC = "LOCK_TO_0"; | ||||
|  |  | |||
|  | @ -282,6 +282,7 @@ struct SynthXilinxPass : public ScriptPass | |||
| 
 | ||||
| 	void script() YS_OVERRIDE | ||||
| 	{ | ||||
| 		bool do_iopad = iopad || (ise && !noiopad); | ||||
| 		std::string ff_map_file; | ||||
| 		if (help_mode) | ||||
| 			ff_map_file = "+/xilinx/{family}_ff_map.v"; | ||||
|  | @ -306,6 +307,8 @@ struct SynthXilinxPass : public ScriptPass | |||
| 			run("proc"); | ||||
| 			if (flatten || help_mode) | ||||
| 				run("flatten", "(with '-flatten')"); | ||||
| 			run("tribuf -logic"); | ||||
| 			run("deminout"); | ||||
| 			run("opt_expr"); | ||||
| 			run("opt_clean"); | ||||
| 			run("check"); | ||||
|  | @ -504,6 +507,9 @@ struct SynthXilinxPass : public ScriptPass | |||
| 		} | ||||
| 
 | ||||
| 		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"; | ||||
| 			if (widemux > 0) | ||||
| 				techmap_args += stringf(" -D MIN_MUX_INPUTS=%d", widemux); | ||||
|  | @ -560,15 +566,8 @@ struct SynthXilinxPass : public ScriptPass | |||
| 		} | ||||
| 
 | ||||
| 		if (check_label("finalize")) { | ||||
| 			bool do_iopad = iopad || (ise && !noiopad); | ||||
| 			if (help_mode || !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 || !noclkbuf) | ||||
| 				run("clkbufmap -buf BUFG O:I ", "(skip if '-noclkbuf')"); | ||||
| 			if (help_mode || ise) | ||||
| 				run("extractinv -inv INV O:I", "(only if '-ise')"); | ||||
| 			run("clean"); | ||||
|  |  | |||
|  | @ -34,11 +34,12 @@ proc | |||
| 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) | ||||
| 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 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 | ||||
|  |  | |||
							
								
								
									
										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 | ||||
| vvp -N ./test_macc | ||||
|  |  | |||
|  | @ -259,29 +259,35 @@ assign o = { 1'b1, 1'bx }; | |||
| assign p = { 1'b1, 1'bx, 1'b0 }; | ||||
| 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 @(negedge clk2) q2 <= q1; | ||||
| 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) | ||||
|     if (r) q <= 1'b0; | ||||
|     else q <= d; | ||||
| 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) | ||||
|     if (r) q <= 1'b1; | ||||
|     else q <= d; | ||||
| 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) q2 <= q1; | ||||
| 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 @(negedge clk) q[1] <= q[0]; | ||||
| 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