Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 126 additions & 37 deletions kernel/celltypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,25 @@ struct CellType
{
RTLIL::IdString type;
pool<RTLIL::IdString> inputs, outputs;
bool is_evaluable;
bool is_combinatorial;
bool is_synthesizable;
bool is_builtin_ff;
bool is_formal;
// Cell is defined in celltypes.h, as opposed to design-specific
bool is_internal;
// Cell can be handled by CellTypes::eval()
bool is_evaluable = false;
// Cell has no state; outputs are determined solely by inputs
bool is_combinatorial = false;
// Cell is able to be fully represented in the synthesizable subset of verilog
bool is_synthesizable = false;
// Cell is built-in memory logic, includes flip-flops and latches, but not complex
// cells like $mem
bool is_builtin_ff = false;
// Cell is non-synthesizable, but used for formal verification
bool is_formal = false;
// Cell is intended for internal Yosys use, containing informational metadata and
// shouldn't be automatically cleaned; currently only used for $scopeinfo
bool is_metainfo = false;
// Non-synthesizable cell with effects that mean it shouldn't be automatically
// cleaned, e.g. $print
bool has_effects = false;
};

struct CellTypes
Expand Down Expand Up @@ -60,30 +74,102 @@ struct CellTypes
setup_stdcells_mem();
}

void setup_type(RTLIL::IdString type, const pool<RTLIL::IdString> &inputs, const pool<RTLIL::IdString> &outputs,
bool is_evaluable = false, bool is_combinatorial = false, bool is_synthesizable = false,
bool is_builtin_ff = false, bool is_formal = false)
void setup_type(RTLIL::IdString type, const pool<RTLIL::IdString> &inputs, const pool<RTLIL::IdString> &outputs)
{
CellType ct = {type, inputs, outputs, is_evaluable, is_combinatorial, is_synthesizable, is_builtin_ff, is_formal};
CellType ct = {
.type = type,
.inputs = inputs,
.outputs = outputs,
.is_internal = false
};
cell_types[ct.type] = ct;
}

// Setup internal cell type with no other default properties
void setup_internal_type(RTLIL::IdString type, const pool<RTLIL::IdString> &inputs, const pool<RTLIL::IdString> &outputs,
bool is_combinatorial = false)
{
CellType ct = {
.type = type,
.inputs = inputs,
.outputs = outputs,
.is_internal = true,
.is_combinatorial = is_combinatorial,
};
cell_types[ct.type] = ct;
}

// Setup combinational cell type which is evaluable and synthesizable
void setup_comb_type(RTLIL::IdString type, const pool<RTLIL::IdString> &inputs, const pool<RTLIL::IdString> &outputs)
// Setup combinatorial cell type which is synthesizable and evaluable (by default)
void setup_comb_type(RTLIL::IdString type, const pool<RTLIL::IdString> &inputs, const pool<RTLIL::IdString> &outputs,
bool is_evaluable = true)
{
setup_type(type, inputs, outputs, true, true, true, false, false);
CellType ct = {
.type = type,
.inputs = inputs,
.outputs = outputs,
.is_internal = true,
.is_evaluable = is_evaluable,
.is_combinatorial = true,
.is_synthesizable = true,
};
cell_types[ct.type] = ct;
}

// Setup builtin ff cell type which is synthesizable
void setup_ff_type(RTLIL::IdString type, const pool<RTLIL::IdString> &inputs, const pool<RTLIL::IdString> &outputs)
{
setup_type(type, inputs, outputs, false, false, true, true, false);
CellType ct = {
.type = type,
.inputs = inputs,
.outputs = outputs,
.is_internal = true,
.is_synthesizable = true,
.is_builtin_ff = true,
};
cell_types[ct.type] = ct;
}

// Setup formal cell type which may be evaluable
void setup_formal_type(RTLIL::IdString type, const pool<RTLIL::IdString> &inputs, const pool<RTLIL::IdString> &outputs, bool is_evaluable = false)
// Setup formal cell type which may be combinatorial, and may have effects
void setup_formal_type(RTLIL::IdString type, const pool<RTLIL::IdString> &inputs, const pool<RTLIL::IdString> &outputs,
bool is_combinatorial = false)
{
setup_type(type, inputs, outputs, is_evaluable, false, false, false, true);
CellType ct = {
.type = type,
.inputs = inputs,
.outputs = outputs,
.is_internal = true,
.is_combinatorial = is_combinatorial,
.is_formal = true,
};
cell_types[ct.type] = ct;
}

// Setup cell type which has effects, and may be formal
void setup_effects_type(RTLIL::IdString type, const pool<RTLIL::IdString> &inputs, const pool<RTLIL::IdString> &outputs,
bool is_formal = false)
{
CellType ct = {
.type = type,
.inputs = inputs,
.outputs = outputs,
.is_internal = true,
.is_formal = is_formal,
.has_effects = true,
};
cell_types[ct.type] = ct;
}

// Setup meta-info cell type
void setup_metainfo_type(RTLIL::IdString type, const pool<RTLIL::IdString> &inputs, const pool<RTLIL::IdString> &outputs)
{
CellType ct = {
.type = type,
.inputs = inputs,
.outputs = outputs,
.is_internal = true,
.is_metainfo = true,
};
cell_types[ct.type] = ct;
}

void setup_module(RTLIL::Module *module)
Expand All @@ -109,9 +195,10 @@ struct CellTypes
{
setup_internals_eval();

setup_comb_type(ID($tribuf), {ID::A, ID::EN}, {ID::Y});
// synthesizable
setup_comb_type(ID($tribuf), {ID::A, ID::EN}, {ID::Y}, false);

// evaluable formal
// combinatorial formal
setup_formal_type(ID($assert), {ID::A, ID::EN}, pool<RTLIL::IdString>(), true);
setup_formal_type(ID($assume), {ID::A, ID::EN}, pool<RTLIL::IdString>(), true);
setup_formal_type(ID($live), {ID::A, ID::EN}, pool<RTLIL::IdString>(), true);
Expand All @@ -124,22 +211,24 @@ struct CellTypes
setup_formal_type(ID($allseq), pool<RTLIL::IdString>(), {ID::Y}, true);
setup_formal_type(ID($equiv), {ID::A, ID::B}, {ID::Y}, true);

// evaluable non-formal
setup_type(ID($specify2), {ID::EN, ID::SRC, ID::DST}, pool<RTLIL::IdString>(), true);
setup_type(ID($specify3), {ID::EN, ID::SRC, ID::DST, ID::DAT}, pool<RTLIL::IdString>(), true);
setup_type(ID($specrule), {ID::EN_SRC, ID::EN_DST, ID::SRC, ID::DST}, pool<RTLIL::IdString>(), true);
setup_type(ID($print), {ID::EN, ID::ARGS, ID::TRG}, pool<RTLIL::IdString>());
// combinatorial non-synthesizable
setup_internal_type(ID($specify2), {ID::EN, ID::SRC, ID::DST}, pool<RTLIL::IdString>(), true);
setup_internal_type(ID($specify3), {ID::EN, ID::SRC, ID::DST, ID::DAT}, pool<RTLIL::IdString>(), true);
setup_internal_type(ID($specrule), {ID::EN_SRC, ID::EN_DST, ID::SRC, ID::DST}, pool<RTLIL::IdString>(), true);

// non-evaluable formal
setup_formal_type(ID($check), {ID::A, ID::EN, ID::ARGS, ID::TRG}, pool<RTLIL::IdString>());
// non-combinatorial formal
setup_formal_type(ID($set_tag), {ID::A, ID::SET, ID::CLR}, {ID::Y});
setup_formal_type(ID($get_tag), {ID::A}, {ID::Y});
setup_formal_type(ID($overwrite_tag), {ID::A, ID::SET, ID::CLR}, pool<RTLIL::IdString>());
setup_formal_type(ID($original_tag), {ID::A}, {ID::Y});
setup_formal_type(ID($future_ff), {ID::A}, {ID::Y});

// non-evaluable non-formal
setup_type(ID($scopeinfo), {}, {});
// has effects
setup_effects_type(ID($print), {ID::EN, ID::ARGS, ID::TRG}, pool<RTLIL::IdString>());
setup_effects_type(ID($check), {ID::A, ID::EN, ID::ARGS, ID::TRG}, pool<RTLIL::IdString>(), true);

// meta-info
setup_metainfo_type(ID($scopeinfo), {}, {});
}

void setup_internals_eval()
Expand Down Expand Up @@ -205,23 +294,23 @@ struct CellTypes
{
setup_internals_ff();

setup_type(ID($memrd), {ID::CLK, ID::EN, ID::ADDR}, {ID::DATA});
setup_type(ID($memrd_v2), {ID::CLK, ID::EN, ID::ARST, ID::SRST, ID::ADDR}, {ID::DATA});
setup_type(ID($memwr), {ID::CLK, ID::EN, ID::ADDR, ID::DATA}, pool<RTLIL::IdString>());
setup_type(ID($memwr_v2), {ID::CLK, ID::EN, ID::ADDR, ID::DATA}, pool<RTLIL::IdString>());
setup_type(ID($meminit), {ID::ADDR, ID::DATA}, pool<RTLIL::IdString>());
setup_type(ID($meminit_v2), {ID::ADDR, ID::DATA, ID::EN}, pool<RTLIL::IdString>());
setup_type(ID($mem), {ID::RD_CLK, ID::RD_EN, ID::RD_ADDR, ID::WR_CLK, ID::WR_EN, ID::WR_ADDR, ID::WR_DATA}, {ID::RD_DATA});
setup_type(ID($mem_v2), {ID::RD_CLK, ID::RD_EN, ID::RD_ARST, ID::RD_SRST, ID::RD_ADDR, ID::WR_CLK, ID::WR_EN, ID::WR_ADDR, ID::WR_DATA}, {ID::RD_DATA});
setup_internal_type(ID($memrd), {ID::CLK, ID::EN, ID::ADDR}, {ID::DATA});
setup_internal_type(ID($memrd_v2), {ID::CLK, ID::EN, ID::ARST, ID::SRST, ID::ADDR}, {ID::DATA});
setup_internal_type(ID($memwr), {ID::CLK, ID::EN, ID::ADDR, ID::DATA}, pool<RTLIL::IdString>());
setup_internal_type(ID($memwr_v2), {ID::CLK, ID::EN, ID::ADDR, ID::DATA}, pool<RTLIL::IdString>());
setup_internal_type(ID($meminit), {ID::ADDR, ID::DATA}, pool<RTLIL::IdString>());
setup_internal_type(ID($meminit_v2), {ID::ADDR, ID::DATA, ID::EN}, pool<RTLIL::IdString>());
setup_internal_type(ID($mem), {ID::RD_CLK, ID::RD_EN, ID::RD_ADDR, ID::WR_CLK, ID::WR_EN, ID::WR_ADDR, ID::WR_DATA}, {ID::RD_DATA});
setup_internal_type(ID($mem_v2), {ID::RD_CLK, ID::RD_EN, ID::RD_ARST, ID::RD_SRST, ID::RD_ADDR, ID::WR_CLK, ID::WR_EN, ID::WR_ADDR, ID::WR_DATA}, {ID::RD_DATA});

setup_type(ID($fsm), {ID::CLK, ID::ARST, ID::CTRL_IN}, {ID::CTRL_OUT});
setup_internal_type(ID($fsm), {ID::CLK, ID::ARST, ID::CTRL_IN}, {ID::CTRL_OUT});
}

void setup_stdcells()
{
setup_stdcells_eval();

setup_comb_type(ID($_TBUF_), {ID::A, ID::E}, {ID::Y});
setup_comb_type(ID($_TBUF_), {ID::A, ID::E}, {ID::Y}, false);
}

void setup_stdcells_eval()
Expand Down
9 changes: 9 additions & 0 deletions passes/cmds/select.cc
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ static bool match_type_prop(RTLIL::IdString type, const std::string &property)
if (ct == nullptr) {
return false;
} else
if (property.compare("internal") == 0) {
return ct->is_internal;
} else
if (property.compare("evaluable") == 0) {
return ct->is_evaluable;
} else
Expand All @@ -161,6 +164,12 @@ static bool match_type_prop(RTLIL::IdString type, const std::string &property)
} else
if (property.compare("formal") == 0) {
return ct->is_formal;
} else
if (property.compare("metainfo") == 0) {
return ct->is_metainfo;
} else
if (property.compare("effects") == 0) {
return ct->has_effects;
} else
log_cmd_error("Unsupported type property '%s'!\n", property.c_str());
}
Expand Down
Loading