K
KJ
Andy said:KJ,
I understand what you are trying to demonstrate, but I don't think
that is what we're asking for.
We? Marcus asked for an example that demonstrated enumeration conversion
functions that result in 0 logic cell usage when the two functions are in
separate entities. My code demonstrates that.
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.
What you want is not always logically achievable....in any case, you're
posing a different question, one that interests you so read on for more on
why
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,
Depending on your starting point, no you can't....again read on for more on
why.
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":
Why are you insisting on a particular form for the solution? You're just
like Weng who is trying to fit it into an if statement. I'll use the
appropriate form for the solution.
Now look at your code again. You have not really told the synthesis toolcase input is
when "0001" => output <= "00";
when "0010" => output <= "01";
when "0100" => output <= "10";
when "1000" => output <= "11";
when others => output <= "--";
end case;
that the input is one hot coded but I'll bet you think you did. To do so,
you 'should' have specified the cases as "---1", '--1-", etc. You know you
can't really do this and get the function you want (it will fail sim because
'0001' is not equal to '---1') so you chose (incorrectly) to write incorrect
case statements because you chose to use a case statement....which is the
wrong tool....just like Weng would like to augment the 'if' statement
because he wants to see everything inside an 'if' statement for whatever
reason. In any case, you haven't 'told' the synthesis tool that this is one
hot encoded, in fact you've left it up to it's discretion about how to
implement 3/4 of the cases.
Run your code through a synthesis tool and check the resource usage. Now
convert the case statement to the if/elsif form using the std_match function
instead where you match to "---1", "--1-", "-1--" and "1---" and compile
again. You'll probably find your logic resource usage drops way down (but
still not to 0 when paired with it's 'inverse' decode function).
Well OK then, now we get into the reason why what you're asking for is notNow, 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.
achievable except under certain usage conditions. In an earlier post to
Marcus I stated
"The encoding and decoding functions can be lots of things but they could
simply be a one hot coding of the enumeration list or a binary coding or
whatever"
While I think it was clear from that post that the encode/decode functions
are functional inverses of each other, an important point that I had
neglected to mention is that these functions need to operate over the same
domain (i.e. all the possible input values) if you want to be able to apply
these functions as a pair in any order and incur no logic cost. I don't
have that as a proof but I'm pretty sure that it is both necessary and
sufficient. I haven't found a case where it is not true but I'll simply
call it "KJ's postulate" since that's about all it is at that point.
If you now have two functions f(x) and g(x) that are candidate conversion
functions (but the input 'x' is not necessarily over the same domain...or in
the digital logic case it would mean that the the 'x' input into f() and g()
do not necessarily have the same number of bits) you can have the following
situations:
1. f(g(x)) = x
2. g(f(x)) /= x
I claim that if f() and g() operate over the same domain (same number of
bits), then condition #2 above will never be true and f(g(x)) = g(f(x)) = x
and the resulting implementation will be wires with no logic resource
required to synthesize.
I claim also that if f() and g() operate over different domains that if the
application USAGE is only of form #1 then the resulting implementation will
be wires with no logic resources. But if the usage is of form #2 there will
be some non zero cost to implementing and the result will not be just wires.
The example I originally put up used 'val and 'pos as the conversion
function pair. Those both operate on the same domain (i.e. the enumerated
type) so they will result in 0 logic when used as a pair in any order. I
could change that function pair to remap things however I wanted (gray code,
7 - 'pos, etc.) and this will always be true (per my first claim).
Now take as an example something to test claim 2, let's say that g(x) is a
3->8 decoder and f(x) is an 8->3 mux. This is an example where the domains
of the two functions are not the same, one works with three bits, the other
with 8. Now implement f(g(x)). The primary input is the 3 bit input which
goes through the 3-> decoder which is fed into the 8->3 mux and out the
chip. This will result in a 0 logic, 'wires' solution.
Now turn it around and implement g(f(x)). The primary input is an 8 bit
input vector which gets encoded to a 3 bit number which then gets decoded to
produce an 8 bit output. Again, implement it but now you'll find that you
get some non-zero logic. The reason is quite simple, the 3 bit code can not
possibly produce the 256 possible input values so g() and f() IN THIS USAGE
are not quite functional inverses of each other . This whole thread has
been about mutual exclusive stuff but putting that aside for a moment, and
ponder, if you have an 8 bit input and happen to set all of them to 1 and
then feed them into the mux/decode logic do you really expect that the
output will be 'FF'? It might, but you definitely won't be able to cycle
through all the input codes from "00" to "FF" and produce those same outputs
on the 8 bit output bus.
You've been preaching on about how telling the synthesis tool that these are
mutually exclusive by way of an assertion could somehow magically produce
what you'd like to see, but I don't think it can (again depending on the
usage). In my case, if there is some known mutual exclusiveness information
I start from that point (whether it's an enumerated type or a coded slv) and
know that the decode/encode process pair costs nothing in logic (but
enhances readability and maintainability) but that the encode/decode process
pair does have a non-zero cost....and of course either function by itself
has a non-zero cost to it. I'd suggest you back off on your unfounded
claims that assertions could do what you seem to think they could until you
can produce anything tangible.
KJ