3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-07-15 03:35:40 +00:00
This commit is contained in:
Emil J. Tywoniak 2026-06-11 20:02:02 +02:00
parent 8e522b08c0
commit afdae7b87e
49 changed files with 1258 additions and 891 deletions

View file

@ -174,14 +174,14 @@ struct Scheduler {
}
};
bool is_unary_cell(RTLIL::IdString type)
bool is_unary_cell(TwineRef type)
{
return type.in(
ID($not), ID($logic_not), ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool),
ID($pos), ID($neg));
}
bool is_binary_cell(RTLIL::IdString type)
bool is_binary_cell(TwineRef type)
{
return type.in(
ID($and), ID($or), ID($xor), ID($xnor), ID($logic_and), ID($logic_or),
@ -190,20 +190,20 @@ bool is_binary_cell(RTLIL::IdString type)
ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($modfloor), ID($divfloor));
}
bool is_extending_cell(RTLIL::IdString type)
bool is_extending_cell(TwineRef type)
{
return !type.in(
ID($logic_not), ID($logic_and), ID($logic_or),
ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool));
}
bool is_inlinable_cell(RTLIL::IdString type)
bool is_inlinable_cell(TwineRef type)
{
return is_unary_cell(type) || is_binary_cell(type) || type.in(
ID($mux), ID($concat), ID($slice), ID($pmux), ID($bmux), ID($demux), ID($bwmux));
}
bool is_ff_cell(RTLIL::IdString type)
bool is_ff_cell(TwineRef type)
{
return type.in(
ID($dff), ID($dffe), ID($sdff), ID($sdffe), ID($sdffce),
@ -212,12 +212,12 @@ bool is_ff_cell(RTLIL::IdString type)
ID($dlatch), ID($adlatch), ID($dlatchsr), ID($sr));
}
bool is_internal_cell(RTLIL::IdString type)
bool is_internal_cell(TwineRef type)
{
return !type.isPublic() && !type.begins_with("$paramod");
}
bool is_effectful_cell(RTLIL::IdString type)
bool is_effectful_cell(TwineRef type)
{
return type.in(ID($print), ID($check));
}

View file

@ -264,9 +264,9 @@ struct Xaiger2Frontend : public Frontend {
log_debug("M: len=%u no_cells=%u no_instances=%u\n", len, no_cells, no_instances);
struct MappingCell {
RTLIL::IdString type;
TwineRef type;
RTLIL::IdString out;
std::vector<RTLIL::IdString> ins;
std::vector<TwineRef ins;
};
std::vector<MappingCell> cells;
cells.resize(no_cells);

View file

@ -396,14 +396,14 @@ namespace AST
struct AstModule : RTLIL::Module {
std::unique_ptr<AstNode> ast;
bool nolatches, nomeminit, nomem2reg, mem2reg, noblackbox, lib, nowb, noopt, icells, pwires, autowire;
RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool mayfail) override;
RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail) override;
TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool mayfail) override;
TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, const dict<TwineRef, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail) override;
std::string derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, std::unique_ptr<AstNode>* new_ast_out, bool quiet = false);
void expand_interfaces(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces) override;
bool reprocess_if_necessary(RTLIL::Design *design) override;
RTLIL::Module *clone() const override;
RTLIL::Module *clone(RTLIL::Design *dst, bool src_id_verbatim = false) const override;
RTLIL::Module *clone(RTLIL::Design *dst, RTLIL::IdString target_name, bool src_id_verbatim = false) const override;
RTLIL::Module *clone(RTLIL::Design *dst, TwineRef target_name, bool src_id_verbatim = false) const override;
void loadconfig() const;
};

View file

@ -2191,9 +2191,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
for (auto it = children.begin(); it != children.end(); it++) {
auto* child = it->get();
if (child->type == AST_CELLTYPE) {
cell->type = child->str;
if (flag_icells && cell->type.begins_with("\\$"))
cell->type = cell->type.substr(1);
std::string type_str = child->str;
if (flag_icells && type_str.size() >= 2 && type_str[0] == '\\' && type_str[1] == '$')
type_str = type_str.substr(1);
cell->type_impl = current_module->design->twines.add(Twine{type_str});
continue;
}
if (child->type == AST_PARASET) {

View file

@ -277,21 +277,21 @@ static void create_ff(RTLIL::Module *module, const LibertyAst *node)
cell->setPort(TW::C, clk_sig);
if (clear_sig.size() == 0 && preset_sig.size() == 0) {
cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N');
cell->type_impl = module->design->twines.add(Twine{stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N')});
}
if (clear_sig.size() == 1 && preset_sig.size() == 0) {
cell->type = stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N');
cell->type_impl = module->design->twines.add(Twine{stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N')});
cell->setPort(TW::R, clear_sig);
}
if (clear_sig.size() == 0 && preset_sig.size() == 1) {
cell->type = stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N');
cell->type_impl = module->design->twines.add(Twine{stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N')});
cell->setPort(TW::R, preset_sig);
}
if (clear_sig.size() == 1 && preset_sig.size() == 1) {
cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N');
cell->type_impl = module->design->twines.add(Twine{stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N')});
SigBit s_sig = preset_sig;
SigBit r_sig = clear_sig;

View file

@ -207,7 +207,7 @@ struct RpcModule : RTLIL::Module {
for (auto module : derived_design->modules())
for (auto cell : module->cells())
if (name_mangling.count(cell->type.str()))
cell->type = name_mangling[cell->type.str()];
cell->type_impl = cell->module->design->twines.add(Twine{name_mangling[cell->type.str()]});
for (auto module : derived_design->modules_) {
std::string mangled_name = name_mangling[derived_design->twines.str(module.first)];

View file

@ -27,7 +27,7 @@ YOSYS_NAMESPACE_BEGIN
struct CellType
{
RTLIL::IdString type;
TwineRef type;
pool<TwineRef> inputs, outputs;
bool is_evaluable;
bool is_combinatorial;
@ -36,7 +36,7 @@ struct CellType
struct CellTypes
{
dict<RTLIL::IdString, CellType> cell_types;
dict<TwineRef, CellType> cell_types;
CellTypes()
{
@ -59,7 +59,7 @@ struct CellTypes
setup_stdcells_mem();
}
void setup_type(RTLIL::IdString type, const pool<TwineRef> &inputs, const pool<TwineRef> &outputs, bool is_evaluable = false, bool is_combinatorial = false, bool is_synthesizable = false)
void setup_type(TwineRef type, const pool<TwineRef> &inputs, const pool<TwineRef> &outputs, bool is_evaluable = false, bool is_combinatorial = false, bool is_synthesizable = false)
{
CellType ct = {type, inputs, outputs, is_evaluable, is_combinatorial, is_synthesizable};
cell_types[ct.type] = ct;
@ -75,7 +75,7 @@ struct CellTypes
if (wire->port_output)
outputs.insert(wire->meta_->name);
}
setup_type(RTLIL::IdString(module->design->twines.str(module->meta_->name)), inputs, outputs);
setup_type(module->meta_->name, inputs, outputs);
}
void setup_design(RTLIL::Design *design)
@ -88,51 +88,51 @@ struct CellTypes
{
setup_internals_eval();
setup_type(ID($tribuf), {TW::A, TW::EN}, {TW::Y});
setup_type(TW($tribuf), {TW::A, TW::EN}, {TW::Y});
setup_type(ID($assert), {TW::A, TW::EN}, pool<TwineRef>());
setup_type(ID($assume), {TW::A, TW::EN}, pool<TwineRef>());
setup_type(ID($live), {TW::A, TW::EN}, pool<TwineRef>());
setup_type(ID($fair), {TW::A, TW::EN}, pool<TwineRef>());
setup_type(ID($cover), {TW::A, TW::EN}, pool<TwineRef>());
setup_type(ID($initstate), pool<TwineRef>(), {TW::Y});
setup_type(ID($anyconst), pool<TwineRef>(), {TW::Y});
setup_type(ID($anyseq), pool<TwineRef>(), {TW::Y});
setup_type(ID($allconst), pool<TwineRef>(), {TW::Y});
setup_type(ID($allseq), pool<TwineRef>(), {TW::Y});
setup_type(ID($equiv), {TW::A, TW::B}, {TW::Y});
setup_type(ID($specify2), {TW::EN, TW::SRC, TW::DST}, pool<TwineRef>());
setup_type(ID($specify3), {TW::EN, TW::SRC, TW::DST, TW::DAT}, pool<TwineRef>());
setup_type(ID($specrule), {TW::SRC_EN, TW::DST_EN, TW::SRC, TW::DST}, pool<TwineRef>());
setup_type(ID($print), {TW::EN, TW::ARGS, TW::TRG}, pool<TwineRef>());
setup_type(ID($check), {TW::A, TW::EN, TW::ARGS, TW::TRG}, pool<TwineRef>());
setup_type(ID($set_tag), {TW::A, TW::SET, TW::CLR}, {TW::Y});
setup_type(ID($get_tag), {TW::A}, {TW::Y});
setup_type(ID($overwrite_tag), {TW::A, TW::SET, TW::CLR}, pool<TwineRef>());
setup_type(ID($original_tag), {TW::A}, {TW::Y});
setup_type(ID($future_ff), {TW::A}, {TW::Y});
setup_type(ID($scopeinfo), {}, {});
setup_type(ID($input_port), {}, {TW::Y});
setup_type(ID($output_port), {TW::A}, {});
setup_type(ID($public), {TW::A}, {});
setup_type(ID($connect), {TW::A, TW::B}, {});
setup_type(TW($assert), {TW::A, TW::EN}, pool<TwineRef>());
setup_type(TW($assume), {TW::A, TW::EN}, pool<TwineRef>());
setup_type(TW($live), {TW::A, TW::EN}, pool<TwineRef>());
setup_type(TW($fair), {TW::A, TW::EN}, pool<TwineRef>());
setup_type(TW($cover), {TW::A, TW::EN}, pool<TwineRef>());
setup_type(TW($initstate), pool<TwineRef>(), {TW::Y});
setup_type(TW($anyconst), pool<TwineRef>(), {TW::Y});
setup_type(TW($anyseq), pool<TwineRef>(), {TW::Y});
setup_type(TW($allconst), pool<TwineRef>(), {TW::Y});
setup_type(TW($allseq), pool<TwineRef>(), {TW::Y});
setup_type(TW($equiv), {TW::A, TW::B}, {TW::Y});
setup_type(TW($specify2), {TW::EN, TW::SRC, TW::DST}, pool<TwineRef>());
setup_type(TW($specify3), {TW::EN, TW::SRC, TW::DST, TW::DAT}, pool<TwineRef>());
setup_type(TW($specrule), {TW::SRC_EN, TW::DST_EN, TW::SRC, TW::DST}, pool<TwineRef>());
setup_type(TW($print), {TW::EN, TW::ARGS, TW::TRG}, pool<TwineRef>());
setup_type(TW($check), {TW::A, TW::EN, TW::ARGS, TW::TRG}, pool<TwineRef>());
setup_type(TW($set_tag), {TW::A, TW::SET, TW::CLR}, {TW::Y});
setup_type(TW($get_tag), {TW::A}, {TW::Y});
setup_type(TW($overwrite_tag), {TW::A, TW::SET, TW::CLR}, pool<TwineRef>());
setup_type(TW($original_tag), {TW::A}, {TW::Y});
setup_type(TW($future_ff), {TW::A}, {TW::Y});
setup_type(TW($scopeinfo), {}, {});
setup_type(TW($input_port), {}, {TW::Y});
setup_type(TW($output_port), {TW::A}, {});
setup_type(TW($public), {TW::A}, {});
setup_type(TW($connect), {TW::A, TW::B}, {});
}
void setup_internals_eval()
{
std::vector<RTLIL::IdString> unary_ops = {
ID($not), ID($pos), ID($buf), ID($neg),
ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool),
ID($logic_not), ID($slice), ID($lut), ID($sop)
std::vector<TwineRef> unary_ops = {
TW($not), TW($pos), TW($buf), TW($neg),
TW($reduce_and), TW($reduce_or), TW($reduce_xor), TW($reduce_xnor), TW($reduce_bool),
TW($logic_not), TW($slice), TW($lut), TW($sop)
};
std::vector<RTLIL::IdString> binary_ops = {
ID($and), ID($or), ID($xor), ID($xnor),
ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx),
ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt),
ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($divfloor), ID($modfloor), ID($pow),
ID($logic_and), ID($logic_or), ID($concat), ID($macc),
ID($bweqx)
std::vector<TwineRef> binary_ops = {
TW($and), TW($or), TW($xor), TW($xnor),
TW($shl), TW($shr), TW($sshl), TW($sshr), TW($shift), TW($shiftx),
TW($lt), TW($le), TW($eq), TW($ne), TW($eqx), TW($nex), TW($ge), TW($gt),
TW($add), TW($sub), TW($mul), TW($div), TW($mod), TW($divfloor), TW($modfloor), TW($pow),
TW($logic_and), TW($logic_or), TW($concat), TW($macc),
TW($bweqx)
};
for (auto type : unary_ops)
@ -141,87 +141,87 @@ struct CellTypes
for (auto type : binary_ops)
setup_type(type, {TW::A, TW::B}, {TW::Y}, true);
for (auto type : std::vector<RTLIL::IdString>({ID($mux), ID($pmux), ID($bwmux)}))
for (auto type : std::vector<TwineRef>({TW($mux), TW($pmux), TW($bwmux)}))
setup_type(type, {TW::A, TW::B, TW::S}, {TW::Y}, true);
for (auto type : std::vector<RTLIL::IdString>({ID($bmux), ID($demux)}))
for (auto type : std::vector<TwineRef>({TW($bmux), TW($demux)}))
setup_type(type, {TW::A, TW::S}, {TW::Y}, true);
setup_type(ID($lcu), {TW::P, TW::G, TW::CI}, {TW::CO}, true);
setup_type(ID($alu), {TW::A, TW::B, TW::CI, TW::BI}, {TW::X, TW::Y, TW::CO}, true);
setup_type(ID($macc_v2), {TW::A, TW::B, TW::C}, {TW::Y}, true);
setup_type(ID($fa), {TW::A, TW::B, TW::C}, {TW::X, TW::Y}, true);
setup_type(TW($lcu), {TW::P, TW::G, TW::CI}, {TW::CO}, true);
setup_type(TW($alu), {TW::A, TW::B, TW::CI, TW::BI}, {TW::X, TW::Y, TW::CO}, true);
setup_type(TW($macc_v2), {TW::A, TW::B, TW::C}, {TW::Y}, true);
setup_type(TW($fa), {TW::A, TW::B, TW::C}, {TW::X, TW::Y}, true);
}
void setup_internals_ff()
{
setup_type(ID($sr), {TW::SET, TW::CLR}, {TW::Q});
setup_type(ID($ff), {TW::D}, {TW::Q});
setup_type(ID($dff), {TW::CLK, TW::D}, {TW::Q});
setup_type(ID($dffe), {TW::CLK, TW::EN, TW::D}, {TW::Q});
setup_type(ID($dffsr), {TW::CLK, TW::SET, TW::CLR, TW::D}, {TW::Q});
setup_type(ID($dffsre), {TW::CLK, TW::SET, TW::CLR, TW::D, TW::EN}, {TW::Q});
setup_type(ID($adff), {TW::CLK, TW::ARST, TW::D}, {TW::Q});
setup_type(ID($adffe), {TW::CLK, TW::ARST, TW::D, TW::EN}, {TW::Q});
setup_type(ID($aldff), {TW::CLK, TW::ALOAD, TW::AD, TW::D}, {TW::Q});
setup_type(ID($aldffe), {TW::CLK, TW::ALOAD, TW::AD, TW::D, TW::EN}, {TW::Q});
setup_type(ID($sdff), {TW::CLK, TW::SRST, TW::D}, {TW::Q});
setup_type(ID($sdffe), {TW::CLK, TW::SRST, TW::D, TW::EN}, {TW::Q});
setup_type(ID($sdffce), {TW::CLK, TW::SRST, TW::D, TW::EN}, {TW::Q});
setup_type(ID($dlatch), {TW::EN, TW::D}, {TW::Q});
setup_type(ID($adlatch), {TW::EN, TW::D, TW::ARST}, {TW::Q});
setup_type(ID($dlatchsr), {TW::EN, TW::SET, TW::CLR, TW::D}, {TW::Q});
setup_type(TW($sr), {TW::SET, TW::CLR}, {TW::Q});
setup_type(TW($ff), {TW::D}, {TW::Q});
setup_type(TW($dff), {TW::CLK, TW::D}, {TW::Q});
setup_type(TW($dffe), {TW::CLK, TW::EN, TW::D}, {TW::Q});
setup_type(TW($dffsr), {TW::CLK, TW::SET, TW::CLR, TW::D}, {TW::Q});
setup_type(TW($dffsre), {TW::CLK, TW::SET, TW::CLR, TW::D, TW::EN}, {TW::Q});
setup_type(TW($adff), {TW::CLK, TW::ARST, TW::D}, {TW::Q});
setup_type(TW($adffe), {TW::CLK, TW::ARST, TW::D, TW::EN}, {TW::Q});
setup_type(TW($aldff), {TW::CLK, TW::ALOAD, TW::AD, TW::D}, {TW::Q});
setup_type(TW($aldffe), {TW::CLK, TW::ALOAD, TW::AD, TW::D, TW::EN}, {TW::Q});
setup_type(TW($sdff), {TW::CLK, TW::SRST, TW::D}, {TW::Q});
setup_type(TW($sdffe), {TW::CLK, TW::SRST, TW::D, TW::EN}, {TW::Q});
setup_type(TW($sdffce), {TW::CLK, TW::SRST, TW::D, TW::EN}, {TW::Q});
setup_type(TW($dlatch), {TW::EN, TW::D}, {TW::Q});
setup_type(TW($adlatch), {TW::EN, TW::D, TW::ARST}, {TW::Q});
setup_type(TW($dlatchsr), {TW::EN, TW::SET, TW::CLR, TW::D}, {TW::Q});
}
void setup_internals_anyinit()
{
setup_type(ID($anyinit), {TW::D}, {TW::Q});
setup_type(TW($anyinit), {TW::D}, {TW::Q});
}
void setup_internals_mem()
{
setup_internals_ff();
setup_type(ID($memrd), {TW::CLK, TW::EN, TW::ADDR}, {TW::DATA});
setup_type(ID($memrd_v2), {TW::CLK, TW::EN, TW::ARST, TW::SRST, TW::ADDR}, {TW::DATA});
setup_type(ID($memwr), {TW::CLK, TW::EN, TW::ADDR, TW::DATA}, pool<TwineRef>());
setup_type(ID($memwr_v2), {TW::CLK, TW::EN, TW::ADDR, TW::DATA}, pool<TwineRef>());
setup_type(ID($meminit), {TW::ADDR, TW::DATA}, pool<TwineRef>());
setup_type(ID($meminit_v2), {TW::ADDR, TW::DATA, TW::EN}, pool<TwineRef>());
setup_type(ID($mem), {TW::RD_CLK, TW::RD_EN, TW::RD_ADDR, TW::WR_CLK, TW::WR_EN, TW::WR_ADDR, TW::WR_DATA}, {TW::RD_DATA});
setup_type(ID($mem_v2), {TW::RD_CLK, TW::RD_EN, TW::RD_ARST, TW::RD_SRST, TW::RD_ADDR, TW::WR_CLK, TW::WR_EN, TW::WR_ADDR, TW::WR_DATA}, {TW::RD_DATA});
setup_type(TW($memrd), {TW::CLK, TW::EN, TW::ADDR}, {TW::DATA});
setup_type(TW($memrd_v2), {TW::CLK, TW::EN, TW::ARST, TW::SRST, TW::ADDR}, {TW::DATA});
setup_type(TW($memwr), {TW::CLK, TW::EN, TW::ADDR, TW::DATA}, pool<TwineRef>());
setup_type(TW($memwr_v2), {TW::CLK, TW::EN, TW::ADDR, TW::DATA}, pool<TwineRef>());
setup_type(TW($meminit), {TW::ADDR, TW::DATA}, pool<TwineRef>());
setup_type(TW($meminit_v2), {TW::ADDR, TW::DATA, TW::EN}, pool<TwineRef>());
setup_type(TW($mem), {TW::RD_CLK, TW::RD_EN, TW::RD_ADDR, TW::WR_CLK, TW::WR_EN, TW::WR_ADDR, TW::WR_DATA}, {TW::RD_DATA});
setup_type(TW($mem_v2), {TW::RD_CLK, TW::RD_EN, TW::RD_ARST, TW::RD_SRST, TW::RD_ADDR, TW::WR_CLK, TW::WR_EN, TW::WR_ADDR, TW::WR_DATA}, {TW::RD_DATA});
setup_type(ID($fsm), {TW::CLK, TW::ARST, TW::CTRL_IN}, {TW::CTRL_OUT});
setup_type(TW($fsm), {TW::CLK, TW::ARST, TW::CTRL_IN}, {TW::CTRL_OUT});
}
void setup_stdcells()
{
setup_stdcells_eval();
setup_type(ID($_TBUF_), {TW::A, TW::E}, {TW::Y});
setup_type(TW($_TBUF_), {TW::A, TW::E}, {TW::Y});
}
void setup_stdcells_eval()
{
setup_type(ID($_BUF_), {TW::A}, {TW::Y}, true);
setup_type(ID($_NOT_), {TW::A}, {TW::Y}, true);
setup_type(ID($_AND_), {TW::A, TW::B}, {TW::Y}, true);
setup_type(ID($_NAND_), {TW::A, TW::B}, {TW::Y}, true);
setup_type(ID($_OR_), {TW::A, TW::B}, {TW::Y}, true);
setup_type(ID($_NOR_), {TW::A, TW::B}, {TW::Y}, true);
setup_type(ID($_XOR_), {TW::A, TW::B}, {TW::Y}, true);
setup_type(ID($_XNOR_), {TW::A, TW::B}, {TW::Y}, true);
setup_type(ID($_ANDNOT_), {TW::A, TW::B}, {TW::Y}, true);
setup_type(ID($_ORNOT_), {TW::A, TW::B}, {TW::Y}, true);
setup_type(ID($_MUX_), {TW::A, TW::B, TW::S}, {TW::Y}, true);
setup_type(ID($_NMUX_), {TW::A, TW::B, TW::S}, {TW::Y}, true);
setup_type(ID($_MUX4_), {TW::A, TW::B, TW::C, TW::D, TW::S, TW::T}, {TW::Y}, true);
setup_type(ID($_MUX8_), {TW::A, TW::B, TW::C, TW::D, TW::E, TW::F, TW::G, TW::H, TW::S, TW::T, TW::U}, {TW::Y}, true);
setup_type(ID($_MUX16_), {TW::A, TW::B, TW::C, TW::D, TW::E, TW::F, TW::G, TW::H, TW::I, TW::J, TW::K, TW::L, TW::M, TW::N, TW::O, TW::P, TW::S, TW::T, TW::U, TW::V}, {TW::Y}, true);
setup_type(ID($_AOI3_), {TW::A, TW::B, TW::C}, {TW::Y}, true);
setup_type(ID($_OAI3_), {TW::A, TW::B, TW::C}, {TW::Y}, true);
setup_type(ID($_AOI4_), {TW::A, TW::B, TW::C, TW::D}, {TW::Y}, true);
setup_type(ID($_OAI4_), {TW::A, TW::B, TW::C, TW::D}, {TW::Y}, true);
setup_type(TW($_BUF_), {TW::A}, {TW::Y}, true);
setup_type(TW($_NOT_), {TW::A}, {TW::Y}, true);
setup_type(TW($_AND_), {TW::A, TW::B}, {TW::Y}, true);
setup_type(TW($_NAND_), {TW::A, TW::B}, {TW::Y}, true);
setup_type(TW($_OR_), {TW::A, TW::B}, {TW::Y}, true);
setup_type(TW($_NOR_), {TW::A, TW::B}, {TW::Y}, true);
setup_type(TW($_XOR_), {TW::A, TW::B}, {TW::Y}, true);
setup_type(TW($_XNOR_), {TW::A, TW::B}, {TW::Y}, true);
setup_type(TW($_ANDNOT_), {TW::A, TW::B}, {TW::Y}, true);
setup_type(TW($_ORNOT_), {TW::A, TW::B}, {TW::Y}, true);
setup_type(TW($_MUX_), {TW::A, TW::B, TW::S}, {TW::Y}, true);
setup_type(TW($_NMUX_), {TW::A, TW::B, TW::S}, {TW::Y}, true);
setup_type(TW($_MUX4_), {TW::A, TW::B, TW::C, TW::D, TW::S, TW::T}, {TW::Y}, true);
setup_type(TW($_MUX8_), {TW::A, TW::B, TW::C, TW::D, TW::E, TW::F, TW::G, TW::H, TW::S, TW::T, TW::U}, {TW::Y}, true);
setup_type(TW($_MUX16_), {TW::A, TW::B, TW::C, TW::D, TW::E, TW::F, TW::G, TW::H, TW::I, TW::J, TW::K, TW::L, TW::M, TW::N, TW::O, TW::P, TW::S, TW::T, TW::U, TW::V}, {TW::Y}, true);
setup_type(TW($_AOI3_), {TW::A, TW::B, TW::C}, {TW::Y}, true);
setup_type(TW($_OAI3_), {TW::A, TW::B, TW::C}, {TW::Y}, true);
setup_type(TW($_AOI4_), {TW::A, TW::B, TW::C, TW::D}, {TW::Y}, true);
setup_type(TW($_OAI4_), {TW::A, TW::B, TW::C, TW::D}, {TW::Y}, true);
}
void setup_stdcells_mem()
@ -230,77 +230,77 @@ struct CellTypes
for (auto c1 : list_np)
for (auto c2 : list_np)
setup_type(stringf("$_SR_%c%c_", c1, c2), {TW::S, TW::R}, {TW::Q});
setup_type(TW($1), {TW::S, TW::R}, {TW::Q});
setup_type(ID($_FF_), {TW::D}, {TW::Q});
setup_type(TW($_FF_), {TW::D}, {TW::Q});
for (auto c1 : list_np)
setup_type(stringf("$_DFF_%c_", c1), {TW::C, TW::D}, {TW::Q});
setup_type(TW($1), {TW::C, TW::D}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
setup_type(stringf("$_DFFE_%c%c_", c1, c2), {TW::C, TW::D, TW::E}, {TW::Q});
setup_type(TW($1), {TW::C, TW::D, TW::E}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_01)
setup_type(stringf("$_DFF_%c%c%c_", c1, c2, c3), {TW::C, TW::R, TW::D}, {TW::Q});
setup_type(TW($1), {TW::C, TW::R, TW::D}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_01)
for (auto c4 : list_np)
setup_type(stringf("$_DFFE_%c%c%c%c_", c1, c2, c3, c4), {TW::C, TW::R, TW::D, TW::E}, {TW::Q});
setup_type(TW($1), {TW::C, TW::R, TW::D, TW::E}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
setup_type(stringf("$_ALDFF_%c%c_", c1, c2), {TW::C, TW::L, TW::AD, TW::D}, {TW::Q});
setup_type(TW($1), {TW::C, TW::L, TW::AD, TW::D}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_np)
setup_type(stringf("$_ALDFFE_%c%c%c_", c1, c2, c3), {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q});
setup_type(TW($1), {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_np)
setup_type(stringf("$_DFFSR_%c%c%c_", c1, c2, c3), {TW::C, TW::S, TW::R, TW::D}, {TW::Q});
setup_type(TW($1), {TW::C, TW::S, TW::R, TW::D}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_np)
for (auto c4 : list_np)
setup_type(stringf("$_DFFSRE_%c%c%c%c_", c1, c2, c3, c4), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q});
setup_type(TW($1), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_01)
setup_type(stringf("$_SDFF_%c%c%c_", c1, c2, c3), {TW::C, TW::R, TW::D}, {TW::Q});
setup_type(TW($1), {TW::C, TW::R, TW::D}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_01)
for (auto c4 : list_np)
setup_type(stringf("$_SDFFE_%c%c%c%c_", c1, c2, c3, c4), {TW::C, TW::R, TW::D, TW::E}, {TW::Q});
setup_type(TW($1), {TW::C, TW::R, TW::D, TW::E}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_01)
for (auto c4 : list_np)
setup_type(stringf("$_SDFFCE_%c%c%c%c_", c1, c2, c3, c4), {TW::C, TW::R, TW::D, TW::E}, {TW::Q});
setup_type(TW($1), {TW::C, TW::R, TW::D, TW::E}, {TW::Q});
for (auto c1 : list_np)
setup_type(stringf("$_DLATCH_%c_", c1), {TW::E, TW::D}, {TW::Q});
setup_type(TW($1), {TW::E, TW::D}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_01)
setup_type(stringf("$_DLATCH_%c%c%c_", c1, c2, c3), {TW::E, TW::R, TW::D}, {TW::Q});
setup_type(TW($1), {TW::E, TW::R, TW::D}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_np)
setup_type(stringf("$_DLATCHSR_%c%c%c_", c1, c2, c3), {TW::E, TW::S, TW::R, TW::D}, {TW::Q});
setup_type(TW($1), {TW::E, TW::S, TW::R, TW::D}, {TW::Q});
}
void clear()
@ -308,24 +308,24 @@ struct CellTypes
cell_types.clear();
}
bool cell_known(RTLIL::IdString type) const
bool cell_known(TwineRef type) const
{
return cell_types.count(type) != 0;
}
bool cell_output(RTLIL::IdString type, TwineRef port) const
bool cell_output(TwineRef type, TwineRef port) const
{
auto it = cell_types.find(type);
return it != cell_types.end() && it->second.outputs.count(port) != 0;
}
bool cell_input(RTLIL::IdString type, TwineRef port) const
bool cell_input(TwineRef type, TwineRef port) const
{
auto it = cell_types.find(type);
return it != cell_types.end() && it->second.inputs.count(port) != 0;
}
RTLIL::PortDir cell_port_dir(RTLIL::IdString type, TwineRef port) const
RTLIL::PortDir cell_port_dir(TwineRef type, TwineRef port) const
{
auto it = cell_types.find(type);
if (it == cell_types.end())
@ -335,7 +335,7 @@ struct CellTypes
return RTLIL::PortDir(is_input + is_output * 2);
}
bool cell_evaluable(RTLIL::IdString type) const
bool cell_evaluable(TwineRef type) const
{
auto it = cell_types.find(type);
return it != cell_types.end() && it->second.is_evaluable;
@ -350,20 +350,20 @@ struct CellTypes
}
// Consider using the ConstEval struct instead if you need named ports and/or multiple outputs
static RTLIL::Const eval(RTLIL::IdString type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len, bool *errp = nullptr)
static RTLIL::Const eval(TwineRef type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len, bool *errp = nullptr)
{
if (type == ID($sshr) && !signed1)
type = ID($shr);
if (type == ID($sshl) && !signed1)
type = ID($shl);
if (type == TW($sshr) && !signed1)
type = TW($shr);
if (type == TW($sshl) && !signed1)
type = TW($shl);
if (type != ID($sshr) && type != ID($sshl) && type != ID($shr) && type != ID($shl) && type != ID($shift) && type != ID($shiftx) &&
type != ID($pos) && type != ID($buf) && type != ID($neg) && type != ID($not)) {
if (type != TW($sshr) && type != TW($sshl) && type != TW($shr) && type != TW($shl) && type != TW($shift) && type != TW($shiftx) &&
type != TW($pos) && type != TW($buf) && type != TW($neg) && type != TW($not)) {
if (!signed1 || !signed2)
signed1 = false, signed2 = false;
}
#define HANDLE_CELL_TYPE(_t) if (type == ID($##_t)) return const_ ## _t(arg1, arg2, signed1, signed2, result_len);
#define HANDLE_CELL_TYPE(_t) if (type == TW($##_t)) return const_ ## _t(arg1, arg2, signed1, signed2, result_len);
HANDLE_CELL_TYPE(not)
HANDLE_CELL_TYPE(and)
HANDLE_CELL_TYPE(or)
@ -403,25 +403,25 @@ struct CellTypes
HANDLE_CELL_TYPE(neg)
#undef HANDLE_CELL_TYPE
if (type.in(ID($_BUF_), ID($buf)))
if (type.in(TW($_BUF_), TW($buf)))
return arg1;
if (type == ID($_NOT_))
if (type == TW($_NOT_))
return eval_not(arg1);
if (type == ID($_AND_))
if (type == TW($_AND_))
return const_and(arg1, arg2, false, false, 1);
if (type == ID($_NAND_))
if (type == TW($_NAND_))
return eval_not(const_and(arg1, arg2, false, false, 1));
if (type == ID($_OR_))
if (type == TW($_OR_))
return const_or(arg1, arg2, false, false, 1);
if (type == ID($_NOR_))
if (type == TW($_NOR_))
return eval_not(const_or(arg1, arg2, false, false, 1));
if (type == ID($_XOR_))
if (type == TW($_XOR_))
return const_xor(arg1, arg2, false, false, 1);
if (type == ID($_XNOR_))
if (type == TW($_XNOR_))
return const_xnor(arg1, arg2, false, false, 1);
if (type == ID($_ANDNOT_))
if (type == TW($_ANDNOT_))
return const_and(arg1, eval_not(arg2), false, false, 1);
if (type == ID($_ORNOT_))
if (type == TW($_ORNOT_))
return const_or(arg1, eval_not(arg2), false, false, 1);
if (errp != nullptr) {
@ -435,34 +435,34 @@ struct CellTypes
// Consider using the ConstEval struct instead if you need named ports and/or multiple outputs
static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool *errp = nullptr)
{
if (cell->type == ID($slice)) {
if (cell->type == TW($slice)) {
int width = cell->parameters.at(ID::Y_WIDTH).as_int();
int offset = cell->parameters.at(ID::OFFSET).as_int();
return arg1.extract(offset, width);
}
if (cell->type == ID($concat)) {
if (cell->type == TW($concat)) {
RTLIL::Const ret = arg1;
ret.append(arg2);
return ret;
}
if (cell->type == ID($bmux))
if (cell->type == TW($bmux))
{
return const_bmux(arg1, arg2);
}
if (cell->type == ID($demux))
if (cell->type == TW($demux))
{
return const_demux(arg1, arg2);
}
if (cell->type == ID($bweqx))
if (cell->type == TW($bweqx))
{
return const_bweqx(arg1, arg2);
}
if (cell->type == ID($lut))
if (cell->type == TW($lut))
{
int width = cell->parameters.at(ID::WIDTH).as_int();
@ -474,7 +474,7 @@ struct CellTypes
return const_bmux(t, arg1);
}
if (cell->type == ID($sop))
if (cell->type == TW($sop))
{
int width = cell->parameters.at(ID::WIDTH).as_int();
int depth = cell->parameters.at(ID::DEPTH).as_int();
@ -515,23 +515,23 @@ struct CellTypes
bool signed_a = cell->parameters.count(ID::A_SIGNED) > 0 && cell->parameters[ID::A_SIGNED].as_bool();
bool signed_b = cell->parameters.count(ID::B_SIGNED) > 0 && cell->parameters[ID::B_SIGNED].as_bool();
int result_len = cell->parameters.count(ID::Y_WIDTH) > 0 ? cell->parameters[ID::Y_WIDTH].as_int() : -1;
return eval(cell->type, arg1, arg2, signed_a, signed_b, result_len, errp);
return eval(cell->type_impl, arg1, arg2, signed_a, signed_b, result_len, errp);
}
// Consider using the ConstEval struct instead if you need named ports and/or multiple outputs
static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, bool *errp = nullptr)
{
if (cell->type.in(ID($mux), ID($_MUX_)))
if (cell->type.in(TW($mux), TW($_MUX_)))
return const_mux(arg1, arg2, arg3);
if (cell->type == ID($_NMUX_))
if (cell->type == TW($_NMUX_))
return eval_not(const_mux(arg1, arg2, arg3));
if (cell->type == ID($bwmux))
if (cell->type == TW($bwmux))
return const_bwmux(arg1, arg2, arg3);
if (cell->type == ID($pmux))
if (cell->type == TW($pmux))
return const_pmux(arg1, arg2, arg3);
if (cell->type == ID($_AOI3_))
if (cell->type == TW($_AOI3_))
return eval_not(const_or(const_and(arg1, arg2, false, false, 1), arg3, false, false, 1));
if (cell->type == ID($_OAI3_))
if (cell->type == TW($_OAI3_))
return eval_not(const_and(const_or(arg1, arg2, false, false, 1), arg3, false, false, 1));
log_assert(arg3.size() == 0);
@ -541,9 +541,9 @@ struct CellTypes
// Consider using the ConstEval struct instead if you need named ports and/or multiple outputs
static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, const RTLIL::Const &arg4, bool *errp = nullptr)
{
if (cell->type == ID($_AOI4_))
if (cell->type == TW($_AOI4_))
return eval_not(const_or(const_and(arg1, arg2, false, false, 1), const_and(arg3, arg4, false, false, 1), false, false, 1));
if (cell->type == ID($_OAI4_))
if (cell->type == TW($_OAI4_))
return eval_not(const_and(const_or(arg1, arg2, false, false, 1), const_or(arg3, arg4, false, false, 1), false, false, 1));
log_assert(arg4.size() == 0);

View file

@ -18,7 +18,7 @@ unsigned int CellCosts::get(RTLIL::Module *mod)
return module_cost;
}
static unsigned int y_coef(RTLIL::IdString type)
static unsigned int y_coef(TwineRef type)
{
if (
// equality
@ -46,7 +46,7 @@ static unsigned int y_coef(RTLIL::IdString type)
return 0;
}
static unsigned int max_inp_coef(RTLIL::IdString type)
static unsigned int max_inp_coef(TwineRef type)
{
if (
// binop reduce
@ -69,7 +69,7 @@ static unsigned int max_inp_coef(RTLIL::IdString type)
return 0;
}
static unsigned int sum_coef(RTLIL::IdString type)
static unsigned int sum_coef(TwineRef type)
{
if (type.in(ID($shr), ID($sshr))) {
// right shift
@ -81,12 +81,12 @@ static unsigned int sum_coef(RTLIL::IdString type)
return 0;
}
static unsigned int is_div_mod(RTLIL::IdString type)
static unsigned int is_div_mod(TwineRef type)
{
return (type == ID($div) || type == ID($divfloor) || type == ID($mod) || type == ID($modfloor));
}
static bool is_free(RTLIL::IdString type)
static bool is_free(TwineRef type)
{
return (
// tags

View file

@ -877,7 +877,7 @@ std::string log_signal(DriveChunkWire const &chunk)
std::string log_signal(DriveChunkPort const &chunk)
{
std::string cell_id = chunk.cell->module->design->twines.str(cell->meta_->name);
std::string cell_id = chunk.cell->module->design->twines.str(chunk.cell->meta_->name);
std::string port_id = chunk.cell->module->design->twines.str(chunk.port);
if (chunk.is_whole())
return stringf("%s <%s>", cell_id, port_id);

View file

@ -661,7 +661,7 @@ Cell *FfData::emit() {
log_assert(!has_srst);
log_assert(!has_sr);
if (is_anyinit) {
cell = module->addAnyinit(name, sig_d, sig_q);
cell = module->addAnyinit(Twine{name.str()}, sig_d, sig_q);
log_assert(val_init.is_fully_undef());
} else {
cell = module->addFf(Twine{name.str()}, sig_d, sig_q);

View file

@ -198,7 +198,7 @@ struct Macc
void to_cell(RTLIL::Cell *cell)
{
cell->type = ID($macc_v2);
cell->type_impl = TW::$macc_v2;
int nproducts = 0, naddends = 0;
Const a_signed, b_signed, a_widths, b_widths, product_negated;

View file

@ -125,7 +125,7 @@ void Mem::emit() {
memid = NEW_ID;
cell = module->addCell(Twine{memid.str()}, ID($mem_v2));
}
cell->type = ID($mem_v2);
cell->type_impl = TW::$mem_v2;
cell->attributes = attributes;
cell->parameters[ID::MEMID] = Const(memid.str());
cell->parameters[ID::WIDTH] = Const(width);
@ -301,7 +301,7 @@ void Mem::emit() {
for (auto &port : rd_ports) {
if (!port.cell)
port.cell = module->addCell(NEW_TWINE, ID($memrd_v2));
port.cell->type = ID($memrd_v2);
port.cell->type_impl = TW::$memrd_v2;
port.cell->attributes = port.attributes;
port.cell->parameters[ID::MEMID] = memid.str();
port.cell->parameters[ID::ABITS] = GetSize(port.addr);
@ -326,7 +326,7 @@ void Mem::emit() {
for (auto &port : wr_ports) {
if (!port.cell)
port.cell = module->addCell(NEW_TWINE, ID($memwr_v2));
port.cell->type = ID($memwr_v2);
port.cell->type_impl = TW::$memwr_v2;
port.cell->attributes = port.attributes;
if (port.cell->parameters.count(ID::PRIORITY))
port.cell->parameters.erase(ID::PRIORITY);
@ -350,7 +350,7 @@ void Mem::emit() {
else {
if (!v2)
init.cell->unsetPort(TW::EN);
init.cell->type = v2 ? ID($meminit_v2) : ID($meminit);
init.cell->type_impl = v2 ? TW::$meminit_v2 : TW::$meminit;
}
init.cell->attributes = init.attributes;
init.cell->parameters[ID::MEMID] = memid.str();

View file

@ -50,67 +50,67 @@ struct CellTableBuilder {
bool is_tristate = false;
};
struct CellInfo {
RTLIL::IdString type;
TwineRef type;
PortList inputs, outputs;
Features features;
};
std::array<CellInfo, MAX_CELLS> cells{};
size_t count = 0;
constexpr void setup_type(RTLIL::IdString type, std::initializer_list<TwineRef> inputs, std::initializer_list<TwineRef> outputs, const Features& features) {
constexpr void setup_type(TwineRef type, std::initializer_list<TwineRef> inputs, std::initializer_list<TwineRef> outputs, const Features& features) {
cells[count++] = {type, PortList(inputs), PortList(outputs), features};
}
constexpr void setup_internals_other()
{
Features features {};
features.is_tristate = true;
setup_type(ID($tribuf), {TW::A, TW::EN}, {TW::Y}, features);
setup_type(TW($tribuf), {TW::A, TW::EN}, {TW::Y}, features);
features = {};
setup_type(ID($assert), {TW::A, TW::EN}, {}, features);
setup_type(ID($assume), {TW::A, TW::EN}, {}, features);
setup_type(ID($live), {TW::A, TW::EN}, {}, features);
setup_type(ID($fair), {TW::A, TW::EN}, {}, features);
setup_type(ID($cover), {TW::A, TW::EN}, {}, features);
setup_type(ID($initstate), {}, {TW::Y}, features);
setup_type(ID($anyconst), {}, {TW::Y}, features);
setup_type(ID($anyseq), {}, {TW::Y}, features);
setup_type(ID($allconst), {}, {TW::Y}, features);
setup_type(ID($allseq), {}, {TW::Y}, features);
setup_type(ID($equiv), {TW::A, TW::B}, {TW::Y}, features);
setup_type(ID($specify2), {TW::EN, TW::SRC, TW::DST}, {}, features);
setup_type(ID($specify3), {TW::EN, TW::SRC, TW::DST, TW::DAT}, {}, features);
setup_type(ID($specrule), {TW::SRC_EN, TW::DST_EN, TW::SRC, TW::DST}, {}, features);
setup_type(ID($print), {TW::EN, TW::ARGS, TW::TRG}, {}, features);
setup_type(ID($check), {TW::A, TW::EN, TW::ARGS, TW::TRG}, {}, features);
setup_type(ID($set_tag), {TW::A, TW::SET, TW::CLR}, {TW::Y}, features);
setup_type(ID($get_tag), {TW::A}, {TW::Y}, features);
setup_type(ID($overwrite_tag), {TW::A, TW::SET, TW::CLR}, {}, features);
setup_type(ID($original_tag), {TW::A}, {TW::Y}, features);
setup_type(ID($future_ff), {TW::A}, {TW::Y}, features);
setup_type(ID($scopeinfo), {}, {}, features);
setup_type(ID($input_port), {}, {TW::Y}, features);
setup_type(ID($output_port), {TW::A}, {}, features);
setup_type(ID($public), {TW::A}, {}, features);
setup_type(ID($connect), {TW::A, TW::B}, {}, features);
setup_type(TW($assert), {TW::A, TW::EN}, {}, features);
setup_type(TW($assume), {TW::A, TW::EN}, {}, features);
setup_type(TW($live), {TW::A, TW::EN}, {}, features);
setup_type(TW($fair), {TW::A, TW::EN}, {}, features);
setup_type(TW($cover), {TW::A, TW::EN}, {}, features);
setup_type(TW($initstate), {}, {TW::Y}, features);
setup_type(TW($anyconst), {}, {TW::Y}, features);
setup_type(TW($anyseq), {}, {TW::Y}, features);
setup_type(TW($allconst), {}, {TW::Y}, features);
setup_type(TW($allseq), {}, {TW::Y}, features);
setup_type(TW($equiv), {TW::A, TW::B}, {TW::Y}, features);
setup_type(TW($specify2), {TW::EN, TW::SRC, TW::DST}, {}, features);
setup_type(TW($specify3), {TW::EN, TW::SRC, TW::DST, TW::DAT}, {}, features);
setup_type(TW($specrule), {TW::SRC_EN, TW::DST_EN, TW::SRC, TW::DST}, {}, features);
setup_type(TW($print), {TW::EN, TW::ARGS, TW::TRG}, {}, features);
setup_type(TW($check), {TW::A, TW::EN, TW::ARGS, TW::TRG}, {}, features);
setup_type(TW($set_tag), {TW::A, TW::SET, TW::CLR}, {TW::Y}, features);
setup_type(TW($get_tag), {TW::A}, {TW::Y}, features);
setup_type(TW($overwrite_tag), {TW::A, TW::SET, TW::CLR}, {}, features);
setup_type(TW($original_tag), {TW::A}, {TW::Y}, features);
setup_type(TW($future_ff), {TW::A}, {TW::Y}, features);
setup_type(TW($scopeinfo), {}, {}, features);
setup_type(TW($input_port), {}, {TW::Y}, features);
setup_type(TW($output_port), {TW::A}, {}, features);
setup_type(TW($public), {TW::A}, {}, features);
setup_type(TW($connect), {TW::A, TW::B}, {}, features);
}
constexpr void setup_internals_eval()
{
Features features {};
features.is_evaluable = true;
std::initializer_list<RTLIL::IdString> unary_ops = {
ID($not), ID($pos), ID($buf), ID($neg),
ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool),
ID($logic_not), ID($slice), ID($lut), ID($sop)
std::initializer_list<TwineRef> unary_ops = {
TW($not), TW($pos), TW($buf), TW($neg),
TW($reduce_and), TW($reduce_or), TW($reduce_xor), TW($reduce_xnor), TW($reduce_bool),
TW($logic_not), TW($slice), TW($lut), TW($sop)
};
std::initializer_list<RTLIL::IdString> binary_ops = {
ID($and), ID($or), ID($xor), ID($xnor),
ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx),
ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt),
ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($divfloor), ID($modfloor), ID($pow),
ID($logic_and), ID($logic_or), ID($concat), ID($macc),
ID($bweqx)
std::initializer_list<TwineRef> binary_ops = {
TW($and), TW($or), TW($xor), TW($xnor),
TW($shl), TW($shr), TW($sshl), TW($sshr), TW($shift), TW($shiftx),
TW($lt), TW($le), TW($eq), TW($ne), TW($eqx), TW($nex), TW($ge), TW($gt),
TW($add), TW($sub), TW($mul), TW($div), TW($mod), TW($divfloor), TW($modfloor), TW($pow),
TW($logic_and), TW($logic_or), TW($concat), TW($macc),
TW($bweqx)
};
for (auto type : unary_ops)
@ -119,43 +119,43 @@ struct CellTableBuilder {
for (auto type : binary_ops)
setup_type(type, {TW::A, TW::B}, {TW::Y}, features);
for (auto type : {ID($mux), ID($pmux), ID($bwmux)})
for (auto type : {TW($mux), TW($pmux), TW($bwmux)})
setup_type(type, {TW::A, TW::B, TW::S}, {TW::Y}, features);
for (auto type : {ID($bmux), ID($demux)})
for (auto type : {TW($bmux), TW($demux)})
setup_type(type, {TW::A, TW::S}, {TW::Y}, features);
setup_type(ID($lcu), {TW::P, TW::G, TW::CI}, {TW::CO}, features);
setup_type(ID($alu), {TW::A, TW::B, TW::CI, TW::BI}, {TW::X, TW::Y, TW::CO}, features);
setup_type(ID($macc_v2), {TW::A, TW::B, TW::C}, {TW::Y}, features);
setup_type(ID($fa), {TW::A, TW::B, TW::C}, {TW::X, TW::Y}, features);
setup_type(TW($lcu), {TW::P, TW::G, TW::CI}, {TW::CO}, features);
setup_type(TW($alu), {TW::A, TW::B, TW::CI, TW::BI}, {TW::X, TW::Y, TW::CO}, features);
setup_type(TW($macc_v2), {TW::A, TW::B, TW::C}, {TW::Y}, features);
setup_type(TW($fa), {TW::A, TW::B, TW::C}, {TW::X, TW::Y}, features);
}
constexpr void setup_internals_ff()
{
Features features {};
features.is_ff = true;
setup_type(ID($sr), {TW::SET, TW::CLR}, {TW::Q}, features);
setup_type(ID($ff), {TW::D}, {TW::Q}, features);
setup_type(ID($dff), {TW::CLK, TW::D}, {TW::Q}, features);
setup_type(ID($dffe), {TW::CLK, TW::EN, TW::D}, {TW::Q}, features);
setup_type(ID($dffsr), {TW::CLK, TW::SET, TW::CLR, TW::D}, {TW::Q}, features);
setup_type(ID($dffsre), {TW::CLK, TW::SET, TW::CLR, TW::D, TW::EN}, {TW::Q}, features);
setup_type(ID($adff), {TW::CLK, TW::ARST, TW::D}, {TW::Q}, features);
setup_type(ID($adffe), {TW::CLK, TW::ARST, TW::D, TW::EN}, {TW::Q}, features);
setup_type(ID($aldff), {TW::CLK, TW::ALOAD, TW::AD, TW::D}, {TW::Q}, features);
setup_type(ID($aldffe), {TW::CLK, TW::ALOAD, TW::AD, TW::D, TW::EN}, {TW::Q}, features);
setup_type(ID($sdff), {TW::CLK, TW::SRST, TW::D}, {TW::Q}, features);
setup_type(ID($sdffe), {TW::CLK, TW::SRST, TW::D, TW::EN}, {TW::Q}, features);
setup_type(ID($sdffce), {TW::CLK, TW::SRST, TW::D, TW::EN}, {TW::Q}, features);
setup_type(ID($dlatch), {TW::EN, TW::D}, {TW::Q}, features);
setup_type(ID($adlatch), {TW::EN, TW::D, TW::ARST}, {TW::Q}, features);
setup_type(ID($dlatchsr), {TW::EN, TW::SET, TW::CLR, TW::D}, {TW::Q}, features);
setup_type(TW($sr), {TW::SET, TW::CLR}, {TW::Q}, features);
setup_type(TW($ff), {TW::D}, {TW::Q}, features);
setup_type(TW($dff), {TW::CLK, TW::D}, {TW::Q}, features);
setup_type(TW($dffe), {TW::CLK, TW::EN, TW::D}, {TW::Q}, features);
setup_type(TW($dffsr), {TW::CLK, TW::SET, TW::CLR, TW::D}, {TW::Q}, features);
setup_type(TW($dffsre), {TW::CLK, TW::SET, TW::CLR, TW::D, TW::EN}, {TW::Q}, features);
setup_type(TW($adff), {TW::CLK, TW::ARST, TW::D}, {TW::Q}, features);
setup_type(TW($adffe), {TW::CLK, TW::ARST, TW::D, TW::EN}, {TW::Q}, features);
setup_type(TW($aldff), {TW::CLK, TW::ALOAD, TW::AD, TW::D}, {TW::Q}, features);
setup_type(TW($aldffe), {TW::CLK, TW::ALOAD, TW::AD, TW::D, TW::EN}, {TW::Q}, features);
setup_type(TW($sdff), {TW::CLK, TW::SRST, TW::D}, {TW::Q}, features);
setup_type(TW($sdffe), {TW::CLK, TW::SRST, TW::D, TW::EN}, {TW::Q}, features);
setup_type(TW($sdffce), {TW::CLK, TW::SRST, TW::D, TW::EN}, {TW::Q}, features);
setup_type(TW($dlatch), {TW::EN, TW::D}, {TW::Q}, features);
setup_type(TW($adlatch), {TW::EN, TW::D, TW::ARST}, {TW::Q}, features);
setup_type(TW($dlatchsr), {TW::EN, TW::SET, TW::CLR, TW::D}, {TW::Q}, features);
}
constexpr void setup_internals_anyinit()
{
Features features {};
features.is_anyinit = true;
setup_type(ID($anyinit), {TW::D}, {TW::Q}, features);
setup_type(TW($anyinit), {TW::D}, {TW::Q}, features);
}
constexpr void setup_internals_mem_noff()
{
@ -163,24 +163,24 @@ struct CellTableBuilder {
features.is_mem_noff = true;
// NOT setup_internals_ff()
setup_type(ID($memrd), {TW::CLK, TW::EN, TW::ADDR}, {TW::DATA}, features);
setup_type(ID($memrd_v2), {TW::CLK, TW::EN, TW::ARST, TW::SRST, TW::ADDR}, {TW::DATA}, features);
setup_type(ID($memwr), {TW::CLK, TW::EN, TW::ADDR, TW::DATA}, {}, features);
setup_type(ID($memwr_v2), {TW::CLK, TW::EN, TW::ADDR, TW::DATA}, {}, features);
setup_type(ID($meminit), {TW::ADDR, TW::DATA}, {}, features);
setup_type(ID($meminit_v2), {TW::ADDR, TW::DATA, TW::EN}, {}, features);
setup_type(ID($mem), {TW::RD_CLK, TW::RD_EN, TW::RD_ADDR, TW::WR_CLK, TW::WR_EN, TW::WR_ADDR, TW::WR_DATA}, {TW::RD_DATA}, features);
setup_type(ID($mem_v2), {TW::RD_CLK, TW::RD_EN, TW::RD_ARST, TW::RD_SRST, TW::RD_ADDR, TW::WR_CLK, TW::WR_EN, TW::WR_ADDR, TW::WR_DATA}, {TW::RD_DATA}, features);
setup_type(TW($memrd), {TW::CLK, TW::EN, TW::ADDR}, {TW::DATA}, features);
setup_type(TW($memrd_v2), {TW::CLK, TW::EN, TW::ARST, TW::SRST, TW::ADDR}, {TW::DATA}, features);
setup_type(TW($memwr), {TW::CLK, TW::EN, TW::ADDR, TW::DATA}, {}, features);
setup_type(TW($memwr_v2), {TW::CLK, TW::EN, TW::ADDR, TW::DATA}, {}, features);
setup_type(TW($meminit), {TW::ADDR, TW::DATA}, {}, features);
setup_type(TW($meminit_v2), {TW::ADDR, TW::DATA, TW::EN}, {}, features);
setup_type(TW($mem), {TW::RD_CLK, TW::RD_EN, TW::RD_ADDR, TW::WR_CLK, TW::WR_EN, TW::WR_ADDR, TW::WR_DATA}, {TW::RD_DATA}, features);
setup_type(TW($mem_v2), {TW::RD_CLK, TW::RD_EN, TW::RD_ARST, TW::RD_SRST, TW::RD_ADDR, TW::WR_CLK, TW::WR_EN, TW::WR_ADDR, TW::WR_DATA}, {TW::RD_DATA}, features);
// What?
setup_type(ID($fsm), {TW::CLK, TW::ARST, TW::CTRL_IN}, {TW::CTRL_OUT}, features);
setup_type(TW($fsm), {TW::CLK, TW::ARST, TW::CTRL_IN}, {TW::CTRL_OUT}, features);
}
constexpr void setup_stdcells_tristate()
{
Features features {};
features.is_stdcell = true;
features.is_tristate = true;
setup_type(ID($_TBUF_), {TW::A, TW::E}, {TW::Y}, features);
setup_type(TW($_TBUF_), {TW::A, TW::E}, {TW::Y}, features);
}
constexpr void setup_stdcells_eval()
@ -188,25 +188,25 @@ struct CellTableBuilder {
Features features {};
features.is_stdcell = true;
features.is_evaluable = true;
setup_type(ID($_BUF_), {TW::A}, {TW::Y}, features);
setup_type(ID($_NOT_), {TW::A}, {TW::Y}, features);
setup_type(ID($_AND_), {TW::A, TW::B}, {TW::Y}, features);
setup_type(ID($_NAND_), {TW::A, TW::B}, {TW::Y}, features);
setup_type(ID($_OR_), {TW::A, TW::B}, {TW::Y}, features);
setup_type(ID($_NOR_), {TW::A, TW::B}, {TW::Y}, features);
setup_type(ID($_XOR_), {TW::A, TW::B}, {TW::Y}, features);
setup_type(ID($_XNOR_), {TW::A, TW::B}, {TW::Y}, features);
setup_type(ID($_ANDNOT_), {TW::A, TW::B}, {TW::Y}, features);
setup_type(ID($_ORNOT_), {TW::A, TW::B}, {TW::Y}, features);
setup_type(ID($_MUX_), {TW::A, TW::B, TW::S}, {TW::Y}, features);
setup_type(ID($_NMUX_), {TW::A, TW::B, TW::S}, {TW::Y}, features);
setup_type(ID($_MUX4_), {TW::A, TW::B, TW::C, TW::D, TW::S, TW::T}, {TW::Y}, features);
setup_type(ID($_MUX8_), {TW::A, TW::B, TW::C, TW::D, TW::E, TW::F, TW::G, TW::H, TW::S, TW::T, TW::U}, {TW::Y}, features);
setup_type(ID($_MUX16_), {TW::A, TW::B, TW::C, TW::D, TW::E, TW::F, TW::G, TW::H, TW::I, TW::J, TW::K, TW::L, TW::M, TW::N, TW::O, TW::P, TW::S, TW::T, TW::U, TW::V}, {TW::Y}, features);
setup_type(ID($_AOI3_), {TW::A, TW::B, TW::C}, {TW::Y}, features);
setup_type(ID($_OAI3_), {TW::A, TW::B, TW::C}, {TW::Y}, features);
setup_type(ID($_AOI4_), {TW::A, TW::B, TW::C, TW::D}, {TW::Y}, features);
setup_type(ID($_OAI4_), {TW::A, TW::B, TW::C, TW::D}, {TW::Y}, features);
setup_type(TW($_BUF_), {TW::A}, {TW::Y}, features);
setup_type(TW($_NOT_), {TW::A}, {TW::Y}, features);
setup_type(TW($_AND_), {TW::A, TW::B}, {TW::Y}, features);
setup_type(TW($_NAND_), {TW::A, TW::B}, {TW::Y}, features);
setup_type(TW($_OR_), {TW::A, TW::B}, {TW::Y}, features);
setup_type(TW($_NOR_), {TW::A, TW::B}, {TW::Y}, features);
setup_type(TW($_XOR_), {TW::A, TW::B}, {TW::Y}, features);
setup_type(TW($_XNOR_), {TW::A, TW::B}, {TW::Y}, features);
setup_type(TW($_ANDNOT_), {TW::A, TW::B}, {TW::Y}, features);
setup_type(TW($_ORNOT_), {TW::A, TW::B}, {TW::Y}, features);
setup_type(TW($_MUX_), {TW::A, TW::B, TW::S}, {TW::Y}, features);
setup_type(TW($_NMUX_), {TW::A, TW::B, TW::S}, {TW::Y}, features);
setup_type(TW($_MUX4_), {TW::A, TW::B, TW::C, TW::D, TW::S, TW::T}, {TW::Y}, features);
setup_type(TW($_MUX8_), {TW::A, TW::B, TW::C, TW::D, TW::E, TW::F, TW::G, TW::H, TW::S, TW::T, TW::U}, {TW::Y}, features);
setup_type(TW($_MUX16_), {TW::A, TW::B, TW::C, TW::D, TW::E, TW::F, TW::G, TW::H, TW::I, TW::J, TW::K, TW::L, TW::M, TW::N, TW::O, TW::P, TW::S, TW::T, TW::U, TW::V}, {TW::Y}, features);
setup_type(TW($_AOI3_), {TW::A, TW::B, TW::C}, {TW::Y}, features);
setup_type(TW($_OAI3_), {TW::A, TW::B, TW::C}, {TW::Y}, features);
setup_type(TW($_AOI4_), {TW::A, TW::B, TW::C, TW::D}, {TW::Y}, features);
setup_type(TW($_OAI4_), {TW::A, TW::B, TW::C, TW::D}, {TW::Y}, features);
}
constexpr void setup_stdcells_ff() {
@ -217,193 +217,193 @@ struct CellTableBuilder {
// for (auto c1 : list_np)
// for (auto c2 : list_np)
// setup_type(std::string("$_SR_") + c1 + c2 + "_", {TW::S, TW::R}, {TW::Q}, features);
setup_type(ID($_SR_NN_), {TW::S, TW::R}, {TW::Q}, features);
setup_type(ID($_SR_NP_), {TW::S, TW::R}, {TW::Q}, features);
setup_type(ID($_SR_PN_), {TW::S, TW::R}, {TW::Q}, features);
setup_type(ID($_SR_PP_), {TW::S, TW::R}, {TW::Q}, features);
setup_type(TW($_SR_NN_), {TW::S, TW::R}, {TW::Q}, features);
setup_type(TW($_SR_NP_), {TW::S, TW::R}, {TW::Q}, features);
setup_type(TW($_SR_PN_), {TW::S, TW::R}, {TW::Q}, features);
setup_type(TW($_SR_PP_), {TW::S, TW::R}, {TW::Q}, features);
setup_type(ID($_FF_), {TW::D}, {TW::Q}, features);
setup_type(TW($_FF_), {TW::D}, {TW::Q}, features);
// for (auto c1 : list_np)
// setup_type(std::string("$_DFF_") + c1 + "_", {TW::C, TW::D}, {TW::Q}, features);
setup_type(ID::$_DFF_N_, {TW::C, TW::D}, {TW::Q}, features);
setup_type(ID::$_DFF_P_, {TW::C, TW::D}, {TW::Q}, features);
setup_type(TW($_DFF_N_), {TW::C, TW::D}, {TW::Q}, features);
setup_type(TW($_DFF_P_), {TW::C, TW::D}, {TW::Q}, features);
// for (auto c1 : list_np)
// for (auto c2 : list_np)
// setup_type(std::string("$_DFFE_") + c1 + c2 + "_", {TW::C, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID::$_DFFE_NN_, {TW::C, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID::$_DFFE_NP_, {TW::C, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID::$_DFFE_PN_, {TW::C, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID::$_DFFE_PP_, {TW::C, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFE_NN_), {TW::C, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFE_NP_), {TW::C, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFE_PN_), {TW::C, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFE_PP_), {TW::C, TW::D, TW::E}, {TW::Q}, features);
// for (auto c1 : list_np)
// for (auto c2 : list_np)
// for (auto c3 : list_01)
// setup_type(std::string("$_DFF_") + c1 + c2 + c3 + "_", {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DFF_NN0_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DFF_NN1_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DFF_NP0_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DFF_NP1_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DFF_PN0_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DFF_PN1_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DFF_PP0_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DFF_PP1_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DFF_NN0_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DFF_NN1_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DFF_NP0_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DFF_NP1_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DFF_PN0_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DFF_PN1_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DFF_PP0_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DFF_PP1_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
// for (auto c1 : list_np)
// for (auto c2 : list_np)
// for (auto c3 : list_01)
// for (auto c4 : list_np)
// setup_type(std::string("$_DFFE_") + c1 + c2 + c3 + c4 + "_", {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFE_NN0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFE_NN0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFE_NN1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFE_NN1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFE_NP0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFE_NP0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFE_NP1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFE_NP1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFE_PN0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFE_PN0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFE_PN1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFE_PN1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFE_PP0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFE_PP0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFE_PP1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFE_PP1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFE_NN0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFE_NN0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFE_NN1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFE_NN1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFE_NP0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFE_NP0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFE_NP1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFE_NP1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFE_PN0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFE_PN0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFE_PN1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFE_PN1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFE_PP0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFE_PP0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFE_PP1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFE_PP1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
// for (auto c1 : list_np)
// for (auto c2 : list_np)
// setup_type(std::string("$_ALDFF_") + c1 + c2 + "_", {TW::C, TW::L, TW::AD, TW::D}, {TW::Q}, features);
setup_type(ID($_ALDFF_NN_), {TW::C, TW::L, TW::AD, TW::D}, {TW::Q}, features);
setup_type(ID($_ALDFF_NP_), {TW::C, TW::L, TW::AD, TW::D}, {TW::Q}, features);
setup_type(ID($_ALDFF_PN_), {TW::C, TW::L, TW::AD, TW::D}, {TW::Q}, features);
setup_type(ID($_ALDFF_PP_), {TW::C, TW::L, TW::AD, TW::D}, {TW::Q}, features);
setup_type(TW($_ALDFF_NN_), {TW::C, TW::L, TW::AD, TW::D}, {TW::Q}, features);
setup_type(TW($_ALDFF_NP_), {TW::C, TW::L, TW::AD, TW::D}, {TW::Q}, features);
setup_type(TW($_ALDFF_PN_), {TW::C, TW::L, TW::AD, TW::D}, {TW::Q}, features);
setup_type(TW($_ALDFF_PP_), {TW::C, TW::L, TW::AD, TW::D}, {TW::Q}, features);
// for (auto c1 : list_np)
// for (auto c2 : list_np)
// for (auto c3 : list_np)
// setup_type(std::string("$_ALDFFE_") + c1 + c2 + c3 + "_", {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_ALDFFE_NNN_), {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_ALDFFE_NNP_), {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_ALDFFE_NPN_), {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_ALDFFE_NPP_), {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_ALDFFE_PNN_), {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_ALDFFE_PNP_), {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_ALDFFE_PPN_), {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_ALDFFE_PPP_), {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_ALDFFE_NNN_), {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_ALDFFE_NNP_), {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_ALDFFE_NPN_), {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_ALDFFE_NPP_), {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_ALDFFE_PNN_), {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_ALDFFE_PNP_), {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_ALDFFE_PPN_), {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_ALDFFE_PPP_), {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q}, features);
// for (auto c1 : list_np)
// for (auto c2 : list_np)
// for (auto c3 : list_np)
// setup_type(std::string("$_DFFSR_") + c1 + c2 + c3 + "_", {TW::C, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DFFSR_NNN_), {TW::C, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DFFSR_NNP_), {TW::C, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DFFSR_NPN_), {TW::C, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DFFSR_NPP_), {TW::C, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DFFSR_PNN_), {TW::C, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DFFSR_PNP_), {TW::C, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DFFSR_PPN_), {TW::C, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DFFSR_PPP_), {TW::C, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DFFSR_NNN_), {TW::C, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DFFSR_NNP_), {TW::C, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DFFSR_NPN_), {TW::C, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DFFSR_NPP_), {TW::C, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DFFSR_PNN_), {TW::C, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DFFSR_PNP_), {TW::C, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DFFSR_PPN_), {TW::C, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DFFSR_PPP_), {TW::C, TW::S, TW::R, TW::D}, {TW::Q}, features);
// for (auto c1 : list_np)
// for (auto c2 : list_np)
// for (auto c3 : list_np)
// for (auto c4 : list_np)
// setup_type(std::string("$_DFFSRE_") + c1 + c2 + c3 + c4 + "_", {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFSRE_NNNN_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFSRE_NNNP_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFSRE_NNPN_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFSRE_NNPP_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFSRE_NPNN_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFSRE_NPNP_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFSRE_NPPN_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFSRE_NPPP_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFSRE_PNNN_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFSRE_PNNP_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFSRE_PNPN_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFSRE_PNPP_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFSRE_PPNN_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFSRE_PPNP_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFSRE_PPPN_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_DFFSRE_PPPP_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFSRE_NNNN_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFSRE_NNNP_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFSRE_NNPN_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFSRE_NNPP_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFSRE_NPNN_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFSRE_NPNP_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFSRE_NPPN_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFSRE_NPPP_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFSRE_PNNN_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFSRE_PNNP_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFSRE_PNPN_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFSRE_PNPP_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFSRE_PPNN_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFSRE_PPNP_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFSRE_PPPN_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_DFFSRE_PPPP_), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q}, features);
// for (auto c1 : list_np)
// for (auto c2 : list_np)
// for (auto c3 : list_01)
// setup_type(std::string("$_SDFF_") + c1 + c2 + c3 + "_", {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_SDFF_NN0_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_SDFF_NN1_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_SDFF_NP0_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_SDFF_NP1_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_SDFF_PN0_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_SDFF_PN1_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_SDFF_PP0_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_SDFF_PP1_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_SDFF_NN0_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_SDFF_NN1_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_SDFF_NP0_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_SDFF_NP1_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_SDFF_PN0_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_SDFF_PN1_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_SDFF_PP0_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_SDFF_PP1_), {TW::C, TW::R, TW::D}, {TW::Q}, features);
// for (auto c1 : list_np)
// for (auto c2 : list_np)
// for (auto c3 : list_01)
// for (auto c4 : list_np)
// setup_type(std::string("$_SDFFE_") + c1 + c2 + c3 + c4 + "_", {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFE_NN0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFE_NN0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFE_NN1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFE_NN1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFE_NP0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFE_NP0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFE_NP1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFE_NP1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFE_PN0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFE_PN0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFE_PN1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFE_PN1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFE_PP0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFE_PP0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFE_PP1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFE_PP1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFE_NN0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFE_NN0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFE_NN1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFE_NN1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFE_NP0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFE_NP0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFE_NP1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFE_NP1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFE_PN0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFE_PN0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFE_PN1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFE_PN1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFE_PP0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFE_PP0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFE_PP1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFE_PP1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
// for (auto c1 : list_np)
// for (auto c2 : list_np)
// for (auto c3 : list_01)
// for (auto c4 : list_np)
// setup_type(std::string("$_SDFFCE_") + c1 + c2 + c3 + c4 + "_", {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFCE_NN0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFCE_NN0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFCE_NN1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFCE_NN1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFCE_NP0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFCE_NP0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFCE_NP1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFCE_NP1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFCE_PN0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFCE_PN0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFCE_PN1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFCE_PN1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFCE_PP0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFCE_PP0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFCE_PP1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(ID($_SDFFCE_PP1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFCE_NN0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFCE_NN0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFCE_NN1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFCE_NN1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFCE_NP0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFCE_NP0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFCE_NP1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFCE_NP1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFCE_PN0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFCE_PN0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFCE_PN1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFCE_PN1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFCE_PP0N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFCE_PP0P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFCE_PP1N_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
setup_type(TW($_SDFFCE_PP1P_), {TW::C, TW::R, TW::D, TW::E}, {TW::Q}, features);
// for (auto c1 : list_np)
// setup_type(std::string("$_DLATCH_") + c1 + "_", {TW::E, TW::D}, {TW::Q}, features);
setup_type(ID($_DLATCH_N_), {TW::E, TW::D}, {TW::Q}, features);
setup_type(ID($_DLATCH_P_), {TW::E, TW::D}, {TW::Q}, features);
setup_type(TW($_DLATCH_N_), {TW::E, TW::D}, {TW::Q}, features);
setup_type(TW($_DLATCH_P_), {TW::E, TW::D}, {TW::Q}, features);
// for (auto c1 : list_np)
// for (auto c2 : list_np)
// for (auto c3 : list_01)
// setup_type(std::string("$_DLATCH_") + c1 + c2 + c3 + "_", {TW::E, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DLATCH_NN0_), {TW::E, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DLATCH_NN1_), {TW::E, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DLATCH_NP0_), {TW::E, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DLATCH_NP1_), {TW::E, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DLATCH_PN0_), {TW::E, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DLATCH_PN1_), {TW::E, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DLATCH_PP0_), {TW::E, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DLATCH_PP1_), {TW::E, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DLATCH_NN0_), {TW::E, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DLATCH_NN1_), {TW::E, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DLATCH_NP0_), {TW::E, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DLATCH_NP1_), {TW::E, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DLATCH_PN0_), {TW::E, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DLATCH_PN1_), {TW::E, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DLATCH_PP0_), {TW::E, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DLATCH_PP1_), {TW::E, TW::R, TW::D}, {TW::Q}, features);
// for (auto c1 : list_np)
// for (auto c2 : list_np)
// for (auto c3 : list_np)
// setup_type(std::string("$_DLATCHSR_") + c1 + c2 + c3 + "_", {TW::E, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DLATCHSR_NNN_), {TW::E, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DLATCHSR_NNP_), {TW::E, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DLATCHSR_NPN_), {TW::E, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DLATCHSR_NPP_), {TW::E, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DLATCHSR_PNN_), {TW::E, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DLATCHSR_PNP_), {TW::E, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DLATCHSR_PPN_), {TW::E, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(ID($_DLATCHSR_PPP_), {TW::E, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DLATCHSR_NNN_), {TW::E, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DLATCHSR_NNP_), {TW::E, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DLATCHSR_NPN_), {TW::E, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DLATCHSR_NPP_), {TW::E, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DLATCHSR_PNN_), {TW::E, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DLATCHSR_PNP_), {TW::E, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DLATCHSR_PPN_), {TW::E, TW::S, TW::R, TW::D}, {TW::Q}, features);
setup_type(TW($_DLATCHSR_PPP_), {TW::E, TW::S, TW::R, TW::D}, {TW::Q}, features);
}
constexpr CellTableBuilder() {
setup_internals_other();
@ -423,8 +423,8 @@ constexpr CellTableBuilder builder {};
struct PortInfo {
struct PortLists {
std::array<CellTableBuilder::PortList, MAX_CELLS> data{};
constexpr CellTableBuilder::PortList operator()(IdString type) const {
return data[type.index_];
constexpr CellTableBuilder::PortList operator()(TwineRef type) const {
return data[type];
}
constexpr CellTableBuilder::PortList& operator[](size_t idx) {
return data[idx];
@ -436,7 +436,7 @@ struct PortInfo {
constexpr PortInfo() {
for (size_t i = 0; i < builder.count; ++i) {
auto& cell = builder.cells[i];
size_t idx = cell.type.index_;
size_t idx = cell.type;
inputs[idx] = cell.inputs;
outputs[idx] = cell.outputs;
}
@ -446,8 +446,8 @@ struct PortInfo {
struct Categories {
struct Category {
std::array<bool, MAX_CELLS> data{};
constexpr bool operator()(IdString type) const {
size_t idx = type.index_;
constexpr bool operator()(TwineRef type) const {
size_t idx = type;
if (idx >= MAX_CELLS)
return false;
return data[idx];
@ -479,7 +479,7 @@ struct Categories {
constexpr Categories() {
for (size_t i = 0; i < builder.count; ++i) {
auto& cell = builder.cells[i];
size_t idx = cell.type.index_;
size_t idx = cell.type;
is_known.set(idx);
is_evaluable.set(idx, cell.features.is_evaluable);
is_combinatorial.set(idx, cell.features.is_combinatorial);
@ -537,17 +537,17 @@ namespace Compat {
};
namespace {
static_assert(categories.is_evaluable(ID($and)));
static_assert(!categories.is_ff(ID($and)));
static_assert(Categories::join(categories.is_evaluable, categories.is_ff)(ID($and)));
static_assert(Categories::join(categories.is_evaluable, categories.is_ff)(ID($dffsr)));
static_assert(!Categories::join(categories.is_evaluable, categories.is_ff)(ID($anyinit)));
static_assert(categories.is_evaluable(TW($and)));
static_assert(!categories.is_ff(TW($and)));
static_assert(Categories::join(categories.is_evaluable, categories.is_ff)(TW($and)));
static_assert(Categories::join(categories.is_evaluable, categories.is_ff)(TW($dffsr)));
static_assert(!Categories::join(categories.is_evaluable, categories.is_ff)(TW($anyinit)));
}
};
struct NewCellType {
RTLIL::IdString type;
TwineRef type;
pool<TwineRef> inputs, outputs;
bool is_evaluable;
bool is_combinatorial;
@ -561,7 +561,7 @@ struct NewCellTypes {
}
};
StaticCellTypes::Categories::Category static_cell_types = StaticCellTypes::categories.empty;
std::unordered_map<RTLIL::IdString, NewCellType, IdStringHash> custom_cell_types {};
std::unordered_map<TwineRef, NewCellType, IdStringHash> custom_cell_types {};
NewCellTypes() {
static_cell_types = StaticCellTypes::categories.empty;
@ -590,10 +590,10 @@ struct NewCellTypes {
if (wire->port_output)
outputs.insert(wire->meta_->name);
}
setup_type(RTLIL::IdString(module->design->twines.str(module->meta_->name)), inputs, outputs);
setup_type(module->meta_->name, inputs, outputs);
}
void setup_type(RTLIL::IdString type, const pool<TwineRef> &inputs, const pool<TwineRef> &outputs, bool is_evaluable = false, bool is_combinatorial = false, bool is_synthesizable = false) {
void setup_type(TwineRef type, const pool<TwineRef> &inputs, const pool<TwineRef> &outputs, bool is_evaluable = false, bool is_combinatorial = false, bool is_synthesizable = false) {
NewCellType ct = {type, inputs, outputs, is_evaluable, is_combinatorial, is_synthesizable};
custom_cell_types[ct.type] = ct;
}
@ -603,11 +603,11 @@ struct NewCellTypes {
static_cell_types = StaticCellTypes::categories.empty;
}
bool cell_known(const RTLIL::IdString &type) const {
bool cell_known(TwineRef type) const {
return static_cell_types(type) || custom_cell_types.count(type) != 0;
}
bool cell_output(const RTLIL::IdString &type, TwineRef port) const
bool cell_output(TwineRef type, TwineRef port) const
{
// TODO refactor
if (static_cell_types(type) && StaticCellTypes::port_info.outputs(type).contains(port)) {
@ -617,7 +617,7 @@ struct NewCellTypes {
return it != custom_cell_types.end() && it->second.outputs.count(port) != 0;
}
bool cell_input(const RTLIL::IdString &type, TwineRef port) const
bool cell_input(TwineRef type, TwineRef port) const
{
if (static_cell_types(type) && StaticCellTypes::port_info.inputs(type).contains(port)) {
return true;
@ -626,7 +626,7 @@ struct NewCellTypes {
return it != custom_cell_types.end() && it->second.inputs.count(port) != 0;
}
RTLIL::PortDir cell_port_dir(RTLIL::IdString type, TwineRef port) const
RTLIL::PortDir cell_port_dir(TwineRef type, TwineRef port) const
{
bool is_input, is_output;
if (static_cell_types(type)) {
@ -641,7 +641,7 @@ struct NewCellTypes {
}
return RTLIL::PortDir(is_input + is_output * 2);
}
bool cell_evaluable(const RTLIL::IdString &type) const
bool cell_evaluable(TwineRef type) const
{
return static_cell_types(type) && StaticCellTypes::categories.is_evaluable(type);
}

File diff suppressed because it is too large Load diff

View file

@ -133,6 +133,7 @@ namespace RTLIL
struct ModuleNameMasq;
struct WireNameMasq;
struct CellNameMasq;
struct CellTypeMasq;
typedef std::pair<SigSpec, SigSpec> SigSig;
struct PortBit;
@ -590,6 +591,9 @@ public:
}
};
inline bool operator==(TwineRef a, RTLIL::IdString b) { return a.untag().value == (size_t)(unsigned)b.index_; }
inline bool operator==(RTLIL::IdString a, TwineRef b) { return b == a; }
struct RTLIL::OwningIdString : public RTLIL::IdString {
inline OwningIdString() { }
inline OwningIdString(const OwningIdString &str) : IdString(str) { get_reference(); }
@ -776,7 +780,7 @@ namespace RTLIL {
extern dict<std::string, std::string> constpad;
[[deprecated("use StaticCellTypes::categories.is_ff() instead")]]
const pool<IdString> &builtin_ff_cell_types();
const pool<TwineRef> &builtin_ff_cell_types();
static inline std::string escape_id(const std::string &str) {
if (str.size() > 0 && str[0] != '\\' && str[0] != '$')
@ -1337,11 +1341,16 @@ struct RTLIL::WireNameMasq {
WireNameMasq &operator=(WireNameMasq &&) = delete;
// Materialise → IdString. Slow path; intended for plugin code.
operator RTLIL::IdString() const;
// Tagged name handle (Twine::Null when unnamed).
TwineRef ref() const;
// Escaped form ('\'-prefixed when public) / bare content.
std::string escaped() const;
std::string unescaped() const;
bool isPublic() const { return twine_is_public(ref()); }
bool empty() const { return RTLIL::IdString(*this).empty(); }
std::string str() const { return RTLIL::IdString(*this).str(); }
std::string str() const { return escaped(); }
const char *c_str() const { return RTLIL::IdString(*this).c_str(); }
bool isPublic() const { return RTLIL::IdString(*this).isPublic(); }
std::string unescape() const { return RTLIL::IdString(*this).unescape(); }
std::string unescape() const { return unescaped(); }
bool begins_with(const char *s) const { return RTLIL::IdString(*this).begins_with(s); }
bool ends_with(const char *s) const { return RTLIL::IdString(*this).ends_with(s); }
template <typename... Ts> bool in(Ts &&...args) const {
@ -1376,11 +1385,16 @@ struct RTLIL::CellNameMasq {
CellNameMasq &operator=(const CellNameMasq &) = delete;
CellNameMasq &operator=(CellNameMasq &&) = delete;
operator RTLIL::IdString() const;
// Tagged name handle (Twine::Null when unnamed).
TwineRef ref() const;
// Escaped form ('\'-prefixed when public) / bare content.
std::string escaped() const;
std::string unescaped() const;
bool isPublic() const { return twine_is_public(ref()); }
bool empty() const { return RTLIL::IdString(*this).empty(); }
std::string str() const { return RTLIL::IdString(*this).str(); }
std::string str() const { return escaped(); }
const char *c_str() const { return RTLIL::IdString(*this).c_str(); }
bool isPublic() const { return RTLIL::IdString(*this).isPublic(); }
std::string unescape() const { return RTLIL::IdString(*this).unescape(); }
std::string unescape() const { return unescaped(); }
bool begins_with(const char *s) const { return RTLIL::IdString(*this).begins_with(s); }
bool ends_with(const char *s) const { return RTLIL::IdString(*this).ends_with(s); }
template <typename... Ts> bool in(Ts &&...args) const {
@ -1407,6 +1421,51 @@ struct RTLIL::CellNameMasq {
inline bool operator==(RTLIL::IdString lhs, const RTLIL::CellNameMasq &rhs) { return lhs == RTLIL::IdString(rhs); }
inline bool operator!=(RTLIL::IdString lhs, const RTLIL::CellNameMasq &rhs) { return lhs != RTLIL::IdString(rhs); }
// Read-only masquerade for Cell::type. Backed by Cell::type_impl.
// Write the type via cell->type_impl directly.
struct RTLIL::CellTypeMasq {
CellTypeMasq() = default;
CellTypeMasq(const CellTypeMasq &) = delete;
CellTypeMasq(CellTypeMasq &&) = delete;
CellTypeMasq &operator=(const CellTypeMasq &) = delete;
CellTypeMasq &operator=(CellTypeMasq &&) = delete;
operator RTLIL::IdString() const;
explicit operator TwineRef() const { return ref(); }
TwineRef ref() const;
std::string escaped() const;
std::string unescaped() const;
bool isPublic() const { return twine_is_public(ref()); }
bool empty() const { return ref() == Twine::Null; }
std::string str() const { return escaped(); } // TODO deprecate
const char *c_str() const { return RTLIL::IdString(*this).c_str(); }
std::string unescape() const { return unescaped(); }
bool begins_with(const char *s) const { return RTLIL::IdString(*this).begins_with(s); }
bool ends_with(const char *s) const { return RTLIL::IdString(*this).ends_with(s); }
template <typename... Ts> bool in(Ts &&...args) const {
return ref().in(std::forward<Ts>(args)...);
}
std::string substr(size_t pos = 0, size_t len = std::string::npos) const {
return RTLIL::IdString(*this).substr(pos, len);
}
size_t size() const { return RTLIL::IdString(*this).size(); }
bool contains(const char *p) const { return RTLIL::IdString(*this).contains(p); }
char operator[](int n) const { return RTLIL::IdString(*this).str()[n]; }
bool operator==(RTLIL::IdString rhs) const { return RTLIL::IdString(*this) == rhs; }
bool operator!=(RTLIL::IdString rhs) const { return RTLIL::IdString(*this) != rhs; }
bool operator<(RTLIL::IdString rhs) const { return RTLIL::IdString(*this) < rhs; }
bool operator==(TwineRef rhs) const { return ref() == rhs; }
bool operator!=(TwineRef rhs) const { return ref() != rhs; }
bool operator==(const std::string &rhs) const { return RTLIL::IdString(*this) == rhs; }
bool operator!=(const std::string &rhs) const { return RTLIL::IdString(*this) != rhs; }
bool operator==(const CellTypeMasq &rhs) const { return ref() == rhs.ref(); }
bool operator!=(const CellTypeMasq &rhs) const { return ref() != rhs.ref(); }
[[nodiscard]] Hasher hash_into(Hasher h) const { return RTLIL::IdString(*this).hash_into(h); }
};
inline bool operator==(RTLIL::IdString lhs, const RTLIL::CellTypeMasq &rhs) { return lhs == RTLIL::IdString(rhs); }
inline bool operator!=(RTLIL::IdString lhs, const RTLIL::CellTypeMasq &rhs) { return lhs != RTLIL::IdString(rhs); }
inline bool operator==(TwineRef lhs, const RTLIL::CellTypeMasq &rhs) { return lhs == rhs.ref(); }
inline bool operator!=(TwineRef lhs, const RTLIL::CellTypeMasq &rhs) { return lhs != rhs.ref(); }
struct RTLIL::SigChunk
{
RTLIL::Wire *wire;
@ -2385,7 +2444,8 @@ public:
void operator=(RTLIL::Cell &other) = delete;
RTLIL::Module *module;
IdString type;
TwineRef type_impl;
[[no_unique_address]] RTLIL::CellTypeMasq type;
dict<TwineRef, RTLIL::SigSpec> connections_;
dict<RTLIL::IdString, RTLIL::Const> parameters;
@ -2800,8 +2860,6 @@ public:
RTLIL::Cell* addDlatchsrGate (Twine &&name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, TwineRef src = Twine::Null);
RTLIL::Cell* addAnyinit(Twine &&name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, TwineRef src = Twine::Null);
// The methods without the add* prefix create a cell and an output signal. They return the newly created output signal.
RTLIL::SigSpec Not (Twine &&name, const RTLIL::SigSpec &sig_a, bool is_signed = false, TwineRef src = Twine::Null);
@ -2967,8 +3025,8 @@ public:
Module();
virtual ~Module();
virtual RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool mayfail = false);
virtual RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail = false);
virtual TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool mayfail = false);
virtual TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail = false);
virtual size_t count_id(TwineRef id);
virtual void expand_interfaces(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces);
virtual bool reprocess_if_necessary(RTLIL::Design *design);
@ -3038,7 +3096,7 @@ public:
// As above, but additionally renames the new module to `target_name` in
// `dst`. Used when source and destination designs may contain modules
// with the same name and the new one must take a different identity.
virtual RTLIL::Module *clone(RTLIL::Design *dst, RTLIL::IdString target_name, bool src_id_verbatim = false) const;
virtual RTLIL::Module *clone(RTLIL::Design *dst, TwineRef target_name, bool src_id_verbatim = false) const;
bool has_memories() const;
bool has_processes() const;
@ -3110,10 +3168,11 @@ public:
RTLIL::Wire *addWire(Twine &&name, const RTLIL::Wire *other);
// Primary overloads.
RTLIL::Cell *addCell(TwineRef name, RTLIL::IdString type);
RTLIL::Cell *addCell(TwineRef name, TwineRef type);
RTLIL::Cell *addCell(TwineRef name, const RTLIL::Cell *other);
// Convenience.
RTLIL::Cell *addCell(Twine &&name, RTLIL::IdString type);
RTLIL::Cell *addCell(Twine &&name, TwineRef type);
RTLIL::Cell *addCell(TwineRef name, Twine &&type);
RTLIL::Cell *addCell(Twine &&name, const RTLIL::Cell *other);
// NEW_ID analog for twine names; see NEW_TWINE in yosys_common.h.
@ -3132,7 +3191,8 @@ public:
// The add* methods create a cell and return the created cell. All signals must exist in advance.
RTLIL::Cell* addAnyinit(RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, TwineRef src = Twine::Null);
RTLIL::Cell* addAnyinit(TwineRef name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, TwineRef src = Twine::Null);
RTLIL::Cell* addAnyinit(Twine &&name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, TwineRef src = Twine::Null);
// The methods without the add* prefix create a cell and an output signal. They return the newly created output signal.
@ -3141,6 +3201,11 @@ public:
RTLIL::SigSpec Allconst (TwineRef name, int width = 1, TwineRef src = Twine::Null);
RTLIL::SigSpec Allseq (TwineRef name, int width = 1, TwineRef src = Twine::Null);
RTLIL::SigSpec Initstate (TwineRef name, TwineRef src = Twine::Null);
RTLIL::SigSpec Anyconst (Twine &&name, int width = 1, TwineRef src = Twine::Null);
RTLIL::SigSpec Anyseq (Twine &&name, int width = 1, TwineRef src = Twine::Null);
RTLIL::SigSpec Allconst (Twine &&name, int width = 1, TwineRef src = Twine::Null);
RTLIL::SigSpec Allseq (Twine &&name, int width = 1, TwineRef src = Twine::Null);
RTLIL::SigSpec Initstate (Twine &&name, TwineRef src = Twine::Null);
RTLIL::SigSpec SetTag (TwineRef name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, TwineRef src = Twine::Null);
RTLIL::Cell* addSetTag (TwineRef name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const RTLIL::SigSpec &sig_y, TwineRef src = Twine::Null);
@ -3148,6 +3213,12 @@ public:
RTLIL::Cell* addOverwriteTag (TwineRef name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, TwineRef src = Twine::Null);
RTLIL::SigSpec OriginalTag (TwineRef name, const std::string &tag, const RTLIL::SigSpec &sig_a, TwineRef src = Twine::Null);
RTLIL::SigSpec FutureFF (TwineRef name, const RTLIL::SigSpec &sig_e, TwineRef src = Twine::Null);
RTLIL::SigSpec SetTag (Twine &&name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, TwineRef src = Twine::Null);
RTLIL::Cell* addSetTag (Twine &&name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const RTLIL::SigSpec &sig_y, TwineRef src = Twine::Null);
RTLIL::SigSpec GetTag (Twine &&name, const std::string &tag, const RTLIL::SigSpec &sig_a, TwineRef src = Twine::Null);
RTLIL::Cell* addOverwriteTag (Twine &&name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, TwineRef src = Twine::Null);
RTLIL::SigSpec OriginalTag (Twine &&name, const std::string &tag, const RTLIL::SigSpec &sig_a, TwineRef src = Twine::Null);
RTLIL::SigSpec FutureFF (Twine &&name, const RTLIL::SigSpec &sig_e, TwineRef src = Twine::Null);
std::string to_rtlil_str() const;
#ifdef YOSYS_ENABLE_PYTHON
@ -3278,26 +3349,108 @@ void RTLIL::Process::rewrite_sigspecs2(T &functor)
it->rewrite_sigspecs2(functor);
}
inline RTLIL::WireNameMasq::operator RTLIL::IdString() const {
inline TwineRef RTLIL::WireNameMasq::ref() const {
const RTLIL::Wire *w = reinterpret_cast<const RTLIL::Wire *>(
reinterpret_cast<const char *>(this) - offsetof(RTLIL::Wire, name));
if (!w->module || !w->module->design || !w->meta_)
return RTLIL::IdString{};
TwineRef id = w->meta_->name;
if (id == Twine::Null)
return RTLIL::IdString{};
return RTLIL::IdString(w->module->design->twines.flat_string(id));
return Twine::Null;
return w->meta_->name;
}
inline RTLIL::CellNameMasq::operator RTLIL::IdString() const {
inline std::string RTLIL::WireNameMasq::escaped() const {
const RTLIL::Wire *w = reinterpret_cast<const RTLIL::Wire *>(
reinterpret_cast<const char *>(this) - offsetof(RTLIL::Wire, name));
TwineRef id = ref();
if (id == Twine::Null)
return std::string();
return w->module->design->twines.str(id);
}
inline std::string RTLIL::WireNameMasq::unescaped() const {
const RTLIL::Wire *w = reinterpret_cast<const RTLIL::Wire *>(
reinterpret_cast<const char *>(this) - offsetof(RTLIL::Wire, name));
TwineRef id = ref();
if (id == Twine::Null)
return std::string();
return w->module->design->twines.unescaped_str(id);
}
inline RTLIL::WireNameMasq::operator RTLIL::IdString() const {
std::string s = escaped();
if (s.empty())
return RTLIL::IdString{};
return RTLIL::IdString(s);
}
inline TwineRef RTLIL::CellNameMasq::ref() const {
const RTLIL::Cell *c = reinterpret_cast<const RTLIL::Cell *>(
reinterpret_cast<const char *>(this) - offsetof(RTLIL::Cell, name));
if (!c->module || !c->module->design || !c->meta_)
return RTLIL::IdString{};
TwineRef id = c->meta_->name;
return Twine::Null;
return c->meta_->name;
}
inline std::string RTLIL::CellNameMasq::escaped() const {
const RTLIL::Cell *c = reinterpret_cast<const RTLIL::Cell *>(
reinterpret_cast<const char *>(this) - offsetof(RTLIL::Cell, name));
TwineRef id = ref();
if (id == Twine::Null)
return std::string();
return c->module->design->twines.str(id);
}
inline std::string RTLIL::CellNameMasq::unescaped() const {
const RTLIL::Cell *c = reinterpret_cast<const RTLIL::Cell *>(
reinterpret_cast<const char *>(this) - offsetof(RTLIL::Cell, name));
TwineRef id = ref();
if (id == Twine::Null)
return std::string();
return c->module->design->twines.unescaped_str(id);
}
inline RTLIL::CellNameMasq::operator RTLIL::IdString() const {
std::string s = escaped();
if (s.empty())
return RTLIL::IdString{};
return RTLIL::IdString(c->module->design->twines.flat_string(id));
return RTLIL::IdString(s);
}
inline TwineRef RTLIL::CellTypeMasq::ref() const {
const RTLIL::Cell *c = reinterpret_cast<const RTLIL::Cell *>(
reinterpret_cast<const char *>(this) - offsetof(RTLIL::Cell, type));
return c->type_impl;
}
inline std::string RTLIL::CellTypeMasq::escaped() const {
const RTLIL::Cell *c = reinterpret_cast<const RTLIL::Cell *>(
reinterpret_cast<const char *>(this) - offsetof(RTLIL::Cell, type));
TwineRef id = c->type_impl;
if (id == Twine::Null)
return std::string();
if (c->module && c->module->design)
return c->module->design->twines.str(id);
// Static (TW::) refs are pool-independent; assert non-local ref.
log_assert(twine_untag(id) < STATIC_TWINE_END);
return TwinePool{}.str(id);
}
inline std::string RTLIL::CellTypeMasq::unescaped() const {
const RTLIL::Cell *c = reinterpret_cast<const RTLIL::Cell *>(
reinterpret_cast<const char *>(this) - offsetof(RTLIL::Cell, type));
TwineRef id = c->type_impl;
if (id == Twine::Null)
return std::string();
if (c->module && c->module->design)
return c->module->design->twines.unescaped_str(id);
log_assert(twine_untag(id) < STATIC_TWINE_END);
return TwinePool{}.unescaped_str(id);
}
inline RTLIL::CellTypeMasq::operator RTLIL::IdString() const {
std::string s = escaped();
if (s.empty())
return RTLIL::IdString{};
return RTLIL::IdString(s);
}
// inline RTLIL::ModuleNameMasq& RTLIL::ModuleNameMasq::operator=(RTLIL::IdString id) {

View file

@ -527,7 +527,7 @@ void RTLIL::Module::remove(RTLIL::Cell *cell)
log_assert(refcount_cells_ == 0);
cells_.erase(cell_id);
if (design && design->flagBufferedNormalized && buf_norm_cell_queue.count(cell)) {
cell->type.clear();
cell->type_impl = Twine::Null;
// design->obj_release_name(cell);
pending_deleted_cells.insert(cell);
} else {

View file

@ -6,10 +6,10 @@ YOSYS_NAMESPACE_BEGIN
std::vector<Twine> TwinePool::globals_;
TwineRef twine_populate(std::string name) {
if (name[1] == '$') {
// Skip prepended '\'
name = name.substr(1);
}
// Globals store content only: drop the prepended '\'. Publicity lives
// in TWINE_PUBLIC_BIT on the TW:: handle, not in the stored string.
log_assert(name[0] == '\\');
name = name.substr(1);
TwinePool::globals_.push_back(Twine{std::move(name)});
return TwinePool::globals_.size() - 1;
}

View file

@ -4,6 +4,8 @@
#include "kernel/yosys_common.h"
#include "kernel/hashlib.h"
#include <cassert>
#include "libs/plf_colony/plf_colony.h"
#include <cstdint>
#include <limits>
@ -21,10 +23,49 @@ YOSYS_NAMESPACE_BEGIN
struct Twine;
struct TwinePool;
using TwineRef = size_t;
struct TwineRef {
size_t value;
static constexpr size_t kLocalBit = 1ULL << 63;
static constexpr size_t kPublicBit = 1ULL << 62;
static constexpr size_t kTagMask = kLocalBit | kPublicBit;
static constexpr size_t kNull = ~size_t{0};
constexpr TwineRef() : value(0) {}
constexpr TwineRef(size_t val) : value(val) {}
constexpr operator size_t() const { return value; }
template <typename... Args>
constexpr bool in(const Args&... args) const {
return ((*this == args) || ...);
}
constexpr TwineRef operator|(TwineRef rhs) const { return TwineRef(value | rhs.value); }
constexpr TwineRef operator&(TwineRef rhs) const { return TwineRef(value & rhs.value); }
constexpr TwineRef operator~() const { return TwineRef(~value); }
constexpr TwineRef& operator++() { ++value; return *this; }
constexpr TwineRef operator++(int) { return TwineRef(value++); }
constexpr bool is_public() const { return value != kNull && (value & kPublicBit); }
constexpr bool is_local() const { return value != kNull && (value & kLocalBit); }
constexpr TwineRef untag() const {
return value == kNull ? *this : TwineRef(value & ~kPublicBit);
}
constexpr TwineRef tag(bool pub) const {
return value == kNull ? *this : TwineRef(pub ? (value | kPublicBit) : (value & ~kPublicBit));
}
Hasher hash_into(Hasher h) const { h.hash64(value); return h; }
};
// Tags TwineChildPool-local refs; never set on refs handed out by TwinePool.
constexpr TwineRef TWINE_LOCAL_BIT = TwineRef(1) << 63;
constexpr TwineRef TWINE_LOCAL_BIT = TwineRef(1LLU << 63);
// Publicity tag carried on name handles. Pool nodes store name *content*
// (no '\' escape); whether a name is public lives in this bit of the
// handle, never inside the pool. TwinePool strips it on every entry path.
constexpr TwineRef TWINE_PUBLIC_BIT = TwineRef(1LLU << 62);
constexpr TwineRef TWINE_TAG_MASK = TWINE_LOCAL_BIT | TWINE_PUBLIC_BIT;
enum : short {
STATIC_TWINE_BEGIN = 0,
@ -35,11 +76,26 @@ enum : short {
};
struct TW {
#define X(N) static constexpr TwineRef N = IDX_##N;
// Static ids are name handles: non-'$' constids were '\'-escaped publics,
// so their handles carry TWINE_PUBLIC_BIT baked in at compile time.
#define X(N) static constexpr TwineRef N = (#N)[0] == '$' ? TwineRef(IDX_##N) : (TwineRef(IDX_##N) | TWINE_PUBLIC_BIT);
#include "kernel/constids.inc"
#undef X
static constexpr TwineRef lookup(std::string_view name)
{
#define X(N) \
if (name == #N) return N;
#include "kernel/constids.inc"
#undef X
throw "unknown twine id";
}
};
#define TW(id) (size_t)lookup_well_known_id(#id)
// #define TW(name) TW::lookup(#name)
struct Twine {
static constexpr TwineRef Null = std::numeric_limits<size_t>::max();
@ -62,6 +118,10 @@ struct Twine {
const Suffix &suffix() const { return std::get<Suffix>(data); }
};
constexpr bool twine_is_public(TwineRef ref) { return ref.is_public(); }
constexpr TwineRef twine_untag(TwineRef ref) { return ref.untag(); }
constexpr TwineRef twine_tag(TwineRef ref, bool is_public) { return ref.tag(is_public); }
struct TwineHash {
using is_transparent = void;
@ -94,6 +154,7 @@ struct TwinePool {
std::unordered_set<TwineRef, TwineHash, TwineEq> index;
const Twine& operator[] (TwineRef ref) const {
ref = twine_untag(ref);
if (ref < STATIC_TWINE_END)
return globals_[ref];
else
@ -124,6 +185,10 @@ struct TwinePool {
}, twine.data);
}
void print(TwineRef ref, std::ostream& os = std::cout) const {
if (ref == Twine::Null)
return;
if (twine_is_public(ref))
os << '\\';
std::visit([&](const auto& val) {
using T = std::decay_t<decltype(val)>;
if constexpr (std::is_same_v<T, std::monostate>) {
@ -141,12 +206,18 @@ struct TwinePool {
}
}, (*this)[ref].data);
}
// Escaped form: leading '\' for public name handles, content otherwise.
std::string str(TwineRef ref) const {
std::ostringstream os;
print(ref, os);
return os.str();
}
// Name content without the publicity escape.
std::string unescaped_str(TwineRef ref) const {
return str(twine_untag(ref));
}
TwinePool() : index(0, TwineHash{this}, TwineEq{this}) {
rebuild_index();
}
@ -180,14 +251,28 @@ struct TwinePool {
index.insert(STATIC_TWINE_END + backing.get_index(it));
}
TwineRef find(const Twine& t) const {
TwineRef find(Twine t) const {
if (auto *children = std::get_if<std::vector<TwineRef>>(&t.data)) {
for (TwineRef &c : *children)
c = twine_untag(c);
} else if (auto *sfx = std::get_if<Twine::Suffix>(&t.data)) {
sfx->prefix = twine_untag(sfx->prefix);
}
if (auto it = index.find(t); it != index.end()) {
return *it;
}
return Twine::Null;
}
TwineRef add(Twine t) {
TwineRef add_inner(Twine t) {
// Nodes store content only: strip publicity tags off child handles.
if (auto *children = std::get_if<std::vector<TwineRef>>(&t.data)) {
for (TwineRef &c : *children)
c = twine_untag(c);
} else if (auto *sfx = std::get_if<Twine::Suffix>(&t.data)) {
sfx->prefix = twine_untag(sfx->prefix);
}
if (auto it = index.find(t); it != index.end()) {
return *it;
}
@ -198,6 +283,40 @@ struct TwinePool {
return ref;
}
// Interns an object name and returns a publicity-tagged handle. Leaf
// strings follow the escaped convention: a leading '\' marks a public
// name (stripped from the stored content), '$' a private one. Suffix
// and concat names inherit the prefix/first-child handle's publicity.
TwineRef add(Twine t) {
bool is_public = false;
if (auto *leaf = std::get_if<std::string>(&t.data)) {
assert(!leaf->empty());
if ((*leaf)[0] == '\\') {
is_public = true;
leaf->erase(0, 1);
assert(!leaf->empty());
} else {
assert((*leaf)[0] == '$');
}
} else if (auto *sfx = std::get_if<Twine::Suffix>(&t.data)) {
is_public = twine_is_public(sfx->prefix);
} else if (auto *children = std::get_if<std::vector<TwineRef>>(&t.data)) {
is_public = false;
}
return twine_tag(add_inner(std::move(t)), is_public);
}
TwineRef add(std::string&& s) {
if (s.size()) {
if (s[0] == '\\')
return twine_tag(add(Twine{s.substr(1)}), true);
else
return twine_tag(add(Twine{std::move(s)}), true);
} else {
return Twine::Null;
}
}
size_t size() const { return backing.size(); }
TwineRef concat(std::span<const TwineRef> ids) {
@ -207,31 +326,39 @@ struct TwinePool {
}
TwineRef copy_from(const TwinePool& src, TwineRef ref) {
if (ref == Twine::Null || ref < STATIC_TWINE_END)
if (ref == Twine::Null)
return ref;
const Twine& t = src[ref];
// Statics are shared across pools; preserve the handle's publicity
// tag across the copy in either case.
bool is_public = twine_is_public(ref);
TwineRef untagged = twine_untag(ref);
if (untagged < STATIC_TWINE_END)
return ref;
const Twine& t = src[untagged];
if (t.is_leaf())
return add(Twine{t.leaf()});
return twine_tag(add(Twine{t.leaf()}), is_public);
if (t.is_concat()) {
std::vector<TwineRef> children;
children.reserve(t.children().size());
for (TwineRef c : t.children())
children.push_back(copy_from(src, c));
return add(Twine{std::move(children)});
return twine_tag(add(Twine{std::move(children)}), is_public);
}
if (t.is_suffix())
return add(Twine{Twine::Suffix{copy_from(src, t.suffix().prefix), t.suffix().tail}});
return twine_tag(add(Twine{Twine::Suffix{copy_from(src, t.suffix().prefix), t.suffix().tail}}), is_public);
return Twine::Null;
}
// linear deep scan; only for rare by-string lookups
// linear deep scan; only for rare by-string lookups. Accepts the
// escaped name convention: a leading '\' is stripped and the returned
// handle carries TWINE_PUBLIC_BIT.
TwineRef lookup(std::string_view sv) const;
// Erases every backing node not reachable from `roots`; refs to
// surviving nodes stay valid. Returns the number of erased nodes.
template<typename Pool>
size_t gc(const Pool& roots) {
std::unordered_set<TwineRef> live;
pool<TwineRef> live;
for (TwineRef ref : roots)
mark_live(ref, live);
size_t erased = 0;
@ -248,7 +375,8 @@ struct TwinePool {
return erased;
}
void mark_live(TwineRef ref, std::unordered_set<TwineRef>& live) const {
void mark_live(TwineRef ref, pool<TwineRef>& live) const {
ref = twine_untag(ref);
if (ref == Twine::Null || ref < STATIC_TWINE_END || !live.insert(ref).second)
return;
const Twine& t = (*this)[ref];
@ -441,21 +569,51 @@ struct TwineChildPool {
TwineChildPool(const TwinePool* parent) : parent(parent) {}
static bool is_local(TwineRef ref) {
return ref != Twine::Null && (ref & TWINE_LOCAL_BIT);
}
static bool is_local(TwineRef ref) { return ref.is_local(); }
const Twine& operator[] (TwineRef ref) const {
if (is_local(ref))
return local_[ref & ~TWINE_LOCAL_BIT];
return local_[ref & ~TWINE_TAG_MASK];
return (*parent)[ref];
}
TwineRef add(Twine t) {
TwineRef add_inner(Twine t) {
local_.push_back(std::move(t));
return (local_.size() - 1) | TWINE_LOCAL_BIT;
}
// Local analog of TwinePool::add; see there for the convention.
TwineRef add(Twine t) {
bool is_public = false;
if (auto *leaf = std::get_if<std::string>(&t.data)) {
assert(!leaf->empty());
if ((*leaf)[0] == '\\') {
is_public = true;
leaf->erase(0, 1);
assert(!leaf->empty());
} else {
assert((*leaf)[0] == '$');
}
} else if (auto *sfx = std::get_if<Twine::Suffix>(&t.data)) {
is_public = twine_is_public(sfx->prefix);
} else if (auto *children = std::get_if<std::vector<TwineRef>>(&t.data)) {
is_public = !children->empty() && twine_is_public(children->front());
}
return twine_tag(add_inner(std::move(t)), is_public);
}
// TODO duplicated code
TwineRef add(std::string&& s) {
if (s.size()) {
if (s[0] == '\\')
return twine_tag(add(Twine{s.substr(1)}), true);
else
return twine_tag(add(Twine{std::move(s)}), true);
} else {
return Twine::Null;
}
}
bool empty() const { return local_.empty(); }
// serial phase only; dest must be *parent; resolve() covers refs added since the previous commit
@ -477,19 +635,22 @@ struct TwineChildPool {
TwineRef resolve(TwineRef ref) const {
if (!is_local(ref))
return ref;
return remap_[ref & ~TWINE_LOCAL_BIT];
return twine_tag(remap_[ref & ~TWINE_TAG_MASK], twine_is_public(ref));
}
};
inline TwineRef TwinePool::lookup(std::string_view sv) const {
bool is_public = !sv.empty() && sv[0] == '\\';
if (is_public)
sv.remove_prefix(1);
DeepTwineEq eq{this};
for (TwineRef ref = 0; ref < globals_.size(); ref++)
if (eq(ref, sv))
return ref;
return twine_tag(ref, is_public);
for (auto it = backing.begin(); it != backing.end(); ++it) {
TwineRef ref = STATIC_TWINE_END + backing.get_index(it);
if (eq(ref, sv))
return ref;
return twine_tag(ref, is_public);
}
return Twine::Null;
}
@ -502,9 +663,13 @@ struct TwineSearch {
index.insert(STATIC_TWINE_END + pool->backing.get_index(it));
}
}
// Escaped-name aware, same contract as TwinePool::lookup.
TwineRef find(std::string_view sv) const {
bool is_public = !sv.empty() && sv[0] == '\\';
if (is_public)
sv.remove_prefix(1);
if (auto it = index.find(sv); it != index.end()) {
return *it;
return twine_tag(*it, is_public);
}
return Twine::Null;
}

View file

@ -10,17 +10,28 @@ using namespace RTLIL;
template class CellAdderMixin<Patch>;
Cell* Patch::addCell(TwineRef name, IdString type) {
Cell* Patch::addCell(TwineRef name, TwineRef type) {
cells_.push_back(std::make_unique<Cell>(Cell::ConstructToken{}));
Cell* cell = cells_.back().get();
cell->type = type;
cell->type_impl = type;
cell->module = nullptr;
staged_cell_names_[cell] = name;
return cell;
}
Cell* Patch::addCell(Twine &&name, IdString type) {
// Cell* Patch::addCell(TwineRef name, IdString type) {
// static TwinePool s_pool;
// TwineRef tref = s_pool.lookup(type.str());
// log_assert(tref != Twine::Null);
// return addCell(name, tref);
// }
Cell* Patch::addCell(TwineRef name, Twine &&type) {
return addCell(name, twine_staging.add(std::move(type)));
}
Cell* Patch::addCell(Twine &&name, TwineRef type) {
return addCell(twine_staging.add(std::move(name)), type);
}

View file

@ -74,9 +74,10 @@ public:
RTLIL::Wire *addWire(Twine &&name, int width = 1);
RTLIL::Wire *addWire(Twine &&name, const RTLIL::Wire *other);
RTLIL::Cell *addCell(TwineRef name, RTLIL::IdString type);
RTLIL::Cell *addCell(TwineRef name, TwineRef type);
RTLIL::Cell *addCell(TwineRef name, const RTLIL::Cell *other);
RTLIL::Cell *addCell(Twine &&name, RTLIL::IdString type);
RTLIL::Cell *addCell(Twine &&name, TwineRef type);
RTLIL::Cell *addCell(TwineRef name, Twine &&type);
RTLIL::Cell *addCell(Twine &&name, const RTLIL::Cell *other);
// NEW_ID analog for twine names; see NEW_TWINE in yosys_common.h.

View file

@ -118,7 +118,7 @@ struct BoxDerivePass : Pass {
}
if (apply_mode)
cell->type = RTLIL::IdString(done[index]->design->twines.str(done[index]->meta_->name));
cell->type_impl = cell->module->design->twines.copy_from(done[index]->design->twines, done[index]->meta_->name);
}
}
}

View file

@ -47,7 +47,7 @@ static RTLIL::IdString formal_flavor(RTLIL::Cell *cell)
static void set_formal_flavor(RTLIL::Cell *cell, RTLIL::IdString flavor)
{
if (cell->type != ID($check)) {
cell->type = flavor;
cell->type_impl = cell->module->design->twines.add(Twine{flavor.str()});
return;
}
@ -441,7 +441,7 @@ struct ChformalPass : public Pass {
if (cell->getPort(TW::ARGS).empty()) {
module->remove(cell);
} else {
cell->type = ID($print);
cell->type_impl = TW::$print;
cell->setPort(TW::EN, combined_en);
cell->unsetPort(TW::A);
cell->unsetParam(ID(FLAVOR));

View file

@ -38,7 +38,9 @@ static void publish_design(RTLIL::Design* design) {
publish(new_name);
design->modules_[mod->meta_->name] = mod;
for (auto* cell : mod->cells()) {
publish(cell->type);
IdString ct = cell->type;
if (ct.begins_with("$"))
cell->type_impl = cell->module->design->twines.add(Twine{"\\" + ct.str()});
}
}
}
@ -100,12 +102,12 @@ struct ChtypePass : public Pass {
for (auto cell : module->selected_cells())
{
if (map_types.count(cell->type)) {
cell->type = map_types.at(cell->type);
cell->type_impl = cell->module->design->twines.add(Twine{map_types.at(cell->type).str()});
continue;
}
if (set_type != IdString()) {
cell->type = set_type;
cell->type_impl = cell->module->design->twines.add(Twine{set_type.str()});
continue;
}
}

View file

@ -304,7 +304,7 @@ struct DesignPass : public Pass {
done[cell->type] = trg_name;
}
cell->type = done.at(cell->type);
cell->type_impl = cell->module->design->twines.add(Twine{done.at(cell->type).str()});
}
}
}

View file

@ -101,7 +101,7 @@ struct DftTagWorker {
log_debug("Applying $overwrite_tag %s for signal %s\n", cell->module->design->twines.str(cell->meta_->name), log_signal(cell->getPort(TW::A)));
SigSpec orig_signal = cell->getPort(TW::A);
SigSpec interposed_signal = divert_users(orig_signal);
auto *set_tag_cell = module->addSetTag(module->design->twines.add(NEW_TWINE), cell->getParam(ID::TAG).decode_string(), orig_signal, cell->getPort(TW::SET), cell->getPort(TW::CLR), interposed_signal);
auto *set_tag_cell = module->addSetTag(NEW_TWINE, cell->getParam(ID::TAG).decode_string(), orig_signal, cell->getPort(TW::SET), cell->getPort(TW::CLR), interposed_signal);
modwalker.add_cell(set_tag_cell); // Make sure the next $overwrite_tag sees the new connections
design_changed = true;
}
@ -110,7 +110,7 @@ struct DftTagWorker {
module->remove(cell);
}
for (auto cell : original_cells) {
cell->type = ID($get_tag);
cell->type_impl = TW::$get_tag;
}
if (design_changed)

View file

@ -186,7 +186,7 @@ struct SetparamPass : public Pass {
{
for (auto cell : module->selected_cells()) {
if (!new_cell_type.empty())
cell->type = new_cell_type;
cell->type_impl = cell->module->design->twines.add(Twine{new_cell_type});
do_setunset(cell->parameters, setunset_list);
}
}

View file

@ -37,7 +37,7 @@ PRIVATE_NAMESPACE_BEGIN
static RTLIL::Wire * add_wire(RTLIL::Module *module, std::string name, int width, bool flag_input, bool flag_output)
{
RTLIL::Wire *wire = NULL;
name = RTLIL::escape_id(name);
TwineRef t = module->design->twines.add(Twine{name});
if (module->count_id(name) != 0)
{

View file

@ -141,7 +141,7 @@ struct statdata_t {
}
}
statdata_t(const RTLIL::Design *design, const RTLIL::Module *mod, bool width_mode, dict<IdString, cell_area_t> &cell_area, string techname)
statdata_t(RTLIL::Design *design, const RTLIL::Module *mod, bool width_mode, dict<IdString, cell_area_t> &cell_area, string techname)
{
tech = techname;
@ -239,17 +239,17 @@ struct statdata_t {
for (auto &it : cell_data.parameter_names) {
TwineRef port_name;
if (it == "A") {
port_name = ID::A;
port_name = TW::A;
} else if (it == "B") {
port_name = ID::B;
port_name = TW::B;
} else if (it == "Y") {
port_name = ID::Y;
port_name = TW::Y;
} else if (it == "Q") {
port_name = ID::Q;
port_name = TW::Q;
} else if (it == "S") {
port_name = ID::S;
port_name = TW::S;
} else {
port_name = ID(it);
port_name = design->twines.add(Twine{it});
}
if (cell->hasPort(port_name)) {
int width = GetSize(cell->getPort(port_name));
@ -744,7 +744,7 @@ statdata_t hierarchy_worker(std::map<RTLIL::IdString, statdata_t> &mod_stat, RTL
return mod_data;
}
statdata_t hierarchy_builder(const RTLIL::Design *design, const RTLIL::Module *top_mod, std::map<RTLIL::IdString, statdata_t> &mod_stat,
statdata_t hierarchy_builder(RTLIL::Design *design, const RTLIL::Module *top_mod, std::map<RTLIL::IdString, statdata_t> &mod_stat,
bool width_mode, dict<IdString, cell_area_t> &cell_area, string techname)
{
if (top_mod == nullptr)

View file

@ -292,7 +292,7 @@ struct WrapcellPass : Pass {
for (auto chunk : collect_chunks(used_outputs))
new_connections[chunk.format(cell)] = chunk.sample(cell);
cell->type = name;
cell->type_impl = cell->module->design->twines.add(Twine{name.str()});
cell->connections_ = new_connections;
}
}

View file

@ -171,9 +171,9 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module)
RTLIL::Cell *state_dff = module->addCell(NEW_TWINE, "");
if (fsm_cell->getPort(TW::ARST).is_fully_const()) {
state_dff->type = ID($dff);
state_dff->type_impl = TW::$dff;
} else {
state_dff->type = ID($adff);
state_dff->type_impl = TW::$adff;
state_dff->parameters[ID::ARST_POLARITY] = fsm_cell->parameters[ID::ARST_POLARITY];
state_dff->parameters[ID::ARST_VALUE] = fsm_data.state_table[fsm_data.reset_state];
for (auto bit : state_dff->parameters[ID::ARST_VALUE])

View file

@ -205,7 +205,7 @@ struct IFExpander
bool has_interfaces_not_found;
std::vector<TwineRef> connections_to_remove;
std::vector<TwineRef> connections_to_add_name;
std::vector<TwineRef> connections_to_add;
std::vector<RTLIL::SigSpec> connections_to_add_signal;
dict<TwineRef, RTLIL::Module*> interfaces_to_add_to_submodule;
dict<TwineRef, RTLIL::IdString> modports_used_in_submodule;
@ -215,7 +215,7 @@ struct IFExpander
{
has_interfaces_not_found = false;
connections_to_remove.clear();
connections_to_add_name.clear();
connections_to_add.clear();
connections_to_add_signal.clear();
interfaces_to_add_to_submodule.clear();
modports_used_in_submodule.clear();
@ -284,7 +284,7 @@ struct IFExpander
for (auto mod_wire : mod_replace_ports->wires()) {
std::string signal_name1 = conn_name_str + "." + mod_wire->name.unescape();
std::string signal_name2 = interface_name.str() + "." + mod_wire->name.unescape();
connections_to_add_name.push_back(design.twines.add(Twine{signal_name1}));
connections_to_add.push_back(design.twines.add(Twine{signal_name1}));
TwineRef signal_name2_ref = design.twines.lookup(signal_name2);
if(module.wire(signal_name2_ref) == nullptr) {
log_error("Could not find signal '%s' in '%s'\n",
@ -365,8 +365,8 @@ struct IFExpander
// interface port connection with the individual signal connections.
void rewrite_interface_connections(RTLIL::Cell &cell) const
{
for(unsigned int i=0;i<connections_to_add_name.size();i++) {
cell.connections_[connections_to_add_name[i]] = connections_to_add_signal[i];
for(unsigned int i=0;i<connections_to_add.size();i++) {
cell.connections_[connections_to_add[i]] = connections_to_add_signal[i];
}
// Remove the connection for the interface itself:
for(unsigned int i=0;i<connections_to_remove.size();i++) {
@ -391,7 +391,7 @@ RTLIL::Module *get_module(RTLIL::Design &design,
std::string cell_type = cell.type.str();
RTLIL::Module *abs_mod = design.module("$abstract" + cell_type);
if (abs_mod) {
cell.type = abs_mod->derive(&design, cell.parameters);
cell.type_impl = design.twines.add(Twine{abs_mod->derive(&design, cell.parameters).str()});
cell.parameters.clear();
RTLIL::Module *mod = design.module(cell.type);
log_assert(mod);
@ -514,7 +514,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
int idx = atoi(cell->type.substr(pos_idx + 1, pos_num).c_str());
int num = atoi(cell->type.substr(pos_num + 1, pos_type).c_str());
array_cells[cell] = std::pair<int, int>(idx, num);
cell->type = cell->type.substr(pos_type + 1);
cell->type_impl = cell->module->design->twines.add(Twine{cell->type.str().substr(pos_type + 1)});
}
dict<RTLIL::IdString, RTLIL::Module*> interfaces_by_name;
@ -576,10 +576,10 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
interfaces_by_name[RTLIL::IdString(design->twines.str(p.first))] = p.second;
for (auto &p : if_expander.modports_used_in_submodule)
modports_by_name[RTLIL::IdString(design->twines.str(p.first))] = p.second;
cell->type = mod->derive(design,
cell->type_impl = design->twines.add(Twine{mod->derive(design,
cell->parameters,
interfaces_by_name,
modports_by_name);
modports_by_name).str()});
cell->parameters.clear();
did_something = true;

View file

@ -88,7 +88,7 @@ struct UniquifyPass : public Pass {
auto smod = tmod->clone();
smod->meta_->name = newname_ref;
cell->type = newname;
cell->type_impl = cell->module->design->twines.add(Twine{newname.str()});
smod->set_bool_attribute(ID::unique);
if (smod->attributes.count(ID::hdlname) == 0)
smod->attributes[ID::hdlname] = RTLIL::Const(tmod_name_str);

View file

@ -277,7 +277,7 @@ struct MuxpackWorker
mux_count += cases;
pmux_count += 1;
first_cell->type = ID($pmux);
first_cell->type_impl = TW::$pmux;
SigSpec b_sig = first_cell->getPort(TW::B);
SigSpec s_sig = first_cell->getPort(TW::S);

View file

@ -159,9 +159,9 @@ void demorgan_worker(
//Change the cell type
if(cell->type == ID($reduce_and))
cell->type = ID($reduce_or);
cell->type_impl = TW::$reduce_or;
else if(cell->type == ID($reduce_or))
cell->type = ID($reduce_and);
cell->type_impl = TW::$reduce_and;
//don't change XOR
//Add an inverter to the output

View file

@ -419,7 +419,7 @@ void handle_clkpol_celltype_swap(Cell *cell, string type1, string type2, TwineRe
IdString(RTLIL::StaticId(port)).unescape(), cell->type.unescape(), cell, cell->module,
log_signal(sig), log_signal(new_sig));
cell->setPort(port, new_sig);
cell->type = cell->type == type1 ? type2 : type1;
cell->type_impl = cell->module->design->twines.add(Twine{cell->type == type1 ? type2 : type1});
}
}
}
@ -715,7 +715,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (cell->type == ID($reduce_xnor)) {
log_debug("Replacing %s cell `%s' in module `%s' with $not cell.\n",
cell->type.unescape(), cell->module->design->twines.str(cell->meta_->name), module);
cell->type = ID($not);
cell->type_impl = TW::$not;
did_something = true;
} else {
OptExprPatcher patcher(module, &assign_map);
@ -1235,7 +1235,7 @@ skip_fine_alu:
cell->setPort(TW::A, input.extract(0, 1));
cell->unsetPort(TW::B);
cell->unsetPort(TW::S);
cell->type = ID($_NOT_);
cell->type_impl = TW::$_NOT_;
goto next_cell;
}
if (input.match("11 ")) ACTION_DO_Y(1);
@ -1340,7 +1340,7 @@ skip_fine_alu:
cell->parameters.erase(ID::B_WIDTH);
cell->parameters.erase(ID::B_SIGNED);
cell->unsetPort(TW::B);
cell->type = ID($not);
cell->type_impl = TW::$not;
did_something = true;
}
goto next_cell;
@ -1360,7 +1360,7 @@ skip_fine_alu:
cell->unsetPort(TW::B);
cell->unsetParam(ID::B_SIGNED);
cell->unsetParam(ID::B_WIDTH);
cell->type = cell->type == ID($eq) ? ID($logic_not) : ID($reduce_bool);
cell->type_impl = (cell->type == ID($eq)) ? TW::$logic_not : TW::$reduce_bool;
did_something = true;
goto next_cell;
}
@ -1524,7 +1524,7 @@ skip_fine_alu:
cell->unsetPort(TW::B);
cell->parameters.erase(ID::B_WIDTH);
cell->parameters.erase(ID::B_SIGNED);
cell->type = arith_inverse ? ID($neg) : ID($pos);
cell->type_impl = arith_inverse ? TW::$neg : TW::$pos;
cell->check();
did_something = true;
@ -1552,9 +1552,9 @@ skip_identity:
cell->parameters[ID::Y_WIDTH] = width;
cell->parameters[ID::A_SIGNED] = 0;
cell->parameters.erase(ID::WIDTH);
cell->type = ID($not);
cell->type_impl = TW::$not;
} else
cell->type = ID($_NOT_);
cell->type_impl = TW::$_NOT_;
did_something = true;
goto next_cell;
}
@ -1571,9 +1571,9 @@ skip_identity:
cell->parameters[ID::A_SIGNED] = 0;
cell->parameters[ID::B_SIGNED] = 0;
cell->parameters.erase(ID::WIDTH);
cell->type = ID($and);
cell->type_impl = TW::$and;
} else
cell->type = ID($_AND_);
cell->type_impl = TW::$_AND_;
did_something = true;
goto next_cell;
}
@ -1590,9 +1590,9 @@ skip_identity:
cell->parameters[ID::A_SIGNED] = 0;
cell->parameters[ID::B_SIGNED] = 0;
cell->parameters.erase(ID::WIDTH);
cell->type = ID($or);
cell->type_impl = TW::$or;
} else
cell->type = ID($_OR_);
cell->type_impl = TW::$_OR_;
did_something = true;
goto next_cell;
}
@ -1637,10 +1637,10 @@ skip_identity:
cell->setPort(TW::B, new_b);
cell->setPort(TW::S, new_s);
if (new_s.size() > 1) {
cell->type = ID($pmux);
cell->type_impl = TW::$pmux;
cell->parameters[ID::S_WIDTH] = new_s.size();
} else {
cell->type = ID($mux);
cell->type_impl = TW::$mux;
cell->parameters.erase(ID::S_WIDTH);
}
did_something = true;
@ -1795,7 +1795,7 @@ skip_identity:
if (bit_idx == 1) {
log_debug("Replacing pow cell `%s' in module `%s' with left-shift\n",
cell->name.c_str(), module->design->twines.str(module->meta_->name).c_str());
cell->type = ID($shl);
cell->type_impl = TW::$shl;
cell->parameters[ID::A_WIDTH] = 1;
cell->setPort(TW::A, Const(State::S1, 1));
}
@ -1865,7 +1865,7 @@ skip_identity:
Const new_b = exp;
cell->type = ID($shl);
cell->type_impl = TW::$shl;
cell->parameters[ID::B_WIDTH] = GetSize(new_b);
cell->parameters[ID::B_SIGNED] = false;
cell->setPort(TW::B, new_b);
@ -1946,7 +1946,7 @@ skip_identity:
Const new_b = exp;
cell->type = ID($sshr);
cell->type_impl = TW::$sshr;
cell->parameters[ID::B_WIDTH] = GetSize(new_b);
cell->parameters[ID::B_SIGNED] = false;
cell->setPort(TW::B, new_b);
@ -1996,7 +1996,7 @@ skip_identity:
if (b_signed || exp == 0)
new_b.push_back(State::S0);
cell->type = ID($and);
cell->type_impl = TW::$and;
cell->parameters[ID::B_WIDTH] = GetSize(new_b);
cell->setPort(TW::B, new_b);
cell->check();

View file

@ -242,17 +242,17 @@ struct OptLutInsPass : public Pass {
else
log_assert(GetSize(new_inputs) <= 4);
if (GetSize(new_inputs) == 1)
cell->type = ID(LUT1);
cell->type_impl = TW::LUT1;
else if (GetSize(new_inputs) == 2)
cell->type = ID(LUT2);
cell->type_impl = TW::LUT2;
else if (GetSize(new_inputs) == 3)
cell->type = ID(LUT3);
cell->type_impl = TW::LUT3;
else if (GetSize(new_inputs) == 4)
cell->type = ID(LUT4);
cell->type_impl = TW::LUT4;
else if (GetSize(new_inputs) == 5)
cell->type = ID(LUT5);
cell->type_impl = TW::LUT5;
else if (GetSize(new_inputs) == 6)
cell->type = ID(LUT6);
cell->type_impl = TW::LUT6;
else
log_assert(0);
cell->unsetPort(TW::I0);

View file

@ -332,7 +332,7 @@ struct OptMuxtreeWorker
mi.cell->setPort(TW::B, new_sig_b);
mi.cell->setPort(TW::S, new_sig_s);
if (GetSize(new_sig_s) == 1) {
mi.cell->type = ID($mux);
mi.cell->type_impl = TW::$mux;
mi.cell->parameters.erase(ID::S_WIDTH);
} else {
mi.cell->parameters[ID::S_WIDTH] = RTLIL::Const(GetSize(new_sig_s));

View file

@ -160,7 +160,7 @@ struct OptReduceWorker
if (new_sig_s.size() > 1) {
cell->parameters[ID::S_WIDTH] = RTLIL::Const(new_sig_s.size());
} else {
cell->type = ID($mux);
cell->type_impl = TW::$mux;
cell->parameters.erase(ID::S_WIDTH);
}
}
@ -228,7 +228,7 @@ struct OptReduceWorker
if (new_sig_s.size() == 1)
{
cell->type = ID($mux);
cell->type_impl = TW::$mux;
cell->setPort(TW::A, new_sig_a.extract(0, width));
cell->setPort(TW::B, new_sig_a.extract(width, width));
cell->setPort(TW::S, new_sig_s);

View file

@ -243,8 +243,8 @@ struct WreduceWorker
void run_reduce_inport(Cell *cell, char port, int max_port_size, bool &port_signed, bool &did_something)
{
port_signed = cell->getParam(stringf("\\%c_SIGNED", port)).as_bool();
auto twines = cell->module->design->twines;
SigSpec sig = mi.sigmap(cell->getPort(twines.add(Twine{stringf("\\%c", twines.str(port))})));
auto &twines = cell->module->design->twines;
SigSpec sig = mi.sigmap(cell->getPort(twines.add(Twine{stringf("\\%c", port)})));
if (port == 'B' && cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr)))
port_signed = false;
@ -268,8 +268,8 @@ struct WreduceWorker
if (bits_removed) {
log("Removed top %d bits (of %d) from port %c of cell %s.%s (%s).\n",
bits_removed, GetSize(sig) + bits_removed, port, module, cell, cell->type.unescape());
// SigSpec sig = mi.sigmap(cell->getPort(twines.add(Twine{stringf("\\%c", twines.str(port))})));
cell->setPort(twines.add(Twine{stringf("\\%c", twines.str(port))}), sig);
// SigSpec sig = mi.sigmap(cell->getPort(twines.add(Twine{stringf("\\%c", port)})));
cell->setPort(twines.add(Twine{stringf("\\%c", port)}), sig);
did_something = true;
}
}

View file

@ -292,10 +292,10 @@ struct proc_dlatch_db_t
cell->setPort(TW::A, sig_any_valid_b);
if (GetSize(sig_new_s) == 1) {
cell->type = ID($mux);
cell->type_impl = TW::$mux;
cell->unsetParam(ID::S_WIDTH);
} else {
cell->type = ID($pmux);
cell->type_impl = TW::$pmux;
cell->setParam(ID::S_WIDTH, GetSize(sig_new_s));
}

View file

@ -262,7 +262,7 @@ void append_pmux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::ve
RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw, cs, ifxmode);
log_assert(ctrl_sig.size() == 1);
last_mux_cell->type = ID($pmux);
last_mux_cell->type_impl = TW::$pmux;
RTLIL::SigSpec new_s = last_mux_cell->getPort(TW::S);
new_s.append(ctrl_sig);

View file

@ -194,7 +194,7 @@ void prep_hier(RTLIL::Design *design, bool dff_mode)
// If derived_type is present in unmap_design, it means that it was processed previously, but found to be incompatible -- e.g. if
// it contained a non-zero initial state. In this case, continue to replace the cell type/parameters so that it has the same properties
// as a compatible type, yet will be safely unmapped later
cell->type = derived_type;
cell->type_impl = cell->module->design->twines.add(Twine{derived_type.str()});
cell->parameters.clear();
unused_derived.erase(derived_type);
}
@ -254,7 +254,7 @@ void prep_hier(RTLIL::Design *design, bool dff_mode)
}
}
cell->type = derived_type;
cell->type_impl = cell->module->design->twines.add(Twine{derived_type.str()});
cell->parameters.clear();
unused_derived.erase(derived_type);
}
@ -320,7 +320,7 @@ void prep_bypass(RTLIL::Design *design)
// Copy inst_module into map_design, with the same interface
// and duplicate $abc9$* wires for its output ports
auto map_module = map_design->addModule(cell->type);
auto map_module = map_design->addModule(cell->type.ref());
for (auto port_name : inst_module->ports) {
auto w = map_module->addWire(port_name, inst_module->wire(port_name));
if (w->port_output)
@ -459,7 +459,7 @@ void prep_dff(RTLIL::Design *design)
for (auto module : design->selected_modules())
for (auto cell : module->cells()) {
if (modules_sel.selected_whole_module(cell->type))
if (modules_sel.selected_whole_module(cell->type.ref()))
continue;
auto inst_module = design->module(cell->type);
if (!inst_module)
@ -1402,7 +1402,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
RTLIL::Module* box_module = design->module(existing_cell->type);
log_assert(existing_cell->parameters.empty());
log_assert(mapped_cell->type == stringf("$__boxid%d", box_module->attributes.at(ID::abc9_box_id).as_int()));
mapped_cell->type = existing_cell->type;
mapped_cell->type_impl = existing_cell->type_impl;
RTLIL::Cell *cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type);
cell->parameters = existing_cell->parameters;

View file

@ -628,7 +628,7 @@ void counter_worker(
cell->unsetParam(ID::Y_WIDTH);
//Change the cell type
cell->type = ID($__COUNT_);
cell->type_impl = TW::$__COUNT_;
//Hook up resets
if(extract.has_reset)

View file

@ -44,7 +44,7 @@ struct Lut2BmuxPass : public Pass {
for (auto module : design->selected_modules())
for (auto cell : module->selected_cells()) {
if (cell->type == ID($lut)) {
cell->type = ID($bmux);
cell->type_impl = TW::$bmux;
cell->setPort(TW::S, cell->getPort(TW::A));
cell->setPort(TW::A, cell->getParam(ID::LUT));
cell->unsetParam(ID::LUT);

View file

@ -332,7 +332,7 @@ struct ShregmapWorker
if (opts.ffe) first_cell->setParam(ID(ENPOL), param_enpol);
}
first_cell->type = shreg_cell_type_str;
first_cell->type_impl = first_cell->module->design->twines.add(Twine{shreg_cell_type_str});
first_cell->setPort(q_port, last_cell->getPort(q_port));
first_cell->setParam(ID::DEPTH, depth);

View file

@ -562,7 +562,7 @@ struct TechmapWorker
}
}
cell->type = extmapper_module->name;
cell->type_impl = extmapper_module->meta_->name;
cell->parameters.clear();
if (!extern_mode || in_recursion) {
@ -933,7 +933,7 @@ struct TechmapWorker
}
log_debug("%s %s.%s to imported %s.\n", mapmsg_prefix, module, cell, m_name);
cell->type = m_name;
cell->type_impl = cell->module->design->twines.add(Twine{m_name.str()});
cell->parameters.clear();
}
else

View file

@ -86,7 +86,7 @@ struct TribufWorker {
cell->setPort(en_port, cell->getPort(TW::S));
cell->unsetPort(TW::B);
cell->unsetPort(TW::S);
cell->type = tri_type;
cell->type_impl = cell->module->design->twines.add(Twine{tri_type.str()});
tribuf_cells[sigmap(cell->getPort(TW::Y))].push_back(cell);
module->design->scratchpad_set_bool("tribuf.added_something", true);
continue;
@ -96,7 +96,7 @@ struct TribufWorker {
cell->setPort(en_port, module->Not(NEW_TWINE, cell->getPort(TW::S)));
cell->unsetPort(TW::B);
cell->unsetPort(TW::S);
cell->type = tri_type;
cell->type_impl = cell->module->design->twines.add(Twine{tri_type.str()});
tribuf_cells[sigmap(cell->getPort(TW::Y))].push_back(cell);
module->design->scratchpad_set_bool("tribuf.added_something", true);
continue;

View file

@ -50,22 +50,22 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
int width = 1 + xorshift32(8 * bloat_factor);
int swidth = cell_type == ID($mux) ? 1 : 1 + xorshift32(8);
wire = module->addWire(design->twines.add(Twine{ID::A.str()}));
wire = module->addWire(TW::A);
wire->width = width;
wire->port_input = true;
cell->setPort(TW::A, wire);
wire = module->addWire(design->twines.add(Twine{ID::B.str()}));
wire = module->addWire(TW::B);
wire->width = width * swidth;
wire->port_input = true;
cell->setPort(TW::B, wire);
wire = module->addWire(design->twines.add(Twine{ID::S.str()}));
wire = module->addWire(TW::S);
wire->width = swidth;
wire->port_input = true;
cell->setPort(TW::S, wire);
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
wire = module->addWire(TW::Y);
wire->width = width;
wire->port_output = true;
cell->setPort(TW::Y, wire);
@ -73,22 +73,22 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
if (cell_type.in(ID($_MUX_), ID($_NMUX_)))
{
wire = module->addWire(design->twines.add(Twine{ID::A.str()}));
wire = module->addWire(TW::A);
wire->width = 1;
wire->port_input = true;
cell->setPort(TW::A, wire);
wire = module->addWire(design->twines.add(Twine{ID::B.str()}));
wire = module->addWire(TW::B);
wire->width = 1;
wire->port_input = true;
cell->setPort(TW::B, wire);
wire = module->addWire(design->twines.add(Twine{ID::S.str()}));
wire = module->addWire(TW::S);
wire->width = 1;
wire->port_input = true;
cell->setPort(TW::S, wire);
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
wire = module->addWire(TW::Y);
wire->width = 1;
wire->port_output = true;
cell->setPort(TW::Y, wire);
@ -99,17 +99,17 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
int width = 1 + xorshift32(8 * bloat_factor);
int swidth = 1 + xorshift32(4 * bloat_factor);
wire = module->addWire(design->twines.add(Twine{ID::A.str()}));
wire = module->addWire(TW::A);
wire->width = width << swidth;
wire->port_input = true;
cell->setPort(TW::A, wire);
wire = module->addWire(design->twines.add(Twine{ID::S.str()}));
wire = module->addWire(TW::S);
wire->width = swidth;
wire->port_input = true;
cell->setPort(TW::S, wire);
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
wire = module->addWire(TW::Y);
wire->width = width;
wire->port_output = true;
cell->setPort(TW::Y, wire);
@ -120,17 +120,17 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
int width = 1 + xorshift32(8 * bloat_factor);
int swidth = 1 + xorshift32(6 * bloat_factor);
wire = module->addWire(design->twines.add(Twine{ID::A.str()}));
wire = module->addWire(TW::A);
wire->width = width;
wire->port_input = true;
cell->setPort(TW::A, wire);
wire = module->addWire(design->twines.add(Twine{ID::S.str()}));
wire = module->addWire(TW::S);
wire->width = swidth;
wire->port_input = true;
cell->setPort(TW::S, wire);
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
wire = module->addWire(TW::Y);
wire->width = width << swidth;
wire->port_output = true;
cell->setPort(TW::Y, wire);
@ -140,27 +140,27 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
{
int width = 1 + xorshift32(8 * bloat_factor);
wire = module->addWire(design->twines.add(Twine{ID::A.str()}));
wire = module->addWire(TW::A);
wire->width = width;
wire->port_input = true;
cell->setPort(TW::A, wire);
wire = module->addWire(design->twines.add(Twine{ID::B.str()}));
wire = module->addWire(TW::B);
wire->width = width;
wire->port_input = true;
cell->setPort(TW::B, wire);
wire = module->addWire(design->twines.add(Twine{ID::C.str()}));
wire = module->addWire(TW::C);
wire->width = width;
wire->port_input = true;
cell->setPort(TW::C, wire);
wire = module->addWire(design->twines.add(Twine{ID::X.str()}));
wire = module->addWire(TW::X);
wire->width = width;
wire->port_output = true;
cell->setPort(TW::X, wire);
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
wire = module->addWire(TW::Y);
wire->width = width;
wire->port_output = true;
cell->setPort(TW::Y, wire);
@ -170,21 +170,21 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
{
int width = 1 + xorshift32(8 * bloat_factor);
wire = module->addWire(design->twines.add(Twine{ID::P.str()}));
wire = module->addWire(TW::P);
wire->width = width;
wire->port_input = true;
cell->setPort(TW::P, wire);
wire = module->addWire(design->twines.add(Twine{ID::G.str()}));
wire = module->addWire(TW::G);
wire->width = width;
wire->port_input = true;
cell->setPort(TW::G, wire);
wire = module->addWire(design->twines.add(Twine{ID::CI.str()}));
wire = module->addWire(TW::CI);
wire->port_input = true;
cell->setPort(TW::CI, wire);
wire = module->addWire(design->twines.add(Twine{ID::CO.str()}));
wire = module->addWire(TW::CO);
wire->width = width;
wire->port_output = true;
cell->setPort(TW::CO, wire);
@ -197,7 +197,7 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
int depth = 1 + xorshift32(6);
int mulbits_a = 0, mulbits_b = 0;
RTLIL::Wire *wire_a = module->addWire(design->twines.add(Twine{ID::A.str()}));
RTLIL::Wire *wire_a = module->addWire(TW::A);
wire_a->width = 0;
wire_a->port_input = true;
@ -228,7 +228,7 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
// Macc::to_cell sets the input ports
macc.to_cell(cell);
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
wire = module->addWire(TW::Y);
wire->width = width;
wire->port_output = true;
cell->setPort(TW::Y, wire);
@ -238,12 +238,12 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
{
int width = 1 + xorshift32(6 * bloat_factor);
wire = module->addWire(design->twines.add(Twine{ID::A.str()}));
wire = module->addWire(TW::A);
wire->width = width;
wire->port_input = true;
cell->setPort(TW::A, wire);
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
wire = module->addWire(TW::Y);
wire->port_output = true;
cell->setPort(TW::Y, wire);
@ -259,12 +259,12 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
int width = 1 + xorshift32(8 * bloat_factor);
int depth = 1 + xorshift32(8 * bloat_factor);
wire = module->addWire(design->twines.add(Twine{ID::A.str()}));
wire = module->addWire(TW::A);
wire->width = width;
wire->port_input = true;
cell->setPort(TW::A, wire);
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
wire = module->addWire(TW::Y);
wire->port_output = true;
cell->setPort(TW::Y, wire);
@ -290,7 +290,7 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
}
if (cell_type_flags.find('A') != std::string::npos) {
wire = module->addWire(design->twines.add(Twine{ID::A.str()}));
wire = module->addWire(TW::A);
if (cell_type_flags.find('b') != std::string::npos)
wire->width = 1;
else
@ -300,7 +300,7 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
}
if (cell_type_flags.find('B') != std::string::npos) {
wire = module->addWire(design->twines.add(Twine{ID::B.str()}));
wire = module->addWire(TW::B);
if (cell_type_flags.find('b') != std::string::npos)
wire->width = 1;
else if (cell_type_flags.find('h') != std::string::npos)
@ -312,7 +312,7 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
}
if (cell_type_flags.find('C') != std::string::npos) {
wire = module->addWire(design->twines.add(Twine{ID::C.str()}));
wire = module->addWire(TW::C);
if (cell_type_flags.find('b') != std::string::npos)
wire->width = 1;
else
@ -322,7 +322,7 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
}
if (cell_type_flags.find('D') != std::string::npos) {
wire = module->addWire(design->twines.add(Twine{ID::D.str()}));
wire = module->addWire(TW::D);
if (cell_type_flags.find('b') != std::string::npos)
wire->width = 1;
else
@ -346,7 +346,7 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
}
if (cell_type_flags.find('Y') != std::string::npos) {
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
wire = module->addWire(TW::Y);
if (cell_type_flags.find('b') != std::string::npos)
wire->width = 1;
else
@ -372,20 +372,20 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
if (cell_type == ID($alu))
{
wire = module->addWire(design->twines.add(Twine{ID::CI.str()}));
wire = module->addWire(TW::CI);
wire->port_input = true;
cell->setPort(TW::CI, wire);
wire = module->addWire(design->twines.add(Twine{ID::BI.str()}));
wire = module->addWire(TW::BI);
wire->port_input = true;
cell->setPort(TW::BI, wire);
wire = module->addWire(design->twines.add(Twine{ID::X.str()}));
wire = module->addWire(TW::X);
wire->width = GetSize(cell->getPort(TW::Y));
wire->port_output = true;
cell->setPort(TW::X, wire);
wire = module->addWire(design->twines.add(Twine{ID::CO.str()}));
wire = module->addWire(TW::CO);
wire->width = GetSize(cell->getPort(TW::Y));
wire->port_output = true;
cell->setPort(TW::CO, wire);
@ -397,7 +397,7 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
int y_size = 1;
if (a_size > 1)
y_size += (xorshift32(8 * bloat_factor) % (a_size - 1));
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
wire = module->addWire(TW::Y);
wire->width = y_size;
wire->port_output = true;
cell->setPort(TW::Y, wire);
@ -409,7 +409,7 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
if (cell_type == ID($concat))
{
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
wire = module->addWire(TW::Y);
wire->width = GetSize(cell->getPort(TW::A)) + GetSize(cell->getPort(TW::B));
wire->port_output = true;
cell->setPort(TW::Y, wire);
@ -417,7 +417,7 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
if (cell_type == ID($buf))
{
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
wire = module->addWire(TW::Y);
wire->width = GetSize(cell->getPort(TW::A));
wire->port_output = true;
cell->setPort(TW::Y, wire);
@ -426,18 +426,18 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
if (cell_type.in(ID($bwmux), ID($bweqx)))
{
int a_size = GetSize(cell->getPort(TW::A));
wire = module->addWire(design->twines.add(Twine{ID::B.str()}));
wire = module->addWire(TW::B);
wire->width = a_size;
wire->port_input = true;
cell->setPort(TW::B, wire);
if (cell_type == ID($bwmux))
{
wire = module->addWire(design->twines.add(Twine{ID::S.str()}));
wire = module->addWire(TW::S);
wire->width = a_size;
wire->port_input = true;
cell->setPort(TW::S, wire);
}
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
wire = module->addWire(TW::Y);
wire->width = a_size;
wire->port_output = true;
cell->setPort(TW::Y, wire);

View file

@ -44,7 +44,7 @@ static void create_ql_macc_dsp(ql_dsp_macc_pm &pm)
log_assert(ab_signed == st.mul->getParam(ID(B_SIGNED)).as_bool());
// Determine DSP type or discard if too narrow / wide
RTLIL::IdString type;
TwineRef type;
size_t tgt_a_width;
size_t tgt_b_width;
size_t tgt_z_width;