I'd rather switch than fight!

Brian Drummond wrote:

Where there are combinatorial outputs to be described, I agree, I'll
describe them outside the main process.

But I can't remember the last time I had one so complex it needed a
process of its own.
In my code, multiplexers (e.g. a number of registers driving the same bus)
end up as process of their own. It is possible to get around that by using
a wire array, though, so

always @*
begin
bus_data = 0;
if(bus_enable)
case(bus_addr)
0: bus_data = xxx;
1: bus_data = yyy;
....
15: bus_data = zzz;
esac
end

converts to

wire [x:0] bus_data_array [0:15];

assign bus_data_array[0] = xxx;
assign bus_data_array[1] = yyy;
....
assign bus_data_array[15] = zzz;

assign bus_data = bus_enable ? bus_data_array[bus_addr] : 0;

but this has a severe simulation disadvantage (the simulator has to
recalculate all bus_data_array elements when the dependencies change, even
when the bus is not used at all).

--
Bernd Paysan
"If you want it done right, you have to do it yourself!"
http://www.jwdt.com/~paysan/
 
On Apr 28, 5:56 am, Brian Drummond <brian_drumm...@btconnect.com>
wrote:
then you must surely allow similar expressions with other enumerations,
for instance:
---------------------------------
Type NTSC_Color is (red, green, blue);  
Signal Channel_Color : NTSC_Color;
Signal Channel_Gain  : real;

Channel_Gain <= Channel_Color ? 0.11 : 0.55 : 0.34;  
-- nice and compact, but descending order to remain compatible with Boolean
---------------------------------

Now I believe that ascending order, like every other positional list in the
language (port lists, argument lists, etc), would be less surprising:

Channel_Gain <= Channel_Color ? 0.34 : 0.55 : 0.11;  
The problem with this approach is that the action depends not only on
the enumerated values defined in the type, but also on their order of
definition. Especially when the type is often defined in a package,
not immediately visible to the user/reviewer, I would much prefer a
more explicit (yes, verbose!) coding of what action is desired. Using
an array indexed by the enumerated type, or using the aforementioned
function, we can do this already, without the conditional operator
(I'm probably in the minority, but this was not a wise addition to the
language in 2008).

By adding such ambiguous shortcut features to the language, we are
only deterring the use of a universally accepted solution to code
complexity: subprograms (functions and/or procedures).

Consistently inconsistent here too...

BTW, WRT combinatorial outputs of clocked processes, many synthesis
tools now support the following:

process (clk, rst) is
variable myvar : ...
begin
if rst then
myvar := ...
elsif rising_edge(clk) then
myvar := myfunc(inputs);
end if;
combout <= outfunc(myvar);
end process;

Combout is then the combinatorial output of outfunc() applied to the
output of the register inferred by the access to myvar.

This gives us the ability to describe combinatorial output logic
without the simulation penalty, latches, and signal overhead
associated with a separate combinatorial process, implied or explicit.

Andy
 
On Wed, 28 Apr 2010 07:02:00 -0700 (PDT), Andy <jonesandy@comcast.net> wrote:

On Apr 28, 5:56 am, Brian Drummond <brian_drumm...@btconnect.com
wrote:

Channel_Gain <= Channel_Color ? 0.11 : 0.55 : 0.34;  
-- nice and compact, but descending order to remain compatible with Boolean
---------------------------------

Now I believe that ascending order, like every other positional list in the
language (port lists, argument lists, etc), would be less surprising:

Channel_Gain <= Channel_Color ? 0.34 : 0.55 : 0.11;  

The problem with this approach is that the action depends not only on
the enumerated values defined in the type, but also on their order of
definition. Especially when the type is often defined in a package,
not immediately visible to the user/reviewer, I would much prefer a
more explicit (yes, verbose!) coding of what action is desired.
I agree; that's why I also suggested an associative version (snipped here)
which I would prefer in practice. But that might not be a selling point to those
who think VHDL too verbose!

By adding such ambiguous shortcut features to the language, we are
only deterring the use of a universally accepted solution to code
complexity: subprograms (functions and/or procedures).
Exactly.

Consistently inconsistent here too...

BTW, WRT combinatorial outputs of clocked processes, many synthesis
tools now support the following:

process (clk, rst) is
variable myvar : ...
begin
if rst then
myvar := ...
elsif rising_edge(clk) then
myvar := myfunc(inputs);
end if;
combout <= outfunc(myvar);
end process;

Combout is then the combinatorial output of outfunc() applied to the
output of the register inferred by the access to myvar.
Neat. And with variables for parameters, it probably doesn't suffer from XST's
longstanding bug passing signals as parameters to procedures.

- Brian.
 
On Wed, 28 Apr 2010 14:29:47 +0200, Bernd Paysan <bernd.paysan@gmx.de> wrote:

Brian Drummond wrote:

Where there are combinatorial outputs to be described, I agree, I'll
describe them outside the main process.

But I can't remember the last time I had one so complex it needed a
process of its own.

In my code, multiplexers (e.g. a number of registers driving the same bus)
end up as process of their own.
I *think* I see why you do that, but I can't see the need for the array, just
one intermediate signal.

Then your process becomes (assuming suitable declarations)
-------------------------------------------------------------------
with bus_addr select bus_data_internal <=
xxx when 0,
yyy when 1,
...
zzz when others;

bus_data <= bus_data_internal when bus_enable else 0;
-------------------------------------------------------------------

- Brian
 
That is one long reply...

On Apr 28, 6:56 am, Brian Drummond <brian_drumm...@btconnect.com>
wrote:
On Tue, 27 Apr 2010 15:56:57 -0700 (PDT), rickman <gnu...@gmail.com> wrote:
On Apr 27, 6:05 am, Brian Drummond <brian_drumm...@btconnect.com
wrote:
I don't agree that the two process model is inherently less
desirable. Or maybe I should say that I don't think describing
combinatorial logic outside of clocked processes is inherently less
desirable.

Where there are combinatorial outputs to be described, I agree, I'll describe
them outside the main process.
No, I am talking about logic that drives the registers. For example,
I have a PLL circuit which has a few registers, but several adders and
a few shift operations (mult/div). I give each a separate concurrent
statement to facilitate debugging. I could put it all inside the
register process, but I can do things with signals I can't do with
variables, such as bring them to the outside world. By giving each
one a separate concurrent assignment it is very easy to monitor and
debug each one individually. Yeah, it may look more verbose, but I
just don't see that as a problem.

The control signals for the registers get evaluated in concurrent
logic. I could add more conditionals (ifs) to the clocked process to
incorporate the full expression as the enable on the register, but by
keeping it external, it is more clear what the evaluation is doing and
again, I have a separate signal I can more easily debug it in the
simulator and in the chip.

Maybe this is a reflection of how we think differently for both design
and debug. I am an old school hardware designer and I think in terms
of registers and logic blocks. So my design reflects that I guess.


But I can't remember the last time I had one so complex it needed a process of
its own.

I seldom put a lot of combinatorial logic in processes,
clocked or unclocked, mainly because the structures in processes and
combinatorial logic are rather weighty (a synonym for verbose I
guess). But it always depends on the logic. Lacking the conditional
expression, VHDL concurrent logic can be a PITB to write complex
expressions in a clear manner. This means sometimes I put
combinatorial in unclocked processes because it is more clear. Simple
logic goes in with the clocked process, but when possible, I put
combinatorial logic in concurrent statements.

I think you are referring to the ?: conditional operator inherited from C?
Yes, Verilog and C I believe.


I just use VHDL's conditional signal assignments for that purpose. As it's
purely combinational, I have never found the need for an equivalent that I can
use inside a process.
Heck, that is very limited. You can't even use in inside of a
separate signal assignment. Try combining the conditional signal
assignment with anything else. I would like to be able to use it
inside the conditional for an if (sometimes) or combine it is ways
that allows the assignment to more directly state the logic of the
problem rather than my having to convert the logic to suit the flow of
the structure.


I eventually figured out what I heartily detest about that (?:) - it's the ONE
construct across all the languages I've encountered that expects the list of
choices in descending order.

(And does so implicitly as opposed to explicitly, with a "downto" or "step -1"
or "when true else..." or some visible indication that it's doing something
quaint)

If VHDL is to adopt a conditional operator I hope it can do better than that!
Something less surprising, and generalisable to other discrete types or at least
other enums.

If you are going to allow
---------------------------------
Signal Flag : Boolean := True;
Signal Int_val : Integer;

Int_val <= Flag?1:0;
---------------------------------
then you must surely allow similar expressions with other enumerations,
for instance:
---------------------------------
Type NTSC_Color is (red, green, blue);
Signal Channel_Color : NTSC_Color;
Signal Channel_Gain : real;

Channel_Gain <= Channel_Color ? 0.11 : 0.55 : 0.34;
-- nice and compact, but descending order to remain compatible with Boolean
---------------------------------
I think this is a rather trivial example. Why not use the selected
signal assignment? It may be more verbose, but it *is* explicit. The
mnemonic for a boolean conditional operator is pretty simple, it is
the same as an IF statement. But to extrapolate that to descending
order for other data types is a bit of a reach. I guess this makes
some sense for an enumerated type, but where else could you use the
conditional operator? An integer range type would be a possible use,
but potentially difficult to use effectively, or maybe I should say,
seldom useful. I think the utility of the conditional operator is
that it can be used in many places and allows a better expression of
the logic (closer to the problem) as well as more compact.


Now I believe that ascending order, like every other positional list in the
language (port lists, argument lists, etc), would be less surprising:

Channel_Gain <= Channel_Color ? 0.34 : 0.55 : 0.11;

There would of course be an associative form of the expression
Channel_Gain <= Channel_Color ? red =>0.34 : green =>0.55 : blue=>0.11;
to make the bugs harder to bury.
Isn't this just a selected signal assignment?


In this context, is anyone still happy with the C-compatible version?

However...

in today's VHDL, if I ever needed ?: I would resort to a trivial function, and
replace

Int_val <= Flag?1:0;
with
Int_val <= cond(Flag,1,0);
or even
Int_val <= cond( test=>Flag, T=>1, F=>0 );

YMMV but for the sake of keeping the language relatively free of warts, I don't
mind typing six extra characters.

It's precisely that wart-free-ness that lets you extend it (e.g. by adding
functions) in simple ways that actually work, instead of frustrating you.
I don't get why you think the conditional operator would be a wart.
It is just an operator. It is a trinary operator rather than uniary
or binary, but it is still an operator and would violate nothing about
VHDL.


And it's precisely the remaining warts that limit the ability to extend it
further. For example, the closed set of operators (a wart shared with most
not-quite-object-oriented languages like C++) stops you naming the
above function "?:" and writing
Int_val <= "?:"( Flag,1, 0 );
to look that little bit more like Verilog or C.

Or a better example: if you allowed types as generics, as Ada does, you could
write the "?:" function once and use it to return different types. (Newer
versions of C++ have this, as the template).

A foolish consistency is the hobgoblin of little minds, but there are
times when consistency is a good thing in engineering, other times
not. I guess I'm consistently inconsistent.

Oh I'm inconsistent too, just not consistently so.

I like "consistently inconsistent" - I suspect it would make the best
description of the underlying design principles of C.
(I don't know Verilog at all well, so won't extend the same courtesy to it!)
I've been warned about verilog, mostly in this thread, and I've been
told once I try it I won't go back. We'll see later this summer...
maybe.

Rick
 
On Wed, 28 Apr 2010 16:55:13 -0700 (PDT), rickman <gnuarm@gmail.com> wrote:

That is one long reply...

On Apr 28, 6:56 am, Brian Drummond <brian_drumm...@btconnect.com
wrote:
On Tue, 27 Apr 2010 15:56:57 -0700 (PDT), rickman <gnu...@gmail.com> wrote:
Or maybe I should say that I don't think describing
combinatorial logic outside of clocked processes is inherently less
desirable.

Where there are combinatorial outputs to be described, I agree, I'll describe
them outside the main process.

No, I am talking about logic that drives the registers. For example,
I have a PLL circuit which has a few registers, but several adders and
a few shift operations (mult/div). I give each a separate concurrent
statement to facilitate debugging. I could put it all inside the
register process, but I can do things with signals I can't do with
variables, such as bring them to the outside world.
I'm not saying a separate combi process is wrong; I just haven't found a need
for it.

Using signals for their different semantics - I am with you on that score..
However I use them in synchronous processes, alongside variables, and this
departs from the "one process with variables" template. Perhaps this simplifies
the remaining cases until a process is unnecessary.

Two reasons I use signals in processes:
(1) as you say, it sometimes gives easier debugging. I am using a simulator
(ISIM) that doesn't yet display variables in the wave window.
(2) Using signals for pipeline registers, I can describe a pipeline right way
round! Using variables I would have to describe it backwards.

Variables do keep the declarations local. However my next move will be to use
blocks to keep the signal declarations local too. (I feel a need to carefully
check the tool support for this!)

I'm unclear why you say a separate concurrent statement facilitates debugging;
are you stepping through code in the simulator? (I haven't done that in over ten
years)

Maybe this is a reflection of how we think differently for both design
and debug. I am an old school hardware designer and I think in terms
of registers and logic blocks. So my design reflects that I guess.
I suspect we both keep a TTL Databook on the shelf...

I just use VHDL's conditional signal assignments for that purpose. As it's
purely combinational, I have never found the need for an equivalent that I can
use inside a process.

Heck, that is very limited. You can't even use in inside of a
separate signal assignment. Try combining the conditional signal
assignment with anything else. I would like to be able to use it
inside the conditional for an if (sometimes) or combine it is ways
that allows the assignment to more directly state the logic of the
problem rather than my having to convert the logic to suit the flow of
the structure.
Such as Bernd's mux-with-enable example yesterday. He used a process, and
suggested the alternative in Verilog was a huge array of signals.

One intermediate signal between mux and enable, and the VHDL solution is easily
understood and less verbose. (Though a combi process would also work)

And as Alan said, VHDL-2008 promises support for these (combi and select) in
processes.


If VHDL is to adopt a conditional operator I hope it can do better than that!
Something less surprising, and generalisable to other discrete types or at least
other enums.

Channel_Gain <= Channel_Color ? 0.11 : 0.55 : 0.34;
-- nice and compact, but descending order to remain compatible with Boolean
---------------------------------

I think this is a rather trivial example. Why not use the selected
signal assignment?
As you said above; because it isn't combinable - e.g. in a process - yet.

The mnemonic for a boolean conditional operator is pretty simple, it is
the same as an IF statement. But to extrapolate that to descending
order for other data types is a bit of a reach.
A better solution all round would be to replace it with an if-expression (in
which "if", "then", "else" are explicit, (don't rely on the reader knowing C)
and a case-expression for the (n>2) enumeration and integer subrange cases.

But that seems to have fallen out of favour since Algol-W.

There would of course be an associative form of the expression
Channel_Gain <= Channel_Color ? red =>0.34 : green =>0.55 : blue=>0.11;
to make the bugs harder to bury.

Isn't this just a selected signal assignment?
Essentially yes - the difference (which, I confess I didn't know, had gone in
VHDL-2008) being that you can use it in a process.

I suppose I'm just saying I appreciate the VHDL-2008 changes which don't break
the language, rather than adding ?: which would.

It's precisely that wart-free-ness that lets you extend it (e.g. by adding
functions) in simple ways that actually work, instead of frustrating you.

I don't get why you think the conditional operator would be a wart.
It is just an operator. It is a trinary operator rather than uniary
or binary, but it is still an operator and would violate nothing about
VHDL.
For a start, what would the syntax for overloading it look like?

My guess is: horrible.

And definitely not worth rewriting half the parser for one operator on one
specific enumerated type.

I've been warned about verilog, mostly in this thread, and I've been
told once I try it I won't go back. We'll see later this summer...
maybe.
I'd certainly be interested to know how you get on.

My prejudices are my own; I'd rather spend the time learning how to push VHDL
harder for more productivity. I have the feeling we've barely scratched the
surface yet.

- Brian
 
Brian Drummond wrote:
On Wed, 28 Apr 2010 16:55:13 -0700 (PDT), rickman <gnuarm@gmail.com> wrote:

The mnemonic for a boolean conditional operator is pretty simple, it is
the same as an IF statement. But to extrapolate that to descending
order for other data types is a bit of a reach.

A better solution all round would be to replace it with an if-expression (in
which "if", "then", "else" are explicit, (don't rely on the reader knowing C)
and a case-expression for the (n>2) enumeration and integer subrange cases.

But that seems to have fallen out of favour since Algol-W.
Conditional expressions in the "if-then-else" syntax are being proposed
for the next Ada standard, and are already implemented in the GNU Ada
compiler. See http://gcc.gnu.org/ml/gcc-patches/2009-07/msg00327.html.

--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
 
On Apr 29, 7:12 am, Brian Drummond <brian_drumm...@btconnect.com>
wrote:
On Wed, 28 Apr 2010 16:55:13 -0700 (PDT), rickman <gnu...@gmail.com> wrote:
That is one long reply...

I'm unclear why you say a separate concurrent statement facilitates debugging;
are you stepping through code in the simulator? (I haven't done that in over ten
years)
Not for stepping, although I sometimes do that. It is so I can put up
each result in the simulator...

DCO <= DCO + (Integrated / INTG_GAIN) + (ErrorReg * PROP_GAIN);

This is overflowing an intermediate result. How do you debug? In the
process of debugging I also found the intermediate results need
saturating arithmetic, at least in test. By using separate
assignments for each step I can see what each operator is doing and
why it is crapping out. Once I split it up, I am leaving it, although
I am removing the saturation logic.


I think this is a rather trivial example.  Why not use the selected
signal assignment?  

As you said above; because it isn't combinable - e.g. in a process - yet.
I am refering to the situation where it is available. It may be in
VHDL 2008, but I guess my machine is still running in 2003.


The mnemonic for a boolean conditional operator is pretty simple, it is
the same as an IF statement.  But to extrapolate that to descending
order for other data types is a bit of a reach.  

A better solution all round would be to replace it with an if-expression (in
which "if", "then", "else" are explicit, (don't rely on the reader knowing C)
and a case-expression for the (n>2) enumeration and integer subrange cases.

But that seems to have fallen out of favour since Algol-W.
I'm not sure what you are referring to. An if is a sequential control
flow structure. I guess you are saying to give it a dual use. The
boolean operator is in common usage and there is no good reason to not
include it in VHDL. I don't know what the syntax is, but I assume it
is similar or the same as in Verilog.


There would of course be an associative form of the expression
Channel_Gain <= Channel_Color ? red =>0.34 : green =>0.55 : blue=>0.11;
to make the bugs harder to bury.

Isn't this just a selected signal assignment?

Essentially yes - the difference (which, I confess I didn't know, had gone in
VHDL-2008) being that you can use it in a process.
In a process this is a case statement. The real difference is that
you can use it inside an assignment while the case statement or
selected signal assignment can't.

foo <= ralph + (('1' = Mode) ? A : B);

compared to

with Mode select
foo <= ralph + A when '1',
ralph + B when '0',
(others => '-') when others;

Both can get very unreadable if they get more complex. However, there
have been many times I have had to write very messy code or at a
minimum had to think hard about how to make it clear using the current
constructs.


I suppose I'm just saying I appreciate the VHDL-2008 changes which don't break
the language, rather than adding ?: which would.
I don't get the "break" part. I think that is a subjective opinion.


I don't get why you think the conditional operator would be a wart.
It is just an operator.  It is a trinary operator rather than uniary
or binary, but it is still an operator and would violate nothing about
VHDL.

For a start, what would the syntax for overloading it look like?
Why would it be any different from what we currently use??? What does
it look like?


My guess is: horrible.

And definitely not worth rewriting half the parser for one operator on one
specific enumerated type.
Ok, now you are going off to unsubstantiated claims. I doubt anyone
would agree to go with a feature that required rewriting half the
compiler.


I've been warned about verilog, mostly in this thread, and I've been
told once I try it I won't go back.  We'll see later this summer...
maybe.

I'd certainly be interested to know how you get on.

My prejudices are my own; I'd rather spend the time learning how to push VHDL
harder for more productivity. I have the feeling we've barely scratched the
surface yet.
We'll see. First I have to finish my current project. I am at the
final few bugs and each one is a trip back and forth to the customer.

Rick
 
On Thu, 29 Apr 2010 05:42:47 -0700 (PDT), rickman <gnuarm@gmail.com> wrote:

On Apr 29, 7:12 am, Brian Drummond <brian_drumm...@btconnect.com
wrote:
On Wed, 28 Apr 2010 16:55:13 -0700 (PDT), rickman <gnu...@gmail.com> wrote:
That is one long reply...

I'm unclear why you say a separate concurrent statement facilitates debugging;
are you stepping through code in the simulator? (I haven't done that in over ten
years)

Not for stepping, although I sometimes do that. It is so I can put up
each result in the simulator...

DCO <= DCO + (Integrated / INTG_GAIN) + (ErrorReg * PROP_GAIN);

This is overflowing an intermediate result. How do you debug?
Sometimes, not very well...

But for this situation I would assert properties of the expression, or better,
of each intermediate term.

So for example, (ErrorReg * PROP_GAIN) might have its own intermediate signal -
(in my code it almost certainly would - within the main process - so I can
control its pipelining but that's another story * ) - I could assert the output
sign matches the input sign (knowing, or asserting, PROP_GAIN is positive).

(* I've had summer interns exploring register retiming tools; they didn't beat
my hand-timed results. Which may say something about the tools, or not)

Then either I get a pinpoint report of the problem, or the testbench is
inadequate...

A better solution all round would be to replace it with an if-expression (in
which "if", "then", "else" are explicit, (don't rely on the reader knowing C)
and a case-expression for the (n>2) enumeration and integer subrange cases.

But that seems to have fallen out of favour since Algol-W.

I'm not sure what you are referring to. An if is a sequential control
flow structure.
Maybe in some languages, but it doesn't have to be.

I used to be able to write code of the form
----
a := if <expr1> then <expr2> [ else <expr3>];
----
(the assignment being skipped if expr1 was false and there was no else clause)
and similarly, case expressions with semantics like case statements.

And I am delighted to hear it's on the way back in a mainstream language and one
of the main influences on VHDL.

foo <= ralph + (('1' = Mode) ? A : B);

compared to

with Mode select
foo <= ralph + A when '1',
ralph + B when '0',
(others => '-') when others;
I think a closer translation would be

foo <= ralph + A when Mode = '1' else ralph + B;

and I don't get the objection to that.

I doubt there's a synthesis tool alive that would duplicate the adder!
But if there were, I would mux A or B onto an intermediate signal .

I don't get the "break" part. I think that is a subjective opinion.
I don't get why you think the conditional operator would be a wart.
It is just an operator.  It is a trinary operator rather than uniary
or binary,
For a start, what would the syntax for overloading it look like?

Why would it be any different from what we currently use??? What does
it look like?
What we currently use and overload are unary and binary operators. In neither of
these do you have to split the operator symbol in half and insert an argument in
the middle.

There is no syntax for expressing that, in VHDL.

That is what I mean by "break". I suspect we'd have to try writing the BNF for a
grammar that would handle its use and overloading to settle the question.

I confess I haven't looked to see how C++ overloads ?: That might be quite
illuminating...

And definitely not worth rewriting half the parser for one operator on one
specific enumerated type.

Ok, now you are going off to unsubstantiated claims. I doubt anyone
would agree to go with a feature that required rewriting half the
compiler.
Maybe so, my compiler writing days are long ago. But something about adding
*one* trinary operator sets off alarm bells.

- Brian
 
On Wed, 28 Apr 2010 12:33:21 +0100, Alan Fitch <alan.fitch@spamtrap.com> wrote:

And VHDL 2008 provides various matching operators that allow std_logic,
bit and so on to be interpreted as Boolean - see
http://www.doulos.com/knowhow/vhdl_designers_guide/vhdl_2008/vhdl_200x_ease/
Heh... It says (and I hope quoting this comes under the heading of fair use)
----------------------------------------------------------------------------------------------
How many times have you wanted to write something like this:
if A and B then
where A and B are STD_LOGIC? ... You have to write this instead:
if A = '1' and B = '1' then

VHDL-2008 introduces a new operator, ??....So you can now write this:
if ?? A and B then
----------------------------------------------------------------------------------------------

I confess, on the odd occasion, to writing
if A and B then
anyway.

Is it cheating to (ab)use overload resolution by return type, overloading "and"
for std_logic args to return a boolean?

If you're interested in VHDL 2008, I recommend the book "VHDL 2008 -
Just the New Stuff" by Peter Ashenden and Jim Lewis.
I'll definitely follow this up...

- Brian
 
I have used two home-grown functions for years for this: is1() and
is0(). Both handle metavalues, etc.

if is1(A and B) then

No silly syntax or language "improvements" required.

Andy
 
On Fri, 30 Apr 2010 14:06:19 -0700 (PDT), rickman <gnuarm@gmail.com>
wrote:

On Apr 29, 5:15 pm, Brian Drummond <brian_drumm...@btconnect.com
wrote:

Not for stepping, although I sometimes do that.  It is so I can put up
each result in the simulator...

DCO <= DCO + (Integrated / INTG_GAIN) + (ErrorReg * PROP_GAIN);

This is overflowing an intermediate result.  How do you debug?

for example, (ErrorReg * PROP_GAIN) might have its own intermediate signal -
(in my code it almost certainly would - within the main process - so I can
control its pipelining but that's another story * ) - I could assert the output
sign matches the input sign (knowing, or asserting, PROP_GAIN is positive).

Pipelining is not possible. This is a PLL and adding register delays
changes the nature of the equation. Yes, you can assert things in
simulation, but what do you do in the chip?
I understand about pipelining in your case; you're right it wouldn't
work (introducing additional poles).But you can still use intermediate
(combinatorial) signals.

And yes you can run many more cycles on the chip - as well as find
unforeseen circumstances - that you can't in sim.

In places (which means I am inconsistent about it ) I have adopted
"hardware asserts" using sticky bits, of the form

process(clk)
begin
if rising_edge(clk) then
shouldnt_happen <= (the expression you would assert);
if clear then
shouldnt_happen_stky <= '0';
else
shouldnt_happen_stky <= shouldnt_happen_stky or
shouldnt_happen;
end if;
end if;
end process;

I collect all the sticky bits into a health monitor register which I
read (and then clear) at leisure. Hardware cost is completely trivial
unless you're using a CPLD.

If any of them trigger, they show which part of the design to focus on,
and make ideal trigger signals for Chipscope.

I had to debug a problem
in the board when the simulation worked perfectly. In fact, I am very
happy with the PLL, it locks in fast and holds the lock tightly. The
problem ended up being a configuration (real time, not compile)
mistake. But it took some real debugging of the PLL to figure that
out.
Good work. (nice story of real world snipped...)

foo <= ralph + (('1' = Mode) ? A : B);

compared to

with Mode select
 foo <= ralph + A when '1',
        ralph + B when '0',
        (others => '-') when others;

I think a closer translation would be

foo <= ralph + A when Mode = '1' else ralph + B;

and I don't get the objection to that.

Yeah, but in simulation I always use the others to catch "illegal"
states in controls. In your code a value of 'u' in Mode results in
foo <= ralph + B and the circuit continues with no problem.
Agreed, but my point was ... the ?: operator does that too!
I didn't say it was a better translation, just more accurate.

I want to
propagate crap with crap. Typically operators do that with std_logic
while your simpler logic doesn't.
So this is a case where the additional verbosity comes, not from the
language missing a useful operator, but from your wish (which I agree
with) to do a better job.

In fact, it is only a warning when you have two drivers of an
std_logic signal. I would like to make that an error by using
std_ulogic, but I'm not sure how that works with the other types. I
need to investigate that sometime.
That's an example of people (myself included) not having pushed the
language capabilities far enough in raising quality or productivity. We
just use std_logic because the tools (templates, Xilinx examples, etc)
just assume it's the default we want to use. But really, outside of
3-state buses, std_ulogic[_vector] should be the default.

I suspect there may be some tools issues in the less-well-trodden path
of std_ulogic. And I have a nagging suspicion that numeric_std is
compatible with std_logic and may be harder to use with its unresolved
cousin. (But I hope not)

Again, if you get a chance to investigate, I would be interested to hear
how you get on.

That is what I mean by "break". I suspect we'd have to try writing the BNF for a
grammar that would handle its use and overloading to settle the question.

If it is a part of VHDL 2008, isn't it done? I can't imagine they
would have added it to the standard if vendors didn't know how to make
it work yet.
?: in the C (Verilog?) form is not in VHDL2008, as far as I know. But
there are other (more VHDL-friendly) improvements in the same area.

Ok, now you are going off to unsubstantiated claims.  I doubt anyone
would agree to go with a feature that required rewriting half the
compiler.

Maybe so, my compiler writing days are long ago. But something about adding
*one* trinary operator sets off alarm bells.

I guess we can ask the vendors about it. Does anyone have VHDL in
their tools yet? Mine don't seem to include it, but that may be a
switch I need to throw.
Some support bits of VHDL2008, but support is still pretty poor.

- Brian.
 
On Apr 29, 5:15 pm, Brian Drummond <brian_drumm...@btconnect.com>
wrote:
On Thu, 29 Apr 2010 05:42:47 -0700 (PDT), rickman <gnu...@gmail.com> wrote:
On Apr 29, 7:12 am, Brian Drummond <brian_drumm...@btconnect.com
wrote:
On Wed, 28 Apr 2010 16:55:13 -0700 (PDT), rickman <gnu...@gmail.com> wrote:
That is one long reply...

I'm unclear why you say a separate concurrent statement facilitates debugging;
are you stepping through code in the simulator? (I haven't done that in over ten
years)

Not for stepping, although I sometimes do that.  It is so I can put up
each result in the simulator...

DCO <= DCO + (Integrated / INTG_GAIN) + (ErrorReg * PROP_GAIN);

This is overflowing an intermediate result.  How do you debug?

Sometimes, not very well...

But for this situation I would assert properties of the expression, or better,
of each intermediate term.

So for example, (ErrorReg * PROP_GAIN) might have its own intermediate signal -
(in my code it almost certainly would - within the main process - so I can
control its pipelining but that's another story * ) - I could assert the output
sign matches the input sign (knowing, or asserting, PROP_GAIN is positive).
Pipelining is not possible. This is a PLL and adding register delays
changes the nature of the equation. Yes, you can assert things in
simulation, but what do you do in the chip? I had to debug a problem
in the board when the simulation worked perfectly. In fact, I am very
happy with the PLL, it locks in fast and holds the lock tightly. The
problem ended up being a configuration (real time, not compile)
mistake. But it took some real debugging of the PLL to figure that
out.


(* I've had summer interns exploring register retiming tools;  they didn't beat
my hand-timed results. Which may say something about the tools, or not)

Then either I get a pinpoint report of the problem, or the testbench is
inadequate...
Actually, yes, in this case a 100% test bench would have caught the
real problem. I wasn't simulating the configuration module which
received the serial config commands. This has bitten me twice, but it
is one of those things where the customer was beating on me to get
something to him to test and I didn't have time to get the last
touches into the top level test bench. Sometimes working the "right"
way appears to be "slow". In this case it cost us about a week of lab
test time vs. about a week of additional test bench design and use. I
am working on the 100% simulation now mainly because I still have to
build a test fixture, the hardware kind, and that uses an FPGA which
the test bench will be programming. The other bug was actually a bug
in the config code which didn't disable multiple use of the same
register bits between two modes. A squelch circuit was activated in a
mode where there wasn't supposed to be any squelch.


A better solution all round would be to replace it with an if-expression (in
which "if", "then", "else" are explicit, (don't rely on the reader knowing C)
and a case-expression for the (n>2) enumeration and integer subrange cases.

But that seems to have fallen out of favour since Algol-W.

I'm not sure what you are referring to.  An if is a sequential control
flow structure.  

Maybe in some languages, but it doesn't have to be.

I used to be able to write code of the form
----
   a := if <expr1> then <expr2> [ else <expr3>];
----
(the assignment being skipped if expr1 was false and there was no else clause)
and similarly, case expressions with semantics like case statements.

And I am delighted to hear it's on the way back in a mainstream language and one
of the main influences on VHDL.

foo <= ralph + (('1' = Mode) ? A : B);

compared to

with Mode select
 foo <= ralph + A when '1',
        ralph + B when '0',
        (others => '-') when others;

I think a closer translation would be

foo <= ralph + A when Mode = '1' else ralph + B;

and I don't get the objection to that.
Yeah, but in simulation I always use the others to catch "illegal"
states in controls. In your code a value of 'u' in Mode results in
foo <= ralph + B and the circuit continues with no problem. I want to
propagate crap with crap. Typically operators do that with std_logic
while your simpler logic doesn't.

In fact, it is only a warning when you have two drivers of an
std_logic signal. I would like to make that an error by using
std_ulogic, but I'm not sure how that works with the other types. I
need to investigate that sometime.


I doubt there's a synthesis tool alive that would duplicate the adder!
But if there were, I would mux A or B onto  an intermediate signal .

I don't get the "break" part.  I think that is a subjective opinion.
I don't get why you think the conditional operator would be a wart.
It is just an operator.  It is a trinary operator rather than uniary
or binary,
For a start, what would the syntax for overloading it look like?

Why would it be any different from what we currently use???  What does
it look like?

What we currently use and overload are unary and binary operators. In neither of
these do you have to split the operator symbol in half and insert an argument in
the middle.

There is no syntax for expressing that, in VHDL.

That is what I mean by "break". I suspect we'd have to try writing the BNF for a
grammar that would handle its use and overloading to settle the question.
If it is a part of VHDL 2008, isn't it done? I can't imagine they
would have added it to the standard if vendors didn't know how to make
it work yet.


And definitely not worth rewriting half the parser for one operator on one
specific enumerated type.

Ok, now you are going off to unsubstantiated claims.  I doubt anyone
would agree to go with a feature that required rewriting half the
compiler.

Maybe so, my compiler writing days are long ago. But something about adding
*one* trinary operator sets off alarm bells.
I guess we can ask the vendors about it. Does anyone have VHDL in
their tools yet? Mine don't seem to include it, but that may be a
switch I need to throw.

Rick
 
On Apr 30, 4:06 pm, rickman <gnu...@gmail.com> wrote:
Yeah, but in simulation I always use the others to catch "illegal"
states in controls.  In your code a value of 'u' in Mode results in
foo <= ralph + B and the circuit continues with no problem.  I want to
propagate crap with crap.  Typically operators do that with std_logic
while your simpler logic doesn't.
I replied earlier about using trivial, home-grown is1() and is0()
functions that will let you know about metavalues with an assertion
warning (default, can be altered with optional arg), as well as
appropriately handle a weak logic value. This is the main reason I
wrote them and have used them for years. If you set severity
appropriately, the debugger will stop exactly where the meta-value was
detected, rather than waiting until you notice garbage data, and trace
it back to its cause.

foo <= ralph + A when is1(Mode) else ralph + B;

I'm beginning to wonder how pleased you will be with verilog, given
some of the features of vhdl you already use.

Andy
 
On Apr 29, 5:42 pm, Brian Drummond <brian_drumm...@btconnect.com>
wrote:
On Wed, 28 Apr 2010 12:33:21 +0100, Alan Fitch <alan.fi...@spamtrap.com> wrote:
How many times have you wanted to write something like this:
if A and B then
where A and B are STD_LOGIC? ... You have to write this instead:
if A = '1' and B = '1' then
You don't HAVE to write it that way...it can also be written (just as
clearly in my opinion, but a few more taps on the keyboard then
VHDL-2008)

if (A and B) = '1' then

KJ
 
On Apr 30, 6:56 pm, Brian Drummond <brian_drumm...@btconnect.com>
wrote:
On Fri, 30 Apr 2010 14:06:19 -0700 (PDT), rickman <gnu...@gmail.com
In fact, it is only a warning when you have two drivers of an
std_logic signal.  I would like to make that an error by using
std_ulogic, but I'm not sure how that works with the other types.  I
need to investigate that sometime.

snip
I suspect there may be some tools issues in the less-well-trodden path
of std_ulogic. And I have a nagging suspicion that numeric_std is
compatible with std_logic and may be harder to use with its unresolved
cousin. (But I hope not)

Again, if you get a chance to investigate, I would be interested to hear
how you get on.
I've been using std_ulogic/std_ulogic_vector for a while...no issues
with Quartus or Synplify on the synthesis front. The only downside is
some extra type conversions to convert between the vectors where you
have to for some reason have std_logic_vector. The upside of course
is that the compiler immediately flags when you have multiple drivers
on a net, you don't have to sim/debug to find that out.

The main place the mixing of std_logic_vector and std_ulogic_vector
occurs is instantiating some outside widget that uses std_logic_vector
on the interface. Once I learned that type conversions can be put
into the port map and you didn't need to create std_ulogic 'wrappers',
or use intermediate signals to connect the vectors, it all came
together rather nicely.

Example:

Inst_Some_Widget : entity work.widget
port map(
Gazinta_slv => std_logic_vector(Gazinta_sulv),
std_logic_vector(Gazouta_slv) => Gazouta_sulv
);

std_logic and std_ulogic can be freely assigned without any type
conversions

Kevin Jennings
 
On Fri, 30 Apr 2010 17:52:10 -0700 (PDT), KJ <kkjennings@sbcglobal.net>
wrote:

On Apr 30, 6:56 pm, Brian Drummond <brian_drumm...@btconnect.com
wrote:
snip
I suspect there may be some tools issues in the less-well-trodden path
of std_ulogic. And I have a nagging suspicion that numeric_std is
compatible with std_logic and may be harder to use with its unresolved
cousin. (But I hope not)

I've been using std_ulogic/std_ulogic_vector for a while...no issues
with Quartus or Synplify on the synthesis front.
Good to know. Seen any extra cruft getting to/from numeric_std?

Once I learned that type conversions can be put
into the port map and you didn't need to create std_ulogic 'wrappers',
or use intermediate signals to connect the vectors, it all came
together rather nicely.

Example:

Inst_Some_Widget : entity work.widget
port map(
Gazinta_slv => std_logic_vector(Gazinta_sulv),
std_logic_vector(Gazouta_slv) => Gazouta_sulv
);
Port map conversions (not this one) are one area where I have seen (and
reported) problems with Xilinx ISIM. Not show-stoppers, I just have to
put the conversions elsewhere and wait patiently for Xilinx to fix it.

But it's my experience that tools issues are a big cause of "drag" in
learning to improve my use of VHDL.

- Brian
 
On May 1, 6:35 am, Brian Drummond <brian_drumm...@btconnect.com>
wrote:
On Fri, 30 Apr 2010 17:52:10 -0700 (PDT), KJ <kkjenni...@sbcglobal.net
I've been using std_ulogic/std_ulogic_vector for a while...no issues
with Quartus or Synplify on the synthesis front.

Good to know. Seen any extra cruft getting to/from numeric_std?
No.

KJ
 
Alan Fitch wrote:

On 28/04/2010 11:56, Brian Drummond wrote:


If VHDL is to adopt a conditional operator I hope it can do better than
that! Something less surprising, and generalisable to other discrete
types or at least other enums.

And VHDL 2008 provides various matching operators that allow std_logic,
bit and so on to be interpreted as Boolean - see

http://www.doulos.com/knowhow/vhdl_designers_guide/vhdl_2008/vhdl_200x_ease/

If you're interested in VHDL 2008, I recommend the book "VHDL 2008 -
Just the New Stuff" by Peter Ashenden and Jim Lewis.
Indeed: highly recommended.

Now if only the tools supported ...
Again: indeed. I asked Mentor Graphics when to expect full support for VHDL
2008 in ModelSim/QuestaSim. This was their answer:

There isn't a set date/revision for full support for VHDL 2008
at this point. Some of the reasons are due ambiguity in the
spec and and the resulting work between customers and the
standards committee, and the priority/usefulness/convenience of
the still to-do features. I see some are not scheduled until
6.7 towards the end of the year and no doubt some will come
later than that.
Seems it is going to take a while....

I sent in my wish list, highest priority first:

- generic types
- generic lists in packages
- generic lists in subprograms
- generic subprograms
- local packages
- context declarations
- unconstrained element types
- signal expressions in port maps
- all signals in sensitivity list
- std_logic_1164: std_logic_vector is a subtype of std_ulogic_vector
- if and case generate
- condition operator ("??")
- matching relational operators ("?=", "?/=", "?<", ...)
- matching case statements ("case?")
The matching operators are low in the list, as I'm mainly interested in
improvements in the area of behavioral VHDL for verification
(testbenches/testcases/BFMs).

--
Paul Uiterlinden
www.aimvalley.nl
e-mail addres: remove the not.
 
On Apr 30, 8:52 pm, KJ <kkjenni...@sbcglobal.net> wrote:
On Apr 30, 6:56 pm, Brian Drummond <brian_drumm...@btconnect.com
wrote:

On Fri, 30 Apr 2010 14:06:19 -0700 (PDT), rickman <gnu...@gmail.com
In fact, it is only a warning when you have two drivers of an
std_logic signal.  I would like to make that an error by using
std_ulogic, but I'm not sure how that works with the other types.  I
need to investigate that sometime.

snip
I suspect there may be some tools issues in the less-well-trodden path
of std_ulogic. And I have a nagging suspicion that numeric_std is
compatible with std_logic and may be harder to use with its unresolved
cousin. (But I hope not)

Again, if you get a chance to investigate, I would be interested to hear
how you get on.

I've been using std_ulogic/std_ulogic_vector for a while...no issues
with Quartus or Synplify on the synthesis front.  
My concern is compatibility with numeric_std types. I almost never
use std_logic_vector, if for no other reason, the name is soooooo long
to type. I much prefer signed/unsigned types. I guess the real issue
is that if I am using signed/unsigned, I am using slv, not sulv... end
of story, right? Would I need to make my own library to use ulogic
based signed/unsigned types?


The main place the mixing of std_logic_vector and std_ulogic_vector
occurs is instantiating some outside widget that uses std_logic_vector
on the interface.  Once I learned that type conversions can be put
into the port map and you didn't need to create std_ulogic 'wrappers',
or use intermediate signals to connect the vectors, it all came
together rather nicely.

Example:

Inst_Some_Widget : entity work.widget
port map(
   Gazinta_slv => std_logic_vector(Gazinta_sulv),
   std_logic_vector(Gazouta_slv) => Gazouta_sulv
);

std_logic and std_ulogic can be freely assigned without any type
conversions
I know I have run into trouble with this in the past. In fact, I
thought there were some limitations in the standard, not just tool
limitations. Rather than learn to work around the limitations, I have
always used "wrapper" signals for the conversion.

Rick
 

Welcome to EDABoard.com

Sponsor

Back
Top