After adding the line number_of_lines <= ram[0], Vivado won't synthesize a BRAM component. Instead I got a LUT scheme.
module bram3 (clka,clkb,ena,enb,wea,web,addra,dia,dib,doa,dob,rst);
input clka,clkb,ena,enb,wea,web,rst;
input [11:0] addra;
input [63:0] dia,dib;
output [63:0] dob, doa;
reg [32:0] ram [254:0];
reg [32:0] dob, doa;
reg [11:0] new_addr=0;
reg [11:0] number_of_lines=0;
always @(posedge clka)
begin
if (ena)
begin
if (wea) ram[addra] <= dia;
doa <= ram[addra];
end
end
always @(posedge clkb or negedge rst)
begin
if (!rst)
begin
new_addr<=0;
end
else if (enb)
begin
if (new_addr==0)
number_of_lines <= ram[0];
new_addr<=new_addr+1;
dob <= ram[new_addr];
if (new_addr==number_of_lines)
new_addr<=0;
end
end
endmodule
I understand that I can't do more than 2 reads (in my code I got 3 reads), but I need logic to work as I implemented in my code.
How can I rewrite the logic to make a synthesizable BRAM like?
Like Soheil wrote above in the comments, you can just store number of lines on the side, outside of the BRAM, and by that reduce one read port.
It should look something like the next:
Notes:
I've separated the BRAM logic (the first two always blocks) from the new_addr and everything extra you've added.
I've added a addr0_shadow register which acts as ram address #0. Every time you write to address #0 this register samples the data as well. I didn't write directly to number_of_lines since I wanted to make this a close as possible to your current RTL behavior. Maybe you can write it directly.
I didn't check for compilation or behavioral functionality. I leave this to you.