UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Contributor
Contributor
5,426 Views
Registered: ‎10-06-2010

Old vs new parser in XST --- design passes on Virtex 6, fails on Virtex 5

I am using a memory block which is replicated several times over. 

I am targetting my design for V6 and V5 devices.

 

The business end of the RAM code is here:

 

    -- Port A (with byte enable)
    porta_rdwr_proc : process (port_a_clk)
    begin
      if port_a_clk'event and port_a_clk = '1' then
        port_a_dout <= RAM(conv_integer(port_a_addr));
        if port_a_we = '1' then
          for i in 0 to DATA_WIDTH/8-1 loop
            if port_a_be(i) = '1' then
              RAM(conv_integer(port_a_addr))(i*8+0) := port_a_din(i*8+0);
              RAM(conv_integer(port_a_addr))(i*8+1) := port_a_din(i*8+1);
              RAM(conv_integer(port_a_addr))(i*8+2) := port_a_din(i*8+2);
              RAM(conv_integer(port_a_addr))(i*8+3) := port_a_din(i*8+3);
              RAM(conv_integer(port_a_addr))(i*8+4) := port_a_din(i*8+4);
              RAM(conv_integer(port_a_addr))(i*8+5) := port_a_din(i*8+5);
              RAM(conv_integer(port_a_addr))(i*8+6) := port_a_din(i*8+6);
              RAM(conv_integer(port_a_addr))(i*8+7) := port_a_din(i*8+7);
            end if;
          end loop;  -- i
        end if;
      end if;
    end process porta_rdwr_proc;

    -- Port B
    portb_rdwr_proc : process (port_b_clk)
    begin
      if port_b_clk'event and port_b_clk = '1' then
        port_b_dout <= RAM(conv_integer(port_b_addr));
        if port_b_we = '1' then
          for j in 0 to DATA_WIDTH/8-1 loop
            if port_b_be(j) = '1' then
              RAM(conv_integer(port_b_addr))(j*8+0) := port_b_din(j*8+0);
              RAM(conv_integer(port_b_addr))(j*8+1) := port_b_din(j*8+1);
              RAM(conv_integer(port_b_addr))(j*8+2) := port_b_din(j*8+2);
              RAM(conv_integer(port_b_addr))(j*8+3) := port_b_din(j*8+3);
              RAM(conv_integer(port_b_addr))(j*8+4) := port_b_din(j*8+4);
              RAM(conv_integer(port_b_addr))(j*8+5) := port_b_din(j*8+5);
              RAM(conv_integer(port_b_addr))(j*8+6) := port_b_din(j*8+6);
              RAM(conv_integer(port_b_addr))(j*8+7) := port_b_din(j*8+7);
            end if;
          end loop;
        end if;
      end if;
    end process portb_rdwr_proc;
 

 

On Virtex-6 devices (tested on ML605) this was synthesized without problems.

 

On Virtex-5 devices (tested on ML510) this fails. I was able to pin down the problem as V5 using an old XST parser.

(VHDL source expression not yet supported: 'AscendingRange'.)

 

I then used the XST option "-use_new_parser yes" option. This passes synthesis but leaves a bunch of uncomfortable warnings.

 

I am not sure how to fix this problem ? I really want to infer the RAMs as portability is an important concern.

 

Does anyone know a workaround ?

 

RRS

0 Kudos
3 Replies
Advisor eilert
Advisor
5,420 Views
Registered: ‎08-14-2007

Re: Old vs new parser in XST --- design passes on Virtex 6, fails on Virtex 5

Hi,

what warnings have you got? Please post them too.

 

V6 and V5 have different architectures.

So if your code is originally made for V6 devices some V5 specific detail may be different causing the warnings.

 

Have a nice synthesis

  Eilert

0 Kudos
Instructor
Instructor
5,402 Views
Registered: ‎08-14-2007

Re: Old vs new parser in XST --- design passes on Virtex 6, fails on Virtex 5

What does the declaration of RAM look like?  It sounds like the problem is with an

ascending range like ( 0 to 1023) instead of (1023 downto 0).

 

-- Gabor

-- Gabor
0 Kudos
Contributor
Contributor
5,400 Views
Registered: ‎10-06-2010

Re: Old vs new parser in XST --- design passes on Virtex 6, fails on Virtex 5

The entire code looks like this:

 

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;
use ieee.std_logic_textio.all;

library std;
use std.textio.all;

entity dual_port_ram_w_be is
  generic(
    DATA_WIDTH            : natural := 32;
    ADDR_WIDTH            : natural := 10;
    INITIALIZE_TO_ZERO    : boolean := true;
    MEMTYPE_PAR_DIRECTIVE : string  := "block"
    );
  port(
    -- Port A
    port_a_clk  : in  std_logic;
    port_a_we   : in  std_logic;
    port_a_be   : in  std_logic_vector(DATA_WIDTH/8-1 downto 0);
    port_a_addr : in  std_logic_vector(ADDR_WIDTH-1 downto 0);
    port_a_din  : in  std_logic_vector(DATA_WIDTH-1 downto 0);
    port_a_dout : out std_logic_vector(DATA_WIDTH-1 downto 0);
    -- Port B
    port_b_clk  : in  std_logic;
    port_b_we   : in  std_logic;
    port_b_be   : in  std_logic_vector(DATA_WIDTH/8-1 downto 0);
    port_b_addr : in  std_logic_vector(ADDR_WIDTH-1 downto 0);
    port_b_din  : in  std_logic_vector(DATA_WIDTH-1 downto 0);
    port_b_dout : out std_logic_vector(DATA_WIDTH-1 downto 0)
    );
end dual_port_ram_w_be;

architecture dual_port_ram_w_be_arch of dual_port_ram_w_be is

  -- Infer a memory
  constant MEM_DEPTH : natural := 2**ADDR_WIDTH;

  type ram_type is array (0 to MEM_DEPTH-1) of std_logic_vector(DATA_WIDTH-1 downto 0);

  -- Memory initialization scheme
  impure function zero_initialize return ram_type is
    variable mem : ram_type;
  begin
    if INITIALIZE_TO_ZERO = true then
      for i in 0 to MEM_DEPTH-1 loop
        mem(i) := (others => '0');
      end loop;  -- i      
    end if;
    return mem;
  end zero_initialize;

  -- RAM declaration
  shared variable RAM : ram_type := zero_initialize;

  -- Constrain memory to use block, auto or distributed
  attribute ram_style        : string;
  attribute ram_style of RAM : variable is MEMTYPE_PAR_DIRECTIVE;

begin

  porta_rdwr_proc : process (port_a_clk)
  begin
    if port_a_clk'event and port_a_clk = '1' then
      port_a_dout <= RAM(conv_integer(port_a_addr));
      if port_a_we = '1' then
        for i in 0 to DATA_WIDTH/8-1 loop
          if port_a_be(i) = '1' then
            RAM(conv_integer(port_a_addr))(i*8+0) := port_a_din(i*8+0);
            RAM(conv_integer(port_a_addr))(i*8+1) := port_a_din(i*8+1);
            RAM(conv_integer(port_a_addr))(i*8+2) := port_a_din(i*8+2);
            RAM(conv_integer(port_a_addr))(i*8+3) := port_a_din(i*8+3);
            RAM(conv_integer(port_a_addr))(i*8+4) := port_a_din(i*8+4);
            RAM(conv_integer(port_a_addr))(i*8+5) := port_a_din(i*8+5);
            RAM(conv_integer(port_a_addr))(i*8+6) := port_a_din(i*8+6);
            RAM(conv_integer(port_a_addr))(i*8+7) := port_a_din(i*8+7);
          end if;
        end loop;  -- i
      end if;
    end if;
  end process porta_rdwr_proc;

  -- Port B
  portb_rdwr_proc : process (port_b_clk)
  begin
    if port_b_clk'event and port_b_clk = '1' then
      port_b_dout <= RAM(conv_integer(port_b_addr));
      if port_b_we = '1' then
        for j in 0 to DATA_WIDTH/8-1 loop
          if port_b_be(j) = '1' then
            RAM(conv_integer(port_b_addr))(j*8+0) := port_b_din(j*8+0);
            RAM(conv_integer(port_b_addr))(j*8+1) := port_b_din(j*8+1);
            RAM(conv_integer(port_b_addr))(j*8+2) := port_b_din(j*8+2);
            RAM(conv_integer(port_b_addr))(j*8+3) := port_b_din(j*8+3);
            RAM(conv_integer(port_b_addr))(j*8+4) := port_b_din(j*8+4);
            RAM(conv_integer(port_b_addr))(j*8+5) := port_b_din(j*8+5);
            RAM(conv_integer(port_b_addr))(j*8+6) := port_b_din(j*8+6);
            RAM(conv_integer(port_b_addr))(j*8+7) := port_b_din(j*8+7);
          end if;
        end loop;
      end if;
    end if;
  end process portb_rdwr_proc;
  
end dual_port_ram_w_be_arch;

 

0 Kudos