Знаковый квадратурный коррелятор на ПЛИС
Квадратурный знаковый коррелятор вполне известная штука, но в сети об этом нет почти никакой информации. Поэтому вполне законно будет осветить данную тему на элементарном примере. Предположим имеется цифровой сигнал (меандр) длительностью 160 мкс и частотой 200 кГц, тоесть 32 периода данной частоты. Необходимо найти максимум его совпадения с его квадратурной моделью, если выборки делать с частотой на 6.25 кГц меньше - 193.75 кГц.
Для этого поступим следующим образом: создадим так называемые синусную и косинусную модели сигнала и сохраним их в памяти. Нам понадобятся 2х32 ячейки памяти в которых будут храниться единички и нолики формирующие последовательно за 32 такта один период синуса и косинуса в цифровом виде.
При чтении из памяти это должно выглядеть так, как на картинке ниже. В нашем случае важен только сдвиг фаз между цифровыми сигналами. Знак можно оставить за скобками.
Далее необходимо осуществить свертку входного цифрового сигнала с синусной и косинусной моделями и подсчитать количество совпадений в процессе свертки. Эту операцию нужно проводить за время между двумя соседними выборками сигнала тоесть с частотой 193.75*32 = 6200 кГц. Итак для построения коррелятора нам понадобятся два элемента памяти один - в который записаны синусная и косинусная цифровые модели сигнала (меандр), другой - память для записи входного сигнала, два счетчика - один на 32 другой на 31, два элемента XOR для определения совпадений сигнала с моделью, два счетчика для подсчета совпадений и сумматор для подсчета общего количества совпадений сигнала с квадратурной моделью. Теперь записывая данные выборок в память, которая прокручивается счетчиком на 31 и ее выходные данные сравниваются с данными памяти модели которая в свою очередь прокручивается счетчиком на 32 можно за время между двумя выборками подсчитать количество совпадений входного сигнала. Поскольку с каждой новой выборкой сигдал будет как-бы наплывать (счет на 1 меньше чем у модели) на свои синусные и косинусные модели то таким образом можно будет определить максимум их совпадений. Этот максимум и называется корреляционным. Если сигнал простой то количество совпадений будет линейно нарастать и спадать образуя что-то вроде корреляционного треугольника. В случае со сложным, например ЛЧМ, сигналом, а это уже тема другого повествования, корреляционный пик будет иметь другой вид.
Код устройства представлен ниже:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity korrsign is
Port (
-- задающий клок 12400кГц
clk: in std_logic;
-- общий сброс
clr: in std_logic;
--
in_s1: in std_logic;
-- выход переноса
out_carry: out std_logic;
out_clrcnt: out std_logic;
out_clk_data: out std_logic;
out_cntsin1: out std_logic_vector(4 downto 0);
out_cntcos1: out std_logic_vector(4 downto 0);
out_sumall1: out std_logic_vector(5 downto 0);
sum_sc_out1: out std_logic_vector(5 downto 0);
--
out_sin: out std_logic;
out_cos: out std_logic;
--
out_in1: out std_logic;
-- выход счетчиков модели и сигнала
out_clk_mod: out std_logic_vector(4 downto 0);
out_clk_sig_rd: out std_logic_vector(4 downto 0);
out_clk_sig_wr: out std_logic_vector(4 downto 0)
);
end korrsign;
architecture Behavioral of korrsign is
--------------------------------------------------------------------
--
component sigdata is
generic
(
DATA_WIDTH : natural := 1;
ADDR_WIDTH : natural := 5
);
port
(
rclk : in std_logic;
wclk : in std_logic;
raddr : in std_logic_vector (0 to ADDR_WIDTH - 1);
waddr : in std_logic_vector (0 to ADDR_WIDTH - 1);
data : in std_logic;
we : in std_logic := '1';
q : out std_logic
);
end component;
--------------------------------------------------------------------
-- модель
component moddata
generic
(
DATA_WIDTH : natural := 2;
ADDR_WIDTH : natural := 5
);
port
(
rclk : in std_logic;
raddr : in std_logic_vector (0 to ADDR_WIDTH - 1);
q : out std_logic_vector((DATA_WIDTH -1) downto 0)
);
end component;
--------------------------------------------------------------------
-- счетчик модели и сигнала
signal clk_mod: std_logic_vector(5 downto 0);
signal clk_sig_rd: std_logic_vector(4 downto 0);
signal clk_sig_wr: std_logic_vector(4 downto 0);
signal clk_data: std_logic;
signal clk_sin1: std_logic_vector(4 downto 0);
signal clk_cos1: std_logic_vector(4 downto 0);
signal sum_all1: std_logic_vector(5 downto 0);
signal sum_sc1: std_logic_vector(5 downto 0);
signal s_data: std_logic;
signal s_outdata: std_logic;
--
signal carry: std_logic;
signal clr_sincos: std_logic;
signal s_q: std_logic_vector(1 downto 0);
signal s_dsin1: std_logic;
signal s_dcos1: std_logic;
--------------------------------------------------------------------
begin
-- входные данные
s_data <= in_s1;
-- память данных
usigdata : sigdata
generic map (1, 5)
port map (
rclk => not clk_mod(0),
wclk => carry,
raddr => clk_sig_rd,
waddr => clk_sig_wr,
data => s_data,
q => s_outdata
);
-- записанные данные на выход
out_in1 <= s_outdata;
-- память модели
umoddata : moddata
generic map (2, 5)
port map (
rclk => not clk_mod(0),
raddr => clk_mod(5 downto 1),
q => s_q
);
-- модель на выход
out_sin <= s_q(0);
out_cos <= s_q(1);
--------------------------------------------------------------------
-- счетчик на 64 с переносом (модель чтение)
process(clk)
begin
if clr = '0' then
clk_mod <= (others => '0');
carry <= '1';
elsif(rising_edge(clk))then
clk_mod <= clk_mod + 1 ;
carry <= '1';
if clk_mod = 63 then
carry <= '0';
else
carry <= '1';
end if;
end if;
end process;
-- частота опроса
clk_data <= clk_mod(0);
-- частота опроса на выход
out_clk_data <= clk_data;
-- перенос на выход
out_carry <= carry;
-- опрос модели на выход
out_clk_mod <= clk_mod(5 downto 1);
-- укороченный перенос
clr_sincos <= not (not carry and not clk);
-- укороченный перенос на выход
out_clrcnt <= clr_sincos;
s_dsin1 <= not (s_q(0) xor s_outdata);
s_dcos1 <= not (s_q(1) xor s_outdata);
-- счетчик на 31(сигнал чтение)
process(clk_mod(0))
begin
if clr = '0' then
clk_sig_rd <= (others => '0');
elsif(falling_edge(clk_data))then
clk_sig_rd <= clk_sig_rd + 1 ;
if clk_sig_rd = 30 then
clk_sig_rd <= (others => '0');
end if;
end if;
end process;
-- сигнал чтение на выход
out_clk_sig_rd <= clk_sig_rd;
-- счетчик на 31(сигнал запись)
process(clk_mod(0))
begin
if clr = '0' then
clk_sig_wr <= (others => '0');
elsif(rising_edge(clk_data))then
clk_sig_wr <= clk_sig_wr + 1 ;
if clk_sig_wr = 30 then
clk_sig_wr <= (others => '0');
end if;
end if;
end process;
-- сигнал запись на выход
out_clk_sig_wr <= clk_sig_wr;
-- двунаправленный счетчик sin sig1
process(clk)
begin
if clr = '0' or clr_sincos = '0' then
clk_sin1 <= (others => '0');
elsif(rising_edge(clk_data))then
if s_dsin1 = '1' then
clk_sin1 <= clk_sin1 + 1 ;
end if;
end if;
out_cntsin1 <= clk_sin1;
end process;
-- двунаправленный счетчик cos sig1
process(clk)
begin
if clr = '0' or clr_sincos = '0' then
clk_cos1 <= (others => '0');
elsif(rising_edge(clk_data))then
if s_dcos1 = '1' then
clk_cos1 <= clk_cos1 + 1 ;
end if;
end if;
out_cntcos1 <= clk_cos1;
end process;
sum_sc1 <= conv_std_logic_vector((conv_integer(clk_sin1) + conv_integer(clk_cos1)), 6);
sum_sc_out1 <= sum_sc1;
-- регистр после сумматора
process(clk)
begin
if(falling_edge(carry))then
if sum_sc1 > sum_all1 then
sum_all1 <= sum_sc1;
end if;
end if;
end process;
out_sumall1 <= sum_all1;
end Behavioral;
Диаграмма свертки: в начале совпадений только 32 затем они постепенно увеличиваются до 48 и это и будет максимум.
Проект квадратурного знакового коррелятора для Quartus90 можно получить по ссылке ниже по тексту.
Электроника :
- Техника электроника (11)
- Полезная электроника (4)
- Электроника для всех (5)
- Техника для дома (6)
- Cхемотехника ПЛИС (11)
- Пректирование PCAD (4)
Программирование :
- Микроконтроллеры (9)
- ПЛИС VHDL Verilog (29)
- C++ Builder (7)
- Visual Studio C++ C# (7)
- Java programming (7)
- Matlab programming (4)
Сайтостроение :
- Сайтостроение HTML (5)
- Сайтостроение PHP (8)
- PHP CMS на файлах (3)
- Web инструменты (9)
- Полезное вебмастеру (11)
- SEO раскрутка сайта (4)
- PHP скрипты (3)
Реклама :
Книги и учебники :
- Шаблоны сайтов (6)
- Книги и учебники (2)
Компьютер и интернет :
Поиск по сайту :
Реклама :
Облако меток :
Бесплатная подписка :
Статистика :
- Популярность (3)
- Посещаемость (3)
- Поисковые запросы (3)