Programming the FPGA

From UConn PAN
Revision as of 18:45, 17 July 2007 by Krueger (talk | contribs)
Jump to navigation Jump to search
Spartan.jpg

The FPGA is the hub of the digital control board and all other chips are connected to and controlled by it. This article discusses the programming of the FPGA. All code is written in VHDL. For the purposes of testing, each chip has not only a controller written for it, but an emulator as well.

Open questions

Programming of the FPGA is an ongoing project, so more questions may be added as the project develops.

  • What is the clock speed of the FPGA? Timing constraints must be taken into account to link the multiple blocks.
  • Current designs (11 July, 2007) account for normal activity. Need to design modules/logic for startup and initialization of each component. This should not be only on startup; we should be able to send a reset packet over Ethernet to trigger a reinitialization of each chip.
  • Do the parts work on falling or rising edges of the clock? Most VHDL designs are currently on rising edges, but this can be easily corrected.
  • The temperature sensor and the ADC share the same SPI-like bus lines; can they be combined into a single VHDL design?

Component code

The temperature sensor

The VHDL files can be found here.

Interface (T)

The AD7314 temperature sensor uses a four-wire interface related to (and compatible with) the SPI bus protocol. The wires are:

  • CE: Chip Enable (input), positive logic enable for SCLK
  • SCLK: Serial Clock (input), clock line supplied by external source
  • SDI: Serial Data In (input), data input line
  • SDO: Serial Data Out (output), data output line

Note that the input/output notations are for slave devices (such as the temperature sensor) but are reversed for master devices (such as the FPGA). Proper SPI protocol flips the I/O polarity of CE and SCLK and crosses the SDI and SDO lines so that SDI is an input on every device and SDO is always an output. To maintain simplicity in wiring conventions we are not using proper SPI protocol, but are calling the slave input/master output line SDI and the slave output/master input line SDO so that the SDI/O notations are proper for slaves. The maximum clock rate is no higher than 10MHz. The interface, having separate input and output lines, is full-duplex; in fact the temperature sensor is unable to function in half-duplex mode. Outputs from the temperature sensor change on rising edges of SCLK, but inputs are latched on falling edges.

There is only one write operation to the temperature sensor and that is used to direct the temperature sensor to enter power-down mode. We do not plan to use this mode, so the SDI input on the temperature sensor will be tied to ground.

A read operation occurs during a 16-cycle pulse of CE. The first transmitted bit will be zero, followed by ten bits of temperature data (MSB first). The remaining five bits are copies of the final data bit. After CE goes low SDO goes into a high-Z state. Temperature data is given in degrees Celsius. The format is two's-complement with two decimal places; in essence it is standard two's-complement, then the result must be divide by four after converting to decimal.

Emulator (T)

 
Temperature sensor emulator functional block diagram

The functional block diagram for the emulator is shown to the right. The blocks are:

  • Error Flag
    • The error flag goes high if the enable line is high for 1-15 or 17+ cycles. It resets to low any time the enable line goes back to high. It is used to notify of a "bad" transmission (not 16 cycles long).
    • inputs
      • Clk: clock
      • Rst: asynchronous, active-low reset
      • En: enable
    • outputs
      • Err: error flag
  • Shift Reg
    • An 11-bit, parallel-in, serial-out shift register that loads when not shifting.
    • inputs
      • Clk: clock
      • Rst: asynchronous, active-low reset
      • Sh/Ld: active-high shift, active-low load
      • Par(10:0): 11-bit parallel input bus
    • outputs
      • Ser: serial output line

Controller (T)

 
Temperature sensor controller functional block diagram

The functional block diagram for the controller is shown to the right. The blocks are:

  • Counter
    • Counts a cycle of 17 pulses; holds En high for 11 pulses, holds CE high for 16 pulses.
    • inputs
      • Clk: clock
      • Rst: asynchronous, active-low rest
      • Go: trigger to begin cycle
    • outputs
      • CE: serial chip enable
      • En: internal shift enable
  • Delay
    • Delays input by one clock cycle.
    • inputs
      • Clk: clock
      • D: input signal
    • outputs
      • Q: output signal
  • Shift Reg
    • A 10-bit, serial-in, parallel-out shift register.
    • inputs
      • Clk: clock
      • Rst: asynchronous, active-low rest
      • D: input signal
      • En: shift enable
    • outputs
      • Q: 10-bit output bus

The ADC

The VHDL files can be found here.

Interface (A)

The AD7928 ADC has several features that we do not need: the shadow/sequencer and the multiple power modes. They could be useful for more advanced or efficient functioning of the system, but are not needed. Thus we will simplify the interface by turning these features off and running the ADC is the most basic mode.

The ADC has a four-wire interface that is compatible with the SPI bus protocol. The four lines are:

  • /CS: Active-low chip select. This line is high when the ADC is idle and goes low for 16 cycles during a conversation. As this is active-low and the only other chip on the bus (the temperature sensor) has an active-high chip select line, it is possible to use a single chip select. That would cause one or the other chip to always be running, which would be more information than we need or than we can send across Ethernet, but it is a possible design decision.
  • SCLK: A serial clock.
  • D_out: Serial data out line, for communications from the ADC to the FPGA. This line idles in high-Z.
  • D_in: Serial data in line, for communications from the FPGA to the ADC.

On startup the ADC requires two "dummy" conversation that write all ones to the ADC and read garbage data from the ADC.

A typical conversation lasts for 16 clock cycles, sends 12 bits to the ADC, and receives 12 bits from the ADC. The 12-bit control register has the following format:

11 10 09 08 07 06 05 04 03 02 01 00
Write Seq DC Addr2 Addr1 Addr0 Pow1 Pow0 Shadow DC Range Coding

The sections of the control register are:

  • Write:
    • if 0, do not update the remaining 11 bits of the control register
    • if 1, write new data to the control register
  • Seq: used for a feature we don't need: set to zero
  • DC: don't care
  • Addr(2:0): 3-bit address of channel to report on during next conversation
  • Pow(1:0): used for changing power modes: set to "11"
  • Shadow: used for a feature we don't need: set to zero
  • DC: don't care
  • Range: set to zero
    • if 0, analog input range is 0 to 2*VRef
    • if 1, analog input range is 0 to VReg
  • Coding: set to zero
    • if 0, output is twos-complement
    • if 1, output is binary-coded decimal

Thus a conversation to read the voltage only (and not update the control register would look like

0 X X X X X X X X X X X

and a conversation to set up a read on channel A(2:0) would look like

1 0 X A2 A1 A0 1 1 0 X 0 0

where an X is a don't-care state. Since the first case is almost all don't-care states, we can send the same data (last 11 bits) as in the second case, but append a zero to the front instead of a 1; this simplifies the logic involved. The don't-care states in bits 9 and 2 we can set to zero.

The data flowing back to the FPGA from the ADC will be voltage data from the channel set in the previous conversation. We are going to use twos-complement format for the data, but it can be set to BCD by changing the last bit in the control register to a one.

The control interface to the FPGA core will be:

  • Clk: input: Clock line
  • Rst: input: Asynchronous, active-low reset line
  • Go: input: Pulse to begin transmission
  • Wr: input: Flag whether or not to write new data to control register
  • A(2:0): input: Address to write to control register
  • C(2:0): output: Address of data coming from ADC
  • D(11:0): output: Data from ADC
  • Done: output: Flag to tell core that new data is ready

Emulator (A)

File:ADC Emulator Block.JPG
ADC emulator functional block diagram

The functional block diagram for the emulator is shown to the right. The blocks are:

  • shift in 16
    • This block is a 16-bit shift-in register with asynchronous, active-low reset and shift enable. Custom outputs select the write bit and the data bits from the input string. This register is designed to shift all 16 cycles of a transfer, but only make use of the first 12 bits of the input.
    • inputs
      • CLK: clock
      • Rst: asynchronous, active-low reset
      • En: shift enable
      • D: data in line
    • outputs
      • Q_W: the write bit from the input string
      • Q_D: the 11 data bits from the input string
  • control reg
    • This block is an 11-bit register with asynchronous, active-low reset and a clock enable line.
    • inputs
      • CLK: clock
      • Rst: asynchronous, active-low reset
      • En: read enable
      • D: data in
    • outputs
      • Q: data out
  • 3-to-8 demux
    • This block is a 3-to-8 demultiplexer.
    • inputs
      • D: data to be demuxed
      • S: 3-bit select
    • outputs
      • Q: 8-bit output
  • error flag
    • This block generates a flag to ensure that data in the control register is in the right format (to help verify synchronization). The format is: d00ddd110000, where a "d" is a don't-care state (0 or 1).
    • inputs
      • D: data in
    • outputs
      • Err: active-high error flag
  • shift out 15
    • This block is a 15-bit shift-out register with asynchronous, active-low reset and a shift/load toggle. Custom inputs load the address (MSB first) as the first 3 bits and the data as the last 12 bits. Idle output is a zero.
    • inputs
      • CLK: clock
      • Rst: asynchronous, active-low reset
      • Sh/Ld: shift/load toggle; active-high shift enable, active-low load enable
      • D: data in
      • A: address in
    • outputs
      • Q: data out

Controller (A)

File:ADC Controller Block.JPG
ADC controller functional block diagram

The functional block diagram for the controller is shown to the right. The blocks are:

  • counter
    • This block is a 5-bit counter. It counts out 17 cycles: from the idle state, a pulse on the Go line begins a count of 16 cycles (during which time CS is low), then on the 17th cycle re-enters the idle state to await another pulse on Go. The Go line is ignored during a 17-cycle run.
    • inputs
      • CLK: clock
      • Rst: asynchronous, active-low reset
      • Go: pulse to leave idle state
    • outputs
      • CS: active-low chip select
  • delayer
    • This block is a single-cycle signal delayer.
    • inputs
      • CLK: clock
      • D: signal to be delayed
    • outputs
      • Q: delayed signal
  • shift out 12
    • This block is a 12-bit shift-out register with asynchronous, active-low reset and a shift/load toggle. Custom inputs load the write bit and address bits, then fill in the remaining bits (W00AAA110000). The register drags a trailing zero. The output idles at zero when output is not enabled.
    • inputs
      • CLK: clock
      • Rst: asynchronous, active-low reset
      • Sh/Ld: shift/load toggle; active-high shift enable, active-low load enable
      • D_W: write bit input
      • D_A: address bits input
    • outputs
      • Q: serial output
  • shift in 15
    • This block is a 15-bit shift-in register with asynchronous, active-low reset and shift enable. Custom outputs select the address bits and data bits.
    • inputs
      • CLK: clock
      • Rst: asynchronous, active-low reset
      • Sh: shift enable
      • D: data in
    • outputs
      • A: address out
      • Q: data out

Ethernet controller

Interface (E)

See also: Ethernet packets

Emulator (E)

Controller (E)

Reset and Initialization

On start-up the FPGA must reset and initialize each component; especially the Ethernet controller. Functionality will also be supplied to reset the system on a command from the PC.

The DAC

The AD5535 DAC has an active-low reset pin. Pulling that pin low will reset the DAC, zeroing all channels.

The temperature sensor

The AD7314 temperature sensor does not have a reset function. It self-initializes on powering up.

The ADC

The AD7928 ADC does not have a reset pin, but does require that certain internal registers be reset upon powering up. The reset procedure is to hold the Din line high while performing two dummy conversions. During both dummy conversions, as well as the third conversation (during which good data can be loaded), invalid data will be returned to the FPGA. It may be worth considering adding a third conversion to the startup procedure that sets the control register to a certain known setting according to our specifications; perhaps setting the next conversion to return channel zero simply as a known point of operation.

The Ethernet controller

The CP2200/1 has a complex reset process, which is laid out in detail in the data sheet (see section 6.2 "Reset Initialization"). The main points of the process will be covered here.

  • The first step is to wait for the reset pin to rise. No flag will be raised upon the completion of this step other than the reset pin (which is an input to the CP2200/1) being high.
  • The second step is to wait for Oscillator Initialization to complete. Completion of this will be signaled by an interrupt request signal.
  • The third step is to wait for Self Initialization to complete. Completion of this will also be signaled by an interrupt request signal.
  • At this point all interrupts will be enabled. Any interrupts which the FPGA will not handle should be disabled now.
  • The physical layer must be initialized, which is itself a multi-step process.
    • See section 15.7 "Initializing the Physical Layer"
    • If auto-negotiation is to be used see section 15.2 "Auto-Negotiation Synchronization."
  • Enable the Link, Act, or Activity/Link LED(s).
  • The MAC must now be initialized, another multi-step subprocess.
    • See section 14.1 "Initializing the MAC."
  • The receive filter must now be configured.
    • See section 12.4 "Initializing the Receive Buffer, Filter and Hash Table."
  • The CP2200/1 is now ready for regular operation.

This process should be used sparingly because (1) it is a long, complex process that renders the board unusable for a short time and (2) while the CP2200/1 is initializing the board and the PC are unable to communicate.