Sign In

Don't have a Xilinx account yet?

  • Choose to receive important news and product information
  • Gain access to special content
  • Personalize your web experience on Xilinx.com

Create Account

Username

Password

Forgot your password?
XClose Panel
Xilinx Home
Reply
Visitor
trounds
Posts: 7
Registered: ‎10-07-2011
0
Accepted Solution

RAM synthesis in registers instead of LUT

Hi All,

 

I am having trouble synthesizing LUT RAM (16 deep by 48 bit wide) and instead the RAM gets built from registers.  After experimenting I found I can get LUT RAM synthesis by commenting out some code I put in to help simulation.  In the code I have two blocks, one for simulation and one for implementation.  Which block gets used depends on an if (SIM_ENB=TRUE/FALSE) generate statement.  The only difference is that the simulation code initializes the memory to zero on reset or startup.  SIM_ENB is a generic boolean value.  I am surprised that it impacts the synthesis method when I set SIM_ENB=FALSE since it shouldn't generate the conditional reset code.

 

So my questions are:

1) Why does the unused and not generated code affect the code I want?  Does this sound like a 'bug' in Xilinx synthesis?

2) Is there a way to force the tools to use LUT RAM (or block RAM) instead of registers or make the tool fail if it can't do so?

 

Sorry if the answer is elsewhere in the forum or if it has already been asked.  I searched but didn't find anything similar.  I am getting around this for now by commenting out the simulation code.

 

Regards to all,

 

Tom Rounds

 

Here is the code--

 

-- RAM used for storing the old output values of the filter:

-- SIMULATION using RAM: inferring a single port, asynchronous READ, synchronous WRITE,

-- Includes self-clear code for simulation: if enabled in synthesis this will implement registers instead of RAM

-- Commenting out this section will correctly synthesize LUT RAM.

SIM_RESULT_RAM: if (SIM_ENB = TRUE) generate

     Proc_SIM_RESULT_RAM :

     process (MCLK)

        variable STARTUP: boolean :=true;    --temporary variable for simulation

     begin

         if (rising_edge(MCLK)) then

            if (STARTUP or RESET = '1') then   -- synchronous clear to initialize RAM contents

                for i in 0 to (STAGE_NUM*CHANNELS-1) loop      -- (RAM clear is needed for simulation)

                   LPF_RAM(i) <= (others => '0');

               end loop;

               STARTUP := FALSE;

           -- Store the new output data when the stage data ready signal is asserted.

           -- Should use some FPGA RAM for this.

           elsif (STAGE_DRDY = '1') then

                 LPF_RAM(to_integer(unsigned(LPF_RAM_ADR))) <= std_logic_vector(OUTNEW);

           end if;

        end if;

  end process Proc_SIM_RESULT_RAM;

end generate SIM_RESULT_RAM;

 

-- SYNTHESIS using RAM: single port, asynchronous READ, synchronous WRITE.

-- The intent is to infer LUT RAM and not registers.

SYN_RESULT_RAM: if (SIM_ENB = FALSE) generate

    Proc_RESULT_RAM :

    process (MCLK)

    begin

         if (rising_edge(MCLK)) then

            if (STAGE_DRDY = '1') then       -- synchronous write to RAM

                 LPF_RAM(to_integer(unsigned(LPF_RAM_ADR))) <= std_logic_vector(OUTNEW);

            end if;

         end if;

     end process Proc_RESULT_RAM;

end generate SYN_RESULT_RAM;

 

-- STAGE_OUT RAM data output is the old data value. This is asynchronous read from the RAM and it forces

-- synthesis of LUT (distributed) RAM.

STAGE_RAM_DO  <= signed(LPF_RAM(to_integer(unsigned(LPF_RAM_ADR))));

 

 

Xilinx Employee
austin
Posts: 3,625
Registered: ‎02-27-2008
0

Re: RAM synthesis in registers instead of LUT

Tom,


If you specify an initial condition, or require a reset, LUTRAM can not be used (as it has no reset/set, and always starts out at 0's when configured).

 

 

Austin Lesea
Principal Engineer
Xilinx San Jose
Visitor
trounds
Posts: 7
Registered: ‎10-07-2011
0

Re: RAM synthesis in registers instead of LUT

Thanks for the quick response.  I only specify an initial condition with this is generated as part of simulation.  There is no initial condition for the code specific to synthesis.  Why doesn't the software know this?

Expert Contributor
eteam00
Posts: 7,505
Registered: ‎07-21-2009
0

Clearing up incidental problems

This doesn't address the primary problem for trounds, but it does clear up what appears to be a mistaken representation which should not be left to stand.

 

Austin wrote:

 

If you specify an initial condition, or require a reset, LUTRAM can not be used (as it has no reset/set, and always starts out at 0's when configured).

 

A reset pin will indeed preclude LUT-RAM, but specifiying an initial condition should be no obstacle.  What are all the logic LUTs in an FPGA design, if not LUT-RAM with a specified initial condition?

 

@trounds:

 

In the interest of removing a roadblock in your path, would a 16x48-bit distributed RAM with initialised state (but no reset-to-zero capability) satisfy both synthesis and simulation requirements, and possibly help you move forward with your design?

 

-- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
Visitor
trounds
Posts: 7
Registered: ‎10-07-2011
0

Re: Clearing up incidental problems

Yes that would satisfy both conditions.  I only need some sort of initial state for simulation.  I don't care what the states are in synthesis since I'm using this for low pass filtering and it will eventually flush out in the real world application.

 

I'm just surprised that the tools are looking at the code related to simulation when I set SIM_ENB = FALSE.  I would have thought it would disregard it.  I have quite a few filters in this FPGA and correcting this problem reduced my utilization of an XC6SLX45 from 73% down to 31%.

 

I am using version 13.3 of the Webpack tools.  I had neglected to mention that before.  I know 13.4 is out but I haven't upgraded yet.

 

Visitor
trounds
Posts: 7
Registered: ‎10-07-2011
0

Re: RAM synthesis in registers instead of LUT

I have just tried getting rid of the RESET = '1' test for simulation and left in the variable for STARTUP.  It didn't help.

 

To be sure, I'm not stuck. I'm just reporting that it isn't behaving like I think it should.

 

I know how to get around this problem; I have chosen to comment out the simulation section of code and add in an assert statement that warns me if SIM_ENB = TRUE so I remember to uncomment the code for simulation.  I could also specifically instantiate a simple RAM from the Coregen tool.    I prefer to infer this logic to be as flexible as possible for future changes.

 

 

Expert Contributor
eteam00
Posts: 7,505
Registered: ‎07-21-2009
0

Re: Clearing up incidental problems

[ Edited ]

I only need some sort of initial state for simulation.

 

The initial state requirement is already met with no additional effort.  A distributed RAM defaults to all locations containing zero after configuration is completed.  For non-zero initial state of distributed RAM, you have (at least) three choices:

 

  • The Distributed Memory Generator coregen wizard prompts you for a .COE (coefficients) file to define initial contents.
  • Use somewhat generic HDL constructs for inferring RAM, combined with synthesis directives for specifying initial contents and synthesised style (e.g.  distributed) of RAM.
  • If you use a device primitive (for example the Spartan-3E RAM16x2S primitive), the initial contents may be specified in-line in your code where the primitive is instantiated, using .INIT attributes.

 

Examples from the ISE  Language Templates (click on the light-bulb icon within ISE Navigator):

 

RAM16X2S #(
      .INIT_00(16'h0000), // Initial contents of bit 0 of RAM
      .INIT_01(16'h0000)  // Initial contents of bit 1 of RAM
   ) RAM16X2S_inst (
      .O0(O0),     // RAM data[0] output
      .O1(O1),     // RAM data[1] output
      .A0(A0),     // RAM address[0] input
      .A1(A1),     // RAM address[1] input
      .A2(A2),     // RAM address[2] input
      .A3(A3),     // RAM address[3] input
      .D0(D0),     // RAM data[0] input
      .D1(D1),     // RAM data[1] input
      .WCLK(WCLK), // Write clock input
      .WE(WE)      // Write enable input
   );

 

 


 

   parameter RAM_WIDTH = <ram_width>;
   parameter RAM_ADDR_BITS = <ram_addr_bits>;

   (* RAM_STYLE="{AUTO | DISTRIBUTED | PIPE_DISTRIBUTED}" *)
   reg [RAM_WIDTH-1:0] <ram_name> [(2**RAM_ADDR_BITS)-1:0];

   wire [RAM_WIDTH-1:0] <output_data>;

   <reg_or_wire> [RAM_ADDR_BITS-1:0] <address>;
   <reg_or_wire> [RAM_WIDTH-1:0] <input_data>;

   always @(posedge <clock>)
      if (<write_enable>)
         <ram_name>[<address>] <= <input_data>;

   assign <output_data> = <ram_name>[<address>];

 

Further reading:  XST User Guide (UG627) has an entire section titled Initializing RAM Coding Examples.

 

-- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
Visitor
trounds
Posts: 7
Registered: ‎10-07-2011
0

Re: RAM synthesis in registers instead of LUT

Yes, I agree, but the simulator doesn't seem to know about the initial/powerup configuration of zero states so it gives me undefined values in the RAM and so I cannot simulate the filter operation.  The new values of the filter are based on previous values (it is an IIR filter) so it never settles out unless I force the simulation to some value.

 

Expert Contributor
eteam00
Posts: 7,505
Registered: ‎07-21-2009
0

Re: RAM synthesis in registers instead of LUT

For what it's worth, the following quick experiment successfully synthesised (ISE 13.4) a 16x48 single port SRAM with 24 Spartan-6 LUTs (2 bits per LUT, as Spartan-6 LUTs are either 64x1 or 32x2).

 

module s6_forum_top (
    input              inclk100m,
    input    [3:0]     lut_addr,
    input    [47:0]    lut_din,
    input              lut_we,
    output   [47:0]    lut_dout
);

(* RAM_STYLE="DISTRIBUTED" *)
reg [47:0] forum_lutram [15:0]; // 16 words deep, 48 data bits wide

 

initial begin
  forum_lutram[0] = 48’h0000_0000_0000;
  forum_lutram[1] = 48’h0001_0000_0001;
  forum_lutram[2] = 48’h0002_0000_0002;
  forum_lutram[3] = 48’h0003_0000_0003;
  forum_lutram[4] = 48’h0004_0000_0004;
  forum_lutram[5] = 48’h0005_0000_0005;
  forum_lutram[6] = 48’h0006_0000_0006;
  forum_lutram[7] = 48’h0007_0000_0007;
  forum_lutram[8] = 48’h0000_0008_0008;
  forum_lutram[9] = 48’h0000_0009_0009;
  forum_lutram[10] = 48’h0000_000A_000A;
  forum_lutram[11] = 48’h0000_000B_000B;
  forum_lutram[12] = 48’h0000_000C_000C;
  forum_lutram[13] = 48’h0000_000D_000D;
  forum_lutram[14] = 48’h0000_000E_000E;
  forum_lutram[15] = 48’h0000_000F_000F;
end

 

always @(posedge inclk100m)
    if (lut_we) forum_lutram[lut_addr] <= lut_din;

assign lut_dout = forum_lutram[lut_addr];

 

endmodule

 

I didn't bother with parameters for memory word depth and data width, but this should be no problem.

 

-- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
Expert Contributor
eteam00
Posts: 7,505
Registered: ‎07-21-2009
0

Re: RAM synthesis in registers instead of LUT

Yes, I agree, but the simulator doesn't seem to know about the initial/powerup configuration of zero states so it gives me undefined values in the RAM and so I cannot simulate the filter operation.

 

This seems like odd behaviour.  Have you tried both behavioural and structural simulation models with identical results?  Just a wild guess....

 

-- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.