How to assign a hex or decimal value to a std_logic_vector o

G

gabor

Guest
I write almost exclusively Verilog code, but I inherited a
VHDL project and I need to make some changes to it.
I'm trying to make this human-readable, but I'm not
versed with VHDL, so I have no clue even what to look this up
under:

This code works, but it is not very readable:

signal flash_addr_i : std_logic_vector (18 downto 0) ;
.. . .
elsif ((flash_addr_i < 128) and write_flag = '1') then
-- How can a human being make sense of of this?
-- and why is 128 OK for the comparison above and not
-- for the assignment below?
flash_addr_i <= "0000000000010000000";
end if;
.. . .
I want to say:

flash_addr_i <= 128;

But then I get messages about flash_addr_i is not compatible with
with type of 128.

and if I try a hex constant like:

flash_addr_i <= x"00080";

I get bit width mis-match problems.

How can I write the equivalent of the Verilog:

flash_addr_i <= 19'd128;
or
flash_addr_i <= 19'h80;

I can't believe there's no way to do this in VHDL?

Stumped,

Gabor
 
Gabor,
signal flash_addr_i : std_logic_vector (18 downto 0) ;

In VHDL-2008 (standardized, but not necessarily implemented yet) you can do:
flash_addr_i <= 19D"128";
flash_addr_i <= 19h"80";

For now you are stuck with:
flash_addr_i <= "000" & h"0080";

Cheers,
Jim
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis SynthWorks VHDL Training http://www.synthworks.com

A bird in the hand may be worth two in the bush,
but it sure makes it hard to type.
 
On Fri, 5 Dec 2008 08:57:01 -0800 (PST)
gabor <gabor@alacron.com> wrote:

I write almost exclusively Verilog code, but I inherited a
VHDL project and I need to make some changes to it.
I'm trying to make this human-readable, but I'm not
versed with VHDL, so I have no clue even what to look this up
under:

This code works, but it is not very readable:

signal flash_addr_i : std_logic_vector (18 downto 0) ;
. . .
elsif ((flash_addr_i < 128) and write_flag = '1') then
-- How can a human being make sense of of this?
-- and why is 128 OK for the comparison above and not
-- for the assignment below?
flash_addr_i <= "0000000000010000000";
end if;
. . .
I want to say:

flash_addr_i <= 128;

But then I get messages about flash_addr_i is not compatible with
with type of 128.

and if I try a hex constant like:

flash_addr_i <= x"00080";

I get bit width mis-match problems.

How can I write the equivalent of the Verilog:

flash_addr_i <= 19'd128;
or
flash_addr_i <= 19'h80;

I can't believe there's no way to do this in VHDL?

Stumped,

Gabor
One answer, possibly not the cleanest:

The address represents a number (something that can be compared and
mathed on), not just a collection of bits, and so should be stored as an
unsigned (defined in numeric_std) rather than a std_logic_vector.

With that in place, you can perform comparisons directly between
unsigneds and integer constants. Assignment can be handled through
the TO_UNSIGNED function as:

flash_addr_i <= TO_UNSIGNED(128, 19);


--
Rob Gaddi, Highland Technology
Email address is currently out of order
 
On Fri, 5 Dec 2008 08:57:01 -0800 (PST), gabor wrote:

I write almost exclusively Verilog code, but I inherited a
VHDL project and I need to make some changes to it.
I'm trying to make this human-readable, but I'm not
versed with VHDL, so I have no clue even what to look this up
under:

This code works, but it is not very readable:

signal flash_addr_i : std_logic_vector (18 downto 0) ;
. . .
elsif ((flash_addr_i < 128) and write_flag = '1') then
-- How can a human being make sense of of this?
-- and why is 128 OK for the comparison above and not
-- for the assignment below?
Because you have pulled in the std_logic_unsigned package, which
overloads most of the arithmetic operators so that they work
as expected between std_logic_vector (treated as unsigned) and
integer. It's not nice, and received wisdom here is that you
should use ieee.numeric_std in preference, but it works.
Assignment operators in VHDL cannot be overloaded, so that's
why your std_logic_vector<=integer assignment doesn't work.

flash_addr_i <= "0000000000010000000";
end if;
. . .
I want to say:

flash_addr_i <= 128;

But then I get messages about flash_addr_i is not compatible with
with type of 128.
Yes, 128 is an integer and std_logic_vector is a bag-o-bits.
That's just VHDL being strongly typed.

and if I try a hex constant like:

flash_addr_i <= x"00080";

I get bit width mis-match problems.
That's VHDL being hacky. The x"..." syntax is a kludge.
It replaces each hex digit with the corresponding string
of four 0/1 digits, and then has another go at the
assignment. But VHDL actually checks the sizes of vectors
across a copy (gosh! what an interesting idea! maybe
Verilog might think about that one day) and your 5-digit
hex number of course comes out as 20 bits, not 19.

How can I write the equivalent of the Verilog:

flash_addr_i <= 19'd128;
or
flash_addr_i <= 19'h80;
The canonical answer is to use the conv_std_logic_vector function
(from std_logic_arith package, but I betcha your code includes
that too). Note the second, bit-width argument.

flash_addr_i <= conv_std_logic_vector(128, 19);
flash_addr_i <= conv_std_logic_vector(16#80#, 19);

But you can do better than that. First off, the literal 19
sucks. Replace it with an attribute of the target vector:

flash_addr_i <= conv_std_logic_vector(128, flash_addr_i'length);

Or, if you find yourself writing a line like that more than
two or three times, declare a little local function (in the
process's or architecture's declarative region) to do that:

function int_to_addr(a: integer) return std_logic_vector is
begin
return conv_std_logic_vector(a, flash_addr_i'length);
end;

and now of course you can just do

flash_addr_i <= int_to_addr(128);

Finally, there's another useful trick you can use based on
the fact that the arithmetic operators are overloaded; but
you must confirm for yourself that your synth tool optimizes
away the add-a-zero operation correctly. Declare a constant
of the same subtype as flash_addr_i that contains zero:

constant addr_0: std_logic_vector(flash_addr_i'range)
:= (others => '0');

Now you can do...

flash_addr_i <= addr_0 + 128;

and the overloaded + operator will sort out all the
type conversions for you. The zero constant must
have the correct width for this to work.

Work *with* the VHDL data type system rather than fighting it,
and you will start to see its considerable strengths and elegance.
Unconstrained array arguments and ports, and array attributes,
are a joy of VHDL that Verilog is only just catching up with
(and rather feebly at that).

Try to find out why the numeric_std package is preferred over
the older std_logic_[un]signed/std_logic_arith evil triplets,
but if you're stuck with legacy code that uses the old packages
then it isn't really a big problem.

Enjoy
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Fri, 5 Dec 2008 09:07:25 -0800, Rob Gaddi wrote:

Assignment can be handled through
the TO_UNSIGNED function as:

flash_addr_i <= TO_UNSIGNED(128, 19);
Sadly, I doubt that. In gabor's code we see...

signal flash_addr_i : std_logic_vector (18 downto 0) ;
. . .
elsif ((flash_addr_i < 128) ...) then
So it seems fair to assume that the poor devil is saddled
with old code that uses std_logic_unsigned instead of
numeric_std. CONV_STD_LOGIC_VECTOR is what he needs.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Dec 5, 11:57 am, gabor <ga...@alacron.com> wrote:

I write almost exclusively Verilog code,
We won't hold that against you.

I want to say:

 flash_addr_i <= 128;
Since VHDL is a strongly typed language you are best viewing this as a
type conversion problem rather than a bit assignment problem. So the
conversion you want is from integer to std_logic_vector. This is a
two step conversion, one to convert from integer to a vector-o-bits
that has a specific numeric interpretation (i.e. type
ieee.numeric_std.unsigned) and then finally from that unsigned type to
a vector that is just a collection of arbitrary bits (i.e.
std_logic_vector). To do what you want then...

flash_addr_i <= std_logic_vector(to_unsigned(128,
flash_addr_i'length));

Or if you prefer hex notation for the constant
flash_addr_i <= std_logic_vector(to_unsigned(16#80#,
flash_addr_i'length));

I can't believe there's no way to do this in VHDL?

There is.

Kevin Jennings
 
On 5 דצמבר, 19:27, Jonathan Bromley <jonathan.brom....@MYCOMPANY.com>
wrote:
On Fri, 5 Dec 2008 09:07:25 -0800, Rob Gaddi wrote:
Assignment can be handled through
the TO_UNSIGNED function as:

flash_addr_i <= TO_UNSIGNED(128, 19);

Sadly, I doubt that. In gabor's code we see...

signal flash_addr_i : std_logic_vector (18 downto 0) ;
. . .
elsif ((flash_addr_i < 128) ...) then

So it seems fair to assume that the poor devil is saddled
with old code that uses std_logic_unsigned instead of
numeric_std. CONV_STD_LOGIC_VECTOR is what he needs.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.brom...@MYCOMPANY.comhttp://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
Here is an example:

library ieee;
use ieee.std_logic_1164.all;

use work.amba.all;
use STD.textio.all;
use IEEE.STD_LOGIC_TEXTIO.all;

use IEEE.std_logic_unsigned."+";

entity mon is
generic (
msg_on : boolean := TRUE;
my_name : STRING := "I ";
--stop_add: std_logic_vector(HAMAX-1 downto 0) := X"8ffffffc"
stop_add: std_logic_vector(31 downto 0) :"10001111111111111111111111111100"
);
port (

HRESETN : in std_logic;
HCLK : in std_logic;

HMASTER : in std_logic_vector(3 downto 0);
....
The code is part of a free AHB monitor:
The following will show a simple AHB monitor. The monitor can be
applied to any AHB bus to debug the activity of the bus.

The monitor is easily attached to an AHB interface....
http://bknpk.no-ip.biz/AHB_MON/ahb_mon_1.html
 
On Dec 5, 12:02 pm, Jim Lewis <j...@synthworks.com> wrote:
Gabor,
signal   flash_addr_i            : std_logic_vector (18 downto 0) ;

In VHDL-2008 (standardized, but not necessarily implemented yet) you can do:
   flash_addr_i <= 19D"128";
   flash_addr_i <= 19h"80";

For now you are stuck with:
   flash_addr_i <= "000" & h"0080";

Cheers,
Jim
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis    SynthWorks VHDL Training    http://www.synthworks.com

A bird in the hand may be worth two in the bush,
but it sure makes it hard to type.
I tried the 2008 standard stuff. XST 10.1 doesn't support
that yet...

I guess I'll use Jonathan's suggestion of adding 128
to another constant vector. That works for XST, which
makes sense because everywhere in the code I see stuff
like:

flash_addr_i <= flash_addr_i + 1;

Adding an integer constant to a std_logic_vector.

Unfortunately the project is also full of case statements
with binary strings for the case values, which makes it
hard to read, too. However I'll get to those when I find
out that they're broken...

This should get me by until I convert the whole project
to Verilog. Usually that helps me to understand other
people's code anyway. I'm not ready to start messing
with libraries.

Thanks for all the replies,

Gabor
 
Gabor,
I tried the 2008 standard stuff. XST 10.1 doesn't support
that yet...
Did you try my other suggestion (it is not new stuff):
flash_addr_i <= "000" & h"0080";

I guess I'll use Jonathan's suggestion of adding 128
to another constant vector. That works for XST, which
makes sense because everywhere in the code I see stuff
like:

flash_addr_i <= flash_addr_i + 1;

Adding an integer constant to a std_logic_vector.
Yes this is operator overloading.

Unfortunately the project is also full of case statements
with binary strings for the case values, which makes it
hard to read, too. However I'll get to those when I find
out that they're broken...
Keep these a binary strings - unfortunately until vhdl-2008,
the case statements are intolerant of "&" and expressions.

This should get me by until I convert the whole project
to Verilog. Usually that helps me to understand other
people's code anyway.
Not a good thing if the rest of your project team is using VHDL.
Probably ought to invest in training instead. VHDL is quite
simple once you get past the initial learning stuff.

Cheers,
Jim
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis SynthWorks VHDL Training http://www.synthworks.com

A bird in the hand may be worth two in the bush,
but it sure makes it hard to type.
 
On Dec 5, 2:54 pm, Jim Lewis <j...@synthworks.com> wrote:
Gabor,> I tried the 2008 standard stuff.  XST 10.1 doesn't support
that yet...

Did you try my other suggestion (it is not new stuff):
flash_addr_i <= "000" & h"0080";

I guess I'll use Jonathan's suggestion of adding 128
to another constant vector.  That works for XST, which
makes sense because everywhere in the code I see stuff
like:

flash_addr_i   <= flash_addr_i + 1;

Adding an integer constant to a std_logic_vector.

Yes this is operator overloading.

Unfortunately the project is also full of case statements
with binary strings for the case values, which makes it
hard to read, too.  However I'll get to those when I find
out that they're broken...

Keep these a binary strings - unfortunately until vhdl-2008,
the case statements are intolerant of "&" and expressions.

This should get me by until I convert the whole project
to Verilog.  Usually that helps me to understand other
people's code anyway.  

Not a good thing if the rest of your project team is using VHDL.
Probably ought to invest in training instead.  VHDL is quite
simple once you get past the initial learning stuff.

Cheers,
Jim
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis    SynthWorks VHDL Training    http://www.synthworks.com

A bird in the hand may be worth two in the bush,
but it sure makes it hard to type.
There is no project "team" at this company or in other words,
I am the team. This project was supposed to be a purchased
turn-key design, but the external contractors didn't finish it.
All of the in-house designs are Verilog and likely to stay so.

Thanks for all your help,

Gabor
 
On Dec 5, 4:30 pm, gabor <ga...@alacron.com> wrote:

There is no project "team" at this company or in other words,
I am the team.
Well what do you know, there is an 'I' in 'team' after all.

KJ
 

Welcome to EDABoard.com

Sponsor

Back
Top