• No results found

Simulation of the behavior model

The simulation result for the UART transmitter is correct and the behaviour model has met the design requirement as the result shown that the most significant bit received from the parallel port of the 8 bits register now is becoming the least significant bit and the least significant bit received form the parallel port of the 8 bits register now is becoming the most significant bit and so on. There is no parity check bit and frame error bit.

Figure 5-1 Simulation behavior of the UART Transmitter

It is really hard to judge the behaviour of the FIR low pass filter form this simulation data however the simulation behaviour is generated based on the design specification in section 3.3 so the behaviour model should be correct.

Figure 5-2 Simulation behavior of the FIR filter

The simulation result for the 16 times baud rate clock is correct as it can be seen that there is only one pulse signal for the clk16x only when 54 50MHz pulses passed so it is correct.

Figure 5-3 Simulation behavior of the16 times baud rate clock The simulation result for the receiver is correct.

Figure 5-4 Simulation behavior of the UART receiver

6

6 CONCLUSION

The traditional methodology for designing a filter consists of two phases: system specification and hardware implementation. Both phases require multiple iterations and can involve a four-to-six-week process just to ensure that a single functional block operates to specification within the system. Creating this filter from the ground up, using either VHDL or other design entry methods, would have required too much development time.MatLab is an excellent tool to design filters. There are toolboxes available to generate VHDL descriptions of the filters which reduce dramatically the time required to generate a solution.

There is more than one way to implement the digital FIR filter. Based on the design specification, careful choice of implementation method and tools can save a lot of time and work. Time can be spent evaluating different implementation alternatives. Proper computation algorithm can improve the FPGA architecture to make it efficient in terms of speed and/or area.

As the filter order increase the amount of resources usage increase correspondently, Non- Symmetric FIR filter took larger amount of resources than symmetric FIR filter as the Amount of hardware component to implement the Non-Symmetric FIR filter is bigger than the symmetric FIR filter.

About future work for the improvement of the project, digital to analogue converter, analogue to digital converter and IIR filter can be tried to implement on the FPGA board.

7

7 BIBLIOGRAPHY

Abdelhak M. Zoubir “Digital Signal Processing and Spectral Analysis”,Manuscript for DSP 304, pp18, 60, 75, 1999

AccelChip, Inc., “AccelWare IP for DSP Design Targeting FPGAs and ASICs” pp5, 2004

AccelChip, Inc., “Comparison of Methods forImplementing DSP Algorithms ” pp. 5, July 2004.

AccelChip, Inc., “Filter Design Methods for FPGAs” pp. 1-10, 2004.

AccelChip, Inc., “Automated Conversion of Floating-point to Fixed-point MATLAB” pp.6 2004.

AccelChip, Inc., “What’s the Right Language for DSP System-level Design?”pp3,2004

AccelChip, Inc., “MATLAB as a System Modeling Language for Hardware,” pp9, 2004.

AccelChip, Inc., “Top-Down DSP Design Flow to Silicon Implementation,” pp6-8, 2004.

Nirman Kendra, “SI40UART01 Universal Asynchronous Receiver/Transmitter Core Factsheet” 12/20/2002

Intersil, Inc..“CMOS Universal Asynchronous Receiver Transmitter (UART)” March 1997

Memcs, Inc..“Virtex-4™ FX12 LC Development Board User’s Guide”,2005

8

8 APPENDICES

Appendix A: Background knowledge about filter design

Table 8.1The four classes of FIR filter and their associate properties

Table 8.2 Suitability of a given class of filter for the four FIR types

Figure 8.3(a) Kaiser windows for β = 0 (solid), 3 (semi-dashed), and 6 (dashed) and N = 21.(b) Fourier transforms corresponding to windows in (a). (c) Fourier transforms of Kaiser Windows with β = 6 and N = 11 (solid), 21 (semi-dashed), and 41 (dashed).

Appendix B: filter design by using FDATool

FDATool has been used to entry the design specification Start the FDATool by entering the fdatool command in the MATLAB Command Window. MATLAB displays the Filter Design & Analysis Tool dialog.

In the Filter Design & Analysis Tool dialog, check that the following filter options are set:

Option Value

Response Type Lowpass

Design Method FIR Equiripple

Filter Order Specify order: 5

Options Density Factor: 20

Frequency Specifications Units: KHz

Fs: 10 Fpass: 2 Fstop: 3

Magnitude Specifications Units: dB Apass: 1 Astop: 80

Click the Set Quantization Parameters button in the left-side tool bar. The FDATool displays a Filter arithmetic menu in the bottom half of its dialog.

Select Fixed-point from the Filter arithmetic list. The FDATool displays the first of three tabbed panels of quantization parameters across the bottom half of its dialog. You use the quantization options to test the effects of various settings with a goal of optimizing the quantized filter's performance and accuracy.

Tab Parameter Setting

Coefficients Numerator word length 16

Best-precision fraction Selected

lengths Use unsigned representation

Cleared

Scale the numerator coefficients to fully utilize

the entire dynamic range

Cleared

Input/Output Input word length 16

Input fraction length 15

Output word length 16

Avoid overflow Selected

Filter Internals Round towards Floor

Overflow mode Saturate

Product mode Full precision

Accum. mode Keep MSB

Accum. word length 40

Cast signals before accum

Selected

Click Apply

Start the Filter Design HDL Coder by selecting Targets–>Generate HDL in the FDATool dialog. The FDATool displays the Generate HDL dialog.

Find the Filter Design HDL Coder online help. Use the help to learn about product details or to get answers to questions as you work with the designer.

a. In the MATLAB window, click the Help button in the toolbar or click Help–>Full Product Family Help.

b. In the Help browser's Contents pane, select Filter Design HDL Coder.

c. Minimize the Help browser.

Click the Help button. The FDATool displays context-sensitive help for the dialog. As necessary, use the Help button on the other Filter Design HDL Coder dialogs for context-sensitive help on those dialog views.

Close the Help window.

Place your cursor over the Name label or text box in the HDL filter pane of the Generate HDL dialog and right-click. A What's This? button appears.

Click What's This? The Filter Design HDL Coder opens context-sensitive help that describes the Name option. Use the context-sensitive help as needed while using the GUI to configure options that control the contents and style of the generated HDL code and test bench. A help topic is available for each option and pane.

In the Name text box of the HDL filter pane, replace the default name with basicfir. This option names the VHDL entity and the file that is to contain the filter's VHDL code.

In the Name text box of the Test bench types pane, replace the default name with basicfir_tb. This option names the generated test bench file.

Click HDL Options. The Filter Design HDL Coder displays an HDL Options dialog.

In the Comment in header text box, type Tutorial - Basic FIR Filter and then click Apply. The Filter Design HDL Coder adds the comment to the end of the header comment block in each generated file.

Select the Ports tab. The Ports pane appears.

Change the names of the input and output ports. Replace filter_in with data_in and filter_out with data_out.

Clear the check box for the Add input register option. The Ports pane should now look like the following.

Click Apply and then OK to register your changes and close the HDL Options dialog.

Click Test Bench Options. The Filter Design HDL Coder displays a Test Bench Options dialog.

You use this dialog to customize the generated test bench. For this tutorial, apply the default settings by clicking OK.

In the Generate HDL dialog, click Generate to start the code generation process. The Filter Design HDL Coder displays the following messages in the MATLAB Command Window as it generates the filter and test bench VHDL files.

### Starting VHDL code generation process for filter: basicfir

### Generating basicfir.vhd file in: hdlsrc ### Starting generation of basicfir VHDL entity

### Starting generation of basicfir VHDL architecture ### HDL latency is 1 samples

### Successful completion of VHDL code generation process for filter: basicfir

### Starting generation of VHDL Test Bench ### Generating input stimulus

### Done generating input stimulus; length 3429 samples. ### Generating VHDL file basicfir_tb.vhd in: hdlsrc ### Please wait ...

### Done generating VHDL test bench.

As the messages indicate, the Filter Design HDL Coder creates the directory hdlsrc under your current working directory and places the files basicfir.vhd and basicfir_tb.vhd in that directory.

The generated VHDL code has the following characteristics:

• VHDL entity named basicfir.

• Registers that use asynchronous resets when the reset signal is active high (1).

• Ports have the following names:

VHDL Port Name

Input data_in

Output data_out

Clock input clk

Clock enable input clk_enable Reset input

reset

• An extra register for handling filter output.

• Clock input, clock enable input and reset ports are of type STD_LOGIC and data input and output ports are of type STD_LOGIC_VECTOR.

Coefficients are named coeffn, where n is the coefficient number, starting with 1.

• Type safe representation is used when zeros are concatenated: '0' & '0'...

• Registers are generated with the statement ELSIF clk'event AND clk='1' THEN rather than with the rising_edge function.

• The postfix string _process is appended to process names. The generated test bench:

• Is a portable VHDL file.

• Forces clock, clock enable, and reset input signals.

• Forces the clock enable input signal to active high.

• Drives the clock input signal high (1) for 5 nanoseconds and low (0) for 5 nanoseconds.

• Forces the reset signal for two cycles plus a hold time of 2 nanoseconds.

• Applies a hold time of 2 nanoseconds to data input signals.

• Applies impulse, step, ramp, chirp, and white noise stimulus types. When you have finished generating code, click Close to close the Generate HDL dialog.

Low-pass FIR filter has been implemented with

Appendix B: Circuit diagram

Figure8-4 Circuit diagram of the overall system

Appendix C: Code 16 times baud rate clock library ieee; use ieee.std_logic_1164.all; entity count54 is port(clk50Mx,en:in std_logic; clk16x:out std_logic); end count54;

architecture count54_arc of count54 is begin

process(clk50Mx,en)

variable count:integer range 0 to 54 :=0; begin

if en='0' then clk16x <= '0';

elsif (rising_edge(clk50Mx)) then count:=count+1; if count=54 then clk16x<='1'; count:=0; else clk16x<='0'; end if; end if; end process; end count54_arc; Direct form FIR filter LIBRARY IEEE; USE IEEE.std_logic_1164.all; USE IEEE.numeric_std.ALL; ENTITY filter IS PORT( clk : IN std_logic; clk_enable : IN std_logic; reset : IN std_logic;

data_in : IN std_logic_vector(7 DOWNTO 0); -- sfix8_En7 data_out : OUT std_logic_vector(7 DOWNTO 0) --

sfix8_En7 ); END filter;

--- --Module Architecture: filter

--- ARCHITECTURE rtl OF filter IS

-- Local Functions -- Type Definitions

TYPE delay_pipeline_type IS ARRAY (NATURAL range <>) OF signed(7 DOWNTO 0); -- sfix8_En7

-- Constants

CONSTANT coeff1 : signed(15 DOWNTO 0) := to_signed(-4423, 16); -- sfix16_En16

CONSTANT coeff2 : signed(15 DOWNTO 0) := to_signed(18623, 16); -- sfix16_En16

CONSTANT coeff3 : signed(15 DOWNTO 0) := to_signed(29114, 16); -- sfix16_En16

CONSTANT coeff4 : signed(15 DOWNTO 0) := to_signed(29114, 16); -- sfix16_En16

CONSTANT coeff5 : signed(15 DOWNTO 0) := to_signed(18623, 16); -- sfix16_En16

CONSTANT coeff6 : signed(15 DOWNTO 0) := to_signed(-4423, 16); -- sfix16_En16

-- Signals

SIGNAL delay_pipeline : delay_pipeline_type(0 TO 4); -- sfix8_En7 SIGNAL data_in_regtype : signed(7 DOWNTO 0); -- sfix8_En7 SIGNAL product6 : signed(31 DOWNTO 0); -- sfix32_En31 SIGNAL mul_temp : signed(23 DOWNTO 0); -- sfix24_En23 SIGNAL product5 : signed(31 DOWNTO 0); -- sfix32_En31 SIGNAL mul_temp_1 : signed(23 DOWNTO 0); -- sfix24_En23 SIGNAL product4 : signed(31 DOWNTO 0); -- sfix32_En31 SIGNAL mul_temp_2 : signed(23 DOWNTO 0); -- sfix24_En23 SIGNAL product3 : signed(31 DOWNTO 0); -- sfix32_En31 SIGNAL mul_temp_3 : signed(23 DOWNTO 0); -- sfix24_En23 SIGNAL product2 : signed(31 DOWNTO 0); -- sfix32_En31 SIGNAL mul_temp_4 : signed(23 DOWNTO 0); -- sfix24_En23 SIGNAL product1 : signed(34 DOWNTO 0); -- sfix35_En31 SIGNAL mul_temp_5 : signed(23 DOWNTO 0); -- sfix24_En23 SIGNAL sum1 : signed(34 DOWNTO 0); -- sfix35_En31 SIGNAL add_temp : signed(35 DOWNTO 0); -- sfix36_En31 SIGNAL sum2 : signed(34 DOWNTO 0); -- sfix35_En31 SIGNAL add_temp_1 : signed(35 DOWNTO 0); -- sfix36_En31 SIGNAL sum3 : signed(34 DOWNTO 0); -- sfix35_En31 SIGNAL add_temp_2 : signed(35 DOWNTO 0); -- sfix36_En31 SIGNAL sum4 : signed(34 DOWNTO 0); -- sfix35_En31 SIGNAL add_temp_3 : signed(35 DOWNTO 0); -- sfix36_En31 SIGNAL sum5 : signed(34 DOWNTO 0); -- sfix35_En31 SIGNAL add_temp_4 : signed(35 DOWNTO 0); -- sfix36_En31 SIGNAL output_typeconvert : signed(7 DOWNTO 0); -- sfix8_En7

SIGNAL output_register : signed(7 DOWNTO 0); -- sfix8_En7

BEGIN

-- Block Statements

Delay_Pipeline_process : PROCESS (clk, reset) BEGIN

IF reset = '1' THEN

delay_pipeline(0 TO 4) <= (OTHERS => (OTHERS => '0')); ELSIF clk'event AND clk = '1' THEN

IF clk_enable = '1' THEN

delay_pipeline(0) <= signed(data_in);

delay_pipeline(1 TO 4) <= delay_pipeline(0 TO 3); END IF;

END IF;

END PROCESS Delay_Pipeline_process; data_in_regtype <= signed(data_in); mul_temp <= delay_pipeline(4) * coeff6;

product6 <= resize( mul_temp & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0', 32); mul_temp_1 <= delay_pipeline(3) * coeff5;

product5 <= resize( mul_temp_1 & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0', 32); mul_temp_2 <= delay_pipeline(2) * coeff4;

product4 <= resize( mul_temp_2 & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0', 32); mul_temp_3 <= delay_pipeline(1) * coeff3;

product3 <= resize( mul_temp_3 & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0', 32); mul_temp_4 <= delay_pipeline(0) * coeff2;

product2 <= resize( mul_temp_4 & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0', 32); mul_temp_5 <= data_in_regtype * coeff1;

product1 <= resize( mul_temp_5 & '0' & '0' & '0' & '0' & '0' & '0' & '0' & '0', 35); add_temp <= resize(product1, 36) + resize(product2, 36);

sum1 <= (34 => '0', OTHERS => '1') WHEN add_temp(35) = '0' AND add_temp(34) /= '0'

ELSE (34 => '1', OTHERS => '0') WHEN add_temp(35) = '1' AND add_temp(34) /= '1'

ELSE (add_temp(34 DOWNTO 0));

add_temp_1 <= resize(sum1, 36) + resize(product3, 36);

sum2 <= (34 => '0', OTHERS => '1') WHEN add_temp_1(35) = '0' AND add_temp_1(34) /= '0'

ELSE (34 => '1', OTHERS => '0') WHEN add_temp_1(35) = '1' AND add_temp_1(34) /= '1'

ELSE (add_temp_1(34 DOWNTO 0));

add_temp_2 <= resize(sum2, 36) + resize(product4, 36);

sum3 <= (34 => '0', OTHERS => '1') WHEN add_temp_2(35) = '0' AND add_temp_2(34) /= '0'

ELSE (34 => '1', OTHERS => '0') WHEN add_temp_2(35) = '1' AND add_temp_2(34) /= '1'

ELSE (add_temp_2(34 DOWNTO 0));

add_temp_3 <= resize(sum3, 36) + resize(product5, 36);

sum4 <= (34 => '0', OTHERS => '1') WHEN add_temp_3(35) = '0' AND add_temp_3(34) /= '0'

ELSE (34 => '1', OTHERS => '0') WHEN add_temp_3(35) = '1' AND add_temp_3(34) /= '1'

ELSE (add_temp_3(34 DOWNTO 0));

add_temp_4 <= resize(sum4, 36) + resize(product6, 36);

sum5 <= (34 => '0', OTHERS => '1') WHEN add_temp_4(35) = '0' AND add_temp_4(34) /= '0'

ELSE (34 => '1', OTHERS => '0') WHEN add_temp_4(35) = '1' AND add_temp_4(34) /= '1'

ELSE (add_temp_4(34 DOWNTO 0));

output_typeconvert <= (7 => '0', OTHERS => '1') WHEN sum5(34) = '0' AND sum5(33 DOWNTO 31) /= "000"

ELSE (7 => '1', OTHERS => '0') WHEN sum5(34) = '1' AND sum5(33 DOWNTO 31) /= "111"

ELSE (sum5(31 DOWNTO 24));

Output_Register_process : PROCESS (clk, reset) BEGIN

IF reset = '1' THEN

output_register <= (OTHERS => '0'); ELSIF clk'event AND clk = '1' THEN IF clk_enable = '1' THEN

output_register <= output_typeconvert; END IF;

END IF;

END PROCESS Output_Register_process; -- Assignment Statements data_out <= std_logic_vector(output_register); END rtl; UART_Receiver --- library ieee ; 67

use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all;

--- entity rx is

port( Din: in std_logic; clock: in std_logic; reset: in std_logic;

Dout: out std_logic_vector(7 downto 0); Drdy: out std_logic

); end rx;

--- architecture FSM of rx is

-- define the states of FSM model type state_type is (S0, S1);

signal next_state, current_state: state_type; signal tmpdata:std_logic_vector(9 downto 0); signal datardy:std_logic;

signal count: std_logic_vector(7 downto 0); signal start: std_logic;

begin

-- cocurrent process#1: state registers process(clock, reset)

begin

if (reset='1') then

current_state <= S0;

elsif (clock'event and clock='1') then current_state <= next_state; end if; end process; process(reset,Din,current_state) begin

if (reset='1') or current_state=S0 then

start <= '0';

elsif current_state = S0 and (Din'event and Din='0') then start <= '1';

end if; end process;

process(clock, reset, current_state)

begin

if reset='1'or current_state = S0 then count<="00000000";

elsif(clock'event and clock='1') then count <= count + 1;

end if; end process;

process(clock, count, Din,current_state) begin

next_state<= current_state; --if next_state<=current_state then

case current_state is when S0 => if start <= '1' then next_state <= S1; datardy<='0'; else next_state <= S0; end if; when S1=> if count=x"18"then next_state <= S1; tmpdata(0)<=Din; datardy<='0';

elsif count=x"28" then next_state <= S1; tmpdata(1)<=Din; datardy<='0'; elsif count=x"38"then next_state <= S1; tmpdata(2)<=Din; datardy<='0'; elsif count=x"48"then next_state <= S1; tmpdata(3)<=Din; datardy<='0'; elsif count=x"58"then next_state<= S1; tmpdata(4)<=Din; datardy<='0'; elsif count=x"68"then next_state<= S1; 69

tmpdata(5)<=Din; datardy<='0'; elsif count=x"78"then next_state<= S1; tmpdata(6)<=Din; datardy<='0'; elsif count=x"88"then next_state<= S1; tmpdata(7)<=Din; datardy<='0';

dout <= tmpdata(7 downto 0);

elsif count=x"95"then next_state<= S1; datardy<='1'; elsif count=x"98"then next_state<= S1; datardy<='1'; elsif count=x"9D"then next_state<= S0; datardy<='0'; else next_state<= S1; end if; when others => next_state<= S0; end case; -- end if; end process; Drdy <= datardy; end FSM; UART_Transmitter library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity Tx is

port ( clk16 : in std_logic; -- Input clock with 50 MHz clock signal wr : in std_logic; -- Write strobe signal

rst : in std_logic; -- Reset button

din : in std_logic_vector(7 downto 0); -- 8 Bits data bus Input

sdo : out std_logic; -- Serial transmit data line tx_rd : out std_logic);-- Transmitter ready to Tx next byte

end Tx;

architecture Tx_arc of Tx is

signal txbr : std_logic_vector(7 downto 0);-- 8 Bits buffer register signal txsr : std_logic_vector(7 downto 0);-- 8 Bits serial register signal txd2 : std_logic; -- tag bits for detecting

signal txd1 : std_logic; -- empty shift register

signal clk : std_logic; -- Transmit clock or baud rate clock signal txdone : std_logic; -- '1' when shifting of byte is done signal txrd : std_logic; -- '1' when data is ready in txhold

begin

process (rst, clk16) -- Toggle clk every 8 counts, which divides the clock frequency by 16

variable count: std_logic_vector(2 downto 0); begin

if rst='1' then clk <= '0' ;

count := (others=>'0') ;

elsif clk16'event and clk16='1' then if (count = "000") then clk <= not clk; end if; count := count + "001"; end if; end process; process (rst, clk) begin if rst='1' then txsr <= (others=>'0') ; txd1 <= '0' ; txd2 <= '0' ; sdo <= '0' ;

elsif clk'event and clk = '1' then

if (txdone and txrd) = '1' then -- Initialize registers and load next byte of data

txsr <= txbr; -- Load tx register from txbr txd2 <= '1'; -- Tag bits for detecting txd1 <= '1'; -- when shifting is done sdo <= '0'; -- Start bit to the serial port else

txsr <= txd1&txsr(7 downto 1); -- Shift data txd1 <= txd2;

txd2 <= '0';

if txdone = '1' then -- Shift out data

sdo <= '1'; -- Stop or idle bit else

sdo <= txsr(0); -- Shift data bit end if;

end if ;

end if;

end process;

txdone <= not(txd2 or txd1 or txsr(7) or txsr(6) or txsr(5) or txsr(4) or txsr(3) or txsr(2) or txsr(1) or txsr(0)); -- txdone = 1 when done shifting (When txtag2 has reached tx)

process (rst, clk16)

variable wr1,wr2: std_logic; -- write signal delayed 1 and 2 cycles or current state and preivous state

variable txdone1: std_logic; -- txdone signal delayed one cycle begin if rst='1' THEN txrd<= '0' ; wr1 := '0' ; wr2 := '0' ; txdone1 := '0' ;

elsif clk16'event and clk16 = '1' then

if wr1 = '0' and wr2= '1' then -- Falling edge on write signal. New data in txbr register

txrd <= '1';

elsif txdone ='0' and txdone1 = '1' then -- Falling edge on txdone signal. Txbr has been read.

txrd <= '0'; end if;

wr2 := wr1; --

Delayed versions of write and txdone signals for edge detection wr1 := wr ;

txdone1 := txdone; end if ;

end process;

txbr <= din when wr = '1'else txbr; -- Latch data bus during write

tx_rd <= not txrd; -- Transmitter ready for write when no data is in txbr

end Tx_arc;

Related documents