Skip to content

Commit fd344e4

Browse files
committed
icell_liberty: flops
1 parent 95ed267 commit fd344e4

File tree

1 file changed

+84
-2
lines changed

1 file changed

+84
-2
lines changed

passes/cmds/icell_liberty.cc

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,27 @@
1818
*/
1919
#include "kernel/yosys.h"
2020
#include "kernel/celltypes.h"
21+
#include "kernel/ff.h"
2122

2223
USING_YOSYS_NAMESPACE
2324
PRIVATE_NAMESPACE_BEGIN
2425

2526
struct LibertyStubber {
2627
CellTypes ct;
27-
CellTypes ct_ff;
2828
LibertyStubber() {
2929
ct.setup();
3030
ct.setup_internals_ff();
3131
}
3232
void liberty_prefix(std::ostream& f)
3333
{
34+
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());
41+
f << "*/\n";
3442
f << "library (yosys) {\n";
3543
f << "\tinput_threshold_pct_fall : 50;\n";
3644
f << "\tinput_threshold_pct_rise : 50;\n";
@@ -45,6 +53,76 @@ struct LibertyStubber {
4553
{
4654
f << "}\n";
4755
}
56+
struct LibertyItemizer {
57+
std::ostream& f;
58+
int indent;
59+
LibertyItemizer(std::ostream& f) : f(f), indent(0) {};
60+
void item(std::string key, std::string val)
61+
{
62+
f << std::string(indent, '\t') << key << " : \"" << val << "\";\n";
63+
}
64+
};
65+
void liberty_flop(Module* base, Module* derived, std::ostream& f)
66+
{
67+
auto base_name = base->name.str().substr(1);
68+
auto derived_name = derived->name.str().substr(1);
69+
70+
FfTypeData ffType(base_name);
71+
LibertyItemizer i(f);
72+
73+
if (ffType.has_gclk) {
74+
log_warning("Formal flip flop %s can't be modeled\n", base_name.c_str());
75+
return;
76+
}
77+
if (ffType.has_ce) {
78+
log_warning("DFFE %s can't be modeled\n", base_name.c_str());
79+
return;
80+
}
81+
82+
f << "\tcell (\"" << derived_name << "\") {\n";
83+
auto& base_type = ct.cell_types[base_name];
84+
i.indent = 3;
85+
for (auto x : derived->ports) {
86+
bool is_input = base_type.inputs.count(x);
87+
bool is_output = base_type.outputs.count(x);
88+
f << "\t\tpin (" << RTLIL::unescape_id(x.str()) << ") {\n";
89+
if (is_input && !is_output) {
90+
i.item("direction", "input");
91+
} else if (!is_input && is_output) {
92+
i.item("direction", "output");
93+
} else {
94+
i.item("direction", "inout");
95+
}
96+
if (RTLIL::unescape_id(x) == "CLK" || RTLIL::unescape_id(x) == "C")
97+
i.item("clock", "true");
98+
if (RTLIL::unescape_id(x) == "Q")
99+
i.item("function", "IQ");
100+
f << "\t\t}\n";
101+
}
102+
103+
f << "\t\tff (\"IQ\",\"IQ_N\") {\n";
104+
i.indent = 3;
105+
// TODO polarities?
106+
if (ffType.has_clk) {
107+
auto pin = ffType.is_fine ? "C" : "CLK";
108+
i.item("clocked_on", pin);
109+
}
110+
if (ffType.has_arst) {
111+
auto meaning = (ffType.val_arst == State::S1) ? "preset" : "clear";
112+
auto pin = ffType.is_fine ? "R" : "ARST";
113+
i.item(meaning, pin);
114+
}
115+
auto next_state = ffType.has_ce ? "D & EN" : "D";
116+
i.item("next_state", next_state);
117+
f << "\t\t}\n";
118+
119+
120+
// bool has_aload;
121+
// bool has_srst;
122+
// bool has_arst;
123+
// bool has_sr;
124+
f << "\t}\n";
125+
}
48126
void liberty_cell(Module* base, Module* derived, std::ostream& f)
49127
{
50128
auto base_name = base->name.str().substr(1);
@@ -53,6 +131,10 @@ struct LibertyStubber {
53131
log_debug("skip skeleton for %s\n", base_name.c_str());
54132
return;
55133
}
134+
135+
if (RTLIL::builtin_ff_cell_types().count(base_name))
136+
return liberty_flop(base, derived, f);
137+
56138
auto& base_type = ct.cell_types[base_name];
57139
f << "\tcell (\"" << derived_name << "\") {\n";
58140
for (auto x : derived->ports) {
@@ -73,7 +155,7 @@ struct LibertyStubber {
73155
};
74156

75157
struct IcellLiberty : Pass {
76-
IcellLiberty() : Pass("icell_liberty", "derive box modules") {}
158+
IcellLiberty() : Pass("icell_liberty", "write Liberty interfaces for used internal cells") {}
77159
void help() override
78160
{
79161
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|

0 commit comments

Comments
 (0)