Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

BRAM simulation model error?

37 views
Skip to first unread message

Patrik Eriksson

unread,
Aug 19, 2002, 11:35:58 AM8/19/02
to
When I simulates the following code this warning message is displayed at
time 0ns.

# ** Warning: Invalid ADDRESS: XXXXXXXXXX. Memory contents will be set
to 'X'.
# Time: 0 ps Iteration: 3 Instance: /theram

This means that I can't simulate with correct INIT values!!
All addresses and control signals are constant but the clock inputs are
toggled.

Have I done anything stupid? Is there an error in the simulation model?
This code is a debug version of my real design just to track the
simulation error.

I thought that if WEx is de-asserted nothing should happen to the memory
contents whatever the other signals looks like.

/Patrik Eriksson
-----------

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

-- synthesis translate_off
library unisim;
-- synthesis translate_on

entity bram_tb is

end entity bram_tb;

architecture sim of bram_tb is

component BUFG
port (
I : in std_logic;
O : out std_logic);
end component;

component IBUFGDS_LVPECL_33
port (
O : out std_ulogic;
I : in std_ulogic;
IB : in std_ulogic);
end component;

component DCM
-- synthesis translate_off
generic (
DLL_FREQUENCY_MODE : string := "LOW";
CLKOUT_PHASE_SHIFT : string := "NONE";
PHASE_SHIFT : integer := 0;
CLKFX_MULTIPLY : integer := 4;
CLKDV_DIVIDE : real := 2.0
);
-- synthesis translate_on
port (
CLKIN : in std_logic;
CLKFB : in std_logic;
DSSEN : in std_logic;
PSINCDEC : in std_logic;
PSEN : in std_logic;
PSCLK : in std_logic;
RST : in std_logic;
CLK0 : out std_logic;
CLK90 : out std_logic;
CLK180 : out std_logic;
CLK270 : out std_logic;
CLK2X : out std_logic;
CLK2X180 : out std_logic;
CLKDV : out std_logic;
CLKFX : out std_logic;
CLKFX180 : out std_logic;
LOCKED : out std_logic;
PSDONE : out std_logic;
STATUS : out std_logic_vector(7 downto 0)
);
end component;

component RAMB16_S9_S9
-- synthesis translate_off
generic (
WRITE_MODE_A : string;
WRITE_MODE_B : string;
INITP_00, INITP_01, INITP_02, INITP_03,
INITP_04, INITP_05, INITP_06, INITP_07,
INIT_00, INIT_01, INIT_02, INIT_03,
INIT_04, INIT_05, INIT_06, INIT_07,
INIT_08, INIT_09, INIT_0A, INIT_0B,
INIT_0C, INIT_0D, INIT_0E, INIT_0F,
INIT_10, INIT_11, INIT_12, INIT_13,
INIT_14, INIT_15, INIT_16, INIT_17,
INIT_18, INIT_19, INIT_1A, INIT_1B,
INIT_1C, INIT_1D, INIT_1E, INIT_1F,
INIT_20, INIT_21, INIT_22, INIT_23,
INIT_24, INIT_25, INIT_26, INIT_27,
INIT_28, INIT_29, INIT_2A, INIT_2B,
INIT_2C, INIT_2D, INIT_2E, INIT_2F,
INIT_30, INIT_31, INIT_32, INIT_33,
INIT_34, INIT_35, INIT_36, INIT_37,
INIT_38, INIT_39, INIT_3A, INIT_3B,
INIT_3C, INIT_3D, INIT_3E, INIT_3F : bit_vector :=
X"0000000000000000000000000000000000000000000000000000000000000000"
);
-- synthesis translate_on

port (
DIA : in std_logic_vector(7 downto 0);
DIPA : in std_logic_vector(0 downto 0);
DIB : in std_logic_vector(7 downto 0);
DIPB : in std_logic_vector(0 downto 0);
ENA : in std_ulogic;
ENB : in std_ulogic;
WEA : in std_ulogic;
WEB : in std_ulogic;
SSRA : in std_ulogic;
SSRB : in std_ulogic;
CLKA : in std_ulogic;
CLKB : in std_ulogic;
ADDRA : in std_logic_vector(10 downto 0);
ADDRB : in std_logic_vector(10 downto 0);
DOA : out std_logic_vector(7 downto 0);
DOPA : out std_logic_vector(0 downto 0);
DOB : out std_logic_vector(7 downto 0);
DOPB : out std_logic_vector(0 downto 0)
);

end component;

constant INITP : bit_vector :=
X"1041000100001400010000100040100001400010004100041000100004000104";
constant INIT : bit_vector :=
X"1001000100001000010000100000100001000010000100001000100001000100";

signal clk_p, clk_n, clk, rst : std_logic;
signal clk_ibufg, clk_bufg : std_logic;

begin -- architecture sim

INBUF: IBUFGDS_LVPECL_33
port map (
O = clk_ibufg,
I = clk_p,
IB = clk_n);

GLOBALBUFFER: BUFG
port map (
I = clk_ibufg,
O = clk_bufg);

clk <= clk_bufg;

THERAM: RAMB16_S9_S9
generic map (
WRITE_MODE_A = "WRITE_FIRST",
WRITE_MODE_B = "READ_FIRST",
INITP_00 = INITP,
INITP_01 = INITP,
INITP_02 = INITP,
INITP_03 = INITP,
INITP_04 = INITP,
INITP_05 = INITP,
INITP_06 = INITP,
INITP_07 = INITP,
INIT_00 = INIT,
INIT_01 = INIT,
INIT_02 = INIT,
INIT_03 = INIT,
INIT_04 = INIT,
INIT_05 = INIT,
INIT_06 = INIT,
INIT_07 = INIT,
INIT_08 = INIT,
INIT_09 = INIT,
INIT_0A = INIT,
INIT_0B = INIT,
INIT_0C = INIT,
INIT_0D = INIT,
INIT_0E = INIT,
INIT_0F = INIT,
INIT_10 = INIT,
INIT_11 = INIT,
INIT_12 = INIT,
INIT_13 = INIT,
INIT_14 = INIT,
INIT_15 = INIT,
INIT_16 = INIT,
INIT_17 = INIT,
INIT_18 = INIT,
INIT_19 = INIT,
INIT_1A = INIT,
INIT_1B = INIT,
INIT_1C = INIT,
INIT_1D = INIT,
INIT_1E = INIT,
INIT_1F = INIT,
INIT_20 = INIT,
INIT_21 = INIT,
INIT_22 = INIT,
INIT_23 = INIT,
INIT_24 = INIT,
INIT_25 = INIT,
INIT_26 = INIT,
INIT_27 = INIT,
INIT_28 = INIT,
INIT_29 = INIT,
INIT_2A = INIT,
INIT_2B = INIT,
INIT_2C = INIT,
INIT_2D = INIT,
INIT_2E = INIT,
INIT_2F = INIT,
INIT_30 = INIT,
INIT_31 = INIT,
INIT_32 = INIT,
INIT_33 = INIT,
INIT_34 = INIT,
INIT_35 = INIT,
INIT_36 = INIT,
INIT_37 = INIT,
INIT_38 = INIT,
INIT_39 = INIT,
INIT_3A = INIT,
INIT_3B = INIT,
INIT_3C = INIT,
INIT_3D = INIT,
INIT_3E = INIT,
INIT_3F = INIT)
port map (
DIA = "00000000",
DIPA = "0",
DIB = "00000000",
DIPB = "0",
ENA = '1',
ENB = '1',
WEA = '0',
WEB = '0',
SSRA = '0',
SSRB = '0',
CLKA = clk_p,
CLKB = clk,
ADDRA = "00000000000",
ADDRB = "00000000000",
DOA = open,
DOPA = open,
DOB = open,
DOPB = open);


-- CLK process
process
begin
clk_p <= '0';
clk_n <= '1';
loop
wait for (10 ns);
clk_p <= not clk_p;
clk_n <= not clk_n;
end loop;
end process;

MAIN: process
begin -- process MAIN

rst <= '1';
wait for 10 ns;
rst <= '0';

wait;

end process MAIN;
end architecture sim;


--
Patrik Eriksson | patrik....@netinsight.net
Net Insight AB | phone: +46 8 685 04 89
Västberga Allé 9 | fax: +46 8 685 04 20
SE-126 30 STOCKHOLM, Sweden | http://www.netinsight.net

lng

unread,
Aug 19, 2002, 5:53:33 PM8/19/02
to
What kind of simulation did you run? timing, functional?
Have you tried to use the "gate point simulation.." , it may work!!!

Ray Andraka

unread,
Aug 19, 2002, 10:19:09 PM8/19/02
to
Try setting the TimingChecksOn generic to false. I've had troubles in the
past when that is in the (default) on state interfacing with RTL designs.
Also, you may be bringing the clock high at the same time you are bringing
the WE to inactive at the very beginning of your sim. Try starting with the
clock low.

Patrik Eriksson wrote:

--
--Ray Andraka, P.E.
President, the Andraka Consulting Group, Inc.
401/884-7930 Fax 401/884-7950
email r...@andraka.com
http://www.andraka.com

"They that give up essential liberty to obtain a little
temporary safety deserve neither liberty nor safety."
-Benjamin Franklin, 1759


Patrik Eriksson

unread,
Aug 20, 2002, 4:02:05 AM8/20/02
to

lng wrote:

> What kind of simulation did you run? timing, functional?


Functional


> Have you tried to use the "gate point simulation.." , it may work!!!
>


No

Thanks!
Patrik

Patrik Eriksson

unread,
Aug 20, 2002, 5:18:34 AM8/20/02
to

Ray Andraka wrote:

> Try setting the TimingChecksOn generic to false. I've had troubles in the
> past when that is in the (default) on state interfacing with RTL designs.


I tried that with the same result.


> Also, you may be bringing the clock high at the same time you are bringing
> the WE to inactive at the very beginning of your sim. Try starting with the
> clock low.


I think that the simulation model is incorrect. It is not true dual port
and the behaviour is wrong.

I've got this from xilinx support:

-----------
I have just found the following internal solution.

Keywords: unisim, functional, simulation, RAMB4_Sm_Sn, RAMB16_Sm_Sn

Urgency: Standard

Description: When performing a functional (behavioral) simulation on a
RAMB16_S9_S9 the following error message may be seen after issuing the
vsim (load design) command:
# ** Warning: Invalid ADDRESS: XXXXXXXXXXX. Memory contents will be set
to 'X'.

The simulation procedes but as suggested by the warning, the memory
contents are not initialised to correct values.

The warning occured because only one of the clock inputs to the dual
port RAM had passed through an IBUFG. The following workarounds will
cure the problem:
1) Ensure that both clocks do NOT have an IBUFG directly instantiated in
the code. IBUFGs will be inferred automatically if the default project
options are set.
OR
2) Ensure that both clocks have an IBUFG.

------------

Solution 2 solved my problem in the simple test code but not my real
design. I have to investigate it further.

Thanks!

Patrik

lng

unread,
Aug 20, 2002, 9:22:27 AM8/20/02
to
Hi there,

I used to use this trick :

1. Run implememtation to pass the "translate" stage to obtain the NGD file, besure your circuit is not sourceless or loadless

2. Run "check point gate simulation", you will see all init values.

Goran Bilski

unread,
Aug 20, 2002, 11:06:42 AM8/20/02
to
Tjena Patrick,

I can't say that I can represent Xilinx support in this issue
but I remember a similar problem I had a while ago.
The problem was that the clocks to the bram started at time 0
but the reset signal was not valid yet.
If you follow the VHDL simulation, the clock will arrive to the
BRAM when the address inputs signals are still invalid ('U').
The address signals will be valid in a few deltas but that is still to late
for the simulation model.
The situation of a active clock input but invalid address signals will set
the memory contents to 'X'.

The fix I did was to drive the reset before a started to drive the clock.

I hope that this will fix your problem since it fixed mine.

Med vänliga hälsningar
Göran

Ray Andraka

unread,
Aug 20, 2002, 11:42:23 AM8/20/02
to
If the timing checks didn't do it, I am pretty sure your BRAM is getting clocked
before the controls are valid. All it takes is one delta cycle. This is why I
recommended starting the simulation with the clock low rather than high, so that
as the simulation starts up the clock goes from 'U' to '0' instead of from 'U' to
1. That way, if there are fewer delta cycle delays on the clock path than on the
controls path you won't have the clock transitioning to '1' before the controls
become othter than 'U'. BTW, If you use the clkdll and drive the BRAM controls
directly from registers, you shouldn't hit this situation (the clk dll has quite a
few delta cycle delay).

Allan Herriman

unread,
Aug 20, 2002, 11:48:31 PM8/20/02
to
On Mon, 19 Aug 2002 15:35:58 GMT, Patrik Eriksson
<patrik....@netinsight.net> wrote:

>When I simulates the following code this warning message is displayed at
>time 0ns.
>
># ** Warning: Invalid ADDRESS: XXXXXXXXXX. Memory contents will be set
>to 'X'.
># Time: 0 ps Iteration: 3 Instance: /theram

I just found that this feature was recently introduced with the
unisim_vcomp.vhd that shipped with a recent service pack of 4.2i.

I had a test bench that had been working fine, and I recently
recompiled my copy of unisim_vcomp (using the SP3 source) and my
testbench stopped working :(

I had the clocks starting at '1', and Ray's suggested fix of having
them start at '0' made the problem go away. (Thanks Ray.)

This points to a bug in the unisim library. I feel that the rambx
components should not see an initial clock of '1' as a rising edge.

Regards,
Allan.

Ray Andraka

unread,
Aug 21, 2002, 12:58:40 AM8/21/02
to
I have seen this happen before in non-Xilinx stuff as well. The problem is
the if clk'event and clk='1' (which is what rising_edge(clk) does too), looks
for an event on the clock and a current value of '1', so any transition that
ends in a '1' is going to be interpreted as a clock rising edge by the sim,
and that includes the initial transition from 'U' to '1'. If the delta
delays in your particular model are such that the clock has more delta delays
than the data, you are fine. If not, then you have a problem. It just so
happens that the old BRAM model had an additional delay into the clock
relative to the data inside the model that is no longer there. I don't think
that this is a xilinx bug per se, although it could certainly be eliminated
by putting initial values or on the data path or extra delta delays
(connecting to local clock signal names) inside the model.

As I said, this is certainly not unique to xilinx, and you are probably
fortunate not to have run into it before.


Allan Herriman wrote:

--

Allan Herriman

unread,
Aug 21, 2002, 4:14:31 AM8/21/02
to
On Wed, 21 Aug 2002 04:58:40 GMT, Ray Andraka <r...@andraka.com> wrote:

>I have seen this happen before in non-Xilinx stuff as well. The problem is
>the if clk'event and clk='1' (which is what rising_edge(clk) does too), looks
>for an event on the clock and a current value of '1', so any transition that
>ends in a '1' is going to be interpreted as a clock rising edge by the sim,
>and that includes the initial transition from 'U' to '1'. If the delta
>delays in your particular model are such that the clock has more delta delays
>than the data, you are fine. If not, then you have a problem. It just so
>happens that the old BRAM model had an additional delay into the clock
>relative to the data inside the model that is no longer there. I don't think
>that this is a xilinx bug per se, although it could certainly be eliminated
>by putting initial values or on the data path or extra delta delays
>(connecting to local clock signal names) inside the model.
>
>As I said, this is certainly not unique to xilinx, and you are probably
>fortunate not to have run into it before.

Hi Ray,

There is a semantic difference between rising_edge(clk) and (clk'event
and clk = '1')

Rising_edge(x) returns

(x'event and
(to_x01(x) = '1') and
(to_x01(x'last_value) = '0'))

which usually avoids the problem at time 0, although it is still
possible to make it fail if the initial values on various signals are
set to provide a delta glitch. You have to try pretty hard to make it
fail though.

I haven't seen this before in my simulations because my clocked
processes always use rising_edge() (rather than clk'event and clk='1')
and always have an async reset (with higher priority than the clock),
and this reset is always active at time zero.

As you say, I've been fortunate. I'll have to check all my old test
benches now :(

If Xilinx are listening: it would be really nice if you could fix the
block ram model.

Regards,
Allan.

Ray Andraka

unread,
Aug 21, 2002, 8:41:12 AM8/21/02
to
See, even a seasoned veteran can learn something off the newsgroups. I never
realized rising_edge was different than clk'event and clk='1', so had been still
using the latter for consistency's sake. Way back when, I had a problem with
rising_edge not being recognized by a simulator, and since then I hadn't used it.

Allan Herriman wrote:

> There is a semantic difference between rising_edge(clk) and (clk'event
> and clk = '1')
>
> Rising_edge(x) returns
>
> (x'event and
> (to_x01(x) = '1') and
> (to_x01(x'last_value) = '0'))
>

--

0 new messages