FPGA: разделите диапазон на фиксированное число, используя справочную таблицу

Я реализовал блок в FPGA, который поддерживает аппаратное умножение. Этот блок выполняет некоторое разделение, практически не используя логических элементов, потому что он может использовать некоторый внутренний DSP.

Этот блок приходится портировать на другой дизайн, а здесь у меня на 2к меньше логических элементов и нет аппаратного множителя.

Я думал реализовать это деление с помощью таблицы поиска в памяти просто потому, что у меня есть 60 кбит, но мне трудно найти правильный способ сделать это. Вот что мне нужно сделать:

Разделите числа от 62720 до 65279 на 20, используя очень мало логических элементов. Я получаю только 128 различных результатов после округления чисел, поэтому таблица не должна быть такой тяжелой, но проблема для меня состоит в том, чтобы удалить все похожие результаты и по-прежнему использовать таблицу для поиска результата для точного деления.

Первые записи таблицы выглядят так:

62720/20 = 3136  
62721/20 = 3136  
62722/20 = 3136      
62723/20 = 3136  
62724/20 = 3136  
62725/20 = 3136  
62726/20 = 3136  
62727/20 = 3136  
62728/20 = 3136  
62729/20 = 3136  
62730/20 = 3137  
62731/20 = 3137  
62732/20 = 3137  
62733/20 = 3137   
62734/20 = 3137   
62735/20 = 3137  
62736/20 = 3137    
62737/20 = 3137    
62738/20 = 3137  
62739/20 = 3137  
62740/20 = 3137    
62741/20 = 3137  
62742/20 = 3137  
62743/20 = 3137  
62744/20 = 3137  
62745/20 = 3137  
62746/20 = 3137  
62747/20 = 3137  
62748/20 = 3137  
62749/20 = 3137  
62750/20 = 3138  
62751/20 = 3138  
62752/20 = 3138  
62753/20 = 3138   
62754/20 = 3138    
62755/20 = 3138   
...   

Для каждого результата у меня есть 20 похожих, кроме первых 3136, которые дают мне только 10 похожих результатов. Была мысль написать пару строчек по этому шаблону, но никак не могу сообразить.

Пожалуйста, поделитесь со мной своими мыслями по этому поводу. Это не обязательно должно быть полное решение, просто некоторые входные данные, потому что я застрял :) Спасибо.


person Olesen Larsen    schedule 13.02.2015    source источник
comment
Это было бы очень легко засунуть в блочную оперативную память. Какой ПЛИС вы используете? Сколько блоков оперативной памяти у вас есть?   -  person Russell    schedule 13.02.2015
comment
Вычтите 62710 (не 62720, чтобы сделать первый диапазон того же размера, что и остальные). Обратите внимание, что 20=5*4, поэтому разделите на 4 (опустите два младших разряда). Теперь у вас есть гораздо меньший диапазон, чтобы вписаться в LUT. Также вычтите 3072 из каждой записи LUT. (Вам нужно только установить 2 бита, чтобы добавить его обратно: сумматор не требуется). Чтобы сделать больше (например, разделить на 5), потребуется некоторый математический анализ, чтобы убедиться, что вы не округлили неправильно.   -  person user_1818839    schedule 13.02.2015
comment
@BrianDrummond сделай это ответом! Нам нужно больше ответов в теге VHDL и меньше вопросов в комментариях.   -  person Josh    schedule 13.02.2015
comment
Готово. Это действительно слишком коротко для ответа, и, вероятно, есть лучшие варианты, которые потребуют больше работы, чтобы получить хорошие ответы, поэтому я надеялся, что кто-то еще вмешается.   -  person user_1818839    schedule 14.02.2015


Ответы (1)


Вычтите 62710 (не 62720, чтобы сделать первый диапазон того же размера, что и остальные). Обратите внимание, что 20=5*4, поэтому разделите на 4 (опустите два младших разряда). Теперь у вас есть гораздо меньший диапазон, чтобы вписаться в LUT.

Также вычтите 3072 из каждой записи LUT. (Вам нужно только установить 2 бита, чтобы добавить его обратно: сумматор не требуется).

Результат меньше 1024 в глубину на 8 в ширину, 1 BlockRam в некоторых технологиях FPGA.

Чтобы сделать больше (например, разделить на 5), потребуется некоторый математический анализ, чтобы убедиться, что вы не округлили неправильно.

person user_1818839    schedule 13.02.2015
comment
Спасибо, Брайан. Поскольку у меня есть только 128 различных результатов, я подумал, что должна быть возможность иметь таблицу только с этими 128 записями. Ваше предложение дает мне меньше 1024, но нельзя ли сделать это меньше? Или я просто не правильно понял? - person Olesen Larsen; 14.02.2015
comment
Его можно уменьшить с помощью некоторых очевидных приемов, однако они включают либо деление на 5, либо умножение на масштабированную и округленную версию 1/5 (которую можно упростить), и вам нужно будет убедиться, что после масштабирования и округления вы 'получит правильный вывод для каждого ввода. В какой момент: стоит ли это времени и усилий? (Это хорошее упражнение, если время не имеет значения, и может быть полезным уроком о трудностях правильного округления...) - person user_1818839; 14.02.2015
comment
Альтернативой, которую вы предлагаете, является таблица входных значений, проиндексированных выходными данными. Это также работает, НО - вам нужно искать всю таблицу для каждого нового ввода. Сколько циклов у вас есть, и насколько большой будет аппаратная поисковая система? - person user_1818839; 14.02.2015
comment
Я немного запутался. Как таблица, которую вы предлагаете, может иметь только 1024 записи, когда у меня есть 2559 различных входных значений? Должно быть, я что-то упустил, когда читал ваше объяснение. Спасибо еще раз. - person Olesen Larsen; 15.02.2015
comment
Из ответа: так что разделите на 4, что даст вам 600+ значений. - person user_1818839; 15.02.2015
comment
Сегодня утром я успешно реализовал это. Спасибо. - person Olesen Larsen; 16.02.2015