From: Brian Drummond on
On Wed, 28 Apr 2010 07:02:00 -0700 (PDT), Andy <jonesandy(a)comcast.net> wrote:

>On Apr 28, 5:56�am, Brian Drummond <brian_drumm...(a)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.


From: rickman on
That is one long reply...

On Apr 28, 6:56 am, Brian Drummond <brian_drumm...(a)btconnect.com>
wrote:
> On Tue, 27 Apr 2010 15:56:57 -0700 (PDT), rickman <gnu...(a)gmail.com> wrote:
> >On Apr 27, 6:05 am, Brian Drummond <brian_drumm...(a)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
From: Brian Drummond on
On Wed, 28 Apr 2010 16:55:13 -0700 (PDT), rickman <gnuarm(a)gmail.com> wrote:

>That is one long reply...
>
>On Apr 28, 6:56 am, Brian Drummond <brian_drumm...(a)btconnect.com>
>wrote:
>> On Tue, 27 Apr 2010 15:56:57 -0700 (PDT), rickman <gnu...(a)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
From: Niklas Holsti on
Brian Drummond wrote:
> On Wed, 28 Apr 2010 16:55:13 -0700 (PDT), rickman <gnuarm(a)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
. @ .
From: rickman on
On Apr 29, 7:12 am, Brian Drummond <brian_drumm...(a)btconnect.com>
wrote:
> On Wed, 28 Apr 2010 16:55:13 -0700 (PDT), rickman <gnu...(a)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