У меня есть подписанный аккумулятор, который используется в качестве индекса для BROM LUT.В любом случае, в моем коде есть проверка ошибок для обнаружения событий переполнения / недостаточного заполнения.Это абсолютно критично, так как применение - это АРУ аналогового радиочастотного интерфейса, поэтому недостаточное пропускание может привести к тому, что гудящий сигнал получит максимальное усиление, взорвав наши передние части.Таким образом, мне нужно найти способ правильно преобразовать подписанное в неподписанное.Например, вот что у меня есть:
library ieee;
...
use ieee.numeric_std.all;
...
process (clk)
variable preSumV : signed(accumToLut'left downto 0) := (others => '0');
variable satCheckV : std_logic_vector(2 downto 0) := (others => '0');
begin
if rising_edge(clk) then
if reset = '1' then
preSumV := (others => '0');
satCheckV := (others => '0');
overflow <= '0';
underflow <= '0';
accumToLut <= (others => '0');
accumToLutValid <= '0';
else
accumToLutValid <= mult.resultValid;
-- accumulate
if mult.resultValid = '1' then
-- perform accum
preSumV := preSumV + mult.result(mult.result'left downto mult.result'left-accumToLut'length+1);
satCheckV := accumToLut(accumToLut'left) & mult.result(mult.result'left) & preSumV(preSumV'left);
-- check for signed OVF/saturation
-- A,B is pos, sum neg = overflow so set max pos
if satCheckV = "001" then
overflow <= '1';
accumToLut(accumToLut'left) <= '0';
accumToLut(accumToLut'left-1 downto 0) <= (others => '1');
-- A,B is neg, sum pos = underflow so set max neg
elsif satCheckV = "110" then
underflow <= '1';
accumToLut(accumToLut'left) <= '1';
accumToLut(accumToLut'left-1 downto 0) <= (others => '0');
-- -- no overflow
else
overflow <= '0';
underflow <= '0';
accumToLut <= preSumV;
--accumToLut <= preSumV(preSumV'left-1 downto 0);
end if;
end if;
end if;
end if;
end process;
accumToLutScaled <= accumToLut(accumToLut'left downto accumToLut'left-GainWordLookup'length+1);
index <= unsigned(accumToLutScaled);
GainWordLookup <= c_LinToDbLut(to_integer(accumToLutScaled));
Проблема, с которой я сталкиваюсь, - это преобразование со знаком в без знака с сигналом index
.Поскольку это дополнение со знаком 2, биты не меняются.Таким образом, когда я устанавливаю значение gastToLut либо в значение max / min со знаком, это не переводится в соответствующее значение max / min без знака, когда я выполняю index <= unsigned(accumToLutScaled)
.
. Чтобы привести пример, предположим, что preSumV
, mult.result
и accumToLut
- все 12 бит.Когда происходит событие переполнения, для StorageToLut устанавливается значение 0x7FF
или 0b0111111111111
, которое является действительным.Однако, когда я преобразую в unsigned, я бы хотел, чтобы это было FFF
, что соответствует максимальному значению записи в LUT.Лучше всего просто добавить смещение к назначению index
, или есть более чистый способ сделать это?