diff --git a/passes/cmds/icell_liberty.cc b/passes/cmds/icell_liberty.cc index 9b89c1125..83252ffb4 100644 --- a/passes/cmds/icell_liberty.cc +++ b/passes/cmds/icell_liberty.cc @@ -1,21 +1,3 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2024 Martin PoviĊĦer - * - * 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. - * - */ #include "kernel/yosys.h" #include "kernel/celltypes.h" #include "kernel/ff.h" @@ -32,12 +14,12 @@ struct LibertyStubber { void liberty_prefix(std::ostream& f) { f << "/*\n"; - f << stringf("Models interfaces of select Yosys internal cell.\n"); - f << stringf("Likely contains INCORRECT POLARITIES.\n"); - f << stringf("Impractical for any simulation, synthesis, or timing.\n"); - f << stringf("Intended purely for SDC expansion.\n"); - f << stringf("Do not microwave or tumble dry.\n"); - f << stringf("Generated by %s\n", yosys_maybe_version()); + f << stringf("\tModels interfaces of select Yosys internal cell.\n"); + f << stringf("\tLikely contains INCORRECT POLARITIES.\n"); + f << stringf("\tImpractical for any simulation, synthesis, or timing.\n"); + f << stringf("\tIntended purely for SDC expansion.\n"); + f << stringf("\tDo not microwave or tumble dry.\n"); + f << stringf("\tGenerated by %s\n", yosys_maybe_version()); f << "*/\n"; f << "library (yosys) {\n"; f << "\tinput_threshold_pct_fall : 50;\n"; @@ -82,7 +64,13 @@ struct LibertyStubber { f << "\tcell (\"" << derived_name << "\") {\n"; auto& base_type = ct.cell_types[base_name]; i.indent = 3; - for (auto x : derived->ports) { + auto sorted_ports = derived->ports; + // Hack for CLK and C coming before Q does + auto cmp = [](IdString l, IdString r) { return l.str() < r.str(); }; + std::sort(sorted_ports.begin(), sorted_ports.end(), cmp); + std::string clock_pin_name = ""; + for (auto x : sorted_ports) { + std::string port_name = RTLIL::unescape_id(x); bool is_input = base_type.inputs.count(x); bool is_output = base_type.outputs.count(x); f << "\t\tpin (" << RTLIL::unescape_id(x.str()) << ") {\n"; @@ -93,10 +81,19 @@ struct LibertyStubber { } else { i.item("direction", "inout"); } - if (RTLIL::unescape_id(x) == "CLK" || RTLIL::unescape_id(x) == "C") + if (port_name == "CLK" || port_name == "C") { i.item("clock", "true"); - if (RTLIL::unescape_id(x) == "Q") + clock_pin_name = port_name; + } + if (port_name == "Q") { i.item("function", "IQ"); + f << "\t\t\ttiming () {\n"; + i.indent++; + log_assert(clock_pin_name.size()); + i.item("related_pin", clock_pin_name); + i.indent--; + f << "\t\t\t}\n"; + } f << "\t\t}\n"; }