Changed the AST genWidthRTLIL subst interface to use a std::map

This commit is contained in:
Clifford Wolf 2014-08-14 23:02:07 +02:00
parent 2f44d8ccf8
commit c83b990458
3 changed files with 31 additions and 21 deletions

View File

@ -51,8 +51,7 @@ namespace AST_INTERNAL {
bool flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire; bool flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire;
AstNode *current_ast, *current_ast_mod; AstNode *current_ast, *current_ast_mod;
std::map<std::string, AstNode*> current_scope; std::map<std::string, AstNode*> current_scope;
RTLIL::SigSpec *genRTLIL_subst_from = NULL; std::map<RTLIL::SigBit, RTLIL::SigBit> *genRTLIL_subst_ptr = NULL;
RTLIL::SigSpec *genRTLIL_subst_to = NULL;
RTLIL::SigSpec ignoreThisSignalsInInitial; RTLIL::SigSpec ignoreThisSignalsInInitial;
AstNode *current_top_block, *current_block, *current_block_child; AstNode *current_top_block, *current_block, *current_block_child;
AstModule *current_module; AstModule *current_module;

View File

@ -228,7 +228,7 @@ namespace AST
// for expressions the resulting signal vector is returned // for expressions the resulting signal vector is returned
// all generated cell instances, etc. are written to the RTLIL::Module pointed to by AST_INTERNAL::current_module // all generated cell instances, etc. are written to the RTLIL::Module pointed to by AST_INTERNAL::current_module
RTLIL::SigSpec genRTLIL(int width_hint = -1, bool sign_hint = false); RTLIL::SigSpec genRTLIL(int width_hint = -1, bool sign_hint = false);
RTLIL::SigSpec genWidthRTLIL(int width, RTLIL::SigSpec *subst_from = NULL, RTLIL::SigSpec *subst_to = NULL); RTLIL::SigSpec genWidthRTLIL(int width, std::map<RTLIL::SigBit, RTLIL::SigBit> *new_subst_ptr = NULL);
// compare AST nodes // compare AST nodes
bool operator==(const AstNode &other) const; bool operator==(const AstNode &other) const;
@ -285,7 +285,8 @@ namespace AST_INTERNAL
extern bool flag_dump_ast1, flag_dump_ast2, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire; extern bool flag_dump_ast1, flag_dump_ast2, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire;
extern AST::AstNode *current_ast, *current_ast_mod; extern AST::AstNode *current_ast, *current_ast_mod;
extern std::map<std::string, AST::AstNode*> current_scope; extern std::map<std::string, AST::AstNode*> current_scope;
extern RTLIL::SigSpec *genRTLIL_subst_from, *genRTLIL_subst_to, ignoreThisSignalsInInitial; extern std::map<RTLIL::SigBit, RTLIL::SigBit> *genRTLIL_subst_ptr;
extern RTLIL::SigSpec ignoreThisSignalsInInitial;
extern AST::AstNode *current_top_block, *current_block, *current_block_child; extern AST::AstNode *current_top_block, *current_block, *current_block_child;
extern AST::AstModule *current_module; extern AST::AstModule *current_module;
struct ProcessGenerator; struct ProcessGenerator;

View File

@ -173,7 +173,7 @@ struct AST_INTERNAL::ProcessGenerator
AstNode *always; AstNode *always;
RTLIL::SigSpec initSyncSignals; RTLIL::SigSpec initSyncSignals;
RTLIL::Process *proc; RTLIL::Process *proc;
const RTLIL::SigSpec &outputSignals; RTLIL::SigSpec outputSignals;
// This always points to the RTLIL::CaseRule beeing filled at the moment // This always points to the RTLIL::CaseRule beeing filled at the moment
RTLIL::CaseRule *current_case; RTLIL::CaseRule *current_case;
@ -198,7 +198,7 @@ struct AST_INTERNAL::ProcessGenerator
// Buffer for generating the init action // Buffer for generating the init action
RTLIL::SigSpec init_lvalue, init_rvalue; RTLIL::SigSpec init_lvalue, init_rvalue;
ProcessGenerator(AstNode *always, RTLIL::SigSpec initSyncSignalsArg = RTLIL::SigSpec()) : always(always), initSyncSignals(initSyncSignalsArg), outputSignals(subst_lvalue_from) ProcessGenerator(AstNode *always, RTLIL::SigSpec initSyncSignalsArg = RTLIL::SigSpec()) : always(always), initSyncSignals(initSyncSignalsArg)
{ {
// generate process and simple root case // generate process and simple root case
proc = new RTLIL::Process; proc = new RTLIL::Process;
@ -278,6 +278,8 @@ struct AST_INTERNAL::ProcessGenerator
offset += lhs.size(); offset += lhs.size();
} }
} }
outputSignals = RTLIL::SigSpec(subst_lvalue_from);
} }
// create new temporary signals // create new temporary signals
@ -398,8 +400,12 @@ struct AST_INTERNAL::ProcessGenerator
case AST_ASSIGN_EQ: case AST_ASSIGN_EQ:
case AST_ASSIGN_LE: case AST_ASSIGN_LE:
{ {
std::map<RTLIL::SigBit, RTLIL::SigBit> new_subst_rvalue_map;
for (int i = 0; i < SIZE(subst_rvalue_to); i++)
new_subst_rvalue_map[subst_rvalue_from[i]] = subst_rvalue_to[i];
RTLIL::SigSpec unmapped_lvalue = ast->children[0]->genRTLIL(), lvalue = unmapped_lvalue; RTLIL::SigSpec unmapped_lvalue = ast->children[0]->genRTLIL(), lvalue = unmapped_lvalue;
RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.size(), &subst_rvalue_from, &subst_rvalue_to); RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.size(), &new_subst_rvalue_map);
lvalue.replace(subst_lvalue_from, subst_lvalue_to); lvalue.replace(subst_lvalue_from, subst_lvalue_to);
if (ast->type == AST_ASSIGN_EQ) { if (ast->type == AST_ASSIGN_EQ) {
@ -415,8 +421,12 @@ struct AST_INTERNAL::ProcessGenerator
case AST_CASE: case AST_CASE:
{ {
std::map<RTLIL::SigBit, RTLIL::SigBit> new_subst_rvalue_map;
for (int i = 0; i < SIZE(subst_rvalue_to); i++)
new_subst_rvalue_map[subst_rvalue_from[i]] = subst_rvalue_to[i];
RTLIL::SwitchRule *sw = new RTLIL::SwitchRule; RTLIL::SwitchRule *sw = new RTLIL::SwitchRule;
sw->signal = ast->children[0]->genWidthRTLIL(-1, &subst_rvalue_from, &subst_rvalue_to); sw->signal = ast->children[0]->genWidthRTLIL(-1, &new_subst_rvalue_map);
current_case->switches.push_back(sw); current_case->switches.push_back(sw);
for (auto &attr : ast->attributes) { for (auto &attr : ast->attributes) {
@ -467,8 +477,12 @@ struct AST_INTERNAL::ProcessGenerator
default_case = current_case; default_case = current_case;
else if (node->type == AST_BLOCK) else if (node->type == AST_BLOCK)
processAst(node); processAst(node);
else else {
current_case->compare.push_back(node->genWidthRTLIL(sw->signal.size(), &subst_rvalue_from, &subst_rvalue_to)); std::map<RTLIL::SigBit, RTLIL::SigBit> new_subst_rvalue_map;
for (int i = 0; i < SIZE(subst_rvalue_to); i++)
new_subst_rvalue_map[subst_rvalue_from[i]] = subst_rvalue_to[i];
current_case->compare.push_back(node->genWidthRTLIL(sw->signal.size(), &new_subst_rvalue_map));
}
} }
if (default_case != current_case) if (default_case != current_case)
sw->cases.push_back(current_case); sw->cases.push_back(current_case);
@ -969,8 +983,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
RTLIL::SigSpec sig = { RTLIL::SigSpec(RTLIL::State::Sx, add_undef_bits_msb), chunk, RTLIL::SigSpec(RTLIL::State::Sx, add_undef_bits_lsb) }; RTLIL::SigSpec sig = { RTLIL::SigSpec(RTLIL::State::Sx, add_undef_bits_msb), chunk, RTLIL::SigSpec(RTLIL::State::Sx, add_undef_bits_lsb) };
if (genRTLIL_subst_from && genRTLIL_subst_to) if (genRTLIL_subst_ptr)
sig.replace(*genRTLIL_subst_from, *genRTLIL_subst_to); sig.replace(*genRTLIL_subst_ptr);
is_signed = children.size() > 0 ? false : id2ast->is_signed && sign_hint; is_signed = children.size() > 0 ? false : id2ast->is_signed && sign_hint;
return sig; return sig;
@ -1377,23 +1391,19 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
// this is a wrapper for AstNode::genRTLIL() when a specific signal width is requested and/or // this is a wrapper for AstNode::genRTLIL() when a specific signal width is requested and/or
// signals must be substituted before beeing used as input values (used by ProcessGenerator) // signals must be substituted before beeing used as input values (used by ProcessGenerator)
// note that this is using some global variables to communicate this special settings to AstNode::genRTLIL(). // note that this is using some global variables to communicate this special settings to AstNode::genRTLIL().
RTLIL::SigSpec AstNode::genWidthRTLIL(int width, RTLIL::SigSpec *subst_from, RTLIL::SigSpec *subst_to) RTLIL::SigSpec AstNode::genWidthRTLIL(int width, std::map<RTLIL::SigBit, RTLIL::SigBit> *new_subst_ptr)
{ {
RTLIL::SigSpec *backup_subst_from = genRTLIL_subst_from; std::map<RTLIL::SigBit, RTLIL::SigBit> *backup_subst_ptr = genRTLIL_subst_ptr;
RTLIL::SigSpec *backup_subst_to = genRTLIL_subst_to;
if (subst_from) if (new_subst_ptr)
genRTLIL_subst_from = subst_from; genRTLIL_subst_ptr = new_subst_ptr;
if (subst_to)
genRTLIL_subst_to = subst_to;
bool sign_hint = true; bool sign_hint = true;
int width_hint = width; int width_hint = width;
detectSignWidthWorker(width_hint, sign_hint); detectSignWidthWorker(width_hint, sign_hint);
RTLIL::SigSpec sig = genRTLIL(width_hint, sign_hint); RTLIL::SigSpec sig = genRTLIL(width_hint, sign_hint);
genRTLIL_subst_from = backup_subst_from; genRTLIL_subst_ptr = backup_subst_ptr;
genRTLIL_subst_to = backup_subst_to;
if (width >= 0) if (width >= 0)
sig.extend_u0(width, is_signed); sig.extend_u0(width, is_signed);