mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-30 19:22:31 +00:00 
			
		
		
		
	Merge remote-tracking branch 'origin/master' into xaig_arrival
This commit is contained in:
		
						commit
						d672b1ddec
					
				
					 28 changed files with 1110 additions and 114 deletions
				
			
		
							
								
								
									
										1
									
								
								Brewfile
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								Brewfile
									
										
									
									
									
								
							|  | @ -6,3 +6,4 @@ brew "git" | |||
| brew "graphviz" | ||||
| brew "pkg-config" | ||||
| brew "python3" | ||||
| brew "tcl-tk" | ||||
|  |  | |||
							
								
								
									
										2
									
								
								COPYING
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								COPYING
									
										
									
									
									
								
							|  | @ -1,4 +1,4 @@ | |||
| Copyright (C) 2012 - 2018  Clifford Wolf <clifford@clifford.at> | ||||
| Copyright (C) 2012 - 2019  Clifford Wolf <clifford@clifford.at> | ||||
| 
 | ||||
| Permission to use, copy, modify, and/or distribute this software for any | ||||
| purpose with or without fee is hereby granted, provided that the above | ||||
|  |  | |||
							
								
								
									
										2
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
										
									
									
									
								
							|  | @ -91,8 +91,10 @@ PLUGIN_LDFLAGS += -undefined dynamic_lookup | |||
| ifneq ($(shell which brew),) | ||||
| BREW_PREFIX := $(shell brew --prefix)/opt | ||||
| $(info $$BREW_PREFIX is [${BREW_PREFIX}]) | ||||
| ifeq ($(ENABLE_PYOSYS),1) | ||||
| CXXFLAGS += -I$(BREW_PREFIX)/boost/include/boost | ||||
| LDFLAGS += -L$(BREW_PREFIX)/boost/lib | ||||
| endif | ||||
| CXXFLAGS += -I$(BREW_PREFIX)/readline/include | ||||
| LDFLAGS += -L$(BREW_PREFIX)/readline/lib | ||||
| PKG_CONFIG_PATH := $(BREW_PREFIX)/libffi/lib/pkgconfig:$(PKG_CONFIG_PATH) | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| ``` | ||||
| yosys -- Yosys Open SYnthesis Suite | ||||
| 
 | ||||
| Copyright (C) 2012 - 2018  Clifford Wolf <clifford@clifford.at> | ||||
| Copyright (C) 2012 - 2019  Clifford Wolf <clifford@clifford.at> | ||||
| 
 | ||||
| Permission to use, copy, modify, and/or distribute this software for any | ||||
| purpose with or without fee is hereby granted, provided that the above | ||||
|  | @ -69,11 +69,14 @@ prerequisites for building yosys: | |||
| 		graphviz xdot pkg-config python3 libboost-system-dev \ | ||||
| 		libboost-python-dev libboost-filesystem-dev zlib1g-dev | ||||
| 
 | ||||
| Similarily, on Mac OS X MacPorts or Homebrew can be used to install dependencies: | ||||
| Similarily, on Mac OS X Homebrew can be used to install dependencies: | ||||
| 
 | ||||
| 	$ brew tap Homebrew/bundle && brew bundle | ||||
| 
 | ||||
| or MacPorts: | ||||
| 
 | ||||
| 	$ sudo port install bison flex readline gawk libffi \ | ||||
| 		git graphviz pkgconfig python36 boost zlib | ||||
| 		git graphviz pkgconfig python36 boost zlib tcl | ||||
| 
 | ||||
| On FreeBSD use the following command to install all prerequisites: | ||||
| 
 | ||||
|  |  | |||
|  | @ -150,6 +150,11 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 					reg->str = stringf("%s[%d]", node->str.c_str(), i); | ||||
| 					reg->is_reg = true; | ||||
| 					reg->is_signed = node->is_signed; | ||||
| 					for (auto &it : node->attributes) | ||||
| 						if (it.first != ID(mem2reg)) | ||||
| 							reg->attributes.emplace(it.first, it.second->clone()); | ||||
| 					reg->filename = node->filename; | ||||
| 					reg->linenum = node->linenum; | ||||
| 					children.push_back(reg); | ||||
| 					while (reg->simplify(true, false, false, 1, -1, false, false)) { } | ||||
| 				} | ||||
|  |  | |||
|  | @ -129,7 +129,7 @@ void yosys_banner() | |||
| 	log(" |                                                                            |\n"); | ||||
| 	log(" |  yosys -- Yosys Open SYnthesis Suite                                       |\n"); | ||||
| 	log(" |                                                                            |\n"); | ||||
| 	log(" |  Copyright (C) 2012 - 2018  Clifford Wolf <clifford@clifford.at>           |\n"); | ||||
| 	log(" |  Copyright (C) 2012 - 2019  Clifford Wolf <clifford@clifford.at>           |\n"); | ||||
| 	log(" |                                                                            |\n"); | ||||
| 	log(" |  Permission to use, copy, modify, and/or distribute this software for any  |\n"); | ||||
| 	log(" |  purpose with or without fee is hereby granted, provided that the above    |\n"); | ||||
|  |  | |||
|  | @ -532,10 +532,10 @@ struct EquivMakePass : public Pass { | |||
| 			log_cmd_error("Equiv module %s already exists.\n", args[argidx+2].c_str()); | ||||
| 
 | ||||
| 		if (worker.gold_mod->has_memories() || worker.gold_mod->has_processes()) | ||||
| 			log_cmd_error("Gold module contains memories or procresses. Run 'memory' or 'proc' respectively.\n"); | ||||
| 			log_cmd_error("Gold module contains memories or processes. Run 'memory' or 'proc' respectively.\n"); | ||||
| 
 | ||||
| 		if (worker.gate_mod->has_memories() || worker.gate_mod->has_processes()) | ||||
| 			log_cmd_error("Gate module contains memories or procresses. Run 'memory' or 'proc' respectively.\n"); | ||||
| 			log_cmd_error("Gate module contains memories or processes. Run 'memory' or 'proc' respectively.\n"); | ||||
| 
 | ||||
| 		worker.read_blacklists(); | ||||
| 		worker.read_encfiles(); | ||||
|  |  | |||
|  | @ -369,7 +369,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | |||
| 	for (auto cell : module->cells()) | ||||
| 		if (design->selected(module, cell) && cell->type[0] == '$') { | ||||
| 			if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && | ||||
| 					cell->getPort(ID::A).size() == 1 && cell->getPort(ID::Y).size() == 1) | ||||
| 					GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::Y)) == 1) | ||||
| 				invert_map[assign_map(cell->getPort(ID::Y))] = assign_map(cell->getPort(ID::A)); | ||||
| 			if (cell->type.in(ID($mux), ID($_MUX_)) && | ||||
| 					cell->getPort(ID::A) == SigSpec(State::S1) && cell->getPort(ID::B) == SigSpec(State::S0)) | ||||
|  | @ -740,12 +740,34 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | |||
| 				if (cell->type.in(ID($reduce_xor), ID($reduce_xnor), ID($lt), ID($le), ID($ge), ID($gt))) | ||||
| 					replace_cell(assign_map, module, cell, "x-bit in input", ID::Y, RTLIL::State::Sx); | ||||
| 				else | ||||
| 					replace_cell(assign_map, module, cell, "x-bit in input", ID::Y, RTLIL::SigSpec(RTLIL::State::Sx, cell->getPort(ID::Y).size())); | ||||
| 					replace_cell(assign_map, module, cell, "x-bit in input", ID::Y, RTLIL::SigSpec(RTLIL::State::Sx, GetSize(cell->getPort(ID::Y)))); | ||||
| 				goto next_cell; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && cell->getPort(ID::Y).size() == 1 && | ||||
| 		if (cell->type.in(ID($shiftx), ID($shift))) { | ||||
| 			SigSpec sig_a = assign_map(cell->getPort(ID::A)); | ||||
| 			int width; | ||||
| 			bool trim_x = cell->type == ID($shiftx) || !keepdc; | ||||
| 			bool trim_0 = cell->type == ID($shift); | ||||
| 			for (width = GetSize(sig_a); width > 1; width--) { | ||||
| 				if ((trim_x && sig_a[width-1] == State::Sx) || | ||||
| 					(trim_0 && sig_a[width-1] == State::S0)) | ||||
| 					continue; | ||||
| 				break; | ||||
| 			} | ||||
| 
 | ||||
| 			if (width < GetSize(sig_a)) { | ||||
| 				cover_list("opt.opt_expr.trim", "$shiftx", "$shift", cell->type.str()); | ||||
| 				sig_a.remove(width, GetSize(sig_a)-width); | ||||
| 				cell->setPort(ID::A, sig_a); | ||||
| 				cell->setParam(ID(A_WIDTH), width); | ||||
| 				did_something = true; | ||||
| 				goto next_cell; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && GetSize(cell->getPort(ID::Y)) == 1 && | ||||
| 				invert_map.count(assign_map(cell->getPort(ID::A))) != 0) { | ||||
| 			cover_list("opt.opt_expr.invert.double", "$_NOT_", "$not", "$logic_not", cell->type.str()); | ||||
| 			replace_cell(assign_map, module, cell, "double_invert", ID::Y, invert_map.at(assign_map(cell->getPort(ID::A)))); | ||||
|  | @ -1142,7 +1164,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | |||
| 
 | ||||
| 		if (mux_undef && cell->type.in(ID($mux), ID($pmux))) { | ||||
| 			RTLIL::SigSpec new_a, new_b, new_s; | ||||
| 			int width = cell->getPort(ID::A).size(); | ||||
| 			int width = GetSize(cell->getPort(ID::A)); | ||||
| 			if ((cell->getPort(ID::A).is_fully_undef() && cell->getPort(ID::B).is_fully_undef()) || | ||||
| 					cell->getPort(ID(S)).is_fully_undef()) { | ||||
| 				cover_list("opt.opt_expr.mux_undef", "$mux", "$pmux", cell->type.str()); | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
| # --------------------------------------
 | ||||
| 
 | ||||
| OBJS += passes/pmgen/test_pmgen.o | ||||
| passes/pmgen/test_pmgen.o: passes/pmgen/test_pmgen_pm.h | ||||
| passes/pmgen/test_pmgen.o: passes/pmgen/test_pmgen_pm.h passes/pmgen/ice40_dsp_pm.h passes/pmgen/peepopt_pm.h | ||||
| $(eval $(call add_extra_objs,passes/pmgen/test_pmgen_pm.h)) | ||||
| 
 | ||||
| # --------------------------------------
 | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| 
 | ||||
| OBJS += techlibs/anlogic/synth_anlogic.o | ||||
| OBJS += techlibs/anlogic/anlogic_eqn.o | ||||
| OBJS += techlibs/anlogic/anlogic_determine_init.o | ||||
| OBJS += techlibs/anlogic/anlogic_fixcarry.o | ||||
| 
 | ||||
| $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/cells_map.v)) | ||||
| $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/arith_map.v)) | ||||
|  |  | |||
|  | @ -1,72 +0,0 @@ | |||
| /*
 | ||||
|  *  yosys -- Yosys Open SYnthesis Suite | ||||
|  * | ||||
|  *  Copyright (C) 2018 Icenowy Zheng <icenowy@aosc.io> | ||||
|  * | ||||
|  *  Permission to use, copy, modify, and/or distribute this software for any | ||||
|  *  purpose with or without fee is hereby granted, provided that the above | ||||
|  *  copyright notice and this permission notice appear in all copies. | ||||
|  * | ||||
|  *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||||
|  *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||||
|  *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||||
|  *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||
|  *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||||
|  *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||||
|  *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| #include "kernel/yosys.h" | ||||
| #include "kernel/sigtools.h" | ||||
| 
 | ||||
| USING_YOSYS_NAMESPACE | ||||
| PRIVATE_NAMESPACE_BEGIN | ||||
| 
 | ||||
| struct AnlogicDetermineInitPass : public Pass { | ||||
| 	AnlogicDetermineInitPass() : Pass("anlogic_determine_init", "Anlogic: Determine the init value of cells") { } | ||||
| 	void help() YS_OVERRIDE | ||||
| 	{ | ||||
| 		log("\n"); | ||||
| 		log("    anlogic_determine_init [selection]\n"); | ||||
| 		log("\n"); | ||||
| 		log("Determine the init value of cells that doesn't allow unknown init value.\n"); | ||||
| 		log("\n"); | ||||
| 	} | ||||
| 
 | ||||
| 	Const determine_init(Const init) | ||||
| 	{ | ||||
| 		for (int i = 0; i < GetSize(init); i++) { | ||||
| 			if (init[i] != State::S0 && init[i] != State::S1) | ||||
| 				init[i] = State::S0; | ||||
| 		} | ||||
| 
 | ||||
| 		return init; | ||||
| 	} | ||||
| 
 | ||||
| 	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE | ||||
| 	{ | ||||
| 		log_header(design, "Executing ANLOGIC_DETERMINE_INIT pass (determine init value for cells).\n"); | ||||
| 
 | ||||
| 		extra_args(args, args.size(), design); | ||||
| 
 | ||||
| 		int cnt = 0; | ||||
| 		for (auto module : design->selected_modules()) | ||||
| 		{ | ||||
| 			for (auto cell : module->selected_cells()) | ||||
| 			{ | ||||
| 				if (cell->type == "\\EG_LOGIC_DRAM16X4") | ||||
| 				{ | ||||
| 					cell->setParam("\\INIT_D0", determine_init(cell->getParam("\\INIT_D0"))); | ||||
| 					cell->setParam("\\INIT_D1", determine_init(cell->getParam("\\INIT_D1"))); | ||||
| 					cell->setParam("\\INIT_D2", determine_init(cell->getParam("\\INIT_D2"))); | ||||
| 					cell->setParam("\\INIT_D3", determine_init(cell->getParam("\\INIT_D3"))); | ||||
| 					cnt++; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		log_header(design, "Updated %d cells with determined init value.\n", cnt); | ||||
| 	} | ||||
| } AnlogicDetermineInitPass; | ||||
| 
 | ||||
| PRIVATE_NAMESPACE_END | ||||
							
								
								
									
										130
									
								
								techlibs/anlogic/anlogic_fixcarry.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								techlibs/anlogic/anlogic_fixcarry.cc
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,130 @@ | |||
| /*
 | ||||
|  *  yosys -- Yosys Open SYnthesis Suite | ||||
|  * | ||||
|  *  Copyright (C) 2019  Miodrag Milanovic <miodrag@symbioticeda.com> | ||||
|  * | ||||
|  *  Permission to use, copy, modify, and/or distribute this software for any | ||||
|  *  purpose with or without fee is hereby granted, provided that the above | ||||
|  *  copyright notice and this permission notice appear in all copies. | ||||
|  * | ||||
|  *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||||
|  *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||||
|  *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||||
|  *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||
|  *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||||
|  *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||||
|  *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| #include "kernel/yosys.h" | ||||
| #include "kernel/sigtools.h" | ||||
| 
 | ||||
| USING_YOSYS_NAMESPACE | ||||
| PRIVATE_NAMESPACE_BEGIN | ||||
| 
 | ||||
| static SigBit get_bit_or_zero(const SigSpec &sig) | ||||
| { | ||||
| 	if (GetSize(sig) == 0) | ||||
| 		return State::S0; | ||||
| 	return sig[0]; | ||||
| } | ||||
| 
 | ||||
| static void fix_carry_chain(Module *module) | ||||
| { | ||||
| 	SigMap sigmap(module); | ||||
| 
 | ||||
| 	pool<SigBit> ci_bits; | ||||
| 	dict<SigBit, SigBit> mapping_bits; | ||||
| 
 | ||||
| 	for (auto cell : module->cells()) | ||||
| 	{ | ||||
| 		if (cell->type == "\\AL_MAP_ADDER") { | ||||
| 			if (cell->getParam("\\ALUTYPE") != Const("ADD")) continue; | ||||
| 			SigBit bit_i0 = get_bit_or_zero(cell->getPort("\\a")); | ||||
| 			SigBit bit_i1 = get_bit_or_zero(cell->getPort("\\b")); | ||||
| 			if (bit_i0 == State::S0 && bit_i1== State::S0) { | ||||
| 				SigBit bit_ci = get_bit_or_zero(cell->getPort("\\c")); | ||||
| 				SigSpec o = cell->getPort("\\o"); | ||||
| 				if (GetSize(o) == 2) { | ||||
| 					SigBit bit_o = o[0]; | ||||
| 					ci_bits.insert(bit_ci);				 | ||||
| 					mapping_bits[bit_ci] = bit_o;				 | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	vector<Cell*> adders_to_fix_cells; | ||||
| 	for (auto cell : module->cells()) | ||||
| 	{ | ||||
| 		if (cell->type == "\\AL_MAP_ADDER") { | ||||
| 			if (cell->getParam("\\ALUTYPE") != Const("ADD")) continue; | ||||
| 			SigBit bit_ci = get_bit_or_zero(cell->getPort("\\c")); | ||||
| 			SigBit bit_i0 = get_bit_or_zero(cell->getPort("\\a")); | ||||
| 			SigBit bit_i1 = get_bit_or_zero(cell->getPort("\\b"));			 | ||||
| 			SigBit canonical_bit = sigmap(bit_ci); | ||||
| 			if (!ci_bits.count(canonical_bit)) | ||||
| 				continue;			 | ||||
| 			if (bit_i0 == State::S0 && bit_i1== State::S0)  | ||||
| 				continue; | ||||
| 
 | ||||
| 			adders_to_fix_cells.push_back(cell); | ||||
| 			log("Found %s cell named %s with invalid 'c' signal.\n", log_id(cell->type), log_id(cell)); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	for (auto cell : adders_to_fix_cells) | ||||
| 	{ | ||||
| 		SigBit bit_ci = get_bit_or_zero(cell->getPort("\\c")); | ||||
| 		SigBit canonical_bit = sigmap(bit_ci); | ||||
| 		auto bit = mapping_bits.at(canonical_bit); | ||||
| 		log("Fixing %s cell named %s breaking carry chain.\n", log_id(cell->type), log_id(cell)); | ||||
| 		Cell *c = module->addCell(NEW_ID, "\\AL_MAP_ADDER"); | ||||
| 		SigBit new_bit = module->addWire(NEW_ID); | ||||
| 		SigBit dummy_bit = module->addWire(NEW_ID); | ||||
| 		SigSpec bits; | ||||
| 		bits.append(dummy_bit); | ||||
| 		bits.append(new_bit); | ||||
| 		c->setParam("\\ALUTYPE", Const("ADD_CARRY")); | ||||
| 		c->setPort("\\a", bit); | ||||
| 		c->setPort("\\b", State::S0); | ||||
| 		c->setPort("\\c", State::S0); | ||||
| 		c->setPort("\\o", bits); | ||||
| 		 | ||||
| 		cell->setPort("\\c", new_bit); | ||||
| 	} | ||||
| 	 | ||||
| } | ||||
| 
 | ||||
| struct AnlogicCarryFixPass : public Pass { | ||||
| 	AnlogicCarryFixPass() : Pass("anlogic_fixcarry", "Anlogic: fix carry chain") { } | ||||
| 	void help() YS_OVERRIDE | ||||
| 	{ | ||||
| 		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 | ||||
| 		log("\n"); | ||||
| 		log("    anlogic_fixcarry [options] [selection]\n"); | ||||
| 		log("\n"); | ||||
| 		log("Add Anlogic adders to fix carry chain if needed.\n"); | ||||
| 		log("\n"); | ||||
| 	} | ||||
| 	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE | ||||
| 	{ | ||||
| 		log_header(design, "Executing anlogic_fixcarry pass (fix invalid carry chain).\n"); | ||||
| 		 | ||||
| 		size_t argidx; | ||||
| 		for (argidx = 1; argidx < args.size(); argidx++) | ||||
| 		{ | ||||
| 			break; | ||||
| 		} | ||||
| 		extra_args(args, argidx, design); | ||||
| 
 | ||||
| 		Module *module = design->top_module(); | ||||
| 
 | ||||
| 		if (module == nullptr) | ||||
| 			log_cmd_error("No top module found.\n"); | ||||
| 
 | ||||
| 		fix_carry_chain(module);		 | ||||
| 	} | ||||
| } AnlogicCarryFixPass; | ||||
| 
 | ||||
| PRIVATE_NAMESPACE_END | ||||
|  | @ -31,7 +31,10 @@ module _80_anlogic_alu (A, B, CI, BI, X, Y, CO); | |||
| 	output [Y_WIDTH-1:0] X, Y; | ||||
| 
 | ||||
| 	input CI, BI; | ||||
| 	output CO; | ||||
| 	output [Y_WIDTH-1:0] CO; | ||||
|     | ||||
| 	wire CIx; | ||||
| 	wire [Y_WIDTH-1:0] COx; | ||||
| 
 | ||||
| 	wire _TECHMAP_FAIL_ = Y_WIDTH <= 2; | ||||
| 
 | ||||
|  | @ -41,15 +44,16 @@ module _80_anlogic_alu (A, B, CI, BI, X, Y, CO); | |||
| 
 | ||||
| 	wire [Y_WIDTH-1:0] AA = A_buf; | ||||
| 	wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf; | ||||
| 	wire [Y_WIDTH+1:0] COx; | ||||
| 	wire [Y_WIDTH+2:0] C = {COx, CI}; | ||||
| 	wire [Y_WIDTH-1:0] C = { COx, CIx }; | ||||
| 
 | ||||
|     wire dummy; | ||||
|     AL_MAP_ADDER #( | ||||
|     	.ALUTYPE("ADD_CARRY")) | ||||
|     adder_cin  ( | ||||
|         .a(C[0]), | ||||
|         .o({COx[0], dummy}) | ||||
|         .a(CI), | ||||
| 		.b(1'b0), | ||||
| 		.c(1'b0), | ||||
|         .o({CIx, dummy}) | ||||
| 	); | ||||
| 
 | ||||
| 	genvar i; | ||||
|  | @ -59,18 +63,22 @@ module _80_anlogic_alu (A, B, CI, BI, X, Y, CO); | |||
|         ) adder_i ( | ||||
|             .a(AA[i]), | ||||
|             .b(BB[i]), | ||||
|             .c(C[i+1]), | ||||
|             .o({COx[i+1],Y[i]}) | ||||
|             .c(C[i]), | ||||
|             .o({COx[i],Y[i]}) | ||||
|         ); | ||||
| 	  end: slice | ||||
| 
 | ||||
| 		wire cout; | ||||
| 		AL_MAP_ADDER #( | ||||
| 			.ALUTYPE("ADD")) | ||||
| 		adder_cout  ( | ||||
| 			.a(1'b0), | ||||
| 			.b(1'b0), | ||||
| 			.c(COx[i]), | ||||
| 			.o({cout, CO[i]}) | ||||
| 		); | ||||
| 	  end: slice	   | ||||
| 	endgenerate | ||||
| 	/* End implementation */ | ||||
| 	AL_MAP_ADDER #( | ||||
| 		.ALUTYPE("ADD")) | ||||
| 	adder_cout  ( | ||||
| 		.c(C[Y_WIDTH+1]), | ||||
| 		.o(COx[Y_WIDTH+1]) | ||||
| 	);				 | ||||
| 	assign CO = COx[Y_WIDTH+1]; | ||||
| 	assign X = AA ^ BB; | ||||
| endmodule | ||||
| 
 | ||||
|    /* End implementation */ | ||||
|    assign X = AA ^ BB; | ||||
| endmodule | ||||
|  |  | |||
|  | @ -154,7 +154,7 @@ struct SynthAnlogicPass : public ScriptPass | |||
| 		{ | ||||
| 			run("memory_bram -rules +/anlogic/drams.txt"); | ||||
| 			run("techmap -map +/anlogic/drams_map.v"); | ||||
| 			run("anlogic_determine_init"); | ||||
| 			run("setundef -zero -params t:EG_LOGIC_DRAM16X4"); | ||||
| 		} | ||||
| 
 | ||||
| 		if (check_label("fine")) | ||||
|  | @ -186,6 +186,11 @@ struct SynthAnlogicPass : public ScriptPass | |||
| 		{ | ||||
| 			run("techmap -map +/anlogic/cells_map.v"); | ||||
| 			run("clean"); | ||||
| 		} | ||||
| 		 | ||||
| 		if (check_label("map_anlogic")) | ||||
| 		{ | ||||
| 			run("anlogic_fixcarry"); | ||||
| 			run("anlogic_eqn"); | ||||
| 		} | ||||
| 
 | ||||
|  |  | |||
|  | @ -17,10 +17,12 @@ endmodule | |||
| // --------------------------------------- | ||||
| (* abc_box_id=1, lib_whitebox *) | ||||
| module CCU2C( | ||||
| 	(* abc_carry *) input CIN, | ||||
| 	(* abc_carry *) | ||||
| 	input  CIN, | ||||
| 	input  A0, B0, C0, D0, A1, B1, C1, D1, | ||||
| 	output S0, S1, | ||||
| 	(* abc_carry *) output COUT | ||||
| 	(* abc_carry *) | ||||
| 	output COUT | ||||
| ); | ||||
| 	parameter [15:0] INIT0 = 16'h0000; | ||||
| 	parameter [15:0] INIT1 = 16'h0000; | ||||
|  | @ -113,7 +115,8 @@ module TRELLIS_DPR16X4 ( | |||
| 	input        WRE, | ||||
| 	input        WCK, | ||||
| 	input  [3:0] RAD, | ||||
| 	/* (* abc_arrival=<TODO> *) */ output [3:0] DO | ||||
| 	/* (* abc_arrival=<TODO> *) */ | ||||
|     output [3:0] DO | ||||
| ); | ||||
| 	parameter WCKMUX = "WCK"; | ||||
| 	parameter WREMUX = "WRE"; | ||||
|  |  | |||
							
								
								
									
										10
									
								
								techlibs/efinix/Makefile.inc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								techlibs/efinix/Makefile.inc
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | |||
| 
 | ||||
| OBJS += techlibs/efinix/synth_efinix.o | ||||
| OBJS += techlibs/efinix/efinix_gbuf.o | ||||
| OBJS += techlibs/efinix/efinix_fixcarry.o | ||||
| 
 | ||||
| $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_map.v)) | ||||
| $(eval $(call add_share_file,share/efinix,techlibs/efinix/arith_map.v)) | ||||
| $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_sim.v)) | ||||
| $(eval $(call add_share_file,share/efinix,techlibs/efinix/brams_map.v)) | ||||
| $(eval $(call add_share_file,share/efinix,techlibs/efinix/bram.txt)) | ||||
							
								
								
									
										79
									
								
								techlibs/efinix/arith_map.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								techlibs/efinix/arith_map.v
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,79 @@ | |||
| /* | ||||
|  *  yosys -- Yosys Open SYnthesis Suite | ||||
|  * | ||||
|  *  Copyright (C) 2018  Miodrag Milanovic <miodrag@symbioticeda.com> | ||||
|  *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at> | ||||
|  * | ||||
|  *  Permission to use, copy, modify, and/or distribute this software for any | ||||
|  *  purpose with or without fee is hereby granted, provided that the above | ||||
|  *  copyright notice and this permission notice appear in all copies. | ||||
|  * | ||||
|  *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||||
|  *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||||
|  *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||||
|  *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||
|  *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||||
|  *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||||
|  *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| (* techmap_celltype = "$alu" *) | ||||
| module _80_efinix_alu (A, B, CI, BI, X, Y, CO); | ||||
| 	parameter A_SIGNED = 0; | ||||
| 	parameter B_SIGNED = 0; | ||||
| 	parameter A_WIDTH  = 1; | ||||
| 	parameter B_WIDTH  = 1; | ||||
| 	parameter Y_WIDTH  = 1; | ||||
| 
 | ||||
| 	input [A_WIDTH-1:0] A; | ||||
| 	input [B_WIDTH-1:0] B; | ||||
| 	output [Y_WIDTH-1:0] X, Y; | ||||
| 
 | ||||
| 	input CI, BI; | ||||
| 	output [Y_WIDTH-1:0] CO; | ||||
|     | ||||
|     wire CIx; | ||||
|     wire [Y_WIDTH-1:0] COx; | ||||
| 
 | ||||
| 	wire _TECHMAP_FAIL_ = Y_WIDTH <= 2; | ||||
| 
 | ||||
| 	wire [Y_WIDTH-1:0] A_buf, B_buf; | ||||
| 	\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); | ||||
| 	\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); | ||||
| 
 | ||||
| 	wire [Y_WIDTH-1:0] AA = A_buf; | ||||
| 	wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf; | ||||
| 	wire [Y_WIDTH-1:0] C = { COx, CIx }; | ||||
| 
 | ||||
|     EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) | ||||
|     adder_cin  ( | ||||
|         .I0(CI), | ||||
|         .I1(1'b1), | ||||
|         .CI(1'b0), | ||||
|         .CO(CIx) | ||||
| 	); | ||||
| 
 | ||||
| 	genvar i; | ||||
| 	generate for (i = 0; i < Y_WIDTH; i = i + 1) begin: slice | ||||
| 		EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) | ||||
| 		adder_i ( | ||||
| 			.I0(AA[i]), | ||||
| 			.I1(BB[i]), | ||||
| 			.CI(C[i]), | ||||
| 			.O(Y[i]), | ||||
| 			.CO(COx[i]) | ||||
| 		); | ||||
| 		EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1))				 | ||||
| 		adder_cout  ( | ||||
| 			.I0(1'b0), | ||||
| 			.I1(1'b0), | ||||
| 			.CI(COx[i]), | ||||
| 			.O(CO[i]) | ||||
| 		); | ||||
| 	  end: slice	   | ||||
| 	endgenerate | ||||
| 
 | ||||
|    /* End implementation */ | ||||
|    assign X = AA ^ BB; | ||||
| endmodule | ||||
							
								
								
									
										32
									
								
								techlibs/efinix/bram.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								techlibs/efinix/bram.txt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,32 @@ | |||
| bram $__EFINIX_5K | ||||
|   init 1 | ||||
| 
 | ||||
|   abits 8  @a8d16 | ||||
|   dbits 16 @a8d16 | ||||
|   abits 9  @a9d8 | ||||
|   dbits 8  @a9d8 | ||||
|   abits 10 @a10d4 | ||||
|   dbits 4  @a10d4 | ||||
|   abits 11 @a11d2 | ||||
|   dbits 2  @a11d2 | ||||
|   abits 12 @a12d1 | ||||
|   dbits 1  @a12d1 | ||||
|   abits 8  @a8d20 | ||||
|   dbits 20 @a8d20 | ||||
|   abits 9  @a9d10 | ||||
|   dbits 10 @a9d10 | ||||
| 
 | ||||
|   groups 2 | ||||
|   ports 1 1 | ||||
|   wrmode 1 0 | ||||
|   enable 1 1 | ||||
|   transp 0 2 | ||||
|   clocks 2 3 | ||||
|   clkpol 2 3 | ||||
| endbram | ||||
| 
 | ||||
| match $__EFINIX_5K | ||||
|   min bits 256 | ||||
|   min efficiency 5 | ||||
|   shuffle_enable B | ||||
| endmatch | ||||
							
								
								
									
										65
									
								
								techlibs/efinix/brams_map.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								techlibs/efinix/brams_map.v
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,65 @@ | |||
| module \$__EFINIX_5K (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); | ||||
| 	parameter CFG_ABITS = 8; | ||||
| 	parameter CFG_DBITS = 20; | ||||
| 	parameter CFG_ENABLE_A = 1; | ||||
| 
 | ||||
| 	parameter CLKPOL2 = 1; | ||||
| 	parameter CLKPOL3 = 1; | ||||
| 	parameter [5119:0] INIT = 5119'bx; | ||||
| 	parameter TRANSP2 = 0; | ||||
| 
 | ||||
| 	input CLK2; | ||||
| 	input CLK3; | ||||
| 
 | ||||
| 	input [CFG_ABITS-1:0] A1ADDR; | ||||
| 	input [CFG_DBITS-1:0] A1DATA; | ||||
| 	input [CFG_ENABLE_A-1:0] A1EN; | ||||
| 
 | ||||
| 	input [CFG_ABITS-1:0] B1ADDR; | ||||
| 	output [CFG_DBITS-1:0] B1DATA; | ||||
| 	input B1EN; | ||||
| 
 | ||||
| 	localparam WRITEMODE_A = TRANSP2 ? "WRITE_FIRST" : "READ_FIRST"; | ||||
| 
 | ||||
| 	EFX_RAM_5K #( | ||||
|    		.READ_WIDTH(CFG_DBITS), | ||||
|    		.WRITE_WIDTH(CFG_DBITS), | ||||
|    		.OUTPUT_REG(1'b0), | ||||
|    		.RCLK_POLARITY(1'b1), | ||||
|    		.RE_POLARITY(1'b1), | ||||
|    		.WCLK_POLARITY(1'b1), | ||||
|    		.WE_POLARITY(1'b1), | ||||
|    		.WCLKE_POLARITY(1'b1), | ||||
|    		.WRITE_MODE(WRITEMODE_A), | ||||
| 		.INIT_0(INIT[ 0*256 +: 256]), | ||||
| 		.INIT_1(INIT[ 1*256 +: 256]), | ||||
| 		.INIT_2(INIT[ 2*256 +: 256]), | ||||
| 		.INIT_3(INIT[ 3*256 +: 256]), | ||||
| 		.INIT_4(INIT[ 4*256 +: 256]), | ||||
| 		.INIT_5(INIT[ 5*256 +: 256]), | ||||
| 		.INIT_6(INIT[ 6*256 +: 256]), | ||||
| 		.INIT_7(INIT[ 7*256 +: 256]), | ||||
| 		.INIT_8(INIT[ 8*256 +: 256]), | ||||
| 		.INIT_9(INIT[ 9*256 +: 256]), | ||||
| 		.INIT_A(INIT[10*256 +: 256]), | ||||
| 		.INIT_B(INIT[11*256 +: 256]), | ||||
| 		.INIT_C(INIT[12*256 +: 256]), | ||||
| 		.INIT_D(INIT[13*256 +: 256]), | ||||
| 		.INIT_E(INIT[14*256 +: 256]), | ||||
| 		.INIT_F(INIT[15*256 +: 256]), | ||||
| 		.INIT_10(INIT[16*256 +: 256]), | ||||
| 		.INIT_11(INIT[17*256 +: 256]), | ||||
| 		.INIT_12(INIT[18*256 +: 256]), | ||||
| 		.INIT_13(INIT[19*256 +: 256]) | ||||
| 	) _TECHMAP_REPLACE_ ( | ||||
|    		.WDATA(A1DATA), | ||||
|    		.WADDR(A1ADDR), | ||||
|    		.WE(A1EN), | ||||
|    		.WCLK(CLK2), | ||||
|    		.WCLKE(1'b1), | ||||
|    		.RDATA(B1DATA), | ||||
|    		.RADDR(B1ADDR), | ||||
|    		.RE(B1EN), | ||||
|    		.RCLK(CLK3) | ||||
| 	); | ||||
| endmodule | ||||
							
								
								
									
										45
									
								
								techlibs/efinix/cells_map.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								techlibs/efinix/cells_map.v
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,45 @@ | |||
| module  \$_DFF_N_ (input D, C, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(1'b0), .Q(Q)); endmodule | ||||
| module  \$_DFF_P_ (input D, C, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(1'b0), .Q(Q)); endmodule | ||||
| 
 | ||||
| module  \$_DFFE_NN_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b0), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule | ||||
| module  \$_DFFE_NP_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule | ||||
| 
 | ||||
| module  \$_DFFE_PN_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b0), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule | ||||
| module  \$_DFFE_PP_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule | ||||
| 
 | ||||
| module  \$_DFF_NN0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule | ||||
| module  \$_DFF_NN1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule | ||||
| module  \$_DFF_PN0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule | ||||
| module  \$_DFF_PN1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule | ||||
| 
 | ||||
| module  \$_DFF_NP0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule | ||||
| module  \$_DFF_NP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule | ||||
| module  \$_DFF_PP0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule | ||||
| module  \$_DFF_PP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule | ||||
| 
 | ||||
| `ifndef NO_LUT | ||||
| module \$lut (A, Y); | ||||
|   parameter WIDTH = 0; | ||||
|   parameter LUT = 0; | ||||
| 
 | ||||
|   input [WIDTH-1:0] A; | ||||
|   output Y; | ||||
| 
 | ||||
|   generate | ||||
|     if (WIDTH == 1) begin | ||||
|       EFX_LUT4 #(.LUTMASK(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(1'b0), .I2(1'b0), .I3(1'b0)); | ||||
|     end else | ||||
|     if (WIDTH == 2) begin | ||||
|       EFX_LUT4 #(.LUTMASK(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(A[1]), .I2(1'b0), .I3(1'b0)); | ||||
|     end else | ||||
|     if (WIDTH == 3) begin | ||||
|       EFX_LUT4 #(.LUTMASK(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(1'b0)); | ||||
|     end else | ||||
|     if (WIDTH == 4) begin | ||||
|       EFX_LUT4 #(.LUTMASK(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(A[3])); | ||||
|     end else begin | ||||
|       wire _TECHMAP_FAIL_ = 1; | ||||
|     end | ||||
|   endgenerate | ||||
| endmodule | ||||
| `endif | ||||
							
								
								
									
										107
									
								
								techlibs/efinix/cells_sim.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								techlibs/efinix/cells_sim.v
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,107 @@ | |||
| module EFX_LUT4( | ||||
|    output O,  | ||||
|    input I0, | ||||
|    input I1, | ||||
|    input I2, | ||||
|    input I3 | ||||
| ); | ||||
|    parameter LUTMASK  = 16'h0000; | ||||
| endmodule | ||||
| 
 | ||||
| module EFX_ADD( | ||||
|    output O, | ||||
|    output CO, | ||||
|    input I0, | ||||
|    input I1, | ||||
|    input CI | ||||
| ); | ||||
|    parameter I0_POLARITY   = 1; | ||||
|    parameter I1_POLARITY   = 1; | ||||
| endmodule | ||||
| 
 | ||||
| module EFX_FF( | ||||
|    output Q, | ||||
|    input D, | ||||
|    input CE, | ||||
|    input CLK, | ||||
|    input SR | ||||
| ); | ||||
|    parameter CLK_POLARITY = 1; | ||||
|    parameter CE_POLARITY = 1; | ||||
|    parameter SR_POLARITY = 1; | ||||
|    parameter SR_SYNC = 0; | ||||
|    parameter SR_VALUE = 0; | ||||
|    parameter SR_SYNC_PRIORITY = 0; | ||||
|    parameter D_POLARITY = 1; | ||||
| endmodule | ||||
| 
 | ||||
| module EFX_GBUFCE( | ||||
|    input CE, | ||||
|    input I, | ||||
|    output O | ||||
| ); | ||||
|    parameter CE_POLARITY = 1'b1; | ||||
| endmodule | ||||
| 
 | ||||
| module EFX_RAM_5K( | ||||
|    input [WRITE_WIDTH-1:0] WDATA, | ||||
|    input [WRITE_ADDR_WIDTH-1:0] WADDR, | ||||
|    input WE,  | ||||
|    input WCLK, | ||||
|    input WCLKE,  | ||||
|    output [READ_WIDTH-1:0] RDATA,  | ||||
|    input [READ_ADDR_WIDTH-1:0] RADDR, | ||||
|    input RE,  | ||||
|    input RCLK | ||||
| ); | ||||
|    parameter READ_WIDTH = 20; | ||||
|    parameter WRITE_WIDTH = 20; | ||||
|    parameter OUTPUT_REG = 1'b0; | ||||
|    parameter RCLK_POLARITY  = 1'b1; | ||||
|    parameter RE_POLARITY    = 1'b1; | ||||
|    parameter WCLK_POLARITY  = 1'b1; | ||||
|    parameter WE_POLARITY    = 1'b1; | ||||
|    parameter WCLKE_POLARITY = 1'b1; | ||||
|    parameter WRITE_MODE = "READ_FIRST"; | ||||
|    parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000; | ||||
|    parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000; | ||||
|    parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000; | ||||
|    parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000; | ||||
|    parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000; | ||||
|    parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000; | ||||
|    parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000; | ||||
|    parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000; | ||||
|    parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000; | ||||
|    parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000; | ||||
|    parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000; | ||||
|    parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000; | ||||
|    parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000; | ||||
|    parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000; | ||||
|    parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000; | ||||
|    parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000; | ||||
|    parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000; | ||||
|    parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000; | ||||
|    parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000; | ||||
|    parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000; | ||||
| 
 | ||||
|    localparam READ_ADDR_WIDTH =  | ||||
| 			    (READ_WIDTH == 16) ? 8 :  // 256x16 | ||||
| 			    (READ_WIDTH == 8)  ? 9 :  // 512x8 | ||||
| 			    (READ_WIDTH == 4)  ? 10 : // 1024x4 | ||||
| 			    (READ_WIDTH == 2)  ? 11 : // 2048x2 | ||||
| 			    (READ_WIDTH == 1)  ? 12 : // 4096x1 | ||||
| 			    (READ_WIDTH == 20) ? 8 :  // 256x20 | ||||
| 			    (READ_WIDTH == 10) ? 9 :  // 512x10 | ||||
| 			    (READ_WIDTH == 5)  ? 10 : -1; // 1024x5 | ||||
|     | ||||
|    localparam WRITE_ADDR_WIDTH =  | ||||
| 			    (WRITE_WIDTH == 16) ? 8 :  // 256x16 | ||||
| 			    (WRITE_WIDTH == 8)  ? 9 :  // 512x8 | ||||
| 			    (WRITE_WIDTH == 4)  ? 10 : // 1024x4 | ||||
| 			    (WRITE_WIDTH == 2)  ? 11 : // 2048x2 | ||||
| 			    (WRITE_WIDTH == 1)  ? 12 : // 4096x1 | ||||
| 			    (WRITE_WIDTH == 20) ? 8 :  // 256x20 | ||||
| 			    (WRITE_WIDTH == 10) ? 9 :  // 512x10 | ||||
| 			    (WRITE_WIDTH == 5)  ? 10 : -1; // 1024x5 | ||||
|     | ||||
| endmodule | ||||
							
								
								
									
										122
									
								
								techlibs/efinix/efinix_fixcarry.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								techlibs/efinix/efinix_fixcarry.cc
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,122 @@ | |||
| /*
 | ||||
|  *  yosys -- Yosys Open SYnthesis Suite | ||||
|  * | ||||
|  *  Copyright (C) 2019  Miodrag Milanovic <miodrag@symbioticeda.com> | ||||
|  * | ||||
|  *  Permission to use, copy, modify, and/or distribute this software for any | ||||
|  *  purpose with or without fee is hereby granted, provided that the above | ||||
|  *  copyright notice and this permission notice appear in all copies. | ||||
|  * | ||||
|  *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||||
|  *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||||
|  *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||||
|  *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||
|  *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||||
|  *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||||
|  *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| #include "kernel/yosys.h" | ||||
| #include "kernel/sigtools.h" | ||||
| 
 | ||||
| USING_YOSYS_NAMESPACE | ||||
| PRIVATE_NAMESPACE_BEGIN | ||||
| 
 | ||||
| static SigBit get_bit_or_zero(const SigSpec &sig) | ||||
| { | ||||
| 	if (GetSize(sig) == 0) | ||||
| 		return State::S0; | ||||
| 	return sig[0]; | ||||
| } | ||||
| 
 | ||||
| static void fix_carry_chain(Module *module) | ||||
| { | ||||
| 	SigMap sigmap(module); | ||||
| 
 | ||||
| 	pool<SigBit> ci_bits; | ||||
| 	dict<SigBit, SigBit> mapping_bits; | ||||
| 
 | ||||
| 	for (auto cell : module->cells()) | ||||
| 	{ | ||||
| 		if (cell->type == "\\EFX_ADD") { | ||||
| 			SigBit bit_i0 = get_bit_or_zero(cell->getPort("\\I0")); | ||||
| 			SigBit bit_i1 = get_bit_or_zero(cell->getPort("\\I1")); | ||||
| 			if (bit_i0 == State::S0 && bit_i1== State::S0) { | ||||
| 				SigBit bit_ci = get_bit_or_zero(cell->getPort("\\CI")); | ||||
| 				SigBit bit_o = sigmap(cell->getPort("\\O")); | ||||
| 				ci_bits.insert(bit_ci);				 | ||||
| 				mapping_bits[bit_ci] = bit_o; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	vector<Cell*> adders_to_fix_cells; | ||||
| 	for (auto cell : module->cells()) | ||||
| 	{ | ||||
| 		if (cell->type == "\\EFX_ADD") { | ||||
| 			SigBit bit_ci = get_bit_or_zero(cell->getPort("\\CI")); | ||||
| 			SigBit bit_i0 = get_bit_or_zero(cell->getPort("\\I0")); | ||||
| 			SigBit bit_i1 = get_bit_or_zero(cell->getPort("\\I1"));			 | ||||
| 			SigBit canonical_bit = sigmap(bit_ci); | ||||
| 			if (!ci_bits.count(canonical_bit)) | ||||
| 				continue;			 | ||||
| 			if (bit_i0 == State::S0 && bit_i1== State::S0)  | ||||
| 				continue; | ||||
| 
 | ||||
| 			adders_to_fix_cells.push_back(cell); | ||||
| 			log("Found %s cell named %s with invalid CI signal.\n", log_id(cell->type), log_id(cell)); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	for (auto cell : adders_to_fix_cells) | ||||
| 	{ | ||||
| 		SigBit bit_ci = get_bit_or_zero(cell->getPort("\\CI")); | ||||
| 		SigBit canonical_bit = sigmap(bit_ci); | ||||
| 		auto bit = mapping_bits.at(canonical_bit); | ||||
| 		log("Fixing %s cell named %s breaking carry chain.\n", log_id(cell->type), log_id(cell)); | ||||
| 		Cell *c = module->addCell(NEW_ID, "\\EFX_ADD"); | ||||
| 		SigBit new_bit = module->addWire(NEW_ID); | ||||
| 		c->setParam("\\I0_POLARITY", State::S1); | ||||
| 		c->setParam("\\I1_POLARITY", State::S1); | ||||
| 		c->setPort("\\I0", bit); | ||||
| 		c->setPort("\\I1", State::S1); | ||||
| 		c->setPort("\\CI", State::S0); | ||||
| 		c->setPort("\\CO", new_bit); | ||||
| 		 | ||||
| 		cell->setPort("\\CI", new_bit); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| struct EfinixCarryFixPass : public Pass { | ||||
| 	EfinixCarryFixPass() : Pass("efinix_fixcarry", "Efinix: fix carry chain") { } | ||||
| 	void help() YS_OVERRIDE | ||||
| 	{ | ||||
| 		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 | ||||
| 		log("\n"); | ||||
| 		log("    efinix_fixcarry [options] [selection]\n"); | ||||
| 		log("\n"); | ||||
| 		log("Add Efinix adders to fix carry chain if needed.\n"); | ||||
| 		log("\n"); | ||||
| 	} | ||||
| 	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE | ||||
| 	{ | ||||
| 		log_header(design, "Executing efinix_fixcarry pass (fix invalid carry chain).\n"); | ||||
| 		 | ||||
| 		size_t argidx; | ||||
| 		for (argidx = 1; argidx < args.size(); argidx++) | ||||
| 		{ | ||||
| 			break; | ||||
| 		} | ||||
| 		extra_args(args, argidx, design); | ||||
| 
 | ||||
| 		Module *module = design->top_module(); | ||||
| 
 | ||||
| 		if (module == nullptr) | ||||
| 			log_cmd_error("No top module found.\n"); | ||||
| 
 | ||||
| 		fix_carry_chain(module);		 | ||||
| 	} | ||||
| } EfinixCarryFixPass; | ||||
| 
 | ||||
| PRIVATE_NAMESPACE_END | ||||
							
								
								
									
										119
									
								
								techlibs/efinix/efinix_gbuf.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								techlibs/efinix/efinix_gbuf.cc
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,119 @@ | |||
| /*
 | ||||
|  *  yosys -- Yosys Open SYnthesis Suite | ||||
|  * | ||||
|  *  Copyright (C) 2019  Miodrag Milanovic <miodrag@symbioticeda.com> | ||||
|  *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at> | ||||
|  * | ||||
|  *  Permission to use, copy, modify, and/or distribute this software for any | ||||
|  *  purpose with or without fee is hereby granted, provided that the above | ||||
|  *  copyright notice and this permission notice appear in all copies. | ||||
|  * | ||||
|  *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||||
|  *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||||
|  *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||||
|  *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||
|  *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||||
|  *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||||
|  *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| #include "kernel/yosys.h" | ||||
| #include "kernel/sigtools.h" | ||||
| 
 | ||||
| USING_YOSYS_NAMESPACE | ||||
| PRIVATE_NAMESPACE_BEGIN | ||||
| 
 | ||||
| static void handle_gbufs(Module *module) | ||||
| { | ||||
| 	SigMap sigmap(module); | ||||
| 
 | ||||
| 	pool<SigBit> clk_bits; | ||||
| 	dict<SigBit, SigBit> rewrite_bits; | ||||
| 	vector<pair<Cell*, SigBit>> pad_bits; | ||||
| 
 | ||||
| 	for (auto cell : module->cells()) | ||||
| 	{ | ||||
| 		if (cell->type == "\\EFX_FF") { | ||||
| 			for (auto bit : sigmap(cell->getPort("\\CLK"))) | ||||
| 				clk_bits.insert(bit); | ||||
| 		} | ||||
| 		if (cell->type == "\\EFX_RAM_5K") { | ||||
| 			for (auto bit : sigmap(cell->getPort("\\RCLK"))) | ||||
| 				clk_bits.insert(bit); | ||||
| 			for (auto bit : sigmap(cell->getPort("\\WCLK"))) | ||||
| 				clk_bits.insert(bit); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	for (auto wire : vector<Wire*>(module->wires())) | ||||
| 	{ | ||||
| 		if (!wire->port_input) | ||||
| 			continue; | ||||
| 
 | ||||
| 		for (int index = 0; index < GetSize(wire); index++) | ||||
| 		{ | ||||
| 			SigBit bit(wire, index); | ||||
| 			SigBit canonical_bit = sigmap(bit); | ||||
| 
 | ||||
| 			if (!clk_bits.count(canonical_bit)) | ||||
| 				continue; | ||||
| 
 | ||||
| 			Cell *c = module->addCell(NEW_ID, "\\EFX_GBUFCE"); | ||||
| 			SigBit new_bit = module->addWire(NEW_ID); | ||||
| 			c->setParam("\\CE_POLARITY", State::S1); | ||||
| 			c->setPort("\\O", new_bit); | ||||
| 			c->setPort("\\CE", State::S1); | ||||
| 			pad_bits.push_back(make_pair(c, bit)); | ||||
| 			rewrite_bits[canonical_bit] = new_bit; | ||||
| 
 | ||||
| 			log("Added %s cell %s for port bit %s.\n", log_id(c->type), log_id(c), log_signal(bit)); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	auto rewrite_function = [&](SigSpec &s) { | ||||
| 		for (auto &bit : s) { | ||||
| 			SigBit canonical_bit = sigmap(bit); | ||||
| 			if (rewrite_bits.count(canonical_bit)) | ||||
| 				bit = rewrite_bits.at(canonical_bit); | ||||
| 		} | ||||
| 	}; | ||||
| 
 | ||||
| 	module->rewrite_sigspecs(rewrite_function); | ||||
| 
 | ||||
| 	for (auto &it : pad_bits) | ||||
| 		it.first->setPort("\\I", it.second); | ||||
| } | ||||
| 
 | ||||
| struct EfinixGbufPass : public Pass { | ||||
| 	EfinixGbufPass() : Pass("efinix_gbuf", "Efinix: insert global clock buffers") { } | ||||
| 	void help() YS_OVERRIDE | ||||
| 	{ | ||||
| 		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 | ||||
| 		log("\n"); | ||||
| 		log("    efinix_gbuf [options] [selection]\n"); | ||||
| 		log("\n"); | ||||
| 		log("Add Efinix global clock buffers to top module as needed.\n"); | ||||
| 		log("\n"); | ||||
| 	} | ||||
| 	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE | ||||
| 	{ | ||||
| 		log_header(design, "Executing efinix_gbuf pass (insert global clock buffers).\n"); | ||||
| 		 | ||||
| 		size_t argidx; | ||||
| 		for (argidx = 1; argidx < args.size(); argidx++) | ||||
| 		{ | ||||
| 			break; | ||||
| 		} | ||||
| 		extra_args(args, argidx, design); | ||||
| 
 | ||||
| 		Module *module = design->top_module(); | ||||
| 
 | ||||
| 		if (module == nullptr) | ||||
| 			log_cmd_error("No top module found.\n"); | ||||
| 
 | ||||
| 		handle_gbufs(module);		 | ||||
| 	} | ||||
| } EfinixGbufPass; | ||||
| 
 | ||||
| PRIVATE_NAMESPACE_END | ||||
							
								
								
									
										219
									
								
								techlibs/efinix/synth_efinix.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										219
									
								
								techlibs/efinix/synth_efinix.cc
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,219 @@ | |||
| /*
 | ||||
|  *  yosys -- Yosys Open SYnthesis Suite | ||||
|  * | ||||
|  *  Copyright (C) 2019  Miodrag Milanovic <miodrag@symbioticeda.com> | ||||
|  *  Copyright (C) 2019  Clifford Wolf <clifford@clifford.at> | ||||
|  * | ||||
|  *  Permission to use, copy, modify, and/or distribute this software for any | ||||
|  *  purpose with or without fee is hereby granted, provided that the above | ||||
|  *  copyright notice and this permission notice appear in all copies. | ||||
|  * | ||||
|  *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||||
|  *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||||
|  *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||||
|  *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||
|  *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||||
|  *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||||
|  *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| #include "kernel/register.h" | ||||
| #include "kernel/celltypes.h" | ||||
| #include "kernel/rtlil.h" | ||||
| #include "kernel/log.h" | ||||
| 
 | ||||
| USING_YOSYS_NAMESPACE | ||||
| PRIVATE_NAMESPACE_BEGIN | ||||
| 
 | ||||
| struct SynthEfinixPass : public ScriptPass | ||||
| { | ||||
| 	SynthEfinixPass() : ScriptPass("synth_efinix", "synthesis for Efinix FPGAs") { } | ||||
| 
 | ||||
| 	void help() YS_OVERRIDE | ||||
| 	{ | ||||
| 		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 | ||||
| 		log("\n"); | ||||
| 		log("    synth_efinix [options]\n"); | ||||
| 		log("\n"); | ||||
| 		log("This command runs synthesis for Efinix FPGAs.\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -top <module>\n"); | ||||
| 		log("        use the specified module as top module\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -edif <file>\n"); | ||||
| 		log("        write the design to the specified EDIF file. writing of an output file\n"); | ||||
| 		log("        is omitted if this parameter is not specified.\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -json <file>\n"); | ||||
| 		log("        write the design to the specified JSON file. writing of an output file\n"); | ||||
| 		log("        is omitted if this parameter is not specified.\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -run <from_label>:<to_label>\n"); | ||||
| 		log("        only run the commands between the labels (see below). an empty\n"); | ||||
| 		log("        from label is synonymous to 'begin', and empty to label is\n"); | ||||
| 		log("        synonymous to the end of the command list.\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -noflatten\n"); | ||||
| 		log("        do not flatten design before synthesis\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -retime\n"); | ||||
| 		log("        run 'abc' with -dff option\n"); | ||||
| 		log("\n"); | ||||
| 		log("\n"); | ||||
| 		log("The following commands are executed by this synthesis command:\n"); | ||||
| 		help_script(); | ||||
| 		log("\n"); | ||||
| 	} | ||||
| 
 | ||||
| 	string top_opt, edif_file, json_file; | ||||
| 	bool flatten, retime; | ||||
| 
 | ||||
| 	void clear_flags() YS_OVERRIDE | ||||
| 	{ | ||||
| 		top_opt = "-auto-top"; | ||||
| 		edif_file = ""; | ||||
| 		json_file = ""; | ||||
| 		flatten = true; | ||||
| 		retime = false; | ||||
| 	} | ||||
| 
 | ||||
| 	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE | ||||
| 	{ | ||||
| 		string run_from, run_to; | ||||
| 		clear_flags(); | ||||
| 
 | ||||
| 		size_t argidx; | ||||
| 		for (argidx = 1; argidx < args.size(); argidx++) | ||||
| 		{ | ||||
| 			if (args[argidx] == "-top" && argidx+1 < args.size()) { | ||||
| 				top_opt = "-top " + args[++argidx]; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (args[argidx] == "-edif" && argidx+1 < args.size()) { | ||||
| 				edif_file = args[++argidx]; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (args[argidx] == "-json" && argidx+1 < args.size()) { | ||||
| 				json_file = args[++argidx]; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (args[argidx] == "-run" && argidx+1 < args.size()) { | ||||
| 				size_t pos = args[argidx+1].find(':'); | ||||
| 				if (pos == std::string::npos) | ||||
| 					break; | ||||
| 				run_from = args[++argidx].substr(0, pos); | ||||
| 				run_to = args[argidx].substr(pos+1); | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (args[argidx] == "-noflatten") { | ||||
| 				flatten = false; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (args[argidx] == "-retime") { | ||||
| 				retime = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
| 		extra_args(args, argidx, design); | ||||
| 
 | ||||
| 		if (!design->full_selection()) | ||||
| 			log_cmd_error("This command only operates on fully selected designs!\n"); | ||||
| 
 | ||||
| 		log_header(design, "Executing SYNTH_EFINIX pass.\n"); | ||||
| 		log_push(); | ||||
| 
 | ||||
| 		run_script(design, run_from, run_to); | ||||
| 
 | ||||
| 		log_pop(); | ||||
| 	} | ||||
| 
 | ||||
| 	void script() YS_OVERRIDE | ||||
| 	{ | ||||
| 		if (check_label("begin")) | ||||
| 		{ | ||||
| 			run("read_verilog -lib +/efinix/cells_sim.v"); | ||||
| 			run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str())); | ||||
| 		} | ||||
| 
 | ||||
| 		if (flatten && check_label("flatten", "(unless -noflatten)")) | ||||
| 		{ | ||||
| 			run("proc"); | ||||
| 			run("flatten"); | ||||
| 			run("tribuf -logic"); | ||||
| 			run("deminout"); | ||||
| 		} | ||||
| 
 | ||||
| 		if (check_label("coarse")) | ||||
| 		{ | ||||
| 			run("synth -run coarse"); | ||||
| 		} | ||||
| 
 | ||||
| 		if (check_label("map_bram", "(skip if -nobram)")) | ||||
| 		{ | ||||
| 			run("memory_bram -rules +/efinix/bram.txt"); | ||||
| 			run("techmap -map +/efinix/brams_map.v"); | ||||
| 			run("setundef -zero -params t:EFX_RAM_5K"); | ||||
| 		} | ||||
| 
 | ||||
| 		if (check_label("fine")) | ||||
| 		{ | ||||
| 			run("opt -fast -mux_undef -undriven -fine"); | ||||
| 			run("memory_map"); | ||||
| 			run("opt -undriven -fine"); | ||||
| 			run("techmap -map +/techmap.v -map +/efinix/arith_map.v"); | ||||
| 			if (retime || help_mode) | ||||
| 				run("abc -dff", "(only if -retime)"); | ||||
| 		} | ||||
| 
 | ||||
| 		if (check_label("map_ffs")) | ||||
| 		{ | ||||
| 			run("dffsr2dff"); | ||||
| 			run("techmap -D NO_LUT -map +/efinix/cells_map.v"); | ||||
| 			run("dffinit -strinit SET RESET -ff AL_MAP_SEQ q REGSET -noreinit"); | ||||
| 			run("opt_expr -mux_undef"); | ||||
| 			run("simplemap"); | ||||
| 		} | ||||
| 
 | ||||
| 		if (check_label("map_luts")) | ||||
| 		{ | ||||
| 			run("abc -lut 4"); | ||||
| 			run("clean"); | ||||
| 		} | ||||
| 
 | ||||
| 		if (check_label("map_cells")) | ||||
| 		{ | ||||
| 			run("techmap -map +/efinix/cells_map.v"); | ||||
| 			run("clean"); | ||||
| 		} | ||||
| 
 | ||||
| 		if (check_label("map_gbuf")) | ||||
| 		{ | ||||
| 			run("efinix_gbuf"); | ||||
| 			run("efinix_fixcarry"); | ||||
| 			run("clean"); | ||||
| 		} | ||||
| 		 | ||||
| 		if (check_label("check")) | ||||
| 		{ | ||||
| 			run("hierarchy -check"); | ||||
| 			run("stat"); | ||||
| 			run("check -noinit"); | ||||
| 		} | ||||
| 
 | ||||
| 		if (check_label("edif")) | ||||
| 		{ | ||||
| 			if (!edif_file.empty() || help_mode) | ||||
| 				run(stringf("write_edif %s", help_mode ? "<file-name>" : edif_file.c_str())); | ||||
| 		} | ||||
| 
 | ||||
| 		if (check_label("json")) | ||||
| 		{ | ||||
| 			if (!json_file.empty() || help_mode) | ||||
| 				run(stringf("write_json %s", help_mode ? "<file-name>" : json_file.c_str())); | ||||
| 		} | ||||
| 	} | ||||
| } SynthEfinixPass; | ||||
| 
 | ||||
| PRIVATE_NAMESPACE_END | ||||
|  | @ -143,11 +143,13 @@ endmodule | |||
| 
 | ||||
| (* abc_box_id = 1, lib_whitebox *) | ||||
| module \$__ICE40_FULL_ADDER ( | ||||
| 	(* abc_carry *) output CO, | ||||
| 	(* abc_carry *) | ||||
| 	output CO, | ||||
| 	output O, | ||||
| 	input A, | ||||
| 	input B, | ||||
| 	(* abc_carry *) input CI | ||||
| 	(* abc_carry *) | ||||
| 	input CI | ||||
| ); | ||||
| 	SB_CARRY carry ( | ||||
| 		.I0(A), | ||||
|  |  | |||
|  | @ -175,9 +175,11 @@ endmodule | |||
| 
 | ||||
| (* abc_box_id = 4, lib_whitebox *) | ||||
| module CARRY4( | ||||
|   (* abc_carry *) output [3:0] CO, | ||||
|   (* abc_carry *) | ||||
|   output [3:0] CO, | ||||
|   output [3:0] O, | ||||
|   (* abc_carry *) input CI, | ||||
|   (* abc_carry *) | ||||
|   input        CI, | ||||
|   input        CYINIT, | ||||
|   input  [3:0] DI, S | ||||
| ); | ||||
|  | @ -299,7 +301,8 @@ endmodule | |||
| 
 | ||||
| module RAM32X1D ( | ||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 | ||||
|   (* abc_arrival=1153 *) output DPO, SPO, | ||||
|   (* abc_arrival=1153 *) | ||||
|   output DPO, SPO, | ||||
|   input  D, | ||||
|   input  WCLK, | ||||
|   input  WE, | ||||
|  | @ -319,7 +322,8 @@ endmodule | |||
| 
 | ||||
| module RAM64X1D ( | ||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 | ||||
|   (* abc_arrival=1153 *) output DPO, SPO, | ||||
|   (* abc_arrival=1153 *) | ||||
|   output DPO, SPO, | ||||
|   input  D, | ||||
|   input  WCLK, | ||||
|   input  WE, | ||||
|  | @ -339,7 +343,8 @@ endmodule | |||
| 
 | ||||
| module RAM128X1D ( | ||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 | ||||
|   (* abc_arrival=1153 *) output DPO, SPO, | ||||
|   (* abc_arrival=1153 *) | ||||
|   output DPO, SPO, | ||||
|   input        D, | ||||
|   input        WCLK, | ||||
|   input        WE, | ||||
|  |  | |||
|  | @ -221,3 +221,73 @@ check | |||
| equiv_opt opt_expr -fine | ||||
| design -load postopt | ||||
| select -assert-count 1 t:$alu r:A_WIDTH=8 r:B_WIDTH=8 r:Y_WIDTH=9 %i %i %i | ||||
| 
 | ||||
| ########### | ||||
| 
 | ||||
| design -reset | ||||
| read_verilog -icells <<EOT | ||||
| module opt_expr_shiftx_1bit(input [2:0] a, input [1:0] b, output y); | ||||
|     \$shiftx #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(4), .B_WIDTH(2), .Y_WIDTH(1)) shiftx (.A({1'bx,a}), .B(b), .Y(y)); | ||||
| endmodule | ||||
| EOT | ||||
| check | ||||
| 
 | ||||
| equiv_opt opt_expr | ||||
| design -load postopt | ||||
| select -assert-count 1 t:$shiftx r:A_WIDTH=3 %i | ||||
| 
 | ||||
| ########### | ||||
| 
 | ||||
| design -reset | ||||
| read_verilog -icells <<EOT | ||||
| module opt_expr_shiftx_3bit(input [9:0] a, input [3:0] b, output [2:0] y); | ||||
|     \$shiftx #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(14), .B_WIDTH(4), .Y_WIDTH(3)) shiftx (.A({4'bxx00,a}), .B(b), .Y(y)); | ||||
| endmodule | ||||
| EOT | ||||
| check | ||||
| 
 | ||||
| equiv_opt opt_expr | ||||
| design -load postopt | ||||
| select -assert-count 1 t:$shiftx r:A_WIDTH=12 %i | ||||
| 
 | ||||
| ########### | ||||
| 
 | ||||
| design -reset | ||||
| read_verilog -icells <<EOT | ||||
| module opt_expr_shift_1bit(input [2:0] a, input [1:0] b, output y); | ||||
|     \$shift #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(4), .B_WIDTH(2), .Y_WIDTH(1)) shift (.A({1'b0,a}), .B(b), .Y(y)); | ||||
| endmodule | ||||
| EOT | ||||
| check | ||||
| 
 | ||||
| equiv_opt opt_expr | ||||
| design -load postopt | ||||
| select -assert-count 1 t:$shift r:A_WIDTH=3 %i | ||||
| 
 | ||||
| ########### | ||||
| 
 | ||||
| design -reset | ||||
| read_verilog -icells <<EOT | ||||
| module opt_expr_shift_3bit(input [9:0] a, input [3:0] b, output [2:0] y); | ||||
|     \$shift #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(14), .B_WIDTH(4), .Y_WIDTH(3)) shift (.A({4'b0x0x,a}), .B(b), .Y(y)); | ||||
| endmodule | ||||
| EOT | ||||
| check | ||||
| 
 | ||||
| equiv_opt opt_expr | ||||
| design -load postopt | ||||
| select -assert-count 1 t:$shift r:A_WIDTH=10 %i | ||||
| 
 | ||||
| ########### | ||||
| 
 | ||||
| design -reset | ||||
| read_verilog -icells <<EOT | ||||
| module opt_expr_shift_3bit_keepdc(input [9:0] a, input [3:0] b, output [2:0] y); | ||||
|     \$shift #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(14), .B_WIDTH(4), .Y_WIDTH(3)) shift (.A({4'b0x0x,a}), .B(b), .Y(y)); | ||||
| endmodule | ||||
| EOT | ||||
| check | ||||
| 
 | ||||
| equiv_opt opt_expr -keepdc | ||||
| design -load postopt | ||||
| select -assert-count 1 t:$shift r:A_WIDTH=13 %i | ||||
|  |  | |||
							
								
								
									
										14
									
								
								tests/various/mem2reg.ys
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								tests/various/mem2reg.ys
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| read_verilog <<EOT | ||||
| module top; | ||||
| parameter DATADEPTH=2; | ||||
| parameter DATAWIDTH=1; | ||||
| (* keep, nomem2reg *) reg [DATAWIDTH-1:0] data1 [DATADEPTH-1:0]; | ||||
| (* keep, mem2reg *) reg [DATAWIDTH-1:0] data2 [DATADEPTH-1:0]; | ||||
| endmodule | ||||
| EOT | ||||
| 
 | ||||
| proc | ||||
| cd top | ||||
| select -assert-count 1 m:data1 a:src=<<EOT:4 %i | ||||
| select -assert-count 2 w:data2[*] a:src=<<EOT:5 %i | ||||
| select -assert-none a:mem2reg | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue