Neat MUX style - but XST warning with non power of 2 inputs

A

Andrew FPGA

Hi,
In the past I have sucessfully used the following style to infer a
multiplexor.

variable : mux_input : std_logic_vector(3 downto 0);
variable : mux_output : std_logic;
variable : mux_select : natural range 0 to 3;
.....
mux_output := mux_input(mux_select);

It seems a lot more elegant than the seemingly industry standard
if/else or case style.
However, when I try to select over a non power of 2 range,( i.e. in the
above example, mux_input would be non power of 2 ) XST gives me the
following ominous warning:

WARNING:Xst:790 - "C:/projec.....vhd" line 282: Index value(s) does not
match array range, simulation mismatch.

1) Does anyone use/like the above mux style?
2) Does anyone know how to use this style to select over ranges that
are non power of 2?

(Just to be clear - I'm talking about for synthesis here..)

Regards
Andrew
 
M

manu

Hi,
I use the same syntax and have the same kind of warning message very
often. I supposed this warning means we should have some simulation
mismatch when simulating the post-synthesis netlist, since there's no
integer overflow check anymore...
If there's no risk of overflow on your mux_select variable (conversion
from a std_logic_vector for example), you should simply ignore this
warning.

Manu

Andrew FPGA a écrit :
 
K

KJ

I've used that style I think it's much clearer as well. The reason for the
synthesis warning is because the synthesis tool in some sense 'loses' the
knowledge about what the range is. Taking as an example, the signals
involved in creating a 5 to 1 mux would be

variable : mux_input : std_logic_vector(4 downto 0);
variable : mux_output : std_logic;
variable : mux_select : natural range 0 to 4;

When the synthesizer gets hold of this it will determine that it needs 4
bits to synthesize the signal 'mux_select' and go ahead and implement
whatever logic you've defined. Presumably the code you write for mux_select
guarantees that it will stay in the range of 0 to 4 (including stray power
up conditions).

From the perspective of the synthesizer though it is simply looking at
mux_select as being a 4 bit unsigned number, therefore potentially it can be
in the range from 0 to 7. In order to prove otherwise it would have to
delve into the logic that you've written for mux_select and see if what
you've written can somehow guarantee this...but it's not going to do this.
It simply looks at the 4 bit number index and then sees that there is no
'mux_input(5)', 'mux_input(6)', or 'mux_input(7)', so what you get if
'mux_select' ever gets to be 5, 6 or 7 might not match the simulation so it
puts up the warning.

You've also got to remember that just because the mux_select signal is
defined to be in the range from 0 to 4 that in itself is no guarantee that
your logic will generate this. If your logic happened to allow mux_select
to get to 5 you would get a simulation error of some sort, who knows what
the actual hardware would do. The synthesizer uses the range only to figure
out how many bits it needs to implement the mux_select signal. It leaves
the implementation of the logic up to you. If your logic really does keep
mux_select in the range that you've specified great, if not then the
synthesizer isn't going to add any code to make sure that it does either.

In any case, you can ignore the warning since if your design ever lets
mux_select get out of the range of 0 to 4 either you've got problems you've
got to fix anyway or you really don't care what the output is if mux_select
is out of the specified range. Which one applies is a design specific
question that only you really know what the proper answer is.

KJ.
 
M

Mike Treseler

Andrew said:
In the past I have sucessfully used the following style to infer a
multiplexor.
variable : mux_input : std_logic_vector(3 downto 0);
variable : mux_output : std_logic;
variable : mux_select : natural range 0 to 3;
....
mux_output := mux_input(mux_select);
WARNING:Xst:790 - "C:/projec.....vhd" line 282: Index value(s) does not
match array range, simulation mismatch.
1) Does anyone use/like the above mux style?
2) Does anyone know how to use this style to select over ranges that
are non power of 2?

I prefer a case of an enumerated type because
this hides the the state encoding and makes
it easier to combine other logic with the mux.

If I take over the encoding job from synthesis,
then I have to describe and maintain the associated logic
as KJ explained.

This intellectual activity adds
no value to my design and in fact
makes the description harder to understand.

-- Mike Treseler
_____________________________
type MuxState_t is (
IDLE,
START,
RECEIVE,
STOP,
FULL,
ERR
);
variable MuxState_v : MuxState_t;
begin -- procedure my_mux
case MuxState_v is
-- ...
 
A

Andrew FPGA

Thank you for the comments and design style comments.
I prefer a case of an enumerated type because
this hides the the state encoding and makes
it easier to combine other logic with the mux.
I agree with that sentiment in the general case, but in my particular
situation I think an enumerated type just obfuscates things and I can't
quite see how it would apply. I am selecting(muxing) one item from an
array of items. A natural number type is the natural type(no pun
intended!) to use when accessing items from an array, isn't it?

The function of my design is to create a frame of data, which consists
of multiple timeslots. I.e. I define an frame of data using an array.
Then index into the array to get
the type of data to be sent.

type TimeslotType_t is (FRAME_SYNC, SRC1, SRC2, EOC_CHANNEL)
type TimeslotType_ta is array of TimeslotType_t...

constant FRAME : TimeslotType_ta := (FRAME_SYNC, SRC1, SRC2, SRC1,SRC2,
EOC_CHANNEL, SRC1, SRC2.....etc) --defines the frame structure

Then when I'm actually sending the frame one timeslot at a time I go
NextTimeslotType := FRAME(index);
index := index +1;
case NextTimeslotType is
when FRAME_SYNC =>
--generate and send frame sync char
when SRC1 =>
--get payload from source 1
....
....

Maybe there is a more elegant way of doing this? But doing it like this
allows me to change the structure/length/organisation of the frame by
just editing the constant definition of FRAME.

Regards
Andrew
 
M

Mike Treseler

Andrew said:
Thank you for the comments and design style comments.

You are welcome.
I agree with that sentiment in the general case, but in my particular
situation I think an enumerated type just obfuscates things and I can't
quite see how it would apply.

My point is that if you have an enumeration type say channel_t
as a range that corresponds to the possible mux settings,
you could use a variable of that type as an index for your mux
instead of a natural to eliminate the warnings and the counting of
channels. And you could easily add or remove channels.

You could loop the channels like this:
for index in channel_t loop
-- do something
end loop;

I am selecting(muxing) one item from an
array of items. A natural number type is the natural type(no pun
intended!) to use when accessing items from an array, isn't it?

Certainly, the easiest solution is to just ignore the warning.

-- Mike Treseler
 
A

Andrew FPGA

Hi Mike,
I'm not quite getting how the enumerated type would work in my
situation.
My point is that if you have an enumeration type say channel_t
as a range that corresponds to the possible mux settings,
you could use a variable of that type as an index for your mux
instead of a natural to eliminate the warnings and the counting of
channels. And you could easily add or remove channels.

I'm actually counting through the FRAME array to pick out the next
channels type. I'm not actually counting through channels.

So are you suggesting something like
type channel_type_t is (CH_TYPE1, CH_TYPE2, CH_TYPE3....); -- mux
select
variable channel_type is channel_type_t;

Then when I'm actually sending the frame one timeslot at a time I go
NextTimeslotType := FRAME(channel_type);
--now how to increment channel_type ??
case NextTimeslotType is
when FRAME_SYNC =>
--generate and send frame sync char
when SRC1 =>
--get payload from source 1 and send that
....

I want to increment the channel_type variable so that I point to the
next element in the FRAME. But channel_type is enumerated and I assume
increment doesn't make sense for an enumerated type.
You could loop the channels like this:
for index in channel_t loop
-- do something
end loop;
So, in a single clock tick this would go through all the items in the
enumerated type. But, I only want to one channels worth of data to be
generated - don't want to generate the whole frames data in one clock
tick.....
Certainly, the easiest solution is to just ignore the warning.
Not looking for an easy solution, trying to figure out something thats
elegant.

Actually I don't quite understand why the warnings won't occur for the
enumerated type suggestion also. The hardware is using bits to
represent the different enumerated types. There will still be
combinations of bits that don't map to enumerated types. Indeed, if the
encoding is one hot there will be heaps of combinations that don't map
to valid values.

Regards
Andrew
 
M

Martin Thompson

Andrew FPGA said:
I want to increment the channel_type variable so that I point to the
next element in the FRAME. But channel_type is enumerated and I assume
increment doesn't make sense for an enumerated type.

Does TYPENAME'succ(variable) fit your needs here?

It may not be the answer to all the rest of your concerns of course
:)

Cheers,
Martin
 
K

KJ

I want to increment the channel_type variable so that I point to the
next element in the FRAME. But channel_type is enumerated and I assume
increment doesn't make sense for an enumerated type.
The increment would make sense if you define simply define an increment
function for the enumerated type something like....

function increment(T: TimeslotType) return TimeslotType is
begin
if (T = EOC_CHANNEL) then <<-- Not sure of an elegant way of
picking off the 'last' enumerated type, any ideas??
return(FRAME_SYNC)
else
return(TimeslotType'succ(T));
end if;
end;

Then to increment some signal 'X' you could just say X <= increment(X);
Actually I don't quite understand why the warnings won't occur for the
enumerated type suggestion also. The hardware is using bits to
represent the different enumerated types. There will still be
combinations of bits that don't map to enumerated types. Indeed, if the
encoding is one hot there will be heaps of combinations that don't map
to valid values.

But if you used the enumerate type you would likely also use a case
statement that would then have a 'when others' case to pick up the
conditions you haven't otherwise defined. Continuing the earlier posted
case, you'd have....

case NextTimeslotType is
when FRAME_SYNC =>
--generate and send frame sync char
when SRC1 =>
--get payload from source 1 and send that
when others =>
-- Define it however you want it here, this takes care of any 'other'
states.
....

So no matter how the synthesizer implemented it (i.e. one hot, gray code,
binary, etc.) it wouldn't run across the situation where you haven't
explicitly chosen what you want as an output for every (im)possible state
encoding that may ever occur.

Like you said earlier, type 'natural' really does seem to be the natural
type to use when selecting from an array of choices as you have in your
situation. The enumerated type approach is a different route that is more
applicable in other situations.

KJ
 
R

radarman

Yes, I have used this sort of an arrangement - and it worked well.
However, I took pains to pad or truncate the vectors to avoid possible
mismatches, and make everything align on powers of two. So, if my mux
select is only 2 bits (0 to 3), I would create a new mux input vector
with the required 4 inputs. If the mux select implies a larger number
of inputs than are implemented, I pad the input vector with constants -
simulating an 'others' statement. (for VHDL)

That said, I always use Synplify Pro, which can identify, and optimize
out, the additional logic, so I don't know how Quartus or XST would
handle it. (presumably, they should reduce the logic as well - I just
haven't used Quartus or ISE for anything other than P&R)
 
B

Brian Drummond

function increment(T: TimeslotType) return TimeslotType is
begin
if (T = EOC_CHANNEL) then <<-- Not sure of an elegant way of
picking off the 'last' enumerated type, any ideas??

If enumerations are scalar types, all the scalar type attributes should
apply.

Aren't 'left, 'right, 'high 'low and 'range defined for enumerations?

- Brian
 
M

Martin Thompson

KJ said:
The increment would make sense if you define simply define an increment
function for the enumerated type something like....

function increment(T: TimeslotType) return TimeslotType is
begin
if (T = EOC_CHANNEL) then <<-- Not sure of an elegant way of
picking off the 'last' enumerated type, any ideas??

TimeslotType'right does that.
<snip the rest>

Cheers,
Martin
 
M

Mike Treseler

Brian said:
Aren't 'left, 'right, 'high 'low and 'range defined for enumerations?

All except for 'range which is an array attribute.
An enumeration is a type declaration
whose identifier is already a valid range.

-- Mike Treseler
 
K

KJ

Brian, Mike, Martin

Thanks, I thought I had tried 'right, looked it up in the books and
convinced myself (in the heat of better things to do though) that 'left and
'right didn't work but maybe I was confusing it with something else and
'range (which sounds like from Mike that that doesn't work). Getting old is
hard on the gray matter.

KJ
 
M

Mike Treseler

KJ said:
Brian, Mike, Martin

Thanks, I thought I had tried 'right, looked it up in the books and
convinced myself (in the heat of better things to do though) that 'left and
'right didn't work but maybe I was confusing it with something else and
'range (which sounds like from Mike that that doesn't work). Getting old is
hard on the gray matter.

I wouldn't say "doesn't work" I would say _not necessary_
since my_enum_t can be used directly as a range without
any attribute.

-- Mike Treseler
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top