Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
14 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

    FvM,

    Thanks for the continued guidance. Am new to the FPGA world, so I'm sure my Q's are rather sophomoric. Not sure I understand you post about behavioral logic (I understand there is a difference between this and combinatorial logic). Could I ask for a VERY brief example of how you implement this as behavioral.

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

    one more thing after re-reading all the posts:

    branch_address and current_tdr_address are defined as:

    reg [15:0] branch_address;

    reg [15:0] current_tdr_address;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    SO I tried something a little different. Rather than creating the if else construct, I did something like this (inside a state machine):

    branch_found:

    begin

    greater_than_false_address[0] <= (current_tdr_address >= branch_false_address[0]) ? 1 :0;

    less_than_true_address[0] <= (current_tdr_address < branch_true_address[0]) ? 1 : 0;

    equal_to_true_address[0] <= (current_tdr_address == branch_true_address[0]) ? 1 : 0;

    branch_processor_state[0] <= processing_branch;

    end

    processing_branch:

    begin

    decision[current_tdr_address] <= greater_than_false_address[0] & less_than_true_address[0];

    end

    All synthesizes well with the same logic and memory usage statistics until I add the single assignment in the processing_branch case.

    I checked my settings and the max_number_of_uninferred_ram_logic is set to -1 (no max). Have attempted to read up on inferred/uninferred ram. It seems that the documentation would be quite helpful for someone that already understood the paradigm. However, I am having trouble converting that written academics to the practical problem that I have (I'm not the sharpest tool in the shed).

    Any help is greatly appreciated....

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

    The post mainly shows that's it's useless to show small code snippets. It's even unclear, if you have synchronous (in an edge sensitive always block) or asynchronous writes to reg decision.

    I suggest to try it the other way around. Understand about the hardware features of FPGA internal RAM and the requirements of RAM inference from behavioral code. Then write your code considering these informations.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Sorry for the confusion. Was trying to simplify the problem for brevity's sake.

    Basically, I am capture the address bus on an old 80196 MPU using Cyclone 4 on a TerASIC DE2-115. Am using a NIOS II processor which preprocesses the 80196 list files to determine if a given address is a branch or not. If so, the branch offset is loaded into the TerASIC SRAM at an offset equal to the MPU address (so if MPU address 0x1234 represents a branch 0f 12, I store 12 at SRAM offset 0x1234).

    When a new address is available, I calculate the two addresses: one the represents the jump that occurs if the branch evaluates true, the other if false (I have to deal with a 5 byte prefetch on the false side).

    All of this synthesizes and fits quite well. My total logic element usage is 13% and my totoal memory bit usage is 53%. This 53% includes a 128k bit array that defines a true and false branch indication for each of the 64k addresses. So I don't think I'm running out of FPGA RAM due to the bit array.

    Once I determine that a given address represents a branch, I continue to collect addresses until either the true or false case is resolved. This is where I run into the RAM megafunction error. The code is in an always loop and looks like this (note branch_address is calculated earlier and is used as an index into the decision array):

    reg decision[0:128k-1] - Sorry too early in the morning to calculate 128 * 1024 - 1

    if ((new_address > branch_false_address) && (new_address < branch_true_address))

    decision[branch_address] <= 1;

    else if (new_address == branch_true_address)

    decision[branch_address+65536] <= 1

    Adding this seeming innocuous code is where the problem lies. Am working to understand if it is the conditional logic statements or trying to set the decision array element that is causing me the problem. It seems that it is the conditionals that are causing the problem. BUt will confirm...

    Hope this clears it up some. Any more thoughts are greatly appreciated.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Besides observing the conditions for RAM inference, you should think about the data type of reg a. It's a bit variable, how can it address a memory array?

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

    Your simplified code isn't very clear.

    But from the looks of the message, you're designing something that requires a huge number of register (more than the FPGA has) and can't be converted to use SRAM.

    What you need to do is to try and re-write your code in such a way that it uses SRAM and meets Quartus HDL SRAM templates.

    See the HDL coding guidelines handbook for details.