Register map for LLRF FPGA, offset 0x40000000 in StrongARM memory map. All registers are 16 bits, but should be read and written as 32-bit quantities with the upper short unused. This is an artifact of using only 16 wires of a 32-bit muxed address/data bus. Keys in [brackets] refer to notes below. 0x0000 RO Product code 0x7702 0x0004 RO Firmware version code 0x0008 RO Status: lsb 0 gray_previous(0) 1 gray_previous(1) 2 gray_sample(0) 3 gray_sample(1) 4 0 5 KCM_load_busy 6 SYNC [1b] 7 RF_ON 8 IL_STAT [1a] 9 PLL_MUXOUT [1a] 10 0 11 dds_unadjustable_config 12 feedforward_config 13 test_buffers_config 14 gen2_board_config msb 15 feedback_config 0x000c RO Errors (atomic clear on read): lsb 0 channel D overflow 1 channel C overflow 2 channel B overflow 3 channel A overflow 4 clk40_missing 5 ext_trigger_skipped 6 sync_missing [1b] 7 sync_error [1b] 8 handshake_error [6] 9 pll_unlocked [1a] 0x0010 XX Number of pulses since last read of this register 0x0014 RO Counter at last trace buffer write 0x0018 WO DDS Frequency (signed, 16 bits, +/- 625kHz full scale) 0x001c RW DS2401 [1a] [7] 0x0020 WO I setpoint (signed, 14 upper bits) 0x0024 WO Q setpoint (signed, 14 upper bits) 0x0028 WO Config: lsb 0 trace_enable 1 phase_sense_adjust [1b] 2 rising_edge_decay 3 continuous_feedforward 4 ignore_rf_off 5 self_retrigger 6 halt 7 trace_sel(0) 8 trace_sel(1) 9 feedback_select 10 integrate_select 11 RF_KILL 12 iq_hand_flip [1b] 13 test2 14 test3 15 test4 0x002c WO trace buffer decimation: lsb 0 bit 2 is counter 2 vs. counter 10 1 bit 3 is counter 3 vs. counter 11 2 bit 4 is counter 4 vs. counter 12 3 bit 5 is counter 5 vs. counter 13 4 bit 6 is counter 6 vs. counter 14 5 bit 7 is counter 7 vs. counter 15 0x0030 - 0x003c XX 0x0040 WO KCM-50MHz-interpolator (-0.707 nominal) 0x0044 WO KCM-real (signed, 12 upper bits) [8] 0x0048 WO KCM-imag " [8] 0x004c WO KCM-integrator " [8] 0x0050 WO KCM-unused4 0x0054 WO KCM-unused5 0x0058 WO KCM-unused6 0x005c WO KCM-unused7 0x0060 RW Serial transaction: MAX1202 0x0064 RW Serial transaction: MAX5742 0x0068 XX Serial transaction: unused 0x006c RW Serial transaction: ADF4001 0x0070 RW Serial transaction: TCN75 0x0074 XX Serial transaction: unused 0x0078 XX Serial transaction: unused 0x007c XX Serial transaction: unused 0x0080 RW length of state 1 (idle) [2a] 0x0084 RW time until end of state 7 (inhibit retrigger) [2b] 0x0088 RW length of state 3 (ADC warmup) [2a] 0x008c RW length of state 4 (feedforward only) [2a] 0x0090 RW length of state 5 (feedback) [2a] 0x0094 RW length of state 6 (acquire decay curve) [2a] 0x0098 RW unused 0x009c RW length of state 0 (wait for trigger) [2b] 0x00a0 - 0x00fc XX 0x0100 - 0x01fc XX stepper controller 0x3000 - 0x37fc RW 512x8 (1 BRAM) feedforward table 0x4000 - 0x4ffc RO 1024x12 (3 BRAM) decay buffer [5] 0x5000 - 0x7ffc XX 0x8000 - 0x8ffc RO 1024x11 (8/3 BRAM) channel A trace buffer 0x9000 - 0x9ffc XX 0xa000 - 0xaffc RO 1024x11 (8/3 BRAM) channel B trace buffer 0xb000 - 0xbffc XX 0xc000 - 0xcffc RO 1024x10 (8/3 BRAM) channel C trace buffer 0xd000 - 0xfffc XX XX -- not implemented RO -- Read Only WO -- Write Only RW -- Read and Write [1a] Not implemented on Rev. 1 hardware [1b] Not implemented on Rev. 2 hardware [2a] Time in units of 100 ns (4 40 MHz clock periods) [2b] Time in units of 400 ns (16 40 MHz clock periods) [3] Write 7 bits of MAX1202 configuration, Read 12 bits of ADC result and 1 bit of "cycle complete" [4] Write 16 bits of MAX528 configuration and data, Read 1 bit of "cycle complete" [5] Input channel selected by trace_sel in config register [6] A write to the error register 0x000c sets the handshake token. The software is expected to write to the error register (0x000c) (the data is ignored) at the beginning of its xfer_from_fpga routine, which is triggered by the interrupt. This puts the handshake logic into "armed" mode, where handshake_token=1. If an RF pulse comes along in this mode, the handshake_error bit is set. The xfer_from_fpga routine will read from error register as the last thing it does, which both finds out if it acted fast enough to not get corrupted data, and sets handshake_token back to 0, so the handshake logic won't complain when the next RF pulse hits. [7] write bits, lsb last: write_data2, write_data1, reset, run read bits, lsb last: count, run, read_presence, read_data To reset: write 0010; wait at least 480 us; write 1101; wait at least 480 us; check read_presence bit To write a bit (b): write b001; poll until run==0 To read a bit: write 1001; poll until run==0, use read_data Note that the output is the same for reading a bit and writing a 1. This is correct. read_data should be 1 after writing a 1. [8] Scaling on KCM registers goes like this: Assume KCM-real = gain * cos(theta), KCM-imag = gain * sin(theta). When gain is maximum (enough to peg KCM-real when theta is 0 or 180, or KCM-imag when theta is 90 or 270), the actual gain from input ADC to output DAC is 0.5. Before 2003-03-02, the maximum gain was 0.25. KCM-integ is scaled such that a full scale positive setting adds 1/16 of the non-integrated output every 100 ns. This places a zero in the transfer function at 0.625e6 radians/sec, or 99.472 kHz. For the raw 12-bit input, the lsb is therefore represents a zero location of 99.472 kHz/2048 = 48.5702 Hz. For the mythical 16-bit signed representation used by the software (of which the 4 lsb are discarded), the zero location is bits * 3.0356384 Hz. Although KCM-integ shares its logic with KCM-real and KCM-imag, and is therefore (like them) signed, it is a big mistake to ever set KCM-integ to a negative value. One final note: it is normally considered good form, when designing a register-based interface like this, to have all writable registers also readable, so the software can verify state. There are a number of good reasons for this practice, but I assert they are insufficient in the context of an FPGA. Hence, the various "WO" entries above. Argument 1: It can expose hardware failure. Rebuttal: Quite true, and enough readback has to be present to detect all forms of manufacturing error or other physical defects outside the FPGA core itself - burnt pins, shorted and open wires -- that could interfere with proper connection between the CPU and the FPGA. After that is done one time, properly, all the internals of the FPGA can be assumed good. In this specific case, the ability to read and write bit patterns from a single 16-bit register is sufficient proof of the linkage. I have the EPICS server process go through this test every time it starts up. Argument 2: It allows multiple software components to share the hardware without confusion. Rebuttal: So don't write software that gets confused! The job of controlling LLRF is sufficiently simple that a single process, the EPICS server, can do all and see all. It can keep internal state that mirrors the values written to hardware. As long as it synchronizes the hardware to those values on startup, everything will work correctly and predictably. Besides, multiple software components sharing a single register is a disaster waiting to happen even _with_ readback. By the time you add the semaphores or other atomic test-and-set capability, you might as well use a copy of the register value in local memory anyway. The real value in sharing amongst software components is to partition function within the chip. The register map above does support that concept: each register and/or subsystem shares no state with any other register or subsytem (if you find something that you wish was more orthogonal, e.g., subdividing error or configuration registers, let me know). That orthogonality and lack of superfluous state has nothing to do with register readback. Argument 3: But it's so easy! Rebuttal: In VLSI, maybe, but not in an FPGA. Every additional bit of readback adds a logic cell to the design, and that adds up fast. Even in a large FPGA with cells to burn, the additional routing demands can slow down the data path.