Instrumentation for quantum computers by Wei-Han Huang Submitted to the Department of Electrical Engineering and Computer Science in partial fulfillment of the requirements for the degree of Master of Science in Electrical Engineering and Computer Science at the MASSACHUSETTS INSTITUTE OF TECHNOLOGY December 2003 @ Massachusetts Institute of Technology 2003. All rights reserved. Author. .. Department o' ... ........ .... ........ ............ ctrical Engineering and Computer Science December 12, 2003 ....... .................. Certified by. Isaac L. Chuang Associate Professor Thesis Supervisor Accepted by ............. Chairman, Department Committee on Graduate Theses MASSACHUSETTS INSTiTUTE OF TECHNOLOGY APR 1BARKER LIBRARIES Instrumentation for quantum computers by Wei-Han Huang Submitted to the Department of Electrical Engineering and Computer Science on December 12, 2003, in partial fulfillment of the requirements for the degree of Master of Science in Electrical Engineering and Computer Science Abstract Quantum computation poses challenging engineering and basic physics issues for the control of nanoscale systems. In particular, experimental realizations of up to sevenqubit NMR quantum computers have acutely illustrated how quantum circuits require extremely precise control instrumentation for pulsed excitation. In this thesis, we develop two general-purpose, low-cost pulse programmers and two Class E power amplifiers, designed for precise control of qubits and complex pulse excitation. The first-generation pulse programmer has timing resolutions of 235 ns, while the second-generation one has resolutions of 10 ns. The Class E power amplifier has ps transient response times, a high quality-factor, and a small form factor. The verification of the pulse programmer and the Class E power amplifier is demonstrated using a customized nuclear quadrupole resonance (NQR) spectrometer, which incorporates both devices. The two devices control the generation of RF pulses used in NQR experiments on paradichlorobenzene (C 6 H 4C1 2 ) and sodium ni35 trite (NaNO 2 ). The NQR signals originating from 14 N in sodium nitrite and from C1 in paradichlorobenzene are measured using the NQR spectrometer. The pulse programmer and the Class E power amplifier represent first steps towards development of practical NMR quantum computers. Thesis Supervisor: Isaac L. Chuang Title: Associate Professor 3 4 Acknowledgments During my senior year in undergraduate studies, I was introduced to a fascinating subject - Quantum computation. It involved all the subjects I loved - computer science, electrical engineering, and quantum physics. Since coming to MIT, I had the opportunity to continue my interest and learn more about the science. The past two years has been an amazing learning experience, both in life and academics. My advisor, Isaac Chuang has been a great inspiration. His wealth of knowledge in the field has helped guide the work conducted in this thesis, and he has taught me how to motivate my work and put it into perspective. His actions has set an example for me on how to conduct myself as a scientist. I would like to thank my lab mates in the Quanta group for being both a wonderful source of support and friendship. I would like to thank Jeff Brock for being a great friend both in and out of the lab. I wish Jeff and Amy's beautiful, baby girl LucyClare good health and a long, happy life. One of the nicest friends I have known is Murali Kota - thanks for the many interesting late night dinner conversations and Sunday lunches about physics. The old man of our group, Matthias Steffen, has been a wonderful source for guidance. His advice on oral and writing presentations has been extremely helpful. Terri Yu's suggestion on taking 8.321 was a great idea. The class gave me better intuition about quantum physics. My UROP student Zilong Chen has been a great help. He is a superposition of both theorist and experimentalist. What can I say about Andrew Houck? His silly antics have always been a source for laughs. Josh Folk, Andy's boss, is an incredible experimentalist as well as a BBQ chef. Many thanks also to Aram, Francois, Andrew Cross, and Joshusa Powell for being great group members and amazing theorists. Working at NIST over the summer of 2003, I found John Martinis to be a great source of knowledge about electronics and Josephson junctions. I greatly appreciate his hospitality as well as his family's. John's excitement and energy shines through day after day. To the NIST crew, Ray Simmons, Robert McDermott, and Dave Pappas - thanks for the interesting conversation both about science, politics, and ape 5 behavior. Steve Waltman is truly a master of analog electronics, especially microwave electonics. electronics. Every conversation I have had with him, I have learned something new. Special thanks to Rebecca Tarantino for putting up with me over the summer and being the best roommate that I have ever had. To my closest friends from undergraduate: thank you Willy, Phil, Cindy, and Raymond for coming up and visiting, time to time, and keeping me grounded. Finally, I would like to thank my family for their support and guidance. To mom, dad, SueBee, Linda, Amy, Will, AK, Dave, Kay, Mike, and the two newest members of our family Momo (Emily) and Giddy (Allison). 6 Contents 1 2 19 Introduction 1.1 Historical background . . . 19 1.2 Purpose of my work . . . . 21 1.2.1 Pulse programmer 22 1.2.2 Class E amplifier 23 1.2.3 Nuclear quadrupole resonance spectrometer 23 1.3 Organization of thesis . . . 24 1.4 Contributions . . . . . . . 25 1.5 Literature . . . . . . . . . 26 Background: Theory of Quantum Computation 29 2.1 Axioms of quantum mechanics . . . . . . . 29 2.2 Quantum bits ................... 32 2.3 Multiple qubits . . . . . . . . . . . . . . . 33 2.4 Computation using quantum systems . . . 34 2.4.1 Entanglement . . . . . . . . . . . . 34 2.4.2 Quantum parallelism and quantum measurement 35 2.5 2.6 . . . . . . . . 36 2.5.1 Unitary evolution . . . . . . . . . . 36 2.5.2 Single-qubit gates . . . . . . . . .. 37 2.5.3 Two-qubit gates . . . . . . . . . .. 40 . . . . . . . . . . . 42 Quantum gates and circuits Quantum algorithms 2.6.1 Shor's algorithm 44 . . 7 2.7 3 Sum m ary 46 Nuclear Magnetic Resonance Quantum Computing 49 3.1 NMR historical background ..... ....................... 50 3.2 NMR quantum computing ...... ........................ 51 3.3 3.2.1 NMR quantum computer: the physical system ......... 51 3.2.2 RF pulses perform quantum operations . . . . . . . . . . . . . 53 NM R spectrom eter . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 Transmitter: pulse programmer and power amplifier . . . . . . 57 NM R experiments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 3.4.1 Experimental realization of Shor's algorithm . . . . . . . . . . 59 3.4.2 The experiment and the importance of the pulse programmer 60 3.3.1 3.4 3.5 3.6 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Instrumentation issue for quantum computers . . . . . . . . . . . . . 63 3.5.1 NMR readout: measurement . . . . . . . . . . . . . . . . . . . 63 3.5.2 Transient data acquisition . . . . . . . . . . . . . . . . . . . . 64 3.5.3 Recovery tim e . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 Sum mary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Class E Amplifier 4.1 66 67 History of the Class E amplifier . . . . . . . . . . . . . . 67 4.1.1 Motivation: a solution to increasing SNR . . . . . 70 4.2 Operation and design . . . . . . . . . . . . . . . . . . . . 70 4.3 Design equations . . . . . . . . . . . . . . . . . . . . . . 73 4.4 Class E amplifier characteristics . . . . . . . . . . . . . . 75 4.4.1 . . . . . . . . . . . . . . 78 . . . . . . . . . . . . . . . . . . . . . . . . . . 79 4.5 Measurement difficulties Sum m ary 5 Pulse Programmer 5.1 81 Problem and approach . . . . . . . . . . . . . . . . . . . . . . . . . . 81 5.1.1 Introduction to the pulse programmer . . . . . . . . . . . . . . 82 5.1.2 A case study: the Varian pulse programmer 83 8 . . . . . . . . . . 5.2 Designing an NMR quantum computer pulse programmer . . 88 5.3 First-generation pulse programmer . . . . . . . . . . . . . . 88 5.3.1 Architecture of first-generation pulse program m er . . . . . . . . . . . . . . . . . . . . . . . 5.3.2 Hardware implementation of first-generation pulse program mer . . . . . . . . . . . . . . . . . . . . . . . 5.3.3 5.4 program mer . . . . . . . . . . . . . . . . . . . . . . . 95 . . . . . . . . . . . . . 97 Architecture of second-generation pulse program m er . . . . . . . . . . . . . . . . . . . . . . . 5.4.2 5.5 98 Software implementation of second-generation pulse program m er . . . . . . . . . . . . . . . . . . . . . . . 5.4.4 97 Hardware implementation of second-generation pulse program m er . . . . . . . . . . . . . . . . . . . . . . . 5.4.3 93 Performance evaluation of first-generation pulse Second-generation pulse programmer 5.4.1 90 Software implementation of first-generation pulse program mer . . . . . . . . . . . . . . . . . . . . . . . 5.3.4 88 99 Performance evaluation of second-generation pulse program m er . . . . . . . . . . . . . . . . . . . . . . . 110 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 Sum m ary 113 6 NQR Testbed 6.1 NQR spectrometer ........ . . . . . . . . . . . 114 6.2 Impedance matching probe . . . . . . . . . . . . . . 115 6.2.1 LC resonator as a probe 6.2.2 Probe design . . . . . . . . . . . 116 . . . . . . . . . . . . . . . . . 119 . . . . . . . . . . . . . . . . . . . 123 6.3 Pin diode switch 6.4 Receiver . . . . . . . . . . . . . . . . . . . . . . . . 127 6.4.1 Homodyne receiver . . . . . . . . . . . . . . 127 6.4.2 Heterodyne receiver . . . . . . . . . . . . . . 128 9 7 6.5 Experiment 6.6 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 Conclusions 7.1 135 Future Prospects: pulse programmer . . . . . . . . . . . . . . . . . A NQR Theory 136 139 A.1 NQR historical background ........... . . . . . . . . . . . . . 139 A.2 Qualitative comparisons of NMR and NQR . . . . . . . . . . . . . . 140 A.3 NQR Hamiltonian and resonance frequencies . . . . . . . . . . . . . 141 A.4 Pure NQR selection rules .............. . . . . . . . . . . . . . 143 A.5 RF excitation and effective signal averaging . . . . . . . . . . . . . 146 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 A.6 Summary B Appendix A: First Generation Code B.1 Source code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 157 C VHDL Pulse Programmer 173 D Probes 199 E Class E amplifier 205 10 List of Figures 2-1 (a) Bloch sphere representation of the state 1,0) of a single qubit. (b) The position in the Bloch sphere of five important states. The states are not norm alized. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-2 33 Quantum circuit representation of (a) an arbitrary single-qubit rotation U, and (b) the NOT gate. . . . . . . . . . . . . . . . . . . . . . . . . . operation, and (b) the operation. 40 2-3 Truth tables for (a) the 2-4 Quantum circuit representation of (a) a controlled-NOT gate, (b) a CNOT 12 CNOT 2 1 40 zero-controlled-NOT, (c) a SWAP gate, and (d) a controlled-U gate. The * symbol denotes the control qubit - the controlled operation is only executed if the qubit is in the 1) state. The o symbol denotes the zero-controlled qubit, i.e., the operation is only executed if the control qubit is in the state 10). 2-5 . . . . . . . . . . . . . . . . . . . . . . . . . Quantum circuit representation of a TOFFOLI gate and its decomposi- tion into two-qubit gates. . . . . . . . . . . . . . . . . . . . . . . . . . 2-6 41 42 The quantum circuit which performs the order-finding algorithm in Shor's algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 3-1 Overview schematic of an NMR spectrometer [FR86] 56 3-2 Picture of an Oxford Instruments 500MHz narrow-bore NMR magnet 3-3 The NMR cabinet houses the transmitter and control electronics for the Varian spectrometer. 3-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 58 Quantum circuit illustrating the order-finding algorithm in Shor's al- gorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 60 3-5 The molecule hexafluoro butadiene is used as the NMR quantum computer in Shor's algorithm . . . . . . . . . . . . . . . . . . . . . . . . . 3-6 61 NMR pulse sequence for implementing Shor's algorithm to factor N=15 with seven qubits. The tall lines represent 90' pulses acting on one of the seven qubits (horizontal lines) about the positive i (no cross), negative , (lower cross) and positive 4-1 (top cross) axis. . . . . . . . A schematic of a Class E amplifier is shown. The resonant load network circuit is used to tune the resonant frequency of the amplifier. .... 4-2 62 72 Example of ideal, transient waveforms for the input and output of the Class E amplifier. When the gate is switched on, the voltage at the drain VD decreases, while the voltage VOUT increases. When the gate is switched off, VD rises and VOUT decreases. . . . . . . . . . . . . . . 72 4-3 The Class E amplifier schematic shown for amplifier tuned at 4.64 MHz. 75 4-4 Measurements of the voltages at the drain and the gate of the power transistor are shown. The drain voltage is about 3 times the gate voltage, fitting closely with theoretical predictions . . . . . . . . . . . 4-5 77 The Class E amplifier shown for the amplifier constructed and tested. The resonance frequency is 4.64MHz. . . . . . . . . . . . . . . . . . . 78 5-1 Structure of the Varian pulse programmer [VNMO1] . . . . . . . . . . 85 5-2 Block diagram of the first-generation pulse programmer. 90 5-3 The hardware uses a buffer to store the pulse sequence and access the . . . . . . . commands during execution. . . . . . . . . . . . . . . . . . . . . . . . 5-4 91 The Rabbit RCM2200 module used as the hardware for the firstgeneration pulse programmer. . . . . . . . . . . . . . . . . . . . . . . 92 5-5 The daugther board customized for the Rabbit RCM2200 module. . . 92 5-6 The state machine for the rabbit pulse programmer. . . . . . . . . . . 95 5-7 Anatomy of a pulse sequence. Each operation has an associated overhead cost for processing a command. The larger the overhead time, the higher the timing resolution. . . . . . . . . . . . . . . . . . . . . . 12 96 5-8 Structure of pulse programmer for the second-generation pulse program m er . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 . 100 5-10 Main framework for VHDL code . . . . . . . . . . . . . . . . . . . . . 101 5-9 Functional block diagram of Digilab 2E development board [Dig02] 5-11 The finite state machine for the pulse programmer entity. The initial state is the exit state. In this state, the pulse programmer loops infinitely. When an enable signal is set, the state machine executes command code fetched from the FIFO. . . . . . . . . . . . . . . . . . 104 5-12 UART data format. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 5-13 The finite state machine for the LED controller. The LED utilized is on the Diligent Inc. D210 board. . . . . . . . . . . . . . . . . . . . . 108 5-14 The main finite state machine shows the overall behavior of the pulse program mer. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 5-15 At 100MHz, the minimum pulse width was 10 ns, which matched with the predicted value. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-1 110 A block diagram of an NQR spectrometer, illustrating the three main components: the transmitter, probe, and receiver. The sample material is placed in the coil. 6-2 . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 LC matching network to the probe. When the capacitors are tuned properly, impedance is matched to a 50Q coaxial line and power transfer is maxim ized. 6-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Schematic of the matching network circuit used for analytic solution. Rwire is the resistance of the wire. In the analysis Rwzre = 3Q. 6-4 117 The tuning and matching capacitors of the matching network. . .. . 118 The capacitors are enclosed in a metal RF box to shield the system from extraneous noise. 6-5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 A single coil used in the probe of the NQR spectrometer, where 1 is the length of the coil. . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 120 6-6 An example of a coil made using the described technique. The inductance of the coil is 9.7pH and the number of turns, N, is 32. . . . . . 6-7 121 The probe encapsulating the test tube and the coil. The sample material is placed in the test tube holder for NQR spectroscopy. . . . . . 122 6-8 The schematic of the pin diode switch. . . . . . . . . . . . . . . . . . 123 6-9 Design consideration: a notch filter forms when the PDS is shut off. The resonance frequency of the notch filter must be considered in the design of the system . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 6-10 The Bode plot of a poorly designed pin diode switch. The resonance frequency is at 4.73MHz which is very close to the resonance frequency of the matching network. Thus, small signals are attenuated by 1. . . 125 6-11 The transmission board containing: (1) RF mixers for producing gated pulses, (2) a pin diode driver circuit, and (3) a pin diode switch. . . . 126 6-12 An example of a receiver chain is shown. A block diagram shown in this figure corresponds to the real devices as seen on the right-hand side. 127 . . . . . . . . . . . . . 128 in paradichlorobenzene . . . . . . 130 . . . . . . . . 131 6-16 The data points from a nutation experiment on NaNO2 . . . . . . . . 132 6-13 A general schematic of a heterodyne receiver. 6-14 The FID signal produced from 3 1C1 6-15 The FID signal of NaNO 2 captured on an oscilloscope. 7-1 A block diagram of a pulse programmer designed for superconducting Josephson-phase qubits. A-1 . . . . . . . . . . . . . . . . . . . . . . . . . 137 A bessels function is the average FID signal induced in NQR experiments. A "7r/2" pulse is produced when wt is 0.667r. The amplitude is normalized in this example. . . . . . . . . . . . . . . . . . . . . . . . 148 B-1 Overview of the entire schematic for the first generation pulse programmer. The next 4 sections show full size schematic diagrams of the daugther board. The sections start from left to right and move from top to bottom . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 152 B-2 The top left corner schematic of the rabbit daugther . . . . . . . . . . 153 B-3 The top right corner schematic of the rabbit daugther board . . . . . 154 B-4 The bottom left corner schematic of the rabbit daugther board . . . . 155 B-5 The bottom right corner schematic of the rabbit daugther board . . . 156 . . . . . . . . . . . . . 172 B-6 The PCB layout of the rabbit daugther board D-1 A die-cast Al RF box is used as the container for the probe and tuning and matching capacitors. Large copper sheet metal is used as the wiring between components. Sheet metal is used to lower parasitic inductance. The probe holder is a piece of paper rolled into a cylinder. The coil is wrapped around the paper. The resonance frequency is 4.649MHz, with C1 = 260pF, C2 = 760pF, and L1 = 1.2pH. . . . . . 200 D-2 The second probe utilizes similar construction methods as the first. The major difference is variable air capacitors are used as the tuning and matching capacitors. Use of the variable air capacitors turns out to be a poor design choice, because the air capacitors have a lot of undesired capacitively coupling to other components. The resonance frequency was not attainable. . . . . . . . . . . . . . . . . . . . . . . 201 D-3 The third probe is the same design as the first, except the length of the coil is increased to maximize the Q. The length of the coil is the same as the diameter of the coil, 0.78 inches. The resonant frequency is 4.649MHz with C1 = 26pF, C2 = 95pF, and L, = 9.6uH. . . . . . . 202 D-4 The last probe is shown here with a 9.7pH coil. The coil slides over a 0.78 inch test tube which fits in the center of the copper cylinder. The tuning and matching capacitors are described in section 6.2.1. . .. . 203 D-5 The mechanical drawings (completed in the software Omax) for the probe (in Figure D-4) is show with lengths in units of inches. . . . . 204 E-1 Protel schematic of a Class E amplifier tuned at 4.638MHz. A IRF510S power transistor is used in the design. 15 . . . . . . . . . . . . . . . . . 206 E-2 Protel PCB layout for the Class E amplifier. The board is made to fit into a NIM box. Additional debugging pins and thru holes (vias) are added to the board. The back-to-back pin diode switches are incorporated into the design of the PCB. . . . . . . . . . . . . . . . . . . . . 207 E-3 Simulations of the Class E amplifier are completed in Protel. Here, the voltage at the gate of the transistor (volt-b) is plotted along with the voltage at the drain (v-out) and the voltage across the resistor (output). 208 16 List of Tables 2.1 The solution to order-finding problem is explicitly calculate for L = 15. Theorderof isr=2 for x=4. . . . . . . . . . . . . . . . . . . . . . 45 4.1 Dependence of P, R, V.c, and V on Qload [Sok98] 74 4.2 Parameters used for the design of a CEA. The resonance frequency is tuned to 4.64M Hz. 4.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 Class E measurements: the measured and simulated values of the amplifier are shown in the table. The percent error is also displayed. . . 78 5.1 Characteristics for evaluating the Varian pulse programmer . . . . . . 86 5.2 Characteristics for the Varian pulse programmer. 87 5.3 The performance of several lab-built pulse sequencers for various ap- . . . . . . . . . . . plications. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.4 87 The list of operational codes available to the RCM2200 pulse sequencer. Currently port C is the only available output channel. . . . . . . . . 93 . . . . . . . . . . . 96 5.5 Characteristics for the Rabbit pulse programmer. 5.6 Pulse sequence byte code and operational code for the pulse programmer. 102 5.7 Control code for the pulse programmer . . . . . . . . . . . . . . . . . 5.8 Characteristics for the second-generation pulse programmer. This table shows the parameters for clock speeds of 100MHz and 150MHz. 6.1 102 . 111 The calculated values used for NQR spectrometer matching network. The resonance frequency of the circuit is 4.64MHz. 17 . . . . . . . . . . 119 18 Chapter 1 Introduction "I'm not happy with all the analyses that go with just classical theory, because Nature isn't classical, dammit, and if you want to make a simulation of Nature, you'd better make it quantum mechanical, and by golly it's a wonderful problem!" Quote from Richard Feynman [Fey8l] 1.1 Historical background In 1947, research by Shockley, Bardeen and Brattain at Bell Labs led to the fortuitous discovery of the first solid state transistor [BB48]. The advent of transistors ushered in a new era in modern computing. Soon after, integrated circuits were introduced. At that time, integrated circuits (ICs) yielded lower cost, higher reliability, and simpler circuit designs than conventional electronics; consequently, the computing industry expanded rapidly. The burst in the field of digital computing led Moore to propose that the number of transistors that could fit onto a square inch of silicon would double every 12 months [Moo65]. His prediction, known as Moore's Law, has held surprisingly true for the past 30 years. But as the number of transistors in microprocessors continued to increase, the sizes of transistors decreased in order to maintain reasonable power efficiency and low costs. The shrinking sizes raised concern among researchers. As technology continued to abide by Moore's Law, the sizes of individual elements made their behavior increasingly affected by the laws of quantum 19 mechanics. Foreseeing this trend, researchers began to ponder the fundamental and physical limits of computation. In 1981, Feynman discussed the problem of simulating physics with computers [Fey82]. He asked whether a universal, classical computer could simulate physics exactly and efficiently. Then, he made a crucial insight. Instead of using classical computers, he proposed using nature to simulate physics. Another words, rather than a classical Turing machine, use a machine based on the laws of quantum mechanics to perform simulations. He produced an abstract model illustrating how a quantum system could be used to do computations. As a result, research into the idea of computational devices based on quantum mechanics quickly emerged. Physicists and computer scientists explored the questions laid out by Feynman, Deutsch, and Benioff [Fey82, Deu85, Ben82]. In 1985, Deutsch realized that Feynman's insight could lead to a general-purpose computer. He extended the theory of quantum computation with the development of the universal quantum computer and the quantum Turing machine [Deu85]. The feasibility of a general-purpose quantum computer led scientists to investigate quantum algorithms. In 1992, Deutsch and Jozsa discovered the Deutsch-Jozsa algorithm [DJ92], which suggested quantum computers might be capable of efficiently solving mathematically hard problems. Then Shor's discovery propelled quantum computing into the limelight. In 1994, he showed that the problem of factoring the product of two prime numbers could be solved efficiently using a quantum computer [Sho94]. Shor's algorithm not only generated academic interest, but it also garnered the attention of the public because of its potential to break encryption schemes, thereby disrupting electronic commerce. Shor's algorithm enables one to decipher encryption codes based on the difficulty of prime factorization. The Rivest-Shamir-Adleman (RSA) algorithm is an example of a popular, public-key crypto-system used for electronic commerce, which can be deciphered using Shor's algorithm. Since the conception of Shor's algorithm, researchers have investigated suitable, physical systems for quantum computers such as Josephson junction superconducting circuits, ion traps, silicon-based semiconductors, and quantum dots [MNAUO2, 20 Kan98, KMWO2, GAPA99] but these physical systems are still in their infancy. Even so, one technology, nuclear magnetic resonance (NMR), has made moderate advances. Through radio-frequency (RF) waves, one can manipulate a quantum system that is physically represented by an ensemble of molecules in a liquid solution. NMR quantum computing is the forerunner in demonstrating the tools and language necessary for quantum computation. Numerous experiments have been performed, which demonstrate the Deutsch-Jozsa algorithm, Grover's algorithm, and Shor's algorithm [SvDH+03a]. 1.2 Purpose of my work NMR quantum computing experiments have demonstrated the validity of quantum algorithms and have demonstrated the complexity of implementation. Current solution NMR techniques for quantum computation, applied at room temperature and using standard magnetic fields for polarization, face experimental challenges that make it unlikely such systems will scale to many quantum bit (qubit) sizes. Because of this, the usefulness of solution NMR quantum computing has been called into question [War97]. Nevertheless, for the development of quantum computers, the techniques and instrumentation of NMR provide a powerful language and tool set. The language developed helps describe and provide physical understanding for controlling quantum computers. Underlying the physical control of the qubit is the NMR spectrometer and its RF electronics. Modern NMR achieves exquisite control, typically apply- ing several hundred RF pulses using sophisticated electronics such as digital pulse programmers, RF amplifiers, phase shifters, mixers, and low-noise amplifiers. The instrumentation is extremely large and expensive, requiring careful maintenance by technicians. Although conventional NMR spectrometers are the cutting-edge tool for quantum computing, they are not optimized for that purpose. By designing electronics specifically for NMR quantum computing applications, we can sidestep some problems associated with current systems. NMR quantum com21 puters require complex pulse programmers and power amplifiers to finely control the generation of RF pulses and pulsed excitation. In our research, we investigate and provide low-cost, compact pulse programmers and power amplifiers, which meet the needs for NMR quantum computing. We study two electronic components: the pulse programmer and the Class E amplifier (CEA) [Sok75]. We discuss the pulse programmer and the CEA in Sections 1.2.1 and 1.2.2 and the targeted design parameters for each device. In Section 1.2.3, we test the pulse programmer and Class E amplifier by incorporating both devices in a nuclear quadrupole resonance (NQR) spectrometer and performing basic NQR experiments. 1.2.1 Pulse programmer In an NMR quantum computer, a pulse programmer controls the duration, amplitude and phase of RF waves applied to a qubit. A series of RF pulses, known as a pulse sequence is generated by the programmer, and quantum logical operations can be accomplished. Pulse sequences are transmitted via RF electronics, known as RF channels. Generally, there exists one RF channel to control one qubit. NMR quantum computers demand complex, high-speed pulse programmers to control the qubits. There are several requirements for NMR quantum computing applications, including scalability and high timing resolution. As the number of qubits increases, the number of RF channels increases. The pulse programmer needs to control more RF channels, making scalability an important design issue. Another design issue is the timing resolution of the pulse programmer. For example, suppose a pulse programmer has a pulse resolution of 50 ns; then it can typically output pulse durations in multiples of 50 ns. Interestingly, a timing resolution of 50 ns is available in some commercial NMR spectrometers. High resolution pulses are used to perform relaxation experiments with special pulse sequences such as the spin echo [Fre97]. For quantum computers, higher resolutions can possibly reduce errors in quantum operations [Ste03]. In this work, we develop two multiple-channel pulse programmers with accurate timing resolutions. For the first pulse programmer, we concentrate on the develop- 22 ment of a transparent, user-friendly interface. High timing resolution becomes central to the design of the second programmer. We attempt to design and implement a pulse programmer with 10 ns timing resolution. 1.2.2 Class E amplifier The control of qubits often requires accurate control of RF field strengths applied on the qubit. Often, power amplifiers are used in NMR systems to obtain such control. For accurate control, the power amplifier used in NMR technology poses several problems and issues, including ringdown time, efficiency, large size, and high production costs. We address the deficiencies of a typical power amplifier by replacing it with a CEA topology [Sok75]. The CEA is a switching mode power amplifier that has high power efficiency, high quality factor (Q), fast ringdown times, and a priori designability. Because of its fast ringdown time, the signal-to-noise ratio in NMR measurements may be increased. In this work, the goal was to improve the ringdown time of the power amplifier. 1.2.3 Nuclear quadrupole resonance spectrometer To test the pulse programmer and the Class E amplifier, we built an NQR spectrometer, demonstrating both devices performing pure NQR spectroscopy experiments. Pure NQR is very similar to NMR, requiring a similar spectrometer design with minor changes. In pure NQR spectroscopy, researchers exploit the nuclear quadrupole moment and electric field gradient surrounding the nucleus with pulse sequences of RF fields to detect a small signal, known as a free induction decay (FID) signal. To produce pulse sequences, digital and analog electronics in NMR and NQR spectrometers are similar, both requiring a pulse programmer and a power amplifier. The main difference between NMR and NQR spectrometers is the absence of a large, superconducting magnet in NQR systems. Since no magnet is required, an NQR spectrometer is cheaper and faster to design and construct than an NMR spectrometer. 23 1.3 Organization of thesis We start with two introductory chapters describing the basic requirements for NMR quantum computing: quantum computation theory and NMR theory. In the next two chapters, we motivate the need to build electronics for NMR quantum computers, specifically the CEA and the pulse programmer. Next, we present the designs for the CEA and for the pulse programmer. In the final chapter, we discuss a customized NQR spectrometer for the express purpose of testing the pulse programmer and CEA. Chapter 2 starts by laying out the fundamental theory of quantum computation, providing the language and background necessary to understand NMR quantum computation and the progress made in the field. We start with the basic axioms of quantum mechanics, and illustrate how computation is accomplished based on the fundamental unit of quantum information: the quantum bit or qubit. Building on this foundation, we illustrate how the properties of entanglement and unitary evolution can be used to compute quantum logical operations and how these operations can be reduced to quantum circuits, which can be used to describe quantum algorithms. We end by describing Shor's algorithm using quantum circuits. Next, we delve into the world of NMR quantum computing in Chapter 3. A single spin-1/2 nucleus is a suitable physical system to represent a qubit. We first describe how a single qubit can be controlled by RF pulse sequences and how to apply quantum computation on multiple qubits via the J-coupling among nuclei. We describe the experimental progress on NMR quantum computing, highlighting Shor's algorithm in Section 3.4. The NMR implementation of Shor's algorithm demonstrates the requirements for the pulse programmer and the power amplifier in an NMR quantum computer. By defining the requirements for the pulse programmer and power amplifier, we can design low-cost control instrumentation for NMR quantum computers. In Chapter 4, we introduce the CEA and present the design and implementation of a CEA tuned for NQR spectroscopy. The circuit operation and topology is described in detail, emphasizing the trade-offs between high Q and power efficiency. As an example, the design of an amplifier tuned at the resonance frequency of 4.64MHz 24 is illustrated. Finally, we discuss several electrical characteristics of a CEA, including:(1) the output power, (2) efficiency, (3) Q and Chapter 5 describes the pulse programmer. (4) ringing time. First, we describe the functionali- ties of a pulse programmer citing an example of one from Varian, Inc. [VNMO1]. Next, we describe two generations of pulse programmers. The first-generation one is implemented with a Rabbit RCM2200 programmable chip with a customized daughterboard, which I designed. The second-generation programmer utilizes field pro- grammable logic arrays (FPGA) to generate pulse sequences. The framework of the code is presented for the second generation pulse programmer. For each pulse programmer, we characterize the behavior by evaluating parameters such as timing resolution, memory size, minimum and maximum pulse delay, and number of RF channels. In order to validate the CEA and the pulse programmer, we develop an NQR spectrometer as a testbed. In Chapter 6, we describe an implementation of an NQR spectrometer and demonstrate the CEA and pulse programmer working in this system. We outline the hardware design, starting off by discussing the three main components of the spectrometer: (1) the transmitter, (2) the probe, and (3) the receiver. The design of each component is discussed by describing the RF methodology for the basic circuit elements, such as the mixer, the LC resonator, the inductor, and the amplifier. Some preliminary results are obtained from the hardware, showing basic signal response from sodium nitride (NaNO 2 ). The last chapter, Chapter 7, summarizes the work in this thesis and recommends future work. It addresses the extension of the pulse programmer to superconducting Josephson phase qubits. 1.4 Contributions In Chapter 4, the CEA is an extension of the work done by graduate student Yael Maguire, who designed a 34MHz CEA for NQR spectroscopy of paradichlorobenzene. Based on his initial designs, I redesigned a CEA tuned at 4.64MHz. 25 I laid out a printed circuit board (PCB) and verified the functionality in Protel. Zilong Chen and I "stuffed" the boards and characterized the behavior of the device. The framework for the pulse programmer described in Chapter 5 was designed with guidance from Professor Chuang. I created an initial version of the pulse programmer using a low-cost, programmable logic device using the programming language C. For the second generation pulse programmer, I wrote the code in very high-speed integrated circuits (VHSIC) hardware description language (VHDL), and tested and debugged the system. The NQR spectrometer described in Chapter 6 was a collaborative effort including me, Zilong Chen, and Professor Chuang. I laid out the transmission board, including the pin diode switch, in Protel. Several versions of the matching network and probe were created before a final circuit was completed. Measurement code was written in Matlab. Prof. Chuang provided code for Fourier transform and GPIB data acquisition. Zilong Chen and I constructed nuclear instrumentation module (NIM) bins for the spectrometer based on designs I produced in Omax. I built several versions of the NQR spectrometer, slowly refining the electronics behind the spectrometer. The goal is to continuously refine and advance the electronics in the system and integrate much of the system into several PCBs. I also designed a well-shielded probe. UROP student Jeff Brock assisted me in procuring the materials necessary for the completion of the probe. 1.5 Literature The following is a compilation of texts that are particularly useful to this thesis: Quantum information theory Nielson and Chuang's Quantum Computation and Quantum Information is a comprehensive introduction to quantum information theory [NCOO]. It covers a wide range of topics, from quantum algorithms to error correction, and highlights the numerous open problems in the field. Another useful book is Gruska's Quantum Computing [GruOO]. This text merges the ideas in the fields of quantum information Theory and 26 Computer Science, making the book accessible to beginners. John Preskill's lecture notes for Physics 219/Computer Science 219 course presents delightful discussions describing quantum computing in an intuitive fashion [Pre98]. Nuclear magnetic resonance Ernst, Bodenhausen, and Wokaun's Principlesof Nuclear Magnetic Resonance in One and Two Dimensions is a wonderful and comprehensive resource for the treatment of NMR, both classically and quantum mechanically [EBW87]. A great companion to the book is Ray Freeman's Spin Choreography [Fre97], which gives an intuitive overview of high-resolution NMR techniques and spin dynamics. Spectrometer instrumentation Experiment Pulse NMR: a Nuts and Bolts Approach is a great book for experimentalists. Fukushima and Roeder discuss NMR spectroscopy from a practical viewpoint and various approaches for constructing a spectrometer [FR86]. Petersen's thesis entitled Pulsed Nuclear Quadrupole Resonance Instrumentation and Study of N14 Spectrum and Relaxation in Sodium Nitrite is an invaluable resource [Pet75], providing tips and techniques that proved to be indispensable to the work covered in this thesis. 27 28 Chapter 2 Background: Theory of Quantum Computation We review the fundamental principles in the theory of quantum computation, illustrating how quantum mechanical operations can be reduced to unitary, logic operations. Section 2.1 discusses the axioms of quantum mechanics. Building on these concepts, we describe how quantum systems are abstractly represented in Sections 2.3 and 2.4 and introduce the necessary ingredients for performing quantum computations, including the phenomena of entanglement and quantum parallelism, which give certain quantum algorithms their speed-up over their classical counterparts. Based upon these properties, we show how quantum operations reduce to quantum gates and circuits, as discussed in Section 2.5. Using quantum gates, we discuss the following algorithms in Section 2.6: the Deutsch-Jozsa algorithm, Grover's algorithm, and Shor's algorithm. 2.1 Axioms of quantum mechanics Quantum theory is a mathematical model of the microscopic, physical world. To characterize the model, we need to specify how it will represent states, observables, measurements, and dynamics in a closed system. We present the basic axioms of quantum mechanics, which are based on discussions in Preskill's lecture notes 29 [Pre98]. 1. States: A state is a complete description of a physical system. In quantum mechanics, a state is a vector in a Hilbert space over the complex numbers C. Vectors are denoted in Dirac's notation as ket 1,0). The complex conjugate and transpose of state IV)) is known as bra (41. norm 11|0)11 2 = (4{4), where The state is defined to be complete, such that, the (..f..) denotes the inner product. The inner product of 1') and 1#), (V510), maps an ordered pair of vectors to a scalar in the set C and is defined by the following properties: * Positivity: (0140) > 0 for 4') # 0; " Linearity: (#| (aI11) + b 102)) = a (#q11) + b (#412); and * Skew symmetry: (01) = ($0)* . 2. Observables: An observable is a property of a physical system that can be measured in principle. In quantum mechanics, an observable is a self-adjoint operator, i.e., A = At, where A is a linear operator. An operator is a linear map taking vectors to vectors, (2.1) A: 14)->AI). A self-adjoint operator in Hilbert space has a spectral representation. Another words, the eigenstates form a complete orthonormal basis. We can express a selfadjoint operation A as A (2.2) anPn, = n where an is an eigenvalue of A and P, is the projector onto the eigenspace of A with eigenvalue an. For example, if an is nondegenerate, then Pn = In )1(, where In) is the eigenvector with eigenvalue an. 3. Measurement: The measurement process of a quantum system has numerous interpretations, but the most common version is called the Copenhagen interpretation. In quantum mechanics, the numerical outcome of a measurement of the observable A is an eigenvalue of A, an. Measurement of a quantum state IV)) is described by the 30 measurement operator P, which gives the output a, with probability P(an) = |IPnjV)f1 2 = (OjPnkb). (2.3) The measurement operator must satisfy the completeness relation (2.4) = I. EP n If the outcome is an, then the normalized quantum state after measurement becomes Pn|b) 1 ((OlPn n) 10)) 1/2-+ .(2.5) If the measurement is immediately repeated, then according to this rule, the same outcome is attained again, with probability one. The state of the quantum system collapses to a post-measurement state. Collapse of the quantum state implies that the information contained in the coefficients of the eigenstates is instantaneously and irreversibly destroyed. Post-measurements cannot reveal information on the other states. 4. Dynamics or Evolution: Under a closed system, the time-evolution of a quantum state is described by unitary operators, where an unitary operation U has the property UtU = I. In the Schr6dinger picture of dynamics, the vector describing the system moves in time as governed by the Schr6dinger equation hd i. dth 1(t)) = HMO(t)), where H is the Hamiltonian and h is Planck's constant. (2.6) Note that in subsequent equations h is set to 1. For the time-independent Schr6dinger equation, the solution is 14(t)) = exp (-i7=Lt)I (t = 0))). 31 (2.7) We denote the time-evolution operator as U(t), where U(t) = exp (-i'Ht) (2.8) |V(t)) = U(t)14'(t = 0)). (2.9) and This completes the four axioms of quantum mechanics. Next, we explore the fundamental unit that makes quantum computation possible: the quantum bit. 2.2 Quantum bits The indivisible unit of classical information is the bit, which takes on one of two possible values: logical 0, or logical 1. The corresponding unit of quantum information is known as the "quantum bit" or qubit. In contrast to classical bits, a qubit can exist in a superposition of states 0 or 1, otherwise denoted by the quantum states: 10) and 11). The most general normalized state for a single qubit can be expressed mathematically as 14) (2.10) = alO) + b1l), where a and b are complex numbers that satisfy Ia12 + b12 = 1. The overall phase of the qubit is physically irrelevant and cannot be revealed by any measurement. We can also write |0) as 4') = cos () 10) + exp (iq) sin (0) 1). (2.11) The state of a qubit can be visualized as a vector in a sphere, called the Bloch sphere, as shown in Figure 2-1. In this representation, the qubit has two degrees of freedom, 6 and #. If the state of the qubit is along the i-axis, then 1') = 10) or 11). When the vector lies along the 2 - Q plane, 11). 32 the qubit is in a superposition of 10) and 10> 10> IV> 10>-i> -----------IV> lo+ 1> ) +il1) Figure 2-1: (a) Bloch sphere representation of the state 1') of a single qubit. (b) The position in the Bloch sphere of five important states. The states are not normalized. 2.3 Multiple qubits If we have two or more qubits, then the picture of the Bloch sphere does not hold true. The state of two qubits, each in an arbitrary superposition 11) = a10) + bill) and 1b2 ) = a 2 10) + b2 11), is written as 10) = 101) 0102) (2.12) 1') = aia 2 |00) + a 1 b2 101) + bia 2 10) + bib 2 |11). (2.13) where 0 is the tensor product or Kronecker product symbol. The coefficients of the terms in the joint superposition state of the two qubits can be viewed independently of each other. Thus, a more general statement is 1#) = cool00) where ICool 2 + coil 2 + cio| 2 + + cio10O) + ci11), + coi0) (2.14) Icnl 2 = 1. For n qubits, a general quantum state 1) can be described as: 2n-1 I) cili), = (2.15) i=o where i is the decimal representation, and ci satisfies the normalization condition 2 n- 1 Icil2 The Hilbert space in an n-qubit system has 2" dimensions, and the state of the 33 quantum system 4') can be in a superposition of 2" states. Notice that the number of degrees of freedom for an n-qubit system grows exponentially. 2.4 Computation using quantum systems Now, we examine the quantum mechanical properties that makes quantum computations possible, such as entanglement, quantum parallelism, and unitary evolutions. 2.4.1 Entanglement An n-qubit system can be expressed as 4') (2.16) = where |0j) is the quantum state of the i-th qubit and D represents the tensor product of n states. For example, Equation 2.13 is in the form of Equation 2.16. If the state of a quantum system can be expressed in the form of Equation 2.16, then the state is deemed separable. One of the properties that makes quantum mechanics unique is that there exists states (in the physical realm) where it is impossible to express a separable state in such a form. We call such a state non-separable or entangled because the qubits are correlated. Entanglement is a very important concept in quantum information theory because it is believed to be a necessary resource to speed up certain algorithms. An important entangled state is the two-qubit Bell states (also known as EPR pairs): |3oo) = 100),+i) (2.17) 1001) = 101),+10) (2.18) ,00)-l) and ) 111i)|#11)== 101) - 110) . 34 (2.19) (2.20) 2.20 Note that the measurement of a qubit in the Bell state reveals the state of the second qubit. This correlation is what Einstein called "spooky action at a distance." 2.4.2 Quantum parallelism and quantum measurement Suppose we apply a classical reversible gate, g(x), where IV) = cob0) + ciii). By linearity, applying g(x) on the superposition yields: colo) + ciii) '-4 colg(0)) + c1|g(1)). (2.21) Interestingly, application of the gate g(x) results in the parallel computation of both states 10) and 11). We begin to see how quantum computation may yield exponential speed-up for certain algorithms. Consider a two-qubit system in the state + cio10) 1') = coo 00) + coi01) + cii1l). (2.22) The execution of g(x) results in the output state 14) = coo g(00)) + coilg(Ol)) + ciolg(10)) + c11 Ig(11)), (2.23) so that four values have been evaluated in parallel. In general, for every additional qubit, the number of parallel evaluations doubles. A function that is applied on n qubits results in the evaluation of 2" possible states: 2"-1 2"-1 1:1X) F- E x=O Ig W) (2.24) x=O where x is the integer encoded by a string of n bits. As the number of qubits grows linearly, the number of evaluations grows exponentially. Thus, a quantum computer can simultaneously perform a number of parallel operations. This property was first introduced by David Deutsch in 1995, and was termed quantum parallelism [Deu85]. As a consequence of quantum parallelism, quantum 35 computers that utilize superposition appeared to have exponentially more power than classical computers. However, as mentioned in Section 2.1, the measurement process collapses the superposition of quantum state into a single eigenstate. Measurement has great implications in the context of quantum parallelism. Suppose, there exists a 2-qubit system. When a measurement of a superposition state occurs, the result probabilistically returns either g(OO), g(01), g(10), or g(11). If n qubits are in a superposition of 2n states, only one of the 2n states will be the result after the measurement. It appears that the exponential power of quantum computers is not accessible. However, quantum measurement is not necessarily detrimental to quantum computation. Despite the necessity of measurement, algorithms exist that utilize entanglement and quantum parallelism to speed up classical computations. 2.5 Quantum gates and circuits The mathematics describing quantum computing can be abstracted to a quantum circuit language, analogous to Boolean, logic gates in electrical engineering. We present a description of unitary operations at an intermediate level of abstraction based on quantum gates analogous to classical gates, such as, the NOT, AND, and XOR gates. We describe: " quantum gates that can be implemented on a quantum computer, * quantum circuit notation for relevant quantum gates, and * a universal set of implementable quantum gates. 2.5.1 Unitary evolution Unitary evolution is used to describe the construction of quantum circuit. One of the axioms of quantum mechanics (Section 2.1) dictates the dynamics of a quantum system, i.e., the time-evolution of a quantum state, are described by: 10(t)) = U(t)10(t = 0)), 36 (2.25) where we denote the time-evolution operator as U(t) as: U(t) = exp (-iZHt). (2.26) H is the Hamiltonian and h is set to 1. Using density operator p, the time-evolution is given by: p(t) = Epi (2.27) piU(t)I i(t = 0))(Oi (t = 0)Ut (t). Oi(t))(4'i(t)I The time-evolution of the quantum state can be visualized as rotations of a single qubit in the Bloch sphere, as shown in Figure 2-1, while multiple qubits can be visualized as rotations in Hilbert space. We can utilize time-evolution to perform quantum logic computations. 2.5.2 Single-qubit gates Unitary evolutions are generated by Hamiltonians, and by controlling these Hamiltonians, specific quantum computations are achieved. A single qubit Rb) is described by col0) + c1 1), which can be expressed in matrix notation as: (co 1') = (2.28) C1 where 14)) is a column vector of two entries, co and ci, and Ico12 + c Here, 10) 1 = 0) and 11) 0 = 12 . Note that the matrix representation of (01 is a row vector; specifically, it is the complex conjugate and transpose of 4'). A single-qubit operation can be describe as a 2x2, unitary matrix acting on 4'initial: 4 )final = U4)initial. (2.29) For example, consider the NOT operation. The NOT function takes 10) to 1) and 11) 37 to |0). The unitary matrix for a NOT operation corresponds to: UNOT By applying UNOT 0 1 1 0 (2.30) =- on state IQinitial, we see that: 0 0fnal - 1 cO Ci 0) ci CO (2.31) This operation switches the states 10) and 1). We have shown that a single qubit can be visualized as a rotation in the Bloch sphere (Figure 2-1). More specifically, any single-qubit rotation takes the form U = exp (ia)Rj(0), (2.32) where R(O) also corresponds to a 0 rotation in the Bloch sphere about the r-axis. We can define Rf1(6) in the following manner: ) =cos (-)cr 2CO R (0) = exp (- i '2 where 0 = (o,, u-Y, o-) i sin - (nru + nYo- + nzo-), 20 (2.33) -y , and oz denote the Pauli matrices: and o-, 0 - 1 1 0 , =- ( 1 0 0 ( -iJ ,o-, 7 (2.34) and a- denotes identity matrix: The Pauli matrices give rise to three useful classes of unitary matrices, the rotation operators about the Rx(0) Ry(6) exp exp (-i 2 2 Gi-? RZ(6)- exp (-i 2) 2 = cos ) (-) 2() 20 o-r - 38 y-, i sin c-i -isin - (2 -, i and i-axes: - c-2, (2.36) - sin - (2.35) o-. 2 UZ (2.37) A rotation about the i-axis of 90' corresponds to an unitary matrix R,(90'), while a rotation R,(180') is a NOT operation with an overall global phase factor. Another interesting single-qubit gate is the HADAMARD gate, given as the matrix 1(1 H= vl2 1N 1 . (2.38) -1)' The HADAMARD gate transforms the basis state, 10) or 11), into equal an equal su- perposition of states 10) and 11) with different phases: ) (2.39) 10)- 1) (2.40) 0) I1) * This gate can be implemented by -- and Q-rotations: H = R'(1800 )R9(900 ) = Rv(90')Rs(180 0 ). Single quantum operations are represented using circuit diagrams. (2.41) A unitary operation, U, is shown in Figure 2-2(a). The NOT gate is represented by the symbol D, as shown in Figure 2-2(b). 39 U (b) (a) Figure 2-2: Quantum circuit representation of (a) an arbitrary single-qubit rotation U, and (b) the NOT gate. 2.5.3 Two-qubit gates The "classical" two-qubit gate is the controlled-NOT, or CNOT, gate. The CNOTij gate has two qubit inputs, i and j. Qubit j is called the target, and qubit i is known as the control qubit. If qubit i is in the state 11), then the target qubit is flipped; otherwise the target qubit remains the same. The truth table is shown in Figure 2-3. Input(ij) 00 01 10 11 Output (i) 00 01 11 10 Input(ij) 00 01 10 11 (a) Output(ij) 00 1 1 10 0 1 (b) Figure 2-3: Truth tables for (a) the CNOT 12 operation, and (b) the CNOT 21 operation. For a two-qubit state 1) = coo100)+coi 01) +c 1o110) +cjI| 11), the unitary matrices for the CNOT gates are: 0 1 0 0 1 0 0 0 0 1 0 0 UCNOT 12 = and UCNOT 2 1 1 0 0 0 = 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 (2.42) 1 An extension of the CNOT gate is the controlled-U gate, where a single-qubit operation U is performed on the target qubit if and only if the control qubit is 1). There is also 40 the zero-controlled-U gate, in which U is executed if and only if the control qubit is 10). Finally, another two-qubit operation is the SWAP gate: 1 0 0 0 Uswap = (2.43) , 0 1 0 0 0 0 0 1) which switches the state of the two qubits. An alternate to express the SWAP operation is by a series of CNOT operations: SWAP 12 = CNOT 12 CNOT 21 CNOT (2.44) 12 . The quantum circuit representations of all two-qubit operations presented in this section are shown in Figure 2-4. U (a) (b) (c) (d) Figure 2-4: Quantum circuit representation of (a) a controlled-NOT gate, (b) a zerocontrolled-NOT, (c) a SWAP gate, and (d) a controlled-U gate. The e symbol denotes the control qubit - the controlled operation is only executed if the qubit is in the 11) state. The o symbol denotes the zero-controlled qubit, i.e., the operation is only executed if the control qubit is in the state 10). One can create multiple-qubit operations, i.e., three or more qubits, using onequbit and two-qubit gates. For example, the TOFFOLI gate, as shown in Figure 2-5, is composed of CNOT gates and controlled-V, where: v= 2 41 (2.45) The TOFFOLI operation flips the target qubit (the third qubit) if and only if the two control qubits are 11); hence, it is also referred to as a doubly-controlled NOT or CCNOT gate. V' V V Figure 2-5: Quantum circuit representation of a TOFFOLI gate and its decomposition into two-qubit gates. The quantum circuits in this section correspond to logical operations similar to classical Boolean circuits. In classical computation, a small set of gates (e.g. AND, OR, NOT) can be used to compute an arbitrary classical function. Such a set is uni- versal for classical computation. Similarly, there exists a set of quantum gates that is universal for quantum computation, i.e., any unitary operation may be approximated to arbitrary accuracy by a set of quantum gates. For example, an arbitrary singlequbit gate and CNOT gate form a set of universal quantum gates. With a universal set of quantum gates, quantum algorithms can be implemented. 2.6 Quantum algorithms This section discusses examples of some milestone quantum algorithms developed in the field of quantum information theory and illustrates Shor's algorithm using quantum circuits. We also describe the Deutsch-Jozsa algorithm and Grover's algorithm. These three algorithms have been proven to be faster in computational steps than their known classical counterparts, requiring less resources, such as quantum memory (e.g. spin of an electron) or quantum channels (e.g. fiber optic line). We briefly give an overview of the Deutsch-Jozsa algorithm and Grover's algorithm, followed by a quantum circuit description of Shor's algorithm. 42 In 1992, Deutsch solved Deutsch's problem, showing an exponential speed-up of the quantum solution over the classical one. Deutsch's problem is stated as follows: Suppose Bob has a black box, or oracle, f(x) with n input bits and one output bit. Alice selects an n-bit number ranging from 0 to 2" - 1. She sends the number to Bob, and he calculates the number using the oracle. The output of the oracle is promisedto be either constant for all possible input values or balanced, i.e., equal to 1 for exactly half of all possible input values, and 0 for the other half. Alice's goal is to determine with certainty whether Bob's oracle is constant or balanced. Classically, Alice needs to send Bob 2/2+1 different inputs to determine whether Bob's oracle is constant or balanced. Deutsch and Jozsa realized that a quantum computer can solve the problem exponentially faster than the classical approach. In the quantum algorithm, the initial input to the oracle is the equal superposition of all possible values from 0 to 2' - 1. During the computation the wrong answers destructively interfere while the correct answer interferes constructively. In this approach, only one query of the oracle is needed, highlighting the potential advantage of a quantum computer. Unfortunately, there are no practical applications known to take advantage of Deutsch's algorithm. It is only a clear demonstration of how a quantum computer can solve certain problems with an exponential speed-up over a classical computer. In contrast to the Deutsch-Jozsa algorithm, Grover's algorithm has practical applications. Grover showed that a quantum computer can search an unsorted database with polynomial speed-up over the best possible classical, unstructured search algorithm. An example of an unstructured search is finding the name corresponding with the phone number in a phone book with n alphabetically listed names. On average, one would look up (n(n + 1)/2 - 1) /n ~ n/2 different numbers before finding the name. With Grover's algorithm, one can find the name in V/n attempts. As in the Deutsch-Jozsa algorithm, there is the notion of a promise problem in Grover's algorithm. In this case, an oracle returns either f(x) = 0, for all values of x except for the unique entry x = x 0 , or f(x) = 1, where x = xo. The input is put into an equal superposition of all possible values, using the HADAMARD transformation, 43 and sent through a quantum circuit, which performs a number of Grover iterations and eventually returns xO. Intuitively, Grover's iteration constructively builds up the amplitude of Ixo) while reducing the amplitudes of the remaining terms. Note that the amplitude of Ixo) peaks to a maximum value, and afterwards, the amplitude oscillates sinusoidally. The measurement of the output will be xO with high probability. Shor's algorithm 2.6.1 Shortly before Grover's algorithm was discovered, another algorithm had made a large impact in the field of quantum computing. In 1997, Shor made a tremendous discovery in the problem of factorization and the computation of discrete logarithms [Sho97]. He showed an exponential speed-up over the best known classical algorithms and provided a method to efficiently decipher public-key crypto-systems that rely on the difficulty of factoring, such as the RSA encryption algorithm. The factorization algorithm quickly became famous and was dubbed as Shor's algorithm. We describe Shor's algorithm and highlight the major steps necessary for obtaining the solution, including the order-finding problem. We outline the solution to the factorization problem. Note that much discussion about the mathematics behind this algorithm is left out of the discussion. The solution to factorization is mainly due to results from number theory. Suppose L is the product of two prime numbers. Shor's algorithm states: " If L is even, then return the factor 2, else " If L = ab for a > 1, b > 2, and a, b E Z, then the factors can be efficiently, probabilistically determined, and the factors are returned. " If L fits neither of the first two conditions, randomly choose x such that 1 < x < (L - 1). If gcd(x, L)> 1, then return the factor gcd(x, L). * If the first three conditions do not return a factor, then use the order finding subroutine to find the order r of x Modulo L. 44 * If r is even and x 2 -1(mod L), then the factors of L are computed by the ged(xl + 1,L) and and the gcd(x" - 1,L). Finally, test to see if these factors are non-trivial. If so, return the factors; otherwise, the algorithm fails. The key step to the exponential speed-up over classical algorithms is the quantum order-finding algorithm, which determines the order, r, of x(mod L). function is represented by the function f(j) = Suppose a xi (mod L). If L = 15 and x = 4, then the order r is 2. We explicitly calculate the order for L = 15 in Table 2.6.1. j f(j) 0 1 2 3 4 5 1 4 1 4 1 4 Table 2.1: The solution to order-finding problem is explicitly calculate for L = 15. The order of is r = 2 for x = 4. The quantum circuit for the order-finding algorithm is shown in Figure 2-6. The unitary operation U performs the transformation Li) 1k) -+ j) |ximod L). The size of the first register is approximated as t = 2 log(L), and the second register is approximated as log(L). The operation, controlled-Us, is efficiently implemented using the modular exponentiation procedure [NCOO]. The circuit operates as follows: " Initialize the quantum state to 10) 1). * Apply the HADAMARD operation to create a superposition of states on the first register, changing the quantum state to 2-1)1). -E * Apply controlled-Uj operations to create 1 E~-I I)lxj(modL)) ~ 1 ENt--1 r_ exp (27ris/r) 1j) Ius), where s/r is an n-bit approximation of s/r and us) = exp (-2isk xkmod L) Note that if we wish to approximate s/r to an accuracy of n-bits with probability of success at least 1 - e, we choose t = n + [log (2 + 1/2c)] 45 * By applying the quantum Fourier transform to the first register, the quantum state becomes L 1 I s/r)Iu,). " Measurement of the first register yields s/r. t )ot H t lif Figure 2-6: The quantum circuit which performs the order-finding algorithm in Shor's algorithm. The continued fractions algorithm is applied to the result of the quantum orderfinding circuit to reveal r [NCOO]. Finally, the factors of L are determined by calcu- lating gcd(x' + 1,L) and gcd(xl - 1,L). 2.7 Summary Based on the axioms of quantum mechanics, we have established methods to perform quantum computations. Simple logical operations are accomplished on a single qubit, which can be mapped to the Bloch sphere. However, the Bloch sphere does not apply for quantum operations on multiple qubits. Operations on multiple qubits can correspond to a parallel number of computations; quantum systems containing n qubits can be represented by 2n complex variables. This concept of quantum parallelism can be used along with entanglement to possibly speed up certain quantum algorithms, which can efficiently solve certain mathematically hard problems. Quantum algorithms can be described by quantum circuits that correspond to unitary evolutions. As quantum circuits increase in size, the complexity of the circuit 46 grows, raising the probability of failure in a quantum circuit; thus, implementing complex RF pulse sequences is a challenging task, requiring precise control of the RF pulse to accomplish a quantum logical operation. In this chapter, we have focused on the ideal theoretical scenario. However, realistically generating precise pulsed excitation to control the qubit system requires one to understand the physics of the system, representing the quantum computer, and the requirements for control. In the next chapter, we describe nuclear magnetic resonance (NMR) quantum computers and identify the methods and tools underlying the control of qubits. 47 48 Chapter 3 Nuclear Magnetic Resonance Quantum Computing The language of quantum computation and quantum circuits can be translated to a sequence of RF pulses, which are generated via analog and digital circuits, such as the pulse programmer and the power amplifier, in a nuclear magnetic resonance (NMR) spectrometer. We begin, in Section 3.1, by describing the history of NMR spectroscopy. Then, Section 3.2 discusses how quantum circuits and operations are accomplished using NMR techniques and RF pulses. Underlying pulsed NMR techniques, there is the NMR instrumentation, which consists of numerous components including the magnet, probe, receiver, workstation, and receiver, as described in Section 3.3. Two major components are of interest: the power amplifier and the pulse programmer. Understanding the limitations of the NMR system for quantum computing helps us identify the problems associated with it. The experimental demonstration of Shor's algorithm shows the need for pulse programmers capable of executing complex, fast RF pulse sequences and low-noise, power amplifiers. In Sections 3.4 and 3.5, we discuss the instrumentational issues with pulse programmers and power amplifiers used for NMR quantum computers, highlighting the challenges of generating complex pulses and decreasing ringdown time of power amplifier, which can increase the signalto-noise ratio (SNR) during readout. 49 3.1 NMR historical background The purpose of spectroscopy is the characterization of a molecular system by a "spectrum." In most cases, the spectrum presents resonance properties of a physical system and can thus provide insight into its quantum mechanical structure. One example of a spectroscopy is nuclear magnetic resonance (NMR) spectroscopy. The first experiments and discoveries about NMR were executed by Bloch and Purcell in 1945 [BHP46, PTP46]. They discovered that it is possible to transfer energy from RF waves to certain nuclei, whose resonance is defined by a uniform, strong magnetic field applied along a fixed axis. Furthermore, they were able to excite the state of the system, populating higher energy levels. When the system relaxed to its equilibrium state, a small signal was induced, which was detected using using a coil. Over the last two decades, NMR spectroscopy has gone through a renaissance. The advancement of modern digital electronics have made it possible to apply novel techniques in NMR such as Fourier analysis, which in turn, made high-resolution NMR possible. The advancement in NMR spectroscopy has made it one of the most powerful analytical tools in modern science with applications including solid state physics, chemistry, molecular biology, and medicine. Interestingly, NMR spectroscopy also has connections to quantum computation. In 1997, Gershenfeld and Chuang [GC97a], and independently Cory, Havel, and Fahmy [CFH97], proposed to use bulk spin NMR for experimental quantum computation. They showed how to implement quantum logic operations using liquid state NMR techniques. In 1998, the first set of experiments that demonstrate a quantum algorithm using NMR were completed by Chuang [CVZ+98] and independently by Jones [JM98]. From 1998 to 2003, feverish work on NMR quantum computing led to the increase from two-qubit systems to seven-qubit systems and to the implementation of the Deutsch-Jozsa algorithm, Grover's algorithm, and Shor's algorithm, the cornerstone algorithms of quantum scomputing. 50 3.2 NMR quantum computing NMR phenomenon provides a physical medium for the application of quantum information theory. In fact, DiVincenzo's criteria [DiVOO] provides a connection between quantum information theory and physical systems. The criteria states that any physical system, considered as a candidate for quantum computation, should satisfy the following: (1) one needs well-defined two-state quantum systems, (2) one should be able to prepare the initial quantum state with sufficient accuracy, (3) a long phase coherence time is needed for coherent operations, (4) control over the qubits' Hamiltonian is required to perform unitary operations, and (5) quantum measurement is necessary for read out. One system that meets these requirements is a spin-1/2 nuclear system. A nuclear spin-1/2 system is a good candidate for a quantum computer. A nuclear spin-1/2 system has a 2-level system, which naturally represents a qubit, as shown in Section 3.2.1. These spins have coherence times long enough to perform quantum operations [GC97b]. Quantum logic circuits can be translated to RF pulses, which can be used to carry out quantum operations with modern NMR spectrometers. Multiple-qubit systems can be engineered with special designer molecules, utilizing inter-molecular coupling and multiple-qubit operations can be carried out, as described in Section 3.2.2. In NMR, single spin detection is extremely difficult to achieve. Hence, quantum operations are applied on a bulk sample of identical and independent spin systems. Each independent system can be thought as an individual quantum computer which runs its quantum operations in parallel with other systems. 3.2.1 NMR quantum computer: the physical system In NMR quantum computing, the physical representation of each qubit is a different nuclear spin, with I = 1/2. The Hamiltonian, of a spin-1/2 particle in a magnetic 51 field of strength B along the 2-axis is hwo Ho = -hyBI, = -hwoI = 0 2 where y is the gyromagnetic ratio of the nucleus, ) , (2 '- (3.1) is the Larmor frequency, and WO =yB. The eigenvalues of the Hamiltonian are 1 -hwo, 2 1 -hwo, 2 = e i = (3.2) and (3.3) where each eigenvalue of the Hamiltonian corresponds to an energy level depending on B. A molecule of n distinguishable uncoupled spin-1/2 nuclei constitutes an n-qubit quantum computer. The Hamiltonian for Zeeman splitting is given as: 'Ho = - where i is the spin index, and h (3.4) wiIl, ! is the Larmor frequency associated with spin i. The Larmor frequencies for each spin are different depending on the atom's -y; thus, different nuclei have distinguishable frequencies for a heteronuclear system. Nuclear spins in a molecule have two distinct interaction mechanisms: (1) dipolar coupling (also known as magnetic dipole-dipole interaction) and (2) J-coupling or scalar coupling. In general, in an isotropic liquid, molecular dipolar coupling is averaged away due to rapid tumbling of molecules. The second interaction, J-coupling, is the dominant mechanism utilized for coupling qubits. For a heteronuclear sys- tem, the resulting coupling is mediated by shared electrons in the chemical bonds between atoms in the molecule. The coupling strength J depends on the element. The first-order approximation is described by the Hamiltonian: 27rJij I® 9 Iz , Hj = h i<j 52 (3.5) where Jij is the coupling between spins i and j. The complete Hamiltonian, neglecting higher order terms, is approximated as: Htot = Hz + Hi The additional J-coupling terms introduce shifts of ± (3.6) in the energy levels, which are independent of the magnetic field. In this case, we have assume |wi -W21 >> I J. For example, two qubits whose interactions are mediated through J-coupling give rise to 4 distinct energy levels. 3.2.2 RF pulses perform quantum operations Quantum circuits are implemented using RF pulses in NMR, which can accomplish both single- and multiple-qubit operations. The energy from electromagnetic RF waves can be selectivity transferred to certain spins in a molecule, thereby producing quantum operations depending on the field strength and time of RF wave. A single, unique pulsed RF of certain frequency corresponds to single gate operations, for example the NOT gate. With multiple RF frequencies and a coupled spin-1/2 system, we can extend beyond single gates operations and perform multiple-qubit logic operations like the CNOT gate. Single qubit rotations Recall from Chapter 2, a spin-1/2 particle can be classically viewed as a magnetization vector in 3-D space. A magnetic field applied along the 2-axis initializes the magnetic vector, aligning it in the same direction as the field vector. The magnetic vector precesses about the 2-axis, which is analogous to a spinning top. By applying RF pulses in the y- axis. - plane, one can rotate the magnetic vector about the 1- and/or This classical picture of spin can be mapped onto the Bloch sphere, where RF pulses corresponds to rotations of the magnetic vector in the Bloch sphere. By applying a polarized RF field in the :- plane on a selected spin i at wi, we can perform single qubit operations. An RF pulse along the ii-axis induces a 0 rotation in the Bloch sphere as expressed by the rotation operator exp (-ig-). In the rotating 53 frame, the application of an RF pulse at the resonance frequency yields a rotation about the applied axis at an angle: 0 = h-yj/t,, (3.7) where tPW is the duration of an RF field and 3 is the RF field strength. An RF pulse about the J axis for an angle of 900 corresponds to the rotation operator Rx(9 0 ). By shifting the phase of the RF pulse by 90', the rotation operator is Ry(9 0 '). Two-qubit rotations Logic gates can be imple- Two-qubit operations are mediated via J-coupling. mented by allowing the system to evolve naturally. We assume that coupling is between spins i and j and that individual couplings can be selectively turned on. Using equation 3.5, the evolution under the coupling Hamiltonian for a duration t is: Uj(t) =exp (-iJijtl 0 Ij) exp (-irJit) 0 0 0 0 exp(i'it) 0 0 (3.8) 2__. 0 0 exp(it) 0 0 0 0 exp ( 2) An example of a two-qubit operation is Z2ZjUj(t = 1/(2Jij))), which yields 0 0 0 0 1 0 0 0 0 1 0 0 0 0 -1 1 exp (iir/4) The operation is a controlled-z acting on spins i and j. CNOTij, ( (3.9) . Another example is the which can be implemented by the following pulse sequence: ZjYj Uj(1/(2Jij))XjZj. 54 Single- and multiple-qubit gates are implemented by a sequence of precisely controlled RF pulses acting on a specially designed molecule. To accomplish single-qubit operations, RF fields are applied at the Larmor frequency of interest, Wi for a finite duration. For multiple-qubit systems, J-coupling interactions among nuclei give rise to unique energy splitting that are accessible to RF pulses. However, as the number of qubits grow, it becomes difficult to address with traditional RF pulses because the splittings in the spectrum start to spread. Undesired transitions outside of the qubit manifold are induced with off-resonance RF pulses, which induce errors in the quantum circuit, such as bit flips. Shaped pulses are used to reduce errors by increasing the selectivity between energy levels due to a narrow spectral density [Ste03]. Pulse shaping is generated by a pulse programmer, which often controls the amplitude and phase of a pulse. Since control of qubits via RF pulses is vital, pulse programmers are an integral part of the NMR spectrometer. 3.3 NMR spectrometer Pulsed NMR techniques, such as pulse shaping, are achieved using a modern NMR spectrometers, as shown in Figure 3-1. Typically, a sample is placed in the center of a large superconducting magnet and under the influence of a large static magnetic field B, causing Zeeman splitting. RF pulse sequences are generated by the spectrometer and applied to the sample through RF coils. This section discusses the main components of a NMR spectrometer, the magnet, probe, receiver, workstation, and transmitter, and cites the Varian NMR spectrometer as an example [VNMO1]. The Varian spectrometer is a commercial spectrometer used for NMR spectroscopy and NMR quantum computing experiments. The version used in our lab is customized for quantum computing, illustrating the need for specialized components. The pulse programmer and the power amplifier are two important components because they contribute to the control of a quantum operation. Magnet and probe In the Varian spectrometer, the magnet and the probe physically compose the greater 55 .9 A A £ Rcoil P a P A ~ Figure 3-1: Overview schematic of an NMR spectrometer [FR86] bulk of the system. A large well-shielded housing encases both the magnet and the probe, with a large, magnetic field generated by a superconducting magnet. The magnet is a solenoid immersed in a bath of liquid helium, which cools it to a temperature of 4.2K, generating a field strength of 11.7 Tesla at 100A. Figure 3-2 shows a picture of an NMR magnet. The probe consists of RF coils, tuning and matching circuits, a temperature control system, and gradient coils. The probe is designed to accommodate the transmission of RF pulses to the sample and the transmission of the FID signal to the receiver (see Section 3.5 for more details). The FID signal is the signal induced from the sample by the RF pulse (see Appendix A for more details). Receiver The receiver detects the FID signal from the probe, by amplifying a signal on the order of [p-Volts. The FID signal travels down a quarter-wavelength cable, which acts as an impedance transformer, to a preamplifier. The preamplifier is a low-noise amplifier with an overall noise figure of 1.7dB for high bandwidth operation preamplifier and 1.6dB for low bandwidth operation. The total gain is 35dB. Next, the FID signal is mixed by an intermediate frequency (IF) of 20MHz. The resulting mixed signal is mixed down to audio frequencies (kHz) and sent through 56 Figure 3-2: Picture of an Oxford Instruments 500MHz narrow-bore NMR magnet audio filters. Furthermore, the signals are mixed such that the £- and Q- magneti- zations from the FID signal are measured. This is known as quadrature detection, and the details are discussed in Section 6.4. For the Varian NMR spectrometer, the maximum sampling rate is 1MHz with a buffer holding up to 524288 points. After the signals are captured, data are uploaded to the workstation. Workstation Central to the operation of an NMR spectrometer is the workstation, which is composed of a Sun Ultra 10 computer with proprietary software (VNMR) from Varian. The user can design different experiments with the software and run multiple automated experiments. Pulse sequences are written in C and compiled into an byte code. Pulse sequences are generated by the pulse programmer, and the resultant signals sent to the workstation for further analysis. 3.3.1 Transmitter: pulse programmer and power amplifier The control of the qubit relies heavily on two components, the pulse programmer and power amplifier, which together make up a large part of the transmitter. The customized Varian NMR is equipped with four RF channels. Each RF signal is gener57 ated from a temperature-controlled master oscillator, which can generate a continuous lVrms signal from 1 to 620MHz via PTS synthesizer. Figure 3-3: The NMR cabinet houses the transmitter and control electronics for the Varian spectrometer. The pulse programmer "gates" the continuous RF wave using transistor-transistor logic (TTL) pulses. In addition, the digital output from the pulse programmer can be used to control analog circuits that determine both the amplitude and phase of the RF pulse; thus, pulse shaping can be accomplished. The NMR spectrometer has a minimum pulse length of 100 ns and a timing resolution of 25 ns. The phase can be set in steps of 0.5' This is accomplished in two steps, either coarse or fine shifters. The coarse shifter sets the phase in steps of 900, while a fine shifter achieves 0.5' resolution by mixing two quadratures with adjustable amplitudes. Each transmitter is equipped with a linear attenuator, which controls the amplitude of the pulse. There are a total of 4096 discrete steps in the amplitude. After the RF-gated pulse is generated, the signal is routed to another set of attenuators, which attenuate the signal over a range of 79dB in steps of 1dB. Overall the coarse attenuators have a greater dynamic range than the linear attenuators in the transmission boards. Figure 3-3 shows the housing for the transmitter boards. 58 As seen in Equation 3.7, the amplitude of the RF pulse is vital to controlling the angular rotation of the vector in the Bloch sphere. The pulse programmer provides minimal amplification, whereas linear power amplifiers provide a large gain. There are two amplifier units, consisting of a low frequency amplifier (6-200MHz) and a high frequency amplifier (200-500MHz). The maximum power is 100W in pulsed mode, providing 50dB gain. In continuous mode, the maximum power is 30W at low frequencies, and 15W at high frequencies. The amplifiers are designed to accept input rise and fall times as short as 200 ns. 3.4 NMR experiments The pulse programmer's and the power amplifier's importance have been demonstrated in recent NMR quantum computing experiments. These experiments have shown the need for complex pulse sequences, requiring precise control of the pulse durations and amplitudes in order to minimize errors in quantum operations. The first experiments demonstrating the feasibility of quantum computers were two-qubit implementations of Grover's algorithm [CGK98, JMH98]. Once NMR proved feasible for the implementation of quantum algorithms, the next goal was to confirm other quantum algorithms. Molecules were developed for three-qubit and five-qubit quantum systems, and the three-qubit Deutsch-Jozsa algorithm was demonstrated using various quantum circuits [LBF98]. As more algorithms were demonstrated, the complexity of these experiments became clearer. The experimental demonstration of the order-finding problem and Shor's factoring algorithm [VSB+01, VSB+00] exhibited complex, shaped-pulses necessary to minimize undesirable transitions, which may lead to errors in quantum operations. 3.4.1 Experimental realization of Shor's algorithm The demonstration of Shor's algorithm illustrates the requirements the pulse programmer and the power amplifier for an NMR quantum computer. The smallest, 59 composite prime number that can be factored using Shor's algorithm is L = 15. A quantum circuit two registers, where the first register is at least n = 2m = 8 and the size of the second register is m = [log215] = 4. To factor 15, one can use quantum circuit shown in Figure 3-4. The outline of this quantum circuit differs from the quan- .H X.,~ x4 6 H 0> H M 11 H H 1> lp __ P VV a a2 Inverse E QFT A _S. a4 a' a a a" a Figure 3-4: Quantum circuit illustrating the order-finding algorithm in Shor's algorithm. tum circuit presented in section 2.6, but the concept remains the same. The quantum circuit implements the order-finding algorithm. The controlled-U operations is given by the classical function: f (X) = (3.10) x2k (modL). We can implement the order-finding algorithm using modular exponentiation and the quantum Fourier transform. Additionally we observe if Ixk) multiply by the first register a2k = 1. If IXk) = = 11) (for k > 2), we 0), then we do nothing. Thus, the circuit can be simplified to seven-qubits, because only a and a2 are implemented and at most two qubits of the first register act non-trivially during execution [VSB+00]. 3.4.2 The experiment and the importance of the pulse programmer The experimental demonstration of Shor's algorithm shows the need for complex pulse sequences to achieve quantum computations. These computations are achieved using the molecule hexafluoro butadiene, as shown in Figure 3-5. Five fluorine atoms and 60 two carbon atoms establish a seven-qubit quantum system. To selectively control the quantum operations, individual qubits must be selectivity addressed by RF pulses corresponding to the qubit's resonance frequency. 3 FJ -N _F c00 4 C5 H5 CO Figure 3-5: The molecule hexafluoro butadiene is used as the NMR quantum computer in Shor's algorithm. Shaped pulses are applied on the qubits in this experiment to effectively address individual qubits. These pulses start at a low magnetic field /, gradually increase in field strength to a maximum peak, and finally taper off to zero field. Shaped pulses can be characterized by the following properties: * selectivity: product of excitation bandwidth and pulse length (lower is more selective) * power: the peak power required for a given pulse length (low is less demanding) " robustness: whether the spin response is very sensitive to experimental imperfections, such as RF field inhomogeneities and calibration errors In this experiment, Gaussian 900 and Hermite 1800 shaped pulses are applied on the qubits. Both Gaussian 90' and Hermite 180' pulses have excellent selectivity and moderate power requirements when compared to traditional hard pulses. Figure 3-6 shows the RF pulse sequence applied on each qubit. A single experimental run consists of approximately 300 Hermite 180' shaped pulses and 30 Gaussian 90' shaped pulses. In the end, the total time for one experimental run is 720ms - 200 ms for initialization, 400ms for modular exponentiation, and 120ms for the quantum Fourier transform. 61 1 : iIJI& ILilunIiIll~ir1111Li IUikU I 2 3 :i_ 4 : 5 IJ. 1 ULiLUIILLLRLiJJJ 14k]LLI l I I II :1 l l I i , l i I I I I I I 6 7 (0) 17-(1)(2() Figure 3-6: NMR pulse sequence for implementing Shor's algorithm to factor N=15 with seven qubits. The tall lines represent 90' pulses acting on one of the seven qubits (horizontal lines) about the positive : (no cross), negative i (lower cross) and positive Q (top cross) axis. As we can see, the experimental implementation of Shor's algorithm is a great technical feat that requires complex, shaped pulses to control the qubits. The shaped pulses are generated by a sophisticated pulse programmer, which precisely controls the amplitude and duration of a pulse. The Varian pulse programmer, a commercial system, creates shaped pulses by constantly modulating the RF signal in discrete time slices. It is capable of outputting 2096 time slices with a minimum time of 0.2ps per slice. The experimental implantation of Shor's algorithm demonstrated the requirements for a pulse programmer. The pulse programmer is necessary for control of the amplitude, phase, and duration of a RF pulse, requiring sub-pus pulse widths. Furthermore, it needs to be scalable, flexible, and easy to use, or transparent. As the number of qubits increases, the pulse programmer must be designed to scale by adding more 62 RF channels to address the qubits. The complexity of synchronization among pulse programmers increases with the number of channels. A properly designed pulse programmer for quantum computing must be flexible so that adding another channel is simple and transparent to the user. Instrumentation issue for quantum computers 3.5 We have shown that precise control of phase and amplitude is required for performing quantum operations by illustrating the experimental implementation of Shor's algorithm. The experiment highlights the requirements for a pulse programmer but also identifies another problem in NMR quantum computing. The power amplifier's ringdown time effects the readout of a qubit's value. Section 3.5.1 discusses the contributing factors to the SNR, and Section 3.5.2 discusses the effect of a power amplifier's recovery time on the SNR. 3.5.1 NMR readout: measurement We have shown the qubits of a molecule are distinguishable by their Larmor frequencies. In the measurement process, when we apply an on-resonance RF pulse, the spectrum of the FID is characterized by a Lorentzian line. The result allows one to determine the state of a qubit after quantum operations are conducted. However, there are some considerations in the measurement process. In particular, the SNR must be considered. Signal-to-noise ratio The maximum NMR signal, V, is measured by an RF pick coil after an NMR FID signal is induced. V depends on the following: * the number of molecules in the sample, which is proportional to the volume V and the concentration nc, " the filling factor, M, which is the fraction of the coil volume occupied by the sample, 63 * the equilibrium polarization, co, which is proportional to y, B, and 1/T, " the frequency, wo, is proportional to y and B, " the geometry of the coil, known as the factor K, " the number of equivalent sites, ne, in the molecule for spin, i.e., there are three 1H in CH3Cl, " the quality factor of the coil, Q, and " the multiplicity of the NMR spectrum, m, which is inversely proportional. The noise in NMR measurements is dominated by the thermal noise in the coil. The root mean square (rms) noise amplitude is proportional to the square root of " the absolute temperature of the coil Tc, " the shunt resistance of the tuned circuit, R = QLwo, " and the bandwidth of the signal, Af. The SNR can be expressed as [Ste03]: S- 0c ncVnhe'y~/2 3/2Qi/2KT Q1 ,n-B K2 N MT (Tc Lof)(1/2) (3.11) The SNR is dependent on these parameters, but in practice, many of these parameters are interdependent. Furthermore, the process of signal acquisition lowers the overall, ideal SNR. 3.5.2 Transient data acquisition After an RF pulse of duration t, an FID signal is induced from the bulk spin sample. In order to measure the signal for data processing, such as Fourier analysis, the FID is digitally sampled. Usually, the sampling rates are tens of kHz up to tens of MHz such that Nyquist's limit is satisfied. Additionally, a low pass filter is used to limit the bandwidth so that aliasing and folding do not pose a problem. 64 An external trigger is used to enable digitization of the signal, which is useful for two reasons. First, magnetization at the correct points in multiple experiments can be sampled for signal averaging. Second, synchronization of two digitizers may be used for quadrature detection. Another important consideration during data acquisition is the recovery time of the receiver. In practice, the maximum SNR cannot be achieved due to the recovery time of the FID signal, which is a result of the rindown time of the power amplifier. The next section explores the issues of recovery time and its relation to the SNR and the ringdown time of the transmitter. 3.5.3 Recovery time After a high-voltage RF pulse from the transmitter is completed, there exists dead time during which no FID signal is detectable. The time that it takes to detect an FID signal after the RF pulse is known as the recovery time. There are two main contributions to the recovery time: " The receiver is saturated by the transmitter signal, which is greater than 0.6V, the break-through voltage of standard back-to-back diodes. This means the FID will be swamped out by the high-voltage transmitter signal. * After the RF pulse is completed, RF excitation takes a time constant, RC = r, to decay to amplitudes comparable to NMR FID signals. Long recovery times contribute to poor SNR. During an RF pulse on a qubit, the FID signal originates from the nucleus because the magnetization vector always precesses in the Bloch sphere picture. So, the entire FID signal cannot be captured because the maximum amplitude of the NMR signal, Vo, occurs during the RF transmission. Furthermore, the amplitude decreases exponentially with respect to recovery time, lowering the SNR. Since the transmitter contributes to the recovery time, the power amplifier becomes an important component to NMR quantum computing. The time an RF pulse 65 takes to decay to amplitudes below the break-through regime of the back-to-back diodes is known as the ringdown time. Generally, the larger the qubit system has the lower the SNR. Hence, for quantum computing, the ringdown time of the power amplifier needs to be decreased to shorten the recovery time during readout. 3.6 Summary We have discussed how to utilize nuclear spin-1/2 systems under a large magnetic field for quantum computation. Single- and multiple-qubit operations are achieved using NMR techniques. Classically, an RF field applied to a single qubit at the resonance frequency causes the magnetic moment of the nucleus to rotate about an axis as described by the Bloch equations. This is a key concept introduced in this chapter, i.e., quantum circuits can be implemented by a sequence of RF pulses. The control of qubits is accomplished via the pulse programmer and the power amplifier; the pulse programmer is used to generate pulse sequences, and the power amplifier contributes to the amplification of the pulse as well as SNR on the readout. We have examined the requirements for the pulse programmer and the power amplifier. The pulse programmer requires complex, arbitrary pulses with precise amplitude and phase control. The pulse programmer is an integral part of the NMR spectrometer, controlling most of the functionality of the system and interfacing between the computer and the spectrometer. The pulse programmer is an extremely complex design to implement. What technologies can we adapt to design a pulse programmer quickly, and yet, targeted for an NMR quantum computer? The readout of the FID signal can be improved by examining alternative power amplifiers applicable to NMR technology. The power amplifier requires fast ringdown times and low-noise amplification. For the power amplifier, naturally we ask, what are needs for an NMR quantum computer, and are there any RF designs that match them? In the next two chapters, we address these questions and discuss the first steps towards designing a power amplifier and a pulse programmer. 66 Chapter 4 Class E Amplifier We turn the focus of this thesis towards a low-cost, power amplifier with fast ringdown times, which meets the requirements discussed in the previous chapter. We present the Class E amplifier (CEA) as an alternative to typical NMR power amplifiers that can be used in quantum computing experiments. The CEA offers high Q, fast switching times, high efficiency, lower costs, and a small form factor. We start by describing the history of the CEA in Section 4.1. Next, the design equations are described in Section 4.3. We follow the design equations and implement a CEA tuned to 4.64MHz. We conclude by describing the device's characteristics in Section 4.4, such as the ringdown time and power efficiency. 4.1 History of the Class E amplifier Originally introduced and patented in 1975 by Nathan Sokal [Sok75], the Class E amplifier (CEA) was a novel design which addressed several issues in power amplifiers. There are several trade-offs in the design of power amplifiers, including: * size and weight, " efficiency, * cost, and 67 * bandwidth. The purpose of the CEA is to address the design issues in power amplifiers, specifically the power efficiency versus the operational bandwidth. The design of the CEA raises the power efficiency by sacrificing the bandwidth. But, the size, weight and cost are reduced as well. The design has practical applications in several industries. In the areas of telecommunications, the CEA is used prevalently. Amateur radios enthusiast immediately found use for RF communications. Rutledge and Lau demonstrated a high-power, low-cost transceiver for ham radios using CEAs [LCQ+97]. Transceivers for televisions were created by Broadcast Electronics, Inc., and other companies [Sok98]. More recently, there have been large investments in developing integrated circuits (ICs) with CEAs for cellular phones and other wireless applications [Tsa99]. To illuminate why companies invest in CEAs for telecommunication applications, different classes of power amplifiers are listed with their salient features. " Class A amplifiers - Amplifier type: linear - Efficiency: 30-40% - Tradeoffs: sacrifice efficiency for predictable, linear behavior. " Class B amplifiers - Amplifier type: linear - Efficiency: 45-55% - Tradeoffs: sacrifice efficiency for predictable, linear behavior. " Class C amplifiers - Amplifier type: linear - Efficiency: 55-65% - Tradeoffs: wide operation bandwidth; efficiency varies with frequency 68 9 Class D amplifiers - Amplifier type: switching - Efficiency: 75-85% - Tradeoffs: reasonable operational bandwidth with high efficiency in audio frequencies * Class E amplifiers - Amplifier type: switching - Efficiency: 85-95% - Tradeoffs: narrow operational bandwidth, but extremely high efficiency and small size. Compared to other amplifiers, CEAs are extremely efficient and small. For cellular phones, these qualities are ideal for longer battery life and compactness. Narrow bandwidth and optimal operation in the microwave regime make them suitable for communication protocols, such as code-division multiple access (CDMA) and timedivision multiple access (TDMA). Although not obvious, the features of CEAs can also be attractive for NMR quantum computing applications. Typically, Class C power amplifiers are used in NMR spectrometers. Class C amplifiers are linear amplifiers, offering a wide bandwidth of operation and higher efficiency than Class A,B, or AB amplifiers. Class C designs are suitable for modern NMR spectroscopy experiments that involve biology or chemistry because Class C amplifiers are capable of operating over a wide range of frequencies, allowing the spectrometer to tune to various frequencies. However, quantum computers do not require wide bandwidth. In quantum computing, the Hamiltonian of the system is known in advance, and thus, the frequencies to control qubits are known. Quantum computing requires optimizations not found in general-purpose spectrometers. Narrow bandwidths and high Qs are two particularly desirable features, making CEAs candidates. 69 4.1.1 Motivation: a solution to increasing SNR In Section 3.5, we discussed some potential problems with NMR hardware in relation to NMR quantum computers. As the number of qubits increases, the SNR poses a critical problem for NMR quantum computers. One possible way to increase the SNR is to maximize the FID signal by decreasing the ringdown time of the power amplifier. The CEA provides a possible solution to increasing the SNR because it has switching times with overall faster rise and fall times than Class C amplifiers. Furthermore, the high Q resonance provides a narrow operational bandwidth. For NMR quantum computation, narrow widths allows for accurate qubit control because the amplifier acts as a filter, removing broadband frequencies, which may introduce more errors in a quantum computation. In addition, the size of a CEA is small in comparison to other classes of amplifiers. This makes it attractive for the possible integration of a probe and amplifier on a single circuit board. Although CEAs are suitable for NMR quantum computers, we briefly describe two potential applications for CEAs in NMR spectroscopy. For small desktop NMR devices [Mag99], CEAs can have an immediate impact because they may be cheaply integrated into a desktop system. Moving towards smaller scales, we find that CEAs may be potentially applied to NMR micro-coil spectroscopy applications. ICs with coils on the scale of microns, between 50Qpm to 100pm in diameter, have been developed in research labs for spectroscopy on drugs and small biological elements [PML94]. However, currently there do not exist RF transmitters integrated with the micro-coils. Since a CEA lends itself well to digital logic, due to its switching behavior, IC designs of a CEA may potentially be integrated into an NMR micro-coil spectrometer, which are known as a spectrometer on a chip (SOC). 4.2 Operation and design The operation of the switching CEA is described. Figure 4-1 is a schematic, and Figure 4-2 is the ideal input and output to the amplifier. Intuitively, the CEA works 70 as follows: * When the transistor is switched off, the current flows into the load network causing a transient rise in voltage. The inductor helps pull the voltage VD above Vdd. In the ideal case, VD peaks at 3 times Vdd. The parallel capacitor C1 is charged until it looks like a short to ground, causing VD to peak and fall back to OV. " When the transistor is switched on, the voltage remains at OV and C1 is discharged through the transistor. The CEA only works for a narrow bandwidth. The input source VIN is applied at the resonance frequency of the CEA, which is determined by the resonance load network, as shown in Figure 4-3. The configuration and operation of the CEA maximizes power efficiency by minimizing the power dissipation through the RF power transistor. The power dissipation across the transistor is the product of the transistor voltage and transistor current at each point in time during the RF period. Ideally, during operation of the circuit, high voltage and high current do not exist at the same time. As long as the slope of the voltage is OV during the transition from off to on, and vice versa, the ideal efficiency is 100% [Sok75]. The efficiency assumes that ideal components are used. In practice, the power efficiency ranges from 80% to 95%. 71 VDD L1 VDi C2 L2 OUT L3 C1 IN 02 500 03 Figure 4-1: A schematic of a Class E amplifier is shown. The resonant load network circuit is used to tune the resonant frequency of the amplifier. VN VD[ ON AO/1> VOUTj time 1 period Figure 4-2: Example of ideal, transient waveforms for the input and output of the Class E amplifier. When the gate is switched on, the voltage at the drain VD decreases, while the voltage VOUT increases. When the gate is switched off, VD rises and VOUT decreases. 72 4.3 Design equations We now present the design equations for the CEA. These equations are from the most recent paper by Sokal [SokOO]. R P = 0 .57 6 80 1 ) F(Qoad) 2 ) ()2 S=V P= c/4 + 1 )FQo V) (V(VCC -Vc-)2 2 1.0012- 0.4517 0 0.4024) (4.1) l oad Qload where F(...) is a least-squares fitted function dependent on Qload and statifies the relation among P, R, Qload, V, and Vo given in Table 4.1. (VcC - Vo)) R = 0.576801 \P 1 ( r2/4+1) C 27rf R 2/22 2iR 2 rf1R) /) ) 0.4517 Qload 0.99836 + 0.91394 Qload Qloa 0.4024 ) (2 0.7 2rf2L1 1.0316 0.7 Qoad (27rf)2L 1 1.0147 1.0013+ Qload - 1.7879) Qioad - 0.1048 QloadR 2= 27rf (4.2) l~oad 1.0316 (Qoad 0.99836 + 0.91394 C, 34.2219f R C2 = (1.0012 (4.3) (4.4) (4.5) Here, * Qload is the desired Q of the circuit, " R is the load resistance, * C1 is the parallel capacitance of the circuit, which includes the output capacitance, 73 o C2 is the capacitance in series with L 1 , " L 2 is the inductance, which is determined by the designer's choice of " L 1 is the inductance connecting the drain voltage to the power supply, Qload, " Vo is the transistor saturation offset voltage, " L 3 and C 3 make up the tank circuit which transforms the R accordingly, and * P is the desired output power with a 50% duty cycle. 00 20 10 PR/(Vec - V0 ) 2 0.57801 0.56402 0.54974 C27rfR 0.18360 0.19111 0.19790 C 2 2-FfR 0 0.05313 0.11375 Qload 5 0.51659 0.20907 0.26924 3 0.46453 0.21834 0.63467 2.5 2 1.7879 0.43550 0.3888 0.35969 0.22036 0.21994 0.21770 1.01219 3.05212 oo Table 4.1: Dependence of P, R, V, and V on Qload [Sok98] Using the design equations, two CEAs were created, one at 34Mhz and the other at 4.64MHz. Each amplifier was designed by a different graduate student. Based on the design equations, Yael Maguire designed a CEA tuned at 34MHz, while I designed a CEA tuned at 4.64MHz. Table 4.2 shows the values for the CEA. In the 4.64MHz CEA, C3 and L 3 are used to transform the 50Q load to a 1OQ load. By transforming the 50Q load to 1OQ, reasonable values for C1 and C2 can be attained. We focus the design the 4.64MHz Class E amplifier. We observe that designing a CEA for low frequencies is a rather difficult endeavor. The design equations given by Sokal fail to match closely with ideal values, especially with the introduction of the tank circuit. Intuitively, we can see that the imaginary part of the tank circuit may yield an undesirable phase, thereby lowering the performance of the amplifier. The CEA has a bode plot such that the gain is attenuated at the frequency of interest. Therefore, instead of strictly adhering to the results of the design equations, we simulated the circuit using Protel. 74 parameter value C1 C2 330pF 10iF 03 L, 54pF nF 1.8pF 6.5pH L2 L3 Table 4.2: Parameters used for the design of a CEA. The resonance frequency is tuned to 4.64MHz. 4.4 Class E amplifier characteristics Figure 4-3 shows the design of the circuit. Once the design was verified, the circuit was built using proto-boards outsourced to and fabricated by a manufacturer. \k d= 22V V 1.8pH 10gF drain 1 AC f\ Signal 33pF 30F1-n 1 1500 in Figure 4-3: The Class E amplifier schematic shown for amplifier tuned at 4.64 MHz. The amplifier characteristics were measured after the circuit was stuffed by soldering discrete components onto the PCB. The power transistor chosen for this application was the IRFP45OLC from International Rectifier. First, the CEA behavior was measured by examining the voltages at the drain and the gate of the switching transistor with the Tektronix TDS3054. After the behavior was confirmed, the efficiency was measured. The efficiency was determined by measuring the total power supplied through the drain of the transistor and the total power dissipated in a 50 test, or dummy, load. The power was measured by determining the current supplied 75 to the transistor and the current through the test load. The drain voltage and gate voltage were measured and confirmed that the CEA was operating in the optimal range, as shown in Figure 4-4. The peak drain voltage was 2.7 times greater than Vdd, matching closely the ideal predictions. The spike behavior observed in every drain voltage cycle was associated with the sudden change in the MOSFET's current due to the transistor turning on 76 (gate > 6.5V). Voltage vs. Time 60 e V rain f\ 400 0.2 0.4 time[psec] Figure 4-4: Measurements of the voltages at the drain and the gate of the power transistor are shown. The drain voltage is about 3 times the gate voltage, fitting closely with theoretical predictions. Several parameters were measured with Vdd set at 22V with a continuous waveform at the input with th frequency of operation set to 4.64MHz. Table 4.3 shows the measurements and simulation values. Two high-power dummy loads were used to calculate the RMS current by measuring the RMS voltages across both loads. All measurements were obtained while the circuit was running in continuous mode. The measured value of efficiency is 98%. The percentage error is about 7.6%. The efficiency is extremely high, suggesting the measured value may not be correct because typical efficiencies are 90%. The ringdown time is 6 As, which is considerable less than the 20ps ringdown time of a linear power amplifier from AR Amplifiers. 77 value 3.44W 3.5W 98% 2.85 Q Ringdown time 6psec parameter Output power Total power Efficiency simulated values 3.35W 3.7W 90% 3 N/A % error 2.6% 5.4% 7.6% 5.2% N/A Table 4.3: Class E measurements: the measured and simulated values of the amplifier are shown in the table. The percent error is also displayed. 4.4.1 Measurement difficulties There are several issues involved in the measurement technique which may lead to an inaccurate measurement. Although a high-power resistor was used to measure the total power supplied to the circuit, the total output power was greater than the maximum rating of the resistor. As a result, the resistor burned out and had to be replaced several times. A future technique to accurately determine the total power dissipation by the CEA is to use several resistors in parallel to measure the power. By varying the resistance load, the current at 0 Q can be extrapolated. Figure 4-5: The Class E amplifier shown for the amplifier constructed and tested. The resonance frequency is 4.64MHz. 78 4.5 Summary The CEA has various characteristics and features that are applicable to the industries of telecommunications and, more recently, NMR spectroscopy. The design of the CEA trades operational bandwidth versus power efficiency, which fits the needs of NMR quantum computers. We found that at low frequencies, the design equations are not accurate. One of the main challenges was to conduct simulations using Protel, which matched realistic values for CEA designs tuned at 4.64MHz. Once a prototype was completed, the device's characteristics were measured and compared to simulated values. We provided the first steps in improving the ringdown of an NMR power amplifier, by demonstrating CEA amplifiers operating at 4.64MHz and 34MHz and ringdown times faster than typical power amplifiers used in modern NMR spectrometers. 79 80 Chapter 5 Pulse Programmer NMR quantum computers require complex pulses with phase and amplitude control to execute quantum algorithms. But what are the requirements needed for an NMR pulse programmer? We delve into this question by examining the current advantages and disadvantages of NMR pulse programmers, and by designing and developing two pulse programmers, both aimed for complex, programmable pulse sequences in an NMR quantum computer. First, we examine a widely used commercial pulse programmer, and then several previously built by other researchers in Section 5.1. We analyze the architecture behind such systems, developing a criteria for evaluating pulse programmers, as described in Section 5.2. Finally, we discuss the design of two pulse programmers in Sections 5.3 and 5.4. The first system is designed around ease of use, or transparency. For the second architecture, we concentrate on improving the timing resolution of the system by targeting it for 10 ns. 5.1 Problem and approach As discussed in Chapter 3, implementing quantum algorithms, such as Shor's algorithm, requires carefully designed shaped pulses. Pulse programmers are used in modern spectrometers to produce RF pulses and perform quantum operations; however, in current state of the art pulse programmers, high cost and large size render 81 them impractical for inexpensive NMR quantum computing. We evaluate existing hardware options for NMR pulse programmers and choose low-cost, commercial systems to implement high-speed, sub-pus pulse programmers. We concentrate on designing software architectures using digitally programmable logic devices. 5.1.1 Introduction to the pulse programmer Early in the history of NMR, typical experiments involved the use of continuous waves (CW) methods [PW51]. CW methods offered the ability to scan across wide spectral ranges and provided much early information about the dynamics of nuclear systems. Since CW methods required continuous RF fields applied on the sample, the signal at the receiver was often saturated and unstable over time. In the early 1950s, pulsed techniques addressed the problems with CW methods. The advantages of pulsed excitation included: " stable operation using linear circuitry, " avoidance of saturation effects in the receiver, " the ability to measure relaxation times, and * the ability to signal-average. These advantages made pulsed spectroscopy the preferred choice among researchers. Pulsed methodologies are made possible by an electronic circuit known as a pulse programmer. A pulse programmer is a digital signal generator capable of outputting binary data patterns in parallel. The output of a single bit is represented by standard digital input/output (I/O) signals, such as TTL, LVDS, and ECL. The outputs are used for multifarious control purposes. Often it digitally sets various RF circuits, which in turn control the phase, amplitude, frequency, or time duration of an RF signal. As the field of NMR progressed, so did the electronics of the pulse programmer. Early spectrometers consisted of home-built pulse programmers. 82 Many first- generation pulse programmers used analog timers and discrete logic gates for generating a limited number of pulses. This was a cumbersome approach to developing more complex pulse sequences. In an effort to improve pulse sequence generation, engineers developed versatile, computer-controlled pulse programmers for commercial and scientific applications. Although the pulse programmers worked extremely well, they were often expensive and occupied several racks in a spectrometer. To address these problems, we study a commercial pulse programmer from Varian, Inc. 5.1.2 A case study: the Varian pulse programmer In order to understand the design parameters, we study a proven pulse programmer used in NMR quantum computing, i.e., the Varian pulse programmer [VNM01]. The Varian spectrometer has been used in several NMR quantum computing experiments [VSB+01, SvDH+03b], as described in Section 3.4. In the spectrometer, the pulse programmer acts as the interface board between the control electronics and the computer. From the computer, the user controls a multitude of parameters. The user can change the phase, amplitude, and frequency of an RF signal. Varian architecture Usually, the pulses are generated in the following manner. First, the user creates the desired pulse sequence via software on the Sun Ultra 10 workstation. When the experiment is executed, the software compiles the sequence into byte-wise code, known as the pulse program. In Varian propriety software, the pulse program is known as Acode. Once the code is compiled, it is transmitted via the computer's I/O bus to the pulse programmer board's memory. Finally, a "go" command is executed, and the byte-wise code is executed. Figure 5-1 shows a functional diagram of the pulse programmer. The compiled pulse sequence is fed into a first-in-first-out (FIFO) buffer, a memory buffer, into which binary data is fed sequentially and which releases the same sequence through the output ports. The number of words in a FIFO buffer is called the depth. The depth of the FIFO is 4096 words. For the pulse programmer, the width of a word is 54 bits. 83 There are two FIFO buffers in the pulse programmer, the preloop FIFO and the loop FIFO. Normally, words "fall through" the preloop FIFO and fill the loop FIFO. Once the loop FIFO is full, the preloop FIFO is filled until it is full. At that point, the FIFO signals the computer, causing the words to temporarily stop filling the FIFO buffers. 84 CPU 1/0 bus bus decoder fast bits (states) times / AP bus words preloop FIFO width 04 loop control multiplexer cr D loop FIFO timers CEHD texres / AP bus words fast bits (states) times AP bus :meter / rf external trigger Figure 5-1: Structure of the Varian pulse programmer [VNM01] 85 Every word in the pulse programmer contains state-related operational codes, called "fast bits", and timing bits. Because the fast bits switch instantaneously with any FIFO word, they directly drive the RF gates controlling various RF circuits and blanking amplifiers through the output of the loop FIFO buffer. The timing bits define the time count, ranging from 1 to 4096, and the time base (seconds, milliseconds, microseconds). When the "go" command is issued, the words in the loop FIFO are released. The timing data are fed into the circuitry, activating the timer. The timer counts down to zero from the time count and causes the next FIFO word to release via an external trigger signal. With each time-step, the output of the loop FIFO is fed to the RF circuits and a multiplexer that determines whether the data into the loop FIFO is taken from the preloop FIFO or from the output. This scheme is known as hardware looping. We can characterize the Varian pulse programmer control board to the criteria listed in Table 5.1: characteristic timing resolution memory size number of channels minimum delay minimum pulse width maximum pulse width number of control lines system clock definition the minimum time-step difference, or time to process one command the length and width of the memory buffer the number of pulsed RF signals the minimum time between two pulses the minimum duration of a pulse the maximum duration of a pulse the number of bits controlling the RF circuits the frequency of the master oscillator Table 5.1: Characteristics for evaluating the Varian pulse programmer 86 Based on our criteria, we summarize the characteristics of the Varian pulse programmer in Table 5-2. value 25 ns 4096 words 54 bits 4 50 ns 25 ns 4096 s 34 bits 40 MHz (25 ns period) parameter timing resolution memory depth memory width number of channels minimum delay minimum pulse width maximum pulse width number of control lines system clock: Table 5.2: Characteristics for the Varian pulse programmer. Several groups have created low-cost programmers for various spectroscopy appli- cations, including NMR spectroscopy [FMSR99, WPBM93, WSF88, Mag99]. We summarize previously designed pulse programmers in Table 5.3, using the criteria that we have developed: parameter Fisher [FMSR99] Wachtar [WSF88] Wu [WPBM93] 1 /-s 1 kBytes 150 ns 128 kBytes 4 /-s 64 kBytes memory width 8 bits 16 bits 1 bit number of channels maximum pulse width number of control lines system clock 8 n/a 8 bits n/a 16 42.9 s 16 bits 100MHz 1 1028 s 1 bit 80MHz timing resolution memory depth Table 5.3: The performance of several lab-built pulse sequencers for various applications. 87 5.2 Designing an NMR quantum computer pulse programmer From Table 5.3, we find that programmers have a limited number of RF channels, control lines, and memory size. For NMR quantum computing, the current generation of pulse programmers are not optimized. An ideally designed pulse programmer should provide fine resolution times, under 1[ps, thus generally making the system clock greater than 1MHz. It should also have maximum pulse widths greater than the TI and T2 times of the samples (times on the order of hundreds of seconds are more than adequate). On the software side, the program to control the pulse programmer should be simple and easy to use. We introduce two designs, using two different hardware solutions; each one has their advantages and disadvantages. The first design aims at typical NMR applications with sub-ps pulse widths and ease of use, and whereas the second design aims is a general-purpose pulse programmer, targeted for high-speed applications with pulse widths at 10 ns. 5.3 First-generation pulse programmer As a first pass in the design phase, we design a pulse programmer that is comparable to the Varian pulse programmer. First, we examine the design of the architecture for the system. Then, we describe the hardware and software implementation of the pulse programmer. Since the hardware is a Rabbit 2200RCM module, we dub this pulse programmer the Rabbit pulse programmer. 5.3.1 Architecture of first-generation pulse programmer In the design of the Rabbit pulse programmer, we consider abstracting the functionality of the pulse programmer into the following layers of communication: 88 * user layer: the user interface to the pulse programmer, e.g., a personal computer connected to the pulse programmer. " interface layer: the communication protocol between the user layer and execution layer; and " execution layer: the implementation of the pulse sequencer (also known as the hardware layer). The design of the system is critical. When we design the pulse programmer, the following design issues are considered for each layer: * The user interface: A transparentuser interface is desirable. In computer software, an action is transparent if it takes place and is hidden to the user. Another relevant design parameter is the concept of platform independence. Platform independent design accommodates multiple operating systems (OS), so that future upgrades to personal computers will be compatible with the pulse programmer. Lastly and most importantly, the control of the pulse programmer must be appropriate for quantum computing and address quantum computing needs. " The interface layer: The concept of a transparentuser interface also applies to the interface layer. This layer dictates the communication between the user and the pulse programmer. A transparent protocol is desired so that the communication between the user and the pulse programmer is reliable. The protocol must guarantee that the data arrive in the proper order. " The execution layer: We seek a synchronized microprocessor that is low-cost and relatively easy to use. Our solution is shown in Figure 5-2. The user layer consists of software, allowing one to input a desired pulse sequence (see Section 5.3.3). There are three methods of input: (1) a file containing the pulse sequence can be uploaded, (2) the pulse sequence can be directly typed, and (3) the sequence can be sent via http post method. The 89 software is written in PHP - a wide purpose, general scripting language that can be embedded into html [LT02]. PHP code utilizes the http protocol to communicate with different clients. Hence, we achieve platform independence if the OS supports http communication. Given that Internet protocols are selected, we can take advantage of the TCP/IP for the interface layer. The protocol guarantees reliable communication between the client and the server. If the pulse programmer acts as a server, then pulse sequence codes can be sent over a TCP/IP link. Through http post/get methods, the server can extract the pulse sequence sent from the client, or user. The pulse sequence code is compiled into byte code (sequence of bytes), which is sent to the execution layer. Pulse Sequence (fike, ;php-cgi itraeCompiler text, Cgi inpuA) (Co"pits putst s0q in Opeodes ond nms it) Interpreter Figure 5-2: Block diagram of the first-generation pulse programmer. The execution layer represents the hardware, or pulse generator. The architecture is shown in Figure 5-3. The pulse generator stores the compiled data into a buffer. Next, the pulse sequence executes the commands stored in the buffer. An interpreter loops through the buffer, executing each command. These commands are listed in Section 5.3.3. 5.3.2 Hardware implementation of first-generation pulse programmer The hardware for the pulse programmer is a Rabbit RCM2200 module, an embedded microprocessor. A block diagram of the module is shown in Figure 5-4. The Rabbit 90 I I Data 512 kB program Figure 5-3: The hardware uses a buffer to store the pulse sequence and access the commands during execution. RCM2200 is an 8-bit microprocessor that supports the "C" programming language. 512 kBytes of SRAM memory are reserved for the program, and 256 kBytes are reserved for data. Other significant features of the processor include the following: " a system clock of 22.1MHz, * on-chip peripherals including serial ports, parallel I/O (shared among ports A,B,C, and D), two built-in timers (ports A and B), and " C library supporting UDP and TCP/IP protocol stack, FTP, http, SMTP, and DNS. Support for UDP and TCP/IP protocol ensures reliable communication between the user and pulse programmer. UDP offers minimal service over IP and guarantees end91 Figure 5-4: The Rabbit RCM2200 module used as the hardware for the firstgeneration pulse programmer. to-end communication. Meanwhile TCP guarantees proper order of data delivery and end-to-end reliability. The module is used in conjunction with a daughter board, which I designed. The daughter board has several functions. First, it routes all the I/O pins to two 40-pin headers, easing testing and debugging of the circuit. Second, it provides power to the RCM2200 module. Third, it is small and modular for easy mounting to other boards or RF boxes. Lastly, four channels output the pulse sequence. The daughter board is shown in Figure 5-5. The hardware provides the foundation for the software. Figure 5-5: The daugther board customized for the Rabbit RCM2200 module. 92 5.3.3 Software implementation of first-generation pulse programmer The software for the pulse programmer consists of two elements: the PHP code for the client interface and the C code. The source codes are given in Appendix B. We focus on operations for both the client and server applications. Client software The client software relays pulse sequence codes to the pulse programmer via an HTML web page. It provides three options to relay data to the pulse programmer, as discussed in Section 5.3.1. The user can input data using the following methods: (1) a file containing the pulse sequence can be uploaded, (2) the pulse sequence can be directly typed, and (3) the sequence can be sent via http post method. In all three methods, the pulse sequence code is being sent to the pulse programmer. The pulse sequence code instructs the pulse programmer how to change the state of the system. It is composed of individual operational codes. Each operational code changes the state of the output channels of port C. The format is as follows: an operational code is sent, followed by a one-byte parameter in ASCII format ranging from 0 to 255. We summarize the available commands in Table 5.4. operational code CO C1 C2 C3 C4 C5 description delay execution of next command by x ps (range 0-255) delay execution of next command by x ms (range 0-255) delay execution of next command by x s (Range 0-255) output one-byte of data on to port C output one-byte of data on to port B no operation Table 5.4: The list of operational codes available to the RCM2200 pulse sequencer. Currently port C is the only available output channel. An example We illustrate the client software by describing a pulse sequence. Let channel one be pin CO, and channel two be pin C2. Both channels start with low output. After one ms, channel one is set high. Then after 10 ps, channel two is set high. One second 93 later, both channels are set low. The pulse sequence code for this sequence is given as: C1 1 C3 1 CO 10 C3 5 C2 1 C3 0. Pulse sequencer In order to obtain the data sent by the client, the Rabbit RCM2200 runs a web server, which listens to incoming connections on a specified port. In this case, the port is set to 80, the standard http port. The web server instantiates events when incoming data are detected. The port is read and the data arrive in the following format: http://192.168.1.10/sendPulse.cgi?data=C&10&C1O, where the ip address denotes the server. The parameters are the code and the repeatnum. The code is the pulse sequence code, and the repeatnum instructs the pulse programmer how many times to repeat the pulse sequence. When the data is read by the server, it is in the format sendPulse.cgi?code= Cl1C31C010C35C21C30&repeatnum=O. The pulse sequencer parses the data and compiles the code into a byte sequence and stores the sequence into a buffer. The operational code is directly translated into the following byte codes: CO -* OxOA, C1 -- 0x10, C2 -- 0x11, C3 - 0x12, C4 -+ 0x13, and C5 -- 0x14. The operational code and parameters are stored in the order of arrival. Once the code is translated to byte code, the sequencer executes the program. If the repeatnum parameter is 0 or less, the pulse sequence is executed an infinite number of times; otherwise it is run for x number of times, where x is the parameter of repeatnum. Now, we examine the state machine in Figure 5-6, which describes the execution phase of the pulse programmer. From the state machine, we find there is an overhead time associated with the execution of each command (see Section 5.3.4 for more details). In the RCM2200, each command requires several clock cycles to determine which operational code to execute. Thus the limiting factor to the timing resolution is the amount of time to determine the command. With this knowledge, we can begin assessing the performance of the pulse programmer. 94 zzi-rx1d CO pcommand r ' ddla ay In Nyfr - ytnopr delay Inotu 0 - outpu byte to port C sooonds Figure 5-6: The state machine for the rabbit pulse programmer. 5.3.4 Performance evaluation of first-generation pulse programmer We characterize the performance of the pulse programmer by evaluating the (1) timing resolution, (2) SRAM width and depth, (3) number of channels, (4) system clock, (5) minimum delay, (6) minimum pulse width, and (7) maximum pulse width. The clock speed and SRAM size and depth are determined by the hardware. Measuring the timing resolution Each byte code is interpreted in real time by the pulse programmer. During execution, there is an overhead in time for processing the byte code. Figure 5-7 highlights the overhead between each command. The additional overhead is critical to accurate timing. The shorter the time it takes to execute a command, the higher timing resolutions we can achieve. We must minimize the overhead time to maximum the resolution. Measurements on the pulse programmer are made with a Tektronix TDS3054 oscilloscope. On average, the time to process one command, or the time resolution, 95 now I- T!= a on operation off1- 70 overhead I Time Figure 5-7: Anatomy of a pulse sequence. Each operation has an associated overhead cost for processing a command. The larger the overhead time, the higher the timing resolution. is 1.15 Ms. This limits minimum delay time between two "on" pulses to 2.30 ps. However, this does not mean the the pulse width is a multiple of 1.15 ps. From the state machine, a for loop is used to delay in the software code. The delay loop has a delay time of 235 ns. Because of the short delay times, we can finely tune the Rabbit pulse programmer to generate ps pulse widths. The characteristics of the Rabbit pulse programmer are summarized in Table 5.3.4: parameter timing resolution memory size number of channels minimum delay minimum pulse width maximum pulse width system clock: value 1.15 Ps 256 kBytes (but 128 kBytes of commands) 4 2.30 ps 1.15 ps 255 s 22.1 MHz Table 5.5: Characteristics for the Rabbit pulse programmer. Lessons learned The first-generation pulse programmer met most of our design goals. The pulse programmer has multiple interfaces that allows one to program complex pulse sequences. 96 There is enough memory to program large pulse sequences, easily accommodating NMR quantum computing experiments. The minimum pulse width is 1.15 ps, which did not meet our target range. Although, this is adequate for most NMR applications, it is not suitable for general-purpose applications, such as pulse programmers for electron spin resonance (ESR) or superconducting quantum computing. Another problem is the lack of control lines. For pulse shaping, the digital I/O from the pulse programmer controls analog circuits, particularly the phase, amplitude, and duration of the pulse. The hardware is limited in the number of control lines. Thus, another iteration of the design is necessary in order to improve the speed of the pulse programmer. 5.4 Second-generation pulse programmer In the next iteration of the design, the goals are higher speeds with a timing resolution of 10 ns and more control lines for analog circuits. We concentrate on the software architecture for this pulse programmer and limit our designs only to the digital I/O. First, we describe the architecture in Section 5.4.1. Then, discuss the hardware and software implementation. Finally, we evaluate the pulse programmer in Section 5.4.4. 5.4.1 Architecture of second-generation pulse programmer Figure 5-8 shows the structure of this version of the pulse programmer. The overall structure is similar to that of the Varian design, which is shown Section 5.1.2, except one FIFO is used in the system, which removes the multiplexer. The system works as follows. Data is sent to the programmer from the acquisition CPU via the CPU I/O bus. The data is decoded and stored into the FIFO in the order of arrival. Like the Varian system, when a "go" command is issued, the data is read from the FIFO and placed into the RF module. 97 CPU IO bus bus decoder depth aeng!h) FIFO Width -VP Figure 5-8: Structure of pulse programmer for the second-generation pulse programmer The data sent to the FIFO are commands that change the state information of the RF output. Like the previous design, shown in Section 5.3, the commands includes timing information, such as n- and pa-s delay. The RF module represents an interpreter which reads the commands and changes the state information of the system. Section 5.4.3 contains more information about the software implementation of the pulse sequencer. 5.4.2 Hardware implementation of second-generation pulse programmer The pulse programmer architecture described in Section 5.4.1 can be implemented by extending the hardware platform to field programmable gate arrays (FPGAs). An FPGA is a chip with combinatorial logic, lookup tables, wires, and flip flops in a 2-dimensional array. Each node, or logic cell, in the 2D grid has control circuitry that tells it how to connect to the rest of the grid. Depending on how it is programmed, the logic cell can perform digital logic operations such as AND, XOR, and OR. In large 2D grid arrays, the operations can be "strung" together to create complex, digital 98 circuits like multiplexers, adders, multipliers, and dividers. Using FPGAs allows precise allocation of digital resources, offers inherent parallelism, reduces implementation time, and lowers production costs. The pulse programmer is implemented on an FPGA system, using a Digilab 2E (D2E) evaluation board from Digilent, Inc., as shown in Figure 5-9. The D2E uses a Xilinx Spartan XC2S200E chip from the Spartan IE family. The XC2S200E has 200,000 system gates, 5,292 logic cells, 512K SRAM, 289 I/O pins, and 4 phase lock loops (PLLs). On board a D2E, there are RS232 drivers, dual 1.5A power regulators at 2.5V and 3.3V, a pulse button and LED for basic I/O, six 40-pin right-angle, DIP sockets, and a 50 MHz oscillator. Six expansion slots are used on the board. Expansion slots A and E share 37 pins, and expansion slots B and F share 11 pins. Expansion slots C and D each use 37 pins. Slots C and D are closest to the FPGA, providing the shortest possible route. Thus connectors C and D are used for high speed output, with data rates up to 100 MHz attainable. Overall 74 pins are available for I/O. The D2E board is designed to work with Xilinx ISE CAD tools. The software used is Xilinx Foundation ISE 4.0. The programming language used for the Xilinx FPGA is VHDL. 5.4.3 Software implementation of second-generation pulse programmer Since VHDL is a concurrent level language, i.e., it can be viewed as parallel programming, we can organize the flow of the code into separate entities, which makes the code modular, easy to understand, and portable to other VHDL applications. The entities include the following: (1) pulse programmer finite state machine (FSM), (2) serial communication block, (3) LED FSM, (4) clock divider, (5) serializer, and (6) the main FSM. The main entity instantiates all other components and concurrently runs each component through its own FSM. Figure 5-10 shows each entity and connections between entities. 99 Power jackfl 5-9VDC li 2.5VDC guato 50MHz CLK Push button tatuS LED I.3vDcI reguatr1 EPP or SP parallel port L Xinx Spaitan2E XC2S200E-PQ208 r4I Por PPo Port fJ TAG Expansion A control. swichExpansion E ExpansionB Expansi n F Figure 5-9: Functional block diagram of Digilab 2E development board [Dig02] A short description of each entity and its relationship to others is presented. The pulse programmer FSM executes the sequence of byte codes stored in the FIFO, as shown in Table 5.6. During the execution, the pulse programmer FSM requests new commands from the main FSM. Once a new command is received, the command is executed. The process of retrieving and executing a command is critical for high timing resolution. The serial communication block uses concurrent processes to transmit/receive data to/from the computer. Data received is sent, via the receive signal (rdx), to the main FSM for processing. The commands are sent via a DB9 serial cable to the device. Transmission occurs when one-byte of data is latched to the device and when transmission is enabled. Sixteen LEDs are controlled via the LED controller. Data is read/written from/to the LED through the main FSM. The main FSM requests read/write operations via read/write signals. The clock divider is an entity which divides the system clock to lower rates. The lower frequencies are used to clock certain entities, such as the LED controller. Only 100 VHDL Microprocessor Clock Divider -mclk- reset FIFO I mik d2io clk uart-clkl wr e rd-en empty reset uartck2 +- t_ data[7:0] - Iedu reemctk rdx-- UART C~nrO|er dsr tdx Man data[7:0] rcv uart~clk_1 uar~ci_2 txenable - FSM tx-latch Prstee "u s rstNProgrammer command[7:. -- reqcmd FSM b-x_ready reset d2Controller d2io-clk Serializer channeloutput I D210 Board Figure 5-10: Main framework for VHDL code one clock divider is instantiated. The serializer entity enables a higher throughput of the pulses. It takes parallel input data and clocks out the data serially. The main FSM unifies all the components and controls communication between components. It executes the command set described in Table 5.4.3. Although full duplex communication is possible, for simplification, the main FSM implements halfduplex communication between the pulse programmer and the computer. Pulse sequence code The pulse sequence code is a language that describes the pulse sequence. A user writes a sequence of codes which controls the output of the desired channel(s). The 101 code is compiled into byte code and sent from the computer to the pulse programmer. Byte code is store in a FIFO on the pulse programmer. Once a "GO" command is issued, the pulse programmer executes the byte code in the order originally sent. The following table explains the syntax and command for the pulse programmer code. The byte corresponding to the command is given as well. opcode CO C1 C2 C3 C4 C5 C6 hexcode Ox00 Ox01 0x02 0x03 0x04 0x05 0x06 description null operation set I/O pin y to ON state (3.3V) set I/O pin y to OFF state (3.3V) delay I/O pin y for x ns delay I/O pin y for x ps delay I/O pin y for x ms delay I/O pin y for x secs Table 5.6: Pulse sequence byte code and operational code for the pulse programmer. Note that the pulse sequence commands for the pulse sequencer are limited to hexadecimal codes under OxlO. This is subject to change in the future. To control the general functionality of the pulse programmer, a set of general control commands are sent. Thus far the control command set is small and performs simple tasks. Table 5.7 lists the hexcode and the associated command. Pulse programmer finite state machine hexcode OxOA 0x0B Ox0C OxOD xOE Ox11 description store sequential byte code (pulse sequence commands) into the FIFO indicate storage into FIFO is complete state pulse programmer request an acknowledgement from the pulse programmer read data in FIFO latch following byte to LEDs (debug tool) Table 5.7: Control code for the pulse programmer The pulse programmer FSM executes the pulse programmer sequence commands stored in the FIFO. The FSM machine is shown in Figure 5-11. Initially, the state starts in the the exit state. In this state, nothing occurs. When enable is set to "1", the FSM moves to the idle state, where upon a request, the command flag is set to 1. 102 This indicates a byte code is requested by the interpreter. If the FIFO is empty, the enable signal is set to 0, returning to the exit state. Otherwise the FIFO is read and a new command is issued. The FSM executes the command, moving into the desired states. After the command is executed, the state is set back to the idle state. This cycle may repeat. The main goal in this pulse programmer is to achieve 10 ns pulse widths, aiming the overhead from executing a command critical to the design. The pulse programmer is limited by the Xilinx FPGA architecture. For example, the time taken to request a command, read from the FIFO, and detect a new command must be minimized. Currently it takes 10 clock cycles to read from the FIFO, because the clock to drive the FIFO is synchronized by the system clock. Thus overhead is approximately 200 ns on a 50 MHz clock. Scaling up to 150 MHz lowers the overhead to 66ns. We examine three methods to increase the timing resolution. The first method is to use pre-programmed pulses. For extremely fast pulses, i.e., less than the 200ns barrier, special codes may be used. An example is having a command which sets the output channel high and, after a set period of time, sets it low automatically. Another way to speed up the overhead time and reduce the number of cycles is to read from the FIFO as the pulse programmer FSM is executing. Then, in the worst case scenario, the maximum number of clock cycles is 10. For most commands, there will be 4-5 clock cycles of overhead. This reduces the overhead by a factor of 2. Reaching 100 ns (at 50 MHz) overhead is more than a possibility. The last possibility is to process is to use parallel-to-serial converters to output the pulse sequence at clock speed. The drawback is the difficulty in implementation. The parallel-to-serial converter must be loaded at the appropriate times to keep the buffer full. We choose to improve the initial timing resolution by using parallel-to-serial converters. 103 --- reset stReset stExit enable = 1 enable=O stidle n~comma new command = 1 = stDelayMics = eghcommand new-command = 1 =stSetLwcmmn command new-command = I =c1ommand = stDelayNs command = stNull stSetHigh stSetLow stNull stDelayNs stDelayMics Figure 5-11: The finite state machine for the pulse programmer entity. The initial state is the exit state. In this state, the pulse programmer loops infinitely. When an enable signal is set, the state machine executes command code fetched from the FIFO. 104 Serial (UART) communication Communication to the pulse programmer occurs through a DB9 serial connection. The serial communication protocol follows standard universal asynchronous receive/transmit (UART) specifications. The UART implemented does not perform handshaking (CTS/RTS) or parity checking. Currently, the serial communication is set to transmit/receive for a baud rate of 9600 kBps, 8 bits, N (no) parity checking, and 1 stop bit. The protocol works as follows: For transmission: the transmission line (TXD) is held in a high state (1). When the line goes low (0), it indicates a start bit. Eight bits of data are sent at the specified data transfer rate. On the 10th bit, TXD is set to 1. For receiving: the data are sampled on the receive line (RXD) at 16 times the baud rate. When 0 is sampled, a start bit is indicated. Each bit is sampled after 16 clock cycles. On the 10th bit, a stop bit is detected. If a stop is not detected, the receiver still assumes the data are completely sent. Figure 5-12 displays the UART data format. The indication of a transmission is a low start bit. start bit step bit Figure 5-12: UART data format. LED controller The LED FSM reads/writes data to 16 LEDs on the Diligent Inc. D210 board. The LEDs serve as a debugging tool. Sixteen bits of data can be sent out and viewed. This process helps speed development time. The FSM is shown in Figure 5-13. The component always outputs a slow clock to the D210 board. The state machine starts in an idle state, which continuously updates the D210 board. When a read signal is detected, data are latched from the input pins and stored in a read buffer. 105 When a write event occurs, the data in the write buffer are latched to the same input pins. Note that it takes two clock cycles to read/write data. The state machine latches the first low byte followed by the next high byte. The status flag indicates that the bus for the D210 board is ready to be read/written (when it is set to 1). Clock divider The clock divider is an entity which simply takes the master clock input and divides the frequency down. The output frequencies include the clocks for the D210 board and the UART entity. It uses a counter to divide the system clock into the appropriate frequencies. Serializer The serializer takes parallel data and clocks the output serially to the output pin. The data are latched parallel via a latch flag. The serializer can be reset/set, causing the parallel data to become 0/1. The serializer is implemented to decrease the timing resolution of the pulse programmer. The main state machine The main FSM controls the messaging between entities. For instance, data can be read/written to the FIFO, LEDs, and serial port. The state machine also controls the flow of data to and from the computer. The FSM is shown in Figure 5-14. Only the general states are shown in the diagram. There are numerous intermediate states, but they are left out of the discussion (see Appendix B for more details). The default state is the idle state. In this state, the FSM waits for commands from the UART entity and responds accordingly. Based on the command received, the next state will be set. The possible states which can be run are the following: " Acknowledgement (stAck), " Latch data into FIFO (stLatch), " Latch data to LED (stWriteLed), " Read FIFO (stRead), and * Start pulse programmer (stStartPP). 106 A brief description of each state and its functionality is given in the order presented above. When an acknowledgement command is received, a one-byte code is sent back to the computer, acknowledging the pulse programmer is alive. The one-byte code is 0x30. If the data command xOA is detected, then subsequent data received in the UART is stored in the FIFO. There is one stipulation. The data sent to the FIFO must be command codes (found in Table 5.6). An escape code (OxODB) is sent to change to the idle state. 107 --- reset stReset stidle read~latch = 1 ;tatus = 1 write_latch = 1 stReadLo stWriteLo status = 1 status=1 status stReadLob stWriteLob status = 1 status=1 stReadHigh~b stWriteHigh~b Figure 5-13: The finite state machine for the LED controller. The LED utilized is on the Diligent Inc. D210 board. 108 Data can be latched to the LED. If the command is issued, then the next byte is displayed on the LED. Once the byte is shown, the state changes to the idle state. A read command (OxOE) causes data to be read from the FIFO and transmitted to the computer via the UART. The state moves to the idle state after execution of the transmission. The last command is the "GO" command (OxOC), which starts the pulse sequence. Upon execution of this command, the pulse programmer FSM is enabled. Data are read from the FIFO and sent to the pulse programmer FSM, whenever a request command is sent from the pulse programmer FSM entity. When the FIFO is empty, the pulse programmer FSM is disabled, and the state changes to the idle state. reset stReset stidle read-latch = I rcv-data = recv__data = MxA rcv_data = OxE FF Ox0C mt 1 revdtxBrcv_data =Ox stAck stLatch stWriteLed stRead stStartPP Figure 5-14: The main finite state machine shows the overall behavior of the pulse programmer. 109 5.4.4 Performance evaluation of second-generation pulse programmer We measured the characteristics of the pulse programmer and examined the following: (1) timing resolution, (2) memory size, (3) minimum delay, (4) minimum pulse width, (5) maximum pulse width, (6) number of control lines, and (7) the clock speed. We measured the timing resolution, minimum delay, and minimum and maximum pulse width with an Agilent Infiniium 54833D oscilloscope. These characteristics varied according to the clock speed. We used a HP 8664A signal generator, and produced frequencies varying from 100 to 200MHz. At 100MHz, the timing resolution was 10 ns, and at 150MHz and 200MHz, the timing resolution was 8 ns. The minimum delay between pulses was 10 ns (at 100MHz), and 8 ns (at 150MHz and 200MHz). At 100MHz, the minimum pulse width was 10 ns, as shown in Figure 5-15, and the maximum pulse width was 256 s. 2 0 >0 I o I I 100 I Time [ns] I 200 Figure 5-15: At 100MHz, the minimum pulse width was 10 ns, which matched with the predicted value. We found that as the frequency increased to 200MHz, the timing resolution remained constant at 8 ns. This was unexpected, as we believed the timing resolution would scale inversely with the clock speed. We also observed as the clock speed in110 creased, the rise time decreased and leveled off. At 100MHz, the pulse rise time was 0.5 ns, and from 150MHz to 200MHz the rise time was 2 ns. We attributed this behavior to the capacitance of the system gates. As the clock speeds increased, the capacitor at the gates could not discharge fast enough. Even though the manufacturer specified 300 MHz at the maximum clock speed, we found that we reached the limits of the FPGA's clock speed at 200MHz. We summarize characteristics of the pulse programmer, with a 100MHz system clock, in Table 5.8. parameter timing resolution memory depth number of control lines minimum delay minimum pulse width maximum pulse width system clock 10 ns 512 kBytes 72 10 ns 10 ns 256 s 100MHz 8 ns 512 kBytes 72 8 ns 8 ns 256 ns 150MHz-200MHz Table 5.8: Characteristics for the second-generation pulse programmer. This table shows the parameters for clock speeds of 100MHz and 150MHz. Lessons learned To achieve 8 to 10 ns pulse widths, the control of timing among the entities was critical. In particular, the clock cycles for reading and writing from the memory was taken into account by using parallel-to-serial converters. We also found that the timing resolution was linearly dependent on the clock speed up to 150MHz. After 150MHz, the timing resolution saturated. The limitations on the timing resolution are unclear, but it is most likely related to the FPGA architecture, suggesting that future goal of reaching sub-ns pulse widths are not achievable using conventional FPGA architectures. This opens the possibility of investigating customized ICs for high-speed pulse programmers. 111 5.5 Summary We explore software architectures to gain insight into developing general-purpose, lowcost pulse programmers. Two architectures are studied, and both are implemented using low-cost programmable devices. The first architecture is designed to tackle the issues of transparency, and portability. Focusing on these issues, we develop a lowcost, portable system using commercial hardware - a Rabbit RCM2200. The second architecture is designed to increase the timing resolution. The goal for the second iteration of the pulse programmer is met with 8 ns pulse widths. This is achieved using parallel-to-serial converters in an VHDL implementation on a FPGA chipset. We found that the as clock speed increases, the pulse width decreases but only up to a maximum threshold. The two design architectures have their strengths and weaknesses. The strengths of the first system are its transparency and platform independence. But it lacks the timing resolution for high-speed applications. The second design focuses on better timing resolution for high-speed design. Our conclusion is that the strengths of the two systems can be incorporated into a single design. We believe a future direction is to merge these two design philosophies, using TCP/IP for communication and FPGA devices for pulse sequencing. 112 Chapter 6 NQR Testbed In order to verify the functionalities of the Class E amplifier (CEA) and pulse programmer (PP), as described in Chapters 4 and 5, we designed a nuclear quadrupole resonance (NQR) spectrometer, which incorporates both devices. An NQR spectrometer is a suitable testbed for the devices because the spectrometer design of nuclear magnetic resonance (NMR) is similar to that of nuclear quadrupole resonance (NQR), as described in Section 6.1. Designing an NQR spectrometer is a challenging task, involving the design of several components: the probe, pin diode switch, receiver, and transmitter. In Sections 6.2, 6.3, and 6.4, we describe RF design methodologies for each component and the challenges associated with their implementation. In addition to designing and developing the NQR spectrometer, the NQR signals from two materials are detected as a verification of the spectrometer's operation. The two chemicals are: (1) paradichlorobenzene (C6 H4 C12 ) and (2) sodium nitrite (NaNO 2 ). Section 6.5 describes the experimental data obtained from NQR spectroscopy on sodium nitrite. The details about the physics of NQR are found in Appendix A. 113 6.1 NQR spectrometer NQR was discovered [Deh50] and studied [Pou50] shortly after the discovery of NMR in bulk media [BHP46, PTP46]. NQR has been used to study phase transitions of materials [PB76] and their ferroelectric properties [SNFY58], and whereas, NMR has gained a wide acceptance as an analytic tool in science, NQR has not gained the acceptance or popularity. NQR has many advantages over NMR. It has greater sensitivity to the environment because the resonance frequency is dependent on the electric field gradient surrounding the nucleus. One of the most important advantages of NQR over NMR is the absence of a large static magnetic field. This means a large superconducting magnet is unnecessary for an NQR spectrometer. As a result, an NQR spectrometer is cheaper to produce. The general components of the NQR spectrometer we designed are shown in Figure 6-1. The components are very similar to an NMR spectrometer, except the magnet and probe are replaced by a small, well-shielded copper encasing, which houses the sample material. The spectrometer requires three main components: the transmitter, probe, and receiver. The operation is as follows: * A computer downloads a pulse sequence into the pulse programmer and generates a sequence of TTL level pulses. " A RF signal at the nuclear resonance frequency is amplitude-modulated (mixed) with the pulse signal, from the pulse programmer, forming RF pulses at the resonance frequency. " The RF pulses are directed into the power amplifier, which is connected in series with a pin diode switch. " The pin diode switch actively filters, or shunts, noise from the power amplifier when the amplifier is not driven. When a high-voltage signal is applied to the input of the pin diode switch, the output follows the input. 114 Transmitter Pulse Programmer Frequency Generator A/D Receiver Power Splitter Power Amp RF Mixer PreAmp Power Amplifier L_______J Figure 6-1: A block diagram of an NQR spectrometer, illustrating the three main components: the transmitter, probe, and receiver. The sample material is placed in the coil. " In series with the pin diode switch is the impedance matching probe. The probe has two functions. The circuit isolates the receiver from the transmitter and matches the impedance to 50Q, maximizing power transfer to the coil. When the sample material is excited by the RF pulse, an FID signal is induced. The coil picks up the signal, which in turn is detected by the receiver. " The FID signal is amplified by the receiver. Then it is detected, filtered, and transmitted to the computer for analysis. 6.2 Impedance matching probe The probe is a critical component of an NQR spectrometer because it houses the sample and maximizes the transfer of RF energy into and out of the nuclei. In this 115 section, we examine the RF methodology used to design a probe and the mechanical aspects involved in the implementation of our design. Section 6.2.1 describes how to maximize the power transfer and Here, Q is Q of the probe. defined as: Q (6.1) fo Af' where fo is the center frequency and Af is the bandwidth. To maximize power transfer, the probe's impedance is matched to 50Q using an LC resonator with variable capacitors. In Section 6.2.2, we describe how to design a coil to hold the sample as well as the mechanical requirements of the probe. The probe and matching network must be durably constructed. Components should be welded or epoxied with nonmagnetic materials to prevent acoustic ringing, which is a potential source of noise. All components should also be well-shielded to prevent the system from coupling with stray RF signals in the environment. 6.2.1 LC resonator as a probe One design issue to consider is that the probe needs to couple energy into and out of the quantum system at the resonance frequency. Therefore, it is important to consider high Q circuits, which transfers the greatest amount of energy at the resonance frequency. Figure 6-2 shows a canonical LC resonator placed in series with a capacitor and series back-to-back diodes. This passive circuit performs two functions: " it separates the power amplifier from the pre-amplifier, and " it maximizes the power transfer by matching the impedance to 50Q. Back-to-back diodes Back-to-back diodes are used to decouple the transmitter and receiver. The diodes are assumed to have a dropout voltage of 0.6V. If the voltage across the back-toback diodes is greater than 0.6V, current is conducted through the diodes. On the 116 other hand, current is not conducted when the voltage is less than 0.6V. In the NQR spectrometer, the pin diode switch bridges the back-to-back diodes to C1. from pin diode switch C1 to receiver 2 Li probe Figure 6-2: LC matching network to the probe. When the capacitors are tuned properly, impedance is matched to a 50Q coaxial line and power transfer is maximized. The operation of the circuit may be understood by considering two models: the large-signal model and the small-signal model. In the case of the large-signal model, both sets of back-to-back diodes are conducting because a high-power RF pulse is being transmitted across the diodes. Assuming the power transfer is maximized, most of the power will be transferred to the coil. The reflected power from the coil is shunted to ground by the second set of back-to-back diodes, thereby protecting the receiver. In the small-signal model, there is no longer an RF pulse, and thus, the back-to-back diodes are open circuits because the voltage is less than O.6V. The transmitter is essentially separated from the receiver. Impedance matching Impedance matching is achieved using high series with L-C 2 Q air capacitors, where C1 is placed in resonant circuit. Variable capacitors are used such that the circuit can be tuned to match 50Q at a resonant frequency. C1 is known as the tuning capacitor, and C2 is known as the matching capacitor. Although the value of the capacitors are experimentally found, an analytic solution is used to help determine the range of valid capacitance values. To solve for the ideal values of the capacitors, the circuit is simplified as shown in Figure 6-3. A 3Q wire resistance is assumed. 117 C1 tuning capacitor 2 Li probe matching capacitor Rwire Figure 6-3: Schematic of the matching network circuit used for analytic solution. Rwire is the resistance of the wire. In the analysis Rwire = 3Q. The Thevien resistance looking into the circuit is: Z = ( jj 1 ++.C1 + (Rwire + iu L1 ) iWC2 lRWwireW - iC2L 1w 2 - iC1 L 1w 2(6.2) C2W (-1 - IC1RwireW + CiLiW2 ) i - C 2 &i In order to match impedance, the following conditions must be met: o Re(Z(w)) = 50Q, and * Im(Z(w)) = 0. Assuming C2, L, and w are fixed and using Im(Z) = 0, C1 is solved for, giving: C C2R2 (Lw(1 - W 2 + (1 2 - C2LIW2)2 C Liw ) - C Rir-W) 2 2 Table 6.1 shows the final values used for the probe based on Equation 6.3. The Q is measured using an HP 3560A network analyzer. The tuning and matching capacitors are shown in Figure 6-4. The input is a 50Q BNC coaxial cable. A die-cast box encases the capacitors and shields the system from RF noise. The air capacitors are the Polyflon NRP series. 118 parameter C1 C2 value 26pF 95pF 9.6tH 100 L, Q Table 6.1: The calculated values used for NQR spectrometer matching network. The resonance frequency of the circuit is 4.64MHz. Figure 6-4: The tuning and matching capacitors of the matching network. The capacitors are enclosed in a metal RF box to shield the system from extraneous noise. 6.2.2 Probe design The tuning and matching capacitors are connected to the inductor, which acts as the "pickup" coil. We consider two parameters in the design of the coil: SNR and Q. The goal is to maximize both parameters. A large inductance as well as small resistive losses are required to maximize the Q of the circuit. As shown in Figure 6-5, the length, 1, of the coil is increased to achieve a large inductance; however, doing so also increases the resistance. In most cases, it has been found empirically that building a coil with the same length and diameter maximizes the SNR [Pet75]. The method of constructing such a coil is quite simple, but effective. First, a test 119 Figure 6-5: A single coil used in the probe of the NQR spectrometer, where 1 is the length of the coil. tube is wrapped with adhesive tape, sticky side out. Next, we lay a copper wire with a thinner wire side-by-side. Both wires are wrapped around the test tube and over the tape. The thinner wire acts as a spacer for the thicker wire. The thinner wire is unwrapped from the test tube; the thicker wire remains adequately affixed to the tape. Finally, non-conductive epoxy is used to firmly bond the coil to the tube. In order to design the coil, it is analytically modeled. The coil design is based on several equations. The inductance, L, can be calculated as follows: L = , 1 7 (6.4) where 1 is the length, A is the coil area, N is the number of turns, and /-o is the permittivity of free space. The field strength of the coil can also be calculated, given in CGS units: H, = 6 104 2NAw (6.5) where H1 is the field strength, e, is the peak voltage applied across the coil, and w is the resonance frequency. Furthermore, the power at the coil can be calculated from H= 1OPQ) 2 VV V where V is the coil volume, v is the frequency, and P is the power. 120 (6.6) Several coils were made using Equation 6.4. Figure 6-6 shows an example coil of such a coil. The coil has a diameter of 0.7 inches, a length of 0.7 inches, and an inductance of 9.7pH with 32 turns. Figure 6-7 is a picture of the actual probe. The top plate is a screw mountable cover, which allows one to easily replace the sample coil. Appendix D includes the mechanical specifications of the probe. Figure 6-6: An example of a coil made using the described technique. The inductance of the coil is 9.7pLH and the number of turns, N, is 32. 121 -I ~ILLW Figure 6-7: The probe encapsulating the test tube and the coil. The sample material is placed in the test tube holder for NQR spectroscopy. 122 6.3 Pin diode switch The pin diode switch (PDS) controls the conduction of the RF signal from the power amplifier to the probe, serving to filter noise from the power amplifier. It is used to switch on and off the transmission from the power amplifier to the probe. When we attempt to detect the NQR signal from the probe, the noise from the power amplifier needs to be filtered; otherwise, the signal cannot be observed. So the PDS is used to "cutoff" the power amplifier from the probe. The operation of the circuit can be thought of as follows: when the PDS is turned off, the voltage across both diodes allows conduction to flow from the input (IN) to the output (OUT). However, when the PDS is turned on, conduction across the diodes (D 1 and D 2 ) ceases, and the path of the input current is shunted to ground through L 1 . The circuit is actively driven by a driver circuit, in which the input is between R1 and R 2 , as shown in Figure 6-8. A gated pulse ranging from +12V to -12V is used to turn the PDS on and off. The driver circuit is an inverting operational amplifier with rail-to-rail output. The signal is switched quickly, on the order of a few ps. C1 D1 D2 C2 C3 IN OUT Li L2 L3 L4 R2 R1 output from pin diode driver Figure 6-8: The schematic of the pin diode switch. Lessons learned Originally, the FID data shown in Section 6.5 could not be detected using the NQR 123 spectrometer. The source of the problem was narrowed down to the PDS. During the design of the PDS, we did not consider the resonance frequency of the notch filter, which turns out to be a critical design issue. Notice that L 4 and C 3 are connected to the coil and probe. When the circuit is shut off, the diode blocks the small signal and essentially separates the transmitter from the probe. However, L 4 and C 3 ,as seen in Figure 6-9, are not separated from the tuning capacitors. These elements form a notch filter. The frequency of the notch filter is (6.7) 1notch- v/L 3 C 4 C3 50I Vin Vout L4I Figure 6-9: Design consideration: a notch filter forms when the PDS is shut off. The resonance frequency of the notch filter must be considered in the design of the system. Utmost precaution is taken in selection of Wnothc. Otherwise, the gain may be reduced significantly near, or at, the resonance frequency, making the FID signal extremely difficult to detect. Thus, Wnotch is designed to be less than the resonance frequency. An example is given for the resonance frequency of 4.64MHz. As seen in Figure 6-10, if L3 = 1.8 [pH and C 4 = 10OOpF, then the resonance frequency is at 3.713MHz, 124 and the 3dB point is 4.7368MHz. Since the free precession frequency is 4.64MHz, the gain is close to !. The FID signal cannot be observed due to attenuation. In order to capture the FID signal, Wnotch is pushed down to 1.0887MHz and w3dB to 0.6532MHz by changing L3 = 7.9/uH and C4 = 10nF. The gain is unity at 4.64MHz, hence, the FID signal can be captured. "*-[ I Amplitude vs. Frequency C1041 . O0 I c=1 ooop 1 a~25 F 01"', 02 0 N 4.7368MHz an6 3.766MHz _0 ~.s freq4mncy (Hz) .5 4 4A5 5 ,x107 Figure 6-10: The Bode plot of a poorly designed pin diode switch. The resonance frequency is at 4.73MHz which is very close to the resonance frequency of the matching network. Thus, small signals are attenuated by 2. A picture of the actual PDS with the driver is shown in Figure 6-11. 125 Figure 6-11: The transmission board containing: (1) RF mixers for producing gated pulses, (2) a pin diode driver circuit, and (3) a pin diode switch. 126 6.4 Receiver The last major component of the NQR spectrometer is the receiver. We receive two types of receiver. Section 6.4.1 describes homodyne receiving, and section 6.4.2 describes heterodyne receiving. 6.4.1 Homodyne receiver The FID signal from the nucleus is very small (on the order of -150 dBm). To detect the signal, a series of low-noise amplifiers is used. The overall gain is measured to be 140dBm. Figure 6-12 shows the receiver chain of the spectrometer. The components of the receiver chain correspond to the actual devices. Oscope [varfawe Gain Amp(SRS) Synthesizer signal I Detector SPower PreAmp IN Figure 6-12: An example of a receiver chain is shown. A block diagram shown in this figure corresponds to the real devices as seen on the right-hand side. An oscilloscope captures the waveform and digitizes the signal. The data are transferred to the computer using the GPIB interface, and they are analyzed using 127 Matlab 6.0. The current setup that we have described is known as a homodyne setup. 6.4.2 Heterodyne receiver The process of measuring both the ;- and y- components of the magnetization vector can be accomplished by phase-shifting the receiver reference frequency. Figure 6-13 is a block diagram illustrating the detection scheme. mixer low pass filter from recv amr mixer L9 (t) OW Pass filter local oscillator Figure 6-13: A general schematic of a heterodyne receiver. Suppose the incoming signal is described as S(t) = A cos (wot), (6.8) and the local oscillator signal is described as VLo(t) = B cos (wf t), (6.9) where A and B are the amplitudes and wo and wf are incoming frequency and local oscillator frequency. A 90' phase shift is applied on VLo(t), producing VLO90*(t). VLo(t) and S(t) are fed into one mixer, and VLo 900 (t) and S(t) are fed into a different 128 mixer. Since a mixer multiply the two signals, the outputs for two mixers are the following: S(t)VLo(t) S(t)VLo 90 = AB cos (wot) cos (wft) = -AB (cos ((wo + wf)t) + cos ((wo - wf)t)) 1 2 (6.10) AB cos (wot) sin (Wf t) (t) 1 - -AB (sin ((wo + wrf)t) - sin ((wo - wrf)t)) 2 (6.11) The phase difference of the local oscillator introduces an offset in the mixer such that the second mixer corresponds to the y-component in the rotating frame. Filters are used to remove the high frequency wo + wrf, leaving the frequency wO - Wrf, given that wf is close to wo. 6.5 Experiment In order to verify the correctness of both the pulse programmer and the Class E amplifier, pure NQR spectroscopy is performed on two different materials: paradichlorobenzene and sodium nitrite. The spectrometer must be configured to detect each material. Configuring the system requires changing the pre-amplifier in the receiver stage, as well as changing the PDS, the matching and tuning capacitors, and the probe's coil according to the material's NQR resonance frequency. Once the spectrometer is set up, we can search for the FID at the frequency of interest. Paradichlorobenzene A sample of paradichlorobenzene (C 6 H4 C1 2 ) is chosen to test the functionality of the spectrometer. Paradichlorobenzene is widely used as a repellent in low-pressure aerosols for insect control, and is the principal ingredient in commercial moth balls, which are 99.9% pure. In fact, our test samples are prepared using commercial moth balls. A test tube is first filled with crystalline pellets, and then the pellets are melted using a handheld torch, resulting in a polycrystalline sample. The resonance frequency of "C1 in paradichlorobenzene was found to be 34.56MHz. 129 The FID signal is shown in Figure 6-14. 0 -5i -7 . .. - 0.6 0. 1 12 14 16 1.6 time [ms] Figure 6-14: The FID signal produced from "Cl in paradichlorobenzene. Sodium nitrite After the NQR spectrometer's operation was validated using paradichlorobenzene, we turn our focus to examining sodium nitrite (NaNO 2 ). This material is studied because of its various properties. In 1958, Sawada [SNFY58] discovered NaNO 2 's ferroelectric property using various spectroscopy techniques, including NQR. Since this discovery, many temperature experiments have been conducted using pure NQR to understand the nature of this material's phase transitions [OMB67, KOB70]. NaNO 2 contains ' 4 N, which turns out to be a common atom found in various explosives. A query of 10,000 materials containing 14 N shows that the NQR resonance frequencies are virtually unique [BGJM94]. As a result, researchers have developed explosive detectors and remote sensing landmine detectors that identify materials based on their NQR frequencies [GBM+01, GBYM93]. Since NaNO 2 contains 14 N, it is a wonderful control material for calibrating NQR explosive detection devices. In our experiment, we have reproduced pure NQR experiments on NaNO 2 at room temperature. The NQR spectrometer was reconfigured to examine 130 14 N in NaNO 2. The ob- served resonance frequency of 14 N is 4.64MHz. This corresponds to an asymmetry parameter of 0.37 and a quadrupole coupling constant of 5.5MHz (see Appendix A for definitions). These parameters fit well with theory and are confirmed by Petersen's experiments [Pet75]. The FID signal of NaNO 2 is shown in Figure 6-15. Figure 6-15: The FID signal of NaNO 2 captured on an oscilloscope. A nutation experiment is performed in order to locate a 900 pulse width. The pulse width is varied from 10ps to 500ps with steps of 10ps. The data points are plotted in Figure 6-16. The signal amplitude is plotted in arbitrary units. According to the discussion in Section A.5, the resultant waveform follows a Bessel function (J1 ). A curve fitted to the Bessel function exhibits a close fit with the chi squared equal to 14.7 and 96% confidence bounds. Although the results are promising, showing the data fit the theory, these may not be correct. A sine fit also exhibits similar confidence bounds with a reduced chi square of 14.1. Unfortunately, because of the lower reduced chi squared value associated with the sine function; this means the sine curve is a better fit than the Bessel curve. The correspondence is associated with RF inhomogeneity. As the time of the pulse width increases, RF inhomogeneity causes undesirable transitions to occur, and thus the data points above 400Ls begin to deviate from the ideal Bessel function, as seen in Figure 6-15. 131 Calibration of 90 deg pulse width data 10000 - 8000- 6000- 4000 E 20000- -2000 -400050 100 150 200 250 300 350 400 450 500 pulse width (s) Figure 6-16: The data points from a nutation experiment on NaNO 2 6.6 Summary An NQR spectrometer was designed and constructed to test the pulse programmer and the Class E amplifier by incorporating the two devices into the NQR spectrometer. There were three major components of the NQR spectrometer: (1) the transmitter, (2) the probe, and (3) the receiver. Both the pulse programmer and Class E amplifier were part of the transmitter. The functionality of both devices were verified by performing simple spectroscopy on two materials: paradichlorobenzene and sodium nitrite. The FID signals for both materials were detected; the resonance frequency for paradichlorobenzene was 34.56MHz, and for sodium nitrite, the resonance frequency was 4.64MHz. The pulse programmer and the Class E amplifier were proven to work in the NQR spectrometer, meeting our goals. However, we found that NQR signal detection is a challenging endeavor. In particular, the pin diode switch must be carefully designed 132 such that Wnotch is less than the material's resonance frequency. In addition, NQR in materials is extremely sensitive to the surrounding environment. Thus, the sample must be well-shielded from stray RF signals; otherwise the resonance frequency will shift constantly. There are many future uses for the NQR spectrometer. Since the NQR spectrometer can detect sodium nitrite, a control material used for explosives detection, we can extend the future use of the spectrometer towards the study of materials for explosives detection. Another possible use is for NQR quantum computing; however, that requires further modification of the hardware, most notably designing and constructing a two-coil probe. Nevertheless, the NQR spectrometer has validated the pulse programmer and Class E amplifier. It demonstrated the flexibility, transparency, and portable of the pulse programmer. It also demonstrated good recovery time of the NQR signal through the use of Class E power amplifier. 133 134 Chapter 7 Conclusions While the field of quantum computing is in its infancy, experimental realization of NMR quantum computers has provided proof of implementation. The implementation of NMR quantum computing experiments imposes stringent requirements for the control of qubits. The control of qubits, or implementation of precise quantum gates, can be reduce to control of RF pulses, which are generated by the pulse programmer and amplified by the power amplifier. I studied the requirements for both these control devices, and I designed and implemented two pulse programmers and two Class E amplifiers. In this thesis, I focused on the digital implementation of low-cost pulse programmers and the design issues associated with NMR pulse programmers. The pulse programmer digitally controls an analog circuit and sets the amplitude, phase, and duration of an RF pulse. Additionally, the pulse programmer requires sub-ns timing resolution to produce complex shaped pulses. We implemented two pulse programmers using programmable logic devices. The first pulse programmer is capable of generating minimum pulse widths of 1 ps, while the other one is capable of generating minimum pulse widths of 8 ns. The Class E amplifier is a low-cost alternative for NMR power amplifiers that is well-suited for the needs of NMR quantum computers. It has a ringdown time faster than a Class C amplifier, which is used in commercial NMR spectrometers. The fast ringdown time contributes to a fast recovery time during measurement of an FID 135 signal, which often results in a higher SNR when compared to slower recovery times. I designed two class E amplifiers, one at 34MHz and the other at 4.64MHz. The pulse programmer and power amplifier are integrated into an NQR spectrometer to test the control of RF pulses with these devices. The NQR signals originating from 14 N in sodium nitrite and from 3 1CI in paradichlorobenzene are measured using the NQR spectrometer as validation of the pulse programmer's and Class E amplifier's functionalities. 7.1 Future Prospects: pulse programmer As quantum computers emerge and mature, the demand for pulse programmers will grow. Quantum computers rely on precise and accurate control of different physical systems. For instance, superconducting quantum computers are proposing high-speed pulse programmers capable of ns and sub-ns timing resolutions. Ion traps are also calling for high-speed pulse programmers capable of complex pulse sequences to manipulate quantum systems. The work done on the pulse programmer in this thesis has established a basis for a new project, which proposes to design and implement pulse programmers for superconducting Josephson-phase quantum computers. The design requirements for the superconducting Josephson-phase quantum computer calls for complex, precise pulse programmers capable of outputting 8 to 10 ns minimum pulse widths, and scalable up to 100 RF output channels. Since these requirements are similar to NMR quantum computers, many of the design issues discussed in Chapter 5 apply to this system. The work on the pulse programmers can be extended to a third-generation pulse programmer. Currently, the hardware design of the third-generation pulse programmer is completed. Figure 7-1 is a block diagram describing the general components of this device. Like the previous pulse programmers, a programmable logic device is the foundation of the pulse programmer. However, in order to develop a general-purpose pulse programmer, we have decided to develop a customized PCB. The pulse programmer has 136 55 MBytes of static memory with a depth of 512 kbits and 82 bits of I/O lines. For clock cycles of 8 ns, this corresponds to a data rate of 12 Gbps, which interestingly, is competitive to commercial grade Ethernet controllers. In addition, the programmer is designed to be configurable. First, the board can be constructed to use ground isolated LVDS connections which reduces the overall noise in the board, and in turn, may reduce the errors in quantum operations. Second, the clock driving the programmable logic device can be configured in one of three ways: (1) a crystal can be used as the oscillator, (2) the clock pin from the connector can be used to route clock signal, or (3) one of two SMA connectors can be used to feed a clock signal. 512Mbit clock 5M SRA J08 en as bts Complex 7 Programmable r is es Logic Device (CPLD 400 pin BGA fl t pq a * Figure 7-1: A block diagram of a pulse programmer designed for superconducting Josephson-phase qubits. Once a properly functioning pulse programmer is designed and implemented, de- sign files will be made open available. This milestone will represent a broadly useful technical contribution of this thesis work to the experimental quantum computing community, spreading lessons learned from NMR implementation to improve control of other physical systems. 137 138 Appendix A NQR Theory We present some basic background on nuclear quadrupole resonance (NQR) theory for spin I = 1 systems. A.1 NQR historical background NQR was discovered [Deh50] and studied [Pou50] shortly after the discovery of NMR in bulk media [BHP46, PTP46]. NQR has been used to study phase transitions of materials [PB76] and their ferroelectric properties [SNFY58], and whereas, NMR has gained a wide acceptance as an analytic tool in science, NQR has not gained the acceptance or popularity. NQR has many advantages over NMR. It has greater sensitivity to the environment because the resonance is dependent on the electric field gradient surrounding the nucleus. One of the most important advantages of NQR over NMR is the absence of a large static magnetic field. This means a large superconducting magnet is unnecessary for a NQR spectrometer. So for materials with large quadrupole coupling constants, NQR signal detection is appealing for industrial and commercial applications because of lower costs and easier maintenance. NQR has found practical applications. The detection of "N via pure NQR [BGJM94] has gained attention because many explosives and narcotics contain 14 N. A query of 10,000 materials containing 14 N shows the NQR resonance frequencies are virtually unique. As a result, researchers have 139 developed explosives detectors and remote sensing landmine detectors that identify materials based on their NQR frequencies [GBM+01, GBYM93]. Recently, theoretical work by Furman shows one can use the nuclear quadrupole moment for quantum computation [FGMS02I. Using two RF fields with different phases and orientations, the degeneracy of a spin 1=3/2 can be theoretically removed. The fields form four nondegenerate basis states, which represents two qubits. An additional RF field is required to manipulate the qubits. A.2 Qualitative comparisons of NMR and NQR In Chapter 3, we introduced NMR. NQR turns out to be quite similar to NMR in many ways, but there are distinct differences between NMR and NQR. The energy splittings in NMR are due to Zeeman interaction, whereas in NQR, the splittings are mainly attributed to electrostatic interactions between the nuclear and electron charge distributions. The energy levels are highly sensitive to slight changes in the molecular structure of the system. We highlight the main differences between NMR and NQR: e NQR signals are not observed in liquids. The energy splittings in NQR are due to nonspherical electron charge distributions that create electric field gradients (EFG) around the nucleus. Within the time scale of NQR experiments, EFG of liquids is averaged to zero due to molecular tumbling motion. In solids, the rapid, random tumbling motion is removed and characterized by a rigid molecular lattice. e In NMR, the orientation of the external static magnetic field and the RF field determine the efficiency of the excitation. In NQR, the relative orientation of the RF field and the molecular crystal structure determine the efficiency of the excitation. Since different crystallites in a powder sample have different molecular frame orientations, it is impossible to excite all the crystallites with maximum efficiency. In other words, all nuclei do not see the same effective 140 EFG; thus, the signal efficiency is lowered. " NQR resonance frequencies are highly dependent on the crystal structure and molecular dynamics. Identical molecules with different packing environments may cause shifts in frequencies between the different systems. Furthermore, if the surrounding field gradient environment forms symmetries about the nucleus, then the frequency is considerablely reduced, even in the presence of a large quadrupole moment. Temperature also plays a role in the NQR frequencies. Temperature changes lead to different vibrational modes, leading to shifts in the resonance frequency. " For a spin system with I < 1, there exists no quadrupole moment, and so, there are no observable NQR effects. However, this should not be interpreted as such nuclei having spherically symmetric charge distributions as we had initially thought. Nuclear physicists generally define an intrinsic quadrupole moment (Qo) with respect to a coordinate axis system fixed on the nucleus. The quadrupole moment (Q) measured in experiments is a projection of Qo onto a coordinate axis system that is independent of the motion of the nucleus such as the lab frame. In general, Qo is nonzero for all nuclei for which the sum of the nucleons does not match the "magic" numbers of the nuclear shell model. Because Qo transforms as a second rank tensor and is thus symmetric under parity transformations, at least three orthogonal directions must be defined for the nuclear body axis to have different probabilities of orientation along the directions. Thus, Q = 0 for I < 1 [Seg77, BM75]. A.3 NQR Hamiltonian and resonance frequencies The NQR phenomenon is a second order effect that arises from the interaction between the nuclear quadrupole moment (Q) and the EFG surrounding the nucleus. The effective Hamiltonian is [DH58]: 141 e2 qQ Ho=41(21 ( 1) ( -1) ( )+7(Xl 2)) (A.1) The choice of axes is such that the EFG tensor is diagonalized and JVxj < IVyyl < IV;zl. is called the asymmetry parameter and is defined as |V27 | - |VYI =z I I (A.2) We note that 0 < 77 < 1. For the case of the spin I = 1, the Hamiltonian in the jm)-basis is represented as 1 Ho = 0 r/ 0 -2 0 0 1 rTI (A.3) with eigenvalues E1,2,3 = 1 + (A.4) ,, -2, 1 -, and corresponding eigenstates 1 v/2 )0 () 1 0 ,12) = ,|3) = 0 (A.5) 0 Equation (A.3) can be rewritten in its quadrupole basis by a basis transformation: HOQ= 0 0 0 0 Ex 0 -2 01 0 E 01 0 0 1+17 0 0 Ez The eigenbasis is then labeled by the Cartesian basis states: 142 (A.6) 1) Ix)= 0 1z) y) = 0 0) 0 (A.7) Sometimes this frame of reference is referred to as the principle axis system (PAS) [Lee02]. A.4 Pure NQR selection rules We have established NMR obeys the familiar selection rules Am = ±1. In pure NQR, the selection rules differ from NMR. There are three energy levels Ex,,,2 that result in three possible frequency transitions: WX = Ez - Ey = 3+7, Wy = E-Ex Wz = Ex - Ez = -2 =-(3-1), and (A.8) The selection rules for wx is Am = ±1, w, is Am = t1, and wz is Am = 0, ±2. At first glance, this seems to violate well-known selection rules, established in NMR, where Am = +1. But the selection rules are not in violation. Upon closer examination, we find the interaction of the 2nd order (quadrupole) electric nuclear wavefunction with the electric field gradient leads to a way of establishing the selection rules through spherical harmonic equations. The electrostatic potential energy of a nucleus of finite dimensions in the field of surrounding electrons is given classically by the expression: WE JJ WE Te l Pe(re)Pn(rn)dTedTn Ir-(A.9) ire - rni Tn where p, is the nuclear charge density, pe is the electron charge density, re is distance of the electric field from the origin, and r, is the distance of the nucleus from the 143 origin. Equation (A.9) can be rewritten in terms of spherically harmonic equations as (A.10) N"-E-", WE = Nlm = 247+ Ek-+ = 24+ I pn(rnirYnm(On, n))drn, and 1prrY -"(Oe, #e))dTe, (A.11) (A.12) where Y"(Oe, 0e) is the angular equation. If the state of the nucleus is described by the wave function TI(R 1 , R 2 , ... RA), then Njn is given by the expectation value of the Hamiltonian operator over the nuclear wave function described by X17 = p r' Y" (Oj, #0). +1,,) 21+1j (A. 13) Similarly the expectation value of the operator over the electronic wave function is - = 24+ (11) Yv-(6k,#k). r)r (A.14) Since the operators transform in the same way as the spherical harmonics, they are called tensor operatorsof order 1. The expectation values of the operator N[" is known as the nuclear multipole moment. General dipole selection rules Applying the operator NGIX, we examine the allowable transitions for the dipole mo- ment by calculating (<DIf IMl <D) oc (n, 1, m fY' (0, 144 #)1n', l', m');. (A.15) After substituting in 1 = 1 and m = 0, (A.15) yields (n, , mf1YI'(0, r 3Rf (r) Ri (r)dr #) In', 1', M')i = 27r +1 exp (i(mf - mj)#)d#, (x)P"(x)d xP," (A.16) 0 0 where x = cos 0. For Equation (A.16) to be nonzero, the following condition must be 27r satisfied m 1 = mi (Am = 0) because f exp (i(mj - mj)O)d = Omf,mi 0 The following recursion relationship for Legrende polynomials XFP1 (x) = 211 ((1 - |m|)P+(x) + (1 + Im)P"'irn(x)) (A.17) shows that Al = ±1 because +1 12 1 ((1 -1 - jmf|)P+1 (x) + (1 + Imi)Pi'_"'(x)) P,,m(x)dx = 61,1 (A. 18) when ' = 1 ± 1. Similarly, the same argument applies for 1 = 1 and m = t1. For (A.15) to be nonzero, Am = +1. Thus, the selection rules are Al = ±1 and Am = 0, ±1. Quadrupole moment selection rules It is well established experimentally that nuclear wave functions are either even or odd with respect to inversion. Since R(r)j is an even function, the expectation value will be the integral of an odd or even function as Ym is odd or even. Since integrals of odd functions are zero, only the even multipole terms of A/j" will survive. This means the nuclear electrostatic dipole moment does not occur, ruling out the established dipole selection rules. Thus, the first term of interest is the quadrupole moment (1 = 2). We determine the selection rules by examining the allowable frequencies. Using Equation A.15 with 1=2, we find that the equation is proportional to: Oc c f(3x2 - 1)Plmf(x)PF"(x)dx f(Pm-f(x) + Pi+f (x))(P177 1 (x) + P";1 (x)) - P m (x)Pj""(x)dx 145 (A.19) (A.20) So Al = 0, ±2 must hold true for the integral to have a nonzero result. m ={0, 1,2, ... }, Equation (A.15) yields Am = 0, ±1, selection rules are Al A.5 = 0 and A = 2. For Thus, the quadrupole 0, ±1, ±2. RF excitation and effective signal averaging The picture of NQR excitation can be seen as a 3-D extension of the excitation process in spin-1/2 NMR. Because the spin-1 systems transforms as three-component vector in 3 space, i.e. PAS frame, the classical notion of precession still applies. For example, a RF field apply along the ly). Iz) basis drives the transitions between Ix) and This is analogous to precession about the 2-axis. Since we consider the PAS frame, the relative orientation of the applied frequency determines the efficiency of the excitation. As a direct consequence, NQR in crystallites cannot be maximally excited in a powder crystalline samples. The expected signal can be theoretically calculated using density matrices. For high temperature, the thermal density matrix is approximated by Pe = exp (A.21) I - -HQ kT kT Since identity does not change under time evolution, this term can be ignored. Also, -1 is constant factor that is dropped. Thus, Equation A.21 can be simplified to the approximation: po = HQ (A.22) In the spin 1=1 case, the density matrix is 1 - / 0 0 0 -2 0 0 0 1 +r po =H As (A.23) in the quadrupole (PAS) basis. The rotating frame (interaction picture) is calculated 146 using the equation: (A.24) pro(t) = U(t)HTOUt(t) where U(t) = Under an RF pulse, the total Hamiltonian, in the exp(iHASst). The RF field is linearly polarized on the quadrupole basis, is HTOT = Ho + H. sample due to relative orientation axis rather than circularly polarized electromagnetic field in NMR. So, the rf field cannot be decomposed into two components. An RF field apply on a disoriented solid, in the i-axis, corresponds to H3 w cos (3 + 71)wt)(cos 6)IfAS, where 0 is the angle between the excitation axis and the PAS (A.25) - plane. In the rotating frame, the matrix for spin 1=1 is 0 rot = PTOT = 1coso 0 cos0 0 0 0 0 0 . (A26 (A.26) In Equation A.26, the fast oscillating terms go to zero. Under time evolution, the Hamiltonian becomes p(t) = U(t)HPAsUt(t) (A.27) where U(t) = exp(iHprott). The read out of the signal is measured in one axis, so the trace of the Hamiltonian along the axis of measurement is 1. Tr(p(t)A) = -(3 + q)w sin ( 3 w(3 + ) 3 t) sin (tw cos ) (A.28) where the measurement operator A = I:AS. The signal is dependent on the relative orientation of the excitation field, and for crystal powders the signal cannot be maximized. Averaging the signal turns out to be f sin (t cos 0) sinOd9 = J(2tw). 147 (A.29) We notice that the averaged signal does not follow a sinusoidal function as in NMR, but rather the Bessel's function as shown in Figure A-1. The maximum signal intensity arises when wt = 1190 or 0.667r. This corresponds to a 90' pulse in NMR. Hence the operation is known as a I pulse. In practice, the maximum signal obtainable from the nuclei is 48% when compare to a signal crystal sample. In a single crystal, the expected averaged signal is expected to follow a sinusoidal function. 0.667E 1 i 1.887t Figure A-1: A bessels function is the average FID signal induced in NQR experiments. A "7r/2" pulse is produced when wt is 0.667r. The amplitude is normalized in this example. A.6 Summary In this appendix, we have introduced NQR theory for spin-1 systems and have highlighted the differences between NMR and NQR. Spin-1 NQR is similar to NMR in many ways. The spin-1/2 precession applies to NQR, but with several key differences: * NQR is not observed in liquids, but often in crystallites and power samples with spin > 1/2. " The interaction between the electric nuclear wavefunction and the electric field orientation yields selection rules Am = 0, i, ±2. In spin-1 systems this results 148 in all possible transitions in the PAS frame. * The resonance frequency is sensitive to the crystal structure and the packing environment around the nuclei. Temperature also plays a role in the resonance frequency, shifting it accordingly. " Random orientations in the sample and different effective EFG in crystal powders reduces the maximum signal intensity is 48% when compared to a single crystal. As a result, detection of a FID in NQR is more difficult in comparison to NMR. Despite these differences, the isolated two-level spin dynamics under signal resonance frequency excitation in NMR has the similar relations to NQR. So methods introduced in NMR (such as spin echo pulse sequences, composite pulses, shaped pulses, and adiabatic pulses) may be applied in a similar fashion to NMR. 149 150 Appendix B Appendix A: First Generation Code This appendix includes the Protel schematics and layout for the daughter used the first generation of pulse programmers. Also included is the rabbit core code, written in C. Several examples of Matlab code for controlling the pulse programmer are included. Some of the features of the rabbit pulse programmer include e TCP/IP connection * A webserver which allows the user to control the pulse programmer o Ability to control the pulse programmer through matlab via cgi-style post methods o TTL pulse as output (upto 4 channels) o Pulse sequence compiler built in the chip o 338ns pulse resolution 151 I I I Figure B-1: Overview of the entire schematic for the first generation pulse programmer. The next 4 sections show full size schematic diagrams of the daugther board. The sections start from left to right and move from top to bottom. 152 3 y CL 4. D 10 l POW IN SI 3 4 2 VM3 -42QCT.5.0 C1 1 AP 13 B~ll / Al:l 151 21 21 237 FUSE 2 AAt 31 rcerca 23 Pi SM ,G UI 40PIN0 PU E L,4L S2 I J27 A Figure B-2: The top left corner schematic of the rabbit daugther 153 I1I I'I I(7 7-fo~ 11 q 2 R US-KnVOU-IONN LED F)l J6 LED LFJ) PAD w r 4' -; 1 .9 IMADM 4X2 Figure B-3: The top right corner schematic of the rabbit daugther board 154 L3 I 9 13 ; Mo GD -I 19 191 A2 17 B na e -l 31 s 32 SMMFI 34 35 s sAes 37 640 o -MOE, 1~ ~ -j. 34 s1 oo eoD vc GD u DAMTE 10 DAUXl 11 - 35 37 39 DAI OAT 31 . LOAD_ 40PIN R2 IK 4OPIN4 A / I 2 3 Figure B-4: The bottom left corner schematic of the rabbit daugther board 155 3 4 SIO AG 0 DACLL 6DB Dr 11 CowAN AI 20 TICDv2% 0 . 99COAXCON 27 WA C A 62 6IK 6= 6) 6 Ra SI SIG 13 8 Ra- 5 4 6 Figure B-5: The bottom right corner schematic of the rabbit daugther board 156 B.1 Source code Author: Wei-Han Huang Date: SEPT-01 Abstract: Pulse program code for the rabbit 2000 Offers webpage that serves as a controllerfor the rabbit 2000 board Date: JUNE-02 Additions: Added code that reads cgi-style function calls to the rabbit board for example: "192.168.1.81\enterA.cgi \variable1=valuel&variable2=value2" current cgi commands that are available: command: runOnce example: runOnce.cgi ?prep=2&pw=40&recover=4&ack=2 abstract: the capturefunction sends rabbit the pulse width and number of samples to be taken the pulse width is in (micro-seconds, le-6) prep time is in (see) -> time between the pulse pw time is in (us) -> time of pulse width recover time is in (us) -> time between the end of pulse and the beginning of acquisition pulse ack time is in (msec) -> duraction of the acqusistion pulse repetitions -> number of repetitions (default case is to run forever) if you just set the pulse width, the other values (parameters will default to prep = 2 (Sec), recover time = 5 (u-sec), ack = 2 (m-sec) the purpose of this function is to run it with matlab, where matlab tells it to run once, while it captures the data. we can then automate the code to capture data accordingly Output ports for the rabbit board are the following: port cO -> acquisition pulse port c2 -> hpulse port c4 -> acquisition pulse command: runPulseSeq example: runPulseSeq.cgireps=-1&code=C0C2C0C300 abstact: attempts to run pulse sequence for n repetitions code -> the pulse sequence code "COC1. . ." nsamp -> number of repetitions #define MYIPADDRESS #define MY-NETMASK 192.168.1.81" "255.255.255.0" *define REDIRECTTO "http://192.168.1.81" #define MAX-INSTRUCTIONS 100 #define OPCODE1 0x0A *define OPCODE2 0x40 #define OPCODE3 0x11 *define OPCODE4 0x12 *define OPCODE5 0x13 #define OPCODE6 0x14 //#define //#define DEBUG -DEBUG- #memmap xmem *use "dcrtcp.lib" *use "http.lib" #ximport "E:\NQR\test2.html" indexhtml #define MAX-FORMSIZE255 *define NUMFIELDINPUTS 19 typedef struct { char *name; char value[MAXFORMSIZE]; } FORMType; FORMType FORMSpec[NUM-FIELD-INPUTS]; int mainState; 157 States in the state machine 1-> http handler 2->run pulse 3->RunHpulseProgramwith TPrep in m-secs, Acq Time in m-sec 4->RunHpulseProgramwith TPrep in secs, Acq Time in rn-sec 5->RunHpulseProgramwith TPrep in m-sees, Acq Time in sec 6->RunHpulseProgramwith TPrep in secs, Acq Time in sec 7->RunOnce (RunHpulseProgramOnce!) Tprep in (secs), and acq time in (rmsec) 8-> RunPulseProgram:run a pulse sequence program int PortA; PortB; PortC; PortD; int int int int Freq; int TPrep; THPulse; int TRecover; int TAck; int TReps; int int num-ops; static char ops [MAXINSTRUCTIONS]; static char code [MAXINSTRUCTIONS]; char last -error[255]; int int int int int int int enterA enterB enterC enterD enterFreq enter.pp runHPulse (HttpState * state); (HttpState * state); (HttpState * state); (HttpState * state); (HttpState * state); (HttpState * state); (HttpState * state); /*test code +/ void test-repeat(int repetitions); /* GET METHOD COMMANDS a/ int runOnce (HttpState * state); (HttpState * state); int runPulseSeq /* PARSING FUNCTIONS */ int ParseCommand(char * string); int CompilePulseCode(char * program); void RunPulseProgram(; void RunPulseProgram2(int treps); void initialize.parser (); int int ASCII.to-Int hex-to-int (char * string); (char c); (char count); void RunPulse void initialize-ports 0; // initialize int parsepost(HttpState* state); void parse-token(HttpState* state); const HttpType http-types[] ={ { ".html", "text/html", NULL}, { ".gif", "image/gif", NULL}, { ".cgi", "", NULL } 1; const HttpSpec http-flashspec[] = { {HTTPSPEC-FILE, "/", index.html, NULL, 0, NULL, NULL}, {HTTPSPEC-FILE, "/index.html", index-html, NULL, 0, NULL, NULL}, {HTTPSPECSFUNCTION, "/enterA.cgi", 0, enterA, 0, NULL, NULL}, {HTTPSPEC-FUNCTION, "/enterB.cgi", 0, enterB, 0, NULL, NULL}, {HTTPSPEC-FUNCTION, "/enterC.cgi", 0, enterC, 0, NULL, NULL}, {HTTPSPECSFUNCTION, "/enterD.cgi", 0, enterD, 0, NULL, NULL}, {HTTPSPEC-FUNCTION, "/enterFreq.cgi", 0, enterFreq, 0, NULL, NULL}, {HTTPSPECSFUNCTION, "/enterpp.cgi", 0, enternpp, 0, NULL, NULL}, {HTTPSPECFUNCTION, "/runHPulse.cgi", 0, runHPulse, 0, NULL, NULL}, {HTTPSPEC-FUNCTION, "/runnce.cgi", 0, runOnce, 0, NULL, NULL}, {HTTPSPEC.FUNCTION, "/rnPulseSeq.cgi", 0, runPulseSeq, 0, NULL, NULL} 1; int { hex-to-int(char hex) // just switch { case case a quick table (hex) '0': '1': 158 case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return case 'A': return case 'B': return case 'C': return case 'D': return case 'E': return case 'F': return } return -1; int (hex - x30); 10; 11; 12; 13; 14; 15; runHPulse (HttpState * state) const char sec[] = "sec"; const char msec[] = "ms"; if(parse.post(state)) TPrep = ASCII.to-Int(FORMSpec[6].value); THPulse = ASCII1to-Int(FORMSpec[7].value); TRecover = ASCII-to-Int(FORMSpec[8].value); TAck = ASCII-to-Int(FORMSpec[9.value); TReps = ASCII-to-Int(FORMSpec[12].value); // returns -1 if it is a string, //default automatically to infinite loop if (strcmp(msec, FORMSpec[10].value) == 0 && strcmp(msec, FORMSpec[11].value) == 0) mainState = 3; else if (strcmp(sec, FORMSpec[10].value) == 0 && strcmp(msec, FORMSpec[11].value) ==0) mainState = 4; else if (strcmp(msec, FORMSpec[10].value) == 0 && strcmp(sec, FORMSpec[11].value) == 0 ) mainState =5; else if (strcmp(sec, FORMSpec[10].value) == 0 && strcmp(sec, FORMSpec[11].value)== 0 ) mainState = 6; } cgi-redirectto(state, REDIRECTTO); return 0; } set the pulse width, prep time, acquisition time, and the recover time and run it once, and then stop the assumption is that prep is in (sec) and ack is in (m-sec) if you just set the pulse width, the other values (parameters will default to prep = 2 (Sec), recover time = 5 (u-sec), ack = 2 (m-sec) int runOnce (HttpState * state) int pulse-width, acquisition, recover, prep-time, reps; if(parse-post(state)) pulse-width = ASCII-toInt(FORMSpec[13].value); acquisition = ASCII-toInt(FORMSpec[14].value); recover = ASCII.to.Int(FORMSpec[15].value); prep-time = ASCII-to-Int(FORMSpec[16].value); printf("string - %s\n", FORMSpec[17].value); reps = ASCI Ito-Int(FORMSpec[17].value); mainState = 7; // error checking if (pulse-width > 255) pulse-width = 255; else if (pulse-width <=0) pulse-width = 5; if (acquisition > 255) acquisition = 255; else if (acquisition <= 0) 159 acquisition = 2; if (recover > 255) recover = 255; else if (recover <= 0) recover = 5; if (prep-time > 255) prep-time = 255; else if (prep-time <= 0) prep-time = 2; if (reps > 255) reps = -1; // run forever //(note that if reps is negative it will run forever) TPrep = prep-time; THPulse = pulse-width; TRecover = recover; TAck = acquisition; printf("reps - d\n", reps); TReps = reps; } cgi-redirectto(state, REDIRECTTO); return 0; } Run a pulse sequence code given the parameters passed to the rabbit chip. If there is an error in the pulse sequence the compiler will catch it and return the error to the user and will not run the pulse sequence int runPulseSeq (HttpState * state) int reps; char * program; if(parse.post(state)) { reps = ASCII1toInt(FORMSpec[17].value); program = FORMSpec[18].value; initialize-parserO; if (CompilePulseCode(program) == 1) mainState = 8; // error checking if (reps > 255) reps = -1; // run forever //(note that if reps is negative it will run forever) if (reps == 0) reps = -1; TReps = reps; cgi-redirectto(state, REDIRECTTO); return 0; } else { mainState = 1; printf("syntax error!\n"); } } cgi-redirectto(state, REDIRECTTO); return 0; } int enter-pp (HttpState * state) int i; #ifdef DEBUG printf("enter pulse program\n"); #endif if(parse-.post(state)) I initialize-parser(); #ifdef DEBUG printf("Program Entry: %s\n". FORMSpec[5].value); #endif if (CompilePulseCode(FORMSpec[5].value) == -1) #ifdef DEBUG 160 printf("Last Error: %s", last-error); else { printf("command value\n"); for (i = 0; i < num-ops; i++) printf("Xd ld\n", ops[i], code[i]); } #else #endif I cgi-redirectto(state, REDIRECTTO); return 0; int enterA (HttpState * state) { if(parse-post(state)) { #ifdef DEBUG printf("Port A out\n"); #endif PortA = ASCII-to-Int(FORMSpec[0].value); if (PortA >= 0) { #ifdef DEBUG printf("Value: #endif %d\n", PortA); tasm push af Id a, (PortA) ioi Id (PADR), a pop af #endasm I //state->length = strlen(state-> buffer); //state->substate++; } cgi-redirectto(state, REDIRECTTO); return 0; int enterB (HttpState * state) { #ifdef DEBUG printf("Port B #endif out\n"); if(parse-post(state)) { PortB = ASCII.to.Int(FORMSpec[].value); if (PortB >= 0) { *asm push af Id a, (PortB) ioi Id (PBDR), a pop af #endasm } //state->length = strlen(state->buffer); //state->substate++; } cgi-redirectto(state, REDIRECTTO); return 0; } int { enterC (HttpState * state) #ifdef DEBUG printf("Port C out\n"); tendif if(parse..post(state)) { PortC = ASCII-to-Int(FORMSpec[2].value); if (PortC { >= 0) *asm push af ld a, (PortC) ioi Id (PCDR), a pop af *endasm } 161 //state->ength = strlen(state->buffer); //state->subst ate++; } cgi-redirectto(state, REDIRECTTO); return 0; } int enterD (HttpState state) { #ifdef DEBUG printf("Port D out\n"); #endif if(parse.post(state)) { PortD = ASCIL1to-Int(FORMSpec[3].value); if (PortD >= 0) { #asm push af Id a, (PortD) ioi ld (PDDR), a pop af Sendasm I //state->length = strlen(state->buffer); / /state->substate++; } cgi-redirectto(state, REDIRECTTO); return 0; } int { enterFreq (HttpState * state) if(parse-post(state)) { Freq = ASCI Ito-Int(FORMSpec[4].value); if (Freq > 0) mainState = 2; //state->ength = strlen(state->buffer); //state->substate++; } cgi-redirectto(state, REDIRECTTO); return 0; } // // // // asssume it is null terminate and the value of the char are ints (if not return -1) also assume value of string is positive so, mainly b/c there's no negative outputs that we are having int ASCII.toInt(char * string) { int i; char cVal; int rval; // error checks if (string -- 0) return -1; if (string[0] -return -1; '-') i - 0; rval - 0; cVal - string[i]; while ( cVal !- 0 { if (cVal < 0x30 I I cVal > return -1; rval - (cVal - Ox30) Ox39) // error! + 10 * rval; cVal - string(++i]; } return rval; } int check-tokens(char c) { if (c-- I return 1; return -1; c -- \n' I c -- 0 c-- '\r') 162 check-validhex(char c) int { if (c >return if (c >return 'a' I Ic 'f') <- 1; I c <- 'A ' 'F') 1; if (c >- '0' return 1; II c <- '9') return 0; } void RunPulseProgram2(int treps) { static int reps; reps - treps; #asm // disable interrupts ipset 3 push af// save the registers push bc push de push hl // disable watchdog ld a, 0x51 ioi Id (WDTTR), a disable the watch dog timer ld a, Ox54 ioi ld (WDTTR), ld a, OxOO// ioi ld init a port c (PCFR), a // put the rep information into register a //and save it on the stack ld a, (reps) ld c, a BEGIN: // b->num ops // c->reps // de->ops // hl->code // cp a, OxO0 // if a is < 0 then don't dec it, just keep it so that // we are in an infinite loop jp m, CMP-A // a is a minus sign dec c CMP-A: // point to the beginning of op code array Id de, ops Id hl, code push bc Id a, (hl) POINTA: // access array and figure out what op code to run Id a, (de) cp a, OxOA jr Z, SHORTDELAY cp a, Ox14 jr Z, NOOP cp a, Ox12 jr Z, TURN-C cp a, Ox13 jr Z, TURN-B cp a, Ox1O jr Z, MID-DELAY cp a, Oxl jr Z, LONG-DELAY cp a, OxOO ; reached end of the pulse program jr Z, CHECK POINTD: // compare num-ops to 0 pop de inc hl // move to the next instuction inc de jr POINT-A CHECK: // get reps and determine whether to run again // check if a == 0, if so then return, // otherwise dec a, and jp to BEGIN // pop de 163 // pop hl pop bc Id a, c cp a, OxOO; compare a with OxQO jr Z, RETURN jr BEGIN // loop forever NOOP: inc hl inc de jr POINTA SHORTDELAY: Id b, (hl) // code that delays by 1 us (2 loops total, // 1 loop for 1 u-sec) delay-usec-: Id c, b; load code[i] ld a, OxGO provides a 2-cycle delay inc a which makes everything delay by exact 1 usec (ain't this code crazy) ld b, a loop-usec_: ; delay by 1 u-sec djnz loop-usec_ ld b, c ; delay by (variable)* usec -djnz delay-usec ;up to this point the delay is lusec inc hl inc de jr POINTA; go to next instruction MID-DELAY: // push hl push de ld b, (hl) // ld b,a delay-msec_: // code the delays by (variable) * ld d, b ld a, OxOA ld b, a// b - 10 loop-msec_: ld c, b// c - 10 Id a, OxFF ld b, a// b - FF 1msec msecA_: djnz msecA_ ld a, OxA6 ld b, a// b - A5 msecB_: djnz msecB_ ld b, c// b - 10 djnz loop-msec// ld b, d delay by 1 msec djnz delayamsec// delay (variable) * jr POINTD// next instruction msec LONGDELAY: // push hl push de ld b, (hl) // ld b, a // code the delay by 1 sec delay-sec_: ld e, b; e - counter ld a, OxFF ld b, a loop.secC_: ld d, b; d - 255 ld a, Ox78 ld b, a loop-secB_: ld c, b; c - 120 ld a, Ox8B ld b, a; b - 139 loop-secA_: djnz loop-secA_ ld b, c djnz loop-secB_ Id b, d djnz loop-secC_; delay by I sec id b, e djnz delay-sec_; delay by variable a 1 sec jr POINTD// next instruction TURNC: // turn on or off port c depending on ld a, (hl) mio ld (PCDR), a inc hl 164 inc de jp POINT'A TURNB: Id a, (hl) ioi ld (PBDR), inc hl inc de jp POINTLA a RETURN: ipres // set interrupts back to normal // re-enable the watchdog timer ld a, Ox51 ld (WDTrR), a pop pop pop pop hl de bc af #endasm printf ("Returning from pulse program"); return; } void RunPulseProgram() { #ifdef DEBUG int i; // read in the op code and then run it // loop around like this if (TReps -- -1) printf("Runs forever\n"); else printf("Runs %d times\n", TReps); for (i - 0; i < numops; i++) { switch (ops[i]) case OPCODEl: // jump to some place in code (assembly and run the code) printf("short delay for %d usec\n". code[i]); break; case OPCODE2: printfC"med delay for 7d msec\n", code~i]); break; case OPCODE3: printf("long delay for %d sec\n", code(i]); break; case OPCODE4: printf ("turn port C to %d\n", code[i]); break; case OPCODE5: printf("turn port B to Xd\n", code[il); break; case OPCODE6: printf ("no operation\n"); break; } } #endif } int ParseCommand(char * string) { char c; int i; int num; if (string -- 0) strcpy(last.error, "empty string\n\0"); return -1; } c - string[D]; if (c <'0' I i c > '9') { strcpy(last-error, "unexpected token: got a letter instead of a number \n\D"); #ifdef DEBUG printf("parse command error expecting a command between 0 and 9, but got the letter %c\n\D", c); printf("The next letter is %c\n\D", string[l)); Rendif 165 return -1; ops[num-ops] - c - 0x30; switch (ops(num-ops)) { case 0: case 1: case 2: // short delay: expect one byte (0-255) micro-sec (I byte) // mid length delay: (0-255 msec) long delay: delay is in secs // if (opsnum-ops) -- 0) ops(num-ops) - OPCODE1; else if (ops[num-ops] -- 1) ops~numops] - OPCODE2; else ops(num-ops) - OPCODE3; code[num-ops] i - c - num - 0; 1; string[i] - 0; do { if (check-tokens(c)---l) { if (c < '0' II c > '9') { #ifdef DEBUG printf("Error: expected number but got Xc", c); #endif return -1; I num - hex-to.int(c) #ifdef DEBUG printf("Xc\n", c); + 10*num; #endif } } c - string[++i]; while ( (c >- '0') && (c <-'9') 1I (c -- ' II c -- '\n' II c --'\r') ); // convert the units (in u-sec) to count u // nits and see what happens code[num.ops] - num; numops++; return i; break; case 3: case 4: // set port b 1 byte data value i - 1; c - string[il; num - 0; do { if (checktokens(c)---1) if (c < '0' Ig c > '9') #ifdef DEBUG printf("Error: expected number but got Xc", c); #endif return -1; I num - hexto-int(c) + 10*num; #ifdef DEBUG printf("Xc\n", c); tendif } c - string[++i]; 0') && (c <-'9') 1 } while ((c >c -- '\r')) I c - \n' (c -- ''I if (ops(num.ops] -- 3) opsnum-ops] - OPCODE4; else if (ops [numops] -- 4) ops [numops) - OPCODE5; code (numops) - num; numops++; return i; break; case 5: 166 // no opcode ops [num-ops] - OPCODE6; code[numops] - OPCODE6; num-ops++; // no operation return 1; break; default: return 1; break; /* compile the pulse code program - it'll even check for errors if there is an error then put the error message in the string last.error the parser is a very very very simple parser that just parses the pulse code int CompilePulseCode(char * program) { char c; int i; int rval; char * str; c 0; = i= 0; rval = 0; if (program == 0) return -1; c = program[i]; while (c != 0) { // found a token #ifdef DEBUG printf("HI HI 1 -> pass: token %c\n", c); #endif if (c 'c' == c == 'C') { // get the command rval = ParseCommand( &program[i+1] ); if ( rval == -1 ) return -1; i rval; += c = program[i]; if ( num.ops > MAX-INSTRUCTIONS ) return -1; // too many instructions c = program[++i]; } // kind of ugly code here <blah> else if (c == ' IIc == '\n' IIc == '\r' II c== '' 1c== '+' c ==OxD II c == '0' c == I|c-==0x0A II Ic == 'D' I| 'A') { c = program[++i]; } else { strcpy(last..error, "Blah: unexpected token\n\0"); return -1; } } *ifdef DEBUG printf("Done Parsing data!\n"); #endif return 1; } /** PARSING FUNCTIONS FOR GET METHODS * * Parse one token 'foo=bar',matching 'foo' to the name field in the struct, and storing 'bar' into the value void parse-token(HttpState* state) { auto int i, len; for(i=0; i<HTTP.MAXBUFFER; i++) { if(state->buffer[i] == '-' state ->buffer[i] = '\0'; } state->p = state->buffer + strlen(state->buffer) + 1; 167 for(i=0; i<(sizeof(FORMSpec)/sizeof(FORMType)); i++) { if(!strcmp(FORMSpec[i].name,state->buffer)) { len = (strlen(state->p)>MAXFORMSIZE) ? MAX-FORMSIZE - 1: strlen(state->p); strncpy(FORMSpec[i].value , state->p, 1+len); FORMSpec[i].value[MAXFORMSIZE - 1] = \O'; } } } parse the following string "variable=data&variable2=data2&variable3=data3\ 0" no spaces allowed int parse-get2(HttpState * state) { char lvalue[25]; char rvalue[255]; char * q; int k; int lvalSet; int i; memset(lvalue, 0, 25); memset(rvalue, 0, 255); IvalSet = 0; k = 0; q = state->p; // if nul is already passed in just return 1 if (*state->p == '\0') return 1; while (1) { if (*state->p == { // copy the ivalue strncpy(lvalue, q, k); q = state->p + 1; k = 0; IvalSet 1; } if ( (*state->p == '&') { (*state->p ==\)) if (lvalSet == 0) { printf("GET: parse error\n"); return 0; } //error strncpy(rvalue, q, k-1); // copy the rvalue q = state->p + 1; k = -1; // copy Ivalue and rvalue into formspec // clear Ivalue and rvalue for (i=0; i < NUM-FIELD-INPUTS; i++) { if (strcmp(lvalue, FORMSpec[i].name) == 0) { memset(FORMSpec[i].value, 0, 255); strcpy(FORMSpec[i].value, rvalue); } } #ifdef -DEBUGprintf("lvalue - %s\n", Ivalue); printf("rvalue - %s\n", rvalue); #endif IvalSet = 0; memset(lvalue, 0, 25); memset(rvalue, 0, 255); if (*state->p =='\0') return 1; } state->p++; k++; return 0; } + * parse the url-encoded POST data into the FORMSpec struct (ie: parse 'foo=bar&baz=qux'into the struct int { parse-post(HttpState* state) auto int retval; auto int len; auto int status; auto int j; while (1) { retval = sock-fastread((sock-type *)&state->s, state->p,1); 168 // read data off of the socket if (state->method == HTTP-METHOD-GET) // get method is detected... //rabbit board, doesn't provide a nice // way of obtaining // data from the client, but luckily i // found out that the information is // embedded in the url // just after a null character!!! j - 0; '\O) j++; while( state->url[j] strcpy(state->buffer, &state->url[j+1l); state->p - state->buffer; #ifdef -DEBUG_ printf("URL Buffer: %s\n", state->buffer); #endif return parse-get2(state); if (0 -- retval) { sstate->p -\' parse-token(state); return 1; } else if (-I -- retval) printf("Socket Error\n"); 1I (*state->p -'\r) if((*state->p -- '&) I (*state->p -- \n')) { /* found one token */ *state->p - '\0'; parse_token(state); state->p - state->buffer; } else { state->p++; } } if ((state->p - state->buffer) > HTTPJMAXBUFFER) return 1; // pass the bounds // end while loop return 0; /* end of data - loop again to give it time to write more */ I // run the pulse ... //toggles the output of port c between 0 and 5 // for the period requested (period) void RunPulse(char count) { // for now we assume that x is greater than 0 // (and not equal to it) static char y; y - count; // printf ("count - %d", y); #asm ipset 3 push push Id a, ioi Id Id a, ioi Id ; 4 clocks - turn off interrupts it's not reccomended i do this, but i will any ways. :-) af bc 10 clocks - save the register 0x51 (WDTTR), a ; disable the watch dog timer Ox54 (WDTTR), a Id a, Ox00 ioi Id (PCFR). a blink: Id c, a ; save led state ioi ld(PCDR),a ; blink //ioi ld(PADR),a ; blink Id a, (y) id b, a; 6 clocks - a is suppose to be 16-bits Id a, c ;restore led sate loop: djnz loop ; 5 clocks - jump two bytes done: xor a, OxFF jr blink pop bc pop af ipres ; 4 clocks - restore the interrupts 169 #endasm } /* initialize port a void initialize-ports() { #asm lda,0x84; port a all outputs ioi ld(SPCR),a ld(SPCRShadow), a; load value into shadow register xora; port e bit 1..7 inputs, 0 output ioi ld(PEFR),a ld(PEFRShadow), a; load shadow register lda,0x01 ioi ld(PEDDR),a ld(PEDDRShadow), a; load shadow register xora ioi ld(PECR),a ld(PECRShadow), a Ida, OxOF; turn off the leds ( i hope) ioi ld (PADR), a #endasm I void initialize.parser() { num.ops = 0; memset(code, 0, MAXINSTRUCTIONS); memset(ops, 0, MAXINSTRUCTIONS); memset(last-error, 0, 255); } void RunHPulseProgram(int t-prep, int t-prep-unit, int t-pulse, int t.pulse-unit, int t.recover, int t.recover-unit, int t-acq, int t-acq-unit, int t-reps) { return; I /* MAIN / main() { int hpul-count; int recover-count; FORMSpec[0].name = "enterA"; FORMSpec[1].name = "enterB"; FORMSpec{2].name = "enterC"; FORMSpec{3].name = "enterD"; FORMSpec[4].name = "enterFreq"; FORMSpec[5].name = "enter-pp"; FORMSpec[6].name = "enterTprep"; FORMSpec[7].name = "enterHPulse"; FORMSpec[8].name = "enter-recover"; FORMSpec[9].name = "enter-ack"; FORMSpec[10].name = "enter-prep-unit"; FORMSpec[11].name = "enter-acq-unit"; FORMSpec[12].name = "enterreps"; FORMSpec[13].name = "p,"; FORMSpec[14].name = "acq"; FORMSpec[15].name = "recover"; FORMSpec[16].name = "prep"; FORMSpec[17].name = "nsamp"; FORMSpec[18].name = "code"; mainState = 1; initialize-portsO; initialize-parsero; the TCP/IP stack sock-inito; /Initializes http-inito; // Initializes the web server tcp-reserveport(80); while (1) switch (mainState) case 1: http-handlero; break; case 2: // run pulse code here (halt the rest of the program) hpul-count = (int) (Freq / 0.24); RunPulse(Freq); break; case 3: 170 // run hpulse code TReps = -1; hpul-count = (int) (THPulse / 0.24); // convert to units recover..count = (int) (TRecover / 0.24); RunHPulseProgram(TPrep, 1, hpul.count, 1, recover-count, 1, TAck, 1. -1); break; case 4: TReps = -1; hpul-count = (int) (THPulse / 0.24); recover-count = (int) (TRecover / 0.24); RunHPulseProgram(TPrep, 0, hpul-count, 1, recover.count, 1, TAck, 1, -1); break; case 5: TReps = -1; hpul-count = (int) (THPulse / 0.24); recover-count = (int) (TRecover / 0.24); RunHPulseProgram(TPrep, 1, hpul.count, 1, recover-count, 1, TAck, 0, -1); break; case 6: TReps = -1; hpul-count = (int) (THPulse / 0.24); recover-count = (int) (TRecover / 0.24); RunHPulseProgram(TPrep, 0, hpul-count, 1, recover..count, 1, TAck, 0, -1); case 7: hpul-count = (int) (THPulse / 0.24); recover-count = (int) (TRecover / 0.24); #ifdef DEBUG printf("run once code\n"); printf("T Prep - %d\n", TPrep); printf("T HPulse - %d\n", THPulse); printf("T Recover - Xd\n", TRecover); printf("T Acqusition - Xd\n", TAck); #endif RunHPulseProgram(TPrep, 0, hpul-count, 1, recover-count, 1, TAck, 1, TReps); http-handlero; mainState = 1; break; case 8: RunPulseProgram2(TReps); http-handlero; mainState = 1; break; default: } } } 171 . . S1 S4 RF .. .. .. PULSE 85ACa DL~sE .N P.. .P...... ... . ........ Figure B-6: The PCB layout of the rabbit daugther board 172 Appendix C VHDL Pulse Programmer The source code for the VHDL pulse programmer is included in this appendix section. 173 buscntrl.vhd Entity: buscntrl (main test FSM) File: buscntrl.vhd -Date: 25-Mar-03 -- Abstract: bus controller... controls reading and writing ~~ to the DI02 board. -INPUTS: (1) mclk (master clock) = 50MHz -(2) clk (slowed clock for the DI02 display multiplexer) -(3) stClk (slowed clock for the state Machine) -(4) databuf (read or write data) -(5) adrbuf (address of the device requested) -(6) read '1' to executed -- (7) write '1' to execute -(8) ready '1' means it is waiting for a command ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> --- library IEEE; use IEEE.STDLOGIC_1164.ALL; use IEEE.STDLOGIC_ARITH.ALL; entity buscntrl is port (--mclk : in STD._LOGIC; - master clock : in STDLOGIC; -- slowed clock stClk : in STDLOGIC; -state machine cl ock reset : in STD_LOGIC; -- input databuf : in STDLOGICVECTOR(7 downto 0); -data to read/write adrbuf : in STD_LOGICVECTOR(2 downto 0); -device to address read : in STDLOGIC; -- '1' to read data write : in STD._LOGIC; -'1' to write data ready : buffer STD_LOGIC; -'1' when done, or nothing is happening and it's ready for use -external lines data inout STD_LOGIC_VECTOR(7 downto 0); adr : out STDLOGICVECTOR(2 downto 0); -: out STDLOGIC; Os chip select ('1' to write /read) out STD_LOGIC; we write enable ('1' to lato h data) out STDLOGIC; read enable ('1' to read data) dclk : out STDLOGIC clk signal busdir signal signal ctlwe signal ctloe -- signal begin ctlcs ctladr cs <= -'1' read, '0' write STDLOGIC; STDLOGIC; STDLOGIC; STDLOGIC; : STD.LOGICVECTOR(2 downto 0); ctl_cs; we <= ctl_we; oe <= ctl-oe; -- write pins if busdir = '0' data <= databuf when busdir = '0' else "ZIZZIZZ"; --data <= "11110000" when busdir = '0' else "01010101"; --and databuf = "11110000" --data <= "11110000"; --adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101"; adr <= adrbuf; dclk <= clk; -clock for DI02 display multiplexer -state machine to output lines process(stBusCurr, stBusNext, read, write) begin case stBusCurr is when => -- idle state -read data if read = '1' then stBusNext <= stBusRead; elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= stBusIdle; end if; stBusIdle output otlocs <= ctl we <= ctloe <= ready <= '1'; busdir <= -- --- oe : : : : on lines... '0'; '0'; '0'; '0'; when stBusRead => -read 1 stBusNext <= stBusRead-b; -output ctl-cs <= ctl-we <= ctloe <= ready <= '0'; busdir <= end entity; architecture behaviour of buscntrl is bus states for writing and readii type bstate is (stBusReset, on lines... '1'; '0'; '0'; '1'; -- when stBusIdle, -- stBusRead, -- Idle bus First state of read cycle -- First state of write cycle stBusRead__b, stBusCurr stBusNext <= read 2 stBusRead_c; -- output on lines... ctl-cs <= '1'; ctl-we <= '0'; ctl-oe <= '1'; ready <= '0'; busdir <= '1'; databuf <= data; stBusWrite_b, stBusWritec); -signals : bstate; signal signal stBusNext : bstate; => -- stBusReadc, stBusWrite, StBusReadb -when stBusReadc if (read => -read 3 = '1') then buscntrl.vhd Entity: buscntrl (main test FSM) File: buscntrl.vhd Date: 25-Mar-03 Abstract: bus controller... controls reading and writing to the D102 board. INPUTS: (1) mclk (master clock) = 50MHz (2) clk (slowed clock for the DIO2 display multiplexer) (3) stClk (slowed clock for the state Machine) (4) databuf (read or write data) -(5) adrbuf (address of the device requested) -(6) read '1' to executed -- (7) write '1' to execute -(8) ready '1' means it is waiting for a command ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> signal busdir : signal ctl_cs : signal ctlwe : signal ctl_oe : -- signal ctladr begin ---------- cs <= STD_LOGIC; -'1' read, '0' write STDLLOGIC; STDLOGIC; STD_LOGIC; : STD_L.OGICVECTOR(2 downto 0); ctl_cs; we <= ctl-we; Oe <= ctloe; write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; --data <= "11110000" when busdir = '0' else "01010101" --and databuf = "11110000" --data <= "11110000"; --adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101"; adr <= adrbuf; -clock for DI02 display multiplexer dclk <= -- library IEEE; use IEEE.STDLOGIC.1164.ALL; use IEEE.STD_LOGIC_kRITH.ALL; clk; state machine to output lines process(stBusCurr, stBusNext, read, write) begin case stBusCurr is when => -- idle state -read data if read = '1' then stBusNext <= stBusRead; elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= end if; -- entity busentrl is : in STD_LOGIC; -port (--mclk clk : in STDLOGIC; slowed clock -stClk : in STDLOGIC; ock reset : in STDLOGIC; -- input databuf : in STD,_LOGICVECTOR(7 downto 0); -data adrbuf : in STDLOGICVECTOR(2 downto 0); read : in STD_LOGIC; write : in STDLOGIC; ready : buffer STD_LOGIC; or nothing is happening and it's ready for use -- external lines data : inout STDLOGIC VECTOR(7 downto 0); adr : out STD_LOGICVECTOR(2 downto 0); cs : out STDLOGIC; -/read) out STD._LOGIC; we h data) out STD_LOGIC; data) dolk : out STD_LOGIC Oe master clock stBusIdle -- state machine cl to read/write -- device to address -'1' to read data -'1' to write data -- '1' when done, stBusIdle; -- output on lines... ctlcs ctl-oe chip select --write enable -- read enable ('1' ('1' to latc ('1' to read <= '0'; '0'; ready <= '1'; busdir <= '0'; to write when stBusRead => -read 1 stBusNext <= stBusReadb; -- output on lines... ctlcs end entity; <= '1'; ctlwe <= '0'; ctleoe <= '0'; ready <= '0'; busdir <= '1'; architecture behaviour of buscntrl is bus states for writing and readir type bstate is (stBusReset, stBusIdle, -stBusRead, -stBusReadb, stBusReadtc, stBusWrite, -stBusWriteb, stBusWritec); <= ctlwe <= '0'; -- signals signal stBusCurr : bstate; signal stBusNext : bstate; -- when stBusReadb => -read 2 stBusNext <= stBusReadc; Idle bus First state of read cycle output on lines... <= '1'; we <= '0'; ctl-oe <= '1'; ready <= '0'; busdir <= '1'; databuf <= data; -- ctlecs First state of write cycle ctl -when stBusReadc if (read = => -read 3 '1') then buscntrl.vhd signal busdir : signal ctl-cs : ctl_we : ctloe : -- signal ctladr begin Entity: buscntrl (main test FSM) File: buscntrl.vhd Date: 25-Mar-03 -- Abstract: bus controller... controls reading and writing -- to the DI02 board. -INPUTS: (1) mclk (master clock) = 50MHz -(2) clk (slowed clock for the DI02 display multiplexer) -(3) stClk (slowed clock for the state Machine) -(4) databuf (read or write data) -(5) adrbuf (address of the device requested) -(6) read '' to executed (7) write '1' to --(8) ready '1' means it is waiting for a command ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ---- signal signal STDLOGIC; STDLOGIC; -- '' read, '0' write STDLOGIC; STDLOGIC; : STDLOGIC_VECTOR(2 downto 0); cs <= ctl-cs; we <= ctlwe; oe execute <= ctl_oe; write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; "11110000" when busdir = '0' else "01010101"; --data <= --and databuf = "11110000" --data <= "11110000"; --adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101"; adr <= adrbuf; dclk <= -clock for DIO2 display multiplexer -- library IEEE; use IEEE.STD_LOGICl64.ALL; use IEEE.STDLOGIC_.ARITH.ALL; clk; state machine to output lines process(stBusCurr, stBusNext, read, write) begin case stBusCurr is when => -- idle state -- read data if read = '1' then stBusNext <= stBusRead; elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= end if; -- entity buscntrl is port (--mclk : in STDLOGIC; -clk : in STD_LOGIC; -slowed clock stClk : in STDOLOGIC; ock reset : in STDLOGIC; -input databuf : in STDLOGICECTOR(7 downto 0); -data adrbuf : in STD_LOGICVECTOR(2 downto 0); read : in STD_LOGIC; write : in STDLOGIC; ready : buffer STDLOGIC; or nothing is happening and it's ready for use -external lines data : inout STD_LOGIC_VECTOR(7 downto 0); adr : out STDLOGICVECTOR(2 downto 0); out STDLOGIC; -/read) we -out STDLOGIC; h data) out STDLOGIC; -data) dclk : out STDLOGIC cs master clock stBusIdle -- state machine cl to read/write -- device to address -'1' to read data -'1' to write data -'1' when done, stBusIdle; output on lines... <= '0'; ctlwe <= '0'; otl-oe <= '0'; ready <= '1'; busdir <= '0'; -- ctlocs chip select ('1' to write write enable ('1' to latc read enable to read when ('1' output ctl cs <= ctl-we <= otl-oe <= ready <= '0'; busdir <= -- end entity; architecture behaviour of buscntrl is bus states for writing and readir type bstate is (stBusReset, => -read 1 stBusNext <= stBusReadb; stBusRead on lines... 'l'; '0'; '0'; '1'; -- when stBusIdle, -- stBusRead, stBusReadb, stBusReadc, -- Idle bus First state of read cycle stBusWrite, -- First state of write cycle -read 2 stBusNext <= stBusReadc; -- => output on lines... ctl cs <= 'l'; ctl-we <= '0'; ctl-oe <= '1'; ready <= '0'; busdir <= '1'; databuf <= data; stBusWriteb, stBusWritec); signals signal stBusCurr : betate; signal stBusNext : betate; stBusRead-b -- when stBusRead_c if (read => = '1') -- read 3 then buscntrl.vhd signal busdir : STDLOGIC; -'1' read, '0' write signal ctlcs : STDLOGIC; signal ctlwe : STDLOGIC; signal ctloe : STDLOGIC; -- signal ctl-adr : STD._LOGICVECTOR(2 downto 0); begin Entity: buscntrl (main test FSM) File: buscntrl.vhd -- Date: 25-Mar-03 -Abstract: bus controller... controls reading and writing -to the DI02 board. INPUTS: (1) mclk (master clock) = 50MHz --(2) olk (slowed clock for the DI02 display multiplexer) -(3) stClk (slowed clock for the state Machine) -(4) databuf (read or write data) -(5) adrbuf (address of the device requested) -(6) read '1' to executed (7) write '1' to execute --(8) ready '1' means it is waiting for a command ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> --- cs we oe <= <= <= ctl_cs; ctlwe; ctl oe; -- write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; --data <= "11110000" when busdir = '0' else "01010101": --and databuf = "11110000" --data <= "11110000"; --adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101"; adr <= adrbuf; dclk <= -clock for DI02 display multiplexer library IEEE; use IEEE.STDLOGIC_1164.ALL; use IEEE.STD LOGICARITH.ALL; clk; state machine to output lines process(stBusCurr, stBusNext, read, write) begin case stBusCurr is when stBusIdle => -- idle state -- read data if read = '1' then stBusNext <= stBusRead; elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= stBusIdle; end if; -- entity buscntrl is port (--mclk : in STD_LOGIC; -elk : in STD._LOGIC; -slowed clock : in STDLOGIC; ock reset : in STDLOGIC; -- input databuf : in STDLOGICVECTOR(7 downto 0); -data adrbuf : in STDLOGICVECTOR(2 downto 0); read : in STDLOGIC; write : in STDLOGIC; ready : buffer STDLOGIC; or nothing is happening and it's ready for use -external lines data : inout STDLOGICVECTOR(7 downto 0); adr : out STD_LOGIC_VECTOR(2 downto 0); cs out STDLOGIC; -/read) out STDLOGIC; h data) out STDLOGIC; data) dclk : out STDLOGIC master clock stClk -- state machine to read/write -- device to address -- '' to read data -'1' to write data -'1' when done, chip select ('1' -- write enable -- read enable we cl ('1' -output ctl-cs <= ctl-we <= ctl-oe <= ready <= '1; busdir <= to write to late when ('1' stBusRead => stBusNext to read -- on lines... '0'; '0'; '0'; '0'; read 1 <= stBusReadb; -- output on lines... ctlocs <= '1'; ctl-we <= '0'; end entity; ctl-oe '0'; ready <= '0'; busdir <= '1'; architecture behaviour of buscntrl is bus states for writing and readir type bstate is (stBusReset, stBusIdle, -- <= -- stBusRead, -- Idle bus First state of read cycle stBusRead-b, stBusRead_c, stBusWrite, stBusWriteb, stBusWrite_c); -- First state of write cycle signals signal stBusCurr : bstate; signal stBusNext : betate; -- when stBusRead-b => -read 2 stBusNext <= stBusReadc; -- output on lines... ctlocs <= 'l'; ctl-we <= '0'; ctl-oe -- <= '1'; ready <= '0'; busdir <= '1'; databuf <= data; read 3 -when stBusReadc => if (read = '1') then buscntrl.vhd -------------- Entity: buscntrl (main test FSM) File: buscntrl.vhd Date: 25-Mar-03 Abstract: bus controller... controls reading and writing to the DI02 board. INPUTS: (1) mclk (master clock) = 50MHz (2) clk (slowed clock for the DI02 display (3) stClk (slowed clock for the state Machine) (4) databuf (read or write data) (5) adrbuf (address of the device requested) (6) read '1' to executed (7) write '1' to execute (8) ready '1' means it is waiting for a command ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -'l' read, '0' write signal busdir : STDLOGIC; signal ctl-cs : STDJLOGIC; signal ctlwe : STD._LOGIC; signal ctleoe : STDLOGIC; -- signal ctl-adr : STDLOGICVECTOR(2 downto 0); begin multiplexer) cs <= ctl_cs; we <= ctlwe; oe ctl_oe; <= write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; --data <= "11110000" when busdir = '0' else "01010101": --and databuf = "11110000" --data <= "11110000"; --adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101": adr <= adrbuf; dclk <= clk; -clock for DI02 display multiplexer -- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STDLOGICARITH.ALL; machine state to output lines process(stBusCurr, stBusNext, read, write) begin case stBusCurr is when stBusIdle => -- idle state -read data if read = '' then stBusNext <= stBusRead; elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= stBusIdle; end if; -- entity buscntrl is port (--mclk : in STDLOGIC; -clk : in STDLOGIC; -slowed clock stClk : in STD._LOGIC; ock reset : in STDELOGIC; -- input databuf : in STD_LOGICVECTOR(7 downto 0); -data adrbuf : in STDLOGICVECTOR(2 downto 0); read : in STD._LOGIC; write : in STDLOGIC; ready : buffer STDLOGIC; or nothing is happening and it's ready for use -- external lines data : inout STDLLOGICVECTOR(7 downto 0); adr : out STDLOGICVECTOR(2 downto 0); ce : out STDLOGIC; -/read) out STD._LOGIC; h data) we out STD_LOGIC; data) dclk : out STDLOGIC master -- clock state machine cl to read/write -device to address -'1' to read data -'1' to write data -'1' when done, output on lines... ctl-cs <= '0'; ctlwe <= '0'; -- ctloe chip select ('1' -- write enable -- read enable ('1' to write <= '0'; ready <= '1'; busdir <= '0'; to late when stBusRead => stBusNext ('1' to read -- -read 1 <= stBusRead-b; output on lines... <= '1'; <= '0'; ctlcs end entity; ctlwe architecture behaviour of buscntrl etloe j <= ready <= '0'; busdir <= bus states for writing and readir type betate is (stBusReset, '0'; '1'; -- stBusldle, stBusRead, --- Idle bus First state of read cycle stBusReadbD, otBusReadtc, stBusWrite, stBusWriteb, stBusWritc); -- First state of write cycle signals signal stBusCurr : batate; signal stBusNext : bstate; -- when stBusRead b => -read 2 stBusNext <= stBusReadec; output on lines... ctlcs <= '1'; ctlwe <= '0'; ctl-oe <= '1'; ready <= '0'; busdir <= '1'; databuf <= data; -- -- when stBusReadtc if (read = => -read 3 '1') then buscntrlvhd buscntrl Entity: (main test FSM) File: buscntrl.vhd Date: 25-Mar-03 Abstract: bus controller... controls reading and writing -- to the DI02 board. -INPUTS: (1) mclk (master clock) = 50MHz -(2) clk (slowed clock for the D102 display multiplexer) -(3) stClk (slowed clock for the state Machine) -(4) databuf (read or write data) (5) adrbuf (address of the device requested) --(6) read '1' to executed -- (7) write '1' to execute -(8) ready '1' means it is waiting for a command ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ----- signal busdir : STD_LOGIC; -'1' read, '0' write signal ctlcs : STDILOGIC; signal ctl_we : STD_LOGIC; signal : STD_LOGIC; -- signal ctl-adr : STDLOGICVECTOR(2 downto 0); begin ctloe cs <= ctlcs; we <= ctl_we; oe <= ctl-oe; -write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; --data <= "11110000" when busdir = '0' else "01010101"; --and databuf = "11110000" --data <= "11110000"; --adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101"; adr <= adrbuf; dclk <= clk; -clock for D102 display multiplexer library IEEE; use IEEE.STDLOGIC_1164.ALL; use IEEE.STDLOGICARITH.ALL; entity buscntrl is port (--mclk : in STD_LOGIC; -: in STDLOGIC; -slowed clock stClk : in STDLOGIC; ock reset : in STDLOGIC; -- input databuf : in STDLOGICVECTOR(7 downto 0); -data adrbuf : in downto 0); read : in STDLOGIC; write : in ready : buffer STD_LOGIC; or nothing is happening and it's ready for use -external lines data : inout STDLOGICVECTOR(7 downto 0); adr : out STD_LOGIC_VECTOR(2 downto 0); -ce : out /read) we : out STD._LOGIC; h data) : out STD_LOGIC; oe data) dclk : out STD._LOGIC clk STDLOGICVECTOR(2 STD._LOGIC; STDLOGIC; -state machine to output lines read, write) process(stBusCurr, begin case stBusCurr is when stBusIdle => -- idle state -read data if read = '1' then stBusNext <= stBusRead; elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= stBusIdle; end if; stBusNext, master clock -- state machine cl to read/write -device to address -'1' to read data -'1' to write data -'1' when done, chip select ('1' -- write enable -- read enable ('1' ('1' on lines... '0'; '0'; '0'; output -ctl-cs <= ctl-we <= ctl-oe <= ready <= '1'; busdir <= to write '0'; to late when stBusRead => -read 1 stBusNext <= stBusRead-b; to read -- output on lines... ctl-cs <= architecture behaviour of buscntrl is bus states for writing and readir type bstate is (stBusReset, stBusIdle, -stBusRead, -- '1'; ctl-we <= '0'; ctl-oe <= '0'; ready <= '0'; busdir <= '1'; end entity; -- when stBusRead.b => -read 2 stBusNext <= stBusRead-c; Idle bus First state of read cycle stBusReadhb, stBusReadc, stBusWrite, stBuswriteb, stBusWrite_c); signals signal stBusCurr : bstate; signal stBusNext : bstate; -- output on lines... ctl-cs <= '1'; ctlwe <= '0'; -- -- First state of write cycle ctl-oe -- '1'; <= ready <= '0'; busdir <= '1'; databuf <= data; when stBusRead-c => if (read = '1') -- read 3 then buscntrl.vhd Entity: buscntrl (main test FSM) File: buscntrl.vhd Date: 25-Mar-03 -- Abstract: bus controller... controls reading and writing -to the D102 board. -INPUTS: (1) mclk (master clock) = 50MHz -(2) (slowed clock for the DI02 display multiplexer) -(3) stClk (slowed clock for the state Machine) -(4) databuf (read or write data) -(5) adrbuf (address of the device requested) -(6) read '1' to executed -(7) write '1' to execute -(8) ready '1' means it is waiting for a command ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>> ---- signal busdir : STDLOGIC; -'1' read, '0' write signal ctl_cs : STD -LOGIC; signal ctlwe : STD_LOGIC; signal ctloe : STD_LOGIC; -- signal ctl-adr : STD__LOGICVECTOR(2 downto 0); begin clk library IEEE; use IEEE.STD LOGIC 1164.ALLuse IEEE.STDLOGICARITH.ALL; STD_LOGIC; STD_LOGIC; STDLOGICVECTOR(7 STD_LOGIC; oe <= ctl cs; we <= ctl we; oe <= otl oe; -- write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; --data <= "11110000" when busdir = '0' else "01010101"; --and databuf = "11110000" --data <= "11110000"; --adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101"adr <= adrbuf; dclk <= -clock for DI02 display multiplexer clk; entity buscntrl is port (--mclk : in STD_LOGIC; -- master clock : in -slowed clock stClk : in -state machine cl ock reset : in STDLOGIC; -- input databuf : in downto 0); -data to read/write adrbuf : in STDLOGIC VECTOR(2 downto 0); -device to address read : in STD_LOGIC; -'1' to read data write : in STD._LOGIC; -'1' to write data ready : buffer -'1' when done, or nothing is happening and it's ready for use -external lines data : inout STDLOGICVECTOR(7 downto 0); adr : out downto 0); cs : out -chip select ('1' to write /read) we out write enable ('1' to latc h data) out read enable ('1' to read data) dclk : out STD LOGIC clk cs STDLOGICVECTOR(2 STD_LOGIC; STDLOGIC; STD._LOGIC; state machine to output lines process(stBusCurr, stBusNext, read, write) begin case stBusCurr is when stBusIdle => -idle state -- read data if read = '1' then stBusNext <= elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= stBusIdle; end if; -- stBusRead; -- output on lines... ctlcs <= '0'; ctl we <= '0'; ctl ?e <= '0'; ready <= '1'; busdir <= '0'; --- when stBusRead => -read 1 stBusNext <= stBusRead-b; output on lines... <= '1'; <= '0'; ctl-oe <= '0'; ready <= '0'; busdir <= '1'; -- cs ctl_we ctl end entity; architecture behaviour of buscntrl is bus states for writing and readir type bstate is (stBusReset, stBusIdle, -stBusRead, -stBusRead__b, -- when stBusReadb stBusNext Idle bus First state of read cycle stBusReadtc' stBusWrite, stBusWrite_b, stBusWritec); signals signal stBusCurr : bstate; signal stBusNext : bstate; -- First state of write cycle -- -- => <= -read 2 stBusRead_c; -- output ctlcs <= ctlwe <= ctl-oe <= ready <= '0'; busdir <= databuf <= on lines... '1'; '0'; '1'; '1'; data; when stBusReadoc => -read 3 if (read = '1') then buscntrl.vhd signal busdir signal signal signal ctloe -- signal ctladr begin Entity: buscntrl (main test FSM) -File: buscntrl.vhd -Date: 25-Mar-03 -- Abstract: bus controller... controls reading and writing -to the DI02 board. -INPUTS: (1) mclk (master clock) = 50MHz -(2) (slowed clock for the DI02 display multiplexer) -(3) stClk (slowed clock for the state Machine) -- (4) databuf (read or write data) (5) adrbuf (address of the device requested) --- (6) read '1' to executed -(7) write '1' to execute -(8) ready '1' means it is waiting for a command ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -- ctl_cs ctl-we clk <= ctlcs; we <= otl we; oe master clock clk -- state machine cl STDLOGIC; STD_LOGICVECTOR(2 oe <= ctl-oe; -- write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; "11110000" when busdir = '0' else "01010101"; --data <= --and databuf = "11110000" --data <= "11110000"; --adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101"; adr <= adrbuf; dclk <= -clock for D102 display multiplexer clk; entity buscntrl is port (--mclk : in STDLOGIC; -: in STDLOGIC; -slowed clock stClk : in STDLOGIC; ock reset : in -- input -data databuf : in STDLOGICVECTOR(7 downto 0); adrbuf : in downto 0); read : in STDLOGIC; write : in STDLOGIC; ready : buffer STD_LOGIC; or nothing is happening and it's ready for use -external lines downto 0); data : inout downto 0); adr : out -: out STDLOGIC; /read) -we out h data) -out da ta) dclk : out STDLOGIC to read/write -- device to address -- '' to read data -- '1' to write data -- '1' when done, -- state machine to output lines process(stBusCurr, stBusNext, read, write) begin case stBusCurr is when stBusIdle => -- idle state -- read data if read = '1' then st~usNext <= stBusRead; elsif write = '1' then stBusNext <= else stBusNext <= stBusIdle; end if; stBusWrite; output on lines... <= ''; <= '0'; <= '0'; ready <= '1'; busdir <= '0'; -- ctlocs ctl we ctl-oe STDLOGICVECTOR(7 STD_LOGICVECTOR(2 STDLOGIC; STDLOGIC; chip select ('1' to write write enable ('1' to lato read enable ('1' to read when stBusRead => -read 1 stBusNext <= stBusReadhb; -- output on lines... cs ctl we ctl-oe ctl <= ''; <= '0'; <= '0'; ready <= '0'; busdir <= '1'; end entity; architecture behaviour of buscntrl is bus states for writing and readiz type bstate is (stBusReset, stBusIdle, --stBusRead, stBusReadtb, stBusRead.c, stBusWrite, -stBusWriteb, stBusWritec); -- signals signal stBusCurr : betate; signal : bstate; -- stBusNext write cs library IEEE; use IEEE.STDLOGIC_1164.ALL; use IEEE. STDLOGICARITH . ALL; cs STDLOGIC; : -'1' read, '0' : STD-LOGIC; : STD LOGIC; : STDLOGIC; : STD_LOGIC_VECTOR(2 downto 0); Idle bus First state of read cycle First state of write cycle read 2 -when stBusRead-b => stBusNext <= stBusRead c; -- output on lines... ctl-cs <= '1'; ctl-we <= '0'; ctl-oe <= '1'; ready <= '0'; busdir <= '1'; databuf <= data; when stBusReadc => -read 3 if (read = '1') then buscntrl.vhd Entity: buscntrl (main test FSM) File: buscntrl.vhd -Date: 25-Mar-03 -Abstract: bus controller... controls reading and writing -to the DI02 board. -INPUTS: (1) molk (master clock) = 50MHz -(2) (slowed clock for the DIO2 display multiplexer) -(3) stClk (slowed clock for the state Machine) -- (4) databuf (read or write data) -- (5) adrbuf (address of the device requested) -(6) read '1' to executed -(7) write '1' to execute -(8) ready '1' means it is waiting for a command ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> --- clk library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STDLOGICARITH.ALL; signal busdir signal ctl-cs signal ctlwe signal ctloe -- signal ctladr begin : STD LOGIC; -'1' read, '0' write : STDLOGIC; : STD_LOGIC; : STDLOGIC; : STDLOGICVECTOR(2 downto 0); cs <= ctlcs; we <= ctl we; oe <= ctloe; -- write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; --data <= "11110000" when busdir = '0' else "01010101"; --and databuf = "11110000" --data <= "11110000"; --adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101"; adr <= adrbuf; dclk <= clk; -clock for DI02 display multiplexer state machine to output lines process(stBusCurr, stBusNext, read, write) begin case stBusCurr is when stBusIdle => -- idle state -- read data if read = '1' then stBusNext <= stBusRead; elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= stBusIdle; end if; -- entity busecntrl is - master clock port (--mclk : in STDLOGIC; : in STD_LOGIC; -slowed clock -state machine cl stClk : in ock reset : in -- input -- data to read/write databuf : in STDLOGICVECTOR(7 downto 0); downto 0); -- device to address adrbuf : in -'1' to read data : in read -'1' to write data write : in STD_LOGIC; -'1' when done, : buffer ready or nothing is happening and it's ready for use external lines -: inout STDLOGICVECTOR(7 downto 0); data downto 0); : out adr -chip select ('1' to write : out STD_LOGIC; /read) out STDLOGIC; write enable ('1' to lato we h data) out STDLOGIC; -read enable ('l' to read data) dclk : out STDLOGIC clk STDLOGIC; STDLOGIC; STD_LOGIC_VECTOR(2 STDLOGIC; STDLOGIC; cs STD_LOGIC_VECTOR(2 -- oe ctlocs on lines... '0'; '0'; '0'; '0'; -read 1 when stBusRead => stBusNext <= stBusRead-b; output on lines... <= '1'; <= '0'; <= '0'; ready <= '0'; busdir <= '1'; -- ctlocs ctl we ctl-oe end entity; architecture behaviour of buscntrl is -- bus states for writing and reading type bstate is (stBusReset, stBusIdle, stBusRead, stBusReadb, --- Idle bus First state of read cycle -- First state of write cycle stBusWrite, stBusWrite-b, stBusWriteC); signals signal stBusCurr : bstate; signal stBusNext : bstate; when stBusRead-b => -read 2 stBusNext <= stBusRead_c; output on lines... <= '1'; <= '0'; ctloe <= 1'; ready <= '0'; busdir <= '1'; databuf <= data; -- stBusRead, -- output <= ctl we <= ctl oe <= ready <= '1'; busdir <= -- ctlocs ctlwe when stBusRead-c => -read 3 if (read = '1') then buscntrl.vhd --- -------- ---- -- Entity: busontrl (main test FSM) File: buscntrl.vhd Date: 25-Mar-03 Abstract: bus controller... controls reading and writing to the DIO2 board. INPUTS: (1) mclk (master clock) = 50MHz (2) clk (slowed clock for the DI02 display multiplexer) (3) stClk (slowed clock for the state Machine) (4) databuf (read or write data) (5) adrbuf (address of the device requested) (6) read 'l' to executed (7) write '' to execute (8) ready '' means it is waiting for a command ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> signal signal signal signal -begin busdir : STDLOGIC; -'1' read, '0' write ctl cs : STD-LOGIC; ctlwe : STDLOGIC; ctl-oe STDLOGIC; ctl-adr : STDLOGICVECTOR(2 downto 0); signal cs we <= ctlcs; <= ctl_we; oe <= ctl-oe; write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; --data <= "11110000" when busdir = '0' else "01010101"; --and databuf = "11110000" --data <= "11110000": -- adr <= "100" when adrbuf = "100" else "101" when adrbuf = "101"; -adr <= adrbuf; dclk <= clk; -clock for DI02 display multiplexer -- library IEEE; use IEEE.STDLOGIC_1164.ALL; use IEEE.STD_LOGICARITH.ALL; state machine to output lines process(stBusCurr, stBusNext, read, write) begin case is when stBusIdle => -- idle state -- read data if read = '1' then stBusNext <= stBusRead; elsif write = '1' then stBusNext <= else stBusNext <= stBusIdle; end if; -- entity buscntrl is port (--mclk : in STDLOGIC; -: in STDLOGIC; -slowed clock stClk : in STDLOGIC; ock reset : in STDLOGIC; -- input databuf : in VECTOR(7 downto 0); -- data adrbuf : in STDLOGICVECTOR(2 downto 0); read : in STD LOGIC; write : in STDLOGIC; ready : buffer STDLOGIC; ready for use or nothing is happening and it's -- external lines data : inout STDLOGICVECTOR(7 downto 0); adr : out STDLOGICVECTOR(2 downto 0); : out STDLOGIC; -/read) out STD.LOGIC; h data) out STDLOGIC; data) dclk : out STDOLOGIC clk STDLOGIC cs master clock -- to read/write -- device to address -'1' to read data -- '1' to write data -'1' when done, output on lines... <= '0'; '0'; '0'; ctlcs chip select ('1' end entity; architecture behaviour of buscntrl is bus states for writing and readir type bstate is (stBusReset, -stBusIdle, -stBusRead, stBusWrite; -- -- write enable -- read enable we stBusCurr elt. machine cI ('1' ('1' to write ctl-we <= ctl-oe <= ready <= '1'; busdir <= '0'; to latc to read -read 1 when stBusRead => stBusNext <= stBusRead-b; output on lines... ctlcs <= '1'; ctl we <= ctl-oe <= ready <= '0'; busdir <= '1'; -- -- stBusRead_b, Idle bus First state of read cycle -- stBusRead-c, stBusWrite, stBusWrite-b, stBusWritec); -signals signal : bstate; signal stBusNext : bstate; stBusCurr when stBusReadb => -read 2 stBusNext <= stBusReadc; output on lines... ctlcs <= ''; -- First state of write cycle ctlwe <= '0'; ctleoe <= '1'; ready <= '0'; busdir <= 'I'; databuf <= data; when stBusRead.C => -read 3 if (read = '1') then buscntrl.vhd STDLOGIC; STDLOGIC; -- signal busdir -'1' read, '0' write signal ctlcs : signal ctlwe STDLOGIC; signal ctloe STD_LOGIC; --signal ctl-adr : STDLOGICVECTOR(2 downto 0); begin Entity: buscntrl (main test FSM) -File: buscntrl.vhd -Date: 25-Mar-03 -- Abstract: bus controller... controls reading and writing -- to the DI02 board. -INPUTS: (1) mclk (master clock) = 50MHz -(2) clk (slowed clock for the DI02 display multiplexer) -(3) stClk (slowed clock for the state Machine) -- (4) databuf (read or write data) -(5) adrbuf (address of the device requested) -- (6) read '1' to executed -(7) write '1' to execute -(8) ready '1' means it is waiting for a command ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> STDLOGIC; STDLOGIC..VECTOR(7 STD_LOGICVECTOR(2 STDLOGIC; STDLOGICVECTOR(7 STD_LOGICVECTOR(2 STDLOGIC; es 0); ctl_cs; ctl we; oe ctl-oe; master clock -- state machine ol to read/write -device to address -'1' to read data -'1' to write data -'1' when done, chip select ('1' -- state machine to output lines process(stBusCurr, stBusNext, read, write) begin case stBusCurr is when stBusIdle => -- idle state -- read data if read = '1' then stBusNext <= stBusRead; elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= end if; stBusidle; -- output on lines... ctl cs <= '0'; ctl we <= '0'; tl-oe <= '0'; ready <= '1'; busdir <= '0'; to write write enable ('1' to lato read enable ('1' to read when stBusRead => -read 1 stBusNext <= stBusRead-b; -- -- bus states for writing and readir type bstate is (stBusReset, stBusIdle, -- stBusRead, stBusRead.b, stBusReadc, stBusWrite, stBuswrite_b, stBusWrite-c); -- Idle bus First state of read cycle -- First state of write cycle ''; when stBusRead-b => -read 2 stBusNext <= stBusReadc; -- output on lines... <= '1'; <= '0'; ctl.oe <= '1'; ready <= '0'; busdir <= 'l'; databuf <= data; ctlecs ctl-we -bstate; bstate; <= <= '0'; <= '0'; ready <= '0'; busdir <= '1'; architecture behaviour of buscntrl is : : output on lines... ctlcs ctl we ctl-oe end entity; -signals signal stBusCurr signal stBusNext <= -- write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; --data <= "11110000" when busdir = '0' else "01010101"; --and databuf = "11110000" --data <= "11110000"; --adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101"; adr <= adrbuf; dclk <= clk; -clock for DI02 display multiplexer library IEEE; use IEEE.STDLOGIC_1164.ALL; use IEEE.STD_LOGICARITH.ALL; entity busontrl is -: in STDLOGIC; port (--mclk clk : in STD_LOGIC; -slowed clock stClk : in STDLOGIC; ock reset : in -- input downto 0); -data databuf : in downto adrbuf : in : in read write : in STDLOGIC; ready : buffer STD_LOGIC; or nothing is happening and it's ready for use -external lines downto 0); : inout data downto 0); adr : out -: out /read) -we : out STDLOGIC; h data) -oe out STDLOGIC; data) dclk : out STDLOGIC ces <= we <= when stBusReadoc => -read 3 if (read = '1') then buscntrl.vhd STDLOGIC; -- Entity: buscntrl (main test FSM) -File: buscntrl.vhd -Date: 25-Mar-03 -Abstract: bus controller... controls reading and writing -- to the DI02 board. -INPUTS: (1) mclk (master clock) = 50MHz -(2) (slowed clock for the DI02 display multiplexer) -(3) stClk (slowed clock for the state Machine) -(4) databuf (read or write data) -(5) adrbuf (address of the device requested) -(6) read '1' to executed -(7) write '1' to execute -- (8) ready '1' means it is waiting for a command ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> signal busdir : -- '1' read, '0' write signal ctlcs : STD-LOGIC; signal ctl_we : STDLOGIC; signal ctloe : STDLOGIC; -- signal ctl-adr : STDLOGICVECTOR(2 downto 0); begin clk cs <= <= ctlcs; we oe <= ctl-oe; ctl_we; -- write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; -- data <= "11110000" when busdir = '0' else "01010101"; --and databuf = "11110000" --data <= "11110000"; --adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101"; adr <= adrbuf; dclk <= -clock for DI02 display multiplexer library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STDLOGICMITH.ALL; clk; state machine to output lines process(stBusCurr, stBusNext, read, write) begin case stBusCurr is stBusIdle => -- idle state -read data if read = '1' then stBusNext <= stBusRead; elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= stBusIdle; end if; -- entity buscntrl is port (--mclk : in STD_LOGIC; : in STDLOGIC; clk -- slowed clock stClk : in STDLOGIC; ock reset : in -- input databuf : in STDLOGICVECTOR(7 downto 0); -- data adrbuf : in STD_LOGICVECTOR(2 downto 0); read : in LOGIC; write : in STD_LOGIC; ready : buffer STD_LOGIC; or nothing is happening and it's ready for use -external lines data : inout STDLOGICVECTOR(7 downto 0); adr : out STD_-LOGICVECTOR(2 downto 0); cs : out STDLOGIC; /read) out STDLOGIC; we h data) out STDLOGIC; -data) dclk : out - master clock when -- state machine ol STDLOGIC; STD to read/write -- device to address -- '1' to read data -- '1' to write data -'1' when done, -- -- chip select ('1' -- write enable ('l' read enable ('1' <= '0'; <= '0'; <= '0'; ready <= '1'; busdir <= '0'; to write to latc when stBusRead => -read 1 stBusNext <= stBusRead-b; to read STDLOGIC output <= <= ctl-oe <= ready <= '0'; busdir <= on lines... '1'; '0'; '0'; -- ctlocs ctl_we end entity; architecture behaviour of buscntrl is bus states for writing and readi type bstate is (stBusReset, stBusIdle, -stBusRead, -stBusReadb, stBusReadc, output on lines... ctlocs ctl-we ctl-oe ''; -- stBusWrite, when stBusReadb => -read 2 stBusNext <= stBusReadc; Idle bus First state of read cycle output on lines... ctl-cs <= '1'; -- ctlwe First state of write cycle signals signal stBusCurr : bstate; signal stBusNext : betate; -- <= '0'; ctl0oe <= '1'; ready <= '0'; busdir <= '1'; databuf <= data; stBusWriteb, stBusWritec); -when stBusRead_c => -- if (read = '1') read 3 then buscntrl.vhd ctlcs clk STDLOGIC; STDLOGIC; STDLOGICVECTOR(7 STDLOGIC; STDLOGIC; oe STDLOGIC; cs bus states for writing and readi type bstate is (stBusReset, -stBusIdle, -stBusRead, stBusReadb, stBusRead_c, -stBusWrite, stBusWrite b, st3usWritee); <= state machine el to read/write -- device to address -- '1' to read data -'1' to write data -- '1' when done, ctl cs; -state machine to output lines process(stBusCurr, stBusNext, read, write) begin case stBusCurr is when stBusIdle => -- idle state -- read data if read = '1' then stBusNext <= stBusRead; elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= stBusIdle; end if; on lines... '0'; '0'; <= '0'; ready <= '1'; busdir <= '0'; -- output ctlocs ctl we ctleoe chip select ('I' to write -- write enable --read enable <= <= ('1' to late ('1' to read when stBusRead => -read 1 stBusNext <= stBusReadb; output <= <= <= ready <= '0'; busdir <= -- etlocs ctlwe ctloe on lines... '1'; '0'; '0'; '1'; -- signals signal stBusCurr signal stBusNext -- : bstate; : bstate; Idle bus First state of read cycle when stBusRead-b => -read 2 stBusNext <= stBusRead_c; output on lines... cs <= '1'; we <= '0'; <= '1'; ctloe ready <= '0'; busdir <= '1'; databuf <= data; -- First state of write cycle downto 0); -- write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; --data <= "11110000" when busdir = '0' else "01010101": --and databuf = "11110000" -- data <= "11110000"; --adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101"; adr <= adrbuf; dclk <= clk; -clock for DI02 display multiplexer -- architecture behaviour of buscntrl is '1' read, '0' write we <= ctl,we; oe <= ctloe; master clock end entity; -- STD.LOGICVECTOR(2 library IEEE; use IEEE.STDLOGIC_1164.ALL; use IEEE.STDLOGICARITH.ALL; entity buscntrl is -port (--mclk : in STD_LOGIC; : in -- slowed clock stClk : in ock reset : in STD LOGIC; -- input -data downto 0); databuf : in adrbuf : in STD_LOGICVECTOR(2 downto 0); read : in : in STD_LOGIC; write ready : buffer ready for use or nothing is happening and it's -- external lines : inout STDLOGICVECTOR(7 downto 0); data : out STDLOGICVECTOR(2 downto 0); adr -cs : out STDLOGIC; /read) out STD_LOGIC; we h data) out data) dclk : out STDLOGIC STD_LOGIC; signal busdir : signal STDLOGIC; signal ctl_we : STDLOGIC; signal ctl_oe : STD_LOGIC; -- signal ctl-adr : begin Entity: buscntrl (main test FSM) -- File: buscntrl.vhd -- Date: 25-Mar-03 -- Abstract: bus controller... controls reading and writing -- to the DI02 board. -INPUTS: (1) molk (master clock) = 50MHz -(2) clk (slowed clock for the DI02 display multiplexer) -(3) stClk (slowed clock for the state Machine) -(4) databuf (read or write data) -(5) adrbuf (address of the device requested) -(6) read '1' to executed -(7) write '1' to execute (8) ready '1' means it is waiting for a command -->>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -- ctl ctl when stBusReadc => -read 3 if (read = '1') then buscntrl.vhd Entity: buscntrl (main test FSM) File: buscntrl.vhd Date: 25-Mar-03 Abstract: bus controller... controls reading and writing -to the D102 board. -INPUTS: (1) mclk (master clock) = 50MHz -(2) clk (slowed clock for the DI02 display multiplexer) -(3) stClk (slowed clock for the state Machine) -(4) databuf (read or write data) -(5) adrbuf (address of the device requested) -(6) read '1' to executed -(7) write 'P' to execute -- (8) ready '1' means it is waiting for a command ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> signal busdir : STD-LOGIC; -'1' read, '0' write signal ctl_cs : STDLOGIC; signal ctl_we : STDLOGIC; signal ctl_oe : STDLOGIC; -- signal ctl-adr : STDLOGIC_VECTOR(2 downto 0); begin ----- cs <= ctlocs; we <= ctl we; oe <= ctl-oe; -- write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; --data <= "11110000" when busdir = '0' else "01010101": --and databuf = "11110000" --data <= "11110000"; --adr <= "100" when adrbuf = "100" else "101" when adrbuf = "101": adr <= adrbuf; dclk <= -clock for DI02 display multiplexer library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGICARITH.ALL; clk; state machine to output lines process(stBusCurr, stBusNext, read, write) begin case stBusCurr is when => -idle state -- read data if read = '1' then stBusNext <= stBusRead; elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= stBusIdle; end if; -- entity busontrl port (--mclk clk -- is : in STD._LOGIC; : in STD_LOGIC; slowed stClk : in STDLOGIC; -- master clock clock -- state machine cl ock reset -- : in STD_LOGIC; input databuf : in STDLOGICVECTOR(7 downto 0); -- data adrbuf : in STD_.LOGIC_.VECTOR(2 downto 0); read : in STD_LOGIC; write : in STDLOGIC; ready : buffer STDLOGIC; or nothing is happening and it's ready for use -external lines data : inout STDLOGICVECTOR(7 downto 0); adr : out STDLOGICVECTOR(2 downto 0); cs : out STDLOGIC; -/read) out STDLOGIC; h data) out STD._LOGIC; -data) : out STDLOGIC dclk to read/write -device to address -'1' to read data -- '1' to write data -'1' when done, output on lines... ctl-cs <= '0'; ctlwe <= '0'; -- ctl-oe chip select ('1' -- write we stBusIdle enable ('1' read enable ('1' to write to latc 1 output on lines... ctl-cs <= '1'; ctl we <= '0'; ctl-oe <= '0'; ready <= '0'; busdir <= '1'; -- architecture behaviour of buscntrl stBusWrite, -- when stBusRead-b => -read 2 stBusNext <= stBusRead-c; Idle bus First state of read cycle output on lines... ctl cs <= '1'; ctl we <= '0'; <= 'l'; ready <= '0'; busdir <= '1'; databuf <= data; -- First state of write cycle ctl-oe stBusWriteb, stBusWritec); signals signal stBusCurr : bstate; signal stBusNext : betate; -- '0'; when stBusRead => -read stBusNext <= stBusRead-b; to read end entity; -bus states for writing and readii type bstate is (stBusReset, stBusIdle, -stBusRead, -stBusReadb, stBusReadc, <= ready <= '1'; busdir <= '0'; -when stBusReadc => -read 3 if (read = '1') then buscntrl.vhd ---- ------ --- ---- signal busdir : STDLOGIC; -'1' read, '0' write signal ctl_cs : STDLOGIC; signal ctlywe : STDLOGIC; signal ctloe : STDLOGIC; --signal ctladr : STDLOGICVECTOR(2 downto 0); begin Entity: buscntrl (main test FSM) File: buscntrl.vhd Date: 25-Mar-03 Abstract: bus controller... controls reading and writing to the DI02 board. INPUTS: (1) molk (master clock) = 50MHz (2) (slowed clock for the DIO2 display multiplexer) (3) stClk (slowed clock for the state Machine) (4) databuf (read or write data) (5) adrbuf (address of the device requested) (6) read '1' to executed (7) write '' to execute (8) ready '1' means it is waiting for a command ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clk cs <= ctl_cs; we <= <= ctlwe; ctl_oe; oe -- write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; --data <= "11110000" when busdir = '0' else "01010101"; --and databuf = "11110000" --data <= "11110000"; --adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101"; adr <= adrbuf; dclk <= -clock for DIO2 display multiplexer ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> library IEEE; use IEEE.STDLOGIC_1164.ALL; use IEEE.STDLOGICARITH.ALL; clk; entity buscntrl is -: in STDLOGIC; port (--mclk : in STDLOGIC; -slowed clock stClk : in STD_LOGIC; ock reset : in STD_LOGIC; -- input -data databuf : in STDLOGIC3VECTOR(7 downto 0); : in STDLOGICVECTOR(2 downto 0); read : in STDLOGIC; : in STD_LOGIC; write ready : buffer STDJLOGIC; or nothing is happening and it's ready for use -external lines : inout STDLOGICVECTOR(7 downto 0); data adr : out STDLOGICVECTOR(2 downto 0); -cs : out STDLOGIC; /read) out STD_LOGIC; we h data) out STDLOGIC; data) dclk : out STD LOGIC clk adrbuf master clock -- -- state machine to output lines process(stBusCurr, stBusNext, read, write) begin case is when stBusIdle => -- idle -read data if read = '1' then stBusNext <= stBusRead; elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= stBusIdle; end if; stBusCurr state machine ci to read/write -- device to address -- '1' to read data -'1' to write data -- '1' when done, state output <= <= <= ready <= '1'; busdir <= -- ctlcs ctlwe ctl oe chip select ('1' -- write enable -- read enable ('l' to write to latc when ('1' to read on lines... '0'; '0'; '0'; '0'; stBusRead => -read 1 stBusNext <= stBusRead-b; output on lines... <= '1'; <= '0'; ctloe <= '0'; ready <= '0'; busdir <= '1'; -- ctlocs ctlwe end entity; architecture behaviour of buscntrl is -- bus states for writing and readir type bstate is (stBusReset, stBusIdle, stBusRead, --- Idle bus First state of read cycle -- First state of write cycle stBusReadb, when stBusRead-b => -read 2 stBusNext <= stBusReadc; stBusWrite, stBusWriteb, stBusWrite-c); -signals signal stBusCurr signal stBusNext -: bstate; : bstate; output on lines... ctl-cs <= '1'; ctl we <= '0'; ctloe <= '1'; ready <= '0'; busdir <= '1'; databuf <= data; -- stBusRead.c, when stBusReadoc => -read 3 if (read = '1') then buscntrl.vhd ---- ------- ----- -'1' read, '0' write signal busdir : STDLOGIC; signal ctl_cs : STD_LOGIC; signal ctl-we : STDLOGIC; signal ctl-oe : STDLOGIC; -- signal ctl-adr : STDLOGICVECTOR(2 downto 0); begin Entity: buscntrl (main test FSM) File: buscntrl.vhd Date: 25-Mar-03 Abstract: bus controller... controls reading and writing to the DI02 board. INPUTS: (1) (master clock) = 50MHz (2) (slowed clock for the DI02 display multiplexer) (3) stClk (slowed clock for the state Machine) (4) databuf (read or write data) (5) adrbuf (address of the device requested) (6) read '1' to executed (7) write '1' to execute (8) ready '1' means it is waiting for a command >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clk mclk cs 0) STDLOGIC; oe ctlcs; ctlwe; oe ctl_oe; master clock -- state machine cl to read/write device to address --'1' to read data -'1' to write data -- '1' when done, -- state machine to output lines process(stBusCurr, stBusNext, read, write) begin case stBusCurr is when stBusIdle => -- idle state -- read data if read = '1' then stBusNext <= stBusRead; elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= end if; stBusIdle; output ctlcs <= ctl we <= ctloe <= ready <= '1'; busdir <= -- chip select ('1' write enable ('1' to write to latc when read enable ('1' to read signals signal stBusCurr signal stBusNext '0'; 1 read stBusNext <= stBusRead-b; => -- when stBusReadb => -read 2 stBusNext <= stBusReadc; Idle bus First state of read cycle output on lines... <= ''; ctlwe <= '0'; ctl-oe <= '1'; ready <= '0'; busdir <= '1'; databuf <= data; -- ctIbcs -- First state of write cycle -: bstate; : bstate; '0'; '0'; output on lines... <= '1'; ctl-we <= '0'; ctl-oe <= '0'; ready <= '0'; busdir <= '1'; stBusRead-.b, -- '0'; ctl-cs architecture behaviour of buscntrl is stBusRead.c, stBusWrite, stBusWrite_b, stBusWrite_c); stBusRead on lines... -- end entity; -- bus states for writing and readii type bstate is (stBusReset, -stBusIdle, etBusRead, -- <= -- write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; --data <= "11110000" when busdir = '0' else "01010101"; --and databuf = "11110000" --data <= "11110000"; -- adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101"; adr <= adrbuf; dclk <= clk; -clock for DI02 display multiplexer library IEEE; use IEEE.STDLOGIC_1164.ALL; use IEEE.STDLOGIC_ARITH.ALL; entity buscntrl is port (--mclk : in STD._LOGIC; -elk : in STD_LOGIC; -slowed clock stClk : in STD_LOGIC; ock reset : in STDLOGIC; -- input databuf : in STDLOGICVECTOR(7 downto 0); -d ata adrbuf : in STD._LOGICVECTOR(2 downto read : in STDLOGIC; write : in STD_LOGIC; ready : buffer STD_LOGIC; or nothing is happening and it's ready for use -external lines data : inout STDLOGICVECTOR(7 downto 0); adr : out STDLOGICVECTOR(2 downto 0); -cs : out STD_LOGIC; /read) -out h data) out STDLOGIC; -data) dclk : out STDLOGIC <= we <= when stBusReadc => -read 3 if (read = '1') then buscntrl.vhd ---- ----- ------ -- Entity: buscntrl (main test FSM) File: buscntrl.vhd Date: 25-Mar-03 Abstract: bus controller... controls reading and writing to the DI02 board. INPUTS: (1) mclk (master clock) = (2) (slowed clock for the DI02 display multiplexer) (3) stClk (slowed clock for the state Machine) (4) databuf (read or write data) (5) adrbuf (address of the device requested) (6) read '1' to executed (7) write '1' to execute (8) ready '1' means it is waiting for a command ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> signal busdir : STDLOGIC; -- '1' read, '0' signal ctlcs : signal ctlwe : STD-LOGIC; signal ctloe : STDLOGIC; -- signal ctl-adr : STD LOGICVECTOR(2 downto 0); begin STDLOGIC; 50MHz clk cs <= ctlcs; we <= ctl_we; oe <= ctl-oe; -- write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; --data <= "11110000" when busdir = '0' else "01010101"; --and databuf = "11110000" -- data <= "11110000"; -- adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101"; adr <= adrbuf; dclk <= elk; -clock for DI02 display multiplexer library IEEE; use IEEE.STDLOGIC_1164.ALL; use IEEE.STDLOGICARITH.ALL; state machine to output lines process(stBusCurr, stBusNext, read, write) begin case stBusCurr is when stBusIdle => -- idle state -- read data if read = '1' then stBusNext <= stBusRead; elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= stBusIdle; end if; -- entity buscntrl is -: in port (--mclk elk : in STDLOGIC; -slowed stClk : in ock reset : in -- input downto 0); -data databuf : in downto 0); adrbuf : in read : in STDLOGIC; write : in STD LOGIC; ready : buffer ready for use or nothing is happening and it's -- external lines : inout STD_LOGIC_VECTOR(7 downto 0); data adr : out STDLOGIC_.VECTOR(2 downto 0); cs : out STDLOGIC; -/read) out STDLOGIC; h data) out STDLOGIC; data) dclk : out STDLOGIC STDLOGIC; clock STDLOGIC; STD.LOGIC; STD_LOGICVECTOR(7 STDLOGICVECTOR(2 STD_LOGIC; master clock -- state machine cl to read/write -- device to address -- '1' to read data -- '1' to write data -- '1' when done, output on lines... ctl-cs <= '0'; ctlwe <= '0'; ctl-oe <= '0'; ready <= '1'; busdir <= '0'; -- chip select ('I' -- write enable -- read enable we to write ('1' to late ('1' to read when stBusRead => -read 1 stBusNext <= stBusReadb; output on lines... <= '1'; <= '0'; otloe <= '0'; ready <= '0'; busdir <= '1'; -- ctlocs ctlwe end entity; architecture behaviour of buscntrl is -- bus states for writing and readir type bstate is (stBusReset, stBusIdle, stBusRead, stBusReadb, --- Idle bus First state of read cycle -- First state of write cycle when stBusReadb => -read 2 stBusNext <= stBusRead-c; -- -signals signal stBusCurr : bstate; signal stBusNext : bstate; output on lines... ctlocs stBusRead-c, stBusWrite, stBusWriteb, stBusWritec); write ctlwe -- <= <= '1'; '0'; ctl-oe <= '1'; ready <= '0'; busdir <= '1'; databuf <= data; when stBusRead-c => -read 3 if (read = '1') then buscntr.vhd Entity: buscntrl (main test FSM) File: buscntrl.vhd -Date: 25-Mar-03 -- Abstract: bus controller... controls reading and writing -to the DIO2 board. -INPUTS: (1) mclk (master clock) = 50MHz -(2) (slowed clock for the DI02 display multiplexer) -(3) stClk (slowed clock for the state Machine) -- (4) databuf (read or write data) -(5) adrbuf (address of the device requested) -- (6) read '1' to executed -(7) write 'l' to execute -(8) ready '1' means it is waiting for a command ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> --- signal busdir signal ctl-cs signal ctlwe signal ctloe : -- signal ctladr begin clk cs we oe <= <= <= STD_LOGIC; -'1' read, '0' write STD-LOGIC; STDLOGIC; STDLOGIC; : STD._LOGIC_VECTOR(2 downto 0); ctl_cs; ctlwe; ctloe; -- write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; --data <= "11110000" when busdir = '0' else "01010101"; --and databuf = "11110000" -- data <= "11110000"; --adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101"; adr <= adrbuf; dclk <= -clock for DI02 display multiplexer library IEEE; use IEEE.STD._LOGICll64.ALL; use IEEE.STDLOGICARITH.ALL; clk; state machine to output lines process(stBusCurr, stBusNext, read, write) begin case stBusCurr is when stBusIdle => -- idle state -- read data if read = '1' then <= stBusRead; elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= stBusIdle; end if; -- entity buscntrl port (--mclk is : in STD_LOGIC; : in STDLOGIC; slowed clock stClk : in STD-LOGIC; -- master clock clk -- -- state machine cl ock reset -- stBusNext : in STD LOGIC; input databuf : in STDLOGIC.VECTOR(7 downto 0); -- data adrbuf : in STDLOGICVECTOR(2 downto 0); read : in STDLOGIC; write : in STDLOGIC; ready : buffer STD_.LOGIC; or nothing is happening and it's ready for use -- external lines data : inout STDLOGICVECTOR(7 downto 0); adr : out STDLOGICVECTOR(2 downto 0); -: out STD_LOGIC; /read) : out STDLOGIC; h data) oe : out STD_LOGIC; -data) dclk : out STDLOGIC cs we to read/write -device to address -- '1' to read data -- '1' to write data -- '1' when done, -- output on lines... <= '0'; <= '0'; ctl-oe <= '0'; ready <= '1'; busdir <= '0'; ctlocs ctl-we chip select ('1' -- write enable read enable to write ('1' to latc ('1' to read when stBusRead => -read I stBusNext <= stBusRead-b; output on lines... ctlcs <= '1'; ctl we <= '0'; ctl-oe <= '0'; ready <= '0'; busdir <= '1'; -- end entity; architecture behaviour of buscntrl is -bus states for writing and readii type bstate is (stBusReset, stBusIdle, stBusRead, --- Idle bus First state of read cycle -- First state of write cycle when stBusRead-b => -read 2 stBusNext <= stBusReadc; stBusReadb, stBusReadc, stBusWrite, stBusWriteb, stBusWritec); -signals signal stBusCurr : bstate; signal stBusNext : bstate; output on lines... ctlcs <= '1'; ctlwe <= '0'; ctloe <= '1'; ready <= '0'; busdir <= '1'; databuf <= data; -- -- c => -(read = '1') when stBusRead if read 3 then buscntrl.vhd -- signal busdir : STD_LOGIC; signal ctlcs : STD_LOGIC; signal ctlwe : STDLOGIC; signal ctl_oe : STD_LOGIC; --signal ctl-adr : begin Entity: buscntrl (main test FSM) File: buscntrl.vhd -Date: 25-Mar-03 -- Abstract: bus controller... controls reading and writing -- to the DI02 board. -INPUTS: (1) mclk (master clock) = 50MHz (slowed clock for the DI02 display multiplexer) -(2) (3) stClk (slowed clock for the state Machine) -(4) databuf (read or write data) -(5) adrbuf (address of the device requested) --- (6) read '1' to executed -- (7) write '1' to execute -- (8) ready '1' means it is waiting for a command ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> --- '1' read, STDLOGICVECTOR(2 clk cs we oe ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> library IEEE; use IEEE.STDLOGIC-1164.ALL; use IEEE.STDLOGIC_ARITH.ALL; <= ctl_cs; <= ctl we; <= ctl-oe; clk; state machine to output lines process(stBusCurr, stBusNext, read, write) begin case stBusCurr is when stBusIdle => -- idle state -read data if read = '1' then stBusNext <= stBusRead; elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= stBusIdle; end if; -- elk cs : master clock -- state machine cl to read/write -- device to address -'1' to read data -'1' to write data -- '1' when done, output on lines... ctlcs <= '0'; -- ctl-we chip select ('1' write enable ('1' to latc read enable to read ('1' <= when stBusRead => -read 1 stousNext <= stBusRead-b; -- output on lines... ctlocs end entity; ctloe <= 0''; '0'; -- output on lines... <= '1'; <= '0'; ctl-oe <= '1'; ready <= '0'; busdir <= '1'; databuf <= data; ctlocs ctlwe First state of write cycle stBusWriteb, stBusWrite-c); -- signals signal stBusCurr : bstate; signal stBusNext : bstate; '1'; when stBusRead-b => -read 2 stBusNext <= stBusReadc; Idle bus First state of read cycle stBusReadc, -- <= ready <= '0'; busdir <= '1'; architecture behaviour of buscntrl is -- bus states for writing and readir type bstate is (stBusReset, -stBusIdle, -stBusRead, stBusReadb, '0'; ctl-oe <= '0'; ready <= '1'; busdir <= '0'; to write ctl-we <= stBusWrite, downto 0); -- write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; "11110000" when busdir = '0' else '01010101": --data <= --and databuf = "11110000" --data <= "11110000"; --adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101"; adr <= adrbuf; dclk <= -clock for DI02 display multiplexer ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> entity buscntrl is -: in STDLOGIC; port (--mclk : in STDLOGIC; -slowed clock stClk : in STDLOGIC; ock reset : in STDLOGIC; -- input -data in STD_LOGICVECTOR(7 downto 0); databuf adrbuf : in STDLOGICVECTOR(2 downto 0); : in STD_LOGIC; read write : in STD_LOGIC; ready : buffer STDLOGIC; ready for use or nothing is happ ening and it's -- external lines inout STDLOGICVECTOR(7 downto 0); data out STD LOGICVECTOR(2 downto 0); adr out STDLOGIC; -/read) out STDLOGIC; we h data) out STDLOGIC; data) dclk : out STDLOGIC '0' write -- read 3 when stBusReadc => -if (read = '1') then buscntrl.vhd ---- ---- Entity: buscntrl (main test FSM) File: buscntrl.vhd Date: 25-Mar-03 Abstract: bus controller... controls reading and writing to the DIO2 board. INPUTS: (1) mclk (master clock) = 50MHz (2) (slowed clock for the DI02 display multiplexer) (3) stClk (slowed clock for the state Machine) (4) databuf (read or write data) (5) adrbuf (address of the device requested) (6) read '1' to executed (7) write '1' to execute (8) ready '1' means it is waiting for a command ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> signal busdir STD-LOGIC; -'1' read, '0' write signal ctl cs : STD-LOGIC; signal ctl_we : STDLOGIC; signal ctloe : STDjLOGIC; -- signal ctl-adr : STDLOGICVECTOR(2 downto 0); begin clk --- --- --- -- cs <= ctlcs; we <= ctl we; oe <= ctl-oe; -- write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; --data <= "11110000" when busdir = '0' else "01010101" --and databuf = "11110000" --data <= "11110000"; --adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101"; adr <= adrbuf; dclk <= -clock for DI02 display multiplexer ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STDLOGIC ARITH.ALL; clk; state machine to output lines process(stBusCurr, stBusNext, read, write) begin case stBusCurr is when => -idle state -- read data if read = '1' then stBusNext <= elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= stBusIdle; end if; -- entity buscntrl is port (--mclk : in STD.LOGIC; -master clock : in LOGIC; -slowed clock stClk : in STD LOGIC: -state machine cl ock reset : in STDLOGIC; -- input databuf : in downto 0); -- data to read/write adrbuf : in -device to address downto 0); read : in STD_LOGIC; -'1' to read data write : in STD_LOGIC; -'1' to write data ready : buffer STDLOGIC; -'1' when done, or nothing is happening and it's ready for use -- external lines data : inout STDLOGIC_VECTOR(7 downto adr : out STDLOGICVECTOR(2 downto cs : out STDLOGIC; -chip select ('1' to write STD clk STD_LOGICVECTOR(7 STDLOGICVECTOR(2 0); /read) out STDLOGIC; stBusIdle stBusRead; -- -- write enable data) dclk : out -- read enable ('1' to latc ('1' to read '0'; when stBusRead => -read 1 stBusNext <= stBusRead-b; STD_LOGIC -output ctlcs <= otlewe <= ctl-oe <= ready <= '0'; busdir <= end entity; architecture behaviour of buscntrl is bus states for writing and readi type bstate is (stBusReset, -stBusIdle, stBusRead, -stBusRead~b, stBusReadc, stBusWrite, -stBusWritb, stBusWritec); <= <= '0'; <= '0'; ready <= '1'; busdir <= '0'; h data) we out STDLOGIC; output on lines... ctl cs ctlewe ctl-oe 0); on lines... '1'; '0'; '0'; '1'; -- -signals signal stBusCurr : betate; signal stBusNext : bstate; when stBusRead-b => -read 2 stBusNext <= stBusRead-c; Idle bus First state of read cycle -- output on lines... <= '1'; <= '0'; ctlocs ctl we ctl-oe First state of write cycle -- <= 'l'; ready <= '0'; busdir <= ''; databuf <= data; when stBusReadc => -read 3 if (read = '1') then buscntrl.vhd signal busdir STDLOGIC; -'1' read, '0' signal ctlcs: STDLOGIC; signal ctlwe STDLOGIC; signal ctlhoe STDLOGIC; -- signal ctl-adr : STDLOGIC_VECTOR(2 downto 0); begin Entity: buscntrl (main test FSM) -File: buscntrl.vhd -Date: 25-Mar-03 -- Abstract: bus controller... controls reading and writing -to the DI02 board. -INPUTS: (1) mclk (master clock) = 50MHz (slowed clock for the DI02 display multiplexer) -(2) -(3) stClk (slowed clock for the state Machine) -- (4) databuf (read or write data) (5) adrbuf (address of the device requested) --(6) read '1' to executed -- (7) write '1' to execute -- (8) ready '1' means it is waiting for a command -- >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -- clk cs <= ctl_cs; we <= <= ctlwe; ctloe; oe -write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; --data <= "11110000" when busdir = '0' else "01010101"; --and databuf = "11110000" --data <= "11110000"; --adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101"; adr <= adrbuf; -clock for DI02 display multiplexer dclk <= clk; library IEEE; use IEEE.STDLOGIC_1164.ALL; use IEEE.STDLOGIC_ARITH.ALL; state machine to output lines process(stBusCurr, stBusNext, read, write) begin case 5tBusCurr is when stBusIdle => -- idle state -- read data if read = '1' then stBusNext <= stBusRead; elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= stBusIdle; end if; -- entity buscntrl is -: in STDLOGIC; port (--mclk ; in STD_LOGIC; -slowed clock stClk : in ock reset : in STDLOGIC; -- input -data databuf : in STD LOGICVECTOR(7 downto 0); LOGICVECTOR(2 downto 0); in adrbuf read in STD-LOGIC; in write buffer STDOLOGIC; ready or nothing is happening and it's ready for use -- external lines : inout STDLOGICVECTOR(7 downto 0); data :out STDLOGICVECTOR(2 downto 0); adr -: out STD_LOGIC; cs /read) -we out STD_LOGIC; h data) -out STD_LOGIC; data) : out STD_LOGIC dclk master clock clk STDLOGIC; STD STD_LOGIC; -- state machine cl to read/write -device to address '' to read data --'1' to write data -'1' when done, -- output on lines... <= '0'; <= '0'; ctlocs ctl_we ctl oe chip select ('1' write enable ('1' to latc read enable to read ('1' <= '0'; ready <= '1'; busdir <= '0'; to write when stBusRead => -read 1 stBusNext <= stBusRead-b; output on lines... otlcs <= 1'; ctlwe <= '0'; ctl-oe <= '0'; ready <= 'g'; busdir <= '1'; -- end entity; architecture behaviour of buscntrl is bus states for writing and readir type bstate is (stBusReset, -stBusIdle, -stBusReadb, stBusRead c, -stBusWrite, stBusWriteb, stBusWritec); -- stBusRead, signals signal stBusCurr signal stBusNext when stBusRead b => stBusNext <= Idle bus First state of read cycle : : bstate; bstate; -- read 2 stBusReadc; output on lines... <= 'I'; ctlwe <= '0'; ctl-oe <= '1'; ready <= '0'; busdir <= databuf <= data; -- ctl-cs First state of write cycle 1'; -- -- write when stBusRead-c => -read 3 if (read = '1') then buscntrlvhd Entity: buscntrl (main test FSM) -File: buscntrl.vhd -Date: 25-Mar-03 -- Abstract: bus controller... controls reading and writing -to the DI02 board. -INPUTS: (1) mclk (master clock) = 50MHz -- (2) (slowed clock for the DI02 display multiplexer) -(3) (slowed clock for the state Machine) -- (4) databuf (read or write data) -(5) adrbuf (address of the device requested) -(6) read '1' to executed -(7) write '1' to execute -(8) ready '1' means it is waiting for a command ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -- signal busdir signal ctl_cs signal ctlwe signal --signal begin : STD-LOGIC; -'1' read, '0' write : STDLOGIC; : STD-LOGIC; : STDLOGIC; ; STDLOGIC_VECTOR(2 downto 0); ctloe ctl-adr clk stClk cs <= ctl cs; we <= ctlwe; oe <= ctloe; write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; --data <= "11110000" when busdir = 'I' else "01010101"; --and databuf = "11110000" -- data <= "11110000"; --adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101"; adr <= adrbuf; dclk <= -clock for DI02 display multiplexer -- library IEEE; use IEEE.STDLOGIC_1164.ALL; use IEEE.STD._LOGICARITH.ALL; clk; state machine to output lines process(stBusCurr, stBusNext, read, write) begin case stBusCurr is when stBusIdle => -idle state -- read data if read = '1' then stBusNext <= elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= stBusIdle; end if; -- entity buscntrl is port (--mclk : in STDLOGIC; - master clock : in LOGIC; -slowed clock stClk : in -state machine ock reset : in STDLOGIC; -- input databuf : in downto 0); -data to read/write adrbuf : in STDLOGICVECTOR(2 downto 0); -device to address read : in STD_LOGIC; -'l to read data write : in -'1' to write data ready : buffer -'1' when done, or nothing is happening and it's ready for use -- external lines data : inout downto 0); adr : out STD.LOGICVECTOR(2 downto 0); cs out STDLOGIC; -chip select ('1' to write /read) out write enable ('1' to latc h data) out read enable ('1' to read data) dclk : out STDLOGIC clk STD cl STDLOGIC; STDLOGICVECTOR(7 STDLOGIC; STDLOGIC; stBusRead; output <= ctl-we <= ctl-oe <= ready <= '1'; busdir <= -- ctl cs STDLOGIC.VECTOR(7 --- STDLOGIC; oe STDLOGIC; on lines... '0'; '0'; 'I'; '0'; when stBusRead => -read I stBusNext <= stBusReadb; output on lines... ctl.cs <= 'l'; <= '0'; ctleoe <= '0'; ready <= '0'; busdir <= '1'; -- ctl-we end entity; architecture behaviour of busentrl is bus states for writing and readii type bstate is (stBusReset, stBusIdle, --- stBusRead, -- Idle bus First state of read cycle -- First state of write cycle when stBusRead_b => -read 2 stBusNext <= stBusReadc; stBusRead_b, stBusReadc, stBusWrite, -- stBusWriteb, stBusWritec); signals signal : bstate; signal stBusNext : bstate; -- stBusCurr on output lines... <= '1'; ctl-cs -- ctlwe <= '0'; ctl_oe <= '1'; ready <= '0'; busdir <= '1'; databuf <= data; when stBusRead_c => -read 3 if (read = '1') then buscntrl.vhd ---- ------ ------ signal busdir : STD_LOGIC; -'1' read, '0' write signal ctlcs : STDLOGIC; signal ctlwe : STDLOGIC; signal ctl-oe : STDLOGIC; -- signal ctl-adr : STDLOGIC_VECTOR(2 downto 0); begin Entity: busontrl (main test FSM) File: buscntrl.vhd Date: 25-Mar-03 Abstract: bus controller... controls reading and writing to the DI02 board. INPUTS: (1) mclk (master clock) = 50MHz (2) (slowed clock for the DI02 display multiplexer) (3) stClk (slowed clock for the state Machine) (4) databuf (read or write data) (5) adrbuf (address of the device requested) (6) read '1' to executed (7) write 'V' to execute (8) ready '' means it is waiting for a command ->>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clk cs we oe clk -- ock is : in STDLOGIC; : in STDLOGIC; slowed stClk : in STD_LOGIC; STDLOGIC; STDLOGICVECTOR(7 downto input master clock -- state machine ol : in data 0); -databuf : in : in STDLOGICVECTOR(2 downto 0); adrbuf : in STD_LOGIC; read write : in ready : buffer STDLOGIC; or nothing is happening and it's ready for use -- external lines LOGICYVECTOR(7 downto 0); data : inout : out STD_LOGICVECTOR(2 downto 0); adr -: out STDLOGIC; /read) -out h data) -out LOGIC; data) dclk : out STD_LOGIC STD_LOGIC; to read/write -device to address -'1' to read data '1' to write data --'1' when done, -- state machine to output lines process(stBusCurr, stBusNext, read, write) begin case st~usCurr is when stBusIdle => -- idle state -read data if read = '1' then stBusNext <= stBusRead; elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= stBusIdle; end if; output on lines... <= '0'; ctl we <= '0'; -- ctlocs STD cs STD_LOGIC; oe STD ctl-oe write enable ('1' read enable <= ready <= '1'; busdir <= chip select (' 1' to write '0'; '0'; to latc when stBusRead => -read 1 stBusNext <= stBusRead-b; ('1' to read -- output on lines... <= '1'; <= '0'; <= '0'; ready <= '0'; busdir <= '1'; ctlocs otl_we ctl-oe end entity; architecture behaviour of buscntrl is bus states for writing and readir type bstate is (stBusReset, stBusIdle, --stBusRead, stBusReadb, stBusReadc, -stBusWrite, stBusWriteb, stBusWritec); ctl oe; write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; -- data <= "11110000" when busdir = '0' else "01010101": --and databuf = "11110000" -- data <= "11110000"; -- adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101"; adr <= adrbuf; dclk <= clk; -clock for DIO2 display multiplexer clock reset -- -- ctlocs; ctl-we; -- library IEEE; use IEEE.STDLOGICl164.ALL; use IEEE.STDLOGICARITH.ALL; entity buscntrl port (--mclk <= <= <= -- signals signal stBusCurr : bstate; signal stBusNext : bstate; -- when stBusRead-b => -read 2 stBusNext <= stBusReadtc; Idle bus First state of read cycle -- output on lines... ctlcs ctl-we First state of write cycle <= <= '1'; '0'; ctl-oe -- <= '1'; ready <= '0'; busdir <= '1'; databuf <= data; when stBusRead-c => -read 3 if (read = '1') then buscntrl.vhd Entity: buscntrl (main test FSM) -File: buscntrl.vhd -- Date: 25-Mar-03 -- Abstract: bus controller... controls reading and writing -- to the DI02 board. -INPUTS: (1) mclk (master clock) = 50MHz -(2) (slowed clock for the DI02 display multiplexer) -(3) stClk (slowed clock for the state Machine) -(4) databuf (read or write data) -- (5) adrbuf (address of the device requested) -(6) read '1' to executed -- (7) write '1' to execute -(8) ready '1' means it is waiting for a command ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -- signal busdir signal ctl-cs signal ctl_we signal --signal begin : STDLOGIC; -- '1' read, '0' write : : STDLOGIC; : STDLOGIC; : STDILOGICVECTOR(2 downto 0); STDLOGIC; ctloe ctl-adr clk cs <= ctlocs; we <= ctl_we; oe <= ctloe; -- write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; --data <= "11110000" when busdir = '0' else "01010101"; --and databuf = "11110000" --data <= "11110000"; --adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101"; adr <= adrbuf; dclk <= -clock for DI02 display multiplexer library IEEE; use IEEE.STDLOGIC-1164.ALL; use IEEE.STDLOGICARITH.ALL; clk; state machine to output lines process(stBusCurr, stBusNext, read, write) begin case stBusCurr is when stBusIdle => -idle state -read data if read = '1' then stBusNext <= stBusRead; elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= stBusIdle; end if; -- entity busontrl is port (--mclk : in STD_LOGIC; -clk : in STDLOGIC; -slowed clock stClk : in STDLOGIC; ock reset : in STD_LOGIC; -- input databuf : in STD_LOGIC_VECTOR(7 downto 0); -data adrbuf : in STDLOGICVECTOR(2 downto 0); read : in STDLOGIC; write : in STDLOGIC; ready : buffer STD_LOGIC; or nothing is happening and it's ready for use -external lines data : inout STDLOGIC VECTOR(7 downto 0); adr : out STD LOGICVECTOR(2 downto 0); out STDLOGIC; -/read) out STD_LOGIC; we -h data) out STDLOGIC; -data) dclk : out STDLOGIC cs oe master clock -- state machine cl to read/write device t o address -'1' to r data -'1' to w rite data -- '1' when done, ead output on lines... <= '0'; <= '0'; <= '0'; ready <= 'l'; busdir <= '0'; -- ctlocs ctl-we ctl oe chip select '1' to write write enable ('1' to lato read enable ('1' to read when stBusRead => -read 1 stBusNext <= stBusReadb; -- <= <= ctl-oe ready <= '0'; busdir <= architecture behaviour of buscntrl is bus states for writing and readir type bstate is (stBusReset, stBusIdle, --stBusRead, stBusReadb, stBusRead_c, stBusWrite, -stBusWritekb, stBusWritec); on lines... 'l'; '0'; '0'; output <= ctlocs ctlwe end entity; 'l'; -- -signals signal stBusCurr : signal stBusNext : bstate; bstate; Idle bus First state of read cycle when stBusReadb => stBusNext <= -- read 2 stBusReadc; output on lines... <= 'l'; <= '0'; <= 'I'; ready <= '0'; busdir <= 'l'; databuf <= data; -- First state of write cycle ctlocs ctlewe ctl-oe when stBusRead_c => if (read = '1') -- read 3 then buscntrl.vhd ---- ---- --- --- --- -- -'1' read, '0' write signal busdir : STD-LOGIC; signal ctl-cs : STDLOGIC; signal ctlwe : STDLOGIC; signal ctlcoe : STDLOGIC; -- signal ctl-adr : STDLOGICVECTOR(2 downto 0); begin Entity: buscntrl (main test FSM) File: buscntrl.vhd Date: 25-Mar-03 Abstract: bus controller... controls reading and writing to the DIO2 board. INPUTS: (1) mclk (master clock) = 50MHz (2) clk (slowed clock for the DI02 display multiplexer) (3) stClk (slowed clock for the state Machine) (4) databuf (read or write data) (5) adrbuf (address of the device requested) (6) read '1' to executed (7) write '1' to execute (8) ready '1' means it is waiting for a command ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> cs we oe <= <= <= ctl cs; ctl we; ctl_oe; write pins if busdir = '0' data <= databuf when busdir = '0' else "ZZZZZZZZ"; --data <= "11110000" when busdir = '0' else "01010101": --and databuf = "11110000" --data <= "11110000"; --adr <= "100" when adrbuf = "100" else -"101" when adrbuf = "101"; adr <= adrbuf; dclk <= -clock for DI02 display multiplexer -- library IEEE; use IEEE.STDLOGIC_1164.ALL; use IEEE.STDLOGICARITH.ALL; clk; state machine to output lines process(stBusCurr, stBusNext, read, write) begin case stBusCurr is when stBusIdle => -- idle state -- read data if read = '1' then stBusNext <= stBusRead; elsif write = '1' then stBusNext <= stBusWrite; else stBusNext <= stBusIdle; end if; -- entity buscntrl is : in STDLOGIC; port (--mclk : in STD_LOGIC; clk -slowed clock : in STD_LOGIC; ock : in STDLOGIC; reset -- input -- data databuf : in STD_LOGICVECTOR(7 downto 0); downto 0); adrbuf : in read : in STDLOGIC; : in STDLOGIC; write ready : buffer STDLOGIC; or nothing is happening and it's ready for use -- external lines : inout STD_LOGICVECTOR(7 downto 0); data downto 0); adr : out -: out STDLOGIC; /read) out STDLOGIC; we h data) out STDLOGIC; data) dclk : out STD_LOGIC - master clock stClk STDLOGICVECTOR(2 cs -- cl to read/write -- device to address -'1' to read data -- '1' to write data -'1' when done, ctlcs ctl we ctl-oe STD_LOGICVECTOR(2 chip select : bstate; : bstate; ('1' to write write enable ('1' read enable architecture behaviour of buscntrl is -- bus states for writing and reading type bstate is (stBusReset, stBusIdle, -stBusRead, -stBusRead.b, stBusReadc, stBusWrite, -stBusWrite-b, stBusWritec); output on lines... <= '0'; <= <= '0'; ready <= '1'; busdir <= '0'; -- end entity; -signals signal stBusCurr signal stBusNext state machine Idle bus First state of read cycle ('1' to latc to read when stBusRead => -read 1 stBusNext <= stBusReadb; -- output <= ctl.we <= ctloe <= ready <= '0'; busdir <= etlcs -- state of write cycle 'l'; read 2 -when stBusRead-b => stBusNext <= stBusReadc; output ctlecs First on lines... '1'; '0'; '0'; ctluwe <= <= on lines... '1'; '0'; ctl-oe <= '1'; ready <= '0'; busdir <= '1'; databuf <= data; when stBusRead-c => -read 3 if (read = '1') then Appendix D Probes Several different versions of the probe and matching network were created. There were numerous unsuccessful versions of the probe before a final design was settled upon. The following pictures are successive interations of the probe. All the probes follow the schematic shown in Figure 6-2, section 6.2.1. A mechanical diagram (done in Omax) of the final probe is also included. The final probe was constructed using a copper cylinder and 0.25 inch copper plates. The patterns were cut with a water jet. The probe was welded together with silver solder. 199 Figure D-1: A die-cast Al RF box is used as the container for the probe and tuning and matching capacitors. Large copper sheet metal is used as the wiring between components. Sheet metal is used to lower parasitic inductance. The probe holder is a piece of paper rolled into a cylinder. The coil is wrapped around the paper. The resonance frequency is 4.649MHz, with C1 = 260pF, C2 = 760pF, and L, = 1.2pH. 200 Figure D-2: The second probe utilizes similar construction methods as the first. The major difference is variable air capacitors are used as the tuning and matching capacitors. Use of the variable air capacitors turns out to be a poor design choice, because the air capacitors have a lot of undesired capacitively coupling to other components. The resonance frequency was not attainable. 201 Figure D-3: The third probe is the same design as the first, except the length of the coil is increased to maximize the Q. The length of the coil is the same as the diameter of the coil, 0.78 inches. The resonant frequency is 4.649MHz with C1 = 26pF, C2 = 95pF, and L, = 9.6pH. 202 Figure D-4: The last probe is shown here with a 9.7pH coil. The coil slides over a 0.78 inch test tube which fits in the center of the copper cylinder. The tuning and matching capacitors are described in section 6.2.1. 203 Figure D-5: The mechanical drawings (completed in the software Omax) for the probe (in Figure D-4) is show with lengths in units of inches. 204 Appendix E Class E amplifier This appendix contains the relevant schematic, in Protel, for the Class E amplifier. The design shown is tuned for 4.638MHz. The PCB layout is also shown in Figure E-2. Lastly the waveforms from the simulations are shown in Figure E-3. 205 2 3 CQypass 100n 4 Vcc 22V 1il 54u V Oxt A Ot 1.8u ?cp IOU a Rload 10.0 Figure E-1: Protel schematic of a Class E amplifier tuned at 4.638MHz. A IRF51OS power transistor is used in the design. 206 ............ ........ U UCC In O S n - (;I 019 027 . 8D29 D28 022 022 dUpower U CouA 1 I .1 I * _ Figure E-2: Protel PCB layout for the Class E amplifier. The board is made to fit into a NIM box. Additional debugging pins and thru holes (vias) are added to the board. The back-to-back pin diode switches are incorporated into the design of the PCB. 207 5.750us 6.000us 6.750uS 6.500us 6.250us 7.000us 7.250us voltb 0.000 V V v.0u190.00 tp -10.00V 30.00OV outpu ._______ ....... .. ____ ______________-00 Figure E-3: Simulations of the Class E amplifier are completed in Protel. Here, the voltage at the gate of the transistor (volt-b) is plotted along with the voltage at the drain (v-out) and the voltage across the resistor (output). 208 Bibliography [BB48] J. Bardeen and W.H. Bratain. The Transistor, A Semi-Conductor Triode. Phys. Rev., 64:230, June 1948. [Ben82] P. Benioff. Quantum mechanical models of Turing machines that dissipate no energy. J. Theor. Phys., 21(182):177, 1982. [BGJM94] M.L. Buess, A.N. Garroway, P. JPYJ, and J.B. Miller. Pure 14N NQR of large specimens. In: Proceeding of the XXVII Congress Ampere, 1:58, 1994. [BHP46] F. Bloch, W.W. Hansen, and M. Packard. Nuclear induction. Phys. Rev., 69:127, 1946. [BM75] A. Bohr and B.R. Mottelson. Nuclear structure. Volume II. Nuclear deformations. W.A. Benjamin Inc., 1975. [CFH97] D.G. Cory, A.F. Fahmy, and T.F. Havel. Ensemble quantum computing by NMR spectroscopy. Proc. Natl. A cad. Sci., 94:1634-1639, 1997. [CGK98] I.L. Chuang, N. Gershenfeld, and M. Kubinec. Experimental implementation of fast quantum searching. Phys. Rev. Lett., 18(15):3408-3411, 1998. [CVZ+98] I.L. Chuang, L.M.K. Vandersypen, X.L. Zhou, D.W. Leung, and S. Lloyd. Experimental realization of a quantum algorithm. Nature, 393:143-146, 1998. 209 [Deh50] H.G. Dehmelt. Pure quadrupole resonance in solids. Naturwiseen- schaften, 31:111, 1950. [Deu85] David Deutsch. Quantum Theory, the Church-Turing Principle and the Universal Quantum Computer. Proc. R. Soc. of London A., 400(1818):97-117, 1985. [DH58] T.P. Dasand and E.L. Hahn. Nuclear Quadrupole Resonance Spec- troscopy. London LtD., 1958. [Dig02] Digilent. Digilent 2E manual. 2002. [DiVOG] David. P. DiVincenzo. The physical implementation of quantum computation. Fortschritteder Physik, 48:771-80, 2000. [DJ92] D. Deutsch and R. Jozsa. Rapid solution of problems by quantum computation. Proc. R. Soc. of London A., 439:553, 1992. [EBW87] R.R. Ernst, G. Bodenhausen, and A. Wokaun. Principles of Nuclear Magnetic Resonance in One and Two Dimensions. Oxford Sci. Pub., 1987. [Fey8l] R.P. Feynman. Simulating physics with computers. In Inter. J. Theor. Phys., volume 21, page 486, 1981. [Fey82] Richard P. Feynman. Simulating physics with computers. Int. J. of Theor. Phys., 21(6&7):467, 1982. [FGMS02] G.B. Fuman, S.D. Goren, V.M. Meerovich, and V.L. Sokolovsky. Two qubits in pure nuclear quadrupole resonance. Journal of Physics: Condensed Matter, 14:8715-8723, 2002. [FMSR99] G. Fisher, E. MacNamara, R.E. Santini, and D. Raftery. A versatile computer-controlled pulsed nuclear quadrupole resonance spectrometer. Review of Scientific Instruments, 70(12):4676-4681, 1999. 210 [FR86] Eiichi Fukushima and Stephen B.W. Roeder. Experimental Pulse Nmr: a Nuts and Bolts Approach. Perseus Publishing, 1986. [Fre97] R. Freeman. Spin Choreography. Spectrum Oxford, 1997. [GAPA99] J.A. Gupta, D.D. Awschalom, X. Peng, and A.P. Alivisatos. Spin- coherence in semiconductor quantum dots. Phys. Rev. B, 59:R10421R10424, 1999. [GBM+01] A.N. Garroway, M.L. Buess, J.B. Miller, B.H. Suits, A.D. Hibbs, G.A. Barrall, R. Matthews, and L.J. Burnett. Remote sensing by nuclear quadrupole resonance. IEEE Trans, 39:1108-1118, 2001. [GBYM93] A.N. Garroway, N.L. Buess, J.P. Yesinowski, and J.B. Miller. Narcotics and explosives detection by 14N pure NQR. SPIE Substance Detection Systems, 2092:318-327, 1993. [GC97a] N. Gershenfeld and I.L. Chuang. Bulk spin resonance quantum computation. Science, 275:350-356, 1997. [GC97b] N. Gershenfeld and I.L. Chuang. The Usefulness of NMR Quantum Computing: Response. Science, page 1689, September 1997. [Gru00] Josef Gruska. Quantum Computing. McGraw Hill, 2000. [JM98] J.A. Jones and M. Mosca. Implementation of a quantum search algorithm on a nuclear magnetic resonance quantum computer. Nature, 393(6683):344, 1998. [JMH98] J.A. Jones, M. Mosca, and R.H. Hansen. Implementation of a quantum search algorithm on a nuclear magnetic resonance quantum computer. Nature, 393:6683, 1998. [Kan98] B.E. Kane. A silicon-based nuclear spin quantum computer. Nature, 393(6681):133-137, 1998. 211 [KMW02] D. Kielpinski, C. Monro, and D.J. Wineland. Architecture for a largescale ion-trap quantum computer. Nature, 417:709-711, 2002. [KOB70] P.K. Kadaba, D.E. O'Reilly, and R. Blinc. Physics of Solids, 42:855, 1970. [LBF98] N. Linden, H. Barjat, and R. Freeman. An implementation of the Deutsch-Jozsa algorithm on a three-qubit NMR quantum computer. Chem. Phys. Lett., 296:61-67, 1998. [LCQ+97] E. Lau, K.W. Chiu, J. Qin, J. Davis, K. Potter, and D. Rutledge. High-Efficiency Class-E Power Amlifiers - Part 1. QST: Amateur Radio, page 42, May 1997. [Lee02] Y.K. Lee. Spin-1 Nuclear Quadrupole Resonance Theory with Comparisons to Nuclear. Magnetic Resonance Concepts in Magnetic Resonance, 14(3):155-171, 2002. [LT02] R. Lerdorf and K. Tatroe. Programming PHP. O'Reilly, 2002. [Mag99] Yael G. Maguire. Towards a Table Top Quantum Computer. Master's thesis, MIT, 1999. [MNAU02] J.M. Martinis, S. Nam, J. Aumentado, and C. Urbina. Rabi Oscillations in a Large Josephson-Junction Qubit. Phys. Rev. Lett., 89(11):1-4, 2002. [Moo65] Gordon Moore. Cramming more components onto integrated circuits. Electronics, 38(8), 1965. [NCOO] M. Nielson and I.L. Chuang. Quantum Computation and Quantum Information. Cambridge Press, 2000. [OMB67] T. Oja, R.A. Marino, and P.J. Bray. 14N nuclear quadrupole resonance in the ferroelectric phase of sodium nitrite. Phys. Lett. A, 26:11, 1967. 212 [PB76] G. Petersen and P.J. Bray. 14N nuclear quadrupole resonance and relaxation measurements of sodium nitrite. Jour. Chem. Phys., 64(2):522530, 1976. [Pet75] G.L. Petersen. Pusled Nuclear Quadrupole Resonance Instrumentation and Study of N14 Spectrum and Relaxation in Sodium Nitrite. PhD thesis, Brown University, 1975. [PML94] T.L. Peck, R.L. Magin, and P.C. Lauterbur. NMR microspectroscopy using 100micro planar RF coils fabricated on gallium arsenide substrates. IEEE Trans. on Biomedical Eng., 1994. [Pou50] R.V. Pound. Nuclear electric quadrupole interaction in crystals. Phys. Rev., 79:685-702, 1950. [Pre98] J. Preskill. Physics 229: Advanced Mathematical Methods of Physics Quantum Computation and Information. California Institue of Technology, 1998. [PTP46] E.M. Purcell, H.C. Torrey, and R.V. Pound. Resonance absorption by nuclear magnetic moments in a solid. Phys. Rev., 69:37-38, 1946. [PW51] R.V. Pound and G.D. Watkins. An improved rf spectrometer. Rev. Sci. Instrum., 82:343, 1951. [Seg77] E. Segre. Nuclei and particles: An introduction to nuclear and subnuclear physics. W.A. Benjamin Inc, 1977. [Sho94] Peter W. Shor. Algorithms for quantum computation: discrete logarithms and factoring* Proceedings of the 35th Annual Symposium on Foundations of Computer Science, page 124, 1994. [Sho97] Peter W. Shor. Polynomial-time algorithms for prime factorization and discrete logarithms on a quantum computer. 26(5):1484-1509, 1997. 213 SIAM J. Comp., [SNFY58] S. Sawada, S. Nomura, S. Fujii, and I. Yoshida. Ferroelectricity in NaNO2. Phys. Rev. Lett., 1:320, 1958. [Sok75] N.O. Sokal. Class E-A new class of high-efficiency tuned single-ended switching power amplifiers. IEEE Jour. Solid-State Cir., 10(3):168-176, June 1975. [Sok98] N.O. Sokal. Class E High-efficiency Power Amplifiers, from HF to Microwave. IEEE, 0-7803-4471-5:1109-112, 1998. [Sok0O] N.O. Sokal. Class E Switching-mode High-efficiency Tuned RF/Microwave Power Amplifier: Improved Equations. 1EE MTT, pages 779-781, 2000. [Ste03] M. Steffen. A prototype quantum computer using nuclear spins in liquid solution. PhD thesis, Stanford, 2003. [SvDH+03a] M. Steffen, W. van Dam, T. Hogg, G. Breyta, and I.L. Chuang. Experimental implementation of an adiabatic quantum optimization algorithm. Phys. Rev. Lett., 90:067903, 2003. [SvDH+03b] M. Steffen, W. van Dam, T. Hogg, G. Breyta, and I.L. Chuang. Experimental implementation of an adiabatic quantum optimization algorithm. Phys. Rev. Lett., 90:067903, 2003. [Tsa99] K.C. Tsai. A 1.9GHz 1W CMOS Class E Power Amplifier for Wireless Communications. IEEE Jour. Solid-State Cir., 34(7):962, July 1999. [VNMO1] Varian VNMR. VNMR Pulse Sequences. Varian, Inc., 2001. [VSB+00] L.M.K. Vandersypen, M. Steffen, G. Breyta, C.S. Yannoni, R. Cleve, and I.L. Chuang. Experimental realization of Shor's quantum factoring algorithm using nuclear magnetic resonance. 2000. 214 Nature, 76(5):646-648, [VSB+01] L.M.K. Vandersypen, M. Steffen, G. Breyta, C.S. Yannoni, R. Cleve, and I.L. Chuang. Experimental realization of an order-finding algorithm with an NMR quantum computer. Phys. Rev. Lett., 85(25):2480-2482, 2001. [War97] W.S. Warren. The Usefulness of NMR Quantum Computing. Science, page 1688, September 1997. [WPBM93] X. Wu, D.A. Patterson, L.G. Butler, and J.B. Miller. band nuclear-magnetic-resonance and flexible pulse programmer. A broad- spectrometer-digital-phase-shifting Review of Scientific Instruments, 64(5):1235-1238, 1993. [WSF88] E.A. Wachter, E.Y. Sidky, and T.C. Farrar. Enhanced state-machine pulse programmer for very-high-precision pulse programming. Review of Scientific Instruments, 59(10):2285-2289, 1988. 215