mirror of
https://github.com/YosysHQ/yosys.git
synced 2026-08-22 06:07:26 +02:00
Add celltype unit tests.
This commit is contained in:
+10
-24
@@ -146,7 +146,7 @@ struct CellTypes
|
|||||||
bool builtin_is_known(size_t idx) const
|
bool builtin_is_known(size_t idx) const
|
||||||
{
|
{
|
||||||
return enabled_cats && idx < (size_t)StaticCellTypes::GEN_MAX_CELLS &&
|
return enabled_cats && idx < (size_t)StaticCellTypes::GEN_MAX_CELLS &&
|
||||||
StaticCellTypes::GeneratedData::is_known[idx];
|
StaticCellTypes::GeneratedData::is_known[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cell_known(const RTLIL::IdString &type) const
|
bool cell_known(const RTLIL::IdString &type) const
|
||||||
@@ -157,7 +157,6 @@ struct CellTypes
|
|||||||
} else if (builtin_match(type.index_)) {
|
} else if (builtin_match(type.index_)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cell_types.count(type) != 0;
|
return cell_types.count(type) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,10 +170,8 @@ struct CellTypes
|
|||||||
for (uint16_t i = 0; i < count; i++)
|
for (uint16_t i = 0; i < count; i++)
|
||||||
if (StaticCellTypes::GeneratedData::port_outputs_ports[idx][i] == target)
|
if (StaticCellTypes::GeneratedData::port_outputs_ports[idx][i] == target)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it = cell_types.find(type);
|
auto it = cell_types.find(type);
|
||||||
return it != cell_types.end() && it->second.outputs.count(port) != 0;
|
return it != cell_types.end() && it->second.outputs.count(port) != 0;
|
||||||
}
|
}
|
||||||
@@ -189,10 +186,8 @@ struct CellTypes
|
|||||||
for (uint16_t i = 0; i < count; i++)
|
for (uint16_t i = 0; i < count; i++)
|
||||||
if (StaticCellTypes::GeneratedData::port_inputs_ports[idx][i] == target)
|
if (StaticCellTypes::GeneratedData::port_inputs_ports[idx][i] == target)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it = cell_types.find(type);
|
auto it = cell_types.find(type);
|
||||||
return it != cell_types.end() && it->second.inputs.count(port) != 0;
|
return it != cell_types.end() && it->second.inputs.count(port) != 0;
|
||||||
}
|
}
|
||||||
@@ -206,24 +201,17 @@ struct CellTypes
|
|||||||
uint32_t target = (uint32_t)port.index_;
|
uint32_t target = (uint32_t)port.index_;
|
||||||
uint16_t ic = StaticCellTypes::GeneratedData::port_inputs_counts[idx];
|
uint16_t ic = StaticCellTypes::GeneratedData::port_inputs_counts[idx];
|
||||||
for (uint16_t i = 0; i < ic; i++)
|
for (uint16_t i = 0; i < ic; i++)
|
||||||
if (StaticCellTypes::GeneratedData::port_inputs_ports[idx][i] == target) {
|
if (StaticCellTypes::GeneratedData::port_inputs_ports[idx][i] == target)
|
||||||
is_in = true;
|
{ is_in = true; break; }
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t oc = StaticCellTypes::GeneratedData::port_outputs_counts[idx];
|
uint16_t oc = StaticCellTypes::GeneratedData::port_outputs_counts[idx];
|
||||||
for (uint16_t i = 0; i < oc; i++)
|
for (uint16_t i = 0; i < oc; i++)
|
||||||
if (StaticCellTypes::GeneratedData::port_outputs_ports[idx][i] == target) {
|
if (StaticCellTypes::GeneratedData::port_outputs_ports[idx][i] == target)
|
||||||
is_out = true;
|
{ is_out = true; break; }
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RTLIL::PortDir(is_in + is_out * 2);
|
return RTLIL::PortDir(is_in + is_out * 2);
|
||||||
}
|
}
|
||||||
auto it = cell_types.find(type);
|
auto it = cell_types.find(type);
|
||||||
if (it == cell_types.end())
|
if (it == cell_types.end())
|
||||||
return RTLIL::PD_UNKNOWN;
|
return RTLIL::PD_UNKNOWN;
|
||||||
|
|
||||||
bool is_in = it->second.inputs.count(port);
|
bool is_in = it->second.inputs.count(port);
|
||||||
bool is_out = it->second.outputs.count(port);
|
bool is_out = it->second.outputs.count(port);
|
||||||
return RTLIL::PortDir(is_in + is_out * 2);
|
return RTLIL::PortDir(is_in + is_out * 2);
|
||||||
@@ -234,8 +222,8 @@ struct CellTypes
|
|||||||
size_t idx = type.index_;
|
size_t idx = type.index_;
|
||||||
bool is_builtin = (enabled_cats == BITS_ALL) ? builtin_is_known(idx) : builtin_match(idx);
|
bool is_builtin = (enabled_cats == BITS_ALL) ? builtin_is_known(idx) : builtin_match(idx);
|
||||||
if (is_builtin)
|
if (is_builtin)
|
||||||
return idx < (size_t)StaticCellTypes::GEN_MAX_CELLS && StaticCellTypes::GeneratedData::is_evaluable[idx];
|
return idx < (size_t)StaticCellTypes::GEN_MAX_CELLS &&
|
||||||
|
StaticCellTypes::GeneratedData::is_cell_evaluable[idx];
|
||||||
auto it = cell_types.find(type);
|
auto it = cell_types.find(type);
|
||||||
return it != cell_types.end() && it->second.is_evaluable;
|
return it != cell_types.end() && it->second.is_evaluable;
|
||||||
}
|
}
|
||||||
@@ -245,7 +233,6 @@ struct CellTypes
|
|||||||
for (auto bit : v)
|
for (auto bit : v)
|
||||||
if (bit == State::S0) bit = State::S1;
|
if (bit == State::S0) bit = State::S1;
|
||||||
else if (bit == State::S1) bit = State::S0;
|
else if (bit == State::S1) bit = State::S0;
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -361,7 +348,6 @@ struct CellTypes
|
|||||||
std::vector<RTLIL::State> t = cell->parameters.at(ID::LUT).to_bits();
|
std::vector<RTLIL::State> t = cell->parameters.at(ID::LUT).to_bits();
|
||||||
while (GetSize(t) < (1 << width))
|
while (GetSize(t) < (1 << width))
|
||||||
t.push_back(State::S0);
|
t.push_back(State::S0);
|
||||||
|
|
||||||
t.resize(1 << width);
|
t.resize(1 << width);
|
||||||
|
|
||||||
return const_bmux(t, arg1);
|
return const_bmux(t, arg1);
|
||||||
@@ -373,7 +359,7 @@ struct CellTypes
|
|||||||
int depth = cell->parameters.at(ID::DEPTH).as_int();
|
int depth = cell->parameters.at(ID::DEPTH).as_int();
|
||||||
std::vector<RTLIL::State> t = cell->parameters.at(ID::TABLE).to_bits();
|
std::vector<RTLIL::State> t = cell->parameters.at(ID::TABLE).to_bits();
|
||||||
|
|
||||||
while (GetSize(t) < width * depth * 2)
|
while (GetSize(t) < width*depth*2)
|
||||||
t.push_back(State::S0);
|
t.push_back(State::S0);
|
||||||
|
|
||||||
RTLIL::State default_ret = State::S0;
|
RTLIL::State default_ret = State::S0;
|
||||||
@@ -385,11 +371,11 @@ struct CellTypes
|
|||||||
|
|
||||||
for (int j = 0; j < width; j++) {
|
for (int j = 0; j < width; j++) {
|
||||||
RTLIL::State a = arg1.at(j);
|
RTLIL::State a = arg1.at(j);
|
||||||
if (t.at(2 * width * i + 2 * j + 0) == State::S1) {
|
if (t.at(2*width*i + 2*j + 0) == State::S1) {
|
||||||
if (a == State::S1) match_x = false;
|
if (a == State::S1) match_x = false;
|
||||||
if (a != State::S0) match = false;
|
if (a != State::S0) match = false;
|
||||||
}
|
}
|
||||||
if (t.at(2 * width * i + 2 * j + 1) == State::S1) {
|
if (t.at(2*width*i + 2*j + 1) == State::S1) {
|
||||||
if (a == State::S0) match_x = false;
|
if (a == State::S0) match_x = false;
|
||||||
if (a != State::S1) match = false;
|
if (a != State::S1) match = false;
|
||||||
}
|
}
|
||||||
|
|||||||
+31
-18
@@ -39,6 +39,7 @@ def resolve_id(index_map, name):
|
|||||||
@dataclass
|
@dataclass
|
||||||
class Features:
|
class Features:
|
||||||
is_evaluable: bool = False
|
is_evaluable: bool = False
|
||||||
|
is_cell_evaluable: bool = False
|
||||||
is_combinatorial: bool = False
|
is_combinatorial: bool = False
|
||||||
is_synthesizable: bool = False
|
is_synthesizable: bool = False
|
||||||
is_stdcell: bool = False
|
is_stdcell: bool = False
|
||||||
@@ -51,7 +52,7 @@ class Features:
|
|||||||
@dataclass
|
@dataclass
|
||||||
class CellInfo:
|
class CellInfo:
|
||||||
type_name: str
|
type_name: str
|
||||||
inputs: MAX_CELLS
|
inputs: list
|
||||||
outputs: list
|
outputs: list
|
||||||
features: Features
|
features: Features
|
||||||
|
|
||||||
@@ -64,7 +65,7 @@ def build_cell_table():
|
|||||||
Features(**vars(features))))
|
Features(**vars(features))))
|
||||||
|
|
||||||
# setup_internals_other
|
# setup_internals_other
|
||||||
f = Features(is_tristate=True)
|
f = Features(is_tristate=True, is_cell_evaluable=True)
|
||||||
setup_type("$tribuf", ["A", "EN"], ["Y"], f)
|
setup_type("$tribuf", ["A", "EN"], ["Y"], f)
|
||||||
|
|
||||||
f = Features()
|
f = Features()
|
||||||
@@ -79,9 +80,13 @@ def build_cell_table():
|
|||||||
setup_type("$allconst", [], ["Y"], f)
|
setup_type("$allconst", [], ["Y"], f)
|
||||||
setup_type("$allseq", [], ["Y"], f)
|
setup_type("$allseq", [], ["Y"], f)
|
||||||
setup_type("$equiv", ["A", "B"], ["Y"], f)
|
setup_type("$equiv", ["A", "B"], ["Y"], f)
|
||||||
|
|
||||||
|
f = Features(is_cell_evaluable=True)
|
||||||
setup_type("$specify2", ["EN", "SRC", "DST"], [], f)
|
setup_type("$specify2", ["EN", "SRC", "DST"], [], f)
|
||||||
setup_type("$specify3", ["EN", "SRC", "DST", "DAT"], [], f)
|
setup_type("$specify3", ["EN", "SRC", "DST", "DAT"], [], f)
|
||||||
setup_type("$specrule", ["EN_SRC", "EN_DST", "SRC", "DST"], [], f)
|
setup_type("$specrule", ["EN_SRC", "EN_DST", "SRC", "DST"], [], f)
|
||||||
|
|
||||||
|
f = Features()
|
||||||
setup_type("$print", ["EN", "ARGS", "TRG"], [], f)
|
setup_type("$print", ["EN", "ARGS", "TRG"], [], f)
|
||||||
setup_type("$check", ["A", "EN", "ARGS", "TRG"], [], f)
|
setup_type("$check", ["A", "EN", "ARGS", "TRG"], [], f)
|
||||||
setup_type("$set_tag", ["A", "SET", "CLR"], ["Y"], f)
|
setup_type("$set_tag", ["A", "SET", "CLR"], ["Y"], f)
|
||||||
@@ -94,7 +99,7 @@ def build_cell_table():
|
|||||||
setup_type("$connect", ["A", "B"], [], f)
|
setup_type("$connect", ["A", "B"], [], f)
|
||||||
|
|
||||||
# setup_internals_eval
|
# setup_internals_eval
|
||||||
f = Features(is_evaluable=True)
|
f = Features(is_evaluable=True, is_cell_evaluable=True)
|
||||||
|
|
||||||
unary_ops = [
|
unary_ops = [
|
||||||
"$not", "$pos", "$buf", "$neg",
|
"$not", "$pos", "$buf", "$neg",
|
||||||
@@ -150,7 +155,7 @@ def build_cell_table():
|
|||||||
f = Features(is_anyinit=True)
|
f = Features(is_anyinit=True)
|
||||||
setup_type("$anyinit", ["D"], ["Q"], f)
|
setup_type("$anyinit", ["D"], ["Q"], f)
|
||||||
|
|
||||||
# setup_internals_mem_noff
|
# setup_internals_mem_noff (mem cells that are NOT FFs)
|
||||||
f = Features(is_mem_noff=True)
|
f = Features(is_mem_noff=True)
|
||||||
setup_type("$memrd", ["CLK", "EN", "ADDR"], ["DATA"], f)
|
setup_type("$memrd", ["CLK", "EN", "ADDR"], ["DATA"], f)
|
||||||
setup_type("$memrd_v2", ["CLK", "EN", "ARST", "SRST", "ADDR"],
|
setup_type("$memrd_v2", ["CLK", "EN", "ARST", "SRST", "ADDR"],
|
||||||
@@ -170,11 +175,11 @@ def build_cell_table():
|
|||||||
setup_type("$fsm", ["CLK", "ARST", "CTRL_IN"], ["CTRL_OUT"], f)
|
setup_type("$fsm", ["CLK", "ARST", "CTRL_IN"], ["CTRL_OUT"], f)
|
||||||
|
|
||||||
# setup_stdcells_tristate
|
# setup_stdcells_tristate
|
||||||
f = Features(is_stdcell=True, is_tristate=True)
|
f = Features(is_stdcell=True, is_tristate=True, is_cell_evaluable=True)
|
||||||
setup_type("$_TBUF_", ["A", "E"], ["Y"], f)
|
setup_type("$_TBUF_", ["A", "E"], ["Y"], f)
|
||||||
|
|
||||||
# setup_stdcells_eval
|
# setup_stdcells_eval
|
||||||
f = Features(is_stdcell=True, is_evaluable=True)
|
f = Features(is_stdcell=True, is_evaluable=True, is_cell_evaluable=True)
|
||||||
setup_type("$_BUF_", ["A"], ["Y"], f)
|
setup_type("$_BUF_", ["A"], ["Y"], f)
|
||||||
setup_type("$_NOT_", ["A"], ["Y"], f)
|
setup_type("$_NOT_", ["A"], ["Y"], f)
|
||||||
setup_type("$_AND_", ["A", "B"], ["Y"], f)
|
setup_type("$_AND_", ["A", "B"], ["Y"], f)
|
||||||
@@ -298,6 +303,7 @@ def build_arrays(cells, index_map):
|
|||||||
cats = {
|
cats = {
|
||||||
"is_known": [0] * MAX_CELLS,
|
"is_known": [0] * MAX_CELLS,
|
||||||
"is_evaluable": [0] * MAX_CELLS,
|
"is_evaluable": [0] * MAX_CELLS,
|
||||||
|
"is_cell_evaluable": [0] * MAX_CELLS,
|
||||||
"is_combinatorial": [0] * MAX_CELLS,
|
"is_combinatorial": [0] * MAX_CELLS,
|
||||||
"is_synthesizable": [0] * MAX_CELLS,
|
"is_synthesizable": [0] * MAX_CELLS,
|
||||||
"is_stdcell": [0] * MAX_CELLS,
|
"is_stdcell": [0] * MAX_CELLS,
|
||||||
@@ -320,9 +326,9 @@ def build_arrays(cells, index_map):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
cats["is_known"][idx] = 1
|
cats["is_known"][idx] = 1
|
||||||
for feat in ["is_evaluable", "is_combinatorial", "is_synthesizable",
|
for feat in ["is_evaluable", "is_cell_evaluable", "is_combinatorial",
|
||||||
"is_stdcell", "is_ff", "is_mem_noff", "is_anyinit",
|
"is_synthesizable", "is_stdcell", "is_ff", "is_mem_noff",
|
||||||
"is_tristate"]:
|
"is_anyinit", "is_tristate"]:
|
||||||
if getattr(cell.features, feat):
|
if getattr(cell.features, feat):
|
||||||
cats[feat][idx] = 1
|
cats[feat][idx] = 1
|
||||||
|
|
||||||
@@ -449,7 +455,13 @@ constexpr int GEN_MAX_PORTS = {MAX_PORTS};
|
|||||||
namespace GeneratedData {{
|
namespace GeneratedData {{
|
||||||
|
|
||||||
extern const uint8_t is_known[GEN_MAX_CELLS];
|
extern const uint8_t is_known[GEN_MAX_CELLS];
|
||||||
|
// Category flag: true for cells in setup_internals_eval / setup_stdcells_eval.
|
||||||
|
// Used by builtin_match() for subset filtering.
|
||||||
extern const uint8_t is_evaluable[GEN_MAX_CELLS];
|
extern const uint8_t is_evaluable[GEN_MAX_CELLS];
|
||||||
|
// Property flag: true for any cell whose original setup_type() had is_evaluable=true.
|
||||||
|
// Superset of is_evaluable (includes $tribuf, $specify*, $_TBUF_).
|
||||||
|
// Used by cell_evaluable() to answer "can this cell be const-evaluated?"
|
||||||
|
extern const uint8_t is_cell_evaluable[GEN_MAX_CELLS];
|
||||||
extern const uint8_t is_combinatorial[GEN_MAX_CELLS];
|
extern const uint8_t is_combinatorial[GEN_MAX_CELLS];
|
||||||
extern const uint8_t is_synthesizable[GEN_MAX_CELLS];
|
extern const uint8_t is_synthesizable[GEN_MAX_CELLS];
|
||||||
extern const uint8_t is_stdcell[GEN_MAX_CELLS];
|
extern const uint8_t is_stdcell[GEN_MAX_CELLS];
|
||||||
@@ -498,15 +510,16 @@ struct GenPortLookup {{
|
|||||||
}}
|
}}
|
||||||
}};
|
}};
|
||||||
|
|
||||||
inline GenCategory gen_is_known() {{ return {{GeneratedData::is_known}}; }}
|
inline GenCategory gen_is_known() {{ return {{GeneratedData::is_known}}; }}
|
||||||
inline GenCategory gen_is_evaluable() {{ return {{GeneratedData::is_evaluable}}; }}
|
inline GenCategory gen_is_evaluable() {{ return {{GeneratedData::is_evaluable}}; }}
|
||||||
inline GenCategory gen_is_combinatorial() {{ return {{GeneratedData::is_combinatorial}}; }}
|
inline GenCategory gen_is_cell_evaluable() {{ return {{GeneratedData::is_cell_evaluable}}; }}
|
||||||
inline GenCategory gen_is_synthesizable() {{ return {{GeneratedData::is_synthesizable}}; }}
|
inline GenCategory gen_is_combinatorial() {{ return {{GeneratedData::is_combinatorial}}; }}
|
||||||
inline GenCategory gen_is_stdcell() {{ return {{GeneratedData::is_stdcell}}; }}
|
inline GenCategory gen_is_synthesizable() {{ return {{GeneratedData::is_synthesizable}}; }}
|
||||||
inline GenCategory gen_is_ff() {{ return {{GeneratedData::is_ff}}; }}
|
inline GenCategory gen_is_stdcell() {{ return {{GeneratedData::is_stdcell}}; }}
|
||||||
inline GenCategory gen_is_mem_noff() {{ return {{GeneratedData::is_mem_noff}}; }}
|
inline GenCategory gen_is_ff() {{ return {{GeneratedData::is_ff}}; }}
|
||||||
inline GenCategory gen_is_anyinit() {{ return {{GeneratedData::is_anyinit}}; }}
|
inline GenCategory gen_is_mem_noff() {{ return {{GeneratedData::is_mem_noff}}; }}
|
||||||
inline GenCategory gen_is_tristate() {{ return {{GeneratedData::is_tristate}}; }}
|
inline GenCategory gen_is_anyinit() {{ return {{GeneratedData::is_anyinit}}; }}
|
||||||
|
inline GenCategory gen_is_tristate() {{ return {{GeneratedData::is_tristate}}; }}
|
||||||
|
|
||||||
inline GenCategory gen_compat_internals_all() {{ return {{GeneratedData::compat_internals_all}}; }}
|
inline GenCategory gen_compat_internals_all() {{ return {{GeneratedData::compat_internals_all}}; }}
|
||||||
inline GenCategory gen_compat_mem_ff() {{ return {{GeneratedData::compat_mem_ff}}; }}
|
inline GenCategory gen_compat_mem_ff() {{ return {{GeneratedData::compat_mem_ff}}; }}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user