2017-02-18 39 views
0

У меня есть АЦП (LTC1407A-1) на плате ПЛИС, которая заполняет 14-битный регистр с дополнением подписанными данными 2. Я хочу, чтобы преобразовать эти данные, чтобы быть без знака:VHDL подписали данные в std_logic_vector для неподписанных данных

  • Источник Диапазон данных: -8192 to 8191
  • Целевой диапазон данных: 0 to 16383

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

library IEEE; 
use ieee.std_logic_arith.all; 
use ieee.std_logic_1164.all; 

entity reg10 is 
    Port (clk : in STD_LOGIC;       --50MHz clock 
      reset : in STD_LOGIC;      --asynchronous reset 
      i_load : in STD_LOGIC;      --load signal 
      i_data : in STD_LOGIC_VECTOR (13 downto 0); --data signal 
      o_data : out STD_LOGIC_VECTOR (15 downto 0) --output data 
    ); 
end reg10; 

architecture Behavioral of reg10 is 
    signal s_data : STD_LOGIC_VECTOR(9 downto 0); 
    signal f_data : STD_LOGIC_VECTOR(13 downto 0); 
    signal t_sign : signed (13 downto 0); 
begin 
    process(clk, reset) 
    begin 
     if reset = '1' then 
      s_data <= "0000000000"; 
     elsif clk'event and clk = '1' then 
      t_sign <= SIGNED(i_data); 
      f_data <= STD_LOGIC_VECTOR(t_sign); 
      s_data <= "00" & f_data(13 downto 6); 
     end if; 
    end process; 
    o_data <= "000010" & s_data(9 downto 0); 
end Behavioral; 

Я сделал много поиска вокруг и найти много примеров, когда преобразование может быть сделано, но я не понимаю, правильно подход. Я попытался присвоить i_data как signed, перебрасывая между внутренними переменными и многими другими рекомендованными решениями, но все это безуспешно.

signal t_sign : signed (13 downto 0); 
f_data <= conv_std_logic_vector(i_data, 14); 

Код буферизует изменяющийся входной вектор и форматирует данные в выходной вектор для отображения VGA-контроллера.

Помогите оценить. Благодарю.

+0

Ну, какой желаемый результат? Особенно, когда значения в источнике не являются легальными значениями в цели, что вы хотите? –

+0

@ brian-drummond. Желаемый результат: вход преобразуется из комплимента 2 в беззнаковое, смещен на полпути. – M1GEO

+0

Тогда почему бы просто не сказать, что желаемый результат - добавить 8192? –

ответ

0

Первая ошибка:

use ieee.std_logic_arith.all; 

Не делай этого. Сделайте это:

use ieee.numeric_std.all; 

Другая библиотека уже рассматривает std_logic как подписанный или неподписанный. Вы не должны этого хотеть. Затем отбрасывается из подписанного файла std_logic_vector в unsigned. например .:

[signal] foo <= unsigned(std_logic_vector(signed(bar))); 

однако, в случае, если вы уже вход std_logic, так что просто бросить в беззнаковое. Он должен работать, если ваше входное представление не является стандартным. (I.e. имеет смещение). Если это смещение, сделать что-то вроде:

[signal] foo <= unsigned(std_logic_vector(signed(bar)+offset)); 

нотабене <= [сигнал] присвоения назначаются в следующей дельта (https://en.wikipedia.org/wiki/Delta_delay). Таким образом, в процессе, который оценивается в пределах одной дельта (т. Е. Без команд ожидания), они не применяются до тех пор, пока процесс не завершится. Так в вас, например, несмотря на то, f_data назначается данным в t_sign линии послеt_sign назначается, t_sign не изменится до конца процесса, поэтому его изменение не будет напрямую влиять f_data. Вместо этого процесс будет запускаться в следующем clk, а clk'event and clk = '1' назначит f_data новое обработанное значение t_sign. По сути, каждый <= введет регистр в ваш пример.

редактировать: я сам бы, вероятно, использовать приведение к целому.

foo <= to_unsigned(to_integer(bar)+offset, foo'length); 
+0

p.s.Я делаю бросок через std_logic_vector, который, вероятно, не требуется, однако, это более читаемый код. Если бы кто-нибудь когда-либо реализовал проверку диапазона при литье непосредственно из подписанного без знака, отрицательные числа вызовут ошибку. – JHBonarius

+0

для редактирования mfro;) – JHBonarius

+0

Только связанный вопрос, данные в 'i_data' подписаны. Но, по-моему, моя первоначальная проблема заключалась в том, что компилятор (если это правильное слово) не знал этого и рассматривал его как неподписанное. Как я могу дать понять компилятору, что 'i_data' подписан? Я знаю, что это присуще вашему ответу, но я не на 100% не понимаю, где это. Очень полезно и информативно, спасибо! Недостаточно REP для +1, но ура! – M1GEO

1

Ваш i_data имеет диапазон от 13 Downto 0. Как Брайан упоминалось преобразование может быть достигнуто путем добавления 8192.

8192 «1_0000_0000_0000» как bit_string, представляющий двоичный файл с длиной, соответствующей i_data.

Это означает, что для конвертирования путем добавления вы просто переносите MSB в дополнение к результату длины самого длинного операнда. Поскольку вы также усекаетесь в назначении s_data, вам нужно всего лишь 8 флип-флопов.

Для:

signal s_data: std_logic_vector (7 downto 0); 

мы могли бы назначить s_data как:

s_data <= (i_data(13) xor '1') & i_data(12 downto 6); 

где o_data задание становится:

o_data <= "00001000" & s_data; 

без заботы о носить дополнение упрощает к одному XOR чтобы перевернуть знак, преобразующий два дополнения в выражение двоичной величины.

f_data и t_data не нужны, как J.H. Bonarius указывает, если желательны две дополнительные стадии трубопровода.

Вы также можете спросить, нужна ли регистрация вообще при вводе одной задержки затвора.

Если регистр устраняется:

o_data <= "00001000" & (i_data(13) xor '1') & i_data(12 downto 6); 

и вы можете также отметить, что в кратчайшие сроки являются i_data 'бита' (5 Downto 0) используется.

И потому, что XOR с константой «1» на одном входе инверсионный:

o_data <= "00001000" & not i_data(13) & i_data(12 downto 6); 

, что операция может быть логическим нет.

Обратите внимание, что арифметический пакет не нужен и не является преобразованием типа (отличная точность в VHDL, преобразование типа допускается только между близкими типами, см. IEEE Std 1076-2008 9.3.6. Преобразования типов).

Вы также можете ожидать, что синтез будет оптимизировать добавление 8192 по существу к одному и тому же результату, если исключаемые, по-видимому, ненужные регистры трубопроводов будут устранены. В модификации вашей исходной модели добавить 8192, что также подразумевает оптимизацию некоторых бит этих регистров конвейера.

Ваша модель дизайна также не использует i_load.

+0

Важно то, что вы объясняете во втором абзаце. Современные инструменты синтеза, вероятно, оптимизируют сумматоры для '... + 8192'. Поэтому больше не нужно делать эти оптимизации. Просто напишите, что вы хотите сделать, что делает код более читабельным и поддерживаемым. Если бы я читал 'o_data <=" 00001000 ", а не i_data (13) & i_data (от 12 до 6):' Я бы подумал, что здесь происходит ', а 'o_data <= unsigned (signed (i_data) +8192); 'очень ясно. И даже лучше было бы заменить «8192» «магическое число» константой, называемой 'dc_offset', или так .. – JHBonarius

+0

Также: большинство людей не имеют доступа к IEEE Std 1076-2008 (у вас должна быть платная подписка IEEE), поэтому лучше процитировать информацию. ;) – JHBonarius

+0

Конверсия добавления фильтров с помощью языка программирования. Парень HW может использовать не значение в связке контактов, будет документировать и все еще ожидать, что читатель поймет VHDL и аппаратное обеспечение. Математик может потребовать использования типа SIGNED на порте i_data. Организации также может потребоваться документировать комментарии и типы конверсий, которые могут быть пересмотрены. Также см. IEEE Std1076 -1987 thru -2002 7.3.5 Преобразования типов. Преобразование типа информации «разрешено только между близкими типами», ссылка LRM - это полномочия и да, затраты. Эти комментарии кажутся плохо сосредоточенными. – user1155120