verilogsystem-verilogfpgayosys

Verilog: mapping an memory array


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...netlistsvg output


Solution

  • module top (
            input wire clk_i,
            output reg data_o
        );
    
        reg [31:0] counter=0;
    
        (* ram_style="block" *)
        reg [31:0] video_ram_array [0:(2**4)-1];
    
        always @(posedge clk_i) begin
            counter <= counter + 1;
            video_ram_array[counter] <= counter;
            // video_ram_array[counter] <= 32'h1234;
        end
    
    
        always @ * begin
            data_o = video_ram_array[counter][0];
        end
    
    endmodule