Re: True dual-port RAM in VHDL: XST question

Discussion in 'VHDL' started by Fredxx, Jun 24, 2009.

  1. Fredxx

    Fredxx Guest

    "Jonathan Bromley" <> wrote in message
    news:p...
    > 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.
     
    Fredxx, Jun 24, 2009
    #1
    1. Advertising

  2. Fredxx

    Fredxx Guest

    "Jonathan Bromley" <> wrote in message
    news:...
    > 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
    >
    > 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.
     
    Fredxx, Jun 24, 2009
    #2
    1. Advertising

  3. Fredxx

    Fredxx Guest

    "Jonathan Bromley" <> wrote in message
    news:...
    > 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.
     
    Fredxx, Jun 24, 2009
    #3
  4. Fredxx

    rickman Guest

    On Jun 24, 7:44 am, "Fredxx" <> wrote:
    > "Jonathan Bromley" <> wrote in message
    >
    > news:...
    >
    >
    >
    > > 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
    > >
    > >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
     
    rickman, Jun 24, 2009
    #4
  5. Fredxx

    Fredxx Guest

    "Jonathan Bromley" <> wrote in message
    news:...
    > 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!!
     
    Fredxx, Jun 24, 2009
    #5
  6. Fredxx

    rickman Guest

    On Jun 24, 10:45 am, "Fredxx" <> wrote:
    > "Jonathan Bromley" <> wrote in message
    >
    > news:...
    >
    >
    >
    > > 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.

    Rick
     
    rickman, Jun 24, 2009
    #6
  7. Fredxx wrote:
    > "Jonathan Bromley" <> wrote in message
    > news:...
    >> 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.
     
    Ed McGettigan, Jun 24, 2009
    #7
  8. Fredxx

    Fredxx Guest

    "Jonathan Bromley" <> wrote in message
    news:...
    > 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.
     
    Fredxx, Jun 24, 2009
    #8
  9. Fredxx

    Fredxx Guest

    rickman wrote:
    > On Jun 24, 10:45 am, "Fredxx" <> wrote:
    >> "Jonathan Bromley" <> wrote in message
    >>
    >> news:...
    >>
    >>
    >>
    >>> 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.
     
    Fredxx, Jun 24, 2009
    #9
  10. Fredxx

    Sandro Guest

    On Jun 24, 2:23 pm, Jonathan Bromley <>
    > ...
    > 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
     
    Sandro, Jun 24, 2009
    #10
  11. Fredxx

    Muzaffer Kal Guest

    On Wed, 24 Jun 2009 16:27:30 +0100, "Fredxx" <> 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
     
    Muzaffer Kal, Jun 24, 2009
    #11
  12. Fredxx

    Andy Guest

    On Jun 24, 6:15 am, Jonathan Bromley <>
    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
     
    Andy, Jun 24, 2009
    #12
  13. Fredxx

    Muzaffer Kal Guest

    On Wed, 24 Jun 2009 18:57:29 +0100, 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.


    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
     
    Muzaffer Kal, Jun 24, 2009
    #13
  14. 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
     
    Mike Treseler, Jun 24, 2009
    #14
  15. Fredxx

    Andy Peters Guest

    On Jun 24, 10:57 am, 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.


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

    -a
     
    Andy Peters, Jun 24, 2009
    #15
  16. Fredxx

    Alex Guest

    On Jun 24, 10:57 am, Jonathan Bromley <>
    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
    > ://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
     
    Alex, Jun 25, 2009
    #16
  17. Jonathan Bromley <> 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

    --

    TRW Conekt - Consultancy in Engineering, Knowledge and Technology
    http://www.conekt.net/electronics.html
     
    Martin Thompson, Jun 25, 2009
    #17
  18. Fredxx

    Nial Stewart Guest

    > 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.
     
    Nial Stewart, Jun 25, 2009
    #18
  19. Fredxx

    sleeman Guest

    On Jun 25, 6:55 am, "Nial Stewart"
    <nial*> wrote:
    > > 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.


    This thread has brought up several very interesting themes. I'd like
    to add my two cents to each.

    1) Synthesis templates for RAMS. I think what Jonathan is doing is a
    great idea. I'd love to see a better definition of what cross-device
    code patterns are safe to use and supported by which tools. From
    experience, I can say that I've done it right for a few key designs,
    and managed to leverage off of that by wrapping this inference in an
    entity, giving me a device-independent (more-or-less) codebase but
    still requiring structural coding around the RAM. It's not ideal by a
    long shot. But by enforcing good version control discipline through
    the organization and introducing a mindset that says "don't fiddle
    around with a perfectly good library module, use it as-is or not at
    all", we have managed to reduce the number of times designers sit
    there, asking the same questions: "I only changed one line of code;
    why did it start making distributed RAM? What were those attributes
    again? When I don't use the read port how do I stop the synthesizer
    from complaining?" and so on and so on.

    2) Clocks versus asynchronous logic. My view of this is that clocks
    are both an obvious physical thing (as anyone who flies a scope for
    living well knows) as well as an abstraction. This abstraction is
    what constitutes the "contract", or point of demarcation between high-
    level circuit digital designer, and the guy who actually codes the
    gate-level RAM and control logic. The job of the low-level transistor
    guy is to provide a circuit that acts as if the clock abstraction is a
    true representation of what actually happens inside. He may use flops,
    latches, vernier timing thingies, or whatever the heck he needs. But
    he *must* obey the clock-concept contract. The job of the high-level
    (FPGA application developer) is to make use of the clock concept
    abstraction in order to make his design synchronous, which implies
    robustness, maintainability, and all the other virtues that regular
    posters here know so well.

    3) People who don't do simulation? Definitely. I've help manage the
    change in an organization growing from a couple of FPGA guys to a
    fairly well-oiled FPGA talent pool with established version control,
    substantial as-is module re-use, and an ingrained mindset that a
    modules doesn't get released without a scripted, regressionable
    testbench. They're two points at opposite ends of a continuum of
    process, but I see a lot of real work in industry done at both ends.

    The "garage shop" FPGA approach typically has some guys who learned
    VHDL in school, then got thrown into the deep end alone, or who "came
    up through the ranks" from CPLDs and board design. No VC, no software
    techniques, no libraries, packages, functions or elegant code in the
    source. Hack job, in short. Two of these guys working on the same
    project may often be running different tool versions, and not even be
    able to load the design as-is from the other guy's sources, without a
    lot of manual GUI fiddling to reset paths, manually link in the right
    libraries, and so on. There's little chance of even building the same
    design twice in a row. These are the guys who throw their bitfile onto
    the board, and if it doesn't work, start writing some testbenches
    (aww, do I *have* to do that... what a pain). They don't want to
    simulate because its too hard/too long to sim the whole chip, and
    because there's poor structure and/or modularity in their own code to
    begin with, so it's also too hard to isolate a portion and make a
    simple test for it, too.

    The "pro" is at the other end of the continuum. Most of the regular
    posters here try to answer the "garage guys" with answers that will
    point them in the direction of becoming a "pro". It's a lot more
    work, but there's a lot of benefit to being able to release a chip
    that you know that anyone on your team can build again, bit/UCF/source-
    accurately, when you're on vacation.

    Of course, some "pros" work in garage shops. But the Big Tool (Big
    Two?) vendors tend to cater most of their tools to the garage shop
    guys. Everything can be set by clicking on a GUI button. Everything
    about a project is stored in unreadable binary files. They try to
    force you into their half-assed version control scheme, if they offer
    one at all. How are you ever going to share designs or document them
    for the future that way? And all of the "sex appeal" about the new
    devices is put into the GUI, the new buttons that you can click on,
    and the new auto-wizards (that don't usually have a mode to generate
    output from anything other than unreliable, unrepeatable user mouse
    clicks). ( I tend to think of this emphasis on sexy GUI tools leading
    then to bad project practices as being akin to drug dealers pushing
    crack in the schoolyards, but that would get me in trouble with my
    local FAEs so I'll refrain :)

    Don't get me wrong... I had a lot of fun as a garage guy myself. I
    built some pretty damn fine hardware "back in the day" before I even
    had the option of simulating my code. But I agree, there are still a
    lot of guys who view testbenches and simulation as something painful
    and only to be done if really necessary. In truth, it's like pretty
    much everything else in life: you get out more when you put in more
    work.

    OK, I'm done ranting now :)

    - Kenn
     
    sleeman, Jun 25, 2009
    #19
  20. Fredxx

    rickman Guest

    On Jun 24, 2:11 pm, Muzaffer Kal <> wrote:
    > On Wed, 24 Jun 2009 18:57:29 +0100, 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.

    >
    > 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.


    I missed something. What question exactly?

    Rick
     
    rickman, Jun 25, 2009
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. john

    FPGA and Dual Port RAM

    john, Nov 3, 2004, in forum: VHDL
    Replies:
    2
    Views:
    3,664
  2. john

    Dual port RAM

    john, Nov 4, 2004, in forum: VHDL
    Replies:
    1
    Views:
    810
    mike_treseler
    Nov 4, 2004
  3. dwerdna

    Dual port Ram - for beginners

    dwerdna, Apr 3, 2005, in forum: VHDL
    Replies:
    7
    Views:
    23,617
    dwerdna
    Apr 8, 2005
  4. Keith Blankenship

    Dual-Port RAM Simulation in ModelSim

    Keith Blankenship, Jan 4, 2006, in forum: VHDL
    Replies:
    1
    Views:
    1,200
    Mike Treseler
    Jan 4, 2006
  5. bdb112
    Replies:
    45
    Views:
    1,399
    jazbees
    Apr 29, 2009
Loading...

Share This Page