I'm trying to make a memory in system verilog and it can be synthesised only when I want to write to the memory directly.
Here is a code that DOES work:
module top (
input logic clk_i,
output logic data_o
);
reg [31:0] counter = '0;
(* ram_style="block" *)
reg [31:0] video_ram_array [0:(2**15)-1];
always_ff @(posedge clk_i) begin
counter <= counter + 1;
// video_ram_array[counter] <= counter;
video_ram_array[counter] <= 32'h1234;
end
always_comb begin
data_o = video_ram_array[counter][0];
end
endmodule
And here is what does NOT work:
module top (
input logic clk_i,
output logic data_o
);
reg [31:0] counter = '0;
(* ram_style="block" *)
reg [31:0] video_ram_array [0:(2**15)-1];
always_ff @(posedge clk_i) begin
counter <= counter + 1;
video_ram_array[counter] <= counter;
// video_ram_array[counter] <= 32'h1234;
end
always_comb begin
data_o = video_ram_array[counter][0];
end
endmodule
It maybe a rookie mistake, but I'm not sure what I am doing wrong. The error in the seconds code block is:
2.8. Executing MEMORY_LIBMAP pass (mapping memories to cells).
<suppressed ~2 debug messages>
ERROR: no valid mapping found for memory top.video_ram_array
make: *** [run] Error 1
I'm using Yosys for synthesis.
EDIT: I'm trying to synthesise for Tang nano 4k, which only has 180k Bits of memory if I'm not mistaken. But I get the same error even if make a very small RAM:
module top (
input logic clk_i,
output logic data_o
);
reg [31:0] counter = '0;
(* ram_style="block" *)
reg [31:0] video_ram_array [0:2];
always_ff @(posedge clk_i) begin
counter <= counter + 1;
video_ram_array[counter & 32'h0000_0003] <= counter;
end
always_comb begin
data_o = video_ram_array[counter][0];
end
endmodule
It may be working the first time because the synthesiser will optimise the BRAM out, but in the same time when launching Yosys to generate me a output json, visualising it via netlistsvg will show it exactly like I would want to. But that does not really mean it is really happening...

dout_o = 32'h1234. The second onecountergoes out of range. Try wraparound (ex:counter <= (counter>=32'h0000_FFFF) ? 0 : counter+1) or try address masking (ex:video_ram_array[counter & 32'h0000_FFFF] <= counter;)