最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

xilinx ise - Variable length unsigned in VHDL function - Stack Overflow

programmeradmin0浏览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)"

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)"

Share Improve this question edited Feb 6 at 17:09 user16145658 7771 gold badge6 silver badges13 bronze badges asked Feb 5 at 16:05 Jim ClayJim Clay 1193 bronze badges 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'. – Matthias Schweikart 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. – Jim Lewis 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? – Jim Clay 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. – Jim Lewis 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? – Jim Lewis Commented Feb 6 at 0:25
 |  Show 1 more comment

1 Answer 1

Reset to default 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;
发布评论

评论列表(0)

  1. 暂无评论