User:Akshay.mistry/ENES-100/shakeman

=Problem= We are now living in an age of Information Technology; most of information technology is based on DSP( digital signal processing). Telecommunication, speech processing, consumer electronics, image processing and biomedical systems are some applications of DSP. Filtering is the most common part of DSP and it is used in all the previously mentioned applications. So what are filters? filters are mainly used in signal processing to remove unwanted frequencies from an incoming signal. FIR's and IIR's are described as the two filter types found in Software Defined Radio. The goal is to build a FIR in a papilio to and figure out how they work. Ultimately the goal is to connect it to open source SDR software running in a computer. FIR's and IIR's are described as the two filter types found in Software Defined Radio. The goal is to build a FIR in a papilio to and figure out how they work. Ultimately the goal is to connect it to open source SDR software running in a computer.

=Conceive=
 * Read this FIR filter basics.
 * Read this wikipedia FIR entry
 * Read this paper up to figure 2.

=Design= <https://en.wikiversity.org/w/index.php?title=User:1sfoerster/enes245/fall2014/FIR_FPGA_SDR_filter&action=edit&section=3

Repeat this project

I will try here to design a simple FIR FPGA SSR filter; this filter will be generic and very flexible. In general, the equation to generate a simple DSP filter is given by: y[n]=∑b x[n−k] from k=0 to k=M. Based on this equation, we will need the following modules: * Multiplier * Adders * Memories: to store the filter coefficients,to store past sample values. * Control block : to coordinate the multiplier. * Address generator: to get the appropriate coefficients and delayed sample values.

First, I will use Matlab( HDL suite) to examine the frequency response of the filtering.

Next, I will write theVHDL code performing the desired filtering.

Finally I will test the VHDL code by comparing its outputs with the filter created in Matlab.

-- Creating the FIR VHDL block: Input : data_in (x[n]) data_in_ ready clk ( rising edge of the clock signal) reset

Output:  data_out ( Y[n]) data_out_ ready

entity FIR is port(    clk : in STD_LOGIC;     reset : in STD_LOGIC;    data_in : in STD_LOGIC_VECTOR(15 downto 0); data_in_ready : in std_logic;    data_out : out STD_LOGIC_VECTOR(15 downto 0); data_out_ready : out std_logic     ); end FIR;

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all;

entity tb_fir is generic(order:positive:=30; width:positive:=16); port(		clk:in std_ulogic:='0';		nRst:in std_ulogic:='0';		--u:in signed(16-1 downto 0);		y:buffer signed(16-1 downto 0)	); end entity tb_fir;

architecture rtl of tb_fir is	signal reset:std_ulogic:='0'; signal u:signed(16-1 downto 0); signal trig:std_logic; --	/* synthesis translate_off */ signal clk:std_ulogic:='0'; signal nRst:std_ulogic:='1'; --	/* synthesis translate_on */ signal count:unsigned(8 downto 0); signal pwrUpCnt:unsigned(3 downto 0):=(others=>'0'); --	/* on-chip debugger */ signal dbgSignals:std_ulogic_vector(127 downto 0):=(others=>'0'); --	/* Explicitly define all multiplications with the "*" operator to use dedicated DSP hardware multipliers. */	attribute multstyle:string; attribute multstyle of rtl:architecture is "dsp";	--altera: --	attribute mult_style:string; attribute mult_style of fir:entity is "block";		--xilinx:

begin --	/* synthesis translate_off*/ clk<=not clk after 10 ns; --	/* synthesis translate_on*/ process(pwrUpCnt,nRst) is begin if pwrUpCnt<10 or nRst='0' then reset<='1'; else reset<='0'; end if; end process; process(reset,clk) is begin if reset='1' then count<=(others =>'0'); elsif rising_edge(clk) then if count<300 then count<=count+1; end if; end if; end process; process(nRst,clk) is begin if nRst='0' then pwrUpCnt<=(others =>'0'); elsif rising_edge(clk) then if pwrUpCnt<10 then pwrUpCnt<=pwrUpCnt+1; end if; end if; end process; --	/* Impulse generator for impulse response measurement. */	u <= (0=>'1', others=>'0') when count=1 else (others=>'0'); filter: entity work.fir(rtl) generic map(order=>order, width=>width) port map(			reset=>reset,			clk=>clk, --			/* Filter ports. */			u=>u,			y=>y	); --	/* Simulation only. */ --	/* synthesis translate_off */ reporter: process(clk) is begin if rising_edge(clk) then --			/* (u,y) pairs will be exported to CSV and Matlab for plotting. --				Results are then correlated to digital simulations and Matlab --			simulations of the filter. --	*/			report ";" & integer'image(to_integer(u)) & ";" & integer'image(to_integer(y)); end if; end process reporter; process is begin assert now<5 us report "simulation stopped." severity failure; wait; end process; --	/* synthesis translate_on */ --	/* Hardware debugger (SignalTap II embedded logic analyser). */	trig<='1' when count<300 else '0';		-- Stop SignalTap Triggering after 300 counts, Total data=280 --	/* SignalTap debugger. */	dbgSignals(width-1 downto 0)<=std_ulogic_vector(u);						-- u:16bits dbgSignals(width*2-1 downto width)<=std_ulogic_vector(y);				-- y:32bits dbgSignals(8+width*2 downto width*2)<=std_ulogic_vector(count);		--9bits (300<512) ); end architecture rtl;

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all;

--/* Filter order = number of unit delays. */ entity fir is generic(order:positive:=30);	--; width:positive:=16);	port( reset:in std_ulogic;			-- asserting reset will start protocol sequence transmission. To restart the re-transmission of the sequence, re-assert this reset signal, and the whole SPI sequence will be re-transmitted again. clk:in std_ulogic:='0'; --		/* Filter ports. */		--u:in signed(width-1 downto 0):=(others=>'0'); --y:buffer signed(width-1 downto 0) u:in signed; y:buffer signed ); end entity fir;

architecture rtl of fir is --	/* Memory I/Os: */ --	signal q:signed(width-1 downto 0):=(others=>'0'); signal q:signed(u'range); --signal rst: std_ulogic; --signal pwrUpCnt: unsigned(8 downto 0):=(others=>'0'); --signal trig:std_logic; --signal c:unsigned(positive(ceil(log2(real(order))))-1 downto 0);	--counter:5bits -- debugger --signal dbgSignals:std_ulogic_vector(127 downto 0);

--/* Memories: */ --	/* TODO: Change these arrays to internal process variables instead. */ --	/* Read-only Memory (ROM). */ --	type signed_vector is array(natural range <>) of signed(width-1 downto 0);		-- 32-by-N matrix array structure (as in RAM). Similar to integer_vector, difference being base vector is 32-bit unsigned. --	type signedx2_vector is array(natural range<>) of signed(width*2-1 downto 0); --	/* 32-by-N matrix array structure (as in RAM). Similar to integer_vector, difference being base vector is 32-bit unsigned. */	type signed_vector is array(natural range <>) of signed(u'range); type signedx2_vector is array(natural range<>) of signed(u'length*2-1 downto 0); --	/* Filter length = number of taps = number of coefficients = order + 1 */ constant b:signed_vector(0 to order):=(		x"FFEF",		x"FFED",		x"FFE8",		x"FFE6",		x"FFEB",		x"0000",		x"002C",		x"0075",		x"00DC",		x"015F",		x"01F4",		x"028E",		x"031F",		x"0394",		x"03E1",		x"03FC",		x"03E1",		x"0394",		x"031F",		x"028E",		x"01F4",		x"015F",		x"00DC",		x"0075",		x"002C",		x"0000",		x"FFEB",		x"FFE6",		x"FFE8",		x"FFED",		x"FFEF"	); --	/*Memory Addressing*/ --	signal c:natural range b'range; --	/* Pipes and delay chains. */	signal y0:signed(u'length*2-1 downto 0); signal u_pipe:signed_vector(b'range):=(others=>'0'));	signal y_pipe:signedx2_vector(b'range):=(others=>'0')); --	/* Counters. */ --	signal cnt:integer range 31 downto -1;			-- symbol / bit counter. Counts the bits transmitted on the serial line. --	/* memory pointers (acts as the read/write address for the synchronous RAM). */ --	signal instrPtr:natural range rfbSequencesCache'range;		--RFB sequence memory addressing. Acts as instruction pointer. Points to the current SPI instruction to be transmitted on MOSI. Size is one more than the instruction cache size, so it points past the last valid address (used for counting). --	/* [end]: Memories. */ --	/* Signal preservations. */ --	attribute keep:boolean; --	/* Explicitly define all multiplications with the "*" operator to use dedicated DSP hardware multipliers. */ --	attribute multstyle:string; attribute multstyle of rtl:architecture is "dsp";	--altera --	attribute mult_style:string; attribute mult_style of fir:entity is "block";		--xilinx begin --	/* 1-Dimensional Synchronous ROM. */ --	readCoeffs: process(clk) is begin --		if rising_edge(clk) then --			if reset='1' then q<=(others=>'0'); --			else q<=b(c); --			end if; --		end if; --	end process readCoeffs; u_pipe(0)<=u; u_dlyChain: for i in 1 to u_pipe'high generate delayChain: process(clk) is begin if rising_edge(clk) then u_pipe(i)<=u_pipe(i-1); end if; end process delayChain; end generate u_dlyChain; y_pipe(0)<=b(0)*u; y_dlyChain: for i in 1 to y_pipe'high generate y_pipe(i)<=b(i)*u_pipe(i) + y_pipe(i-1); end generate y_dlyChain; y0<=y_pipe(y_pipe'high) when reset='0' else (others=>'0'); y<=y0(y'range); end architecture rtl;

=Next Steps= The next step is to completely debug all the VHDL codes for the different modules and simulate the filter to make sure that the frequency response of the filter is what is expected.