mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	Merge pull request #1186 from YosysHQ/eddie/abc9_ice40_fix
abc9/ice40: encapsulate SB_CARRY+SB_LUT4 into one box
This commit is contained in:
		
						commit
						ba8ccbdea8
					
				
					 9 changed files with 122 additions and 31 deletions
				
			
		| 
						 | 
				
			
			@ -1172,8 +1172,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
 | 
			
		|||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			cell_stats[RTLIL::unescape_id(c->type)]++;
 | 
			
		||||
			else
 | 
			
		||||
				cell_stats[RTLIL::unescape_id(c->type)]++;
 | 
			
		||||
 | 
			
		||||
			if (c->type == "\\_const0_" || c->type == "\\_const1_") {
 | 
			
		||||
				RTLIL::SigSig conn;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,15 +3,11 @@
 | 
			
		|||
# NB: Inputs/Outputs must be ordered alphabetically
 | 
			
		||||
#     (with exceptions for carry in/out)
 | 
			
		||||
 | 
			
		||||
# Inputs: I0 I1 CI
 | 
			
		||||
# Outputs: CO
 | 
			
		||||
# Inputs: A B CI
 | 
			
		||||
# Outputs: O CO
 | 
			
		||||
#   (NB: carry chain input/output must be last
 | 
			
		||||
#        input/output and have been moved there
 | 
			
		||||
#        overriding the alphabetical ordering)
 | 
			
		||||
SB_CARRY 1 1 3 1
 | 
			
		||||
$__ICE40_FULL_ADDER 1 1 3 2
 | 
			
		||||
400 379 316
 | 
			
		||||
259 231 126
 | 
			
		||||
 | 
			
		||||
# Inputs: I0 I1 I2 I3
 | 
			
		||||
# Outputs: O
 | 
			
		||||
SB_LUT4 2 1 4 1
 | 
			
		||||
449 400 379 316
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,15 +3,11 @@
 | 
			
		|||
# NB: Inputs/Outputs must be ordered alphabetically
 | 
			
		||||
#     (with exceptions for carry in/out)
 | 
			
		||||
 | 
			
		||||
# Inputs: CI I0 I1
 | 
			
		||||
# Outputs: CO
 | 
			
		||||
# Inputs: A B CI
 | 
			
		||||
# Outputs: O CO
 | 
			
		||||
#   (NB: carry chain input/output must be last
 | 
			
		||||
#        input/output and have been moved there
 | 
			
		||||
#        overriding the alphabetical ordering)
 | 
			
		||||
SB_CARRY 1 1 3 1
 | 
			
		||||
$__ICE40_FULL_ADDER 1 1 3 2
 | 
			
		||||
589 558 465
 | 
			
		||||
675 609 186 
 | 
			
		||||
 | 
			
		||||
# Inputs: I0 I1 I2 I3
 | 
			
		||||
# Outputs: O
 | 
			
		||||
SB_LUT4 2 1 4 1
 | 
			
		||||
661 589 558 465
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,15 +3,11 @@
 | 
			
		|||
# NB: Inputs/Outputs must be ordered alphabetically
 | 
			
		||||
#     (with exceptions for carry in/out)
 | 
			
		||||
 | 
			
		||||
# Inputs: I0 I1 CI
 | 
			
		||||
# Outputs: CO
 | 
			
		||||
# Inputs: A B CI
 | 
			
		||||
# Outputs: O CO
 | 
			
		||||
#   (NB: carry chain input/output must be last
 | 
			
		||||
#        input/output and have been moved there
 | 
			
		||||
#        overriding the alphabetical ordering)
 | 
			
		||||
SB_CARRY 1 1 3 1
 | 
			
		||||
675 609 278
 | 
			
		||||
 | 
			
		||||
# Inputs: I0 I1 I2 I3
 | 
			
		||||
# Outputs: O
 | 
			
		||||
SB_LUT4 2 1 4 1
 | 
			
		||||
1285 1231 1205 874
 | 
			
		||||
$__ICE40_FULL_ADDER 1 1 3 2
 | 
			
		||||
1231 1205 874
 | 
			
		||||
675  609  278
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,6 +44,15 @@ module _80_ice40_alu (A, B, CI, BI, X, Y, CO);
 | 
			
		|||
 | 
			
		||||
	genvar i;
 | 
			
		||||
	generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice
 | 
			
		||||
`ifdef _ABC
 | 
			
		||||
		\$__ICE40_FULL_ADDER carry (
 | 
			
		||||
			.A(AA[i]),
 | 
			
		||||
			.B(BB[i]),
 | 
			
		||||
			.CI(C[i]),
 | 
			
		||||
			.CO(CO[i]),
 | 
			
		||||
			.O(Y[i])
 | 
			
		||||
		);
 | 
			
		||||
`else
 | 
			
		||||
		SB_CARRY carry (
 | 
			
		||||
			.I0(AA[i]),
 | 
			
		||||
			.I1(BB[i]),
 | 
			
		||||
| 
						 | 
				
			
			@ -63,6 +72,7 @@ module _80_ice40_alu (A, B, CI, BI, X, Y, CO);
 | 
			
		|||
			.I3(C[i]),
 | 
			
		||||
			.O(Y[i])
 | 
			
		||||
		);
 | 
			
		||||
`endif
 | 
			
		||||
	end endgenerate
 | 
			
		||||
 | 
			
		||||
	assign X = AA ^ BB;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,3 +61,27 @@ module \$lut (A, Y);
 | 
			
		|||
  endgenerate
 | 
			
		||||
endmodule
 | 
			
		||||
`endif
 | 
			
		||||
 | 
			
		||||
`ifdef _ABC
 | 
			
		||||
module \$__ICE40_FULL_ADDER (output CO, O, input A, B, CI);
 | 
			
		||||
  SB_CARRY carry (
 | 
			
		||||
    .I0(A),
 | 
			
		||||
    .I1(B),
 | 
			
		||||
    .CI(CI),
 | 
			
		||||
    .CO(CO)
 | 
			
		||||
  );
 | 
			
		||||
  SB_LUT4 #(
 | 
			
		||||
    //         I0: 1010 1010 1010 1010
 | 
			
		||||
    //         I1: 1100 1100 1100 1100
 | 
			
		||||
    //         I2: 1111 0000 1111 0000
 | 
			
		||||
    //         I3: 1111 1111 0000 0000
 | 
			
		||||
    .LUT_INIT(16'b 0110_1001_1001_0110)
 | 
			
		||||
  ) adder (
 | 
			
		||||
    .I0(1'b0),
 | 
			
		||||
    .I1(A),
 | 
			
		||||
    .I2(B),
 | 
			
		||||
    .I3(CI),
 | 
			
		||||
    .O(O)
 | 
			
		||||
  );
 | 
			
		||||
endmodule
 | 
			
		||||
`endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -127,7 +127,7 @@ endmodule
 | 
			
		|||
 | 
			
		||||
// SiliconBlue Logic Cells
 | 
			
		||||
 | 
			
		||||
(* abc_box_id = 2, lib_whitebox *)
 | 
			
		||||
(* lib_whitebox *)
 | 
			
		||||
module SB_LUT4 (output O, input I0, I1, I2, I3);
 | 
			
		||||
	parameter [15:0] LUT_INIT = 0;
 | 
			
		||||
	wire [7:0] s3 = I3 ? LUT_INIT[15:8] : LUT_INIT[7:0];
 | 
			
		||||
| 
						 | 
				
			
			@ -136,11 +136,34 @@ module SB_LUT4 (output O, input I0, I1, I2, I3);
 | 
			
		|||
	assign O = I0 ? s1[1] : s1[0];
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
(* abc_box_id = 1, abc_carry="CI,CO", lib_whitebox *)
 | 
			
		||||
(* lib_whitebox *)
 | 
			
		||||
module SB_CARRY (output CO, input I0, I1, CI);
 | 
			
		||||
	assign CO = (I0 && I1) || ((I0 || I1) && CI);
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
(* abc_box_id = 1, abc_carry="CI,CO", lib_whitebox *)
 | 
			
		||||
module \$__ICE40_FULL_ADDER (output CO, O, input A, B, CI);
 | 
			
		||||
	SB_CARRY carry (
 | 
			
		||||
		.I0(A),
 | 
			
		||||
		.I1(B),
 | 
			
		||||
		.CI(CI),
 | 
			
		||||
		.CO(CO)
 | 
			
		||||
	);
 | 
			
		||||
	SB_LUT4 #(
 | 
			
		||||
		//         I0: 1010 1010 1010 1010
 | 
			
		||||
		//         I1: 1100 1100 1100 1100
 | 
			
		||||
		//         I2: 1111 0000 1111 0000
 | 
			
		||||
		//         I3: 1111 1111 0000 0000
 | 
			
		||||
		.LUT_INIT(16'b 0110_1001_1001_0110)
 | 
			
		||||
	) adder (
 | 
			
		||||
		.I0(1'b0),
 | 
			
		||||
		.I1(A),
 | 
			
		||||
		.I2(B),
 | 
			
		||||
		.I3(CI),
 | 
			
		||||
		.O(O)
 | 
			
		||||
	);
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
// Positive Edge SiliconBlue FF Cells
 | 
			
		||||
 | 
			
		||||
module SB_DFF (output `SB_DFF_REG, input C, D);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -83,6 +83,51 @@ static void run_ice40_opts(Module *module)
 | 
			
		|||
			}
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (cell->type == "$__ICE40_FULL_ADDER")
 | 
			
		||||
		{
 | 
			
		||||
			SigSpec non_const_inputs, replacement_output;
 | 
			
		||||
			int count_zeros = 0, count_ones = 0;
 | 
			
		||||
 | 
			
		||||
			SigBit inbit[3] = {
 | 
			
		||||
				cell->getPort("\\A"),
 | 
			
		||||
				cell->getPort("\\B"),
 | 
			
		||||
				cell->getPort("\\CI")
 | 
			
		||||
			};
 | 
			
		||||
			for (int i = 0; i < 3; i++)
 | 
			
		||||
				if (inbit[i].wire == nullptr) {
 | 
			
		||||
					if (inbit[i] == State::S1)
 | 
			
		||||
						count_ones++;
 | 
			
		||||
					else
 | 
			
		||||
						count_zeros++;
 | 
			
		||||
				} else
 | 
			
		||||
					non_const_inputs.append(inbit[i]);
 | 
			
		||||
 | 
			
		||||
			if (count_zeros >= 2)
 | 
			
		||||
				replacement_output = State::S0;
 | 
			
		||||
			else if (count_ones >= 2)
 | 
			
		||||
				replacement_output = State::S1;
 | 
			
		||||
			else if (GetSize(non_const_inputs) == 1)
 | 
			
		||||
				replacement_output = non_const_inputs;
 | 
			
		||||
 | 
			
		||||
			if (GetSize(replacement_output)) {
 | 
			
		||||
				optimized_co.insert(sigmap(cell->getPort("\\CO")[0]));
 | 
			
		||||
				module->connect(cell->getPort("\\CO")[0], replacement_output);
 | 
			
		||||
				module->design->scratchpad_set_bool("opt.did_something", true);
 | 
			
		||||
				log("Optimized $__ICE40_FULL_ADDER cell back to logic (without SB_CARRY) %s.%s: CO=%s\n",
 | 
			
		||||
						log_id(module), log_id(cell), log_signal(replacement_output));
 | 
			
		||||
				cell->type = "$lut";
 | 
			
		||||
				cell->setPort("\\A", { RTLIL::S0, inbit[0], inbit[1], inbit[2] });
 | 
			
		||||
				cell->setPort("\\Y", cell->getPort("\\O"));
 | 
			
		||||
				cell->unsetPort("\\B");
 | 
			
		||||
				cell->unsetPort("\\CI");
 | 
			
		||||
				cell->unsetPort("\\CO");
 | 
			
		||||
				cell->unsetPort("\\O");
 | 
			
		||||
				cell->setParam("\\LUT", RTLIL::Const::from_string("0110100110010110"));
 | 
			
		||||
				cell->setParam("\\WIDTH", 4);
 | 
			
		||||
			}
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (auto cell : sb_lut_cells)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -238,7 +238,7 @@ struct SynthIce40Pass : public ScriptPass
 | 
			
		|||
	{
 | 
			
		||||
		if (check_label("begin"))
 | 
			
		||||
		{
 | 
			
		||||
			run("read_verilog -lib -D_ABC +/ice40/cells_sim.v");
 | 
			
		||||
			run("read_verilog -icells -lib -D_ABC +/ice40/cells_sim.v");
 | 
			
		||||
			run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
 | 
			
		||||
			run("proc");
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -294,7 +294,7 @@ struct SynthIce40Pass : public ScriptPass
 | 
			
		|||
			if (nocarry)
 | 
			
		||||
				run("techmap");
 | 
			
		||||
			else
 | 
			
		||||
				run("techmap -map +/techmap.v -map +/ice40/arith_map.v");
 | 
			
		||||
				run("techmap -map +/techmap.v -map +/ice40/arith_map.v" + std::string(abc == "abc9" ? " -D _ABC" : ""));
 | 
			
		||||
			if (retime || help_mode)
 | 
			
		||||
				run(abc + " -dff", "(only if -retime)");
 | 
			
		||||
			run("ice40_opt");
 | 
			
		||||
| 
						 | 
				
			
			@ -338,6 +338,7 @@ struct SynthIce40Pass : public ScriptPass
 | 
			
		|||
					else
 | 
			
		||||
						wire_delay = 250;
 | 
			
		||||
					run(abc + stringf(" -W %d -lut +/ice40/abc_%s.lut -box +/ice40/abc_%s.box", wire_delay, device_opt.c_str(), device_opt.c_str()), "(skip if -noabc)");
 | 
			
		||||
					run("techmap -D NO_LUT -D _ABC -map +/ice40/cells_map.v");
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
					run(abc + " -dress -lut 4", "(skip if -noabc)");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue