Goto page Previous 1, 2, 3
rickman
Guest
Sun Jan 23, 2011 12:02 am
On Jan 22, 12:03 pm, KJ <kkjenni...@sbcglobal.net> wrote:
Quote:
On Jan 22, 9:35 am, rickman <gnu...@gmail.com> wrote:
On Jan 21, 4:58 pm, KJ <kkjenni...@sbcglobal.net> wrote:
Consider using a function (for one output, or a procedure for multiple
outputs) instead. Then the only extra baggage is that of
instantianting the function/procedure call. The code you would've
written in the process simply moves to the function/procedure. If you
forget some input, the compiler complains.
KJ
Are you sure about that?
Yes...you will get an error message of the form shown below if you
don't connect something up
"No feasible entries for subprogram "xyz"
If you use a function/procedure in a process
and don't include one of the inputs to that function/procedure in the
sensitivity list, the compiler complains?
That's not what I was suggesting. What I was suggesting is to take a
process like this...
architecture rtl of foo is
signal a, b, c: std_logic;
begin
process(a, b: std_logic)
begin
c <= a or b;
end process;
end rtl;
and replace it with a function/procedure that is defined in the
architecture, and then call the function/procedure as a concurrent
statement. So the code above would then look like this...
architecture rtl of foo is
signal a, b, c: std_logic;
function my_func(a, b: std_logic) return std_logic is
begin
return(a or b);
end process;
begin
c <= my_func(a, b);
end rtl;
The only extra baggage compared to using the process is the extra
typing of "c <= my_func(a, b);". The rest of the code that was in the
process simply moves to the function/procedure with some minor edits
as shown. In exchange for the bit of extra typing, you get the full
benefit of using 'sequential VHDL statements' like 'if', 'case', etc.,
in a place where you need to implement logic that is not to be
clocked.
The benefit is that the equivalent of missing a signal in the
sensitivity list in the 'process' form will be missing an input to a
function in the 'function/process' form which will result in the
compiler flagging the error.
Use this method where others would use a process and you can ignore
all the chatter about sensitivity list maintenance.
Kevin Jennings
Ok, that's a different animal. I've used functions like this, but
only for simple functions with few ins and outs... well, one out to be
exact... :^) Paul was saying you can use procedures like this too,
I'm not aware of that.
I guess the downside of this is that it can get pretty messy to
describe a complex process as functions, which is pretty much what we
are talking about. If it doesn't have many inputs and if they are in
a single assignment, then you aren't likely to mess up the sensitivity
list.
I'm expecting this to apply to something like a state machine. That
would have lots of inputs and outputs. Mapping that to functions
would be a bit of a mess. I never realized that a procedure could be
used as a concurrent statement, or maybe I've just never done it and
forgot!
While looking this up just now I found that the Entity declaration can
contain statements including a "passive concurrent procedure call".
They don't define what "passive" means in this context. Also allowed
are "concurrent assertion statements" and "passive process
statements". That is pretty amazing and I'm not even sure exactly
what that means compared to the same statements in the architecture.
When would these statements be evaluated?
Anyone familiar with this?
Rick
KJ
Guest
Sun Jan 23, 2011 2:33 am
On Jan 22, 5:02 pm, rickman <gnu...@gmail.com> wrote:
Quote:
On Jan 22, 12:03 pm, KJ <kkjenni...@sbcglobal.net> wrote:
On Jan 22, 9:35 am, rickman <gnu...@gmail.com> wrote:
Use this method where others would use a process and you can ignore
all the chatter about sensitivity list maintenance.
Kevin Jennings
Ok, that's a different animal. I've used functions like this, but
only for simple functions with few ins and outs... well, one out to be
exact... :^) Paul was saying you can use procedures like this too,
I'm not aware of that.
In this case, functions are just a special case of procedures. If you
have more than one output signal to describe with a particular hunk of
code you have to use a procedure since you're unlimited on the number
of outputs. If you *happen* to have only one output signal to
generate you can choose to use either a procedure or a function. For
consistency, maybe you would want to always use procedures, that would
be your choice.
Quote:
I guess the downside of this is that it can get pretty messy to
describe a complex process as functions, which is pretty much what we
are talking about.
That's not correct. The code for the 'complex process' will look
nearly identical to the code for a function (if you have only one
output to generate) or a procedure (which you can use for one output
or several). If you think one looks messy, the other will look just
as messy.
Quote:
If it doesn't have many inputs and if they are in
a single assignment, then you aren't likely to mess up the sensitivity
list.
Your original post was complaining about the lack of wildcards on
sensitivity lists. Presumably that complaint was based on your use of
processes with many signal inputs not processes with only a few.
Quote:
I'm expecting this to apply to something like a state machine. That
would have lots of inputs and outputs. Mapping that to functions
would be a bit of a mess.
Maybe you're missing the point that you can only use a function *if*
your messy hunk of code just happens to only be generating one
output. Without any extra work you could use a procedure in that
case. The point is you have a choice in that one particular case.
You must use a procedure if your messy hunk of code generates more
than one output.
The syntax for when you call the procedure will look nearly the same
as when you instantiate an entity. If there are a number of I/O, then
the port map will be pretty long. For the particular case of a state
machine that you mention here, the far better approach is the clocked
process which avoids all of this discussion.
All that being said, I haven't happened to need to describe complex
code in an unclocked process so I haven't needed to worry much about
getting the sensitivity list correct. I do recognize the sensitivity
list as a potential design issue though so I avoid using it for the
most part to avoid getting bitten. The general approach is
- Processes are sensitive only to clock
- Concurrent statements picked up most everything else.
- Occasionally, I'll use an unclocked process if there are very few
inputs (like < 4).
- On the rare occasions where none of the above were suitable, I would
use a function or a procedure as described above.
Quote:
I never realized that a procedure could be
used as a concurrent statement, or maybe I've just never done it and
forgot!
Now you've acquired two approaches to solving your original complaint.
- Use the VHDL-2008 syntax with a tool that supports the updated
syntax
- Use a procedure (in some cases a function if you choose)
Quote:
While looking this up just now I found that the Entity declaration can
contain statements including a "passive concurrent procedure call".
They don't define what "passive" means in this context. Also allowed
are "concurrent assertion statements" and "passive process
statements". That is pretty amazing and I'm not even sure exactly
what that means compared to the same statements in the architecture.
When would these statements be evaluated?
Anyone familiar with this?
Practically speaking, I haven't found it to mean much compared to
putting the same code in the architecture. The syntax for the
assertion in an entity is
entity foo is port(
...);
begin
assert ... report "OOPS!" severity ERROR;
end foo;
So you could put assertions to check that related items in the entity
have the proper relationship. However, you won't get any feedback
from the compiler that you've connected anything incorrectly since
that check won't come until you start the simulator. When you do
start sim though the assertion will fire but that is the same time
that the same assertion would be checked if it had been put into the
architecture.
If for some reason you wanted to keep the architecture code secret but
allow access to the entity then you may be motivated to put the
assertions in the entity so the user would have the information they
need to connect things properly. I haven't had such a need, maybe
others have.
Lastly, brand 'S' synthesis tool didn't used to support assertions in
the entity at all. I reported the bug and I think it has been fixed.
I tend to use brand 'A' tools now though and don't use brand 'S'
anymore, in part due to the number of bugs I reported, the length of
time it took to fix them and the obscure error message that made it
next to impossible to figure out what the work around is while they
work the problem. Brand 'A' supports (or at least doesn't choke on)
assertions in the entity, I haven't tried with brand 'X'.
Kevin Jennings
Mike Treseler
Guest
Sun Jan 23, 2011 6:23 pm
On 1/22/2011 2:02 PM, rickman wrote:
Quote:
Ok, that's a different animal. I've used functions like this, but
only for simple functions with few ins and outs... well, one out to be
exact... :^)
I can use more than one.
Quote:
Paul was saying you can use procedures like this too,
A function returns a value.
A procedure returns a block of code.
A concurrent procedure returns a process.
Quote:
I guess the downside of this is that it can get pretty messy to
describe a complex process as functions, which is pretty much what we
are talking about.
I disagree. A function is a clean way
to hide an asynchronous process and
the wires and sensitivity that go with it.
Quote:
I never realized that a procedure could be
used as a concurrent statement, or maybe I've just never done it and
forgot!
It would be hard for me to forget that experience.
I prefer using an direct instance in this case.
-- Mike Treseler
rickman
Guest
Sun Jan 23, 2011 9:11 pm
On Jan 23, 12:23 pm, Mike Treseler <mtrese...@gmail.com> wrote:
Quote:
On 1/22/2011 2:02 PM, rickman wrote:
Ok, that's a different animal. I've used functions like this, but
only for simple functions with few ins and outs... well, one out to be
exact... :^)
I can use more than one.
If you replace a process that assigns multiple signals with multiple
functions, you are likely going to duplicate a lot of code. It is
very likely that because you would use a process to begin with, the
signals were not easy to describe with concurrent assignments anyway,
so functions would likely be using IFs and CASEs. If the signal
assignments partitioned very cleanly, then yes, functions could be
ok. But it is very likely that much of the IF and CASE structure
would need to be duplicated.
Of course, procedures are a different matter. Then the entire process
can be shoved into the procedure if you wanted. Personally, I prefer
not to do this mainly because it separates relevant code so that I
can't see it together in one screen. Or can you define procedures
anywhere you wish in the concurrent code? I believe they have to be
at the head of the architecture in the definitions.
Quote:
Paul was saying you can use procedures like this too,
A function returns a value.
A procedure returns a block of code.
A concurrent procedure returns a process.
That was the part I wasn't aware of. Not that I am likely to use a
concurrent procedure. But it is something to keep in mind. I mostly
use subprograms when there is a likelihood of reuse. But I am aware
that it can help with design partitioning and decision hiding.
Too bad I am working on learning Verilog. Simpler tools for simpler
minds perhaps. :^)
Quote:
I guess the downside of this is that it can get pretty messy to
describe a complex process as functions, which is pretty much what we
are talking about.
I disagree. A function is a clean way
to hide an asynchronous process and
the wires and sensitivity that go with it.
Whaaa..? What wires does it hide that doesn't happen in a process?
Rick
Jan Decaluwe
Guest
Sun Jan 23, 2011 9:22 pm
rickman wrote:
Quote:
On Jan 23, 12:23 pm, Mike Treseler <mtrese...@gmail.com> wrote:
I guess the downside of this is that it can get pretty messy to
describe a complex process as functions, which is pretty much what we
are talking about.
I disagree. A function is a clean way
to hide an asynchronous process and
the wires and sensitivity that go with it.
Whaaa..? What wires does it hide that doesn't happen in a process?
A function that works on intermediate/temporary variables
within a clocked process can create combinatorial logic
without requiring sensitivity specifications.
Big news?
--
Jan Decaluwe - Resources bvba -
http://www.jandecaluwe.com
Python as a HDL:
http://www.myhdl.org
VHDL development, the modern way:
http://www.sigasi.com
Analog design automation:
http://www.mephisto-da.com
World-class digital design:
http://www.easics.com
Paul Uiterlinden
Guest
Sun Jan 23, 2011 10:41 pm
Mike Treseler wrote:
Quote:
On 1/22/2011 2:02 PM, rickman wrote:
Ok, that's a different animal. I've used functions like this, but
only for simple functions with few ins and outs... well, one out to be
exact... :^)
I can use more than one.
Paul was saying you can use procedures like this too,
A function returns a value.
A procedure returns a block of code.
A concurrent procedure returns a process.
In my opinion this tends to unneeded mystification. A procedure does not
return anything. The only thing that happens are the assignments via the
OUT an INOUT mode parameters.
Every concurrent procedure call has its equivalent process description.
So in my example:
my_proc_i: my_proc(sig1, sig2, sig3, sig4, sig5);
where the third to fifth formal parameter are of mode IN, the equivalent
process description would be:
my_proc_i: PROCESS IS
BEGIN
my_proc(sig1, sig2, sig3, sig4, sig5);
WAIT ON sig3, sig4, sig5;
END PROCESS my_proc_i;
No more, no less.
It also shows that any local varaible declared in in the procedure will not
hold its value over time. Each time one or more signals changes (has an
event), the procedure is called and the local variable are initialized
again.
Quote:
I never realized that a procedure could be
used as a concurrent statement, or maybe I've just never done it and
forgot!
It would be hard for me to forget that experience.
I prefer using an direct instance in this case.
I use concurrent procedure calls in behavioral code.
Another trick I use then is to make an endless loop in the body of the
procedure. That way the local variables of the procedure hold their values
over time. That is because the procedure is never left: it does not contain
a RETURN statement, nor does it ever reach the end. Of course, the
procedure will contain a WAIT statement in the endless loop.
All this of course is highly non-synthesisable! But I guess the simple
concurrent procedure call is synthesisable. Never tried it though: I hardly
ever write synthesisable code. Synthesizers are sooo limiting.... ;-)
--
Paul Uiterlinden
www.aimvalley.nl
e-mail addres: remove the not.
Paul Uiterlinden
Guest
Sun Jan 23, 2011 10:55 pm
rickman wrote:
Quote:
While looking this up just now I found that the Entity declaration can
contain statements including a "passive concurrent procedure call".
They don't define what "passive" means in this context.
From the LRM (Language Reference Manual):
A process statement is said to be a passive process if neither the process
itself, nor any procedure of which the process is a parent, contains a
signal assignment statement. It is an error if a process or a concurrent
statement, other than a passive process or a concurrent statement
equivalent to such a process, appears in the entity statement part of an
entity declaration.
--
Paul Uiterlinden
www.aimvalley.nl
e-mail addres: remove the not.
Mike Treseler
Guest
Sun Jan 23, 2011 11:17 pm
Quote:
Mike Treseler wrote:
A function returns a value.
A procedure returns a block of code.
A concurrent procedure returns a process.
On 1/23/2011 1:41 PM, Paul Uiterlinden wrote:
Quote:
In my opinion this tends to unneeded mystification.
A procedure does not return anything.
Yes, that is a simplification,
but I could elaborate a procedure call in my editor
by pasting the procedure, and replacing the formal parameters.
That's my mental picture.
Quote:
The only thing that happens are the assignments via the
OUT an INOUT mode parameters.
The structural view is also valid.
I often use process variables in scope, so I don't see the wires.
....
Quote:
It also shows that any local variable declared in in the procedure will not
hold its value over time.
But process variables do, and synthesis will make
the gates or flops as needed.
-- Mike Treseler
Paul Uiterlinden
Guest
Sun Jan 23, 2011 11:36 pm
Mike Treseler wrote:
Quote:
The only thing that happens are the assignments via the
OUT an INOUT mode parameters.
The structural view is also valid.
I often use process variables in scope, so I don't see the wires.
You mean that you use the process variables within the procedure body
without passing them as procedure arguments, right?
Quote:
It also shows that any local variable declared in in the procedure will
not hold its value over time.
But process variables do, and synthesis will make
the gates or flops as needed.
Indeed they do. I merely wanted to make clear that local variables in
procedures don't, even if the procedure is used with a concurrent procedure
call.
--
Paul Uiterlinden
www.aimvalley.nl
e-mail addres: remove the not.
KJ
Guest
Mon Jan 24, 2011 3:31 am
On Jan 23, 2:11 pm, rickman <gnu...@gmail.com> wrote:
Quote:
Personally, I prefer
not to do this mainly because it separates relevant code so that I
can't see it together in one screen. Or can you define procedures
anywhere you wish in the concurrent code? I believe they have to be
at the head of the architecture in the definitions.
Not necessarily. With a few more keystrokes you can make the
procedure right where you want it in the code using a block
statement. The 'block' is essentially the same as an architecture in
structure allowing you to define functions, procedure, signals, etc.
Not much extra typing to get this, and can be worth it in terms of
keeping the code readable without having to jump around.
Example:
my_block: block
-- Define your procedures and functions here
-- You can also define 'local' signals here that are
-- not visible outside of the block.
begin
-- Put your code here that uses the procedure
end block my_block;
rickman
Guest
Mon Jan 24, 2011 7:23 am
On Jan 23, 3:22 pm, Jan Decaluwe <j...@jandecaluwe.com> wrote:
Quote:
rickman wrote:
On Jan 23, 12:23 pm, Mike Treseler <mtrese...@gmail.com> wrote:
I guess the downside of this is that it can get pretty messy to
describe a complex process as functions, which is pretty much what we
are talking about.
I disagree. A function is a clean way
to hide an asynchronous process and
the wires and sensitivity that go with it.
Whaaa..? What wires does it hide that doesn't happen in a process?
A function that works on intermediate/temporary variables
within a clocked process can create combinatorial logic
without requiring sensitivity specifications.
Big news?
And how exactly is that different from a process??? Sounds to me like
no news at all.
Rick
Jan Decaluwe
Guest
Mon Jan 24, 2011 9:31 am
rickman wrote:
Quote:
On Jan 23, 3:22 pm, Jan Decaluwe <j...@jandecaluwe.com> wrote:
rickman wrote:
On Jan 23, 12:23 pm, Mike Treseler <mtrese...@gmail.com> wrote:
I guess the downside of this is that it can get pretty messy to
describe a complex process as functions, which is pretty much what we
are talking about.
I disagree. A function is a clean way
to hide an asynchronous process and
the wires and sensitivity that go with it.
Whaaa..? What wires does it hide that doesn't happen in a process?
A function that works on intermediate/temporary variables
within a clocked process can create combinatorial logic
without requiring sensitivity specifications.
Big news?
And how exactly is that different from a process???
Again, because functions don't have sensitivity lists of course!
Still, they are guaranteed to have combinatorial semantics as
they can't have side effects in VHDL.
Jan
--
Jan Decaluwe - Resources bvba -
http://www.jandecaluwe.com
Python as a HDL:
http://www.myhdl.org
VHDL development, the modern way:
http://www.sigasi.com
Analog design automation:
http://www.mephisto-da.com
World-class digital design:
http://www.easics.com
backhus
Guest
Mon Jan 24, 2011 10:41 am
On 21 Jan., 22:28, Jonathan Bromley <s...@oxfordbromley.plus.com>
wrote:
Quote:
On Thu, 20 Jan 2011 23:37:50 -0800 (PST), backhus wrote:
if you want to implement the all keyword in your favorite synthesis
tool, you can do it like this:
signal all : std_logic ;
Now you can use
process(all)
in your non-VHDL2008 synthesis tool, and it won't throw errors.
I fear not. 'all' is already a reserved word in every
version of the VHDL standard that I know of. (Think of
"use ieee.std_logic_1164.all;")
Cute idea, though.
--
Jonathan Bromley
Hi Jonathan,
*$%&! You're right, of course.
My only excuse is that the library stuff is handled by templates in
99.9% of my sources.
Sorry everybody for causing confusion.
Regards
Eilert
rickman
Guest
Mon Jan 24, 2011 4:47 pm
On Jan 24, 3:31 am, Jan Decaluwe <j...@jandecaluwe.com> wrote:
Quote:
rickman wrote:
On Jan 23, 3:22 pm, Jan Decaluwe <j...@jandecaluwe.com> wrote:
rickman wrote:
On Jan 23, 12:23 pm, Mike Treseler <mtrese...@gmail.com> wrote:
I guess the downside of this is that it can get pretty messy to
describe a complex process as functions, which is pretty much what we
are talking about.
I disagree. A function is a clean way
to hide an asynchronous process and
the wires and sensitivity that go with it.
Whaaa..? What wires does it hide that doesn't happen in a process?
A function that works on intermediate/temporary variables
within a clocked process can create combinatorial logic
without requiring sensitivity specifications.
Big news?
And how exactly is that different from a process???
Again, because functions don't have sensitivity lists of course!
Still, they are guaranteed to have combinatorial semantics as
they can't have side effects in VHDL.
So in regards to hiding the "wires", they are not different at all...
Rick
Mike Treseler
Guest
Mon Jan 24, 2011 11:04 pm
On 1/24/2011 6:47 AM, rickman wrote:
Quote:
On Jan 24, 3:31 am, Jan Decaluwe<j...@jandecaluwe.com> wrote:
rickman wrote:
On Jan 23, 3:22 pm, Jan Decaluwe<j...@jandecaluwe.com> wrote:
rickman wrote:
On Jan 23, 12:23 pm, Mike Treseler<mtrese...@gmail.com> wrote:
I guess the downside of this is that it can get pretty messy to
describe a complex process as functions, which is pretty much what we
are talking about.
I disagree. A function is a clean way
to hide an asynchronous process and
the wires and sensitivity that go with it.
Whaaa..? What wires does it hide that doesn't happen in a process?
A function that works on intermediate/temporary variables
within a clocked process can create combinatorial logic
without requiring sensitivity specifications.
Big news?
And how exactly is that different from a process???
Again, because functions don't have sensitivity lists of course!
Still, they are guaranteed to have combinatorial semantics as
they can't have side effects in VHDL.
So in regards to hiding the "wires", they are not different at all...
This thread is about the vhdl process sensitivity list and how to avoid
simulation problems if I use it for anything other than the clock
or reset inputs. This question has been answered.
The "wires" issue is a red herring.
http://en.wikipedia.org/wiki/Red_herring
By "wire hiding" I mean that by using a single process
description using variables, there are only port inputs
and outputs in the logic description.
Everything goes in one box -- the entity.
There are no internal "directions" to worry about,
other than code going from the top to the bottom of the page.
In a multi-process description,
I have two or more process boxes inside the entity,
each with inputs and outputs.
I claim that not having to worry about connecting internal
"outputs" together in my description is a side benefit *for me*
of this description style.
-- Mike Treseler
Goto page Previous 1, 2, 3