VHDL hexadecimal instead of binary

Status
Not open for further replies.

shaiko

Advanced Member level 5
Joined
Aug 20, 2011
Messages
2,644
Helped
303
Reputation
608
Reaction score
297
Trophy points
1,363
Activity points
18,302
PHP:
process is
   begin
       case address_i is
	when "0100" => 
	    --- do something
             when "0101" =>
                 --- do something else
             when others =>
                 --- do something else
       end case ;
end process  ;

address_i is defined as an unsigned ( 3 downto 0 ).
instead of writing the long binary address I want to write it in Hex.
x"4" instead of "0100"
x"5" instead of "0101"
What is the correct way to do it ?
 

like you wrote it: x"4" for an address range from 0 to 15 (0 -> F), x"FF" for an address range of 0 to FF (255).
If you want you can use a separator between bytes, like: x"C0_FF_EE", which is identical to x"C0FFEE".
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
There's a problem here.
actually "0100" is just an example.
The real address bus I'm dealing with is 15 bits wide ( wich isn't a multiple of 4 ).
 

    Dev_DD

    Points: 2
    Helpful Answer Positive Rating
you could concatenate 3 bits with 3 hex digits.

Code:
case addr is
  when "000" & x"ABC" =>
    -- do something
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
I think it is better to do a concatenation in the case expression:

Code:
case '0' & addr is
  when x"7890" => do_something

If you then use a constant higher than x"7FFF" it can never be true. The highest bit must be '0'.

It compiles correctly, but Modelsim gives the following warning about the "case '0' & addr":
"Array type case expression must be of a locally static subtype."
I don't really understand this warning. You can ignore it, or avoid it like this:

Code:
variable tmp_addr: std_logic_vector(15 downto 0);
begin
  tmp_addr := '0' & addr;
  case tmp_addr is
    when x"7890" => do_something
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
I would concatenate before the case using a variable like std_match did
 

There's a problem here.
actually "0100" is just an example.
The real address bus I'm dealing with is 15 bits wide ( wich isn't a multiple of 4 ).

Declare an integer variable of the proper range, convert the vector to the integer and then use the integer as the case expression

Code:
variable address_integer: natural range 0 to 2**15 - 1;
...
address_integer := to_integer(address_i)
case address_integer is
    when 16#0004# => 
    when 16#1234# => 
    when 16#2BCD# => 
    when 16#7FFF# => 
    when others =>
end case;
Kevin Jennings
 
Last edited:

K-J,
Is writing 16#7FFF# and x"7FFF" is the same ?
 

K-J,
Is writing 16#7FFF# and x"7FFF" is the same ?
No (but kind of close depending on what you mean by 'same'). In the context that you're using it here, x"7FFF" is an unsigned vector (i.e. the type of 'address_i'), whereas 16#7FFF# is an integer constant. VHDL allows you to specify integer literals with a base by using the # wrapper. The number before the first # sign indicates the base. The base must be between 2 and 16, so each of these are valid

123 -- Base 10 implied
10#123# -- Base 10 explicitly specified
16#ABCD# -- Hexadecimal
8#777# -- Octal
5#1234321# -- Base 5

Note that since you're specifying an integer value rather than bits within a collection, you're not hamstrung by having to have the right collection of bits as you are currently having with your posted problem which has 15 bits which isn't a multiple of 4 which means you have to kludge together the last three bits somehow.

So even though 16#1234# appears to be 4 digit hex number, it does not have a 'vector' number of bits associated with it so it is not '16 bits' wide. It is simply a constant integer. That means though that you can't assign 16#7FFF# to an unsigned, nor can you assign x"7FFF" to an integer.

my_unsigned <= 16#7FFF# -- Illegal, the right hand side is integer, the left is unsigned
my_unsigned <= to_unsigned(16#7FFF#, my_unsigned'length); -- Legal

my_integer <= x"7FFF"; -- Illegal, the right hand side is unsigned (actually ambigous, could be a string), the left is integer
my_integer <= to_integer(unsigned'(x"7FFF")); -- Legal

Kevin Jennings
 

K-J,
Is writing 16#7FFF# and x"7FFF" is the same ?

No.
16#7FFF# is a number and the maximum value than can be written in this way is (normally) 16#7FFFFFFF#.
This means that it can only be used to handle unsigned/std_logic_vector with a size up to 31 bits.

x"7FFF" is not a number. It corresponds directly to unsigned/std_logic_vector, and can be used for any size that is a multiple of 4.
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
just as a note, VHDL2008 has some string literal enhancements:

Code:
variable S : std_logic_vector(5 downto 0);

S := 6x"0f";  -- specify width 6
S := 6x"XF";  -- means "XX1111"
S := 6SX"F";  -- "111111" (sign extension)
S := 6Ux"f";  -- "001111" (zero extension)
S := 6sb"11"; -- "111111" (binary format)
S := 6uO"7";  -- "000111" (octal format)

copied from
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…