The addressing scheme is described in the following table:
VME Address bits |
Usage |
Comment |
23:19 |
VME Slot |
Compared to VME_GA[4:0] inverted |
18:15 |
VSR=0, XTOP=1, XBOT=2, FTOP=4, FBOT=5, ITOP=6, IBOT=7, SLB1-6=8-13 | |
14:0 |
Localbus Address |
Direct 1:1 mapping |
#define HTR_VSR 0x0 #define HTR_XILINX_TOP 0x8000 #define HTR_XILINX_BOT 0x10000 #define HTR_FLASH_TOP 0x20000 #define HTR_FLASH_BOT 0x28000 #define HTR_IND_TOP 0x30000As an example, if you have a HTR in VME Slot 4, and you want to do a read or a write to Localbus address 0x20 on the TOP Xilinx, you would build the VME addressing in the following way:#define HTR_IND_BOT 0x38000 #define HTR_SLB_1 0x10000 //or equivalently, (SLB+7)<<15 where 1<=SLB<=8 is the SLB number
int vme_slot = 4; int localbus_address = 0x20; int VME_A = vme_slot<<19 + HTR_XILINX_TOP + localbus_address;
Name | Value | R/W | Bits | Comments |
ID | 0x00 | R | 24 | Returns 0xEDCAFE, indicates HTR present in the slot |
Reset | 0x04 | W | none | Causes internal reset (limited use, mostly for XILINX config reset) |
Configure TOP | 0x08 | W | none | Initiates configuration of Xilinx TOP from TOP FLASH |
Version | 0x0C | R | 24 | VME FPGA firmware version |
Status Register | 0x10 | R | 24 | Concatenation of internal bits (see below) |
Configure BOTTOM | 0x14 | W | none | Initiates configuration of Xilinx BOTTOM from BOTTOM FLASH |
Test Register 1 | 0x18 | R/W | 24 | Test I/O |
Test Register 2 | 0x1C | R/W | 24 | Test I/O |
TOP XILINX FLASH CRC | 0x20 | R | 24 | Read the 24-bit CRC calculation for the TOP flash |
BOT XILINX FLASH CRC | 0x24 | R | 24 | Read the 24-bit CRC calculation for the BOT flash |
TOP Indirect Global Address | 0x28 | R/W | 9 | Sets the indirect global (page) register for the TOP Xilinx |
BOT Indirect Global Address | 0x2C | R/W | 9 | Sets the indirect global (page) register for the BOT Xilinx |
TTCrx I2C_{data[], dir, address[6:0]} | 0x34 | R/W | 16 | I2C bus to TTCrx (probably bad, missing pullup resistors) |
TTCrx I2C_start | 0x38 | W | 1 | I2C bus to TTCrx (probably bad, missing pullup resistors) |
TTCrx I2C_{start, busy, success, DOut[7:0]} | 0x3C | R | 11 | I2C bus to TTCrx (probably bad, missing pullup resistors) |
HTR_ID | 0x40 | R | 9 | HTR ID = SN on the label |
Name | VME_A bit | R/W | Bits | Comment |
Reset Internal Address Pointer | VME_A[2] | W | None | Resets the internal Flash address to zero |
Write Data | VME_A[3] | W | 8 | Writes VME_D[7:0] into Flash using internal Address Pointer |
Read Data | VME_A[4] | R | 8 | Reads one byte from Flash using internal Address Pointer, outputs onto VME_D[7:0] |
Flash Reset | VME_A[5] | W | none | Reset FLASH state machine |
Flash Erase | VME_A[6] | W | none | Puts Flash into Erase cycle |
Increment Internal Address Pointer | VME_A[7] | W | none | Increments internal Flash address pointer by 1 |
Read Internal Address Pointer | VME_A[8] | R | 21 | Reads internal Flash address pointer |
The Localbus inside the HTR is a 21-bit addressable bus. However,the VME address bus is restricted to 24 bits total (A24). In addition, the VME address bits 23:19 are reserved for slot identification, bits 18:15 are reserved for Localbus Device selection, and the bottom 2 bits are off limits since we are running in D32 mode. This leaves only 13 bits (14:2) for legitimate addresses. In order to make an address access that has more than 13 bits, we need another scheme. This is the origin of the indirect addressing in the HTR.
So far (as of 2004) the only "devices" inside the HTR which need more than 13 bits of address space are the Look-up Tables (LUTs) and simulated data rams (RAMS) for injecting data into the front-end of the HTR Xilinx (bypassing the TLK2501 deserializers). These are described below:
There are 2 types of LUTS:
This LUT converts from 7-bit QIE data format to 10 bit nonlinear plus the muon bit (11 bits total). This LUT will have the pedestal subtraction, linearity, and sin(q) to convert to transverse energy, resulting in a 10-bit number. The 11th bit is a muon feature bit - describes whether the energy is consistent with that from a minimum ionizing muon. Since there are 7 bits in, this LUT is 7-bit addressable. There are 24 of these LUTs, 1 per QIE channel, and the output of these LUTs are used for the TPGs.
This LUT converts the energy into a form for sending to the SLB and from there to the Level 1 trigger. Since there are 10 bits in, this LUT needs 10 bits in the address field. There are 24 of these LUTs, 1 per TPG channel.
We have the ability to inject data into the HTR to mimic raw data coming up from the Front-end boards. This will allow you to debug without the need of fiber data, if necessary.
There will be 8 RAMS per Xilinx FPGA, 1 per fiber. You write to the indirect address register of the Altera (VSR, see below) (0x28 for TOP and 0x2C for BOT) and in the low 9 bits of the VME data word you put the fiber number (from 0 to 7) + 0x180. The Altera FPGA latches these values. This will tell the Xilinx FPGA which RAM you will be reading from or writing to. Then you write to the relative address (a total of 10 bits, so there are 1024 different RAM addresses).
For example, say you want to read or write to RAM addresses for fiber 2 (8 fibers, 1 to 8) of the TOP Xilinx of the HTR in VME slot 12. The sequence is:
Then, to read from or write into any of the 1024 individual RAM addresses, you read/write to that address over VME (shifted over 2 bits to the left) with the indirect device set. So, with the above example already done (writing 0x181 to 0x600028) say you would like to write 0x5432 to RAM address 0xF, you would write the 0x5432 as VME data to VME address 0x600000 + 0x30000 + (0xF <<2) = 0x63003C.
To use this, we suggest the following sequence (which you can do inside htr):
The following .htr file (htr macro, sent via ./htr -x <file>) will set gaussians to each fiber, with a different gaussian mean and sigma 1 for all 8 fibers, then send a TTC broadcast command ("test") to get things rolling:
slot 12 #or whatever slot you are working in rams #fiber 1 gaussian at 3 width 1 gen 0 3 1 #fiber 2 gaussian at 6 width 1 fiber 2 gen 0 6 1 #fiber 3 gaussian at 9 width 1 fiber 3 gen 0 9 1 #fiber 4 gaussian at 12 width 1 fiber 4 gen 0 12 1 #fiber 5 gaussian at 15 width 1 fiber 5 gen 0 15 1 #fiber 6 gaussian at 18 width 1 fiber 6 gen 0 18 1 #fiber 7 gaussian at 21 width 1 fiber 7 gen 0 21 1 #fiber 8 gaussian at 24 width 1 fiber 8 gen 0 24 1 # now enabl the rams and put in repeat mode control 1 1 quit # now send the ttc command ttc reset bro 20 1 quit quit
Since there are 24 LUTs per type, and 2 types ("Input_LUT" and "Output_LUT"), we need at least 6 bits to determine which LUT we are working with. The Output_LUT needs 10 bits for addressing, which makes 16 bits total. This number exceeds the 13 bits available over VME (see above). To get around this limitation, we defined a "global indirect address" to "point" to which LUT or RAM we are working with, then we do the reads and writes using the "indirect address" for the individual LUT or RAM.
Setting the "Global Indirect Address" is done via a write to the VSR space (Localbus Device = 0). For the TOP Xilinx, you write the global address to the register at 0x28 and for the BOT Xilinx, you write to 0x2C. For example, if you wanted to read/write the global indirect address for the TOP HTR in slot 16, the VME address would be:
16<<19 + 0x0 + 0x28 = 0x01000028
Similary for the BOT xilinx (0x0100002C)
Type | Page Address | Address Size | Data Size |
RAM | 0x180 + fiber number [0-7] | 1024 per fiber | 18 bits {ER,DV,16 bit half of 32 bit QIE word from FE} |
Input LUT | 0x81 + QIE[0-23] | 7 bits per QIE | 11 bits {Feature bit, 10 bits of linearized ET) |
Output LUT | 0x99 + QIE[0-23] | 10 bits per QIE | 8 bits of RCT-type TPG data |
Last Update 10Oct2005 Drew Baden