caps_lock 0 3 октября, 2007 Опубликовано 3 октября, 2007 · Жалоба всем привет. тема уже поднималась как минимум раза 2, но все же - скажите правильно ли я думаю Есть выход дельта-сигма модулятoра, 1 bit stream идет с частотой 64*44.1 (kHz) = 2.8224 (MHz) нужно провести децимацию и на выходе получить 16 бит PCM с sample rate = 44.1 kHz. как проводим децимацию вроде бы понятно: (M=64) ФНЧ КИХ- (вырезаем шумы) + регистр (тактируемый частотой 2.8224 MHz / 64). но вот как получить 16 битные x(n) из однобитового потока. в pdf статье (в самом конце) написано, что используется трансверсальный фильтр с коэффициентами = 1. Если коэффиценты = 1, то это похоже на сдвиговый регистр разрядность 16 бит. я прав? Далее, в начале этой статьи написано, что fT = Kпер * fД в моем случае fT = 2.8224 MHz fД = 44.1 кГц Kпер = 64. Но ниже написано Kпер = 2^N, N - разрядность выходного сигнала. мне надо 16 бит, 2^16 = 65536, получается Kпер = 65536, но ведь у меня 64. что я неправильно понял? И все же, сколько линий здержек долно быть в фильтре-преобразователе 1 bit to 16 bits? 16 или 6 (2^6=64)? если шесть, то где разрядность 16 бит? SIGMA_DELTA_ARTICLE.pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexZabr 0 3 октября, 2007 Опубликовано 3 октября, 2007 · Жалоба Я в плане FPGA новичок, врядле смогу помочь конкретно к сожалению, но имею понятие в DSP (хотя больше в плане теории, практический опет - небольшой). Я честно говоря не совсем понял: имеется 1-битный serial stream данных который представляет из себя 64-битный (т.е. цельное данное есть 64 разряда) поток sampled с 44.1 kHz ? Если так то на выходе bit rate действитеьно 64*44.1kHz. Вам нужно продесимировать ? Или уменьшить разрядность данных ? По моему это разные вещи. Десимация вам уменьшит эффектиную частоту (sampling rate и соотв. nyquist-limited bandwith) что дает более низкие rates сигнала и ессно позволяет обработку сигнала на более низких частотах. Насколько я понял, вы говорите об уменьшении разрядности данных в 4 раза (т.е. разрядность данного падает с 64 до 16 бит). Я ошибаюсь ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
caps_lock 0 4 октября, 2007 Опубликовано 4 октября, 2007 (изменено) · Жалоба Я в плане FPGA новичок, врядле смогу помочь конкретно к сожалению, но имею понятие в DSP (хотя больше в плане теории, практический опет - небольшой). Я честно говоря не совсем понял: имеется 1-битный serial stream данных который представляет из себя 64-битный (т.е. цельное данное есть 64 разряда) поток sampled с 44.1 kHz ? Если так то на выходе bit rate действитеьно 64*44.1kHz. Вам нужно продесимировать ? Или уменьшить разрядность данных ? По моему это разные вещи. Десимация вам уменьшит эффектиную частоту (sampling rate и соотв. nyquist-limited bandwith) что дает более низкие rates сигнала и ессно позволяет обработку сигнала на более низких частотах. Насколько я понял, вы говорите об уменьшении разрядности данных в 4 раза (т.е. разрядность данного падает с 64 до 16 бит). Я ошибаюсь ? однобитовый поток идет с чатотой 2.8224 МГц,из него мне надо сделать 16 бит с sample rate'ом 44.1 кГц с помощью дециматора я уменьшу частоту дискретизации в 64 раза, т.е. получу 44.1 кГц, но на входе дециматора мне надо как-то из однобитового сделать 16 битовый, вот я и хочу узнать корректно ли поставить сдвиговый регистр разрядносью 16 бит, 16битный выход которого я подам на дециматор. Изменено 4 октября, 2007 пользователем Don Man Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DmitryR 0 4 октября, 2007 Опубликовано 4 октября, 2007 · Жалоба Есть выход дельта-сигма модулятoра, 1 bit stream идет с частотой 64*44.1 (kHz) = 2.8224 (MHz) нужно провести децимацию и на выходе получить 16 бит PCM с sample rate = 44.1 kHz. reg [15:0] delay; reg [ 1:0] decim_cnt=0; reg [ 3:0] dv_cnt=0; integer i; always @(posedge clk) begin decim_cnt<=decim_cnt+1; if(decim_cnt==2'b11) begin dv_cnt<=dv_cnt+1; delay[0]<=serial_data_in; for(i=1;i<16;i=i+1) delay<=delay[i-1]; end end assign parallel_output=delay; assign parallel_output_data_valid=(dv_cnt==0) ? 1:0 Так по-простому. Но раз там есть КИХ - я бы дециматор в него встроил наверное. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
caps_lock 0 4 октября, 2007 Опубликовано 4 октября, 2007 · Жалоба reg [15:0] delay; reg [ 1:0] decim_cnt=0; reg [ 3:0] dv_cnt=0; integer i; always @(posedge clk) begin decim_cnt<=decim_cnt+1; if(decim_cnt==2'b11) begin dv_cnt<=dv_cnt+1; delay[0]<=serial_data_in; for(i=1;i<16;i=i+1) delay<=delay[i-1]; end end assign parallel_output=delay; assign parallel_output_data_valid=(dv_cnt==0) ? 1:0 Так по-простому. Но раз там есть КИХ - я бы дециматор в него встроил наверное. немного не понял: decim_cnt<=decim_cnt+1; if(decim_cnt==2'b11) а зачем этот enable? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexZabr 0 4 октября, 2007 Опубликовано 4 октября, 2007 · Жалоба По идее, если я правильно понял, после необходимого LPFа (antialiasing режущий на 1/4 первоначального nyquist-bandwithа) нужно просто брать каждый 4ый sample и пихать его в сдвиговый регистр с параллельным считыванием 16 бит. Хоть я не знаком с синтаксисом Верилога, но чисто интуитивно строчки: decim_cnt<=decim_cnt+1; if(decim_cnt==2'b11) как раз и отсчитывают каждый четвертый sample. А вот след. часть кода мне не совсем ясна. То что вижу это каждый четвертый sample принимается на вход сдвиг. регистра и затем в for рутине сдвигается на 16 позиций вперед (по принципу fifo ?). Но если так, то по идее, насколько я понимаю каждый послд. отобранный sample (т.е. каждый четвертый последующий) должен сдвигаться на одни сдвиг меньше (т.е. второй отобранный идет на 15ое место, третуй отобранный на 14ое место и т.д. пока 16ый отобранный не станет на первое место). А в коде все отобранные биты сдвигаются на одинаковое (максимальное) кольво сдвигов (т.е. на 16) Я ошибаюсь ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
el34 0 4 октября, 2007 Опубликовано 4 октября, 2007 · Жалоба по поводу единичных коэффициентов.... повидимому , т.к. поток 1_битовый, имелись ввиду коэффициенты равные 1 и 0 , но это не коэффициенты фильтра , а множители в сдвиговом регистре(1_о битовый поток с модулятора) , для получения многобитовой последовательностьи и децимации этои 1и0 домножаются(учавствует этот коэфф. или нет тк моножитель 1 или 0) на коэффициенты фильтра требуемой разрядности и складываются(fir)....и тд итп может я что не понял ... тогда сорри... еще рекомендую посмореть Cascaded Integrator-Comb (CIC) Filter они хорошо заточены под FPGA реализацию Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
PSP 0 5 октября, 2007 Опубликовано 5 октября, 2007 (изменено) · Жалоба По идее, если я правильно понял, после необходимого LPFа (antialiasing режущий на 1/4 первоначального nyquist-bandwithа) нужно просто брать каждый 4ый sample и пихать его в сдвиговый регистр с параллельным считыванием 16 бит. Хоть я не знаком с синтаксисом Верилога, но чисто интуитивно строчки: decim_cnt<=decim_cnt+1; if(decim_cnt==2'b11) как раз и отсчитывают каждый четвертый sample. А вот след. часть кода мне не совсем ясна. То что вижу это каждый четвертый sample принимается на вход сдвиг. регистра и затем в for рутине сдвигается на 16 позиций вперед (по принципу fifo ?). Но если так, то по идее, насколько я понимаю каждый послд. отобранный sample (т.е. каждый четвертый последующий) должен сдвигаться на одни сдвиг меньше (т.е. второй отобранный идет на 15ое место, третуй отобранный на 14ое место и т.д. пока 16ый отобранный не станет на первое место). А в коде все отобранные биты сдвигаются на одинаковое (максимальное) кольво сдвигов (т.е. на 16) Я ошибаюсь ? Видимо ошибаетесь. for(i=1;i<16;i=i+1) delay<=delay[i-1]; Этот код означает не 16 сдвигов входного бита, а сдвиг на 1 разряд 16-ти битного регистра. Т.е. 0-й разряд в 1-й, 1- во 2-й и т.д. Изменено 5 октября, 2007 пользователем PSP Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexZabr 0 5 октября, 2007 Опубликовано 5 октября, 2007 · Жалоба Видимо ошибаетесь. Этот код означает не 16 сдвигов входного бита, а сдвиг на 1 разряд 16-ти битного регистра. Т.е. 0-й разряд в 1-й, 1- во 2-й и т.д. Да, согласен, так и есть. Чего-то затмение нашло... :) Но что мне непонятно - каждый новый sample (релевантный бит) должен задвигаться в регистр по каждому 4ому клоку. Как уже упоминал, я ноль в синтаксе Верилога (начла изучать VHDL), но насколько я понимаю, продвижение в рутине сдвигового регистра: for(i=1;i<16;i=i+1) delay[i]<=delay[i-1]; засинхронизировано по тому-же клоку что и вся рутина целиком, т.е. по always @(posedge clk) . . . ибо весь код находиться внутри eventа по данному клоку Если это так, то туманно для меня как может приосходить временная синхронизация между отбором каждого четвертого бита и сдвиги в регистре ? Или иnкрементация индекса i тоже по тому-же клоку ? Мне кажется тут может быть фундаментальное отличие обычного программирования от hardwerного - тот concurrent выполнение, т.е. на один и тот-же клок отбирается бит кратный 4ем (по порядку поступление) и на тот-же клок происходит инкрементация индекса i регистра. Затем выходим из главной рутоны и ждем очередного 4ого по счету бита, тогда как индекс i помнит свое последнее значение. Если-бы оно посалось в обычной пограмме (не под железо), то вся сдвиговая рутина должна была-бы пробежать все 16 циклов и лишь тогда-бы мы-бы вышли в начало главной рутины. Буду рад поправкам/замечаниям ежели ошибаюсь.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
PSP 0 6 октября, 2007 Опубликовано 6 октября, 2007 · Жалоба Строчки со сдвигом бита специально находятся внутри условия if(decim_cnt==2'b11) begin ... end что и позволяет им выполняться на каждый 4-й такт. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexZabr 0 6 октября, 2007 Опубликовано 6 октября, 2007 · Жалоба Строчки со сдвигом бита специально находятся внутри условия if(decim_cnt==2'b11) begin ... end что и позволяет им выполняться на каждый 4-й такт. Да видимо. Я просто привык к контексту обычного программирования, где цикл for выполнлся бы полностью (т.е. по всему его отсчету) каждый раз когда он встречается в коде, и лишь потом рассматривается что есть дальше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
caps_lock 0 7 октября, 2007 Опубликовано 7 октября, 2007 · Жалоба и как же должно быть правильно? без условия "==2'b11" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dvladim 0 7 октября, 2007 Опубликовано 7 октября, 2007 · Жалоба delay[0]<=serial_data_in; for(i=1;i<16;i=i+1) delay<=delay[i-1]; Вот это обычно пишут так: delay <= {delay[14 : 0], serial_data_in}; Ну и вот это: assign parallel_output_data_valid=(dv_cnt==0) ? 1:0 тоже "масло масляное" assign parallel_output_data_valid = (dv_cnt == 4'h0); Хотя, я бы, поставил триггер с тем же условием, что и вычисления. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться