RIDLTom Montagliano

Document Number

Altera FPGA Testing

Version 1.0

Author: / Tom Montagliano / Date: / May 27, 2009
Reviewer: / Don Figer / Date:

Printed on Wednesday, July 01, 2009Altera FPGA Testing v2.doc

RIDLTom Montagliano

1.0Introduction

2.0Generating a bit stream

3.0Receiving a bit stream

4.0Setting an analog voltage with the DAC

5.0Read a voltage with the ADC

6.0Write and read data from RAM for a single pixel

7.0Write and read data from RAM for a 32x32 pixel array

8.0Appendix A: HDL Code

8.1Generating a Bit Stream: square_wave.vhd

8.2Receiving a Bit Stream: receive_sw.vhd

8.3Read and Write data to RAM from Single Pixel: single_pixel.vhd

8.4Writing and reading from a 32x32 pixel array: sub_frame.vhd

8.5Next Next Entry

9.0Appendix B: Connections and Pinouts

9.1THDB-ADA GPIO pinout

9.2THDB-HTG GPIO pinout

9.3Altera III Starter Board HSMC pinout

Printed on Wednesday, July 01, 2009Altera FPGA Testing v2.doc

RIDLTom Montagliano

1.0Introduction

This document describes functionality testing of the Altera Cyclone III FPGA Starter Kit Development Board. It also includes testing of associated daughterboards, i.e. the ADA ADC/DAC board and the HSMC to GPIO adapter board. The equipment is given in Table 1.

Table 1. Parts used for FPGA testing.
Part No. / Item / Vendor
???? / Cyclone III Starter XXXXXXXXX / Altera?????
???? / ADA XXXXXXXX / Terasic???????

2.0Generatinga bit stream

Using the Altera Cyclone III Starter Board, and the HSTC to GPIO daughter card, a bit stream can be created with the Quartus II Software. The code used for this will be used in future designs to create clocks of different speeds to drive the inputs of the DAC Board. The code can be found in Section 6.1.

The code operates by creating a loop that will increment a variable, count, on each clock cycle and then invert the bit stream each time that count equals the freq signal. The signal freq acts as a clock divider and controls the frequency of the bit stream. In this application, the on board clock operates at 50MHz so the frequency can be calculated by the equation Frequency = ((Clock Frequency)/ freq ) * (1/2). It is multiplied by ½ because it inverts the signal on the rising edge of each clock and therefore halves the frequency.

This code can be verified with the set-up shown below in Figure 1. The software is used to route the signal onto the associated header pin and then the waveform is captured on the oscilloscope, as shown in Figure 2.

Figure 1: Setup used to generate and measure bit stream. The HSMC to GPIO daughterboard, made by Terasic, is shown on the left.
Figure 2 : Waveform of a 250kHz bit stream, generated with the setup shown in Figure 1.

3.0Receiving a bit stream

Once again, using the Altera Cyclone III Starter Board and the HSTC to GPIO daughter board, a signal can be received through the I/O port using the Quartus II software. This can be used to read in data from an external source and interpret it in software. Eventually, this will be used to retrieve data from the ADC (Analog to Digital Converter).

This program uses the same code used in Section 3.0 to divide and create a signal. In addition to that, a D Flip Flop is created in the process, DFF, which will synchronize the input and output signal. There is another process, compare, which will compare the input and output. If the input and output signals are equal, an LED will light up indicating that the program is working. For this application, the freq signal is adjusted to 10,000,000 so that the frequency is 2.5Hz. This allows us to see the LED go from blinking to solid when the connection from output to input is made. The code can be found in Section 6.2.

This code can be verified with the set-up shown below inFigure 3.The software is used to route the signal onto the associated header pin and then the waveform is captured on the oscilloscope as shown in Figure 4.

Figure 3:Test setup used to receive a bit stream.
Figure 4 : Waveform of a 250kHz bit stream, measured with the setup shown in Figure 3.

4.0Setting an analog voltage with the DAC

The DAC can be configured to output a desired voltage based on the digital input. The exact voltage and resolution is a result of the load resistor combined with the value of the digital input. With the DAC daughter board, the DAC is setup to operate in differential coupling mode. For our application, we want the output to be in single ended mode. In order to do this, the transformer T5 and T6 must be removed and a short must be installed at R60 and R62; see Figure 5. This places the minimumoutput voltage at ground and the maximum output voltage at around 1V. This maximum output voltage is calculated found by multiplying thefull scale output current from the DAC, 20mA, by the load resistance (50 ohms).

Figure 5 : Schematic of output circuit on the ADA ADC/DAC daughterboard. This section of the schematic shows the circuit between the two DAC channels and the SMA output connectors. Note the transformers, T5 and T6, and the associated resistors that had to be modified for single-ended operation.

The code for driving this DAC basically writes a value, count, onto the digital inputs and provides the appropriate clocking necessary to synchronize the write cycles. The DAC board can operate at speeds of up to 125MHz. Figure 6 shows a screen shot of the analog output for decimal input value of 12555. Given that the peak value was measured to be 0.936V, the resolution was calculated to be 0.57uV/bit. Therefore, for a input value of 12555 we should see an analog output of around 0.717V.

Figure 6: Analog output value for a decimal input of 12555

5.0Read a voltage with the ADC

The ADC can be driven by inputting a transient waveform into the analog input. Digital outputs will then be created at a sampling rate that is dictated by the clock signal, see Figure 7 below for the timing diagram. The maximum sampling rate for the ADC on the THDB-ADA Daughter card is 65Mhz.

Figure 7 : Timing Diagram for the ADC

The input voltage range is 2Vp-p. As a result of the coupling capacitor, C1 in Figure 8, the DC offset of the input does not make a difference on the output. With this configuration, the output will be generated based on the change in voltage. Figure9 shows the digital output for an analog input that is ramped. For our application, we may modify the circuit to operate in single-ended mode so that we can effectively determine the exact input voltage based on the digital output.

Figure 8 : Schematic for ADC Input
Figure 9 : Digital Outputs for a Ramping Input

The digital signals were obtained by using the test setup shown in Figure 10below. The analog sine wave was input using a function generator. The Logic Analyzer probe cable was placed on the corresponding pins,ADC_DA13-ADC_DA0, of the GPIO 0 port. The exact pin locations can be found by using the pinout in Section 7.1.

Figure 10 : Test Setup for Measure the Digital Outputs of the ADC

In order to verify that the digital signals were being properly read into the FPGA, the in-system memory was utilized using the RAM megafunction in the Quartus II software. This enabled us to write to a memory location on the Cyclone III FPGA and then use the In-System Memory Content Editor program in Quartus II to verify that the data was received correctly. A 1 MHz sine wave was input into the ADC and the output is shown in Figure 11. Since this is a 14 bit converter, the maximum hex value will be 3FFF and the minimum hex value will be 0000. The values are plotted using IDL in Figure 12and correlate with the expected sinusoidal wave on the output.

Figure 11 : In-System Memory Content Editor with hex values for a 1MHz Sine Wave
Figure 12 : Plot of values from output of the ADC;
x-axis:number of the sample, y-axis:decimal equivalent of the hex output

6.0Write and read data from RAM for a single pixel

Using a state machine in VHDL, a program was written to control the signals that will drive the MOSIS 2 chip. This code was simply written to write and read the first pixel in the array 256 times. A few important things need to be considered in order to effectively control the MOSIS 2 chip.

The code was designed so that when a button on the Altera Cyclone III Starter Board was pressed, pb, it would take a value output from the comparator, comp_out_v, and output that result to a location in memory. In this application, the “comparator” value is generated by toggling an external push button as seen in Figure13. In the actual application, the MOSIS 2 chip will have a comparator that compares the Vthresh to actual voltage from the pixel being read. Once 256 samples have been taken, a reset state will be entered until another push button has be initialized. This is also shown in Figure 13.

Figure 13 :The code goes into a reset state after 256 samples. This activates the cs_rs_reset, pd_reset and v_reset signals. It will remain in this reset state until an external push button, pb, has been pushed.

An adjustable delay is created within the software to accommodate for the settling time of the comparator. This was set to 3 clock cycles for this example which is around 60ns. After the delay has finished a data valid signal, latch_np_v, will be sent out which lets other software modules know that the comparator value is valid. Figure 14 shows exactly how this works.

Figure 14 : Three clock cycle delays are created to allow for the comparator to settle. The results from the comparator are loaded into an 8 bit word and then the address is incremented after each 8 bit word is written to RAM.

The memory is written to in blocks of 8 bit words. Each bit of the word represents one sample from the output of the comparator for a pixel. In Figure 14 you can see the comparator results being loaded into the word. Figure 14 also shows that the address is incremented after 8 bits have been read. All of the code for instantiating this logic can be found in Section 7.3.

Once the code was simulated, it was loaded onto the Altera Cyclone III Starter kit board and verified using the In-System Memory Content Editor program in Quartus II. For this test, the out_comp signal was routed to a push button since there was value coming from the comparator. Also, it should be noted that the delay constant, delay_lim, in the code needed to be increased to 1500000 in order to verify that it was reading in the comparator values correctly. Otherwise, the RAM will be loaded too quickly and all F’s or 0’s will be loaded into the memory. The results can be seen in Figure 15. Notice that it stops at memory address x00020 which is 32 words. This makes sense because there are 8 bits in each word which works out to 256 samples.

Figure 15 : Bit stream being read from RAM.

The code was also verified using an oscilloscope. It was verified using the setup shown inFigure 16. The Altera Cyclone III Starter Board was connected to the THDB-HTG GPIO board. The signals were connected to the digital inputs to the oscilloscope and routed to the GPIO pins using the Pin Planner in the Quartus II software and the pinout diagram located in Section 8.2.

Figure 16 : Test setup to read digital outputs on the oscilloscope

The screen shot in Figure17 shows that the 60ns delay on the comparator output is working correctly. It also matches the expected waveforms as shown in Figure 14.

Figure 17 :Screen Shot of 60ns delay on oscilloscope

The screen shot in Figure 18 shows that the reset is working correctly at the end of 256 samples. As expected, the pd_reset, V_reset and cs_rs_reset signals become active.

Figure 18: Reset at the end of 256 samples on the oscilloscope

7.0Write and read data from RAM for a 32x32 pixel array

Using a similar state machine from the single pixel read and write cycles, a full array can be rastered through. A few things must be considered in order to clock through the array properly.

The design of MOSIS 2 pixel array can be seen in the schematic in Figure 19. Note that there is no flip flop on the first pixel. In order to access pixel (1, 1), which would be row 1 column 1; the signal D_CS and D_RS must be set high. To clock through the array to the next pixel, pixel (1, 2), the D_CS line must be kept high while CLK_CS is toggled. The remaining 30 pixels in the row can be accessed by bringing D_CS signal low and toggling the CLK_CS line for each successive pixel. The first few read cycles are simulated in ModelSim in Figure 20.

Figure 19: Schematic for the MOSIS 2 pixel array
Figure 20:Clocking through the first three pixels in the array in ModelSim

Once a row has been completed, an extra CLK_CS pulse must be initialized in order to empty out the flip flip on the end. This is shown in Figure 21. This figure shows pixel (2,1) being read right after the extra clk_cs pulse. Note that D_CS is high during the rising edge of CLK_RS. This will increment the row. Every successive row will only require a single CLK_RS pulse and D_CS will remain low until a frame is complete.

Figure 21: An extra CLK_CS pulse must be added at the end of a row read

At the end of a frame, the program will go idle remain there until another push button has been initialized. This will eventually be changed so that the clocking continues and a reset state will be created and added to this program.

The memory was designed to be written in 32 bit blocks. Therefore, at each address location is the information from the comparator for one full row. For a 32 x 32 bit array with 256 samples there will be 13 bits required on the address bus to have enough storage. The associated math and memory map can be seen in Figure 22

Figure 22: Memory Map and associated math

Once the code was simulated, it was loaded onto the Altera Cyclone III Starter kit board and verified using the In-System Memory Content Editor program in Quartus II. For this test, the out_comp signal was routed to a push button since there was value coming from the comparator. Also, it should be noted that the delay constant, delay_lim, in the code needed to be increased to 1500000 in order to verify that it was reading in the comparator values correctly. Otherwise, the RAM will be loaded too quickly and all F’s or 0’s will be loaded into the memory. A screenshot can be seen in Figure 23. Note that there are 4 bytes per memory location and that the last memory location is h01FFF.

Figure 23: RAM being read from the Altera Cyclone III

The code was also verified using an oscilloscope. It was verified using the setup shown in Figure 16. The Altera Cyclone III Starter Board was connected to the THDB-HTG GPIO board. The signals were connected to the digital inputs to the oscilloscope and routed to the GPIO pins using the Pin Planner in the Quartus II software and the pinout diagram located in Section 8.2.

The results on the oscilloscope were consistent with the expected outputs that were simulated using ModelSim. A screenshot of the clocking for the first pixel can be seen in Figure 24.

Figure 24: Screenshot of oscilloscope during the read of pixel (1,1)

The VHDL code for the writing and reading of the 32x32 pixel array can be found in Section 8.4

8.0Appendix A: HDL Code

8.1Generating a Bit Stream: square_wave.vhd

library ieee;

use ieee.std_logic_1164.all;

entity dac is

port(

clk : in std_logic; --set up clk

dac_da : out std_logic_vector(13 downto 0):= "11111111111111");--array for DAC input lines

end dac;

architecture sqwv of dac is

signal square : std_logic; --signal to latch square wave state

signal freq :integer := 100; --sets frequency of square wave to 250kHz

begin

squarewave: process (clk,square) is

variable count : natural := 0;

begin

if (clk'event and clk ='0') then

count := count + 1; --increment count variable every 50MHz clock cycle

if (count >= freq ) then

square <= not square; --invert square wave value

count := 0;-- reset count value

end if;

end if;

end process squarewave ;

dac_da(7) <= square;-- assign square wave to the 8th bit of the DAC data lines

end sqwv;

8.2Receiving a Bit Stream:receive_sw.vhd

library ieee;

use ieee.std_logic_1164.all;

entity dac is

port(

clk,dff_en,dac_in : in std_logic; --set up clk

led0 : out std_logic; --set up led

dac_da : out std_logic_vector(13 downto 0):= "11111111111111");--array for DAC input lines

end dac;

architecture sqwv of dac is

signal d0,d1 : std_logic; --signal to latch square wave state

signal q0,q1 : std_logic;

signal freq :integer := 10000000; --sets frequency of square wave to 2.5Hz

begin

squarewave: process (clk,d0) is

variable count : natural := 0;

begin

if (clk'event and clk ='0') then

count := count + 1; --increment count variable every 50MHz clock cycle

if (count >= freq ) then

d0 <= not d0; --invert square wave value

count := 0;-- reset count value

end if;

end if;

end process squarewave ;

dac_da(8) <= q0;-- assign square wave to the 8th bit of the DAC data lines

d1 <= dac_in;

DFF: process (d0, d1, dff_en)

begin

if (dff_en = '0') then

q0 <= '1';

q1 <= '0';

elsif (clk'event and clk = '0') then

q0 <= d0;

q1 <= d1;

end if;

end process DFF;

compare: process (q1, q0)

begin

if (q0=q1) then

led0 <= '0';

else

led0 <= '1';

end if;

end process compare;

end sqwv;

8.3Read and Write data to RAM from Single Pixel: single_pixel.vhd

library ieee;

use ieee.std_logic_1164.all;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity single_pixel is

port(

clk_in :in std_logic;