Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > the "|" operator

Reply
Thread Tools

the "|" operator

 
 
abasili
Guest
Posts: n/a
 
      11-04-2008
Hi everyone I would have liked to ask you about the difference between
the two following codes:

-- case 1

process (clk, nrst)
begin
if nrst = '0' then
En <= '0';
elsif rising_edge (clk) then
case present_state is
when S0 | S1 | S2 =>
En <= '1';
when others =>
En <= '0';
end case;
end if;
end process;

-- case 2

process (clk, nrst)
begin
if nrst = '0' then
En <= '0';
elsif rising_edge (clk) then
case present_state is
when S0 =>
En <= '1';
when S1 =>
En <= '1';
when S2 =>
En <= '1';
when others =>
En <= '0';
end case;
end if;
end process;


I found this example on few references (as the VHDL Reference Manual of
Synario design automation), but when I look at the RTL produced with
Synplify then it's clear that the compiler produces something different
in the two cases.

My logic works fine (so far) and i'm using the first case but only
recently I realized about the differences and i was wondering why the
RTLs are different and whether one syntax is more convenient than the
other one. By the way I still didn't learn what's the name of that
symbol (i know is something that produce a mutually exclusive logic) and
I didn't yet find some information through Google and some books i have.
Thanks a lot for any help or reference.

Al
 
Reply With Quote
 
 
 
 
Tricky
Guest
Posts: n/a
 
      11-04-2008
My guess would be that Synplify hasnt recognised that in the 2nd case
S0, S1 and S2 outcomes are the same, whereas in the first you have
explicitly told it so. With this being the case, you only need 1 bit
to represent "present_state", whereas in case 2 its probably given you
2 and muxed it.
 
Reply With Quote
 
 
 
 
abasili
Guest
Posts: n/a
 
      11-04-2008
Tricky wrote:
> My guess would be that Synplify hasnt recognised that in the 2nd case
> S0, S1 and S2 outcomes are the same, whereas in the first you have
> explicitly told it so. With this being the case, you only need 1 bit
> to represent "present_state", whereas in case 2 its probably given you
> 2 and muxed it.


present_state is not defined here, so the number of bit associated with
it can be anything. According to the present_state definition (which is
elsewhere), the second case generates only a mux to generate En, while
in apparently in the first case it has an additional OR which i don't
know where it comes from.
The so called "vertical bar" (or "vertical line") apparently is needed
for mutually exclusive choices, as it should be in a case statement, so
the outcome should always be a mux, but I don't understand why the two
RTL are different.
Am I missing something? Probably yes
 
Reply With Quote
 
KJ
Guest
Posts: n/a
 
      11-04-2008
On Nov 4, 3:25*am, abasili <(E-Mail Removed)> wrote:
> I found this example on few references (as the VHDL Reference Manual of
> Synario design automation), but when I look at the RTL produced with
> Synplify then it's clear that the compiler produces something different
> in the two cases.
>


You might want to recheck what you're seeing, I couldn't reproduce
your results. At the end of this post is a complete design that
incorporates your logic. What I added to it to make it complete is an
entity and logic to cycle 'present_state' through it's various values.

Given this design, whether I use the 'case 1' approach or the 'case 2'
approach Synplify (vers 9.6.1) appears to produce the exact same RTL
and Technology views which is what is expected.

> My logic works fine (so far) and i'm using the first case but only
> recently I realized about the differences and i was wondering why the
> RTLs are different


Maybe you changed something else in your code between when you tried
'case 1' and 'case 2'.

As an example, take a look at the code I added for driving the signal
'present_state'. What I have is a simple two bit roll over counter
that produces an index and then I convert that index to a valid
't_state' for the assignment to 'present_state'. If instead of an
unsigned counter you simply write code for 'present_state' that simply
cycles through 'S0'...'S3' you'll likely get a different RTL and Tech
view because Synplify might implement 'present_state' in one hot form
(i.e. use four flops, only one of which is '1' at any given time).
However, when you switch between 'case 1' and 'case 2' I think you'll
still end up with the same thing, just not the same as with my posted
code. If you then tell Synplify to use binary encoding instead of one
hot or default then you should end up with the same RTL/Tech view as
with my posted code. It could simply be that whatever you changed
when testing 'case 1' and 'case 2' changed something else that caused
'present_state' to be implemented differently.

Assuming that the above is the explanation for the differences that
you're seeing, then all you're seeing is the result of different
implemenation approaches (one hot versus binary encoding). Whether
one is 'better' or not depends on what your criteria for 'better' is.
For the most part the synthesis tool writers know the devices very
well and the resulting logic fits and meets timing which is the real
bottom line.

> and whether one syntax is more convenient than the
> other one.


The first form had less typing and is probably less prone to making
errors.

Kevin Jennings

-- Start of code
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Foo is
port(
clk: in std_ulogic;
nrst: in std_ulogic;
en: out std_ulogic);
end Foo;

architecture RTL of Foo is
type t_state is (S0, S1, S2, S3);
signal present_state: t_state;
signal counter: unsigned(1 downto 0);
begin

process(clk)
begin
if rising_edge(clk) then
if (nrst = '0') then
counter <= to_unsigned(0, counter'length);
else
counter <= counter + 1;
end if;
end if;
end process;

present_state <= t_state'val(to_integer(counter));

process (clk, nrst)
begin
if nrst = '0' then
En <= '0';
elsif rising_edge (clk) then
case present_state is
when S0 | S1 | S2 =>
En <= '1';
when others =>
En <= '0';
end case;
end if;
end process;


-- case 2


--Case 2 process (clk, nrst)
--Case 2 begin
--Case 2 if nrst = '0' then
--Case 2 En <= '0';
--Case 2 elsif rising_edge (clk) then
--Case 2 case present_state is
--Case 2 when S0 =>
--Case 2 En <= '1';
--Case 2 when S1 =>
--Case 2 En <= '1';
--Case 2 when S2 =>
--Case 2 En <= '1';
--Case 2 when others =>
--Case 2 En <= '0';
--Case 2 end case;
--Case 2 end if;
--Case 2 end process;

end RTL;
-- End of code
 
Reply With Quote
 
abasili
Guest
Posts: n/a
 
      11-05-2008
KJ wrote:
> As an example, take a look at the code I added for driving the signal
> 'present_state'. What I have is a simple two bit roll over counter
> that produces an index and then I convert that index to a valid
> 't_state' for the assignment to 'present_state'. If instead of an
> unsigned counter you simply write code for 'present_state' that simply
> cycles through 'S0'...'S3' you'll likely get a different RTL and Tech
> view because Synplify might implement 'present_state' in one hot form
> (i.e. use four flops, only one of which is '1' at any given time).


Most probably I was not focusing on the "present_state" implementation
which might have been different in the two cases (even though I don't
understand why) and this of course affected the way the rest of the
logic I was focusing on did change.

> Assuming that the above is the explanation for the differences that
> you're seeing, then all you're seeing is the result of different
> implemenation approaches (one hot versus binary encoding). Whether
> one is 'better' or not depends on what your criteria for 'better' is.
> For the most part the synthesis tool writers know the devices very
> well and the resulting logic fits and meets timing which is the real
> bottom line.
>


Totally agree, optimization is always a very delicate point and I do
believe tools are much more advanced than users to optimize code.
Usually I first try to make it working, than maybe I will "beautify" it.

>> and whether one syntax is more convenient than the
>> other one.

>
> The first form had less typing and is probably less prone to making
> errors.


I think it facilitates readability of the code as well and it's easier
to maintain.
>
> Kevin Jennings
>
> -- Start of code
> library ieee;
> use ieee.std_logic_1164.all;
> use ieee.numeric_std.all;
> entity Foo is
> port(
> clk: in std_ulogic;
> nrst: in std_ulogic;
> en: out std_ulogic);
> end Foo;
>
> architecture RTL of Foo is
> type t_state is (S0, S1, S2, S3);
> signal present_state: t_state;
> signal counter: unsigned(1 downto 0);
> begin
>
> process(clk)
> begin
> if rising_edge(clk) then
> if (nrst = '0') then
> counter <= to_unsigned(0, counter'length);
> else
> counter <= counter + 1;
> end if;
> end if;
> end process;
>
> present_state <= t_state'val(to_integer(counter));
>
> process (clk, nrst)
> begin
> if nrst = '0' then
> En <= '0';
> elsif rising_edge (clk) then
> case present_state is
> when S0 | S1 | S2 =>
> En <= '1';
> when others =>
> En <= '0';
> end case;
> end if;
> end process;
>
>
> -- case 2
>
>
> --Case 2 process (clk, nrst)
> --Case 2 begin
> --Case 2 if nrst = '0' then
> --Case 2 En <= '0';
> --Case 2 elsif rising_edge (clk) then
> --Case 2 case present_state is
> --Case 2 when S0 =>
> --Case 2 En <= '1';
> --Case 2 when S1 =>
> --Case 2 En <= '1';
> --Case 2 when S2 =>
> --Case 2 En <= '1';
> --Case 2 when others =>
> --Case 2 En <= '0';
> --Case 2 end case;
> --Case 2 end if;
> --Case 2 end process;
>
> end RTL;
> -- End of code

 
Reply With Quote
 
abasili
Guest
Posts: n/a
 
      11-05-2008
Mike Treseler wrote:
> The RTL viewer shows a logical netlist *before* optimization.
> Small differences that are logically correct can be safely ignored.
>

But still when at least I write code I have some RTL in mind and if
there are some differences than maybe I'm not completely understanding
what I'm doing, which means that something is wrong in my hardware
description.

> If I am debugging synth code on the simulator,
> there is no need to worry about the state encoding.
> I just view the state as an enumeration.
> I describe outputs in terms of enum values.
> I let synthesis use its default encoding.
> There is no need for me to even know what
> the encoding is.
>


That's true, but I guess we are interested in implementation as well,
otherwise we will have hard time to fit the logic into the device, no?

> If I did care about the encoding,
> I shouldn't be using an enumeration in the first place.
>


Also true, but again that means your are interested in the
implementation in the very first place. You may want to have different
strategies even though your logic works perfectly in simulation. Maybe I
don't trust that much the simulation tool, especially because I don't
have a very good experience with "test patterns", but most of all
because I found it hard to simulate the whole environment your logic
will work in.

Al

> -- Mike Treseler

 
Reply With Quote
 
Mike Treseler
Guest
Posts: n/a
 
      11-05-2008

> Mike Treseler wrote:
>> The RTL viewer shows a logical netlist *before* optimization.
>> Small differences that are logically correct can be safely ignored.


abasili wrote:
> But still when at least I write code I have some RTL in mind and if
> there are some differences than maybe I'm not completely understanding
> what I'm doing, which means that something is wrong in my hardware
> description.


.... or maybe synthesis found a better way to pack the gates.
The only way to be sure the code does what I expect
is to run a sim.
>> There is no need for me to even know what
>> the encoding is.


abasili wrote:
> That's true, but I guess we are interested in implementation as well,
> otherwise we will have hard time to fit the logic into the device, no?


To really count registers and LUTs and verify timing,
I have to run a full synthesis, which takes
much longer than a sim, and tells me little about
how the design functions.

-- Mike Treseler
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
T::operator int () const ambiguous with T::operator Handle () const? Tim Clacy C++ 15 05-30-2005 02:14 AM
Member operators operator>>() and operator<<() Alex Vinokur C++ 3 03-20-2005 03:11 PM
operator*(Foo) and operator*(int) const: ISO C++ says that these are ambiguous: Alex Vinokur C++ 4 11-26-2004 11:46 PM
Operator overloading on "default" operator John Smith C++ 2 10-06-2004 10:22 AM
Q: operator void* or operator bool? Jakob Bieling C++ 2 03-05-2004 04:27 PM



Advertisments