Yes, the name given in the BMM file for the block RAM is just a name. Any relation to the Xilinx soft-core processors is just a coincidence. It appears that Data2MEM does not place any restrictions on the reference provided for the block RAM array specified in the BMM file.
The examples given in the Data2MEM user's guide do give the impression that the tool was designed specifically to patch program and data memory for Xilinx soft-core processors. It is a good thing that is not the case, and that it can be used for the purpose of patching the block RAM initialization data of any configuration bit stream.
Your module is instantiating an HDL library element for the Spartan-3 family. In regards to your question of how to use Data2MEM with multiple block RAMs, I will try the following:
Code:
module BRAM4KX16 (
input CLK
, input [11:0] A
, output [15:0] DO
, input [15:0] DI
, input EN
, input WR
);
// MAM, 13K27, Increase memory array from 1024 x 16 to 4096 x 16.
assign RAM_EN0 = EN & (A[11:10] == 2'b00);
(*LOC="RAMB16_X0Y0"*)
RAMB16_S18
#( .INIT(18'h00000),.SRVAL(18'h00000))
bram0(
.CLK(CLK), .ADDR(A[9:0]), .DO(DO[15:0]), .DI(DI[15:0]), .WE(WR&RAM_EN0),
.EN(1), .SSR(~RAM_EN0), //on deselect, output 00
.DIP(0)
);
assign RAM_EN1 = EN & (A[11:10] == 2'b01);
(*LOC="RAMB16_X0Y1"*)
RAMB16_S18
#( .INIT(18'h00000),.SRVAL(18'h00000))
bram1(
.CLK(CLK), .ADDR(A[9:0]), .DO(DO[15:0]), .DI(DI[15:0]), .WE(WR&RAM_EN1),
.EN(1), .SSR(~RAM_EN1), //on deselect, output 00
.DIP(0)
);
assign RAM_EN2 = EN & (A[11:10] == 2'b10);
(*LOC="RAMB16_X0Y3"*)
RAMB16_S18
#( .INIT(18'h00000),.SRVAL(18'h00000))
bram2(
.CLK(CLK), .ADDR(A[9:0]), .DO(DO[15:0]), .DI(DI[15:0]), .WE(WR&RAM_EN2),
.EN(1), .SSR(~RAM_EN2), //on deselect, output 00
.DIP(0)
);
assign RAM_EN3 = EN & (A[11:10] == 2'b11);
(*LOC="RAMB16_X0Y3"*)
RAMB16_S18
#( .INIT(18'h00000),.SRVAL(18'h00000))
bram3(
.CLK(CLK), .ADDR(A[9:0]), .DO(DO[15:0]), .DI(DI[15:0]), .WE(WR&RAM_EN3),
.EN(1), .SSR(~RAM_EN3), //on deselect, output 00
.DIP(0)
);
endmodule
Code:
ADDRESS_SPACE bram RAMB16 INDEX_ADDRESSING [0x00000000:0x00001FFF]
// Address Range: 0x0000:0x07FF -- Each Block RAM is 2kB in size.
BUS_BLOCK
bram/bram0 [15:0] PLACED = X0Y0;
END_BUS_BLOCK;
// Address Range: 0x0800:0x0FFF -- Each Block RAM is 2kB in size.
BUS_BLOCK
bram/bram1 [15:0] PLACED = X0Y1;
END_BUS_BLOCK;
// Address Range: 0x1000:0x17FF -- Each Block RAM is 2kB in size.
BUS_BLOCK
bram/bram2 [15:0] PLACED = X0Y2;
END_BUS_BLOCK;
// Address Range: 0x1800:0x1FFF -- Each Block RAM is 2kB in size.
BUS_BLOCK
bram/bram3 [15:0] PLACED = X0Y3;
END_BUS_BLOCK;
END_ADDRESS_SPACE;
You may have already tried something like this. If so, let me know. I've got a couple of other ideas to try.