FEBEX4A memory map
Addresses in FEBEX are not unique only a few bits of the address are used to generate semaphores which mux different modules to the GOSIP address and data bus. In the user.c supplied by GSI don’t care (‘x’) is sent over GOSIP as ‘0’ which seems a sensible convention and will be used in this document. In this document the FEBEX internal address is shown on the left and the GOSIP address on the right. The difference between the two addresses is caused by a non-circular two place right shift applied to GOSIP addresses when they enter FEBEX (the lowest two bits are ignored).
SEL_BUF0[0]:
0000 0000 0000 0000 0000 => (0x00)
SEL_BUF0[1]: 0000 0010
0000 0000 0000 => 0000 1000 0000 0000 0000 (0x8000)
SEL_BUF0[2]:
0000 0100 0000 0000 0000 => 0001 0000 0000 0000 0000
(0x18000)
SEL_BUF0[3]: 0000 0110 0000 0000 0000 => 0001 1000
0000 0000 0000 (0x18000)
SEL_BUF0[4]: 0000 1000 0000 0000 0000
=> 0010 0000 0000 0000 0000 (0x20000)
SEL_BUF0[5]: 0000 1010
0000 0000 0000 => 0010 1000 0000 0000 0000 (0x28000)
SEL_BUF0[6]:
0000 1100 0000 0000 0000 => 0011 0000 0000 0000 0000
(0x30000)
SEL_BUF0[7]: 0000 1110 0000 0000 0000 => 0011 1000
0000 0000 0000 (0x38000)
SEL_BUF0[8]: 0001 0000 0000 0000 0000
=> 0100 0000 0000 0000 0000 (0x40000)
SEL_BUF0[9]: 0001 0010
0000 0000 0000 => 0100 1000 0000 0000 0000
(0x48000)
SEL_BUF0[10]: 0001 0100 0000 0000 0000 => 0101 0000
0000 0000 0000 (0x50000)
SEL_BUF0[11]: 0001 0110 0000 0000 0000
=> 0101 1000 0000 0000 0000 (0x58000)
SEL_BUF0[12]: 0001
1000 0000 0000 0000 => 0110 0000 0000 0000 0000
(0x60000)
SEL_BUF0[13]: 0001 1010 0000 0000 0000 => 0110 1000
0000 0000 0000 (0x68000)
SEL_BUF0[14]: 0001 1100 0000 0000 0000
=> 0111 0000 0000 0000 0000 (0x70000)
SEL_BUF0[15]: 0001
1110 0000 0000 0000 => 0111 1000 0000 0000 0000
(0x78000)
SEL_BUF0[16]: 0010 0000 0000 0000 0000 => 1000 0000
0000 0000 0000 (0x80000)
SEL_BUF1[0]:
0100 0000 0000 0000 0000 => 0001 0000 0000 0000 0000 0000
(0x100000)
SEL_BUF1[1]: 0100 0010 0000 0000 0000 => 0001 0000
1000 0000 0000 0000 (0x108000)
SEL_BUF1[2]: 0100 0100 0000 0000
0000 => 0001 0001 0000 0000 0000 0000 (0x118000)
SEL_BUF1[3]:
0100 0110 0000 0000 0000 => 0001 0001 1000 0000 0000 0000
(0x118000)
SEL_BUF1[4]: 0100 1000 0000 0000 0000 => 0001
0010 0000 0000 0000 0000 (0x120000)
SEL_BUF1[5]: 0100 1010 0000
0000 0000 => 0001 0010 1000 0000 0000 0000
(0x128000)
SEL_BUF1[6]: 0100 1100 0000 0000 0000 => 0001 0011
0000 0000 0000 0000 (0x130000)
SEL_BUF1[7]: 0100 1110 0000 0000
0000 => 0001 0011 1000 0000 0000 0000 (0x138000)
SEL_BUF1[8]:
0101 0000 0000 0000 0000 => 0001 0100 0000 0000 0000 0000
(0x140000)
SEL_BUF1[9]: 0101 0010 0000 0000 0000 => 0001 0100
1000 0000 0000 0000 (0x148000)
SEL_BUF1[10]: 0101 0100 0000
0000 0000 => 0001 0101 0000 0000 0000 0000
(0x150000)
SEL_BUF1[11]: 0101 0110 0000 0000 0000 => 0001
0001 0101 1000 0000 0000 (0x158000)
SEL_BUF1[12]: 0101 1000
0000 0000 0000 => 0001 0110 0000 0000 0000 0000
(0x160000)
SEL_BUF1[13]: 0101 1010 0000 0000 0000 => 0001
0110 1000 0000 0000 0000 (0x168000)
SEL_BUF1[14]: 0101 1100
0000 0000 0000 => 0001 0111 0000 0000 0000 0000
(0x170000)
SEL_BUF1[15]: 0001 1110 0000 0000 0000 => 0001
0111 1000 0000 0000 0000 (0x178000)
SEL_BUF1[16]: 0010 0000
0000 0000 0000 => 0001 1000 0000 0000 0000 0000 (0x180000)
This limits the memories to 32768 addresses, the actual memories are dual ported 32 bit wide with 4096 addresses (32bit GOSIP side) and 8192 (16bit ADC side), going over range will result in access looping back to the start of the memory. Both memories (buf0/1) have the same data inputs which are a_out_reg[i] where i is the memory number, they should contain identical data. The a_out_reg[i] is a_out signal originating from dataout of ringbuf_14b. We have verified that the data input to ringbuf_14b is ADC data so it follows that this is also the data on a_out.
(INTERNAL FEBEX ADDRESS) => (GOSIP ADDRESS – used by GOC E.T.C)
1000 0010 0000 0000 0000 => 0010 0000 0000 0000 0000 0000 (0x200000)
reg_data <= {29'b0,mem_sel[1:0],ctl_reg[0]};
buf0_adc_ws[1] <= mem_sel[0]; buf1_adc_ws[1] <= mem_sel[1]; also drives or is driven by mem_sel ports on ringbuf_14b modules. This is part of double buffering functionality that is not enabled currently in the FEBEX firmware.
ctl_reg[0] goes to restn of event_control module, setting to ‘0’ resets the event controller. It also drives rstn of ringbuf_14b
ctl_reg[7:0] <= dpm_data_in[7:0];
1000 0000 0000 0000 0001 => 0010 0000 0000 0000 0000 0100 (0x200004)
reg_data <= {16'b0,del_reg};
del_reg is wired to t1in of ringbuf_14b. I think this value is the number of samples before the trigger in a trace, in ringbuf_14b there is the following comment “// max look back is 0x7ff = 2047 samples” in relation to del_reg.
del_reg <= dpm_data_in[15:0];
1000 0000 0000 0000 0010 => 0010 0000 0000 0000 0000 1000 (0x200008)
reg_data <= {16'b0,trlen_reg};
This is wired to t2in of ringbuf_14b I think this determines the number of samples after the trigger in a trace. There is the following comment in ringbuf_14b “// max trace length is 0x3ffe * 10ns = 160µs” this corresponds to 16382 samples.
trlen_reg <= dpm_data_in[15:0];
1000 0000 0000 0000 0011 => 0010 0000 0000 0000 0000 1100 (0x20000C)
reg_data <= {19'b0,dco_delay_mon_0[12:0]};
dco_delay_mon is wired to DCO_DELAY_MON_0 of ADC_Ch16IO_v01 so will allow monitoring of the dco setting that is been used for ADC data reception of ADC0.
dco_del_reg0<= dpm_data_in[0];
1000 0010 0000 0000 0100 => 0010 0000 0000 0000 0001 0000 (0x200010)
reg_data <= {19'b0,dco_delay_mon_1[12:0]}; As above but ADC1.
dco_del_reg1<= dpm_data_in[0];
1000 0000 0000 0000 0101 => 0010 0000 0000 0000 0001 0100 (0x200014)
reg_data <= spi_read_status[31:0]; When performing reads of the SPI bus with the two ADCs on this is the register that holds the data
spi_reg[16:0] <= dpm_data_in[16:0];
1000 0000 0000 0000 0110 => 0010 0000 0000 0000 0001 1000 (0x200018)
reg_data <= {31'b0,time_lock}; broken feature as there is a wire not connected to anything.
time_reg <= dpm_data_in[2:0]; broken as time_reg is not connected to anything
1000 0000 0000 0000 0111 => 0010 0000 0000 0000 0001 1100 (0x20001A)
reg_data <= {4'h0,adc_sel_ch,8'h0,adc_sel_data[1]};
I think this is a slow direct ADC read peripheral used for debug
adc_sel_ch <= dpm_data_in[3:0];
The SPI register is mapped to the address 0x200014. Writing to this address can perform an SPI read or an SPI write. The register is acting as an intermediate access mechanism to a bus with its own addressing external to the FPGA. If an SPI read is performed the results can subsequently be found by reading this address.
LIPC-1 mbsdaq > goc -w -x 1 0 0x200014 0x10100
LIPC-1 mbsdaq > goc -r -x 1 0 0x200014
0x18f018f
This example is reading the chip ID of the two ADCs. The first command issues a read of address 0x01, first nibble (0x1) sets read, next two nibbles address and last two nibbles ignored (as this is a read). The second command reads the returned data; this is 8F for both chips. The 0x1 and 0x01 is additional data left in the register from the previous command and should be ignored.
Command sequence to put the ADCs into checkboard pattern mode:
goc -w -x 1 0 0x200014 0x00D04
goc -w -x 1 0 0x200014 0x100D04
goc -r -x 1 0 0x200014
0xd040d04
Details of the ADC (AD9681) registers and addresses can be found in its data sheet. Currently the only register that is set to a non-default value known about in FEBEX is 0x14 (output mode) which is set to 0x00 to change from twos complement to offset binary format. Both ADCs are written to at the same time so it’s impossible for them to have different settings.