Forum Discussion

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

RAM property help

Hi all,

I have a question about using on chip ram. According to what I read from the quartus handbook, the port input (e.g. address, input data) to a RAM should be clocked in order to let software fit the design to the on chip memory (otherwise it may use logic cell to finish the fitting). [Correct me if I did not get this right]

Now, I am doing some kind of sorting data of a true dual port ram, m1. What I am trying to do is input two addresses, adr1 & adr2 into m1, and get two data output, q1 & q2. Then I need to compare q1 & q2 and save each pair in ascending order to another true dual port ram, m2.

example : m1 :[ 4, 1, 5 ,2] ==[take pair 1 and compare] ==> m2 : [1, 4, X, X]

m1 : [4, 1, 5 ,2 ] ==[take pair 2 and compare] ==> m2 : [1, 4, 2, 5]

etc..

I can make sure the input (address) of m1 is clocked, but I am not sure if the input of m2 (input data & address) is clocked in this case, since the output data from m1 have to be compared before input to m2.

The following is the code I have write


PROCESS (clk)
VARIABLE rd1 : INTEGER := 0;
VARIABLE rd2 : INTEGER := 1;
VARIABLE wr1 : INTEGER := 0;
VARIABLE wr2 : INTEGER := 1;
BEGIN
IF RISING_EDGE (CLK) THEN---------------------------------------
        --         read data from m1----------------------------------------
IF (rd1 < 128) THEN
M1RdenA <= '1';
    M1RdenB <= '1';
    M1AdrA <= STD_LOGIC_VECTOR (TO_UNSIGNED (rd1, 7));
    M1AdrB <= STD_LOGIC_VECTOR (TO_UNSIGNED (rd2, 7));
    rd1 := rd1 + 2;
    rd2 := rd2 + 2;
END IF;
--------------------------------------------
--           compare and save to m2
---------------------------------------------
IF (wr1 < 128) THEN
    IF (rd_delay < 3) THEN    ------------ read delay of 3 clock cycle due to clocked input and output for m1
    rd_delay := rd_delay + 1;
ELSE
        IF (M1QA = M1QB) THEN
            M2WrenA <= '1';
            M2WrenB <= '1';
            M2AdrA <= STD_LOGIC_VECTOR (TO_UNSIGNED (wr1, 7));
            M2AdrB <= STD_LOGIC_VECTOR (TO_UNSIGNED (wr2, 7));
            M2DataA <= M1QA;
            M2DataB <= M1QB;
            wr1 := wr1 + 1;
            wr2 := wr2 + 1;
        ELSIF (M1QA < M1QB) THEN
            M2WrenA <= '1';
            M2WrenB <= '1';
            M2AdrA <= STD_LOGIC_VECTOR (TO_UNSIGNED (wr1, 7));
            M2AdrB <= STD_LOGIC_VECTOR (TO_UNSIGNED (wr2, 7));
            M2DataA <= M1QA;
            M2DataB <= M1QB;
            wr1 := wr1 + 1;
            wr2 := wr2 + 1;
        ELSIF (M1QA > M1QB) THEN
            M2WrenA <= '1';
            M2WrenB <= '1';
            M2AdrA <= STD_LOGIC_VECTOR (TO_UNSIGNED (wr2, 7));
            M2AdrB <= STD_LOGIC_VECTOR (TO_UNSIGNED (wr1, 7));
            M2DataA <= M1QA;
            M2DataB <= M1QB;
            wr1 := wr1 + 1;
            wr2 := wr2 + 1;
        END IF;
    END IF; 
END IF;
END IF;
END PROCESS;

7 Replies

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

    They are clocked here, but this isn't your ram logic. What problems are you having with your code?

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

    Hi,

    I am writing a sorting network with 64 nodes and 5 RAMs in each node, but according to the compiling result, some of the RAMs is fitting using logic cell but not on chip memory which reduce the performance a lot.

    According to the compiling report, there is 64 RAMs which is compiled using logic cell. After I do some search about the problem, it seems the unclocked input may cause this problem, thus I just wondering if my compare and and input to m2 process have this unclocked problem. If not, I may need to look at other place of the code.

    Is there any way I can check which RAM is fitting to logic cell but not on chip memory?

    Thanks for the help.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You didn't show the ram code. If you are having problems inferring ram, you may be better off generating the ram from the megawizard/ip catalogue to ensure you alwaus get the ram you want.

    Without seeing the ram code, is impossible to say what's wrong with your code.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    hi&#65292;

    I use the wizard to generate most of the ram and port map to it. the only ram i did not directly use wizard is the one with mif file. There are 64 of them with different mif file. But I just copy the code and edit the mif file name only.

    
    LIBRARY ieee;
    USE ieee.std_logic_1164.all;
    LIBRARY altera_mf;
    USE altera_mf.altera_mf_components.all;
    ENTITY mem_0 IS
       PORT
       (
          address_a      : IN STD_LOGIC_VECTOR (6 DOWNTO 0);
          address_b      : IN STD_LOGIC_VECTOR (6 DOWNTO 0);
          clock      : IN STD_LOGIC  := '0';
          data_a      : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
          data_b      : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
          rden_a      : IN STD_LOGIC  := '1';
          rden_b      : IN STD_LOGIC  := '1';
          wren_a      : IN STD_LOGIC  := '0';
          wren_b      : IN STD_LOGIC  := '0';
          q_a      : OUT STD_LOGIC_VECTOR (31 DOWNTO 0)
          q_a      : OUT STD_LOGIC_VECTOR (31 DOWNTO 0)
       );
    END mem_0;
    ARCHITECTURE SYN OF mem_0 IS
       SIGNAL sub_wire0    : STD_LOGIC_VECTOR (31 DOWNTO 0);
       SIGNAL sub_wire1    : STD_LOGIC_VECTOR (31 DOWNTO 0);
    BEGIN
       q_a    <= sub_wire0(31 DOWNTO 0);
       q_b    <= sub_wire0(31 DOWNTO 0);
       altsyncram_component : altsyncram
       GENERIC MAP (
          address_reg_b => "CLOCK0",
          clock_enable_input_a => "BYPASS",
          clock_enable_input_b => "BYPASS",
          clock_enable_output_a => "BYPASS",
          clock_enable_output_b => "BYPASS",
          indata_reg_b => "CLOCK0",
          init_file => "router_0_init_data.mif",  ----------- I only edit this line for diff mif file name 
          intended_device_family => "Stratix V",
          lpm_type => "altsyncram", 
          numwords_a => 128,
          numwords_b => 128,
          operation_mode => "BIDIR_DUAL_PORT",
          outdata_aclr_a => "NONE",
          outdata_aclr_b => "NONE",
          outdata_reg_a => "CLOCK0",
          outdata_reg_b => "CLOCK0",
          power_up_uninitialized => "FALSE",
          ram_block_type => "M20K",
          read_during_write_mode_mixed_ports => "DONT_CARE",
          read_during_write_mode_port_a => "NEW_DATA_NO_NBE_READ",
          read_during_write_mode_port_b => "NEW_DATA_NO_NBE_READ",
          widthad_a => 7,
          widthad_b => 7,
          width_a => 32,
          width_b => 32,
          width_byteena_a => 1,
          width_byteena_b => 1,
          wrcontrol_wraddress_reg_b => "CLOCK0"
       )
       PORT MAP (
          address_a => address_a,
          address_b => address_b,
          clock0 => clock,
          data_a => data_a,
          data_b => data_b,
          rden_a => rden_a,
          rden_b => rden_b,
          wren_a => wren_a,
          wren_b => wren_b,
          q_a => sub_wire0,
          q_b => sub_wire1
       );
    END SYN;
    

    The above is what I have for the ram with .mif file. Then I use matlab to print these code 64 time with different mif file name. Is there anything wrong with it?

    Currently I am not sure which memory is fitted to logic cell, but other rams I have is directly port map to the wizard generated component, thus I think the above one might be the one using logic cell.

    Is there any way I can check which ram is generated by logic cell? Does Quartus have this function?

    many thanks for the help.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    What is your BLOCK RAM utilization on the device (you don't say which device/family you are using). Maybe your design is utilizing all the available BLOCK RAM?

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

    In the fitter report tyre is a section that lists resource usage by entity. You can use this to find it which block is using lutram rather than dedicated rams. But i suspect you have run out of ram is they are all generated from the mega Wizard.

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

    I use a stratix V chip. I only use around 2% of Block Memory according to the report. I will take a look of fitter report. Thanks for the help!