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,7 +1172,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
 | 
				
			||||||
					continue;
 | 
										continue;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
				cell_stats[RTLIL::unescape_id(c->type)]++;
 | 
									cell_stats[RTLIL::unescape_id(c->type)]++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (c->type == "\\_const0_" || c->type == "\\_const1_") {
 | 
								if (c->type == "\\_const0_" || c->type == "\\_const1_") {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,15 +3,11 @@
 | 
				
			||||||
# NB: Inputs/Outputs must be ordered alphabetically
 | 
					# NB: Inputs/Outputs must be ordered alphabetically
 | 
				
			||||||
#     (with exceptions for carry in/out)
 | 
					#     (with exceptions for carry in/out)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Inputs: I0 I1 CI
 | 
					# Inputs: A B CI
 | 
				
			||||||
# Outputs: CO
 | 
					# Outputs: O CO
 | 
				
			||||||
#   (NB: carry chain input/output must be last
 | 
					#   (NB: carry chain input/output must be last
 | 
				
			||||||
#        input/output and have been moved there
 | 
					#        input/output and have been moved there
 | 
				
			||||||
#        overriding the alphabetical ordering)
 | 
					#        overriding the alphabetical ordering)
 | 
				
			||||||
SB_CARRY 1 1 3 1
 | 
					$__ICE40_FULL_ADDER 1 1 3 2
 | 
				
			||||||
 | 
					400 379 316
 | 
				
			||||||
259 231 126
 | 
					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
 | 
					# NB: Inputs/Outputs must be ordered alphabetically
 | 
				
			||||||
#     (with exceptions for carry in/out)
 | 
					#     (with exceptions for carry in/out)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Inputs: CI I0 I1
 | 
					# Inputs: A B CI
 | 
				
			||||||
# Outputs: CO
 | 
					# Outputs: O CO
 | 
				
			||||||
#   (NB: carry chain input/output must be last
 | 
					#   (NB: carry chain input/output must be last
 | 
				
			||||||
#        input/output and have been moved there
 | 
					#        input/output and have been moved there
 | 
				
			||||||
#        overriding the alphabetical ordering)
 | 
					#        overriding the alphabetical ordering)
 | 
				
			||||||
SB_CARRY 1 1 3 1
 | 
					$__ICE40_FULL_ADDER 1 1 3 2
 | 
				
			||||||
 | 
					589 558 465
 | 
				
			||||||
675 609 186 
 | 
					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
 | 
					# NB: Inputs/Outputs must be ordered alphabetically
 | 
				
			||||||
#     (with exceptions for carry in/out)
 | 
					#     (with exceptions for carry in/out)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Inputs: I0 I1 CI
 | 
					# Inputs: A B CI
 | 
				
			||||||
# Outputs: CO
 | 
					# Outputs: O CO
 | 
				
			||||||
#   (NB: carry chain input/output must be last
 | 
					#   (NB: carry chain input/output must be last
 | 
				
			||||||
#        input/output and have been moved there
 | 
					#        input/output and have been moved there
 | 
				
			||||||
#        overriding the alphabetical ordering)
 | 
					#        overriding the alphabetical ordering)
 | 
				
			||||||
SB_CARRY 1 1 3 1
 | 
					$__ICE40_FULL_ADDER 1 1 3 2
 | 
				
			||||||
 | 
					1231 1205 874
 | 
				
			||||||
675  609  278
 | 
					675  609  278
 | 
				
			||||||
 | 
					 | 
				
			||||||
# Inputs: I0 I1 I2 I3
 | 
					 | 
				
			||||||
# Outputs: O
 | 
					 | 
				
			||||||
SB_LUT4 2 1 4 1
 | 
					 | 
				
			||||||
1285 1231 1205 874
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,6 +44,15 @@ module _80_ice40_alu (A, B, CI, BI, X, Y, CO);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	genvar i;
 | 
						genvar i;
 | 
				
			||||||
	generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice
 | 
						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 (
 | 
							SB_CARRY carry (
 | 
				
			||||||
			.I0(AA[i]),
 | 
								.I0(AA[i]),
 | 
				
			||||||
			.I1(BB[i]),
 | 
								.I1(BB[i]),
 | 
				
			||||||
| 
						 | 
					@ -63,6 +72,7 @@ module _80_ice40_alu (A, B, CI, BI, X, Y, CO);
 | 
				
			||||||
			.I3(C[i]),
 | 
								.I3(C[i]),
 | 
				
			||||||
			.O(Y[i])
 | 
								.O(Y[i])
 | 
				
			||||||
		);
 | 
							);
 | 
				
			||||||
 | 
					`endif
 | 
				
			||||||
	end endgenerate
 | 
						end endgenerate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	assign X = AA ^ BB;
 | 
						assign X = AA ^ BB;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,3 +61,27 @@ module \$lut (A, Y);
 | 
				
			||||||
  endgenerate
 | 
					  endgenerate
 | 
				
			||||||
endmodule
 | 
					endmodule
 | 
				
			||||||
`endif
 | 
					`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
 | 
					// SiliconBlue Logic Cells
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(* abc_box_id = 2, lib_whitebox *)
 | 
					(* lib_whitebox *)
 | 
				
			||||||
module SB_LUT4 (output O, input I0, I1, I2, I3);
 | 
					module SB_LUT4 (output O, input I0, I1, I2, I3);
 | 
				
			||||||
	parameter [15:0] LUT_INIT = 0;
 | 
						parameter [15:0] LUT_INIT = 0;
 | 
				
			||||||
	wire [7:0] s3 = I3 ? LUT_INIT[15:8] : LUT_INIT[7: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];
 | 
						assign O = I0 ? s1[1] : s1[0];
 | 
				
			||||||
endmodule
 | 
					endmodule
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(* abc_box_id = 1, abc_carry="CI,CO", lib_whitebox *)
 | 
					(* lib_whitebox *)
 | 
				
			||||||
module SB_CARRY (output CO, input I0, I1, CI);
 | 
					module SB_CARRY (output CO, input I0, I1, CI);
 | 
				
			||||||
	assign CO = (I0 && I1) || ((I0 || I1) && CI);
 | 
						assign CO = (I0 && I1) || ((I0 || I1) && CI);
 | 
				
			||||||
endmodule
 | 
					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
 | 
					// Positive Edge SiliconBlue FF Cells
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module SB_DFF (output `SB_DFF_REG, input C, D);
 | 
					module SB_DFF (output `SB_DFF_REG, input C, D);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,6 +83,51 @@ static void run_ice40_opts(Module *module)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			continue;
 | 
								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)
 | 
						for (auto cell : sb_lut_cells)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -238,7 +238,7 @@ struct SynthIce40Pass : public ScriptPass
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (check_label("begin"))
 | 
							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(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
 | 
				
			||||||
			run("proc");
 | 
								run("proc");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -294,7 +294,7 @@ struct SynthIce40Pass : public ScriptPass
 | 
				
			||||||
			if (nocarry)
 | 
								if (nocarry)
 | 
				
			||||||
				run("techmap");
 | 
									run("techmap");
 | 
				
			||||||
			else
 | 
								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)
 | 
								if (retime || help_mode)
 | 
				
			||||||
				run(abc + " -dff", "(only if -retime)");
 | 
									run(abc + " -dff", "(only if -retime)");
 | 
				
			||||||
			run("ice40_opt");
 | 
								run("ice40_opt");
 | 
				
			||||||
| 
						 | 
					@ -338,6 +338,7 @@ struct SynthIce40Pass : public ScriptPass
 | 
				
			||||||
					else
 | 
										else
 | 
				
			||||||
						wire_delay = 250;
 | 
											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(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
 | 
									else
 | 
				
			||||||
					run(abc + " -dress -lut 4", "(skip if -noabc)");
 | 
										run(abc + " -dress -lut 4", "(skip if -noabc)");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue