Блок MAC кода VHDL - как избежать переполнения путем суммирования двух сигналов со знаком без добавления дополнительных битов

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

library IEEE;
use IEEE.NUMERIC_STD.ALL;
use ieee.std_logic_1164.all

entity adder is
    port(clock : in std_logic;
         ADD_value : in signed(k-1 downto 0));
         Result: out signed(k-1 downto 0));
end adder;

architecture behavioral of adder is


begin
variable acc_value : signed(k-1 downto 0);
    process(clock)
    begin
        if rising_edge(clock) then
            acc_value := acc_value + Add_value;
            Result<=acc_value ;
        end if;
    end process;
end behavioral;

Проблема в том, что обе переменные подписаны. Если происходит переполнение, то переполнение переходит из позиции k-1 в позицию k-1, что означает уничтожение знака. Например, если у меня есть 01111 с первым «0» в качестве знака, и я добавляю «10», он переходит к «10001», что побитово правильно, но неправильно со знаком, потому что это отрицательное значение

Я пробовал такие вещи, как acc_value := resize(acc_value + Result_var,k); или acc_value := to_signed(acc_value + Result_var,k);, но у меня была та же проблема.

В результате я хочу сохранить длину данных k и в случае переполнения. Если происходит переполнение, результат должен быть установлен на максимально возможное значение по отношению к знаку. Это означает, что мне все равно, есть ли переполнение, мне нужно только максимальное/минимальное значение

Максимум (минимум в случае отрицательного значения) как разновидность насыщения. Можно снова уйти от максимума, так как допускаются и отрицательные значения.

Почему acc_value это inout? VHDL 2008 позволяет читать out порты. inout обычно требуется только для буферов с тремя состояниями.

Tricky 10.01.2023 20:47

С acc_value и result_var одинаковой длины, у вас всегда будет эта проблема. Сложение двух чисел требует дополнительного бита для захвата переполнения. Вы, вероятно, хотите, чтобы временное значение выполняло обнаружение переполнения.

Tricky 10.01.2023 20:48

«вещи, которые вы пробовали», не будут работать с кодом, как опубликовано, потому что 1. acc_value не является переменной, и вы использовали присвоение переменной, и 2. нет объявления объекта k.

Tricky 10.01.2023 20:49

В опубликованном вами коде, помимо отсутствующего объявления объекта k, вам также не хватает пункта использования для use ieee.std_logic_1164.all, чтобы сделать тип std_logic видимым.

Tricky 10.01.2023 20:52

Спасибо за подсказку. Это означает, что вы должны записать его в новую переменную, а затем изменить размер переменной до нужной длины?

hajo 10.01.2023 21:05

Да. И тогда у вас есть лишний бит, позволяющий вам проверять переполнение или недополнение.

Tricky 10.01.2023 22:14

Изменение размера значений со знаком подразумевает либо отсечение значащих битов, либо удлинение знака до большей длины и не устраняет потерю информации. Аккумулятор в первую очередь хочет быть достаточно большим. Используйте отдельные дженерики для спецификаторов длины или свяжите аккумулятор с количеством раз, которое он может накапливать, прежде чем он будет отброшен/сброшен/загружен (здесь отсутствует). Обратите внимание, что общее предложение или предложение использования, делающее k непосредственно видимым, отсутствует. Не используйте входной режим, выходные порты режима -2008 имеют ту же семантику, что и буфер режима, и могут быть оценены.

user16145658 10.01.2023 22:36

"Как избежать переполнения" слишком расплывчато: укажите желаемое поведение. Это факт, что переполнение происходит, когда значение максимальное, и вы увеличиваете его на единицу. Что происходит после этого, так это бизнес-логика: т.е. специфичная для ваших требований.

JHBonarius 11.01.2023 09:08

Спасибо. Я уточнил название, вопрос, свои требования. Я тоже исправил код. Мои требования заключаются в том, что в случае переполнения я хочу установить максимальное значение по отношению к знаку. Это означает максимум/минимум. Я не хочу менять длину бита.

hajo 11.01.2023 13:31
Ускорьте разработку веб-приложений Laravel с помощью этих бесплатных стартовых наборов
Ускорьте разработку веб-приложений Laravel с помощью этих бесплатных стартовых наборов
Laravel - это мощный PHP-фреймворк, используемый для создания масштабируемых и надежных веб-приложений. Одним из преимуществ Laravel является его...
Что такое двойные вопросительные знаки (??) в JavaScript?
Что такое двойные вопросительные знаки (??) в JavaScript?
Как безопасно обрабатывать неопределенные и нулевые значения в коде с помощью Nullish Coalescing
Создание ресурсов API Laravel: Советы по производительности и масштабируемости
Создание ресурсов API Laravel: Советы по производительности и масштабируемости
Создание API-ресурса Laravel может быть непростой задачей. Она требует глубокого понимания возможностей Laravel и лучших практик, чтобы обеспечить...
Как сделать компонент справочного центра с помощью TailwindCSS
Как сделать компонент справочного центра с помощью TailwindCSS
Справочный центр - это веб-сайт, где клиенты могут найти ответы на свои вопросы и решения своих проблем. Созданный для решения многих распространенных...
Асинхронная передача данных с помощью sendBeacon в JavaScript
Асинхронная передача данных с помощью sendBeacon в JavaScript
В современных веб-приложениях отправка данных из JavaScript на стороне клиента на сервер является распространенной задачей. Одним из популярных...
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Отказ от ответственности: Эта статья предназначена только для демонстрации и не должна использоваться в качестве инвестиционного совета.
0
9
74
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Нет смысла накапливать вечно. Должен существовать барьер, который вы могли бы проверить (и, возможно, сигнализировать о переполнении, если барьер превышен). Ваш сигнал acc_value должен иметь ширину max_bit_width, которая представляет этот барьер (учтите, что сигнал sum_temp имеет на 1 бит больше, см. ниже). Result_var может иметь еще ширину k. Затем вы можете закодировать (я изменил acc_value с «out» на «buffer», чтобы иметь возможность его прочитать, возможно, вам следует ввести промежуточный сигнал и оставить acc_value как «out» или использовать VHDL2008, как было предложено):

         acc_value : buffer signed(maximum_bit_width-1 downto 0);
…
    process(clock)
        variable sum_temp : signed(maximum_bit_width downto 0);
    begin
        if rising_edge(clock) then
            sum_temp := acc_value(maximum_bit_width-1)&acc_value + Result_var;
            if sum_temp(maximum_bit_width)=sum_temp(maximum_bit_width-1) then
                acc_value <= sum_temp(maximum_bit_width-1 downto 0);
            else
                if sum_temp(maximum_bit_width)=‘0‘ then
                    acc_value <= (‘0‘, others => ‘1‘);
                else
                    acc_value <= (‘1‘, others => ‘0‘);
                end if;
            end if;
        end if;
    end process;

Вместо того, чтобы вручную расширять acc_value, вы можете использовать функцию resize, так как это подпишет расширение за вас. sum_temp :=resize(acc_value, sum_temp'length) + Result_var; Я бы также рекомендовал никогда не использовать режим buffer, так как это может усложнить подключение портов при создании экземпляров.

Tricky 11.01.2023 09:08

Спасибо за ответ. Меня код не устраивает. Во-первых, я не вижу объявления «переполнения». Если это сигнал, мне пришлось добавить дополнительный порт, чего я не хочу. Мои требования заключаются в том, что в случае переполнения я хочу установить максимальное значение по отношению к знаку. Это означает максимум/минимум. Я не хочу менять длину бита.

hajo 11.01.2023 13:33

К «Нет смысла накапливать вечно»: Есть случаи, в которых есть смысл. См. максимум (минимум в случае отрицательного значения) как своего рода насыщение. Также можно снова отойти от максимума, так как допускаются и отрицательные значения.

hajo 11.01.2023 13:35

@hajo: я отредактировал ответ в соответствии с вашими идеями.

Matthias Schweikart 11.01.2023 14:25

Большое спасибо за ваше решение! Так рад, что есть решение для этого. 2 маленькие подсказки на моем сайте: 1. acc_value <= ('1', (другие => '0')); выдает мне ошибку, что на нужном сайте он видит только один элемент вместо элементов max_bit_width-1. 2. работа с max_bit_width-1 и max_bit_width была для меня довольно запутанной, я думаю, что с написанием «высокий» или «длина» это лучше понятно. Большое спасибо!

hajo 11.01.2023 17:19

@hajo: я исправил вашу точку зрения 1. отредактировав ответ, я ввел слишком много скобок.

Matthias Schweikart 12.01.2023 10:50

Большое спасибо ! Я очень благодарен за ваши усилия и ваш ответ!

hajo 12.01.2023 15:36

Пожалуйста, возможно вам это тоже пригодится: hdl_fsm_editor

Matthias Schweikart 12.01.2023 15:44

Спасибо, посмотрю!

hajo 12.01.2023 16:07

Другие вопросы по теме