Chapter 9

Digital Filters

Abstract

An important part of digital or computing systems that interface to the “real /world” of sensors and analog interfaces is the ability to process sampled data in the digital domain. This is often called Sampled Data Systems (SDS) or defined as operating in the Z-domain. Most engineers are familiar with the operation of filters in the Laplace or S-domain where a continuous function defines the characteristics of the filter and this is the digital domain equivalent to that.

Keywords

Digital filters

Sample data systems

Z domain

9.1 Introduction

An important part of digital or computing systems that interface to the “real/world” of sensors and analog interfaces is the ability to process sampled data in the digital domain. This is often called Sampled Data Systems (SDS) or defined as operating in the Z-domain. Most engineers are familiar with the operation of filters in the Laplace or S-domain where a continuous function defines the characteristics of the filter and this is the digital domain equivalent to that.

For example, consider a simple RC circuit in the analog domain, which is designed to be a low pass filter, as shown in Figure 9.1.

f09-01-9780080971292
Figure 9.1 RC filter in the analog domain.

This has a low pass filter behavior and can be represented mathematically using the continuous Laplace (or S-domain) notation:

L(s)=11+sRC

si1_e  (9.1)

This function is a low pass filter because the Laplace operator s is equivalent to , where ω = 2πf (with f being the frequency). If f is zero (the d.c. condition), then the gain will be 1, but if the value of sRC is equal to 1, then the gain will be 0.5. This in dB is −3 dB and is the classical low pass filter cut-off frequency.

In the digital domain, the s operation is replaced by Z. Z−1 is equivalent in a practical sense to a delay operator, and similar functions to the Laplace filter equations can be constructed for the digital, or Z domain, equivalent.

There are a number of design techniques, many beyond the scope of this book (if the reader requires a more detailed introduction to the realm of digital filters, Cunningham’s Digital Filtering: An Introduction is a useful starting point); however, it is useful to introduce some of the basic techniques used in practice and illustrate them with examples.

The remainder of this chapter will cover the introduction to the basic techniques and then demonstrate how these can be implemented using VHDL and Verilog on FPGAs.

9.2 Converting S Domain to Z Domain

The method of converting an S domain equation for a filter to its equivalent Z domain expression uses the bilinear transform. This is a standard method for expressing the S-domain equation in the Z-domain. The basic approach is to replace each instance of s with its equivalent Z domain notation and then rearrange into the most convenient form. The transform is called bilinear as both the numerator and denominator of the expression are linear in terms of z.

s=z1z+1

si2_e  (9.2)

If we take a simple example of a basic second order filter we can show how this is translated into the equivalent Z domain form:

H(s)=1s2+2s+1

si3_e  (9.3)

In order to get the function H(s) in its Z-domain equivalent, replace each occurrence of s with the expression for s in terms of z shown in Equation (9.2), giving:

H(z)=1(z1z+1)2+2(z1z+1)+1

si4_e  (9.4)

H(z)=(z+1)2(z1)2+(z1)(z+1)+(z+1)2

si5_e  (9.5)

H(z)=z2+2z+13z2+1

si6_e  (9.6)

Now, the term H(z) is really the output Y (z) over the input X(z) and we can use this to express the Z domain equation in terms of the input and output:

H(z)=z2+2z+13z2+1=Y(z)X(z)

si7_e  (9.7)

This can then be turned into a sequence expression using delays (z is one delay, z2 is two delays and so on) with the following result:

3z2Y(z)+Y(z)=z2X(z)+2zX(z)+X(z)

si8_e  (9.8)

3y(n+2)+y(n)=x(n+1)+2x(n+1)+x(n)

si9_e  (9.9)

This is useful because we are now expressing the Z domain equation in terms of delay terms, and the final step is to express the value of y(n) (the current output) in terms of past elements by reducing the delays accordingly (by 2 in this case):

3y(n)+y(n2)=x(n)+2x(n1)+x(n2)

si10_e  (9.10)

y(n)+1/3y(n2)=1/3x(n)+2/3x(n1)+1/3x(n2)

si11_e  (9.11)

y(n)=1/3x(n)+2/3x(n1)+1/3x(n1)1/3y(n2)

si12_e  (9.12)

The final design note at this point is to make sure that the design frequency is correct, for example the low pass cut-off frequency. The frequencies are different between the S and Z domain models, even after the bilinear transformation, and in fact the desired digital domain frequency must be translated into the equivalent s domain frequency using a technique called prewarping. This simple step translates the frequency from one domain to the other using the following expression:

ωc=tanΩcT2

si13_e  (9.13)

where Ωc is the digital domain frequency, T is the sampling period of the Z domain system and ωc is the resulting frequency for the analog domain calculations.

Once we have obtained our Z domain expressions, how do we turn this into practical designs? The next section will explain how this can be achieved in VHDL.

9.3 Implementing Z Domain Functions in VHDL

9.3.1 Introduction

Z domain functions are essentially digital in the time domain as they are discrete and sampled. The functions are also discrete in the amplitude axis, as the variables or signals are defined using a fixed number of bits in a real hardware system; whether this is integer, signed, fixed point, or floating point, there is always a finite resolution to the signals. For the remainder of this chapter, signed arithmetic is assumed for simplicity and ease of understanding. This also essentially defines the number of bits to be used in the system. If we have 8 bits, the resolution is 1 bit and the range is −128 to +127.

9.3.2 Gain Block

The first main Z domain block is a simple gain block. This requires a single signed input, a single signed output and a parameter for the gain. This could be an integer or also a signed value. The VHDL model for a simple Z domain gain block is given as:

1 library ieee;

2 use ieee . numeric_std . all;

4 entity zgain is

5 generic (n : integer := 8;

6   gain : signed

7  );

8 port (

9   zin : in signed (n −1 downto 0);

10   zout : out signed (n −1 downto 0)

11 );

12 end entity zgain;

13 

14 architecture zdomain of zgain is

15 begin

16 p1 : process (zin)

17   variable product : signed (2* n −1 downto 0);

18 begin

19   product := zin * gain;

20   zout <= product (n −1 downto 0);

21 end process p1;

22 end architecture zdomain;

We can test this with a simple testbench that ramps up the input and we can observe the output being changed in turn:

1 library ieee;

2 use ieee . std_logic_1164 . all;

3 use ieee . numeric_std . all;

5 entity tb is

6 end entity tb;

8 architecture testbench of tb is

10 signal clk : std_logic := ’0’;

11 signal dir : std_logic := ’0’;

12 signal zin : signed (7 downto 0):= X ” 00 ”;

13 signal zout : signed (7 downto 0):= X ” 00 ”;

14 

15 component zgain

16 generic (

17   n : integer := 8;

18   gain : signed := X ” 02 ”

19 );

20 port (

21   signal zin : in signed (n −1 downto 0);

22   signal zout : out signed (n −1 downto 0)

23 );

24 end component;

25 for all : zgain use entity work . zgain;

26 

27 

28 begin

29 clk <= not clk after 1 us;

30 

31 DUT : zgain generic map (8, X ” 02 ”) port map (zin, zout);

32 

33 p1 : process (clk)

34 begin

35   zin <= zin + 1;

36 end process p1;

37 end architecture testbench;

Clearly, this model has no error checking or range checking and the obvious problem with this type of approach is that of overflow. For example, if we multiply the input (64) by a gain of 2, we will get 128, but that is the sign bit, and so the result will show −128! This is an obvious problem with this simplistic model and care must be taken to ensure that adequate checking takes place in the model.

9.3.3 Sum and Difference

Using this same basic approach, we can create sum and difference models which are also essential building blocks for a Z domain system. The sum model VHDL is shown here:

1 library ieee;

2 use ieee . numeric_std . all;

4 entity zsum is

5 generic (n : integer := 8

6  );

7 port (

8   zin1 : in signed (n −1 downto 0);

9   zin2 : in signed (n −1 downto 0);

10   zout : out signed (n −1 downto 0)

11  );

12 end entity zsum;

13 

14 architecture zdomain of zsum is

15 begin

16 p1 : process (zin)

17   variable zsum : signed (2* n −1 downto 0);

18 begin

19   zsum := zin1 + zin2;

20   zout <= zsum (n −1 downto 0);

21 end process p1;

22 end architecture zdomain;

Despite the potential for problems with overflow, both of the models shown have the internal variable that is twice the number of bits required, and so this can take care of any possible overflow internal to the model, and in fact checking could take place prior to the final assignment of the output to ensure the data is correct. The difference model is almost identical to the sum model except that the difference of zin1 and zin2 is computed.

9.3.4 Division Model

A useful model for scaling numbers simply in the Z domain is the division by 2 model. This model simply shifts the current value in the input to the right by one bit, hence giving a division by 2. The model could easily be extended to shift right by any number of bits, but this simple version is very useful by itself. The VHDL for the model relies on the logical shift right operator (SRL) which not only shifts the bits right (losing the least significant bit) but adds a zero at the most significant bit. The resulting VHDL is shown for this specific function:

1 zout <= zin srl 1;

The unit shift can be replaced by any integer number to give a shift of a specific number of bits. For example, to shift right by 3 bits (effectively a divide by 8) would have the following VHDL:

1 zout <= zin srl 3;

The complete division by 2 model is given here:

1 library ieee;

2 use ieee . numeric_std . all;

4 entity zdiv2 is

5 generic (n : integer := 8

6  );

7 port (

8   zin : in signed (n −1 downto 0);

9   zout : out signed (n −1 downto 0)

10  );

11  end entity zdiv2;

12 

13 architecture zdomain of zdiv2 is

14 begin

15 zout <= zin srl 1;

16 end architecture zdomain;

In order to test the model a simple test circuit that ramps up the input is used and this is given as follows:

1 library ieee;

2 use ieee . numeric_std . all;

4 entity zdiv2 is

5 generic (n : integer := 8

6  );

7 port (

8   zin : in signed (n −1 downto 0);

9   zout : out signed (n −1 downto 0)

10  );

11  end entity zdiv2;

12 

13  architecture zdomain of zdiv2 is

14  begin

15  zout <= zin srl 1;

16  end architecture zdomain;

The behavior of the model is useful to review. If the input is X03 (Decimal 3), binary 00000011 and the number is right shifted by one, then the resulting binary number will be 00000001 (X01 or decimal 1); in other words this operation always rounds down. This has obvious implications for potential loss of accuracy and the operation is skewed downward, which has, again, implications for how numbers will be treated using this operator in a more complex circuit.

9.3.5 Unit Delay Model

The final basic model is the unit delay model (zdelay). This has a clock input (clk) using a std_logic signal to make it simple to interface to standard digital controls. The output is simply a one clock cycle delayed version of the input.

Notice that the output zout is initialized to all zeros for the initial state; otherwise don’t care conditions can result that propagate across the complete model.

1 library ieee;

2 use ieee . std_logic_1164 . all;

3 use ieee . numeric_std . all;

5 entity zdelay is

6 generic (n : integer := 8);

7 port (

8   clk : in std_logic;

9   zin : in signed (n −1 downto 0);

10   zout : out signed (n −1 downto 0) := (others => 0)

11  );

12  end entity zdelay;

13 

14  architecture zdomain of zdelay is

15  signal lastzin : signed (n −1 downto 0) := (others => ’0’);

16  begin

17  p1 : process (clk)

18  begin

19    if rising_edge (clk) then

20    zout <= lastzin;

21    lastzin <= zin;

22    end if;

23  end process p1;

24  end architecture zdomain;

9.4 Basic Low Pass Filter Model

We can put these elements together in simple models that implement basic filter blocks in any configuration we require, as always taking care to ensure that overflow errors are checked for in practice.

To demonstrate this, we can implement a simple low pass filter using the basic block diagram shown in Figure 9.2.

f09-02-9780080971292
Figure 9.2 Simple Z domain low pass filter.

We can create a simple test circuit that uses the individual models we have already shown for the sum and delay blocks and apply a step change and observe the response of the filter to this stimulus. Clearly, in this case, with unity gain the filter exhibits positive feedback and so to ensure the correct behavior we use the divide by 2 model zdiv2 in both the inputs to the sum block to ensure gain of 0.5 on both. These are not shown in the figure. The resulting VHDL model is shown in the following code (note the use of the zdiv2 model):

1 library ieee;

2 use ieee . std_logic_1164 . all;

3 use ieee . numeric_std . all;

5 entity tb is

6 end entity tb;

8 architecture testbench of tb is

10 signal clk : std_logic := ’0’;

11 signal x : signed (7 downto 0):= X ” 00 ”;

12 signal y : signed (7 downto 0):= X ” 00 ”;

13 signal y1 : signed (7 downto 0):= X ” 00 ”;

14 signal yd : signed (7 downto 0):= X ” 00 ”;

15 signal yd2 : signed (7 downto 0):= X ” 00 ”;

16 signal x2 : signed (7 downto 0):= X ” 00 ”;

17 

18 component zsum

19 generic (

20   n : integer := 8

21 );

22 port (

23   signal zin1 : in signed (n −1 downto 0);

24   signal zin2 : in signed (n −1 downto 0);

25   signal zout : out signed (n −1 downto 0)

26  );

27  end component;

28  for all : zsum use entity work . zsum;

29 

30 component zdiff

31 generic (

32   n : integer := 8

33  );

34 port (

35   signal zin1 : in signed (n −1 downto 0);

36   signal zin2 : in signed (n −1 downto 0);

37   signal zout : out signed (n −1 downto 0)

38  );

39 end component;

40 for all : zdiff use entity work . zdiff;

41 

42 component zdiv2

43 generic (

44   n : integer := 8

45  );

46 port (

47   signal zin : in signed (n −1 downto 0);

48   signal zout : out signed (n −1 downto 0)

49  );

50 end component;

51 for all : zdiv2 use entity work . zdiv2;

52 

53 component zdelay

54 generic (

55   n : integer := 8

56  );

57 port (

58   signal clk : in std_logic;

59   signal zin : in signed (n −1 downto 0);

60   signal zout : out signed (n −1 downto 0)

61  );

62 end component;

63 for all : zdelay use entity work . zdelay;

64 

65 begin

66 clk <= not clk after 1 us;

67 

68 GAIN1 : zdiv2 generic map (8) port map (x, x2);

69 GAIN2 : zdiv2 generic map (8) port map (yd, yd2);

70 SUM1 : zsum generic map (8) port map (x2, yd2, y);

71 D1 : zdelay generic map (8) port map (clk, y, yd);

72 

73 x <= X ” 00 ”, X ” 0 F ” after 10 us;

74 end architecture testbench;

The test circuit applies a step change of X00 to X0F after 10 μs, and this results in the filter response. We can show this graphically in Figure 9.3 with the output in both hexadecimal and analog form for illustration.

f09-03-9780080971292
Figure 9.3 Basic low pass filter simulation waveforms.

It is interesting to note the effect of using the zdiv2 function on the results. With the input of 0F (binary 00001111) we lose the LSB when we divide by 2, giving the resulting input to the sum block of 00000111 (7) which added together with the division of the output gives a total of 14 as the maximum possible output from the filter. In fact, the filter gives an output of X0D or binary 00001101, which is two down from the theoretical maximum of X0F and this highlights the practical difficulties when using a coarse approximation technique for numerical work rather than a fixed or floating point method. On the other hand, it is clearly a simple and effective method of implementing a basic filter in VHDL.

Later in this book, the use of fixed and floating point numbers are discussed, as is the use of multiplication for more exact calculations and for practical filter design; where higher accuracy is required, then it is likely that both these methods would be used. There may be situations, however, where it is simply not possible to use these advanced techniques, particularly a problem when space is at a premium on the FPGA and, in these cases, the simple approach described in this chapter will be required.

There are numerous texts on more advanced topics in digital filter design, and these are beyond the scope of this book, but it is useful to introduce some key concepts at this stage of the two main types of digital filter in common usage today. These are the recursive (or Infinite Impulse Response, IIR) filters and nonrecursive (or Finite Impulse Response, FIR) filters.

9.5 Implementing Z Domain Functions in Verilog

9.5.1 Gain Block

The first main Z domain block is a simple gain block. This requires a single signed input, a single signed output and a parameter for the gain. This could be an integer or also a signed value. The Verilog model for a simple Z domain gain block is given as follows:

1 module zgain (

2 din, // Digital Input

3 dout // Digital Output

4  );

6 parameter n = 8; // Width of Digital Input and Output

7 parameter gain = 1; // Gain Parameter

9 input [ n −1:0] din;

10 output [2*n−1:0] dout;

11 

12 wire signed [n−1:0] din;

13 reg signed [2*n−1:0] dout;

14 

15 always @ (din)

16 begin

17 dout <= din * gain;

18 end

19 

20 endmodule

Clearly, as with the VHDL model, this model has no error checking or range checking and the obvious problem with this type of approach is that of overflow. For example, in an 8-bit model, if we multiply the input (64) by a gain of 2, we will get 128, but that is the sign bit, and so the result will show −127! This is an obvious problem with this simplistic model and care must be taken to ensure that adequate checking takes place in the model.

We can test the model by using a simple test bench that has a lookup table to generate a sine wave which will go from −127 to +127, and the gain can be varied using the parameter of the gain block. The number of bits in the gain block defaults to the parameter n value (default is 8) and the output is 2 * n. This makes the assumption that the gain will be no larger than the input value maximum, and this should obviously be checked thoroughly in a practical model to avoid the possibility of overflow errors occurring. The test bench Verilog is shown here:

1 module zsine_tb ();

2 // declare the counter signals

3 reg clk;

4 reg signed [7:0] zvalue;

5 reg rst;

7 wire signed [15:0] gvalue;

8 // Set up the initial variables and reset

9 initial begin

10 $display (” time t clk zvalue ”);

11 $monitor (” % g t % b % d ”,

12 $time, clk, zvalue);

13 clk = 1;   // initialize the clock to 1

14 rst = 1;  // set the reset to 1 (not reset)

15 #5 rst = 0;  // reset = 0 : resets the counter

16 #10 rst = 1;  // reset back to 1 : counter can start

17 #5 zvalue = 0;

18 #5 zvalue = 22;

19 #5 zvalue = 44;

20 #5 zvalue = 64;

21 #5 zvalue = 82;

22 #5 zvalue = 98;

23 #5 zvalue = 111;

24 #5 zvalue = 120;

25 #5 zvalue = 126;

26 #5 zvalue = 127;

27 #5 zvalue = 126;

28 #5 zvalue = 120;

29 #5 zvalue = 111;

30 #5 zvalue = 98;

31 #5 zvalue = 82;

32 #5 zvalue = 64;

33 #5 zvalue = 44;

34 #5 zvalue = 22;

35 #5 zvalue = 0;

36 #5 zvalue = −22;

37 #5 zvalue = −44;

38 #5 zvalue = −64;

39 #5 zvalue = −82;

40 #5 zvalue = −98;

41 #5 zvalue = −111;

42 #5 zvalue = −120;

43 #5 zvalue = −126;

44 #5 zvalue = −127;

45 #5 zvalue = −126;

46 #5 zvalue = −120;

47 #5 zvalue = −111;

48 #5 zvalue = −98;

49 #5 zvalue = −82;

50 #5 zvalue = −64;

51 #5 zvalue = −44;

52 #5 zvalue = −22;

53 #5 zvalue = 0;

54 #1000 $finish;  // Finish the simulation

55 end

56 

57 // Clock generator

58 always begin

59 #5 clk = ˜clk; // Clock every 5 time slots

60 end

61 

62 zgain #(8,2) a1(zvalue, gvalue);

63 

64 endmodule

When the model was simulated with a gain of 2, n = 8, the output values can be seen in Figure 9.4 to exactly double the input values, and as the gain block sensitivity is on the input, the change is immediate (unlike a synchronous model which would only change on the clock edge). The waveforms are shown in Figure 9.4.

f09-04-9780080971292
Figure 9.4 Z gain simulation test with gain = 2.

When the gain is reversed to − 2, the output has the same amplitude as before, but now the output is inverted, and this can easily be seen to be correct in the waveform diagram in Figure 9.5.

f09-05-9780080971292
Figure 9.5 Z gain simulation test with gain = −2.

9.5.2 Sum and Difference

Using this same basic approach, we can create sum and difference models which are also essential building blocks for a Z domain system. The sum model Verilog is shown here:

1 module zsum (

2 din1, // Digital Input 1

3 din2, // Digital Input 2

4 dout // Digital Output

5  );

7 parameter n = 8; // Width of Digital Input and Output

9 input [ n −1:0] din1;

10 input [n−1:0] din2;

11 output [2*n−1:0] dout;

12 

13 wire signed [n−1:0] din1;

14 wire signed [n−1:0] din2;

15 reg signed [2*n−1:0] dout;

16 

17 always @ (din1 or din2)

18 begin

19 dout <= din1 + din2;

20 end

21 

22 endmodule

Despite the potential for problems with overflow, both of the models shown have the internal variable that is twice the number of bits required, and so this can take care of any possible overflow internal to the model, and in fact checking could take place prior to the final assignment of the output to ensure the data is correct. The difference model is almost identical to the sum model except that the difference of din1 and din2 is computed.

1 module zdiff (

2 din1, // Digital Input 1

3 din2, // Digital Input 2

4 dout // Digital Output

5  );

7 parameter n = 8; // Width of Digital Input and Output

9 input [ n −1:0] din1;

10 input [n−1:0] din2;

11 output [2*n−1:0] dout;

12 

13 wire signed [n−1:0] din1;

14 wire signed [n−1:0] din2;

15 reg signed [2*n−1:0] dout;

16 

17 always @ (din1 or din2)

18 begin

19 dout <= din1 − din2;

20 end

21 

22 endmodule

9.5.3 Unit Delay Model

The final basic model is the unit delay model (zdelay). This has a clock input (clk) and a reset (rst) signal to make it simple to interface to standard digital controls. The output is simply a one clock cycle delayed version of the input.

Notice that the output dout is initialized to all zeros for the initial state, otherwise don’t care conditions can result that propagate across the complete model.

1 module zdelay (

2 clk, // clock input

3 rst, // reset input

4 din, // Digital Input

5 dout // Digital Output

6 );

8 parameter n = 8; // Width of Digital Input and Output

10 input clk;

11 input rst;

12 input [n−1:0] din;

13 output [n−1:0] dout;

14 

15 reg [n−1:0] dout;

16 

17 reg [n−1:0] dstored;

18 

19 always @ (posedge clk)

20 begin

21 if (rst == 0 ) begin

22  dout <= 0;

23  dstored <= 0;

24 end

25 else begin

26  dout <= dstored;

27  dstored <= din;

28 end

29 end

30 

31 endmodule

The model was tested using a basic test bench as shown below to illustrate how the simple delay operates:

1 module zdelay_tb ();

2 // declare the counter signals

3 reg clk;

4 reg signed [7:0] zvalue;

5 reg rst;

7 wire signed [7:0] gvalue;

8 // Set up the initial variables and reset

9 initial begin

10 $display (” time t clk zvalue ”);

11 $monitor (” % g t % b %d”,

12 $time, clk, zvalue);

13 clk = 1;  // initialize the clock to 1

14 rst = 1;  // set the reset to 1 (not reset)

15 #5 rst = 0;  // reset = 0 : resets the counter

16 #10 rst = 1;  // reset back to 1 : counter can start

17 #10 zvalue = 23;

18 #10 zvalue = 54;

19 #10 zvalue = 12;

20 #1000 $finish;  // Finish the simulation

21 end

22 

23 // Clock generator

24 always begin

25 $mbox{#}$5 clk = ˜clk; // Clock every 5 time slots

26 end

27 

28 zdelay $mbox{#}$(8) a1(clk, rst, zvalue, gvalue);

29 

30 endmodule

The resulting behavior can clearly be seen in Figure 9.6.

f09-06-9780080971292
Figure 9.6 Z delay simulation.

Later in this book, the use of fixed and floating point numbers are discussed, as is the use of multiplication for more exact calculations and for practical filter design, where higher accuracy is required, it is likely that both these methods would be used. There may be situations, however, where it is simply not possible to use these advanced techniques, particularly a problem when space is at a premium on the FPGA; in these cases, the simple approach described in this chapter will be required.

There are numerous texts on more advanced topics in digital filter design, and these are beyond the scope of this book, but it is useful to introduce some key concepts at this stage of the two main types of digital filter in common usage today. These are the recursive (or Infinite Impulse Response, IIR) filters and nonrecursive (or Finite Impulse Response, FIR) filters.

9.6 Finite Impulse Response Filters

Finite impulse response (FIR) filters are characterized by the fact that they use only delayed versions of the input signal to filter the input to the output. For example, if we take the expression for a general FIR filter below, we can see that the output is a function of a series of delayed, scaled versions of the input:

y=i=0nAix[i]

si14_e  (9.14)

where Ai is the scale factor for the ith delayed version of the input. We can represent this graphically in the diagram shown in Figure 9.7. We can implement this model using the basic building blocks described in this chapter of gain, division, sums and delays to develop block based models for such filters. As noted in the previous section, it is important to ensure that for higher accuracy filters, fixed or floating point arithmetic is required and also the use of multipliers for added accuracy is preferable in most cases to that of simple gain and division blocks as described previously in this chapter.

f09-07-9780080971292
Figure 9.7 FIR filter schematic.

9.7 Infinite Impulse Response Filters

Infinite impulse response (IIR) filters are characterized by the fact that they use delayed versions of the input signal and fed-back and delayed versions of the output signal to filter the input to the output. For example, if we take the expression for a general IIR filter below, we can see that the output is a function of a series of delayed, scaled versions of the input and output.

y=i=0nAix[i]Biy[i]

si15_e  (9.15)

where Ai is the scale factor for the ith delayed version of the input and Bi is the scale factor for the ith delayed version of the output. This is obviously very similar to the FIR example previously given and can be built up using the same basic elements. If we consider the simple example earlier in this chapter, it can be seen that this is in fact a simple first order (single delay) IIR filter, with no delayed versions of the input and a single delayed version of the output.

9.8 Summary

This chapter has introduced the concepts of implementing basic digital filters and Z-domain functions in VHDL and Verilog and has given examples of both the building blocks and constructed filters for implementation on an FPGA platform. The general concepts of FIR and IIR filters have been introduced so that the reader can implement the topology and type of filter appropriate for their own application. A detailed treatise on filters is beyond the scope of this book and the reader is referred to one of the many digital filter design texts available for a more in-depth analysis of the topic.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.175.182