Kirill.L 0 12 июля, 2023 Опубликовано 12 июля, 2023 · Жалоба Добрый день! Я хочу реализовать DDS и для этого логично нужна таблица поиска синуса в ПЗУ, я решил взять способ представления синуса через интерполяцию из книги Титце и Шенка 1982 года (да можно CORDIC или разложение в ряды по Чебышеву или Тейлору, но мне интересно попробовать так), на вход ПЗУ будет поступать 12-и разрядное слово и на выходе тоже будет 12-и разрядное слово, АЦП 10 бит. Возник вопрос, АЦП работает в диапазоне от 0 1024, а на выходе ПЗУ мы получаем дробное число, тогда для адекватного представления данных из АЦП мне надо выходное число из ПЗУ дополнительно умножить на 512 и прибавить 512, но тогда по логике разрядность числа после этих этих операций составит 20 бит минимум, и не понятно как потом его подавать на АЦП, выкинуть 10 бит лишних? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 61 12 июля, 2023 Опубликовано 12 июля, 2023 · Жалоба On 7/12/2023 at 8:48 AM, Kirill.L said: выкинуть 10 бит лишних? Да, взять только 10 старших бит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 12 июля, 2023 Опубликовано 12 июля, 2023 · Жалоба Задавать начальную фазу как планируете в интеполяционной реализации? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kirill.L 0 12 июля, 2023 Опубликовано 12 июля, 2023 · Жалоба 14 минут назад, Maverick_ сказал: Задавать начальную фазу как планируете в интеполяционной реализации? Через фазовый аккумулятор, возможно я конечно не понял вопроса. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 16 12 июля, 2023 Опубликовано 12 июля, 2023 · Жалоба 1 hour ago, Kirill.L said: на выходе ПЗУ мы получаем дробное число Ничего подобного. В ПЗУ хранится таблица синуса в целых числах, то есть уже умноженных на какую-то степень двойки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 12 июля, 2023 Опубликовано 12 июля, 2023 · Жалоба library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; use ieee.math_real.all; entity dds_sine is port( i_clk : in std_logic; i_rstb : in std_logic; i_sync_reset : in std_logic; i_fcw : in std_logic_vector(31 downto 0); i_start_phase : in std_logic_vector(31 downto 0); o_sine : out std_logic_vector(13 downto 0)); end dds_sine; architecture rtl of dds_sine is constant C_LUT_DEPTH : integer := 2**13; -- 8Kword constant C_LUT_BIT : integer := 14; -- 14 bit LUT type t_lut_sin is array(0 to C_LUT_DEPTH-1) of std_logic_vector(C_LUT_BIT-1 downto 0); -- quantize a real value as signed function quantization_sgn(nbit : integer; max_abs : real; dval : real) return std_logic_vector is variable temp : std_logic_vector(nbit-1 downto 0):=(others=>'0'); constant scale : real :=(2.0**(real(nbit-1)))/max_abs; constant minq : integer := -(2**(nbit-1)); constant maxq : integer := +(2**(nbit-1))-1; variable itemp : integer := 0; begin if(nbit>0) then if (dval>=0.0) then itemp := +(integer(+dval*scale+0.49)); else itemp := -(integer(-dval*scale+0.49)); end if; if(itemp<minq) then itemp := minq; end if; if(itemp>maxq) then itemp := maxq; end if; end if; temp := std_logic_vector(to_signed(itemp,nbit)); return temp; end quantization_sgn; -- generate the sine values for a LUT of depth "LUT_DEPTH" and quantization of "LUT_BIT" function init_lut_sin return t_lut_sin is variable ret : t_lut_sin:=(others=>(others=>'0')); -- LUT generated variable v_tstep : real:=0.0; variable v_qsine_sgn : std_logic_vector(C_LUT_BIT-1 downto 0):=(others=>'0'); constant step : real := 1.00/real(C_LUT_DEPTH); begin for count in 0 to C_LUT_DEPTH-1 loop v_qsine_sgn := quantization_sgn(C_LUT_BIT, 1.0,sin(MATH_2_PI*v_tstep)); ret(count) := v_qsine_sgn; v_tstep := v_tstep + step; end loop; return ret; end function init_lut_sin; -- initialize LUT with sine samples constant C_LUT_SIN : t_lut_sin := init_lut_sin; signal r_sync_reset : std_logic; signal r_start_phase : unsigned(31 downto 0); signal r_fcw : unsigned(31 downto 0); signal r_nco : unsigned(31 downto 0); signal lut_addr : std_logic_vector(12 downto 0); signal lut_value : std_logic_vector(13 downto 0); begin p_nco : process(i_clk,i_rstb) begin if(i_rstb='0') then r_sync_reset <= '1'; r_start_phase <= (others=>'0'); r_fcw <= (others=>'0'); r_nco <= (others=>'0'); elsif(rising_edge(i_clk)) then r_sync_reset <= i_sync_reset ; r_start_phase <= unsigned(i_start_phase); r_fcw <= unsigned(i_fcw); if(r_sync_reset='1') then r_nco <= r_start_phase; else r_nco <= r_nco + r_fcw; end if; end if; end process p_nco; p_rom : process(i_clk) begin if(rising_edge(i_clk)) then lut_addr <= std_logic_vector(r_nco(31 downto 19)); lut_value <= C_LUT_SIN(to_integer(unsigned(lut_addr))); end if; end process p_rom; p_sine : process(i_clk,i_rstb) begin if(i_rstb='0') then o_sine <= (others=>'0'); elsif(rising_edge(i_clk)) then o_sine <= lut_value; end if; end process p_sine; end rtl; у меня так сделано PS при симуляции не забудь сделать o_sine : out std_logic_vector(13 downto 0)); => signed иначе будете наблюдать в Analog представлении не синус 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kirill.L 0 12 июля, 2023 Опубликовано 12 июля, 2023 · Жалоба Видимо я плохо понял, что к чему, может кто то пояснить как я могу сделать эту несчастную таблицу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 12 июля, 2023 Опубликовано 12 июля, 2023 · Жалоба Мое описание не вариант? там автоматически генерируется второй вариант через матлаб скрипт - инициализируете память 10 minutes ago, Kirill.L said: Видимо я плохо понял, что к чему, может кто то пояснить как я могу сделать эту несчастную таблицу. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
krux 8 13 июля, 2023 Опубликовано 13 июля, 2023 · Жалоба Добавлю немного из истории математики. Легендарные таблицы Брадиса были сделаны при помощи полиномов Чебышева. Сначала определялся необходимый порядок полинома, для того чтобы ошибка в результате вычислений не превышала некий допуск, а затем вперед и с песней, заполняем таблицу. Кстати в области EECS floating point, Ieee754 и библиотеки glibc под *nix всем этим пользуются втихую, но поскольку комментариев там в коде нету -- они все делают вид что это ноу-хау и константы, подставляемые в SIMD/SSE2/AVX-регистры для вычислений взялись "из воздуха". И да, при наличии "железячной" реализации операции умножения стоит оценить затраты по сравнению с CORDIC. Для потоковых вычислений с плавающим углом вектора CORDIC конечно будет интереснее, а во всех других случаях - нужно такты считать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_4afc_ 25 14 июля, 2023 Опубликовано 14 июля, 2023 · Жалоба 16 hours ago, krux said: Добавлю немного из истории математики. Кстати в области EECS floating point, Ieee754 и библиотеки glibc под *nix всем этим пользуются втихую, но поскольку комментариев там в коде нету -- они все делают вид что это ноу-хау и константы, подставляемые в SIMD/SSE2/AVX-регистры для вычислений взялись "из воздуха". Тоже добавлю немного истории HARD+SOFT: легендарный математический сопроцессор фирмы Motorolla MC68881 поддерживал в том числе тригонометрические функции. The monadic operations available with the FPCP are as follows: FABS Absolute Value FLOG2 Log Base 2 FACOS Arc Cosine FLOGN Log Base e FASIN Arc Sine FLOGNP1 Log Base e of (x+ 1) FATAN Arc Tangent FNEG Negate FATANH Hyperbolic Arc Tangent FSIN Sine FCOS Cosine FSINCOS Simultaneous Sine and Cosine FCOSH Hyperbolic Cosine FSINH Hyperbolic Sine FETOX e to the x Power FSORT Square Root FETOXM1 e to the x Power - 1 FTAN Tangent FGETEXP Get Exponent FTANH Hyperbolic Tangent FGETMAN Get Mantissa FTENTOX 10 to the x Power FINT Integer Part FTST Test FINTRZ Integer Part (Truncated) FTWOTOX 2 to the x Power FLOG 10 Log Base 10 В последствии все вычисления FPU встроили в 68040/68060, убрав при этом все эти sin/cos. Получившуюся несовместимость с уже существующим софтом решали программно: вызовом библиотек через срабатывающие исключения, поэтому многие алгоритмы на 68881 работали быстрее чем на 68060 🙂 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться