Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Unable to infer RAM on Quartus Prime

Status
Not open for further replies.

FecP

Newbie level 6
Joined
Oct 17, 2016
Messages
14
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
160
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!
 


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?
 

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?
 

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.
 

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.
 

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

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.
 

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

 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top