The TransistoriZed logo should be here! But... curses! Your browser does not support SVG!

homelist of postsdocsγ ~> e-about & FAQ


A mixed-signal testchip sequencer solution

Every mixed-signal system needs some form of a digital sequencing which controls the internal blocks. Typically for test systems it is highly desirable that this sequencer is also flexible. While there are a number of ways of achieveing this, I am sharing a tool and perhaps a solution for generating control signals for testchips based on an external FPGA-based ROM memory block. This approach may not be the most efficient when it comes to silicon real estate or power. However, what I like in this methodology is that it is extremely flexible, and yet is relatively simple to work with. Fiddling with dedicated state machines is perhaps the most efficient methodology but it is a bit more time consuming for inexperienced people in digital design as myself.

To start with, here's an overview of an example system:

An example configuration of a Device-Under-Test sequencer system

An FPGA contains a RAM/ROM block, together with some control circuitry. Pretty simple huh? And it truly is. The UART module clocks-in the memory content to the write and read address generator, which loads the data into the memory. After the memory is initialized, all the address generator does is to loop through the RAM's depth (addresses).

One can generate the RAM block using the IPcore generator in Xilinx's Vivado. If you use other vendors I am sure they would be offering similar tools. What you need to take care of is the memory's width, which is driven by the number of sequener signals you need, as well as its depth — depends on the sequencer resolution you are targeting, as well as its length. For most cases, if you use a large FPGA you shouldn't run out of dedicated memory block space. Here's an example screenshot oof Xilinx's IPcore generator:

Screenshot of Xilix's IPcore memory generator tool.

There's plenty of ways to generate memories with various tools. If one has to write the memory content bit-by-bit it'll take him, perhaps not years, but hours. Fiddling with raw "1/0" text files, boxes, csv, or whatever else is a painful task.

To try and automate things a little bit, I created a tiny assembler instruction interpreter, which compiles memory machine code, which I can then directly load into the memory via the UART. This is currently a work in progress, however, I have put a plenty of code comments, and I've tried to keep things clean. Hehe, well, as much as perl code can be made clean.

The instruction list is currently embedded into the code and remains under the parse_line() subroutine, where you can swap bit posisions, instruction syntax and add new functionality. There are two global definitions in the main() subroutine needed to be taken care of. These are the: \$ram_width and \$ram_depth. The latter define the exact size of the memory file and must match with the ones used during the generation of the IP core, as well as the address length of the memory addresser module. Here's how the memory content file looks like:

 
memory_initialization_radix=2;
memory_initialization_vector=
00000100111010011001111010100000,
00000100111010011001111010100000,
00000100111010011001111010100000,
00000000111110011001100011100000,
00000000111110011001100011100000,
00000000111010011111110011100000,
00000000111010011110110011100000,
00000000111010011110110011100000,
00000000111010011110110011100000,
00000000111010011111110011100000,
...

Each instruction, when called, alters a specific bit (also may be multiple bits) in the memory. Right now the tool has a set of 30ish instructions. Here's a complete list:

 
;|------------------------------------------------------------------|
;| 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                                       |
;|------------------------------------------------------------------|

I tried to kind-of preserve the classic assembler language constructs as much as I could, e.g. comments use ";", to load a signal you start with MOV, then issue the command e.g. ROW followed by its specific bit e.g. 0x01 and finally the value to be written. The NOP instructions stall the system (copy the previous memory line for N cycles), LOAD PAR pushes the next instructions into the PAR register, afterwards SET PAR sets the modified instructions after LOAD PAR, in parallel. Here's a sample code:

START	

;|----------------------------|
;| Initialize startup signals |
;|----------------------------|

LOAD PAR
MOV REF 0x03 1		; ota_dyn_pon always @ '1'
MOV CNT 0x04 1		; count_updn '1'
MOV CNT 0x01 1		; count_rst '1'
MOV CNT 0x05 1		; count_inc_one '1'
MOV CNT 0x08 1		; count_lsb_clk '1'
MOV MEM 0x00 1		; count_mem_wr '1'
MOV FVAL 0x00 1 	; FVAL '1'
MOV COM 0x01 1		; comp_dyn_pon always @ '1'

;|-----------------|
;| Sequencer start |
;|-----------------|

; references and shr sampling
MOV ADX 0x00 1		; adr
MOV SHX 0x00 1		; shr
MOV REF 0x01 1		; ref_vref_sh
MOV REF 0x00 1		; ref_vref_ramp_rst
MOV COM 0x00 1		; comp_bias_sh
SET PAR

NOP 22			; halt 220 ns - phase 1 in vref_ramp

LOAD PAR
MOV REF 0x01 0		; vref_sh
SET PAR
NOP 8			; halt 80 ns
MOV REF 0x02 0		; cla off
NOP 6

; reset counter
LOAD PAR
MOV CNT 0x04 0
MOV CNT 0x01 0
MOV CNT 0x05 0
SET PAR
NOP 2
LOAD PAR
MOV CNT 0x04 1
MOV CNT 0x01 1
MOV CNT 0x05 1
SET PAR
NOP

NOP 52			; halt 520 ns - wait for ramp buffer to settle

MOV SER 0x00 1		; stop data serialization out
NOP 34			; prehalt - wait SHA

MOV SHX 0x00 0		; complete shr sampling
NOP 2

; start count + ramp current
LOAD PAR
MOV REF 0x00 0
MOV CNT 0x00 1
SET PAR

NOP 102 		; halt 1024 ns (ramp slew time)

MOV CNT 0x00 0		; stop counter
MOV REF 0x00 1		; stop ramp current
...

The execution of the script is rather simple:

asmitp.pl program.asm -o instr.coe

Future to do:

1. Put instruction table setting in an external file

2. Add a vec and vcd file generation switch, to allow integration with spectre/spice

3. Implement JUMP instruction (loop)

4. Implement conditional statements

5. Create pdf documentation

If you find this approach appealing, please feel free to fork my repo or write to me so that I can add you as a contributor and develop these tools further. Cheers ;)

Date:Sun Mar 19 13:23:26 CET 2017

LEAVE A COMMENT | SEE OTHER COMMENTS



6 great articles on the field of engineering science

I always feel heartfelt while reading great and sensuous short texts about the field of engineering. I am offering you a few beautiful, 1 to 3 minute reads on topics related to engineering science.

Where are today's engineering heroes?By failing to celebrate its finest contributors, the profession risks far more than mere obscurity. This enriching article puts on the spotlight those engineering heroes who are often forgotten but have by far contributed equally much to our field.

Illustration by Tavis Coburn, IEEE Spectrum

Naturally, you might then ask, What makes an engineering hero?, Stephen Harris has tried to shed some more light with a follow-up article, revealing some of our views on engineering achievements.

What would engineering be without its daily battles with complexity and trade-offs? Robert Lucky rubs salt into the wound with the headaches of Unsystematic engineering. But there should be a better handle to the control problem, how's that even happening?

Perhaps the problem lies in The ever-evolving field of electrical engineering. How exactly is electrical engineering defined nowadays? Is circuit design the only E-related early stage subject which all EEs take during their first year at university? Do you have any idea of what EEs actually do?

You think you do? But then, how about Engineers starting to think like field biologists?, Samuel Arbesman has some radical ideas for coping with complexity.

Finally, we all know that solving complexities is always accompanied by the birth of Great Thoughts, here Robert Lucky is stressing that great ideas accompany us in unusual times and places. So, always keep that pen and paper ready, you never know when would that bird land on your shoulder.

Hope these writings reach more people. Happy reading!

Date:Sat Jan 26 22:33:05 GMT 2017

LEAVE A COMMENT | SEE OTHER COMMENTS



The chips are here!

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:

ADC Board: 1024 column-parallel hybrid single-slope ADCs

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:

Chip 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.

FPGA Readout Board

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.

Register control tool

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.

An example configuration of the current sequencer system

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:

Noise histogram over 32K samples

3D plot, noise histogram over 32K samples, 128 columns

3D plot, noise histogram over 32K samples, 1024 columns

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.

First bathtub histogram test, note that the sinewave used here is not full range, neither it clips the ADC

Another angle of the bathtub, first 128 columns only

You can see some stairs here:

Staircase at 1 us ramp time. A tiny glitch which can be fixed. Also note the input signal samples in this case are not sufficient.

To prove that the digital correlated double sampling works, here is the mean value of all columns under a uniform voltage input:

Mean value of all columns over 8k samples

Nice and uniform gray "image" with just ever so little (unnoticeable?) column fixed pattern noise. Do your eyes see it?

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.

Date:Sat Jan 25 20:43:40 GMT 2017

LEAVE A COMMENT | SEE OTHER COMMENTS



Powered by ICs

I recently participated in a T-shirt design contest organized by the solid-state circuits society. I just got an e-mail rejecting my entry as apparently another participant has won the contest. His design, compared to mine looks neat and clean. Congrats!

Nevertheless, now that the contest is over, let me introduce you to my design, and perhaps make SSCS angry about not following their strict copyright ownership rules. Apparently, by submitting your design you are automatically giving out all of your copyright to SSCS. Yeah, sure! :)

From the satellites information comes down!

Perhaps one of the most fascinating technologies empowered by solid-state devices is data communication and processing. I tried to express the peak of humanity, hehe "peak" (as well as IC design) with space technologies. My design entry contains an outline graphic of the Soyuz capsule, which is used for bringing in and out astronauts to the international space station (ISS) every 200 days. Keeping continents connected wouldn't have been possible without geostationary satellites. Similarly the ISS also relies on communication satellites, which is why my design also includes small satellite symbols surrounding the Soyuz capsule. All of that would not be possible without microchips, hence, the big chip with the SSCS logo at the center, linking the Earth and space.

Creating a hero of the IC designer is a rather hard and ambitious task, as solid-state technologies are so much embedded in today's life, that makes it hard for one to decide on the coolest application made possible by ICs.

Huge credit goes to my cousin (Queller 4) for giving a hand with the drawing.

Date:Sat Jan 14 10:54:30 GMT 2017

LEAVE A COMMENT | SEE OTHER COMMENTS



What is the current state of microelectronics outreach anyway?

a.k.a. the magic smoke got let out, so it doesn't work anymore

Yesterday on a pop-sci talk I heard one of the presenters say "robotics is the main reason for the emergence of self-driving cars and the world we know today," as if that could be a rock solid argument. It reminded me of a big misconception that is etched into the brains of general public, that all those fancy fields; robotics, artificial intelligence or machine learning play a major role in the development of our modern world. Perhaps they are right to a serious extent, except for that they blunder a significant chunk from the puzzle.

That chunk I call microelectronics which goes hand-in-hand with materials science, physics and all the brave engineering behind modern computing systems. Before reaching the pinnacle of our age — alias current affairs in artificial intelligence — a long way has been paved by generations of multi-disciplinary scientists and engineers towards building the computing infrastructures we know today. Unfortunately, nor microelectronics or materials science come out to be as prolific to the bare eye as their neighbouring fields, hence, the public's general bias and black-box awareness of the actual technology drivers. Ask your average Joe whether has heard of material science; chances are he has a vague idea, but yet, much more ambiguous than his image about Tesla's new self-driving car. So what or who brings this dissonant knowledge gap?

That's a surprisingly tough question to answer. For one thing though, we can definitely try pointing out some of the suspects:

1. Microelectronics could be very confusing — it deals with signals and processes that appear to be virtual, if not even magical; they cannot be seen or felt, have no smell and are squeezed within areas just about the size of a grain of sugar. It is so confusing to the public that it has led to popular myths following a post-hoc logic such as the one about the magic smoke: once it gets let out the chip doesn't work anymore, hence, to get it back up and running you just need a refill. That's what all those engineer ninjas do all day and night, right?

2. The field is not run by a single engineer ninja — another misconception is that our sphere is typically composed of "nerds" working alone in dazzling basements having no connection to the outside world. Such ideas prematurely put off all general interest in public towards anything "nerdy" as most of us are "pro people persons". That actually resonates well with superhero fiction movies like October Sky or Iron Man, where a rock-star engineer does it all by himself, being indifferent to anyone getting on his way. In reality I know no engineer working like that. In reverse — microelectronics is a very collaborative field and, in fact, most present day electronics is a product of extensive communication between various "Homo sapiens". We are cool people talking often with each other, and above all, we do not work in basements!

3. Popularizing is hard — when speaking in public, not only can you not show any big physical objects (e.g. vs. the case of a funny walking AI robot) but when presenting, one is typically limited to speaking numbers, or showing colorful polygon-o-fractal pictures at its best. All of that typically tends to induce boredom in the audience. I have so far given a few introductory talks about the field and I've learnt that public, in general, does not even differentiate analog from digital. Then what is one micro Watt anyway?

4. Vetoed speech — most engineers boiling in these industries are strictly prohibited to talk about their work. This automatically shrinks down the outreach producers to those in academia and perhaps some individual hooligans. But it is the chefs from the kitchen corner that keep the most delightful stories to tell.

5. Access to technology — while this is constantly evolving, currently only few of us are blessed to have the keys to silicon foundries as well as the complex custom software needed to create a chip. I'm not even mentioning the knowledge factor here. The reason here resides partly in pt. 1 and the fact this gear is expensive. Not every hobbyist can afford 60 K€ for a chip fabrication run. Also, sometimes even if you have the money you cannot access just any process you like due some political reasons. The good news is that there is a positive change towards process accessibility owing to the Multi Project Wafer (MPW) and Multi Layer Mask (MLM) services, now commonly offered by major foundries and coordinating institutions. It is still expensive though, but the trend is changing to the better.

Perhaps there are even more obstacles hindering the outreach of this cocktail of sciences which drive the electronics industry today. It is likely though, that public awareness will grow with time, but so far, to help make this happen, we should try to ring the bell a bit more often.

Date:Fri Dec 30 11:40:29 CET 2016

LEAVE A COMMENT | SEE OTHER COMMENTS