diff options
Diffstat (limited to 'techlibs/anlogic')
| -rw-r--r-- | techlibs/anlogic/Makefile.inc | 2 | ||||
| -rw-r--r-- | techlibs/anlogic/anlogic_determine_init.cc | 72 | ||||
| -rw-r--r-- | techlibs/anlogic/anlogic_fixcarry.cc | 130 | ||||
| -rw-r--r-- | techlibs/anlogic/arith_map.v | 44 | ||||
| -rw-r--r-- | techlibs/anlogic/synth_anlogic.cc | 7 | 
5 files changed, 163 insertions, 92 deletions
| diff --git a/techlibs/anlogic/Makefile.inc b/techlibs/anlogic/Makefile.inc index 67cf9cf10..9426b5ca5 100644 --- a/techlibs/anlogic/Makefile.inc +++ b/techlibs/anlogic/Makefile.inc @@ -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)) diff --git a/techlibs/anlogic/anlogic_determine_init.cc b/techlibs/anlogic/anlogic_determine_init.cc deleted file mode 100644 index c4089dac2..000000000 --- a/techlibs/anlogic/anlogic_determine_init.cc +++ /dev/null @@ -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 diff --git a/techlibs/anlogic/anlogic_fixcarry.cc b/techlibs/anlogic/anlogic_fixcarry.cc new file mode 100644 index 000000000..87164d375 --- /dev/null +++ b/techlibs/anlogic/anlogic_fixcarry.cc @@ -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 diff --git a/techlibs/anlogic/arith_map.v b/techlibs/anlogic/arith_map.v index 6d6a7ca37..1186543da 100644 --- a/techlibs/anlogic/arith_map.v +++ b/techlibs/anlogic/arith_map.v @@ -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
\ No newline at end of file + +   /* End implementation */ +   assign X = AA ^ BB; +endmodule diff --git a/techlibs/anlogic/synth_anlogic.cc b/techlibs/anlogic/synth_anlogic.cc index 620bf3965..b87fc8566 100644 --- a/techlibs/anlogic/synth_anlogic.cc +++ b/techlibs/anlogic/synth_anlogic.cc @@ -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");  		} | 
