Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] VHDL error: Cannot determine exact overloaded matching definition for "&"

Status
Not open for further replies.

dpaul

Advanced Member level 5
Joined
Jan 16, 2008
Messages
1,797
Helped
317
Reputation
635
Reaction score
341
Trophy points
1,373
Location
Germany
Activity points
13,048
VHDL error: Cannot determine exact overloaded matching definition for "&"

Hi all,

I am trying to simulate a "True DP Asym RAM Write First". I have adapted the code from UG901 v2017.1, page 141.
I have used use IEEE.NUMERIC_STD.ALL instead of use ieee.std_logic_unsigned.all and use ieee.std_logic_arith.all.

Here is the VHDL code. The commented out parts are the Xilinx code lines.
Code:
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- use ieee.std_logic_unsigned.all;
-- use ieee.std_logic_arith.all;
library unisim;
use unisim.vcomponents.all;


entity asym_ram_tdp is
    generic (
        WIDTHA      : integer := 4;
        SIZEA       : integer := 1024;
        ADDRWIDTHA  : integer := 10;
        WIDTHB      : integer := 16;
        SIZEB       : integer := 256;
        ADDRWIDTHB  : integer := 8 
    );
    port (
        clkA        : in  std_logic;
        clkB        : in  std_logic;
        enA         : in  std_logic;
        enB         : in  std_logic;
        weA         : in  std_logic;
        weB         : in  std_logic;
        addrA       : in  std_logic_vector(ADDRWIDTHA-1 downto 0);
        addrB       : in  std_logic_vector(ADDRWIDTHB-1 downto 0);
        diA         : in  std_logic_vector(WIDTHA-1 downto 0);
        diB         : in  std_logic_vector(WIDTHB-1 downto 0);
        doA         : out std_logic_vector(WIDTHA-1 downto 0);
        doB         : out std_logic_vector(WIDTHB-1 downto 0)
    );
end asym_ram_tdp;


architecture asym_ram_tdp_arc of asym_ram_tdp is

function max(L, R: INTEGER) return INTEGER is
begin
    if L > R then
        return L;
    else
        return R;
    end if;
end;

function min(L, R: INTEGER) return INTEGER is
begin
    if L < R then
        return L;
    else
        return R;
    end if;
end;

function log2 (val: INTEGER) return natural is
    variable res : natural;
begin
    for i in 0 to 31 loop
        if (val <= (2**i)) then
            res := i;
            exit;
        end if;
    end loop;
    return res;
end function Log2;

constant minWIDTH : integer := min(WIDTHA,WIDTHB);
constant maxWIDTH : integer := max(WIDTHA,WIDTHB);
constant maxSIZE  : integer := max(SIZEA,SIZEB);
constant RATIO    : integer := maxWIDTH / minWIDTH;

-- An asymmetric RAM is modeled in a similar way as a symmetric RAM, with an array of array object.
-- Its aspect ratio corresponds to the port with the lower data width (larger depth).
type ramType is array (0 to maxSIZE-1) of std_logic_vector(minWIDTH-1 downto 0);
signal my_ram                 : ramType := (others => (others => '0'));

signal readA  : std_logic_vector(WIDTHA-1 downto 0):= (others => '0');
signal readB  : std_logic_vector(WIDTHB-1 downto 0):= (others => '0');
signal regA   : std_logic_vector(WIDTHA-1 downto 0):= (others => '0');
signal regB   : std_logic_vector(WIDTHB-1 downto 0):= (others => '0');
  
begin

    process (clkA)
    begin
      if rising_edge(clkA) then
        if enA = '1' then
          if weA = '1' then
              my_ram(to_integer(unsigned(addrA))) <= diA; --my_ram(conv_integer(addrA)) <= diA;
              readA <= diA;
          else
              readA <= my_ram(to_integer(unsigned(addrA)));
          end if;
        end if;
        regA <= readA;
      end if;
    end process;
        
    process (clkB)
    begin
      if rising_edge(clkB) then
          for i in 0 to RATIO-1 loop
              if enB = '1' then
                  if weB = '1' then
                      my_ram( to_integer(unsigned( addrB & std_logic_vector(to_unsigned(i,log2(RATIO))) )) ) <= diB((i+1)*minWIDTH-1 downto i*minWIDTH);
                      --my_ram(  conv_integer( addrB & conv_std_logic_vector(i,log2(RATIO)) )  ) <= diB((i+1)*minWIDTH-1 downto i*minWIDTH);
                  end if;              
                  -- The read statement below is placed after the write statement on purpose to ensure write-first synchronization
                  -- through the variable mechanism
                  readB((i+1)*minWIDTH-1 downto i*minWIDTH) <= my_ram(  to_integer(unsigned( addrB & std_logic_vector(to_unsigned(i,log2(RATIO))) ))  );
                  --readB((i+1)*minWIDTH-1 downto i*minWIDTH) <= my_ram(  conv_integer( addrB & conv_std_logic_vector(i,log2(RATIO)) )  );
              end if;
          end loop;
          regB <= readB;
      end if;
    end process;
  
    doA <= regA;
    doB <= regB;

end asym_ram_tdp_arc;

The error shown:
Code:
INFO: [VRFC 10-163] Analyzing VHDL file "C:/Work/true_dp_filtersets_ram/true_dp_filtersets_ram.srcs/sources_1/new/asym_ram_tdp.vhd" into library xil_defaultlib
INFO: [VRFC 10-307] analyzing entity asym_ram_tdp
ERROR: [VRFC 10-724] found '2' definitions of operator "&", cannot determine exact overloaded matching definition for "&" [C:/Work/true_dp_filtersets_ram/true_dp_filtersets_ram.srcs/sources_1/new/asym_ram_tdp.vhd:132]
ERROR: [VRFC 10-724] found '2' definitions of operator "&", cannot determine exact overloaded matching definition for "&" [C:/Work/true_dp_filtersets_ram/true_dp_filtersets_ram.srcs/sources_1/new/asym_ram_tdp.vhd:137]
ERROR: [VRFC 10-1504] unit asym_ram_tdp_arc ignored due to previous errors [C:/Work/true_dp_filtersets_ram/true_dp_filtersets_ram.srcs/sources_1/new/asym_ram_tdp.vhd:59]
INFO: [VRFC 10-240] VHDL file C:/Work/true_dp_filtersets_ram/true_dp_filtersets_ram.srcs/sources_1/new/asym_ram_tdp.vhd ignored due to errors


In my opinion at line 132, addrB and i are both std_logic_vector. Same is for line 137. So why am I seeing this?
Does it have something to do with my change of libraries or am I making some silly mistake somewhere?

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
PortA is my write port and PortB is my read port for initial analysis. The TB should write writes 32 bits data at a time via PortA
PortA size (32 bits) < PortB size (1280 bits).
At portB, I only want to read out the written data 1280 bits at a time.

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;

library unisim;
use unisim.vcomponents.all;


entity asym_ram_tdp_tb is
--  Port ( );
end asym_ram_tdp_tb;


architecture asym_ram_tdp_tb_arc of asym_ram_tdp_tb is

component asym_ram_tdp is
    generic (
        WIDTHA      : integer := 4;
        SIZEA       : integer := 1024;
        ADDRWIDTHA  : integer := 10;
        WIDTHB      : integer := 16;
        SIZEB       : integer := 256;
        ADDRWIDTHB  : integer := 8 
    );
    port (
        clkA        : in  std_logic;
        clkB        : in  std_logic;
        enA         : in  std_logic;
        enB         : in  std_logic;
        weA         : in  std_logic;
        weB         : in  std_logic;
        addrA       : in  std_logic_vector(ADDRWIDTHA-1 downto 0);
        addrB       : in  std_logic_vector(ADDRWIDTHB-1 downto 0);
        diA         : in  std_logic_vector(WIDTHA-1 downto 0);
        diB         : in  std_logic_vector(WIDTHB-1 downto 0);
        doA         : out std_logic_vector(WIDTHA-1 downto 0);
        doB         : out std_logic_vector(WIDTHB-1 downto 0)
    );
end component;

-- Denfine clocks
constant CLK_111M111_PERIOD : time      := 9.000 ns;
constant CLK_100_PERIOD     : time      := 10.000 ns;
signal   clk_111M111        : std_logic := '0';
signal   clk_100M           : std_logic := '0';

signal write_done           : std_logic := '0';
signal write_done_q         : std_logic := '0';

-- Port B
constant DATA_WIDTH_B : integer                                   := 1280; 
constant SIZE_B       : integer                                   := 128; 
constant ADDR_WIDTH_B : integer                                   := 7; 
signal   en_b         : std_logic                                 := '0' ;
signal   w_en_b       : std_logic                                 := '0' ;
signal   addr_b       : std_logic_vector(ADDR_WIDTH_B-1 downto 0) := (others => '0');
signal   d_in_b       : std_logic_vector(DATA_WIDTH_B-1 downto 0) := (others => '0');
signal   d_out_b      : std_logic_vector(DATA_WIDTH_B-1 downto 0)                   ;
signal   addr_b_cnt   : integer range 0 to 127                    := 0              ;

-- Port A
constant DATA_WIDTH_A : integer                                   := 32  ; 
constant SIZE_A       : integer                                   := 8192;
constant ADDR_WIDTH_A : integer                                   := 13;
signal   en_a         : std_logic                                 := '0' ;
signal   w_en_a       : std_logic                                 := '0' ;
signal   addr_a       : std_logic_vector(ADDR_WIDTH_A-1 downto 0) := (others => '0');
signal   d_in_a       : std_logic_vector(DATA_WIDTH_A-1 downto 0) := (others => '0');
signal   d_out_a      : std_logic_vector(DATA_WIDTH_A-1 downto 0)                   ;
signal   addr_a_cnt   : integer range 0 to 8191                   := 0              ; 

constant FILTER_SET_NUM : integer := DATA_WIDTH_B/DATA_WIDTH_A; 

begin

    dp_filterset_ram : asym_ram_tdp
    generic map(
        WIDTHA      => DATA_WIDTH_A,
        SIZEA       => SIZE_A      ,
        ADDRWIDTHA  => ADDR_WIDTH_A,
        WIDTHB      => DATA_WIDTH_B,
        SIZEB       => SIZE_B      ,
        ADDRWIDTHB  => ADDR_WIDTH_B 
    )
    port map(
        clkA        => clk_111M111,
        clkB        => clk_100M   ,
        enA         => en_a       ,
        enB         => en_b       ,
        weA         => w_en_a     ,
        weB         => w_en_b     ,
        addrA       => addr_a     ,
        addrB       => addr_b     ,
        diA         => d_in_a     ,
        diB         => d_in_b     ,
        doA         => d_out_a    ,
        doB         => d_out_b
    );
    

    -- Generate clocks
    clk_111M111 <= not(clk_111M111) after CLK_111M111_PERIOD/2;
    clk_100M    <= not(clk_100M) after CLK_100_PERIOD/2;   
    
    ------------
    -- Write RAM
    ------------    
    write_p : process
    
    begin    
    
        -- For testing we will fill in 3 filter-sets. So we need 3x20 write cycles.
       
        en_a   <= '0';
        w_en_a <= '0';
        addr_a <= (others => '0');    
        wait for CLK_111M111_PERIOD*2; 
        
        fill_ram_1: for i in 0 to FILTER_SET_NUM-1 loop
            en_a       <= '1';
            w_en_a     <= '1';
            addr_a     <= std_logic_vector(to_unsigned(i, ADDR_WIDTH_A));
            d_in_a     <= std_logic_vector(to_unsigned(i, DATA_WIDTH_A));
            addr_a_cnt <= i; 
            wait until rising_edge(clk_111M111);        
        end loop fill_ram_1;
        
        en_a   <= '0';
        w_en_a <= '0';
        addr_a <= (others => '0');        
        write_done <= '1';
        wait for CLK_111M111_PERIOD*1;
        write_done <= '0';
          
        fill_ram_2: for i in addr_a_cnt+1 to addr_a_cnt+1+FILTER_SET_NUM loop
            en_a       <= '1';
            w_en_a     <= '1';
            addr_a     <= std_logic_vector(to_unsigned(i, ADDR_WIDTH_A));
            d_in_a     <= std_logic_vector(to_unsigned(i, DATA_WIDTH_A));
            addr_a_cnt <= i; 
            wait until rising_edge(clk_111M111);        
        end loop fill_ram_2; 
        
        en_a   <= '0';
        w_en_a <= '0';
        addr_a <= (others => '0');
        write_done <= '1';
        wait for CLK_111M111_PERIOD*1;
        write_done <= '0';
        
        fill_ram_3: for i in addr_a_cnt+1 to addr_a_cnt+1+FILTER_SET_NUM loop
            en_a       <= '1';
            w_en_a     <= '1';
            addr_a     <= std_logic_vector(to_unsigned(i, ADDR_WIDTH_A));
            d_in_a     <= std_logic_vector(to_unsigned(i, DATA_WIDTH_A));
            addr_a_cnt <= i; 
            wait until rising_edge(clk_111M111);        
        end loop fill_ram_3; 

        en_a   <= '0';
        w_en_a <= '0';
        addr_a <= (others => '0');
        write_done <= '1';
        wait for CLK_111M111_PERIOD*1;
        write_done <= '0';

        fill_ram_4: for i in addr_a_cnt+1 to addr_a_cnt+1+FILTER_SET_NUM loop
            en_a       <= '1';
            w_en_a     <= '1';
            addr_a     <= std_logic_vector(to_unsigned(i, ADDR_WIDTH_A));
            d_in_a     <= std_logic_vector(to_unsigned(i, DATA_WIDTH_A));
            addr_a_cnt <= i; 
            wait until rising_edge(clk_111M111);        
        end loop fill_ram_4;

        en_a   <= '0';
        w_en_a <= '0';
        addr_a <= (others => '0');
        write_done <= '1';
        wait for CLK_111M111_PERIOD*1;
        write_done <= '0'; 
               
        wait;

    end process write_p;        
        
    ------------
    -- Read RAM
    ------------
    read_p : process
        begin
                
        en_b        <= '0';
        wait for CLK_100_PERIOD*FILTER_SET_NUM;

        en_b        <= '1';
        addr_b      <= std_logic_vector(to_unsigned(0, ADDR_WIDTH_B));  

        wait for CLK_100_PERIOD*1; 
        
        en_b        <= '0';
                
        wait for CLK_100_PERIOD*FILTER_SET_NUM;

        en_b        <= '1';
        addr_b      <= std_logic_vector(to_unsigned(1, ADDR_WIDTH_B));  

        wait for CLK_100_PERIOD*1; 
        
        en_b        <= '0';    
                 
        wait;

    end process read_p;
 
Last edited:

Re: VHDL error: Cannot determine exact overloaded matching definition for "&"

It has to do with the unsigned type cast of the concatenated std_logic_vectors. Stuff like this is why I dislike using VHDL.

You might want to change the types you use to all unsigned for the address and then only have the one to_unsigned conversion function to get the my_ram index.

I managed to fix the compilation error by using a variable to assign the concatenated addrB & (........RATIO)))) stuf which I then used in the my_ram stuff.

Code:
variable test : std_logic_vector(WIDTHB-1 downto 0);
test := addrB & (std_logic_vector(to_unsigned(i,log2(RATIO))));
my_ram( to_integer(unsigned('0' & test)) ) <= diB((i+1)*minWIDTH-1 downto i*minWIDTH);
not sure if the '0' is required, but I didn't want the unsigned operation to think that the value was negative. I always forget the details of VHDL signed/unsigned conversions of std_logic_vectors.
 
  • Like
Reactions: dpaul

    dpaul

    Points: 2
    Helpful Answer Positive Rating
Re: VHDL error: Cannot determine exact overloaded matching definition for &quot;&amp;&quot;

The extra 0 is not required. That is usually added to increase the bit width of the result, as the result is always the same length as the longest operand in addition. It also covers the sign bit when converting to signed.

- - - Updated - - -

Btw, there is no problem with your code as posted in #1. I compiled and ran it in ActiveHDL without fault. Are these errors coming from Vivado? or have you accidently posted the wrong code, and you've actually got another library added somewhere?
 
  • Like
Reactions: dpaul and ads-ee

    ads-ee

    Points: 2
    Helpful Answer Positive Rating

    dpaul

    Points: 2
    Helpful Answer Positive Rating
Re: VHDL error: Cannot determine exact overloaded matching definition for "&"

Vivado produces the error, that is what I tried as the VRFC messages gave it away. Didn't think to try with Modelsim.
 

Re: VHDL error: Cannot determine exact overloaded matching definition for "&"

Thanks for your inputs!

@tricky, yes its the same code, but as told by ads-ee, Vivado complains.

@all,
My simulation environment:
Vivado: 2017.4
Processor: i5-6400 CPU @ 2.7GHz
Installed RAM : 16 GB
OS : Win7 Pro, 64 bit
HDD : SSD

After making the changes suggested by ads-ee, I am trying to run simulation using the Tb posted in #1. Function of the TB is very simple, write from A and read from port B (complexity will be added later), as mentioned in 1. Now xsim (Vivado) takes >15 min to go past the "Executing elaborate step..."
Actually shouldn't be this long, can anyone please verify?

- - - Updated - - -

Moreover, see what is happening to the RAM when I am simulating the memory.

ramsim.jpg

I have reduced the size of the memory to 5KB in my testbench, which was used for sim.

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;

library unisim;
use unisim.vcomponents.all;


entity asym_ram_tdp_tb is
--  Port ( );
end asym_ram_tdp_tb;


architecture asym_ram_tdp_tb_arc of asym_ram_tdp_tb is

component asym_ram_tdp is
--component asym_ram_tdp_xil is
    generic (
        WIDTHA      : integer := 4;
        SIZEA       : integer := 1024;
        ADDRWIDTHA  : integer := 10;
        WIDTHB      : integer := 16;
        SIZEB       : integer := 256;
        ADDRWIDTHB  : integer := 8 
    );
    port (
        clkA        : in  std_logic;
        clkB        : in  std_logic;
        enA         : in  std_logic;
        enB         : in  std_logic;
        weA         : in  std_logic;
        weB         : in  std_logic;
        addrA       : in  std_logic_vector(ADDRWIDTHA-1 downto 0);
        addrB       : in  std_logic_vector(ADDRWIDTHB-1 downto 0);
        diA         : in  std_logic_vector(WIDTHA-1 downto 0);
        diB         : in  std_logic_vector(WIDTHB-1 downto 0);
        doA         : out std_logic_vector(WIDTHA-1 downto 0);
        doB         : out std_logic_vector(WIDTHB-1 downto 0)
    );
end component;

-- Denfine clocks
constant CLK_111M111_PERIOD : time      := 9.000 ns;
constant CLK_100_PERIOD     : time      := 10.000 ns;
signal   clk_111M111        : std_logic := '0';
signal   clk_100M           : std_logic := '0';

signal write_done           : std_logic := '0';
signal write_done_q         : std_logic := '0';

-- Port B
constant DATA_WIDTH_B : integer                                   := 1280; -- 79B+79B+2B = 160 x 8
constant SIZE_B       : integer                                   := 32; --128;  -- 2^7 = 128 filter sets
constant ADDR_WIDTH_B : integer                                   := 5;--7;    
signal   en_b         : std_logic                                 := '0' ;
signal   w_en_b       : std_logic                                 := '0' ;
signal   addr_b       : std_logic_vector(ADDR_WIDTH_B-1 downto 0) := (others => '0');
signal   d_in_b       : std_logic_vector(DATA_WIDTH_B-1 downto 0) := (others => '0');
signal   d_out_b      : std_logic_vector(DATA_WIDTH_B-1 downto 0)                   ;
signal   addr_b_cnt   : integer range 0 to 127                    := 0              ;

-- Port A
constant DATA_WIDTH_A : integer                                   := 32  ; -- 32bits AXI4Lite bus width
constant SIZE_A       : integer                                   := 2048; --8192; -- 2^13, Needed 20480B/4B = 5120;
constant ADDR_WIDTH_A : integer                                   := 11;   -- 13
signal   en_a         : std_logic                                 := '0' ;
signal   w_en_a       : std_logic                                 := '0' ;
signal   addr_a       : std_logic_vector(ADDR_WIDTH_A-1 downto 0) := (others => '0');
signal   d_in_a       : std_logic_vector(DATA_WIDTH_A-1 downto 0) := (others => '0');
signal   d_out_a      : std_logic_vector(DATA_WIDTH_A-1 downto 0)                   ;
signal   addr_a_cnt   : integer range 0 to 8191                   := 0              ; 

constant FILTER_SET_NUM : integer := DATA_WIDTH_B/DATA_WIDTH_A; 

begin

    dp_filterset_ram : asym_ram_tdp
    generic map(
        WIDTHA      => DATA_WIDTH_A,
        SIZEA       => SIZE_A      ,
        ADDRWIDTHA  => ADDR_WIDTH_A,
        WIDTHB      => DATA_WIDTH_B,
        SIZEB       => SIZE_B      ,
        ADDRWIDTHB  => ADDR_WIDTH_B 
    )
    port map(
        clkA        => clk_111M111,
        clkB        => clk_100M   ,
        enA         => en_a       ,
        enB         => en_b       ,
        weA         => w_en_a     ,
        weB         => w_en_b     ,
        addrA       => addr_a     ,
        addrB       => addr_b     ,
        diA         => d_in_a     ,
        diB         => d_in_b     ,
        doA         => d_out_a    ,
        doB         => d_out_b
    );
    

    -- Generate clocks
    clk_111M111 <= not(clk_111M111) after CLK_111M111_PERIOD/2;
    clk_100M    <= not(clk_100M) after CLK_100_PERIOD/2;   
    
    ------------
    -- Write RAM
    ------------    
    write_p : process
    
    begin    
    
        -- For testing we will fill in 3 filter-sets. So we need 3x20 write cycles.
       
        en_a   <= '0';
        w_en_a <= '0';
        addr_a <= (others => '0');    
        wait for CLK_111M111_PERIOD*2; 
        
        fill_ram_1: for i in 0 to FILTER_SET_NUM-1 loop
            en_a       <= '1';
            w_en_a     <= '1';
            addr_a     <= std_logic_vector(to_unsigned(i, ADDR_WIDTH_A));
            d_in_a     <= std_logic_vector(to_unsigned(i, DATA_WIDTH_A));
            addr_a_cnt <= i; 
            wait until rising_edge(clk_111M111);        
        end loop fill_ram_1;
        
        en_a   <= '0';
        w_en_a <= '0';
        addr_a <= (others => '0');        
        write_done <= '1';
        wait for CLK_111M111_PERIOD*1;
        write_done <= '0';
          
        fill_ram_2: for i in addr_a_cnt+1 to addr_a_cnt+1+FILTER_SET_NUM loop
            en_a       <= '1';
            w_en_a     <= '1';
            addr_a     <= std_logic_vector(to_unsigned(i, ADDR_WIDTH_A));
            d_in_a     <= std_logic_vector(to_unsigned(i, DATA_WIDTH_A));
            addr_a_cnt <= i; 
            wait until rising_edge(clk_111M111);        
        end loop fill_ram_2; 
        
        en_a   <= '0';
        w_en_a <= '0';
        addr_a <= (others => '0');
        write_done <= '1';
        wait for CLK_111M111_PERIOD*1;
        write_done <= '0';
        
        fill_ram_3: for i in addr_a_cnt+1 to addr_a_cnt+1+FILTER_SET_NUM loop
            en_a       <= '1';
            w_en_a     <= '1';
            addr_a     <= std_logic_vector(to_unsigned(i, ADDR_WIDTH_A));
            d_in_a     <= std_logic_vector(to_unsigned(i, DATA_WIDTH_A));
            addr_a_cnt <= i; 
            wait until rising_edge(clk_111M111);        
        end loop fill_ram_3; 

        en_a   <= '0';
        w_en_a <= '0';
        addr_a <= (others => '0');
        write_done <= '1';
        wait for CLK_111M111_PERIOD*1;
        write_done <= '0';

        fill_ram_4: for i in addr_a_cnt+1 to addr_a_cnt+1+FILTER_SET_NUM loop
            en_a       <= '1';
            w_en_a     <= '1';
            addr_a     <= std_logic_vector(to_unsigned(i, ADDR_WIDTH_A));
            d_in_a     <= std_logic_vector(to_unsigned(i, DATA_WIDTH_A));
            addr_a_cnt <= i; 
            wait until rising_edge(clk_111M111);        
        end loop fill_ram_4;

        en_a   <= '0';
        w_en_a <= '0';
        addr_a <= (others => '0');
        write_done <= '1';
        wait for CLK_111M111_PERIOD*1;
        write_done <= '0'; 
       
        
        wait;

    end process write_p;        
        
    ------------
    -- Read RAM
    ------------
    read_p : process
        begin        
       
        en_b        <= '0';
        wait for CLK_100_PERIOD*FILTER_SET_NUM;

        en_b        <= '1';
        addr_b      <= std_logic_vector(to_unsigned(0, ADDR_WIDTH_B));  

        wait for CLK_100_PERIOD*1; 
        
        en_b        <= '0';
                
        wait for CLK_100_PERIOD*FILTER_SET_NUM;

        en_b        <= '1';
        addr_b      <= std_logic_vector(to_unsigned(1, ADDR_WIDTH_B));  

        wait for CLK_100_PERIOD*1; 
        
        en_b        <= '0';             
                         
        wait;

    end process read_p;        
    
    
end asym_ram_tdp_tb_arc;

I have adapted the "True DualPort Asym Block RAM Write First" from UG901 Vivado Synthesis Guide, v2017.1, April19,2017, page 141. So would also like to know whether my TB is properly writing to it or not!

The above situation can be avoided by using "shared variables", BUT..... as far as I know, it will not synthesize using Vivado2017.4.
Note: I have already asked Xilinx forums for "shared variables" stuff and waiting for inputs.
Other than using "shared variables" is there any elegant solution?
 
Last edited:

Re: VHDL error: Cannot determine exact overloaded matching definition for "&"

shared variables is the ONLY way to get write first behaviour from inferred code. Until recently, only Xilinx supported inferring write first, and altera forced you to generate a core to get the behaviour. The only other option, afaik, is to generate a ram core.
 

Re: VHDL error: Cannot determine exact overloaded matching definition for "&"

Yes this problem is now solved. "shared variables" must be used.
Actually I always use VHDL2008. But if there is shared variable usage, then that *.vhd should be of type VHDL instead of VHDL 2008. Else synthesis will fail.
Just learnt this from Xilinx and of course this was not intuitive for me and not mentioned in any of Xilinx docu.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top