Beyond Newbie Question

M

mottoblatto

I will not even consider myself a newbie in VHDL. I am trying to hack
someone else's code to do what I need it to do...which is trivial. I
am using Xilinx tools by the way.

I have a signal coming into a module:

USB_FIFODATA_I : std_logic_vector(31 downto 0);

All I want to do is make a trigger signal that asserts whenever that
input is NOT '0'.

So I have tried all the tricks I know (I don't know any tricks) and my
parser keeps giving me fits. Here's some examples of my stupidity:

trigger <= USB_FIFODATA_I /= '0';
trigger <= USB_FIFODATA_I(31 downto 0) /= '0';
trigger <= USB_FIFODATA_I /= "00000000000000000000000000000000";

Obviously, I don't know what I am doing. I have a book, but I can't
seem to find what I am looking for. Could someone please help me out
so I can debug what I need to!

Thanks!!
 
R

Ralf Hildebrandt

trigger <= USB_FIFODATA_I /= '0';

use IEEE.numeric_std.all;

trigger<='1' when ( to_01(unsigned(USB_FIFODATA_I)) /= 0 ) else '0';

Conversion to unsigned is needed for the comparison. With Numeric_std an
integer can be compared to an unsigned vector. Comparison with an
integer value is independent of the bit width, but restricted to 32 bits.

The function to_01() is used to avoid comparisons of an integer with a
'X', 'Z', 'U' value, which occurs at least at the start of the
simulation. It is a way to suppress annoying warnings during simulation.


Note that trigger is a hazarderous signal!

Ralf
 
P

Paul Uiterlinden

I will not even consider myself a newbie in VHDL. I am trying to hack
someone else's code to do what I need it to do...which is trivial. I
am using Xilinx tools by the way.

I have a signal coming into a module:

USB_FIFODATA_I : std_logic_vector(31 downto 0);

All I want to do is make a trigger signal that asserts whenever that
input is NOT '0'.

So I have tried all the tricks I know (I don't know any tricks) and my
parser keeps giving me fits. Here's some examples of my stupidity:

trigger <= USB_FIFODATA_I /= '0';
trigger <= USB_FIFODATA_I(31 downto 0) /= '0';
trigger <= USB_FIFODATA_I /= "00000000000000000000000000000000";

Obviously, I don't know what I am doing. I have a book, but I can't
seem to find what I am looking for. Could someone please help me out
so I can debug what I need to!

The first two examples do not work because your are comparing an array
(std_logic_vector) with a scalar (std_logic).

The third example probably (you did not give the error message and the
declaration of trigger) does not work because you assign a boolean (the
result of the /= operator) to a signal of type std_logic. If signal trigger
was boolean, it would be correct.

As a side note: I do not like long strings such
as "00000000000000000000000000000000". Is it not one bit short/long? I
don't like counting bits.

More convenient is:
trigger <= USB_FIFODATA_I /= x"0000_0000";
This uses a hex bit-string literal, where each character represents four
bits. Underscores may be added to improve readability.

Or even:
trigger <= USB_FIFODATA_I /= (USB_FIFODATA_I'range => '0');
Now you don't need to count bits at all!
 
R

Ralf Hildebrandt

Shannon said:
Can you explain why?

Ok maybe not in this particular case.
* The comparison with zero is a OR-operation over all bits, with should
not produce hazards.
* There is an even number of bits to compare with results in a
"symmetric OR-tree" during synthesis

But I guess the synthesis tool will not use OR gates. NORs and NANDs are
preferrable. Because the bit width is even and if there are 4-input NORs
and NADs in the target library this again will result in a symmetrical
tree with no hazards.
But what if the routing is not symmetrical or there are only 3-input
NORs and NADs? I guess it is safe to say that hazards /may/ occur.



And if USB_FIFODATA_I is hazarderous, then trigger is it too.

And if one changes the comparison to a different number other than zero,
one almost certainly gets an asymmetrical combinational tree which may
produce hazards.

Ralf
 
A

Andy

Along the lines of what Paul said, I _hate_ typing and counting
digits, and I prefer code that adapts automatically to changes (like
width of the vector, etc.)

The following example will also work (assume boolean trigger):

trigger <= unsigned(usb_fifodata) /= 0;

or with std_logic trigger (concurrent statement):

trigger <= '1' when unsigned(usb_fifodata) /= 0 else '0';

or (sequential statement):

if unsigned(usp_fifodata) /= 0 then
trigger <= '1';
else
trigger <= '0';
end if;

Andy
 
P

Paul Uiterlinden

Andy said:
Along the lines of what Paul said, I _hate_ typing and counting
digits, and I prefer code that adapts automatically to changes (like
width of the vector, etc.)

The following example will also work (assume boolean trigger):

trigger <= unsigned(usb_fifodata) /= 0;

or with std_logic trigger (concurrent statement):

trigger <= '1' when unsigned(usb_fifodata) /= 0 else '0';

Expanding on that, I'm not so fond of this kind of selected signal
assignments. It gets even worse if it was a sequential statement (so in a
process):

if unsigned(usb_fifodata) /= 0 then
trigger <= '1';
else
trigger <= '0';
end if;

Too many words and (shudder!) repetition of the target name.

I like to use a function in those cases. This works equally well for
concurrent an sequential statements:

trigger <= bool2sl(unsigned(usb_fifodata) /= 0);

Where bool2sl is a function that comes out of a package with all this kind
of small but oh so handy subprograms:

function bool2sl(val: boolean) return std_ulogic is
begin
if val then
return '1';
else
return '0';
end if;
end function bool2sl;
 
A

Andy

Expanding on that, I'm not so fond of this kind of selected signal
assignments. It gets even worse if it was a sequential statement (so in a
process):

if unsigned(usb_fifodata) /= 0 then
trigger <= '1';
else
trigger <= '0';
end if;

Too many words and (shudder!) repetition of the target name.

I like to use a function in those cases. This works equally well for
concurrent an sequential statements:

trigger <= bool2sl(unsigned(usb_fifodata) /= 0);

Where bool2sl is a function that comes out of a package with all this kind
of small but oh so handy subprograms:

function bool2sl(val: boolean) return std_ulogic is
begin
if val then
return '1';
else
return '0';
end if;
end function bool2sl;

Paul... Didn't you ever learn that subprograms should have exactly one
exit point? ;^)

function bool2sl(val: boolean) return std_ulogic is
retval : std_logic := '0';
begin
if val then
retval := '1';
end if;
return retval;
end function bool2sl;

or, you don't even need a subprogram:

type bool2sl_t is array (boolean) of std_ulogic;
constant bool2sl : bool2sl_t := (true => '1'; false => '0');

But I agree, we all need one of those packages with all our little
tricks

Some of my favorites:

subtype slv is std_logic_vector; -- abbreviation
subtype sl is std_logic; -- abbreviation
function is1()... -- convert sl to bool with assertion against
metavalues
function is0()...

The is1() & is0() functions have an optional severity level argument.

Andy
 
P

Paul Uiterlinden

Andy said:
Paul... Didn't you ever learn that subprograms should have exactly one
exit point? ;^)

Yes, but rules are there to be bent occasionally. :p
function bool2sl(val: boolean) return std_ulogic is
retval : std_logic := '0';
begin
if val then
retval := '1';
end if;
return retval;
end function bool2sl;

or, you don't even need a subprogram:

type bool2sl_t is array (boolean) of std_ulogic;
constant bool2sl : bool2sl_t := (true => '1'; false => '0');

True, but there is a subtle difference: only the function bool2sl may be
used directly in a port map. The table bool2sl may not. For a general
package I choose the function for that reason. For local conversion
functions I use indeed a table.
But I agree, we all need one of those packages with all our little
tricks

Some of my favorites:

subtype slv is std_logic_vector; -- abbreviation
subtype sl is std_logic; -- abbreviation
function is1()... -- convert sl to bool with assertion against
metavalues
function is0()...

min(), max(), inc(), dec(), reverse(), sl2bool(), rand_num_gen(),
rand_vec_gen(), and_reduce(), or_reduce(), xor_reduce() ...
The is1() & is0() functions have an optional severity level argument.

Instead of your is1 and is0 I use the sl2bool function, with (surprise!) an
optional argument to enable checking against metavalues.

All great people think alike. :p :p :p
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top