Altera firmware

From ExtraTerrestrik

Contents

[hide]

Altera Cyclone 3

The FPGA is documeted in the Altera Cyclone 3 Handbook. We chose the biggest Cyclone 3 that comes in a 144 pin package, an EP3C25. It features:

  • 24624 locic elements,
  • 66 M9K memeory blocks, i.e., about 66 kByte,
  • 66 18x18 multipliers,
  • 4 PLLs,
  • 20 global clock networks,
  • 82 user IO pins,
  • 6 LVDS IO, and 8 LVDS clk inputs

The logic is compiled into a raw binary file, which is uncompressed 5,800,000 bits. The compressed files are about ΒΌ Mbyte.

Tools

The logic in the FPGA is programmed in a Hardware Description Language (HDL). We use Verilog. Other options are VHDL or Alteras own HDL, or even schematic entry, We use Verilog.

Synthesis

To compile the logic we need to use the Quartus II software from Altera. The Makefile includes commands to compile the design without running the GUI. The output format is compressed raw binary file.

Some Megafunction Wizards do not work properly in Linux, but when those are done, Windows is not required. Megafunctions are needed to use the PLLs, memory block, and multipliers.

Simulation

Our designs are entered in Verilog and simulated with Icarus Verilog, the simulation results are viewed with GTKWave.


The frontend module

This is somewhat backwards. From the FPGA point of view it is the backend module. The module provides the interface to the ARM and some infrastructure for the core.

mclk

The core logic must run on a PLL derived clock with a frequency well higher than the SPI interface clock from the ARM, i.e., 30MHz. A megafunction module called pll96 is provided to generate a set of clock freuencies: 8, 12, 24, 48, and 96 MHz. Any other frequency well above 30 MHz will do. For lower core frequencies, we either need to run the SPI on the ARM at a lower bit rate, or run the frontend module on a different clock than the core.

spi_slave

This module receives SPI frames from the ARM and translates then into commands. A command is issued synchronous to the the core clock. The responses are captured synchronous to the core clock into a 2k word spififo. The spi_slave module performs the clock domain transitions.

command format

A command is issued on four outputs from the module:

  • we: is high for one cycle
  • wp: is high when the command has a parameter
  • wa[13:0]: command address
  • wd[15:0]: command parameter.

wp, wa, and wd can be sampled when we is high, but stay valid for a good part of half a microsecond.

Typically, commands with a parameter are considered write commands, while commands without parameter are read commands.

responses

Data that shall be returned to the ARM is pusched into the spififo at any time, via two module inputs:

  • re: high for one cycle for each word.
  • rd[15:0]: data, sampled when re is high.

Typically we do not do any resonse arbitration. All data sources just send data whenever they are triggered to do so. All re and rd[15:0] sources are just or-ed. Collisions are considered a user error.

The frontend provides three fifos for asynchronous data.

registers

The frontend module instantiates a set of register modules, for it's own use and as a service to the core. These registers are accessed by commands from the spi_slave and provide input and outputs to the user.

Core code can instantiate these modules for internal use.

stat_reg module

The stat_reg module is read-only. It is basically a command to return the state of some signal levels.

master_stat

The master_stat instance in the frontend is used to return some frontend status, unused bits can be provided by the core, via the stats module input.

  • address 'h0005: master_stat
  • bits 'h0001: error summary
  • bits 'h00f0: fifos full, f3/f2/f1/hk
  • bits 'h0f00: fifos empty, f3/f2/f1/hk
  • bits 'hf000: fifos have a packet, f3/f2/f1/hk

conf_reg module

The stat_reg module is read/write. It provides 16 bits of output, that can be written and read via SPI. It occupies a single command address. When a parameter is provided, it is written to the conf register. In all cases, the (previous) register status is returned.

spide_reg

This frontend conf_reg defines the data values that shall be returned in SPI frames, when no response data is available.

  • address 'h0002: spide_reg
hksizereg, hkmaskreg, hkhdrvreg

These registers define the properties of packets in the housekeeping fifo.

  • address 'h0018: hksize
  • address 'h0019: hkmask
  • address 'h001A: hkhdrv

cntl_reg module

A cntl_reg module occupies four command addresses, read and write. Read commands all return the state of the control registers. Write commands depend on two address bits. Register bits are set high only with writes when address bit 1 is set. To clear bits in the register, address bit 0 must be set. When both bits are set, all bits in the register are written. When no address bit is set, the command is essentially a read, the parameter is ignored.

master_conf

The master_conf instance in the frontend controls some frontend functions, the (other) bits can be used by the core, through module output confs.

  • address 'h0008: master_conf read
  • address 'h0009: master_conf clear bits
  • address 'h000a: master_conf set bits
  • address 'h000b: master_conf write
  • bits 'h0008: clock enable
  • bits 'h00f0: fifos enable, f3/f2/f1/hk
  • bits 'h0100: fifos to ssp disable (clear for streaming)
  • bits 'h0200: frontend to ssp disable (set for streaming)
  • bits 'h0400: core to ssp disable (set for streaming)

error_reg module

The error_reg module reads or resets the status of latches. When an input bit is high, the corresponding bit in the error register is set. It stays set until a 1 is written to the register bit.

master_errc

The master_errc instance has a few unused bits that can be used by the core through the errors module input.

  • address 'h0006: master_errc
  • bits 'h0001: spi_overflow
  • bits 'h00f0: fifos were full, f3/f2/f1/hk
  • bits 'h0f00: fifos were empty, f3/f2/f1/hk
  • bits 'hf000: fifos had a packet, f3/f2/f1/hk

cntr_reg module

A cntr_reg module implements a 32-bit counter. It occupies four command addresses. The address bits control which half of the counter is accessed, and if the access latches.

  • read 00: copy counter to latch, read low word of latch
  • read 01: copy counter to latch, read high word of latch
  • read 10: read low word of the latch
  • read 11: read high word of the latch
  • write 00: write low word of latch
  • write 01: write high word of latch
  • write 10: write low word of latch, copy latch to counter
  • write 11: write high word of latch, copy latch to counter
master_clock

The master_clock instance counts ticks provided by the core, gated by the clock_enable bit in the master_conf register. The core may tie tick high, to count mclk cycles. The core can read the clock through the clock module output.

  • address 'h000c: master_clock low, little endian
  • address 'h000d: master_clock high, big endian
  • address 'h000e: master_clock low, big endian
  • address 'h000f: master_clock high, little endian

packetfifo module

The frontend module provides four packetfifo instances. The housekeeping fifo is fed by commands via SPI. The other three fifos are fed by the core. Each packetfifo can store 2k words. (It is based on an spi_fifo module instance.)

A fifo_read command (address 'h8000) triggers the transfer of a data packet from a packet fifo to the spi_fifo. The packet fifos are checked in priority order. The first one that is enabled by the master_conf register and (thinks) it has a complete packet inside will dump the whole packet to the SPI. Fifo responses must not be disabled in the master_conf register bit 8, else the data will drop into the bitbucket.

packet size

Each packetfifo has a packet size assigned to it. This can be a constand, hardwired by the core, or some register or logic. The packet size is one word more than the number on the psize module input. As soon as that many word are stored in the fifo, the packet is considered complete. Header syncing may invalidate this assumption.

packet header

To provide some limited synchronization of the packet bouindaries, a packet fifo will scan for a packet header word. Words preceding a valid header word are not counted towards the packet size while a packet is sent to SPI. The fifo may run out of words before the packet is complete, since it volunteered to send a complete packet before checking the header.

The header specification consists of a mask and a value word. The masked data word must match the value. If the mask and value are zero, effectivle not header checking is performed. All words match.

If any value bit is set while the corresponding mask bit is not, no header matches, and the fifo is completely drained, possibly overflowing the spi fifo.

Housekeeping fifo

The highest priority fifo is not available to the core, but shall be used by ARM software to inject (housekeeping) packets into the telemetry stream. Registers define packet size and header.

Core fifos

The core must provide packet size and header parameters for three fifos, and write 16-bit wide data into the fifo inputs.

fifo_full outputs are provided to the core, that flag when less that a packet of free space remains in the fifo. fifo_full shall decide if a packet is started, but not prevent the completion of a partially submitted packet.