FPGA Central - World's 1st FPGA / CPLD Portal

FPGA Central

World's 1st FPGA Portal

 

Go Back   FPGA Groups > NewsGroup > FPGA

FPGA comp.arch.fpga newsgroup (usenet)

Reply
 
LinkBack Thread Tools Display Modes
  #1 (permalink)  
Old 06-24-2009, 11:45 AM
Jonathan Bromley
Guest
 
Posts: n/a
Default True dual-port RAM in VHDL: XST question

hi all,

As promised many weeks ago, I'm building what I
hope will be a comprehensive summary of how to do
RAM inference from VHDL and Verilog code for all
the common synthesis tools and FPGAs. It will
go on our website some time this summer (sorry,
it's not a high-priority project).

I've encountered what seems to me to be a bug
in XST (all versions from 8 to 11 inclusive)
and I would value your opinion before I start
to give Xilinx a hard time about it. By the
way, exactly the same bug appears to be present
in Quartus but I haven't yet done enough detailed
investigation to comment on that properly.

To create true (dual-clock) dual-port RAM,
I need to create two clocked processes. This
requires me to use a shared variable for
the memory itself (ugly but possible, works
correctly in XST):

type t_mem is array (0 to 2**ABITS-1) of
std_logic_vector(DBITS-1 downto 0);
shared variable mem: t_mem; -- the memory storage
begin -- the architecture
process (clock0) -- manages port A
begin
if rising_edge (clock0) then
if we0 = '1' then -- write to port A
mem(to_integer(unsigned(a0))) := wd0;
rd0 <= wd0;
else
rd0 <= mem(to_integer(unsigned(a0)));
end if;
end if;
end process;
--
process (clock1) -- manages port B
begin
if rising_edge (clock1) then
if we1 = '1' then
mem(to_integer(unsigned(a1))) := wd1;
rd1 <= wd1;
else
rd1 <= mem(to_integer(unsigned(a1)));
end if;
end if;
end process;

That, I believe, is the right way to do it.

However, both XST and Quartus give THE SAME SYNTHESIS
RESULTS if I change "shared variable" to "signal", and
make signal assignments instead of variable assignments
to the mem() array. This is just plain WRONG! Writing
to a signal from two processes represents two resolved
drivers on the signal, and does not correctly model a
dual-port memory in simulation.

Given that the whole point of memory inference from
HDL code is that you get a convenient, readable,
accurate simulation model as part of your design
code, this behaviour by the synthesis tools is
incomprehensible to me. Can anyone clarify? Has
anyone fallen foul of this problem? Best of all,
could Brian Philofsky, who has written so clearly
and helpfully about XST in the past, please speak
up and tell us what the blazes is going on here?

Thanks
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
[email protected]
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
Reply With Quote
  #2 (permalink)  
Old 06-24-2009, 12:37 PM
Fredxx
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question


"Jonathan Bromley" <[email protected]> wrote in message
news[email protected]..
> hi all,
>
> As promised many weeks ago, I'm building what I
> hope will be a comprehensive summary of how to do
> RAM inference from VHDL and Verilog code for all
> the common synthesis tools and FPGAs. It will
> go on our website some time this summer (sorry,
> it's not a high-priority project).
>
> I've encountered what seems to me to be a bug
> in XST (all versions from 8 to 11 inclusive)
> and I would value your opinion before I start
> to give Xilinx a hard time about it. By the
> way, exactly the same bug appears to be present
> in Quartus but I haven't yet done enough detailed
> investigation to comment on that properly.
>
> To create true (dual-clock) dual-port RAM,
> I need to create two clocked processes. This
> requires me to use a shared variable for
> the memory itself (ugly but possible, works
> correctly in XST):
>
> type t_mem is array (0 to 2**ABITS-1) of
> std_logic_vector(DBITS-1 downto 0);
> shared variable mem: t_mem; -- the memory storage
> begin -- the architecture
> process (clock0) -- manages port A
> begin
> if rising_edge (clock0) then
> if we0 = '1' then -- write to port A
> mem(to_integer(unsigned(a0))) := wd0;
> rd0 <= wd0;
> else
> rd0 <= mem(to_integer(unsigned(a0)));
> end if;
> end if;
> end process;
> --
> process (clock1) -- manages port B
> begin
> if rising_edge (clock1) then
> if we1 = '1' then
> mem(to_integer(unsigned(a1))) := wd1;
> rd1 <= wd1;
> else
> rd1 <= mem(to_integer(unsigned(a1)));
> end if;
> end if;
> end process;
>
> That, I believe, is the right way to do it.
>
> However, both XST and Quartus give THE SAME SYNTHESIS
> RESULTS if I change "shared variable" to "signal", and
> make signal assignments instead of variable assignments
> to the mem() array. This is just plain WRONG! Writing
> to a signal from two processes represents two resolved
> drivers on the signal, and does not correctly model a
> dual-port memory in simulation.
>
> Given that the whole point of memory inference from
> HDL code is that you get a convenient, readable,
> accurate simulation model as part of your design
> code, this behaviour by the synthesis tools is
> incomprehensible to me. Can anyone clarify? Has
> anyone fallen foul of this problem? Best of all,
> could Brian Philofsky, who has written so clearly
> and helpfully about XST in the past, please speak
> up and tell us what the blazes is going on here?
>


Your knowledge of VHDL is greater than mine, but I assumed that

> if we1 = '1' then
> mem(to_integer(unsigned(a1))) := wd1;
> end if;


was equivalent to;
if we1 = '1' then
mem(to_integer(unsigned(a1))) := wd1;
else
mem(to_integer(unsigned(a1))) := mem(to_integer(unsigned(a1)));
end if;

if you used something like;
if we1 = '1' then
mem(to_integer(unsigned(a1))) := wd1;
else
mem(to_integer(unsigned(a1))) := (others => 'Z');
end if;

Would this then give more consistent results where both processes wouldn't
be fighting against each other?

Happy to be told I'm wrong.


Reply With Quote
  #3 (permalink)  
Old 06-24-2009, 01:15 PM
Jonathan Bromley
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question

On Wed, 24 Jun 2009 11:37:24 +0100, "Fredxx" wrote:

>if you used something like;
> if we1 = '1' then
> mem(to_integer(unsigned(a1))) := wd1;
> else
> mem(to_integer(unsigned(a1))) := (others => 'Z');
> end if;
>
>Would this then give more consistent results where both processes wouldn't
>be fighting against each other?


Sadly, no. I see what you're getting at, but I don't think you could
ever get the memory to have the correct contents if both ports are
doing that all the time. Each process may overwrite locations it's
already correctly written, using Zs, for no good reason.

Suppose you could get it right somehow, and arrange that each process
is driving Z to all locations it's never written, but appropriate
values to locations it has written. What then happens if the second
process writes to a location that previously was written by the other?
How can it tell the first process now to put Z on that location?

In truth the "correct" solution would be to write the whole thing
as a single process with two clocks:

process (clock0, clock1)
variable mem: t_mem;
begin
if rising_edge(clock0) then
if we0 = '1' then
mem(a0) := wd0;
end if;
end if;
if rising_edge(clock1) then
if we1 = '1' then
mem(a1) := wd1;
end if;
end if;
...

But I suspect synthesis tools would chuck that overboard
without a second thought.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
[email protected]
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.

Reply With Quote
  #4 (permalink)  
Old 06-24-2009, 01:44 PM
Fredxx
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question


"Jonathan Bromley" <[email protected]> wrote in message
news:[email protected]..
> On Wed, 24 Jun 2009 11:37:24 +0100, "Fredxx" wrote:
>
>>if you used something like;
>> if we1 = '1' then
>> mem(to_integer(unsigned(a1))) := wd1;
>> else
>> mem(to_integer(unsigned(a1))) := (others => 'Z');
>> end if;
>>
>>Would this then give more consistent results where both processes wouldn't
>>be fighting against each other?

>
> Sadly, no. I see what you're getting at, but I don't think you could
> ever get the memory to have the correct contents if both ports are
> doing that all the time. Each process may overwrite locations it's
> already correctly written, using Zs, for no good reason.
>
> Suppose you could get it right somehow, and arrange that each process
> is driving Z to all locations it's never written, but appropriate
> values to locations it has written. What then happens if the second
> process writes to a location that previously was written by the other?
> How can it tell the first process now to put Z on that location?
>
> In truth the "correct" solution would be to write the whole thing
> as a single process with two clocks:
>
> process (clock0, clock1)
> variable mem: t_mem;
> begin
> if rising_edge(clock0) then
> if we0 = '1' then
> mem(a0) := wd0;
> end if;
> end if;
> if rising_edge(clock1) then
> if we1 = '1' then
> mem(a1) := wd1;
> end if;
> end if;
> ...
>
> But I suspect synthesis tools would chuck that overboard
> without a second thought.
> --
> Jonathan Bromley, Consultant
>
> DOULOS - Developing Design Know-how
> VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services
>
> Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
> [email protected]
> http://www.MYCOMPANY.com
>
> The contents of this message may contain personal views which
> are not the views of Doulos Ltd., unless specifically stated.
>


I perhaps am making the (erroneous) assumption that two statements will be
or'd together and the Z's will be overdriven by the signals. But as you
say, I would be replacing the RAM locations with Z's or something that the
synthesiser concocts.

To be honest, I think it isn't good practice to have signals driven by 2
clocks, and I'd probably use clock switching primitives instead so the
memory would be written in one process with just one clock.


Reply With Quote
  #5 (permalink)  
Old 06-24-2009, 02:23 PM
Jonathan Bromley
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question

On Wed, 24 Jun 2009 12:44:27 +0100, "Fredxx" wrote:

>I perhaps am making the (erroneous) assumption that two statements will be
>or'd together and the Z's will be overdriven by the signals.


That's more-or-less correct. Each process represents a driver
on any signal it writes. If multiple processes write to a signal,
then the actual signal value is determined by resolving the
various driven values. Of course, anything else overdrives Z.

The hard-to-solve problem: suppose process A writes a value
to a memory location at some time; clearly, you want that
value to remain in the location and not to be overwritten
to Z on the next clock, so you can't allow process A to change
its mind about that value. Some time later, suppose process B
writes to the same location. Now you have two non-Z drivers
on the same set of bits. How can process B tell process A
that it's time for its driver to lapse back to Z? Shared
variables, for all their ugliness, solve this problem
neatly (which is why my problem simply doesn't exist in
Verilog, where all variables are shared).

>To be honest, I think it isn't good practice to have signals driven by 2
>clocks, and I'd probably use clock switching primitives instead so the
>memory would be written in one process with just one clock.


In normal logic I would 100% agree, but here I'm talking about
modeling and synthesizing the FPGAs' built-in RAM blocks, which
have the option of independent clocks on the two ports. So
it is important to write VHDL corresponding to that behavior.
You could mux the clocks onto a single port, but that would
be a totally different design.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
[email protected]
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
Reply With Quote
  #6 (permalink)  
Old 06-24-2009, 02:54 PM
Fredxx
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question


"Jonathan Bromley" <[email protected]> wrote in message
news:[email protected]..
> On Wed, 24 Jun 2009 12:44:27 +0100, "Fredxx" wrote:
>
>
> In normal logic I would 100% agree, but here I'm talking about
> modeling and synthesizing the FPGAs' built-in RAM blocks, which
> have the option of independent clocks on the two ports. So
> it is important to write VHDL corresponding to that behavior.
> You could mux the clocks onto a single port, but that would
> be a totally different design.


Ah - I see - that does sound rather tricky and can see where you're coming
from.


Reply With Quote
  #7 (permalink)  
Old 06-24-2009, 04:18 PM
rickman
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question

On Jun 24, 7:44*am, "Fredxx" <fre...@spam.com> wrote:
> "Jonathan Bromley" <jonathan.brom...@MYCOMPANY.com> wrote in message
>
> news:[email protected]..
>
>
>
> > On Wed, 24 Jun 2009 11:37:24 +0100, "Fredxx" wrote:

>
> >>if you used something like;
> >> * * *if we1 = '1' then
> >> * * * *mem(to_integer(unsigned(a1))) := wd1;
> >> * * *else
> >> * * * *mem(to_integer(unsigned(a1))) := (others => 'Z');
> >> * * *end if;

>
> >>Would this then give more consistent results where both processes wouldn't
> >>be fighting against each other?

>
> > Sadly, no. *I see what you're getting at, but I don't think you could
> > ever get the memory to have the correct contents if both ports are
> > doing that all the time. *Each process may overwrite locations it's
> > already correctly written, using Zs, for no good reason.

>
> > Suppose you could get it right somehow, and arrange that each process
> > is driving Z to all locations it's never written, but appropriate
> > values to locations it has written. *What then happens if the second
> > process writes to a location that previously was written by the other?
> > How can it tell the first process now to put Z on that location?

>
> > In truth the "correct" solution would be to write the whole thing
> > as a single process with two clocks:

>
> > *process (clock0, clock1)
> > * *variable mem: t_mem;
> > *begin
> > * *if rising_edge(clock0) then
> > * * *if we0 = '1' then
> > * * * *mem(a0) := wd0;
> > * * *end if;
> > * *end if;
> > * *if rising_edge(clock1) then
> > * * *if we1 = '1' then
> > * * * *mem(a1) := wd1;
> > * * *end if;
> > * *end if;
> > * *...

>
> > But I suspect synthesis tools would chuck that overboard
> > without a second thought.
> > --
> > Jonathan Bromley, Consultant

>
> > DOULOS - Developing Design Know-how
> > VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

>
> > Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
> > jonathan.brom...@MYCOMPANY.com
> >http://www.MYCOMPANY.com

>
> > The contents of this message may contain personal views which
> > are not the views of Doulos Ltd., unless specifically stated.

>
> I perhaps am making the (erroneous) assumption that two statements will be
> or'd together and the Z's will be overdriven by the signals. *But as you
> say, I would be replacing the RAM locations with Z's or something that the
> synthesiser concocts.
>
> To be honest, I think it isn't good practice to have signals driven by 2
> clocks, and I'd probably use clock switching primitives instead so the
> memory would be written in one process with just one clock.



That would be a truly bizarre circuit design. I don't know how they
actually construct memory to use separate clocks, but I expect it uses
an async memory with two independent synchronous interfaces. FPGA
reps have posted here that there is a lot of "magic" in the logic
between the sync interfaces and the async memory inside the block
ram. All of this would be very hard to describe using an HDL. But
driving a signal with 'z' or switching clocks is not the way to go at
all...

Rick
Reply With Quote
  #8 (permalink)  
Old 06-24-2009, 04:45 PM
Fredxx
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question


"Jonathan Bromley" <[email protected]> wrote in message
news:[email protected]..
> On Wed, 24 Jun 2009 12:44:27 +0100, "Fredxx" wrote:
>
>>I perhaps am making the (erroneous) assumption that two statements will be
>>or'd together and the Z's will be overdriven by the signals.

>
> That's more-or-less correct. Each process represents a driver
> on any signal it writes. If multiple processes write to a signal,
> then the actual signal value is determined by resolving the
> various driven values. Of course, anything else overdrives Z.
>
> The hard-to-solve problem: suppose process A writes a value
> to a memory location at some time; clearly, you want that
> value to remain in the location and not to be overwritten
> to Z on the next clock, so you can't allow process A to change
> its mind about that value. Some time later, suppose process B
> writes to the same location. Now you have two non-Z drivers
> on the same set of bits. How can process B tell process A
> that it's time for its driver to lapse back to Z? Shared
> variables, for all their ugliness, solve this problem
> neatly (which is why my problem simply doesn't exist in
> Verilog, where all variables are shared).
>
>>To be honest, I think it isn't good practice to have signals driven by 2
>>clocks, and I'd probably use clock switching primitives instead so the
>>memory would be written in one process with just one clock.

>
> In normal logic I would 100% agree, but here I'm talking about
> modeling and synthesizing the FPGAs' built-in RAM blocks, which
> have the option of independent clocks on the two ports. So
> it is important to write VHDL corresponding to that behavior.
> You could mux the clocks onto a single port, but that would
> be a totally different design.


What's wrong with an asynchronous memory, where the appropriate clocks latch
the control signals to create synchronous RAM.

Then we can do something like:

process (a0, we0, wd0, a1, we1, wd1)
begin
if we0 = '1' then -- write to port A
mem(conv_integer(a0)) <= wd0;
end if;
if we1 = '1' then -- write to port A
mem(conv_integer(a1)) <= wd1;
end if;
rd0 <= mem(conv_integer(a0));
rd1 <= mem(conv_integer(a1));
end process;

It works in simulation!!


Reply With Quote
  #9 (permalink)  
Old 06-24-2009, 04:57 PM
Jonathan Bromley
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question

On Wed, 24 Jun 2009 15:45:37 +0100, "Fredxx" wrote:

>What's wrong with an asynchronous memory[...]
>It works in simulation!!


Nothing wrong with them, except that they don't exist
in real FPGAs. By contrast, dual-ported dual-clock
synchronous RAMs most certainly do :-)
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
[email protected]
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
Reply With Quote
  #10 (permalink)  
Old 06-24-2009, 05:00 PM
rickman
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question

On Jun 24, 10:45*am, "Fredxx" <fre...@spam.com> wrote:
> "Jonathan Bromley" <jonathan.brom...@MYCOMPANY.com> wrote in message
>
> news:[email protected]..
>
>
>
> > On Wed, 24 Jun 2009 12:44:27 +0100, "Fredxx" wrote:

>
> >>I perhaps am making the (erroneous) assumption that two statements willbe
> >>or'd together and the Z's will be overdriven by the signals.

>
> > That's more-or-less correct. *Each process represents a driver
> > on any signal it writes. *If multiple processes write to a signal,
> > then the actual signal value is determined by resolving the
> > various driven values. *Of course, anything else overdrives Z.

>
> > The hard-to-solve problem: *suppose process A writes a value
> > to a memory location at some time; clearly, you want that
> > value to remain in the location and not to be overwritten
> > to Z on the next clock, so you can't allow process A to change
> > its mind about that value. *Some time later, suppose process B
> > writes to the same location. *Now you have two non-Z drivers
> > on the same set of bits. *How can process B tell process A
> > that it's time for its driver to lapse back to Z? *Shared
> > variables, for all their ugliness, solve this problem
> > neatly (which is why my problem simply doesn't exist in
> > Verilog, where all variables are shared).

>
> >>To be honest, I think it isn't good practice to have signals driven by 2
> >>clocks, and I'd probably use clock switching primitives instead so the
> >>memory would be written in one process with just one clock.

>
> > In normal logic I would 100% agree, but here I'm talking about
> > modeling and synthesizing the FPGAs' built-in RAM blocks, which
> > have the option of independent clocks on the two ports. *So
> > it is important to write VHDL corresponding to that behavior.
> > You could mux the clocks onto a single port, but that would
> > be a totally different design.

>
> What's wrong with an asynchronous memory, where the appropriate clocks latch
> the control signals to create synchronous RAM.
>
> Then we can do something like:
>
> process (a0, we0, wd0, a1, we1, wd1)
> begin
> * if we0 = '1' then *-- write to port A
> * * mem(conv_integer(a0)) <= wd0;
> * end if;
> * if we1 = '1' then *-- write to port A
> * * mem(conv_integer(a1)) <= wd1;
> * end if;
> * rd0 <= mem(conv_integer(a0));
> * rd1 <= mem(conv_integer(a1));
> end process;
>
> It works in simulation!!


I doubt that it will synthesize. Synthesis is largely a matter of
template matching. You can describe a behavior any way you want in
simulation. But if the synthesis tool does not recognize that form,
it won't synthesize to anything useful. Often memory that is not
recognized as a block ram is synthesized as distributed memory using
much of the FFs on a chip. Not only that, but it takes forever to
complete just to find out you don't have a workable design.

Rick
Reply With Quote
  #11 (permalink)  
Old 06-24-2009, 05:24 PM
Ed McGettigan
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question

Fredxx wrote:
> "Jonathan Bromley" <[email protected]> wrote in message
> news:[email protected]..
>> On Wed, 24 Jun 2009 12:44:27 +0100, "Fredxx" wrote:
>>
>>> I perhaps am making the (erroneous) assumption that two statements will be
>>> or'd together and the Z's will be overdriven by the signals.

>> That's more-or-less correct. Each process represents a driver
>> on any signal it writes. If multiple processes write to a signal,
>> then the actual signal value is determined by resolving the
>> various driven values. Of course, anything else overdrives Z.
>>
>> The hard-to-solve problem: suppose process A writes a value
>> to a memory location at some time; clearly, you want that
>> value to remain in the location and not to be overwritten
>> to Z on the next clock, so you can't allow process A to change
>> its mind about that value. Some time later, suppose process B
>> writes to the same location. Now you have two non-Z drivers
>> on the same set of bits. How can process B tell process A
>> that it's time for its driver to lapse back to Z? Shared
>> variables, for all their ugliness, solve this problem
>> neatly (which is why my problem simply doesn't exist in
>> Verilog, where all variables are shared).
>>
>>> To be honest, I think it isn't good practice to have signals driven by 2
>>> clocks, and I'd probably use clock switching primitives instead so the
>>> memory would be written in one process with just one clock.

>> In normal logic I would 100% agree, but here I'm talking about
>> modeling and synthesizing the FPGAs' built-in RAM blocks, which
>> have the option of independent clocks on the two ports. So
>> it is important to write VHDL corresponding to that behavior.
>> You could mux the clocks onto a single port, but that would
>> be a totally different design.

>
> What's wrong with an asynchronous memory, where the appropriate clocks latch
> the control signals to create synchronous RAM.
>
> Then we can do something like:
>
> process (a0, we0, wd0, a1, we1, wd1)
> begin
> if we0 = '1' then -- write to port A
> mem(conv_integer(a0)) <= wd0;
> end if;
> if we1 = '1' then -- write to port A
> mem(conv_integer(a1)) <= wd1;
> end if;
> rd0 <= mem(conv_integer(a0));
> rd1 <= mem(conv_integer(a1));
> end process;
>
> It works in simulation!!
>
>


Asynchronous memories only work correctly if the input delays are well
controlled and internal self timed circuits function correctly. In
order to achieve reliability memory designers have to build in a lot of
margin so asynchronous memories will operate much slower than a
synchronous memory and even then there are tight specs on the address
and data busses.

For example take the code example that you have above and instead of
having a test bench that transitions the a0, a1, wd0 and wd1 at the same
time add some delay to various bits in the address and data busses and
observe the results.

Ed McGettigan
--
Xilinx Inc.
Reply With Quote
  #12 (permalink)  
Old 06-24-2009, 05:27 PM
Fredxx
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question


"Jonathan Bromley" <[email protected]> wrote in message
news:[email protected]..
> On Wed, 24 Jun 2009 15:45:37 +0100, "Fredxx" wrote:
>
>>What's wrong with an asynchronous memory[...]
>>It works in simulation!!

>
> Nothing wrong with them, except that they don't exist
> in real FPGAs. By contrast, dual-ported dual-clock
> synchronous RAMs most certainly do :-)


I thought you were trying to simulate and synthesise dual port block RAM,
without using the normal block RAM primitives. In your first post you said
"of how to do RAM inference from VHDL and Verilog code for all the common
synthesis tools and FPGAs".

The asynchronous memory is an array of flip-flops rather than a memory, but
that's a mute point. It does both synthesise and simulate in Xilinx ISE
tools.


Reply With Quote
  #13 (permalink)  
Old 06-24-2009, 05:31 PM
Fredxx
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question

rickman wrote:
> On Jun 24, 10:45 am, "Fredxx" <fre...@spam.com> wrote:
>> "Jonathan Bromley" <jonathan.brom...@MYCOMPANY.com> wrote in message
>>
>> news:[email protected]..
>>
>>
>>
>>> On Wed, 24 Jun 2009 12:44:27 +0100, "Fredxx" wrote:

>>
>>>> I perhaps am making the (erroneous) assumption that two statements
>>>> will be or'd together and the Z's will be overdriven by the
>>>> signals.

>>
>>> That's more-or-less correct. Each process represents a driver
>>> on any signal it writes. If multiple processes write to a signal,
>>> then the actual signal value is determined by resolving the
>>> various driven values. Of course, anything else overdrives Z.

>>
>>> The hard-to-solve problem: suppose process A writes a value
>>> to a memory location at some time; clearly, you want that
>>> value to remain in the location and not to be overwritten
>>> to Z on the next clock, so you can't allow process A to change
>>> its mind about that value. Some time later, suppose process B
>>> writes to the same location. Now you have two non-Z drivers
>>> on the same set of bits. How can process B tell process A
>>> that it's time for its driver to lapse back to Z? Shared
>>> variables, for all their ugliness, solve this problem
>>> neatly (which is why my problem simply doesn't exist in
>>> Verilog, where all variables are shared).

>>
>>>> To be honest, I think it isn't good practice to have signals
>>>> driven by 2 clocks, and I'd probably use clock switching
>>>> primitives instead so the memory would be written in one process
>>>> with just one clock.

>>
>>> In normal logic I would 100% agree, but here I'm talking about
>>> modeling and synthesizing the FPGAs' built-in RAM blocks, which
>>> have the option of independent clocks on the two ports. So
>>> it is important to write VHDL corresponding to that behavior.
>>> You could mux the clocks onto a single port, but that would
>>> be a totally different design.

>>
>> What's wrong with an asynchronous memory, where the appropriate
>> clocks latch the control signals to create synchronous RAM.
>>
>> Then we can do something like:
>>
>> process (a0, we0, wd0, a1, we1, wd1)
>> begin
>> if we0 = '1' then -- write to port A
>> mem(conv_integer(a0)) <= wd0;
>> end if;
>> if we1 = '1' then -- write to port A
>> mem(conv_integer(a1)) <= wd1;
>> end if;
>> rd0 <= mem(conv_integer(a0));
>> rd1 <= mem(conv_integer(a1));
>> end process;
>>
>> It works in simulation!!

>
> I doubt that it will synthesize. Synthesis is largely a matter of
> template matching. You can describe a behavior any way you want in
> simulation. But if the synthesis tool does not recognize that form,
> it won't synthesize to anything useful. Often memory that is not
> recognized as a block ram is synthesized as distributed memory using
> much of the FFs on a chip. Not only that, but it takes forever to
> complete just to find out you don't have a workable design.
>


Perhaps I've been lucky with ISE tools, but I have found constructs like
this to work.

I was of the opinion that Johnathan wanted to create a VHDL block which
could replace the normal dual port block RAMs normlly found in FPGAs.
Therefore I don't see the problem in using std_logic_vector flipflops to
create the memory.


Reply With Quote
  #14 (permalink)  
Old 06-24-2009, 05:31 PM
Sandro
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question

On Jun 24, 2:23*pm, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
> ...
> In normal logic I would 100% agree, but here I'm talking about
> modeling and synthesizing the FPGAs' built-in RAM blocks, which
> have the option of independent clocks on the two ports. *So
> it is important to write VHDL corresponding to that behavior.
> You could mux the clocks onto a single port, but that would
> be a totally different design.
> ...


If you are curious please take a look to the vhdl VITAL
simulations sources...
you can find in

<ISE INST PATH>/Xilinx/10.1/ISE/vhdl/src/unisims/unisim_VITAL.vhd

but be careful ;-) ... they are NOT 20 lines of code.

Regards
Sandro
Reply With Quote
  #15 (permalink)  
Old 06-24-2009, 06:50 PM
Muzaffer Kal
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question

On Wed, 24 Jun 2009 16:27:30 +0100, "Fredxx" <[email protected]> wrote:
>The asynchronous memory is an array of flip-flops rather than a memory, but
>that's a mute point. It does both synthesise and simulate in Xilinx ISE
>tools.
>

Flip-flops need a clock to function. How do you write to them without
a clock to implement asynchronous memory (which by definition doesn't
have it?). You can use an array of latches as opposed to flip-flops
but timing latches is quite difficult especially in an fpga context
where tools are really not geared towards it. You maybe able to
synthesize it in ISE and the original code simulates for sure but have
you tried a back-annotated gate level simulation? It would be an
interesting challenge to get it to work fully unless your read/write
pulse widths and separations are extremely conservative.
One last to remember is that there are a lot fewer slice registers
(from which latches are made) than memory bits in an FPGA so you're
quite limited in how much async memory of this type you can make.
---
Muzaffer Kal

DSPIA INC.
ASIC/FPGA Design Services
http://www.dspia.com
Reply With Quote
  #16 (permalink)  
Old 06-24-2009, 07:53 PM
Andy
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question

On Jun 24, 6:15*am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
> In truth the "correct" solution would be to write the whole thing
> as a single process with two clocks:
>
> * process (clock0, clock1)
> * * variable mem: t_mem;
> * begin
> * * if rising_edge(clock0) then
> * * * if we0 = '1' then
> * * * * mem(a0) := wd0;
> * * * end if;
> * * end if;
> * * if rising_edge(clock1) then
> * * * if we1 = '1' then
> * * * * mem(a1) := wd1;
> * * * end if;
> * * end if;
> * * ...
>
> But I suspect synthesis tools would chuck that overboard
> without a second thought.


Current synthesis tools would probably have an issue with this, but
there's no good reason for it. DDR synthesis (though not the same as
independent clock, dual port memories) needs it anyway. Some synthesis
tools support dual clock processes, just not writes to the same var/
sig on both clocks. The only time this example does not behave like a
true dual clock/port ram is when two writes are attempted to the same
address at exactly the same time, which is not even defined for the
real HW. Good system design makes that case meaningless anyway.

Andy
Reply With Quote
  #17 (permalink)  
Old 06-24-2009, 07:57 PM
Jonathan Bromley
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question

On Wed, 24 Jun 2009 08:31:26 -0700 (PDT), Sandro wrote:

>If you are curious please take a look to the vhdl VITAL
>simulations sources...


I know about the vendor-provided simulation models,
which are fine pieces of work that do their job well.
But they are completely irrelevant both to my original
problem and to the issue I asked about.

I'm trying to assemble a complete and accurate list
of the _synthesizable_ templates for all common types
of FPGA memory, and I have discovered a template
that synthesizes to dual-clock RAM in two FPGA
vendors' tools but is a complete nonsense for
simulation. I want to know why this has happened,
what we can do about it, and why the vendors haven't
already been beaten to pulp over it by users.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
[email protected]
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
Reply With Quote
  #18 (permalink)  
Old 06-24-2009, 08:01 PM
Jonathan Bromley
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question

On Wed, 24 Jun 2009 10:53:49 -0700 (PDT), Andy wrote:

[of multi-clocked processes in VHDL]

>Current synthesis tools would probably have an issue with this, but
>there's no good reason for it. DDR synthesis (though not the same as
>independent clock, dual port memories) needs it anyway.


I completely agree. One of the side-effects of the
survey I'm doing will probably be that I'll log requests
for exactly this feature with all the synthesis vendors.
I don't hold out much hope, though. Support welcomed ;-)
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
[email protected]
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
Reply With Quote
  #19 (permalink)  
Old 06-24-2009, 08:11 PM
Muzaffer Kal
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question

On Wed, 24 Jun 2009 18:57:29 +0100, Jonathan Bromley
<[email protected]> wrote:

>I'm trying to assemble a complete and accurate list
>of the _synthesizable_ templates for all common types
>of FPGA memory, and I have discovered a template
>that synthesizes to dual-clock RAM in two FPGA
>vendors' tools but is a complete nonsense for
>simulation. I want to know why this has happened,
>what we can do about it, and why the vendors haven't
>already been beaten to pulp over it by users.


Originally coming from ASIC side I find this incredible but it seems
that majority of people doing FPGA design don't simulate. I was at an
FPGA infomercial the other day about two new device families coming
out from a vendor to stay nameless and only %20 or so people raised
their hands when asked this question. This might explain how these
templates survived as is for such a long time.
---
Muzaffer Kal

DSPIA INC.
ASIC/FPGA Design Services
http://www.dspia.com
Reply With Quote
  #20 (permalink)  
Old 06-24-2009, 09:05 PM
Mike Treseler
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question

Jonathan Bromley wrote:

> I'm trying to assemble a complete and accurate list
> of the _synthesizable_ templates for all common types
> of FPGA memory, and I have discovered a template
> that synthesizes to dual-clock RAM in two FPGA
> vendors' tools but is a complete nonsense for
> simulation. I want to know why this has happened,
> what we can do about it, and why the vendors haven't
> already been beaten to pulp over it by users.


This has happen because the majority of FPGA
designers prefer to wire together blocks
by others, and verify on the bench using
trial and error synthesis.

The silly dual clock RAM model is ignored
not because it is silly, but because
a vendor netlist is preferred to RTL
to get at all the asynchronous black magic.

What to do? I stick with single clock RAMs
and arbitrate synchronously.

-- Mike Treseler


Reply With Quote
  #21 (permalink)  
Old 06-24-2009, 09:43 PM
Fredxx
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question


"Muzaffer Kal" <[email protected]> wrote in message
news:[email protected]..
> On Wed, 24 Jun 2009 16:27:30 +0100, "Fredxx" <[email protected]> wrote:
>>The asynchronous memory is an array of flip-flops rather than a memory,
>>but
>>that's a mute point. It does both synthesise and simulate in Xilinx ISE
>>tools.
>>

> Flip-flops need a clock to function. How do you write to them without
> a clock to implement asynchronous memory (which by definition doesn't
> have it?). You can use an array of latches as opposed to flip-flops
> but timing latches is quite difficult especially in an fpga context
> where tools are really not geared towards it. You maybe able to
> synthesize it in ISE and the original code simulates for sure but have
> you tried a back-annotated gate level simulation? It would be an
> interesting challenge to get it to work fully unless your read/write
> pulse widths and separations are extremely conservative.
> One last to remember is that there are a lot fewer slice registers
> (from which latches are made) than memory bits in an FPGA so you're
> quite limited in how much async memory of this type you can make.


Different types of flip flops can be inferred by VHDL. Not all have to use
the global clock, or even a clock as such.

True - if it was my problem, I would look at the logic it creates, but at
the moment I don't have time.


Reply With Quote
  #22 (permalink)  
Old 06-24-2009, 10:02 PM
Andy Peters
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question

On Jun 24, 10:57*am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
> I'm trying to assemble a complete and accurate list
> of the _synthesizable_ templates for all common types
> of FPGA memory, and I have discovered a template
> that synthesizes to dual-clock RAM in two FPGA
> vendors' tools but is a complete nonsense for
> simulation. *I want to know why this has happened,
> what we can do about it, and why the vendors haven't
> already been beaten to pulp over it by users.


The vendors say, "Instantiate the component from the library," which
neatly sidesteps the difficult work of actually enabling such
inference.

-a
Reply With Quote
  #23 (permalink)  
Old 06-25-2009, 03:43 AM
Alex
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question

On Jun 24, 10:57*am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
> On Wed, 24 Jun 2009 08:31:26 -0700 (PDT), Sandro wrote:
> >If you are curious please take a look to the vhdl VITAL
> >simulations sources...

>
> I know about the vendor-provided simulation models,
> which are fine pieces of work that do their job well.
> But they are completely irrelevant both to my original
> problem and to the issue I asked about. *
>
> I'm trying to assemble a complete and accurate list
> of the _synthesizable_ templates for all common types
> of FPGA memory, and I have discovered a template
> that synthesizes to dual-clock RAM in two FPGA
> vendors' tools but is a complete nonsense for
> simulation. *I want to know why this has happened,
> what we can do about it, and why the vendors haven't
> already been beaten to pulp over it by users.
> --
> Jonathan Bromley, Consultant
>
> DOULOS - Developing Design Know-how
> VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services
>
> Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
> jonathan.brom...@MYCOMPANY.comhttp://www.MYCOMPANY.com
>
> The contents of this message may contain personal views which
> are not the views of Doulos Ltd., unless specifically stated.



The truth is that current FPGA Synthesis tools quite often do a poor
job (not counting trivial cases here) in inference of FPGA vendors'
macros. From the other hand FPGA vendors want users to instantiate
their macros (and so to be locked into their devices) and make it very
easy to configure and generate the code for instantiation using
proprietary vendor tools.
So majority of users prefers to instantiate the macros as a better
alternative to make the Synthesis tools infer the necessary structure
(and lose sometimes days on debugging different synthesis attributes,
directives etc...)
Just wanted to offer a possible explanation in answer to your
question, Jonathan :^)

Theoretically, independent FPGA synthesis tools vendors (Mentor,
Synopsys) should be interested for users to create a vendor
independent code. This way they'll have a much stronger case for multi-
vendor tools...

Alex Yourovski
Reply With Quote
  #24 (permalink)  
Old 06-25-2009, 12:03 PM
Martin Thompson
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question

Jonathan Bromley <[email protected]> writes:

> I completely agree. One of the side-effects of the
> survey I'm doing will probably be that I'll log requests
> for exactly this feature with all the synthesis vendors.
> I don't hold out much hope, though. Support welcomed ;-)


You have mine!

And thanks for sharing the results of your investigations with us all!

Cheers,
Martin

--
[email protected]
TRW Conekt - Consultancy in Engineering, Knowledge and Technology
http://www.conekt.net/electronics.html
Reply With Quote
  #25 (permalink)  
Old 06-25-2009, 12:55 PM
Nial Stewart
Guest
 
Posts: n/a
Default Re: True dual-port RAM in VHDL: XST question

> Originally coming from ASIC side I find this incredible but it seems
> that majority of people doing FPGA design don't simulate. I was at an
> FPGA infomercial the other day about two new device families coming
> out from a vendor to stay nameless and only %20 or so people raised
> their hands when asked this question. This might explain how these
> templates survived as is for such a long time.



Do you mean don't simulate the P&R'd design, or not at all?



Nial.


Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
I whant connected one port of dual port BRAM from NIOS. help.... axalay FPGA 1 08-05-2008 01:10 PM
True Dual Port RAM Colin Hankins FPGA 4 01-10-2008 10:20 PM
true dual port memory v/s simple dual port memory [email protected] FPGA 10 05-17-2005 09:40 AM
Xilinx: infering dual port ROM in VHDL sebastian FPGA 2 06-11-2004 02:09 PM
Dual-port and single-port BlockRAM instantiation arkaitz FPGA 5 12-09-2003 09:30 AM


All times are GMT +1. The time now is 02:08 AM.


Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0
Copyright 2008 @ FPGA Central. All rights reserved