VHDL: справочная таблица косинуса

Я работаю с VGA на своей FPGA Basys3, и в настоящее время я хочу нарисовать зонную пластину, для которой уравнение (1 + cos (k * r ^ 2)) / 2, где r - расстояние от центра пластины, k=2*pi/lambda — волновое число, определяющее масштаб пластины. Я предполагаю, что лучшим способом действий было бы использование косинусной LUT, но я действительно понятия не имею, как ее создать. Я немного понимаю идею, стоящую за этим, но я не знаю, как ее написать и какие значения она должна содержать.

Это код, который я пытаюсь проверить:

Единственная проблема сейчас в том, что я не знаю, какими значениями заполнить memory_type :=(), чтобы оно равнялось k*r^2 из формулы.

architecture Behavioral of VGAdraw is

signal i : integer range 0 to 29:=0;
signal r : integer :=2;
type memory_type is array (0 to 29) of integer range -128 to 127; 
signal cosine : memory_type :=();

begin

process(CLK)
begin
if (CLK'EVENT and CLK = '1') then
    if (cntHor >= 0) AND (cntHor <= cstHorAL - 1) then
            RED <= conv_std_logic_vector ((1 - cosine (i)) / 2, 8) (7 downto 4);
            GREEN <= conv_std_logic_vector ((1 - cosine (i)) / 2, 8) (7 downto 4);
            BLUE <= conv_std_logic_vector ((1 - cosine (i)) / 2, 8) (7 downto 4);
            i <= i + 1;
    else
            RED <= "0000";
            GREEN <= "0000";
            BLUE <= "0000";
    end if;
end if;
end process;
end Behavioral;

cntHor - горизонтальный счетчик

cstHorAL - количество пикселей в активной строке

Я не могу опубликовать само изображение из-за отсутствия репутации, но вот как оно должно выглядеть: http://handforgedvideo.com/wp-content/uploads/2013/02/1920x1080p24_Luma_Zone_Plate_Main.png

Любая помощь приветствуется. Благодарю вас!


person Levente Rigán    schedule 26.04.2016    source источник
comment
LUT может быть создан как ПЗУ, которое инициализируется значениями функции, или просто как функция, которая затем преобразуется в комбинаторную логику с помощью инструмента синтеза. Пожалуйста, включите часть кода, которая показывает формат и точность аргумента и результата для более лучшего ответа.   -  person Morten Zilmer    schedule 26.04.2016
comment
Дело в том, что я даже не знаю, как начать. Код, который я добавил, — это то, что я нашел где-то еще, и я пытаюсь его проверить. Но я действительно не знаю, как это работает, каковы эти значения в структуре case и как связать это с моими цветовыми выходами, чтобы нарисовать пластину зоны, используя приведенное выше уравнение.   -  person Levente Rigán    schedule 26.04.2016


Ответы (1)


Ваш общий код не так уж далек, но, как указал Мортен, вы не указываете формат ввода (тета) или выходов (sin_data и cos_data). Являются ли они значениями с фиксированной точкой? Где дробная точка? Это просто целые числа?

Ты говоришь:

Я предполагаю, что лучшим способом действий было бы использование косинусной LUT, но я действительно понятия не имею, как ее создать.

Я предполагаю, что вы подразумеваете под «LUT» общую «таблицу поиска». Использование «LUT» в вашем вопросе неоднозначно, поскольку вы также упоминаете Basys3. В литературе по FPGA LUT — это особый тип логической структуры на FPGA. Это также означает «справочную таблицу», но размер и сложность ограничены несколькими цифровыми входами. Нет доступных объектов "косинус LUT". Я просто хотел уточнить, что под «LUT» вы подразумеваете общую таблицу поиска.

Теперь ваш код не за горами. Это действительно таблица поиска для передачи theta и вывода sin_data и cos_data. Вопросы заключаются в следующем: а) точно ли ваши выходные данные представляют функцию и б) является ли ваша реализация наиболее эффективной.

Что касается первого, я не уверен, поскольку вы не указываете формат ввода и вывода. Кроме того, вы не указываете сопоставление между ϴ и вашей функцией. Является ли ϴ аргументом функции cos()? Или это к? Или это λ?

В последнем случае взгляните на Xilinx UG901. В нем приведены примеры того, как выводить ПЗУ (см. раздел «Методы кодирования ПЗУ HDL»). Ваш код в том виде, в каком он написан, вероятно, будет наименее эффективным методом. Вам нужны две таблицы поиска с записями по 4 КБ каждая (sin_data и cos_data), поэтому две 4 КБ x 12 бит. Вам лучше собрать ПЗУ из блочной ОЗУ.

person PlayDough    schedule 26.04.2016
comment
В этом проблема с заимствованным кодом. Я не до конца его понимаю. Во всяком случае, я попытался реализовать это, используя более простой код. Я отредактирую свой пост. - person Levente Rigán; 26.04.2016
comment
@LeventeRigán Вы собираетесь синтезировать код? - person PlayDough; 26.04.2016
comment
Да, в конце концов, это было бы целью :) - person Levente Rigán; 27.04.2016
comment
Если вашей целью является синтезируемый код, вы не можете использовать cos() в том виде, в котором вы его написали. Вы синтезируете сигнал на основе такой функции. Однако вы можете получать константы из функции cos(). Я рекомендую вам просмотреть UG901 в поисках стиля для синтеза ПЗУ, а затем инициализировать содержимое ПЗУ (начальное значение является постоянным значением) с помощью вызова cos(). - person PlayDough; 27.04.2016
comment
Хорошо, я проверил это, и кажется, что мой предыдущий код был немного ближе к тому, как должен выглядеть process(CLK). Но тогда я до сих пор не знаю, как добраться до части рисования. Я назначаю константы, полученные из cos(), цветовым выходам? - person Levente Rigán; 27.04.2016
comment
@LeventeRigán Я не эксперт по VGA, поэтому не знаю, как создать вывод VGA. Но я могу говорить о вашем поколении выходных данных cos() и sin() на основе некоторых входных данных. Я понимаю, что вы хотите вычислить 1 + cos(k*r^2). Является ли k входом? Является ли r константой? До сих пор неясно, каковы ваши входы и выходы или как они отформатированы. Они целые? Фиксированная точка? Дайте более подробную информацию о входах и выходах, и я могу предоставить больше помощи. - person PlayDough; 27.04.2016