Various fixes for memories with offsets

This commit is contained in:
Clifford Wolf 2015-02-14 14:21:15 +01:00
parent dcf2e24240
commit e9368a1d7e
5 changed files with 24 additions and 13 deletions

View File

@ -1214,9 +1214,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_DATA", current_module->memories[str]->width);
wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);
int addr_bits = 1;
while ((1 << addr_bits) < current_module->memories[str]->size)
addr_bits++;
int mem_width, mem_size, addr_bits;
id2ast->meminfo(mem_width, mem_size, addr_bits);
cell->setPort("\\CLK", RTLIL::SigSpec(RTLIL::State::Sx, 1));
cell->setPort("\\ADDR", children[0]->genWidthRTLIL(addr_bits));
@ -1243,9 +1242,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
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++;
int mem_width, mem_size, addr_bits;
id2ast->meminfo(mem_width, mem_size, addr_bits);
cell->setPort("\\ADDR", children[0]->genWidthRTLIL(addr_bits));
cell->setPort("\\DATA", children[1]->genWidthRTLIL(current_module->memories[str]->width));

View File

@ -1421,6 +1421,7 @@ skip_dynamic_range_lvalue_expansion:;
if (current_always->type != AST_INITIAL)
wrnode->children.push_back(new AstNode(AST_IDENTIFIER));
wrnode->str = children[0]->str;
wrnode->id2ast = children[0]->id2ast;
wrnode->children[0]->str = id_addr;
wrnode->children[1]->str = id_data;
if (current_always->type != AST_INITIAL)

View File

@ -38,8 +38,6 @@ void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory)
memory->name.c_str(), module->name.c_str());
int addr_bits = 0;
while ((1 << addr_bits) < memory->size)
addr_bits++;
Const init_data(State::Sx, memory->size * memory->width);
SigMap sigmap(module);
@ -64,8 +62,15 @@ void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory)
for (auto &cell_it : module->cells_) {
RTLIL::Cell *cell = cell_it.second;
if (cell->type.in("$memrd", "$memwr", "$meminit") && memory->name == cell->parameters["\\MEMID"].decode_string())
if (cell->type.in("$memrd", "$memwr", "$meminit") && memory->name == cell->parameters["\\MEMID"].decode_string()) {
addr_bits = std::max(addr_bits, cell->getParam("\\ABITS").as_int());
memcells.push_back(cell);
}
}
if (memcells.empty()) {
log(" no cells found. removing memory.\n");
return;
}
std::sort(memcells.begin(), memcells.end(), memcells_cmp);

View File

@ -83,7 +83,7 @@ struct MemoryMapWorker
int mem_size = cell->parameters["\\SIZE"].as_int();
int mem_width = cell->parameters["\\WIDTH"].as_int();
// int mem_offset = cell->parameters["\\OFFSET"].as_int();
int mem_offset = cell->parameters["\\OFFSET"].as_int();
int mem_abits = cell->parameters["\\ABITS"].as_int();
SigSpec init_data = cell->getParam("\\INIT");
@ -114,7 +114,7 @@ struct MemoryMapWorker
// FIXME: Actually we should check for wr_en.is_fully_const() also and
// create a $adff cell with this ports wr_en input as reset pin when wr_en
// is not a simple static 1.
static_cells_map[wr_addr.as_int()] = wr_data;
static_cells_map[wr_addr.as_int() - mem_offset] = wr_data;
static_ports.insert(i);
continue;
}
@ -187,6 +187,9 @@ struct MemoryMapWorker
{
RTLIL::SigSpec rd_addr = cell->getPort("\\RD_ADDR").extract(i*mem_abits, mem_abits);
if (mem_offset)
rd_addr = module->Sub(NEW_ID, rd_addr, SigSpec(mem_offset, GetSize(rd_addr)));
std::vector<RTLIL::SigSpec> rd_signals;
rd_signals.push_back(cell->getPort("\\RD_DATA").extract(i*mem_width, mem_width));
@ -263,6 +266,10 @@ struct MemoryMapWorker
RTLIL::SigSpec wr_addr = cell->getPort("\\WR_ADDR").extract(j*mem_abits, mem_abits);
RTLIL::SigSpec wr_data = cell->getPort("\\WR_DATA").extract(j*mem_width, mem_width);
RTLIL::SigSpec wr_en = cell->getPort("\\WR_EN").extract(j*mem_width, mem_width);
if (mem_offset)
wr_addr = module->Sub(NEW_ID, wr_addr, SigSpec(mem_offset, GetSize(wr_addr)));
RTLIL::Wire *w_seladdr = addr_decode(wr_addr, RTLIL::SigSpec(i, mem_abits));
int wr_offset = 0;

View File

@ -213,7 +213,7 @@ module memtest09 (
input a_wen, b_wen,
output reg [3:0] a_dout, b_dout
);
reg [3:0] memory [0:35];
reg [3:0] memory [10:35];
always @(posedge clk) begin
if (a_wen)
@ -222,7 +222,7 @@ module memtest09 (
end
always @(posedge clk) begin
if (b_wen && (10 + a_addr != 20 + b_addr))
if (b_wen && (10 + a_addr != 20 + b_addr || !a_wen))
memory[20 + b_addr] <= b_din;
b_dout <= memory[20 + b_addr];
end