Clock Edge notation

On Mon, 01 Dec 2008 20:52:06 -0600, Klaus Hahn <klaus.hahn@einheit.net>
wrote:

*On suorastaan mielenkintoista huomata muuten miten juuri SUPO:n
poliisivaltuuksia, nettivakoilua, puhelinsalaisuuksia ja urkintalupia yhän
....

Just a heads up: this is part of an ongoing attempt to disrupt the
Finnish language groups. While this post is ONLY to this group, anyone
replying without explicitly trimming followups would unwittingly add to
the pollution there...

So please ignore this and any similar post.

- Brian
 
Aurinkokunnassa planeettojen ratanopeus pienenee etäisyyden auringossa
kasvaessa, koska gravitaatio heikkenee vastaavasti auringosta.(Juuri kuten
aiemmin kerroin olevan tilanne myös atomien K, L, M-kuorikerroksien
ionisaatiotaulukossa, jonka tänne hetki sitten vastaanvänkääjien harmiksi
postasin. Eli totutusti minä olin myös tässä täysin oikeassa ja SUPO/TVO
insinööristöt totaalisen väärässä.. .Noin yllättyikö enää kukaan?) Galaksien
on todettu pyörivän kuin polkupyörän pinnat ja syyksi löytyy mystinen
galakseja ympäröivä ns. musta aine. Neutriinon löytynyt massa on osa tätä
ainetta. Myös sammuneet ruskeat tähdet, mutta nyt haetaan myös MACHOA
Massive Compact Halo Object. Jokia ympäröi mustana aineena galaksien
ulkopuolella.

Näkyvä mailmankaikkeus on 4%, 23% on pimeää ainetta ja loput 73% on nimetty
pimeäksi energiaksi. Sitten erittäin tärkeä tieto: 7miljardia vuotta
alkuräjähdyksestä on gravitaatio ja sen mm. vuokseilmiöiden kaltaiset
fossiilienergiahäviöt hidastaneet alkupaukun laajenemisenergian voimia.
Gravitaatio vetää myös ihan suoraan kappaleita takaisin yhteen. Nyt ei vaan
tiedetä riittääkä gravitaatiomassan voimavarat lopettamaan koko
fossiilienergialaajenemisen alkupaukusta. Maailmaan on todettu alkavan
vaikuttamaan pimeän enmergian kasvava vaikutus kiihdyttäen laajentumista.
Tämä selittyy sillä, että tyhjiöavaruuksissa ainetta muodostuu alati aineen
ja antiaineen pareja, jotka "lainaavat" energiaa gravitaatiopvärähelysäikein
ympäriltään näitä muodostaakseen.

(Kyseisessä ilmiössä ei ole toki mitään ihmeellistä vaan kyse on jo 60v
tunnetusta arkisesta Casimir-efektistä. Mutta koska kaava antaa fotoneille
massan, säteilyenergialle kyvyn varastoitua, siirtyä ja viiveellä purkautua
ja näin radioaktiivisuudelle sen pysyvyydet ja beetta-soihduille kyvyn
10-kertaistaa säteilytaustamme IAEA päätti kylmässä viisaudessaan kieltää
MYÖS tällaisten faktojen olemassaolot tuosta vaan! Fysiikka invalidisoitiin
aina koulutuspuutetta myöten ja nyt ei maailmassa juuri muut ymmärrä
fysiikkaa kuin näiden "kadotetun tusinakaavaston metsästäjät!")

Kirja jatkaa salatuista gravitatiolinkkiytyvistä Casimireistä peitellysti:
"Tämän pitäisi olla juuri sitä, mitä olemme etsimässä. Lisäksi: mitä
suuremmasta tyhjiöstä on kyse, sitä suurempi poistovoima näillä kyseisillä
virtuaalimuodostushiukkaspareilla. Oletamme siis tämän voiman kasvavan
maailmankaikkeuden laajetessa, juuri niinkuin olemme havainneet. Kosminen
vääristyminen satojentuhansien galaksien muodostumisessa ovat osoittaneet
massallisten fotonivalokimppujen vääristyneen massan vääristäminä. (Juuri
kuten Rytkönen oivasti esittää!) Ilmiö tynnetaan myös Einsteinin
valorenkaina esim. 4C 05.51 radiokohteessa. Galaksien on usein todettu
venyvän mm.kaariksi. Galaksit kallistuvat jne.

Nyt jotain lekaa niille SUPO harhatiedottajille mm. Evojeesuksille, joiden
mukaan nykyfysiikka osaa laskea 15 numeron tarkkuudella tapahtumiamme:"S.87
Itse asiassa laajentumisteorian tähtitieteellisten havaintojen ja teorioiden
mallin välillä oleva ero on luokkaa 10^120. Virhe on niin suuri, että
kyseessä täytyy olla suurin virhe teorian ja havaintojen välillä KOKO
tieteen historiassa!" .. .. ..!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

*Nyt ei voi kun vetää henkeä ja naureskella sille sulalle hulluudelle jota
IAEA:n "kadotetun fysiikkatusinan kaavakato maailmallemme aiheuttaa. Ja
tosiaan alkakaa nyt laajasti ymmärtää, että mm. Rytkösen, ja minun
kritiikini nykyfysiikkaharhasta perustuu JUURI tämänkaltaisiin asioihin!
Nimenomaan vaikka aihesta ei suin surmin halua ydinhallintomme räikeän
härskein painostuksin keskustella, niin Newtonilla, Malenkalla ja Einsteinin
pysyvien ja katoamattomien säteilyenergioittensa maailmassa jo oli fysiikka
miljoonasti paremmin hallussa kun nykyisessä IAEA:n invbalidisoimassa
fysiikkaharhautuksessa!
 
Jan Decaluwe wrote:

No, .next is only for signals. Other types of objects and
assignments are supported by the convertor, and (only) those
map to variables.
OK. I get it.

Now, neither Python nor MyHDL currently support your favorite
coding style of local interfaceless procedures. This is because
of Python's current scoping rules. Perhaps that explains some
of the confusion?
Yes.
Maybe that is why both a signal and a variable
are needed for an output assignment.

-- Mike Treseler
 
Thank you for the form and content of your answer.

As to content:
Although I may never have any need of vhdl, I think I just learned
something.

As to form:
Your answer demonstrates that questions on the border between naive and
"do my homework" can be answered politely.

Martin Thompson wrote:
"devil6600" <devil6600@gmail.com> writes:


can some one point me out the difference between the following three
assignments in vhdl:



Wrong group (you want comp.lang.vhdl - followup set), but I'm in a
helpful mood today... I'm not going to give you all the answers
though - is this a homework "assignment" :)


1) c <= a and b;
2) c = a and b;
3) c := a and b;


Two of them assign to different types of vhdl "things". One is not
legal - unless you remove the semicolon, in which case it is, but then
it's not an assigment.

Cheers,
Martin
 
Richard Owlett <rowlett@atlascomm.net> writes:

Thank you for the form and content of your answer.
Thanks for the thanks :)

As to content:
Although I may never have any need of vhdl, I think I just learned
something.
Excellent - I wonder if the OP got what they needed also...

As to form:
Your answer demonstrates that questions on the border between naive
and "do my homework" can be answered politely.
My first attempt was not worded in quite the same way, but
fortuantely, I had a pause before posting moment!

Cheers,
Martin

--
martin.j.thompson@trw.com
TRW Conekt - Consultancy in Engineering, Knowledge and Technology
http://www.conekt.net/electronics.html
 
hi, i am a new user to VHDL and trying to port a bio-informatics
application onto RCS card. could anybody help me regarding the
Application which is suitable for implementing onto RCS card,
configured with FPGA.

Thank you
 
Dave wrote:

If you simply don't assign the signal's value in those states where
the signal should remain unchanged, then the value will remain the
same until the next clock tick. The synthesizer will implement this by
making the clock enable for the signal's register '0' for those states
where the signal is not assigned. This is one of the nice things about
single-process state machines.
Yes.
Describing changes takes less text
than describing the full state and output.

It is unfortunate that asynchronous processes
and the default assignments they require,
are so well covered in vhdl instruction.

Some designers retain this verbose
style in all cases, out of habit.

-- Mike Treseler
 
On Jun 16, 12:22 pm, Mike Treseler <mtrese...@gmail.com> wrote:
Dave wrote:
If you simply don't assign the signal's value in those states where
the signal should remain unchanged, then the value will remain the
same until the next clock tick. The synthesizer will implement this by
making the clock enable for the signal's register '0' for those states
where the signal is not assigned. This is one of the nice things about
single-process state machines.

Yes.
Describing changes takes less text
than describing the full state and output.

It is unfortunate that asynchronous processes
and the default assignments they require,
are so well covered in vhdl instruction.

Some designers retain this verbose
style in all cases, out of habit.

        -- Mike Treseler
What's worse, most texts that promote dual processes also don't
promote the best way to avoid latches in the combinatorial processes:
default assignments right up front in the process. With those, you
have your choice of default signal behavior being unchanged, set or
reset for each signal. Most texts try to focus on an else for every
if, and complete assignment lists in every state, both of which are
much harder to write, read and update/maintain.

You still have all the default behavior choices with a single clocked
process, which is much better in the first place.

Andy
 
On Jun 16, 10:36 am, Andy <jonesa...@comcast.net> wrote:
On Jun 16, 12:22 pm, Mike Treseler <mtrese...@gmail.com> wrote:



Dave wrote:
If you simply don't assign the signal's value in those states where
the signal should remain unchanged, then the value will remain the
same until the next clock tick. The synthesizer will implement this by
making the clock enable for the signal's register '0' for those states
where the signal is not assigned. This is one of the nice things about
single-process state machines.

Yes.
Describing changes takes less text
than describing the full state and output.

It is unfortunate that asynchronous processes
and the default assignments they require,
are so well covered in vhdl instruction.

Some designers retain this verbose
style in all cases, out of habit.

        -- Mike Treseler

What's worse, most texts that promote dual processes also don't
promote the best way to avoid latches in the combinatorial processes:
default assignments right up front in the process. With those, you
have your choice of default signal behavior being unchanged, set or
reset for each signal. Most texts try to focus on an else for every
if, and complete assignment lists in every state, both of which are
much harder to write, read and update/maintain.

You still have all the default behavior choices with a single clocked
process, which is much better in the first place.

Andy
thanks for the help. I suspected the answer moments after I pressed
send. I used to be a two-process person but you guys convinced me
otherwise. I never was a three-process person.

Shannon
 
"Jonathan Bromley" <jonathan.bromley@MYCOMPANY.com> wrote in message
news:prs345lln7bmpp71hrk9p33ehfkq8231gj@4ax.com...
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.
 
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.bromley@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.
 
"Jonathan Bromley" <jonathan.bromley@MYCOMPANY.com> wrote in message
news:bn0445lbemmf3qnl87te1hps2l3nc9novv@4ax.com...
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.bromley@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.
 
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
jonathan.bromley@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.
 
"Jonathan Bromley" <jonathan.bromley@MYCOMPANY.com> wrote in message
news:e76445hlo55p6dki0oi764adcblv5oloul@4ax.com...
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.
 
"Jonathan Bromley" <jonathan.bromley@MYCOMPANY.com> wrote in message
news:e76445hlo55p6dki0oi764adcblv5oloul@4ax.com...
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!!
 
On Wed, 24 Jun 2009 15:45:37 +0100, "Fredxx" wrote:

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
jonathan.bromley@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.
 
Fredxx wrote:
"Jonathan Bromley" <jonathan.bromley@MYCOMPANY.com> wrote in message
news:e76445hlo55p6dki0oi764adcblv5oloul@4ax.com...
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.
 
"Jonathan Bromley" <jonathan.bromley@MYCOMPANY.com> wrote in message
news:akf4459nrqg50jo7q29e4h3sbf5uf4gcp4@4ax.com...
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.
 
rickman wrote:
On Jun 24, 10:45 am, "Fredxx" <fre...@spam.com> wrote:
"Jonathan Bromley" <jonathan.brom...@MYCOMPANY.com> wrote in message

news:e76445hlo55p6dki0oi764adcblv5oloul@4ax.com...



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.
 

Welcome to EDABoard.com

Sponsor

Back
Top