mirror of https://github.com/YosysHQ/yosys.git
memory_bram: Fix initdata bit order after shuffling
In some cases the memory_bram pass shuffles the order of the bits in a memory's RD_DATA port. Although the order of the bits in the WR_DATA and WR_EN ports is changed to match the RD_DATA port, the order of the bits in the initialization data is not. This causes reads of initialized memories to return invalid data (until the initialization data is overwritten). This commit fixes the bug by shuffling the initdata bits in exactly the same order as the RD_DATA/WR_DATA/WR_EN bits.
This commit is contained in:
parent
47a5dfdaa4
commit
4fef9689ab
|
@ -472,8 +472,12 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram,
|
||||||
std::vector<SigSpec> new_wr_en(GetSize(old_wr_en));
|
std::vector<SigSpec> new_wr_en(GetSize(old_wr_en));
|
||||||
std::vector<SigSpec> new_wr_data(GetSize(old_wr_data));
|
std::vector<SigSpec> new_wr_data(GetSize(old_wr_data));
|
||||||
std::vector<SigSpec> new_rd_data(GetSize(old_rd_data));
|
std::vector<SigSpec> new_rd_data(GetSize(old_rd_data));
|
||||||
|
std::vector<std::vector<State>> new_initdata;
|
||||||
std::vector<int> shuffle_map;
|
std::vector<int> shuffle_map;
|
||||||
|
|
||||||
|
if (cell_init)
|
||||||
|
new_initdata.resize(mem_size);
|
||||||
|
|
||||||
for (auto &it : en_order)
|
for (auto &it : en_order)
|
||||||
{
|
{
|
||||||
auto &bits = bits_wr_en.at(it);
|
auto &bits = bits_wr_en.at(it);
|
||||||
|
@ -489,6 +493,10 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram,
|
||||||
}
|
}
|
||||||
for (int j = 0; j < rd_ports; j++)
|
for (int j = 0; j < rd_ports; j++)
|
||||||
new_rd_data[j].append(old_rd_data[j][bits[i]]);
|
new_rd_data[j].append(old_rd_data[j][bits[i]]);
|
||||||
|
if (cell_init) {
|
||||||
|
for (int j = 0; j < mem_size; j++)
|
||||||
|
new_initdata[j].push_back(initdata[j][bits[i]]);
|
||||||
|
}
|
||||||
shuffle_map.push_back(bits[i]);
|
shuffle_map.push_back(bits[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,6 +507,10 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram,
|
||||||
}
|
}
|
||||||
for (int j = 0; j < rd_ports; j++)
|
for (int j = 0; j < rd_ports; j++)
|
||||||
new_rd_data[j].append(State::Sx);
|
new_rd_data[j].append(State::Sx);
|
||||||
|
if (cell_init) {
|
||||||
|
for (int j = 0; j < mem_size; j++)
|
||||||
|
new_initdata[j].push_back(State::Sx);
|
||||||
|
}
|
||||||
shuffle_map.push_back(-1);
|
shuffle_map.push_back(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -522,6 +534,11 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram,
|
||||||
|
|
||||||
for (int i = 0; i < rd_ports; i++)
|
for (int i = 0; i < rd_ports; i++)
|
||||||
rd_data.replace(i*mem_width, new_rd_data[i]);
|
rd_data.replace(i*mem_width, new_rd_data[i]);
|
||||||
|
|
||||||
|
if (cell_init) {
|
||||||
|
for (int i = 0; i < mem_size; i++)
|
||||||
|
initdata[i] = Const(new_initdata[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// assign write ports
|
// assign write ports
|
||||||
|
|
Loading…
Reference in New Issue