mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-19 05:35:47 +00:00
WIP
This commit is contained in:
parent
8e522b08c0
commit
afdae7b87e
49 changed files with 1258 additions and 891 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
604
kernel/rtlil.cc
604
kernel/rtlil.cc
File diff suppressed because it is too large
Load diff
205
kernel/rtlil.h
205
kernel/rtlil.h
|
|
@ -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> ¶meters, bool mayfail = false);
|
||||
virtual RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, 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> ¶meters, bool mayfail = false);
|
||||
virtual TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, 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) {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
209
kernel/twine.h
209
kernel/twine.h
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue