Перейти к содержанию
    

CORDIC и отрицательные числа, как правильно преобразовать

1 час назад, Aleksey_Serov сказал:

но с unsigned и std_logic_vector выдается ошибка

Как говорили когда-то, телепаты в отпуске. Не сообщения об ошибке -- гадать нет смысла.

Если делитель -- константа  и степерь двойки, то можно использовать функцию shift_right для signed/unsigned. Аналогично для умножения -- shift_left.

Для деления двух произвольных чисел обычно используют специальное IP core.

10 минут назад, petrov сказал:

Это нормальный стиль

Это спорный вопрос.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 hours ago, Aleksey_Serov said:

нигде примеров sla не нашел как назло

Странно что Вы наткнулись на sla, которая если ещё не удалена из языка, то как минимум не используется(на память, она кажется только с bit_vector работает). Но при этом не наткнулись на shift_left, shift_right, sll, srl.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот тестовый пример

library ieee;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity ADSQ is 
port(
aa: in signed (12 downto 0);
bb: out signed (12 downto 0)
);
end entity;
architecture adswq of ADSQ is
begin
process(aa)
begin
bb<=aa sla 2;
end process;
end adswq;

вот текст ошибки

ERROR:HDLParsers:808 - "H:/Xilinx/Projects_12.1/CORDIC20bit/XY_adder/XY_adder.vhd" Line 16. sla can not have such operands in this context.

вместо signed я подставлял также std_logic_vector и integer

3 минуты назад, Strob сказал:

Странно что Вы наткнулись на sla, которая если ещё не удалена из языка, то как минимум не используется(на память, она кажется только с bit_vector работает). Но при этом не наткнулись на shift_left, shift_right, sll, srl.

В книге Бибило целый разворот с этими сдвигами, я туда долго смотрел там прочитал, арифметический сдвиг, когда старший бит копируется, только перепутал, вправо, это деление на 2, мне оно и нужно

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, Aleksey_Serov сказал:

sla can not have such operands in this context.

вместо signed я подставлял также std_logic_vector и integer

sla работает с bit_vector. Таки изучайте стандартную библиотеку.

2 часа назад, Aleksey_Serov сказал:

В книге Бибило целый разворот с этими сдвигами

Лучшая документация -- исходный код. Посмотрите исходный код numeric_std,  там нет ничего сложного. Зато многие вопросы отпадут.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот так теперь выглядит мой проект

library ieee;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity ADSQ is 
port(
in_aa,in_bb: in signed (28 downto 0);
out_cc: out signed (28 downto 0);
to_xyy: out std_logic
);
end entity;
architecture adswq of ADSQ is
signal adsr: signed (29 downto 0);
begin
adding:process(in_aa,in_bb)
begin
if(in_aa<1)then adsr<=in_aa+in_bb;
elsif(in_aa>0)then adsr<=in_aa-in_bb;end if;
to_xyy<=adsr(28);
out_cc<=adsr(28 downto 0);
end process;
end adswq;
------------------------------------------------------
------------------------------------------------------
library ieee;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity ADRQ is 
port(
in_aa,in_bb: in signed (32 downto 0);
out_cc: out signed (32 downto 0);
from_z: in std_logic
);
end entity;
architecture adsrwq of ADRQ is
signal adsr: signed (33 downto 0);
begin
adding:process(in_aa,in_bb,from_z)
begin
if(from_z = '0' )then adsr<=in_aa+in_bb;
elsif(from_z = '1' ) then adsr<=in_aa-in_bb;end if;

out_cc<=adsr(32 downto 0);
end process;
end adsrwq;
------------------------------------------------------
------------------------------------------------------
library ieee;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity kolonka_z is
port(
test_005: out signed ( 32 downto 0 ));
end entity;

architecture kolonka_zz of kolonka_z is
type ARCTG_MSV is array ( 20 downto 0 ) of signed (28 downto 0);signal arctg: ARCTG_MSV;
type Z_to_Z_MSV is array ( 21 downto 0 ) of signed (28 downto 0);signal ztz: Z_to_Z_MSV;
type X_shifted is array (21 downto 0) of signed ( 32 downto 0 ); signal x_sdvinut: X_shifted;
type Y_shifted is array (21 downto 0) of signed ( 32 downto 0 ); signal y_sdvinut: Y_shifted;
type IN_X is array (21 downto 0) of signed ( 32 downto 0 ); signal xtx: IN_X;
type IN_Y is array (21 downto 0) of signed ( 32 downto 0 ); signal yty: IN_Y;
signal to_xy: std_logic_vector( 21 downto 0 );
----------------------------------------------------
component ADSQ
port(
in_aa,in_bb: in signed (28 downto 0);
out_cc: out signed (28 downto 0);
to_xyy: out std_logic
);
end component;

component ADRQ
port(
in_aa,in_bb: in signed (32 downto 0);
out_cc: out signed (32 downto 0);
from_z: in std_logic
);
end component;

begin
abbc003: process
begin
to_xy(0)<='0';
xtx(0)<="001000000000000000000000000000000";
yty(0)<="000000000000000000000000000000000";
  -- ztz(0)<="00010000000000000000000000001";
  ztz(0)<="00000111000111000111000111000";
arctg(0)<="00010000000000000000000000000";
arctg(1)<="00001001011100100000001010001";
arctg(2)<="00000100111111011001110000101";
arctg(3)<="00000010100010001000100011101";
arctg(4)<="00000001010001011000011010100";
arctg(5)<="00000000101000101110101111110";
arctg(6)<="00000000010100010111101100001";
arctg(7)<="00000000001010001011111000101";
arctg(8)<="00000000000101000101111100101";
arctg(9)<="00000000000010100010111110010";
arctg(10)<="00000000000001010001011111001";
arctg(11)<="00000000000000101000101111100";
arctg(12)<="00000000000000010100010111110";
arctg(13)<="00000000000000001010001011111";
arctg(14)<="00000000000000000101000101111";
arctg(15)<="00000000000000000010100010111";
arctg(16)<="00000000000000000001010001011";
arctg(17)<="00000000000000000000101000101";
arctg(18)<="00000000000000000000010100010";
arctg(19)<="00000000000000000000001010001";
arctg(20)<="00000000000000000000000101000";
test_005<=xtx(21);
end process;

obviazka_adder: for i in 0 to 20 generate
obviazka_gen:ADSQ
port map(
in_aa=>ztz(i),
in_bb=>arctg(i),
out_cc=>ztz(i+1),
to_xyy=>to_xy(i+1)
);
end generate;
X_obviazka: for k in 0 to 20 generate
y_sdvinut(k)<=shift_right (yty(k),k);
obviazkax_gen:ADRQ
port map(
in_aa=>xtx(k),
in_bb=>y_sdvinut(k),
out_cc=>xtx(k+1),
from_z=>not to_xy(k)
);
end generate;
Y_obviazka: for k in 0 to 20 generate
x_sdvinut(k)<=shift_right (xtx(k),k);
obviazkay_gen:ADRQ
port map(
in_aa=>yty(k),
in_bb=>x_sdvinut(k),
out_cc=>yty(k+1),
from_z=> to_xy(k)
);
end generate;
end kolonka_zz;

Арктангенсы в этом же entity, как и исходные данные. В сумматорах вначале было применено 2 независимых if, потом переделал на elsif, Warning'ов стало меньше, хотя не до конца понимаю в чем дело - elsif  проиллюстрирован в примерах где мультиплексоры подключены лестницей. Разрядность выбрал избыточную - это поправимо, для НЧ АЦП (приемник с преобразованием вниз до ПЧ в десятки кГц) может и так нормально. Код компактный, но синтезатор генерирует дольше

maxresdefault.jpg

Изменено пользователем Aleksey_Serov
Добавление текста

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...