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
philipnye
Posts: 10
Registered: ‎11-06-2008
0
Accepted Solution

How to stop XST optimizing my BRAMs away

My project uses lookup ROMs which are synthesized into BRAM resources. Because I need to repeatedly change the ROM content without re-synthesizing the logic, I am using data2mem in my design flow to load and modify the contents of my ROMs. This means that my verilog source has no specific ROM content and I want to declare it as blank (all 0s or all 1s) memory

 

This works fine with XST correctly inferring all my ROMs until it gets to the "Low Level Synthesis" pass when it apparently spots duplications in BRAM content and optimizes some or all the BRAMs away with a message like this:

 

  "INFO:Xst:2399 - RAMs <Mram_phaserom2>, <Mram_phaserom1> are equivalent, second RAM is removed"

 

This leaves me with a design which data2mem cannot work with. How can I prevent this optimization so that the BRAMs get preserved in the NGC file?

Xilinx Employee
Xilinx Employee
ywu
Posts: 2,861
Registered: ‎11-28-2007

Re: How to stop XST optimizing my BRAMs away

Take a look at http://www.xilinx.com/itp/xilinx10/books/docs/xst/xst.pdf and look for "EQUIVALENT_REGISTER_REMOVAL" under "XST HDL Constraints".

 

Cheers,

Jim

 

Cheers,
Jim
Visitor
philipnye
Posts: 10
Registered: ‎11-06-2008
0

Re: How to stop XST optimizing my BRAMs away

Thanks Jim, I thought there must be a switch like this but had not found it.

 

Unfortunately though it does not work! Am I missing something obvious?

 

I have tried setting EQUIVALENT_REGISTER_REMOVAL to NO on the ROM register declaration, on the module containing the ROM, on the top level module and as a command switch to XST. It shows up as set to NO in the synthesis log, but I still get the following in low level synthesis:

 

  WARNING:Xst:1989 - Unit <lookup>: instances <phaseroms[0].phdat>, <phaseroms[1].phdat> of unit <phaserom> are equivalent, second instance is removed

  ...

  INFO:Xst:2399 - RAMs <phlookup/phaseroms[0].phdat/Mram_phaserom2>, <lookup/phaseroms[0].phdat/Mram_phaserom1> are equivalent, second RAM is removed

 

I am using XST Release 10.1.02 - xst K.37 (lin)

 

My ROMS are logically organized as four ROMS of 2048 words by 36 bits - each logical ROM is initially synthesized as 4xRAMB16_S9. This should use 16 out of the 20 BRAMs on a  Spartan 3E (3s500efg320-4). After the unwanted optimizations I end up with just one BRAM!

 

 

It may be unconnected but I have found this which relates to an earlier version of ISE?

  http://www.fpga-faq.com/archives/111600.html#11160

Xilinx Employee
Xilinx Employee
ywu
Posts: 2,861
Registered: ‎11-28-2007

Re: How to stop XST optimizing my BRAMs away

If you can post your code, it would help see what's going on. I tried the code in the link you mentioned. The code as it is had the same problem you mentioned. I then added equivalent_register_removal attribute to the ROM address signal (see bolded lines below) , the problem went away (i.e. no inferred RAM optimized out).

 

Cheers,

Jim

 

 

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;

entity mc8051_rom is

   port (clk        : in  std_logic;                -- clock signal
         reset      : in  std_logic;                -- reset signal
         rom_data_o : out std_logic_vector(7 downto 0);    -- data output
         rom_adr_i  : in  std_logic_vector(15 downto 0));  -- adresses
end mc8051_rom;

architecture behav of mc8051_rom is


   attribute equivalent_register_removal: string;

-- we use a RAM that is initialized via data2mem with the hexfile.
   type   rom_type is array (16383 downto 0) of std_logic_vector(7 downto 0);
   constant c : rom_type := (16383 downto 20 => x"01",
--    using 4Kbyte works?!
--  type   rom_type is array (4095 downto 0) of std_logic_vector(7 downto 0);
--  constant extrom : rom_type := (4095 downto 20 => x"01",
                                  19 downto 6 => x"00",
                                  5 downto 0 => x"23"
                                  );     -- to avoid optimalizing out? Needed?

   signal rom_adr : std_logic_vector(13 downto 0);

   attribute equivalent_register_removal of rom_adr : signal is "no";

begin

  rom_adr  <= rom_adr_i(13 downto 0);

  rom_read : process (clk)
   begin
     if rising_edge(clk) then
         rom_data_o <= c(conv_integer(unsigned(rom_adr)));
     end if;
   end process rom_read;


end behav;

Cheers,
Jim
Visitor
philipnye
Posts: 10
Registered: ‎11-06-2008
0

Re: How to stop XST optimizing my BRAMs away

Problem partially solved! Thanks to your post, I applied equivalent_register_removal="NO" to the address lines of my ROM and it worked like a charm. This sorts out my immediate problem.

 

However, I am surprised that it does not work if I turn equivalent_register_removal off globally (command line option -equivalent_register_removal NO) even though the setting appears clearly in the synthesis report.

 

It does not work either if I attach the attribute to the ROM registers declaration, to the entire module containing the ROM or to the top-level module in the design. It only seems to work if I attach it to the address lines.

 

Here is my code with the attribute on the entire module::

 

 (* equivalent_register_removal = "NO" *) module phaserom(phasedata, phaseaddr, clk);

    parameter ROMWIDTH = 36;
    parameter ADDRBITS = 11;

    output reg [ROMWIDTH - 1 : 0] phasedata;
    input wire [ADDRBITS - 1 : 0] phaseaddr;
    input wire clk;

    localparam WORDCOUNT = 1 << ADDRBITS;

    reg [ROMWIDTH - 1 : 0] phaserom [WORDCOUNT - 1 : 0];

    initial begin
        $readmemh("rom-blank.mem", phaserom, 0, WORDCOUNT - 1);
    end

    /* Dummy write lines improve synthesis */
    wire dummywen = 0;
    wire [ROMWIDTH - 1 : 0] dummydat = 0;

    always @(posedge clk) begin
        if (dummywen) begin    /* dummy write to satisfy XST */
            phaserom[phaseaddr] <= dummydat;
            phasedata <= dummydat;
        end
        else phasedata <= phaserom[phaseaddr];
    end

endmodule