"Non-static aggregate with multiple choices has non-static others choice."

1140 views
Skip to first unread message

rickman

unread,
Mar 23, 2013, 6:20:27 PM3/23/13
to
This is the code,

Bias <= (Bias(Bias'high-1) => '1', others => '0');

This is the error,

"Non-static aggregate with multiple choices has non-static others choice."

When I looked this up on the web they talk about things like using a
loop index to select the bit in the word. Another page mentions that
the items in an aggregate must be non-overlapping. If they need to be
non-overlapping what is the point of the others? I could have sworn
that I was told using others to fill in the remainder of a vector was ok
as long as it was last in the aggregate.

A post from 2003 used a fixed index into the vector, so it seems the
problem is not from the use of Bias'high in the index.

This kind of thing is what drives people nuts about VHDL. For some of
us it is a short trip.

--

Rick

Brian Drummond

unread,
Mar 23, 2013, 7:28:35 PM3/23/13
to
On Sat, 23 Mar 2013 18:20:27 -0400, rickman wrote:

> This is the code,
>
> Bias <= (Bias(Bias'high-1) => '1', others => '0');

Is the indirection deliberate, or did you mean

Bias <= (Bias'high-1 => '1', others => '0'); -- ?

If there's an error report from the latter, I'd be quite surprised.

- Brian

rickman

unread,
Mar 24, 2013, 6:24:49 PM3/24/13
to
I'm not sure now. I had already changed the code and regenerated it for
the post... ok, I tried changing it back and still get the error with
the code below - copied and pasted fresh from the editor. The tool is a
slightly old copy of Active HDL. My license is from 2008. I should try
it with a current tool. So I tried it with AHDL 9.1 from 2011, same
error. It also complains a bit about my coding style... picky, picky,
picky...

Bias <= (Bias'high-1 => '1', others => '0');

The Synplify tool... what? Oh, this code is in the test bench, so I
can't try it under Synplify. Or more correctly Synplify complains that
the test bench has no ports... lol

Reading about this gets into the whole globally static vs locally static
thing which I have to look up every time I encounter it. I like to work
with tools that can understand at least as much as I do.

--

Rick

Alan Fitch

unread,
Mar 24, 2013, 7:20:27 PM3/24/13
to
Hi Rickman,
I'm unclear from your comments whether you care for an explanation, or
are just fed up with the cryptic rules :-)

But anyway - there are two things at play.

Firstly, there is a mysterious rule for aggregates - quoted from the
VHDL-2002 standard section 7.3.2.2

"A named association of an array aggregate is allowed to have a choice
that is not locally static, or likewise a choice that is a null range,
only if the aggregate includes a single element association and this
element association has a single choice. An others choice is locally
static if the applicable index constraint is locally static."

In your example you do not have a single element association. From this
rule

s <= (Bias'high-1 => '1');

would be legal as it only has a single element association whether
Bias'High-1 was globally or locally static.

Secondly, the curse of locally and globally static. It's hard to work
out, but it seems to me that

Bias'high-1

should be locally static - but to be really sure I'd have to know how
Bias was declared, and also if you really meant

Bias'HIGH-1

or

Bias(Bias'High-1) as in your original post.

Anyway, if you're happy to use a process, often the easiest fix is to
use inertial delay, e.g.

process(bias)
begin
bias <= (others => '0');
bias(bias'high-1) <= '1';

end process;

hopefully staving off the madness,

kind regards
Alan

--
Alan Fitch

Brian Drummond

unread,
Mar 25, 2013, 7:38:17 AM3/25/13
to
On Sun, 24 Mar 2013 18:24:49 -0400, rickman wrote:

ok, I tried changing it back and still get the error with
> the code below - copied and pasted fresh from the editor.
> Bias <= (Bias'high-1 => '1', others => '0');

My usual solution is a simple function to wrap these bit twiddling ops,
then I can write

Bias <= SetBiasValue;

- Brian

Andy

unread,
Mar 25, 2013, 10:05:47 AM3/25/13
to
Brian,

Is the range of Bias defined locally, without the use of a custom function, generic, or unconstrained port/argument index/length/range or value? If so, then it should have worked. But if Bias'range is defined based on any of the above exclusions, then bias'high (and therefore bias'high-1) is not locally static.

There are certain parts of the VHDL language for which it is desired to allow the stand-alone analysis to determine syntactical correctness for all possible invocations of a module (entity/architecture, function, or procedure). This decision was made to make it easier to define modules (architectures, functions, prodecures) for which the syntactical correctness was not dependent upon how it was invoked or called. This in turn allows more complete verification of a module without having to test every possible invocation. While this may be irritating to individual developers of non-reusable code, it is crucial to the development of large projects with many developers/users and long, varying life-cycles.

That said, this is a case where any NLS single element assignment is allowed, and 'others' is always allowed by itself or in addition to any assignment of LS element(s); but for some reason, 'others' cannot be used in addition to a NLS single element assignment.

Perhaps this should be allowed in a future version of the VHDL standard (and the next version of the standard is in work now!)

Andy

rickman

unread,
Mar 25, 2013, 6:03:30 PM3/25/13
to
Thanks to everyone for your replies. I am frustrated with extremely
arcane rationals for some of the things you can't do in VHDL. I have
been using the language for some 18 years now, but I don't use it all
the time. I do a project for a few weeks or months and then do some
more VHDL a year later typically. So in some ways I am a beginner every
time. lol I rely on cheat sheets to help me through the morass. One I
found recently is from Hardi Electronics and was designed to make a
pamphlet. It is organized for quick reference and has a lot more info
than the typical single sheet info form. But it is from 2000 and only
covers VHDL '93. Not much chance of an update as they were acquired by
Synplicity in 2007. Oh well...

Declaration:

generic(
MPCN_WIDTH : POSITIVE := 4
)
.
.
.
signal Bias : signed (MPCN_WIDTH+1 downto 0);


Usage:

Bias <= (Bias'high-1 => '1', others => '0');

This is a concurrent assignment.

All the fancy explanation aside, I don't get why the tool can't figure
this out. In all fairness, the AHDL tool does suggest an option -relax
that will work around this issue, but I prefer to write code that meets
the standard, even if the standard is a bit anal.

Alan suggested that the aggregate would be valid...

s <= (Bias'high-1 => '1');

But this is not a bloody useful aggregate is it? In fact, it is only an
aggregate by definition I suppose.

I just found one problem with the Hardi cheat sheet. It is locked
against copying! I was going to copy a line talking about 'others', but
I can't. What is with people??? Why are they so frikin' paranoid?

--

Rick

Alan Fitch

unread,
Mar 25, 2013, 7:57:50 PM3/25/13
to
With the description above, the code you've written is *not* locally
static, as it requires the generic to be elaborated before the range of
Bias is known - so Aldec is correct :-(

I guess the tool *can* figure it out with "relax" - it's just not
allowed to according to the standard. The real question is why this code
is illegal according to the standard. Unfortunately I don't know the
rationale for that decision.

Some of the weirder decisions in the standard were based on the
perceived "unreasonable" cost of compile-time or elaboration-time
analysis of the code back in 1987. I wonder if that's the case here? Who
knows??

> Alan suggested that the aggregate would be valid...
>
> s <= (Bias'high-1 => '1');
>
> But this is not a bloody useful aggregate is it? In fact, it is only an
> aggregate by definition I suppose.

Indeed - that's why I described that part of the standard as
"mysterious" :-)

<snip>

Alan

--
Alan Fitch

KJ

unread,
Mar 29, 2013, 10:30:12 PM3/29/13
to
On Monday, March 25, 2013 6:03:30 PM UTC-4, rickman wrote:
> Declaration: generic( MPCN_WIDTH : POSITIVE := 4 )
> signal Bias : signed (MPCN_WIDTH+1 downto 0);
> Usage: Bias <= (Bias'high-1 => '1', others => '0');

Since Bias is signed, why wouldn't you just assign it like this...
Bias <= to_signed(-2**MPCN_WIDTH, Bias'length);

One might have also defined Bias to be an integer and assigned it like this...
signal Bias : integer range -2**MPCN_WIDTH to (2**MPCN_WIDTH-1);
Bias <= -2**MPCN_WIDTH;

Since your intention appears to be that you want to assign the largest
negative number to the value of Bias, both of these forms would seem to
fit your intended usage better than bit picking.

Kevin Jennings

rickman

unread,
Mar 30, 2013, 7:06:56 PM3/30/13
to
No, this is *not* the largest negative number. That would be Bias'high
=> '1'. This is supposed to be the next to highest bit set. I'm not
sure why Bias is shown as signed. I'm not working on that code at the
moment, but I recall the Bias parameter is supposed to be unsigned. But
this is the test bench, maybe I made it signed here for display purposes.

Thanks for the tip. I have been thinking of some of the conversion
routines that let you extend the length of signed and unsigned numbers,
but I get rusty in VHDL and forget some of this stuff.

--

Rick

Rick C

unread,
Nov 7, 2020, 3:48:19 PM11/7/20
to
I still run into this problem from time to time. For whatever reason this is still not an intuitive matter for me. I guess I don't have a clear understanding of globally and locally static to recognize the issue before I get the error message.

Anyway, in my current matter I am trying to set a single bit to '1' in an unsigned and the rest '0'. I decided the least annoying way to deal with this is two separate assignments.

Temp := (others => '0');
Temp(Index) := '1';

rather than

Temp := (Index => '1', others => '0');

Index is passed into a procedure while Temp is a variable.

procedure Test_Button (signal Button_Action : in unsigned;
DelayA : in time;
DelayB : in time;
Index : integer ) is
variable Temp : unsigned (Button_Action'range) := Button_Action;


I like to keep my code tight and neat as it helps me with understanding it when I return to it later. But at some point you have to accept your losses and move on. This is not just me working, but a team effort with total strangers working together using different tools, so the code needs to work across platforms. One guy is a total Xilinx freak. So obviously he is using Vivado or whatever name Xilinx gave their tools.

Consider this as a note to self, but comment if you wish. When I search for problems these days I'm as likely to find my own posts on a topic as much as anything else.

--

Rick C.

- Get 1,000 miles of free Supercharging
- Tesla referral code - https://ts.la/richard11209
Reply all
Reply to author
Forward
0 new messages