mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 13:29:12 +00:00 
			
		
		
		
	Merge pull request #1700 from YosysHQ/eddie/abc9_fixes
Use (* abc9_init *) attribute, fix use of abc9_arrival for flops
This commit is contained in:
		
						commit
						0cf7598cd6
					
				
					 3 changed files with 51 additions and 29 deletions
				
			
		| 
						 | 
				
			
			@ -643,14 +643,13 @@ struct XAigerWriter
 | 
			
		|||
			write_s_buffer(ff_bits.size());
 | 
			
		||||
 | 
			
		||||
			for (const auto &i : ff_bits) {
 | 
			
		||||
				const SigBit &d = i.first;
 | 
			
		||||
				const Cell *cell = i.second;
 | 
			
		||||
 | 
			
		||||
				int mergeability = cell->attributes.at(ID(abc9_mergeability)).as_int();
 | 
			
		||||
				log_assert(mergeability > 0);
 | 
			
		||||
				write_r_buffer(mergeability);
 | 
			
		||||
 | 
			
		||||
				Const init = cell->attributes.at(ID(abc9_init));
 | 
			
		||||
				Const init = cell->attributes.at(ID(abc9_init), State::Sx);
 | 
			
		||||
				log_assert(GetSize(init) == 1);
 | 
			
		||||
				if (init == State::S1)
 | 
			
		||||
					write_s_buffer(1);
 | 
			
		||||
| 
						 | 
				
			
			@ -661,7 +660,11 @@ struct XAigerWriter
 | 
			
		|||
					write_s_buffer(0);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				write_i_buffer(arrival_times.at(d, 0));
 | 
			
		||||
				auto it = cell->attributes.find(ID(abc9_arrival));
 | 
			
		||||
				if (it != cell->attributes.end())
 | 
			
		||||
					write_i_buffer(it->second.as_int());
 | 
			
		||||
				else
 | 
			
		||||
					write_i_buffer(0);
 | 
			
		||||
				//write_o_buffer(0);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -192,20 +192,9 @@ void prep_dff(RTLIL::Module *module)
 | 
			
		|||
		clkdomain_t key(abc9_clock);
 | 
			
		||||
 | 
			
		||||
		auto r = clk_to_mergeability.insert(std::make_pair(abc9_clock, clk_to_mergeability.size() + 1));
 | 
			
		||||
		auto r2 YS_ATTRIBUTE(unused) = cell->attributes.insert(std::make_pair(ID(abc9_mergeability), r.first->second));
 | 
			
		||||
		log_assert(r2.second);
 | 
			
		||||
 | 
			
		||||
		Wire *abc9_init_wire = module->wire(stringf("%s.init", cell->name.c_str()));
 | 
			
		||||
		if (abc9_init_wire == NULL)
 | 
			
		||||
			log_error("'%s.init' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module));
 | 
			
		||||
		log_assert(GetSize(abc9_init_wire) == 1);
 | 
			
		||||
		SigSpec abc9_init = assign_map(abc9_init_wire);
 | 
			
		||||
		if (!abc9_init.is_fully_const())
 | 
			
		||||
			log_error("'%s.init' is not a constant wire present in module '%s'.\n", cell->name.c_str(), log_id(module));
 | 
			
		||||
		if (abc9_init == State::S1)
 | 
			
		||||
			log_error("'%s.init' in module '%s' has value 1'b1 which is not supported by 'abc9 -dff'.\n", cell->name.c_str(), log_id(module));
 | 
			
		||||
		r2 = cell->attributes.insert(std::make_pair(ID(abc9_init), abc9_init.as_const()));
 | 
			
		||||
		auto r2  = cell->attributes.insert(ID(abc9_mergeability));;
 | 
			
		||||
		log_assert(r2.second);
 | 
			
		||||
		r2.first->second = r.first->second;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	RTLIL::Module *holes_module = design->module(stringf("%s$holes", module->name.c_str()));
 | 
			
		||||
| 
						 | 
				
			
			@ -265,13 +254,19 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
 | 
			
		|||
 | 
			
		||||
	SigMap sigmap(module);
 | 
			
		||||
 | 
			
		||||
	dict<SigBit, Cell*> abc9_ff_d;
 | 
			
		||||
	dict<SigBit, pool<IdString>> bit_drivers, bit_users;
 | 
			
		||||
	TopoSort<IdString, RTLIL::sort_by_id_str> toposort;
 | 
			
		||||
	dict<IdString, std::vector<IdString>> box_ports;
 | 
			
		||||
 | 
			
		||||
	for (auto cell : module->cells()) {
 | 
			
		||||
		if (cell->type == "$__ABC9_FF_")
 | 
			
		||||
		if (cell->type == "$__ABC9_FF_") {
 | 
			
		||||
			auto d = sigmap(cell->getPort(ID(D)));
 | 
			
		||||
			auto r = abc9_ff_d.insert(d);
 | 
			
		||||
			log_assert(r.second);
 | 
			
		||||
			r.first->second = cell;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		if (cell->has_keep_attr())
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -368,6 +363,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
 | 
			
		|||
 | 
			
		||||
		IdString derived_type = box_module->derive(design, cell->parameters);
 | 
			
		||||
		box_module = design->module(derived_type);
 | 
			
		||||
		auto abc9_flop = box_module->get_bool_attribute("\\abc9_flop");
 | 
			
		||||
 | 
			
		||||
		auto r = cell_cache.insert(derived_type);
 | 
			
		||||
		auto &holes_cell = r.first->second;
 | 
			
		||||
| 
						 | 
				
			
			@ -406,7 +402,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
 | 
			
		|||
 | 
			
		||||
				// For flops only, create an extra 1-bit input that drives a new wire
 | 
			
		||||
				//   called "<cell>.abc9_ff.Q" that is used below
 | 
			
		||||
				if (box_module->get_bool_attribute("\\abc9_flop")) {
 | 
			
		||||
				if (abc9_flop) {
 | 
			
		||||
					box_inputs++;
 | 
			
		||||
					Wire *holes_wire = holes_module->wire(stringf("\\i%d", box_inputs));
 | 
			
		||||
					if (!holes_wire) {
 | 
			
		||||
| 
						 | 
				
			
			@ -436,6 +432,28 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
 | 
			
		|||
				holes_module->connect(holes_wire, holes_cell->getPort(port_name));
 | 
			
		||||
			else // blackbox
 | 
			
		||||
				holes_module->connect(holes_wire, Const(State::S0, GetSize(w)));
 | 
			
		||||
 | 
			
		||||
			// Transfer abc9_arrival value from flop box output to $__ABC9_FF_ cell
 | 
			
		||||
			if (abc9_flop) {
 | 
			
		||||
				auto it = w->attributes.find(ID(abc9_arrival));
 | 
			
		||||
				if (it == w->attributes.end())
 | 
			
		||||
					continue;
 | 
			
		||||
				auto jt = cell->connections_.find(port_name);
 | 
			
		||||
				if (jt == cell->connections_.end())
 | 
			
		||||
					continue;
 | 
			
		||||
				auto kt = abc9_ff_d.find(jt->second);
 | 
			
		||||
				if (kt == abc9_ff_d.end())
 | 
			
		||||
					continue;
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
				if (ys_debug(1)) {
 | 
			
		||||
					static std::set<std::pair<IdString,IdString>> seen;
 | 
			
		||||
					if (seen.emplace(cell->type, port_name).second) log("%s.%s abc9_arrival = %d\n", log_id(cell->type), log_id(port_name), it->second.as_int());
 | 
			
		||||
				}
 | 
			
		||||
#endif
 | 
			
		||||
				auto r = kt->second->attributes.insert(ID(abc9_arrival));
 | 
			
		||||
				log_assert(r.second);
 | 
			
		||||
				r.first->second = it->second;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -68,9 +68,10 @@
 | 
			
		|||
// (c) a special abc9_ff.clock wire to capture its clock domain and polarity
 | 
			
		||||
//     (indicated to `abc9' so that it only performs sequential synthesis
 | 
			
		||||
//     (with reachability analysis) correctly on one domain at a time)
 | 
			
		||||
// (d) a special abc9_ff.init wire to encode the flop's initial state
 | 
			
		||||
//     NOTE: in order to perform sequential synthesis, `abc9' also requires
 | 
			
		||||
//     that the initial value of all flops be zero
 | 
			
		||||
// (d) an (* abc9_init *) attribute on the $__ABC9_FF_ cell capturing its
 | 
			
		||||
//     initial state
 | 
			
		||||
//     NOTE: in order to perform sequential synthesis, `abc9' requires that
 | 
			
		||||
//     the initial value of all flops be zero
 | 
			
		||||
// (e) a special _TECHMAP_REPLACE_.abc9_ff.Q wire that will be used for feedback
 | 
			
		||||
//     into the (combinatorial) FD* cell to facilitate clock-enable behaviour
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -103,11 +104,11 @@ module FDRE (output Q, (* techmap_autopurge *) input C, CE, D, R);
 | 
			
		|||
    );
 | 
			
		||||
  end
 | 
			
		||||
  endgenerate
 | 
			
		||||
  (* abc9_init = 1'b0 *)
 | 
			
		||||
  $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
 | 
			
		||||
 | 
			
		||||
  // Special signals
 | 
			
		||||
  wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
 | 
			
		||||
  wire [0:0] abc9_ff.init = 1'b0;
 | 
			
		||||
  wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
 | 
			
		||||
endmodule
 | 
			
		||||
module FDRE_1 (output Q, (* techmap_autopurge *) input C, CE, D, R);
 | 
			
		||||
| 
						 | 
				
			
			@ -130,11 +131,11 @@ module FDRE_1 (output Q, (* techmap_autopurge *) input C, CE, D, R);
 | 
			
		|||
    );
 | 
			
		||||
  end
 | 
			
		||||
  endgenerate
 | 
			
		||||
  (* abc9_init = 1'b0 *)
 | 
			
		||||
  $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
 | 
			
		||||
 | 
			
		||||
  // Special signals
 | 
			
		||||
  wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
 | 
			
		||||
  wire [0:0] abc9_ff.init = 1'b0;
 | 
			
		||||
  wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -166,11 +167,11 @@ module FDSE (output Q, (* techmap_autopurge *) input C, CE, D, S);
 | 
			
		|||
      .D(D), .Q($Q), .C(C), .CE(CE), .S(S)
 | 
			
		||||
    );
 | 
			
		||||
  end endgenerate
 | 
			
		||||
  (* abc9_init = 1'b0 *)
 | 
			
		||||
  $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
 | 
			
		||||
 | 
			
		||||
  // Special signals
 | 
			
		||||
  wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
 | 
			
		||||
  wire [0:0] abc9_ff.init = 1'b0;
 | 
			
		||||
  wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
 | 
			
		||||
endmodule
 | 
			
		||||
module FDSE_1 (output Q, (* techmap_autopurge *) input C, CE, D, S);
 | 
			
		||||
| 
						 | 
				
			
			@ -192,11 +193,11 @@ module FDSE_1 (output Q, (* techmap_autopurge *) input C, CE, D, S);
 | 
			
		|||
      .D(D), .Q($Q), .C(C), .CE(CE), .S(S)
 | 
			
		||||
    );
 | 
			
		||||
  end endgenerate
 | 
			
		||||
  (* abc9_init = 1'b0 *)
 | 
			
		||||
  $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
 | 
			
		||||
 | 
			
		||||
  // Special signals
 | 
			
		||||
  wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
 | 
			
		||||
  wire [0:0] abc9_ff.init = 1'b0;
 | 
			
		||||
  wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -242,11 +243,11 @@ module FDCE (output Q, (* techmap_autopurge *) input C, CE, D, CLR);
 | 
			
		|||
    // Since this is an async flop, async behaviour is dealt with here
 | 
			
		||||
    $__ABC9_ASYNC0 abc_async (.A($QQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ));
 | 
			
		||||
  end endgenerate
 | 
			
		||||
  (* abc9_init = 1'b0 *)
 | 
			
		||||
  $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
 | 
			
		||||
 | 
			
		||||
  // Special signals
 | 
			
		||||
  wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
 | 
			
		||||
  wire [0:0] abc9_ff.init = 1'b0;
 | 
			
		||||
  wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
 | 
			
		||||
endmodule
 | 
			
		||||
module FDCE_1 (output Q, (* techmap_autopurge *) input C, CE, D, CLR);
 | 
			
		||||
| 
						 | 
				
			
			@ -280,11 +281,11 @@ module FDCE_1 (output Q, (* techmap_autopurge *) input C, CE, D, CLR);
 | 
			
		|||
    );
 | 
			
		||||
    $__ABC9_ASYNC0 abc_async (.A($QQ), .S(CLR), .Y(QQ));
 | 
			
		||||
  end endgenerate
 | 
			
		||||
  (* abc9_init = 1'b0 *)
 | 
			
		||||
  $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
 | 
			
		||||
 | 
			
		||||
  // Special signals
 | 
			
		||||
  wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
 | 
			
		||||
  wire [0:0] abc9_ff.init = 1'b0;
 | 
			
		||||
  wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -328,11 +329,11 @@ module FDPE (output Q, (* techmap_autopurge *) input C, CE, D, PRE);
 | 
			
		|||
    );
 | 
			
		||||
    $__ABC9_ASYNC1 abc_async (.A($QQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ));
 | 
			
		||||
  end endgenerate
 | 
			
		||||
  (* abc9_init = 1'b0 *)
 | 
			
		||||
  $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
 | 
			
		||||
 | 
			
		||||
  // Special signals
 | 
			
		||||
  wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
 | 
			
		||||
  wire [0:0] abc9_ff.init = 1'b0;
 | 
			
		||||
  wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
 | 
			
		||||
endmodule
 | 
			
		||||
module FDPE_1 (output Q, (* techmap_autopurge *) input C, CE, D, PRE);
 | 
			
		||||
| 
						 | 
				
			
			@ -366,11 +367,11 @@ module FDPE_1 (output Q, (* techmap_autopurge *) input C, CE, D, PRE);
 | 
			
		|||
    );
 | 
			
		||||
    $__ABC9_ASYNC1 abc_async (.A($QQ), .S(PRE), .Y(QQ));
 | 
			
		||||
  end endgenerate
 | 
			
		||||
  (* abc9_init = 1'b0 *)
 | 
			
		||||
  $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
 | 
			
		||||
 | 
			
		||||
  // Special signals
 | 
			
		||||
  wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
 | 
			
		||||
  wire [0:0] abc9_ff.init = 1'b0;
 | 
			
		||||
  wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
 | 
			
		||||
endmodule
 | 
			
		||||
`endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue