Forum Discussion

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

Verilog Synthesis Q

Am bumping into a synthesis problem inside of an always construct. Simplified code is

reg true_or_false[0:9999];

reg a;

always (negedge clk)

begin

if (a <5000)

true_or_false[a] <= 1

else if (a < 10000)

true_or_false[a+5000] <= 1

end

The error I get is "Cannot convert all sets of registers into RAM megafunctions when creating nodes. The resulting number of registers remaining in design exceeds the number of registers in device....."

If I remove the if else construct, no allocations (register/memory/etc) are > 30%.

I'm quite sure I'm violating an HDL paradigm. Could use a little guidance on why and thoughts on how I might implement it correctly.

THNX,

ME

17 Replies

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

    Another thought as I work my way through this....

    The array in question is also accessed from the NIOS CPU via an Avalon MM Slave interface. This works quite well. My NIOS application successfully reads and writes to the same array I am trying to access. I do have a single bit entity that defines whether the NIOS or my custom FPGA code has access to the array. Does the use of the Avalon MM slave "force" quartus to define the array as memory (thus why it shows up as memory bits in the compilation report)?

    Thanks again,

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

    First question:

    Indeed, the write condition is not required for the code to be inferred into RAM.

    You'll just get a RAM block which is constantly writing into the position indicated by address.

    Second question:

    I assume you refer to the code in your post# 6. Two questions there.

    1. If you don't have a statement which writes the RAM, the reads always return 0 and thus Quartus should optimize it away entirely.

    2. How do you read it?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Ok, that answers my questions.

    No, the Avalon-MM slave doesn't force anything. It's the reverse, actually.

    The way you've coded the read/write access from the Avalon-MM interface allows Quartus to infer RAM blocks. Which is happily does.

    When you add the extra code to write the array, you're adding something that is preventing Quartus from inferring a RAM.

    There are two reasons for Quartus not being able to infer a RAM.

    1. It's not possible. Your code describes a behaviour that the M9K blocks can't implement: asynchronous access or clearing the contents for example. Quartus tends to provide messages in those cases.

    2. Software limitation. Synthesis is somewhat pattern orientated and Quartus doesn't always recognize the code. That's why we have to follow the templates.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    First question: Yeah! I got one right.....8>)

    Second question: Yes, I am referencing the code which writes to the array in# 6. I am reading it via a NIOS CPU application via an Avaon MM slave interface. I'm guessing that even though I remove the write statement in# 6, because the array is accessed from the NIOS, it is being instantiated as RAM. The NIOS interface works perfectly (Can read and write to the array). As soon as I add something as simple as:

    decision[0] <= 1;

    to the code from# 6, i get the ram inference issue.

    At this point I'm working through the I don't know what I don't know issue. I appreciate your continued guidance...

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

    If decision[current_tdr_address] <= any_expression is inside an edge sensitive always block, and the only write access to the the register array, it should cause no difficulties to implement it in internal RAM. The problem can be caused on the read side as well. The problem can't be determined from these code snippets.

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

    DING..I think the light just went on. I have a different module that does a similar thing. However, it doesn't have to go through an complex logic. It simply sets a bit in a similar array based on the address that comes in. It works fine. It is also accessed via the NIOS application as well as from my custom code. However, all of the accesses (from both the NIOs and my FPGA code) are in the same synchronous always construct. The synthesizer displays a message that it is inferring RAM and now I think I understand why. Since both types of accesses are in the same always construct the synthesizer configures that array as RAM. However, in my decision array instance I was attempting to access the array via two different always constructs. In one instance as a Avalon MM slave and in the second as a direct write. In the second case, since i don't conform to the memory interface stndards, the synthesizer can't resolve it as memory and thus tries to make it registers.

    Am I close?

    Anyway, as soon as I moved the write access into the same always construct, everything started to compile.

    I'll see how this progresses today. Hopefully, you won't hear from me any mre.

    THANKS AGAIN TO BOTH OF YOU FOR YOUR HELP. I TRULY APPRECIATE YOU MENTORSHIP.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    FvM,

    Just saw your last post. My apologies for the code snippets. I wasn't trying to be evasive. I didn't want to post a plethora of code and ask you to fix it. I wanted to work through the issue so I understood why? Both your and rbug's guidance has been very helpful.

    I was planning on asking about inferred RAM upon completion of my project as I din't quite understand the implications. Based on today's thread and your guidance, I understand now.....

    You help is truly appreciated....

    Have a great day.

    Mark