Awhile ago I wrote about the time I've been investing on designing an image sensor and its column-parallel ADCs in particular. If we know each other well chances are I've been moaning your years about that chip for a long time. Well, they ARE here! Alive! With practically no functional bugs such as inverted signals or wrong connections whatsoever! I might say that this device actually turned out pretty successful, especially considering that every single circuit inside was built all from scracth in a sharp tapeout deadline!
Of course there are a few glitches here and there, but thank goodness it's nothing critical. Besides I haven't seen a first time right image sensor yet, requiring no mask tweaking.
Let's not wait any longer. Here's a very quick and preliminary summary of my measurement adventures so far. And... sorry folks, the striptease will be next time, when I plan to reveal some of the circuits inside. Unfortunately due to some harsh journal pre-publication and disclosure rules I don't really want to get into trouble just yet.
To start with, here's a picture of the chip and the board itself:
It took quite awhile getting the board back with some iteraitons from the bonding vendor, despite the nice bonding diagrams sketched. Nevertheless, turns out bonding and ESD finally turned out to be successful. Hehe, well, I have some infant mortality in a few boards where the bonding operator has forgotten to weld a group of wires. Perhaps he thought the chips may miraculously work without a signal or two?
You may wonder what's with all these bond wires? Why so many (170)? Actually most of them are redundant power supply pads. The bottom side of the chip contains 16 LVDS output data pairs i.e. 32 pins, one pair LVDS clock in used for the serialization and SRAM readout. In-between the LVDS pairs there are power pads supplying the columns. Indivitual Analog (3.3V), Digital(1.5V), and IO (LVDS, 1.5V). The right side of the chip has another LVDS clock input used for the fast count clock 266 MHz, split power supply for the voltage references bias and control. The control signals for the sensor are on the right and top side, a few pins for the SPI and bias trim. Everything else is used for supplying the matrix with isolated from the ADC power and ground. To recap, here's a coarse high-level diagram:
The digital test system is based on a Xilix Spartan 6 LX150 FPGA, controlling a Cypress FX3 USB 3.0 chip for the high-speed ADC data transmission to the ADC. Even so, the bottleneck to reading out the chip at its highest rate is the USB 3.0 link and not the chip itself. Perhaps a PCI-Express protocol would have suited the applicaiton better.
The ADC board has AD8620 14-bit DACs which are used for providing test sweep voltages to the ADC. An ADC used for measuring the power drawn by the separate supplies, which are driven by a few fixed-voltage LDOs. There are also voltage translators to 1.5 V as the FPGA's banks operate on 1.8 V minimum.
It took me over three months to setup the FPGA and readout to the PC. The FPGA contains a few elemental blocks:
1. An UART Rx/Tx module which I use for preloading various settings and data to the FPGA. The module is bit-banged and re-used from a lab assignment during my MSc university days.
2. A bit-banged SPI module specifically tailored to the SPI register inside the testchip.
3. A bit-banged SPI module for the AD8620 DACs
4. A 4 kB block RAM with asynchronous write/read capability. The RAM contains the sequencer data and is preloaded via the UART module.
5. 16 hardware 1:6 deserializers (ISERDES), with automatic phase alignment of the strobation pulse and automatic bitslip module based on the received training pattern from the chip.
6. Two 12288 kbit frame line FIFO buffers which allow for fully pipelined ADC SRAM readout.
7. A transmission header combinarion module.
8. Control state machine for the FX3 GPIIF interface.
The FPGA without any readout software is useless. I use the in-house viewer at the company I was hosted for capturing images over the USB, while the register programming and sequener I had to design myself. To ease life with configuring the chip registers I created a tiny Java GUI calculator? which allows me to enable or disable the various on-chip registers. I also use it for controlling the DAC voltages and well as some of the FPGA internals. Its backend is written in bash and practically controls the corresponding UART device via the /dev folder.
Being able to easily change the chip's timing is one of the most important things in chip testing. My initial solution for a sequencer was to use hard-coded state machines on the FPGA. Such scheme however, is extremely hard to tune or tweak, making it impractical. To improve flexibility, I designed a tiny assembler, decoding my custom instructions controlling each individual (or combined) signals. Nothing extraordinary but a perl script parsing my assembler files, translating them to a binary stream, which is then fed via the same UART backend to the FPGA and ultimately the block RAM.
Here is a sample of the instruction set
;|------------------------------------------------------------------| ;| Instruction List and Function | ;|------------------------------------------------------------------| ;| ROW 0x00 1/0 - set row_rs | ;| ROW 0x01 1/0 - set row_rst | ;| ROW 0x02 1/0 - set row_tx | ;| ROW 0x03 1/0 - set col_bias_sh | ;| ROW 0x04 1/0 - set row_next | ;| SHX 0x00 1/0 - set shr | ;| SHX 0x01 1/0 - set shs | ;| ADX 0x00 1/0 - set adr | ;| ADX 0x01 1/0 - set ads | ;| COM 0x00 1/0 - set comp_bias_sh | ;| COM 0x01 1/0 - set comp_dyn_pon | ;| CNT 0x00 1/0 - set count_en | ;| CNT 0x01 1/0 - set count_rst | ;| CNT 0x02 1/0 - set count_inv_clk | ;| CNT 0x03 1/0 - set count_hold | ;| CNT 0x04 1/0 - set count_updn | ;| CNT 0x05 1/0 - set count_inc_one | ;| CNT 0x06 1/0 - set count_jc_shift_en | ;| CNT 0x07 1/0 - set count_lsb_en | ;| CNT 0x08 1/0 - set count_lsb_clk | ;| MEM 0x00 1/0 - set count_mem_wr | ;| REF 0x00 1/0 - set ref_vref_ramp_rst | ;| REF 0x01 1/0 - set ref_vref_sh | ;| REF 0x02 1/0 - set ref_vref_clamp | ;| REF 0x03 1/0 - set ref_vref_ramp_ota_dyn_pon | ;| SER 0x00 1/0 - set digif_seraial_rst | ;| LOAD PAR - load follow-up instructions to buf register | ;| SET PAR - set the loaded in buf register to output | ;| START - initialize output register to 0x0000 | ;| NOP - NOP operation (stall) one cycle | ;| NOP n - NOP operation (stall) n cycles | ;| FVAL 0x00 1/0 - frame valid | ;| LVAL 0x00 1/0 - line valid | ;|------------------------------------------------------------------|
Here comes the interesting part. The ADCs can be run at 1us ramp time, which is as designed, and achieve a noise variance of about 1.6 LSB at 1x gain. According to the preliminary histogram tests with a sinewave from the soundcard from my laptop and buffered via a, perhaps not so linear opamp, provides a monotonic response and DNL of less than 1 LSB. It would be desirable to be less than 0.5 LSB, however, I see tiny glitches popping up beyond 0.5 LSB. The root cause for this may likely be a poor duty cycle ratio of the count clock, as my architecture relies on a sharp clock with 50 % duty cycle. But for that I shall investigate further. The ADCs consume 35ish mW from the digital supply (1.5V) and about 100mW from the analog (3.3).
Here are some preliminary fancy pictures, starting with a noise histogram:
The noise may perhaps be dampened further, as the PCB itself can not boast with being the best low-noise design. The external DACs used for feeding in the input voltage use the power supply as a voltage reference (via a low-pass filter of course), which is horrendous circuit design practice.
Here is a posh 3D code distribution histogram for the columns in the first ADC group of 128. Shown is a bathtub distribution produced by feeding in an input sinewave to the columns.
You can see some stairs here:
To prove that the digital correlated double sampling works, here is the mean value of all columns under a uniform voltage input:
The pixel array also works and I can successfully acquire blank images. The pixel sequencer needs tuning so as to eliminate some strange column FPN artefacts. I also plan on attaching better lens, as the current ones are probably the worst possible choice for a sensor with a small size as the current.
Finally, just wanted to mention that this is work in progress, so stay tuned for more updates in the nearby months. But please lower your expectations for design details. I need to make sure this work is accepted in some of the major journals before publishing anything here. Sorry folks, it will come eventually.
Warning: require(comments.php): failed to open stream: No such file or directory in /home/transist/public_html/post/stdal/post63.htm on line 273
Fatal error: require(): Failed opening required 'comments.php' (include_path='.:/usr/lib/php:/usr/local/lib/php') in /home/transist/public_html/post/stdal/post63.htm on line 273