This example demonstrates how to generate HDL code for a programmable FIR filter. You can program the filter to a desired response by loading the coefficients into internal registers using the host interface.
In this example, we will implement a bank of filters, each having different responses, on a chip. If all of the filters have a direct-form FIR structure, and the same length, then we can use a host interface to load the coefficients for each response to a register file when needed.
This design adds latency of a few cycles before the input samples can be processed with the loaded coefficients. However, it has the advantage that the same filter hardware can be programmed with new coefficients to obtain a different filter response. This saves chip area, as otherwise each filter would be implemented separately on the chip.
You must have an HDL Coder™ license to run this example.
Enter the following commands to open the example model:
modelname = 'dspprogfirhdl'; open_system(modelname);
Consider two FIR filters, one with a lowpass response and the other with a highpass response. The coefficients can be specified with the Model Properties InitFcn Callback function.
The Programmable FIR via Registers block loads the lowpass coefficients from the Host Behavioral Model, and processes the input chirp samples first. Then the block loads the highpass coefficients and processes the same chirp samples again.
Enter the following commands to open the Programmable FIR via Registers block:
systemname = [modelname '/Programmable FIR via Registers']; open_system(systemname);
The coeffs_registers block loads the coefficients into internal registers when the 'write_enable' signal is high. The following shadow registers are updated from the coefficients registers when the 'write_done' signal is high. This enables simultaneous loading and processing of data by the filter entity. In this example, we apply fully parallel architecture implementation to the Discrete FIR Filter block. You can also choose serial architectures from the HDL Block Properties menu.
Notice that the blocks load the second set of coefficients and process the last few input samples simultaneously.
Enter the following command to run the example model:
Enter the following command to open the scope:
Compare the DUT (Design under Test) output with the reference output.
Enter the following command to close the scope:
You can also view the signals in the Logic Analyzer. The Logic Analyzer enables you to view multiple signals in one window. It also makes it easy to spot the transitions in the signals.
The signals of interest - input coefficients, write address, write enable, write done, filter in, filter out, reference out and error have been streamed for visualization.
Launch the Logic Analyzer from the model's toolbar.
The Logic Analyzer display can also be controlled on a per-wave or per-divider basis. To modify an individual wave or divider, select a wave or divider and then click on the "Wave" tab. A useful mode of visualization in the Logic Analyzer is the Analog format.
For further information on the Logic Analyzer System object, refer to the documentation.
Get a unique temporary directory name for the generated files
workingdir = tempname;
To check whether there are any issues with the model for HDL code generation, without generating HDL code, you can run the following command:
Enter the following command to generate HDL code:
### Generating HDL for 'dspprogfirhdl/Programmable FIR via Registers'. ### Starting HDL check. ### Begin VHDL Code Generation for 'dspprogfirhdl'. ### Working on dspprogfirhdl/Programmable FIR via Registers/coeffs_registers as /tmp/BR2016bd_418663_21018/publish_examples1/tp4d3289e4_3caf_4ee3_8b1a_7efcf193ea92/dspprogfirhdl/coeffs_registers.vhd. ### Working on dspprogfirhdl/Programmable FIR via Registers/Discrete FIR Filter as /tmp/BR2016bd_418663_21018/publish_examples1/tp4d3289e4_3caf_4ee3_8b1a_7efcf193ea92/dspprogfirhdl/Discrete_FIR_Filter.vhd. ### Working on dspprogfirhdl/Programmable FIR via Registers as /tmp/BR2016bd_418663_21018/publish_examples1/tp4d3289e4_3caf_4ee3_8b1a_7efcf193ea92/dspprogfirhdl/Programmable_FIR_via_Registers.vhd. ### Generating package file /tmp/BR2016bd_418663_21018/publish_examples1/tp4d3289e4_3caf_4ee3_8b1a_7efcf193ea92/dspprogfirhdl/Programmable_FIR_via_Registers_pkg.vhd. ### Creating HDL Code Generation Check Report file:///tmp/BR2016bd_418663_21018/publish_examples1/tp4d3289e4_3caf_4ee3_8b1a_7efcf193ea92/dspprogfirhdl/Programmable_FIR_via_Registers_report.html ### HDL check for 'dspprogfirhdl' complete with 0 errors, 0 warnings, and 0 messages. ### HDL code generation complete.
Enter the following command to generate the test bench:
### Begin TestBench generation. ### Generating HDL TestBench for 'dspprogfirhdl/Programmable FIR via Registers'. ### Begin simulation of the model 'gm_dspprogfirhdl'... ### Collecting data... ### Generating test bench data file: /tmp/BR2016bd_418663_21018/publish_examples1/tp4d3289e4_3caf_4ee3_8b1a_7efcf193ea92/dspprogfirhdl/coeffs_in.dat. ### Generating test bench data file: /tmp/BR2016bd_418663_21018/publish_examples1/tp4d3289e4_3caf_4ee3_8b1a_7efcf193ea92/dspprogfirhdl/write_address.dat. ### Generating test bench data file: /tmp/BR2016bd_418663_21018/publish_examples1/tp4d3289e4_3caf_4ee3_8b1a_7efcf193ea92/dspprogfirhdl/write_enable.dat. ### Generating test bench data file: /tmp/BR2016bd_418663_21018/publish_examples1/tp4d3289e4_3caf_4ee3_8b1a_7efcf193ea92/dspprogfirhdl/write_done.dat. ### Generating test bench data file: /tmp/BR2016bd_418663_21018/publish_examples1/tp4d3289e4_3caf_4ee3_8b1a_7efcf193ea92/dspprogfirhdl/filter_in.dat. ### Generating test bench data file: /tmp/BR2016bd_418663_21018/publish_examples1/tp4d3289e4_3caf_4ee3_8b1a_7efcf193ea92/dspprogfirhdl/filter_out_expected.dat. ### Working on Programmable_FIR_via_Registers_tb as /tmp/BR2016bd_418663_21018/publish_examples1/tp4d3289e4_3caf_4ee3_8b1a_7efcf193ea92/dspprogfirhdl/Programmable_FIR_via_Registers_tb.vhd. ### Generating package file /tmp/BR2016bd_418663_21018/publish_examples1/tp4d3289e4_3caf_4ee3_8b1a_7efcf193ea92/dspprogfirhdl/Programmable_FIR_via_Registers_tb_pkg.vhd. ### HDL TestBench generation complete.
The following figure shows the ModelSim HDL simulator after running the generated .do file scripts for the test bench. Compare the ModelSim result with the Simulink result as plotted before.
This ends the Generate HDL Code for Programmable FIR Filter example.