मैंने अभी तक IIR फ़िल्टर के साथ काम नहीं किया है, लेकिन अगर आपको केवल दिए गए समीकरण की गणना करने की आवश्यकता है
y[n] = y[n-1]*b1 + x[n]
एक बार सीपीयू चक्र के बाद, आप पाइपलाइनिंग का उपयोग कर सकते हैं।
एक चक्र में आप गुणा करते हैं और एक चक्र में आपको प्रत्येक इनपुट नमूने के लिए योग करने की आवश्यकता होती है। इसका मतलब है कि आपका FPGA दिए गए नमूना दर पर नजर रखने पर एक चक्र में गुणा करने में सक्षम होना चाहिए! फिर आपको केवल वर्तमान नमूने का गुणा करने की आवश्यकता होगी और अंतिम नमूने के गुणा का परिणाम समानांतर होगा। यह 2 चक्रों के निरंतर प्रसंस्करण अंतराल का कारण होगा।
ठीक है, चलो सूत्र पर एक नज़र डालें और एक पाइपलाइन डिज़ाइन करें:
y[n] = y[n-1]*b1 + x[n]
आपका पाइपलाइन कोड इस तरह दिख सकता है:
output <= last_output_times_b1 + last_input
last_output_times_b1 <= output * b1;
last_input <= input
ध्यान दें कि सभी तीन आदेशों को समानांतर में निष्पादित करने की आवश्यकता है और दूसरी पंक्ति में "आउटपुट" इसलिए अंतिम घड़ी चक्र से आउटपुट का उपयोग करता है!
मैंने वेरिलॉग के साथ ज्यादा काम नहीं किया, इसलिए यह कोड का सिंटैक्स सबसे अधिक गलत है (उदाहरण के लिए इनपुट / आउटपुट सिग्नल की थोड़ी-सी चौड़ाई गायब है; गुणन के लिए निष्पादन सिंटैक्स)। हालाँकि आपको यह विचार करना चाहिए:
module IIRFilter( clk, reset, x, b, y );
input clk, reset, x, b;
output y;
reg y, t, t2;
wire clk, reset, x, b;
always @ (posedge clk or posedge reset)
if (reset) begin
y <= 0;
t <= 0;
t2 <= 0;
end else begin
y <= t + t2;
t <= mult(y, b);
t2 <= x
end
endmodule
पुनश्च: हो सकता है कि कुछ अनुभवी वेरिलोग प्रोग्रामर इस कोड को संपादित कर सकते हैं और बाद में इस टिप्पणी और कोड के ऊपर की टिप्पणी को हटा सकते हैं। धन्यवाद!
PPS: यदि आपका कारक "b1" एक स्थिर स्थिरांक है, तो आप एक विशेष गुणक को लागू करके डिजाइन को अनुकूलित करने में सक्षम हो सकते हैं जो केवल एक स्केलर इनपुट लेता है और केवल "बार b1" की गणना करता है।
इसका उत्तर: "दुर्भाग्य से, यह वास्तव में y [n] = y [n-2] * b1 + [[n] के बराबर है। यह अतिरिक्त पाइपलाइन चरण के कारण है।" उत्तर के पुराने संस्करण के लिए टिप्पणी के रूप में
हां, यह वास्तव में निम्नलिखित पुराने (INCORRECT !!!) संस्करण के लिए सही था:
always @ (posedge clk or posedge reset)
if (reset) begin
t <= 0;
end else begin
y <= t + x;
t <= mult(y, b);
end
मुझे उम्मीद है कि इस बग को अब इनपुट मानों में देरी करके ठीक किया जाएगा, वह भी एक दूसरे रजिस्टर में:
always @ (posedge clk or posedge reset)
if (reset) begin
y <= 0;
t <= 0;
t2 <= 0;
end else begin
y <= t + t2;
t <= mult(y, b);
t2 <= x
end
यह सुनिश्चित करने के लिए कि यह इस बार सही ढंग से काम करता है आइए देखें कि पहले कुछ चक्रों में क्या होता है। ध्यान दें कि पहले 2 चक्र अधिक या कम (परिभाषित) कचरा उत्पन्न करते हैं, क्योंकि पिछले उत्पादन मूल्य नहीं हैं (जैसे y [-1] == ??) उपलब्ध हैं। रजिस्टर y को 0 से आरंभ किया गया है, जो मान के बराबर है [-1] == 0।
पहला चक्र (n = 0):
BEFORE: INPUT (x=x[0], b); REGISTERS (t=0, t2=0, y=0)
y <= t + t2; == 0
t <= mult(y, b); == y[-1] * b = 0
t2 <= x == x[0]
AFTERWARDS: REGISTERS (t=0, t2=x[0], y=0), OUTPUT: y[0]=0
दूसरा चक्र (n = 1):
BEFORE: INPUT (x=x[1], b); REGISTERS (t=0, t2=x[0], y=y[0])
y <= t + t2; == 0 + x[0]
t <= mult(y, b); == y[0] * b
t2 <= x == x[1]
AFTERWARDS: REGISTERS (t=y[0]*b, t2=x[1], y=x[0]), OUTPUT: y[1]=x[0]
तीसरा चक्र (n = 2):
BEFORE: INPUT (x=x[2], b); REGISTERS (t=y[0]*b, t2=x[1], y=y[1])
y <= t + t2; == y[0]*b + x[1]
t <= mult(y, b); == y[1] * b
t2 <= x == x[2]
AFTERWARDS: REGISTERS (t=y[1]*b, t2=x[2], y=y[0]*b+x[1]), OUTPUT: y[2]=y[0]*b+x[1]
चौथा चक्र (n = 3):
BEFORE: INPUT (x=x[3], b); REGISTERS (t=y[1]*b, t2=x[2], y=y[2])
y <= t + t2; == y[1]*b + x[2]
t <= mult(y, b); == y[2] * b
t2 <= x == x[3]
AFTERWARDS: REGISTERS (t=y[2]*b, t2=x[3], y=y[1]*b+x[2]), OUTPUT: y[3]=y[1]*b+x[2]
हम देख सकते हैं, कि शुरुआत n = 2 से होती है, हमें निम्न आउटपुट मिलते हैं:
y[2]=y[0]*b+x[1]
y[3]=y[1]*b+x[2]
जो के बराबर है
y[n]=y[n-2]*b + x[n-1]
y[n]=y[n-1-l]*b1 + x[n-l], where l = 1
y[n+l]=y[n-1]*b1 + x[n], where l = 1
जैसा कि ऊपर उल्लेख किया गया है, हम l = 1 चक्रों के अतिरिक्त अंतराल का परिचय देते हैं। इसका मतलब है कि आपके आउटपुट y [n] में lag l = 1 की देरी है। इसका मतलब है कि आउटपुट डेटा बराबर है लेकिन एक "इंडेक्स" द्वारा देरी हो रही है। अधिक स्पष्ट होने के लिए: आउटपुट डेटा में देरी 2 चक्र हो सकती है, क्योंकि एक (सामान्य) घड़ी चक्र की आवश्यकता होती है और मध्यवर्ती चरण के लिए 1 अतिरिक्त (अंतराल l = 1) घड़ी चक्र जोड़ा जाता है।
डेटा को कैसे प्रवाहित किया जाता है, इसका चित्रण करने के लिए यहां एक रेखाचित्र दिया गया है:
पुनश्च: मेरे कोड पर एक करीबी नज़र रखने के लिए धन्यवाद। तो मैंने भी कुछ सीखा! ;-) मुझे बताएं कि क्या यह संस्करण सही है या यदि आप कोई और समस्या देखते हैं।