Jump to content

    
Sign in to follow this  
Aleksey_Serov

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

Recommended Posts

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

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

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

image238.jpg

Share this post


Link to post
Share on other sites
57 минут назад, Aleksey_Serov сказал:

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

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

 

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

Share this post


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

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

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

 

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

 

Edited by Yuri124

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
1 hour ago, Aleksey_Serov said:

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

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

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

Всё.

Share this post


Link to post
Share on other sites
8 hours ago, andrew_b said:

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

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

 

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

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

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

Share this post


Link to post
Share on other sites
2 часа назад, Doka сказал:

 

 

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

 

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

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

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

Share this post


Link to post
Share on other sites
56 minutes ago, Aleksey_Serov said:

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

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

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

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

srsly

Share this post


Link to post
Share on other sites
36 минут назад, Doka сказал:

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

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

srsly

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

Share this post


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

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

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

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

Share this post


Link to post
Share on other sites

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

Цитата

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

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

 

Share this post


Link to post
Share on other sites

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;

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

Edited by Strob

Share this post


Link to post
Share on other sites

Вобщем сделал вычислительную часть, считает синус (Ну и косинус) правильно, все это сделал особым "стилем "(по выражению как написано в книге бибило) стиль в том что сумматоры побитно расписаны и все сигналы - битовые векторы, может это и не совсем правильно - запись громоздкая но судя по той же книге "и чего такого", ни одной записи вроде 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===|---|

--

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

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

 

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