mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-03 21:09:12 +00:00 
			
		
		
		
	booth: Move away from explicit Wire pointers
				
					
				
			To represent intermediate signals use the `SigBit`/`SigSpec` classes as is customary in the Yosys codebase. Do not pass around `Wire` pointers unless we have special reason to.
This commit is contained in:
		
							parent
							
								
									934c82254d
								
							
						
					
					
						commit
						fedd12261f
					
				
					 1 changed files with 194 additions and 248 deletions
				
			
		| 
						 | 
				
			
			@ -94,7 +94,7 @@ struct BoothPassWorker {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	// Unary gate
 | 
			
		||||
	RTLIL::Wire *mk_ugate1(const RTLIL::IdString &red_typ, std::string &name, RTLIL::Wire *ip1, std::string &op_name)
 | 
			
		||||
	RTLIL::Wire *mk_ugate1(const RTLIL::IdString &red_typ, std::string &name, SigBit ip1, std::string &op_name)
 | 
			
		||||
	{
 | 
			
		||||
		std::string op_wire_name;
 | 
			
		||||
		if (op_name.empty())
 | 
			
		||||
| 
						 | 
				
			
			@ -112,7 +112,7 @@ struct BoothPassWorker {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	// Binary gate
 | 
			
		||||
	RTLIL::Wire *mk_ugate2(const RTLIL::IdString &red_typ, std::string &name, RTLIL::Wire *ip1, RTLIL::Wire *ip2, std::string &op_name)
 | 
			
		||||
	RTLIL::Wire *mk_ugate2(const RTLIL::IdString &red_typ, std::string &name, SigBit ip1, SigBit ip2, std::string &op_name)
 | 
			
		||||
	{
 | 
			
		||||
		auto g = module->addCell(new_id(name, __LINE__, ""), red_typ);
 | 
			
		||||
		std::string op_wire_name;
 | 
			
		||||
| 
						 | 
				
			
			@ -135,7 +135,7 @@ struct BoothPassWorker {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	// Booth unsigned decoder lsb
 | 
			
		||||
	void BuildBur4d_lsb(std::string &name, RTLIL::Wire *lsb_i, RTLIL::Wire *one_i, RTLIL::Wire *s_i, RTLIL::Wire *&ppij_o,
 | 
			
		||||
	void BuildBur4d_lsb(std::string &name, SigBit lsb_i, SigBit one_i, SigBit s_i, SigBit &ppij_o,
 | 
			
		||||
			    std::string op_wire_name)
 | 
			
		||||
	{
 | 
			
		||||
		std::string empty;
 | 
			
		||||
| 
						 | 
				
			
			@ -144,8 +144,8 @@ struct BoothPassWorker {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	// Booth unsigned radix4 decoder
 | 
			
		||||
	void BuildBur4d_n(std::string &name, RTLIL::Wire *yn_i, RTLIL::Wire *ynm1_i, RTLIL::Wire *one_i, RTLIL::Wire *two_i, RTLIL::Wire *s_i,
 | 
			
		||||
			  RTLIL::Wire *&ppij_o)
 | 
			
		||||
	void BuildBur4d_n(std::string &name, SigBit yn_i, SigBit ynm1_i, SigBit one_i, SigBit two_i, SigBit s_i,
 | 
			
		||||
			  SigBit &ppij_o)
 | 
			
		||||
	{
 | 
			
		||||
		// ppij = ((yn & one)   | (ynm1 & two)) ^ s;
 | 
			
		||||
		std::string empty;
 | 
			
		||||
| 
						 | 
				
			
			@ -156,7 +156,7 @@ struct BoothPassWorker {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	// Booth unsigned radix4 decoder
 | 
			
		||||
	void BuildBur4d_msb(std::string &name, RTLIL::Wire *msb_i, RTLIL::Wire *two_i, RTLIL::Wire *s_i, RTLIL::Wire *&ppij_o)
 | 
			
		||||
	void BuildBur4d_msb(std::string &name, SigBit msb_i, SigBit two_i, SigBit s_i, SigBit &ppij_o)
 | 
			
		||||
	{
 | 
			
		||||
		// ppij = (msb & two)  ^ s;
 | 
			
		||||
		std::string empty;
 | 
			
		||||
| 
						 | 
				
			
			@ -165,7 +165,7 @@ struct BoothPassWorker {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	// half adder, used in CPA
 | 
			
		||||
	void BuildHa(std::string &name, RTLIL::Wire *a_i, RTLIL::Wire *b_i, RTLIL::Wire *&s_o, RTLIL::Wire *&c_o)
 | 
			
		||||
	void BuildHa(std::string &name, SigBit a_i, SigBit b_i, SigBit &s_o, SigBit &c_o)
 | 
			
		||||
	{
 | 
			
		||||
		std::string empty;
 | 
			
		||||
		s_o = mk_ugate2(ID($xor), name, a_i, b_i, empty);
 | 
			
		||||
| 
						 | 
				
			
			@ -173,9 +173,8 @@ struct BoothPassWorker {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	// Booth unsigned radix 4 encoder
 | 
			
		||||
	void BuildBur4e(std::string &name, RTLIL::Wire *y0_i, RTLIL::Wire *y1_i, RTLIL::Wire *y2_i,
 | 
			
		||||
 | 
			
		||||
			RTLIL::Wire *&one_o, RTLIL::Wire *&two_o, RTLIL::Wire *&s_o, RTLIL::Wire *&sb_o)
 | 
			
		||||
	void BuildBur4e(std::string &name, SigBit y0_i, SigBit y1_i, SigBit y2_i,
 | 
			
		||||
			SigBit &one_o, SigBit &two_o, SigBit &s_o, SigBit &sb_o)
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
		std::string empty;
 | 
			
		||||
| 
						 | 
				
			
			@ -186,11 +185,10 @@ struct BoothPassWorker {
 | 
			
		|||
		two_o = mk_ugate1(ID($not), name, mk_ugate2(ID($or), name, inv_y1_xor_y2, one_o, empty), empty);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void BuildBr4e(std::string &name, RTLIL::Wire *y2_m1_i,
 | 
			
		||||
		       RTLIL::Wire *y2_i, // y2i
 | 
			
		||||
		       RTLIL::Wire *y2_p1_i,
 | 
			
		||||
 | 
			
		||||
		       RTLIL::Wire *&negi_o, RTLIL::Wire *&twoi_n_o, RTLIL::Wire *&onei_n_o, RTLIL::Wire *&cori_o)
 | 
			
		||||
	void BuildBr4e(std::string &name, SigBit y2_m1_i,
 | 
			
		||||
		       SigBit y2_i, // y2i
 | 
			
		||||
		       SigBit y2_p1_i,
 | 
			
		||||
		       SigBit &negi_o, SigBit &twoi_n_o, SigBit &onei_n_o, SigBit &cori_o)
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
		std::string empty;
 | 
			
		||||
| 
						 | 
				
			
			@ -217,9 +215,8 @@ struct BoothPassWorker {
 | 
			
		|||
	//
 | 
			
		||||
	// signed booth radix 4 decoder
 | 
			
		||||
	//
 | 
			
		||||
	void BuildBr4d(std::string &name, RTLIL::Wire *nxj_m1_i, RTLIL::Wire *twoi_n_i, RTLIL::Wire *xj_i, RTLIL::Wire *negi_i, RTLIL::Wire *onei_n_i,
 | 
			
		||||
 | 
			
		||||
		       RTLIL::Wire *&ppij_o, RTLIL::Wire *&nxj_o)
 | 
			
		||||
	void BuildBr4d(std::string &name, SigBit nxj_m1_i, SigBit twoi_n_i, SigBit xj_i, SigBit negi_i, SigBit onei_n_i,
 | 
			
		||||
		       SigBit &ppij_o, SigBit &nxj_o)
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
		std::string empty;
 | 
			
		||||
| 
						 | 
				
			
			@ -227,8 +224,8 @@ struct BoothPassWorker {
 | 
			
		|||
		// nxj_o = xnj_in,
 | 
			
		||||
		// ppij = ~( (nxj_m1_i | twoi_n_i) & (nxj_int | onei_n_i));
 | 
			
		||||
		nxj_o = mk_ugate2(ID($xnor), name, xj_i, negi_i, empty);
 | 
			
		||||
		RTLIL::Wire *or1 = mk_ugate2(ID($or), name, nxj_m1_i, twoi_n_i, empty);
 | 
			
		||||
		RTLIL::Wire *or2 = mk_ugate2(ID($or), name, nxj_o, onei_n_i, empty);
 | 
			
		||||
		SigBit or1 = mk_ugate2(ID($or), name, nxj_m1_i, twoi_n_i, empty);
 | 
			
		||||
		SigBit or2 = mk_ugate2(ID($or), name, nxj_o, onei_n_i, empty);
 | 
			
		||||
		ppij_o = mk_ugate1(ID($not), name, mk_ugate2(ID($and), name, or1, or2, empty), empty);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -237,12 +234,9 @@ struct BoothPassWorker {
 | 
			
		|||
	  using non-booth encoded logic. We can save a booth
 | 
			
		||||
	  encoder for the first couple of bits.
 | 
			
		||||
	*/
 | 
			
		||||
	void BuildBoothQ1(std::string &name, RTLIL::Wire *negi_i, RTLIL::Wire *cori_i, RTLIL::Wire *x0_i, RTLIL::Wire *x1_i, RTLIL::Wire *y0_i,
 | 
			
		||||
			  RTLIL::Wire *y1_i,
 | 
			
		||||
 | 
			
		||||
			  RTLIL::Wire *&nxj_o, RTLIL::Wire *&cor_o, RTLIL::Wire *&pp0_o, RTLIL::Wire *&pp1_o
 | 
			
		||||
 | 
			
		||||
	)
 | 
			
		||||
	void BuildBoothQ1(std::string &name, SigBit negi_i, SigBit cori_i, SigBit x0_i, SigBit x1_i, SigBit y0_i,
 | 
			
		||||
			  SigBit y1_i,
 | 
			
		||||
			  SigBit &nxj_o, SigBit &cor_o, SigBit &pp0_o, SigBit &pp1_o)
 | 
			
		||||
	{
 | 
			
		||||
		/*
 | 
			
		||||
		  assign NXJO = ~(X1 ^ NEGI);
 | 
			
		||||
| 
						 | 
				
			
			@ -258,11 +252,11 @@ struct BoothPassWorker {
 | 
			
		|||
		std::string empty;
 | 
			
		||||
		nxj_o = mk_ugate2(ID($xnor), name, x1_i, negi_i, empty);
 | 
			
		||||
		pp0_o = mk_ugate2(ID($and), name, x0_i, y0_i, empty);
 | 
			
		||||
		RTLIL::Wire *pp1_1_int = mk_ugate2(ID($and), name, x1_i, y0_i, empty);
 | 
			
		||||
		RTLIL::Wire *pp1_2_int = mk_ugate2(ID($and), name, x0_i, y1_i, empty);
 | 
			
		||||
		SigBit pp1_1_int = mk_ugate2(ID($and), name, x1_i, y0_i, empty);
 | 
			
		||||
		SigBit pp1_2_int = mk_ugate2(ID($and), name, x0_i, y1_i, empty);
 | 
			
		||||
		pp1_o = mk_ugate2(ID($xor), name, pp1_1_int, pp1_2_int, empty);
 | 
			
		||||
 | 
			
		||||
		RTLIL::Wire *pp1_nor_pp0 = mk_ugate1(ID($not), name, mk_ugate2(ID($or), name, pp1_o, pp0_o, empty), empty);
 | 
			
		||||
		SigBit pp1_nor_pp0 = mk_ugate1(ID($not), name, mk_ugate2(ID($or), name, pp1_o, pp0_o, empty), empty);
 | 
			
		||||
		cor_o = mk_ugate2(ID($and), name, pp1_nor_pp0, cori_i, empty);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -355,13 +349,13 @@ struct BoothPassWorker {
 | 
			
		|||
					buf->setPort(ID::Y, SigSpec(Y));
 | 
			
		||||
 | 
			
		||||
					if (is_signed == false) /* unsigned multiplier */
 | 
			
		||||
						CreateBoothUMult(module, x_sz_revised, y_sz_revised, required_op_size,
 | 
			
		||||
						CreateBoothUMult(module,
 | 
			
		||||
								 expanded_A, // multiplicand
 | 
			
		||||
								 expanded_B, // multiplier(scanned)
 | 
			
		||||
								 expanded_Y  // result
 | 
			
		||||
						);
 | 
			
		||||
					else /*signed multiplier */
 | 
			
		||||
						CreateBoothSMult(module, x_sz_revised, y_sz_revised, required_op_size,
 | 
			
		||||
						CreateBoothSMult(module,
 | 
			
		||||
								 expanded_A, // multiplicand
 | 
			
		||||
								 expanded_B, // multiplier(scanned)
 | 
			
		||||
								 expanded_Y  // result (sized)
 | 
			
		||||
| 
						 | 
				
			
			@ -382,19 +376,17 @@ struct BoothPassWorker {
 | 
			
		|||
	  extra row of decoders and extended multiplier
 | 
			
		||||
	*/
 | 
			
		||||
 | 
			
		||||
	void CreateBoothUMult(RTLIL::Module *module, int x_sz, int y_sz, int z_sz,
 | 
			
		||||
			      RTLIL::Wire *X, // multiplicand
 | 
			
		||||
			      RTLIL::Wire *Y, // multiplier
 | 
			
		||||
			      RTLIL::Wire *Z)
 | 
			
		||||
	void CreateBoothUMult(RTLIL::Module *module,
 | 
			
		||||
			      SigSpec X, // multiplicand
 | 
			
		||||
			      SigSpec Y, // multiplier
 | 
			
		||||
			      SigSpec Z)
 | 
			
		||||
	{ // result
 | 
			
		||||
		int x_sz = X.size(), z_sz = Z.size();
 | 
			
		||||
 | 
			
		||||
		std::vector<RTLIL::Wire *> one_int;
 | 
			
		||||
		std::vector<RTLIL::Wire *> two_int;
 | 
			
		||||
		std::vector<RTLIL::Wire *> s_int;
 | 
			
		||||
		std::vector<RTLIL::Wire *> sb_int;
 | 
			
		||||
		SigSpec one_int, two_int, s_int, sb_int;
 | 
			
		||||
		int encoder_count = 0;
 | 
			
		||||
 | 
			
		||||
		BuildBoothUMultEncoders(Y, y_sz, one_int, two_int, s_int, sb_int, module, encoder_count);
 | 
			
		||||
		BuildBoothUMultEncoders(Y, one_int, two_int, s_int, sb_int, module, encoder_count);
 | 
			
		||||
 | 
			
		||||
		// Build the decoder rows
 | 
			
		||||
		// format of each Partial product to be passed to CSA
 | 
			
		||||
| 
						 | 
				
			
			@ -404,31 +396,10 @@ struct BoothPassWorker {
 | 
			
		|||
		// Shift
 | 
			
		||||
		// Sign bit to be added
 | 
			
		||||
		//
 | 
			
		||||
		std::vector<std::tuple<std::vector<RTLIL::Wire *>, int, RTLIL::Wire *>> ppij_int;
 | 
			
		||||
 | 
			
		||||
		static int constant_ix;
 | 
			
		||||
		constant_ix++;
 | 
			
		||||
		std::string buf_name = "constant_buf_" + std::to_string(constant_ix);
 | 
			
		||||
		auto buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos));
 | 
			
		||||
		RTLIL::Wire *constant_one = module->addWire(new_id(buf_name, __LINE__, ""), 1);
 | 
			
		||||
		buf->setPort(ID::A, State::S1);
 | 
			
		||||
		buf->setParam(ID::A_WIDTH, 1);
 | 
			
		||||
		buf->setParam(ID::Y_WIDTH, 1);
 | 
			
		||||
		buf->setParam(ID::A_SIGNED, true);
 | 
			
		||||
		buf->setPort(ID::Y, constant_one);
 | 
			
		||||
 | 
			
		||||
		constant_ix++;
 | 
			
		||||
		buf_name = "constant_buf_" + std::to_string(constant_ix);
 | 
			
		||||
		buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos));
 | 
			
		||||
		RTLIL::Wire *constant_zero = module->addWire(new_id(buf_name, __LINE__, ""), 1);
 | 
			
		||||
		buf->setPort(ID::A, State::S0);
 | 
			
		||||
		buf->setParam(ID::A_WIDTH, 1);
 | 
			
		||||
		buf->setParam(ID::Y_WIDTH, 1);
 | 
			
		||||
		buf->setParam(ID::A_SIGNED, true);
 | 
			
		||||
		buf->setPort(ID::Y, constant_zero);
 | 
			
		||||
		std::vector<std::tuple<SigSpec, int, SigBit>> ppij_int;
 | 
			
		||||
 | 
			
		||||
		// Row 0: special case 1. Format S/.S.S.C.Data
 | 
			
		||||
		std::vector<RTLIL::Wire *> ppij_row_0;
 | 
			
		||||
		SigSpec ppij_row_0;
 | 
			
		||||
		BuildBoothUMultDecoderRow0(module, X, s_int, sb_int, one_int, two_int, ppij_row_0);
 | 
			
		||||
 | 
			
		||||
		// data, shift, sign
 | 
			
		||||
| 
						 | 
				
			
			@ -436,11 +407,11 @@ struct BoothPassWorker {
 | 
			
		|||
 | 
			
		||||
		for (int i = 1; i < encoder_count - 2; i++) {
 | 
			
		||||
			// format 1,S.Data.shift = encoder_ix*2,sign = sb_int[i]
 | 
			
		||||
			std::vector<RTLIL::Wire *> ppij_row_n;
 | 
			
		||||
			SigSpec ppij_row_n;
 | 
			
		||||
 | 
			
		||||
			BuildBoothUMultDecoderRowN(module,
 | 
			
		||||
						   X, // multiplicand
 | 
			
		||||
						   one_int[i], two_int[i], s_int[i], sb_int[i], ppij_row_n, constant_one, i,
 | 
			
		||||
						   one_int[i], two_int[i], s_int[i], sb_int[i], ppij_row_n, i,
 | 
			
		||||
						   false, // include sign
 | 
			
		||||
						   false  // include constant
 | 
			
		||||
			);
 | 
			
		||||
| 
						 | 
				
			
			@ -450,18 +421,18 @@ struct BoothPassWorker {
 | 
			
		|||
 | 
			
		||||
		// Build second to last row
 | 
			
		||||
		// format S/,Data + sign bit
 | 
			
		||||
		std::vector<RTLIL::Wire *> ppij_row_em1;
 | 
			
		||||
		SigSpec ppij_row_em1;
 | 
			
		||||
		BuildBoothUMultDecoderRowN(module, X, one_int[encoder_count - 2], two_int[encoder_count - 2], s_int[encoder_count - 2],
 | 
			
		||||
					   sb_int[encoder_count - 2], ppij_row_em1, constant_one, encoder_count - 2,
 | 
			
		||||
					   sb_int[encoder_count - 2], ppij_row_em1, encoder_count - 2,
 | 
			
		||||
					   false, // include sign
 | 
			
		||||
					   true	  // no constant
 | 
			
		||||
		);
 | 
			
		||||
		ppij_int.push_back(std::make_tuple(ppij_row_em1, (encoder_count - 2) * 2, s_int[encoder_count - 2]));
 | 
			
		||||
		// Build last row
 | 
			
		||||
		// format Data + sign bit
 | 
			
		||||
		std::vector<RTLIL::Wire *> ppij_row_e;
 | 
			
		||||
		SigSpec ppij_row_e;
 | 
			
		||||
		BuildBoothUMultDecoderRowN(module, X, one_int[encoder_count - 1], two_int[encoder_count - 1], s_int[encoder_count - 1],
 | 
			
		||||
					   sb_int[encoder_count - 1], ppij_row_e, constant_one, encoder_count - 1,
 | 
			
		||||
					   sb_int[encoder_count - 1], ppij_row_e, encoder_count - 1,
 | 
			
		||||
					   true, // no sign
 | 
			
		||||
					   true	 // no constant
 | 
			
		||||
		);
 | 
			
		||||
| 
						 | 
				
			
			@ -471,13 +442,13 @@ struct BoothPassWorker {
 | 
			
		|||
		//  DebugDumpPP(ppij_int);
 | 
			
		||||
 | 
			
		||||
		// Summation of Partial Products (Wallace Tree)
 | 
			
		||||
		std::vector<std::vector<RTLIL::Wire *>> aligned_pp;
 | 
			
		||||
		std::vector<SigSpec> aligned_pp;
 | 
			
		||||
		aligned_pp.resize(encoder_count + 1); // make an entirely redundant row
 | 
			
		||||
		// just for sign bit in lsb. (We then filter this out).
 | 
			
		||||
 | 
			
		||||
		// resize all to be same size as z
 | 
			
		||||
		for (int i = 0; i < encoder_count + 1; i++)
 | 
			
		||||
			aligned_pp[i].resize(z_sz);
 | 
			
		||||
			aligned_pp[i].extend_u0(z_sz);
 | 
			
		||||
 | 
			
		||||
		AlignPP(x_sz, z_sz, ppij_int, aligned_pp);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -485,8 +456,8 @@ struct BoothPassWorker {
 | 
			
		|||
		// Later on yosys will clean up unused constants
 | 
			
		||||
		//  DebugDumpAlignPP(aligned_pp);
 | 
			
		||||
 | 
			
		||||
		std::vector<RTLIL::Wire *> s_vec;
 | 
			
		||||
		std::vector<RTLIL::Wire *> c_vec;
 | 
			
		||||
		SigSpec s_vec;
 | 
			
		||||
		SigSpec c_vec;
 | 
			
		||||
		std::vector<std::vector<RTLIL::Cell *>> debug_csa_trees;
 | 
			
		||||
 | 
			
		||||
		debug_csa_trees.resize(z_sz);
 | 
			
		||||
| 
						 | 
				
			
			@ -504,9 +475,9 @@ struct BoothPassWorker {
 | 
			
		|||
	*/
 | 
			
		||||
 | 
			
		||||
	void BuildBoothUMultDecoderRow0(RTLIL::Module *module,
 | 
			
		||||
					RTLIL::Wire *X, // multiplicand
 | 
			
		||||
					std::vector<RTLIL::Wire *> &s_int, std::vector<RTLIL::Wire *> &sb_int, std::vector<RTLIL::Wire *> &one_int,
 | 
			
		||||
					std::vector<RTLIL::Wire *> &two_int, std::vector<RTLIL::Wire *> &ppij_vec)
 | 
			
		||||
					SigSpec X, // multiplicand
 | 
			
		||||
					SigSpec s_int, SigSpec sb_int, SigSpec one_int,
 | 
			
		||||
					SigSpec two_int, SigSpec &ppij_vec)
 | 
			
		||||
	{
 | 
			
		||||
		(void)module;
 | 
			
		||||
		int x_sz = GetSize(X);
 | 
			
		||||
| 
						 | 
				
			
			@ -514,73 +485,72 @@ struct BoothPassWorker {
 | 
			
		|||
		// lsb
 | 
			
		||||
		std::string dec_name = "row0_lsb_dec";
 | 
			
		||||
 | 
			
		||||
		RTLIL::Wire *ppij;
 | 
			
		||||
		SigBit ppij;
 | 
			
		||||
		std::string ppij_name = "ppij_0_0";
 | 
			
		||||
		BuildBur4d_lsb(dec_name, mk_wireFromSigSpec(SigSpec(X, 0, 1)), one_int[0], s_int[0], ppij, ppij_name);
 | 
			
		||||
		ppij_vec.push_back(ppij);
 | 
			
		||||
		BuildBur4d_lsb(dec_name, X[0], one_int[0], s_int[0], ppij, ppij_name);
 | 
			
		||||
		ppij_vec.append(ppij);
 | 
			
		||||
 | 
			
		||||
		// 1..xsize -1
 | 
			
		||||
		for (int i = 1; i < x_sz; i++) {
 | 
			
		||||
			dec_name = "row0_dec_" + std::to_string(i);
 | 
			
		||||
			RTLIL::Wire *ppij;
 | 
			
		||||
			BuildBur4d_n(dec_name, mk_wireFromSigSpec(SigSpec(X, i, 1)), mk_wireFromSigSpec(SigSpec(X, i - 1, 1)), one_int[0], two_int[0],
 | 
			
		||||
			SigBit ppij;
 | 
			
		||||
			BuildBur4d_n(dec_name, X[i], X[i - 1], one_int[0], two_int[0],
 | 
			
		||||
				     s_int[0], ppij);
 | 
			
		||||
			ppij_vec.push_back(ppij);
 | 
			
		||||
			ppij_vec.append(ppij);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// The redundant bit. Duplicate decoding of last bit.
 | 
			
		||||
		dec_name = "row0_dec_msb";
 | 
			
		||||
		BuildBur4d_msb(dec_name, mk_wireFromSigSpec(SigSpec(X, x_sz - 1, 1)), two_int[0], s_int[0], ppij);
 | 
			
		||||
		ppij_vec.push_back(ppij);
 | 
			
		||||
		BuildBur4d_msb(dec_name, X[x_sz - 1], two_int[0], s_int[0], ppij);
 | 
			
		||||
		ppij_vec.append(ppij);
 | 
			
		||||
 | 
			
		||||
		// append the sign bits
 | 
			
		||||
		ppij_vec.push_back(s_int[0]);
 | 
			
		||||
		ppij_vec.push_back(s_int[0]);
 | 
			
		||||
		ppij_vec.push_back(sb_int[0]);
 | 
			
		||||
		ppij_vec.append(s_int[0]);
 | 
			
		||||
		ppij_vec.append(s_int[0]);
 | 
			
		||||
		ppij_vec.append(sb_int[0]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Build a generic row of decoders.
 | 
			
		||||
 | 
			
		||||
	void BuildBoothUMultDecoderRowN(RTLIL::Module *module,
 | 
			
		||||
					RTLIL::Wire *X, // multiplicand
 | 
			
		||||
					RTLIL::Wire *one_int, RTLIL::Wire *two_int, RTLIL::Wire *s_int, RTLIL::Wire *sb_int,
 | 
			
		||||
					std::vector<RTLIL::Wire *> &ppij_vec, RTLIL::Wire *constant_one, int row_ix, bool no_sign, bool no_constant)
 | 
			
		||||
					SigSpec X, // multiplicand
 | 
			
		||||
					SigSpec one_int, SigSpec two_int, SigSpec s_int, SigSpec sb_int,
 | 
			
		||||
					SigSpec &ppij_vec, int row_ix, bool no_sign, bool no_constant)
 | 
			
		||||
	{
 | 
			
		||||
		(void)module;
 | 
			
		||||
		int x_sz = GetSize(X);
 | 
			
		||||
 | 
			
		||||
		// lsb
 | 
			
		||||
		std::string ppij_name = "ppij_" + std::to_string(row_ix) + "_0";
 | 
			
		||||
		RTLIL::Wire *ppij = nullptr;
 | 
			
		||||
		SigBit ppij;
 | 
			
		||||
		std::string empty;
 | 
			
		||||
		std::string dec_name = "row" + std::to_string(row_ix) + "_lsb_dec";
 | 
			
		||||
		BuildBur4d_lsb(dec_name, mk_wireFromSigSpec(SigSpec(X, 0, 1)), one_int, s_int, ppij, empty);
 | 
			
		||||
		BuildBur4d_lsb(dec_name, X[0], one_int, s_int, ppij, empty);
 | 
			
		||||
 | 
			
		||||
		ppij_vec.push_back(ppij);
 | 
			
		||||
		ppij_vec.append(ppij);
 | 
			
		||||
 | 
			
		||||
		// core bits
 | 
			
		||||
		for (int i = 1; i < x_sz; i++) {
 | 
			
		||||
 | 
			
		||||
			dec_name = "row_" + std::to_string(row_ix) + "_dec_" + std::to_string(i);
 | 
			
		||||
			RTLIL::Wire *ppij = nullptr;
 | 
			
		||||
			BuildBur4d_n(dec_name, mk_wireFromSigSpec(SigSpec(X, i, 1)), mk_wireFromSigSpec(SigSpec(X, i - 1, 1)), one_int, two_int,
 | 
			
		||||
				     s_int, ppij);
 | 
			
		||||
			ppij_vec.push_back(ppij);
 | 
			
		||||
			BuildBur4d_n(dec_name, X[i], X[i - 1],
 | 
			
		||||
				     one_int, two_int, s_int, ppij);
 | 
			
		||||
			ppij_vec.append(ppij);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// redundant bit
 | 
			
		||||
 | 
			
		||||
		dec_name = "row_dec_red";
 | 
			
		||||
		BuildBur4d_msb(dec_name, mk_wireFromSigSpec(SigSpec(X, x_sz - 1, 1)), two_int, s_int, ppij);
 | 
			
		||||
		ppij_vec.push_back(ppij);
 | 
			
		||||
		BuildBur4d_msb(dec_name, X[x_sz - 1], two_int, s_int, ppij);
 | 
			
		||||
		ppij_vec.append(ppij);
 | 
			
		||||
 | 
			
		||||
		// sign bit
 | 
			
		||||
		if (no_sign == false) // if no sign is false then make a sign bit
 | 
			
		||||
			ppij_vec.push_back(sb_int);
 | 
			
		||||
			ppij_vec.append(sb_int);
 | 
			
		||||
 | 
			
		||||
		// constant bit
 | 
			
		||||
		if (no_constant == false) { // if non constant is false make a constant bit
 | 
			
		||||
			ppij_vec.push_back(constant_one);
 | 
			
		||||
			ppij_vec.append(State::S1);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -663,8 +633,8 @@ struct BoothPassWorker {
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void BuildCSATree(RTLIL::Module *module, std::vector<std::vector<RTLIL::Wire *>> &bits_to_reduce, std::vector<RTLIL::Wire *> &s_vec,
 | 
			
		||||
			  std::vector<RTLIL::Wire *> &c_vec, std::vector<std::vector<RTLIL::Cell *>> &debug_csa_trees)
 | 
			
		||||
	void BuildCSATree(RTLIL::Module *module, std::vector<SigSpec> &bits_to_reduce, SigSpec &s_vec,
 | 
			
		||||
			  SigSpec &c_vec, std::vector<std::vector<RTLIL::Cell *>> &debug_csa_trees)
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
		if (!(bits_to_reduce.size() > 0))
 | 
			
		||||
| 
						 | 
				
			
			@ -672,24 +642,24 @@ struct BoothPassWorker {
 | 
			
		|||
 | 
			
		||||
		int column_size = bits_to_reduce[0].size();
 | 
			
		||||
		int row_size = bits_to_reduce.size();
 | 
			
		||||
		std::vector<RTLIL::Wire *> carry_bits_to_add_to_next_column;
 | 
			
		||||
		SigSpec carry_bits_to_add_to_next_column;
 | 
			
		||||
 | 
			
		||||
		for (int column_ix = 0; column_ix < column_size; column_ix++) {
 | 
			
		||||
 | 
			
		||||
			// get the bits in this column.
 | 
			
		||||
			std::vector<RTLIL::Wire *> column_bits;
 | 
			
		||||
			SigSpec column_bits;
 | 
			
		||||
			for (int row_ix = 0; row_ix < row_size; row_ix++) {
 | 
			
		||||
				if (bits_to_reduce[row_ix].at(column_ix))
 | 
			
		||||
					column_bits.push_back(bits_to_reduce[row_ix].at(column_ix));
 | 
			
		||||
				if (bits_to_reduce[row_ix][column_ix].wire)
 | 
			
		||||
					column_bits.append(bits_to_reduce[row_ix][column_ix]);
 | 
			
		||||
			}
 | 
			
		||||
			for (auto c : carry_bits_to_add_to_next_column) {
 | 
			
		||||
#ifdef DEBUG_CSA
 | 
			
		||||
				printf("\t Propagating column bit %s to column %d from column %d\n", c->name.c_str(), column_ix, column_ix - 1);
 | 
			
		||||
#endif
 | 
			
		||||
				column_bits.push_back(c);
 | 
			
		||||
				column_bits.append(c);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			carry_bits_to_add_to_next_column.resize(0);
 | 
			
		||||
			carry_bits_to_add_to_next_column = {};
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_CSA
 | 
			
		||||
			printf("Column %d Reducing %d bits\n", column_ix, column_bits.size());
 | 
			
		||||
| 
						 | 
				
			
			@ -699,16 +669,15 @@ struct BoothPassWorker {
 | 
			
		|||
			printf("\n");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			RTLIL::Wire *s = nullptr;
 | 
			
		||||
			RTLIL::Wire *c = nullptr;
 | 
			
		||||
			SigBit s, c;
 | 
			
		||||
#ifdef DEBUG_CSA
 | 
			
		||||
			int csa_count_before = debug_csa_trees[column_ix].size();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			ReduceBits(module, column_ix, column_bits, s, c, carry_bits_to_add_to_next_column, debug_csa_trees);
 | 
			
		||||
 | 
			
		||||
			s_vec.push_back(s);
 | 
			
		||||
			c_vec.push_back(c);
 | 
			
		||||
			s_vec.append(s);
 | 
			
		||||
			c_vec.append(c);
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_CSA
 | 
			
		||||
			int csa_count_after = debug_csa_trees[column_ix].size();
 | 
			
		||||
| 
						 | 
				
			
			@ -738,8 +707,8 @@ struct BoothPassWorker {
 | 
			
		|||
	  Pad out rows with zeros and left the opt pass clean them up.
 | 
			
		||||
 | 
			
		||||
	*/
 | 
			
		||||
	void AlignPP(int x_sz, int z_sz, std::vector<std::tuple<std::vector<RTLIL::Wire *>, int, RTLIL::Wire *>> &ppij_int,
 | 
			
		||||
		     std::vector<std::vector<RTLIL::Wire *>> &aligned_pp)
 | 
			
		||||
	void AlignPP(int x_sz, int z_sz, std::vector<std::tuple<SigSpec, int, SigBit>> &ppij_int,
 | 
			
		||||
		     std::vector<SigSpec> &aligned_pp)
 | 
			
		||||
	{
 | 
			
		||||
		unsigned aligned_pp_ix = aligned_pp.size() - 1;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -748,7 +717,7 @@ struct BoothPassWorker {
 | 
			
		|||
 | 
			
		||||
		for (unsigned i = 0; i < aligned_pp.size(); i++) {
 | 
			
		||||
			for (int j = 0; j < z_sz; j++) {
 | 
			
		||||
				aligned_pp[i][j] = nullptr;
 | 
			
		||||
				aligned_pp[i][j] = State::S0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -758,21 +727,19 @@ struct BoothPassWorker {
 | 
			
		|||
		// in first column of the last partial product
 | 
			
		||||
		// which is at index corresponding to size of multiplicand
 | 
			
		||||
		{
 | 
			
		||||
			RTLIL::Wire *prior_row_sign = nullptr;
 | 
			
		||||
			prior_row_sign = get<2>(ppij_int[aligned_pp_ix - 1]);
 | 
			
		||||
			if (prior_row_sign) {
 | 
			
		||||
			SigBit prior_row_sign = get<2>(ppij_int[aligned_pp_ix - 1]);
 | 
			
		||||
			//if (prior_row_sign) {
 | 
			
		||||
				log_assert(aligned_pp_ix < aligned_pp.size());
 | 
			
		||||
				log_assert(x_sz - 1 < (int)(aligned_pp[aligned_pp_ix].size()));
 | 
			
		||||
				aligned_pp[aligned_pp_ix][x_sz - 1] = prior_row_sign;
 | 
			
		||||
			}
 | 
			
		||||
			//}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (int row_ix = aligned_pp_ix - 1; row_ix >= 0; row_ix--) {
 | 
			
		||||
			int shift_amount = get<1>(ppij_int[row_ix]);
 | 
			
		||||
			RTLIL::Wire *prior_row_sign = nullptr;
 | 
			
		||||
 | 
			
		||||
			// copy in data
 | 
			
		||||
			unsigned copy_ix = shift_amount;
 | 
			
		||||
			int copy_ix = shift_amount;
 | 
			
		||||
			for (auto w : get<0>(ppij_int[row_ix])) {
 | 
			
		||||
				if (copy_ix < aligned_pp[row_ix].size()) {
 | 
			
		||||
					aligned_pp[row_ix][copy_ix] = w;
 | 
			
		||||
| 
						 | 
				
			
			@ -786,7 +753,7 @@ struct BoothPassWorker {
 | 
			
		|||
				// the destination of the sign bit is the (row_ix -1)*2
 | 
			
		||||
				// eg destination for sign bit for row 0 is 0.
 | 
			
		||||
				// eg destination for sign bit for row 1 is 1
 | 
			
		||||
				prior_row_sign = get<2>(ppij_int[row_ix - 1]);
 | 
			
		||||
				SigBit prior_row_sign = get<2>(ppij_int[row_ix - 1]);
 | 
			
		||||
				copy_ix = (row_ix - 1) * 2;
 | 
			
		||||
				aligned_pp[row_ix][copy_ix] = prior_row_sign;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -797,32 +764,23 @@ struct BoothPassWorker {
 | 
			
		|||
	  Build a Carry Propagate Adder
 | 
			
		||||
	  -----------------------------
 | 
			
		||||
	  First build the sum and carry vectors to be added.
 | 
			
		||||
	  Axioms:
 | 
			
		||||
	  c_vec.size() == s_vec.size()
 | 
			
		||||
	  result.size() == s_vec.size() + 2; (assume result is reserved to hold correct size)
 | 
			
		||||
	*/
 | 
			
		||||
	void BuildCPA(RTLIL::Module *module, std::vector<RTLIL::Wire *> &s_vec, std::vector<RTLIL::Wire *> &c_vec, RTLIL::Wire *result)
 | 
			
		||||
	void BuildCPA(RTLIL::Module *module, SigSpec s_vec, SigSpec c_vec, SigSpec result)
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
		static int cpa_id;
 | 
			
		||||
		cpa_id++;
 | 
			
		||||
 | 
			
		||||
		RTLIL::Wire *carry = nullptr;
 | 
			
		||||
		log_assert(c_vec.size() == s_vec.size());
 | 
			
		||||
		// TODO: doesn't pass
 | 
			
		||||
		//log_assert(result.size() == s_vec.size() + 2);
 | 
			
		||||
 | 
			
		||||
		log_assert(s_vec.size() == c_vec.size());
 | 
			
		||||
 | 
			
		||||
		for (unsigned n = 0; n < s_vec.size(); n++) {
 | 
			
		||||
		SigBit carry;
 | 
			
		||||
		for (int n = 0; n < s_vec.size(); n++) {
 | 
			
		||||
			std::string carry_name;
 | 
			
		||||
 | 
			
		||||
			// Base Case: Bit 0 is sum 0
 | 
			
		||||
			if (n == 0) {
 | 
			
		||||
				std::string buf_name = "base_buf_" + std::to_string(cpa_id) + "_" + std::to_string(n);
 | 
			
		||||
				auto buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos));
 | 
			
		||||
				buf->setPort(ID::A, s_vec[0]);
 | 
			
		||||
				buf->setParam(ID::A_WIDTH, 1);
 | 
			
		||||
				buf->setParam(ID::Y_WIDTH, 1);
 | 
			
		||||
				buf->setParam(ID::A_SIGNED, false);
 | 
			
		||||
				buf->setPort(ID::Y, SigSpec(result, 0, 1));
 | 
			
		||||
				module->addBufGate(NEW_ID_SUFFIX(stringf("base_buf_%d_%d", cpa_id, n)), s_vec[0], result[0]);
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_CPA
 | 
			
		||||
				printf("CPA bit [%d] Cell %s IP 0 %s \n", n, buf->name.c_str(), s_vec[0]->name.c_str());
 | 
			
		||||
| 
						 | 
				
			
			@ -835,10 +793,9 @@ struct BoothPassWorker {
 | 
			
		|||
			//
 | 
			
		||||
			else if (n == 1) {
 | 
			
		||||
				std::string ha_name = "cpa_" + std::to_string(cpa_id) + "_ha_" + std::to_string(n);
 | 
			
		||||
				RTLIL::Wire *ha_op;
 | 
			
		||||
				SigBit ha_op;
 | 
			
		||||
				BuildHa(ha_name, s_vec[n], c_vec[n - 1], ha_op, carry);
 | 
			
		||||
 | 
			
		||||
				module->connect(ha_op, SigSpec(result, n, 1));
 | 
			
		||||
				module->connect(result[n], ha_op);
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_CPA
 | 
			
		||||
				printf("CPA bit [%d] Cell %s IPs [%s] [%s] \n", n, ha_cell->name.c_str(), s_vec[n]->name.c_str(),
 | 
			
		||||
| 
						 | 
				
			
			@ -847,9 +804,10 @@ struct BoothPassWorker {
 | 
			
		|||
 | 
			
		||||
			}
 | 
			
		||||
			// End Case
 | 
			
		||||
			else if (n == (unsigned)((s_vec.size() - 1))) {
 | 
			
		||||
			else if (n == s_vec.size() - 1) {
 | 
			
		||||
				// Make the carry results.. Two extra bits after fa.
 | 
			
		||||
				std::string fa_name = "cpa_" + std::to_string(cpa_id) + "_fa_" + std::to_string(n);
 | 
			
		||||
 | 
			
		||||
				auto fa_cell = module->addCell(new_id(fa_name, __LINE__, ""), ID($fa));
 | 
			
		||||
				fa_cell->setParam(ID::WIDTH, 1);
 | 
			
		||||
				carry_name = "cpa_" + std::to_string(cpa_id) + "carry_" + std::to_string(n);
 | 
			
		||||
| 
						 | 
				
			
			@ -857,7 +815,7 @@ struct BoothPassWorker {
 | 
			
		|||
				fa_cell->setPort(ID::B, c_vec[n - 1]);
 | 
			
		||||
				fa_cell->setPort(ID::C, carry);
 | 
			
		||||
				// wire in result and carry out
 | 
			
		||||
				fa_cell->setPort(ID::Y, SigSpec(result, n, 1));
 | 
			
		||||
				fa_cell->setPort(ID::Y, result[n]);
 | 
			
		||||
 | 
			
		||||
				// make a new carry bit for carry out...
 | 
			
		||||
				carry = module->addWire(new_id(carry_name, __LINE__, ""), 1);
 | 
			
		||||
| 
						 | 
				
			
			@ -867,16 +825,16 @@ struct BoothPassWorker {
 | 
			
		|||
				printf("CPA bit [%d] Cell %s IPs [%s] [%s] [%s]\n", n, fa_cell->name.c_str(), s_vec[n]->name.c_str(),
 | 
			
		||||
				       c_vec[n - 1]->name.c_str(), carry->name.c_str());
 | 
			
		||||
#endif
 | 
			
		||||
				if (n + 1 < (unsigned)(GetSize(result))) {
 | 
			
		||||
				if (n + 1 < GetSize(result)) {
 | 
			
		||||
					// Now make a half adder: c_vec[n] = carry
 | 
			
		||||
					std::string ha_name = "cpa_" + std::to_string(cpa_id) + "_ha_" + std::to_string(n);
 | 
			
		||||
					RTLIL::Wire *ha_sum;
 | 
			
		||||
					RTLIL::Wire *ha_carry;
 | 
			
		||||
					SigBit ha_sum;
 | 
			
		||||
					SigBit ha_carry;
 | 
			
		||||
					BuildHa(ha_name, c_vec[n], carry, ha_sum, ha_carry);
 | 
			
		||||
					if (n + 1 < (unsigned)GetSize(result))
 | 
			
		||||
						module->connect(ha_sum, SigSpec(result, n + 1, 1));
 | 
			
		||||
					if (n + 2 < (unsigned)GetSize(result))
 | 
			
		||||
						module->connect(ha_carry, SigSpec(result, n + 2, 1));
 | 
			
		||||
					if (n + 1 < GetSize(result))
 | 
			
		||||
						module->connect(result[n + 1], ha_sum);
 | 
			
		||||
					if (n + 2 < GetSize(result))
 | 
			
		||||
						module->connect(result[n + 2], ha_carry);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			// Step case
 | 
			
		||||
| 
						 | 
				
			
			@ -890,7 +848,7 @@ struct BoothPassWorker {
 | 
			
		|||
				fa_cell->setPort(ID::B, c_vec[n - 1]);
 | 
			
		||||
				fa_cell->setPort(ID::C, carry);
 | 
			
		||||
				// wire in result and carry out
 | 
			
		||||
				fa_cell->setPort(ID::Y, SigSpec(result, n, 1));
 | 
			
		||||
				fa_cell->setPort(ID::Y, result[n]);
 | 
			
		||||
				// make a new carry bit for carry out...
 | 
			
		||||
				carry = module->addWire(new_id(carry_name, __LINE__, ""), 1);
 | 
			
		||||
				fa_cell->setPort(ID::X, carry);
 | 
			
		||||
| 
						 | 
				
			
			@ -907,8 +865,8 @@ struct BoothPassWorker {
 | 
			
		|||
	// Pass the carry bits from each csa to the next
 | 
			
		||||
	// column for summation.
 | 
			
		||||
 | 
			
		||||
	void ReduceBits(RTLIL::Module *module, int column_ix, std::vector<RTLIL::Wire *> &column_bits, RTLIL::Wire *&s_result, RTLIL::Wire *&c_result,
 | 
			
		||||
			std::vector<RTLIL::Wire *> &carry_bits_to_sum, std::vector<std::vector<RTLIL::Cell *>> &debug_csa_trees)
 | 
			
		||||
	void ReduceBits(RTLIL::Module *module, int column_ix, SigSpec column_bits, SigBit &s_result, SigBit &c_result,
 | 
			
		||||
			SigSpec &carry_bits_to_sum, std::vector<std::vector<RTLIL::Cell *>> &debug_csa_trees)
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
		int csa_ix = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -918,12 +876,12 @@ struct BoothPassWorker {
 | 
			
		|||
		unique_id++;
 | 
			
		||||
 | 
			
		||||
		if (column_size > 0) {
 | 
			
		||||
			unsigned var_ix = 0;
 | 
			
		||||
			std::vector<RTLIL::Wire *> first_csa_ips;
 | 
			
		||||
			int var_ix = 0;
 | 
			
		||||
			SigSpec first_csa_ips;
 | 
			
		||||
			// get the first 3 inputs, if possible
 | 
			
		||||
			for (var_ix = 0; var_ix < column_bits.size() && first_csa_ips.size() != 3; var_ix++) {
 | 
			
		||||
				if (column_bits[var_ix])
 | 
			
		||||
					first_csa_ips.push_back(column_bits[var_ix]);
 | 
			
		||||
				if (column_bits[var_ix].is_wire())
 | 
			
		||||
					first_csa_ips.append(column_bits[var_ix]);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (first_csa_ips.size() > 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -961,16 +919,16 @@ struct BoothPassWorker {
 | 
			
		|||
				c_result = c_wire;
 | 
			
		||||
 | 
			
		||||
				if (var_ix <= column_bits.size() - 1)
 | 
			
		||||
					carry_bits_to_sum.push_back(c_wire);
 | 
			
		||||
					carry_bits_to_sum.append(c_wire);
 | 
			
		||||
 | 
			
		||||
				// Now build the rest of the tree if we can
 | 
			
		||||
				while (var_ix <= column_bits.size() - 1) {
 | 
			
		||||
					std::vector<RTLIL::Wire *> csa_ips;
 | 
			
		||||
					SigSpec csa_ips;
 | 
			
		||||
					// get the next two variables to sum
 | 
			
		||||
					for (; var_ix <= column_bits.size() - 1 && csa_ips.size() < 2;) {
 | 
			
		||||
						// skip any empty bits
 | 
			
		||||
						if (column_bits[var_ix] != nullptr)
 | 
			
		||||
							csa_ips.push_back(column_bits[var_ix]);
 | 
			
		||||
						if (column_bits[var_ix].is_wire())
 | 
			
		||||
							csa_ips.append(column_bits[var_ix]);
 | 
			
		||||
						var_ix++;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -993,7 +951,7 @@ struct BoothPassWorker {
 | 
			
		|||
						c_wire = module->addWire(new_id(carry_wire_name, __LINE__, ""), 1);
 | 
			
		||||
 | 
			
		||||
						if (var_ix <= column_bits.size() - 1)
 | 
			
		||||
							carry_bits_to_sum.push_back(c_wire);
 | 
			
		||||
							carry_bits_to_sum.append(c_wire);
 | 
			
		||||
 | 
			
		||||
						sum_wire_name = "csa_" + std::to_string(column_ix) + "_" + std::to_string(csa_ix) + "_s";
 | 
			
		||||
						s_wire = module->addWire(new_id(sum_wire_name, __LINE__, ""), 1);
 | 
			
		||||
| 
						 | 
				
			
			@ -1009,28 +967,30 @@ struct BoothPassWorker {
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void BuildBoothUMultEncoders(RTLIL::Wire *Y, int y_sz, std::vector<RTLIL::Wire *> &one_int, std::vector<RTLIL::Wire *> &two_int,
 | 
			
		||||
				     std::vector<RTLIL::Wire *> &s_int, std::vector<RTLIL::Wire *> &sb_int, RTLIL::Module *module, int &encoder_ix)
 | 
			
		||||
	void BuildBoothUMultEncoders(SigSpec Y, SigSpec &one_int, SigSpec &two_int,
 | 
			
		||||
				     SigSpec &s_int, SigSpec &sb_int, RTLIL::Module *module, int &encoder_ix)
 | 
			
		||||
	{
 | 
			
		||||
		int y_sz = GetSize(Y);
 | 
			
		||||
 | 
			
		||||
		for (int y_ix = 0; y_ix < y_sz;) {
 | 
			
		||||
			std::string enc_name = "bur_enc_" + std::to_string(encoder_ix) + "_";
 | 
			
		||||
 | 
			
		||||
			std::string two_name = "two_int" + std::to_string(encoder_ix);
 | 
			
		||||
			two_int.push_back(module->addWire(new_id(two_name, __LINE__, ""), 1));
 | 
			
		||||
			two_int.append(module->addWire(new_id(two_name, __LINE__, ""), 1));
 | 
			
		||||
 | 
			
		||||
			std::string one_name = "one_int" + std::to_string(encoder_ix);
 | 
			
		||||
			one_int.push_back(module->addWire(new_id(one_name, __LINE__, ""), 1));
 | 
			
		||||
			one_int.append(module->addWire(new_id(one_name, __LINE__, ""), 1));
 | 
			
		||||
 | 
			
		||||
			std::string s_name = "s_int" + std::to_string(encoder_ix);
 | 
			
		||||
			s_int.push_back(module->addWire(new_id(s_name, __LINE__, ""), 1));
 | 
			
		||||
			s_int.append(module->addWire(new_id(s_name, __LINE__, ""), 1));
 | 
			
		||||
 | 
			
		||||
			std::string sb_name = "sb_int" + std::to_string(encoder_ix);
 | 
			
		||||
			sb_int.push_back(module->addWire(new_id(sb_name, __LINE__, ""), 1));
 | 
			
		||||
			sb_int.append(module->addWire(new_id(sb_name, __LINE__, ""), 1));
 | 
			
		||||
 | 
			
		||||
			if (y_ix == 0) {
 | 
			
		||||
 | 
			
		||||
				BuildBur4e(enc_name, mk_wireFromSigSpec(State::S0), mk_wireFromSigSpec(SigSpec(Y, y_ix, 1)),
 | 
			
		||||
					   mk_wireFromSigSpec(SigSpec(Y, y_ix + 1, 1)), one_int[encoder_ix], two_int[encoder_ix], s_int[encoder_ix],
 | 
			
		||||
				BuildBur4e(enc_name, State::S0, Y[y_ix],
 | 
			
		||||
					   Y[y_ix + 1], one_int[encoder_ix], two_int[encoder_ix], s_int[encoder_ix],
 | 
			
		||||
					   sb_int[encoder_ix]);
 | 
			
		||||
 | 
			
		||||
				y_ix = y_ix + 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -1041,39 +1001,37 @@ struct BoothPassWorker {
 | 
			
		|||
				// then add an extra booth encoder bounded by
 | 
			
		||||
				// zeroes to ensure unsigned works.
 | 
			
		||||
				//
 | 
			
		||||
				RTLIL::Wire *y0_wire;
 | 
			
		||||
				RTLIL::Wire *y1_wire;
 | 
			
		||||
				RTLIL::Wire *y2_wire;
 | 
			
		||||
				SigBit y0, y1, y2;
 | 
			
		||||
 | 
			
		||||
				bool need_padded_cell = false;
 | 
			
		||||
 | 
			
		||||
				if (y_ix > y_sz - 1) {
 | 
			
		||||
					y0_wire = mk_wireFromSigSpec(SigSpec(Y, State::S0));
 | 
			
		||||
					y0 = State::S0;
 | 
			
		||||
					need_padded_cell = false;
 | 
			
		||||
				} else {
 | 
			
		||||
					y0_wire = mk_wireFromSigSpec(SigSpec(Y, y_ix, 1));
 | 
			
		||||
					y0 = Y[y_ix];
 | 
			
		||||
					y_ix++;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (y_ix > y_sz - 1) {
 | 
			
		||||
					need_padded_cell = false;
 | 
			
		||||
					y1_wire = mk_wireFromSigSpec(SigSpec(Y, State::S0));
 | 
			
		||||
					y1 = State::S0;
 | 
			
		||||
				} else {
 | 
			
		||||
					y1_wire = mk_wireFromSigSpec(SigSpec(Y, y_ix, 1));
 | 
			
		||||
					y1 = Y[y_ix];
 | 
			
		||||
					y_ix++;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (y_ix > y_sz - 1) {
 | 
			
		||||
					need_padded_cell = false;
 | 
			
		||||
					y2_wire = mk_wireFromSigSpec(SigSpec(Y, State::S0));
 | 
			
		||||
					y2 = State::S0;
 | 
			
		||||
				} else {
 | 
			
		||||
					if (y_ix == y_sz - 1)
 | 
			
		||||
						need_padded_cell = true;
 | 
			
		||||
					else
 | 
			
		||||
						need_padded_cell = false;
 | 
			
		||||
					y2_wire = mk_wireFromSigSpec(SigSpec(Y, y_ix, 1));
 | 
			
		||||
					y2 = Y[y_ix];
 | 
			
		||||
 | 
			
		||||
					BuildBur4e(enc_name, y0_wire, y1_wire, y2_wire, one_int[encoder_ix], two_int[encoder_ix], s_int[encoder_ix],
 | 
			
		||||
					BuildBur4e(enc_name, y0, y1, y2, one_int[encoder_ix], two_int[encoder_ix], s_int[encoder_ix],
 | 
			
		||||
						   sb_int[encoder_ix]);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1087,25 +1045,25 @@ struct BoothPassWorker {
 | 
			
		|||
					std::string enc_name = "br_enc_pad" + std::to_string(encoder_ix) + "_";
 | 
			
		||||
 | 
			
		||||
					std::string two_name = "two_int" + std::to_string(encoder_ix);
 | 
			
		||||
					two_int.push_back(module->addWire(new_id(two_name, __LINE__, ""), 1));
 | 
			
		||||
					two_int.append(module->addWire(new_id(two_name, __LINE__, ""), 1));
 | 
			
		||||
 | 
			
		||||
					std::string one_name = "one_int" + std::to_string(encoder_ix);
 | 
			
		||||
					one_int.push_back(module->addWire(new_id(two_name, __LINE__, ""), 1));
 | 
			
		||||
					one_int.append(module->addWire(new_id(two_name, __LINE__, ""), 1));
 | 
			
		||||
 | 
			
		||||
					std::string s_name = "s_int" + std::to_string(encoder_ix);
 | 
			
		||||
					s_int.push_back(module->addWire(new_id(s_name, __LINE__, ""), 1));
 | 
			
		||||
					s_int.append(module->addWire(new_id(s_name, __LINE__, ""), 1));
 | 
			
		||||
 | 
			
		||||
					std::string sb_name = "sb_int" + std::to_string(encoder_ix);
 | 
			
		||||
					sb_int.push_back(module->addWire(new_id(sb_name, __LINE__, ""), 1));
 | 
			
		||||
					sb_int.append(module->addWire(new_id(sb_name, __LINE__, ""), 1));
 | 
			
		||||
 | 
			
		||||
					RTLIL::Wire *one_o_int, *two_o_int, *s_o_int, *sb_o_int;
 | 
			
		||||
					BuildBur4e(enc_name, mk_wireFromSigSpec(SigSpec(Y, y_ix, 1)), mk_wireFromSigSpec(State::S0),
 | 
			
		||||
						   mk_wireFromSigSpec(State::S0), one_o_int, two_o_int, s_o_int, sb_o_int);
 | 
			
		||||
					SigBit one_o_int, two_o_int, s_o_int, sb_o_int;
 | 
			
		||||
					BuildBur4e(enc_name, Y[y_ix], State::S0,
 | 
			
		||||
						   State::S0, one_o_int, two_o_int, s_o_int, sb_o_int);
 | 
			
		||||
 | 
			
		||||
					join_wires_with_buffer(one_o_int, one_int[encoder_ix]);
 | 
			
		||||
					join_wires_with_buffer(two_o_int, two_int[encoder_ix]);
 | 
			
		||||
					join_wires_with_buffer(s_o_int, s_int[encoder_ix]);
 | 
			
		||||
					join_wires_with_buffer(sb_o_int, sb_int[encoder_ix]);
 | 
			
		||||
					module->connect(one_int[encoder_ix], one_o_int);
 | 
			
		||||
					module->connect(two_int[encoder_ix], two_o_int);
 | 
			
		||||
					module->connect(s_int[encoder_ix], s_o_int);
 | 
			
		||||
					module->connect(sb_int[encoder_ix], sb_o_int);
 | 
			
		||||
					y_ix++;
 | 
			
		||||
					encoder_ix++;
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -1116,8 +1074,10 @@ struct BoothPassWorker {
 | 
			
		|||
	/*
 | 
			
		||||
	  Signed Multiplier
 | 
			
		||||
	*/
 | 
			
		||||
	void CreateBoothSMult(RTLIL::Module *module, int x_sz, int y_sz, int z_sz, RTLIL::Wire *X, RTLIL::Wire *Y, RTLIL::Wire *Z)
 | 
			
		||||
	void CreateBoothSMult(RTLIL::Module *module, SigSpec X, SigSpec Y, SigSpec Z)
 | 
			
		||||
	{ // product
 | 
			
		||||
		int x_sz = X.size(), y_sz = Y.size(), z_sz = Z.size();
 | 
			
		||||
 | 
			
		||||
		unsigned enc_count = (y_sz / 2) + (((y_sz % 2) != 0) ? 1 : 0);
 | 
			
		||||
		int dec_count = x_sz + 1;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1128,10 +1088,12 @@ struct BoothPassWorker {
 | 
			
		|||
		    "Result of size %d. %d encoders %d decoders\n",
 | 
			
		||||
		    x_sz, y_sz, z_sz, enc_count, dec_count);
 | 
			
		||||
 | 
			
		||||
		RTLIL::Wire **negi_n_int = new RTLIL::Wire *[enc_count];
 | 
			
		||||
		RTLIL::Wire **twoi_n_int = new RTLIL::Wire *[enc_count];
 | 
			
		||||
		RTLIL::Wire **onei_n_int = new RTLIL::Wire *[enc_count];
 | 
			
		||||
		RTLIL::Wire **cori_n_int = new RTLIL::Wire *[enc_count];
 | 
			
		||||
		SigSpec negi_n_int, twoi_n_int, onei_n_int, cori_n_int;
 | 
			
		||||
 | 
			
		||||
		negi_n_int.extend_u0(enc_count);
 | 
			
		||||
		twoi_n_int.extend_u0(enc_count);
 | 
			
		||||
		onei_n_int.extend_u0(enc_count);
 | 
			
		||||
		cori_n_int.extend_u0(enc_count);
 | 
			
		||||
 | 
			
		||||
		for (unsigned encoder_ix = 1; encoder_ix <= enc_count; encoder_ix++) {
 | 
			
		||||
			std::string enc_name = "enc_" + std::to_string(encoder_ix) + "_";
 | 
			
		||||
| 
						 | 
				
			
			@ -1146,38 +1108,34 @@ struct BoothPassWorker {
 | 
			
		|||
 | 
			
		||||
			if (encoder_ix == 1) {
 | 
			
		||||
 | 
			
		||||
				BuildBr4e(enc_name, mk_wireFromSigSpec(SigSpec(State::S0)), mk_wireFromSigSpec(SigSpec(Y, 0, 1)),
 | 
			
		||||
					  mk_wireFromSigSpec(SigSpec(Y, 1, 1)),
 | 
			
		||||
 | 
			
		||||
				BuildBr4e(enc_name, State::S0, Y[0], Y[1],
 | 
			
		||||
					  negi_n_int[encoder_ix - 1], twoi_n_int[encoder_ix - 1], onei_n_int[encoder_ix - 1],
 | 
			
		||||
					  cori_n_int[encoder_ix - 1]);
 | 
			
		||||
 | 
			
		||||
			} else {
 | 
			
		||||
				RTLIL::Wire *y1_wire;
 | 
			
		||||
				RTLIL::Wire *y2_wire;
 | 
			
		||||
				RTLIL::Wire *y3_wire;
 | 
			
		||||
				SigBit y1, y2, y3;
 | 
			
		||||
 | 
			
		||||
				y1 = Y[(encoder_ix - 1) * 2 - 1];
 | 
			
		||||
 | 
			
		||||
				y1_wire = mk_wireFromSigSpec(SigSpec(Y, ((encoder_ix - 1) * 2 - 1), 1)); //-1
 | 
			
		||||
				if ((encoder_ix - 1) * 2 >= (unsigned)y_sz)
 | 
			
		||||
					y2_wire = mk_wireFromSigSpec(SigSpec(State::S0)); // constant 0
 | 
			
		||||
					y2 = State::S0; // constant 0
 | 
			
		||||
				else
 | 
			
		||||
					y2_wire = mk_wireFromSigSpec(SigSpec(Y, ((encoder_ix - 1) * 2), 1)); // 0
 | 
			
		||||
					y2 = Y[(encoder_ix - 1) * 2]; // 0
 | 
			
		||||
 | 
			
		||||
				if (((encoder_ix - 1) * 2 + 1) >= (unsigned)y_sz)
 | 
			
		||||
					y3_wire = mk_wireFromSigSpec(SigSpec(State::S0)); // constant 0
 | 
			
		||||
					y3 = State::S0; // constant 0
 | 
			
		||||
				else
 | 
			
		||||
					y3_wire = mk_wireFromSigSpec(SigSpec(Y, ((encoder_ix - 1) * 2 + 1), 1)); //+1
 | 
			
		||||
 | 
			
		||||
				BuildBr4e(enc_name, y1_wire, y2_wire, y3_wire,
 | 
			
		||||
					y3 = Y[(encoder_ix - 1) * 2 + 1]; //+1
 | 
			
		||||
 | 
			
		||||
				BuildBr4e(enc_name, y1, y2, y3,
 | 
			
		||||
					  negi_n_int[encoder_ix - 1], twoi_n_int[encoder_ix - 1], onei_n_int[encoder_ix - 1],
 | 
			
		||||
					  cori_n_int[encoder_ix - 1]);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Decoders and PP generation
 | 
			
		||||
		RTLIL::Wire **PPij = new RTLIL::Wire *[enc_count * dec_count];
 | 
			
		||||
		RTLIL::Wire **nxj = new RTLIL::Wire *[enc_count * dec_count];
 | 
			
		||||
		SigSpec PPij(State::S0, enc_count * dec_count);
 | 
			
		||||
		SigSpec nxj(State::S0, enc_count * dec_count);
 | 
			
		||||
 | 
			
		||||
		for (int encoder_ix = 1; encoder_ix <= (int)enc_count; encoder_ix++) {
 | 
			
		||||
			for (int decoder_ix = 1; decoder_ix <= dec_count; decoder_ix++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1220,16 +1178,16 @@ struct BoothPassWorker {
 | 
			
		|||
				std::string dec_name = "dec_" + std::to_string(encoder_ix) + "_" + std::to_string(decoder_ix) + "_";
 | 
			
		||||
 | 
			
		||||
				BuildBr4d(dec_name, nxj[((encoder_ix - 1) * dec_count) + decoder_ix - 1], twoi_n_int[encoder_ix - 1],
 | 
			
		||||
					  mk_wireFromSigSpec(SigSpec(X, decoder_ix - 1, 1)), negi_n_int[encoder_ix - 1], onei_n_int[encoder_ix - 1],
 | 
			
		||||
					  X[decoder_ix - 1], negi_n_int[encoder_ix - 1], onei_n_int[encoder_ix - 1],
 | 
			
		||||
					  PPij[((encoder_ix - 1) * dec_count) + decoder_ix - 1], nxj[((encoder_ix - 1) * dec_count) + decoder_ix]);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// duplicate end for sign fix
 | 
			
		||||
			// applies to 9th decoder (xsz+1 decoder).
 | 
			
		||||
			std::string dec_name = "dec_" + std::to_string(encoder_ix) + "_" + std::to_string(x_sz + 1) + "_";
 | 
			
		||||
			RTLIL::Wire *unused_op = nullptr;
 | 
			
		||||
			SigBit unused_op;
 | 
			
		||||
			BuildBr4d(dec_name, nxj[((encoder_ix - 1) * dec_count) + dec_count - 1], twoi_n_int[encoder_ix - 1],
 | 
			
		||||
				  mk_wireFromSigSpec(SigSpec(X, dec_count - 2, 1)), negi_n_int[encoder_ix - 1], onei_n_int[encoder_ix - 1],
 | 
			
		||||
				  X[dec_count - 2], negi_n_int[encoder_ix - 1], onei_n_int[encoder_ix - 1],
 | 
			
		||||
				  PPij[((encoder_ix - 1) * dec_count) + dec_count - 1], unused_op);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1239,8 +1197,8 @@ struct BoothPassWorker {
 | 
			
		|||
		int fa_el_ix = 0;
 | 
			
		||||
		int fa_row_ix = 0;
 | 
			
		||||
		// use 1 d arrays (2d cannot have variable sized indices)
 | 
			
		||||
		RTLIL::Wire **fa_sum_n = new RTLIL::Wire *[fa_row_count * fa_count];
 | 
			
		||||
		RTLIL::Wire **fa_carry_n = new RTLIL::Wire *[fa_row_count * fa_count];
 | 
			
		||||
		SigSpec fa_sum_n(State::S0, fa_row_count * fa_count);
 | 
			
		||||
		SigSpec fa_carry_n(State::S0, fa_row_count * fa_count);
 | 
			
		||||
 | 
			
		||||
		for (fa_row_ix = 0; fa_row_ix < fa_row_count; fa_row_ix++) {
 | 
			
		||||
			for (fa_el_ix = 0; fa_el_ix < fa_count; fa_el_ix++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1416,11 +1374,11 @@ struct BoothPassWorker {
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		// instantiate the cpa
 | 
			
		||||
		RTLIL::Wire **cpa_carry = new RTLIL::Wire *[z_sz];
 | 
			
		||||
		SigSpec cpa_carry;
 | 
			
		||||
 | 
			
		||||
		for (int cix = 0; cix < z_sz; cix++) {
 | 
			
		||||
			std::string cpa_cix_name = "cpa_carry_" + std::to_string(cix) + "_";
 | 
			
		||||
			cpa_carry[cix] = module->addWire(new_id(cpa_cix_name, __LINE__, ""), 1);
 | 
			
		||||
			cpa_carry.append(module->addWire(new_id(cpa_cix_name, __LINE__, ""), 1));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (int cpa_ix = 0; cpa_ix < z_sz; cpa_ix++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1439,7 +1397,7 @@ struct BoothPassWorker {
 | 
			
		|||
				buf->setParam(ID::A_WIDTH, 1);
 | 
			
		||||
				buf->setParam(ID::Y_WIDTH, 1);
 | 
			
		||||
				buf->setParam(ID::A_SIGNED, true);
 | 
			
		||||
				buf->setPort(ID::Y, SigSpec(Z, cpa_ix, 1));
 | 
			
		||||
				buf->setPort(ID::Y, Z[cpa_ix]);
 | 
			
		||||
 | 
			
		||||
				cpa_ix++;
 | 
			
		||||
				buf_name = "pp_buf_" + std::to_string(cpa_ix) + "_" + "driven_by_fa_row_" + std::to_string(fa_row_ix) + "_";
 | 
			
		||||
| 
						 | 
				
			
			@ -1448,22 +1406,22 @@ struct BoothPassWorker {
 | 
			
		|||
				buf->setParam(ID::A_WIDTH, 1);
 | 
			
		||||
				buf->setParam(ID::Y_WIDTH, 1);
 | 
			
		||||
				buf->setParam(ID::A_SIGNED, true);
 | 
			
		||||
				buf->setPort(ID::Y, SigSpec(Z, cpa_ix, 1));
 | 
			
		||||
				buf->setPort(ID::Y, Z[cpa_ix]);
 | 
			
		||||
			} else {
 | 
			
		||||
				int offset = fa_row_count * 2;
 | 
			
		||||
				bool base_case = cpa_ix - offset == 0 ? true : false;
 | 
			
		||||
				std::string cpa_name = "cpa_" + std::to_string(cpa_ix - offset) + "_";
 | 
			
		||||
 | 
			
		||||
				RTLIL::Wire *ci_wire;
 | 
			
		||||
				SigBit ci;
 | 
			
		||||
				if (base_case)
 | 
			
		||||
					ci_wire = cori_n_int[enc_count - 1];
 | 
			
		||||
					ci = cori_n_int[enc_count - 1];
 | 
			
		||||
				else
 | 
			
		||||
					ci_wire = cpa_carry[cpa_ix - offset - 1];
 | 
			
		||||
					ci = cpa_carry[cpa_ix - offset - 1];
 | 
			
		||||
 | 
			
		||||
				RTLIL::Wire *op_wire = module->addWire(NEW_ID, 1);
 | 
			
		||||
				BuildHa(cpa_name, fa_sum_n[(fa_row_count - 1) * fa_count + cpa_ix - offset + 2], ci_wire, op_wire,
 | 
			
		||||
				SigBit op;
 | 
			
		||||
				BuildHa(cpa_name, fa_sum_n[(fa_row_count - 1) * fa_count + cpa_ix - offset + 2], ci, op,
 | 
			
		||||
					cpa_carry[cpa_ix - offset]);
 | 
			
		||||
				module->connect(op_wire, SigSpec(Z, cpa_ix, 1));
 | 
			
		||||
				module->connect(Z[cpa_ix], op);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1473,35 +1431,23 @@ struct BoothPassWorker {
 | 
			
		|||
		//
 | 
			
		||||
		std::string q1_name = "icb_booth_q1_";
 | 
			
		||||
 | 
			
		||||
		RTLIL::Wire *pp0_o_int;
 | 
			
		||||
		RTLIL::Wire *pp1_o_int;
 | 
			
		||||
		RTLIL::Wire *nxj_o_int;
 | 
			
		||||
		RTLIL::Wire *cor_o_int;
 | 
			
		||||
		SigBit pp0_o_int;
 | 
			
		||||
		SigBit pp1_o_int;
 | 
			
		||||
		SigBit nxj_o_int;
 | 
			
		||||
		SigBit cor_o_int;
 | 
			
		||||
 | 
			
		||||
		BuildBoothQ1(q1_name,
 | 
			
		||||
			     negi_n_int[0], // negi
 | 
			
		||||
			     cori_n_int[0], // cori
 | 
			
		||||
 | 
			
		||||
			     mk_wireFromSigSpec(SigSpec(X, 0, 1)), // x0
 | 
			
		||||
			     mk_wireFromSigSpec(SigSpec(X, 1, 1)), // x1
 | 
			
		||||
			     mk_wireFromSigSpec(SigSpec(Y, 0, 1)), // y0
 | 
			
		||||
			     mk_wireFromSigSpec(SigSpec(Y, 1, 1)), // y1
 | 
			
		||||
			     X[0], X[1], Y[0], Y[1],
 | 
			
		||||
 | 
			
		||||
			     nxj_o_int, cor_o_int, pp0_o_int, pp1_o_int);
 | 
			
		||||
 | 
			
		||||
		join_wires_with_buffer(pp0_o_int, fa_sum_n[(0 * fa_count) + 0]);
 | 
			
		||||
		join_wires_with_buffer(pp1_o_int, fa_sum_n[(0 * fa_count) + 1]);
 | 
			
		||||
		join_wires_with_buffer(cor_o_int, fa_carry_n[(0 * fa_count) + 1]);
 | 
			
		||||
		join_wires_with_buffer(nxj_o_int, nxj[(0 * dec_count) + 2]);
 | 
			
		||||
 | 
			
		||||
		delete[] negi_n_int;
 | 
			
		||||
		delete[] twoi_n_int;
 | 
			
		||||
		delete[] onei_n_int;
 | 
			
		||||
		delete[] cori_n_int;
 | 
			
		||||
 | 
			
		||||
		delete[] fa_sum_n;
 | 
			
		||||
		delete[] fa_carry_n;
 | 
			
		||||
		delete[] cpa_carry;
 | 
			
		||||
		module->connect(fa_sum_n[(0 * fa_count) + 0], pp0_o_int);
 | 
			
		||||
		module->connect(fa_sum_n[(0 * fa_count) + 1], pp1_o_int);
 | 
			
		||||
		module->connect(fa_carry_n[(0 * fa_count) + 1], cor_o_int);
 | 
			
		||||
		module->connect(nxj[(0 * dec_count) + 2], nxj_o_int);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue