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

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

Начал делать цифровой гетеродин CORDIC в VHDL, решил модули выполнять с минимального уровня, то есть сумматор расписывал как ряд однобитных сумматоров, в тех в свою очередь логические операции, сигналы std_logic_vector, вычитание или сложение в следующей итерации определял по старшему 28 биту результата сложения двух опять же 28 битных чисел (старший 29-й бит отбрасывался) проверку в железе тоже делал - самодельная плата с xilinx spartan-3, и обнаружил какую-то ошибку - в некоторых итерациях (всего их 20) появляется расхождение на единицу, до меня смутно доходит что дело в преобразовании положительных чисел в отрицательные. Я использовал twos compliment с добавлением дополнительной единицы после инверсии. Думаю дело в этом, может быть где-то это делать не надо или надо сделать второй раз после сложения. Арктангенсы записаны в отдельный модуль как положительные числа, в зависимости от знака предыдущего результата инвертируются. В чем может быть дело? Проверяю если что в EXEL - составил таблицу и теперь вот добиваюсь чтобы было как в ней. Да, речь идет только о столбце Z, знаки кторого уже рулят вычитанием/сложением в последующих итерациях самой величины Z и в столбцах X и Y

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

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


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

Сделайте тестбенч, посмотрите на поведение вашего сумматора. Если все ОК, то в железе подключите чипскоп, чтобы поймать момент сбоя.

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


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

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

А еще хотел спросить, если выполнять преобразования векторов в integer и наоборот, это не увеличивает задержку сигнала, или в ПЛИС все будет скоммутировано также, а разница только в VHDL описании?

image238.jpg

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


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

57 минут назад, Aleksey_Serov сказал:

А еще хотел спросить, если выполнять преобразования векторов в integer и наоборот, это не увеличивает задержку сигнала, или в ПЛИС все будет скоммутировано также, а разница только в VHDL описании?

В железе никаких интежеров нет. Соответственно, нет никаких преобразований.

 

Другой вопрос, зачем вы строите сумматоры из триггеров? Авторы стандартной библиотеки VHDL и авторы синтезаторов всё для вас написали, только пользуйтесь. Соревноваться с оптимизирующим компилятором бессмыссленно.

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


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

18 hours ago, Aleksey_Serov said:

сумматор расписывал как ряд однобитных сумматоров

А сколько разрядный сумматор планируете? У Вас же там последовательный перенос - как бы эта задержка переноса не порезала рабочую частоту...

 

Пока писал пост - уже выше дали правильный совет.

 

Изменено пользователем Yuri124

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


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

Я вначале хотел написать в модуле c:=a+b как в примерах но почему-то требует c=>a+b, (я уже напрягся) уж в зависимости от бита вычитание или сложение я вообще не осилил, хотя в примерах есть. Также нашел кучу примеров, в том числе и книгу Бибило где сумматоры расписываются с базовых блоков, поэтому решил что так можно. А задержка переноса как порежет частоту до 30 МГц, если сделать конвейер и выдавать каждую итерацию по спаду/нарастанию клока, должно успеть, провернуть всю колонку из 20 сложений это конечно не успеет. Конечно, написать как в Си проще, кто же спорит, я когда за ПЛИС взялся, то мыслил категориями микроконтроллерщика, наверно не я один такой, сейчас в другую крайность наверно ударился, "собирая" все из логических элементов

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


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

1 hour ago, Aleksey_Serov said:

Я вначале хотел написать в модуле c:=a+b как в примерах но почему-то требует c=>a+b, (я уже напрягся)

задаете разрядность операндов.

используете c <= a+b;

Всё.

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


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

8 hours ago, andrew_b said:

Соревноваться с оптимизирующим компилятором бессмыссленно.

...и порой даже вредно

 

On 11/30/2020 at 2:44 PM, Aleksey_Serov said:

вычитание или сложение в следующей итерации определял по старшему 28 биту результата сложения двух опять же 28 битных чисел (старший 29-й бит отбрасывался)

действительно необходима такая точность кордика или это учебный проект?

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


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

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

 

 

действительно необходима такая точность кордика или это учебный проект?

 

Скорее учебный, разбираюсь пока, потом хочу на нч ЦАП сигнал подать, потом на высокочастотный, передатчик чм реализовать, короче, много еще в этом модуле поменяется если вообще не переделаю.

Сделать сумматор записав c <= a+b; это получается, но вот приладить туда сигнал z std_logic, который в соответствии с case заставлял бы в одном entity складывать или вычитать - вот это никак пока

И еще глюк, не знаю, может это так и должно быть, перед объявлением каждого нового entity нужно писать все включенные библиотеки, а не только в начале файла

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


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

56 minutes ago, Aleksey_Serov said:

Сделать сумматор записав c <= a+b; это получается, но вот приладить туда сигнал z std_logic, который в соответствии с case заставлял бы в одном entity складывать или вычитать - вот это никак пока

И еще глюк, не знаю, может это так и должно быть, перед объявлением каждого нового entity нужно писать все включенные библиотеки, а не только в начале файла

так может ну его этот VHDL, раз вся затея ради just for fun,

в мире ведь столько всего прекрасного: verilog, HLS, python...

srsly

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


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

36 минут назад, Doka сказал:

так может ну его этот VHDL, раз вся затея ради just for fun,

в мире ведь столько всего прекрасного: verilog, HLS, python...

srsly

vhdl - прекрасный язык. Зря вы так... Просто им уметь пользоваться надо)

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


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

9 hours ago, Aleksey_Serov said:

Сделать сумматор записав c <= a+b; это получается, но вот приладить туда сигнал z std_logic, который в соответствии с case заставлял бы в одном entity складывать или вычитать - вот это никак пока

И еще глюк, не знаю, может это так и должно быть, перед объявлением каждого нового entity нужно писать все включенные библиотеки, а не только в начале файла

прочитайте любой учебник по VHDL, хотя бы того же Сергиенко, куча вопросов снимутся.

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


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

Вы бы хоть код выложили. А то непонятен смысл этого:

Цитата

Сделать сумматор записав c <= a+b; это получается, но вот приладить туда сигнал z std_logic, который в соответствии с case заставлял бы в одном entity складывать или вычитать - вот это никак пока

И еще глюк, не знаю, может это так и должно быть, перед объявлением каждого нового entity нужно писать все включенные библиотеки, а не только в начале файла

 

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


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

process(clock)

begin

if rising_edge(clock) then

c <= a - b when z else a + b;

end if;

end process;

Как то так не пробовали?

13 hours ago, Aleksey_Serov said:

Сделать сумматор записав c <= a+b; это получается, но вот приладить туда сигнал z std_logic, который в соответствии с case заставлял бы в одном entity складывать или вычитать - вот это никак пока

Писал по памяти, может надо

c <= a - b when ??z else a + b;

Зависит от контекста

Изменено пользователем Strob

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


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

Вобщем сделал вычислительную часть, считает синус (Ну и косинус) правильно, все это сделал особым "стилем "(по выражению как написано в книге бибило) стиль в том что сумматоры побитно расписаны и все сигналы - битовые векторы, может это и не совсем правильно - запись громоздкая но судя по той же книге "и чего такого", ни одной записи вроде a+b, только хардкорная логика, может быть переделаю в "другой стиль", осталось только модуль генерации фазы написать

 

вот так выглядит сумматор
 

--------------------------

--------------------------

--

--     aa===|---|===cc

--          |add|

--     z ---|   |

--     bb===|---|

--

--------------------------

--------------------------

library ieee;

use ieee.std_logic_1164.ALL;

use ieee.numeric_std.ALL;

library UNISIM;

use UNISIM.Vcomponents.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

use IEEE.numeric_std.all;

use ieee.std_logic_misc.all;

 

entity ADSN is

port(

in_aa: in std_logic_vector (28 downto 0);

in_bb: in std_logic_vector (28 downto 0);

zn_b:in std_logic;

zn_c:out std_logic;

out_cc: out std_logic_vector (28 downto 0));

end ADSN;

 

architecture abb_sum of ADSN is

signal shina_carry_p: std_logic_vector (27 downto 0);

signal shina_data_b: std_logic_vector (28 downto 0);

-----------------------------------

-----------------------------------

component adder_other

port(

aa: in std_logic;

bb: in std_logic;

ssmm: out std_logic;

inperenos:in std_logic;

ouatperenos: out std_logic

);

end component;

----------------------------

component adder_msb

port(

aa: in std_logic;

bb: in std_logic;

ssmm: out std_logic;

ssnn: out std_logic;

inperenos:in std_logic

);

end component;

----------------------------

component invertor

port(

inp_b:in std_logic;

inp_z: in std_logic;

otp_b: out std_logic

);

end component;

begin

 

obvadderother00:adder_other

port map(

aa=>in_aa(0),

bb=>shina_data_b(0),

ssmm=>out_cc(0),

inperenos=>zn_b,

ouatperenos=>shina_carry_p(0)

);

 

makeobv: for i in 1 to 27 generate

sostavobvadders:adder_other

port map(

aa=>in_aa(i),

bb=>shina_data_b(i),

ssmm=>out_cc(i),

inperenos=>shina_carry_p(i-1),

ouatperenos=>shina_carry_p(i)

);

end generate;

 

obvadderother28:adder_msb

port map(

aa=>in_aa(28),

bb=>shina_data_b(28),

ssmm=>out_cc(28),

ssnn=>zn_c,

inperenos=>shina_carry_p(27)

);

 

makeinver: for ii in 0 to 28 generate

sostavinvq:invertor

port map(

inp_b=>in_bb(ii),

inp_z=>zn_b,

otp_b=>shina_data_b(ii)

);

end generate;

end abb_sum;

-----------------------------------

-----------------------------------

 

library ieee;

use ieee.std_logic_1164.ALL;

use ieee.numeric_std.ALL;

library UNISIM;

use UNISIM.Vcomponents.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

use IEEE.numeric_std.all;

use ieee.std_logic_misc.all;

 

entity adder_other is

port(

aa: in std_logic;

bb: in std_logic;

ssmm: out std_logic;

inperenos:in std_logic;

ouatperenos: out std_logic);

end adder_other;

 

architecture sum_elem02 of adder_other is

begin

ssmm<=

((not aa) and (not bb) and inperenos)or

(aa and (not bb) and (not inperenos))or

((not aa) and bb and (not inperenos))or(

aa and bb and inperenos);

ouatperenos<=

(aa and inperenos) or

(inperenos and bb) or

(aa and bb);

end sum_elem02;

-----------------------------------

-----------------------------------

 

 

library ieee;

use ieee.std_logic_1164.ALL;

use ieee.numeric_std.ALL;

library UNISIM;

use UNISIM.Vcomponents.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

use IEEE.numeric_std.all;

use ieee.std_logic_misc.all;

 

entity adder_msb is

port(

aa: in std_logic;

bb: in std_logic;

ssmm: out std_logic;

ssnn: out std_logic;

inperenos:in std_logic

);

end adder_msb;

 

architecture sum_elem03 of adder_msb is

begin

ssmm<=

((not aa) and (not bb) and inperenos)or

(aa and (not bb) and (not inperenos))or

((not aa) and bb and (not inperenos))or(

aa and bb and inperenos);

ssnn<=

((not aa) and (not bb) and inperenos)or

(aa and (not bb) and (not inperenos))or

((not aa) and bb and (not inperenos))or(

aa and bb and inperenos);

end sum_elem03;

-----------------------------------

-----------------------------------

library ieee;

use ieee.std_logic_1164.ALL;

use ieee.numeric_std.ALL;

library UNISIM;

use UNISIM.Vcomponents.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

use IEEE.numeric_std.all;

use ieee.std_logic_misc.all;

 

entity invertor is

port(

inp_b:in std_logic;

otp_b: out std_logic;

inp_z: in std_logic

);

end invertor;

 

architecture inverdd of invertor is

begin

otp_b<=(inp_b and (not inp_z))or((not inp_b) and inp_z);

--if inp_z==1 then inp_z_bits are inverted

end inverdd;

--------------------------

--------------------------

--

--     aa===|---|===cc

--          |add|

--     z ---|   |

--     bb===|---|

--

--------------------------

--------------------------

 

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


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

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

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

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

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

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

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

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

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

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