Блок 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
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
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

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