0

I want to create an unsigned in a function whose length is determined by the function parameters. I thought that was a legit thing to do- pretty sure I've even done it before, but maybe not- but ISE 14.7 doesn't think so (I know, I know. I have to use ISE because we're resurrecting an old system).

The purpose of the function is divide by a power of 2 and round the result. ISE doesn't like that I'm subtracting num_bits from the length of the input when declaring truncated. Is there a better way to do this?

 function my_round(data_in : in unsigned; num_bits : in integer) return unsigned is
     variable truncated : unsigned(data_in'left - num_bits downto 0);
  begin
     truncated := data_in(data_in'left downto num_bits);
     if my_and_reduce(truncated) = '0' and data_in(num_bits-1) = '1' then
        truncated := truncated + 1;
     end if;
     return truncated;
  end my_round;

The error message that ISE gives me when trying to synthesize the code is "Constant value expected for expression (31 - num_bits)"

6
  • 1
    You could truncate outside the function and change the interface of the procedure to function my_round(truncated : in unsigned; highest_cut_off_bit : in std_logic) .... The parameter highest_cut_off_bit must then be filled with data_in(num_bits-1) when you call the function. The check data_in(num_bits-1) = '1' would then be highest_cut_off_bit='1'. Commented Feb 5 at 16:28
  • 1
    Data_in is unconstrained. You cannot guarantee the range is not something like 0 to 7 - especially since functions from some libraries can return that range. You may which to use data_in'length to calculate your indices. You may also wish to normalize data_in using an alias. Commented Feb 5 at 16:57
  • @JimLewis You're saying that the problem is I'm assuming that data_in is a "downto" vector, while ISE recognizes that it could be a "to" vector? Commented Feb 5 at 18:14
  • @JimClay Not at all. I am not sure the reason Xilinx does not like it. OTOH, from a VHDL standpoint, your function is only doing what you expect when the arguments are something downto 0. Commented Feb 6 at 0:19
  • Have you thought about what sort of hardware this might create? The integer is unbounded. So is the unsigned. So a barrel shifter followed by a conditional incrementer. What was the call like? Commented Feb 6 at 0:25

1 Answer 1

1

It turned out that iSim, the Xilinx ISE simulator, did not have an issue with the function, so it appears to me that the problem is not at the language level, rather it's an ISE implementation problem.

I changed the function to the following, since I always called it with a num_bit parameter of 14, and it built fine.

 function my_round(data_in : in unsigned; dummy : in integer) return unsigned is
     constant num_bits : integer := 14;
     variable truncated : unsigned(data_in'left - num_bits downto 0);
  begin
     truncated := data_in(data_in'left downto num_bits);
     if my_and_reduce(truncated) = '0' and data_in(num_bits-1) = '1' then
        truncated := truncated + 1;
     end if;
     return truncated;
  end my_round;
Sign up to request clarification or add additional context in comments.

1 Comment

Using a constant num_bits and a declared object or expression range (e.g. downto) tells us the return value is indeed not variable length (as in the title of question). ISE stands for Integrated Synthesis Environment while the tool complaining about the lack of static subtype is XST (Xilinx Synthesis Technology). You could also declare a subtype to use as the return value type mark. Your're no exposing the environment for the function call making it hard for your readers to suggest accepatable alternatives in answers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.