реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> sine with cordic vhdl, Может кому понадобится
Boobrilla
сообщение Sep 28 2017, 08:55
Сообщение #1





Группа: Участник
Сообщений: 11
Регистрация: 14-08-17
Пользователь №: 98 790



Цитата(Boobrilla @ Sep 28 2017, 08:48) *
Привет всем. Просто доделал, решил поделиться) Может молодым спецам пригодится)
Кордик для вычисления синуса 100KHz c четвертью в 250 тактов. (если какие нибудь замечания будут, или советы по оптимизации, был бы рад)
CODE
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_SIGNED.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity Toplvl is

port (
clk : std_logic;
reset : std_logic;
sinus1 : out std_logic_vector(16 downto 0));
end Toplvl;

architecture Behavioral of Toplvl is

signal quarter_1 : std_logic_vector (1 downto 0);
signal t : std_logic_vector (16 downto 0);
signal e : std_logic_vector (16 downto 0);


component math
port (
clk : in std_logic;
reset : in std_logic;
qu : out std_logic_vector (1 downto 0);
cosin : out std_logic_vector (16 downto 0);
sinus : out std_logic_vector (16 downto 0));
end component;

component right
port (
clk : in std_logic;
reset : in std_logic;
x : in std_logic_vector(16 downto 0);
y : in std_logic_vector(16 downto 0);
quarter : in std_logic_vector (1 downto 0);
xo : out std_logic_vector(16 downto 0);
yo : out std_logic_vector(16 downto 0));
end component;

begin

--sinus1 <= yx;

math_end : math
port map (
clk => clk,
reset => reset,
qu => quarter_1,
cosin => t,
sinus => e);

right_end : right
port map (
clk => clk,
reset => reset,
x => t,
y => e,
quarter => quarter_1,
yo => sinus1);

end Behavioral;


CODE
entity math is
port (
clk : in std_logic;
reset : in std_logic;
qu : out std_logic_vector (1 downto 0);
sinus : out std_logic_vector (16 downto 0);
cosin : out std_logic_vector (16 downto 0));
end math;

architecture Behavioral of math is

type my_type is array (0 to 16) of signed (16 downto 0);
signal x : my_type;
signal y : my_type;
signal z : my_type;
signal j : my_type :=("00111110011110010", "00100100111011010", "00010011011111111", "00001001111011110", "00000100111101111",
"00000010011111000", "00000001001111011", "00000000100111110", "00000000010011011", "00000000001010000",
"00000000000101000", "00000000000010100", "00000000000001010", "00000000000000101", "00000000000000011",
"00000000000000010", "00000000000000001");
signal l : std_logic_vector(16 downto 0);
signal f : std_logic_vector(16 downto 0);
component delay
port (
clk : in std_logic;
reset : in std_logic;
quarter_do : out std_logic_vector(1 downto 0));
end component;

component rotation
generic (
first : integer := 0;
second : integer := 1;
third : integer := 2;
fourth : integer := 3);
Port (
clk : in std_logic;
reset : in std_logic;
Angle : out std_logic_vector (12 downto 0);
quarter_in : out std_logic_vector (1 downto 0));
end component;

signal xangle : std_logic_vector(12 downto 0);
signal xxangle : signed(16 downto 0);

begin

rotation_XYN : rotation
port map (
clk => clk,
Angle => xangle,
reset => reset
);

delay_XYN : delay
port map (
clk => clk,
reset => reset,
quarter_do => qu
);

xxangle(16) <= '0';
xxangle(15 downto 4) <= signed(xangle(11 downto 0));
xxangle(3 downto 0) <= (others => '0');

process(clk)
begin
if rising_edge(clk) then
if reset <= '1' then
x(0) <= "00000100110110110";
y(0) <= "00000000000000000";
z(0) <= signed(xxangle);
For n in 0 to 15 loop
if (z(n) < 0) then
x(n+1) <= x(n) + (y(n)/2**n);
y(n+1) <= y(n) - (x(n)/2**n);
z(n+1) <= z(n) + j(n);
else
x(n+1) <= x(n) -(y(n)/2**n);
y(n+1) <= y(n) +(x(n)/2**n);
z(n+1) <= z(n) - j(n);
end if;
f <= std_logic_vector(x(16));
l <= std_logic_vector(y(16));
cosin <= f;
sinus <= l;
end loop;
end if;
end if;
end process;

end Behavioral;


CODE
entity rotation is
generic (
first : integer := 0;
second : integer := 1;
third : integer := 2;
fourth : integer := 3);
Port (
clk : in std_logic;
reset : in std_logic;
Angle : out std_logic_vector (12 downto 0);
quarter_in : out std_logic_vector (1 downto 0));
end rotation;

architecture Behavioral of rotation is

signal Ang : std_logic_vector (12 downto 0) := (others => '0');
signal state : unsigned (1 downto 0) := to_unsigned(first,2);
signal count_ang : std_logic_vector (11 downto 0) := (others => '0');

begin

process (clk)

begin

if (rising_edge(clk)) then
if (reset = '1') then
case(state) is
when to_unsigned(first,2) => if (count_ang >= 3999) then --00
state <= to_unsigned(second,2);
count_ang <= "000000010000";
quarter_in <= "01";
Ang <= Ang - 16;
else
state <= to_unsigned(first,2);
quarter_in <= "00";
Ang <= Ang + 16;
count_ang <= count_ang + 16;
end if;
when to_unsigned(second,2) => if (count_ang >= 3999) then --01
state <= to_unsigned(third,2);
count_ang <= "000000010000";
quarter_in <= "10";
Ang <= Ang + 16;
else
state <= to_unsigned(second,2);
quarter_in <= "01";
Ang <= Ang - 16;
count_ang <= count_ang + 16;
end if;
when to_unsigned(third,2) => if (count_ang >= 3999) then
state <= to_unsigned(fourth,2);
count_ang <= "000000010000";
quarter_in <= "11";
Ang <= Ang - 16;
else
state <= to_unsigned(third,2);
quarter_in <= "10";
Ang <= Ang + 16;
count_ang <= count_ang + 16;
end if;
when to_unsigned(fourth,2) => if (count_ang >= 3999) then
state <= to_unsigned(first,2);
count_ang <= "000000010000";
quarter_in <= "00";
Ang <= Ang + 16;
else
state <= to_unsigned(fourth,2);
quarter_in <= "11";
Ang <= Ang - 16;
count_ang <= count_ang + 16;
end if;
when others => count_ang <= (others => '0');
end case;
end if;
end if;
end process;
Angle <= Ang;
end Behavioral;


CODE
entity delay is
port (
clk : in std_logic;
reset : in std_logic;
quarter_do : out std_logic_vector(1 downto 0));

end delay;

architecture Behavioral of delay is
signal delay_1 : std_logic_vector(1 downto 0);
signal delay_2 : std_logic_vector(1 downto 0);
signal delay_3 : std_logic_vector(1 downto 0);
signal delay_4 : std_logic_vector(1 downto 0);
signal delay_5 : std_logic_vector(1 downto 0);
signal delay_6 : std_logic_vector(1 downto 0);
signal delay_7 : std_logic_vector(1 downto 0);
signal delay_8 : std_logic_vector(1 downto 0);
signal delay_9 : std_logic_vector(1 downto 0);
signal delay_10 : std_logic_vector(1 downto 0);
signal delay_11 : std_logic_vector(1 downto 0);
signal delay_12 : std_logic_vector(1 downto 0);
signal delay_13 : std_logic_vector(1 downto 0);
signal delay_14 : std_logic_vector(1 downto 0);
signal delay_15 : std_logic_vector(1 downto 0);
signal delay_16 : std_logic_vector(1 downto 0);
signal delay_17 : std_logic_vector(1 downto 0);
signal delay_18 : std_logic_vector(1 downto 0);
signal delay_19 : std_logic_vector(1 downto 0);

component rotation
generic (
first : integer := 0;
second : integer := 1;
third : integer := 2;
fourth : integer := 3);
Port (
clk : in std_logic;
reset : in std_logic;
Angle : out std_logic_vector (12 downto 0);
quarter_in : out std_logic_vector (1 downto 0));
end component;

begin

rotation_XYN : rotation
port map (
clk => clk,
reset => reset,
quarter_in => delay_1
);

process(clk)
begin
if rising_edge(clk) then
delay_2 <= delay_1;
delay_3 <= delay_2;
delay_4 <= delay_3;
delay_5 <= delay_4;
delay_6 <= delay_5;
delay_7 <= delay_6;
delay_8 <= delay_7;
delay_9 <= delay_8;
delay_10 <= delay_9;
delay_11 <= delay_10;
delay_12 <= delay_11;
delay_13 <= delay_12;
delay_14 <= delay_13;
delay_15 <= delay_14;
delay_16 <= delay_15;
delay_17 <= delay_16;
delay_18 <= delay_17;
delay_19 <= delay_18;
quarter_do <= delay_19;
end if;
end process;

end Behavioral;


CODE
entity right is
port (
clk : in std_logic;
reset : in std_logic;
x : in std_logic_vector(16 downto 0);
y : in std_logic_vector(16 downto 0);
quarter : in std_logic_vector (1 downto 0);
xo : out std_logic_vector(16 downto 0);
yo : out std_logic_vector(16 downto 0));
end right;

architecture Behavioral of right is

signal xq1 : std_logic_vector(16 downto 0);
signal xq2 : std_logic_vector(16 downto 0);
signal yq1 : std_logic_vector(16 downto 0);
signal yq2 : std_logic_vector(16 downto 0);

signal xr : std_logic_vector(16 downto 0);
signal yr : std_logic_vector(16 downto 0);

begin

xq1 <= x + 0;
yq1 <= y + 0;
xq2 <= 0 - x;
yq2 <= 0 - y;


process(clk)

begin
if (rising_edge(clk)) then
if (reset = '1') then
case (quarter) is
when "00" =>
yr <= yq1;
xr <= xq1;
when "01" =>
yr <= yq1;
xr <= xq2;
when "10" =>
yr <= yq2;
xr <= xq2;
when "11" =>
yr <= yq2;
xr <= xq1;
when others =>
xr <= (others => '0');
yr <= (others => '0');
end case;
else
xr <= (others => '0');
yr <= (others => '0');
end if;
end if;
end process;
xo <= xr;
yo <= yr;
end Behavioral;

Ну и результат



Сообщение отредактировал Boobrilla - Sep 28 2017, 09:17
Go to the top of the page
 
+Quote Post
Flip-fl0p
сообщение Sep 28 2017, 10:28
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 423
Регистрация: 11-06-13
Из: Санкт-Петербург
Пользователь №: 77 140



А вот у Вас в модуле Toplvl есть порты, которые объявляются без указания направления. Это так задумано, или ошибка, или ISE позволяет такие вольности с языком ?
Код
entity Toplvl is

    port (
            clk         : std_logic;
            reset     : std_logic;
            sinus1     : out std_logic_vector(16 downto 0));
end Toplvl;


Из советов по оптимизации я бы модуль delay - описал так(только параметры WIDTH и LENGTH указал):
Это по сути многоразрядный сдвиговый регистр.
Ваш подход "в лоб" уж больно некрасиво смотрится.
А если надо длину задержки поменять ?
Код
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;

ENTITY SHIFT_RAM IS
    GENERIC
    (
        WIDTH      : INTEGER := 24;
        LENGTH     : INTEGER := 6
    );
    PORT
    (
       CLK          : IN   STD_LOGIC;
       DATA_IN      : IN   STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
       DATA_OUT     : OUT  STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0)
    );
END ENTITY;

ARCHITECTURE RTL OF SHIFT_RAM IS
    TYPE      REG_RAM IS ARRAY (LENGTH-1 DOWNTO 0) OF STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
    SIGNAL    REG  : REG_RAM;
    ATTRIBUTE RAMSTYLE : STRING;
    ATTRIBUTE RAMSTYLE OF REG : SIGNAL IS "M9K";
BEGIN
    SHIFT_REG_PROC : PROCESS
    (
        CLK
    )
    BEGIN
        IF (RISING_EDGE(CLK)) THEN                              -- По каждому переднему фронту
            REG <= REG(LENGTH-2 DOWNTO 0) & DATA_IN;             -- Запишем в младший разряд данные со входа и сдвинем их
        END IF;
    END PROCESS SHIFT_REG_PROC;              
    DATA_OUT <= REG(LENGTH-1);
END ARCHITECTURE;


Сообщение отредактировал Flip-fl0p - Sep 28 2017, 10:30
Go to the top of the page
 
+Quote Post
Boobrilla
сообщение Sep 28 2017, 12:35
Сообщение #3





Группа: Участник
Сообщений: 11
Регистрация: 14-08-17
Пользователь №: 98 790



По портам не заметил) Но, видимо, ISE позволяет) (оба in).
По поводу подхода "в лоб" - я слишком еще не опытен. Лучше сделать так, как точно будет работать) Ну а если нужно будет изменить длину задержки, то просто добавлять/удалять кол-во переменных действий) В моем случае задержка была 190 ns = 19 по 10 ns.
Go to the top of the page
 
+Quote Post
Flip-fl0p
сообщение Sep 28 2017, 12:38
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 423
Регистрация: 11-06-13
Из: Санкт-Петербург
Пользователь №: 77 140



Цитата(Boobrilla @ Sep 28 2017, 15:35) *
По портам не заметил) Но, видимо, ISE позволяет) (оба in).
По поводу подхода "в лоб" - я слишком еще не опытен. Лучше сделать так, как точно будет работать) Ну а если нужно будет изменить длину задержки, то просто добавлять/удалять кол-во переменных действий) В моем случае задержка была 190 ns = 19 по 10 ns.

А если задержка 1000 ns ? Тогда 100 по 10 ? wacko.gif
Go to the top of the page
 
+Quote Post
Boobrilla
сообщение Sep 28 2017, 12:58
Сообщение #5





Группа: Участник
Сообщений: 11
Регистрация: 14-08-17
Пользователь №: 98 790



Ну выходит что так) Но я бы просто тогда наверно вермя такта менял, если бы этого позволяло задание

Сообщение отредактировал Boobrilla - Sep 28 2017, 13:00
Go to the top of the page
 
+Quote Post
Maverick
сообщение Sep 28 2017, 14:58
Сообщение #6


я только учусь...
******

Группа: Модераторы
Сообщений: 3 394
Регистрация: 29-01-07
Из: Украина
Пользователь №: 24 839



Цитата(Boobrilla @ Sep 28 2017, 15:58) *
Ну выходит что так) Но я бы просто тогда наверно вермя такта менял, если бы этого позволяло задание

где тестбенч для симуляции?


--------------------
If it doesn't work in simulation, it won't work on the board.

"Ты живешь в своих поступках, а не в теле. Ты — это твои действия, и нет другого тебя" Антуан де Сент-Экзюпери повесть "Маленький принц"
Go to the top of the page
 
+Quote Post
Boobrilla
сообщение Oct 2 2017, 06:27
Сообщение #7





Группа: Участник
Сообщений: 11
Регистрация: 14-08-17
Пользователь №: 98 790



Цитата(Maverick @ Sep 28 2017, 14:58) *
где тестбенч для симуляции?

Тестбенч не кидал, ибо он стандартно "пустой", ничего не добавлял. Кроме наверное ресета = 1 .
CODE
ENTITY Final IS
END Final;

ARCHITECTURE behavior OF Final IS

COMPONENT Toplvl
PORT(
clk : IN std_logic;
reset : IN std_logic;
sinus1 : OUT std_logic_vector(16 downto 0)
);
END COMPONENT;


--Inputs
signal clk : std_logic := '0';
signal reset : std_logic := '0';

--Outputs
signal sinus1 : std_logic_vector(16 downto 0);

-- Clock period definitions
constant clk_period : time := 10 ns;

BEGIN

-- Instantiate the Unit Under Test (UUT)
uut: Toplvl PORT MAP (
clk => clk,
reset => reset,
sinus1 => sinus1
);

-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;

-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait for 100 ns;

wait for clk_period*10;
reset <= '1';
-- insert stimulus here

wait;
end process;
END;
Go to the top of the page
 
+Quote Post
Bad0512
сообщение Oct 3 2017, 05:06
Сообщение #8


Знающий
****

Группа: Свой
Сообщений: 787
Регистрация: 11-05-07
Из: Томск
Пользователь №: 27 650



Цитата(Boobrilla @ Sep 28 2017, 15:55) *
Ну и результат

Какой SFDR у вас в итоге получился? Сколько ресурсов при этом было сожрано? По сравнению с классической DDS (четверть периода в RAM block плюс логика управления) какие преимущества у вашего решения?
Ну и более глобальный вопрос ( на вырост ) : с какой целью все эти усилия по изобретению очередного велосипеда?
Go to the top of the page
 
+Quote Post
Amurak
сообщение Oct 3 2017, 13:21
Сообщение #9


Частый гость
**

Группа: Свой
Сообщений: 193
Регистрация: 18-11-12
Пользователь №: 74 459



Цитата(Bad0512 @ Oct 3 2017, 08:06) *
Ну и более глобальный вопрос ( на вырост ) : с какой целью все эти усилия по изобретению очередного велосипеда?


Сейчас отобьете у человека желание заниматься проектированием ПЛИС. sm.gif
Go to the top of the page
 
+Quote Post
Flip-fl0p
сообщение Oct 3 2017, 13:39
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 423
Регистрация: 11-06-13
Из: Санкт-Петербург
Пользователь №: 77 140



Цитата(Amurak @ Oct 3 2017, 16:21) *
Сейчас отобьете у человека желание заниматься проектированием ПЛИС. sm.gif

То что человек выложил готовый модуль - это хорошо, честь ему и хвала за старание и плюсик в карму.
То что модуль задокументирован чуть больше чем никак - это плохо. Ибо отсутствие какой-либо документации кода (хотя бы комментариев) сводит на нет всю пользу модуля.
Проще с нуля написать, чем разобраться в этом коде. Тем более, по моему скромному мнению, многие куски кода написаны уж больно "некрасиво".
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th November 2017 - 09:42
Рейтинг@Mail.ru


Страница сгенерированна за 0.01327 секунд с 7
ELECTRONIX ©2004-2016