Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
12 years ago

Quartus sythesizes double the on-chip memory bits

Hello,

I'm testing out how to code and simulate the on-chip memory usage, which is working well.

However I've noticed in the Flow Summary window after compiling, it's using double the memory bits that my code is set to use. The Altera-Sim correctly shows me the memory usage that I've coded in HDL, not the "phantom" bits. Could it be an optimization or some other synthesizer option causing this?

I've created a really basic HDL file which calls an instantiated MegaWizard single port RAM module to simulate this behavior. Everything is 16bit (input data, RAM width, output data, etc), yet Quartus synthesizes 32 bits in the Flow Summary?

Any help is greatly appreciated.

Verilog HDL code:


module mem_test (clock, data_in, data_out);
parameter ADDR_WIDTH = 16;
input clock;
input data_in;
output wiredata_out;
single_port_ram RAM1 (address, clock, data_in, wren, data_out);
endmodule

MegaWizard Single Port RAM HDL code:


// megafunction wizard: %RAM: 1-PORT%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: altsyncram
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module single_port_ram (
    address,
    clock,
    data,
    wren,
    q);
    input      address;
    input      clock;
    input      data;
    input      wren;
    output      q;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
    tri1      clock;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif
    wire  sub_wire0;
    wire  q = sub_wire0;
    altsyncram    altsyncram_component (
                .address_a (address),
                .clock0 (clock),
                .data_a (data),
                .wren_a (wren),
                .q_a (sub_wire0),
                .aclr0 (1'b0),
                .aclr1 (1'b0),
                .address_b (1'b1),
                .addressstall_a (1'b0),
                .addressstall_b (1'b0),
                .byteena_a (1'b1),
                .byteena_b (1'b1),
                .clock1 (1'b1),
                .clocken0 (1'b1),
                .clocken1 (1'b1),
                .clocken2 (1'b1),
                .clocken3 (1'b1),
                .data_b (1'b1),
                .eccstatus (),
                .q_b (),
                .rden_a (1'b1),
                .rden_b (1'b1),
                .wren_b (1'b0));
    defparam
        altsyncram_component.clock_enable_input_a = "BYPASS",
        altsyncram_component.clock_enable_output_a = "BYPASS",
        altsyncram_component.intended_device_family = "Cyclone IV E",
        altsyncram_component.lpm_hint = "ENABLE_RUNTIME_MOD=NO",
        altsyncram_component.lpm_type = "altsyncram",
        altsyncram_component.numwords_a = 32,
        altsyncram_component.operation_mode = "SINGLE_PORT",
        altsyncram_component.outdata_aclr_a = "NONE",
        altsyncram_component.outdata_reg_a = "UNREGISTERED",
        altsyncram_component.power_up_uninitialized = "FALSE",
        altsyncram_component.ram_block_type = "M9K",
        altsyncram_component.read_during_write_mode_port_a = "DONT_CARE",
        altsyncram_component.widthad_a = 5,
        altsyncram_component.width_a = 16,
        altsyncram_component.width_byteena_a = 1;
endmodule

7 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Your "mem_test" module references signals "address" and "wren" which you have not defined anywhere.

    Fix those problems and try again.

    If you are still confused about what is happening, check the report Fitter->Resource Section->RAM Summary and see what it thinks it's doing for you.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The memories inside fpga are block ram, so it's possible the memory usage is more than implemented by your own codes.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Your "mem_test" module references signals "address" and "wren" which you have not defined anywhere.

    Fix those problems and try again.

    If you are still confused about what is happening, check the report Fitter->Resource Section->RAM Summary and see what it thinks it's doing for you.

    --- Quote End ---

    I've just had a look at the report, and it says:

    Implementation Port A Width = 16

    Implementation Port A Depth = 2

    That would be 32bits. Any reason why it's using 2 deep even though I've fixed the address to a single address?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    One address bit can be used to select (2) values.

    If what you really want is zero address bits, with only 16 bits of storage, then why do you want to use a RAM at all and why not just use a register?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi ted,

    Thanks for your help so far. I plan on using a lot of ram in a future project and would like to understand the usage and functionality beforehand.

    I've modified the "mem_test" module with a fixed "address" of 0, and pulsing on/off the "wren" bit every 16-ish cycles, no change.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The behavior you are seeing is most likely the result of how the tools are optimizing away resources due to the fact that your supplied address is fixed value. For example, it doesn't know how to produce zero address lines, so you are stuck with one address line after synthesis, which the fitter knows can correspond to a depth of 2.

    Make your 'address' come from an input port and you will find that the RAM summary will report a power-of-two 'depth' based on the width of the address.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    ted, you're a champ! I've set "address" as an input and specified the number of address bits which does synthesize to a power of 2 times address width. EG:

    1 bit address = 16*2 = 32bits used.

    2 bit address = 16*4 = 64bits used.

    Thanks again!