Forum Discussion

GDagi1's avatar
GDagi1
Icon for Occasional Contributor rankOccasional Contributor
5 years ago
Solved

Unable to Infer M9K in Quartus

Hi all,

I borrowed some code from a Xilinx project, where RAM was inferred successfully. I would like to do the same in my Quartus 18.1 project with my MAX10 FPGA DevKit. Here's both methods of inferring I have attempted:

reg [(DWIDTH-1):0] mem [(1<<AWIDTH)-1:0] /* synthesis ramstyle = M9K */;

(* ramstyle = "M9K" *) reg [(DWIDTH-1):0] mem [(1<<AWIDTH)-1:0];

Neither of which throw any errors or warnings (searched Quartus console).

I have also checked the resource utilization report, and see Logic Cells (~10,000) / Dedicated Logic Registers (~8000) being used rather than M9Ks (0).

Thanks in advance!

  • Your code for the memory block itself is way too complicated for Quartus to infer it from block rams.

    You need to look at the verilog templates that Quartus supplies for inferred memory.

    Here is what I use and it infers as block ram (M9K, M4K depending) just fine.

    Note addr, mdi, mwr are wire type; mdo are reg type.

    reg [0:11] memory [0:MEMSIZE-1] /* synthesis ramstyle = "no_rw_check" */;

    always @(posedge clk)
    begin
    if (mwr) memory[addr] <= #TPD mdi;
    mdo <= #TPD memory[addr];
    end

5 Replies

  • sstrell's avatar
    sstrell
    Icon for Super Contributor rankSuper Contributor

    Where is the code for how the RAM is to operate? If you don't code the RAM properly, it's not going to get inferred into a RAM block.

    • GDagi1's avatar
      GDagi1
      Icon for Occasional Contributor rankOccasional Contributor

      always@(posedge clk) begin
      if(rst) begin
      // set things to 0
      end

      else begin
      if((|wea_r) && wr_ena_r) begin
      for (i = 0; i < (DWIDTH/8); i=i+1) begin
      if (wea_r[i]) begin
      for (j = 0; j < 8; j = j + 1) begin
      mem[wr_addr_r][(8*i)+j] <= data_in_r[(8*i)+j] && wea_r[i];
      end
      end
      end
      end

      if (rd_ena)
      data_out_r <= mem[rd_addr_r];
      else
      data_out_r <= 0;
      end
      end

      • ak6dn's avatar
        ak6dn
        Icon for Regular Contributor rankRegular Contributor

        Your code for the memory block itself is way too complicated for Quartus to infer it from block rams.

        You need to look at the verilog templates that Quartus supplies for inferred memory.

        Here is what I use and it infers as block ram (M9K, M4K depending) just fine.

        Note addr, mdi, mwr are wire type; mdo are reg type.

        reg [0:11] memory [0:MEMSIZE-1] /* synthesis ramstyle = "no_rw_check" */;

        always @(posedge clk)
        begin
        if (mwr) memory[addr] <= #TPD mdi;
        mdo <= #TPD memory[addr];
        end