This is the original code,It is synthesized as a BRAM
module RAM_IMAGINARY (clk, we, en, addr, di, dout);
input clk;
input we;
input en;
input [7:0] addr;
input [15:0] di;
output [15:0] dout;
logic [15:0] RAM_IMAGINARY [167:0];
logic [15:0] dout;
always @(posedge clk)
begin
if (en)begin
if (we) begin
RAM_IMAGINARY[addr] <= di;
dout <= di;
end
else
dout <= RAM_IMAGINARY[addr];
end
end
endmodule
I want to write a whole column in my memory at a cycle, Imagine that this RAM is 12x14.
I also tried to instantiate just one of the 12 in each module like so ,but they weren't recognized as BRAMs due to the small width and depth.
module RAM_IMAGINARY (clk, we, en, addr, di, dout);
input clk;
input we;
input en;
input [7:0] addr;
input [15:0] di;
output [15:0] dout;
logic [15:0] RAM_IMAGINARY [13:0];
logic [15:0] dout;
always @(posedge clk)
begin
if (en)begin
if (we) begin
RAM_IMAGINARY[addr] <= di;
dout <= di;
end
else
dout <= RAM_IMAGINARY[addr];
end
end
endmodule
module Top(clk, we, en, addr, di, dout0,dout1,dout2,dout3,dout4,dout5,dout6,dout7,dout8,dout9,dout10,dout11);
input clk;
input we;
input en;
input [7:0] addr;
input [15:0] di;
output [15:0] dout0,dout1,dout2,dout3,dout4,dout5,dout6,dout7,dout8,dout9,dout10,dout11;
RAM_IMAGINARY RAM0 (clk, we, en, addr, di, dout0) ;
RAM_IMAGINARY RAM1 (clk, we, en, addr, di, dout1) ;
RAM_IMAGINARY RAM2 (clk, we, en, addr, di, dout2) ;
RAM_IMAGINARY RAM3 (clk, we, en, addr, di, dout3) ;
RAM_IMAGINARY RAM4 (clk, we, en, addr, di, dout4) ;
RAM_IMAGINARY RAM5 (clk, we, en, addr, di, dout5) ;
RAM_IMAGINARY RAM6 (clk, we, en, addr, di, dout6) ;
RAM_IMAGINARY RAM7 (clk, we, en, addr, di, dout7) ;
RAM_IMAGINARY RAM8 (clk, we, en, addr, di, dout8) ;
RAM_IMAGINARY RAM9 (clk, we, en, addr, di, dout9) ;
RAM_IMAGINARY RAM10 (clk, we, en, addr, di, dout10) ;
RAM_IMAGINARY RAM11 (clk, we, en, addr, di, dout11) ;
endmodule
This is my code which is a typical BRAM code from vivado guide, I want to write into a whole column at once, imagine that it is a 12x14 memory. I tried to instantiate 12 rams and write into each one at the same cycle ,but due to the small depth and width, it wasn't recognized as a BRAM. Help
I tried writing into 12 addresses at same cycle
I added the
(* ram_style = “block” *)attribute to the RAM_IMAGINARY model, now it is recognized as BRAM during Vivado synthesis as a stand-alone module and as a instance in the Top module.The tool needed a hint re the intent to infer BRAM.
Sometimes the tool needs the attribute to infer what you want (BRAM, DSP Block etc); sometimes not. Its tricky to know why. I think the details involve the tool optimizing recourses given the circumstances. Vivado seems to want to use distributed RAM aka LUT RAM if it can. If you use the true dual port model then the tool can't use LUT RAM and I think the bias switches to BRAM. If you model structures not supported as RAM, then the tool will use logic fabric.
Here is the ram model with the attributed added
I used your Top module with no changes
See UG901 P49 for more on the ram_style attribute.
(* ram_style = “block” *)causes compile errors for me in the big four commercial simulators available on EDA Playground; its a Xilinx/Vivado attribute only.The post synthesis schematic and utilization report summary look like this, after adding the attribute
As you can see Vivado inferred a single memory. The Top model RTL is structurally modeled as 12 memories, however the same address and data are connected to each memory. The same data would be read from all 12. Because of this, Vivado optimizes and infers one memory connected to all 12 output busses. If you modify the code to use 12 unique addresses then the tool will infer 12 memories. You could modify the design to use 12 unique addresses on the read side and the tool should infer 12 memories.
Here is the 12 memories version\w a parameter to set the number of memories.
And the synthesis result