mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-15 03:35:40 +00:00
WIP
This commit is contained in:
parent
8e522b08c0
commit
afdae7b87e
49 changed files with 1258 additions and 891 deletions
|
|
@ -174,14 +174,14 @@ struct Scheduler {
|
|||
}
|
||||
};
|
||||
|
||||
bool is_unary_cell(RTLIL::IdString type)
|
||||
bool is_unary_cell(TwineRef type)
|
||||
{
|
||||
return type.in(
|
||||
ID($not), ID($logic_not), ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool),
|
||||
ID($pos), ID($neg));
|
||||
}
|
||||
|
||||
bool is_binary_cell(RTLIL::IdString type)
|
||||
bool is_binary_cell(TwineRef type)
|
||||
{
|
||||
return type.in(
|
||||
ID($and), ID($or), ID($xor), ID($xnor), ID($logic_and), ID($logic_or),
|
||||
|
|
@ -190,20 +190,20 @@ bool is_binary_cell(RTLIL::IdString type)
|
|||
ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($modfloor), ID($divfloor));
|
||||
}
|
||||
|
||||
bool is_extending_cell(RTLIL::IdString type)
|
||||
bool is_extending_cell(TwineRef type)
|
||||
{
|
||||
return !type.in(
|
||||
ID($logic_not), ID($logic_and), ID($logic_or),
|
||||
ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool));
|
||||
}
|
||||
|
||||
bool is_inlinable_cell(RTLIL::IdString type)
|
||||
bool is_inlinable_cell(TwineRef type)
|
||||
{
|
||||
return is_unary_cell(type) || is_binary_cell(type) || type.in(
|
||||
ID($mux), ID($concat), ID($slice), ID($pmux), ID($bmux), ID($demux), ID($bwmux));
|
||||
}
|
||||
|
||||
bool is_ff_cell(RTLIL::IdString type)
|
||||
bool is_ff_cell(TwineRef type)
|
||||
{
|
||||
return type.in(
|
||||
ID($dff), ID($dffe), ID($sdff), ID($sdffe), ID($sdffce),
|
||||
|
|
@ -212,12 +212,12 @@ bool is_ff_cell(RTLIL::IdString type)
|
|||
ID($dlatch), ID($adlatch), ID($dlatchsr), ID($sr));
|
||||
}
|
||||
|
||||
bool is_internal_cell(RTLIL::IdString type)
|
||||
bool is_internal_cell(TwineRef type)
|
||||
{
|
||||
return !type.isPublic() && !type.begins_with("$paramod");
|
||||
}
|
||||
|
||||
bool is_effectful_cell(RTLIL::IdString type)
|
||||
bool is_effectful_cell(TwineRef type)
|
||||
{
|
||||
return type.in(ID($print), ID($check));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -264,9 +264,9 @@ struct Xaiger2Frontend : public Frontend {
|
|||
log_debug("M: len=%u no_cells=%u no_instances=%u\n", len, no_cells, no_instances);
|
||||
|
||||
struct MappingCell {
|
||||
RTLIL::IdString type;
|
||||
TwineRef type;
|
||||
RTLIL::IdString out;
|
||||
std::vector<RTLIL::IdString> ins;
|
||||
std::vector<TwineRef ins;
|
||||
};
|
||||
std::vector<MappingCell> cells;
|
||||
cells.resize(no_cells);
|
||||
|
|
|
|||
|
|
@ -396,14 +396,14 @@ namespace AST
|
|||
struct AstModule : RTLIL::Module {
|
||||
std::unique_ptr<AstNode> ast;
|
||||
bool nolatches, nomeminit, nomem2reg, mem2reg, noblackbox, lib, nowb, noopt, icells, pwires, autowire;
|
||||
RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool mayfail) override;
|
||||
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) override;
|
||||
TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool mayfail) override;
|
||||
TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, const dict<TwineRef, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail) override;
|
||||
std::string derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, std::unique_ptr<AstNode>* new_ast_out, bool quiet = false);
|
||||
void expand_interfaces(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces) override;
|
||||
bool reprocess_if_necessary(RTLIL::Design *design) override;
|
||||
RTLIL::Module *clone() const override;
|
||||
RTLIL::Module *clone(RTLIL::Design *dst, bool src_id_verbatim = false) const override;
|
||||
RTLIL::Module *clone(RTLIL::Design *dst, RTLIL::IdString target_name, bool src_id_verbatim = false) const override;
|
||||
RTLIL::Module *clone(RTLIL::Design *dst, TwineRef target_name, bool src_id_verbatim = false) const override;
|
||||
void loadconfig() const;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2191,9 +2191,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
for (auto it = children.begin(); it != children.end(); it++) {
|
||||
auto* child = it->get();
|
||||
if (child->type == AST_CELLTYPE) {
|
||||
cell->type = child->str;
|
||||
if (flag_icells && cell->type.begins_with("\\$"))
|
||||
cell->type = cell->type.substr(1);
|
||||
std::string type_str = child->str;
|
||||
if (flag_icells && type_str.size() >= 2 && type_str[0] == '\\' && type_str[1] == '$')
|
||||
type_str = type_str.substr(1);
|
||||
cell->type_impl = current_module->design->twines.add(Twine{type_str});
|
||||
continue;
|
||||
}
|
||||
if (child->type == AST_PARASET) {
|
||||
|
|
|
|||
|
|
@ -277,21 +277,21 @@ static void create_ff(RTLIL::Module *module, const LibertyAst *node)
|
|||
cell->setPort(TW::C, clk_sig);
|
||||
|
||||
if (clear_sig.size() == 0 && preset_sig.size() == 0) {
|
||||
cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N');
|
||||
cell->type_impl = module->design->twines.add(Twine{stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N')});
|
||||
}
|
||||
|
||||
if (clear_sig.size() == 1 && preset_sig.size() == 0) {
|
||||
cell->type = stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N');
|
||||
cell->type_impl = module->design->twines.add(Twine{stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N')});
|
||||
cell->setPort(TW::R, clear_sig);
|
||||
}
|
||||
|
||||
if (clear_sig.size() == 0 && preset_sig.size() == 1) {
|
||||
cell->type = stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N');
|
||||
cell->type_impl = module->design->twines.add(Twine{stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N')});
|
||||
cell->setPort(TW::R, preset_sig);
|
||||
}
|
||||
|
||||
if (clear_sig.size() == 1 && preset_sig.size() == 1) {
|
||||
cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N');
|
||||
cell->type_impl = module->design->twines.add(Twine{stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N')});
|
||||
|
||||
SigBit s_sig = preset_sig;
|
||||
SigBit r_sig = clear_sig;
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ struct RpcModule : RTLIL::Module {
|
|||
for (auto module : derived_design->modules())
|
||||
for (auto cell : module->cells())
|
||||
if (name_mangling.count(cell->type.str()))
|
||||
cell->type = name_mangling[cell->type.str()];
|
||||
cell->type_impl = cell->module->design->twines.add(Twine{name_mangling[cell->type.str()]});
|
||||
|
||||
for (auto module : derived_design->modules_) {
|
||||
std::string mangled_name = name_mangling[derived_design->twines.str(module.first)];
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ struct BoxDerivePass : Pass {
|
|||
}
|
||||
|
||||
if (apply_mode)
|
||||
cell->type = RTLIL::IdString(done[index]->design->twines.str(done[index]->meta_->name));
|
||||
cell->type_impl = cell->module->design->twines.copy_from(done[index]->design->twines, done[index]->meta_->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ static RTLIL::IdString formal_flavor(RTLIL::Cell *cell)
|
|||
static void set_formal_flavor(RTLIL::Cell *cell, RTLIL::IdString flavor)
|
||||
{
|
||||
if (cell->type != ID($check)) {
|
||||
cell->type = flavor;
|
||||
cell->type_impl = cell->module->design->twines.add(Twine{flavor.str()});
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -441,7 +441,7 @@ struct ChformalPass : public Pass {
|
|||
if (cell->getPort(TW::ARGS).empty()) {
|
||||
module->remove(cell);
|
||||
} else {
|
||||
cell->type = ID($print);
|
||||
cell->type_impl = TW::$print;
|
||||
cell->setPort(TW::EN, combined_en);
|
||||
cell->unsetPort(TW::A);
|
||||
cell->unsetParam(ID(FLAVOR));
|
||||
|
|
|
|||
|
|
@ -38,7 +38,9 @@ static void publish_design(RTLIL::Design* design) {
|
|||
publish(new_name);
|
||||
design->modules_[mod->meta_->name] = mod;
|
||||
for (auto* cell : mod->cells()) {
|
||||
publish(cell->type);
|
||||
IdString ct = cell->type;
|
||||
if (ct.begins_with("$"))
|
||||
cell->type_impl = cell->module->design->twines.add(Twine{"\\" + ct.str()});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -100,12 +102,12 @@ struct ChtypePass : public Pass {
|
|||
for (auto cell : module->selected_cells())
|
||||
{
|
||||
if (map_types.count(cell->type)) {
|
||||
cell->type = map_types.at(cell->type);
|
||||
cell->type_impl = cell->module->design->twines.add(Twine{map_types.at(cell->type).str()});
|
||||
continue;
|
||||
}
|
||||
|
||||
if (set_type != IdString()) {
|
||||
cell->type = set_type;
|
||||
cell->type_impl = cell->module->design->twines.add(Twine{set_type.str()});
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ struct DesignPass : public Pass {
|
|||
done[cell->type] = trg_name;
|
||||
}
|
||||
|
||||
cell->type = done.at(cell->type);
|
||||
cell->type_impl = cell->module->design->twines.add(Twine{done.at(cell->type).str()});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ struct DftTagWorker {
|
|||
log_debug("Applying $overwrite_tag %s for signal %s\n", cell->module->design->twines.str(cell->meta_->name), log_signal(cell->getPort(TW::A)));
|
||||
SigSpec orig_signal = cell->getPort(TW::A);
|
||||
SigSpec interposed_signal = divert_users(orig_signal);
|
||||
auto *set_tag_cell = module->addSetTag(module->design->twines.add(NEW_TWINE), cell->getParam(ID::TAG).decode_string(), orig_signal, cell->getPort(TW::SET), cell->getPort(TW::CLR), interposed_signal);
|
||||
auto *set_tag_cell = module->addSetTag(NEW_TWINE, cell->getParam(ID::TAG).decode_string(), orig_signal, cell->getPort(TW::SET), cell->getPort(TW::CLR), interposed_signal);
|
||||
modwalker.add_cell(set_tag_cell); // Make sure the next $overwrite_tag sees the new connections
|
||||
design_changed = true;
|
||||
}
|
||||
|
|
@ -110,7 +110,7 @@ struct DftTagWorker {
|
|||
module->remove(cell);
|
||||
}
|
||||
for (auto cell : original_cells) {
|
||||
cell->type = ID($get_tag);
|
||||
cell->type_impl = TW::$get_tag;
|
||||
}
|
||||
|
||||
if (design_changed)
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ struct SetparamPass : public Pass {
|
|||
{
|
||||
for (auto cell : module->selected_cells()) {
|
||||
if (!new_cell_type.empty())
|
||||
cell->type = new_cell_type;
|
||||
cell->type_impl = cell->module->design->twines.add(Twine{new_cell_type});
|
||||
do_setunset(cell->parameters, setunset_list);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ PRIVATE_NAMESPACE_BEGIN
|
|||
static RTLIL::Wire * add_wire(RTLIL::Module *module, std::string name, int width, bool flag_input, bool flag_output)
|
||||
{
|
||||
RTLIL::Wire *wire = NULL;
|
||||
name = RTLIL::escape_id(name);
|
||||
TwineRef t = module->design->twines.add(Twine{name});
|
||||
|
||||
if (module->count_id(name) != 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ struct statdata_t {
|
|||
}
|
||||
}
|
||||
|
||||
statdata_t(const RTLIL::Design *design, const RTLIL::Module *mod, bool width_mode, dict<IdString, cell_area_t> &cell_area, string techname)
|
||||
statdata_t(RTLIL::Design *design, const RTLIL::Module *mod, bool width_mode, dict<IdString, cell_area_t> &cell_area, string techname)
|
||||
{
|
||||
tech = techname;
|
||||
|
||||
|
|
@ -239,17 +239,17 @@ struct statdata_t {
|
|||
for (auto &it : cell_data.parameter_names) {
|
||||
TwineRef port_name;
|
||||
if (it == "A") {
|
||||
port_name = ID::A;
|
||||
port_name = TW::A;
|
||||
} else if (it == "B") {
|
||||
port_name = ID::B;
|
||||
port_name = TW::B;
|
||||
} else if (it == "Y") {
|
||||
port_name = ID::Y;
|
||||
port_name = TW::Y;
|
||||
} else if (it == "Q") {
|
||||
port_name = ID::Q;
|
||||
port_name = TW::Q;
|
||||
} else if (it == "S") {
|
||||
port_name = ID::S;
|
||||
port_name = TW::S;
|
||||
} else {
|
||||
port_name = ID(it);
|
||||
port_name = design->twines.add(Twine{it});
|
||||
}
|
||||
if (cell->hasPort(port_name)) {
|
||||
int width = GetSize(cell->getPort(port_name));
|
||||
|
|
@ -744,7 +744,7 @@ statdata_t hierarchy_worker(std::map<RTLIL::IdString, statdata_t> &mod_stat, RTL
|
|||
return mod_data;
|
||||
}
|
||||
|
||||
statdata_t hierarchy_builder(const RTLIL::Design *design, const RTLIL::Module *top_mod, std::map<RTLIL::IdString, statdata_t> &mod_stat,
|
||||
statdata_t hierarchy_builder(RTLIL::Design *design, const RTLIL::Module *top_mod, std::map<RTLIL::IdString, statdata_t> &mod_stat,
|
||||
bool width_mode, dict<IdString, cell_area_t> &cell_area, string techname)
|
||||
{
|
||||
if (top_mod == nullptr)
|
||||
|
|
|
|||
|
|
@ -292,7 +292,7 @@ struct WrapcellPass : Pass {
|
|||
for (auto chunk : collect_chunks(used_outputs))
|
||||
new_connections[chunk.format(cell)] = chunk.sample(cell);
|
||||
|
||||
cell->type = name;
|
||||
cell->type_impl = cell->module->design->twines.add(Twine{name.str()});
|
||||
cell->connections_ = new_connections;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,9 +171,9 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module)
|
|||
|
||||
RTLIL::Cell *state_dff = module->addCell(NEW_TWINE, "");
|
||||
if (fsm_cell->getPort(TW::ARST).is_fully_const()) {
|
||||
state_dff->type = ID($dff);
|
||||
state_dff->type_impl = TW::$dff;
|
||||
} else {
|
||||
state_dff->type = ID($adff);
|
||||
state_dff->type_impl = TW::$adff;
|
||||
state_dff->parameters[ID::ARST_POLARITY] = fsm_cell->parameters[ID::ARST_POLARITY];
|
||||
state_dff->parameters[ID::ARST_VALUE] = fsm_data.state_table[fsm_data.reset_state];
|
||||
for (auto bit : state_dff->parameters[ID::ARST_VALUE])
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ struct IFExpander
|
|||
|
||||
bool has_interfaces_not_found;
|
||||
std::vector<TwineRef> connections_to_remove;
|
||||
std::vector<TwineRef> connections_to_add_name;
|
||||
std::vector<TwineRef> connections_to_add;
|
||||
std::vector<RTLIL::SigSpec> connections_to_add_signal;
|
||||
dict<TwineRef, RTLIL::Module*> interfaces_to_add_to_submodule;
|
||||
dict<TwineRef, RTLIL::IdString> modports_used_in_submodule;
|
||||
|
|
@ -215,7 +215,7 @@ struct IFExpander
|
|||
{
|
||||
has_interfaces_not_found = false;
|
||||
connections_to_remove.clear();
|
||||
connections_to_add_name.clear();
|
||||
connections_to_add.clear();
|
||||
connections_to_add_signal.clear();
|
||||
interfaces_to_add_to_submodule.clear();
|
||||
modports_used_in_submodule.clear();
|
||||
|
|
@ -284,7 +284,7 @@ struct IFExpander
|
|||
for (auto mod_wire : mod_replace_ports->wires()) {
|
||||
std::string signal_name1 = conn_name_str + "." + mod_wire->name.unescape();
|
||||
std::string signal_name2 = interface_name.str() + "." + mod_wire->name.unescape();
|
||||
connections_to_add_name.push_back(design.twines.add(Twine{signal_name1}));
|
||||
connections_to_add.push_back(design.twines.add(Twine{signal_name1}));
|
||||
TwineRef signal_name2_ref = design.twines.lookup(signal_name2);
|
||||
if(module.wire(signal_name2_ref) == nullptr) {
|
||||
log_error("Could not find signal '%s' in '%s'\n",
|
||||
|
|
@ -365,8 +365,8 @@ struct IFExpander
|
|||
// interface port connection with the individual signal connections.
|
||||
void rewrite_interface_connections(RTLIL::Cell &cell) const
|
||||
{
|
||||
for(unsigned int i=0;i<connections_to_add_name.size();i++) {
|
||||
cell.connections_[connections_to_add_name[i]] = connections_to_add_signal[i];
|
||||
for(unsigned int i=0;i<connections_to_add.size();i++) {
|
||||
cell.connections_[connections_to_add[i]] = connections_to_add_signal[i];
|
||||
}
|
||||
// Remove the connection for the interface itself:
|
||||
for(unsigned int i=0;i<connections_to_remove.size();i++) {
|
||||
|
|
@ -391,7 +391,7 @@ RTLIL::Module *get_module(RTLIL::Design &design,
|
|||
std::string cell_type = cell.type.str();
|
||||
RTLIL::Module *abs_mod = design.module("$abstract" + cell_type);
|
||||
if (abs_mod) {
|
||||
cell.type = abs_mod->derive(&design, cell.parameters);
|
||||
cell.type_impl = design.twines.add(Twine{abs_mod->derive(&design, cell.parameters).str()});
|
||||
cell.parameters.clear();
|
||||
RTLIL::Module *mod = design.module(cell.type);
|
||||
log_assert(mod);
|
||||
|
|
@ -514,7 +514,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
|
|||
int idx = atoi(cell->type.substr(pos_idx + 1, pos_num).c_str());
|
||||
int num = atoi(cell->type.substr(pos_num + 1, pos_type).c_str());
|
||||
array_cells[cell] = std::pair<int, int>(idx, num);
|
||||
cell->type = cell->type.substr(pos_type + 1);
|
||||
cell->type_impl = cell->module->design->twines.add(Twine{cell->type.str().substr(pos_type + 1)});
|
||||
}
|
||||
|
||||
dict<RTLIL::IdString, RTLIL::Module*> interfaces_by_name;
|
||||
|
|
@ -576,10 +576,10 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
|
|||
interfaces_by_name[RTLIL::IdString(design->twines.str(p.first))] = p.second;
|
||||
for (auto &p : if_expander.modports_used_in_submodule)
|
||||
modports_by_name[RTLIL::IdString(design->twines.str(p.first))] = p.second;
|
||||
cell->type = mod->derive(design,
|
||||
cell->type_impl = design->twines.add(Twine{mod->derive(design,
|
||||
cell->parameters,
|
||||
interfaces_by_name,
|
||||
modports_by_name);
|
||||
modports_by_name).str()});
|
||||
cell->parameters.clear();
|
||||
did_something = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ struct UniquifyPass : public Pass {
|
|||
|
||||
auto smod = tmod->clone();
|
||||
smod->meta_->name = newname_ref;
|
||||
cell->type = newname;
|
||||
cell->type_impl = cell->module->design->twines.add(Twine{newname.str()});
|
||||
smod->set_bool_attribute(ID::unique);
|
||||
if (smod->attributes.count(ID::hdlname) == 0)
|
||||
smod->attributes[ID::hdlname] = RTLIL::Const(tmod_name_str);
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ struct MuxpackWorker
|
|||
mux_count += cases;
|
||||
pmux_count += 1;
|
||||
|
||||
first_cell->type = ID($pmux);
|
||||
first_cell->type_impl = TW::$pmux;
|
||||
SigSpec b_sig = first_cell->getPort(TW::B);
|
||||
SigSpec s_sig = first_cell->getPort(TW::S);
|
||||
|
||||
|
|
|
|||
|
|
@ -159,9 +159,9 @@ void demorgan_worker(
|
|||
|
||||
//Change the cell type
|
||||
if(cell->type == ID($reduce_and))
|
||||
cell->type = ID($reduce_or);
|
||||
cell->type_impl = TW::$reduce_or;
|
||||
else if(cell->type == ID($reduce_or))
|
||||
cell->type = ID($reduce_and);
|
||||
cell->type_impl = TW::$reduce_and;
|
||||
//don't change XOR
|
||||
|
||||
//Add an inverter to the output
|
||||
|
|
|
|||
|
|
@ -419,7 +419,7 @@ void handle_clkpol_celltype_swap(Cell *cell, string type1, string type2, TwineRe
|
|||
IdString(RTLIL::StaticId(port)).unescape(), cell->type.unescape(), cell, cell->module,
|
||||
log_signal(sig), log_signal(new_sig));
|
||||
cell->setPort(port, new_sig);
|
||||
cell->type = cell->type == type1 ? type2 : type1;
|
||||
cell->type_impl = cell->module->design->twines.add(Twine{cell->type == type1 ? type2 : type1});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -715,7 +715,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
|
|||
if (cell->type == ID($reduce_xnor)) {
|
||||
log_debug("Replacing %s cell `%s' in module `%s' with $not cell.\n",
|
||||
cell->type.unescape(), cell->module->design->twines.str(cell->meta_->name), module);
|
||||
cell->type = ID($not);
|
||||
cell->type_impl = TW::$not;
|
||||
did_something = true;
|
||||
} else {
|
||||
OptExprPatcher patcher(module, &assign_map);
|
||||
|
|
@ -1235,7 +1235,7 @@ skip_fine_alu:
|
|||
cell->setPort(TW::A, input.extract(0, 1));
|
||||
cell->unsetPort(TW::B);
|
||||
cell->unsetPort(TW::S);
|
||||
cell->type = ID($_NOT_);
|
||||
cell->type_impl = TW::$_NOT_;
|
||||
goto next_cell;
|
||||
}
|
||||
if (input.match("11 ")) ACTION_DO_Y(1);
|
||||
|
|
@ -1340,7 +1340,7 @@ skip_fine_alu:
|
|||
cell->parameters.erase(ID::B_WIDTH);
|
||||
cell->parameters.erase(ID::B_SIGNED);
|
||||
cell->unsetPort(TW::B);
|
||||
cell->type = ID($not);
|
||||
cell->type_impl = TW::$not;
|
||||
did_something = true;
|
||||
}
|
||||
goto next_cell;
|
||||
|
|
@ -1360,7 +1360,7 @@ skip_fine_alu:
|
|||
cell->unsetPort(TW::B);
|
||||
cell->unsetParam(ID::B_SIGNED);
|
||||
cell->unsetParam(ID::B_WIDTH);
|
||||
cell->type = cell->type == ID($eq) ? ID($logic_not) : ID($reduce_bool);
|
||||
cell->type_impl = (cell->type == ID($eq)) ? TW::$logic_not : TW::$reduce_bool;
|
||||
did_something = true;
|
||||
goto next_cell;
|
||||
}
|
||||
|
|
@ -1524,7 +1524,7 @@ skip_fine_alu:
|
|||
cell->unsetPort(TW::B);
|
||||
cell->parameters.erase(ID::B_WIDTH);
|
||||
cell->parameters.erase(ID::B_SIGNED);
|
||||
cell->type = arith_inverse ? ID($neg) : ID($pos);
|
||||
cell->type_impl = arith_inverse ? TW::$neg : TW::$pos;
|
||||
cell->check();
|
||||
|
||||
did_something = true;
|
||||
|
|
@ -1552,9 +1552,9 @@ skip_identity:
|
|||
cell->parameters[ID::Y_WIDTH] = width;
|
||||
cell->parameters[ID::A_SIGNED] = 0;
|
||||
cell->parameters.erase(ID::WIDTH);
|
||||
cell->type = ID($not);
|
||||
cell->type_impl = TW::$not;
|
||||
} else
|
||||
cell->type = ID($_NOT_);
|
||||
cell->type_impl = TW::$_NOT_;
|
||||
did_something = true;
|
||||
goto next_cell;
|
||||
}
|
||||
|
|
@ -1571,9 +1571,9 @@ skip_identity:
|
|||
cell->parameters[ID::A_SIGNED] = 0;
|
||||
cell->parameters[ID::B_SIGNED] = 0;
|
||||
cell->parameters.erase(ID::WIDTH);
|
||||
cell->type = ID($and);
|
||||
cell->type_impl = TW::$and;
|
||||
} else
|
||||
cell->type = ID($_AND_);
|
||||
cell->type_impl = TW::$_AND_;
|
||||
did_something = true;
|
||||
goto next_cell;
|
||||
}
|
||||
|
|
@ -1590,9 +1590,9 @@ skip_identity:
|
|||
cell->parameters[ID::A_SIGNED] = 0;
|
||||
cell->parameters[ID::B_SIGNED] = 0;
|
||||
cell->parameters.erase(ID::WIDTH);
|
||||
cell->type = ID($or);
|
||||
cell->type_impl = TW::$or;
|
||||
} else
|
||||
cell->type = ID($_OR_);
|
||||
cell->type_impl = TW::$_OR_;
|
||||
did_something = true;
|
||||
goto next_cell;
|
||||
}
|
||||
|
|
@ -1637,10 +1637,10 @@ skip_identity:
|
|||
cell->setPort(TW::B, new_b);
|
||||
cell->setPort(TW::S, new_s);
|
||||
if (new_s.size() > 1) {
|
||||
cell->type = ID($pmux);
|
||||
cell->type_impl = TW::$pmux;
|
||||
cell->parameters[ID::S_WIDTH] = new_s.size();
|
||||
} else {
|
||||
cell->type = ID($mux);
|
||||
cell->type_impl = TW::$mux;
|
||||
cell->parameters.erase(ID::S_WIDTH);
|
||||
}
|
||||
did_something = true;
|
||||
|
|
@ -1795,7 +1795,7 @@ skip_identity:
|
|||
if (bit_idx == 1) {
|
||||
log_debug("Replacing pow cell `%s' in module `%s' with left-shift\n",
|
||||
cell->name.c_str(), module->design->twines.str(module->meta_->name).c_str());
|
||||
cell->type = ID($shl);
|
||||
cell->type_impl = TW::$shl;
|
||||
cell->parameters[ID::A_WIDTH] = 1;
|
||||
cell->setPort(TW::A, Const(State::S1, 1));
|
||||
}
|
||||
|
|
@ -1865,7 +1865,7 @@ skip_identity:
|
|||
|
||||
Const new_b = exp;
|
||||
|
||||
cell->type = ID($shl);
|
||||
cell->type_impl = TW::$shl;
|
||||
cell->parameters[ID::B_WIDTH] = GetSize(new_b);
|
||||
cell->parameters[ID::B_SIGNED] = false;
|
||||
cell->setPort(TW::B, new_b);
|
||||
|
|
@ -1946,7 +1946,7 @@ skip_identity:
|
|||
|
||||
Const new_b = exp;
|
||||
|
||||
cell->type = ID($sshr);
|
||||
cell->type_impl = TW::$sshr;
|
||||
cell->parameters[ID::B_WIDTH] = GetSize(new_b);
|
||||
cell->parameters[ID::B_SIGNED] = false;
|
||||
cell->setPort(TW::B, new_b);
|
||||
|
|
@ -1996,7 +1996,7 @@ skip_identity:
|
|||
if (b_signed || exp == 0)
|
||||
new_b.push_back(State::S0);
|
||||
|
||||
cell->type = ID($and);
|
||||
cell->type_impl = TW::$and;
|
||||
cell->parameters[ID::B_WIDTH] = GetSize(new_b);
|
||||
cell->setPort(TW::B, new_b);
|
||||
cell->check();
|
||||
|
|
|
|||
|
|
@ -242,17 +242,17 @@ struct OptLutInsPass : public Pass {
|
|||
else
|
||||
log_assert(GetSize(new_inputs) <= 4);
|
||||
if (GetSize(new_inputs) == 1)
|
||||
cell->type = ID(LUT1);
|
||||
cell->type_impl = TW::LUT1;
|
||||
else if (GetSize(new_inputs) == 2)
|
||||
cell->type = ID(LUT2);
|
||||
cell->type_impl = TW::LUT2;
|
||||
else if (GetSize(new_inputs) == 3)
|
||||
cell->type = ID(LUT3);
|
||||
cell->type_impl = TW::LUT3;
|
||||
else if (GetSize(new_inputs) == 4)
|
||||
cell->type = ID(LUT4);
|
||||
cell->type_impl = TW::LUT4;
|
||||
else if (GetSize(new_inputs) == 5)
|
||||
cell->type = ID(LUT5);
|
||||
cell->type_impl = TW::LUT5;
|
||||
else if (GetSize(new_inputs) == 6)
|
||||
cell->type = ID(LUT6);
|
||||
cell->type_impl = TW::LUT6;
|
||||
else
|
||||
log_assert(0);
|
||||
cell->unsetPort(TW::I0);
|
||||
|
|
|
|||
|
|
@ -332,7 +332,7 @@ struct OptMuxtreeWorker
|
|||
mi.cell->setPort(TW::B, new_sig_b);
|
||||
mi.cell->setPort(TW::S, new_sig_s);
|
||||
if (GetSize(new_sig_s) == 1) {
|
||||
mi.cell->type = ID($mux);
|
||||
mi.cell->type_impl = TW::$mux;
|
||||
mi.cell->parameters.erase(ID::S_WIDTH);
|
||||
} else {
|
||||
mi.cell->parameters[ID::S_WIDTH] = RTLIL::Const(GetSize(new_sig_s));
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ struct OptReduceWorker
|
|||
if (new_sig_s.size() > 1) {
|
||||
cell->parameters[ID::S_WIDTH] = RTLIL::Const(new_sig_s.size());
|
||||
} else {
|
||||
cell->type = ID($mux);
|
||||
cell->type_impl = TW::$mux;
|
||||
cell->parameters.erase(ID::S_WIDTH);
|
||||
}
|
||||
}
|
||||
|
|
@ -228,7 +228,7 @@ struct OptReduceWorker
|
|||
|
||||
if (new_sig_s.size() == 1)
|
||||
{
|
||||
cell->type = ID($mux);
|
||||
cell->type_impl = TW::$mux;
|
||||
cell->setPort(TW::A, new_sig_a.extract(0, width));
|
||||
cell->setPort(TW::B, new_sig_a.extract(width, width));
|
||||
cell->setPort(TW::S, new_sig_s);
|
||||
|
|
|
|||
|
|
@ -243,8 +243,8 @@ struct WreduceWorker
|
|||
void run_reduce_inport(Cell *cell, char port, int max_port_size, bool &port_signed, bool &did_something)
|
||||
{
|
||||
port_signed = cell->getParam(stringf("\\%c_SIGNED", port)).as_bool();
|
||||
auto twines = cell->module->design->twines;
|
||||
SigSpec sig = mi.sigmap(cell->getPort(twines.add(Twine{stringf("\\%c", twines.str(port))})));
|
||||
auto &twines = cell->module->design->twines;
|
||||
SigSpec sig = mi.sigmap(cell->getPort(twines.add(Twine{stringf("\\%c", port)})));
|
||||
|
||||
if (port == 'B' && cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr)))
|
||||
port_signed = false;
|
||||
|
|
@ -268,8 +268,8 @@ struct WreduceWorker
|
|||
if (bits_removed) {
|
||||
log("Removed top %d bits (of %d) from port %c of cell %s.%s (%s).\n",
|
||||
bits_removed, GetSize(sig) + bits_removed, port, module, cell, cell->type.unescape());
|
||||
// SigSpec sig = mi.sigmap(cell->getPort(twines.add(Twine{stringf("\\%c", twines.str(port))})));
|
||||
cell->setPort(twines.add(Twine{stringf("\\%c", twines.str(port))}), sig);
|
||||
// SigSpec sig = mi.sigmap(cell->getPort(twines.add(Twine{stringf("\\%c", port)})));
|
||||
cell->setPort(twines.add(Twine{stringf("\\%c", port)}), sig);
|
||||
did_something = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -292,10 +292,10 @@ struct proc_dlatch_db_t
|
|||
cell->setPort(TW::A, sig_any_valid_b);
|
||||
|
||||
if (GetSize(sig_new_s) == 1) {
|
||||
cell->type = ID($mux);
|
||||
cell->type_impl = TW::$mux;
|
||||
cell->unsetParam(ID::S_WIDTH);
|
||||
} else {
|
||||
cell->type = ID($pmux);
|
||||
cell->type_impl = TW::$pmux;
|
||||
cell->setParam(ID::S_WIDTH, GetSize(sig_new_s));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ void append_pmux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::ve
|
|||
|
||||
RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw, cs, ifxmode);
|
||||
log_assert(ctrl_sig.size() == 1);
|
||||
last_mux_cell->type = ID($pmux);
|
||||
last_mux_cell->type_impl = TW::$pmux;
|
||||
|
||||
RTLIL::SigSpec new_s = last_mux_cell->getPort(TW::S);
|
||||
new_s.append(ctrl_sig);
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ void prep_hier(RTLIL::Design *design, bool dff_mode)
|
|||
// If derived_type is present in unmap_design, it means that it was processed previously, but found to be incompatible -- e.g. if
|
||||
// it contained a non-zero initial state. In this case, continue to replace the cell type/parameters so that it has the same properties
|
||||
// as a compatible type, yet will be safely unmapped later
|
||||
cell->type = derived_type;
|
||||
cell->type_impl = cell->module->design->twines.add(Twine{derived_type.str()});
|
||||
cell->parameters.clear();
|
||||
unused_derived.erase(derived_type);
|
||||
}
|
||||
|
|
@ -254,7 +254,7 @@ void prep_hier(RTLIL::Design *design, bool dff_mode)
|
|||
}
|
||||
}
|
||||
|
||||
cell->type = derived_type;
|
||||
cell->type_impl = cell->module->design->twines.add(Twine{derived_type.str()});
|
||||
cell->parameters.clear();
|
||||
unused_derived.erase(derived_type);
|
||||
}
|
||||
|
|
@ -320,7 +320,7 @@ void prep_bypass(RTLIL::Design *design)
|
|||
|
||||
// Copy inst_module into map_design, with the same interface
|
||||
// and duplicate $abc9$* wires for its output ports
|
||||
auto map_module = map_design->addModule(cell->type);
|
||||
auto map_module = map_design->addModule(cell->type.ref());
|
||||
for (auto port_name : inst_module->ports) {
|
||||
auto w = map_module->addWire(port_name, inst_module->wire(port_name));
|
||||
if (w->port_output)
|
||||
|
|
@ -459,7 +459,7 @@ void prep_dff(RTLIL::Design *design)
|
|||
|
||||
for (auto module : design->selected_modules())
|
||||
for (auto cell : module->cells()) {
|
||||
if (modules_sel.selected_whole_module(cell->type))
|
||||
if (modules_sel.selected_whole_module(cell->type.ref()))
|
||||
continue;
|
||||
auto inst_module = design->module(cell->type);
|
||||
if (!inst_module)
|
||||
|
|
@ -1402,7 +1402,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
|
|||
RTLIL::Module* box_module = design->module(existing_cell->type);
|
||||
log_assert(existing_cell->parameters.empty());
|
||||
log_assert(mapped_cell->type == stringf("$__boxid%d", box_module->attributes.at(ID::abc9_box_id).as_int()));
|
||||
mapped_cell->type = existing_cell->type;
|
||||
mapped_cell->type_impl = existing_cell->type_impl;
|
||||
|
||||
RTLIL::Cell *cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type);
|
||||
cell->parameters = existing_cell->parameters;
|
||||
|
|
|
|||
|
|
@ -628,7 +628,7 @@ void counter_worker(
|
|||
cell->unsetParam(ID::Y_WIDTH);
|
||||
|
||||
//Change the cell type
|
||||
cell->type = ID($__COUNT_);
|
||||
cell->type_impl = TW::$__COUNT_;
|
||||
|
||||
//Hook up resets
|
||||
if(extract.has_reset)
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ struct Lut2BmuxPass : public Pass {
|
|||
for (auto module : design->selected_modules())
|
||||
for (auto cell : module->selected_cells()) {
|
||||
if (cell->type == ID($lut)) {
|
||||
cell->type = ID($bmux);
|
||||
cell->type_impl = TW::$bmux;
|
||||
cell->setPort(TW::S, cell->getPort(TW::A));
|
||||
cell->setPort(TW::A, cell->getParam(ID::LUT));
|
||||
cell->unsetParam(ID::LUT);
|
||||
|
|
|
|||
|
|
@ -332,7 +332,7 @@ struct ShregmapWorker
|
|||
if (opts.ffe) first_cell->setParam(ID(ENPOL), param_enpol);
|
||||
}
|
||||
|
||||
first_cell->type = shreg_cell_type_str;
|
||||
first_cell->type_impl = first_cell->module->design->twines.add(Twine{shreg_cell_type_str});
|
||||
first_cell->setPort(q_port, last_cell->getPort(q_port));
|
||||
first_cell->setParam(ID::DEPTH, depth);
|
||||
|
||||
|
|
|
|||
|
|
@ -562,7 +562,7 @@ struct TechmapWorker
|
|||
}
|
||||
}
|
||||
|
||||
cell->type = extmapper_module->name;
|
||||
cell->type_impl = extmapper_module->meta_->name;
|
||||
cell->parameters.clear();
|
||||
|
||||
if (!extern_mode || in_recursion) {
|
||||
|
|
@ -933,7 +933,7 @@ struct TechmapWorker
|
|||
}
|
||||
|
||||
log_debug("%s %s.%s to imported %s.\n", mapmsg_prefix, module, cell, m_name);
|
||||
cell->type = m_name;
|
||||
cell->type_impl = cell->module->design->twines.add(Twine{m_name.str()});
|
||||
cell->parameters.clear();
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ struct TribufWorker {
|
|||
cell->setPort(en_port, cell->getPort(TW::S));
|
||||
cell->unsetPort(TW::B);
|
||||
cell->unsetPort(TW::S);
|
||||
cell->type = tri_type;
|
||||
cell->type_impl = cell->module->design->twines.add(Twine{tri_type.str()});
|
||||
tribuf_cells[sigmap(cell->getPort(TW::Y))].push_back(cell);
|
||||
module->design->scratchpad_set_bool("tribuf.added_something", true);
|
||||
continue;
|
||||
|
|
@ -96,7 +96,7 @@ struct TribufWorker {
|
|||
cell->setPort(en_port, module->Not(NEW_TWINE, cell->getPort(TW::S)));
|
||||
cell->unsetPort(TW::B);
|
||||
cell->unsetPort(TW::S);
|
||||
cell->type = tri_type;
|
||||
cell->type_impl = cell->module->design->twines.add(Twine{tri_type.str()});
|
||||
tribuf_cells[sigmap(cell->getPort(TW::Y))].push_back(cell);
|
||||
module->design->scratchpad_set_bool("tribuf.added_something", true);
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -50,22 +50,22 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
|
|||
int width = 1 + xorshift32(8 * bloat_factor);
|
||||
int swidth = cell_type == ID($mux) ? 1 : 1 + xorshift32(8);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::A.str()}));
|
||||
wire = module->addWire(TW::A);
|
||||
wire->width = width;
|
||||
wire->port_input = true;
|
||||
cell->setPort(TW::A, wire);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::B.str()}));
|
||||
wire = module->addWire(TW::B);
|
||||
wire->width = width * swidth;
|
||||
wire->port_input = true;
|
||||
cell->setPort(TW::B, wire);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::S.str()}));
|
||||
wire = module->addWire(TW::S);
|
||||
wire->width = swidth;
|
||||
wire->port_input = true;
|
||||
cell->setPort(TW::S, wire);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
|
||||
wire = module->addWire(TW::Y);
|
||||
wire->width = width;
|
||||
wire->port_output = true;
|
||||
cell->setPort(TW::Y, wire);
|
||||
|
|
@ -73,22 +73,22 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
|
|||
|
||||
if (cell_type.in(ID($_MUX_), ID($_NMUX_)))
|
||||
{
|
||||
wire = module->addWire(design->twines.add(Twine{ID::A.str()}));
|
||||
wire = module->addWire(TW::A);
|
||||
wire->width = 1;
|
||||
wire->port_input = true;
|
||||
cell->setPort(TW::A, wire);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::B.str()}));
|
||||
wire = module->addWire(TW::B);
|
||||
wire->width = 1;
|
||||
wire->port_input = true;
|
||||
cell->setPort(TW::B, wire);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::S.str()}));
|
||||
wire = module->addWire(TW::S);
|
||||
wire->width = 1;
|
||||
wire->port_input = true;
|
||||
cell->setPort(TW::S, wire);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
|
||||
wire = module->addWire(TW::Y);
|
||||
wire->width = 1;
|
||||
wire->port_output = true;
|
||||
cell->setPort(TW::Y, wire);
|
||||
|
|
@ -99,17 +99,17 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
|
|||
int width = 1 + xorshift32(8 * bloat_factor);
|
||||
int swidth = 1 + xorshift32(4 * bloat_factor);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::A.str()}));
|
||||
wire = module->addWire(TW::A);
|
||||
wire->width = width << swidth;
|
||||
wire->port_input = true;
|
||||
cell->setPort(TW::A, wire);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::S.str()}));
|
||||
wire = module->addWire(TW::S);
|
||||
wire->width = swidth;
|
||||
wire->port_input = true;
|
||||
cell->setPort(TW::S, wire);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
|
||||
wire = module->addWire(TW::Y);
|
||||
wire->width = width;
|
||||
wire->port_output = true;
|
||||
cell->setPort(TW::Y, wire);
|
||||
|
|
@ -120,17 +120,17 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
|
|||
int width = 1 + xorshift32(8 * bloat_factor);
|
||||
int swidth = 1 + xorshift32(6 * bloat_factor);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::A.str()}));
|
||||
wire = module->addWire(TW::A);
|
||||
wire->width = width;
|
||||
wire->port_input = true;
|
||||
cell->setPort(TW::A, wire);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::S.str()}));
|
||||
wire = module->addWire(TW::S);
|
||||
wire->width = swidth;
|
||||
wire->port_input = true;
|
||||
cell->setPort(TW::S, wire);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
|
||||
wire = module->addWire(TW::Y);
|
||||
wire->width = width << swidth;
|
||||
wire->port_output = true;
|
||||
cell->setPort(TW::Y, wire);
|
||||
|
|
@ -140,27 +140,27 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
|
|||
{
|
||||
int width = 1 + xorshift32(8 * bloat_factor);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::A.str()}));
|
||||
wire = module->addWire(TW::A);
|
||||
wire->width = width;
|
||||
wire->port_input = true;
|
||||
cell->setPort(TW::A, wire);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::B.str()}));
|
||||
wire = module->addWire(TW::B);
|
||||
wire->width = width;
|
||||
wire->port_input = true;
|
||||
cell->setPort(TW::B, wire);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::C.str()}));
|
||||
wire = module->addWire(TW::C);
|
||||
wire->width = width;
|
||||
wire->port_input = true;
|
||||
cell->setPort(TW::C, wire);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::X.str()}));
|
||||
wire = module->addWire(TW::X);
|
||||
wire->width = width;
|
||||
wire->port_output = true;
|
||||
cell->setPort(TW::X, wire);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
|
||||
wire = module->addWire(TW::Y);
|
||||
wire->width = width;
|
||||
wire->port_output = true;
|
||||
cell->setPort(TW::Y, wire);
|
||||
|
|
@ -170,21 +170,21 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
|
|||
{
|
||||
int width = 1 + xorshift32(8 * bloat_factor);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::P.str()}));
|
||||
wire = module->addWire(TW::P);
|
||||
wire->width = width;
|
||||
wire->port_input = true;
|
||||
cell->setPort(TW::P, wire);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::G.str()}));
|
||||
wire = module->addWire(TW::G);
|
||||
wire->width = width;
|
||||
wire->port_input = true;
|
||||
cell->setPort(TW::G, wire);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::CI.str()}));
|
||||
wire = module->addWire(TW::CI);
|
||||
wire->port_input = true;
|
||||
cell->setPort(TW::CI, wire);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::CO.str()}));
|
||||
wire = module->addWire(TW::CO);
|
||||
wire->width = width;
|
||||
wire->port_output = true;
|
||||
cell->setPort(TW::CO, wire);
|
||||
|
|
@ -197,7 +197,7 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
|
|||
int depth = 1 + xorshift32(6);
|
||||
int mulbits_a = 0, mulbits_b = 0;
|
||||
|
||||
RTLIL::Wire *wire_a = module->addWire(design->twines.add(Twine{ID::A.str()}));
|
||||
RTLIL::Wire *wire_a = module->addWire(TW::A);
|
||||
wire_a->width = 0;
|
||||
wire_a->port_input = true;
|
||||
|
||||
|
|
@ -228,7 +228,7 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
|
|||
// Macc::to_cell sets the input ports
|
||||
macc.to_cell(cell);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
|
||||
wire = module->addWire(TW::Y);
|
||||
wire->width = width;
|
||||
wire->port_output = true;
|
||||
cell->setPort(TW::Y, wire);
|
||||
|
|
@ -238,12 +238,12 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
|
|||
{
|
||||
int width = 1 + xorshift32(6 * bloat_factor);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::A.str()}));
|
||||
wire = module->addWire(TW::A);
|
||||
wire->width = width;
|
||||
wire->port_input = true;
|
||||
cell->setPort(TW::A, wire);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
|
||||
wire = module->addWire(TW::Y);
|
||||
wire->port_output = true;
|
||||
cell->setPort(TW::Y, wire);
|
||||
|
||||
|
|
@ -259,12 +259,12 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
|
|||
int width = 1 + xorshift32(8 * bloat_factor);
|
||||
int depth = 1 + xorshift32(8 * bloat_factor);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::A.str()}));
|
||||
wire = module->addWire(TW::A);
|
||||
wire->width = width;
|
||||
wire->port_input = true;
|
||||
cell->setPort(TW::A, wire);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
|
||||
wire = module->addWire(TW::Y);
|
||||
wire->port_output = true;
|
||||
cell->setPort(TW::Y, wire);
|
||||
|
||||
|
|
@ -290,7 +290,7 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
|
|||
}
|
||||
|
||||
if (cell_type_flags.find('A') != std::string::npos) {
|
||||
wire = module->addWire(design->twines.add(Twine{ID::A.str()}));
|
||||
wire = module->addWire(TW::A);
|
||||
if (cell_type_flags.find('b') != std::string::npos)
|
||||
wire->width = 1;
|
||||
else
|
||||
|
|
@ -300,7 +300,7 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
|
|||
}
|
||||
|
||||
if (cell_type_flags.find('B') != std::string::npos) {
|
||||
wire = module->addWire(design->twines.add(Twine{ID::B.str()}));
|
||||
wire = module->addWire(TW::B);
|
||||
if (cell_type_flags.find('b') != std::string::npos)
|
||||
wire->width = 1;
|
||||
else if (cell_type_flags.find('h') != std::string::npos)
|
||||
|
|
@ -312,7 +312,7 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
|
|||
}
|
||||
|
||||
if (cell_type_flags.find('C') != std::string::npos) {
|
||||
wire = module->addWire(design->twines.add(Twine{ID::C.str()}));
|
||||
wire = module->addWire(TW::C);
|
||||
if (cell_type_flags.find('b') != std::string::npos)
|
||||
wire->width = 1;
|
||||
else
|
||||
|
|
@ -322,7 +322,7 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
|
|||
}
|
||||
|
||||
if (cell_type_flags.find('D') != std::string::npos) {
|
||||
wire = module->addWire(design->twines.add(Twine{ID::D.str()}));
|
||||
wire = module->addWire(TW::D);
|
||||
if (cell_type_flags.find('b') != std::string::npos)
|
||||
wire->width = 1;
|
||||
else
|
||||
|
|
@ -346,7 +346,7 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
|
|||
}
|
||||
|
||||
if (cell_type_flags.find('Y') != std::string::npos) {
|
||||
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
|
||||
wire = module->addWire(TW::Y);
|
||||
if (cell_type_flags.find('b') != std::string::npos)
|
||||
wire->width = 1;
|
||||
else
|
||||
|
|
@ -372,20 +372,20 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
|
|||
|
||||
if (cell_type == ID($alu))
|
||||
{
|
||||
wire = module->addWire(design->twines.add(Twine{ID::CI.str()}));
|
||||
wire = module->addWire(TW::CI);
|
||||
wire->port_input = true;
|
||||
cell->setPort(TW::CI, wire);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::BI.str()}));
|
||||
wire = module->addWire(TW::BI);
|
||||
wire->port_input = true;
|
||||
cell->setPort(TW::BI, wire);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::X.str()}));
|
||||
wire = module->addWire(TW::X);
|
||||
wire->width = GetSize(cell->getPort(TW::Y));
|
||||
wire->port_output = true;
|
||||
cell->setPort(TW::X, wire);
|
||||
|
||||
wire = module->addWire(design->twines.add(Twine{ID::CO.str()}));
|
||||
wire = module->addWire(TW::CO);
|
||||
wire->width = GetSize(cell->getPort(TW::Y));
|
||||
wire->port_output = true;
|
||||
cell->setPort(TW::CO, wire);
|
||||
|
|
@ -397,7 +397,7 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
|
|||
int y_size = 1;
|
||||
if (a_size > 1)
|
||||
y_size += (xorshift32(8 * bloat_factor) % (a_size - 1));
|
||||
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
|
||||
wire = module->addWire(TW::Y);
|
||||
wire->width = y_size;
|
||||
wire->port_output = true;
|
||||
cell->setPort(TW::Y, wire);
|
||||
|
|
@ -409,7 +409,7 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
|
|||
|
||||
if (cell_type == ID($concat))
|
||||
{
|
||||
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
|
||||
wire = module->addWire(TW::Y);
|
||||
wire->width = GetSize(cell->getPort(TW::A)) + GetSize(cell->getPort(TW::B));
|
||||
wire->port_output = true;
|
||||
cell->setPort(TW::Y, wire);
|
||||
|
|
@ -417,7 +417,7 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
|
|||
|
||||
if (cell_type == ID($buf))
|
||||
{
|
||||
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
|
||||
wire = module->addWire(TW::Y);
|
||||
wire->width = GetSize(cell->getPort(TW::A));
|
||||
wire->port_output = true;
|
||||
cell->setPort(TW::Y, wire);
|
||||
|
|
@ -426,18 +426,18 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
|
|||
if (cell_type.in(ID($bwmux), ID($bweqx)))
|
||||
{
|
||||
int a_size = GetSize(cell->getPort(TW::A));
|
||||
wire = module->addWire(design->twines.add(Twine{ID::B.str()}));
|
||||
wire = module->addWire(TW::B);
|
||||
wire->width = a_size;
|
||||
wire->port_input = true;
|
||||
cell->setPort(TW::B, wire);
|
||||
if (cell_type == ID($bwmux))
|
||||
{
|
||||
wire = module->addWire(design->twines.add(Twine{ID::S.str()}));
|
||||
wire = module->addWire(TW::S);
|
||||
wire->width = a_size;
|
||||
wire->port_input = true;
|
||||
cell->setPort(TW::S, wire);
|
||||
}
|
||||
wire = module->addWire(design->twines.add(Twine{ID::Y.str()}));
|
||||
wire = module->addWire(TW::Y);
|
||||
wire->width = a_size;
|
||||
wire->port_output = true;
|
||||
cell->setPort(TW::Y, wire);
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ static void create_ql_macc_dsp(ql_dsp_macc_pm &pm)
|
|||
log_assert(ab_signed == st.mul->getParam(ID(B_SIGNED)).as_bool());
|
||||
|
||||
// Determine DSP type or discard if too narrow / wide
|
||||
RTLIL::IdString type;
|
||||
TwineRef type;
|
||||
size_t tgt_a_width;
|
||||
size_t tgt_b_width;
|
||||
size_t tgt_z_width;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue