+ Post New Thread
Results 1 to 9 of 9
  1. #1
    Newbie level 6
    Points: 163, Level: 2

    Join Date
    Oct 2016
    Posts
    14
    Helped
    0 / 0
    Points
    163
    Level
    2

    Unable to infer RAM on Quartus Prime

    Hi! I am trying to infer a single port ram with width = 8 bits and depth = 2^13.
    This is the code that I've pulled from the templates and the altera website for a single port ram with one read/write address and write before read behaviour.

    Code:
    	reg [7:0] ram[8191:0];
    	reg [12:0] ptr;
    	reg [12:0] ptr_reg;
    	
    	always @ (posedge read_clock)
    	begin
    		if (we)
    	           ram[ptr] <= Write_Val1;
    		   ptr_reg   <= ptr;
    	end
    		
    	always @(posedge read_clock) 
    	begin
    		if (!RESET) ptr <= 0; 
    		else if (we || re) ptr <= ptr + 1;
    	end
    
    	assign outputq = ram[ptr_reg];
    When I compile this, I get the following warning
    "Warning (276002): Cannot convert all sets of registers into RAM megafunctions when creating nodes; therefore, the resulting number of registers remaining in design can cause longer compilation time or result in insufficient memory to complete Analysis and Synthesis."

    Strangely, explicitly using the megafunction wizard/IP core, I get no such warning and I can verify that the exact same ram configuration has been synthesized.

    What appears to be the problem?

    Thank you!

  2. #2
    Super Moderator
    Points: 30,484, Level: 42
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    7,012
    Helped
    1676 / 1676
    Points
    30,484
    Level
    42

    Re: Unable to infer RAM on Quartus Prime

    This does not look anything like the standard code for inferring a RAM http://quartushelp.altera.com/14.1/m...m_inferred.htm.

    One thing is that extra ptr_reg, which is generating the output and the we || re stuff with an auto incrementing ptr (address) which does not exist in any Altera block RAM.



    •   AltAdvertisment

        
       

  3. #3
    Newbie level 6
    Points: 163, Level: 2

    Join Date
    Oct 2016
    Posts
    14
    Helped
    0 / 0
    Points
    163
    Level
    2

    Re: Unable to infer RAM on Quartus Prime

    I tried this too, but it didn't work. The code I posted can be found in the Quartus Prime Menu :
    Edit--->Insert Template---> Verilog HDL---->Full Designs----> RAMs & ROMs----> Single Port Ram.

    As for the second point, I am incrementing the pointer whenever the ram is written to or read from.Is this not okay? How am I supposed to traverse the contents of the RAM without incrementing the pointer?



  4. #4
    Advanced Member level 5
    Points: 37,449, Level: 47
    Achievements:
    7 years registered

    Join Date
    Jun 2010
    Posts
    6,805
    Helped
    1997 / 1997
    Points
    37,449
    Level
    47

    Re: Unable to infer RAM on Quartus Prime

    Id say it does look like the ram thats expected. Can you post the code in context? are you using it in some illegal way?
    What device are you using? has it got enough ram bits?



    •   AltAdvertisment

        
       

  5. #5
    Super Moderator
    Points: 30,484, Level: 42
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    7,012
    Helped
    1676 / 1676
    Points
    30,484
    Level
    42

    Re: Unable to infer RAM on Quartus Prime

    Quote Originally Posted by FecP View Post
    I tried this too, but it didn't work. The code I posted can be found in the Quartus Prime Menu :
    Edit--->Insert Template---> Verilog HDL---->Full Designs----> RAMs & ROMs----> Single Port Ram.

    As for the second point, I am incrementing the pointer whenever the ram is written to or read from.Is this not okay? How am I supposed to traverse the contents of the RAM without incrementing the pointer?
    Okay fine, but you've organized the code poorly...IMO the incrementing pointer code should not be stuffed in between the read output of the ram and the ram, yes the tools will infer what you mean, but at a glance a human (like me) will have to study the code to figure out the pointer addition logic is misplaced in the code.

    BTW why do you use a read clock to write to the ram? If it is a synchronous ram with the read and write clocks the same it shouldn't be called a read clock. You should really consider putting any inferred rams in their own file so there is no other code (to confuse things) beside the inferred ram and you can then synthesize the ram by itself to ensure it will infer the ram you expect.

    Maybe TrickyDicky is better at reading badly organized code. I guess I'm just too used to reading my own code now days as I don't get stuck with the horrible, pick up the POS code and make it work tasks, like I used to get stuck with all the time.



  6. #6
    Newbie level 6
    Points: 163, Level: 2

    Join Date
    Oct 2016
    Posts
    14
    Helped
    0 / 0
    Points
    163
    Level
    2

    Re: Unable to infer RAM on Quartus Prime

    No, I don't think I am using it illegally because the exact same parameters and port connections infer RAM when the Megafunction wizard is used.I appreciate the organization tips and will continue to look into this and post here.



  7. #7
    Super Moderator
    Points: 30,484, Level: 42
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    7,012
    Helped
    1676 / 1676
    Points
    30,484
    Level
    42

    Re: Unable to infer RAM on Quartus Prime

    I always put my inferred rams in a separate file, makes for a cleaner design and allows for easier code reuse.



  8. #8
    Advanced Member level 3
    Points: 5,972, Level: 18

    Join Date
    Feb 2015
    Posts
    979
    Helped
    280 / 280
    Points
    5,972
    Level
    18

    Re: Unable to infer RAM on Quartus Prime

    Does the combinatorial assignment to outputq confuse the tools?

    For example, I know that the assignment could be moved into the always block, and ptr could be used, but do the tools notice this?

    It also seems harsh to call the organization "poor". The only thing that bothers me is the lack of begin/end with if/else statements. Especially given the indentation of ptr_reg. I can justify the other decisions even though I wouldn't have made them.

    - - - Updated - - -

    from: Quartus II Handbook Version 9.1 Volume 1: Design and Synthesis, Chapter 6: Recommended HDL Coding Styles

    One common problem occurs when there is a continuous read in the HDL code, as
    shown in the following examples. You should avoid using these coding styles:
    Code:
    //Verilog HDL concurrent signal assignment
    assign q = ram[raddr_reg];
    -- VHDL concurrent signal assignment
    q <= ram(raddr_reg);
    When a write operation occurs, this type of HDL implies that the read should
    immediately reflect the new data at the address, independent of the read clock.
    However, that is not the behavior of TriMatrix memory blocks. In the device
    architecture, the new data is not available until the next edge of the read clock.



    •   AltAdvertisment

        
       

  9. #9
    Super Moderator
    Points: 255,029, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    44,441
    Helped
    13537 / 13537
    Points
    255,029
    Level
    100

    Re: Unable to infer RAM on Quartus Prime

    I don't understand the initially reported problem. I supplemented a module header and got inferred RAM in Quartus 13.1 and 15.1 without warnings.

    Code Verilog - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
    module my_ram 
     
    (
        input [7:0] Write_Val1,
        input re, we, read_clock,RESET,
        output [7:0] outputq
    );
    reg [7:0] ram[8191:0];
        reg [12:0] ptr;
        reg [12:0] ptr_reg;
        
        always @ (posedge read_clock)
        begin
            if (we)
                   ram[ptr] <= Write_Val1;
               ptr_reg   <= ptr;
        end
            
        always @(posedge read_clock) 
        begin
            if (!RESET) ptr <= 0; 
            else if (we || re) ptr <= ptr + 1;
        end
     
        assign outputq = ram[ptr_reg];
    endmodule



--[[ ]]--