mirror of https://github.com/YosysHQ/nextpnr.git
himbaechel/xilinx: emit RAM_EXTENSION_{A,B}_LOWER for cascaded RAMB36E1
Depth-cascaded RAMB36E1 pairs (e.g. an inferred 64K x 1 memory) set
RAM_EXTENSION_A/B to LOWER on the bottom cell and UPPER on the top
cell. The fasm writer ignored these parameters entirely.
The UPPER value shares its encoding with NONE (feature bit clear), so
only the LOWER cell needs its RAM_EXTENSION_{A,B}_LOWER bit written.
Without it the cascade data path between the two cells is not
configured and the memory misbehaves beyond the first 32K.
Verified against Vivado bitstreams and on xc7a100t hardware (128K
ROM built from cascaded pairs passes a full content fingerprint).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
75c8144d42
commit
1686fe7cb3
|
|
@ -1452,6 +1452,16 @@ struct FasmBackend
|
|||
for (const char *port : {"READ_WIDTH_A", "READ_WIDTH_B", "WRITE_WIDTH_A", "WRITE_WIDTH_B"})
|
||||
if (int_or_default(ci->params, ctx->id(port), 0) == 1)
|
||||
write_bit(std::string("BRAM36_") + port + "_1");
|
||||
// Depth-cascaded pairs (64K x 1): the LOWER cell needs its
|
||||
// RAM_EXTENSION bit set; UPPER shares the NONE encoding (bit
|
||||
// clear), so only LOWER is written. Was never emitted, which
|
||||
// breaks true width-1 cascaded memories.
|
||||
for (const char *port : {"A", "B"}) {
|
||||
std::string ext =
|
||||
str_or_default(ci->params, ctx->id(std::string("RAM_EXTENSION_") + port), "NONE");
|
||||
if (ext == "LOWER")
|
||||
write_bit(std::string("RAM_EXTENSION_") + port + "_LOWER");
|
||||
}
|
||||
pop();
|
||||
}
|
||||
pop();
|
||||
|
|
|
|||
Loading…
Reference in New Issue