Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Generic VHDL functions

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
Hello,

What do you think of the following functions:


function binary_to_gray(x: unsigned) return unsigned is
variable binary_vector: unsigned(x'length - 1 downto 0) := x;
variable gray_vector: unsigned(x'length - 1 downto 0) := (others => '0');
begin
gray_vector(x'length - 1) := binary_vector(x'length - 1);
for i in (x'length - 2) downto 0 loop
gray_vector(i) := binary_vector(i + 1) xor binary_vector(i);
end loop;

return gray_vector;
end binary_to_gray;




function gray_to_binary(x: unsigned) return unsigned is
variable gray_vector: unsigned(x'length - 1 downto 0) := x;
variable binary_vector: unsigned(x'length - 1 downto 0) := (others => '0');
begin
binary_vector(x'length - 1) := gray_vector(x'length - 1);
for i in (x'length - 2) downto 1 loop
binary_vector(i) := binary_vector(i + 1) xor gray_vector(i);
end loop;
return binary_vector;
end gray_to_binary;
 

theres a few problems and bits you could improve:

variable binary_vector: unsigned(x'length - 1 downto 0) := x;

use the range attribute instead - the input vector might not be (A downto 0), it could be (31 downto 15) or (21 to 45)

variable binary_vector: unsigned(x'range) := x; --why do you even need this - why not use X?

gray_vector(x'length - 1) := binary_vector(x'length - 1);

Same problem as above, they might not be using a (A downto 0) vector, so use 'high instead:

gray_vector(x'high) := bindary_vector(x'high);

And for the for loop, you can use 'range again. The array might not be a downto vector, it could be to.

Code:
for i in x'range loop
  if i /= x'high then
    --do grey
  end if;
end loop;

I'll let you make the same changes to the 2nd function.
 

you mean like this?

--------------------------------------------------------------------------------------------------
function binary_to_gray(binary_vector: unsigned) return unsigned is
variable gray_vector: unsigned(binary_vector'length - 1 downto 0) := (others => '0');
begin
gray_vector(binary_vector'high) := binary_vector(binary_vector'high);
for i in binary_vector'range loop
if i /= binary_vector'high then
gray_vector(i) := binary_vector(i + 1) xor binary_vector(i);
end if;
end loop;

return gray_vector;
end binary_to_gray;
--------------------------------------------------------------------------------------------------
 

change the declaration of grey vector to:

variable gray_vector: unsigned(binary_vector'range) := (others => '0');

And its much better
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
I understand the motivation to use 'range instead of 'length when we get the arguments from outside...but variable "gray_vector" is declared locally. What is the problem to use 'length here ?
 

Usually the done thing is to return a value with the same range as the input. Remember the input could be (A to B) as well as (B downto A). Your grey_vector is always going to be downto, which may cause problems.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
for generic functions where the bit order is important, a temp value should be used for the inputs to convert them into a known format.

what about the code my_func(x(7 downto 4))? you have 'range as 7654, and the internal variable as 3210. the indexing fails. also my_func("1101") would be a possible case where "to" might be the direction of the input vector.

I don't see the issue with returning a vector as downto. I think you'd have to work very hard to have issues. Keep in mind that the directions and ranges of intermediate terms in an expression don't really matter. eg, x <= "1101" will set x3 = 1, x2 = 1, x1 = 0, x0 = 1, even though the literal "1101" has a direction of "to".
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
I don't see the issue with returning a vector as downto. I think you'd have to work very hard to have issues. Keep in mind that the directions and ranges of intermediate terms in an expression don't really matter. eg, x <= "1101" will set x3 = 1, x2 = 1, x1 = 0, x0 = 1, even though the literal "1101" has a direction of "to".

In this case, "1101" actually has the same direction of X, because it is implied from the code. Only in this case:

constant X : std_logic_vector := "1101";

would it be a "to" vector because no direction is already set.

There is nothing wrong with returning a downto, as long as the user is aware that the function always returns a downto result. Assigning the output of this function to a two vector would flip all the bits over though.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
neither VHDL nor Verilog would flip the bits.

signal x : std_logic_vector(4 downto 1);
signal y : std_logic_vector(0 to 3);

x <= "1101"; -- "1101" is a 0 to 3 vector by default.
y <= x; -- x is "1101"
--y gets "1101".

both x and y will (eventually) have the value "1101", though the indexing of the bits will be different. the vector will not flip unless you use a loop mapping y(ii) <= x(ii);
 
  • Like
Reactions: shaiko

    shaiko

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

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top