Skip to content

Commit

Permalink
memory_libmap: look for ram_style attributes on surrounding signals
Browse files Browse the repository at this point in the history
  • Loading branch information
nakengelhardt committed Oct 19, 2023
1 parent d21c464 commit ec31a7b
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 5 deletions.
1 change: 1 addition & 0 deletions kernel/constids.inc
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ X(nomem2reg)
X(nomeminit)
X(nosync)
X(nowrshmsk)
X(no_ram)
X(no_rw_check)
X(O)
X(OFFSET)
Expand Down
6 changes: 6 additions & 0 deletions kernel/mem.cc
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ void Mem::emit() {
for (int j = 0; j < (1 << wr_ports[i].wide_log2); j++)
wr_port_xlat.push_back(i);
for (auto &port : rd_ports) {
for (auto attr: port.attributes)
cell->attributes.insert(attr);
if (port.cell) {
module->remove(port.cell);
port.cell = nullptr;
Expand Down Expand Up @@ -210,6 +212,8 @@ void Mem::emit() {
cell->setPort(ID::RD_ADDR, rd_addr);
cell->setPort(ID::RD_DATA, rd_data);
for (auto &port : wr_ports) {
for (auto attr: port.attributes)
cell->attributes.insert(attr);
if (port.cell) {
module->remove(port.cell);
port.cell = nullptr;
Expand Down Expand Up @@ -246,6 +250,8 @@ void Mem::emit() {
cell->setPort(ID::WR_ADDR, wr_addr);
cell->setPort(ID::WR_DATA, wr_data);
for (auto &init : inits) {
for (auto attr: init.attributes)
cell->attributes.insert(attr);
if (init.cell) {
module->remove(init.cell);
init.cell = nullptr;
Expand Down
44 changes: 39 additions & 5 deletions passes/memory/memory_libmap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -481,18 +481,49 @@ void MemMapping::dump_config(MemConfig &cfg) {
}
}

std::pair<bool, Const> search_for_attribute(Mem mem, IdString attr) {
if (mem.has_attribute(attr))
return std::make_pair(true, mem.attributes.at(attr));
for (auto &port: mem.rd_ports){
if (port.has_attribute(attr))
return std::make_pair(true, port.attributes.at(attr));
log_debug("looking for attribute %s on signal %s\n", log_id(attr), log_signal(port.data));
for (SigBit bit: port.data)
if (bit.is_wire() && bit.wire->has_attribute(attr))
return std::make_pair(true, bit.wire->attributes.at(attr));
log_debug("looking for attribute %s on signal %s\n", log_id(attr), log_signal(port.data));
for (SigBit bit: port.addr)
if (bit.is_wire() && bit.wire->has_attribute(attr))
return std::make_pair(true, bit.wire->attributes.at(attr));
}
for (auto &port: mem.wr_ports){
if (port.has_attribute(attr))
return std::make_pair(true, port.attributes.at(attr));
log_debug("looking for attribute %s on signal %s\n", log_id(attr), log_signal(port.data));
for (SigBit bit: port.data)
if (bit.is_wire() && bit.wire->has_attribute(attr))
return std::make_pair(true, bit.wire->attributes.at(attr));
for (SigBit bit: port.addr)
if (bit.is_wire() && bit.wire->has_attribute(attr))
return std::make_pair(true, bit.wire->attributes.at(attr));
}
return std::make_pair(false, Const());
}

// Go through memory attributes to determine user-requested mapping style.
void MemMapping::determine_style() {
kind = RamKind::Auto;
style = "";
if (mem.get_bool_attribute(ID::lram)) {
auto find_attr = search_for_attribute(mem, ID::lram);
if (find_attr.first && find_attr.second.as_bool()) {
kind = RamKind::Huge;
log("found attribute 'lram' on memory %s.%s, forced mapping to huge RAM\n", log_id(mem.module->name), log_id(mem.memid));
return;
}
for (auto attr: {ID::ram_block, ID::rom_block, ID::ram_style, ID::rom_style, ID::ramstyle, ID::romstyle, ID::syn_ramstyle, ID::syn_romstyle}) {
if (mem.has_attribute(attr)) {
Const val = mem.attributes.at(attr);
find_attr = search_for_attribute(mem, attr);
if (find_attr.first) {
Const val = find_attr.second;
if (val == 1) {
kind = RamKind::NotLogic;
log("found attribute '%s = 1' on memory %s.%s, disabled mapping to FF\n", log_id(attr), log_id(mem.module->name), log_id(mem.memid));
Expand Down Expand Up @@ -526,8 +557,11 @@ void MemMapping::determine_style() {
return;
}
}
if (mem.get_bool_attribute(ID::logic_block))
kind = RamKind::Logic;
for (auto attr: {ID::logic_block, ID::no_ram}){
find_attr = search_for_attribute(mem, attr);
if (find_attr.first && find_attr.second.as_bool())
kind = RamKind::Logic;
}
}

// Determine whether the memory can be mapped entirely to soft logic.
Expand Down
22 changes: 22 additions & 0 deletions tests/memlib/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -1513,6 +1513,28 @@ def __init__(self, name, src, libs, defs, cells):
["block_sp_full"], defs,
{"RAM_BLOCK_SP": 1, "$*": add_logic}
))

ROM_CASE = """
module rom(input clk, input [2:0] addr, {attr}output reg [7:0] data);
always @(posedge clk) begin
case (addr)
3'b000: data <= 8'h12;
3'b001: data <= 8'hAB;
3'b010: data <= 8'h42;
3'b011: data <= 8'h23;
3'b100: data <= 8'h66;
3'b101: data <= 8'hC0;
3'b110: data <= 8'h3F;
3'b111: data <= 8'h95;
endcase
end
endmodule
"""

TESTS.append(Test("rom_case", ROM_CASE.format(attr=""), ["block_sdp"], [], {"RAM_BLOCK_SDP" : 0}))
TESTS.append(Test("rom_case_block", ROM_CASE.format(attr="(* rom_style = \"block\" *) "), ["block_sdp"], [], {"RAM_BLOCK_SDP" : 1}))

with open("run-test.mk", "w") as mf:
mf.write("ifneq ($(strip $(SEED)),)\n")
Expand Down

0 comments on commit ec31a7b

Please sign in to comment.