3150 views|0 replies

32

Posts

0

Resources
The OP
 

Share post: Just completed FPGA interpolation filter design [Copy link]


1 Project Background (Source Code Download Exchange Tutorial Group: 544453837) 1.1 Multi-sampling Rate Digital Filter
Multi-sampling rate means having multiple sampling rates. The FIR and IIR filters mentioned above have only one sampling frequency, which is a fixed sampling rate. However, in some cases, signals with different sampling frequencies are required.
According to the traditional rate conversion theory, if we want to realize the conversion of sampling rate, we can do this. Suppose there is a useful sinusoidal wave analog signal, and the AD sampling rate is f1. Now I need to use a signal with a sampling frequency of f2. The traditional approach is to perform DA conversion on the signal after f1 sampled, and then sample the converted analog signal at the f2 sampling frequency to obtain a digital signal with a sampling rate of f2. The conversion of sampling frequency is thus completed.
However, this approach is not only troublesome, but also will damage the signal if not handled properly, so this idea has been eliminated. The sampling rate conversion method we use now is the idea of decimation and interpolation.
1.2 Decimation
Let's first explain the meaning of decimation in general: Didn't we say earlier that a useful sinusoidal analog signal is sampled with a sampling signal of sampling frequency f1 to obtain a digital signal? Obviously, this digital signal sequence is obtained at the frequency of f1. Now, if I extract a signal every few points, for example 5, and I extract a signal every 5 points, is it equivalent to sampling the analog signal at a sampling frequency of 1/5 times f1? So, the process of decimation is the process of reducing the sampling rate, but we know that this is sampling in the time domain. Sampling in the time domain is equal to the period extension of the signal in the frequency domain waveform. The period is the sampling frequency. Therefore, in order to avoid spectrum aliasing in the frequency domain, the sampling theorem is also a factor we need to consider.
Let's introduce it in detail
As shown in the figure above, if the above is the spectrum of a useful signal sampled by sampling frequency f1, assuming that the sampling frequency at this time is 8Khz, it can be obtained by counting the grids. There are 8 spaces from 0 to F1, and each space represents 1Khz. Some friends may ask, isn’t this in the digital frequency domain? Isn’t the unit π? Where does hz come from? Yes, this is the digital frequency domain, and the sampling frequency F1 corresponds to 2π. Here, just for the sake of explanation, we use analog frequency to correspond to digital frequency.
The above is a frequency domain diagram of a digital signal with a sampling frequency of 8K. Now I want to perform time domain extraction on this digital signal to reduce the sampling rate of the signal. We know that once we perform time domain extraction on a digital signal, the sampling rate will decrease, and the sampling rate is the waveform period of the digital signal in the frequency domain, so the period will decrease. Therefore, we must have a degree of extraction of the signal and extract the signal under the condition that the sampling theorem is satisfied, otherwise spectrum aliasing will occur. The above figure is a signal sampled at 1/5 of the F1 sampling frequency. It can be seen that spectrum aliasing occurs because 1/5 of F1 is 1600hz, and the frequency band of the signal is 1000hz, which does not satisfy the sampling theorem, resulting in spectrum aliasing. Therefore, in order to avoid this situation, in addition to satisfying the sampling theorem, that is, the sampling multiple cannot be too high, we also need to set the frequency band of the signal below F1/2 to ensure that the signal does not have spectrum aliasing. Therefore, we need to add a low-pass filter before decimation, which is called an anti-aliasing low-pass filter in the book. It is used to limit the frequency band of the signal, and then decimate. In this case, let's calculate
The cutoff frequency of the low-pass filter is 1/2 times the sampling rate after decimation, that is, fc = 1/2 * (F1/M), M is the decimation multiple. The number domain frequency corresponding to 1/2*F1 is π, so we can conclude that
The cutoff frequency of the anti-aliasing low-pass filter is π/M
1.3 Interpolation
The process of decimation is the process of reducing the sampling rate, so the process of interpolation is of course the process of increasing the sampling rate. The general idea can be understood as follows: we interpolate between every two points of the digital signal obtained by f1 sampling, and the inserted value is 0. After interpolation, the number of sampling points of the signal per unit time increases, which is of course the increase of the sampling rate. After the sampling rate is increased, we know that the period of the signal spectrum will increase
One thing to note is that before and after interpolation, we only inserted D-1 zero values in the middle of the time domain signal, which only changed the sampling rate and did not change the signal information. Therefore, in the frequency domain, the shape of the signal spectrum will not change, only the period will change. As shown in the figure above, F1 is the period of the signal before interpolation. After interpolation, the shape of the signal spectrum remains unchanged, and the period becomes F1*D, where D is the interpolation multiple. If we directly use the sampling rate of F1*D to sample the signal, we will find that the obtained spectrum will not have the two waveforms in the middle. Therefore, these two waveforms are redundant, which is called mirror spectrum in the book. Since it is redundant, we can filter it out with a low-pass filter. Such a low-pass filter is called a mirror low-pass filter. So let's calculate the cutoff frequency of the mirror low-pass filter
According to the above figure, we can find the cutoff frequency of the mirror low-pass filter. We can see that fc = 1/2 *F1. Here we assume that the sampling frequency after interpolation is F2=F1*D, then fc =1/2*(F2/D), and 1/2*F2 corresponds to π. Note that here 1/2*F2 corresponds to π, not 1/2*F1, because this is the spectrum after the sampling rate is increased after interpolation, so we get: The cutoff frequency of the mirror low-pass filter is: π/D Tohoma]1 Design Goal
This case will use a dual-channel oscilloscope with a sampling rate greater than 100M. Connect the two channels of the oscilloscope to DA channel 1 and DA channel 2 of the FPGA respectively to observe the output of the two DA channels. The connection diagram is shown in the following figure:
In this case, a sinusoidal signal is generated inside the FPGA. One path of the sinusoidal signal is output to DA channel A, and the other path is output to DA channel B after passing through an interpolation filter.
The sine signal generating circuit generates a frequency of 62.5KHz sine signal, which is composed of 8 points.
The interpolation filter is a 4-fold interpolation, which means that the input is a sine wave of 8 points, and the output will be a sine wave of 32 points.
Simulation effect, the upper waveform is before interpolation, and the lower one is after interpolation. It can be clearly seen that the lower waveform is smoother.
Below is the display effect of the oscilloscope
3 Design and Implementation3.1 Top-level signal
Create a new directory: D:\mdy_book\cic_prj. In this directory, create a file named cic_prj.v, open it with GVIM, and start writing code.
The function we want to achieve, in summary, is that FPGA generates and controls AD9709, so that channel A outputs an unfiltered sine signal and channel B outputs a filtered sine signal. In order to control the working mode of AD9709, it is necessary to control the MODE and SLEEP pins of AD9709; in order to control channel A, it is necessary to control the CLK1, WRT1, and DB7~0P1 pins of AD9729; in order to control channel B, it is necessary to control the CLK2, WRT2, and DB7~0P2 pins of AD9729. According to the requirements of the design goals, the entire project requires the following signals:
1. Use clk to connect to the crystal oscillator to indicate the input of the 50M clock.
2. Use rst_n to connect to the button to indicate the reset signal. 3. Use the dac_mode signal to connect to the MODE pin of AD9709 to control its working mode. 4. Use the dac_sleep signal to connect to the SLEEP pin of AD9709 to control its sleep mode. 5. Use the dac_clka signal to connect to the CLK1 pin of AD9709 to control the clock of channel A. 6. Use the dac_wra signal to connect to the WRT1 pin of AD9709 to control the write enable of channel A.
7. Use the 8-bit signal dac_da to connect to the DB7~0P1 pin of AD9709 to control the write data of channel A.
8. Use the dac_clkb signal to connect to the CLK2 pin of AD9709 to control the clock of channel B.
9.Use dac_wrb to connect to the WRT2 pin of AD9709 to control the enable of channel B. 10. Use the 8-bit signal dac_db to connect to the DB7~0P2 pin of AD9709 to control the write data of channel B.
In summary, our project requires 10 signals, clock clk, reset rst_n, dac_mode, dac_sleep, dac_clka, dac_wra, dac_da, dac_clkb, dac_wrb and dac_db signals, of which dac_da and dac_db are 8-bit signals, and the others are 1-bit signals. The following table shows the connection relationship of the hardware circuit diagram.
Define the name of the module as cic_prj, the code is as follows:
Among them, clk and rst_n are 1-bit input signals, dac_da and dac_db are 8-bit output signals, dac_mode, dac_clka, dac_wra, dac_sleep, dac_clkb, dac_wrb are 1-bit output signals.
3.2 Sine signal design
Assume that the generated sinusoidal signal is named sin_data. sin_data has a total of 8 values, which are sampled from a sinusoidal signal at intervals of (2*pi/8), and can be listed in the following table.
It is natural to define a 7-bit selection signal addr. As long as we control addr, we can easily get sin_data. Therefore, we can write the following code. :
addr is used to control the address of the selected data. By controlling the increase in the value of addr, the required sine wave can be generated.
This case requires the generation of a 62.5KHz sine signal. The period of the sine signal is 16000ns. The working clock of this project is 20ns, which means that 16000/20 = 800 clocks output a sine signal, which means that 800 clocks output the 8 values in the table above, that is, addr is output plus 1 every 100 clocks.
Output a value every 100 clocks, which means we need a counter cnt0, which is used to count these 100. The counter's increment condition is "1", and the end condition is "count to 100". Therefore, the code for cnt0 can be written.
After every 100 clocks, addr is incremented by 1. This means that addr is also a counter, and the increment condition of the counter is "counting to 100 clocks", that is, end_cnt0, and the end condition is "counting to 8".
3.3 CIC filter design3.3.1 Create a new FPGA project
1.) Open quartus, click File and select New ProjectWizard.... in the File menu. 6c]
(3) Set the project directory, project name, and top-level module name
The project directory is set to: D:\mdy_book\cic_prj
Project name: cic_prj
Top-level module name: cic_prj
After filling in, click next to enter the next interface.
(3.) In the file adding interface, do not select any file. Click Next to enter the next interface. In the project type interface, select Empty project for Project Type and select a blank project. Click Next to enter the next interface.
(3.) In the file adding interface, do not select any file. Click Next to enter the next interface. :
(4.) Device selection interface. Select Cyclone IV E in the Device family field and select EP4CE6F23C8 in the Available device field. Click Finish when you are done.
3.3.2FPGA generates CIC IP core
After creating the project, in the IP catalog interface in quartus, select DSP, select Filter in the next catalog, and then select CIC.
Click to enter this interface and select the following path for the newly generated FIR filter IP core: D:\mdy_book\cic_prj, and fill in entityname: my_cic. Click OK to enter the FIR filter setting interface.
Set as follows:
Filter Type: Select Interpolator, which means it is an interpolation filter.
Rate change factor: Fill in 4, which means 4x interpolation.
Output Rounding Method: Select Truncation, which means the output result will be truncated.
Output data width: Select 8. It means the output result will be truncated to 8 bits.
Leave other options as default. Click Generate Hdl in the lower right corner of the window and the following window will pop up.
Note that the file selected is the Verilog file, and you don't need to check the others. Click Generate, and the Verilog file of y_cic will be generated. :
Click Finish to close the CIC filter generation window.
If the above prompt appears, it means that you need to manually add the IP core just generated to this project.
Select Add/Remove File to Project in the Project menu, and a file window will pop up.
Click on the upper right corner, and in the pop-up window, double-click and select the my_cic.qip file in the D:\mdy_book\cic_prj\my_cic\synthesis directory (be careful not to mistake the file type). Then remember to click Add to officially add it to the project.
Click OK to close this window.
After the IP core is generated, this dialog box pops up and click yes to add the IP core to the project.
3.3.3 Instantiate CIC IP core
Use GVIM to open the D:\mdy_book\cic_prj\my_cic\synthesis\my_cic.v file, which is the generated CIC IP core file
It should be noted that the input data and output data of the filter are both signed numbers (in the form of complement, -128~127). As we know, the sine signal sin_data is an unsigned number (0~255). So we need to convert sin_data into a signed number and then send it to FIR for filtering. Assume that the converted signal is cic_din, which has an 8-bit bit width. The method of converting an unsigned number into a signed number is very simple: cic_din = sin_data - 128. Readers who are interested can verify it. After generating the CIC IP core, we need to instantiate it before we can use this IP core. The instantiation name is u_my_cic, and the output data signal of cic is named cic_dout.
We need to control the output of the CIC IP core so that each data can be output at equal intervals. Since the input of the CIC filter is one data every 100 clocks and the CIC is 4 times the rate, the output is one data every 25 clocks. So we connect a valid signal to the out_ready interface every 25 clocks. At this time, a counter cnt1 is needed to time 25 clocks. The condition for the counter to add 1 is "1" and the end condition is "counting to 25".
With these signals, you can instantiate the CIC IP core.
3.4 DA interface signal design
Next is to design the signal dac_da. dac_da directly outputs a sinusoidal signal, but since the output voltage of DA is in an inversely proportional linear relationship with dac_da, dac_da is always obtained by (255-sin_data). Then you can write the code for dac_da.
Next is to design the signal dac_sleep. AD is always working, so dac_sleep should be always 0.
dac_clka In order to meet the time requirement of tS, dac_clka can be set to ~clk.
dac_wra can be the same as dac_clka. , 微软雅黑, Tohoma]
dac_db directly outputs the filtered signal cic_dout. But it should be noted that cic_dout is a signed number (range is -128~127), so it needs to be converted to an unsigned number (0~255). Assuming that the converted signal is cic_dout2, then cic_dout2 = cic_dout + 128. In addition, since the output voltage of channel 2 of DA is in an inversely proportional linear relationship with dac_db, dac_db is obtained by (255-cic_dout2). Then the code of dac_db can be written.
In order to meet the time requirement of tS, dac_clkb can be set to ~clk.
dac_wrb can be the same as dac_clkb.
3.5 Signal Definition
At this point, the main body of the module has been completed. The next step is to complete the module.
cnt0 is a signal generated by always, so its type is reg. The maximum value of cnt0 is 99, which needs to be represented by 7 wires, that is, the bit width is 7 bits. add_cnt0 and end_cnt0 are both designed by assign, so their type is wire. And their values are 0 or 1, which can be represented by 1 wire. So the code is as follows:
cnt1 is a signal generated by always, so its type is reg. The maximum value of cnt1 is 24, which needs to be represented by 5 wires, that is, the bit width is 5 bits. add_cnt1 and end_cnt1 are both designed by assign, so their type is wire. And their values are 0 or 1, which can be represented by 1 wire. So the code is as follows:
addr is designed using assign, so the type is wire. Its maximum value is 7, with a total of 3 wires and a bit width of 3. add_addr and end_addr are both designed using assign, so the type is wire. And its value is 0 or 1, which can be represented by 1 wire. So the code is as follows
sin_data is designed with always, so the type is reg. Its maximum value is 255, which requires 8 lines to represent it, and the bit width is 8, so the code is as follows
cic_din is designed with assign, so the type is wire. Its bit width is 8, so the code is as follows
cic_dout2 is designed with assign, not always, so the type is wire. Its bit width is 8, so the code is as follows
dac_da is designed with always, so the type is reg. Its bit width is 8; dac_sleep is designed with assign, so the type is wire, and the bit width is 1; dac_wra is designed with assign, so the type is wire, and the bit width is 1; dac_clka is designed with assign, so the type is wire, and the bit width is 1; dac_mode is designed with assign, so the type is wire, and the bit width is 1. So the code is as follows
dac_db is designed with always, so the type is reg. Its bit width is 8; dac_wrb is designed with assign, so the type is wire, and the bit width is 1; dac_clkb is designed with assign, so the type is wire, and the bit width is 1. So the code is as follows.
Write endmodule at the end of the code
So far, the design of the entire code has been completed. The next step is to create a new project and put it on the board to check the phenomenon.
4 Synthesis and boarding 4.1 Add files to the project
1.) Creating a new project has been introduced above. Now open quartus and select Add/Remove File to Project in the Project menu to pop up a file window.
Click on the upper right corner, in the pop-up window, double-click and select the fir_prj.v file in the D:\mdy_book\fir_prj directory. Then remember to click Add to officially add it to the project.
Click OK to close this window.
4.2 Comprehensive
In the menu bar, select Processing, and then select Start Compilation to start compiling and synthesizing the entire project.
The appearance of the above interface indicates that the compilation and synthesis are successful.
4.3 Configuration Pins
In the menu bar, select Assignments, then select Pin Planner, and a window for configuring pins will pop up.
[font=punctuation, Microsoft YaHei,10.sina.com.cn/mw690/007n4XDCzy7p2EdQxU549[/img][/url]
Configure the pins of each signal as above, and the final effect is as shown in the figure below.
After configuring the pins of each signal as above, the final effect is as shown in the figure below.
Close Pin Planner, the software automatically saves the pin configuration information.
4.4 Comprehensive again
In the menu bar, select Processing, then select Start Compilation to start compiling and synthesizing the entire project.
The appearance of the above interface indicates that the compilation and synthesis are successful.
4.5 Connect the development board
The connection diagram is shown in the figure above. Connect the power supply to the development board; connect one end of the USBBLASTER to the JTAG socket and the other end to the USB port of the PC; connect the P7 port and P11 on the development board to the two channels of the oscilloscope. Finally, turn on the power supply.
4.6 Board
In the Task window of quartus, right-click Program Device and select Open to enter the burning interface.
In the above interface, the file output/fir_prj.sof will be selected by default. If it is not generated, please see XXXX.
Next to Setup, it will say: USB-Blaster. If not, please see XXXX.
Click statr, and if the progress bar shows 100%, it means success. Now you can see the FPGA output effect.
This content was created by EEWORLD forum user guyu_1. If you need to reprint or use it for commercial purposes, you must obtain the author's consent and indicate the sourcehtml#blogid=&url=http://album.sina.com.cn/pic/007n4XDCzy7p2Eu9F7L1d][/url]
Next to Setup, it will say: USB-Blaster. If not, please see XXXX.
Click statr, and if the progress bar shows 100%, it means success. Now you can see the FPGA output effect.
This content was created by EEWORLD forum user guyu_1. If you need to reprint or use it for commercial purposes, you must obtain the author's consent and indicate the sourcehtml#blogid=&url=http://album.sina.com.cn/pic/007n4XDCzy7p2Eu9F7L1d][/url]
Next to Setup, it will say: USB-Blaster. If not, please see XXXX.
Click statr, and if the progress bar shows 100%, it means success. Now you can see the FPGA output effect.
This content was created by EEWORLD forum user guyu_1. If you need to reprint or use it for commercial purposes, you must obtain the author's consent and indicate the source

This post is from FPGA/CPLD
Personal signature我与fpga的那些事儿http://blog.sina.com.cn/u/5707446562
 

Guess Your Favourite
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list