Ваша функция не использует переменную k_int
и константы stage_aux
и nin
(которые могут выводить предупреждение во время моделирования или синтеза) и не возвращает целое число (это дает ошибку в Vivado 2018.1).
Если вы добавите предложение return
, код имитируется, как и ожидалось, и синтез также работает в vivado 2018.1. (код синтезируется)
Если у вас все еще есть проблема, уточните, какой строке кода соответствуют 2 ошибки, которые вы написали выше.
Обратите внимание, что в моем коде я тестировал, когда LOG2_FFT_LEN
является общим или целым числом, и это не имело значения.
EDIT Итак, я обновил свой код для моделирования, у меня есть это:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity fft_engine_tb is
generic(
LOG2_FFT_LEN : integer := 10
);
end entity;
architecture Behavioral of fft_engine_tb is
signal clk : std_logic := '1'; --the clock (not used, only to see it in the simulation waves)
constant period : time := 8us; --the clock period
constant half_period : time := 4us; --the half period of the clock
signal int_return : integer := 0;
signal int_return_loop : integer := 0;
begin
--the generation of the clock
clk <= not clk after half_period;
--process that call your function
process
--definition of your second function (the pure keyword is optionnal)
function n2k (
constant stage : integer; -- stage number
constant step : integer; -- butterfly block number
constant nin : integer -- input number (0 or 1)
)
return integer is
variable k_uns : unsigned(LOG2_FFT_LEN-1 downto 0);
variable k_int : integer;
begin
k_uns := to_unsigned(step, LOG2_FFT_LEN);
if stage > 0 then
k_uns(LOG2_FFT_LEN-1 downto LOG2_FFT_LEN-stage) := k_uns(LOG2_FFT_LEN-2 downto LOG2_FFT_LEN-stage-1);
end if;
if nin = 0 then
k_uns(LOG2_FFT_LEN-stage-1) := '0';
else
k_uns(LOG2_FFT_LEN-stage-1) := '1';
end if;
k_int := to_integer(k_uns);
return k_int;
end function;
--definition of your second function with the loop (the pure keyword is optionnal)
function n2k_with_loop (
constant stage : integer; -- stage number
constant step : integer; -- butterfly block number
constant nin : integer -- input number (0 or 1)
)
return integer is
variable k_uns : unsigned(LOG2_FFT_LEN-1 downto 0);
variable k_int : integer;
begin
k_uns := to_unsigned(step, LOG2_FFT_LEN);
if stage > 0 then
for i in 0 to stage - 1 loop
k_uns(LOG2_FFT_LEN - 1 - i) := k_uns(LOG2_FFT_LEN - 2 - i);
end loop;
end if;
if nin = 0 then
k_uns(LOG2_FFT_LEN-stage-1) := '0';
else
k_uns(LOG2_FFT_LEN-stage-1) := '1';
end if;
k_int := to_integer(k_uns);
return k_int;
end function;
begin
wait for period;
int_return <= n2k( 2, 2, 0); --We expect 2
int_return_loop <= n2k_with_loop( 2, 2, 0); --We expect 2
wait for period;
int_return <= n2k( 2, 2, 1); --We expect 130
int_return_loop <= n2k_with_loop( 2, 2, 1); --We expect 130
wait for period;
int_return <= n2k( 5, 1023, 0); --We expect 1007
int_return_loop <= n2k_with_loop( 5, 1023, 0); --We expect 1007
wait for period;
int_return <= n2k( 5, 1023, 1); --We expect 1023
int_return_loop <= n2k_with_loop( 5, 1023, 1); --We expect 1023
wait for period;
int_return <= n2k( 5, 682, 0); --We expect 330
int_return_loop <= n2k_with_loop( 5, 682, 0); --We expect 330
wait for period;
int_return <= n2k( 5, 682, 1); --We expect 346
int_return_loop <= n2k_with_loop( 5, 682, 1); --We expect 346
wait for period;
int_return <= n2k( 1, 682, 0); --We expect 170
int_return_loop <= n2k_with_loop( 1, 682, 0); --We expect 170
wait for period;
int_return <= n2k( 1, 682, 1); --We expect 426
int_return_loop <= n2k_with_loop( 1, 682, 1); --We expect 426
wait;
end process;
end architecture;
Под Vivado 2018.1 симулирует отлично и все как положено:
![Имитация волн в Vivado 2018.1](https://i.stack.imgur.com/fRu8K.png)
Кроме того, ваша функция полностью синтезируема, она работает на vivado 2018.1. Я также сделал это.
Следовательно, я считаю, что ваша проблема связана не с синтаксисом VHDL, а с инструментальной проблемой (проблема Quartus).
Я не могу подтвердить вам это, так как у меня нет квартуса и я никогда его не использовал, но я провел некоторое исследование: похоже, ваша проблема связана с ограничением синтеза. Вы должны показать компилятору, что константа stage
и общий LOG2_FFT_LEN
не могут принимать значения, которые привели бы к недопустимому диапазону.
Например, если stage
принимает значение -20
(он может принимать это значение, так как является целым числом), то остальная часть вашего кода не будет работать должным образом.
Итак, если это проблема, измените способ объявления своих констант/дженериков:
LOG2_FFT_LEN : POSITIVE := 10 --generic
Ключевое слово POSITIVE
является подтипом integer
:
type Positive is Integer range 1 to Integer'high;
Для вас постоянно:
constant stage : integer range 1 to LOG2_FFT_LEN-1; -- stage number
Если это все еще не работает, попробуйте распространить эту идею на другие ваши константы/сигналы/переменные. Если ничего не изменится, то можете ли вы уточнить, что именно вы сделали? Симуляция работает так, как вы ожидаете? Это не удается? Не получается только часть синтеза?
Обратите внимание, что обе ваши функции работают нормально (для меня), но первая (без цикла) лучше/красивее, чем вторая. Вы должны придерживаться его.
Вот несколько ссылок людей, у которых была аналогичная ошибка:
выражение VHDL не является константой
vhdl "выражение не является постоянным"
person
dalex78
schedule
03.09.2019