mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 13:29:12 +00:00 
			
		
		
		
	Merge remote-tracking branch 'origin/master' into xc7dsp
This commit is contained in:
		
						commit
						e742478e1d
					
				
					 28 changed files with 717 additions and 213 deletions
				
			
		
							
								
								
									
										8
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										8
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -88,7 +88,7 @@ ifeq ($(OS), Darwin)
 | 
			
		|||
PLUGIN_LDFLAGS += -undefined dynamic_lookup
 | 
			
		||||
 | 
			
		||||
# homebrew search paths
 | 
			
		||||
ifneq ($(shell command -v brew),)
 | 
			
		||||
ifneq ($(shell :; command -v brew),)
 | 
			
		||||
BREW_PREFIX := $(shell brew --prefix)/opt
 | 
			
		||||
$(info $$BREW_PREFIX is [${BREW_PREFIX}])
 | 
			
		||||
ifeq ($(ENABLE_PYOSYS),1)
 | 
			
		||||
| 
						 | 
				
			
			@ -102,8 +102,8 @@ PKG_CONFIG_PATH := $(BREW_PREFIX)/tcl-tk/lib/pkgconfig:$(PKG_CONFIG_PATH)
 | 
			
		|||
export PATH := $(BREW_PREFIX)/bison/bin:$(BREW_PREFIX)/gettext/bin:$(BREW_PREFIX)/flex/bin:$(PATH)
 | 
			
		||||
 | 
			
		||||
# macports search paths
 | 
			
		||||
else ifneq ($(shell command -v port),)
 | 
			
		||||
PORT_PREFIX := $(patsubst %/bin/port,%,$(shell command -v port))
 | 
			
		||||
else ifneq ($(shell :; command -v port),)
 | 
			
		||||
PORT_PREFIX := $(patsubst %/bin/port,%,$(shell :; command -v port))
 | 
			
		||||
CXXFLAGS += -I$(PORT_PREFIX)/include
 | 
			
		||||
LDFLAGS += -L$(PORT_PREFIX)/lib
 | 
			
		||||
PKG_CONFIG_PATH := $(PORT_PREFIX)/lib/pkgconfig:$(PKG_CONFIG_PATH)
 | 
			
		||||
| 
						 | 
				
			
			@ -115,7 +115,7 @@ LDFLAGS += -rdynamic
 | 
			
		|||
LDLIBS += -lrt
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
YOSYS_VER := 0.9+36
 | 
			
		||||
YOSYS_VER := 0.9+231
 | 
			
		||||
GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN)
 | 
			
		||||
OBJS = kernel/version_$(GIT_REV).o
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								README.md
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -332,6 +332,10 @@ Verilog Attributes and non-standard features
 | 
			
		|||
  that represent module parameters or localparams (when the HDL front-end
 | 
			
		||||
  is run in ``-pwires`` mode).
 | 
			
		||||
 | 
			
		||||
- Wires marked with the ``hierconn`` attribute are connected to wires with the
 | 
			
		||||
  same name (format ``cell_name.identifier``) when they are imported from
 | 
			
		||||
  sub-modules by ``flatten``.
 | 
			
		||||
 | 
			
		||||
- The ``clkbuf_driver`` attribute can be set on an output port of a blackbox
 | 
			
		||||
  module to mark it as a clock buffer output, and thus prevent ``clkbufmap``
 | 
			
		||||
  from inserting another clock buffer on a net driven by such output.
 | 
			
		||||
| 
						 | 
				
			
			@ -351,19 +355,16 @@ Verilog Attributes and non-standard features
 | 
			
		|||
  blackbox or whitebox definition to a corresponding entry in a `abc9`
 | 
			
		||||
  box-file.
 | 
			
		||||
 | 
			
		||||
- The port attribute ``abc_scc_break`` indicates a module input port that will
 | 
			
		||||
  be treated as a primary output during `abc9` techmapping. Doing so eliminates
 | 
			
		||||
  the possibility of a strongly-connected component (i.e. a combinatorial loop)
 | 
			
		||||
  existing. Typically, this is specified for sequential inputs on otherwise
 | 
			
		||||
  combinatorial boxes -- for example, applying ``abc_scc_break`` onto the `D`
 | 
			
		||||
  port of a LUTRAM cell prevents `abc9` from interpreting any `Q` -> `D` paths
 | 
			
		||||
  as a combinatorial loop.
 | 
			
		||||
 | 
			
		||||
- The port attribute ``abc_carry`` marks the carry-in (if an input port) and
 | 
			
		||||
  carry-out (if output port) ports of a box. This information is necessary for
 | 
			
		||||
  `abc9` to preserve the integrity of carry-chains. Specifying this attribute
 | 
			
		||||
  onto a bus port will affect only its most significant bit.
 | 
			
		||||
 | 
			
		||||
- The port attribute ``abc_arrival`` specifies an integer (for output ports
 | 
			
		||||
  only) to be used as the arrival time of this sequential port. It can be used,
 | 
			
		||||
  for example, to specify the clk-to-Q delay of a flip-flop for consideration
 | 
			
		||||
  during techmapping.
 | 
			
		||||
 | 
			
		||||
- In addition to the ``(* ... *)`` attribute syntax, Yosys supports
 | 
			
		||||
  the non-standard ``{* ... *}`` attribute syntax to set default attributes
 | 
			
		||||
  for everything that comes after the ``{* ... *}`` statement. (Reset
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -83,6 +83,7 @@ struct XAigerWriter
 | 
			
		|||
	dict<SigBit, pair<SigBit, SigBit>> and_map;
 | 
			
		||||
	vector<std::tuple<SigBit,RTLIL::Cell*,RTLIL::IdString,int>> ci_bits;
 | 
			
		||||
	vector<std::tuple<SigBit,RTLIL::Cell*,RTLIL::IdString,int,int>> co_bits;
 | 
			
		||||
	dict<SigBit, float> arrival_times;
 | 
			
		||||
 | 
			
		||||
	vector<pair<int, int>> aig_gates;
 | 
			
		||||
	vector<int> aig_outputs;
 | 
			
		||||
| 
						 | 
				
			
			@ -247,14 +248,15 @@ struct XAigerWriter
 | 
			
		|||
				if (!holes_mode) {
 | 
			
		||||
					toposort.node(cell->name);
 | 
			
		||||
					for (const auto &conn : cell->connections()) {
 | 
			
		||||
						if (cell->input(conn.first)) {
 | 
			
		||||
						auto port_wire = inst_module->wire(conn.first);
 | 
			
		||||
						if (port_wire->port_input) {
 | 
			
		||||
							// Ignore inout for the sake of topographical ordering
 | 
			
		||||
							if (cell->output(conn.first)) continue;
 | 
			
		||||
							if (port_wire->port_output) continue;
 | 
			
		||||
							for (auto bit : sigmap(conn.second))
 | 
			
		||||
								bit_users[bit].insert(cell->name);
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						if (cell->output(conn.first))
 | 
			
		||||
						if (port_wire->port_output)
 | 
			
		||||
							for (auto bit : sigmap(conn.second))
 | 
			
		||||
								bit_drivers[bit].insert(cell->name);
 | 
			
		||||
					}
 | 
			
		||||
| 
						 | 
				
			
			@ -271,7 +273,7 @@ struct XAigerWriter
 | 
			
		|||
						log_error("Connection '%s' on cell '%s' (type '%s') not recognised!\n", log_id(c.first), log_id(cell), log_id(cell->type));
 | 
			
		||||
 | 
			
		||||
					if (is_input) {
 | 
			
		||||
						for (auto b : c.second.bits()) {
 | 
			
		||||
						for (auto b : c.second) {
 | 
			
		||||
							Wire *w = b.wire;
 | 
			
		||||
							if (!w) continue;
 | 
			
		||||
							if (!w->port_output || !cell_known) {
 | 
			
		||||
| 
						 | 
				
			
			@ -287,7 +289,17 @@ struct XAigerWriter
 | 
			
		|||
						}
 | 
			
		||||
					}
 | 
			
		||||
					if (is_output) {
 | 
			
		||||
						for (auto b : c.second.bits()) {
 | 
			
		||||
						int arrival = 0;
 | 
			
		||||
						if (port_wire) {
 | 
			
		||||
							auto it = port_wire->attributes.find("\\abc_arrival");
 | 
			
		||||
							if (it != port_wire->attributes.end()) {
 | 
			
		||||
								if (it->second.flags != 0)
 | 
			
		||||
									log_error("Attribute 'abc_arrival' on port '%s' of module '%s' is not an integer.\n", log_id(port_wire), log_id(cell->type));
 | 
			
		||||
								arrival = it->second.as_int();
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						for (auto b : c.second) {
 | 
			
		||||
							Wire *w = b.wire;
 | 
			
		||||
							if (!w) continue;
 | 
			
		||||
							input_bits.insert(b);
 | 
			
		||||
| 
						 | 
				
			
			@ -295,6 +307,9 @@ struct XAigerWriter
 | 
			
		|||
							if (O != b)
 | 
			
		||||
								alias_map[O] = b;
 | 
			
		||||
							undriven_bits.erase(O);
 | 
			
		||||
 | 
			
		||||
							if (arrival)
 | 
			
		||||
								arrival_times[b] = arrival;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -489,16 +504,16 @@ struct XAigerWriter
 | 
			
		|||
			aig_outputs.push_back(bit2aig(bit));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (output_bits.empty()) {
 | 
			
		||||
			output_bits.insert(State::S0);
 | 
			
		||||
			omode = true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (auto bit : output_bits) {
 | 
			
		||||
			ordered_outputs[bit] = aig_o++;
 | 
			
		||||
			aig_outputs.push_back(bit2aig(bit));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (output_bits.empty()) {
 | 
			
		||||
			aig_o++;
 | 
			
		||||
			aig_outputs.push_back(0);
 | 
			
		||||
			omode = true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void write_aiger(std::ostream &f, bool ascii_mode)
 | 
			
		||||
| 
						 | 
				
			
			@ -560,26 +575,38 @@ struct XAigerWriter
 | 
			
		|||
 | 
			
		||||
		f << "c";
 | 
			
		||||
 | 
			
		||||
		log_assert(!output_bits.empty());
 | 
			
		||||
		auto write_buffer = [](std::stringstream &buffer, int i32) {
 | 
			
		||||
			int32_t i32_be = to_big_endian(i32);
 | 
			
		||||
			buffer.write(reinterpret_cast<const char*>(&i32_be), sizeof(i32_be));
 | 
			
		||||
		};
 | 
			
		||||
		std::stringstream h_buffer;
 | 
			
		||||
		auto write_h_buffer = std::bind(write_buffer, std::ref(h_buffer), std::placeholders::_1);
 | 
			
		||||
		write_h_buffer(1);
 | 
			
		||||
		log_debug("ciNum = %d\n", GetSize(input_bits) + GetSize(ci_bits));
 | 
			
		||||
		write_h_buffer(input_bits.size() + ci_bits.size());
 | 
			
		||||
		log_debug("coNum = %d\n", GetSize(output_bits) + GetSize(co_bits));
 | 
			
		||||
		write_h_buffer(output_bits.size() + GetSize(co_bits));
 | 
			
		||||
		log_debug("piNum = %d\n", GetSize(input_bits));
 | 
			
		||||
		write_h_buffer(input_bits.size());
 | 
			
		||||
		log_debug("poNum = %d\n", GetSize(output_bits));
 | 
			
		||||
		write_h_buffer(output_bits.size());
 | 
			
		||||
		log_debug("boxNum = %d\n", GetSize(box_list));
 | 
			
		||||
		write_h_buffer(box_list.size());
 | 
			
		||||
 | 
			
		||||
		auto write_buffer_float = [](std::stringstream &buffer, float f32) {
 | 
			
		||||
			buffer.write(reinterpret_cast<const char*>(&f32), sizeof(f32));
 | 
			
		||||
		};
 | 
			
		||||
		std::stringstream i_buffer;
 | 
			
		||||
		auto write_i_buffer = std::bind(write_buffer_float, std::ref(i_buffer), std::placeholders::_1);
 | 
			
		||||
		for (auto bit : input_bits)
 | 
			
		||||
			write_i_buffer(arrival_times.at(bit, 0));
 | 
			
		||||
		//std::stringstream o_buffer;
 | 
			
		||||
		//auto write_o_buffer = std::bind(write_buffer_float, std::ref(o_buffer), std::placeholders::_1);
 | 
			
		||||
		//for (auto bit : output_bits)
 | 
			
		||||
		//	write_o_buffer(0);
 | 
			
		||||
 | 
			
		||||
		if (!box_list.empty()) {
 | 
			
		||||
			auto write_buffer = [](std::stringstream &buffer, int i32) {
 | 
			
		||||
				int32_t i32_be = to_big_endian(i32);
 | 
			
		||||
				buffer.write(reinterpret_cast<const char*>(&i32_be), sizeof(i32_be));
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			std::stringstream h_buffer;
 | 
			
		||||
			auto write_h_buffer = std::bind(write_buffer, std::ref(h_buffer), std::placeholders::_1);
 | 
			
		||||
			write_h_buffer(1);
 | 
			
		||||
			log_debug("ciNum = %d\n", GetSize(input_bits) + GetSize(ci_bits));
 | 
			
		||||
			write_h_buffer(input_bits.size() + ci_bits.size());
 | 
			
		||||
			log_debug("coNum = %d\n", GetSize(output_bits) + GetSize(co_bits));
 | 
			
		||||
			write_h_buffer(output_bits.size() + co_bits.size());
 | 
			
		||||
			log_debug("piNum = %d\n", GetSize(input_bits));
 | 
			
		||||
			write_h_buffer(input_bits.size());
 | 
			
		||||
			log_debug("poNum = %d\n", GetSize(output_bits));
 | 
			
		||||
			write_h_buffer(output_bits.size());
 | 
			
		||||
			log_debug("boxNum = %d\n", GetSize(box_list));
 | 
			
		||||
			write_h_buffer(box_list.size());
 | 
			
		||||
 | 
			
		||||
			RTLIL::Module *holes_module = module->design->addModule("$__holes__");
 | 
			
		||||
			log_assert(holes_module);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -643,19 +670,12 @@ struct XAigerWriter
 | 
			
		|||
				write_h_buffer(box_count++);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			f << "h";
 | 
			
		||||
			std::string buffer_str = h_buffer.str();
 | 
			
		||||
			int32_t buffer_size_be = to_big_endian(buffer_str.size());
 | 
			
		||||
			f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be));
 | 
			
		||||
			f.write(buffer_str.data(), buffer_str.size());
 | 
			
		||||
 | 
			
		||||
			std::stringstream r_buffer;
 | 
			
		||||
			auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1);
 | 
			
		||||
			write_r_buffer(0);
 | 
			
		||||
 | 
			
		||||
			f << "r";
 | 
			
		||||
			buffer_str = r_buffer.str();
 | 
			
		||||
			buffer_size_be = to_big_endian(buffer_str.size());
 | 
			
		||||
			std::string buffer_str = r_buffer.str();
 | 
			
		||||
			int32_t buffer_size_be = to_big_endian(buffer_str.size());
 | 
			
		||||
			f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be));
 | 
			
		||||
			f.write(buffer_str.data(), buffer_str.size());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -709,6 +729,23 @@ struct XAigerWriter
 | 
			
		|||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		f << "h";
 | 
			
		||||
		std::string buffer_str = h_buffer.str();
 | 
			
		||||
		int32_t buffer_size_be = to_big_endian(buffer_str.size());
 | 
			
		||||
		f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be));
 | 
			
		||||
		f.write(buffer_str.data(), buffer_str.size());
 | 
			
		||||
 | 
			
		||||
		f << "i";
 | 
			
		||||
		buffer_str = i_buffer.str();
 | 
			
		||||
		buffer_size_be = to_big_endian(buffer_str.size());
 | 
			
		||||
		f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be));
 | 
			
		||||
		f.write(buffer_str.data(), buffer_str.size());
 | 
			
		||||
		//f << "o";
 | 
			
		||||
		//buffer_str = o_buffer.str();
 | 
			
		||||
		//buffer_size_be = to_big_endian(buffer_str.size());
 | 
			
		||||
		//f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be));
 | 
			
		||||
		//f.write(buffer_str.data(), buffer_str.size());
 | 
			
		||||
 | 
			
		||||
		f << stringf("Generated by %s\n", yosys_version_str);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -760,11 +797,11 @@ struct XAigerWriter
 | 
			
		|||
			f << stringf("box %d %d %s\n", box_count++, 0, log_id(cell->name));
 | 
			
		||||
 | 
			
		||||
		output_lines.sort();
 | 
			
		||||
		if (omode)
 | 
			
		||||
			output_lines[State::S0] = "output 0 0 $__dummy__\n";
 | 
			
		||||
		for (auto &it : output_lines)
 | 
			
		||||
			f << it.second;
 | 
			
		||||
		log_assert(output_lines.size() == output_bits.size());
 | 
			
		||||
		if (omode && output_bits.empty())
 | 
			
		||||
			f << "output " << output_lines.size() << " 0 $__dummy__\n";
 | 
			
		||||
 | 
			
		||||
		wire_lines.sort();
 | 
			
		||||
		for (auto &it : wire_lines)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -430,6 +430,7 @@ void AigerReader::parse_xaiger(const dict<int,IdString> &box_lookup)
 | 
			
		|||
			else if (c == 'r') {
 | 
			
		||||
				uint32_t dataSize YS_ATTRIBUTE(unused) = parse_xaiger_literal(f);
 | 
			
		||||
				flopNum = parse_xaiger_literal(f);
 | 
			
		||||
				log_debug("flopNum: %u\n", flopNum);
 | 
			
		||||
				log_assert(dataSize == (flopNum+1) * sizeof(uint32_t));
 | 
			
		||||
				f.ignore(flopNum * sizeof(uint32_t));
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -496,8 +497,7 @@ void AigerReader::parse_aiger_ascii()
 | 
			
		|||
 | 
			
		||||
	// Parse latches
 | 
			
		||||
	RTLIL::Wire *clk_wire = nullptr;
 | 
			
		||||
	if (L > 0) {
 | 
			
		||||
		log_assert(clk_name != "");
 | 
			
		||||
	if (L > 0 && !clk_name.empty()) {
 | 
			
		||||
		clk_wire = module->wire(clk_name);
 | 
			
		||||
		log_assert(!clk_wire);
 | 
			
		||||
		log_debug2("Creating %s\n", clk_name.c_str());
 | 
			
		||||
| 
						 | 
				
			
			@ -513,7 +513,10 @@ void AigerReader::parse_aiger_ascii()
 | 
			
		|||
		RTLIL::Wire *q_wire = createWireIfNotExists(module, l1);
 | 
			
		||||
		RTLIL::Wire *d_wire = createWireIfNotExists(module, l2);
 | 
			
		||||
 | 
			
		||||
		module->addDffGate(NEW_ID, clk_wire, d_wire, q_wire);
 | 
			
		||||
		if (clk_wire)
 | 
			
		||||
			module->addDffGate(NEW_ID, clk_wire, d_wire, q_wire);
 | 
			
		||||
		else
 | 
			
		||||
			module->addFfGate(NEW_ID, d_wire, q_wire);
 | 
			
		||||
 | 
			
		||||
		// Reset logic is optional in AIGER 1.9
 | 
			
		||||
		if (f.peek() == ' ') {
 | 
			
		||||
| 
						 | 
				
			
			@ -621,8 +624,7 @@ void AigerReader::parse_aiger_binary()
 | 
			
		|||
 | 
			
		||||
	// Parse latches
 | 
			
		||||
	RTLIL::Wire *clk_wire = nullptr;
 | 
			
		||||
	if (L > 0) {
 | 
			
		||||
		log_assert(clk_name != "");
 | 
			
		||||
	if (L > 0 && !clk_name.empty()) {
 | 
			
		||||
		clk_wire = module->wire(clk_name);
 | 
			
		||||
		log_assert(!clk_wire);
 | 
			
		||||
		log_debug2("Creating %s\n", clk_name.c_str());
 | 
			
		||||
| 
						 | 
				
			
			@ -638,7 +640,10 @@ void AigerReader::parse_aiger_binary()
 | 
			
		|||
		RTLIL::Wire *q_wire = createWireIfNotExists(module, l1);
 | 
			
		||||
		RTLIL::Wire *d_wire = createWireIfNotExists(module, l2);
 | 
			
		||||
 | 
			
		||||
		module->addDff(NEW_ID, clk_wire, d_wire, q_wire);
 | 
			
		||||
		if (clk_wire)
 | 
			
		||||
			module->addDff(NEW_ID, clk_wire, d_wire, q_wire);
 | 
			
		||||
		else
 | 
			
		||||
			module->addFf(NEW_ID, d_wire, q_wire);
 | 
			
		||||
 | 
			
		||||
		// Reset logic is optional in AIGER 1.9
 | 
			
		||||
		if (f.peek() == ' ') {
 | 
			
		||||
| 
						 | 
				
			
			@ -776,19 +781,19 @@ void AigerReader::post_process()
 | 
			
		|||
		// NB: Assume box_module->ports are sorted alphabetically
 | 
			
		||||
		//     (as RTLIL::Module::fixup_ports() would do)
 | 
			
		||||
		for (auto port_name : box_module->ports) {
 | 
			
		||||
			RTLIL::Wire* w = box_module->wire(port_name);
 | 
			
		||||
			log_assert(w);
 | 
			
		||||
			RTLIL::Wire* port = box_module->wire(port_name);
 | 
			
		||||
			log_assert(port);
 | 
			
		||||
			RTLIL::SigSpec rhs;
 | 
			
		||||
			RTLIL::Wire* wire = nullptr;
 | 
			
		||||
			for (int i = 0; i < GetSize(w); i++) {
 | 
			
		||||
				if (w->port_input) {
 | 
			
		||||
			for (int i = 0; i < GetSize(port); i++) {
 | 
			
		||||
				RTLIL::Wire* wire = nullptr;
 | 
			
		||||
				if (port->port_input) {
 | 
			
		||||
					log_assert(co_count < outputs.size());
 | 
			
		||||
					wire = outputs[co_count++];
 | 
			
		||||
					log_assert(wire);
 | 
			
		||||
					log_assert(wire->port_output);
 | 
			
		||||
					wire->port_output = false;
 | 
			
		||||
				}
 | 
			
		||||
				if (w->port_output) {
 | 
			
		||||
				if (port->port_output) {
 | 
			
		||||
					log_assert((piNum + ci_count) < inputs.size());
 | 
			
		||||
					wire = inputs[piNum + ci_count++];
 | 
			
		||||
					log_assert(wire);
 | 
			
		||||
| 
						 | 
				
			
			@ -797,6 +802,7 @@ void AigerReader::post_process()
 | 
			
		|||
				}
 | 
			
		||||
				rhs.append(wire);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			cell->setPort(port_name, rhs);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -814,6 +820,7 @@ void AigerReader::post_process()
 | 
			
		|||
				RTLIL::Wire* wire = inputs[variable];
 | 
			
		||||
				log_assert(wire);
 | 
			
		||||
				log_assert(wire->port_input);
 | 
			
		||||
				log_debug("Renaming input %s", log_id(wire));
 | 
			
		||||
 | 
			
		||||
				if (index == 0) {
 | 
			
		||||
					// Cope with the fact that a CI might be identical
 | 
			
		||||
| 
						 | 
				
			
			@ -840,6 +847,7 @@ void AigerReader::post_process()
 | 
			
		|||
						wire->port_input = false;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				log_debug(" -> %s\n", log_id(wire));
 | 
			
		||||
			}
 | 
			
		||||
			else if (type == "output") {
 | 
			
		||||
				log_assert(static_cast<unsigned>(variable + co_count) < outputs.size());
 | 
			
		||||
| 
						 | 
				
			
			@ -850,6 +858,7 @@ void AigerReader::post_process()
 | 
			
		|||
					wire->port_output = false;
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
				log_debug("Renaming output %s", log_id(wire));
 | 
			
		||||
 | 
			
		||||
				if (index == 0) {
 | 
			
		||||
					// Cope with the fact that a CO might be identical
 | 
			
		||||
| 
						 | 
				
			
			@ -871,6 +880,7 @@ void AigerReader::post_process()
 | 
			
		|||
					else {
 | 
			
		||||
						wire->port_output = false;
 | 
			
		||||
						module->connect(wire, existing);
 | 
			
		||||
						wire = existing;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else if (index > 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -896,6 +906,7 @@ void AigerReader::post_process()
 | 
			
		|||
						wire->port_output = false;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				log_debug(" -> %s\n", log_id(wire));
 | 
			
		||||
			}
 | 
			
		||||
			else if (type == "box") {
 | 
			
		||||
				RTLIL::Cell* cell = module->cell(stringf("$__box%d__", variable));
 | 
			
		||||
| 
						 | 
				
			
			@ -1004,8 +1015,8 @@ struct AigerFrontend : public Frontend {
 | 
			
		|||
		log("        Name of module to be created (default: <filename>)\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -clk_name <wire_name>\n");
 | 
			
		||||
		log("        AIGER latches to be transformed into posedge DFFs clocked by wire of");
 | 
			
		||||
		log("        this name (default: clk)\n");
 | 
			
		||||
		log("        If specified, AIGER latches to be transformed into $_DFF_P_ cells\n");
 | 
			
		||||
		log("        clocked by wire of this name. Otherwise, $_FF_ cells will be used.\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -map <filename>\n");
 | 
			
		||||
		log("        read file with port and latch symbols\n");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1530,10 +1530,16 @@ skip_dynamic_range_lvalue_expansion:;
 | 
			
		|||
		current_scope[wire_en->str] = wire_en;
 | 
			
		||||
		while (wire_en->simplify(true, false, false, 1, -1, false, false)) { }
 | 
			
		||||
 | 
			
		||||
		std::vector<RTLIL::State> x_bit;
 | 
			
		||||
		x_bit.push_back(RTLIL::State::Sx);
 | 
			
		||||
		AstNode *check_defval;
 | 
			
		||||
		if (type == AST_LIVE || type == AST_FAIR) {
 | 
			
		||||
			check_defval = new AstNode(AST_REDUCE_BOOL, children[0]->clone());
 | 
			
		||||
		} else {
 | 
			
		||||
			std::vector<RTLIL::State> x_bit;
 | 
			
		||||
			x_bit.push_back(RTLIL::State::Sx);
 | 
			
		||||
			check_defval = mkconst_bits(x_bit, false);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		AstNode *assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bit, false));
 | 
			
		||||
		AstNode *assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), check_defval);
 | 
			
		||||
		assign_check->children[0]->str = id_check;
 | 
			
		||||
		assign_check->children[0]->was_checked = true;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1546,9 +1552,13 @@ skip_dynamic_range_lvalue_expansion:;
 | 
			
		|||
		default_signals->children.push_back(assign_en);
 | 
			
		||||
		current_top_block->children.insert(current_top_block->children.begin(), default_signals);
 | 
			
		||||
 | 
			
		||||
		assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), new AstNode(AST_REDUCE_BOOL, children[0]->clone()));
 | 
			
		||||
		assign_check->children[0]->str = id_check;
 | 
			
		||||
		assign_check->children[0]->was_checked = true;
 | 
			
		||||
		if (type == AST_LIVE || type == AST_FAIR) {
 | 
			
		||||
			assign_check = nullptr;
 | 
			
		||||
		} else {
 | 
			
		||||
			assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), new AstNode(AST_REDUCE_BOOL, children[0]->clone()));
 | 
			
		||||
			assign_check->children[0]->str = id_check;
 | 
			
		||||
			assign_check->children[0]->was_checked = true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (current_always == nullptr || current_always->type != AST_INITIAL) {
 | 
			
		||||
			assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(1, false, 1));
 | 
			
		||||
| 
						 | 
				
			
			@ -1560,7 +1570,8 @@ skip_dynamic_range_lvalue_expansion:;
 | 
			
		|||
		assign_en->children[0]->was_checked = true;
 | 
			
		||||
 | 
			
		||||
		newNode = new AstNode(AST_BLOCK);
 | 
			
		||||
		newNode->children.push_back(assign_check);
 | 
			
		||||
		if (assign_check != nullptr)
 | 
			
		||||
			newNode->children.push_back(assign_check);
 | 
			
		||||
		newNode->children.push_back(assign_en);
 | 
			
		||||
 | 
			
		||||
		AstNode *assertnode = new AstNode(type);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -76,8 +76,7 @@ inline std::string remap_name(RTLIL::IdString abc_name)
 | 
			
		|||
	return stringf("$abc$%d$%s", map_autoidx, abc_name.c_str()+1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void handle_loops(RTLIL::Design *design,
 | 
			
		||||
		const dict<IdString,pool<IdString>> &scc_break_inputs)
 | 
			
		||||
void handle_loops(RTLIL::Design *design)
 | 
			
		||||
{
 | 
			
		||||
	Pass::call(design, "scc -set_attr abc_scc_id {}");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -114,30 +113,6 @@ void handle_loops(RTLIL::Design *design,
 | 
			
		|||
			}
 | 
			
		||||
			cell->attributes.erase(it);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		auto jt = scc_break_inputs.find(cell->type);
 | 
			
		||||
		if (jt != scc_break_inputs.end())
 | 
			
		||||
			for (auto port_name : jt->second) {
 | 
			
		||||
				RTLIL::SigSpec sig;
 | 
			
		||||
				auto &rhs = cell->connections_.at(port_name);
 | 
			
		||||
				for (auto b : rhs) {
 | 
			
		||||
					Wire *w = b.wire;
 | 
			
		||||
					if (!w) continue;
 | 
			
		||||
					w->port_output = true;
 | 
			
		||||
					w->set_bool_attribute(ID(abc_scc_break));
 | 
			
		||||
					w = module->wire(stringf("%s.abci", w->name.c_str()));
 | 
			
		||||
					if (!w) {
 | 
			
		||||
						w = module->addWire(stringf("%s.abci", b.wire->name.c_str()), GetSize(b.wire));
 | 
			
		||||
						w->port_input = true;
 | 
			
		||||
					}
 | 
			
		||||
					else {
 | 
			
		||||
						log_assert(b.offset < GetSize(w));
 | 
			
		||||
						log_assert(w->port_input);
 | 
			
		||||
					}
 | 
			
		||||
					sig.append(RTLIL::SigBit(w, b.offset));
 | 
			
		||||
				}
 | 
			
		||||
				rhs = sig;
 | 
			
		||||
			}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	module->fixup_ports();
 | 
			
		||||
| 
						 | 
				
			
			@ -272,8 +247,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
 | 
			
		|||
		bool cleanup, vector<int> lut_costs, bool dff_mode, std::string clk_str,
 | 
			
		||||
		bool /*keepff*/, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode,
 | 
			
		||||
		bool show_tempdir, std::string box_file, std::string lut_file,
 | 
			
		||||
		std::string wire_delay, const dict<int,IdString> &box_lookup,
 | 
			
		||||
		const dict<IdString,pool<IdString>> &scc_break_inputs
 | 
			
		||||
		std::string wire_delay, const dict<int,IdString> &box_lookup
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	module = current_module;
 | 
			
		||||
| 
						 | 
				
			
			@ -413,7 +387,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
 | 
			
		|||
		RTLIL::Selection& sel = design->selection_stack.back();
 | 
			
		||||
		sel.select(module);
 | 
			
		||||
 | 
			
		||||
		handle_loops(design, scc_break_inputs);
 | 
			
		||||
		handle_loops(design);
 | 
			
		||||
 | 
			
		||||
		Pass::call(design, "aigmap");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1050,9 +1024,6 @@ struct Abc9Pass : public Pass {
 | 
			
		|||
			}
 | 
			
		||||
			if (arg == "-box" && argidx+1 < args.size()) {
 | 
			
		||||
				box_file = args[++argidx];
 | 
			
		||||
				rewrite_filename(box_file);
 | 
			
		||||
				if (!box_file.empty() && !is_absolute_path(box_file))
 | 
			
		||||
					box_file = std::string(pwd) + "/" + box_file;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (arg == "-W" && argidx+1 < args.size()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1063,8 +1034,15 @@ struct Abc9Pass : public Pass {
 | 
			
		|||
		}
 | 
			
		||||
		extra_args(args, argidx, design);
 | 
			
		||||
 | 
			
		||||
		// ABC expects a box file for XAIG
 | 
			
		||||
		if (box_file.empty())
 | 
			
		||||
		    box_file = "+/dummy.box";
 | 
			
		||||
 | 
			
		||||
		rewrite_filename(box_file);
 | 
			
		||||
		if (!box_file.empty() && !is_absolute_path(box_file))
 | 
			
		||||
		    box_file = std::string(pwd) + "/" + box_file;
 | 
			
		||||
 | 
			
		||||
		dict<int,IdString> box_lookup;
 | 
			
		||||
		dict<IdString,pool<IdString>> scc_break_inputs;
 | 
			
		||||
		for (auto m : design->modules()) {
 | 
			
		||||
			auto it = m->attributes.find(ID(abc_box_id));
 | 
			
		||||
			if (it == m->attributes.end())
 | 
			
		||||
| 
						 | 
				
			
			@ -1082,17 +1060,13 @@ struct Abc9Pass : public Pass {
 | 
			
		|||
			for (auto p : m->ports) {
 | 
			
		||||
				auto w = m->wire(p);
 | 
			
		||||
				log_assert(w);
 | 
			
		||||
				if (w->port_input) {
 | 
			
		||||
					if (w->attributes.count(ID(abc_scc_break)))
 | 
			
		||||
						scc_break_inputs[m->name].insert(p);
 | 
			
		||||
					if (w->attributes.count(ID(abc_carry))) {
 | 
			
		||||
				if (w->attributes.count(ID(abc_carry))) {
 | 
			
		||||
					if (w->port_input) {
 | 
			
		||||
						if (carry_in)
 | 
			
		||||
							log_error("Module '%s' contains more than one 'abc_carry' input port.\n", log_id(m));
 | 
			
		||||
						carry_in = w;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if (w->port_output) {
 | 
			
		||||
					if (w->attributes.count(ID(abc_carry))) {
 | 
			
		||||
					else if (w->port_output) {
 | 
			
		||||
						if (carry_out)
 | 
			
		||||
							log_error("Module '%s' contains more than one 'abc_carry' input port.\n", log_id(m));
 | 
			
		||||
						carry_out = w;
 | 
			
		||||
| 
						 | 
				
			
			@ -1144,7 +1118,7 @@ struct Abc9Pass : public Pass {
 | 
			
		|||
			if (!dff_mode || !clk_str.empty()) {
 | 
			
		||||
				abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, dff_mode, clk_str, keepff,
 | 
			
		||||
						delay_target, lutin_shared, fast_mode, show_tempdir,
 | 
			
		||||
						box_file, lut_file, wire_delay, box_lookup, scc_break_inputs);
 | 
			
		||||
						box_file, lut_file, wire_delay, box_lookup);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1290,7 +1264,7 @@ struct Abc9Pass : public Pass {
 | 
			
		|||
				en_sig = assign_map(std::get<3>(it.first));
 | 
			
		||||
				abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, !clk_sig.empty(), "$",
 | 
			
		||||
						keepff, delay_target, lutin_shared, fast_mode, show_tempdir,
 | 
			
		||||
						box_file, lut_file, wire_delay, box_lookup, scc_break_inputs);
 | 
			
		||||
						box_file, lut_file, wire_delay, box_lookup);
 | 
			
		||||
				assign_map.set(mod);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -205,20 +205,38 @@ struct TechmapWorker
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		std::map<RTLIL::IdString, RTLIL::IdString> positional_ports;
 | 
			
		||||
		dict<Wire*, IdString> temp_renamed_wires;
 | 
			
		||||
 | 
			
		||||
		for (auto &it : tpl->wires_) {
 | 
			
		||||
			if (it.second->port_id > 0)
 | 
			
		||||
				positional_ports[stringf("$%d", it.second->port_id)] = it.first;
 | 
			
		||||
			IdString w_name = it.second->name;
 | 
			
		||||
			apply_prefix(cell->name, w_name);
 | 
			
		||||
			RTLIL::Wire *w = module->addWire(w_name, it.second);
 | 
			
		||||
			w->port_input = false;
 | 
			
		||||
			w->port_output = false;
 | 
			
		||||
			w->port_id = 0;
 | 
			
		||||
			if (it.second->get_bool_attribute(ID(_techmap_special_)))
 | 
			
		||||
				w->attributes.clear();
 | 
			
		||||
			if (w->attributes.count(ID(src)))
 | 
			
		||||
				w->add_strpool_attribute(ID(src), extra_src_attrs);
 | 
			
		||||
			RTLIL::Wire *w = module->wire(w_name);
 | 
			
		||||
			if (w != nullptr) {
 | 
			
		||||
				if (!flatten_mode || !w->get_bool_attribute(ID(hierconn))) {
 | 
			
		||||
					temp_renamed_wires[w] = w->name;
 | 
			
		||||
					module->rename(w, NEW_ID);
 | 
			
		||||
					w = nullptr;
 | 
			
		||||
				} else {
 | 
			
		||||
					w->attributes.erase(ID(hierconn));
 | 
			
		||||
					if (GetSize(w) < GetSize(it.second)) {
 | 
			
		||||
						log_warning("Widening signal %s.%s to match size of %s.%s (via %s.%s).\n", log_id(module), log_id(w),
 | 
			
		||||
								log_id(tpl), log_id(it.second), log_id(module), log_id(cell));
 | 
			
		||||
						w->width = GetSize(it.second);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if (w == nullptr) {
 | 
			
		||||
				w = module->addWire(w_name, it.second);
 | 
			
		||||
				w->port_input = false;
 | 
			
		||||
				w->port_output = false;
 | 
			
		||||
				w->port_id = 0;
 | 
			
		||||
				if (it.second->get_bool_attribute(ID(_techmap_special_)))
 | 
			
		||||
					w->attributes.clear();
 | 
			
		||||
				if (w->attributes.count(ID(src)))
 | 
			
		||||
					w->add_strpool_attribute(ID(src), extra_src_attrs);
 | 
			
		||||
			}
 | 
			
		||||
			design->select(module, w);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -380,6 +398,16 @@ struct TechmapWorker
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		module->remove(cell);
 | 
			
		||||
 | 
			
		||||
		for (auto &it : temp_renamed_wires)
 | 
			
		||||
		{
 | 
			
		||||
			Wire *w = it.first;
 | 
			
		||||
			IdString name = it.second;
 | 
			
		||||
			IdString altname = module->uniquify(name);
 | 
			
		||||
			Wire *other_w = module->wire(name);
 | 
			
		||||
			module->rename(other_w, altname);
 | 
			
		||||
			module->rename(w, name);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool techmap_module(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Design *map, std::set<RTLIL::Cell*> &handled_cells,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,3 +29,4 @@ $(eval $(call add_share_file,share,techlibs/common/gate2lut.v))
 | 
			
		|||
$(eval $(call add_share_file,share,techlibs/common/cmp2lut.v))
 | 
			
		||||
$(eval $(call add_share_file,share,techlibs/common/cells.lib))
 | 
			
		||||
$(eval $(call add_share_file,share,techlibs/common/mul2dsp.v))
 | 
			
		||||
$(eval $(call add_share_file,share,techlibs/common/dummy.box))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								techlibs/common/dummy.box
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								techlibs/common/dummy.box
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
(dummy) 1 0 0 0
 | 
			
		||||
| 
						 | 
				
			
			@ -15,6 +15,9 @@ $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/arith_map.v))
 | 
			
		|||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/latches_map.v))
 | 
			
		||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/dsp_map.v))
 | 
			
		||||
 | 
			
		||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_map.v))
 | 
			
		||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_unmap.v))
 | 
			
		||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_model.v))
 | 
			
		||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_5g.box))
 | 
			
		||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_5g.lut))
 | 
			
		||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_5g_nowide.lut))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,16 +15,16 @@ CCU2C   1      1   9      3
 | 
			
		|||
630  379  630  379  526   275  392  141  273
 | 
			
		||||
516  516  516  516  412   412  278  278  43
 | 
			
		||||
 | 
			
		||||
# Box 2 : TRELLIS_DPR16X4 (16x4 dist ram)
 | 
			
		||||
# Box 2 : TRELLIS_DPR16X4_COMB (16x4 dist ram)
 | 
			
		||||
# Outputs: DO0, DO1, DO2, DO3
 | 
			
		||||
# name            ID  w/b   ins   outs
 | 
			
		||||
TRELLIS_DPR16X4   2     0   14    4
 | 
			
		||||
# name               ID  w/b   ins   outs
 | 
			
		||||
$__ABC_DPR16X4_COMB  2     0   8    4
 | 
			
		||||
 | 
			
		||||
#DI0   DI1   DI2   DI3   RAD0   RAD1   RAD2   RAD3   WAD0    WAD1   WAD2   WAD3  WCK   WRE
 | 
			
		||||
-      -     -     -     141    379    275    379    -       -      -      -     -     -
 | 
			
		||||
-      -     -     -     141    379    275    379    -       -      -      -     -     -
 | 
			
		||||
-      -     -     -     141    379    275    379    -       -      -      -     -     -
 | 
			
		||||
-      -     -     -     141    379    275    379    -       -      -      -     -     -
 | 
			
		||||
#A0   A1   A2   A3   RAD0   RAD1   RAD2   RAD3
 | 
			
		||||
0     0    0    0    141    379    275    379
 | 
			
		||||
0     0    0    0    141    379    275    379
 | 
			
		||||
0     0    0    0    141    379    275    379
 | 
			
		||||
0     0    0    0    141    379    275    379
 | 
			
		||||
 | 
			
		||||
# Box 3 : PFUMX (MUX2)
 | 
			
		||||
# Outputs: Z
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										24
									
								
								techlibs/ecp5/abc_map.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								techlibs/ecp5/abc_map.v
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
// ---------------------------------------
 | 
			
		||||
 | 
			
		||||
module TRELLIS_DPR16X4 (
 | 
			
		||||
	input  [3:0] DI,
 | 
			
		||||
	input  [3:0] WAD,
 | 
			
		||||
	input        WRE,
 | 
			
		||||
	input        WCK,
 | 
			
		||||
	input  [3:0] RAD,
 | 
			
		||||
	output [3:0] DO
 | 
			
		||||
);
 | 
			
		||||
	parameter WCKMUX = "WCK";
 | 
			
		||||
	parameter WREMUX = "WRE";
 | 
			
		||||
	parameter [63:0] INITVAL = 64'h0000000000000000;
 | 
			
		||||
    wire [3:0] \$DO ;
 | 
			
		||||
 | 
			
		||||
    TRELLIS_DPR16X4 #(
 | 
			
		||||
      .WCKMUX(WCKMUX), .WREMUX(WREMUX), .INITVAL(INITVAL)
 | 
			
		||||
    ) _TECHMAP_REPLACE_ (
 | 
			
		||||
      .DI(DI), .WAD(WAD), .WRE(WRE), .WCK(WCK),
 | 
			
		||||
      .RAD(RAD), .DO(\$DO )
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    \$__ABC_DPR16X4_COMB do (.A(\$DO ), .S(RAD), .Y(DO));
 | 
			
		||||
endmodule
 | 
			
		||||
							
								
								
									
										5
									
								
								techlibs/ecp5/abc_model.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								techlibs/ecp5/abc_model.v
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
// ---------------------------------------
 | 
			
		||||
 | 
			
		||||
(* abc_box_id=2 *)
 | 
			
		||||
module \$__ABC_DPR16X4_COMB (input [3:0] A, S, output [3:0] Y);
 | 
			
		||||
endmodule
 | 
			
		||||
							
								
								
									
										5
									
								
								techlibs/ecp5/abc_unmap.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								techlibs/ecp5/abc_unmap.v
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
// ---------------------------------------
 | 
			
		||||
 | 
			
		||||
module \$__ABC_DPR16X4_COMB (input [3:0] A, S, output [3:0] Y);
 | 
			
		||||
    assign Y = A;
 | 
			
		||||
endmodule
 | 
			
		||||
| 
						 | 
				
			
			@ -109,16 +109,13 @@ module PFUMX (input ALUT, BLUT, C0, output Z);
 | 
			
		|||
endmodule
 | 
			
		||||
 | 
			
		||||
// ---------------------------------------
 | 
			
		||||
//(* abc_box_id=2 *)
 | 
			
		||||
module TRELLIS_DPR16X4 (
 | 
			
		||||
	(* abc_scc_break *)
 | 
			
		||||
	input  [3:0] DI,
 | 
			
		||||
	(* abc_scc_break *)
 | 
			
		||||
	input  [3:0] WAD,
 | 
			
		||||
	(* abc_scc_break *)
 | 
			
		||||
	input        WRE,
 | 
			
		||||
	input        WCK,
 | 
			
		||||
	input  [3:0] RAD,
 | 
			
		||||
	/* (* abc_arrival=<TODO> *) */
 | 
			
		||||
	output [3:0] DO
 | 
			
		||||
);
 | 
			
		||||
	parameter WCKMUX = "WCK";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -310,12 +310,17 @@ struct SynthEcp5Pass : public ScriptPass
 | 
			
		|||
			if (abc2 || help_mode) {
 | 
			
		||||
				run("abc", "      (only if -abc2)");
 | 
			
		||||
			}
 | 
			
		||||
			run("techmap -map +/ecp5/latches_map.v");
 | 
			
		||||
			std::string techmap_args = "-map +/ecp5/latches_map.v";
 | 
			
		||||
			if (abc9)
 | 
			
		||||
				techmap_args += " -map +/ecp5/abc_map.v -max_iter 1";
 | 
			
		||||
			run("techmap " + techmap_args);
 | 
			
		||||
 | 
			
		||||
			if (abc9) {
 | 
			
		||||
				if (nowidelut)
 | 
			
		||||
					run("abc9 -lut +/ecp5/abc_5g_nowide.lut -box +/ecp5/abc_5g.box -W 200");
 | 
			
		||||
				else
 | 
			
		||||
					run("abc9 -lut +/ecp5/abc_5g.lut -box +/ecp5/abc_5g.box -W 200");
 | 
			
		||||
				run("techmap -map +/ecp5/abc_unmap.v");
 | 
			
		||||
			} else {
 | 
			
		||||
				if (nowidelut)
 | 
			
		||||
					run("abc -lut 4 -dress");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,10 @@
 | 
			
		|||
`define SB_DFF_REG reg Q = 0
 | 
			
		||||
// `define SB_DFF_REG reg Q
 | 
			
		||||
 | 
			
		||||
`define ABC_ARRIVAL_HX(TIME) `ifdef ICE40_HX (* abc_arrival=TIME *) `endif
 | 
			
		||||
`define ABC_ARRIVAL_LP(TIME) `ifdef ICE40_LP (* abc_arrival=TIME *) `endif
 | 
			
		||||
`define ABC_ARRIVAL_U(TIME)  `ifdef ICE40_U (* abc_arrival=TIME *) `endif
 | 
			
		||||
 | 
			
		||||
// SiliconBlue IO Cells
 | 
			
		||||
 | 
			
		||||
module SB_IO (
 | 
			
		||||
| 
						 | 
				
			
			@ -169,20 +173,42 @@ module \$__ICE40_CARRY_WRAPPER (
 | 
			
		|||
	);
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
// Max delay from: https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
 | 
			
		||||
//                 https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
 | 
			
		||||
//                 https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
 | 
			
		||||
 | 
			
		||||
// Positive Edge SiliconBlue FF Cells
 | 
			
		||||
 | 
			
		||||
module SB_DFF (output `SB_DFF_REG, input C, D);
 | 
			
		||||
module SB_DFF (
 | 
			
		||||
	`ABC_ARRIVAL_HX(540)
 | 
			
		||||
	`ABC_ARRIVAL_LP(796)
 | 
			
		||||
	`ABC_ARRIVAL_U(1391)
 | 
			
		||||
	output `SB_DFF_REG,
 | 
			
		||||
	input C, D
 | 
			
		||||
);
 | 
			
		||||
	always @(posedge C)
 | 
			
		||||
		Q <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module SB_DFFE (output `SB_DFF_REG, input C, E, D);
 | 
			
		||||
module SB_DFFE (
 | 
			
		||||
	`ABC_ARRIVAL_HX(540)
 | 
			
		||||
	`ABC_ARRIVAL_LP(796)
 | 
			
		||||
	`ABC_ARRIVAL_U(1391)
 | 
			
		||||
	output `SB_DFF_REG,
 | 
			
		||||
	input C, E, D
 | 
			
		||||
);
 | 
			
		||||
	always @(posedge C)
 | 
			
		||||
		if (E)
 | 
			
		||||
			Q <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module SB_DFFSR (output `SB_DFF_REG, input C, R, D);
 | 
			
		||||
module SB_DFFSR (
 | 
			
		||||
	`ABC_ARRIVAL_HX(540)
 | 
			
		||||
	`ABC_ARRIVAL_LP(796)
 | 
			
		||||
	`ABC_ARRIVAL_U(1391)
 | 
			
		||||
	output `SB_DFF_REG,
 | 
			
		||||
	input C, R, D
 | 
			
		||||
);
 | 
			
		||||
	always @(posedge C)
 | 
			
		||||
		if (R)
 | 
			
		||||
			Q <= 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -190,7 +216,13 @@ module SB_DFFSR (output `SB_DFF_REG, input C, R, D);
 | 
			
		|||
			Q <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module SB_DFFR (output `SB_DFF_REG, input C, R, D);
 | 
			
		||||
module SB_DFFR (
 | 
			
		||||
	`ABC_ARRIVAL_HX(540)
 | 
			
		||||
	`ABC_ARRIVAL_LP(796)
 | 
			
		||||
	`ABC_ARRIVAL_U(1391)
 | 
			
		||||
	output `SB_DFF_REG,
 | 
			
		||||
	input C, R, D
 | 
			
		||||
);
 | 
			
		||||
	always @(posedge C, posedge R)
 | 
			
		||||
		if (R)
 | 
			
		||||
			Q <= 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -198,7 +230,13 @@ module SB_DFFR (output `SB_DFF_REG, input C, R, D);
 | 
			
		|||
			Q <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module SB_DFFSS (output `SB_DFF_REG, input C, S, D);
 | 
			
		||||
module SB_DFFSS (
 | 
			
		||||
	`ABC_ARRIVAL_HX(540)
 | 
			
		||||
	`ABC_ARRIVAL_LP(796)
 | 
			
		||||
	`ABC_ARRIVAL_U(1391)
 | 
			
		||||
	output `SB_DFF_REG,
 | 
			
		||||
	input C, S, D
 | 
			
		||||
);
 | 
			
		||||
	always @(posedge C)
 | 
			
		||||
		if (S)
 | 
			
		||||
			Q <= 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -206,7 +244,13 @@ module SB_DFFSS (output `SB_DFF_REG, input C, S, D);
 | 
			
		|||
			Q <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module SB_DFFS (output `SB_DFF_REG, input C, S, D);
 | 
			
		||||
module SB_DFFS (
 | 
			
		||||
	`ABC_ARRIVAL_HX(540)
 | 
			
		||||
	`ABC_ARRIVAL_LP(796)
 | 
			
		||||
	`ABC_ARRIVAL_U(1391)
 | 
			
		||||
	output `SB_DFF_REG,
 | 
			
		||||
	input C, S, D
 | 
			
		||||
);
 | 
			
		||||
	always @(posedge C, posedge S)
 | 
			
		||||
		if (S)
 | 
			
		||||
			Q <= 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -214,7 +258,13 @@ module SB_DFFS (output `SB_DFF_REG, input C, S, D);
 | 
			
		|||
			Q <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module SB_DFFESR (output `SB_DFF_REG, input C, E, R, D);
 | 
			
		||||
module SB_DFFESR (
 | 
			
		||||
	`ABC_ARRIVAL_HX(540)
 | 
			
		||||
	`ABC_ARRIVAL_LP(796)
 | 
			
		||||
	`ABC_ARRIVAL_U(1391)
 | 
			
		||||
	output `SB_DFF_REG,
 | 
			
		||||
	input C, E, R, D
 | 
			
		||||
);
 | 
			
		||||
	always @(posedge C)
 | 
			
		||||
		if (E) begin
 | 
			
		||||
			if (R)
 | 
			
		||||
| 
						 | 
				
			
			@ -224,7 +274,13 @@ module SB_DFFESR (output `SB_DFF_REG, input C, E, R, D);
 | 
			
		|||
		end
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module SB_DFFER (output `SB_DFF_REG, input C, E, R, D);
 | 
			
		||||
module SB_DFFER (
 | 
			
		||||
	`ABC_ARRIVAL_HX(540)
 | 
			
		||||
	`ABC_ARRIVAL_LP(796)
 | 
			
		||||
	`ABC_ARRIVAL_U(1391)
 | 
			
		||||
	output `SB_DFF_REG,
 | 
			
		||||
	input C, E, R, D
 | 
			
		||||
);
 | 
			
		||||
	always @(posedge C, posedge R)
 | 
			
		||||
		if (R)
 | 
			
		||||
			Q <= 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -232,7 +288,13 @@ module SB_DFFER (output `SB_DFF_REG, input C, E, R, D);
 | 
			
		|||
			Q <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module SB_DFFESS (output `SB_DFF_REG, input C, E, S, D);
 | 
			
		||||
module SB_DFFESS (
 | 
			
		||||
	`ABC_ARRIVAL_HX(540)
 | 
			
		||||
	`ABC_ARRIVAL_LP(796)
 | 
			
		||||
	`ABC_ARRIVAL_U(1391)
 | 
			
		||||
	output `SB_DFF_REG,
 | 
			
		||||
	input C, E, S, D
 | 
			
		||||
);
 | 
			
		||||
	always @(posedge C)
 | 
			
		||||
		if (E) begin
 | 
			
		||||
			if (S)
 | 
			
		||||
| 
						 | 
				
			
			@ -242,7 +304,13 @@ module SB_DFFESS (output `SB_DFF_REG, input C, E, S, D);
 | 
			
		|||
		end
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module SB_DFFES (output `SB_DFF_REG, input C, E, S, D);
 | 
			
		||||
module SB_DFFES (
 | 
			
		||||
	`ABC_ARRIVAL_HX(540)
 | 
			
		||||
	`ABC_ARRIVAL_LP(796)
 | 
			
		||||
	`ABC_ARRIVAL_U(1391)
 | 
			
		||||
	output `SB_DFF_REG,
 | 
			
		||||
	input C, E, S, D
 | 
			
		||||
);
 | 
			
		||||
	always @(posedge C, posedge S)
 | 
			
		||||
		if (S)
 | 
			
		||||
			Q <= 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -252,18 +320,36 @@ endmodule
 | 
			
		|||
 | 
			
		||||
// Negative Edge SiliconBlue FF Cells
 | 
			
		||||
 | 
			
		||||
module SB_DFFN (output `SB_DFF_REG, input C, D);
 | 
			
		||||
module SB_DFFN (
 | 
			
		||||
	`ABC_ARRIVAL_HX(540)
 | 
			
		||||
	`ABC_ARRIVAL_LP(796)
 | 
			
		||||
	`ABC_ARRIVAL_U(1391)
 | 
			
		||||
	output `SB_DFF_REG,
 | 
			
		||||
	input C, D
 | 
			
		||||
);
 | 
			
		||||
	always @(negedge C)
 | 
			
		||||
		Q <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module SB_DFFNE (output `SB_DFF_REG, input C, E, D);
 | 
			
		||||
module SB_DFFNE (
 | 
			
		||||
	`ABC_ARRIVAL_HX(540)
 | 
			
		||||
	`ABC_ARRIVAL_LP(796)
 | 
			
		||||
	`ABC_ARRIVAL_U(1391)
 | 
			
		||||
	output `SB_DFF_REG,
 | 
			
		||||
	input C, E, D
 | 
			
		||||
);
 | 
			
		||||
	always @(negedge C)
 | 
			
		||||
		if (E)
 | 
			
		||||
			Q <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module SB_DFFNSR (output `SB_DFF_REG, input C, R, D);
 | 
			
		||||
module SB_DFFNSR (
 | 
			
		||||
	`ABC_ARRIVAL_HX(540)
 | 
			
		||||
	`ABC_ARRIVAL_LP(796)
 | 
			
		||||
	`ABC_ARRIVAL_U(1391)
 | 
			
		||||
	output `SB_DFF_REG,
 | 
			
		||||
	input C, R, D
 | 
			
		||||
);
 | 
			
		||||
	always @(negedge C)
 | 
			
		||||
		if (R)
 | 
			
		||||
			Q <= 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -271,7 +357,13 @@ module SB_DFFNSR (output `SB_DFF_REG, input C, R, D);
 | 
			
		|||
			Q <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module SB_DFFNR (output `SB_DFF_REG, input C, R, D);
 | 
			
		||||
module SB_DFFNR (
 | 
			
		||||
	`ABC_ARRIVAL_HX(540)
 | 
			
		||||
	`ABC_ARRIVAL_LP(796)
 | 
			
		||||
	`ABC_ARRIVAL_U(1391)
 | 
			
		||||
	output `SB_DFF_REG,
 | 
			
		||||
	input C, R, D
 | 
			
		||||
);
 | 
			
		||||
	always @(negedge C, posedge R)
 | 
			
		||||
		if (R)
 | 
			
		||||
			Q <= 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -279,7 +371,13 @@ module SB_DFFNR (output `SB_DFF_REG, input C, R, D);
 | 
			
		|||
			Q <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module SB_DFFNSS (output `SB_DFF_REG, input C, S, D);
 | 
			
		||||
module SB_DFFNSS (
 | 
			
		||||
	`ABC_ARRIVAL_HX(540)
 | 
			
		||||
	`ABC_ARRIVAL_LP(796)
 | 
			
		||||
	`ABC_ARRIVAL_U(1391)
 | 
			
		||||
	output `SB_DFF_REG,
 | 
			
		||||
	input C, S, D
 | 
			
		||||
);
 | 
			
		||||
	always @(negedge C)
 | 
			
		||||
		if (S)
 | 
			
		||||
			Q <= 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -287,7 +385,13 @@ module SB_DFFNSS (output `SB_DFF_REG, input C, S, D);
 | 
			
		|||
			Q <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module SB_DFFNS (output `SB_DFF_REG, input C, S, D);
 | 
			
		||||
module SB_DFFNS (
 | 
			
		||||
	`ABC_ARRIVAL_HX(540)
 | 
			
		||||
	`ABC_ARRIVAL_LP(796)
 | 
			
		||||
	`ABC_ARRIVAL_U(1391)
 | 
			
		||||
	output `SB_DFF_REG,
 | 
			
		||||
	input C, S, D
 | 
			
		||||
);
 | 
			
		||||
	always @(negedge C, posedge S)
 | 
			
		||||
		if (S)
 | 
			
		||||
			Q <= 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -295,7 +399,13 @@ module SB_DFFNS (output `SB_DFF_REG, input C, S, D);
 | 
			
		|||
			Q <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module SB_DFFNESR (output `SB_DFF_REG, input C, E, R, D);
 | 
			
		||||
module SB_DFFNESR (
 | 
			
		||||
	`ABC_ARRIVAL_HX(540)
 | 
			
		||||
	`ABC_ARRIVAL_LP(796)
 | 
			
		||||
	`ABC_ARRIVAL_U(1391)
 | 
			
		||||
	output `SB_DFF_REG,
 | 
			
		||||
	input C, E, R, D
 | 
			
		||||
);
 | 
			
		||||
	always @(negedge C)
 | 
			
		||||
		if (E) begin
 | 
			
		||||
			if (R)
 | 
			
		||||
| 
						 | 
				
			
			@ -305,7 +415,13 @@ module SB_DFFNESR (output `SB_DFF_REG, input C, E, R, D);
 | 
			
		|||
		end
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module SB_DFFNER (output `SB_DFF_REG, input C, E, R, D);
 | 
			
		||||
module SB_DFFNER (
 | 
			
		||||
	`ABC_ARRIVAL_HX(540)
 | 
			
		||||
	`ABC_ARRIVAL_LP(796)
 | 
			
		||||
	`ABC_ARRIVAL_U(1391)
 | 
			
		||||
	output `SB_DFF_REG,
 | 
			
		||||
	input C, E, R, D
 | 
			
		||||
);
 | 
			
		||||
	always @(negedge C, posedge R)
 | 
			
		||||
		if (R)
 | 
			
		||||
			Q <= 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -313,7 +429,13 @@ module SB_DFFNER (output `SB_DFF_REG, input C, E, R, D);
 | 
			
		|||
			Q <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module SB_DFFNESS (output `SB_DFF_REG, input C, E, S, D);
 | 
			
		||||
module SB_DFFNESS (
 | 
			
		||||
	`ABC_ARRIVAL_HX(540)
 | 
			
		||||
	`ABC_ARRIVAL_LP(796)
 | 
			
		||||
	`ABC_ARRIVAL_U(1391)
 | 
			
		||||
	output `SB_DFF_REG,
 | 
			
		||||
	input C, E, S, D
 | 
			
		||||
);
 | 
			
		||||
	always @(negedge C)
 | 
			
		||||
		if (E) begin
 | 
			
		||||
			if (S)
 | 
			
		||||
| 
						 | 
				
			
			@ -323,7 +445,13 @@ module SB_DFFNESS (output `SB_DFF_REG, input C, E, S, D);
 | 
			
		|||
		end
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module SB_DFFNES (output `SB_DFF_REG, input C, E, S, D);
 | 
			
		||||
module SB_DFFNES (
 | 
			
		||||
	`ABC_ARRIVAL_HX(540)
 | 
			
		||||
	`ABC_ARRIVAL_LP(796)
 | 
			
		||||
	`ABC_ARRIVAL_U(1391)
 | 
			
		||||
	output `SB_DFF_REG,
 | 
			
		||||
	input C, E, S, D
 | 
			
		||||
);
 | 
			
		||||
	always @(negedge C, posedge S)
 | 
			
		||||
		if (S)
 | 
			
		||||
			Q <= 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -334,6 +462,9 @@ endmodule
 | 
			
		|||
// SiliconBlue RAM Cells
 | 
			
		||||
 | 
			
		||||
module SB_RAM40_4K (
 | 
			
		||||
	`ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
 | 
			
		||||
	`ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
 | 
			
		||||
	`ABC_ARRIVAL_U(1179)  // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
 | 
			
		||||
	output [15:0] RDATA,
 | 
			
		||||
	input         RCLK, RCLKE, RE,
 | 
			
		||||
	input  [10:0] RADDR,
 | 
			
		||||
| 
						 | 
				
			
			@ -502,6 +633,9 @@ module SB_RAM40_4K (
 | 
			
		|||
endmodule
 | 
			
		||||
 | 
			
		||||
module SB_RAM40_4KNR (
 | 
			
		||||
	`ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
 | 
			
		||||
	`ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
 | 
			
		||||
	`ABC_ARRIVAL_U(1179)  // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
 | 
			
		||||
	output [15:0] RDATA,
 | 
			
		||||
	input         RCLKN, RCLKE, RE,
 | 
			
		||||
	input  [10:0] RADDR,
 | 
			
		||||
| 
						 | 
				
			
			@ -567,6 +701,9 @@ module SB_RAM40_4KNR (
 | 
			
		|||
endmodule
 | 
			
		||||
 | 
			
		||||
module SB_RAM40_4KNW (
 | 
			
		||||
	`ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
 | 
			
		||||
	`ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
 | 
			
		||||
	`ABC_ARRIVAL_U(1179)  // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
 | 
			
		||||
	output [15:0] RDATA,
 | 
			
		||||
	input         RCLK, RCLKE, RE,
 | 
			
		||||
	input  [10:0] RADDR,
 | 
			
		||||
| 
						 | 
				
			
			@ -632,6 +769,9 @@ module SB_RAM40_4KNW (
 | 
			
		|||
endmodule
 | 
			
		||||
 | 
			
		||||
module SB_RAM40_4KNRNW (
 | 
			
		||||
	`ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
 | 
			
		||||
	`ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
 | 
			
		||||
	`ABC_ARRIVAL_U(1179)  // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
 | 
			
		||||
	output [15:0] RDATA,
 | 
			
		||||
	input         RCLKN, RCLKE, RE,
 | 
			
		||||
	input  [10:0] RADDR,
 | 
			
		||||
| 
						 | 
				
			
			@ -700,7 +840,12 @@ endmodule
 | 
			
		|||
 | 
			
		||||
module ICESTORM_LC (
 | 
			
		||||
	input I0, I1, I2, I3, CIN, CLK, CEN, SR,
 | 
			
		||||
	output LO, O, COUT
 | 
			
		||||
	output LO,
 | 
			
		||||
	`ABC_ARRIVAL_HX(540)
 | 
			
		||||
	`ABC_ARRIVAL_LP(796)
 | 
			
		||||
	`ABC_ARRIVAL_U(1391)
 | 
			
		||||
	output O,
 | 
			
		||||
	output COUT
 | 
			
		||||
);
 | 
			
		||||
	parameter [15:0] LUT_INIT = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1300,6 +1445,7 @@ module SB_MAC16 (
 | 
			
		|||
	input ADDSUBTOP, ADDSUBBOT,
 | 
			
		||||
	input OHOLDTOP, OHOLDBOT,
 | 
			
		||||
	input CI, ACCUMCI, SIGNEXTIN,
 | 
			
		||||
	//`ABC_ARRIVAL_U(1984)  // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
 | 
			
		||||
	output [31:0] O,
 | 
			
		||||
	output CO, ACCUMCO, SIGNEXTOUT
 | 
			
		||||
);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -238,7 +238,14 @@ struct SynthIce40Pass : public ScriptPass
 | 
			
		|||
	{
 | 
			
		||||
		if (check_label("begin"))
 | 
			
		||||
		{
 | 
			
		||||
			run("read_verilog -icells -lib +/ice40/cells_sim.v");
 | 
			
		||||
			std::string define;
 | 
			
		||||
			if (device_opt == "lp")
 | 
			
		||||
				define = "-D ICE40_LP";
 | 
			
		||||
			else if (device_opt == "u")
 | 
			
		||||
				define = "-D ICE40_U";
 | 
			
		||||
			else
 | 
			
		||||
				define = "-D ICE40_HX";
 | 
			
		||||
			run("read_verilog -icells " + define + " -lib +/ice40/cells_sim.v");
 | 
			
		||||
			run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
 | 
			
		||||
			run("proc");
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,6 +40,9 @@ $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut_map.v))
 | 
			
		|||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/mux_map.v))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/dsp_map.v))
 | 
			
		||||
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_map.v))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_unmap.v))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_model.v))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_xc7.box))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_xc7.lut))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_xc7_nowide.lut))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										123
									
								
								techlibs/xilinx/abc_map.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								techlibs/xilinx/abc_map.v
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,123 @@
 | 
			
		|||
/*
 | 
			
		||||
 *  yosys -- Yosys Open SYnthesis Suite
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 | 
			
		||||
 *                2019  Eddie Hung    <eddie@fpgeh.com>
 | 
			
		||||
 *
 | 
			
		||||
 *  Permission to use, copy, modify, and/or distribute this software for any
 | 
			
		||||
 *  purpose with or without fee is hereby granted, provided that the above
 | 
			
		||||
 *  copyright notice and this permission notice appear in all copies.
 | 
			
		||||
 *
 | 
			
		||||
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
			
		||||
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
			
		||||
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
			
		||||
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
			
		||||
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
			
		||||
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
// ============================================================================
 | 
			
		||||
 | 
			
		||||
module RAM32X1D (
 | 
			
		||||
  output DPO, SPO,
 | 
			
		||||
  input  D,
 | 
			
		||||
  input  WCLK,
 | 
			
		||||
  input  WE,
 | 
			
		||||
  input  A0, A1, A2, A3, A4,
 | 
			
		||||
  input  DPRA0, DPRA1, DPRA2, DPRA3, DPRA4
 | 
			
		||||
);
 | 
			
		||||
  parameter INIT = 32'h0;
 | 
			
		||||
  parameter IS_WCLK_INVERTED = 1'b0;
 | 
			
		||||
  wire \$DPO , \$SPO ;
 | 
			
		||||
  RAM32X1D #(
 | 
			
		||||
    .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
 | 
			
		||||
  ) _TECHMAP_REPLACE_ (
 | 
			
		||||
    .DPO(\$DPO ), .SPO(\$SPO ),
 | 
			
		||||
    .D(D), .WCLK(WCLK), .WE(WE),
 | 
			
		||||
    .A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4),
 | 
			
		||||
    .DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4)
 | 
			
		||||
  );
 | 
			
		||||
  \$__ABC_LUT6 dpo (.A(\$DPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(DPO));
 | 
			
		||||
  \$__ABC_LUT6 spo (.A(\$SPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(SPO));
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module RAM64X1D (
 | 
			
		||||
  output DPO, SPO,
 | 
			
		||||
  input  D,
 | 
			
		||||
  input  WCLK,
 | 
			
		||||
  input  WE,
 | 
			
		||||
  input  A0, A1, A2, A3, A4, A5,
 | 
			
		||||
  input  DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5
 | 
			
		||||
);
 | 
			
		||||
  parameter INIT = 64'h0;
 | 
			
		||||
  parameter IS_WCLK_INVERTED = 1'b0;
 | 
			
		||||
  wire \$DPO , \$SPO ;
 | 
			
		||||
  RAM64X1D #(
 | 
			
		||||
    .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
 | 
			
		||||
  ) _TECHMAP_REPLACE_ (
 | 
			
		||||
    .DPO(\$DPO ), .SPO(\$SPO ),
 | 
			
		||||
    .D(D), .WCLK(WCLK), .WE(WE),
 | 
			
		||||
    .A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4), .A5(A5),
 | 
			
		||||
    .DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4), .DPRA5(DPRA5)
 | 
			
		||||
  );
 | 
			
		||||
  \$__ABC_LUT6 dpo (.A(\$DPO ), .S({A0, A1, A2, A3, A4, A5}), .Y(DPO));
 | 
			
		||||
  \$__ABC_LUT6 spo (.A(\$SPO ), .S({A0, A1, A2, A3, A4, A5}), .Y(SPO));
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module RAM128X1D (
 | 
			
		||||
  output       DPO, SPO,
 | 
			
		||||
  input        D,
 | 
			
		||||
  input        WCLK,
 | 
			
		||||
  input        WE,
 | 
			
		||||
  input  [6:0] A, DPRA
 | 
			
		||||
);
 | 
			
		||||
  parameter INIT = 128'h0;
 | 
			
		||||
  parameter IS_WCLK_INVERTED = 1'b0;
 | 
			
		||||
  wire \$DPO , \$SPO ;
 | 
			
		||||
  RAM128X1D #(
 | 
			
		||||
    .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
 | 
			
		||||
  ) _TECHMAP_REPLACE_ (
 | 
			
		||||
    .DPO(\$DPO ), .SPO(\$SPO ),
 | 
			
		||||
    .D(D), .WCLK(WCLK), .WE(WE),
 | 
			
		||||
    .A(A),
 | 
			
		||||
    .DPRA(DPRA)
 | 
			
		||||
  );
 | 
			
		||||
  \$__ABC_LUT7 dpo (.A(\$DPO ), .S(A), .Y(DPO));
 | 
			
		||||
  \$__ABC_LUT7 spo (.A(\$SPO ), .S(A), .Y(SPO));
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module SRL16E (
 | 
			
		||||
  output Q,
 | 
			
		||||
  input A0, A1, A2, A3, CE, CLK, D
 | 
			
		||||
);
 | 
			
		||||
  parameter [15:0] INIT = 16'h0000;
 | 
			
		||||
  parameter [0:0] IS_CLK_INVERTED = 1'b0;
 | 
			
		||||
  wire \$Q ;
 | 
			
		||||
  SRL16E #(
 | 
			
		||||
    .INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED)
 | 
			
		||||
  ) _TECHMAP_REPLACE_ (
 | 
			
		||||
    .Q(\$Q ),
 | 
			
		||||
    .A0(A0), .A1(A1), .A2(A2), .A3(A3), .CE(CE), .CLK(CLK), .D(D)
 | 
			
		||||
  );
 | 
			
		||||
  \$__ABC_LUT6 q (.A(\$Q ), .S({1'b1, A0, A1, A2, A3, 1'b1}), .Y(Q));
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module SRLC32E (
 | 
			
		||||
  output Q,
 | 
			
		||||
  output Q31,
 | 
			
		||||
  input [4:0] A,
 | 
			
		||||
  input CE, CLK, D
 | 
			
		||||
);
 | 
			
		||||
  parameter [31:0] INIT = 32'h00000000;
 | 
			
		||||
  parameter [0:0] IS_CLK_INVERTED = 1'b0;
 | 
			
		||||
  wire \$Q ;
 | 
			
		||||
  SRLC32E #(
 | 
			
		||||
    .INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED)
 | 
			
		||||
  ) _TECHMAP_REPLACE_ (
 | 
			
		||||
    .Q(\$Q ), .Q31(Q31),
 | 
			
		||||
    .A(A), .CE(CE), .CLK(CLK), .D(D)
 | 
			
		||||
  );
 | 
			
		||||
  \$__ABC_LUT6 q (.A(\$Q ), .S({1'b1, A}), .Y(Q));
 | 
			
		||||
endmodule
 | 
			
		||||
							
								
								
									
										34
									
								
								techlibs/xilinx/abc_model.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								techlibs/xilinx/abc_model.v
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,34 @@
 | 
			
		|||
/*
 | 
			
		||||
 *  yosys -- Yosys Open SYnthesis Suite
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 | 
			
		||||
 *                2019  Eddie Hung    <eddie@fpgeh.com>
 | 
			
		||||
 *
 | 
			
		||||
 *  Permission to use, copy, modify, and/or distribute this software for any
 | 
			
		||||
 *  purpose with or without fee is hereby granted, provided that the above
 | 
			
		||||
 *  copyright notice and this permission notice appear in all copies.
 | 
			
		||||
 *
 | 
			
		||||
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
			
		||||
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
			
		||||
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
			
		||||
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
			
		||||
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
			
		||||
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
// ============================================================================
 | 
			
		||||
 | 
			
		||||
(* abc_box_id = 3, lib_whitebox *)
 | 
			
		||||
module \$__XILINX_MUXF78 (output O, input I0, I1, I2, I3, S0, S1);
 | 
			
		||||
  assign O = S1 ? (S0 ? I3 : I2)
 | 
			
		||||
                : (S0 ? I1 : I0);
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
(* abc_box_id=2000 *)
 | 
			
		||||
module \$__ABC_LUT6 (input A, input [5:0] S, output Y);
 | 
			
		||||
endmodule
 | 
			
		||||
(* abc_box_id=2001 *)
 | 
			
		||||
module \$__ABC_LUT7 (input A, input [6:0] S, output Y);
 | 
			
		||||
endmodule
 | 
			
		||||
							
								
								
									
										28
									
								
								techlibs/xilinx/abc_unmap.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								techlibs/xilinx/abc_unmap.v
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,28 @@
 | 
			
		|||
/*
 | 
			
		||||
 *  yosys -- Yosys Open SYnthesis Suite
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 | 
			
		||||
 *                2019  Eddie Hung    <eddie@fpgeh.com>
 | 
			
		||||
 *
 | 
			
		||||
 *  Permission to use, copy, modify, and/or distribute this software for any
 | 
			
		||||
 *  purpose with or without fee is hereby granted, provided that the above
 | 
			
		||||
 *  copyright notice and this permission notice appear in all copies.
 | 
			
		||||
 *
 | 
			
		||||
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
			
		||||
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
			
		||||
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
			
		||||
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
			
		||||
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
			
		||||
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
// ============================================================================
 | 
			
		||||
 | 
			
		||||
module \$__ABC_LUT6 (input A, input [5:0] S, output Y);
 | 
			
		||||
  assign Y = A;
 | 
			
		||||
endmodule
 | 
			
		||||
module \$__ABC_LUT7 (input A, input [6:0] S, output Y);
 | 
			
		||||
  assign Y = A;
 | 
			
		||||
endmodule
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +1,5 @@
 | 
			
		|||
# Max delays from https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf
 | 
			
		||||
#                 https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf
 | 
			
		||||
 | 
			
		||||
# NB: Inputs/Outputs must be ordered alphabetically
 | 
			
		||||
#     (with exceptions for carry in/out)
 | 
			
		||||
| 
						 | 
				
			
			@ -14,6 +15,10 @@ F7MUX 1 1 3 1
 | 
			
		|||
MUXF8 2 1 3 1
 | 
			
		||||
104 94 273
 | 
			
		||||
 | 
			
		||||
# Box containing MUXF7.[AB] + MUXF8,
 | 
			
		||||
#   Necessary to make these an atomic unit so that
 | 
			
		||||
#   ABC cannot optimise just one of the MUXF7 away
 | 
			
		||||
#   and expect to save on its delay
 | 
			
		||||
# Inputs: I0 I1 I2 I3 S0 S1
 | 
			
		||||
# Outputs: O
 | 
			
		||||
$__MUXF78 3 1 6 1
 | 
			
		||||
| 
						 | 
				
			
			@ -37,22 +42,20 @@ CARRY4 4 1 10 8
 | 
			
		|||
580 526 507 398 385 508 528 378 380 114
 | 
			
		||||
 | 
			
		||||
# SLICEM/A6LUT
 | 
			
		||||
# Inputs: A0 A1 A2 A3 A4 D DPRA0 DPRA1 DPRA2 DPRA3 DPRA4 WCLK WE
 | 
			
		||||
# Outputs: DPO SPO
 | 
			
		||||
RAM32X1D 5 0 13 2
 | 
			
		||||
-   -   -   -   -   - 631 472 407 238 127 - -
 | 
			
		||||
631 472 407 238 127 - -   -   -   -   -   - -
 | 
			
		||||
# Box to emulate comb/seq behaviour of RAMD{32,64} and SRL{16,32}
 | 
			
		||||
#   Necessary since RAMD* and SRL* have both combinatorial (i.e.
 | 
			
		||||
#   same-cycle read operation) and sequential (write operation
 | 
			
		||||
#   is only committed on the next clock edge).
 | 
			
		||||
#   To model the combinatorial path, such cells have to be split
 | 
			
		||||
#   into comb and seq parts, with this box modelling only the former.
 | 
			
		||||
# Inputs: A S0 S1 S2 S3 S4 S5
 | 
			
		||||
# Outputs: Y
 | 
			
		||||
$__ABC_LUT6 2000 0 7 1
 | 
			
		||||
0 642 631 472 407 238 127
 | 
			
		||||
 | 
			
		||||
# SLICEM/A6LUT
 | 
			
		||||
# Inputs: A0 A1 A2 A3 A4 A5 D DPRA0 DPRA1 DPRA2 DPRA3 DPRA4 DPRA5 WCLK WE
 | 
			
		||||
# SLICEM/A6LUT + F7BMUX
 | 
			
		||||
# Box to emulate comb/seq behaviour of RAMD128
 | 
			
		||||
# Inputs: A S0 S1 S2 S3 S4 S5 S6
 | 
			
		||||
# Outputs: DPO SPO
 | 
			
		||||
RAM64X1D 6 0 15 2
 | 
			
		||||
-   -   -   -   -   -   - 642 631 472 407 238 127 - -
 | 
			
		||||
642 631 472 407 238 127 - -   -   -   -   -   -   - -
 | 
			
		||||
 | 
			
		||||
# SLICEM/A6LUT + F7[AB]MUX
 | 
			
		||||
# Inputs: A0 A1 A2 A3 A4 A5 A6 D DPRA0 DPRA1 DPRA2 DPRA3 DPRA4 DPRA5 DPRA6 WCLK WE
 | 
			
		||||
# Outputs: DPO SPO
 | 
			
		||||
RAM128X1D 7 0 17 2
 | 
			
		||||
-    -    -   -   -   -   -   - 1009 998 839 774 605 494 450 - -
 | 
			
		||||
1047 1036 877 812 643 532 478 - -    -   -   -   -   -   -   - -
 | 
			
		||||
$__ABC_LUT7 2001 0 8 1
 | 
			
		||||
0 1047 1036 877 812 643 532 478
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -331,7 +331,6 @@ module \$_MUX16_ (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V, Y)
 | 
			
		|||
endmodule
 | 
			
		||||
`endif
 | 
			
		||||
 | 
			
		||||
`ifndef _ABC
 | 
			
		||||
module \$__XILINX_MUXF78 (O, I0, I1, I2, I3, S0, S1);
 | 
			
		||||
  output O;
 | 
			
		||||
  input I0, I1, I2, I3, S0, S1;
 | 
			
		||||
| 
						 | 
				
			
			@ -364,4 +363,3 @@ module \$__XILINX_MUXF78 (O, I0, I1, I2, I3, S0, S1);
 | 
			
		|||
  else
 | 
			
		||||
    MUXF8 mux8 (.I0(T0), .I1(T1), .S(S1), .O(O));
 | 
			
		||||
endmodule
 | 
			
		||||
`endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -184,14 +184,6 @@ module MUXF8(output O, input I0, I1, S);
 | 
			
		|||
  assign O = S ? I1 : I0;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
`ifdef _ABC
 | 
			
		||||
(* abc_box_id = 3, lib_whitebox *)
 | 
			
		||||
module \$__XILINX_MUXF78 (output O, input I0, I1, I2, I3, S0, S1);
 | 
			
		||||
  assign O = S1 ? (S0 ? I3 : I2)
 | 
			
		||||
                : (S0 ? I1 : I0);
 | 
			
		||||
endmodule
 | 
			
		||||
`endif
 | 
			
		||||
 | 
			
		||||
module XORCY(output O, input CI, LI);
 | 
			
		||||
  assign O = CI ^ LI;
 | 
			
		||||
endmodule
 | 
			
		||||
| 
						 | 
				
			
			@ -236,7 +228,15 @@ endmodule
 | 
			
		|||
 | 
			
		||||
`endif
 | 
			
		||||
 | 
			
		||||
module FDRE (output reg Q, (* clkbuf_sink *) input C, input CE, D, R);
 | 
			
		||||
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L238-L250
 | 
			
		||||
 | 
			
		||||
module FDRE (
 | 
			
		||||
  (* abc_arrival=303 *)
 | 
			
		||||
  output reg Q,
 | 
			
		||||
  (* clkbuf_sink *)
 | 
			
		||||
  input C, 
 | 
			
		||||
  input CE, D, R
 | 
			
		||||
);
 | 
			
		||||
  parameter [0:0] INIT = 1'b0;
 | 
			
		||||
  parameter [0:0] IS_C_INVERTED = 1'b0;
 | 
			
		||||
  parameter [0:0] IS_D_INVERTED = 1'b0;
 | 
			
		||||
| 
						 | 
				
			
			@ -248,7 +248,13 @@ module FDRE (output reg Q, (* clkbuf_sink *) input C, input CE, D, R);
 | 
			
		|||
  endcase endgenerate
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module FDSE (output reg Q, (* clkbuf_sink *) input C, input CE, D, S);
 | 
			
		||||
module FDSE (
 | 
			
		||||
  (* abc_arrival=303 *)
 | 
			
		||||
  output reg Q,
 | 
			
		||||
  (* clkbuf_sink *)
 | 
			
		||||
  input C,
 | 
			
		||||
  input CE, D, S
 | 
			
		||||
);
 | 
			
		||||
  parameter [0:0] INIT = 1'b1;
 | 
			
		||||
  parameter [0:0] IS_C_INVERTED = 1'b0;
 | 
			
		||||
  parameter [0:0] IS_D_INVERTED = 1'b0;
 | 
			
		||||
| 
						 | 
				
			
			@ -260,7 +266,13 @@ module FDSE (output reg Q, (* clkbuf_sink *) input C, input CE, D, S);
 | 
			
		|||
  endcase endgenerate
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module FDCE (output reg Q, (* clkbuf_sink *) input C, input CE, D, CLR);
 | 
			
		||||
module FDCE (
 | 
			
		||||
  (* abc_arrival=303 *)
 | 
			
		||||
  output reg Q,
 | 
			
		||||
  (* clkbuf_sink *)
 | 
			
		||||
  input C,
 | 
			
		||||
  input CE, D, CLR
 | 
			
		||||
);
 | 
			
		||||
  parameter [0:0] INIT = 1'b0;
 | 
			
		||||
  parameter [0:0] IS_C_INVERTED = 1'b0;
 | 
			
		||||
  parameter [0:0] IS_D_INVERTED = 1'b0;
 | 
			
		||||
| 
						 | 
				
			
			@ -274,7 +286,13 @@ module FDCE (output reg Q, (* clkbuf_sink *) input C, input CE, D, CLR);
 | 
			
		|||
  endcase endgenerate
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module FDPE (output reg Q, (* clkbuf_sink *) input C, input CE, D, PRE);
 | 
			
		||||
module FDPE (
 | 
			
		||||
  (* abc_arrival=303 *)
 | 
			
		||||
  output reg Q,
 | 
			
		||||
  (* clkbuf_sink *)
 | 
			
		||||
  input C,
 | 
			
		||||
  input CE, D, PRE
 | 
			
		||||
);
 | 
			
		||||
  parameter [0:0] INIT = 1'b1;
 | 
			
		||||
  parameter [0:0] IS_C_INVERTED = 1'b0;
 | 
			
		||||
  parameter [0:0] IS_D_INVERTED = 1'b0;
 | 
			
		||||
| 
						 | 
				
			
			@ -288,38 +306,61 @@ module FDPE (output reg Q, (* clkbuf_sink *) input C, input CE, D, PRE);
 | 
			
		|||
  endcase endgenerate
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module FDRE_1 (output reg Q, (* clkbuf_sink *) input C, input CE, D, R);
 | 
			
		||||
module FDRE_1 (
 | 
			
		||||
  (* abc_arrival=303 *)
 | 
			
		||||
  output reg Q,
 | 
			
		||||
  (* clkbuf_sink *)
 | 
			
		||||
  input C,
 | 
			
		||||
  input CE, D, R
 | 
			
		||||
);
 | 
			
		||||
  parameter [0:0] INIT = 1'b0;
 | 
			
		||||
  initial Q <= INIT;
 | 
			
		||||
  always @(negedge C) if (R) Q <= 1'b0; else if(CE) Q <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module FDSE_1 (output reg Q, (* clkbuf_sink *) input C, input CE, D, S);
 | 
			
		||||
module FDSE_1 (
 | 
			
		||||
  (* abc_arrival=303 *)
 | 
			
		||||
  output reg Q,
 | 
			
		||||
  (* clkbuf_sink *)
 | 
			
		||||
  input C,
 | 
			
		||||
  input CE, D, S
 | 
			
		||||
);
 | 
			
		||||
  parameter [0:0] INIT = 1'b1;
 | 
			
		||||
  initial Q <= INIT;
 | 
			
		||||
  always @(negedge C) if (S) Q <= 1'b1; else if(CE) Q <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module FDCE_1 (output reg Q, (* clkbuf_sink *) input C, input CE, D, CLR);
 | 
			
		||||
module FDCE_1 (
 | 
			
		||||
  (* abc_arrival=303 *)
 | 
			
		||||
  output reg Q,
 | 
			
		||||
  (* clkbuf_sink *)
 | 
			
		||||
  input C,
 | 
			
		||||
  input CE, D, CLR
 | 
			
		||||
);
 | 
			
		||||
  parameter [0:0] INIT = 1'b0;
 | 
			
		||||
  initial Q <= INIT;
 | 
			
		||||
  always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module FDPE_1 (output reg Q, (* clkbuf_sink *) input C, input CE, D, PRE);
 | 
			
		||||
module FDPE_1 (
 | 
			
		||||
  (* abc_arrival=303 *)
 | 
			
		||||
  output reg Q,
 | 
			
		||||
  (* clkbuf_sink *)
 | 
			
		||||
  input C,
 | 
			
		||||
  input CE, D, PRE
 | 
			
		||||
);
 | 
			
		||||
  parameter [0:0] INIT = 1'b1;
 | 
			
		||||
  initial Q <= INIT;
 | 
			
		||||
  always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
(* abc_box_id = 5 *)
 | 
			
		||||
module RAM32X1D (
 | 
			
		||||
  // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
 | 
			
		||||
  (* abc_arrival=1153 *)
 | 
			
		||||
  output DPO, SPO,
 | 
			
		||||
  (* abc_scc_break *)
 | 
			
		||||
  input  D,
 | 
			
		||||
  (* clkbuf_sink *)
 | 
			
		||||
  input  WCLK,
 | 
			
		||||
  (* abc_scc_break *)
 | 
			
		||||
  input  WE,
 | 
			
		||||
  input  A0, A1, A2, A3, A4,
 | 
			
		||||
  input  DPRA0, DPRA1, DPRA2, DPRA3, DPRA4
 | 
			
		||||
| 
						 | 
				
			
			@ -335,14 +376,13 @@ module RAM32X1D (
 | 
			
		|||
  always @(posedge clk) if (WE) mem[a] <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
(* abc_box_id = 6 *)
 | 
			
		||||
module RAM64X1D (
 | 
			
		||||
  // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
 | 
			
		||||
  (* abc_arrival=1153 *)
 | 
			
		||||
  output DPO, SPO,
 | 
			
		||||
  (* abc_scc_break *)
 | 
			
		||||
  input  D,
 | 
			
		||||
  (* clkbuf_sink *)
 | 
			
		||||
  input  WCLK,
 | 
			
		||||
  (* abc_scc_break *)
 | 
			
		||||
  input  WE,
 | 
			
		||||
  input  A0, A1, A2, A3, A4, A5,
 | 
			
		||||
  input  DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5
 | 
			
		||||
| 
						 | 
				
			
			@ -358,14 +398,13 @@ module RAM64X1D (
 | 
			
		|||
  always @(posedge clk) if (WE) mem[a] <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
(* abc_box_id = 7 *)
 | 
			
		||||
module RAM128X1D (
 | 
			
		||||
  output       DPO, SPO,
 | 
			
		||||
  (* abc_scc_break *)
 | 
			
		||||
  // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
 | 
			
		||||
  (* abc_arrival=1153 *)
 | 
			
		||||
  output DPO, SPO,
 | 
			
		||||
  input        D,
 | 
			
		||||
  (* clkbuf_sink *)
 | 
			
		||||
  input        WCLK,
 | 
			
		||||
  (* abc_scc_break *)
 | 
			
		||||
  input        WE,
 | 
			
		||||
  input  [6:0] A, DPRA
 | 
			
		||||
);
 | 
			
		||||
| 
						 | 
				
			
			@ -379,6 +418,8 @@ module RAM128X1D (
 | 
			
		|||
endmodule
 | 
			
		||||
 | 
			
		||||
module SRL16E (
 | 
			
		||||
  // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905
 | 
			
		||||
  (* abc_arrival=1472 *)
 | 
			
		||||
  output Q,
 | 
			
		||||
  input A0, A1, A2, A3, CE,
 | 
			
		||||
  (* clkbuf_sink *)
 | 
			
		||||
| 
						 | 
				
			
			@ -423,7 +464,10 @@ module SRLC16E (
 | 
			
		|||
endmodule
 | 
			
		||||
 | 
			
		||||
module SRLC32E (
 | 
			
		||||
  // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905
 | 
			
		||||
  (* abc_arrival=1472 *)
 | 
			
		||||
  output Q,
 | 
			
		||||
  (* abc_arrival=1114 *)
 | 
			
		||||
  output Q31,
 | 
			
		||||
  input [4:0] A,
 | 
			
		||||
  input CE,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -275,9 +275,9 @@ struct SynthXilinxPass : public ScriptPass
 | 
			
		|||
	{
 | 
			
		||||
		if (check_label("begin")) {
 | 
			
		||||
			if (vpr)
 | 
			
		||||
				run("read_verilog -lib -icells -D _ABC -D_EXPLICIT_CARRY +/xilinx/cells_sim.v");
 | 
			
		||||
				run("read_verilog -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v");
 | 
			
		||||
			else
 | 
			
		||||
				run("read_verilog -lib -icells -D _ABC +/xilinx/cells_sim.v");
 | 
			
		||||
				run("read_verilog -lib +/xilinx/cells_sim.v");
 | 
			
		||||
 | 
			
		||||
			run("read_verilog -lib +/xilinx/cells_xtra.v");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -429,7 +429,7 @@ struct SynthXilinxPass : public ScriptPass
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		if (check_label("map_cells")) {
 | 
			
		||||
			std::string techmap_args = "-map +/techmap.v -D _ABC -map +/xilinx/cells_map.v";
 | 
			
		||||
			std::string techmap_args = "-map +/techmap.v -map +/xilinx/cells_map.v";
 | 
			
		||||
			if (widemux > 0)
 | 
			
		||||
				techmap_args += stringf(" -D MIN_MUX_INPUTS=%d", widemux);
 | 
			
		||||
			run("techmap " + techmap_args);
 | 
			
		||||
| 
						 | 
				
			
			@ -449,10 +449,12 @@ struct SynthXilinxPass : public ScriptPass
 | 
			
		|||
			if (flatten_before_abc)
 | 
			
		||||
				run("flatten");
 | 
			
		||||
			if (help_mode)
 | 
			
		||||
				run("abc -luts 2:2,3,6:5[,10,20] [-dff]", "(option for 'nowidelut', option for '-retime')");
 | 
			
		||||
				run("abc -luts 2:2,3,6:5[,10,20] [-dff]", "(option for 'nowidelut'; option for '-retime')");
 | 
			
		||||
			else if (abc9) {
 | 
			
		||||
				if (family != "xc7")
 | 
			
		||||
					log_warning("'synth_xilinx -abc9' currently supports '-family xc7' only.\n");
 | 
			
		||||
				run("techmap -map +/xilinx/abc_map.v -max_iter 1");
 | 
			
		||||
				run("read_verilog -icells -lib +/xilinx/abc_model.v");
 | 
			
		||||
				if (nowidelut)
 | 
			
		||||
					run("abc9 -lut +/xilinx/abc_xc7_nowide.lut -box +/xilinx/abc_xc7.box -W " + std::to_string(XC7_WIRE_DELAY));
 | 
			
		||||
				else
 | 
			
		||||
| 
						 | 
				
			
			@ -470,14 +472,15 @@ struct SynthXilinxPass : public ScriptPass
 | 
			
		|||
			//   has performed any necessary retiming
 | 
			
		||||
			if (!nosrl || help_mode)
 | 
			
		||||
				run("xilinx_srl -fixed -minlen 3", "(skip if '-nosrl')");
 | 
			
		||||
 | 
			
		||||
			std::string techmap_args = "-map +/xilinx/lut_map.v -map +/xilinx/cells_map.v";
 | 
			
		||||
			if (help_mode)
 | 
			
		||||
					techmap_args += " [-map +/xilinx/ff_map.v]";
 | 
			
		||||
			else if (!abc9)
 | 
			
		||||
					techmap_args += " -map +/xilinx/ff_map.v";
 | 
			
		||||
				techmap_args += " [-map +/xilinx/ff_map.v]";
 | 
			
		||||
			else if (abc9)
 | 
			
		||||
				techmap_args += " -map +/xilinx/abc_unmap.v";
 | 
			
		||||
			else
 | 
			
		||||
				techmap_args += " -map +/xilinx/ff_map.v";
 | 
			
		||||
			run("techmap " + techmap_args);
 | 
			
		||||
			if (!abc9)
 | 
			
		||||
			if (!abc9 || help_mode)
 | 
			
		||||
				run("dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT -ff FDSE Q INIT "
 | 
			
		||||
						"-ff FDRE_1 Q INIT -ff FDCE_1 Q INIT -ff FDPE_1 Q INIT -ff FDSE_1 Q INIT", "(without '-abc9' only)");
 | 
			
		||||
			run("clean");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,5 @@
 | 
			
		|||
// Max delays from https://github.com/SymbiFlow/prjxray-db/blob/f8e0364116b2983ac72a3dc8c509ea1cc79e2e3d/artix7/timings/BRAM_L.sdf#L138-L147
 | 
			
		||||
 | 
			
		||||
module RAMB18E1 (
 | 
			
		||||
	(* clkbuf_sink *)
 | 
			
		||||
	input CLKARDCLK,
 | 
			
		||||
| 
						 | 
				
			
			@ -21,9 +23,13 @@ module RAMB18E1 (
 | 
			
		|||
	input [1:0] WEA,
 | 
			
		||||
	input [3:0] WEBWE,
 | 
			
		||||
 | 
			
		||||
	(* abc_arrival=2454 *)
 | 
			
		||||
	output [15:0] DOADO,
 | 
			
		||||
	(* abc_arrival=2454 *)
 | 
			
		||||
	output [15:0] DOBDO,
 | 
			
		||||
	(* abc_arrival=2454 *)
 | 
			
		||||
	output [1:0] DOPADOP,
 | 
			
		||||
	(* abc_arrival=2454 *)
 | 
			
		||||
	output [1:0] DOPBDOP
 | 
			
		||||
);
 | 
			
		||||
	parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
| 
						 | 
				
			
			@ -147,9 +153,13 @@ module RAMB36E1 (
 | 
			
		|||
	input [3:0] WEA,
 | 
			
		||||
	input [7:0] WEBWE,
 | 
			
		||||
 | 
			
		||||
	(* abc_arrival=2454 *)
 | 
			
		||||
	output [31:0] DOADO,
 | 
			
		||||
	(* abc_arrival=2454 *)
 | 
			
		||||
	output [31:0] DOBDO,
 | 
			
		||||
	(* abc_arrival=2454 *)
 | 
			
		||||
	output [3:0] DOPADOP,
 | 
			
		||||
	(* abc_arrival=2454 *)
 | 
			
		||||
	output [3:0] DOPBDOP
 | 
			
		||||
);
 | 
			
		||||
	parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,5 +5,7 @@ always @*
 | 
			
		|||
endmodule
 | 
			
		||||
 | 
			
		||||
module abc9_test028(input i, output o);
 | 
			
		||||
unknown u(~i, o);
 | 
			
		||||
wire w;
 | 
			
		||||
unknown u(~i, w);
 | 
			
		||||
unknown2 u2(w, o);
 | 
			
		||||
endmodule
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue