SlideShare une entreprise Scribd logo
1  sur  27
Télécharger pour lire hors ligne
FIR Filters with FPGA
Page | 1
FIR Filters with FPGAs
ECE 5211
irvin rynning
10 May 2016
FIR Filters with FPGA
Page | 2
Contents:
Front page 1
Contents 2
Part 1
Introduction and Motivation 3
Goals 3
Outside Sources 3
Part 2
Project Description 3
Interface 4
System Diagram 5
Design Flow 5
FIR Filter Design 6
Implementation 8
Part 3
Hardware Design 8
Block Diagram 8
Peripherals 10
Problems 10
Part 4
Discussion and results 11
Conclusion 12
References 13
Summary 14
Code 15
Main Wrapper 16
Digital to Analog 20
Second Wrapper 24
FIR Filters with FPGA
Page | 3
This project was motivated by the desire to use a Field Programmable Gate Array (FPGA) to
accomplish a task in which its performance would rival that of an embedded system or
microprocessor. Previously I had experience in using the Texas Instruments TMDSLCDK6748i
,
which provided for sixteen bit, floating point arithmetic with sample rate from 8 kHz to 96 kHz, and
implemented using the Integrated Development Environment (IDE) called Code Composer in the
both Cee programming language and an Assembly language.
On this platform were developed real-time applications such as sweep oscillators, Finite Impulse
Response (FIR) and Infinite Impulse response (IIR) filters, as well as analog equivalents in dynamics
processing (compressors, gates, expanders), and time domain effects such as a “flanger”, chorus, and
digital delay used in musical performance and production. The FIR caught my attention as it
offered incredibly steep cutoffs coupled with minimal phase delay and distortion, processing which
is normally done after the fact — i.e., not in real time — due to the high latency (or time delay) of
the process. For example
Goal
The goal of this project then is three-fold:
1) Development the FPGA to pass audio frequencies from input to output
2) Incorporate a FIR of the several types
a) High pass
b) Low pass
c) Band pass
3) Add more FIRs of increasing depth (stages) to observe real-time performance
This is done on a qualitative basis, and will not measure time delays and real time parameters, nor
use various sample rates to find limitations on performance. Indeed I did not expect to achieve the
results I did.
Outside Sources
Other sources for Verilog programming and fpga implementation are as follows:
Embedded Design Using Programmable Gate Arrays, Dennis Silageii
The Verilog Hardware Description Language, 5th
Edition, Thomas & Moorby.iii
Advanced Digital Design, M Cilletti.iv
Spartan-3E FPGA Starter Kit Board User Guide, Xilinx Incv
.
Core Generator Guide, Xilinx Inc.vi
This project evolved from the Homework Seven of the course in Rapid Prototyping with FPGA, ECE-
5211, taught by Dr D. Perera in the Spring of 2016. In this assignment the embedded preamplifier
FIR Filters with FPGA
Page | 4
and analog to digital converter was implemented, and the conversion result displayed on the light
emitting diodes (LEDs), also on the FPGA.
From this I added the digital to analog conversion, setting up timing parameters, and creating an
analog signal on the connecting header called J5 on the circuit board which echoed the input.
Interface
Necessary were two interface designs:
The first was adjusting the input signal to be referenced to ½ the power voltage of +3.3 volts,
shown in figure 1. The connections were made to the 6-pin ADC Header (J7), using the input A, as
well as the GND and VCC pins.
Figure 1 Input circuit
The second was the output from 6-pin DAC Header (J5), using output A and the GND pins, and
shown in figure 2. The Spartan 3E board does not have any low pass filtering for digital to analog
conversion, and thus aliasing is expected. Further work implementing a typical Butterworth analog
filter using a dual operational amplifier (op amp) would be essential.
FIR Filters with FPGA
Page | 5
Figure 2 Output circuit
System Diagram
System Diagram
FIRsSignalFlowClocks
Input Interface
Preamp/ADC
SPI Clock
DAC
SPI Clock
Multiplexer
FIRs in
To DAC Out
FIRS
Digital Clock
Manager
Translation to FIRS
50 MHz
CLK FX
×4 ÷5 > 40MHZ
CLX DIV
12½MHz
Everywhere
40MHz/100 = 40kHz
SPI Clock
Output Interface
Slide Switches
Gain
Select FIR
Figure 3 Diagram showing major components
Design Flow
After completing homework seven, and developing a free running analog to digital converter (ADC)
and using an SPI clock of 12.5 MHz — the sample rate Fs was not implemented, other than the
ADCONV signal which was 34 × SPI clock, or — 2.72µs, about 367kHz — I then attacked the
digital to analog convertor (DAC). This first took a translation of the 14 bit signed integer data to
the 12 bit unsigned required by the DAC. This algorithm is as follows, given signals ADC_data and
DAC_data.
wire [13:0] ADC_data;
wire [11:0] DAC_data;
wire [13:0] temp;
always @ ( * ) begin
temp[13] = ~(ADC_data[13]) ;
FIR Filters with FPGA
Page | 6
temp[12:0] = ADC_data[12:0] ;
DAC_data = ~( temp[13:2] ;
end
Once good throughput of the incoming analog signal — which was always in the extended audio
frequency range, 10 Hz to 50 kHz — was obtained I then went into FIR filter design.
Fir Filter Design
FIR filters are essentially multiply and add algorithms, with a given set of constants and a buffer of
previous samples. A brief summary of this is given with figure 4. Successive input samples are
loaded into a buffer whose length is the number of stages, each element of the buffer is multiplied
by a constant, and the results are summed to create the output sample. The sample buffer is shifted
with the next being inserted, and the process repeats.
Figure 4 FIR block diagram from Cilletti
FIR Filters with FPGA
Page | 7
I investigated the Xilinx CORE development tools, such as floating point conversions and
operations, and block core memories, and then found that there exists a FIR CORE tool,vii
called IP
LogiCORE FIR Compiler, as well as several videos, one of which is referenced hereviii
.
Figure 5 Page 1 of the CORE FIR Compiler
I will not go into detail of the use of this tool other than to mention caveats and issues I had. The
first is the use of a coefficients file— highly recommended, using the MatLab fdatool to create a set
of 16 bit signed integers, as well as giving a graphical display of response. It is noted that the Freq.
Response in above (figure 4) mirrors the one that MatLab creates (figure 5).
FIR Filters with FPGA
Page | 8
Figure 6 MatLab Created Response
Additionally there is a setting for input bit width (16) and fractional depth (always 15). When the
latter is set to 0 or 1, there is no output. The control lines for the filters were not implemented, as
this is free running.
Implementation
After getting the throughput working and adding one filter, I then proceeded to add additional ones,
with the use of the slide switches to control the output. I then implemented the network analyzer
(otherwise called a spectrum analyzer) which generated an input of 10 Hz to a maximum of one half
the sample rate. The sample rate was chosen to be arithmetically simple, 1000th
of a 40 MHz clock.
This Fs = 40 kHz has a period of 25 ms, which the ADC, starting on the positive edge of Fs, taking
34× SPI clock < 12.5 ms, as well as the output y[n] sample being determined in time for the DAC to
take place on the negative edge of Fs. No glitches were observed in FIRs as great as some 110
stages.
A block diagram generated using Microsoft’s Visio program is as follows. This shows four FIR
filters being implements, their outputs being selected by the slide switches called SW on the Spartan
3E board. It shows the elements of the code and the hardware, and the interconnections. There is a
discharge path 100kΩ resistor from the input coupling capacitor to ground not shown.
Also not shown are all the clocks, as well as the data path width (number of bits).
the input is marked with a square wave symbol, and the output with a sine wave. This is actually
indicative of the performance of the filter, e.g., when a 1 kHz square is input and the “2 kHz low
pass” filter selected, the output is a sine, for the third harmonic, 3 kHz, is down 40dB.
FIR Filters with FPGA
Page | 9
Figure 7 System Block Diagram
FIR Filters with FPGA
Page | 10
External devices found in the project include a DC shift mixer for the ADC input, implemented
using a resistor divider to create a 50% VCC level, which is added to an AC coupled source from an
oscillator or other signal generating device. The other is a DC blocking capacitor and a minimal
response passive low pass filter on the DAC output. AS the testing was not done with a focus on the
upper octave signals (10 kHz–20 kHz), this was not an issue. A better implementation would include
active devices (op amps) on input to provide isolation and DC level shift, and on the output to
provide a steeper low pass response. It is to be noted that actually listening to a typical tone through
loudspeakers was rather harsh, owing to the aliasing.
Development problems have already been mentioned, but I will reiterate them (and others) here.
Input DC Level Shift:
As discovered in homework seven, the input is clipped if it goes below 0 V with reference to the
GND from the board. Thus a mixer is required, which raises the DC level to 50% of Vcc, 1•65 V
while maintaining impedance and DC isolation.
Signed versus Unsigned
A useful, fast and simple algorithm was needed to translate the ADC data. Without translation, the
output jumped from 0x0000 to 0x3fff when viewing a sine wave, creating an “upside down”
chopped effect.
Data Length Conversion
Significant noise is introduced when altering data lengths from 14 bits to 16, and again from 30 plus
bits from the filters, to the 12 bits needed for DAC. This is noted in the analyzer waveforms.
Output DC level Shift
A simple blocking capacitor, with suitable discharge resistors, was implemented.
Output Low Pass
Only a simple 6dB roll off passive filter was used. This was insufficient to offer a listening, or aural,
quality. Necessary is an active filter, using op amps, which necessitates additional power source(s),
which should measure at least 9V to ensure op amp performance.
FIR Filters with FPGA
Page | 11
Three of the FIR cores implemented worked well.
A simple low pass at 100 Hz is shown with theoretical and actual measurement.
Figure 8 100 Hz low pass filter, from MatLab. Figure 9 100 Hz Low pass, measured
Figure 10 Bandpass 2 - 4 kHz from MatLab Figure 11 2-4 kHz bandpass measured
FIR Filters with FPGA
Page | 12
Figure 12 2 kHz low passd, from MatLab Figure 13 2 kHz low pass, measured
The use of the Xilinx Core design tool is ripe with confusion. Two filters worked perfectly, a third
had a high noise figure, and two not at all. The lack of a good low pass filter aggravated pictorial
results. I think that tighter control of the filter — as opposed to its free running — might abet the
noise glitches observed. Using the alternative, hard-coded form of the filter as opposed to the Core
generator might give better results, but it would need some manner of automation for higher orders,
say, greater than 100.
Future work would be on several fronts, getting better accuracy and less noise, and implementing
parallel outputs for the several filters, as well as using a stereo (dual channel) source. Additionally
using higher sample rates should be tried, as well as measuring the time delay to create the next
output sample.
FIR Filters with FPGA
Page | 13
i TMS320C6748 Fixed/Floating Point DSP, Texas Instruments, http://www.ti.com/lit/ds/symlink/tms320c6748.pdf,
2014.
ii Embedded design Using Programmable Gate Arrays, Dennis Silage, Temple University, Bookstand Publishing, Gilroy Cal,
2008.
iii The Verilog Hardware Description Language, 5th Edition, D Thomas, P Moorby, Springer, New York, 2002.
iv Advanced Digital design, M Cilletti, Person Publishing, Upper Saddle River, NJ, 2003.
v Spartan-3E FPGA Starter Kit Board User Guide, Xilinx Inc, www.xilinx.com, 2008.
vi Core Generator Guide, Xilinx Inc., www.xilinx.com, 2000.
vii IP LogiCORE FIR Compiler v5.0, Xilinx,
http://www.xilinx.com/support/documentation/ip_documentation/fir_compiler_ds534.pdf, 2011.
viiiviii Xilinx ISE FIR Core Complier, https://youtu.be/MUoJtv_M48M, “eazye8523”, 2015.
FIR Filters with FPGA
Page | 14
vProj_fir_25Passes Project Status (05/10/2016 - 17:23:35)
Project File: proj40k.xise Parser Errors: No Errors
Module Name: vProj_fir_25_6 Implementation State:
Programming File
Generated
Target Device: xc3s500e-4fg320
 Errors:
No Errors
Product
Version:
ISE 14.5
 Warnings:
86 Warnings (86 new)
Design Goal: Balanced
 Routing Results: All Signals Completely
Routed
Design
Strategy:
Xilinx Default
(unlocked)
 Timing Constraints:
All Constraints Met
Environment: System Settings
 Final Timing Score:
0 (Timing Report)
Device Utilization Summary [-]
Logic Utilization Used Available Utilization Note(s)
Total Number Slice Registers 1,423 9,312 15%
Number used as Flip Flops 1,409
Number used as Latches 14
Number of 4 input LUTs 1,206 9,312 12%
Number of occupied Slices 1,072 4,656 23%
Number of Slices containing only related
logic
1,072 1,072 100%
Number of Slices containing unrelated logic 0 1,072 0%
Total Number of 4 input LUTs 1,398 9,312 15%
Number used as logic 901
Number used as a route-thru 192
Number used for Dual Port RAMs 24
Number used as Shift registers 281
Number of bonded IOBs 30 232 12%
Number of RAMB16s 17 20 85%
FIR Filters with FPGA
Page | 15
Number of BUFGMUXs 5 24 20%
Number of DCMs 1 4 25%
Number of MULT18X18SIOs 6 20 30%
Average Fanout of Non-Clock Nets 2.22
Performance Summary [-]
Final Timing
Score:
0 (Setup: 0, Hold: 0, Component Switching
Limit: 0)
Pinout
Data:
Pinout Report
Routing Results: All Signals Completely Routed
Clock
Data:
Clock Report
Timing
Constraints:
All Constraints Met
Detailed Reports [-]
Report Name Status Generated Errors Warnings Infos
Synthesis Report Current
Tue May 10
17:20:11 2016
0
63 Warnings (63
new)
11 Infos (11
new)
Translation Report Current
Tue May 10
17:20:36 2016
0
19 Warnings (19
new)
1 Info (0 new)
Map Report Current
Tue May 10
17:21:32 2016
0
1 Warning (1
new)
6 Infos (6 new)
Place and Route
Report
Current
Tue May 10
17:22:42 2016
0
2 Warnings (2
new)
0
Power Report
Post-PAR Static
Timing Report
Current
Tue May 10
17:22:53 2016
0 0 5 Infos (5 new)
Bitgen Report Current
Tue May 10
17:23:13 2016
0
1 Warning (1
new)
1 Info (1 new)
Secondary Reports [-]
Report Name Status Generated
WebTalk Report Current Tue May 10 17:23:14 2016
WebTalk Log File Current Tue May 10 17:23:31 2016
Date Generated: 05/10/2016 - 17:23:36
FIR Filters with FPGA
Page | 16
Main Wrapper
//********************** sacred header
//**********************
module vProj_fir_25_6(
input wire CCLK, // 50 MHz/20 ns
SPIMISO, //Master In, Slave Out
BTN_EAST, // get sample
BTN_NORTH, // reset
BTN_WEST, // set preamp gain = -1
input [3:0] SW,
output wire SPIMOSI,
SPISCK,
AMPSD, AMPCS,
DACCS, DACCLR,
ADCONV,
sfCEbar,
fpgaINITb,
J4a, J4b, J4c, J4d,
output [7:0] LED
);
//********************** sacred variables
parameter ONE = 1'b1,
ZERO = 1'b0;
parameter sampl = 125; // set sample rate 250 = 20kHz 125 = 40kHz
wire clk4, Fs, Fs_clk2, CCLK50, clk40MHz; // from clock divider Fs = 20kHz Fs_clk2 =
320kHz
wire reset, start, d2a_enable;
wire [3:0] gain;
assign gain = SW;
wire get_a2d, set_preAmp;
// spi_miso,
wire spiclkP, spiMosiP, // CCLK & data to preamp
spiclkA, spiMosiA, // clk & data from a2d
spiclkD, spiMosiD;
wire [13:0] CN_Adat; //, CN_Bdat;
wire [11:0] data2Write;
FIR Filters with FPGA
Page | 17
wire raw_set_preAmp; // west button to single shot
// filter wrapper vars
wire [13:0] a2d_out;
wire [11:0] d2a_in_T;
wire clk_enable;
assign a2d_out = CN_Adat;
assign data2Write = d2a_in_T;
assign clk_enable = ONE;
assign LED = { ADCONV, DACCS, data2Write[11:6] };
//************************** filter vars
wire signed [15:0] filter_in; //sfix16_En15
wire signed [15:0] filter_out; //sfix36_En31 was 35 bits
wire rdy, rfd;
wire [2:0] AB; // ab switch for comparing in vs
out signal
assign AB = SW[3:1];
// test signals on S3e
assign J4a = ADCONV;
assign J4b = DACCS;
assign J4c = Fs;
assign J4d = rdy;
///************************** sacred code as above, so below
// .assign spi_miso = SPIMISO;
assign start = BTN_EAST;
assign reset = BTN_NORTH;
assign raw_set_preAmp = BTN_WEST;
assign sfCEbar = ONE; //parallel flash enable lo
assign fpgaINITb = ZERO; // flash enable hi
assign SPIMOSI = (spiMosiP && ~AMPCS) || (spiMosiD && ~DACCS);// || spiMosiA ; // data
TO SPI stuff
assign SPISCK = (spiclkP && ~AMPCS) || (spiclkD && ~DACCS) || spiclkA ; // // data
FROM SPI stuff
wire buf_clk;
BUFG bufg(.I( CCLK50 ), .O( buf_clk ) );
wire [15:0] TRIG0;
assign TRIG0 = {
SPIMISO, SPIMOSI, SPISCK, ADCONV, DACCS,
CN_Adat[13:9], // five bits of 14 from a2d
data2Write[11:7], // five bits of 12 to d2a
reset };
FIR Filters with FPGA
Page | 18
// reset, set_preAmp, start, SPIMISO,
// SPIMOSI, SPISCK, get_a2d, d2a_enable,
// AMPSD, AMPCS, DACCS, DACCLR,
///************************** sacred code above
//***************************
wire clk12MHz, buf_clk12, wrapClk;
BUFG bufg12( .I( clk12MHz ), .O( clk4 ) );
BUFG bufg50( .I( CCLK50 ), .O( wrapClk ) );
/*Div4 div4(
.clk( CCLK50 ),
.reset( reset ),
.clk4( clk4 )
); */
// replaced with Fs_clk2
/*
DivFs F_samp( // create Fs clock Fs
.clk( CCLK50 ),
.reset( reset ),
.divisor( 10*sampl ), //2500 = 20k 1250 = 40k
.clkDiv( Fs )
); */
//*********************
clk40M clk40Div ( // forty MHz generator
.CLKIN_IN( CCLK ),
.RST_IN( reset ),
.CLKDV_OUT( clk12MHz ), // 25 MHz
.CLKFX_OUT( clk40MHz ),
.CLKIN_IBUFG_OUT( ),
.CLK0_OUT( CCLK50 )
);
DivFs C320kHz(
.clk( clk40MHz ),
.reset( reset ),
.divisor( 8*sampl ), // 2000 = 20kHz
.clkDiv( Fs_clk2 )
);
assign Fs = Fs_clk2;
//************************
SampleEnable Sammy(
.clk( CCLK50 ), .clk16( clk4 ),
FIR Filters with FPGA
Page | 19
.reset( reset ),
.start( start ),
.fs( Fs ),
.a2d_enable( get_a2d ),
.d2a_enable( d2a_enable )
);
//**************************more sacred code begin
//******************************************
A2D a2d ( // like RDID, only different
// inputs
.spi_miso ( SPIMISO ), .clk ( clk4 ),
.reset ( reset ), .get_a2d ( get_a2d ),
//outputs
.spi_sck ( spiclkA ),
.spi_mosi ( spiMosiA ),
.ADCONV( ADCONV ),
.CN_Adat ( CN_Adat )
// .CN_Bdat ( CN_Bdat )
);
///************************** sacred code above
preAmp PA ( // like RDID, only different
.spi_miso( SPIMISO ), .clk( clk4 ),
.reset ( reset ),
.set_preAmp ( set_preAmp ),
.gain( gain ),
.spi_sck ( spiclkP ),
.spi_mosi ( spiMosiP ),
.AMPCS( AMPCS ), // preamp chip select, active low
.AMPSD( AMPSD ) // shut down not, power on, active low
);
D2A d2a(
.spi_miso( SPIMISO ), // SPI read data
.clk( clk4 ),
.reset( reset ),
.d2a_enable( d2a_enable ),
.data2Write( data2Write ), // data to write input wire [15:0]
.spi_sck( spiclkD ), // SPI clock
.spi_mosi( spiMosiD ), // SPI Data to write
.DACCS( DACCS ), // chip select, active low while sending data
.DACCLR( DACCLR) // clear d2s
FIR Filters with FPGA
Page | 20
);
oneShot PreShot (
.clk( clk4 ), // wire source to wire destination
.trig( raw_set_preAmp ), // reg to wire
.trigOut( set_preAmp )// wire to wire
);
// sign2unsign conJob(
// .in( sign_dat ), // 14 bits
// .data2Write( data2Write ) // 16 bits
// );
//********************************** filter wrapper
filter_wrapper wrap(
.clk( wrapClk ),
.Fs_clk2( Fs_clk2 ),
.clk_enable( clk_enable ),
.reset( reset ),
.a2d_out( a2d_out ),
.rfd( rfd ), // output rfd
.rdy( rdy ), // output rdy
.AB( AB ),
.d2a_in( d2a_in_T ) // transfers a2d_out to d2a_in_T
);
endmodule
Digital to Analog Converter (like RDID, only different
// SPI Master for the ST MicroM25P16 Serial Flash
`default_nettype none
module D2A(
input wire spi_miso, // SPI read data
input wire clk,
input wire reset, // Active high
input wire d2a_enable,
input wire [11:0] data2Write, // data to write
output reg spi_sck, // SPI clock
output wire spi_mosi, // SPI Data to write
output reg DACCS, // chip select, active low while sending gain command
output wire DACCLR // clear d2s
);
FIR Filters with FPGA
Page | 21
reg [2:0] cs_d2a, ns_d2a;
reg [4:0] send_count;
reg [4:0] get_count;
reg enable_get_count, enable_send_count;
reg mosi_enable;
reg assert_DACCS;
wire [31:0] data_word; // command to turn on d2a, create wave
parameter [4:0] SEND_COUNT_MAX = 5'h1F; //----------------------------------------- was 24/17
// parameter [4:0] GET_COUNT_MAX = 5'h18;
parameter [2:0] IDLE = 3'b000,
SET_CS = 3'b001,
sendInstruct = 3'b10,
//getDATA = 3'b011,
Clr_DAC_CS = 3'b100;
parameter ONE = 1'b1;
parameter ZERO = 1'b0;
parameter ZZ = 1'bz;
assign DACCLR = ONE;
assign data_word = { 8'h00, 4'b0010, 4'b1111, data2Write, 4'h0 };
// 8 + 4 + 4 + 12 + 4 = 32 bits
/////////////////////////////////////////////////////////// added eight bits of zero
always @ ( * ) begin
// Defaults
ns_d2a = IDLE;
enable_send_count = ZERO;
// enable_get_count = 1'b0;
assert_DACCS = ZERO;
mosi_enable = ZERO;
case (cs_d2a)
// Remain in idle until told to send data
IDLE: begin
if ( d2a_enable )
ns_d2a = SET_CS;
else ns_d2a = IDLE;
mosi_enable = ZERO;
//else assert_DACCS = ZERO;
end
// Assert chip select in its own state to meet chip select assertion setup time
SET_CS: begin
FIR Filters with FPGA
Page | 22
ns_d2a = sendInstruct;
assert_DACCS = ONE;
end
// Provide clocks to d2a_enable the instructions
sendInstruct: begin
enable_send_count = ONE;
assert_DACCS = ONE;
mosi_enable = ONE;
if ( send_count == 0 )
ns_d2a = Clr_DAC_CS;
else
ns_d2a = sendInstruct;
end
// Deassert chip select in its own state to meet chip select deassertion setup time
Clr_DAC_CS: begin
ns_d2a = IDLE;
assert_DACCS = ZERO;
enable_send_count = ZERO;
mosi_enable = ZERO;
end
endcase
end
// Need a register so the chip select don't glitch
always @(posedge clk or posedge reset) begin
if ( reset )
DACCS <= ONE;
else if ( assert_DACCS )
DACCS <= ZERO;
else
DACCS <= ONE;
end
// Current state gets next state at the positive edge of the clock
always @(posedge clk or posedge reset) begin
if ( reset )
cs_d2a <= IDLE;
else
cs_d2a <= ns_d2a;
end
// maintain a count of the spi_sck's we've provided sending
always @(posedge clk or posedge reset) begin
FIR Filters with FPGA
Page | 23
if ( reset )
send_count <= SEND_COUNT_MAX;
// Reset counter every time we're asked to get the ID again.
else if ( d2a_enable )
send_count <= SEND_COUNT_MAX;
else if ( enable_send_count && spi_sck)
send_count <= send_count - 1'b1;
end
// maintain a count of the spi_sck's
/*
always @(posedge clk or posedge reset) begin
if ( reset )
get_count <= GET_COUNT_MAX;
// Reset counter every time we're asked to get the ID again.
else if ( d2a_enable )
get_count <= GET_COUNT_MAX;
else if (enable_get_count && !spi_sck)
get_count <= get_count - ONE;
end
*/
// Collect read_data
/* always @(posedge clk or posedge reset) begin //*************************************
// always @(negedge clk or posedge reset) begin
if (reset)
read_data <= 24'b0;
else if (enable_get_count && !spi_sck)
read_data[get_count-1] <= spi_miso;
end
*/
// Toggle spi_sck. Need a register so the clock doesn't glitch
always @(posedge clk or posedge reset) begin
if (reset)
spi_sck <= ZERO;
else if (enable_send_count) // || enable_get_count)
spi_sck <= !spi_sck;
else if ( d2a_enable )
spi_sck <= ZERO;
else spi_sck <= ZERO;
end
// spi-mosi is just an index into the data_word vector
assign spi_mosi = data_word[send_count] && mosi_enable;
//synopsys translate_off
reg [95:0] ASCII_csd2a, ASCII_nsd2a; // Hold 12 characters (8*12=96)
FIR Filters with FPGA
Page | 24
always @* begin
case (cs_d2a)
IDLE: ASCII_csd2a = "IDLE";
SET_CS: ASCII_csd2a = "SET_CS";
sendInstruct: ASCII_csd2a = "sendInstruct";
// getDATA: ASCII_csd2a = "getDATA";
Clr_DAC_CS: ASCII_csd2a = "Clr_DAC_CS";
endcase
end
always @* begin
case (ns_d2a)
IDLE: ASCII_nsd2a = "IDLE";
SET_CS: ASCII_nsd2a = "SET_CS";
sendInstruct: ASCII_nsd2a = "sendInstruct";
// getDATA: ASCII_nsd2a = "getDATA";
Clr_DAC_CS: ASCII_nsd2a = "Clr_DAC_CS";
endcase
end
//synopsys translate_on
endmodule
/*
D2A your_name_here(
.spi_miso( spi_miso ), // SPI read data
.clk( clk ),
.reset( reset ),
.d2a_enable( d2a_enable ),
.data2Write( data2Write ), // data to write input wire [15:0]
.spi_sck( spi_sck ), // SPI clock
.spi_mosi( spi_mosi ), // SPI Data to write
.DACCS( DACCS ), // chip select, active low while sending gain command
.DACCLR( DACCLR) // clear d2s
);
*/
Second Wrapper
Instantiates the filters.
module Second_wrapper(
input clk, // 50 MHz
clk320, // nominal sample freq x 16
FIR Filters with FPGA
Page | 25
clk_enable,
reset,
output wire rdylp, rfdlp,
input wire [2:0] AB,
input wire signed [15:0] filter_in_16,
//output reg signed [15:0] filter_out_16LP,
//output reg signed [15:0] filter_out_16HP,
//output reg signed [15:0] filter_out_16BP,
output reg signed [15:0] filter_out_16
);
parameter outMSB_LP = 40; // fir41 fir40 is 37;
parameter outMSB_HP = 37; // fir41 fir40 is 37;
parameter outMSB_BP = 39;
parameter outMSB_HPlong = 41;
parameter outMSB_HPshort = 42;
wire ndL, ndH, ndB, ndHl;
assign ndL = 1'b1; //(AB == 2'b11);
assign ndH = 1'b1; //(AB == 2'b10);
assign ndB = 1'b1; //(AB == 2'b01);
assign ndHl = 1'b1; //(AB == 2'b01);
wire rdyhp, rfdhp, rfdHl;
wire rdybp, rfdbp, rdyHl;
wire signed [15:0] filter_in_16LP;
wire signed [15:0] filter_in_16HP;
wire signed [15:0] filter_in_16BP;
wire signed [15:0] filter_in_16HPlong;
assign filter_in_16LP = filter_in_16;
assign filter_in_16HP = filter_in_16;
assign filter_in_16BP = filter_in_16;
assign filter_in_16HPlong = filter_in_16;
wire signed [outMSB_LP:0] firLP;
wire signed [outMSB_HP:0] firHP;
wire signed [outMSB_BP:0] firBP;
wire signed [outMSB_HPlong:0] firHPlong;
wire signed [outMSB_HPshort:0] firHPshort;
wire signed [39:0] HP10c;
always @ ( * ) begin
case( AB )
3'b000: // IN >> OUT
FIR Filters with FPGA
Page | 26
filter_out_16 = filter_in_16;
3'b110: begin // LP 100 / 300 hZ
filter_out_16 = firLP[ outMSB_LP : outMSB_LP-15 ];// << 2;
filter_out_16 = filter_out_16 << 4;
end
3'b100: begin // LP 2K / 3kHz
filter_out_16 = firHP[ outMSB_HP : outMSB_HP-15 ];// << 2;
filter_out_16 = filter_out_16 << 4;
end
3'b010: begin // IN >> OUT
filter_out_16 = firBP[ outMSB_BP : outMSB_BP-15 ];// << 2;
filter_out_16 = filter_out_16 << 4;
end
//**************************
3'b001: begin
filter_out_16 = firHPlong[ outMSB_HPlong : outMSB_HPlong-15 ];// << 2;
filter_out_16 = filter_out_16 << 4;
end
3'b011: begin
filter_out_16 = firHPshort[ outMSB_HPshort : outMSB_HPshort-15 ];// << 2;
filter_out_16 = filter_out_16 << 4;
end
3'b111: begin
filter_out_16 = HP10c[39:39-15];// << 2;
filter_out_16 = filter_out_16 << 4;
end
endcase
end // always
Fir_BP BP_15c2k_4k5_40kHz ( // BP_15c2k_4k5_40kHz 1500 2000 4K 5K SWITCH 010
.clk(clk), // input clk
.nd( ndB ), // input nd
.rfd( rfdbp ), // output rfd
.rdy( rdybp ), // output rdy
.din( filter_in_16BP ), // input [15 : 0] din
.dout( firBP )
); // output [39 : 0] dout
Fir41 Fir_41_LP ( // LP1c_3c_284stage_40kHz_40.coe 100 -- 300 40:0
SWITCH 110
.clk( clk ), // input clk
.nd( ndL ), // input nd
.rfd( rfdlp ), // output rfd
FIR Filters with FPGA
Page | 27
.rdy( rdylp ), // output rdy
.din( filter_in_16LP ), // input [15 : 0] din
.dout( firLP ) ); // output [34 : 0] dout
FIR40 Fir2_3k ( // Fir2_3__40kHz57stage.coe 2000 -- 3000 LP
SWITCH 100
.clk( clk ), // input clk
.nd( ndH ), // input nd
.rfd( rfdhp ), // output rfd
.rdy( rdyhp ), // output rdy
.din( filter_in_16HP ), // input [15 : 0] din
.dout( firHP ) ); // output [34 : 0] dout
HP_90_120_2836stage HP_120Hz ( //HP1c_2836stage_40kHz.coe 100Hz HP // SWITCH 001
.clk( clk ), // input clk
.nd( ndHl ), // input nd
.rfd( rfdHl ), // output rfd
.rdy( rdyHl ), // output rdy
.chan_out(chan_out), // output [2 : 0] chan_out
.din( filter_in_16HPlong ), // input [15 : 0] din
.dout( firHPlong )
); // output [40 : 0] dout
HP1000 HPTencElevenc (
.clk( clk ), // input clk
.nd( ndHl ),
.rfd( ), // output rfd
.rdy( ), // output rdy
.din( filter_in ), // input [15 : 0] din
.dout( HP10c ) // output [41 : 0] dout
);
HP1702 HP_200Hz ( // HP150_200_1702stage
.clk( clk ), // input clk
.nd( ndHl ),
.rfd( ), // output rfd
.rdy( ), // output rdy
.din( filter_in_16 ), // input [15 : 0] din
.dout( firHPshort )); // output [42 : 0] dout
endmodule

Contenu connexe

Tendances

8086 labmanual
8086 labmanual8086 labmanual
8086 labmanualiravi9
 
Microprocessor square wave
Microprocessor square waveMicroprocessor square wave
Microprocessor square waveFthi Arefayne
 
FPGA Implementation of ADPLL with Ripple Reduction Techniques
FPGA Implementation of ADPLL with Ripple Reduction TechniquesFPGA Implementation of ADPLL with Ripple Reduction Techniques
FPGA Implementation of ADPLL with Ripple Reduction TechniquesVLSICS Design
 
Microprocessor lab
Microprocessor labMicroprocessor lab
Microprocessor labkpaulraj
 
Microprocessor lab manual
Microprocessor lab manualMicroprocessor lab manual
Microprocessor lab manualDhaval Shukla
 
Microprocessor system - summarize
Microprocessor system - summarizeMicroprocessor system - summarize
Microprocessor system - summarizeHisham Mat Hussin
 
Unit 6 assembly language programming
Unit 6   assembly language programmingUnit 6   assembly language programming
Unit 6 assembly language programmingKartik Sharma
 
8051-mazidi-solution
8051-mazidi-solution8051-mazidi-solution
8051-mazidi-solutionZunAib Ali
 
IEEE_Peer_Reviewed_Paper_1
IEEE_Peer_Reviewed_Paper_1IEEE_Peer_Reviewed_Paper_1
IEEE_Peer_Reviewed_Paper_1Saad Mahboob
 
1347 Assembly Language Programming Of 8051
1347 Assembly Language Programming Of 80511347 Assembly Language Programming Of 8051
1347 Assembly Language Programming Of 8051techbed
 
LinuxCNC 入門簡介
LinuxCNC 入門簡介LinuxCNC 入門簡介
LinuxCNC 入門簡介roboard
 
8051 programming skills using EMBEDDED C
8051 programming skills using EMBEDDED C8051 programming skills using EMBEDDED C
8051 programming skills using EMBEDDED CAman Sharma
 
Linux cnc overview
Linux cnc overviewLinux cnc overview
Linux cnc overviewNylon
 
Lect2 up370 (100329)
Lect2 up370 (100329)Lect2 up370 (100329)
Lect2 up370 (100329)aicdesign
 
Micro Processor Lab Manual!
Micro Processor Lab Manual!Micro Processor Lab Manual!
Micro Processor Lab Manual!PRABHAHARAN429
 

Tendances (20)

8086 labmanual
8086 labmanual8086 labmanual
8086 labmanual
 
Microprocessor square wave
Microprocessor square waveMicroprocessor square wave
Microprocessor square wave
 
FPGA Implementation of ADPLL with Ripple Reduction Techniques
FPGA Implementation of ADPLL with Ripple Reduction TechniquesFPGA Implementation of ADPLL with Ripple Reduction Techniques
FPGA Implementation of ADPLL with Ripple Reduction Techniques
 
Bm33388392
Bm33388392Bm33388392
Bm33388392
 
Analog to Digital Converter
Analog to Digital ConverterAnalog to Digital Converter
Analog to Digital Converter
 
Microprocessor lab
Microprocessor labMicroprocessor lab
Microprocessor lab
 
Microprocessor lab manual
Microprocessor lab manualMicroprocessor lab manual
Microprocessor lab manual
 
Microprocessor system - summarize
Microprocessor system - summarizeMicroprocessor system - summarize
Microprocessor system - summarize
 
DSP_Assign_1
DSP_Assign_1DSP_Assign_1
DSP_Assign_1
 
Unit 6 assembly language programming
Unit 6   assembly language programmingUnit 6   assembly language programming
Unit 6 assembly language programming
 
8051-mazidi-solution
8051-mazidi-solution8051-mazidi-solution
8051-mazidi-solution
 
IEEE_Peer_Reviewed_Paper_1
IEEE_Peer_Reviewed_Paper_1IEEE_Peer_Reviewed_Paper_1
IEEE_Peer_Reviewed_Paper_1
 
1347 Assembly Language Programming Of 8051
1347 Assembly Language Programming Of 80511347 Assembly Language Programming Of 8051
1347 Assembly Language Programming Of 8051
 
Aihro-1
Aihro-1Aihro-1
Aihro-1
 
LinuxCNC 入門簡介
LinuxCNC 入門簡介LinuxCNC 入門簡介
LinuxCNC 入門簡介
 
8051 programming skills using EMBEDDED C
8051 programming skills using EMBEDDED C8051 programming skills using EMBEDDED C
8051 programming skills using EMBEDDED C
 
Linux cnc overview
Linux cnc overviewLinux cnc overview
Linux cnc overview
 
Lect2 up370 (100329)
Lect2 up370 (100329)Lect2 up370 (100329)
Lect2 up370 (100329)
 
Micro Processor Lab Manual!
Micro Processor Lab Manual!Micro Processor Lab Manual!
Micro Processor Lab Manual!
 
3 jump, loop and call instructions
3 jump, loop and call instructions3 jump, loop and call instructions
3 jump, loop and call instructions
 

En vedette

Fpga 11-sequence-detector-fir-iir-filter
Fpga 11-sequence-detector-fir-iir-filterFpga 11-sequence-detector-fir-iir-filter
Fpga 11-sequence-detector-fir-iir-filterMalik Tauqir Hasan
 
Design and Implementation of Axi-Apb Bridge based on Amba 4.0
Design and Implementation of Axi-Apb Bridge based on Amba 4.0Design and Implementation of Axi-Apb Bridge based on Amba 4.0
Design and Implementation of Axi-Apb Bridge based on Amba 4.0ijsrd.com
 
FPGA Implementation of FIR Filter using Various Algorithms: A Retrospective
FPGA Implementation of FIR Filter using Various Algorithms: A RetrospectiveFPGA Implementation of FIR Filter using Various Algorithms: A Retrospective
FPGA Implementation of FIR Filter using Various Algorithms: A RetrospectiveIJORCS
 
RISC Implementation Of Digital IIR Filter in DSP
RISC Implementation Of Digital IIR Filter in DSPRISC Implementation Of Digital IIR Filter in DSP
RISC Implementation Of Digital IIR Filter in DSPiosrjce
 
Digital filter design using VHDL
Digital filter design using VHDLDigital filter design using VHDL
Digital filter design using VHDLArko Das
 
Design and implementation of qpsk modulator using digital subcarrier
Design and implementation of qpsk modulator using digital subcarrierDesign and implementation of qpsk modulator using digital subcarrier
Design and implementation of qpsk modulator using digital subcarrierGongadi Nagaraju
 
Digital filter design using VHDL
Digital filter design using VHDLDigital filter design using VHDL
Digital filter design using VHDLArko Das
 

En vedette (9)

FPGA Implementation of High Speed FIR Filters and less power consumption stru...
FPGA Implementation of High Speed FIR Filters and less power consumption stru...FPGA Implementation of High Speed FIR Filters and less power consumption stru...
FPGA Implementation of High Speed FIR Filters and less power consumption stru...
 
Fpga 11-sequence-detector-fir-iir-filter
Fpga 11-sequence-detector-fir-iir-filterFpga 11-sequence-detector-fir-iir-filter
Fpga 11-sequence-detector-fir-iir-filter
 
Design and Implementation of Axi-Apb Bridge based on Amba 4.0
Design and Implementation of Axi-Apb Bridge based on Amba 4.0Design and Implementation of Axi-Apb Bridge based on Amba 4.0
Design and Implementation of Axi-Apb Bridge based on Amba 4.0
 
FPGA Implementation of FIR Filter using Various Algorithms: A Retrospective
FPGA Implementation of FIR Filter using Various Algorithms: A RetrospectiveFPGA Implementation of FIR Filter using Various Algorithms: A Retrospective
FPGA Implementation of FIR Filter using Various Algorithms: A Retrospective
 
Zynq architecture
Zynq architectureZynq architecture
Zynq architecture
 
RISC Implementation Of Digital IIR Filter in DSP
RISC Implementation Of Digital IIR Filter in DSPRISC Implementation Of Digital IIR Filter in DSP
RISC Implementation Of Digital IIR Filter in DSP
 
Digital filter design using VHDL
Digital filter design using VHDLDigital filter design using VHDL
Digital filter design using VHDL
 
Design and implementation of qpsk modulator using digital subcarrier
Design and implementation of qpsk modulator using digital subcarrierDesign and implementation of qpsk modulator using digital subcarrier
Design and implementation of qpsk modulator using digital subcarrier
 
Digital filter design using VHDL
Digital filter design using VHDLDigital filter design using VHDL
Digital filter design using VHDL
 

Similaire à FIR_Filters_with_FPGA

International Journal of Computational Engineering Research(IJCER)
International Journal of Computational Engineering Research(IJCER)International Journal of Computational Engineering Research(IJCER)
International Journal of Computational Engineering Research(IJCER)ijceronline
 
Design and Implement Any Digital Filters in Less than 60 Seconds
Design and Implement Any Digital Filters in Less than 60 SecondsDesign and Implement Any Digital Filters in Less than 60 Seconds
Design and Implement Any Digital Filters in Less than 60 SecondsMike Ellis
 
Fpga applications using hdl
Fpga applications using hdlFpga applications using hdl
Fpga applications using hdlSankarshan D
 
Software Design of Digital Receiver using FPGA
Software Design of Digital Receiver using FPGASoftware Design of Digital Receiver using FPGA
Software Design of Digital Receiver using FPGAIRJET Journal
 
DickeyS_presentation_2015_3_26_2_1
DickeyS_presentation_2015_3_26_2_1DickeyS_presentation_2015_3_26_2_1
DickeyS_presentation_2015_3_26_2_1Sergey Dickey
 
IRJET- A Digital Down Converter on Zynq SoC
IRJET-  	  A Digital Down Converter on Zynq SoCIRJET-  	  A Digital Down Converter on Zynq SoC
IRJET- A Digital Down Converter on Zynq SoCIRJET Journal
 
Grasp the Critical Issues for a Functioning JESD204B Interface
Grasp the Critical Issues for a Functioning JESD204B InterfaceGrasp the Critical Issues for a Functioning JESD204B Interface
Grasp the Critical Issues for a Functioning JESD204B InterfaceAnalog Devices, Inc.
 
02_Cornelsen_Doug_mapld09_pres_1.ppt
02_Cornelsen_Doug_mapld09_pres_1.ppt02_Cornelsen_Doug_mapld09_pres_1.ppt
02_Cornelsen_Doug_mapld09_pres_1.pptssuserf2cc17
 
20081114 Friday Food iLabt Bart Joris
20081114 Friday Food iLabt Bart Joris20081114 Friday Food iLabt Bart Joris
20081114 Friday Food iLabt Bart Jorisimec.archive
 
E0364025031
E0364025031E0364025031
E0364025031theijes
 
Iaetsd pipelined parallel fft architecture through folding transformation
Iaetsd pipelined parallel fft architecture through folding transformationIaetsd pipelined parallel fft architecture through folding transformation
Iaetsd pipelined parallel fft architecture through folding transformationIaetsd Iaetsd
 
Nt1310 Unit 5 Algorithm
Nt1310 Unit 5 AlgorithmNt1310 Unit 5 Algorithm
Nt1310 Unit 5 AlgorithmAngie Lee
 
FPGA Implementation of Optimized CIC Filter for Sample Rate Conversion in Sof...
FPGA Implementation of Optimized CIC Filter for Sample Rate Conversion in Sof...FPGA Implementation of Optimized CIC Filter for Sample Rate Conversion in Sof...
FPGA Implementation of Optimized CIC Filter for Sample Rate Conversion in Sof...idescitation
 
High Performance DSP with Xilinx All Programmable Devices (Design Conference ...
High Performance DSP with Xilinx All Programmable Devices (Design Conference ...High Performance DSP with Xilinx All Programmable Devices (Design Conference ...
High Performance DSP with Xilinx All Programmable Devices (Design Conference ...Analog Devices, Inc.
 
Hardware Description Beyond Register-Transfer Level (RTL) Languages
Hardware Description Beyond Register-Transfer Level (RTL) LanguagesHardware Description Beyond Register-Transfer Level (RTL) Languages
Hardware Description Beyond Register-Transfer Level (RTL) LanguagesLEGATO project
 
Seminar on field programmable gate array
Seminar on field programmable gate arraySeminar on field programmable gate array
Seminar on field programmable gate arraySaransh Choudhary
 
Efficient FPGA implementation of high speed digital delay for wideband beamfor...
Efficient FPGA implementation of high speed digital delay for wideband beamfor...Efficient FPGA implementation of high speed digital delay for wideband beamfor...
Efficient FPGA implementation of high speed digital delay for wideband beamfor...journalBEEI
 
INDUSTRIAL TRAINING REPORT
INDUSTRIAL TRAINING REPORTINDUSTRIAL TRAINING REPORT
INDUSTRIAL TRAINING REPORTABHISHEK DABRAL
 

Similaire à FIR_Filters_with_FPGA (20)

International Journal of Computational Engineering Research(IJCER)
International Journal of Computational Engineering Research(IJCER)International Journal of Computational Engineering Research(IJCER)
International Journal of Computational Engineering Research(IJCER)
 
Design and Implement Any Digital Filters in Less than 60 Seconds
Design and Implement Any Digital Filters in Less than 60 SecondsDesign and Implement Any Digital Filters in Less than 60 Seconds
Design and Implement Any Digital Filters in Less than 60 Seconds
 
Fpga applications using hdl
Fpga applications using hdlFpga applications using hdl
Fpga applications using hdl
 
Software Design of Digital Receiver using FPGA
Software Design of Digital Receiver using FPGASoftware Design of Digital Receiver using FPGA
Software Design of Digital Receiver using FPGA
 
Introduction to Blackfin BF532 DSP
Introduction to Blackfin BF532 DSPIntroduction to Blackfin BF532 DSP
Introduction to Blackfin BF532 DSP
 
DickeyS_presentation_2015_3_26_2_1
DickeyS_presentation_2015_3_26_2_1DickeyS_presentation_2015_3_26_2_1
DickeyS_presentation_2015_3_26_2_1
 
IRJET- A Digital Down Converter on Zynq SoC
IRJET-  	  A Digital Down Converter on Zynq SoCIRJET-  	  A Digital Down Converter on Zynq SoC
IRJET- A Digital Down Converter on Zynq SoC
 
Grasp the Critical Issues for a Functioning JESD204B Interface
Grasp the Critical Issues for a Functioning JESD204B InterfaceGrasp the Critical Issues for a Functioning JESD204B Interface
Grasp the Critical Issues for a Functioning JESD204B Interface
 
02_Cornelsen_Doug_mapld09_pres_1.ppt
02_Cornelsen_Doug_mapld09_pres_1.ppt02_Cornelsen_Doug_mapld09_pres_1.ppt
02_Cornelsen_Doug_mapld09_pres_1.ppt
 
20081114 Friday Food iLabt Bart Joris
20081114 Friday Food iLabt Bart Joris20081114 Friday Food iLabt Bart Joris
20081114 Friday Food iLabt Bart Joris
 
E0364025031
E0364025031E0364025031
E0364025031
 
Iaetsd pipelined parallel fft architecture through folding transformation
Iaetsd pipelined parallel fft architecture through folding transformationIaetsd pipelined parallel fft architecture through folding transformation
Iaetsd pipelined parallel fft architecture through folding transformation
 
Nt1310 Unit 5 Algorithm
Nt1310 Unit 5 AlgorithmNt1310 Unit 5 Algorithm
Nt1310 Unit 5 Algorithm
 
FPGA Implementation of Optimized CIC Filter for Sample Rate Conversion in Sof...
FPGA Implementation of Optimized CIC Filter for Sample Rate Conversion in Sof...FPGA Implementation of Optimized CIC Filter for Sample Rate Conversion in Sof...
FPGA Implementation of Optimized CIC Filter for Sample Rate Conversion in Sof...
 
High Performance DSP with Xilinx All Programmable Devices (Design Conference ...
High Performance DSP with Xilinx All Programmable Devices (Design Conference ...High Performance DSP with Xilinx All Programmable Devices (Design Conference ...
High Performance DSP with Xilinx All Programmable Devices (Design Conference ...
 
Hardware Description Beyond Register-Transfer Level (RTL) Languages
Hardware Description Beyond Register-Transfer Level (RTL) LanguagesHardware Description Beyond Register-Transfer Level (RTL) Languages
Hardware Description Beyond Register-Transfer Level (RTL) Languages
 
Design Radix-4 64-Point Pipeline FFT/IFFT Processor for Wireless Application
Design Radix-4 64-Point Pipeline FFT/IFFT Processor for Wireless ApplicationDesign Radix-4 64-Point Pipeline FFT/IFFT Processor for Wireless Application
Design Radix-4 64-Point Pipeline FFT/IFFT Processor for Wireless Application
 
Seminar on field programmable gate array
Seminar on field programmable gate arraySeminar on field programmable gate array
Seminar on field programmable gate array
 
Efficient FPGA implementation of high speed digital delay for wideband beamfor...
Efficient FPGA implementation of high speed digital delay for wideband beamfor...Efficient FPGA implementation of high speed digital delay for wideband beamfor...
Efficient FPGA implementation of high speed digital delay for wideband beamfor...
 
INDUSTRIAL TRAINING REPORT
INDUSTRIAL TRAINING REPORTINDUSTRIAL TRAINING REPORT
INDUSTRIAL TRAINING REPORT
 

FIR_Filters_with_FPGA

  • 1. FIR Filters with FPGA Page | 1 FIR Filters with FPGAs ECE 5211 irvin rynning 10 May 2016
  • 2. FIR Filters with FPGA Page | 2 Contents: Front page 1 Contents 2 Part 1 Introduction and Motivation 3 Goals 3 Outside Sources 3 Part 2 Project Description 3 Interface 4 System Diagram 5 Design Flow 5 FIR Filter Design 6 Implementation 8 Part 3 Hardware Design 8 Block Diagram 8 Peripherals 10 Problems 10 Part 4 Discussion and results 11 Conclusion 12 References 13 Summary 14 Code 15 Main Wrapper 16 Digital to Analog 20 Second Wrapper 24
  • 3. FIR Filters with FPGA Page | 3 This project was motivated by the desire to use a Field Programmable Gate Array (FPGA) to accomplish a task in which its performance would rival that of an embedded system or microprocessor. Previously I had experience in using the Texas Instruments TMDSLCDK6748i , which provided for sixteen bit, floating point arithmetic with sample rate from 8 kHz to 96 kHz, and implemented using the Integrated Development Environment (IDE) called Code Composer in the both Cee programming language and an Assembly language. On this platform were developed real-time applications such as sweep oscillators, Finite Impulse Response (FIR) and Infinite Impulse response (IIR) filters, as well as analog equivalents in dynamics processing (compressors, gates, expanders), and time domain effects such as a “flanger”, chorus, and digital delay used in musical performance and production. The FIR caught my attention as it offered incredibly steep cutoffs coupled with minimal phase delay and distortion, processing which is normally done after the fact — i.e., not in real time — due to the high latency (or time delay) of the process. For example Goal The goal of this project then is three-fold: 1) Development the FPGA to pass audio frequencies from input to output 2) Incorporate a FIR of the several types a) High pass b) Low pass c) Band pass 3) Add more FIRs of increasing depth (stages) to observe real-time performance This is done on a qualitative basis, and will not measure time delays and real time parameters, nor use various sample rates to find limitations on performance. Indeed I did not expect to achieve the results I did. Outside Sources Other sources for Verilog programming and fpga implementation are as follows: Embedded Design Using Programmable Gate Arrays, Dennis Silageii The Verilog Hardware Description Language, 5th Edition, Thomas & Moorby.iii Advanced Digital Design, M Cilletti.iv Spartan-3E FPGA Starter Kit Board User Guide, Xilinx Incv . Core Generator Guide, Xilinx Inc.vi This project evolved from the Homework Seven of the course in Rapid Prototyping with FPGA, ECE- 5211, taught by Dr D. Perera in the Spring of 2016. In this assignment the embedded preamplifier
  • 4. FIR Filters with FPGA Page | 4 and analog to digital converter was implemented, and the conversion result displayed on the light emitting diodes (LEDs), also on the FPGA. From this I added the digital to analog conversion, setting up timing parameters, and creating an analog signal on the connecting header called J5 on the circuit board which echoed the input. Interface Necessary were two interface designs: The first was adjusting the input signal to be referenced to ½ the power voltage of +3.3 volts, shown in figure 1. The connections were made to the 6-pin ADC Header (J7), using the input A, as well as the GND and VCC pins. Figure 1 Input circuit The second was the output from 6-pin DAC Header (J5), using output A and the GND pins, and shown in figure 2. The Spartan 3E board does not have any low pass filtering for digital to analog conversion, and thus aliasing is expected. Further work implementing a typical Butterworth analog filter using a dual operational amplifier (op amp) would be essential.
  • 5. FIR Filters with FPGA Page | 5 Figure 2 Output circuit System Diagram System Diagram FIRsSignalFlowClocks Input Interface Preamp/ADC SPI Clock DAC SPI Clock Multiplexer FIRs in To DAC Out FIRS Digital Clock Manager Translation to FIRS 50 MHz CLK FX ×4 ÷5 > 40MHZ CLX DIV 12½MHz Everywhere 40MHz/100 = 40kHz SPI Clock Output Interface Slide Switches Gain Select FIR Figure 3 Diagram showing major components Design Flow After completing homework seven, and developing a free running analog to digital converter (ADC) and using an SPI clock of 12.5 MHz — the sample rate Fs was not implemented, other than the ADCONV signal which was 34 × SPI clock, or — 2.72µs, about 367kHz — I then attacked the digital to analog convertor (DAC). This first took a translation of the 14 bit signed integer data to the 12 bit unsigned required by the DAC. This algorithm is as follows, given signals ADC_data and DAC_data. wire [13:0] ADC_data; wire [11:0] DAC_data; wire [13:0] temp; always @ ( * ) begin temp[13] = ~(ADC_data[13]) ;
  • 6. FIR Filters with FPGA Page | 6 temp[12:0] = ADC_data[12:0] ; DAC_data = ~( temp[13:2] ; end Once good throughput of the incoming analog signal — which was always in the extended audio frequency range, 10 Hz to 50 kHz — was obtained I then went into FIR filter design. Fir Filter Design FIR filters are essentially multiply and add algorithms, with a given set of constants and a buffer of previous samples. A brief summary of this is given with figure 4. Successive input samples are loaded into a buffer whose length is the number of stages, each element of the buffer is multiplied by a constant, and the results are summed to create the output sample. The sample buffer is shifted with the next being inserted, and the process repeats. Figure 4 FIR block diagram from Cilletti
  • 7. FIR Filters with FPGA Page | 7 I investigated the Xilinx CORE development tools, such as floating point conversions and operations, and block core memories, and then found that there exists a FIR CORE tool,vii called IP LogiCORE FIR Compiler, as well as several videos, one of which is referenced hereviii . Figure 5 Page 1 of the CORE FIR Compiler I will not go into detail of the use of this tool other than to mention caveats and issues I had. The first is the use of a coefficients file— highly recommended, using the MatLab fdatool to create a set of 16 bit signed integers, as well as giving a graphical display of response. It is noted that the Freq. Response in above (figure 4) mirrors the one that MatLab creates (figure 5).
  • 8. FIR Filters with FPGA Page | 8 Figure 6 MatLab Created Response Additionally there is a setting for input bit width (16) and fractional depth (always 15). When the latter is set to 0 or 1, there is no output. The control lines for the filters were not implemented, as this is free running. Implementation After getting the throughput working and adding one filter, I then proceeded to add additional ones, with the use of the slide switches to control the output. I then implemented the network analyzer (otherwise called a spectrum analyzer) which generated an input of 10 Hz to a maximum of one half the sample rate. The sample rate was chosen to be arithmetically simple, 1000th of a 40 MHz clock. This Fs = 40 kHz has a period of 25 ms, which the ADC, starting on the positive edge of Fs, taking 34× SPI clock < 12.5 ms, as well as the output y[n] sample being determined in time for the DAC to take place on the negative edge of Fs. No glitches were observed in FIRs as great as some 110 stages. A block diagram generated using Microsoft’s Visio program is as follows. This shows four FIR filters being implements, their outputs being selected by the slide switches called SW on the Spartan 3E board. It shows the elements of the code and the hardware, and the interconnections. There is a discharge path 100kΩ resistor from the input coupling capacitor to ground not shown. Also not shown are all the clocks, as well as the data path width (number of bits). the input is marked with a square wave symbol, and the output with a sine wave. This is actually indicative of the performance of the filter, e.g., when a 1 kHz square is input and the “2 kHz low pass” filter selected, the output is a sine, for the third harmonic, 3 kHz, is down 40dB.
  • 9. FIR Filters with FPGA Page | 9 Figure 7 System Block Diagram
  • 10. FIR Filters with FPGA Page | 10 External devices found in the project include a DC shift mixer for the ADC input, implemented using a resistor divider to create a 50% VCC level, which is added to an AC coupled source from an oscillator or other signal generating device. The other is a DC blocking capacitor and a minimal response passive low pass filter on the DAC output. AS the testing was not done with a focus on the upper octave signals (10 kHz–20 kHz), this was not an issue. A better implementation would include active devices (op amps) on input to provide isolation and DC level shift, and on the output to provide a steeper low pass response. It is to be noted that actually listening to a typical tone through loudspeakers was rather harsh, owing to the aliasing. Development problems have already been mentioned, but I will reiterate them (and others) here. Input DC Level Shift: As discovered in homework seven, the input is clipped if it goes below 0 V with reference to the GND from the board. Thus a mixer is required, which raises the DC level to 50% of Vcc, 1•65 V while maintaining impedance and DC isolation. Signed versus Unsigned A useful, fast and simple algorithm was needed to translate the ADC data. Without translation, the output jumped from 0x0000 to 0x3fff when viewing a sine wave, creating an “upside down” chopped effect. Data Length Conversion Significant noise is introduced when altering data lengths from 14 bits to 16, and again from 30 plus bits from the filters, to the 12 bits needed for DAC. This is noted in the analyzer waveforms. Output DC level Shift A simple blocking capacitor, with suitable discharge resistors, was implemented. Output Low Pass Only a simple 6dB roll off passive filter was used. This was insufficient to offer a listening, or aural, quality. Necessary is an active filter, using op amps, which necessitates additional power source(s), which should measure at least 9V to ensure op amp performance.
  • 11. FIR Filters with FPGA Page | 11 Three of the FIR cores implemented worked well. A simple low pass at 100 Hz is shown with theoretical and actual measurement. Figure 8 100 Hz low pass filter, from MatLab. Figure 9 100 Hz Low pass, measured Figure 10 Bandpass 2 - 4 kHz from MatLab Figure 11 2-4 kHz bandpass measured
  • 12. FIR Filters with FPGA Page | 12 Figure 12 2 kHz low passd, from MatLab Figure 13 2 kHz low pass, measured The use of the Xilinx Core design tool is ripe with confusion. Two filters worked perfectly, a third had a high noise figure, and two not at all. The lack of a good low pass filter aggravated pictorial results. I think that tighter control of the filter — as opposed to its free running — might abet the noise glitches observed. Using the alternative, hard-coded form of the filter as opposed to the Core generator might give better results, but it would need some manner of automation for higher orders, say, greater than 100. Future work would be on several fronts, getting better accuracy and less noise, and implementing parallel outputs for the several filters, as well as using a stereo (dual channel) source. Additionally using higher sample rates should be tried, as well as measuring the time delay to create the next output sample.
  • 13. FIR Filters with FPGA Page | 13 i TMS320C6748 Fixed/Floating Point DSP, Texas Instruments, http://www.ti.com/lit/ds/symlink/tms320c6748.pdf, 2014. ii Embedded design Using Programmable Gate Arrays, Dennis Silage, Temple University, Bookstand Publishing, Gilroy Cal, 2008. iii The Verilog Hardware Description Language, 5th Edition, D Thomas, P Moorby, Springer, New York, 2002. iv Advanced Digital design, M Cilletti, Person Publishing, Upper Saddle River, NJ, 2003. v Spartan-3E FPGA Starter Kit Board User Guide, Xilinx Inc, www.xilinx.com, 2008. vi Core Generator Guide, Xilinx Inc., www.xilinx.com, 2000. vii IP LogiCORE FIR Compiler v5.0, Xilinx, http://www.xilinx.com/support/documentation/ip_documentation/fir_compiler_ds534.pdf, 2011. viiiviii Xilinx ISE FIR Core Complier, https://youtu.be/MUoJtv_M48M, “eazye8523”, 2015.
  • 14. FIR Filters with FPGA Page | 14 vProj_fir_25Passes Project Status (05/10/2016 - 17:23:35) Project File: proj40k.xise Parser Errors: No Errors Module Name: vProj_fir_25_6 Implementation State: Programming File Generated Target Device: xc3s500e-4fg320  Errors: No Errors Product Version: ISE 14.5  Warnings: 86 Warnings (86 new) Design Goal: Balanced  Routing Results: All Signals Completely Routed Design Strategy: Xilinx Default (unlocked)  Timing Constraints: All Constraints Met Environment: System Settings  Final Timing Score: 0 (Timing Report) Device Utilization Summary [-] Logic Utilization Used Available Utilization Note(s) Total Number Slice Registers 1,423 9,312 15% Number used as Flip Flops 1,409 Number used as Latches 14 Number of 4 input LUTs 1,206 9,312 12% Number of occupied Slices 1,072 4,656 23% Number of Slices containing only related logic 1,072 1,072 100% Number of Slices containing unrelated logic 0 1,072 0% Total Number of 4 input LUTs 1,398 9,312 15% Number used as logic 901 Number used as a route-thru 192 Number used for Dual Port RAMs 24 Number used as Shift registers 281 Number of bonded IOBs 30 232 12% Number of RAMB16s 17 20 85%
  • 15. FIR Filters with FPGA Page | 15 Number of BUFGMUXs 5 24 20% Number of DCMs 1 4 25% Number of MULT18X18SIOs 6 20 30% Average Fanout of Non-Clock Nets 2.22 Performance Summary [-] Final Timing Score: 0 (Setup: 0, Hold: 0, Component Switching Limit: 0) Pinout Data: Pinout Report Routing Results: All Signals Completely Routed Clock Data: Clock Report Timing Constraints: All Constraints Met Detailed Reports [-] Report Name Status Generated Errors Warnings Infos Synthesis Report Current Tue May 10 17:20:11 2016 0 63 Warnings (63 new) 11 Infos (11 new) Translation Report Current Tue May 10 17:20:36 2016 0 19 Warnings (19 new) 1 Info (0 new) Map Report Current Tue May 10 17:21:32 2016 0 1 Warning (1 new) 6 Infos (6 new) Place and Route Report Current Tue May 10 17:22:42 2016 0 2 Warnings (2 new) 0 Power Report Post-PAR Static Timing Report Current Tue May 10 17:22:53 2016 0 0 5 Infos (5 new) Bitgen Report Current Tue May 10 17:23:13 2016 0 1 Warning (1 new) 1 Info (1 new) Secondary Reports [-] Report Name Status Generated WebTalk Report Current Tue May 10 17:23:14 2016 WebTalk Log File Current Tue May 10 17:23:31 2016 Date Generated: 05/10/2016 - 17:23:36
  • 16. FIR Filters with FPGA Page | 16 Main Wrapper //********************** sacred header //********************** module vProj_fir_25_6( input wire CCLK, // 50 MHz/20 ns SPIMISO, //Master In, Slave Out BTN_EAST, // get sample BTN_NORTH, // reset BTN_WEST, // set preamp gain = -1 input [3:0] SW, output wire SPIMOSI, SPISCK, AMPSD, AMPCS, DACCS, DACCLR, ADCONV, sfCEbar, fpgaINITb, J4a, J4b, J4c, J4d, output [7:0] LED ); //********************** sacred variables parameter ONE = 1'b1, ZERO = 1'b0; parameter sampl = 125; // set sample rate 250 = 20kHz 125 = 40kHz wire clk4, Fs, Fs_clk2, CCLK50, clk40MHz; // from clock divider Fs = 20kHz Fs_clk2 = 320kHz wire reset, start, d2a_enable; wire [3:0] gain; assign gain = SW; wire get_a2d, set_preAmp; // spi_miso, wire spiclkP, spiMosiP, // CCLK & data to preamp spiclkA, spiMosiA, // clk & data from a2d spiclkD, spiMosiD; wire [13:0] CN_Adat; //, CN_Bdat; wire [11:0] data2Write;
  • 17. FIR Filters with FPGA Page | 17 wire raw_set_preAmp; // west button to single shot // filter wrapper vars wire [13:0] a2d_out; wire [11:0] d2a_in_T; wire clk_enable; assign a2d_out = CN_Adat; assign data2Write = d2a_in_T; assign clk_enable = ONE; assign LED = { ADCONV, DACCS, data2Write[11:6] }; //************************** filter vars wire signed [15:0] filter_in; //sfix16_En15 wire signed [15:0] filter_out; //sfix36_En31 was 35 bits wire rdy, rfd; wire [2:0] AB; // ab switch for comparing in vs out signal assign AB = SW[3:1]; // test signals on S3e assign J4a = ADCONV; assign J4b = DACCS; assign J4c = Fs; assign J4d = rdy; ///************************** sacred code as above, so below // .assign spi_miso = SPIMISO; assign start = BTN_EAST; assign reset = BTN_NORTH; assign raw_set_preAmp = BTN_WEST; assign sfCEbar = ONE; //parallel flash enable lo assign fpgaINITb = ZERO; // flash enable hi assign SPIMOSI = (spiMosiP && ~AMPCS) || (spiMosiD && ~DACCS);// || spiMosiA ; // data TO SPI stuff assign SPISCK = (spiclkP && ~AMPCS) || (spiclkD && ~DACCS) || spiclkA ; // // data FROM SPI stuff wire buf_clk; BUFG bufg(.I( CCLK50 ), .O( buf_clk ) ); wire [15:0] TRIG0; assign TRIG0 = { SPIMISO, SPIMOSI, SPISCK, ADCONV, DACCS, CN_Adat[13:9], // five bits of 14 from a2d data2Write[11:7], // five bits of 12 to d2a reset };
  • 18. FIR Filters with FPGA Page | 18 // reset, set_preAmp, start, SPIMISO, // SPIMOSI, SPISCK, get_a2d, d2a_enable, // AMPSD, AMPCS, DACCS, DACCLR, ///************************** sacred code above //*************************** wire clk12MHz, buf_clk12, wrapClk; BUFG bufg12( .I( clk12MHz ), .O( clk4 ) ); BUFG bufg50( .I( CCLK50 ), .O( wrapClk ) ); /*Div4 div4( .clk( CCLK50 ), .reset( reset ), .clk4( clk4 ) ); */ // replaced with Fs_clk2 /* DivFs F_samp( // create Fs clock Fs .clk( CCLK50 ), .reset( reset ), .divisor( 10*sampl ), //2500 = 20k 1250 = 40k .clkDiv( Fs ) ); */ //********************* clk40M clk40Div ( // forty MHz generator .CLKIN_IN( CCLK ), .RST_IN( reset ), .CLKDV_OUT( clk12MHz ), // 25 MHz .CLKFX_OUT( clk40MHz ), .CLKIN_IBUFG_OUT( ), .CLK0_OUT( CCLK50 ) ); DivFs C320kHz( .clk( clk40MHz ), .reset( reset ), .divisor( 8*sampl ), // 2000 = 20kHz .clkDiv( Fs_clk2 ) ); assign Fs = Fs_clk2; //************************ SampleEnable Sammy( .clk( CCLK50 ), .clk16( clk4 ),
  • 19. FIR Filters with FPGA Page | 19 .reset( reset ), .start( start ), .fs( Fs ), .a2d_enable( get_a2d ), .d2a_enable( d2a_enable ) ); //**************************more sacred code begin //****************************************** A2D a2d ( // like RDID, only different // inputs .spi_miso ( SPIMISO ), .clk ( clk4 ), .reset ( reset ), .get_a2d ( get_a2d ), //outputs .spi_sck ( spiclkA ), .spi_mosi ( spiMosiA ), .ADCONV( ADCONV ), .CN_Adat ( CN_Adat ) // .CN_Bdat ( CN_Bdat ) ); ///************************** sacred code above preAmp PA ( // like RDID, only different .spi_miso( SPIMISO ), .clk( clk4 ), .reset ( reset ), .set_preAmp ( set_preAmp ), .gain( gain ), .spi_sck ( spiclkP ), .spi_mosi ( spiMosiP ), .AMPCS( AMPCS ), // preamp chip select, active low .AMPSD( AMPSD ) // shut down not, power on, active low ); D2A d2a( .spi_miso( SPIMISO ), // SPI read data .clk( clk4 ), .reset( reset ), .d2a_enable( d2a_enable ), .data2Write( data2Write ), // data to write input wire [15:0] .spi_sck( spiclkD ), // SPI clock .spi_mosi( spiMosiD ), // SPI Data to write .DACCS( DACCS ), // chip select, active low while sending data .DACCLR( DACCLR) // clear d2s
  • 20. FIR Filters with FPGA Page | 20 ); oneShot PreShot ( .clk( clk4 ), // wire source to wire destination .trig( raw_set_preAmp ), // reg to wire .trigOut( set_preAmp )// wire to wire ); // sign2unsign conJob( // .in( sign_dat ), // 14 bits // .data2Write( data2Write ) // 16 bits // ); //********************************** filter wrapper filter_wrapper wrap( .clk( wrapClk ), .Fs_clk2( Fs_clk2 ), .clk_enable( clk_enable ), .reset( reset ), .a2d_out( a2d_out ), .rfd( rfd ), // output rfd .rdy( rdy ), // output rdy .AB( AB ), .d2a_in( d2a_in_T ) // transfers a2d_out to d2a_in_T ); endmodule Digital to Analog Converter (like RDID, only different // SPI Master for the ST MicroM25P16 Serial Flash `default_nettype none module D2A( input wire spi_miso, // SPI read data input wire clk, input wire reset, // Active high input wire d2a_enable, input wire [11:0] data2Write, // data to write output reg spi_sck, // SPI clock output wire spi_mosi, // SPI Data to write output reg DACCS, // chip select, active low while sending gain command output wire DACCLR // clear d2s );
  • 21. FIR Filters with FPGA Page | 21 reg [2:0] cs_d2a, ns_d2a; reg [4:0] send_count; reg [4:0] get_count; reg enable_get_count, enable_send_count; reg mosi_enable; reg assert_DACCS; wire [31:0] data_word; // command to turn on d2a, create wave parameter [4:0] SEND_COUNT_MAX = 5'h1F; //----------------------------------------- was 24/17 // parameter [4:0] GET_COUNT_MAX = 5'h18; parameter [2:0] IDLE = 3'b000, SET_CS = 3'b001, sendInstruct = 3'b10, //getDATA = 3'b011, Clr_DAC_CS = 3'b100; parameter ONE = 1'b1; parameter ZERO = 1'b0; parameter ZZ = 1'bz; assign DACCLR = ONE; assign data_word = { 8'h00, 4'b0010, 4'b1111, data2Write, 4'h0 }; // 8 + 4 + 4 + 12 + 4 = 32 bits /////////////////////////////////////////////////////////// added eight bits of zero always @ ( * ) begin // Defaults ns_d2a = IDLE; enable_send_count = ZERO; // enable_get_count = 1'b0; assert_DACCS = ZERO; mosi_enable = ZERO; case (cs_d2a) // Remain in idle until told to send data IDLE: begin if ( d2a_enable ) ns_d2a = SET_CS; else ns_d2a = IDLE; mosi_enable = ZERO; //else assert_DACCS = ZERO; end // Assert chip select in its own state to meet chip select assertion setup time SET_CS: begin
  • 22. FIR Filters with FPGA Page | 22 ns_d2a = sendInstruct; assert_DACCS = ONE; end // Provide clocks to d2a_enable the instructions sendInstruct: begin enable_send_count = ONE; assert_DACCS = ONE; mosi_enable = ONE; if ( send_count == 0 ) ns_d2a = Clr_DAC_CS; else ns_d2a = sendInstruct; end // Deassert chip select in its own state to meet chip select deassertion setup time Clr_DAC_CS: begin ns_d2a = IDLE; assert_DACCS = ZERO; enable_send_count = ZERO; mosi_enable = ZERO; end endcase end // Need a register so the chip select don't glitch always @(posedge clk or posedge reset) begin if ( reset ) DACCS <= ONE; else if ( assert_DACCS ) DACCS <= ZERO; else DACCS <= ONE; end // Current state gets next state at the positive edge of the clock always @(posedge clk or posedge reset) begin if ( reset ) cs_d2a <= IDLE; else cs_d2a <= ns_d2a; end // maintain a count of the spi_sck's we've provided sending always @(posedge clk or posedge reset) begin
  • 23. FIR Filters with FPGA Page | 23 if ( reset ) send_count <= SEND_COUNT_MAX; // Reset counter every time we're asked to get the ID again. else if ( d2a_enable ) send_count <= SEND_COUNT_MAX; else if ( enable_send_count && spi_sck) send_count <= send_count - 1'b1; end // maintain a count of the spi_sck's /* always @(posedge clk or posedge reset) begin if ( reset ) get_count <= GET_COUNT_MAX; // Reset counter every time we're asked to get the ID again. else if ( d2a_enable ) get_count <= GET_COUNT_MAX; else if (enable_get_count && !spi_sck) get_count <= get_count - ONE; end */ // Collect read_data /* always @(posedge clk or posedge reset) begin //************************************* // always @(negedge clk or posedge reset) begin if (reset) read_data <= 24'b0; else if (enable_get_count && !spi_sck) read_data[get_count-1] <= spi_miso; end */ // Toggle spi_sck. Need a register so the clock doesn't glitch always @(posedge clk or posedge reset) begin if (reset) spi_sck <= ZERO; else if (enable_send_count) // || enable_get_count) spi_sck <= !spi_sck; else if ( d2a_enable ) spi_sck <= ZERO; else spi_sck <= ZERO; end // spi-mosi is just an index into the data_word vector assign spi_mosi = data_word[send_count] && mosi_enable; //synopsys translate_off reg [95:0] ASCII_csd2a, ASCII_nsd2a; // Hold 12 characters (8*12=96)
  • 24. FIR Filters with FPGA Page | 24 always @* begin case (cs_d2a) IDLE: ASCII_csd2a = "IDLE"; SET_CS: ASCII_csd2a = "SET_CS"; sendInstruct: ASCII_csd2a = "sendInstruct"; // getDATA: ASCII_csd2a = "getDATA"; Clr_DAC_CS: ASCII_csd2a = "Clr_DAC_CS"; endcase end always @* begin case (ns_d2a) IDLE: ASCII_nsd2a = "IDLE"; SET_CS: ASCII_nsd2a = "SET_CS"; sendInstruct: ASCII_nsd2a = "sendInstruct"; // getDATA: ASCII_nsd2a = "getDATA"; Clr_DAC_CS: ASCII_nsd2a = "Clr_DAC_CS"; endcase end //synopsys translate_on endmodule /* D2A your_name_here( .spi_miso( spi_miso ), // SPI read data .clk( clk ), .reset( reset ), .d2a_enable( d2a_enable ), .data2Write( data2Write ), // data to write input wire [15:0] .spi_sck( spi_sck ), // SPI clock .spi_mosi( spi_mosi ), // SPI Data to write .DACCS( DACCS ), // chip select, active low while sending gain command .DACCLR( DACCLR) // clear d2s ); */ Second Wrapper Instantiates the filters. module Second_wrapper( input clk, // 50 MHz clk320, // nominal sample freq x 16
  • 25. FIR Filters with FPGA Page | 25 clk_enable, reset, output wire rdylp, rfdlp, input wire [2:0] AB, input wire signed [15:0] filter_in_16, //output reg signed [15:0] filter_out_16LP, //output reg signed [15:0] filter_out_16HP, //output reg signed [15:0] filter_out_16BP, output reg signed [15:0] filter_out_16 ); parameter outMSB_LP = 40; // fir41 fir40 is 37; parameter outMSB_HP = 37; // fir41 fir40 is 37; parameter outMSB_BP = 39; parameter outMSB_HPlong = 41; parameter outMSB_HPshort = 42; wire ndL, ndH, ndB, ndHl; assign ndL = 1'b1; //(AB == 2'b11); assign ndH = 1'b1; //(AB == 2'b10); assign ndB = 1'b1; //(AB == 2'b01); assign ndHl = 1'b1; //(AB == 2'b01); wire rdyhp, rfdhp, rfdHl; wire rdybp, rfdbp, rdyHl; wire signed [15:0] filter_in_16LP; wire signed [15:0] filter_in_16HP; wire signed [15:0] filter_in_16BP; wire signed [15:0] filter_in_16HPlong; assign filter_in_16LP = filter_in_16; assign filter_in_16HP = filter_in_16; assign filter_in_16BP = filter_in_16; assign filter_in_16HPlong = filter_in_16; wire signed [outMSB_LP:0] firLP; wire signed [outMSB_HP:0] firHP; wire signed [outMSB_BP:0] firBP; wire signed [outMSB_HPlong:0] firHPlong; wire signed [outMSB_HPshort:0] firHPshort; wire signed [39:0] HP10c; always @ ( * ) begin case( AB ) 3'b000: // IN >> OUT
  • 26. FIR Filters with FPGA Page | 26 filter_out_16 = filter_in_16; 3'b110: begin // LP 100 / 300 hZ filter_out_16 = firLP[ outMSB_LP : outMSB_LP-15 ];// << 2; filter_out_16 = filter_out_16 << 4; end 3'b100: begin // LP 2K / 3kHz filter_out_16 = firHP[ outMSB_HP : outMSB_HP-15 ];// << 2; filter_out_16 = filter_out_16 << 4; end 3'b010: begin // IN >> OUT filter_out_16 = firBP[ outMSB_BP : outMSB_BP-15 ];// << 2; filter_out_16 = filter_out_16 << 4; end //************************** 3'b001: begin filter_out_16 = firHPlong[ outMSB_HPlong : outMSB_HPlong-15 ];// << 2; filter_out_16 = filter_out_16 << 4; end 3'b011: begin filter_out_16 = firHPshort[ outMSB_HPshort : outMSB_HPshort-15 ];// << 2; filter_out_16 = filter_out_16 << 4; end 3'b111: begin filter_out_16 = HP10c[39:39-15];// << 2; filter_out_16 = filter_out_16 << 4; end endcase end // always Fir_BP BP_15c2k_4k5_40kHz ( // BP_15c2k_4k5_40kHz 1500 2000 4K 5K SWITCH 010 .clk(clk), // input clk .nd( ndB ), // input nd .rfd( rfdbp ), // output rfd .rdy( rdybp ), // output rdy .din( filter_in_16BP ), // input [15 : 0] din .dout( firBP ) ); // output [39 : 0] dout Fir41 Fir_41_LP ( // LP1c_3c_284stage_40kHz_40.coe 100 -- 300 40:0 SWITCH 110 .clk( clk ), // input clk .nd( ndL ), // input nd .rfd( rfdlp ), // output rfd
  • 27. FIR Filters with FPGA Page | 27 .rdy( rdylp ), // output rdy .din( filter_in_16LP ), // input [15 : 0] din .dout( firLP ) ); // output [34 : 0] dout FIR40 Fir2_3k ( // Fir2_3__40kHz57stage.coe 2000 -- 3000 LP SWITCH 100 .clk( clk ), // input clk .nd( ndH ), // input nd .rfd( rfdhp ), // output rfd .rdy( rdyhp ), // output rdy .din( filter_in_16HP ), // input [15 : 0] din .dout( firHP ) ); // output [34 : 0] dout HP_90_120_2836stage HP_120Hz ( //HP1c_2836stage_40kHz.coe 100Hz HP // SWITCH 001 .clk( clk ), // input clk .nd( ndHl ), // input nd .rfd( rfdHl ), // output rfd .rdy( rdyHl ), // output rdy .chan_out(chan_out), // output [2 : 0] chan_out .din( filter_in_16HPlong ), // input [15 : 0] din .dout( firHPlong ) ); // output [40 : 0] dout HP1000 HPTencElevenc ( .clk( clk ), // input clk .nd( ndHl ), .rfd( ), // output rfd .rdy( ), // output rdy .din( filter_in ), // input [15 : 0] din .dout( HP10c ) // output [41 : 0] dout ); HP1702 HP_200Hz ( // HP150_200_1702stage .clk( clk ), // input clk .nd( ndHl ), .rfd( ), // output rfd .rdy( ), // output rdy .din( filter_in_16 ), // input [15 : 0] din .dout( firHPshort )); // output [42 : 0] dout endmodule