DP RAM infering

R

RobertP

Guest
I'm trying to infer a 8x8 bit dual port distributed RAM in VirtexII
device, using XST.

My code looks similarly to the one from XST manual:


type RAM_TYPE is array(7 downto 0) of std_logic_vector(7 downto 0);

signal RAM : RAM_TYPE;
signal A: std_logic_vector(2 downto 0);
signal DPRA: std_logic_vector(2 downto 0);

..
..
..

RAM_INFER: process (clk)
begin
if (clk'event and clk = '1') then
if (RDBYTECNT_EN = '1') then
RAM(conv_integer(RDBYTE_CNT)) <= W1_DIN;
end if;
end if;
end process;

-- two 8-bit output ports are merged into 16-bit vector

RAM_OUT <= (RAM(conv_integer(DPRA))) & (RAM(conv_integer(A)));



Now I have two problems with above:

1) Every time (I think) modelsim executes function conv_integer()

it gives warnings like that:

There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result
will be 'X'(es).
CONV_INTEGER: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
operand, and it has been converted to 0.


conv_integer() function comes from ieee.std_logic_unsigned pakcage.


I tried also using different packege, i.e. ieee.numeric_std, then it
looks like that:

RAM(to_integer(unsigned(A)))

and Modelsim outputs

NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0

Am I doing something wrong? Aside from the warnings, simulation results
seem to be OK.

2)The synthesis report says:

Found 8x8-bit dual-port distributed RAM for signal <ram>.
-----------------------------------------------------------------------
| aspect ratio | 8-word x 8-bit |
| clock | connected to signal <clk> | rise
| write enable | connected to signal <rdbytecnt_en> | high
| address | connected to signal <rdbyte_cnt> |
| dual address | connected to signal <dpra> |
| data in | connected to signal <w1_din> |
| data out | not connected |
| dual data out | connected to internal node |
| ram_style | Distributed |

-----------------------------------------------------------------------
INFO:Xst:1442 - The RAM contents appears to be read asynchronousely. A
synchronous read would allow you to take advantage of available block
RAM resources, for optimized device usage and improved timings. Please
refer to your documentation for coding guidelines.
Found 8x8-bit dual-port distributed RAM for signal <ram>.
-----------------------------------------------------------------------
| aspect ratio | 8-word x 8-bit |
| clock | connected to signal <clk> | rise
| write enable | connected to signal <rdbytecnt_en> | high
| address | connected to signal <rdbyte_cnt> |
| dual address | connected to signal <a> |
| data in | connected to signal &lt;w1_din&gt; |
| data out | not connected |
| dual data out | connected to internal node |
| ram_style | Distributed |
-----------------------------------------------------------------------
INFO:Xst:1442 - The RAM contents appears to be read asynchronousely. A
synchronous read would allow you to take advantage of available block
RAM resources, for optimized device usage and improved timings. Please
refer to your documentation for coding guidelines.



Does it mean that synthesizer infered two RAMs instead of one? Is this OK?

I'm using ISE5.2 with service pack 3.

--
Robert Pudlik
 
OK, I found answer to problem 1).
At the start of simulation some signals were not initialized.
Also in the test bench I was assigning 'Z' to adrress input (this RAM is
part of a bigger design, and Address bus is bidirectional).

The result was as I described - I could read/write proper values from/to
the RAM.

I still don't have answer to question 2).

--
Robert Pudlik
 
Robert,
How do think that you can send two differents addresses at the same ram and
output 2 differents values at the same time?
It's impossible. So your synthesiser is bright and did the job for you by
infering 2 ram (same write address and different read address).

regards
fe


"RobertP" &lt;rpudlik@poczta.onet.pl&gt; wrote in message
news:ble3kl$884$1@news.onet.pl...
OK, I found answer to problem 1).
At the start of simulation some signals were not initialized.
Also in the test bench I was assigning 'Z' to adrress input (this RAM is
part of a bigger design, and Address bus is bidirectional).

The result was as I described - I could read/write proper values from/to
the RAM.

I still don't have answer to question 2).

--
Robert Pudlik
 
I might be wrong but distributed RAMs don't support the dual-port operation
you're using (one R/W and one R port). Block RAMs don't support async read
(as the warning suggests). So the synthesizer is pretty much hosed. What it
can do is to use two sets of distributed RAMs, write them simultaneously and
read them independently as you've specified. Quite neat it did so though, I
didn't know XST can be that claver...

Regards,
Andras Tantos

"RobertP" &lt;rpudlik@poczta.onet.pl&gt; wrote in message
news:ble3kl$884$1@news.onet.pl...
OK, I found answer to problem 1).
At the start of simulation some signals were not initialized.
Also in the test bench I was assigning 'Z' to adrress input (this RAM is
part of a bigger design, and Address bus is bidirectional).

The result was as I described - I could read/write proper values from/to
the RAM.

I still don't have answer to question 2).

--
Robert Pudlik
 
Robert,

Kudos on figuring out #1 on your own. I find when I've finally given up on
a problem and turn to someone for help, during the act of explaining it, the
answer comes to me. Funny how the mind works.

type RAM_TYPE is array(7 downto 0) of std_logic_vector(7 downto 0);
signal RAM : RAM_TYPE;
One trick I use for initializing RAMs for simulation is:

signal RAM : RAM_TYPE := (others =&gt; (others =&gt; '0'));

The nice thing is I don't have to change the initialization even when I
change the dimention of the ram. This works in Aldec. Never tried XST.

As for #2, the problem is you have three addresses hooked up to your DP ram:
RDBYTE_CNT, DPRA, and A. One port is a R/W port and must use the same
address for both R and W. The second port is R only and has it's own
address. That answers the "Why did XST infer two RAMs?"

You can answer the "Did XST infer two RAMs?" yourself by setting up a very
simple design that only contains your RAM code. Then look at the resource
utilization. Your 8x8 DPRAM should only use up 8(bit width) * 1(since your
depth isn't greater than 16) *2(ports) = 16 LUTs. You can also use FPGA
Editor or Floorplanner if you want to visually check what happened.

Hope that helps.


Regards,
Vinh
 
Vinh Pham wrote:

As for #2, the problem is you have three addresses hooked up to your DP ram:
RDBYTE_CNT, DPRA, and A. One port is a R/W port and must use the same
address for both R and W. The second port is R only and has it's own
address.
Yes, you are right. I need to rethink this, maybe it will be possible
to use only two addresses and save some resources.


--
Robert Pudlik
 
Yes, you are right. I need to rethink this, maybe it will be possible
to use only two addresses and save some resources.
Best of luck. Always a pain having to re-organize your design.
 

Welcome to EDABoard.com

Sponsor

Back
Top