Jump to content

    
Sign in to follow this  
Aleksey_Serov

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

Recommended Posts

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

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

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

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

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

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

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

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

Share this post


Link to post
Share on other sites
2 hours ago, Aleksey_Serov said:

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

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

Share this post


Link to post
Share on other sites

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

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, мне оно и нужно

Share this post


Link to post
Share on other sites
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,  там нет ничего сложного. Зато многие вопросы отпадут.

Share this post


Link to post
Share on other sites

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

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

Edited by Aleksey_Serov
Добавление текста

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this