New keyword 'orif' and its implications

M

Mike Treseler

Jonathan said:
What Weng is very reasonably trying to
do is to find a way to capture known mutual exclusivity
in situations that are much less self-evident than
my example, and in which no simple re-coding could
capture the required knowledge. The results of my
little synthesis experiment shows that this is worth
trying to achieve.

This is interesting from a language point of view
but I am not convinced that it would make my job
any easier. I use lots of enumeration types in my code
and have not suffered (so far) with a synthesis setting
of AUTO. With quartus and ise this usually results
in a binary encoding for small enums and one-hot
for larger ones.

My point is that, until I inadvertently
set off this thread, I have not
had to invest any intellectual effort in considering
the synthesis details of enumeration encoding and decoding.

I have played with changing the AUTO setting to binary,
because this is what I used in the 22v10 days
when I had no choice but to do this by hand.
This costs a trifling amount of resources,
but since synthesis is willing to keep track
of the vector encoding, I have no good reason not
to stick with AUTO.

Does anyone have a synthesis example where
describing such enum encoding details in my code
is a big win?
Note, for the avoidance of any confusion, that I am
NOT hereby advocating the "orif" proposal.

So say we all.

-- Mike Treseler
 
K

KJ

Sure. See code below.

[snip]

Sorry Kevin, this has not even slightly convinced me. Your Receiver
has statically-guaranteed mutual exclusivity because the communication
path from transmitter to receiver was an enumeration.
Rather than converting enum->SLV->enum as you claim, you're
doing SLV->enum->SLV (with the enum re-coded as SLV by the tool)
which is quite different.

I think you read more into this than was intended. What Marcus had
asked for (or at least what I thought he had asked for) was example
code showing that the conversion of an enumerated type to and from a
std_logic_vector really took 0 logic elements.

It really had nothing to do with Weng's 'orif'. The branch that this
sub-topic was on started because you challenged me to optomize across
entity boundaries where the interface between the entities is a
std_logic_vector (or something along those lines). My sample code
conversion was slv->enum->slv, although the reverse of what I had
stated, simply because the synthesizer does not make the assumption
that I/O pins are mutually exclusive so putting an enumerated type as
pins of the FPGA can be problematic. Since I was not trying to
demonstrate optomization across FPGA boundaries, I made that change.
While that point IS relevant to Weng's 'orif' (but also likely
solvable by the sum of products), my posting was simply to show that
conversions can be made internal to a single FPGA design to and from
enumerated type using std_logic_vectors as the interface between
entities and it will incur no synthesis cost in terms of resource
usage....that's all.

Just to show that things can go the other way as well though, I've
posted code at the end that does the following conversions in separate
entities:
slv->enum->slv->enum->slv

Again, it takes 0 logic cells and reduces to wires in the technology
map viewer and there is an enum->slv->enum conversion inside the
design. Now you can again take issue with the fact that I'm starting
with slv but these enumerated type signals are all going to be
internal to the device but in order to produce example code
demonstrating the concept I had to bring signals out to pins otherwise
it will get reduced to 0 logic cells and 0 pins.

By the way, my conversion functions have never used if
statements....not saying they couldn't, or that if they did that they
might consume resources, just that I've never run across the need for
an if statement in a type conversion function yet and I'm happy with
the usage, the localization of stuff that tends to be 'bit twiddling'
types of operations to a single spot in the code, and of course the 0
logic resource cost.
I have a counter-example that multiplexes a 9-value enumeration or
an 8-bit std_logic_vector onto an 8-bit SLV bus, the enum being
one-hot-zero coded by a function, and the mux control being conveyed
on a separate std_logic. My receiver uses the mux control to
either drive the 8-bit SLV on to an 8-bit output port, or
drive the 8-bit one-hot-zero code on to the same 8-bit output
port using this bit of code:

if mode_i = '0' then -- receive an operation code
if data_i(0) = '1' then opr_o <= X"01" ;
elsif data_i(1) = '1' then opr_o <= X"02" ;
elsif data_i(2) = '1' then opr_o <= X"04" ;
elsif data_i(3) = '1' then opr_o <= X"08" ;
elsif data_i(4) = '1' then opr_o <= X"10" ;
elsif data_i(5) = '1' then opr_o <= X"20" ;
elsif data_i(6) = '1' then opr_o <= X"40" ;
elsif data_i(7) = '1' then opr_o <= X"80" ;
else opr_o <= X"00";
end if;
else -- receive an 8-bit value
opr_o <= data_i;
end if;

And, surprise surprise, NO synth tool I've yet tried can
automatically infer that the various branches of the long
if-elsif are mutually exclusive, even though I've put all
the relevant modules in a single file and, taking the
design as a whole, the mutual exclusivity can easily be
proven. I get truckloads of redundant logic.

Maybe you should consider my approach of constructing simple type
conversion functions to/from an enumerated type, you likely won't need
the big 'if' statement in those functions which is a likely cause of
the redundant logic you're seeing....just speculating though, you
certainly know your particular code better than I.

Now, I am fully aware that I could easily re-code this
no-op decoder in a different way that would give me
the wires-only hardware I desire. But any such coding
would inherently capture my knowledge of the mutual
exclusivity.

Sounds like a good approach to me.
What Weng is very reasonably trying to
do is to find a way to capture known mutual exclusivity
in situations that are much less self-evident than
my example, and in which no simple re-coding could
capture the required knowledge. The results of my
little synthesis experiment shows that this is worth
trying to achieve.

Again though, your simple experiment may not really be demonstrating
what problem really can best be solved by 'orif' as opposed to
enumerated types or sum of products....which is where we were at a
couple days ago in this thread when the question was raised about just
what problem is Weng trying to solve? Or more to the point, how come
there is no actual good example of such a problem that 'orif' is a
better solution than the current forms? Fitting all control logic
into an 'if' statement (Weng's stated goal) is a solution to WHAT
problem?
Note, for the avoidance of any confusion, that I am
NOT hereby advocating the "orif" proposal.
--

And I am neither an advocate nor a detractor of 'orif'. I rail
against the unsubstantiated claims mostly.

KJ
---- START OF UPDATED CODE ----
entity Junk is port(
Gazinta1: in std_ulogic_vector(2 downto 0);
Gazouta1: out std_ulogic_vector(2 downto 0);

Gazinta2: in std_ulogic_vector(2 downto 0);
Gazouta2: out std_ulogic_vector(2 downto 0));
end Junk;

architecture RTL of Junk is
signal My_Type_Signal: work.pkg_My_Package.My_Type;
signal My_Type_Signal2 : work.pkg_My_Package.My_Type;
signal My_Type_Signal3 : work.pkg_My_Package.My_Type;
signal my_slv : std_ulogic_vector(2 downto 0);
begin
XMIT1 : entity work.Transmitter port map(Gazinta1, My_Type_Signal);
RCV1 : entity work.Receiver port map(My_Type_Signal, Gazouta1);

RCV2A : entity work.Transmitter port map(Gazinta2,
My_Type_Signal2);
RCV2B : entity work.Receiver port map(My_Type_Signal2, my_slv);
XMIT2 : entity work.Transmitter port map(my_slv, My_Type_Signal3);
RCV2C : entity work.Receiver port map(My_Type_Signal3, Gazouta2);
end RTL;
---- END OF UPDATED CODE ----
 
A

Andy

Hi Andy,
Now it is clear to me, if not to you,

What assertion onehot0() can do, orif can do better !

"You can NEVER use a parameterized loop of if-then structures"

It is wrong now after our long discussions.

Whenever you write a loop and try to transfer mutually exclusive
information into it, you must remember that you must clearly write
'if..elsif..." structure, then each elsif is a perfect candatate to be
replaced within your loop.

Weng,

Neither of your statements is true.

With 'orif' you must have all of your mutually exclusive (orif)
conditions in a single if-orif tree. 'orif' statements in different if-
orif trees have no context relative to each other, and therefore
cannot indicate mutual exclusivity. For example:

if a = '1 then
z <= x;
orif b = '1' then -- a and b are mutex
z <= y;
end if;

if c = '1' then
g <= e;
orif d = '1' then -- c and d are mutex
g <= f;
end if;

Note that the above does not indicate that a and c are mutex, nor
would you want it to, because then how would you code it such that a
and c are NOT mutex, but both are executed (so you could not use
elsif). For practical reasons, the scope of the mutual exclusivity
must be limited to the same if- or elsif- tree.

You can only unroll a loop of if-then statements into a single if-orif
tree if you know the number of choices when you write it. Otherwise,
you must use a loop with an if-then statement, using a parameter to
determine the number of loop iterations. The if-then statement in the
loop unrolls during synthesis to become separate if-then statements,
so even if there was an orif in the loop's if-then statement, it would
be meaningless between the separate, unrolled if-then statements. The
parameter to control loop iterations may be related to a generic, or
to the size of an unconstrained array port, so you could not possibly
know it ahead of time and manually transform the loop into an if-orif
tree.
REMEMBER: if you want to use assertion onehot0() to transfer mutually
exclusive information, all signals in onehot() entries must be used
after keywords if and elsif. Other coding short cut would leave the
information useless and wastful.

An example of using an assertion without an associated if-then
statement:

Case state_a is
....
when multiply_a =>
x <= y * z;
....
end case.
....
case state_b is
....
when multiply_b =>
a <= b * c;
....
end case;
....
assert zero_one_hot((state_a=multiply_a, state_b=multiply_b));

The assertion could tell the synthesis tool that only one physical
multiplier is needed.

Andy
 
A

Andy

"Conversely, there are several situations where
'orif' is not an option, but an assertion would be. "

NEVER !

If you have an example to support your opinion, I would recall my
propose forever.

Weng,

If you can re-write the following with an if-orif tree to indicate
that every element in enable is mutually exclusive, then you win!

BTW, the range of enable is unknown, but somewhere within the range of
integer'low to integer'high, if that helps.

type data_t is array (enable'range) of std_logic_vector(output'range);
signal data: data_t; -- could be a port instead...
....
for i in enable(i) loop
if enable(i) = '1' then
output <= data(i);
exit;
end if;
end loop;
assert zero_one_hot(enable);

Andy
 
A

Andy

KJ,

I understand what you are trying to demonstrate, but I don't think
that is what we're asking for.

What we want is a way to take an input slv for which we are certain
that exactly one of those bits is set at any given time (one-hot,
mutually exclusive), and convert that slv into an output integer that
is the index of the bit that is set, with no priority encoding, etc.
An integer is sufficient because integer encodings are by definition
mutually exclusive. Also enumerated types are impossible to define
with an arbitrary (parameterized) number of possible values.

Now, we know this can be done with boolean equations, but can you do
it in behavioral code without resorting to boolean operations (and,
or, etc.). I think it can be done with a case statement (and std_logic
types), but I'm not sure whether most synthesis tools will "take the
bait":

case input is
when "0001" => output <= "00";
when "0010" => output <= "01";
when "0100" => output <= "10";
when "1000" => output <= "11";
when others => output <= "--";
end case;

For a loop implementation:

variable temp : slv(input'range);
output <= (others => '-');
for i in input'range loop
temp := (others => '0');
temp(i) := '1';
if input = temp then
output <= slv(to_unsigned(i, output'length));
end if;
end loop;

Now, if I convert the integer encoding back to one hot:

result := (others => '0');
result(to_integer(unsigned(output))) := '1';


However, if this string of logic is synthesized, It will not reduce to
wires (because we had to use binary encoding because we had an
arbitrary number of inputs).

So, I would presume that, for an arbitrary number of mutually
exclusive inputs, there is no conversion from one hot to any mutually
exclusive encoding and back that reduces to wires.

Therefore, we need a method to do that.

Andy
 
W

Weng Tianxiang

Weng,

If you can re-write the following with an if-orif tree to indicate
that every element in enable is mutually exclusive, then you win!

BTW, the range of enable is unknown, but somewhere within the range of
integer'low to integer'high, if that helps.

type data_t is array (enable'range) of std_logic_vector(output'range);
signal data: data_t; -- could be a port instead...
...
for i in enable(i) loop
if enable(i) = '1' then
output <= data(i);
exit;
end if;
end loop;
assert zero_one_hot(enable);

Andy

Hi Andy,

Your code:
for i in enable(i) loop
if enable(i) = '1' then
output <= data(i);
exit;
end if;
end loop;
assert zero_one_hot(enable); <-- useless and wasting time in its
purpose

My code:
for i in enable(i) loop
if enable(i) = '1' then
output <= data(i);
exit;
end if;
end loop;

Why do you need to tell VHDL compiler that every element in enable is
mutually exclusive?

My coding has already told VHDL compiler that
1. all enable(i) are mutually exclusive;
2. You don't have to do anything, I have done it for you and please
take the rest.

If you really want to tell SIMULATOR the information, it has nothing
to do with orif. You may write any function following assertion
statement without any problem.

Target to transfer mutually exclusive information to VHDL compiler is
the pivotal point. VHDL compiler fails to do a better job because VHDL
language lacks elements concisely, relaibly, easily and safely to
transfer the mutually exclusive information to VHDL compiler, not to
SIMULATOR.

VHDL doesn't lack tools to transfer any information to SIMULATORS.
Assertion have already been there for the purpose since its birth.

Jim just unexpertly devised a mechanism that is almost useless in its
purpose.

I would like to thank for your discussion on this topics, because
through our discussions I realized that if one wants to transfer
mutually exclusive information to VHDL compiler, he must stick with
the 'if...end if' statement strucure. Before it, I failed to recognize
it. This is what I said you had given me as a gift.

Please declare who is the
wiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiner.

Weng
 
J

Jim Lewis

Weng,
Jim just unexpertly devised a mechanism that is almost
useless in its purpose.
What do you hope to accomplish by belittling other people?
This is not going to help promote your thoughts.

Please note, I did not participate in the PSL effort, I simply
observed that PSL (with the Accellera VHDL-2006 integration)
provides a capability that seems to address a number of the
use cases you are implying you need.

I would like to thank for your discussion on this topics, because
through our discussions I realized that if one wants to transfer
mutually exclusive information to VHDL compiler, he must stick with
the 'if...end if' statement strucure. Before it, I failed to recognize
it. This is what I said you had given me as a gift.
Yet you have failed to demonstrate anything to anyone
other than yourself.

Unfortunately, your ideas will not go anywhere unless someone
follows the steps I outlined previously. All proposals put
forward to the working group must go through these steps
of analysis of both the capability requested and the
proposed solution. At this point, I don't see anyone
as excited as yourself to handle this.

Please declare who is the
wiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiner.
Any volunteers :)

Cheers,
Jim
 
J

Jim Lewis

Andy and Weng,
Andy's code:
for i in enable(i) loop
if enable(i) = '1' then
output <= data(i);
exit;
end if;
end loop;
assert zero_one_hot(enable); <-- useless and wasting time in its
purpose

Weng's code:
for i in enable(i) loop
if enable(i) = '1' then
output <= data(i);
exit;
end if;
end loop;

I note that both of these have priority built into
the logic as the exit makes only the first enable set
take effect. Hence, without additional information (such as
the assertion), a synthesis tool will be obliged to create
the priority that is in the code.

If we really want mutually exclusive logic, then perhaps
a variable will do the trick. For give me if someone else
already suggested this as I have not re-read the threads.

process (enable, data)
variable vOutput : std_logic_vector(...) ;
begin
vOutput := (others => '0') ; -- assuming combinational logic
for i in enable'range loop
if enable(i) = '1' then
vOutput := data(i) or vOutput ;
end if;
end loop;
Output <= vOutput ;
end process ;

For those that like testing code on synthesis tools, I would
be curious to know how that plays the following (which is more
hardware implementation specific):

process (enable, data)
variable vOutput : std_logic_vector(...) ;
begin
vOutput := (others => '0') ; -- assuming combinational logic
for i in enable'range loop
vOutput := (data(i) and enable(i)) or vOutput ; -- vhdl-2006 "and"
end loop;
Output <= vOutput ;
end process ;


If you are coding this in a clocked process, you can put guard on
the enable using the reduction form of or (from VHDL-2006) or replace
it with or_reduce from ieee.std_logic_misc (not a standard package and
hence not recommended by me):

process (Clk)
variable vOutput : std_logic_vector(...) ;
begin
if rising_edge(Clk) then
if OR( enable) = '1' then
vOutput := (others => '0') ; -- assuming combinational logic
for i in enable'range loop
vOutput := (data(i) and enable(i)) or vOutput ; -- vhdl-2006 "and"
end loop;
Output <= vOutput ;
end if ;
end if ;
end process ;


Cheers,
Jim
SynthWorks VHDL Training
 
M

Michael Jørgensen

Andy said:
KJ,

I understand what you are trying to demonstrate, but I don't think
that is what we're asking for.

What we want is a way to take an input slv for which we are certain
that exactly one of those bits is set at any given time (one-hot,
mutually exclusive), and convert that slv into an output integer that
is the index of the bit that is set, with no priority encoding, etc.
An integer is sufficient because integer encodings are by definition
mutually exclusive. Also enumerated types are impossible to define
with an arbitrary (parameterized) number of possible values.

Now, we know this can be done with boolean equations, but can you do
it in behavioral code without resorting to boolean operations (and,
or, etc.). I think it can be done with a case statement (and std_logic
types), but I'm not sure whether most synthesis tools will "take the
bait":

case input is
when "0001" => output <= "00";
when "0010" => output <= "01";
when "0100" => output <= "10";
when "1000" => output <= "11";
when others => output <= "--";
end case;

For a loop implementation:

variable temp : slv(input'range);
output <= (others => '-');
for i in input'range loop
temp := (others => '0');
temp(i) := '1';
if input = temp then
output <= slv(to_unsigned(i, output'length));
end if;
end loop;

Now, if I convert the integer encoding back to one hot:

result := (others => '0');
result(to_integer(unsigned(output))) := '1';


However, if this string of logic is synthesized, It will not reduce to
wires (because we had to use binary encoding because we had an
arbitrary number of inputs).

So, I would presume that, for an arbitrary number of mutually
exclusive inputs, there is no conversion from one hot to any mutually
exclusive encoding and back that reduces to wires.

Therefore, we need a method to do that.

This is an interesting example. I tried your above example on Quartus 7.1
(see complete code below), and indeed it leads to a sub-optimal logic
design. Running a gate-level simulation shows that the circuit behaves
correctly when the input is one-hot, i.e. "0001" -> "0001", "0010" ->
"0010", etc. The most optimal implementation would be straight wires, but
the netlist generated contains a number of ALUT's. (Interestingly enough,
the input signal input[0] is not used.)

Anyway, in this simple example I would have guessed the synthesis tool to be
able to recognize that straight wires is a valid and optimal design. It
surprises me that Quartus does not recognize that.

However, this really has nothing to do with mutual exclusiveness or one-hot
encoding. This problem is more general: In a case statement, some inputs may
be specified as "don't care" behaviour. How does the synthesis tool use
those extra degress of freedom?

Returning to the OP's suggestion of using orif: In this specific example, I
don't see a need for changing the source code. It seems that all the
information necessary for the synthesis tool is already present in the
source file. Instead, this specific example shows that the synthesis tool
itself could be made smarter.

-Michael.


library ieee;
use ieee.std_logic_1164.all;

package p_test_decode is
subtype t_data is std_logic_vector(3 downto 0);
end p_test_decode;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.p_test_decode.all;

entity test_decode is
port (
input : in t_data;
output : out t_data
);
end entity test_decode;

architecture rtl of test_decode is
signal val : std_logic_vector(1 downto 0);
begin
decode: process(input) is
begin
case input is
when "0001" => val <= "00";
when "0010" => val <= "01";
when "0100" => val <= "10";
when "1000" => val <= "11";
when others => val <= "--";
end case;
end process decode;

encode: process(val) is
begin
output <= (others => '0');
output(to_integer(unsigned(val))) <= '1';
end process encode;

end architecture rtl;
 
B

Brian Drummond

Hi Andy,

Your code:
for i in enable(i) loop
if enable(i) = '1' then
output <= data(i);
exit;
end if;
end loop;
assert zero_one_hot(enable); <-- useless and wasting time in its
purpose

My code:
for i in enable(i) loop
if enable(i) = '1' then
output <= data(i);
exit;
end if;
end loop;

Why do you need to tell VHDL compiler that every element in enable is
mutually exclusive?

My coding has already told VHDL compiler that
1. all enable(i) are mutually exclusive;
2. You don't have to do anything, I have done it for you and please
take the rest.

Unfortunately, enable was accidentally set to "00010111"

Andy's code caught the problem before synthesis, so he fixed it.
Because his synthesis tool (the 2008 version) understood the assertion,
it was free to generate fast logic instead of following the priority.

Yours did not, and if your synthesis tool believed statement (1) above,
instead of following the priority built into the loop, it enabled four
drivers onto the "output" bus at once.

While you contemplate the smoking remains of your chip, you are invited
to explain how your comment "What assertion onehot0() can do, orif can
do better !" applies to this example.

- Brian
 
A

Andy

Weng,

To elaborate on what Jim and Brian have stated, In the loop, in order
for enable(n) to be considered, enable(n-1) must have been false. This
evaluation of enable(n-1) requires additional gates UNLESS there is
something else that tells the compiler (synthesis or simulation) that
the enable bits are mutually exclusive, and therefore that if
enable(n) is set, by definition enable(n-1) is not set.

It is interesting to note that the presence of the exit statement has
no effect on the synthesized gates IF enable is mutually exclusive.
However in the absence of both the exit statement and mutual
exclusivity, the last executed assignment to output wins, so enable(n)
is only used if enable(n+1) is not set, thus also requiring additional
gates.

Both of these explanations assume an index ordering of "to", not
"downto"; however, the behavior is similar (and the effect on
hardware the same) with "downto".

So, in fact your code DOES NOT demonstrate, nor optimize for, the
mutual exclusivity of the bits in enable. Contrary to your erroneous
statement, your code merely demonstrates your lack of understanding of
the significance of order of execution among sequential statements, a
fundamental concept in simulation and logic synthesis.

Jim's (and others') implementation using OR works well for data types
that support the OR operator: booleans, bits and vectors, but neither
integers, enumerated types nor other aggregate types, without a
conversion to/from an ORable data type, can use this method.

In addition, without the assertion, the (erroneous) lack of mutual
exclusivity upon which the solution depends would likely go unnoticed
in simulation. And while the ability of the simulator to use the
assertion has existed since the beginning, the ability of synthesis
tools to use the assertion (not to verify it, but to optimize
circuitry because of it) does not, to this day, exist.

Oh, and by the way, I AM THE WINNER! ;^)

Andy
 
A

Andy

Michael,

Yep, I stumbled across the lack of input(0) myself when I manually
converted it. It seems that the code assumes that EXACTLY one bit of
input is set (no bits set is not an option). So absence of the three
other bits is taken as the presence of the first bit. It may be that
if an extra bit is used to indicate that no bits were set, and that
bit used to reconstruct the one hot (er... zero one hot) vector, maybe
it would actually optimize out?

Just for grins, did you try it with one process? Perhaps the
optimization on the total stream failed because parts of it are in
separate processes. Not that this would be particularly acceptable,
since the nature of the problem we are trying to solve involves
communication between different entities, let alone different
processes.

Andy
 
W

Weng Tianxiang

Hi Brian,
1. Please write target answer's name, otherwise I may miss your
comments.

2. Before 2006, we didn't have 2006/2008 VHDL compilers available, did
you see any burning?

3. The following claim is irrelative to Andy's requirement:
"Andy's code caught the problem before synthesis, so he fixed it.
Because his synthesis tool (the 2008 version) understood the
assertion"

Andy wants me to use orif to transfer mutually exclusive information
to within loop, in this respect, no orif is needed and things are done
perfectly, because mutually exclusive Information has been clearly
transfered to within the loop by coding style.

I think it is the best explanation to your question:

Nothing is better than extra.

Whatever assertion onehot0() can do in terms of mutually exclusive
information tranfer mechanism, orif can do better, faster, safer and
more reliable !

The above sentence is too long to remember, the following sentence was
used and everyone involved knows its full meaning:
What assertion onehot0() can do, orif can do better.

I have to emphasize that onehot0() function is useful in general, but
useless in terms of its introduction purpose.

Weng
 
W

Weng Tianxiang

Andy,
Your following claim is false:
"...enable(n-1) must have been false.."

Only enable() is a static, a foolish case, the above situation would
happen and your assertion part plays a role for a VHDL compiler.

The static values may be all 0. So that no code would be generated for
the code segment. Are you serious enough to design a mechanims to deal
with the stupid case only?

It has nothing to do with mutually exclusive information.

Nothing is better than extra gabage.

Weng
 
M

Mike Treseler

Andy said:
Yep, I stumbled across the lack of input(0) myself when I manually
converted it. It seems that the code assumes that EXACTLY one bit of
input is set (no bits set is not an option). So absence of the three
other bits is taken as the presence of the first bit. It may be that
if an extra bit is used to indicate that no bits were set, and that
bit used to reconstruct the one hot (er... zero one hot) vector, maybe
it would actually optimize out?

This is just a logic minimization from 4 input to 3 input LUTs.
It follows directly from the "others" case.

I tried this both ways:

case input is
when "0001" => val <= "00";
when "0010" => val <= "01";
when "0100" => val <= "10";
when "1000" => val <= "11";
-- when others => val <= "00"; -- 4in LUT-OR, input(0) used
when others => val <= "--"; -- 3in LUT-OR input(0) ignored
end case;

So synthesis found an optimization,
It just didn't find the best one.
Just for grins, did you try it with one process?

This made no difference.

-- Mike Treseler
 
A

Andy

Andy,
Your following claim is false:
"...enable(n-1) must have been false.."

Only enable() is a static, a foolish case, the above situation would
happen and your assertion part plays a role for a VHDL compiler.

Enable() is NOT static! It is a dynamic signal/variable that is driven
from elsewhere.

Note that I said "in order for enable(n) to be considered". I did NOT
say "for enable(n) to be set"!
If enable(n-1) was set, then the loop would have exited before
evaluating enable(n). Therefore output gets data(n) only if enable(n)
= '1' AND enable(n-1) = '0' AND enable(n-2) = '0' AND... This
results in additional logic that is not necessary if it is known that
the enable bits are mutually exclusive.

If you don't believe me, compare the synthesis results of your code
with Jim's code (since the assertion in my code is not understood by
synthesis yet). Jim's code is the logical equivalent of what a
synthesis tool should implement for your code (or my code), if the
tool was aware of, and could optimize for, mutual exclusivity.
The static values may be all 0. So that no code would be generated for
the code segment. Are you serious enough to design a mechanims to deal
with the stupid case only?

Since you ask, this function is intended for a clocked process, so
"doing nothing" means maintaining the previous value (i.e. a clock
enable), which is far from a "stupid case".

Andy
 
A

Andy

This is just a logic minimization from 4 input to 3 input LUTs.
It follows directly from the "others" case.

I tried this both ways:

case input is
when "0001" => val <= "00";
when "0010" => val <= "01";
when "0100" => val <= "10";
when "1000" => val <= "11";
-- when others => val <= "00"; -- 4in LUT-OR, input(0) used
when others => val <= "--"; -- 3in LUT-OR input(0) ignored
end case;

So synthesis found an optimization,
It just didn't find the best one.


This made no difference.

-- Mike Treseler

Wow; interesting...

Thanks,

Andy
 
B

Brian Drummond

Hi Brian,
1. Please write target answer's name, otherwise I may miss your
comments.

2. Before 2006, we didn't have 2006/2008 VHDL compilers available, did
you see any burning?

Back in the TTL days, yes.
3. The following claim is irrelative to Andy's requirement:
"Andy's code caught the problem before synthesis, so he fixed it.
Because his synthesis tool (the 2008 version) understood the
assertion"

Andy wants me to use orif to transfer mutually exclusive information
to within loop, in this respect, no orif is needed and things are done
perfectly, because mutually exclusive Information has been clearly
transfered to within the loop by coding style.

it's exactly relevant because in his example, the ONLY mutually
exclusive information IS the assertion. In your counterexample I don't
see any such information, despite the fact that you are free to use
"orif".
Whatever assertion onehot0() can do in terms of mutually exclusive
information tranfer mechanism, orif can do better, faster, safer and
more reliable !

This has still not been demonstrated for this example.

- Brian
 
K

KJ

Andy said:
KJ,


The guiding principle of HDL-logic synthesis is this: The behavior
exhibited by the simulator should determine the behavior exhibited by
the hardware synthesized by the same code.

In fact the guiding principle of logic synthesis is that the behaviour
exhibited by the hardware should conform to the language specification not
'the simulator' (whatever that might be). Every tool that I've picked up
claims conformance to some flavor of VHDL (i.e. '87, '93, '02), I've yet to
pick one up that claims conformance to Modelsim 6.3a.

This may only be a matter of semantics, but the synthesis tool would
not be "checking" assertions, but merely using the information
provided by them to identify "don't care" conditions. Assertions may
provide information like: "if more than one of these bits is set, I
don't care what the hardware does, because that won't happen (and did
not happen in simulation)." The assertion gives permission to optimize
out any additional logic related to those don't care conditions.
But the logic description (i.e. everything BUT the asserts) completely
describes the logic function by definition. The asserts are:
- Generally not complete behavioural descriptions
- Unverifiable as to correctness. In fact, a formal logic checker program
would take the asserts and the logic description and formally prove (or
disprove) that the description (the non-assert statements) accurately
produce the stated behaviour (the asserts). Since formal logic checkers can
'fail' (i.e. show that incorrect behaviour can result from the given logic
description) this would tend to drive a stake completely through your claim.
The assertion IS a part of the logic description!

No, it is a (possibly incorrect) statement of what is believed to be correct
behaviour.

Repeat after me; "The 'logic function' is determined by the
simulator's behavior, which includes the assertions."
On that point, we most definitely do not agree. The non-asserts completely
define the logic function, the asserts incompletely (at least in VHDL)
describe correct behaviour.

KJ
 

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,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top