मतलाब में बटरवर्थ फ़िल्टर डिज़ाइन करना और ऑनलाइन वेरिलॉग एचडीएल कोड जनरेटर के लिए पूर्णांक के रूप में गुणांक [ab] गुणांक प्राप्त करना


15

मैंने Matlab का उपयोग करते हुए एक बहुत ही सरल कम-पास बटरवर्थ फ़िल्टर बनाया है। निम्न कोड स्निपेट प्रदर्शित करता है कि मैंने क्या किया है।

fs = 2.1e6;
flow = 44 * 1000;
fNorm =  flow / (fs / 2);
[b,a] = butter(10, fNorm, 'low');

[ख] में, फ़िल्टर गुणांक संग्रहीत किए जाते हैं। मैं पूर्णांक के रूप में [b] प्राप्त करना चाहता हूं, ताकि मैं वेरिलोग में कोड उत्पन्न करने के लिए एक ऑनलाइन एचडीएल कोड जनरेटर का उपयोग कर सकूं।

ऑनलाइन कोड जनरेटर (सर्वर-साइड पर्ल स्क्रिप्ट को गुणांक के साथ कोड जनरेट करने से इनकार करता है) के साथ उपयोग करने के लिए Matlab [b] मान बहुत छोटा प्रतीत होता है, और मैं सोच रहा हूं कि क्या यह संभव होगा [b] a] एक ऐसे रूप में जिसका उपयोग एक उचित इनपुट के रूप में किया जा सकता है।

मतलाब में मुझे जो गुणांक मिलते हैं वे हैं:

1.0000
-9.1585
37.7780
-92.4225
148.5066
-163.7596
125.5009
-66.0030
22.7969
-4.6694
0.4307

मतलेब में मुझे जो बी गुणांक मिलते हैं वे हैं:

1.0167e-012
1.0167e-011
4.5752e-011
1.2201e-010
2.1351e-010
2.5621e-010
2.1351e-010
1.2201e-010
4.5752e-011
1.0167e-011
1.0167e-012

ऑनलाइन जनरेटर का उपयोग करते हुए, मैं 12-बिट बिटकॉइन और I या II फिल्टर फॉर्म के साथ एक फिल्टर डिजाइन करना चाहूंगा। मुझे नहीं पता कि उपरोक्त लिंक पर "आंशिक बिट्स" का क्या मतलब है।

कोड जनरेटर (http://www.spiral.net/hardware/filter.html) को चलाने में [ख], ऊपर सूचीबद्ध गुणांक, भिन्नात्मक बिट्स २० पर सेट और १२ की एक बिटवॉयर के साथ, मुझे निम्न रन त्रुटि प्राप्त होती है :

Integer A constants: 1048576 -9603383 39613104 -96912015 155720456 -171714386 131597231 -69209161 23904282 -4896220 451621
Integer B constants: 0 0 0 0 0 0 0 0 0 0 0

Error: constants wider than 26 bits are not allowed, offending constant = -69209161, effective bitwidth = 7 mantissa + 20 fractional = 27 total.

An error has occurred - please revise the input parameters. 

मैं अपना डिज़ाइन कैसे बदल सकता हूं ताकि यह त्रुटि न हो?

अद्यतन: 6-क्रम का बटरवर्थ फ़िल्टर बनाने के लिए मतलाब का उपयोग करना, मुझे निम्नलिखित गुणांक मिलते हैं:

के लिए:

1.0000
-5.4914
12.5848
-15.4051
10.6225
-3.9118
0.6010 

बी के लिए:

0.0064e-005
0.0382e-005
0.0954e-005
0.1272e-005
0.0954e-005
0.0382e-005
0.0064e-005

ऑनलाइन कोड जनरेटर (http://www.spiral.net/hardware/filter.html) चला रहा हूं, मुझे अब निम्न त्रुटि (8 के रूप में आंशिक बिट्स और 20 के बिटकॉइन के साथ) प्राप्त होती है:

./iirGen.pl -A 256  '-1405' '3221' '-3943' '2719' '-1001' '153' -B  '0' '0' '0' '0' '0' '0' '0' -moduleName acm_filter -fractionalBits 8 -bitWidth 20 -inData inData  -inReg   -outReg  -outData outData -clk clk -reset reset -reset_edge negedge -filterForm 1  -debug  -outFile ../outputs/filter_1330617505.v 2>&1 
At least 1 non-zero-valued constant is required.  Please check the inputs and try again.

शायद b- गुणांक बहुत छोटा है, या शायद कोड जनरेटर (http://www.spiral.net/hardware/filter.html) दूसरे प्रारूप में [b, a] चाहता है?

अपडेट करें:

शायद मुझे जो करने की आवश्यकता है, वह पूर्णांक के रूप में गुणांक प्राप्त करने के लिए भिन्नात्मक बिट्स की संख्या के हिसाब से [बी, ए] गुणांक है।

a .* 2^12
b .* 2^12

हालांकि, मुझे अभी भी लगता है कि बी गुणांक बहुत छोटा है। मुझसे यहां क्या गलत हो रहा है?

शायद एक और प्रकार का फ़िल्टर (या फ़िल्टर डिज़ाइन विधि) अधिक उपयुक्त होगा? क्या कोई सुझाव दे सकता है?

अद्यतन: जैसा कि नीचे टिप्पणी में जेसन आर और क्रिस्टोफर फेल्टन द्वारा सुझाया गया है, एक एसओएस फ़िल्टर अधिक उपयुक्त होगा। मैंने अब SOS फ़िल्टर प्राप्त करने के लिए कुछ Matlab कोड लिखे हैं।

fs = 2.1e6;
flow = 44 * 1000;      
fNorm =  flow / (fs / 2);
[A,B,C,D] = butter(10, fNorm, 'low');
[sos,g] = ss2sos(A,B,C,D);

एसओएस मैट्रिक्स जो मुझे मिलता है वह है:

1.0000    3.4724    3.1253    1.0000   -1.7551    0.7705
1.0000    2.5057    1.9919    1.0000   -1.7751    0.7906
1.0000    1.6873    1.0267    1.0000   -1.8143    0.8301
1.0000    1.2550    0.5137    1.0000   -1.8712    0.8875
1.0000    1.0795    0.3046    1.0000   -1.9428    0.9598

क्या अभी भी इस SOS फ़िल्टर को लागू करने के लिए Verilog कोड जनरेशन टूल (http://www.spiral.net/hardware/filter.html) का उपयोग करना संभव है, या मुझे बस हाथ से वेरिलॉग लिखना चाहिए? क्या एक अच्छा संदर्भ उपलब्ध है?

मुझे आश्चर्य होगा कि इस स्थिति में एफआईआर फिल्टर का उपयोग करना बेहतर होगा।

अधिक: पुनरावर्ती IIR फ़िल्टर को गुणांक को भिन्न के रूप में व्यक्त करके पूर्णांक गणित का उपयोग करके लागू किया जा सकता है। (आगे के विवरणों के लिए स्मिथ की उत्कृष्ट डीएसपी सिग्नल प्रोसेसिंग बुक देखें: http://www.dspguide.com/ch19/5.htm )

निम्नलिखित Matlab कार्यक्रम बटरवर्थ फ़िल्टर गुणांक को आंशिक भागों में Matlab चूहे () फ़ंक्शन का उपयोग करके परिवर्तित करता है। फिर जैसा कि टिप्पणियों में उल्लेख किया गया है, दूसरे क्रम खंडों का उपयोग फ़िल्टर को पूरा करने के लिए किया जा सकता है (http://en.wikipedia.org/wiki/Digital_biquad_filter)।

% variables
% variables
fs = 2.1e6;                     % sampling frequency           
flow = 44 * 1000;               % lowpass filter


% pre-calculations
fNorm =  flow / (fs / 2);       % normalized freq for lowpass filter

% uncomment this to look at the coefficients in fvtool
% compute [b,a] coefficients
% [b,a] = butter(7, fNorm, 'low');
% fvtool(b,a)  

% compute SOS coefficients (7th order filter)
[z,p,k] = butter(7, fNorm, 'low');

% NOTE that we might have to scale things to make sure
% that everything works out well (see zp2sos help for 'up' and 'inf' options)
sos = zp2sos(z,p,k, 'up', 'inf'); 
[n,d] = rat(sos); 
sos_check = n ./ d;  % this should be the same as SOS matrix

% by here, n is the numerator and d is the denominator coefficients
% as an example, write the the coefficients into a C code header file
% for prototyping the implementation

 % write the numerator and denominator matices into a file
[rownum, colnum] = size(n);  % d should be the same
sections = rownum;           % the number of sections is the same as the number of rows
fid = fopen('IIR_coeff.h', 'w');

fprintf(fid, '#ifndef IIR_COEFF_H\n');
fprintf(fid, '#define IIR_COEFF_H\n\n\n');
for i = 1:rownum
   for j = 1:colnum

       if(j <= 3)  % b coefficients
            bn = ['b' num2str(j-1) num2str(i) 'n' ' = ' num2str(n(i,j))];
            bd = ['b' num2str(j-1) num2str(i) 'd' ' = ' num2str(d(i,j))];
            fprintf(fid, 'const int32_t %s;\n', bn);
            fprintf(fid, 'const int32_t %s;\n', bd);

       end
       if(j >= 5)  % a coefficients
            if(j == 5) 
                colstr = '1'; 
            end
            if(j == 6) 
                colstr = '2'; 
            end
            an = ['a' colstr num2str(i) 'n' ' = ' num2str(n(i,j))];
            ad = ['a' colstr num2str(i) 'd' ' = ' num2str(d(i,j))];
            fprintf(fid, 'const int32_t %s;\n', an);
            fprintf(fid, 'const int32_t %s;\n', ad);
       end
   end
end

% write the end of the file
fprintf(fid, '\n\n\n#endif');
fclose(fid);

4
उच्च-क्रम IIR फ़िल्टर इस तरह से होते हैं जिन्हें आमतौर पर दूसरे-क्रम अनुभागों का उपयोग करके लागू किया जाता है ; यदि आप इच्छित दूसरे क्रम के एक से अधिक सेकंड-ऑर्डर चरणों (एक एकल पहले चरण के साथ) को कैस्केडिंग करके इच्छित फ़िल्टर प्राप्त करते हैं। यह आमतौर पर उच्च-क्रम फिल्टर को सीधे लागू करने की तुलना में अधिक मजबूत कार्यान्वयन है।
जेसन आर

3
यदि आप वह नहीं करते हैं जो @JasonR बताता है कि आपके पास बहुत बड़े शब्द आकार होंगे। एक मूल IIR संरचना के साथ कार्यान्वित होने पर इस तरह के फ़िल्टर एकल परिशुद्धता फ़्लोटिंग पॉइंट को विफल कर सकते हैं, आपको एसओएस की आवश्यकता होती है।
क्रिस्टोफर फेल्टन

@ जैसनआर: यह सुझाव देने के लिए धन्यवाद। मैंने ऊपर उत्तर द्वारा अद्यतन किया है।
निकोलस किन्नर

@ChristopherFelton: इसे सुदृढ़ करने में मदद के लिए धन्यवाद।
निकोलस किन्नर

हां अपने नए एसओएस मैट्रिक्स के साथ आप साइट से 3 फिल्टर बना सकते हैं। या आप यहां मेरे कोड का उपयोग कर सकते हैं । यह वेबसाइट की तरह ही काम करेगा। मैं एसओएस मैट्रिक्स को छोड़कर स्क्रिप्ट को खुशी से अपडेट करूंगा।
क्रिस्टोफर फेल्टन

जवाबों:


5

जैसा कि चर्चा की गई है कि वर्गों के योग का उपयोग करना सबसे अच्छा है, जो उच्च क्रम वाले फिल्टर को कैस्केड किए गए 2 ऑर्डर फिल्टर में तोड़ देता है। अद्यतन प्रश्न में SOS मैट्रिक्स है। इस कोड और एक उदाहरण का उपयोग करके यहां पायथन ऑब्जेक्ट का उपयोग व्यक्तिगत अनुभागों को उत्पन्न करने के लिए किया जा सकता है।

मतलूब में

save SOS

अजगर में

import shutil
import numpy
from scipy.io import loadmat
from siir import SIIR

matfile = loadmat('SOS.mat')  
SOS = matfile['SOS']
b = numpy.zeros((3,3))
a = numpy.zeros((3,3))
section = [None for ii in range(3)]
for ii in xrange(3):
    b[ii] = SOS[ii,0:3]
    a[ii] = SOS[ii,3:6]

    section[ii] = SIIR(b=b[ii], a=a[ii], W=(24,0))
    section[ii].Convert()  # Create the Verilog for the section
    shutil.copyfile('siir_hdl.v', 'iir_sos_section%d.v'%(ii))

निर्धारित बिंदु पर अतिरिक्त जानकारी यहां पाई जा सकती है


आप सभी के लिए बहुत बहुत आभारी हूँ, और पायथन कोड के लिए; मुझे आशा है कि आपका उत्तर (और यहां पोस्ट किए गए अन्य उत्तर) कई अन्य लोगों के लिए अच्छे संदर्भ के रूप में काम करेगा। मेरी इच्छा है कि मैं यहां स्वीकृत सभी प्रतिक्रियाओं को चिह्नित कर सकूं।
निकोलस किन्नर

1
यदि आपके पास कोई समस्या है तो मुझे बताएं और यदि यह आपके लिए काम नहीं करता है तो मैं कोड को अपडेट / फिक्स कर दूंगा। मैं इसे (अपेक्षाकृत जल्द ही, दोहे) संशोधित कर सीधे एसओएस मैट्रिक्स को स्वीकार करूंगा।
क्रिस्टोफर फेल्टन

1
मैंने अपने उदाहरण से अपने स्वयं के संस्करण को लागू करने का प्रयास किया। मेरे सिस्टम पर, मुझे "सुन्न आयात शून्य से" का उपयोग करना पड़ा और लोमतट को लोडमैट () में बदलना पड़ा। क्या Matlab द्वारा दिया गया SOS मैट्रिक्स ( mathworks.com/help/toolbox/signal/ref/ss2sos.html ) उम्मीद के मुताबिक ही है? एसओएस मैट्रिक्स का उपयोग करने की कोशिश करते समय मुझे निम्न त्रुटि प्राप्त होती है: "टाइपरोर: अनहैसे टाइप" जब दुभाषिया लाइन पर पहुंचता है "बी [ii] = एसओएस [0: 3, ii]"
निकोलस किनर

1
यह SOS.mat फ़ाइल के प्रारूप पर निर्भर करेगा। अगर आप बस >>> प्रिंट (मैटफाइल) करते हैं तो यह आपको लोडेड .mat फाइल में कीज दिखाएगा। Scipy.io.loadmat हमेशा एक शब्दकोश (BOMK) के रूप में लोड होता है।
क्रिस्टोफर फेल्टन

1
हां, यह सही है, 0 का आउटपुट 1 और इसके बाद का इनपुट है। शब्द चौड़ाई में थोड़ा विचार करने की आवश्यकता है। डिफ़ॉल्ट दो उपयोग है 24 बिट अंश (0 पूर्णांक, 23 अंश, 1 संकेत)। मेरा मानना ​​है कि आप मूल रूप से एक छोटे शब्द चौड़ाई का उपयोग करना चाहते थे।
क्रिस्टोफर फेल्टन

10

'फ्रैक्शनल बिट्स' एक बस में बिट्स की संख्या होती है, जिसे आपने किसी संख्या के आंशिक भाग (जैसे .75 में 3.75) का प्रतिनिधित्व करने के लिए समर्पित किया है।

कहो कि आप एक डिजिटल बस 4 बिट्स चौड़ा है, किस संख्या का 1001प्रतिनिधित्व करता है ? इसका मतलब '9' हो सकता है यदि आप इसे एक धनात्मक पूर्णांक (2 ^ 3 + 2 ^ 0 = 8 + 1 = 9) के रूप में मानते हैं। या इसका अर्थ -7 दो पूरक संकेतन में हो सकता है: (-2 ^ 3 + 2 ^ 0 = -8 + 1 = -7)।

उनमें कुछ अंशों वाली संख्याओं के बारे में क्या है, अर्थात 'वास्तविक' संख्याएँ? वास्तविक संख्याओं को हार्डवेयर में "फिक्स्ड-पॉइंट" या "फ्लोटिंग पॉइंट" के रूप में दर्शाया जा सकता है। ऐसा लगता है कि फिल्टर जनरेटर तय बिंदु का उपयोग करते हैं।

हमारी 4 बिट बस ( 1001) पर वापस। आइए एक द्विआधारी बिंदु का परिचय दें ताकि हम प्राप्त करें 1.001। इसका मतलब यह है कि अब पूर्णांक बनाने के लिए बिंदु के आरएचएस पर बिट्स का उपयोग कर रहे थे, और एलएचएस पर बिट्स को एक अंश बनाने के लिए। एक डिजिटल बस द्वारा निर्धारित संख्या 1.0011.125 ( 1* 2 ^ 0 + 0* 2 ^ -1 + 0* 2 ^ -2 + 1* 2 ^ -3 = 1 + 0.125 = 1.125) है। इस मामले में, बस में 4 बिट्स में से, हम किसी संख्या के भिन्नात्मक भाग का प्रतिनिधित्व करने के लिए उनमें से 3 का उपयोग कर रहे हैं। या, हमारे पास 3 भिन्नात्मक बिट्स हैं।

इसलिए यदि आपके पास ऊपर की तरह वास्तविक संख्याओं की एक सूची है, तो आपको अब यह तय करना होगा कि आप कितने भिन्न बिट्स का प्रतिनिधित्व करना चाहते हैं। और यहां ट्रेड-ऑफ है: आपके द्वारा उपयोग किए जाने वाले अधिक आंशिक बिट्स, आपके द्वारा इच्छित संख्या का प्रतिनिधित्व कर सकते हैं, लेकिन आपका सर्किट जितना बड़ा होगा। और क्या अधिक है, आपके द्वारा उपयोग किए जाने वाले कम आंशिक बिट्स, फ़िल्टर की वास्तविक आवृत्ति प्रतिक्रिया आपके द्वारा शुरू किए गए डिज़ाइन से विचलित हो जाएगी!

और मामले को बदतर बनाने के लिए, आप एक अनंत आवेग प्रतिक्रिया (IIR) फ़िल्टर बनाने के लिए देख रहे हैं। ये वास्तव में अस्थिर हो सकते हैं यदि आपके पास पर्याप्त भिन्नात्मक और पूर्णांक बिट्स नहीं हैं!


इस व्यावहारिक जवाब देने के लिए धन्यवाद। मैं ऊपर छोटे बी गुणांक का उपयोग करके कोड जनरेटर चलाने की कोशिश कर रहा हूं, और मुझे अभी भी कुछ त्रुटियां प्राप्त हैं। क्या आप कुछ ऐसा सुझाव दे सकते हैं जो मैं जनरेटर को ठीक से चलाने के लिए कर सकता हूं? मैंने जो किया है उसे दिखाने के लिए ऊपर दिए गए उत्तर को अपडेट करूंगा।

10

इसलिए मार्टी ने बिट्स प्रश्न का अच्छी तरह से ध्यान रखा है। फ़िल्टर पर ही, मुझे लगता है कि आपको खराब स्केल वाले गुणांक के बारे में मैटलैब से चेतावनी या शिकायत मिलने की संभावना है? जब मैं फिल्टर की साजिश रचता हूं, तो स्किपी से मतलाब नहीं, लेकिन यह बहुत समान है।

प्रतिक्रिया

जो पासबैंड पर 100 डीबी नीचे है! इसलिए, आप यह सुनिश्चित करना चाहते हैं कि आप एक छोटा ऑर्डर फ़िल्टर चाहते हैं, जो आपको वैसे भी लागू करने में मदद करेगा। जब मुझे 6 वाँ ऑर्डर फिल्टर मिलता है तो मुझे खराब गुणांक के बारे में शिकायतें मिलना बंद हो जाती हैं। शायद आदेश को कम करने की कोशिश करें और देखें कि क्या यह अभी भी आपकी आवश्यकताओं को पूरा करता है।


यह सुझाव देने के लिए धन्यवाद! मुझे लगता है कि एक 6 ठे क्रम फिल्टर भी काम करेगा। मतलाब के fvtool का उपयोग करते हुए, मुझे लगता है कि प्रतिक्रिया मेरे आवेदन के लिए अच्छी है। मैंने अब अपनी प्रतिक्रिया ऊपर अपडेट कर दी है। हालाँकि, वेरिलॉग एचडीएल कोड जनरेटर ( स्पाइरिल.नेट / हार्डवेयर / फ़िल्टरHtml ) के साथ अभी भी कुछ गलत हो रहा है । शायद यह दूसरे प्रारूप में [बी, ए] चाहता है। इसके अलावा, SciPy के उपयोग के लिए +1।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.