Using std_ulogic at synthesis level

  • Thread starter alessandro.strazzero@gmai
  • Start date
A

alessandro.strazzero@gmai

Guest
Dear everybody,

in the following piece of code ...

if sRxOld /= iRx then
if vHIGH >= T_500ns then
sBit <= 'U';
elsif vLOW >= T_500ns then
sBit <= 'U';
elsif vLH = '1' then
sBit <= '0';
else
sBit <= '1';
end if;
else
sBit <= 'X';
end if;

.... I assign the sBit signal of type std_ulogic to 'U', '0', '1' and
'X'. Then, anywhere in the code, I have a sequential
statement like this: if sBit /= 'X' then ...

My question is: when the VHDL is synthesized how the 'X' state is
represented ? Is the FPGA able to
distinguish between the 'X' state and '0' or '1' state ?

Best Regards

/Alessandro
 
On 22 July, 10:14, "alessandro.strazz...@gmail.com"
<alessandro.strazz...@gmail.com> wrote:
Dear everybody,

in the following piece of code ...

                        if sRxOld /= iRx then
                          if vHIGH >= T_500ns then
                            sBit <= 'U';
                          elsif vLOW >= T_500ns then
                            sBit <= 'U';
                          elsif vLH = '1' then
                            sBit <= '0';
                          else
                            sBit  <= '1';
                          end if;
                        else
                          sBit <= 'X';
                        end if;

... I assign the sBit signal of type std_ulogic to 'U', '0', '1' and
'X'. Then, anywhere in the code, I have a sequential
statement like this: if sBit /= 'X' then ...

My question is: when the VHDL is synthesized how the 'X' state is
represented ? Is the FPGA able to
distinguish between the 'X' state and '0' or '1' state ?

Best Regards

/Alessandro
Any input can only see a "1" or a "0". Although if the input is near
the voltage where it has to decide then it will take a random amount
of time to make up its mind and noise could make it change its mind.

I wonder why we don't get this sort of thing as often as we used to?

Colin
 
On 7/22/2010 6:20 AM, colin wrote:
On 22 July, 10:14, "alessandro.strazz...@gmail.com"
alessandro.strazz...@gmail.com> wrote:
Dear everybody,

in the following piece of code ...

if sRxOld /= iRx then
if vHIGH>= T_500ns then
sBit<= 'U';
elsif vLOW>= T_500ns then
sBit<= 'U';
elsif vLH = '1' then
sBit<= '0';
else
sBit<= '1';
end if;
else
sBit<= 'X';
end if;

... I assign the sBit signal of type std_ulogic to 'U', '0', '1' and
'X'. Then, anywhere in the code, I have a sequential
statement like this: if sBit /= 'X' then ...

My question is: when the VHDL is synthesized how the 'X' state is
represented ? Is the FPGA able to
distinguish between the 'X' state and '0' or '1' state ?

Best Regards

/Alessandro

Any input can only see a "1" or a "0". Although if the input is near
the voltage where it has to decide then it will take a random amount
of time to make up its mind and noise could make it change its mind.

I wonder why we don't get this sort of thing as often as we used to?

Colin
Although this brings up a (fairly tool dependent) question that I've
had. If I assign a don't care output '-' (or an X or a U for that
matter) what happens? For instance, I just used in a project:

-- Start by setting up the address
C_addr <= (others => '-');

case TO_INTEGER(FCTL_I.ADDR) is
when REG_FIRST_COEF to REG_LAST_COEF =>
C_addr(7) <= '0';
C_addr(6 downto 5) <= UNSIGNED(fcsel_channel);
C_addr(4) <= fcsel_rt;
C_addr(3 downto 0) <= FCTL_I.ADDR(3 downto 0);

when REG_FIRST_CAL to REG_LAST_CAL =>
C_addr(7) <= '1';
C_addr(6 downto 5) <= UNSIGNED(fcsel_channel);
C_addr(0) <= FCTL_I.ADDR(0);

when others =>
C_we <= (others => false);

end case;

Now, I know what would happen if I were sitting around drawing Karnaugh
maps for these terms; C_addr(4) would always be equal to fcsel_rt,
regardless of FCTL_I.ADDR. What I don't know is whether or not XST is
smart enough to handle that don't care correctly, or whether all don't
care values get mapped to '0'. What about Quartus? What about
Synplicity? What about more complicated cases such as the following
inferred RAM, in which the bottom 7 bits of addr can always be used to
address the RAM?

if (addr < 128) then
dout <= RAM(addr);
else
dout <= (others => '-');
end if;

--
Rob Gaddi, Highland Technology
Email address is currently out of order
 
On Thu, 22 Jul 2010 09:50:33 -0700, Rob Gaddi <rgaddi@technologyhighland.com>
wrote:

Although this brings up a (fairly tool dependent) question that I've
had. If I assign a don't care output '-' (or an X or a U for that
matter) what happens? For instance, I just used in a project:

-- Start by setting up the address
C_addr <= (others => '-');

case TO_INTEGER(FCTL_I.ADDR) is
when REG_FIRST_COEF to REG_LAST_COEF =
C_addr(7) <= '0';
C_addr(6 downto 5) <= UNSIGNED(fcsel_channel);
C_addr(4) <= fcsel_rt;
C_addr(3 downto 0) <= FCTL_I.ADDR(3 downto 0);

when REG_FIRST_CAL to REG_LAST_CAL =
C_addr(7) <= '1';
C_addr(6 downto 5) <= UNSIGNED(fcsel_channel);
C_addr(0) <= FCTL_I.ADDR(0);

when others =
C_we <= (others => false);

end case;

Now, I know what would happen if I were sitting around drawing Karnaugh
maps for these terms; C_addr(4) would always be equal to fcsel_rt,
regardless of FCTL_I.ADDR. What I don't know is whether or not XST is
smart enough to handle that don't care correctly, or whether all don't
care values get mapped to '0'. What about Quartus? What about
Synplicity?
I wouldn't necessarily trust even different versions of XST to do the same
thing. As long as there is no extra cost in LUTs to either approach, the synth
tool can do either. But I probably wouldn't care.

If I did, I would code to more accurately reflect what I wanted : in this case,
that would probably involve a separate case statement (or IF, or simple
assignment for bits 4,5,6) for each bit group in the signal.

- Brian
 
On Jul 22, 3:14 pm, Brian Drummond <brian_drumm...@btconnect.com>
wrote:
On Thu, 22 Jul 2010 09:50:33 -0700, Rob Gaddi <rga...@technologyhighland.com
wrote:



Although this brings up a (fairly tool dependent) question that I've
had.  If I assign a don't care output '-' (or an X or a U for that
matter) what happens?  For instance, I just used in a project:

    -- Start by setting up the address
    C_addr  <= (others => '-');

    case TO_INTEGER(FCTL_I.ADDR) is
        when REG_FIRST_COEF to REG_LAST_COEF =
            C_addr(7)           <= '0';
            C_addr(6 downto 5)  <= UNSIGNED(fcsel_channel);
            C_addr(4)           <= fcsel_rt;
            C_addr(3 downto 0)  <= FCTL_I.ADDR(3 downto 0);

        when REG_FIRST_CAL to REG_LAST_CAL =
            C_addr(7)           <= '1';
            C_addr(6 downto 5)  <= UNSIGNED(fcsel_channel);
            C_addr(0)           <= FCTL_I.ADDR(0);

        when others =
            C_we <= (others => false);

    end case;

Now, I know what would happen if I were sitting around drawing Karnaugh
maps for these terms; C_addr(4) would always be equal to fcsel_rt,
regardless of FCTL_I.ADDR.  What I don't know is whether or not XST is
smart enough to handle that don't care correctly, or whether all don't
care values get mapped to '0'.  What about Quartus?  What about
Synplicity?  

I wouldn't necessarily trust even different versions of XST to do the same
thing. As long as there is no extra cost in LUTs to either approach, the synth
tool can do either. But I probably wouldn't care.

If I did, I would code to more accurately reflect what I wanted : in this case,
that would probably involve a separate case statement (or IF, or simple
assignment for bits 4,5,6) for each bit group in the signal.

- Brian
Actually I have found that XST is pretty good at minimizing logic
when left with don't cares. It's not just a matter of LUT's. In this
case
any dependence on FCTL_I.ADDR would add connections to
the LUT and reducing routing is another possibly more important
optimization. In fact in this case you should end up with no
LUT at all unless this logic gets flattened together with other
code.
 
On Jul 22, 12:50 pm, Rob Gaddi <rga...@technologyhighland.com> wrote:
Although this brings up a (fairly tool dependent) question that I've
had.  If I assign a don't care output '-' (or an X or a U for that
matter) what happens?  
This brings up the question of why are you asking what happens if you
assign something as don't care? Sounds like you care...or perhaps
you're just curious...and the way to satisfy curiousity is to try it
out. But don't expect or get miffed if you happen to get different
results from different tools for something you explicitly said you
don't care about.

<snip>
Now, I know what would happen if I were sitting around drawing Karnaugh
maps for these terms; C_addr(4) would always be equal to fcsel_rt,
regardless of FCTL_I.ADDR.  What I don't know is whether or not XST is
smart enough to handle that don't care correctly, or whether all don't
care values get mapped to '0'.  What about Quartus?  What about
Synplicity?  
Review the synthesis report more closely.

What about more complicated cases such as the following
inferred RAM, in which the bottom 7 bits of addr can always be used to
address the RAM?

     if (addr < 128) then
         dout <= RAM(addr);
     else
         dout <= (others => '-');
     end if;
Again, try it and find out. If you're disappointed with the results,
then you know you need to be more explicit. In this case, more
explicit is also simpler.

dout <= ram(addr mod 128);

Kevin Jennings
 
On Jul 22, 5:14 am, "alessandro.strazz...@gmail.com"
<alessandro.strazz...@gmail.com> wrote:
Dear everybody,

in the following piece of code ...

                        if sRxOld /= iRx then
                          if vHIGH >= T_500ns then
                            sBit <= 'U';
                          elsif vLOW >= T_500ns then
                            sBit <= 'U';
                          elsif vLH = '1' then
                            sBit <= '0';
                          else
                            sBit  <= '1';
                          end if;
                        else
                          sBit <= 'X';
                        end if;

... I assign the sBit signal of type std_ulogic to 'U', '0', '1' and
'X'. Then, anywhere in the code, I have a sequential
statement like this: if sBit /= 'X' then ...

My question is: when the VHDL is synthesized how the 'X' state is
represented ?
'X' is not represented, the code you have listed is not synthesizable
(1). If you run it through a synthesis tool, peruse the warnings that
get generated looking for what it has to say about lines of code where
you assign something the value of 'X' and where you compare some
signal to 'X'.

Is the FPGA able to
distinguish between the 'X' state and '0' or '1' state ?
Perhaps you review digital logic first.

Kevin Jennings

(1) The definition of 'synthesizable code' here being that any
testbench that exercises the original code, produces the same result
when exercising the synthesis output code. Exceptions for startup are
allowed, but that's it. Specifically, the definition of synthesizable
that I'm using is NOT simply that the synthesis tool produced an
output file with no errors.
 
KJ <kkjennings@sbcglobal.net> writes:

Specifically, the definition of synthesizable that I'm using is NOT
simply that the synthesis tool produced an output file with no
errors.
I like that :) I'll save that quote (attributed of course) if you don't mind?

Martin

--
martin.j.thompson@trw.com
TRW Conekt - Consultancy in Engineering, Knowledge and Technology
http://www.conekt.co.uk/capabilities/39-electronic-hardware
 
On Jul 23, 4:51 am, Martin Thompson <martin.j.thomp...@trw.com> wrote:
KJ <kkjenni...@sbcglobal.net> writes:
Specifically, the definition of synthesizable that I'm using is NOT
simply that the synthesis tool produced an output file with no
errors.

I like that :) I'll save that quote (attributed of course) if you don't mind?

Martin

--
Don't mind at all

KJ
 
On Jul 22, 9:50 am, Rob Gaddi <rga...@technologyhighland.com> wrote:

What about more complicated cases such as the following
inferred RAM, in which the bottom 7 bits of addr can always be used to
address the RAM?

     if (addr < 128) then
         dout <= RAM(addr);
     else
         dout <= (others => '-');
     end if;
Some hand-optimization might be good here:

dout <= RAM(addr);

After all, in this (likely contrived!) case, you don't care about the
assignment if the address is 128 or higher, so then not doing the
comparison at all and just doing the assignment anyway gives the best
result.

A smart synthesis tool should do that optimization.

-a
 
On Jul 23, 7:22 pm, Andy Peters <goo...@latke.net> wrote:
On Jul 22, 9:50 am, Rob Gaddi <rga...@technologyhighland.com> wrote:

What about more complicated cases such as the following
inferred RAM, in which the bottom 7 bits of addr can always be used to
address the RAM?

     if (addr < 128) then
         dout <= RAM(addr);
     else
         dout <= (others => '-');
     end if;

Some hand-optimization might be good here:

    dout <= RAM(addr);

After all, in this (likely contrived!) case, you don't care about the
assignment if the address is 128 or higher, so then not doing the
comparison at all and just doing the assignment anyway gives the best
result.

A smart synthesis tool should do that optimization.
Not quite. As I mentioned in my earlier post, the way to write the
code is
dout <= ram(addr mod 128);

If you just write "dout <= RAM(addr);" then a larger memory will be
inferred. You're assuming that addr is not something 'big' like

signal addr: natural range 0 to 1048575; -- 20 bits

Kevin Jennings
 

Welcome to EDABoard.com

Sponsor

Back
Top