1- /*
2- * yosys -- Yosys Open SYnthesis Suite
3- *
4- * Copyright (C) 2024 Martin Povišer <povik@cutebit.org>
5- *
6- * Permission to use, copy, modify, and/or distribute this software for any
7- * purpose with or without fee is hereby granted, provided that the above
8- * copyright notice and this permission notice appear in all copies.
9- *
10- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17- *
18- */
191#include " kernel/yosys.h"
202#include " kernel/celltypes.h"
213#include " kernel/ff.h"
@@ -32,12 +14,12 @@ struct LibertyStubber {
3214 void liberty_prefix (std::ostream& f)
3315 {
3416 f << " /*\n " ;
35- f << stringf (" Models interfaces of select Yosys internal cell.\n " );
36- f << stringf (" Likely contains INCORRECT POLARITIES.\n " );
37- f << stringf (" Impractical for any simulation, synthesis, or timing.\n " );
38- f << stringf (" Intended purely for SDC expansion.\n " );
39- f << stringf (" Do not microwave or tumble dry.\n " );
40- f << stringf (" Generated by %s\n " , yosys_maybe_version ());
17+ f << stringf (" \t Models interfaces of select Yosys internal cell.\n " );
18+ f << stringf (" \t Likely contains INCORRECT POLARITIES.\n " );
19+ f << stringf (" \t Impractical for any simulation, synthesis, or timing.\n " );
20+ f << stringf (" \t Intended purely for SDC expansion.\n " );
21+ f << stringf (" \t Do not microwave or tumble dry.\n " );
22+ f << stringf (" \t Generated by %s\n " , yosys_maybe_version ());
4123 f << " */\n " ;
4224 f << " library (yosys) {\n " ;
4325 f << " \t input_threshold_pct_fall : 50;\n " ;
@@ -82,7 +64,13 @@ struct LibertyStubber {
8264 f << " \t cell (\" " << derived_name << " \" ) {\n " ;
8365 auto & base_type = ct.cell_types [base_name];
8466 i.indent = 3 ;
85- for (auto x : derived->ports ) {
67+ auto sorted_ports = derived->ports ;
68+ // Hack for CLK and C coming before Q does
69+ auto cmp = [](IdString l, IdString r) { return l.str () < r.str (); };
70+ std::sort (sorted_ports.begin (), sorted_ports.end (), cmp);
71+ std::string clock_pin_name = " " ;
72+ for (auto x : sorted_ports) {
73+ std::string port_name = RTLIL::unescape_id (x);
8674 bool is_input = base_type.inputs .count (x);
8775 bool is_output = base_type.outputs .count (x);
8876 f << " \t\t pin (" << RTLIL::unescape_id (x.str ()) << " ) {\n " ;
@@ -93,10 +81,19 @@ struct LibertyStubber {
9381 } else {
9482 i.item (" direction" , " inout" );
9583 }
96- if (RTLIL::unescape_id (x) == " CLK" || RTLIL::unescape_id (x) == " C" )
84+ if (port_name == " CLK" || port_name == " C" ) {
9785 i.item (" clock" , " true" );
98- if (RTLIL::unescape_id (x) == " Q" )
86+ clock_pin_name = port_name;
87+ }
88+ if (port_name == " Q" ) {
9989 i.item (" function" , " IQ" );
90+ f << " \t\t\t timing () {\n " ;
91+ i.indent ++;
92+ log_assert (clock_pin_name.size ());
93+ i.item (" related_pin" , clock_pin_name);
94+ i.indent --;
95+ f << " \t\t\t }\n " ;
96+ }
10097 f << " \t\t }\n " ;
10198 }
10299
0 commit comments