mirror of https://github.com/YosysHQ/yosys.git
Creating $meminit cells in verilog front-end
This commit is contained in:
parent
910556560f
commit
a8e9d37c14
|
@ -58,7 +58,7 @@ namespace AST_INTERNAL {
|
|||
std::map<std::string, AstNode*> current_scope;
|
||||
const dict<RTLIL::SigBit, RTLIL::SigBit> *genRTLIL_subst_ptr = NULL;
|
||||
RTLIL::SigSpec ignoreThisSignalsInInitial;
|
||||
AstNode *current_top_block, *current_block, *current_block_child;
|
||||
AstNode *current_always, *current_top_block, *current_block, *current_block_child;
|
||||
AstModule *current_module;
|
||||
}
|
||||
|
||||
|
@ -132,6 +132,7 @@ std::string AST::type2str(AstNodeType type)
|
|||
X(AST_TERNARY)
|
||||
X(AST_MEMRD)
|
||||
X(AST_MEMWR)
|
||||
X(AST_MEMINIT)
|
||||
X(AST_TCALL)
|
||||
X(AST_ASSIGN)
|
||||
X(AST_CELL)
|
||||
|
|
|
@ -107,6 +107,7 @@ namespace AST
|
|||
AST_TERNARY,
|
||||
AST_MEMRD,
|
||||
AST_MEMWR,
|
||||
AST_MEMINIT,
|
||||
|
||||
AST_TCALL,
|
||||
AST_ASSIGN,
|
||||
|
@ -299,7 +300,7 @@ namespace AST_INTERNAL
|
|||
extern std::map<std::string, AST::AstNode*> current_scope;
|
||||
extern const dict<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_always, *current_top_block, *current_block, *current_block_child;
|
||||
extern AST::AstModule *current_module;
|
||||
struct ProcessGenerator;
|
||||
}
|
||||
|
|
|
@ -1235,28 +1235,31 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
|
||||
// generate $memwr cells for memory write ports
|
||||
case AST_MEMWR:
|
||||
case AST_MEMINIT:
|
||||
{
|
||||
std::stringstream sstr;
|
||||
sstr << "$memwr$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++);
|
||||
sstr << (type == AST_MEMWR ? "$memwr$" : "$meminit$") << str << "$" << filename << ":" << linenum << "$" << (autoidx++);
|
||||
|
||||
RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$memwr");
|
||||
RTLIL::Cell *cell = current_module->addCell(sstr.str(), type == AST_MEMWR ? "$memwr" : "$meminit");
|
||||
cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);
|
||||
|
||||
int addr_bits = 1;
|
||||
while ((1 << addr_bits) < current_module->memories[str]->size)
|
||||
addr_bits++;
|
||||
|
||||
cell->setPort("\\CLK", RTLIL::SigSpec(RTLIL::State::Sx, 1));
|
||||
cell->setPort("\\ADDR", children[0]->genWidthRTLIL(addr_bits));
|
||||
cell->setPort("\\DATA", children[1]->genWidthRTLIL(current_module->memories[str]->width));
|
||||
cell->setPort("\\EN", children[2]->genRTLIL());
|
||||
|
||||
cell->parameters["\\MEMID"] = RTLIL::Const(str);
|
||||
cell->parameters["\\ABITS"] = RTLIL::Const(addr_bits);
|
||||
cell->parameters["\\WIDTH"] = RTLIL::Const(current_module->memories[str]->width);
|
||||
|
||||
cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(0);
|
||||
cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(0);
|
||||
if (type == AST_MEMWR) {
|
||||
cell->setPort("\\CLK", RTLIL::SigSpec(RTLIL::State::Sx, 1));
|
||||
cell->setPort("\\EN", children[2]->genRTLIL());
|
||||
cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(0);
|
||||
cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(0);
|
||||
}
|
||||
|
||||
cell->parameters["\\PRIORITY"] = RTLIL::Const(autoidx-1);
|
||||
}
|
||||
|
|
|
@ -262,6 +262,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
|||
auto backup_current_block = current_block;
|
||||
auto backup_current_block_child = current_block_child;
|
||||
auto backup_current_top_block = current_top_block;
|
||||
auto backup_current_always = current_always;
|
||||
|
||||
if (type == AST_ALWAYS || type == AST_INITIAL)
|
||||
current_always = this;
|
||||
|
||||
int backup_width_hint = width_hint;
|
||||
bool backup_sign_hint = sign_hint;
|
||||
|
@ -501,6 +505,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
|||
current_block = backup_current_block;
|
||||
current_block_child = backup_current_block_child;
|
||||
current_top_block = backup_current_top_block;
|
||||
current_always = backup_current_always;
|
||||
|
||||
for (auto it = backup_scope.begin(); it != backup_scope.end(); it++) {
|
||||
if (it->second == NULL)
|
||||
|
@ -1300,11 +1305,14 @@ skip_dynamic_range_lvalue_expansion:;
|
|||
current_scope[wire_data->str] = wire_data;
|
||||
while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }
|
||||
|
||||
AstNode *wire_en = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
|
||||
wire_en->str = id_en;
|
||||
current_ast_mod->children.push_back(wire_en);
|
||||
current_scope[wire_en->str] = wire_en;
|
||||
while (wire_en->simplify(true, false, false, 1, -1, false, false)) { }
|
||||
AstNode *wire_en = nullptr;
|
||||
if (current_always->type != AST_INITIAL) {
|
||||
wire_en = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
|
||||
wire_en->str = id_en;
|
||||
current_ast_mod->children.push_back(wire_en);
|
||||
current_scope[wire_en->str] = wire_en;
|
||||
while (wire_en->simplify(true, false, false, 1, -1, false, false)) { }
|
||||
}
|
||||
|
||||
std::vector<RTLIL::State> x_bits_addr, x_bits_data, set_bits_en;
|
||||
for (int i = 0; i < addr_bits; i++)
|
||||
|
@ -1320,13 +1328,17 @@ skip_dynamic_range_lvalue_expansion:;
|
|||
AstNode *assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_data, false));
|
||||
assign_data->children[0]->str = id_data;
|
||||
|
||||
AstNode *assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, mem_width));
|
||||
assign_en->children[0]->str = id_en;
|
||||
AstNode *assign_en = nullptr;
|
||||
if (current_always->type != AST_INITIAL) {
|
||||
assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, mem_width));
|
||||
assign_en->children[0]->str = id_en;
|
||||
}
|
||||
|
||||
AstNode *default_signals = new AstNode(AST_BLOCK);
|
||||
default_signals->children.push_back(assign_addr);
|
||||
default_signals->children.push_back(assign_data);
|
||||
default_signals->children.push_back(assign_en);
|
||||
if (current_always->type != AST_INITIAL)
|
||||
default_signals->children.push_back(assign_en);
|
||||
current_top_block->children.insert(current_top_block->children.begin(), default_signals);
|
||||
|
||||
assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[0]->children[0]->children[0]->clone());
|
||||
|
@ -1341,15 +1353,16 @@ skip_dynamic_range_lvalue_expansion:;
|
|||
|
||||
std::vector<RTLIL::State> padding_x(offset, RTLIL::State::Sx);
|
||||
|
||||
for (int i = 0; i < mem_width; i++)
|
||||
set_bits_en[i] = offset <= i && i < offset+width ? RTLIL::State::S1 : RTLIL::State::S0;
|
||||
|
||||
assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER),
|
||||
new AstNode(AST_CONCAT, mkconst_bits(padding_x, false), children[1]->clone()));
|
||||
assign_data->children[0]->str = id_data;
|
||||
|
||||
assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false));
|
||||
assign_en->children[0]->str = id_en;
|
||||
if (current_always->type != AST_INITIAL) {
|
||||
for (int i = 0; i < mem_width; i++)
|
||||
set_bits_en[i] = offset <= i && i < offset+width ? RTLIL::State::S1 : RTLIL::State::S0;
|
||||
assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false));
|
||||
assign_en->children[0]->str = id_en;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1364,16 +1377,17 @@ skip_dynamic_range_lvalue_expansion:;
|
|||
log_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum);
|
||||
int width = left_at_zero_ast->integer - right_at_zero_ast->integer + 1;
|
||||
|
||||
for (int i = 0; i < mem_width; i++)
|
||||
set_bits_en[i] = i < width ? RTLIL::State::S1 : RTLIL::State::S0;
|
||||
|
||||
assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER),
|
||||
new AstNode(AST_SHIFT_LEFT, children[1]->clone(), offset_ast->clone()));
|
||||
assign_data->children[0]->str = id_data;
|
||||
|
||||
assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER),
|
||||
new AstNode(AST_SHIFT_LEFT, mkconst_bits(set_bits_en, false), offset_ast->clone()));
|
||||
assign_en->children[0]->str = id_en;
|
||||
if (current_always->type != AST_INITIAL) {
|
||||
for (int i = 0; i < mem_width; i++)
|
||||
set_bits_en[i] = i < width ? RTLIL::State::S1 : RTLIL::State::S0;
|
||||
assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER),
|
||||
new AstNode(AST_SHIFT_LEFT, mkconst_bits(set_bits_en, false), offset_ast->clone()));
|
||||
assign_en->children[0]->str = id_en;
|
||||
}
|
||||
|
||||
delete left_at_zero_ast;
|
||||
delete right_at_zero_ast;
|
||||
|
@ -1385,23 +1399,28 @@ skip_dynamic_range_lvalue_expansion:;
|
|||
assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[1]->clone());
|
||||
assign_data->children[0]->str = id_data;
|
||||
|
||||
assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false));
|
||||
assign_en->children[0]->str = id_en;
|
||||
if (current_always->type != AST_INITIAL) {
|
||||
assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false));
|
||||
assign_en->children[0]->str = id_en;
|
||||
}
|
||||
}
|
||||
|
||||
newNode = new AstNode(AST_BLOCK);
|
||||
newNode->children.push_back(assign_addr);
|
||||
newNode->children.push_back(assign_data);
|
||||
newNode->children.push_back(assign_en);
|
||||
if (current_always->type != AST_INITIAL)
|
||||
newNode->children.push_back(assign_en);
|
||||
|
||||
AstNode *wrnode = new AstNode(AST_MEMWR);
|
||||
wrnode->children.push_back(new AstNode(AST_IDENTIFIER));
|
||||
AstNode *wrnode = new AstNode(current_always->type == AST_INITIAL ? AST_MEMINIT : AST_MEMWR);
|
||||
wrnode->children.push_back(new AstNode(AST_IDENTIFIER));
|
||||
wrnode->children.push_back(new AstNode(AST_IDENTIFIER));
|
||||
if (current_always->type != AST_INITIAL)
|
||||
wrnode->children.push_back(new AstNode(AST_IDENTIFIER));
|
||||
wrnode->str = children[0]->str;
|
||||
wrnode->children[0]->str = id_addr;
|
||||
wrnode->children[1]->str = id_data;
|
||||
wrnode->children[2]->str = id_en;
|
||||
if (current_always->type != AST_INITIAL)
|
||||
wrnode->children[2]->str = id_en;
|
||||
current_ast_mod->children.push_back(wrnode);
|
||||
|
||||
goto apply_newNode;
|
||||
|
|
Loading…
Reference in New Issue