verilogyosysice40

Cannot get yosys to infer BRAM


I'm vaguely following this tutorial with my ice40 breakout board. I've got to step 11 around separating out the memory into a module, and I cannot seem to persuade yosys to synthesise BRAM.

This is my memory module:

module memory (
    input                CLK,
    input      [31:0]    memory_address,      // the address to be read
    output reg [31:0]    memory_read_data,    // the data read from memory
    input                memory_read_strobe   // raised when address is valid to trigger read
);
    parameter SIZE = 256 - 1;

    reg [31:0] MEM[SIZE:0];

    integer  i;
    initial begin
        //                  f7   rs2   rs1    f3   rd   opcode
        // add x1, x1, x2
        //                add      x2   x1   add   x1   alureg
        MEM[0] = 32'b0000000_00010_00001_000_00001_0000001;

        // add x1, x1, x2
        //                add      x2   x1   add   x1   alureg
        MEM[1] = 32'b0000000_00010_00001_000_00001_0000010;

        // add x1, x1, x2
        //                add      x2   x1   add   x1   alureg
        MEM[2] = 32'b0000000_00010_00001_000_00001_0000100;
        MEM[3] = 32'b0000000_00010_00001_000_00001_0001000;
        MEM[4] = 32'b0000000_00010_00001_000_00001_0010000;
        MEM[5] = 32'b0000000_00010_00001_000_00001_0100000;
        MEM[6] = 32'b0000000_00010_00001_000_00001_1000000;
        MEM[7] = 32'b0000000_00010_00001_000_00001_0100000;
        MEM[8] = 32'b0000000_00010_00001_000_00001_0010000;
    end

    always @(posedge CLK) begin
      if(memory_read_strobe) begin
         memory_read_data <= MEM[memory_address[9:2]];
      end
   end

endmodule

and this is the bench I'm using to avoid having to post the whole processor:

`include "memory.v"

module memory_tb(
    input CLK,
    output reg [7:0] LED
);
    reg [31:0]  memory_address;
    reg         memory_read_strobe;
    wire [31:0] memory_read_data;
    reg         state;
    reg [31:0]  pc;

    memory RAM(
        .CLK(CLK),
        .memory_address(memory_address),   
        .memory_read_data(memory_read_data), 
        .memory_read_strobe(memory_read_strobe)
    );

    localparam k_state_fetch = 0;
    localparam k_state_wait  = 1;

    assign memory_address = programme_counter;
    assign memory_read_strobe = (state == k_state_fetch);

    always @(posedge DIV_CLK) begin
        case(state)
            k_state_fetch:
                state <= k_state_wait;
            k_state_wait: begin
                state <= k_state_fetch;
                pc <= pc + 1;
            end
        endcase
    end

    clockworks #(
`ifndef BENCH
        .SLOW(21)
`endif
    ) div_clk (
        .CLK(CLK),
        .DIV_CLK(DIV_CLK)
    );
endmodule

module clockworks 
(
   input  CLK,       // clock pin of the board
   output DIV_CLK    // (optionally divided) clock for the design.
);
    parameter SLOW=0;
    
    reg [SLOW:0] slow_CLK = 0;
    always @(posedge CLK) begin
        slow_CLK <= slow_CLK + 1;
    end
    assign DIV_CLK = slow_CLK[SLOW];
endmodule

I'm running yosys with this command:

yosys -p "read_verilog hw/memory_tb.v ; synth_ice40 -top memory_tb -json memory_tb.json" 

and the salient part of the output shows that no RAM is being synthesised:

Info: Device utilisation:
Info:            ICESTORM_LC:      41/   5280     0%
Info:           ICESTORM_RAM:       0/     30     0%
Info:                  SB_IO:      12/     96    12%
Info:                  SB_GB:       2/      8    25%
Info:           ICESTORM_PLL:       0/      1     0%
Info:            SB_WARMBOOT:       0/      1     0%
Info:           ICESTORM_DSP:       0/      8     0%
Info:         ICESTORM_HFOSC:       0/      1     0%
Info:         ICESTORM_LFOSC:       0/      1     0%
Info:                 SB_I2C:       0/      2     0%
Info:                 SB_SPI:       0/      2     0%
Info:                 IO_I3C:       0/      2     0%
Info:            SB_LEDDA_IP:       0/      1     0%
Info:            SB_RGBA_DRV:       0/      1     0%
Info:         ICESTORM_SPRAM:       0/      4     0%

The complete yosys output is here

I have found, and I believe followed, a zipcpu guide on the subject but I am neither getting BRAM or any warnings about not inferring BRAM. Does anyone understand what it is which I'm not doing correctly?


Solution

  • It turns out that I didn't wire the LED output to anything, and so yosys optimised the RAM away. If I add

        assign LED = memory_read_data[7:0];
    

    to the test bench, then the RAM is correctly synthesised:

    Info: Device utilisation:
    Info:            ICESTORM_LC:      27/   5280     0%
    Info:           ICESTORM_RAM:       1/     30     3%
    Info:                  SB_IO:       9/     96     9%
    Info:                  SB_GB:       3/      8    37%
    Info:           ICESTORM_PLL:       0/      1     0%