PLACE IN RETURN BOX to remove this checkout from your record. TO AVOID FINES return on or before date due. MAY BE RECALLED with earlier due date if requested. DATE DUE DATE DUE DATE DUE 6/01 c-JCIRC/MeDuopss-ms STAR. STAR EMC TRIGGER LEVEL DESIGN FOR AN ORCA FPGA By Brian Scott Foulds A THESIS Submitted to Michigan State University in partial fulfillment of the requirements for the degree of MASTER OF SCIENCE Department of Electrical and Computer Engineering 2001 \- T ”551%? p' ||\ .v‘ .' ‘ ;‘a— ‘ 1‘1“ , . § _\ u\\.\l|'|r “ u i‘“.; ' Jkl " ’P "h .u , ‘C. ? “if p-K\C\x ABSTRACT STAR EMC TRIGGER LEVEL DESIGN FOR AN ORCA FPGA By Brian Scott Foulds The STAR project, located on Long Island, New York, represents the latest and most powerful atomic-level particle detector in the world. The Electromagnetic Calorimeter, or EMC, sub-detector attempts to generate energy data for up to 1000 particles a second, a very computational intensive task. To help filter out unwanted data that represents a non-critical event, an FPGA-based computational engine is used to help make the decision using fast, reconfigurable hardware. This thesis discusses the design of the EMC, FPGA-based, computational engine and all of the challenges that were incurred in the process. It also provides a comparison between the FPGA design and a possible PC-based implementation. Finally, FPGA coding and design rules, gathered from the knowledge of the design process, are summarized for efficient design practices. lLil 0f “Cl Rl.‘ LN OF TABLES- lBl 0F ABBRU I llmduction ........ IBachround Info-n 1'. ill-{1C .c; I: NC DC?" ‘ \‘ ,n_ '-~ I."v'( u: \ TABLE OF CONTENTS LIST OF FIGURES ................................................................................ vi LIST OF TABLES ................................................................................ viii LIST OF ABBREVIATIONS .................................................................... ix 1 Introduction ......................................................................................... l 2 Background Information ........................................................................ 5 2.1 RHIC and The STAR Detector ......................................................... 5 2.2 EMC Detector and Trigger ............................................................. 8 2.3 PC vs. FPGA Implementation ........................................................ 12 2.4 Xilinx vs. Lucent FPGA’S ............................................................. 13 3 Architecture and Design Overview ............................................................ 19 3.1 Overall Architecture Overview ........................................................ 19 3.2 Timing Constraints ..................................................................... 21 3.3 Level 1 Architecture .................................................................. 23 3.4 Level 2 Architecture ................................................................... 27 3.5 Level 3 Architecture .................................................................. 31 3.6 Summary ................................................................................ 34 4 PC-Based Implementation ...................................................................... 35 4.1 Motivation ............................................................................... 35 4.2 VC++/VB Program Overview ......................................................... 36 4.3 Results ................................................................................... 39 5 FPGA-Based Implementation .................................................................. 41 5.1 Common Components ................................................................. 41 iii 'ar , .'-, LLCIL... 5.3 lac: I ' {(1 !~ ~‘Lr'613l 5.2 Level 1 Components ................................................................... 43 5.3 Level 2 Components ................................................................... 51 5.4 Level 3 Components ................................................................... 53 5.5 Summary ................................................................................. 54 6 Simulation and Synthesis Results ............................................................. 55 6.1 Overall Design Methodology ......................................................... 55 6.2 Testbench Design and Structure ....................................................... 59 6.3 Synthesis Results ....................................................................... 60 6.4 Simulation Results ...................................................................... 63 7 Synthesis Coding Guidelines for Enabling Performance .................................. 65 7.1 Arithmetic Operations ................................................................... 65 7.2 Other Operations ........................................................................ 70 7.3 Synthesis Guidelines For F PGA’S .................................................... 74 7.4 Portability Library Concept ............................................................ 76 8 Conclusions and Future Investigations ....................................................... 79 8.1 STAR EMC Trigger Level Design Evaluation ...................................... 79 8.2 PC vs. FPGA Implementation: The Final Word .................................... 80 8.3 FPGA Synthesis Guidelines Summary .............................................. 81 8.4 Future Investigations ................................................................... 81 APPENDIX A (Common Synthesis Code) ..................................................... 83 APPENDIX B (Level 1 Synthesis Code) ....................................................... 96 APPENDIX C (Level 2 Synthesis Code) ....................................................... 141 APPENDIX D (Level 3 Synthesis Code) ...................................................... 185 iv Truman wumxrrsw. BBUOCIUPI“ . APPENDIX E (PC Implementation Code) ................................................... 214 APPENDIX F (Synthesis Simulation Results) ................................................ 230 BIBLIOGRAPHY ................................................................................. 239 V‘ "-I2 .‘J'I' . \ at“ ..\\" ‘ ‘ .r *' “er 3" . :0 ‘._ I l .I.".'ni- I V not a . .0 I I 1-....4s ‘ I ‘ 5“ . ,...b\v \\ ‘I. I‘. e' ' _“ .._~. I I ‘Q_\_“. N.“- \\‘ I ..~ .0 I \ch ‘3‘ \' 'P .“k....i..sb’ --\ . \ h‘. M‘" ‘ 4“ 'q . 'II . .....,I...5\- --\ - .. mafi' \‘r L-'.- -‘ . - bImI . '\I---\\' . D A I ‘1"""')‘ ' . ,. , .- . . I 4 . ..~.....uuu"- Illll A - as]. I “1 AWN)“ "' I" -.\ u.,gws1".m‘n L '-1 ‘II .1 am . I“ ' \‘ I \‘\t - I 5» [Ix i‘ t .l ‘ -~ )“TKj‘-_;JI 3‘.“ ‘ r.‘.l\\d .( \I ..' '- n“ J . _ ““A )s . ‘-«-.' ;.l I“ ‘ ; xv L. wink ‘Q. ‘ ”rah, ' . 3‘ . ' ~"“f “l“! ‘fludI ‘ Q :.‘\‘ I513} 1 -cm -.. 2"" I 5M “”41 ‘- \H' . 3‘s]. w'» . ”‘-‘-‘:» \1 Isl-k. \\ ’ ‘V ‘ N . \' .‘ ' ~I.1,. ‘ T ' {HHPMI )‘ )1 «0t. 2‘! A /‘ I “. A. 'l. \' 'Ie‘ ‘ HI,“ ‘ 5 I‘"‘\\‘ P¢H1. \ .H A. 'i.‘ \[“‘n k‘ a.“ :14 {“135k :1": \t ‘( I 4' «mm ‘~ x. I“; ..\::r ‘1 I ‘: A. . ‘ \ I - X. Hut‘ LIST OF FIGURES 2.] STAR Detector Diagram [5] ..................................................................... 9 2.2 EMC Physical Layout [9] ....................................................................... 10 2.3 Simplified xc4000x CLB [18] ................................................................. 14 2.4 Simplified xc4000x IOB [18] .................................................................. 15 2.5 Simplified or2c00a PFU [15] .................................................................. 16 2.6 Simplified or2c00a PIC [15] ................................................................... 17 3.1 Overall Architecture Diagram ................................................................. 20 3.2 Computational Engine Internal Pipeline Structure ......................................... 21 3.3 Computational Engine Timing Structure .................................................... 22 3.4 Level 1 Trigger Macro ......................................................................... 24 3.5 Simplified Level 1 Trigger Control ........................................................... 25 3.6 Simplified ei and e0 Stages for Level 1 Trigger ............................................ 26 3.7 Simplified Partial e1 Stage for Level 1 Trigger #1 ......................................... 26 3.8 Simplified Partial el Stage for Level 1 Trigger #2 ......................................... 27 3.9 Level 2 Trigger Macro ......................................................................... 28 3.10 Simplified Level 2 Trigger Control .......................................................... 29 3.1] Simplified ei and e0 Stages for Level 2 Trigger .......................................... 30 3‘12 Simplified Partial e1 Stage for Level 2 Trigger #1 ........................................ 30 3'13 Simplified Partial e1 Stage for Level 2 Trigger #2 ........................................ 31 3- 14 Level 3 Trigger Macro ........................................................................ 32 3.15 Simplified ei and co Stages for Level 3 Trigger ........................................... 33 vi . .n, -“. ‘~V‘*\-I I s.o ' ‘ ‘0. ,‘n‘p‘ . - a ' P'". h 4? {VIC PC-Bm‘ E i.:.f\’\\i“"' ' ‘ s ".‘\ ' "‘ \ J‘.‘4'I Apes. ' I.I\-NE\‘EIA‘~‘L - "t.‘ r» ll‘ .0. ‘.\¢—q-‘e-‘4 P... I. \ ~~ Vang in! E I U: ' I": l I'I D l n.‘ :‘r. i' . “71.3w; \‘ \ A [no ‘;\. I ~.u;\h.‘j:l S...“ ‘ ‘ 3.16 Simplified Partial el Stage for Level 3 Trigger #1 ........................................ 33 3.17 Simplified Partial e1 Stage for Level 3 Trigger #2 ........................................ 34 4.1 EMC PC-Based Evaluator Program Screenshot ............................................. 39 5.1 Inverse Mapping Strategy ..................................................................... 46 5.2 Portion of Ratio Result Saved .................................................................. 47 5.3 Simplified Ratio Technique for e0 Stage ..................................................... 47 5.4 A CSA for Four Operands [14] ................................................................. 49 5.5 Final Level 1 Trigger Component Taxonomy ............................................... 50 5.6 Final Level 2 Trigger Component Taxonomy ............................................... 53 5.7 Final Level 3 Trigger Component Taxonomy ............................................... 54 6.1 Overall Design Methodology ................................................................... 56 6.2 Functional Simulation Design Methodology ................................................ 56 6.3 Synthesis Design Methodology ................................................................ 57 6.4 Implementation Design Methodology ........................................................ 58 6.5 Timing Simulation Design Methodology .................................................... 59 6'6 Improved Inverse Mapping Strategy .......................................................... 61 6.7 Average Percent Error for Various Inverse Mappings ..................................... 62 7-1 Resource Usage for 2-Operand Adder Techniques ......................................... 66 7.2 Maximum Delay for 2-Operand Adder Techniques ....................................... 67 7.3 VHDL Portability Coding Methodology .................................................... 77 vii .‘t 1‘? \ ’3 "."" .ouh'beh |"-."' \ ~5 .r a? ' .-.\':I.‘ In. M". \ . 4'» ur ‘fi Anni-t: 110. C {11C 3‘ fi'I rt RI .4» LIST OF TABLES 3.1 Level 1 Trigger Signal Summary ............................................................. 24 3.2 Level 2 Trigger Signal Summary ............................................................. 28 3.2 Level 3 Trigger Signal Summary ............................................................. 32 4.1 Software EMC Computational Engine Function Description ............................ 37 4.2 EMC Software Results Summary ............................................................. 40 5.1 Level 1 Trigger Level Signal Interface Summary .......................................... 44 5.2 Level 1 Trigger Level Register Specification Summary .................................. 45 5.3 Level 2 Trigger Level Register Specification Summary .................................. 51 5.4 Level 3 Trigger Level Register Specification Summary .................................. 53 6.1 Synthesis Results ............................................................................... 62 7.1 Summary of Multi-Operand Addition Synthesis ........................................... 69 7.2 FMAP/HMAP Resource Usage of Normal/Tri-state Multiplexers ...................... 73 7.3 Maximum Delay Time (ns) of Normal/Tri-state Multiplexers ............................ 73 viii iSlC - Apr ENC - B: l BS‘ID . Brl CLB - Clef" CPA-C.l'.j.-TI 6.1-(:3: D10 ' Dsii ' DLL - D2; I r! V‘- . C" [Q ...t," m 3 C... 11C . P" “n.1,“. \ "‘--. 399°39‘9993Pr— pwsewpwNHSBEBSSAriPPWSQMAri LIST OF ABBREVIATIONS ASIC - Application Specific Integrated Circuit BEMC - Barrel Electromagnetic Calorimeter BSMD - Barrel Shower Maximum Detector CLA - Carly-Look-Ahead Adder CLB - Combinational Logic Block CPA - Carry-Propagate Adder CSA - Carry-Save Adder DAQ - Data Acquisition DLL - Dynamic Link Library e0 - Engine 0 Stage e1 - Engine 1 Stage eo - Engine Output Stage EDIF - Electronic Design Interchange Format EMC - Electromagnetic Calorimeter ENAIC - Electronic Numerical Integrator And Calculator ESMD - Endcap Shower Maximum Detector FPGA — Field Programmable Gate Array GUI - Graphical User Interface HDL - Hardware Description Language IDE - Integrated Development Environment IEEE - Institute of Electrical and Electronics Engineers IOB - Input/Output Block JT AG - Joint Test Action Group 10 - Level Operations Stage LUT - Lookup Table PAR - Place and Route PFU - Programmable Function Unit PIC - Programmable Input/Output Cells PLC - Programmable Logic Cells QGP - Quark-Gluon Plasma RAM - Random Access Memory RHIC - Relativistic Heavy Ion Collider SDF - Standard Delay Format STAR - Solenoid Tracker At RHIC SVT - Silicon Vertex Tracker TOF - Time of F light TPC - Time Projection Chamber VHDL - VHSIC Hardware Description Language VHSIC - Very High-Speed Integrated Circuits ix Chapter 1 Introduction One the very first computers, the ENIAC (Electronic Numerical Integrator And Calculator), was built by J. Presper Eckert and John Mauchly at the Moore School of the University of Pennsylvania [12]. Disclosed in 1946, this machine was funded by the United States Army and was fully operational during WWII. General-purpose in nature, this machine, or what is now referred to as hardware, was used exclusively to calculate the artillery firing tables during the war. The difference between ENIAC and many Previous calculators was that this machine provided conditional statements thus making it fully Programmable. Designers of ENIAC separated out a hardware side from the Sofiware or programmable portion of the design, which was never done before. Fast forward to today. The idea of hardware and software can be easily comprehended by just about anyone who fiequently uses a computer. Today’s general processors are capable of performing millions of calculations per second and are the main I"338011 behind the technological push of the 1990’s. But in some cases, even in highly parallel Processing systems, the calculating power is simply not enough and the process 21s :9 Iozg. Tilt Z 0 I”.- .5-“ g an» ). i... ix'u“. ”‘1 "' I . I ' '2» nw‘a' ”Ni" 1* .‘f.su--L""‘ I I' \.., M. fio~ ‘ . ”Kidnfguiic‘c I. . 1w 1- ' v- ' ' ‘. , 1']; if h ' IRA n -‘1A In in! v --»» «fix my», ' ‘4‘ 'L uIt‘ It .. h‘i'r" 2“: I v?.l.z..~.‘- '1‘ .\:Tl“ 2.-...3, t“ 9:: 4» 3310? A“ I H Till? this 13 Trim 0“... I ~ ii S ' C UlCTLL I .0 *~‘--.._,; m,,l ‘ ‘ ‘ 1‘4‘ Hw. .g. S N affirm '3'“ 33.- "‘C; ‘ , v 139571;», «A\. ‘1‘" 5. ° E II F» 45:" '\ NA“ ‘ ~.l_lrn h-lg’ v . I res to long. The obvious need is a programmable hardware system that can take on any rm desired and provide the ability for rapid prototyping of designs Similar to that of the w typical hardware/software system. Enter VHDL and the FPGA. In the early 80’s, the United States government set t to create a modeling language for integrated circuits. Their VHSIC (Very High- eed Integrated Circuits) program needed a language that could accurately describe the lotion and structure of digital systems. VHDL (VHSIC Hardware Description Iguage) was the result of their efforts. Later in the decade, the FPGA (Field Gate Igrammable Array) was created which provided a means by which to apply the guage to a non-custom device. The result of the combination is a rapid prototyping Item of re-programmable hardware that allows designers complete freedom and with Iically better throughput than general CPU’S. This thesis is an application of the VHDL and FPGA design cycle to a real world )blem, the Solenoid Tracker At RHIC Electromagnetic Calorimeter Trigger mputational Engine. The proposed design, consisting of 35 custom-built FPGA-based mputational boards, computes the final energy value from inputs representing spatially :ated signals from the detector. In addition, the threshold information is used to [ermine if the higher precision energy values, stored in buffers, should be either saved discarded. This data, clocked in at a rate of 38 MHz, consists of 300 trigger tower Brgies, representing the average energy, and 300 high tower energies, representing the hem energy, The energy values are then calculated through 4 successive layers of rse custom boards, producing the final energy and additional coded outputs. Overall, . l I ' »'-u- O 1' 3" '- 7 Lana; .C‘a -‘ ~- I . ‘ a" ,‘.‘....-q . 07-. A‘ML'CI. :1”. all . .3, 9 W n a} \u‘II‘..I' n'. . c . azn- ’ . f -0 up tI..........|.‘I. l'. 3 L. . ' 0 q, ""l' h , . 1‘”- “;~‘-‘I- J‘.‘ ‘k C" s . ' I -‘-~.n . Y|E"‘I_ are» .Iu. i If .k‘ ‘IL .4 ‘ V I e A .4“ a ’ “1 alt. “"55 I .c: is spat ctr.-.- l'L. - .le l" . I. . I.. x-?... ‘ "MI-.011 § I n ma 1 "j'I‘vL tut; u... “L i{\ “a k. ' In ‘ \ Jw 'j'u :L l {The . N If \jhi-lu. 3... . w. I I. “35:2; . ~ * it t:- - U i I. ’- P‘X‘J‘“ I D “U: hit {’1‘}. ‘ ‘_ I I," Q" ‘G~ I 'U, I- T‘IL\ ' “ Ui the final results in the filtering computational engine indicate whether a significant event has occurred in the detector and whether the data should be saved for further analysis. As custom-based hardware solutions, such as proposed above, are expensive, an examination of a cheaper PC-based solution vs. an FPGA design is explored. This application, however, brings a set of problems, most notably critical clock speed issues, which prove to not be possible on a PC-Based design. Not only is the timing critical in this design, the system also has to be flexible and re-programmable due to the changing ideas and demands of the physicists who eventually will end up using the system. Because of these, a non-custom, F PGA-based design is, ideally, the solution. Close examination and study of the F PGA architecture had to be done in order to meet the speed demands of the design. An exploration into the differences of the typical Xilinx architecture, which is used at Michigan State University, vs. the Lucent Technologies FPGA used for the project, was performed. The special functions and features of each architecture were noted, compared, and summarized. Finally, algorithmic techniques in conjunction with special chip features enabled through correct cornI-"iler use were also examined for speed purposes. The STAR EMC Trigger Computation Engine was designed from the input of PhySicists and board engineers on the project. Implementation of said design was created from the knowledge of VHDL, the specific F PGA architecture, and algorithmic teChniques. In Chapter 2 we will discuss the STAR project, feasibility issues for a PC- based design, and touch on the Specific Xilinx and Lucent FPGA architectures. Chapter 3 Will discuss the constraints and the overall architecture of the design. Implementation and results of a PC-based solution will be discussed in Chapter 4. The FPGA-based ox.- ~11 ’5‘.-. I... q l \3", fitt‘..- I .'.. ,io‘p- ‘v-olu- "I v .iC3‘.....'C‘ 15--.. I I ".‘K v- ,r ." «r n. .. "Nut. .II x“... - 1"“. V Jy‘ r-.-."\_-e w - - mlnbenn§¥om design will be explained on a component-by-component basis in Chapter 5. In Chapter 6, results of the synthesis and implementation of the design will be summarized. Chapter 7 will focus on enabling special features and functions for enhancing performance on FPGA architectures. Concluding remarks and results will be finalized in the last chapter, Chapter 8. Chapter 2 Background Information This chapter will provide background information and motivation for the thesis. Presented is a brief explanation of the STAR project at RHIC and the importance of its existence. The EMC Trigger electronics and related detector, a small portion of the overall STAR project, will be elaborated. A PC-based and an FPGA-based solution to the project will be talked about and examined. Finally, selected FPGA architectures from Xilinx and Lucent will be analyzed in context with the project. 2.1 RHIC and The STAR Detector Brookhaven National Laboratory, located 60 miles west of New York City on Long Island, is home to the RHIC project, which consists of the STAR detector, among others. Founded in 1947 by the US. Government as an applied scientific research center [7]. In 1952, the center began to focus primarily on high-energy physics, which has Continued up to the present [7]. Since 1960, the facility has been the home to three Nobel Dear”? CIA" I... ”mm- '"|. . u 'L .' I . 3.3.35 *l'... ~36 RI.“ [mini 3"; .I...“‘ .r" l "v. ' ' .1 1351.93?le l' 4w. . . I ‘ I . .LE'E. diva, Pl “wt" ‘7' I"- ‘ A“ - L.‘ ‘ I 1" E ‘5 :b‘Aal-II it” '.V I 4M0!) n‘ F‘“ ‘ . I" ““" gags“ - . ‘ W pea aw F ‘ 5 ALICA‘AE‘IL‘L 0t ‘1 \ I l [I So It} Rl I e I w . “3’"... . '!---LII lt' ' risk". -. -.: s‘ . «ms of I.‘ use" fz’Ls- 0L I .I: _;(\15 l'\ l»- t \. ‘5‘, ‘ “L.:'.D‘ f “‘ 43 UI alIS'mS . H. Idliftfi. a\ Irrimt ' I». “It {III I‘h c-V‘l- I 4". "‘n .g' ' "kill! A“ “fun "“h- 01 t 9 I HILT I" c. ‘N. LD- -.- . s. “‘3 In 'L II. “it ; mute“: J u UV .‘ms “WI. \ U i ”MYT- WI 4 l L . . “ ‘Q l l .1. Art: n‘.’ ‘ :H‘N‘L I'm kw Prize-winning experiments [7]. It is the premier nuclear physics laboratory in the United States with the RHIC project continuing this outstanding tradition. In 1983, the need for a relativistic heavy ion collider (RHIC) was acknowledged [7]. The acronym RHIC really describes what researches envisioned in 1983. Particles that travel near the Speed of light are considered relativistic, forever endured in Einstein’s famous equation E=mc2 [6]. Heavy ions are large atoms, such as gold (Au), missing their electrons [6]. Finally, a collider will attempt to smash two heavy ions, head on, at relativistic speeds to see what occurs from the impact [6]. The research, design, and implementation of such a facility continues today and will continue well into the future. So why RHIC and why is it important? In order to answer that question it is important to understand the physics behind the idea. It is well known that matter is made up of millions of atoms that form the basis of everything that is known. The computer that this thesis is being written on to the paper that it will eventually reside on consists of millions of atoms. These are referred to as atomic particles. However, as we know from such areas as solid-state electronics, atomic particles can be further broken down. Such particles are known as subatomic particles, or particles smaller than an atom. These are such things as protons and neutrons, which make up the nucleus or center of the atom, to the electrons, which surround the nucleus. The differences in the amounts of protons, neutron, and electron configuration give rise to the different elements seen on the periodic table. Modern physics tells us that these subatomic particles can be broken down even further. The protons and neutrons that form the nucleus of the atom consist of quarks and gluons. Specifically, each proton and neutron contains three quarks bound together by m 2 Ir "-' A..J ‘ \‘I'tii ls cf fi'r‘ “a"! 4"” I ’. ...s.$st..li. . 0L5 7a: r. W I“ :; IMA mil ‘ I I ~ "M; w.» . ., .~ will; {Mlllft‘r l ruptureL “\u u" . ‘i,~‘ 5Afl S. II . 1' I a... I.I.‘ “A“ 1 \ I 7‘ I... l‘\ » n. lb 10:19 "V7. ‘. II “i-u. I "RID. “so“? ‘ “:- 3?;‘rur1~ 'IrI . i'l 9:51,) and I" . M, "eflhs‘:\ s “"1“ . f“ IUILI hi “mflm . V" “.V I v. ’ "-‘ull' 'i' M ‘ Kiln .l " \\q a”):y~ ‘ :"‘l I ‘. I?! , “."..~,, gluons [5]. A proton has what is known as two “up” quarks and one “down” quark, whereas a neutron has one “up” quark and two “down” quarks [5]. What is of interest to physicists, and the reason for RHIC, is the quark-gluon interaction. A heavy atom with many protons and neutrons, usually gold, will be stripped of its electrons to form an ion. Several of these ions, known as beams, will be smashed, head on, with another beam of ions by accelerating each in opposite directions along the 2.4 mile cyclotron track at Brookhaven [8]. The result is a relativistic heavy ion collision, which hopefully will result in a significant quark-gluon event that can be studied. Still, what is the significance and importance of the RHIC project? Physicists theorize that there was a time when atoms, let alone protons or neutrons, did not exist [8]. Only free-floating quarks and gluons, known as quark-gluon plasma (QGP), existed. This was approximately 18 billion years ago, just before the Big Bang [8]. Just after the Big Bang, approximately 1 second, the free-floating particles bound together forming protons and neutrons. This process is known as hadronization [8]. Shortly thereafter, these protons and neutrons coalesced into nuclei in a process known as nucliosynthesis. 13 billion years later atoms formed. The purpose of RHIC is to go back to the beginning of time and study a new form of matter lmown as quark-gluon plasma. This will be down by smashing high-density particles, like gold, and for a brief moment produce QGP [8]. By producing this reaction Over and over again in the laboratory, physicists expect to gain a new understanding of subatomic particle interaction as well as an understanding of how the universe was . ‘ .. n p . . final. 1 :1‘ 11..“- k V 1 ‘ “flmh Qn|1 9 .pg Nastuhn; IL‘ ..... ' C . 32L: QGP 3“: 11:26 PTU‘L.\.0 gI. -x. | "~ "" . . n W.'b_ “‘a‘vfi‘ ‘1 I]. I C‘. (I .:“x .. f. 3‘5. h? ‘L , \.L41t W"... i“ I l ‘ L3; 1 ‘w :-. '_ an“! 1 formed. This firndamental research can and will be applied to many disciplines, thus solidifying its importance and significance. Each collision in a RHIC collision produces a scattering of different particles. STAR, or Solenoid Tracker At RHIC, will specialize in tracking thousands of those particles [3]. Specifically, STAR will focus on the quark-gluon interaction as RHIC attempts to produce quark-gluon plasma with these collisions. The hope of STAR is to detect the signatures of QGP and to analyze the data related to the conditions in which created QGP. Being as big as a home and weighing approximately 1200 tons, the heart of STAR is the Time Projection Chamber (TPC) [3]. This area is home to the many electronic devices that will identify and track the particles. In parallel with the RHIC collisions, the electronics will look at several parameters trying to identify significant events, or events where, briefly, quark-gluon plasma has formed. It will reconstruct what occurred by taking the thousands of pieces of data from the thousands of events per second [3]. In summary, STAR will attempt to use all of this data to study the relations and interactions of particles known as hadrons, which are made up of quarks and gluons. It will look for signatures of such possible material on an event-by-event basis. This approach will allow physicists to understand hadronic interactions at high energies [4]. 2.2 EMC Detector and Trigger The EMC (Electromagnetic Calorimeter) detector will be used to detect the energies of the particles passing through the STAR detector. It will be used primarily to detect unusual and rare events [9] that can only be captured using the EMC or a combination of the EMC and other detectors within STAR. Its inclusion and completion is essential to the success of the project. The EMC Detector is actually made up of four detectors that are referred to as the EMC detector. They are as follows: the Barrel Electromagnetic Calorimeter (BEMC), the Barrel Shower Maximum Detector (BSMD), the Endcap Electromagnetic Calorimeter (EEMC), and the Endcap Shower Maximum Detector (ESMD) [2]. The only concern and relevance of this thesis is the BEMC. In order to fully understand the layout of the EMC, the layout of STAR must first be examined. Figure 2.1 [5] shows the physical structure of the STAR detector. STAR Detector Silicon Vertex Magnet “Tracke E-M Calorimeter Time Projection ‘ Chamber Time Of Flight onics Elfit orms Forward Time Projection Chamber Figure 2.1 - STAR Detector Diagram [5] Tit BM .1" 52'. 1:13? 'TPC I ;. Ina. Inuit: [3' 3393: {c ’hc ~ Elf all. _‘ " v . 1"»; [I n 7‘. ‘h 0'. ‘ 4%.“ *...\u a“ '\ O a s,‘ ' :1. “qt-S .L' 1 —\. 9 M' W}; at???“ ’ ‘ \‘ Q «f Hf e I ’ 3 LC The EMC, as shown, is only one of many detectors and devices. The Time Projection Chamber (TPC) is used to track and identify significant particles and events. The Silicon Vertex Tracker (SVT), the Time Of Flight (TOF), and other detectors not shown, contribute to the overall STAR detector. The EMC detector is in the shape of a long tube or barrel, which surrounds the area in which the particle beam will pass, shown in Figure 2.2 [9]. TPC SVT TPC (TB/[OF ml ‘ ‘\\\\\lll_ll_llllll,,’, \\\\\\\\\\\\\\\\uum III/Ill [ill/ll/ ...... ({1}. _____ {, °§ \\\T“-\ .0,- o. ?{” I ."'n.--a0".‘. _ ’-"-”lll_ru|_lr,\\1\. 1?!) ‘ um _ wit")! C... 0 Endcap o“ \ \\\,. §>o ll.” \ . I Wartime” Magnet Coils Figure 2.2 - EMC Physical Layout [9] Due to the construction constraints of the overall project, the detector was designed in modules that could be assembled after a majority of STAR was completed. The EMC consists of 120 calorimeter modules [9] that represent the area of the TPC. Each module extends 6° in d) (0.1 radians) and 1 unit in n, where 4) is the azrnuthal angle and n is the pseudorapidity. The azrnuthal angle is the angle of the barrel surrounding the beam line through the center of STAR. Pseudorapidity represents a length unit for the barrel. Specifically, a unit of 1 represents 1/2 the length of the TPC; the values of 1] range from -1 t0 1, with 0 being the center point of the TPC. Hence 60 calorimeter modules surround if , Nil-uh“ " {6.69.1t‘ZL5'.‘ 5 .0107“ ' .11...” v- W‘ ‘k'h A The EW. ’f‘“ ‘ W" ‘ ' l I. ‘ Kg.“ . ”\l 5.. .a- W‘ » WM! 1*“. ’ .um m ‘1 [CV " _ .I :3: ”\HC' 5} .L‘ .L‘- “\W K ' ‘ &b .u,‘ 'h . to“: Ric Ki-‘N " I l' . w». y ‘ \..\ir tiflDI :1» ~ '- ., . tram 31 ‘- 5:. vhgn 6 t:~CUC\: \‘ '- .‘q I . " tn" .1 \ ‘ I ‘ ‘uLaSler... nit ‘-.'\\.r| M: N m "c Lc “I L. £0Lu\ “JAN ‘0 [ltx ‘ Tilt1 ‘ll'l\ h :92» 5c. . ac first it, by» a my. . m fr 5.. “‘1‘“. ‘5» If. r..[€3,.t~-,. L‘\'-‘ r ' .m Tie,- NV)\1!!rl — A0—A3 -'—*- —+—QLUTO 3- N I -Flop 8 m J > L—b 4 a. _U‘I 3;. 81-84 __ —-—/—— QLUTU g N I Flop 4 g j ,_ 80-83 8 N [ ——/—QLUTO a -Flop Cin I J H wows Clock Figure 2.5 - Simplified or2c00a PFU [15] Logic operations for the ORCA 2 series of chips are programmed through the Programmable Function Unit, the programmable portion of the PLC. The main PF U structure can be seen in figure 2.5 [15]. The power behind the PFU comes from the Lookup Tables, or LUTs. Each LUT can be configured to provide basic logic operations, ripple operations such as adders and multipliers, or read/write memory operations. The PFU has two 5-bit input buses, A and B, which address directly into 2 LUT blocks for a 16 . . ’1’" ‘. Vt’V " ' "\ .m. 1'“ no. $1 --1 I I 1 '9 . 7.-" < 0 1 ."‘~ «-3th 1. ML“.\\. § 39>»! . 5'4‘5- HWL ! ‘Slm' total of 4 blocks per PFU. These 4 blocks give rise to the multitude of configuration options for each PFU, from two 4-input logic operations to one S-input logic operation to memory capabilities to, finally, a special function mode. The outputs of the PFU can be registered, if desired. VDD DelayICMOSflT L :1 lo— Pulldown Dintb. Dinlr < In - - Pad Tri Dout/Out R Slew-rate :1 f——— Pullup Ground Figure 2.6 — Simplified or2c00a PIC [15] The Programmable Input/Output Cells (PIC) for the ORCA family of chips is similar in functionality to the 108s of the Xilinx family. Like the xc4000 series, the ORCA chip supports timing delays on the input signal to registered or unregistered input signals. High slew-rate buffers for registered or unregistered output signals exist for use on higher frequency signals. Additionally, the output pins can be disabled, similar to the xc4000, to preserve power consumption. Finally, the 1/0 is both TTL and CMOS compatible. The ORCA 2 family, like its Xilinx counterpart, contains many of the same kinds Of Special blocks and modes of operation. Again, fast carry logic exists for addition and 17 5‘1“}:- out-25.- . '.‘.l.._h S“ hw- "‘ H-.,.r . O- C I " Vi‘u" -\--. ‘1 ' d. ,..\m‘~£ *\b.’\. In " I DCQO. - O I . fin, ‘F‘l-“V w aka... tut-11.5 ll. 5 My: ;, As; ,, P‘Tv-‘a- Lh Ams.l'\l multiplication functions. ORCA chips also require special instantiation of RAM blocks to produce usable and efiicient memory modules. Boundary Scan features exist on these devices, accessible through special coding. Finally, internal clocking blocks provide additional timing modules for use within a design. Special features of both chips are explored in further detail in Chapter 7. 18 {~31 1 '11 La 5] kg: . ‘\' Y 41L , t Pie: .‘ '11", Chapter 3 Architecture and Design Overview After a brief introduction into the overall goal of the STAR project, specifics about the EMC detector, and the technologies employed to deliver the computational engine of the detector, the architecture and design constraints of the computational engine levels 1 to 3 will be the focus of this chapter. Detailed analysis of the timing constraints and overall top-down design functionality will be discussed. An overview of each level will be presented in detail. 3.1 Overall Architecture Overview The EMC computational engine is simply a data filter. Based upon the results generated and the results expected certain items of data are recorded while others are thrown away. There are 4 level triggers to this filter, ranging from the first, Level 0, to the last, Level 3. Level 0, generated directly from within the EMC detector, was discussed previously in Chapter 2. The other level triggers, from a computational engine 19 . . .- 5" r‘ .- 44- ’ D a. .- b- " _ ~ .1 statul ; ::1‘;f This grim 111111-111 l1 1’? fed 1.111- Lhe L 21" ' - 1. «id 1.11:1 U11 +‘r ‘5’ 31}; Th. ' “L~ \\ point of view, will later be elaborated upon in detail. What is important to first understand is the overall top of the design from in terms of data transfer. Trigger Tower & High Tower Values from Level 0 Level1(1) Level2(0 Leve|2(3 Level1(2) I Level1(29 Figure 3.1 - Overall Architecture Diagram As stated previously, the Level 0 trigger is generated from within the detector itself. This generates a 6-bit trigger tower signal and a 6-bit high tower value that is passed into the Level 1 triggers. In turn, this processes the data and generates values that are fed into the Level 2 triggers. Finally, the values computed from the Level 2 trigger are fed into the final trigger, Level 3. The overall structure is shown in Figure 3.1. 300 Trigger Tower and High Tower energy signals are generated from the fast Level 0 Trigger. Therefore, since each Level 1 Trigger can accept 10 of each, 30 Level 1 Triggers are needed, specified on the above figure as 0 through 29. 4 Level 2 Triggers are needed with a final Level 3 Trigger to due the remaining calculations. In total 35 designs are needed to provide the data filtering procedure. 20 3.2 liming Con Tllt“ E‘blC t mfimmflka inurCRCA l H U fit .1135? 5 lU 33C ‘ v _ I i"\ 1!" i J v ml“ p "“5 bib \ R‘."“. H rift-”1c Yeti .‘tCT ‘ “I” ‘L. ‘Qv—l «m. w. N 5“; ‘ 311. mi.“ lav-L _ - “Ilty ’r MKS l (7- ‘s. N 111 “1&1, .1341 1,31 3.2 Timing Constraints The EMC computational engine has only three major design constraints. First and foremost, it must meet the functional needs of the design. Second, it must be able to fit onto an ORCA series 2, 304 pin, 40,000-gate equivalence FPGA. Lastly, it must meet and adhere to the specific timing structure and speed laid out for other portions of the overall STAR design. Internal pipelining is used within each level of design. Each pipeline stage corresponds directly to the structure of timing used across all of STAR. There are four pipeline registers within each level and each refers to a specific stage within the design, which can be seen in Figure 3.2. The first stage in known as the Engine Input Stage (ei), ——v 1——r —r ——-——9 $3 ——9 -—l- A (2‘ 3 s—p I D Q.) 9;), v a.) g 93» m (D .9 I (D Q .9- o. : .9- E ‘1 S C ”181. D. - . ~— '11 —1 E : m c 3 a: u E a O E : '3’ C m U) I If] I.” E r: n m LU : C LIJ Figure 3.2 - Computational Engine Internal Pipeline Structure which latches and buffers the external input signals. In the next stage, Engine 0 (e0), work is performed on the buffered signals. This portion of work is then passed to the next stage, Engine 1 (e1) where the last amount of work is completed. The results are buffered and latched to the outside through the Engine Output Stage (eo). A final non- Pipelined stage, which performs the control aspect of each level, is known as the Level Operations (10) stage. 21 333535115 10 i“ 1"" -' ‘L L" V 31311031111. L.A‘ Vl-‘l l. .' h l 11.11 1.11! WAT] {Q g. . 1 1'35. XI” WW 3‘1 h I -.nbe\| 4“ 1 I EA. $5.161 Ik‘ it". C I}: U)C (41‘ ”Fir-0 ~ 'a-g- 7".» m 1 ‘:1A1.1\ #1“ Elfi’: o “11‘ 01111:". “13! Cllfixck , l' , I 11 Timing of each stage, as well as the overall engine, is critical. Each level must adhere to a specific timing request, as well as each stage within each level. This corresponds to two different clocks, one for the engine, and one for the stage. The time given to each engine, from input to output, is 105 ns; this is approximately a 9.5 MHz clock known as clk9. Another clock known as clk36 has a period of 26.25 us or approximately 38 MHz; this clock is used to move data from pipe to pipe, stage to stage, and level to level. The use of two clocks provides flexibility in timing for each stage. It allows for a varying time period depending on the needs of the stage. This flexibility is taken advantage of within the design. Figure 3.3 illustrates the varying timing of each stage. T I Clkg l .— one / \/ \/ / . . a OUtpUt Engine Input Stage (8:) Engine 0 Stage (80) Engine 1 iotage (e1) Sta e :80; i 1 l i i 0 ns 25.25 ns 52.5 ns 78.75 ns 105 ns Figure 3.3 - Computational Engine Timing Structure The first stage, ei, is given 1.5 clocks of clk36 to input and buffer extemals signals. This particular clock size is due to the delay associated with the Level 0 trigger. Both e0 and e 1 are given 1 clock of clk36 to perform the computation and work of the level. Finally, the last stage, eo, is given 0.5 clocks of clk36 to buffer and output an external signal. With the exception of eo which is clocked on a positive-edge, all stages are clocked on 22 1 ..~0-'. ". "1" "‘ “,3 '»M‘ 1.15: US. v, ,I' 1313' 1311135 25 n5 3 .. " 33... Jain. bhéu' 11-. .. . 1.12121. 3111: 431 i . y - a. to QTFA 1‘1... ‘ . l1 ‘“ . - ' 1‘ - ‘Jk‘u It‘ Ibric D- ra~ ~ AM lecture .2 33 lo 11 1 Ar the negative-edge of clk36. The total time for all stage equals the period of clk9, or 105 us. The problems with this structure are obvious. For each computation stage only a mere 26.25 ns are allocated to do work. In total, each engine has 52.5 ns to due all of the necessary calculations to meet the functionality requirements; this is stringent and places a burden on the design. What appears to be a simple design at the outset becomes a significant challenge due to timing. One possible solution would be to move one clock from ei to the work stages. However, this is impossible. The amount of time is in place to guarantee that the fast trigger fiom Level 0 produces correct results. This time is needed to sample and lookup the 6-bit trigger and tower values. Therefore, the only real solution to the problem is efficient algorithmic techniques in coding and effective use of FPGA features and resources. 3.3 Level 1 Architecture The Level 1 trigger is the largest and most complex of all triggers. Several sub modules or macro models perform a small amount of the functionality of the overall design. In doing so, it makes the job of designing and debugging the system significantly simpler since each component can be designed and tested before inclusion in the top design. However, to fully understand this top-down methodology, it is important to start fiom the highest level of abstraction and burrow down to the smallest of macro models. As was discussed previously, most of the signal inputs into the Level 1 trigger are the trigger tower and high tower energies. However, there are many other lines of communication at this top level of abstraction needed in order to satisfy the functionality 23 ‘Q 1 ' 1823:6622??? '1 . .L' , 2'me “LL". J b .; - 1. ...' . .L 1‘16 in§.ru}s..t . n 1 , Q ‘-~.~.o.~y. .61 .‘ 11.1.1. 1, C...Lt. of the design; this is shown in table 3.1. Of particular interest are the signals vme_select_engine_n, which selects the EMC computational engine out of several possible engines within STAR, and vme_write_n, which enables writing to the control registers within each Level, each F PGA. The data written to these registers comes from id, the instruction data, which is 16-bits in width. This data is then placed at a register location specified from ia, a 4-bit instruction address. When writing is being performed Table 3.1 -Level 1 Trigger Signal Summary Name Bit Width Direction Description Clk 1 In 38MHz clock; also known as clk36 let 1 In Active high asynchronous reset vme_select_engine_n 1 In Active low engine select vme_write_n 1 In Active low control write enable la 4 In Engine instruction address Id 16 InlOut Engine instruction data trigger_tower (0-9) 6 In Trigger tower energy; 10 total signals high_tower (0-9) 6 In High tower energy; 10 total signals engine_ack_n 1 Out Active low indicating engine received & executing instruction; high indicates engine is ready engine_output 16 Out Level 1 engine output on these registers indicated by the vrne signals, engine_ack_n goes low indicating the instruction has been received and is being processed; all other times this is high. Figure 3.4 - Level 1 Trigger Macro 24 llZi;’Ti‘.:.. ‘ 4%,“. : «0": v, “\Q‘CL u ”II . \ Elf. 3772712 0i i' 5 - v p I Pettinifll 0r: .1... . L. Hie 'c-di “1..“ TR 11“» L' Q .._~ ‘ 57.11.46”? 'i‘i' ' i kill L... \.»5| 1 Internally, the Level 1 trigger is similar in structure to what has already been discussed with regards to timing. First, is the control section that deals with the reading and writing of the control registers. Secondly are latching and buffering operations performed on the input signals. Also crucial are both computational sections that do all of the real work. Finally are the latching and buffering operations of the output signals. The level operations (10) are the most important portion of the design. This area specifies the parametric threshold values needed for proper filtering of the data. Signals la 4 \\ id 0°- \1 triggermwerleveI(D-2) - vme_engine_select_n _ \6 high lower level (0-2) * vme_write_n Leve' ReacVWrite a ratio level (02) and Order \ = Operations en ine ack n Figure 3.5 - Simplified Level 1 Trigger Control vme_select_engine_n, vme_write_n, ia, and id are only applied to this area and no other. Three threshold levels for each the Trigger Tower, High Tower, and the Ratio are assigned here for use in comparisons in the el stage. Greater detail of the control operation will be discussed in the Chapter 5. Trigger Tower and High Tower signals are latched safely after 1.5 clocks. It is at this point that the data if valid for the first engine stage, e0. After 1.5 clocks, the 10 25 r~~a P a..- _.T u. \ Fil “i:f"‘i~‘ ‘c3-Lfllihc 'a-. -. \ 5:- :5. 1 u C. \ :75 ' q \ h .. n". ."‘ P d. ~:.~A ‘.J . .g‘ - I" .1". " AI. ‘41 ‘ 1:... . ~4_. :- A latched and buffered Trigger Tower signals are passed to the energy summation macro. Latched High Tower signals are sent, along with Trigger Towers, to the first stage of the Trigger Tower ((3-9) \0 ‘ \ r G 2’, CD .9 High Tower (0.9) \0 “L N ; g s (D g D) C I.Ll M5,), Tngger Tower Latched Leve|1 \8 (0-9) Sum of 10 Energy ‘ Trigger \ Towers Partial Ratio \8 Ratioomg) 9 Triaggrrlto \ Partial \ Towers 9 Ratioi (El-9) ngh \ - Tower Leo) Latched (Cl-9) cl 6 Figure 3.6 Simplified ei and e0 Stages for Level 1 Trigger Engine 0 Pipe (e0) V ratio or divide macro. During the l clock cycle, a full summation of all 10 Trigger Tower energies and the 10 partial ratios are performed. These are then passed to the next stage of the pipeline. Ratios of the Trigger Tower to the High Tower, always less than 1, are completed in the next stage, el. Final ratios, as well as the Latched Trigger and High Tower Level 1 Level 1 Energy \10 110 Energy , ‘ ‘ Ratio Level (0—2) 8 ' Partial , , x c 3 Ration (0.9) \8 g \g‘ Ratio Final Ratio (03) A Umpare +1p Partial 3 "3151 Ag] Ram“ (09) g E \8 - Towers High Level (0-2) \3 4 D \ in 181) High Tower (El-9) é Compare —\3—+ g) \ C UJ Trigger Level (0—2) \8 sum.» Trigger Tower (0.9); : Compare Ai—e \ Figure 3.7 - Simplified Partial e1 Stage for Level 1 Trigger #1 26 {337365 £61.“. 3:31 They: ‘I A ~- Energies are then compared against the threshold values set in the control portion, with those greater than the levels assigned a high value indicating a significant event. For each category, 30 comparisons are performed generating 10 values for each threshold value. These values are OR'd together to indicate that at least 1 of the signals exceeded Compare OR’d Results \3‘ (gagitpgée \\2A ’5‘ 9.3, OR'd Results 3 Compare 2 if .331 Compare % Encoder \‘ ‘1'; 9; '9- 16 a 10 it \ ~ 5 are 0 E 3 Compare ORdResults {3* E%?::; \2- ”g; 9 10 “J Leveli Figure 3.8 - Simplified Partial e1 Stage for Level 1 Trigger #2 the level. The final 3-bit result is then sent into an encoder that reduces the information to 2-bits. Trigger Levels bits, 6 of them in total representing Trigger, High, and Ratio threshold comparisons, and the lO-bits of the energy sum are concatenated together and clocked into the el pipe after 1 clock cycle. Finally, after an addition 0.5 clocks, the results are buffered and sent externally to the next level. 3.4 Level 2 Architecture Level 2 trigger is significantly less complex than the previous design, but harder on timing constraints due to wider internal signals. Operations such as compares and additions become more time intensive due to these wider signals. However, it still 27 .'w‘ m )r. IE1.\II-o.‘l|i|.\ I 1 9 ‘n'w- , . - ii. 5.1.415. U <""‘J]\ y'l ‘1 in u ... 7‘ .' bmmfllo 5 £11 ' er 1 1 '1 Cg M iv a“ 11:. performs most of the same functionality as Level 1 excluding operation of the high and ratio signals. Signals into the Level 2 trigger are nearly identical to that of the previous trigger as seen in Figure 3.10. All control signals are identical and perform the same Table 3.2 -Level 2 Trigger Signal Summary [Name Bit Width Direction Description CIk 1 In 38MHz clock; also known as clk36 Rst 1 In Active high asynchronous reset vme_select_engine_n 1 In Active low engine select vme_write_n 1 In Active low control write enable la 4 In Engine instruction address Id 16 InlOut Engine instruction data Ievel_1__energy (0-7) 10 In Level 1 energy; 8 signals Ievel_1_triglev (0-7) 6 In Level 1 trigger level bits; 8 signals engine_ack_n 1 Out Active low indicating engine received & executing instruction; high indicates engine is ready engine_output 22 Out Level 2 engine output fimctionality as in the previous case. Differences occur in the data signals, where the Level 1 energy and trigger level bits are latched into the design instead of the Trigger and High Tower energies as in the previous case. There are two options that can occur based upon a per implementation basis. Figure 3.9 — Level 2 Trigger Macro 28 13...”... 3' ‘ I ' L~‘€a a h'a::¥ .. (“I '..L. 4 d6.” ‘ ' ' I _fl} fik‘LC xdlbu\ ' ‘v‘.-.O.-q - .‘ :Lifiéhuk 4!} L N 1 o ‘ .‘F‘ ’1"- ‘9‘ ‘f‘ . LLK -k.'c..\‘ I kind L" l 1 a .L. ”A In M." g I . . 3".“‘7 ”‘r \O. ‘.\“‘L': aI-AAL,“ an Level 1 trigger generate 30 sets of signals that must be analyzed, an odd number, which is not fully devisable. It was decided that for 2 of the Level 2 triggers, 8 sets of signals would be attached as input, while 7 sets of signals would be attached as input in the other case, giving a total of 30 signal sets. The unused inputs for the latter case are grounded indicating an effective energy of zero with no threshold values met. This does not alter the functionality of the design in any way, it only allows for one consist design to be used for the Level 2 trigger. In the control stage (lo), only one set of level registers exists to provide the data filtering functionality. Three threshold values for the sum of 4 Level 1 trigger energies, l3 4 id 10 vme_eng‘ne_select_n _ and Order Operations I glkflfi . > \13 level 2triggerleveI(D-2) _ engine_ack_n ‘ll Figure 3.10 - Simplified Level 2 Trigger Control or one half the Level 2 energy, are provided to fulfill design requirements. Based upon the previous discussion, either 7 or 8 sets of Level 1 trigger energies and level bits are latched afier 1.5 clocks during the ei stage. In the first engine stage, three individual sums are performed on the energy signals. First, a full sum of all energy 29 signals is performed. Secondly, two sums of 4 energies are done for use in comparisons to threshold values in the next engine stage. Level 1 Trigger Level bits are passed Level 1 Energy LBVBI 2 Level 1 Energy (CI-7) \10 Latched Sum Ener fl fl \10 (0'7) - of Level 1 \14 gy - Q Energy 8 Level 1 Trigger Level B. 1’2 of £3. Blts (a?) \o g \6 (0-3) 1r2 Sum Leve' 2 E; x a or Level 1 +__93___.‘° 5"” g 5 Energy a.) “g’ 1/2 of g g (4-7) 1r2 Sum Leve' 2 63 of Level 1 W Ener limp. gy > ; Level 1 Trigger Level Bits Latched (0-7) to e1 Figure 3.11 - Simplified ei and e0 Stages for Level 2 Trigger directly from the ei pipeline to the el stage, while the sums are latched into the e0 pipeline. The full Level 2 energy signal is passed directly from the e0 pipeline to the el pipeline. However, the half Level 2 energy signals are compared against the threshold Level 2 Level 2 Energy \14‘ co Energy ‘ \ \ v- U2 of Level 2 A Level 2 Trigger Level (El-2km Energy 1, 3 ,6 ‘ A Compare 3 m V \ ++ \ 8- V 10 of Level 2 3 Level 2 Trigger Level (02)” Energy ,5 m ,6 ‘ ‘ Compare 3 s c x - AV—fi \ “a, \ C [U 2115;1qu Figure 3.12 - Simplified Partial e1 Stage for Level 2 Trigger #1 values from the 10 stage, or the control module. The bits from these comparisons are then 30 Compare OR 0 Results \3- (gaging: \fr '8‘ .03. Compare E '58- .E'é ‘5 CL \22- g- +fi22 Levell Trigger Levell 8 3 Level Bits '5 Tri er \0- a “E _4‘.’ 99 \ c) Latched (0-7) Level Bits LE LICJ from el 0R r41 Level 2 Energy Cl 3 > .QIJQQ.> Figure 3.13 - Simplified Partial e1 Stage for Level 2 Trigger #2 OR’d together to indicate any threshold crossing that may have occurred. All of the Level 1 Trigger Level bits are un-encoded, OR’d together for indication of threshold crossing, and then encoded again into one signal. 3.5 Level 3 Architecture Similarities between the Level 3 architecture and Level 2 architecture are abundant; they are nearly identical. As a growing trend from level to level, however, is the increasing internal signal width within the design. Significant timing problems resulting from the aforementioned trend made the design of the Level 3 trigger the toughest to meet the given timing constraints. Again, the signals for the Level 3 trigger macro are nearly the same as the previous design, with the exception of the input and output of the data signals. Control lines are the same as in previous design. The difference occurs in the data signals where all the sets of signals from the Level 2 triggers are latched for use within the design 31 Table 3.3 — Level 3 Trigger Signal Summary me_select_engine_n me_write_n level_2_energy (0-3) level_2_trlglev (0-3) ngine_ack_n ngine_output Bit Width 1 1 1 1 4 1 1 8 26 Direction Description In 38MHz clock; also known as clk36 In Active high asyncronous reset In Active low engine select In Active low control write enable ln Engine instruction address InlOut Engine instruction data In Level 2 energy; 4 signals In Level 2 trigger level bits; 4 signals Active low indicating engine received & executing instruction; high indicates Out engine is ready Out Level 3 engine output instead of Level 1 signals. level2 energy (El-3) 314 lewl2_mgw (0-3) ‘8 la \4 \ id as \ vme_write_n vme select eng'ne n rst clk .— ‘> engne ack n Level 3 $ engine_output Figure 3.14 - Level 3 Trigger Macro The level operations (lo) or control stage offers nothing new over the previous design. Again, three threshold values can be set to compare against the final energy value calculated in the computational stages. As in the previous two cases, the control signals to and from the 10 stage are the same. Four sets of signals from the Level 2 triggers are latched into the ei stage to the e0 stage after 1.5 clocks. During the e0 stage, the four signals representing the Level 2 trigger energy are summed to determine the final energy level for the STAR detector. 32 I I I II I ll 7 7 C» 5 N10] 0 \. hill“ n\ v. . . h . \ P» b 9 . \. W n o '- ulnmru .y .c. w.“ F . b 1‘ . I‘ F . . .ln‘. . _. ink 2m .\ ed -1. MN; ”m ”N «K as . an . WU 0Q A. N a . “up; ~\ PS .1 . I . . c I d . . I iv v d n L a a" a . . k ‘51» or 3 . rlilu ill ill a ad u .1. i. l 9% r l. Lian , V 1hr... .\c at» Ll» : s 134 x. .4. lat .Mws rl - f 1...... new. law . me. .i “ Level 2 Energy (0-4) \14 Level 2 ‘ ‘ Energy 5 Latched Sum léevel 3 fl "’ - ner :3 Level 2Trigger Level 3 21:4 (0 7) - of Level 2 \13 gy - .03, Bits (0-7) a 0- 8 Energy 8 k g \ at E Cl 8” r: [U LU MD m> ; Level 2Trigger Level Bits Latched (El-7) to e1 Figure 3.15 - Simplified ei and e0 Stages for Level 3 Trigger The value is then passed into the e0 pipeline for use within the el stage. Level 2 Trigger level bits are passed directly from the ei pipeline to the el stage. As in the previous cases, the final energy signal is compared against three Level 3 Energy 8 Level 2 3 Level 3 Trigger Level (El-2) 16 Energy 8. 3‘ 3 goA E \16 Compare .\__. \ O V (D E U) C UJ Elkafi .> Figure 3.16 - Simplified Partial e1 Stage for Level 3 Trigger #1 threshold values. Level 3 energy signal is passed from the e0 pipeline to the el pipeline. The comparison bits are then encoded and passed to the el pipeline. Level 2 Trigger Level bits are, un-encoded, OR’d, encoded and passed to the el pipeline stage. These signals are concatenated and sent to the engine output stage. 33 7.’EI " a Iii!» v 'I‘.‘ ~‘D A .1 H' v .1 D ‘ 5.1. " KL, ' CTLJL‘ W;K.’ ' ‘ 3 Compare Compare \\ ‘ Encoder \ 3 A O 31.3. H OJ ‘6 .9.- w 0. OJ H . .9 a Level 2 Trigger Level 2 CL AEL *5 —\2°—. LBVBI Bits 8 Trigger \8‘ '— O Latched (04) ‘ Level Bits \ 3%.), E from ei OR LE 3’ UJ Level 2 '43 Energy CIKQE, M> Figure 3.17 - Simplified Partial e1 Stage for Level 3 Trigger #2 3.6 Summary The purpose of this chapter was to provide an overview of each level’s architecture. Although the designs are straightforward in structure, meeting both the space and timing requirements was a tough challenge. It ofien required recoding the underlying modules several times in order to meet these opposing goals. Intimate knowledge of the hardware structure of the targeted FPGA was necessary in order to achieve success. Success also depended on the application of algorithmic techniques in order to suppress synthesis tool weaknesses and to enhance overall performance. In Chapter 5 the use of these ideas will be explored as the embedded macro modules are explored in full detail. 34 Chapter 4 PC-Based Implementation An interesting idea that came about while designing each Trigger level was the thought of doing such a task on a microprocessor-based system. To meet such an idea, a one-processor (Pentium II) system was employed to perform all of the calculations of every level in software. Without much knowledge of such a design, it is hard to imagine such a system capable of handling the demand of calculations. While this is true, it was not the intent to recreate an exact performance and functional model in sofiware, rather to view its performance as compared to the specifications and to make a judgment on the possibility of an expanded system meeting such needs, which is the focus and intent of this chapter. 4.1 Motivation Clearly, the sofiware industry has expanded, especially over the last decade. Because of the Internet, computers have gone mainstream and nearly everyone has daily contact with said devices. Such widespread use has caused a nearly unthinkable and 35 inmenmhm. wnpzns.lhcth urine is mien-g. '25 projects. I Ewen PCs or “\Vintcl" ‘ hmflehnv haematolfl Emitter. Sill} FPGA-hated W“. The ahl 2;: ”$51350 fieid. , Emmeiomu acflyvhe} unprecedented reduction in hardware costs further expanding the use and popularity of computers. The thought of possibly using cheap PC’s for the STAR EMC computational engine is enticing. Thus its appeal due to cost, a driving force in all government funded research projects, cannot be ignored. There are an abundant number of software development tools on the market for PC’s or “Wintel” machines. Microsoft makes some of the best, most optimized tools on the market for x86-based systems. This is key, since performance is the most significant characteristic of the project. However, unlike tools like gcc for Solaris and Linux, they are not free. Still, the low cost of such tools is overshadowed by the high cost for each F PGA-based programmable board. The ability to program in C or C++ has become a requirement for success in the scientific field. Although some programmers may not have as sufficient skill as others, the today’s optimized compilers generally do a great job in translating high-level code to assembly, whether it is bad or good. This, however, cannot be said of VHDL. Synthesis tools, on the other hand, are still relatively young in their development as compared to C and some degree of skill is necessary in order to extract out the desired measure of performance. Because of this, non-recun'ing engineering costs for designing FPGA- based systems will most definitely be greater than that of standard software-based designs. 4.2 VC++/VB Program Overview In order to design a software-based implementation of the STAR EMC Computational Engine, Microsoft’s Visual Studio 6.0 was chosen as the software 36 l _ i ' inclement Zoo. . [DE lime-gram Dc | ifiiVISLi Belt. 3 m-lrrrrw‘r Kr” r“? “111.1: I 't‘ maxim of the There arc r (slayer: the fruit maiden. an 2; misting lurk 't med defiant V 9'. ,-.- \ «we warmed v D'Ll ll" -‘ ‘ - Q thlwn Marlee of C RITE? m1 development tool for the design. This design environment includes Visual C++, a design IDE (Integrated Development Environment) based off of the powerful C/C++ language and Visual Basic, another IDE based off of the Basic language. Each IDE, each programming language has their strengths that were used to maximize the ease and performance of the design. There are always two parts to a visual or graphical user interface (GUI) software program: the front-end and the back-end. The front-end is the GUI portion that provides a mechanism, an interface for user control and input, while the back-end does all the calculating work based upon the user’s intervention. Performance is typically crucial to back-end design where most of the calculation takes place, while the front-end design is more concerned with ascetics and easy-of-use. With this particular design, a Visual C++ DLL was chosen to provide for the back-end of the design due to the superior performance of C, while Visual Basic was chosen for the GUI. Three main functions were written in C to provide the performance estimating criteria of the software-based design. These functions deal with estimating the processor clock speed, determine the offset between time measurements, and estimating the time required to perform all calculations. Table 4.1 summarizes the function name and description. Table 4.1 — Software EMC Computational Engine Function Description Function Name Description GetClockSpeed Estimates the processor clock speed GetClockOffset Estimates the offset between time measurements GetExecutionSpeed Estimates the time required to complete engine The Pentium MMX processor was the first Intel CPU to feature a register specifically designed to count clock cycles. This 64-bit register, known as the time stamp register [4], counts the number of cycles since the power-up of the processor. Obtained 37 l mg‘. he use .2 @5565 helm-1‘. i.‘ . ‘O‘ZEN\ 99 ~. li.;fi Will: tree I A}. Lit" \ mg“ i ‘ h‘ \61 Tr“ \C‘ .I' . ‘ N.“ . ltNlZu.g Ir“ 1m ‘ . QM‘PICIC‘ 5‘31‘ In?» 1.143110“ though the use an assembly instruction, effective use of this register is key to obtaining accurate timing information. However, since the time stamp counter only counts the number of cycles, which is independent of time, it is important to estimate the processor clock speed to make use of the counter. It is also crucial to estimate the number of clock cycles between two consecutive reads of the counter to determine a baseline and an offset for these critical timing calculations. The functions, GetClockSpeed and GetClockOffset, perform these firnctions, respectively. All of the timing information is derived fi'om two assembly instructions, rdtsc and cpuid [6]. The instruction rdtsc reads the time stamp counter and places the 64-bit value into the edx and eax registers, with edx containing the higher 32-bits [13]. This is a non- serializing instruction, which does not necessarily wait for all previous instructions to complete before it reads the time stamp counter. In order to provide accurate timing information, all instructions must be completed before the register is read. Thus, the pipeline must be flushed or serialized before execution of rdtsc. A serializing instruction, cpuid, is placed before read of the counter to insure that all instructions have been processed. The combination of these two instructions, with proper use, gives a means to derive accurate timing information on a Pentium II processor. The final C code function is GetExecutionSpeed. This function takes the timing information derived fiom the previous functions and performs all the calculations for all EMC levels in software. The calculations are done at a higher precision than needed, 16- bits for the 6-bit unsigned energy values, but this is an unfortunate result of the specified instruction set of the processor; these calculations could not be done in any other manner due to the inflexibility of the Pentium II architecture. That said, this function does 38 c... .9 , Q ..... JA‘L uteri a” l (3:. '— ..r. Bret $1.5” A4" n‘ullu-ls. '7".\.v0 2. Lily. 1‘ . .‘r‘ SJ Ln): Tu“? um 7‘9; U estimate the performance of all calculations for one pass on the engine and returns the execution time, in nanoseconds. Using the functions described above, Visual Basic provides the rest of what is needed to complete the performance estimation. This includes an area to display information, as well as the ability to change the process priority. High process priority is important to insure that the OS minimally interrupts the process. Figure 4.1 is a screenshot of the program. EMC PC-Based Evaluator 5 2. w r': «our». . Figure 4.1 — EMC PC-Based Evaluator Program Screenshot 4.3 Results The EMC PC-Based Evaluator was run for the four different process priority levels: idle, normal, high, and real-time. Each was run for 1000 iterations to smooth any inconsistencies and to indicate a true and accurate response. Table 4.2 summarizes the results. 39 Ll‘f‘hifig .. Aime circuit - trz.\iueoi: mm needed. CPU pf Clocll Speed 44 08 w . Avg. Elecutlon Tm (ns) mom Mons "I “‘3‘? v. ‘ I ““1016 solutll Looking at the results it’s clear to see that a PC-based solution has no merit. The average execution time for the best result was only 43,556 ns. Comparing this to the target value of 315 ns, the software solution provides approximately only 0.72% of the capacity needed. Although scaling this to a multi-processor system would drastically Table 4.2 — EMC Software Results Summary CPU Pentium II Clock Speed 448.90753 MHz 08 Windows 98 Avg. Execution Time (ns) for 1000 Iterations Iteration 1 Iteration 2 Iteration 3 Iteration 4 Iteration 5 Avg Std. Dev. Idle 43919 44409 44205 44997 44457 44397.4 396.5763 Normal 44426 44520 44141 44106 43667 44172 333.9019 ngh 43461 43317 43546 43556 43784 43532.8 169.955 Realtlme 43435 43575 43513 43632 43781 43587.2 130.7524 Totals 43922.35 257.7964 improve performance due to the parallel nature of the calculations, such a design would be costly and not as flexible as an FPGA-based system. Additionally, the shear number of inputs into the system would be nearly impossible to interface with a standard PC thus custom electronics would be required in the this case as well. Overall, an F PGA—based design, although costly, meets performance constraints and provides the most flexible possible solution. 40 Chap FPGA-E 35rd an iixussion ahn it‘lh ' "“l( I , ‘ ”“0 tilt Qt lfili’éx \' Ll. 1‘51”“, 1 c 81‘13‘1 I “iii; 4. Mullet, d 32" Chapter 5 FPGA-Based Implementation After an overview of the top-level architecture for each trigger level, as well as a discussion about a possible PC-based implementation, the focus of the chapter will now shift into the details regarding the macro model specification, based on IEEE Standard Logic signals, for the components that reside within each top design. This will begin with detailed descriptions of the common components or those macros models used within all three trigger levels. Similar components, such as energy summation macros, will next be discussed. Finally, an overall macro taxonomy will be presented. 5.1 Component Design 5.1 Common Components 5.1.1 Full Adder (fa) The standard full adder circuit is crucial to implementing fast algorithmic techniques for macros such as multi-operand adders and multipliers. The full adder 41 v-r- :, . - 4 11'1" CJLul~ kw \\.5.u | situation bits :1 131:1“ in: ma. ma. compel ill-tin he come 5.12 lilo-111p" In order umpire: til 0 d 52:. 011.1131“ cl? bl: signal rm}: : Eric} is mdicail I . 213;! ch ; ‘tnl Wilt circuit used within this project provides the functionality of a basic adder, with two summation bits and a carry input. The characteristic output is one sum bit and a carry out bit used for ripple carry propagate adders. The STAR EMC Computational Engines internal components make extensive use of this macro to enhance speed and reduce size within the context of algorithmic VHDL design. 5.1.2 Two-Input Comparator (compare_20ps) In order to provide a facility for data filtering, a comparison macro, which compares two distinct signals of variable width, is needed. Specifically in this design, the signal op, the computed value, is compared against level, the trigger level value. The one- bit signal result indicates whether the computed value is greater than or equal to the trigger level as indicated by a high signal. As in the previous macro, this macro is used extensively throughout the design, but in this case as a compiler instantiated macro, not algorithmic. 5.1.3 Positive and Negative-Edge Latches (latch_clk36_p & latch_clk36_n) Input and output signals, as well as the internal pipelining structure of each engine, makes use of both positive and negative-edge triggered latches. These latches are of typical fashion with input, output, clock, and reset signals. The generic nature of said macro makes use of a parameter that denotes the width of the latch. The functionality of these components is well documented and the information provided is only mentioned in passing. 42 5.1.4 Compare 15 lists ' empresstt‘ to I ngievcontprrl result compare riddle. or high tireshid: exec 5.1.4 Compare Encoder (compare_encoder) As was mentioned in the Chapter 3, the output bits fiom the comparisons are compressed to indicate the highest threshold that was exceeded. The three-bit result, triglev_compare, from the comparisons against each trigger level is reduced to a two-bit result, compare_encode. An output value of one, two, or three indicates that the lowest, middle, or highest threshold value was exceeded, while zero indicates an error or no thresholds exceeded. This is simply done by seeing how many bits have been set and reducing this to a binary value. Because of this, the engine output is reduced by one signal for each trigger comparison. 5.2 Level 1 Components 5.2.1 Level 1 Trigger Level (level_l_trigger_level) Level operations, or control, of the Level 1 engine are firlly dictated by the macro 1evel_l_trigger_level. Its purpose is to provide a small memory location for storing threshold values for comparisons against the Trigger Towers, High Towers, and Ratios, which are used in the el stage. These 9 registers, representing 3 threshold values for each category, are controlled by external, off-chip signals directly passed to this macro. The interface to these signals, user defined VHDL types and subtypes of IEEE Standard Logic, along with others, are summarized in Table 5.1. 43 Table 5.1 — Level 1 Trigger Level Signal Interface Summary ame Bit Width Direction Description lk 1 In 38MHz clock; also known as clk36 Rst 1 In Active high asyncronous reset me_select_engine 1 In Active low engine select me_write_n 1 ln Active low control write enable la 5 In Engine instruction address Id 16 InlOut Engine instruction data Array of trigger level thresholds; 3 evel_1_triQIev (0-2) 8 InlOut signals Array of high level thresholds; 3 evel_1_highlev (0-2) 8 InlOut signals Array of ratio level thresholds; 3 evel_1_rationlev (0-2) 8 InlOut signals Active low indicating engine received 8 executing instruction; high indicates ine_ack_n 1 Out engine is ready The use and understanding of the above signals fully drives the functionality of the level operations macro. Arguably the most important is me_select_engine, the engine selection signal, which must be set low in order to activate any operation. It determines which particular computational engine control is being passed. The writing to the registers is enabled through setting vme_write_n low in conjunction with the selected engine. Register addresses, summarized in Table 5.2, are indicated by a 5-bit signal ia, the instruction address. Instruction data, indicated by a 6-bit signal id, which sets or returns data in the specified register. An asynchronous reset signal, rst, can be set high to clear all registers. Finally, engine_ack_n, is set low to indicate that an instruction is being performed, while it is set high when the engine is ready for computations. 44 Table 5 \ Register Address Nmmwa—Ao /., Table 5.2 — Level 1 Trigger Level Register Specification Summary Register Address Register Name Data Bit Width Description 0 emc_level_1_triglev_0_adr 6 A Trigger Tower threshold level 1 emc_level_1_triglev_1_adr 6 A Trigger Tower threshold level 2 emc_level_1_triglev_2_adr 6 A Trigger Tower threshold level 3 emc_level_1_highlev_0_adr 6 A High Tower threshold level 4 emc_level_1_highlev_1_adr 6 A High Tower threshold level 5 emc_level_1_highlev_2__adr 6 A High Tower threshold level 6 emc_level_1_ratiolev_0_adr 6 A Ratio threshold level 7 emc_level_1_ratiolev_1_adr 6 A Ratio threshold level 8 emc_level_1_ratiolev_2_adr 6 A Ratio threshold level 5.2.2 Level 1 Ratio (ratio_e0 & ratio_e1) A key event indicator as theorized by the physicists who will eventually use the data collected from STAR, is the idea of a ratio or division of each Trigger Tower by the corresponding High Tower. They have debated as to the usefulness of this portion of the design, but, as of now, it is crucial. Since the Trigger Tower is an average of 16 different energy signals, and the High Tower is the highest of any of these signals, the generated unsigned ratio will always be less than or equal to 1. Although this sounds simple enough, in order to meet timing and functionality requirements, all 10 divides must be done in parallel. In addition, timing is so tight that almost all known divide algorithmic techniques are unusable for F PGA’s. Each of the 10 ratio signals must be completed early in the el stage so that the Comparisons in that stage can be performed correctly. Because of this, most of the work for the ratio must be done in the e0 stage, with little left to do for the el stage. Typical add/ Shift methods for performing division are too slow in yielding the result. An 45 ,l. ... 215.74.. '6 mt“ 11317360? iiit‘ l apprilzrzrtn; Ro‘A‘ ~ *u “3 «\l "rite the .3 ”NC 1311" i1 385“” 03.2” 'slll s C? alternative method is division through multiplication [4]. In this scenario, the numerator, N, is multiplied by a scaling factor, R, to produce the quotient. The scaling factor is the inverse of the divisor, D. The problems with this technique are errors associated with approximating the inverse and the size of the lookup table containing the inverse values. Reducing the error in computing the inverse of a number is simply a matter of increasing the precision of the inverse. For this particular macro, the 6-bit value is mapped into an unsigned 12-bit inverse value, with the highest inverse bit having a weight of 2”“) and the lowest bit having a weight of 2**("2). Thus, on average with 2**(-1) 2'*(—12) D f ‘I’ 'l' ‘I' t t t ‘I’ ‘I' ‘l‘ I * Figure 5.1 - Inverse Mapping Strategy this particular mapping, the error associated with each division is approximately 0.17%; this is negligible in the context of its use of data filtering. However, this increased ' precision slows down the calculation and increases the size of the 64-entry lookup table. The first step in the multiplication speedup is through partitioning and padding of the numerator and inverse values. The 12-bit unsigned inverse number is broken into three 4-bit sections, Rh, Rm, and R., with Rh containing the highest 4-bits. In addition, the 6-bit numerator is padded or sign-extended with 2 zero bits and broken into two 4-bits sections, Nh, N, with Nb containing the highest 4-bits. All combinations of blocks are multiplied together to produce an 8-bit unsigned result. Specifically, N. * R], N. * Rm, and so on until all possible combinations are produced. This parallel, block-based approach helps to increase speed by performing several faster multiplications as opposed to one slow multiplication. 46 Pmflw -..‘ 67.; '. IDul'. CIIIL‘ICF‘I... .‘ ‘ . . INF. 9.70“) lo 5 13811611 due mm the in‘ the multiplh; met} INC (93' Sal e A b I. 1 IF" . M“) PM; + Performing several multiplications can improve speed, but totaling up the final result efficiently is a problem. By multiplying a 12-bit number by an 8-bit number, the result grows to 20-bits, of which only 8-bits need to be kept. The bottom 4-bits are Discarded Saved Discarded OUUUUUUU.‘ttttti-tt 521114) 2tt(_8)£ I I l l lt‘l‘tt l Figure 5.2 - Portion of Ratio Result Saved discarded due to loss of precision, and the upper 8-bits are discarded since they will contain the integer value, which is zero. Using these rules, the 8-bit result blocks from the multiplications are added up in their correct spatial alignment; this is the same strategy used on simple multiplication rules. In order to add several blocks efficiently, a Carry Save Adder (CSA) [4] technique is used to reduce several blocks down to 2 8-bits blocks, product_0 and product_1 in the e0 stage, illustrated in Figure 5.2. Rh Rm X Nu NI FF; N. Rm ’ NI 1 thN. Ru * Nh l Rm wh ' operand_0 ‘ operand_1 : Figure 5.3 — Simplified Ratio Technique for e0 Stage 47 Although this handles most possible results for the ratio macro in the e0 stage, there are two special cases that need to be taken into consideration. First, if both the numerator and denominator are the same, product_0 will be set to all 1’s while product_1 will be set to all 0’s indicating a ratio of approximately 1. In the second special case, where the denominator is zero, the same approach is applied. Both of these cases are done through a behavioral VHDL assignment process. To complete the ratio process, a Carry Propagate Adder (CPA) is used to produce the final sum of the 2 operands in the el stage called product. By insuring that the addition is of nibble or 4-bit width, the synthesis tool uses the fast hardware adder logic in the Lucent FPGA to implement the adder insuring the fastest possible 2-input adder. Therefore, this adder is implemented by the synthesis tool and not through an algorithm as in the case of the CSA. Any algorithmic technique would not be faster than the hardware support instantiated through the code and the tool. 5.2.3 Sum of Trigger Tower Energy (sum_trigger_energy) As discussed previously, a sum of all 10 Trigger Tower energies has to be performed and passed to the Level 2 trigger. This is another time critical component that has to be specially and carefully developed in order to meet all functional and timing specifications. Simple application of the standard addition function in VHDL for each addition is too slow and the synthesis tool can only optimize for a 2-operand case and not for multiple operands. Therefore, a different algorithmic technique must be applied in order to extract out the best possible performance. This is done through the use of several CSA stages and a CPA stage. 48 Alii‘il‘u': it m not dew to mother $1.": gt propagation its. irbll input and accepts hese re Treated until .1 mmmk In the xi Since it GCCCptx Mare. 11 "g. OffiieCSA. c. l: C '5 r. . - 353131313! 4. A (I (D Although the CSA algorithmic technique was mentioned in the previous section, it was not described in detail. The main idea behind and CSA strategy is to pass the carry to another stage of addition instead of letting it propagate throughout every addition; propagation thus will only occur in the final CPA stage. A typical CSA level accepts an n-bit input and produces an n-bit sum and an n-bit carry. The next stage in the CSA accepts these results along with another input to produce another set of results. This is repeated until a final 2-operand result is achieved at which time any standard CPA strategy can be applied to produce a final sum. In the simplest of circumstances, a full adder, commonly called a (3,2) counter since it accepts three inputs and has two outputs, is used as the basic element of the CAS structure. It “coun ” the number of inputs, in parallel, and passes the results to the rest of the CSA. Consider the 4-bit wide 4-input case (w,x,y,z) shown in figure 5.4. X31623 x238212 X13112, Xooze ------I-l-- ----i—-l-i----- i—l : (3.2) CSA . Figure 5.4 -- A CSA for Four Operands [14] Carry bits from the ith column of the ith stage are passed or “saved” to the i +1 column of the 1' +1 stage. Sum bits are passed from the ith column of the ith stage are passed to the 49 it seem o: I and a h".itll'.‘.l)f.. fine lint? CPA s where I is the r isla'gel) rec'ue This It‘t‘ tigger‘loal er_ I Taggirt'rnt’nls. 1 Sage: required stage is instant". fittest possible meter that W Le 52.1 Final 1 Listt ith column of the i +1 stage. As shown, this continues until a 2-operand case is developed and a traditional CPA stage is applied. The number of CAS stages required to produce the final CPA stage is approximately Number of levels ~ log(k/2)/log(3/2) [14] where k is the number of operands. As one can easily see, the overall signal propagation is largely reduced fi‘om a typical multi-operand massively propagated case. This technique is applied to the sum of the 10 6-bit Trigger Tower energies, trigger__tower__0 through trigger_tower_9, in order to meet the critical timing requirements. In this case where the number of operands is 10, the number of CSA stages required is 4. A final CPA stage is used to produce the final result. This CPA stage is instantiated through the compiler, using nibble width operands, to insure the fastest possible unsigned adder. The final result is the fastest possible multi-operand adder that was designed for this design. 5.2.4 Final Trigger Level 1 Taxonomy Listed below in Figure 5.5 is the final Level 1 Trigger taxonomy. q I I I I I I I I I I I I I I I I I I I I l I I I I I I I I I I I I I I I I I I ‘ ETOD OIDESIQII level_l 1 3+ compare_2ops ' """""""" “mung...“ nmde ElC-gslhgrfigrfitifsic _. sum_level_1_energy é. EI—p Iatch_clk26_n ggmghgntsj :5 I—. ratio_e0 _§_ §_, latch_clk26_p ' 5: ratio_ e1 3 4: ~ fa E Figure 5. 5— Final Level 1 Trigger Component Taxonomy 50 5.3 Luelll 53.1 [ml 2 l Functét Liggc: lead. ' we on!) one : mum: at lover. and R. * Q Windham, Tah Register Addr / —. 5.3 Level 2 Components 5.3.1 Level 2 Trigger Level (level_2_trigger_level) Functionality of the level_2_trigger_level is identical to that of the previous trigger level. The difference between the two exists in the data registers, where in this case only one set of registers is needed. The comparison levels used within this component are for the 1/2 sum of the level 2 energy instead of the Trigger Tower, High Tower, and Ratio levels as in the level 1 case. Table 5.3 summarizes the register specification. Table 5.3 - Level 2 Trigger Level Register Specification Summary Register Address Register Name Data Bit Width Description 0 emc_level_2_triglev_0_adr 16 A 1/2 Level 2 energy level 1 emc_level_2_triglev_1_adr 16 A 1/2 Level 2 energy level 2 emc_level_2_triglev_2_adr 16 A 1/2 Level 2 eneLgy level 5.3.2 Sum of Level 1 Energy (sum_level_1_energy & half_sum_level_l_energy) The 8 unsigned level 1 energy signals are summed in the same fashion as the previous trigger. However, for level comparison purposes, the 2 half unsigned sums are also calculated in parallel with the total sum. This additional hardware space is insignificant, but the benefits of increased speed and reduced complexity are necessary. The total sum macro, sum_level_1_energy, sums the level 1 energy inputs level_l_energy__0 through level_l_energy_7 and produces a final unsigned sum level_2_energy through the use of a CSA structure. Additionally, the half sum macro, half_sum_level_l_energy, sums 4 level 1 energy signals through the same technique. The total energy sum macro was added since the sum of these two half energy components would not complete fully in the e0 stage. 51 533 ORing 0 Due ll' Io prmidc the . mm sing. Okng of " l 0“ “mid produce 610666611; this '. ‘11"."10".'~f.; QWIi-Lii); It ‘1 Al ”(V585 that red The trig acarding m rm. dl:‘Er’eonaniruh‘ b1tare an dune m OR‘d \alu 5.3.3 ORing of Level 1 Trigger Level Bits (level_l_triglev_or) Due to the compacting of the trigger level bits, a special component was created to provide the data ORing of the trigger level bits fi'om the first trigger level. This is necessary since a direct ORing of data values would produce an incorrect result. A direct ORing of “10” and “01”, indicating that the lowest and middle levels were exceeded, would produce an incorrect result of “l 1”, indicating that the highest threshold was exceeded; this is unacceptable. To produce true and accurate results, these values of “ll”, “10”, “01”, and “00” must first be expanded to “100”, “010”, “001”, and “000”, respectfillly, then OR’d, and finally re-compressed. This is a simple but necessary process that reduces the number of output signals. The trigger level bits, level_l_triglev_0 through level_1_triglev_7, are expanded according to their binary value then OR’d and assigned to level_1_triglev_or. This is done on an individually basis. The Trigger Tower, High Tower, and Ratio trigger level bits are all done individually, just as in the top design, and concatenated to produce the final OR’d value. 5.3.4 Final Trigger Level 2 Taxonomy Listed below in Figure 5.6 is the final Level 2 Trigger taxonomy. 52 Level Specific Components """""" 15 iare‘ge‘fiixe‘igei 2Trigger Canaan; 5.25.135; ' ’ ' ' ’ ' ' ' ' ’ ' —e level_2_trigger_level L, sum_leve|_1_e nergy 1 half_sum_level_1_energy 4 level_1_triglev_or -1—————--—-—-—--—--fi-— —r compare_20ps _ompare_encoder Common _v '3tCh_C'k25—n Components _J latch_clk2 6_p - fa 5.4 Level 3 Components 5.4.1 Level 3 Trigger Level (level_3_trigger_level) The level_3_trigger_level is identical to that of the level 2 trigger level except for the naming of the data registers. Table 5.4 summarizes this register specification. Table 5.4 - Level 3 Trigger Level Register Specification Summary Register Address 0 1 2 Register Name emc_level_3_triglev_0_adr emc_level_3_triglev_1_adr emc_level_3_triglev_2_adr Data Bit Width Description 16 Final Level 3 energy level 16 Final Level 3 energy level 16 Final Level 3 energy level 5.4.2 Sum of Level 2 Energy (sum__level_2_energy) As in all of the previous cases, this 4-operand unsigned adder uses a CSA StruCtur-e to produce fast, accurate results. The inputs level_2_energy_0 through leVel \Zhencrgyj are summed to produce the final trigger energy level, level_3_energy. 5.4 ‘3 ORing of Level 2 Trigger Level Bits (level_2_triglev_or) 53 Mm? Mmkwll rmylmcii larlFTUg: nmaMm lemfll, Una Mmmy Y (r- "A 4C-‘ Qfi‘ ! PJL__,4 I,‘ ' 5e"'c{‘.tr:.“ .. \~-_ A VJ~1'_-F:pr._ F' "v H: ’. ‘- .. ‘- " Identical in functionality to the second level OR component, this macro takes the inputs level_2_triglev_0 through level_2_triglev_3 and produces the final trigger level bit array, level_2_triglev_or. This signal, along with the additional bits generated from the Level 3 Trigger, are the final data filtering bits used to determine the significance of the event at hand. 5.4.3 Final Trigger Level 3 Taxonomy Listed below in Figure 5.7 is the final Level 3 Trigger taxonomy or component —p compare_20ps I l 5‘ u 0 * U ("D 9. (D 3 co ------------------------------------ _. level_3_trigger_level _ompare_encoder —-—---J Common Level Specific Components Components —u |atch_clk2 6_n _y sum_level_2_energy i .1, level_2_triglev_or _.. latch_clk26_p + fa mg... 5.7 _ Final Level 3 nigger 65.355555; T551165; """""" 5 -5 Summary Details of each component of each level were summarized within this chapter. This detailed description of each macro, in addition to the Trigger Level overview of Chapter 3, should provide an accurate and vibrant account of the overall design. Details or each component’s code can be found in Appendices A-D. The following chapter, Chapter 6, will focus on the synthesis results of each Trigger level. 54 ¥ Simulai NO“ [1 W015 Chap Meme) pr mine 0i the Chapter 6 Simulation and Synthesis Results Now that the design has been fully modeled and described in detail in the previous chapters, the synthesis of these designs to hardware will be discussed. The challenges, problems, and pitfalls of this process will be elaborated upon throughout the course of the chapter. Finally, the results from synthesis of all three levels will be stated and the design requirements will be confirmed. 6-1 Overall Design Methodology In order to fully realize the design, both in terms of functionality and timing, a Specific design methodology was followed. This included both a strict design flow and the Preferred tools to complete the final design. Figure 6.1 shows the process by which this Was accomplished. The double arrows indicate that several passes between each step Was Performed to satisfy all requirements. This was performed mostly at the functional 8. Ill—1‘11 ation and synthesis steps, a byproduct of attempting to meet both the functional and tin-1 - 1118 requirements. 55 Functional Simulation VHDL Design Files (Active-HO L) (Notepad) d 1 Synthesis (FPGA Express) J Timing Simulation Implementation (Active-HO L) (ORCA Foun dry) Figure 6.1 — Overall Design Methodology The VHDL design source files were created separately in Window’s notepad and then simulated in Active-HDL, an HDL simulation tool from Aldec. Initially, each separate source file was simulated to verify that the individual, small task design file met functional requirements. For the total and complete simulation, however, all source files for a particular level, as well as a Testbench file, were simulated and verified as shown in Figure 6.2. The output waveform form Active-HDL showed the results from the stimulus VHDL Design Files ( .vh d) ll """""" l VHDL . . . Te stbench Functional Simulation (. vh d) ' (Active-H0 L) Simulation Waveform (.awf) Figure 6.2 — Functional Simulation Design Methodology applied by the Testbench and verified that the overall design functionality was met. 56 0:; .iithigan Si. Haiti er. {in ORICM. a due the Earl In {in package. H’l “Fifi the dc FPGA Elpn M13 i0? lhc musing lhfi eSlimd W ii it the SM ( pigs“ bet SWIM-Sis \ on FM. Cl‘l‘dEl} k Originally, the designs were to target Xilinx F PGA architectures, for which Michigan State University has full capability; this was around the beginning of 1999. However, the final target technology changed to a Lucent ORCA F PGA, specifically OR2C40A, a 40,000 gate-equivalent device. This placed a burden on finishing the design due the lack of sufficient synthesis and implementation tools locally at Michigan State. In the interim until a final solution could be reached, an evaluation software package, F PGA Express, from the leading synthesis tool provider, Synopsys, was used to verify the design. The functionally verified VHDL source files were synthesized by FPGA Express to produce an EDIF netlist consisting of interconnections of ORCA F PGA parts for the OR2C40A. A great feature, not offered on the Xilinx Tools supported at the VHDL Design Files (.vh d) 11 """""" 1 Synthesis Synthesis (FPGA Express) F—T Report File 1 (mt) EDIF Netlist (.edf) Figure 6.3 — Synthesis Design Methodology university, was a report file given for each run before the vendor place & route that gave the estimated timing performance. Having this information available made it possible to modify the VHDL source files before the lengthy process of implementation to improve the Speed of the design while still maintaining the identical functionality. Thus, many pasSes between the modification of the VHDL source files, the functional simulation, and S3’1'7‘thesis were performed to meet all the desired functional and timing requirements. Once the design was completed after numerous passes though the above tl”‘Odology, an onlrne tool provrder, www.toolw1re.com, was used to perform the final 57 ¥ minis .1 Express b} was tile iOOiS. A pr ' l “‘3'? e, mrMufi'nr. mm“ 0m i’ "c . er‘Wdlli) minim Hing 331' gmeialcd Pied: died 2 synthesis and implementation of the VHDL models with online versions of F PGA Express by Synopsys and ORCA implementation tools by Lucent. Again, the VHDL source files were synthesized, creating an EDIF netlist to be used by the implementation tools. A preference file, in conjunction with the netlist, was used to constrain the implementation tools by providing required pin locations and timing performance. EDlF Netlist (.edf) Preference File HDL or EDIF Macros (.prf) applied to (.vhd, .edf) Trani'ate all Stages Map + Place 8. Route : PAR Report it File (.gpr) Trace e Timing Report File if (Mr) Back Annotate 4r VHDL i Functional Bitstream Generator Netlist and SDF file i, (.vhd. .sdf) Configuration Bit File (.bit) Figure 6.4 — Implementation Design Methodology There were several steps involved with the implementation tools to produce the correct outputs, including the configuration bitstream and the needed files for design Verification. The translate and mapping steps took the EDIF netlist and flattened and mapped the components to the FPGA. Place and route took the mapped file, with the timing and pin constraints, and produced another, optimized, netlist. A PAR report was generated giving valuable information regarding pin locations and resource usage. Trace p r()(1110ed a timing report that gave the actual, accurate timing information for all nets w ‘ - I thln the design. The VHDL and Standard Delay Format file, used for design 58 ¥ imilulili‘? we (KNEE “it tiring 3m. . . ‘ . imam {making Milking fruits, 6'2 Test in W desig; \HDL Cod the slower verification, was generated in the Back Annotate step. Lastly, the configuration bitstream was generated from the optimized netlist for use in configuring the FPGA. The last step in the design methodology process was to verify the design still met timing and fimctionality requirements after implementation. This was accomplished by Back Standard Annotate Delay VHDL File (.vhd) (.sdf) VHDL Functional Simulation 15:?” _" (Active-HDL) 1 Simulation Waveform (.awf) Figure 6.5 — Timing Simulation Design Methodology simulating the back annotation VHDL file and the SDF file with the Testbench used for functional simulation. This process was performed in the same identical way as the functional simulation, with the addition of timing information, to yield the verified results. 6.2 Testbench Design and Structure In order to facilitate an organized, dependable, and accurate testing method for each design, an automated general testbench structure for validation was developed. This VHDL code provides a means to stimulate the engine and check the engine output against the expected output. Additionally, the level operations of each design, including the ia 59 it pit mi '; Oh: i vectors for v fuels. ens, design. \ Ski. his proud: A ra generator \\ ransom mi mitt-m O‘verioddc 53586: up: Meme} My. . Minion] n and id signals, are checked and verified. The testbenches provide a means to check both the pre and post-synthesis results. One problem in the verification in each design was the generation of the test vectors for stimulus. It was decided that a pseudorandom sequence of signals for the levels, energies, and trigger level bits was the best way to get accurate coverage for the design. Using this approach, longer testing times would yield better fault coverage and, thus, provide more solid verification of the design. A random number generation package derived from a basic C random number generator was developed as a package for use within each testbench. It provides for basic random number types, such as integer and real. These types support minimum and maximum values, an initial seeding value, and well as the pseudorandom number. An overloaded firnction, GeandNum, produces the random number given the variable and based upon the type. Given the testbench structure and the nature of testing, this worked extremely well and was the only viable method to verify the results. The code for this random number package can be found in Appendix A. 6.3 Synthesis Results The Synopsys synthesis tool, F PGA Express, has limited options for synthesis. One of the main options that are displayed on the initial synthesis screen is the option to synthesize for speed or area. If a designer wishes to compile for area, then the tool will try to fit the design into the smallest amount of physical resources as possible. However, in the case of the EMC, the option for speed, which maps the design to meet timing 60 m it. Will mil)? . Cli‘.’ ll'Zé probe) f anthers r. regimes. listless as ‘. Sifr'it’i' the: PAR rep): M We mam micro. iii Bream ( fainting 1 l Caicuiation i mm ’5 31th 0mm for a criteria, needed to be selected. By doing so, the design had the best chance to meet the tight timing constraints. Going into the synthesis of the Level 1 Trigger, it was apparent that the design was probably going to be too large to implement on the targeted F PGA. The initial synthesis run through F PGA Express yielded a design that just met the timing requirements. However, attempts at implementation through the ORCA tools proved fi'uitless as the tool ran for over a week with the results from initial iterations much slower than needed. The attempt to place and route 808 of 900 PFU’s, obtained from the PAR report, was not going to yield any results. After going through the various synthesis reports, the problem portion of the code was narrowed down to the ratio_e0 macro, an obvious culprit. The 6 multiply blocks per macro, for a total of 60 multiply blocks per F PGA, proved to be too taxing on the system. Because of this, the precision on the inverse was reduced from 12-bits to 8-bits, thus reducing the number of multiply blocks by 1/2, the ROM tables by 2/3, and the CSA 2"(-1) 2"(-8) U '1' I’ 1' ‘8‘ t ‘8' ‘8' ‘l’ 0 Figure 6.6 — Improved Inverse Mapping Strategy stage by 1/2. Although this reduces the precision of the ratio unit, the precision loss is not critical. By moving fiom a 12-bit inverse lookup table to an 8-bit inverse lookup table, the associated error grows from 0.17% to 4.44%, as shown in Figure 6.7. However, each calculation in each FPGA is done separately and each error is also separate. Thus, this error is averaged across the 10 calculations, as there is only one set of coded comparison outputs for all the ratios. Furthermore, the set of coded comparison outputs is averaged 61 across the 3 Smut 'les g 1... r c ‘ n (P. 5) ’V-'~' 'th-"‘ “'7‘" I.a mmSiQn Q “Ca .1' ‘ . 01'5“) (images i C , . “5771:1151 Ins across the 30 Level 1 F PGA’s, reducing the effects of the error and producing the correct output result, as shown in Appendix G. Average Percent Error for Ratio Lookup Tables [TTT‘TT T T T TTTW "‘ L—Z’Ye'f‘g‘i ”EEC"; Numberoialte Figure 6.7 — Average Percent Error for Various Inverse Mappings Once the ratio__e0 macro was remodeled, using the same technique with reduced precision, the Level 1 Trigger design was re-synthesized and re-implemented with no significant problems. Additionally, the Level 2 and Level 3 Trigger designs were also synthesized and implemented with no problems. Table 6.1 summarizes these results Table 6.1 — Synthesis Results Design it of PFU's (out of 900) Max Clocking Freq. (in MHz) Level 1 Trigger 619 39.14 Level 2 Trigger 212 46.49 Level 3 Trigger 103 53.62 obtained fiom the Trace report. It can be seen from the table that the level of complexity decreases with each design. This can also be seen from the code itself. The number of external signals that each design has to deal with, along with the number of calculations 62 ai it to pa. ' 1 minimum Cr 6.4 Simula mes hi it Expected re Which con: gm Sims “Winner, 3?) mi er making prcrbiem 5 ihe desire Tr Ramp rhr and iii lei “ith Finds accepting C fiOm [hf d ._ discrepant needed. or each has to perform, decreases with each design affecting the PFU count and the maximum clocking frequency. 6.4 Simulation Results Simulation of each design was performed at both the pre and post synthesis stages. In the pre-synthesis stage, the modeled functionality was checked against the expected results with no regard to timing. Usually in the post-synthesis stage a SDF file, which contains the timing information for the design, is used in conjunction with the given structural VHDL code created during the back annotate stage of the implementation. This could not be performed, however, since the SDF file created several errors within Active-VHDL when it was simulated. Therefore, only a functionality check could be performed after synthesis. This was not a tremendous problem since the timing was already verified from the implementation reports and only the desired functionality had to be simulated. The created testbench for each design has specific sequential tasks it performs on startup through the end of the simulation. Upon the initialization of the system, it is reset and all level registers are cleared out. The level registers are then loaded, one by one, with random level trigger values. Once the level registers are set, the engine begins accepting data and the testbench begins creating random data every 105 us. The results from the design are checked against results generated by the testbench and any error or discrepancies are reported back to the user. The simulation can continue forever, if needed, or until the user stops it. 63 npllg V L.‘u.‘. \ ¥ . I'- : rec . l‘ r. hm “\lu 11A. . Fit" ".7‘ W .V “MIN-hum". i ; ,, ufimflt‘ .1! Using the above procedure, each design was simulated using the design files, the testbench, and Active-VHDL. As expected and designed for, each design performed without error for a duration of 1 us, a fraction of the real running time, but enough time to determine any flaws in the resulting system. Appendix G contains the generated waveforms for each design. 64 C] Syr Per Chapter 7 Synthesis Coding Guidelines For Enabling Performance The underlying theme throughout this thesis has been the issue of performance and performance extraction from VHDL coding as applied to FPGA’s. Although the issue has not been explicitly singled out in previous chapters, it will now be explored in detail. Emphasis will be placed on coding techniques for arithmetic operations, but techniques for other types of operations, such as RAM, will also be explored. 7.1 Arithmetic Operations 7.1.1 Two-Operand Adders At the heart of most of this thesis were the use adders to sum the incoming energy signals into a resultant energy signal. The final stage in all cases, the Carry Propagate Adder stage, was a form of a 2-operand adder. It became apparent in the early stages of design that determining the fastest possible adder technique was necessary for completion of the project. This coding problem became a focus of some of the initial research. 65 Three adder-coding techniques, two of which are adder algorithms, were initially looked at for resource usage and speed. A simple ripple-adder, a carry-look-ahead adder [l4], and the “+” overloaded operator from the IEEE standard logic unsigned library were all compared for overall performance. Other techniques, such as the carry-skip adder and the carry-select adder were considered but ruled out. Each were coded in VHDL, each technique varying in 10 bit width from 4 to l6-bits, and synthesized for speed in Xilinx Foundation v1.5 and targeted for the XC4010XL 84-pin device, which is available at Michigan State University. 2-Operand Adder Resource Usage Bit Width Figure 7.1 — Resource Usage for 2-Operand Adder Techniques For each technique both the speed or maximum delay and the resource usage were examined and ordered for best possible performance. As shown in figure 7.1, the technique which consumed the least amount of resources was the “+” scheme while the CLA algorithm consumed the most resources. The same ordering occurred in regards to 66 the maxi CLA 31 r" u- y 5 Yimo (Hill) 85’ the maximum delay as well, where the “+” method proved to be the fastest while the CLA algorithm was the slowest. This is shown in figure 7.2 2-Operand Adder Max Delay [;Ripple~ i—CLA | || .*. . L-___._,_l Figure 7.2 — Maximum Delay for 2-Operand Adder Techniques Before synthesizing the VHDL code, it was thought that the CLA adder would provide the least delay but use the most resources; one of those was true. While the CLA’s performance was initially puzzling, it can be explained through the surprising results from the “+” operator. By looking at the post-synthesis reports, it can be seen that only the “+” operator enables the built-in fast logic on the XC4010XL [18] while the other algorithmic methods fail to do so. From these results, it appears that the compiler cannot interpret coding well enough to map to specialized hardware like fast-carry logic. In these general cases, it simply maps the equations through the lookup tables and interconnect lines, which is not the fastest possible result for FPGA’s. The “+” operator on the other hand, is mapped to the fast-carry logic since the compiler has an idea what is 67 mfcrrt‘c .. . :- lili‘udr'i I .‘piildii hale [h Foundfs ll 0ka 'I’ “ NOT: 7.1: .\r Mali) is) bei‘ ifin‘,» “Y‘crnf “CDC. inferred before compilation due to use of the standard IEEE libraries. This standardization is the only way the compiler has a chance of mapping functionality to specialized resources. The results obtained from the above experiments are supported fi'om previous work [16][l 1]. An additional adding technique not applied but discussed in this paper is the use of specialized “X-BLOX” components inferred by the “+” operator through Xilinx DesignWare [11]. Use of these specially crafied blocks reduces both the resource size and the delay time significantly. The drawback, however, is that not all vendors have the same level of support for front-end tools which enhance performance. Lucent Foundry tools are simply back-end implantation tools that have no support for design work. This limitation makes it impossible to supply the same coding styles across all vendors, all platforms. 7.1.2 Multi-Operand Adders Multi-operand adders offer a different challenge since there is no corresponding specialized hardware for their implementation. The question of coding becomes cloudier than before due to the above results. Instead of a clear-cut path to the best implementation, the question of whether algorithmic techniques will work as compared to inference through IEEE standard procedures looms. The answer to this question was needed since a majority of the work on each design revolved around multi-operand adders. Using the same strategy as before, two different multi-operand adders were designed in VHDL to sum 10 6-bit unsigned numbers. The first technique applied the 68 CSA dire: CSA/CPA algorithm described in Chapter 5 while the other applied the “+” operator directly 9 times and assigned the final result. The synthesis results are described in Table 7.1. Table 7.1 — Summary of Multi-Operand Addition Synthesis Method HMAPIFMAP Count Max Delay (ns) Plus 84 58.76 CSA/CPA 124 36.56 Although the “+” operator method produces a more compact result, the CSA/CPA algorithm is significantly faster. By looking at the synthesized circuit it can be seen that the “+” method applies the fast-carry logic over and over again. The first two operands are added through fast-carry logic, the resulting sum is added to another operand through fast-carry logic, and so on and so forth. For the CSA case, the carry bits are saved or passed from one stage to another and no propagation, like in the “+” case, occurs. The final CPA stage, inferred through the “+” operator, provides similar results as before. At times simple assignment through known standards, such as IEEE libraries, is the best possible coding solution. In other cases, algorithmic techniques are needed to extract the best possible performance. It appears fi'om these experiments that when known hardware exists which support the desired feature, inference through IEEE standards that the compiler can interpret is the best approach. This can apply to addition, subtraction, multipliers, and comparators where in modern FPGA’s fast hardware exists [15][1 8]. However, to ensure performance, a multi-operand case must be filtered to a 2- operand case to utilize the given hardware resources. Failure to do so will result in poorly implemented designs that can consume up to 50% more resources and be far slower [l 1]. 69 31 f 55) CT: precedes nthrrcri. wing fa millions iii-Picnic be fire; Varied Wilma Mfrs 7'2 0r. 73.1 E1 1 . r- mpm 7.1.2 Division Division is the most difficult arithmetic operation to implement. Although there are several different methods to perform division [14], there is no IEEE standard procedure for VHDL. Even worse, while there is direct hardware support for the other arithmetic operators, no direct hardware support exists for division. Due to these facts, coding fast and efficient division algorithms is wide open and there are several possible solutions to the problem. One very attractive technique used in this design is to turn the division operator over and make it a multiplication operation, one that has direct hardware support. By doing so, division is only limited by the possible error allowed by the calculation of the inverse and by the speed and size of the resulting multiplication/ROM table implementation. Although this will not provide for an extremely compact design, it will be faster than most if not all other methods due to direct hardware support; this was verified through trial and error during the design of the ratio macro. In other cases where resources are a concern, algorithmic techniques, such as high-radix division and array dividers, can be applied. 7.2 Other Operations 7.2.1 Efficient RAM Every design incorporates some form of memory, whether it is full-blown RAM modules or simply a few registers. The problem on FPGA architectures is efficient implementation of RAM structures through coding. Behavioral techniques always yield 70 poor re Riki r singic- ‘ 1 aitllit SIM: Rik insra beh d Eiiic poor results and thus their implementation is rarely used. Again, the answer is direct hardware support for RAM blocks. Direct hardware memory modules can be instantiated by declaring the special RAM components that the compiler recognizes. One such component, RAM16X1, is a single-port, l-bit, 16-address memory unit. In VHDL, this block is declared in the architecture section by the following code component RAM16X1 port ( D: in std_logic; A3: in std_logic; A2: in std_logic; A1: in std_logic; A0: in std_logic; WE: in std_logic; 0: out std_logic ); end component; where D is the input data, A3-A0 is the address, WE is the active-high write enable, and O is the output; other RAM blocks exist, both single and dual-port, which can be declared in a similar manner. Use of these components insures the best possible memory structures. In order to show the effectiveness of direct RAM mapping, two VHDL coded RAM modules were designed, one through behavioral coding and one through instantiation of RAM blocks. Afier synthesis, the generated reports indicated the behavioral RAM consumed 220 CLB’s, while the other method used just 16 CLB’s. The efficiency difference between these two can be seen in the way each was implemented. For the behavioral code, the memory storage units used the flip-flops contained in each CLB. Since there are only 2 flip-flops per CLB, the size of the code becomes unusable due to the massive amount of resources used. For the direct method, 16 RAM bits are 71 sited in t. shrimp} 2 treaties .a r 72.2 Muir Car, also. he indc 103nm the LLse( 51356 brf; 3“ng iii. mdpiacin' stored in each of the two LUT’s per CLB thus increasing the efficiency dramatically. As shown by these results, the only effective method for RAM in VHDL code is through direct hardware support through component instantiation. 7.2.2 Multiplexers Multiplexers are used significantly in any design. Effective and efficient coding of multiplexers or signal selectors is a must for compact, fast implementation. The problem with coding multiplexers in VHDL is the variation in style and the variance in the resulting implementation. One possible coding style is to have a case statement for the selection signal that determines the correct routing of the inputs to the output. This can also be inferred through the use of an index into an array of incoming signals where the index is generated from the selection signal; both of these sections of code synthesize to a multiplexer. An additional, less known, method for creating an efficient multiplexer is through the use of tri-state buffers. When unused in other potions of an FPGA-based design, tri- state buffers can improve design density by removing the overhead from CLB’s when acting like multiplexers. This is done by setting the output to the correctly routed input and placing the additional inputs into the high-impedance state. By using tri-state buffers in this manner, CLB’s are freed up and can be used in other areas of the design. Like in the previous sections of this chapter, code was written for a standard multiplexer with typical signal selection and for a tri-state multiplexer. The input data width and the number of incoming signals were varied from 4-bits to l6-bits in nibble 72 Mir. 1.“ are shor Tal bliick j Spiiia] width increments. The results, both resource usage and maximum delay in nanoseconds, are shown in tables 7.2 and 7.3, respectively. Table 7.2 - FMAP/HMAP Resource Usage of Normal/Tri-state Multiplexers Table 7.3 - Maximum Delay Time (ns) of Normal/Tri-state Multiplexers 11.49/11.25 1232/1293 1272/1276 15.74/1207 15.74/2292 15.74/14.58 22.09/1291 2292/1459 22.92/15.42 As is clearly shown in both tables, tri-state buffer-based multiplexers provide smaller, faster implementations than normal multiplexer coded designs. Therefore, in designs where tri-state buffers are underused, it is best to replace normal multiplexer components with tri-state versions for the number of incoming signals greater than 2; for a selection of 2 signals normal versions are as efficient [I 1]. 7.2.3 Other Special Components In addition to the special features mentioned already in this chapter, other special components can be instantiated through VHDL code. Internal oscillators, the startup block including the global set/reset, and JT AG testing support can instantiated through special component declaration just as in the RAM block case. The exact component 73 decirr for Xi 73.4 1 this.“ music stile. logic C 916 lm: burr) the on some 5 ml flex declaration for each special FPGA feature can be found here [8] for ORCA and here [18] for Xilinx F PGA’s. 7.2.4 Sequential Logic Including State Machines Sequential logic, including latches and flip-flops, is the most documented and easiest of the VHDL coding techniques [l][10][1 l][15][18]. Simple VHDL coding constructs are represented consistently from design to design, coding style to coding style. State encoding for state machines can be the only really crucial part of sequential logic design. This, however, does not come from the VHDL code itself, but rather from the implementation tool. In most cases, only a couple of choices exist, such as one-hot or binary encoding. Since F PGA structures are rich in flip-flops, the best state encoding is the one-hot method, which applies one flip-flop per state [1 1]; all other methods perform some sort of binary state encoding reducing the number of required flip-flops, which is not necessary with F PGA architectures. 7.3 Synthesis Guidelines for FPGA’s Through the course of this design, FPGA datasheets [15][18], other books on synthesis [l][10], additional papers on synthesis [16][11], and finally trial and error, a set of guidelines for synthesis for FPGA devices has emerged. The guidelines are Specifically aimed at FPGA architectures and not general synthesis techniques for both F PGA’s and ASIC’s as denoted by most developed guidelines. Listed below are the guidelines in no particular order: 1. Always use IEEE std_logic for 10 and internal signals. 74 2. Always use IEEE standard procedures whenever applicable. 3. If possible, use additional design tools, such as LogiBLOX for Xilinx F PGA’s, to improve design performance. 4. If rule 3 is not possible, use “+”, “*”, “=”, “<=”, and “>=” overloaded operators to instantiate fast logic in most F PGA architectures for the 2- operand case. 5. For multi-operand case, use algorithmic techniques to reduce signals to a 2- operand case then apply rule 3 or 4 depending on availability. 6. Instantiate dedicated RAM components instead of behavioral code. 7. When tri-state buffer usage is low within the design, use tri-state multiplexers for smaller/ faster designs. 8. Synthesize state machines with one-hot encoding for smallest/fastest design. 9. For testing/startup/oscillatory or any other special block needs, refer to datasheets for component declaration in VHDL. 10. Whenever possible, keep bus signals to nibble width since most FPGA structures are such. Fast logic is enabled most efficiently through nibble width buses. 1 1. Know the limitations of device in terms of both size and speed when designing. Use of these guidelines, all of which are either obvious or were proved to be useful with the above experimentation, will insure that the VHDL written for a specific target technology will be as compiler readable as possible. Code written with these loose rules in mind will be better performers in terms of speed and/or resource consumption. 75 7.4 P VHD one i reisi IO‘m; 7.4 Portability Library Concept Using the guidelines pointed out in the previous section limits the use of the VHDL code for only the specific target technology. Attempts to use a component from one device on another’device may prove too fi'uitless, as the code may need major revision. This adds non-recurring engineering costs to the design and also increases time- to-market, which affects the overall profitability and success of any project. This actually occurred in design of the Trigger Levels. Originally, a Xilinx FPGA was targeted for coding but this was later switched to the current ORCA FPGA. Nearly all of the level specific code needed to be re-written since certain portions of the design that worked perfectly on the Xilinx device were poor performers on the Lucent device. This cost nearly two months of design time for the small design project; larger projects would definitely be a drain on resources and time. At that time, a need for a VHDL portability library of constant, functions, and components became apparent. By having a consistent programming interface between generic VHDL code and device specific VHDL code, the types of problems that these designs faced could be averted. Non-recurring engineering costs could be lowered and time-to-market improved. This idea of code portability is not relegated to just VHDL coding. In the world of computers, a software library known as wxWindows provides a consistent interface across most computer systems. Code written with the wxWindows library of widgets, or GUI components, can be ported with ease to Unix, Windows, or Mac systems due to the 76 oerf 3.1.1: ope raj mo. fire. it. “ l consistent nature of the programming interface. A concept such as this would definitely have merit in the VHDL world of programming. In the previous portion of this chapter, VHDL coding experimentation was performed in order to view performance of different code fragments. A more intimate analysis of these results yields some interesting thoughts and ideas about VHDL code portability. It appears fiom the results that coding can be broken into three main areas of emphasis. First, some coding must be geared through some sort of translation layer that provides consistent interfacing to components such as RAM blocks and JT AG support; different vendors name similar firnctioning components differently. Secondly, a coding methodology must be in place to take care of things such as efficient arithmetic operations and multiplexer/decoder operations. Lastly, some code needs no apparent coding style change except for possible synthesis option selections as in the case of state encoding for state machines. Figure 7.3 illustrates this concept. Programming __, . Level User Progammcr Codmg , Translation m, Translation Layer Coding Methodology Level Device Level —9 mmxl £95m or2c00a -------------------- ASIC Figure 7.3 — VHDL Portability Coding Methodology Writing a translation library for each FPGA, although taxing, is very possible and feasible. The real problem, however, is enforcing a coding methodology for portability. As is well known, every designer has his or her own coding style and these styles vary 77 across the board from good to bad, from consistent to inconsistent. Stating rules to follow for good portable code is one thing, but following them is another. A potential solution to this problem is to write an open-architecture coding tool that attempts to enforce the methodology. With a template library, a tool that enforces the portability methodology, and correct synthesis settings, VHDL portability from FPGA to F PGA and from FGPA to even ASIC designs can be possible. 78 Chapter 8 Conclusions and Future Investigations This final chapter summarizes the accomplishments and success of the STAR EMC Trigger Level designs. The possibility of using the PC as a computational engine is presented and discussed. Good synthesis guidelines, specific for FPGA architectures, are also discussed. Finally, future investigations are presented to further understand the relationship between synthesis and F PGA architectures. 8.1 STAR EMC Trigger Level Design Evaluation After thorough understanding of the target technology, as well as synthesis for F PGA architectures, the design of each Trigger Level was a success. However, this was not without much difficulty, as much of the code was rewritten several times to adhere to Strict timing requests. In order to meet these demands, several trial and error attempts Were made to understand the relationship among coding style, synthesis tool, and FPGA architecture. Although tedious, these coding attempts proved invaluable in understanding the overall FPGA-based HDL design picture. 79 The portion of the design that gave the most trouble in meeting the design needs, both in terms of size and speed, was the ratio macros located within the first Trigger Level. After synthesis with the Synopsis tool, the initial 12-bit precision macro worked flawlessly and met all timing constraints. However, this design was too big to implement correctly and thus changes were needed. A reduction in the ratio precision from 12-bits to 8-bits was performed that cut the ratio macro in half. This implementation version of the macro, although not as precise, was still viable enough as its primary operation as a data filter and not a final calculation engine. This minor change guaranteed overall engine success. Of course the design will be ever changing and this is not the final implementation, only the first. Already there is talk of dropping the ratio macros since firrther studies have shown that these generate no useful insight into the data. Additional things such as IT AG for testability or further modifications to the design, such as replacement of the ratio with another macro, are possible. The reconfigureable nature of F PGA’s makes designs evolvable to continue to meet the application demands. 8.2 PC vs. FPGA Implementation: The Final Word Although a PC-based implementation is comparably cheap to an equivalent F PGA—based design, it was shown to be too slow for this application. The problem resides around the speed of execution for the series of instruction necessary to perform the parallel nature of the FPGA design. It is not possible on a single CPU PC [4] due to the delays of multiple instructions to perform the same functionality as the final design. 80 qua imp KO 181 gls .11. This is not to say that a future PC-based design is not possible, only not possible in the tested configuration. A multiple CPU design could meet the needs of the design, but with additional cost that may make such an implementation not feasible. Additionally, the robustness and fault tolerance of added overhead, such as a RTOS, are questionable when compared against a purely hardware system such as the final FPGA implementation. The costs of the proposed system, both in hardware and reliability, are too great to warrant its use as the system of choice over the current design. 8.3 FPGA Synthesis Guidelines Summary In the course of design, guidelines for HDL-based FPGA synthesis became clear. These guidelines, illustrated in the previous chapter, show a direct difference from what is perceived as good coding techniques are what actually are good coding techniques. As shown, coding is target technology dependent, synthesis tool specific, and programmer dependant. Coding that works well on one type of technology may perform poorly on a different technology. It is up to the programmer to insure that the best possible performance has been extracted for the particular design. 8.4 Future Investigations As stated previously, FPGA-based designs are flexible and evolving systems. The same can be said of this specific system, the STAR EMC Trigger. What was developed for this thesis was merely a guideline, a first incarnation of a design to be applied in this area. Proposed changes can be easily made due to the component nature of the design. Additional features, such as IT AG support for testability, can be added 81 without impacting the performance of the given design. Current features, such as the ratio macro, can be removed in favor of additional macros that provide some desired firnctionality. This flexible nature allows for design changes throughout the cycle of the application in order to meet the current functionality requirements. For the STAR EMC Trigger, this will be an ongoing process. Due to the increased gate capacities of current F PGA technology, these reconfigurable devices are no longer used just for glue logic. Intellectual Property and reuse is now becoming important factors for FPGA devices as designs move from simple schematic projects to HDL-based implementations. Very soon a methodology for fast, efficient FPGA-based design will be needed to meet timing and areas constraints for large HDL-only designs. Strict resource limitations and special hardware make performance-critical HDL designs difficult to achieve. Additionally, this device-dependent coding makes porting of designs to either other FPGA architectures or custom ASIC’s a challenge where time-to- market and non-recurring engineering costs are a priority. A portability methodology must be developed which can bridge the gap between large designs and technology independence as related to performance. Enabling such a methodology will ensure the continued use of soft-cores for reuse on F PGA’s, a key component in meeting the desired design requirements. Continued research on portability and performance is key to the continued success and further mainstream use of F PGA’s. 82 APPENDIX A Common Synthesis Code A1 emc.vhd (Package for STAR EMC Trigger Level) -- Space Sciences Laboratory, UC Berkeley (c) 1999 -— Michigan State University -- STAR Trigger Electronics -- Filename: emc.vhd -- Description: Package for ernc project -- Author: Andrew Vander Molen -- Author: Brian F oulds - Board Engineer: Krista Marks - History: -- 06/11/99 Initial version -- 03/25/00 Removed level ordering constants & types -- Chnaged the addresses on the level registers library IEEE; use IEEE.std_logic_l l64.all; -- PACKAGE DECLARATION package ernc is -- TYPE DECLARATION -- Nibble subtypes subtype one_nibble is std_logic_vector(3 downto 0); subtype two_nibbles is std_logic_vector(7 downto 0); subtype three_nibbles is std_logic_vector( ll downto 0); subtype four_nibbles is std_logic_vector( l 5 downto 0); -- Level 1 trigger level subtypes type emc_level_l_triglev_vector is array(0 to 2) of two_nibbles; type emc_level_1__highlev_vector is array(0 to 2) of two_nibbles; type emc_level_1_ratiolev_vector is array(0 to 2) of two_nibbles; 83 subtype emc_level_l_triglev_bits is std_logic_vector(S downto 0); type emc_level_1_triglev_bits_vector is array(0 to 7) of emc_level_l_triglev_bits; -- Level 2 trigger level subtypes subtype emc_level_2_triglev_bits is std_logic_vector(7 downto 0); type emc_level_2_triglev_vector is array(0 to 2) of four_nibbles; type emc_level_2_triglev_bits__vector is array(0 to 3) of emc_level_2_triglev_bits; -- Level 3 trigger level subtypes subtype emc_level_3_triglev is std_logic_vector(l 5 downto 0); type emc_level_3_triglev_vector is array(0 to 2) of emc_level_3_triglev; -- All trigger level subtypes subtype emc_triglev_compare is std_logic_vector(Z downto 0); -- Trigger & High energy subtypes subtype emc_trigger_energy is std_logic_vector(S downto 0); type emc_trigger_energy_vector is array(0 to 9) of two_nibbles; subtype ernc_high_energy is std_logic_vector(S downto 0); type emc_high_energy_vector is array(0 to 9) of two_nibbles; -- Level 1 energy subtypes subtype emc_level_l_half_energy is std_logic_vector(8 downto 0); subtype emc_level_l__energy is std_logic_vector(9 downto 0); type emc_level_l_energy_vector is array(0 to 7) of emc_level_l_energy; -- Level 2 energy subtypes subtype emc_level_2_quarter_energy is std_logic_vector(ll downto 0); subtype emc_level_2_half_energy is std_logic_vector(12 downto 0); subtype emc_level_2_energy is std_logic_vector( 1 3 downto 0); type emc_level_2_energy_vector is array(0 to 3) of emc_level_2_energy; -- Level 3 energy subtypes subtype emc_level_3_half_energy is std_logic_vector(14 downto 0); subtype emc_level_3_energy is std_logic_vector( l 5 downto 0); -- Level 1 ratio subtypes subtype emc_ratio_adjust_vector is std_logic_vector(9 downto 0); type emc_ratio_pO_vector is array(0 to 9) of two_nibbles; type emc_ratio_pl_vector is array(0 to 9) of one_nibble; 84 type emc_ratio_vector is array(0 to 9) of two_nibbles; -- Output subtypes subtype emc_level_l_output is std_logic_vector(] 5 downto 0); subtype emc_level_2_output is std_logic_vector(2] downto 0); subtype emc_level_3_output is std_logic_vector(25 downto 0); -- Other subtypes subtype emc_ia is std_logic_vector(4 downto 0); subtype emc_id is std_logic_vector(l 5 downto 0); subtype emc_level_l_compare is std_logic_vector(9 downto 0); subtype emc_compare_encode is std_logic_vector(] downto 0); subtype emc_compare_expand is std_logic_vector(2 downto 0); type ratio_rom is array(0 to 63) of std_logic_vector(7 downto 0); -- CONSTANT DECLARATION -- Level Address Constants constant emc_level_l_triglev_0_adr: std_logic_vector(4 downto 0) := "00000"; constant emc_level_l_triglev_1_adr: std_logic_vector(4 downto 0) := "00001"; constant emc_level_l_triglev_2_adr: std_logic_vector(4 downto 0) := "00010"; constant emc_level_l_highlev_0_adr: std_logic_vector(4 downto 0) := "00011"; constant emc_level_1_hi ghlev_1_adr: std_logic_vector(4 downto 0) := "00100"; constant emc_level_1_highlev_2_adr: std_logic_vector(4 downto 0) := "00101"; constant emc_level_l_ratiolev_0__adr: std_logic_vector(4 downto 0) := "00110"; constant emc_level_l_ratiolev_l_adr: std_logic_vector(4 downto 0) := "00111"; constant emc_level_l_ratiolev_2__adr: std_logic_vector(4 downto 0) := "01000"; constant emc_level_2_triglev_0_adr: std_logic_vector(4 downto 0) := "00000"; constant emc_level_2_triglev_l_adr: std_logic_vector(4 downto 0) := "00001 "; constant emc_level_2_triglev_2_adr: std_logic_vector(4 downto 0) := "00010"; constant emc_level_3_triglev_0_adr: std_logic_vector(4 downto 0) := "00000"; 85 constant emc_level_3_triglev_1_adr: std_logic_vector(4 downto 0) := "00001"; constant emc_level_3_triglev_2_adr: std_logic_vector(4 downto 0) := "00010"; -- Level Ordering Constants constant emc_level_order_zero: std_logic_vector(l downto 0) := "00"; constant emc_level_order_one: std_logic_vector(l downto 0) := "01"; constant emc_level_order_two: std_logic_vector(l downto 0) := "10"; constant emc_level_order_three: std_logic_vector(l downto 0) := "11"; -- Level Compare Constants constant emc_level_compare_zero: std_logic_vector(2 downto 0) := "000"; constant emc_level_compare_one: std_logic_vector(2 downto 0) := "001"; constant emc_level_compare_two: std_logic_vector(2 downto 0) := "010"; constant emc_level_compare_three: std_logic_vector(2 downto 0) := "011"; constant emc_level_compare_four: std_logic_vector(2 downto 0) := "100"; constant emc_level_compare_five: std_logic_vector(2 downto 0) := " 101 "; constant emc_level_compare_six: std_logic_vector(2 downto 0) := "110"; constant emc_level_compare_seven: std_logic_vector(2 downto 0) := "1 l 1"; end ernc; A2 fa.vhd (Full adder) -- Space Sciences Laboratory, UC Berkeley (c) 1999 -- Michigan State University -- STAR Trigger Electronics -- Filename: fa.vhd -- Description: Full Adder Component - Input: x - Addition Bit y - Addition Bit cin - Carry In -- Output: 3 - Sum cout - Carry Out -- Author: Andrew Vander Molen -- Author: Brian Foulds -- Board Engineer: Krista Marks - History: 02/18/99 Version 1.0.0 (Initial) library IEEE; 86 use IEEE.std_logic_l 164.all; -- PORT DECLARATION entity fa is port ( x: in std_logic; y: in std_logic; cin: in std_logic; s: out std_logic; cout: out std_logic ); end fa; -- ARCHITECTURE DECLARATION architecture structural of fa is begin -- CONCURRENT STATEMENTS 8 <= x xor y xor cin; cout <= (x and y) or (x and cin) or (y and cin); end structural; A3 latch_clk36_n.vhd (Negative edge-triggered latch) -- Space Sciences Laboratory, UC Berkeley (c) 1999 -- Michigan State University - STAR Trigger Electronics -- F ilenarne: latch_clk3 6_n.vhd -- Description: Negative-edge triggered latch for clk36 -- Generic: width - Bit width of i/o signals -- Input: clk - Clock -- rst - Reset -- input - Latch Data Input -- Output: output - Latch Data Output 87 -- Author: Andrew Vander Molen -- Author: Brian Foulds -- Board Engineer: Krista Marks -- History: -- 03/01/99 Version 1.0.0 (Initial) library IEEE; use IEEE.std_logic_l l64.all; -- PORT DECLARATION entity latch_clk36_n is generic (width: integer); port ( clk: in std_logic; rst: in std_logic; input: in std_logic_vector((width - l) downto 0); output: out std_logic_vector((width - 1)downto 0) ); end latch_clk3 6_n; -- ARCHITECTURE DECLARATION architecture rtl of latch_clk36_n is begin -- PROCESS STATEMENTS latch: process (clk, rst) begin if (clk'event and clk = '0') then output <= input; end if; if(rst = '1') then output <= (others => '0'); end if; end process; 88 end rtl; A4 latch_clk36_p.vhd (Positive edge-triggered latch) -- Space Sciences Laboratory, UC Berkeley (c) 1999 -— Michigan State University -- STAR Trigger Electronics -- Filename: latch_clk36_p.vhd -- Description: Positive-edge triggered latch for clk36 -- Input: clk - Clock -- rst - Reset -- input - Latch Data Input -- Output: output - Latch Data Output -- Author: Andrew Vander Molen -- Author: Brian Foulds -- Board Engineer: Krista Marks -- History: - 03/01/99 Version 1.0.0 (Initial) library IEEE; use IEEE.std_logic_l l64.all; -- PORT DECLARATION entity latch_clk36_p is generic (width: integer); port ( clk: in STD_LOGIC; rst: in STD_LOGIC; input: in STD_LOGIC_VECTOR ((width - 1) downto 0); output: out STD_LOGIC_VECTOR ((width - l) downto 0) ); end latch_clk3 6 _p; -- ARCHITECTURE DECLARATION architecture rtl of latch_clk36_p is 89 begin -- PROCESS STATEMENTS latch: process (clk, rst) begin if (clk'event and clk = '1') then output <= input; end if; if (rst = '1') then output <= (others => '0'); end if; end process; end rtl; A5 compare_20ps.vhd (Compares two operands) -- Space Sciences Laboratory, UC Berkeley (c) 1999 -- Michigan State University -- STAR Trigger Electronics -- Filename: compare_20ps.vhd -- Description: Compares 2 operands to a specified level and -- generates '1' if the Operand is greater than -- or equal to the level value. -- Generic: width - Nibble width of compare words -- Input: level - Compare to value -- op - An operand value -- Output: result - Comparison bit -- Author: Andrew Vander Molen -- Author: Brian F oulds -- Board Engineer: Krista Marks -- History: -- 03/01/99 Version 1.0.0 (Initial) library IEEE; use IEEE.std_logic_1 164.All; use IEEE.std_logic_unsigned.All; 9O -- PORT DECLARATION entity compare_20ps is generic (nibble_cnt: integer := 4); port ( level: in std_logic_vector((4 * nibble_cnt - l) downto 0); op: in std_logic_vector((4 * nibble_cnt - 1) downto 0); result: out std_logic ); end compare_20ps; -- ARCHITECTURE DECLARATION architecture structural of compare_20ps is begin -- PROCESS STATEMENTS compare: process (level, op) begin if (op >= level) then result <= '1'; else result <= '0’; end if; end process compare; end structural; A6 compare_encoder.vhd (Encodes the outputs of comparisons) -- Space Sciences Laboratory, UC Berkeley (c) 1999 - Michigan State University -- STAR Trigger Electronics -- F ilenarne: compare_encoder.vhd -- Description: Encodes trigger level comparisons into the -- following manner: -- Zero - Compare error or no level threshold met 91 -- One - Lowest level threshold met -- Two - Middle & Lowest level thresholds met -- Three - All level thresholds met -- Input: triglev_compare - The trigger level bits from the -- comparisons. These bits will get -- encoded into zero, one, two, or -- three depending on how many -- thresholds they exceed -- Output: compare_encode - The encoded comparison output -- Author: Andrew Vander Molen -- Author: Brian F oulds -- Board Engineer: Krista Marks -- History: -- 05/20/99 Version 1.0.0 (Initial) -- 03/13/00 Removed the highest level inputs library IEEE; use IEEE.std_logic_1 164.all; use IEEE.std_logic_arith.all; library WORK; use WORK.emc.all; -- PORT DECLARATION entity compare_encoder is port ( triglev_compare: in emc_triglev_compare; compare_encode: out emc_compare_encode ); end compare_encoder; -- ARCHITECTURE DECLARATION architecture behavioral of compare_encoder is begin -- CONCURRENT STATEMENTS 92 compare_encode <= emc_level_order_three when (triglev_compare = emc_level_compare_seven) else emc_level_order_two when (triglev_compare = emc_level_compare_three) or (triglev_compare = emc_level_compare_five) or (triglev_compare = emc_level_compare_six) else emc_level_order_one when (triglev_compare = emc_level_compare_one) or (triglev_compare = emc_level_compare_two) or (triglev_compare = emc_level_compare_four) else emc_level_order_zero; end behavioral; A7 RndNumGen.vhd (Pseudo-random number package) -- Space Sciences Laboratory, UC Berkeley (c) 1999 -- Michigan State University -- STAR Trigger Electronics -- Filename: RndNumGen.vhd -- Description: Pseudo-random number generation package for -- simulation of design (used by testbenches) -- Author: Andrew Vander Molen - Author: Brian Foulds -- Board Engineer: Krista Marks -- History: -- 03/25/00 Initial version package RndNumGen is -- constant definitions constant A: integer := 9301; constant C: integer := 49297; constant M: integer := 233280; -- type definitions type rnd_int is record md: real; seed: integer; 93 init: integer; min: integer; max: integer; value: integer; reset: boolean; end record; type md_real is record rnd: real; seed: integer; init: integer; min: real; max: real; value: real; reset: boolean; end record; -- procedure definitions procedure Geand(r: inout md_int); procedure Geand(r: inout md_real); end RndNumGen; package body RndNumGen is -- procedure bodies procedure Geand(r: inout md_int) is begin if (not r.reset) then r.reset := true; r.seed := r.init; end if; r.seed := ((r.seed * A) + C) mod M; r.md := real(r.seed) / real(M); r.value := integer(real(r.max - r.min) * r.md + real(r.min)); end Geand; procedure Geand(r: inout md_real) is begin if (not r.reset) then r.reset := true; r.seed := r.init; end if; r.seed := ((r.seed * A) + C) mod M; r.md := real(r.seed) / real(M); 94 r.value := (r.max - r.min) * r.rnd + r.min; end Geand; end RndNumGen; 95 APPENDIX B Level 1 Synthesis Code B1 level_l_triglev.vhd (Level 1 Trigger Level operations) -- Space Sciences Laboratory, UC Berkeley (c) 1999 -- Michigan State University -- STAR Trigger Electronics -- Filename: level_l_trigger_level.vhd -- Description: Sets the trigger levels and determines the highest -- trigger, high, and ratio levels for level 1 -- Input: clk - 38Mhz Clock (clk36) -- rst - Global reset -- vme_select_engine_n - From op controller; -- VME w/r engine registers -- vme_write_n__3 - From op controller; -- Write = 0, Read = 1 -- ia - From VME, instruction address -- id - From VME, instruction data -- Inout: level_l_triglev - The array of trigger level -- thresholds -- level_l_highlev - The array of high level -- thresholds -- level_l_ratiolev - The array of ratio level -- thresholds -- Output: engine_ack_n - To op controller - done; -- VME w/r to registers -- Author: Andrew Vander Molen -- Author: Brian F oulds -- Board Engineer: Krista Marks -- History: -- 05/20/99 Version 1.0.0 (Initial) -- 06/08/99 Changed id signal to input only -- 03/13/00 Removed all highest level outputs library IEEE; use IEEE.std_logic_l l64.all; use IEEE.std_logic_arith.all; library WORK; 96 use WORK.ernc.all; -- PORT DECLARATION entity level_l_trigger_level is port ( clk: in std_logic; rst: in std_logic; vme_select_engine_n: in std_logic; vme_write_n: in std_logic; ia: in emc_ia; id: in emc_id; level_l_triglev: inout emc_level_l_triglev_vector; level_l_highlev: inout emc_level_1_highlev_vector; level_l_ratiolev: inout emc_level_1_ratiolev_vector; engine_ack_n: out std_logic ); end level_l_trigger_level; -- ARCHITECTURE DECLARATION architecture behavioral of level_l_trigger_level is begin -- PROCESS STATEMENTS level_control: process(clk, rst) begin if (clk'event and clk = '1') then if (vme_select_engine_n = '0' and vme_write_n = '0') then if (ia = emc_level_l_triglev_0_adr) then level_l_triglev(0) <= id(7 downto 0); elsif (ia = emc_level_l_triglev_l_adr) then level_l_triglev(l) <= id(7 downto 0); elsif (ia = emc_level_l_triglev_2_adr) then level_l_triglev(2) <= id(7 downto 0); elsif (ia = emc_level_l_highlev_0_adr) then level_l_highlev(0) <= id(7 downto O); 97 elsif (ia = emc_level_1_highlev_l_adr) then level_l_highlev(l) <= id(7 downto 0); elsif (ia = emc_level_l_highlev_2_adr) then level_l_highlev(2) <= id(7 downto 0); elsif (ia = emc_level_1_ratiolev_0_adr) then level_l_ratiolev(O) <= id(7 downto 0); elsif (ia = emc_level_1_ratiolev_l_adr) then level_l_ratiolev(l) <= id(7 downto 0); elsif (ia = emc_level_1_ratiolev_2_adr) then level_l_ratiolev(2) <= id(7 downto 0); end if; engine_ack_n <= '0'; else engine_ack_n <= '1'; end if; end if; if(rst = '1') then level_l_triglev(O) <== (others => '0'); level_l_triglev(l) <= (others => '0'); level_l_triglev(2) <= (others => '0'); level_l_highlev(O) <= (others => '0'); level_l_highlev(l) <= (others => '0'); level_l_highlev(2) <= (others => '0'); level_l_ratiolev(O) <= (others => '0'); level_l_ratiolev(l) <= (others => '0'); level_l_ratiolev(2) <= (others => '0'); engine_ack_n <= '1'; end if; end process level_control; end behavioral; B2 sum_trigger_energy.vhd (Sum of Trigger energy) -- Space Sciences Laboratory, UC Berkeley (c) 1999 -- Michigan State University -- STAR Trigger Electronics - F ilename: sum_trigger_energy.vhd -- Description: Unsigned sum of ten trigger energies -- Input: op_x - Trigger energy -- Output: sum - Final level 1 energy -- Structure: 98 -- fa - Full Adder Component -- Author: Andrew Vander Molen -- Author: Brian Foulds -- Board Engineer: Krista Marks -- History: -- ' 05/20/99 Version 1.0.0 (Initial) library IEEE; use IEEE.std_logic_l l64.all; use IEEE.std_logic_unsigned.all; library WORK; use WORK.emc.all; -- PORT DECLARATION entity sum_trigger_energy is port ( ' op_O: in emc_trigger_energy; 1: in emc_trigger_energy; op 2: in emc_trigger_energy; _3: in emc_trigger_energy; 4: in emc_trigger_energy; op_5: in emc_trigger_energy; op_6: in emc_trigger_energy; p_7: in emc_trigger_energy; op_8: in emc_trigger_energy; _9: in emc_trigger_energy; sum: out emc_level_l_energy ); end sum_trigger_energy; ---..--_ - -------- _— 99 component fa pom x: in std_logic; y: in std_logic; cin: in std_logic; 8: out std_logic; cout: out std_logic ); end component; -- SIGNAL DECLARATION signal op_ll_c0_b0 : : std_logic; : std_logic; signal op_l l_c1_b3 signal 0p_ll_c0_bl signal op_ll_cl_b4 : signal op_ll_c0_b2 : signal op_ll_cl_bS : signal op_ll_cl_bO : : std_logic; signal op_ll_c2_b3 signal op_ll_cl_bl : signal op_ll_c2_b4 : signal op_ll_cl_b2 : : std_logic; signal op_l 1_c2_b5 signal op_l l_c2_b0 : signal op_ll_c3_b3 : : std_logic; signal op_l l_c2_bl signal op_ll_c3_b4 : signal op_ll_c2_b2 : signal op_l 1_c3_b5 : signal op_ll_c3_b0 : signal op_ll_c4 b3 : : std_logic; signal op_ll_c4 b4 : : std_logic; signal op_l l_c4_b5 : signal op_ll_c4__b0 : : std_logic; : std_logic; signal op_ll_c5_b4 : signal op_ll_c4_b2 : signal op_ll_c5_b5 : signal op_ll_c5_b0 : signal op_ll_c6_b0 : signal op_ll_c3:b1 signal op_ll_c3:b2 signal op_l l_c5_b3 signal op_ll_c4_b1 std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; 100 signal op_l 1_c5_b 1 signal op_l l_c6_bl signal op_ll_c5_b2 : signal op_ll_c6_b2 : signal op_12_c0_b0 : signal op_12_c1_b2 : signal op_12_cl_b0 : signal op_12_02_b2 : : std_logic; : std_logic; signal op_12_c2_b0 : signal op_12_c3_b2 : : std_logic; signal op_12_c1_b1 signal op_12_02_b3 signal op_12_c2_bl signal op_12_c3_b3 : signal op_12_c3_b0 : signal op_12_c4_b2 : : std_logic; : std_logic; signal op_12_c4_b0 : signal op_12_05_b2 : : std_logic; : std_logic; signal op_12_c3_bl signal op_12_c4_b3 signal op_12_c4_b1 signal op_12_c5_b3 signal op_12_c5_b0 : : std_logic; : std_logic; signal op_12_c6_b2 : signal op_12_c6_b0 : signal op_12_c7_b0 : : std_logic; signal op_12_c6_bl signal op_12_05_bl signal op_l3_cl_bl signal op_l3_cl__b0 : signal op_l3_c2_b2 : signal op_13_02_b0 : : std_logic; : std_logic; : std_logic; signal op_l3_c3_b0 : signal op_l3_c4_b2 : : std_logic; : std_logic; signal op_l3_c4_b0 : signal op_l3_c5_b2 : : std_logic; : std_logic; signal op_l3_c3_b2 signal op_l3_c2_bl signal op_l3_c3_b3 signal op_l3_c3_bl signal op_l3_c4_b3 signal op_l3_c4_b1 signal op_l3_cS_b3 signal op_l3_c5_b0 : : std_logic; : std_logic; signal op_13__c6__bl signal op_l3_c5_bl : std_logic; : std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; 101 signal op_13_c6_b2 : std_logic; signal op_l3_c6_b0 : std_logic; signal op_13_c7_b0 : std_logic; signal op_l4__c2_bl : std_logic; signal op_l4_c2_b0 : std_logic; signal op_l4_c3_bl : std_logic; signal op_l4_c3_b0 : std_logic; signal op_l4_c4_bl : std_logic; signal op_l4_c4_b0 : std_logic; signal op_l4_c5_bl : std_logic; signal op_l4_c5_b0 : std_logic; signal op_l4_c6_bl : std_logic; signal op_l4_c6_b0 : std_logic; signal op_l4_c7_b1 : std_logic; signal op_l4__c7_b0 : std_logic; signal sum_O: emc_level_l_half_energy; signal sum_l: emc_level_l_half_energy; signal sum_int: three_nibbles; signal gnd: std_logic; begin -- CONCURRENT STATEMENTS and <= '0'; -- CSA structure declaration -- Level 0, Bit 0 csa_fa_10_c0_0: fa port map (op_0(0), op_1(0), op_2(0), op_ll_cO_b0, op_l l_c1_b3); csa_fa_10_c0_l: fa port map (op_3(0), op_4(0), op_5(0), op_ll_c0_b1, op_l l_c1_b4); csa_fa_lO_cO_2: fa port map (op_6(0), op_7(0), op_8(0), op_l 1_c0_b2, op_ll_cl_b5); -- Level 0, Bit 1 csa_fa_10_cl_0: fa port map (op_0(1), 0p__l(l), op_2(1), op_ll_cl_bO, op_ll_c2_b3); csa_fa_10_cl_l: fa port map (op_3(1), op_4(l), op_5(l), op_l l_c1_b1 , op_ll_c2_b4); csa_fa_10_cl_2: fa 102 port map (op_6(1), op_7(1), op_8(1), op_l l_c1_b2, op_ll_c2_b5); -- Level 0, Bit 2 csa_fa_10_c2__0: fa port map (op_0(2), op_1(2), op_2(2), op_ll_c2_b0, op_ll_c3_b3); csa__fa_10_c2_l: fa port map (op_3(2), op_4(2), op_5(2), op_ll_c2_bl , op_ll_c3_b4); csa_fa_10_c2_2: fa port map (op_6(2), op_7(2), op_8(2), op_l 1_c2_b2, op_ll_c3_b5); -- Level 0, Bit 3 csa__fa_10_c3_0: fa port map (op_0(3), op_1(3), op_2(3), op_ll_c3_b0, op_ll_c4_b3); csa_fa_10_c3_1: fa port map (op_3(3), op_4(3), op_5(3), op_ll_c3_bl , op_ll_c4_b4); csa__fa_10_c3_2: fa port map (op_6(3), op_7(3), op_8(3), op_l 1_c3_b2, op_ll_c4_b5); -- Level 0, Bit 4 csa_fa_10_c4_0: fa port map (op_0(4), op_1(4), op_2(4), op_ll_c4_b0, op_ll_cS_b3); csa_fa_10_c4_l: fa port map (op_3(4), op_4(4), op_5(4), op_ll_c4_b1, op_l l_c5_b4); csa_fa_10_c4_2: fa port map (op_6(4), op_7(4), op_8(4), op_l l_c4_b2, op_ll_c5_b5); -- Level 0, Bit 5 csa__fa_10_c5_0: fa port map (op_0(5), op_1(5), op_2(5), op_l 1_c5_b0, op_ll_c6_b0); csa_fa_10_c5_1: fa port map (op_3(5), op_4(5), op_5(5), op_ll_c5_bl, op_ll_c6_bl); csa_fa_10_c5_2: fa port map (op_6(5), op_7(5), op_8(5), op_ll_c5_b2, op_ll_c6_b2); -- Level 1, Bit 0 csa_fa_l l_c0__0: fa port map (op_l 1_c0_b0, op_ll_c0_bl, op_l 1_c0_b2, op_12_c0_b0, op_12_c1_b2); 103 -- Level 1, Bit 1 csa_fa__l 1_c1__0: fa port map (op_ll_cl_bO, op_ll_cl_bl , op_l l_c1_b2, op_12_c1_b0, op_12_c2_b2); csa__fa_ll__cl_l : fa port map (op_ll_cl_b3, op_ll_cl_b4, op_l l__cl_b5, op_12_c1_b l , op_12_c2_b3); -- Level 1, Bit 2 csa_fa__l 1_c2_0: fa port map (op_ll_cZ_b0, op_ll_c2_bl, op_ll_c2_b2, op_12_c2_b0, op_12_c3_b2); csa_fa_l 1_c2_1 : fa port map (op_ll_c2_b3, op_ll_c2_b4, op_l 1_c2_b5, op_12_c2_b l , op_12_c3_b3); -- Level 1, Bit 3 csa_fa_l l_c3_0: fa port map (op_ll_c3_b0, op_ll_c3_b1, op_ll_c3_b2, op_12_c3_b0, op_12_c4_b2); cs a_fa_l l_c3_l : fa port map (op_ll_c3_b3, op_ll_c3_b4, op_l l_c3_b5, op_12_c3_b l , op_12_c4_b3); -- Level 1, Bit 4 csa_fa_l l_c4_0: fa port map (op_l l_c4_b0, op_l 1_c4_b1, op_l l_c4_b2, op_12_c4_b0, op_12_c5_b2); csa__fa_l l_c4_l : fa port map (op_l l_c4_b3, op_l 1_c4_b4, op_ll_c4_b5, op_12_c4_b 1 , op_12_c5_b3); -- Level 1, Bit 5 csa___fa_l 1_c5_0: fa port map (op_ll_c5_b0, op_ll_c5_b1, op_ll_c5_b2, op_12_c5_b0, op_12_c6_b 1 ); csa_fa_ll_c5_1 : fa port map (op_ll_c5_b3, op_ll_c5_b4, op_l l_c5_b5, op_12_05_b1 , op_12_c6_b2); 104 -- Level 1, Bit 6 csa_fa_l l_c6_0: fa port map (op_ll_c6_b0, op_ll_c6_b1, op_l 1_c6_b2, op_12_c6_b0, op_12_c7_b0); -- Level 2, Bit 0 csa_fa_12_c0_0: fa port map (op_12_c0_b0, op_9(0), gnd, sum_0(0), 0p__l3_cl__b1); -- Level 2, Bit 1 csa_fa_12_cl_0: fa port map (op_l2_cl_b0, op_12_c1_b1, op_12_c1_b2, op_l3_cl_b0, op_l3_c2_b2); -- Level 2, Bit 2 csa_fa_12_c2_0: fa port map (op_12_c2_b0, op_12_c2__bl, op_12_c2_b2, op_l3_c2_b0, op_13_c3_b2); csa_fa_12_c2__l: fa port map (op_12_c2_b3, op_9(2), gnd, op_l3_c2_b1, op_l3_c3_b3); -- Level 2, Bit 3 csa_fa_12_c3_0: fa port map (op_12_c3_b0, op_12_c3_bl, 0p_12_c3__b2, 0p_l3_c3_b0, op_l3_c4_b2); csa_fa_12_03_l: fa port map (op_12_c3_b3, op_9(3), gnd, op_l3_c3_b1, op_l3_c4_b3); -- Level 2, Bit 4 csa_fa_12_c4_0: fa port map (op_12_c4_b0, op_12_c4_b1, op_12_c4_b2, op_l3_c4_b0, op_l3_cS_b2); csa_fa_12_c4_1: fa port map (op_12_c4_b3, op_9(4), gnd, op_l3_c4_b l , op_l3_c5_b3); -- Level 2, Bit 5 csa_fa_12_c5_0: fa port map (op_12_c5_b0, op_12_c5_b], op_12_c5_b2, op_l3_cS_b0, op_l3_c6_b l); csa_fa_12_c5_1: fa port map (op_12_c5_b3, op_9(5), gnd, op_l3_c5_b1, op_l3_c6_b2); 105 -- Level 2, Bit 6 csa_fa_12_c6_0: fa port map (op_12_c6_b0, op_12_c6_bl, op_l3_c6_b0, op_l3_c7_b0); -- Level 3, Bit 1 csa_fa_l3_cl_0: fa port map (op_l3_cl_b0, op_l3_cl_bl , op_l4_c2_b l ); -- Level 3, Bit 2 csa_fa_l3_c2_0: fa port map (op_l3_c2_b0, op_l3_c2_b1, op_l4_c2_b0, op_l4_c3_b l ); -- Level 3, Bit 3 csa_fa_13_c3_0: fa port map (op_l3_c3_b0, op_l3_c3_bl, op_l4_c3_b0, op_l4_c4_b l ); -- Level 3, Bit 4 csa_fa_13_c4_0: fa port map (op_l3_c4_b0, op_l3_c4_b] , op_l4_c4_b0, op_l4_c5_b l ); -- Level 3, Bit 5 csa_fa_l3_c5_0: fa port map (op_l3_c5_b0, op_l3_c5_bl, op_l4_c5_b0, op_l4_c6_b1); -- Level 3, Bit 6 csa_fa_l3_c6_0: fa port map (op_l3_c6_b0, op_l3_c6_b], op_l4_c6_b0, op_l4_c7_b l ); -- Level 3, Bit 7 csa_fa_13_c7__0: fa op_12_c6_b2, op_9(l), sum_0(l), op_l3_c2_b2, op_13_c3_b2, 0p_l3_c4_b2, 0p_l3_05_b2, op_l3_c6_b2, port map (op_l3_c7_b0, op_12_c7_b0, grid, op_l4_c7_b0, sum_0(8)); -— Level 4, Bit 2 csa_fa_l4_c2_0: fa port map (op_l4_c2_b0, op_l4_c2_b l , -- Level 4, Bit 3 csa_fa_l4_03_0: fa port map (op_l4_c3_b0, op_l4_c3_b 1 , 106 gnd, sum_0(2), sum_1(3)); op_l3_c3_b3, sum_0(3), sum_l(4)); -- Level 4, Bit 4 csa_fa_l4_c4_0: fa port map (op_l4_c4_b0, op_l4_c4_b l , op_l3_c4_b3, sum_0(4), sum_l(5)); -- Level 4, Bit 5 csa_fa_l4_c5_0: fa port map (op_l4_cS_b0, op_l4_c5_b] , op_l3_c5_b3, sum_0(5), sum_l(6)); -- Level 4, Bit 6 csa_fa_l4_c6_0: fa port map (op_l4_c6_b0, op_l4_c6_bl , gnd, sum_0(6), sum_l(7)); -- Level 4, Bit 7 csa_fa_l4_c7_0: fa port map (op_l4_c7_b0, op_l4_c7_b], gnd, sum_0(7), sum_l(8)); -- Grounded Sum Operand Outputs sum_l(O) <= gird; sum_l(1)<= gnd; sum_l(2) <= gnd; sum_0(8) <= gnd; -- Final CPA level sum_int <= ("000" & sum_O) 1’ ("000" & sum_l ); sum <= sum_int(9 downto 0); end structural; B3 ratio_e0.vhd (First stage of ratio) -- Space Sciences Laboratory, UC Berkeley (0) 1999 -- Michigan State University -- STAR Trigger Electronics -- F ilename: ratio_eO.vhd -- Description: First stage of unsigned divide -- of 2 operands of 6-bit width -- Input: dividend - Trigger energy -- divisor - High energy -- Output: product_O - One product term -- product_1 - One product term 107 -- adjust - Adjustment bit for ratio -- Author: Andrew Vander Molen -- Author: Brian Foulds -- Board Engineer: Krista Marks -- History: -— 04/09/99 Version 1.0.0 (Initial) -- 06/12/99 Rewrote for for precision -- 06/ 14/99 Rewrote to include data checking library IEEE; use IEEE.std_logic_l l64.all; use IEEE.std_logic_unsigned.all; library WORK; use WORK.emc.all; -- PORT DECLARATION entity ratio_eO is p0rt( dividend: in emc_trigger_energy; divisor: in ernc_high_energy; product_O: out two_nibbles; product_1: out one_nibble; adjust: out std_logic ); end ratio_eO; architecture behavioral of ratio_eO is -- COMPONENT DECLARATIONS component fa p011 ( x: in std_logic; y: in std_logic; cin: in std_logic; 3: out std_logic; cout: out std_logic 108 end component; -- SIGNAL DECLARATIONS begin -- Ground & lookup signals signal gnd: std_logic; signal high: std_logic; signal lookup: ratio_rom; -- Partial product signals signal Ale: two_nibbles; signal Ath: two_nibbles; signal Ath: two_nibbles; -- Other signals signal junk: std_logic; -— CONCURRENT STATEMENTS -- Ground signals sfl<=95 -- Assign all lookup values lookup(O) <= "11111111"; lookup(l) <= "11111111"; lookup(2) <= "00000000"; lookup(3) <= "01010100"; lookup(4) <= "00000000"; lookup(S) <= "10011010"; lookup(6) <= "01010100"; lookup(7) <= "00100100"; lookup(8) <= "00000000"; lookirp(9) <= "11001000"; lookup(10) <= "10011010"; lookup(11)<= "01110100"; lookup(12) <= "01010110"; lookup(l3) <= "00111100"; lookup( 14) <= "00100100"; lookup(15) <= "00010010"; lookup(l6) <= "00000000"; lookup(l7) <= "11100011"; 109 lookup(18)<="11001001"; lookup(l9) <= "10110001"; lookup(20) <= "1001 1011"; lookup(21) <= "10000111"; lookup(22) <= "01110101"; lookup(23) <= "01 100101"; lookup(24) <= "010101 1 1"; lookup(25) <= "01001001"; lookup(26) <= "001 11101"; lookup(27) <= "001 10001"; lookup(28) <= "00100101 "; lookup(29) <= "0001 101 1"; lookup(30) <= "0001001 1"; lookup(3 1) <= "00001 1 11"; lookup(32) <= "00000001"; lookup(33) <= "11111101"; lookup(34) <= "11 10001 1"; lookup(35) <= "11010101"; lookup(36) <= "11000111"; lookup(37) <= "10111011"; lookup(3 8) <= "101 10001"; lookup(39) <= "10100101"; lookup(40) <= "1001 1011"; lookup(41) <= "10010001"; lookup(42) <= "100001 1 1"; lookup(43) <= "01111111"; lookup(44) <= "01110101"; lookup(45) <= "01 101 101"; lookup(46) <= "01 100101"; lookup(47) <= "010] 1101"; lookup(48) <= "0101011 1"; lookup(49) <= "010011 1 1"; lookup(50) <= "01001001 "; lookup(51) <= "0100001 1"; lookup(52) <= "001 11101"; lookup(53) <== "00110101"; lookup(54) <= "001 10001"; lookup(55) <= "00101011"; lookup(56) <= "00100101"; lookup(57) <= "00100001 "; lookup(58) <= "0001 1101"; lookup(59) <= "0001011 1"; lookup(60) <= "00010001 "; lookup(61) <= "000011 1 1"; lookup(62) <= "00001001"; lookup(63) <= "00000101"; 110 -- Perform the partial multiplication Ale <= lookup(CONV_INTEGER(divisor))(3 downto 0) * dividend(3 downto 0); Ath <= lookup(CONV_INTEGER(divisor))(7 downto 4) * dividend(3 downto 0); Ath <= lookup(CONV_INTEGER(divisor))(3 downto 0) * (gnd & gnd & dividend(S downto 4)); -- Assign the lower 4-bits of the 2-operand product product_0(3 downto 0) <= Ale(3 downto 0); product_1(0) <= '0'; -- Perform CSA on all partial products -- Level 0, Bit 0 csa_fa_10_cO_0: fa port map(Ale(4), Ath(0), Ath(0), product_0(4), product_1(1)); -- Level 0, Bit 1 csa_fa_10_cl_0: fa port map(Ale(5), Ath(l), A1Xh(l), product_0(5), product_1(2)); -- Level 0, Bit 2 csa_fa_10_c2_0: fa port map(Ale(6), Ath(2), Ath(2), product_0(6), product_1(3)); -- Level 0, Bit 3 csa_fa_10_c3_0: fa port map(Ale(7), Ath(3), Ath(3), product_0(7), junk); -- CONCURRENT STATEMENTS ratio_e0_adjust: process(dividend, divisor) begin if (dividend = divisor) then adjust <= '1'; elsif (divisor = "000000") then adjust <= '1'; else adjust <= '0'; end if; end process ratio_e0_adjust; end behavioral; lll B4 ratio_e1.vhd (Second stage of ratio) -- Space Sciences Laboratory, UC Berkeley (c) 1999 -- Michigan State University -- STAR Trigger Electronics -- Filename: ratio_e1.vhd -- Description: Second Stage of unsigned divide -- of 2 operands of 6-bit width -- Input: product_O - One partial product term -- product_1 - One partial'product term -- adjust - Adjustment bit for ratio -- Output: product - Product result -- Author: Andrew Vander Molen -- Author: Brian F oulds -- Board Engineer: Krista Marks - History: -- 04/09/99 Version 1.0.0 (Initial) -- 06/11/99 Changed ratio scheme library IEEE; use IEEE.std_logic_l l64.all; use IEEE.std_logic_unsigned.all; library WORK; use WORK.emc.all; -- PORT DECLARATION entity ratio_el is port( product_O: in two_nibbles; product_1: in one_nibble; adjust: in std_logic; product: out two_nibbles ); end ratio_el; -- ARCHITECTURE DECLARATION 112 architecture behavioral of ratio_el is begin -- PROCESS STATEMENTS -- Perform the final partial product sum ratio_el_adjust: process(product_0, product_1, adjust) begin if (adjust = '1') then product <= "1 1 1 l l l l 1"; else product <= product_0 + (product_1 & "0000"); end if; end process ratio_el_adjust; end behavioral; B5 level_l.vhd (Top of design) -- Space Sciences Laboratory, UC Berkeley (c) 1999 -- Michigan State University -- STAR Trigger Electronics -- F ilename: level_l .vhd -- Description: Computational engine for Levell of emc detector -- Input: clk - 38Mhz Clock (clk36) -- rst - Global reset -- vme_select_engine_n - From op controller; -- VME w/r engine registers -- vme_write_n_3 - From op controller; -- Write = 0, Read = l -- ia - From VME, instruction address -- id - From VME, instruction data -- trigger_tower_x - Energy from LUTO - LUT9 -- high_tower_x - Energy from LUTlO - LUT19 -- Output: engine_ack_n - To op controller - done; -- VME w/r to registers -- engine_output - DSM comp. engine output -- Structure: —- latch_clk36_p - Positive-edge triggered 113 latch for clk36 latch_clk3 6_n - Negative-edge triggered latch for clk36 level_l_trigger_level - Sets the trigger levels for level 1 sum_trigger_energy - Unsigned sum of ten trigger energies ratio_eO - First stage of unsigned divide of 2 operands of 6-bit width ratio_el - Second Stage of unsigned divide of 2 operands of 6-bit width compare_20ps - Compares 2 operands to a specified level and generates '1' if the operand is greater than or equal to the level compare_encoder - Encodes trigger level comparisons into the following manner: Zero - Compare error or no level threshold met One - Lowest trigger compare threshold met Two - Middle & Lowest trigger compare threshold met Three - All trigger compare thresholds met -- * note - component specific only to level 1 -- Comments: -- lo - Indicates components belonging to -- the computational engine trigger level -- operations -- ei - Indicates signals or components belonging -- to the computational engine input stage -- e0 - Indicates signals or components belonging -- to the first computational engine stage -- el - Indicates signals or components belonging -- to the second computational engine stage -- eo - Indicates signals or components belonging -- to the computational engine output state -- Author: Andrew Vander Molen 114 -- Author: Brian Foulds -- Board Engineer: Krista Marks -- History: -- 05/26/99 Version 1.0.0 (Initial) -- 06/08/99 Changed id signal to input only -- 06/11/99 Changed ratio components -- 03/13/00 Removed maximum levels from level_l_triglev macro library IEEE; use IEEE.std_logic_l l64.all; library WORK; use WORK.ernc.all; -- PORT DECLARATION entity level_l is port( clk: in std_logic; rst: in std_logic; vme_select_engine_n: in std_logic; vme_write_n: in std_logic; engine_ack_n: out std_logic; ia: in emc_ia; id: in emc_id; trigger_tower_O: in emc_trigger_energy; trigger_tower_l: in emc_trigger_energy; trigger_tower_2: in emc_trigger_energy; trigger_tower_3: in emc_trigger_energy; trigger_tower_4: in emc_trigger_energy; trigger_tower_S: in emc_trigger_energy; trigger_tower_6: in emc_trigger_energy; trigger_tower_7: in emc_trigger_energy; trigger_tower_8: in emc_trigger_energy; trigger_tower_9: in emc_trigger_energy; hi gh_tower_0: in ernc_high_energy; hi gh_tower_l : in ernc_high_energy; hi gh__tower_2: in ernc_high_energy; hi gh_tower_3: in ernc_high_energy; hi gh_tower_4: in ernc_high_energy; high_tower_S: in ernc_high_energy; hi gh_tower_6: in ernc_high_energy; hi gh_tower_7: in ernc_high_energy; 115 hi gh_tower_8: in ernc_high_energy; hi gh_tower_9: in ernc_high_energy; engine_output: out emc_level_l_output ); end level_l; -- ARCHITECTURE DECLARATION architecture 111 of level_l is -- SIGNAL DECLARATION signal level_l_triglev: signal level_l_highlev: signal level_l_ratiolev: signal ei_trigger_latched: signal ei_high_latched: signal e0_ratio_0: signal e0_ratio_l: signal e0_ratio_adjust: signal e0_energy: signal el_ratio_O: signal el_ratio_l: signal el_ratio_adjust: signal el_ratio: signal el_energy: signal el_triglev_compare_O: signal el_triglev_compare_l: signal el_triglev_compare_2: signal el_triglev_compare: signal el_triglev_compare_encode: signal el_highlev_compare_O: signal el_highlev_compare_l: signal el_highlev_compare_2: signal el_highlev_compare: signal el_highlev_compare_encode: signal el_ratiolev_compare_O: signal el_ratiolev_compare_l: signal el_ratiolev_compare_2: signal el_ratiolev_compare: signal el_ratiolev_compare_encode: signal e1__latch_input: emc_level_l_triglev_vector; emc_level_1_highlev_vector; emc_level_1_ratiolev_vector; emc_trigger_energy_vector; emc_hr'gh_energy_vector; emc_ratio_pO_vector; emc_ratio_pl_vector; emc_ratio_adj ust_vector; emc_level_l_energy; emc_ratio_pO_vector; emc_ratio_pl_vector; emc_ratio_adj ust_vector; emc_ratio_vector; emc_level_l_energy; emc_level_l_compare; emc_level_l_compare; emc_level_l_compare; emc_triglev_compare; emc_compare_encode; emc_level_l_compare; emc_level_l_compare; emc_level_l_compare; emc_triglev_compare; emc_compare_encode; emc_level_l_compare; emc_level_l_compare; emc_level_l_compare; emc_triglev_compare; emc_compare_encode; emc_level_l_output; 116 signal el_latch_output: emc_level_1 _output; -- COMPONENT DECLARATION component latch_clk36_p generic (width: integer); p011( clk: in std_logic; rst: in std_logic; input: in std_logic_vector ((width - 1) downto 0); output: out std_logic_vector ((width - 1) downto 0) ); end component; component latch_clk3 6_n generic (width: integer); port ( clk: in std_logic; rst: in std_logic; input: in std_logic_vector ((width - l) downto 0); output: out std_logic_vector ((width - l) downto 0) ); end component; component level_l_trigger_level port ( clk: in std_logic; rst: in std_logic; vme_select_engine_n: in std_logic; vme_write_n: in std_logic; ia: in emc_ia; id: in emc_id; level_l _triglev: inout emc_level_l_triglev_vector; level_l_highlev: inout emc_level_1_highlev_vector; level_l_ratiolev: inout emc_level_1_ratiolev_vector; engine_ack_n: out std_logic ); end component; component sum_trigger_energy port( op_O: in emc_trigger_energy; op_l: in emc_trigger_energy; op_2: in emc_trigger_energy; 117 begin op_3: in emc_trigger_energy; op_4: in emc_trigger_energy; op_5: in emc_trigger_energy; op_6: in emc_trigger_energy; op_7: in emc_trigger_energy; op_8: in emc_trigger_energy; op_9: in emc_trigger_energy; sum: out emc_level_l_energy ); end component; component ratio_e0 pom dividend: in emc_trigger_energy; divisor: in ernc_high_energy; product_O: out two_nibbles; product_1: out one_nibble; adjust: out std_logic ); end component; component ratio_el port ( product_O: in two_nibbles; product_1: in one_nibble; adjust: in std_logic; product: out two_nibbles ); end component; component compare_20ps generic (nibble_cnt: integer); p011( level: in std_logic_vector((4 * nibble_cnt - l) downto 0); op: in std_logic_vector((4 * nibble_cnt - l) downto 0); result: out std_logic ); end component; component compare_encoder port ( triglev_compare: in emc_triglev_compare; compare_encode: out emc_compare_encode ); end component; 118 -- GROUNDING OPERATIONS OF COMPUTATIONAL ENGINE ei_trigger_latched(0)(7 downto 6) <= "00"; ei_trigger_latched(1)(7 downto 6) <= "00"; ei_trigger_latched(2)(7 downto 6) <= "00"; ei_trigger_latched(3)(7 downto 6) <= "00"; ei_trigger_latched(4)(7 downto 6) <= "00"; ei_trigger_latched(5)(7 downto 6) <= "00"; ei_trigger_latched(6)(7 downto 6) <= "00"; ei_trigger_latched(7)(7 downto 6) <= "00"; ei_trigger_latched(8)(7 downto 6) <= "00"; ei_trigger_latched(9)(7 downto 6) <= "00"; ei_high_latched(0)(7 downto 6) <= "00"; ei_high_latched(l)(7 downto 6) <= "00"; ei_high_latched(2)(7 downto 6) <= "00"; ei_high_latched(3)(7 downto 6) <= "00"; ei_high_latched(4)(7 downto 6) <= "00"; ei_high_latched(5)(7 downto 6) <= "00"; ei_high_latched(6)(7 downto 6) <= "00"; ei_high_latched(7)(7 downto 6) <= "00"; ei_high_latched(8)(7 downto 6) <= "00"; ei_high_latched(9)(7 downto 6) <= "00"; -- LEVEL OPERATIONS OF COMPUTATIONAL ENGINE level_l_lo: level_l_trigger__level port map (clk, rst, vme_select_engine_n, vme_write_n, ia, id, level_l_triglev, level_l_highlev, level_l_ratiolev, engine_ack_n); -- INPUT LATCH STAGE OF COMPUTATIONAL ENGINE (ei) - Latches for trigger towers level_l _ei_tri g ger_l atch_0: latch_clk3 6_n generic map (6) port map (clk, rst, trigger_tower_O, ei_trigger_latched(0)(5 downto 0)); level_l_ei_trigger_latch_l: latch_clk36_n 119 generic map (6) port map (clk, rst, trigger_tower_l, ei_trigger_latched( l )(5 downto 0)); level_l_ei_trigger_latch_Z: latch_clk3 6_n generic map (6) port map (clk, rst, trigger_tower_2, ei_trigger_latched(2)(5 downto 0)); level_l_ei_trigger_latch_3: latch_clk36_n generic map (6) port map (clk, rst, trigger_tower_3, ei_trigger_latched(3)(5 downto 0)); level_l_ei_trigger_latch_4: latch_clk3 6_n generic map (6) port map (clk, rst, trigger_tower_4, ei_trigger_latched(4)(5 downto 0)); level_l_ei_trigger_latch_S: latch_clk3 6_n generic map (6) port map (clk, rst, trigger_tower_S, ei_trigger_latched(5)(5 downto 0)); level_l_ei_trigger_latch_6: latch_clk3 6_n generic map (6) port map (clk, rst, trigger_tower_6, ei_trigger_latched(6)(5 downto 0)); level_l_ei_trigger_latch_7: latch_clk3 6_n generic map (6) port map (clk, rst, trigger_tower_7, ei_trigger_latched(7)(5 downto 0)); level_l_ei_trigger_latch_8: latch_clk3 6_n generic map (6) port map (clk, rst, trigger_tower_8, ei_trigger_latched(8)(5 downto 0)); level_l_ei_trigger_latch_9: latch_clk3 6_n generic map (6) port map (clk, rst, trigger_tower_9, ei_trigger_latched(9)(5 downto 0)); -- Latches for high towers level_l_ei_high_latch_0: latch_clk3 6_n 120 generic map (6) port map (clk, rst, high_tower_O, ei_high_latched(0)(5 downto 0)); level_l_ei_high_latch_l: latch_clk3 6_n generic map (6) port map (clk, rst, high_tower_l , ei_high_latched( l )(5 downto 0)); level_l_ei_high_latch_Z: latch_clk3 6_n generic map (6) port map (clk, rst, high_tower_2, ei_high_latched(2)(5 downto 0)); level_l_ei_high_latch_3: latch_clk3 6_n generic map (6) port map (clk, rst, high_tower_3, ei_high_latched(3)(5 downto 0)); level_l_ei_high_latch_4: latch_clk3 6_n generic map (6) port map (clk, rst, high_tower_4, ei_high_latched(4)(5 downto 0)); level_l_ei_high_latch_S: latch_clk3 6_n generic map (6) port map (clk, rst, high_tower_S, ei_high_latched(5)(5 downto 0)); level__1_ei_high_latch__6: latch_clk3 6_n generic map (6) port map (clk, rst, high_tower_6, ei_high_latched(6)(5 downto 0)); level_l_ei_high_latch_7: latch_clk3 6_n generic map (6) port map (clk, rst, high_tower_7, ei_high_latched(7)(5 downto 0)); level_l_ei_high_latch_8: latch_clk3 6_n generic map (6) port map (clk, rst, high_tower_8, ei_high_latched(8)(5 downto 0)); level_l_ei_high_latch_9: latch_clk3 6_n generic map (6) 121 port map (clk, rst, high_tower_9, ei_high_latched(9)(5 downto 0)); -- FIRST STAGE OF COMPUTATIONAL ENGINE (eO) -- Compute the energy sum partials level_l_e0__sum : sum_trigger_energy port map (ei_trigger_latched(0)(5 downto 0), ei_trigger_latched( l )(5 downto 0), ei_trigger_latched(2)(5 downto 0), ei_trigger_latched(3)(5 downto 0), ei_trigger_latched(4)(5 downto 0), ei_trigger_latched(5)(5 downto 0), ei_trigger_latched(6)(5 downto 0), ei_trigger_latched(7)(5 downto 0), ei_trigger_latched(8)(5 downto 0), ei_trigger_latched(9)(5 downto 0), e0_energy); -- Generate the ratios level_l_e0__ratio: fori in 0 to 9 generate cells: ratio_eO port map (ei_trigger_latched(iXS downto 0), ei_high_latched(i)(5 downto 0), e0_ratio_0(i), e0_ratio_1 (i), e0_ratio_adjust(i)); end generate; -- Save the e0 state for e1 level_l_eO_energy_latch: latch_clk3 6_n generic map (10) port map (clk, rst, e0_energy, el_energy); level_l_e0_ratio_adj ust_latch: latch_clk3 6_n generic map (10) port map (clk, rst, e0_ratio_adjust, el_ratio_adjust); level_l_e0_ratio_low_latch: for i in 0 to 9 generate cells__0: latch_clk3 6_n generic map (8) port map (clk, rst, e0_ratio_0(i), e1_ratio_0(i)); cells_l: latch_clk36_n generic map (4) 122 port map (clk, rst, e0_ratio_l(i), el_ratio_l(i)); end generate; -- SECOND STAGE OF COMPUTATIONAL ENGINE (e1) -- Compute the final ratio 1evel_l_el__ratio_high: for i in 0 to 9 generate cells: ratio_el port map (e1_ratio_0(i), el_ratio_1(i), el_ratio_adjust(i), el_ratio(i)); end generate; -- Compare Trigger Towers to 3 thresholds level_l_el_triglev_0_compare: for i in 0 to 9 generate cells: compare_20ps generic map(2) port map (level_l_triglev(O), ei_trigger_latched(i), e1_triglev_compare_0(i)); end generate; el_triglev_compare(0) <= e1_triglev_compare_0(0) or e1_triglev_compare_0( l) or e1_triglev_compare_0(2) or e1_triglev_compare_0(3) or e1_triglev_compare_0(4) or e1_triglev_compare_0(5) or e1_triglev_compare_0(6) or e1_triglev_compare_0(7) or e1_triglev_compare_0(8) or e1_triglev_compare_0(9); level_l_e1_triglev_l_compare: for i in 0 to 9 generate cells: compare_20ps generic map(2) port map (level_l_triglev(l ), ei_trigger_latched(i), e l_tri g1ev_compare_l (i)); end generate; e1_triglev_compare(l) <= e1_triglev_compare_l(0) or e1_triglev_compare_l(l) or e1_triglev_compare_l(2) or el_triglev_compare_l (3) or e1_triglev_compare_l(4) or e1_triglev_compare_l(5) or e1_triglev_compare_l(6) or e1_triglev_compare_l(7) or e1_triglev_compare_l(8) or e1_triglev_compare_l (9); level_l_e1_tri glev_2_compare: for i in 0 to 9 generate 123 cells: compare_20ps generic map(2) port map (level_l_triglev(2), ei_trigger_latched(i), e1_triglev_compare_2(i)); end generate; el_triglev_compare(2) <= e1_triglev_compare_2(0) or e1_triglev_compare_2(l) or e1_triglev_compare_2(2) or e1_triglev_compare_2(3) or e1_triglev_compare_2(4) or e1_triglev_compare_2(5) or e1_triglev_compare_2(6) or e1_triglev_compare_2(7) or e1_triglev_compare_2(8) or e 1_triglev_compare_2(9); level_l_el_trigger_compare_encode: compare_encoder port map (el_triglev_compare, el_triglev_compare_encode); - Compare High Towers to 3 thresholds level_l_e1_highlev_0_compare: fori in 0 to 9 generate cells: compare_20ps generic map(2) port map (level_l_highlev(O), ei_high_latched(i), el_highlev_compare_0(i)); end generate; el_highlev_compare(0) <= el_highlev_compare_0(0) or el_highlev_compare_0( l) or el_highlev_compare_0(2) or e1_hr'ghlev_compare_0(3) or el_highlev_compare_0(4) or el_highlev_compare_0(5) or el_highlev_compare_0(6) or el_highlev_compare_0(7) or el_highlev_compare_0(8) or e1 _highlev_compare_0(9); level_l_e1_highlev__1_compare: for i in 0 to 9 generate cells: compare_20ps generic map(2) port map (level_l_highlev( 1), ei_high_latched(i), e l _highlev_compare_l (i)); end generate; el_highlev_compare(l) <= el_highlev_compare_l(O) or el__highlev_compare_l( 1) or el_highlev_compare_l (2) or el_highlev_compare_l (3) or el_highlev_compare_l(4) or el_highlev_compare_l(S) or el_highlev_compare_l(6) or el_highlev_compare_l(7) or el_highlev_compare_l(8) or e 1 _hi ghlev_compare_1 (9); 124 level_l_e1_highlev_2_compare: for i in 0 to 9 generate cells: compare_20ps generic map(2) port map (level_l_highlev(2), ei_high_latched(i), el_highlev_compare_2(i)); end generate; el_highlev_compare(2) <= el_highlev_compare_2(0) or el_highlev_compare_2(1) or el_highlev_compare_2(2) or el_highlev_compare_2(3) or el_highlev_compare_2(4) or el_highlev_compare_2(5) or el_highlev_compare_2(6) or el_highlev_compare_2(7) or el_highlev_compare_2(8) or el_highlev_compare_2(9); top_el_highlev_compare_encode: compare_encoder port map (el_highlev_compare, e l_highlev_compare_encode); -- Compare Ratios to 3 thresholds level_l_e1_ratio_0_compare: for i in 0 to 9 generate cells: compare_20ps generic map (2) port map (level_l_ratiolev(O), el_ratio(i), el_ratiolev_compare_0(i)); end generate; el_ratiolev_compare(0) <= el_ratiolev_compare_0(0) or e1_ratiolev_compare_0( l) or e1_ratiolev_compare_0(2) or el_ratiolev_compare_0(3) or e1_ratiolev__compare_0(4) or el_ratiolev_compare_0(5) or el_ratiolev_compare_0(6) or el_ratiolev_compare_0(7) or el_ratiolev_compare_0(8) or e 1_ratiolev_compare_0(9); level_l_el_ratio_l_compare: for i in 0 to 9 generate cells: compare_20ps generic map (2) port map (level_l_ratiolev(l), el_ratio(i), e 1 _ratiolev_compare_l (i)); end generate; e1_ratiolev_compare(l) <= el_ratiolev_compare_l(O) or el_ratiolev_compare_l(l) or el_ratiolev_compare_l(2) or el_ratiolev_compare_l(3) or el_ratiolev_compare_l(4) or el_ratiolev_compare_l(S) or el_ratiolev_compare_l(6) or el_ratiolev_compare_l (7) or el_ratiolev_compare_l (8) or e l _ratiolev_compare_1 (9); 125 level_l_el_ratio_2_compare: for i in 0 to 9 generate cells: compare_20ps generic map (2) port map (level_l_ratiolev(2), el_ratio(i), el_ratiolev_compare_2(i)); end generate; el_ratiolev_compare(2) <= el_ratiolev_compare_2(0) or el_ratiolev_compare_2(l) or el_ratiolev_compare_2(2) or el_ratiolev_compare_2(3) or el_ratiolev_compare_2(4) or el_ratiolev_compare_2(5) or el_ratiolev_compare_2(6) or el_ratiolev_compare_2(7) or el_ratiolev_compare_2(8) or el_ratiolev_compare_2(9); top_el_ratio_compare_encode: compare_encoder port map (el_ratiolev_compare, el_ratiolev_compare_encode); -- Save e1 state for output e l_latch_input <= el_ratiolev_compare_encode & el_highlev_compare_encode & el_triglev_compare_encode & el_energy; top_el_latch: latch_clk3 6_n generic map (16) port map (clk, rst, el_latch_input, el_latch_output); -- OUTPUT LATCH STAGE OF COMPUTATIONAL ENGINE (e0) -- Engine output latch top_engine_output_latch: latch_clk36_p generic map (16) port map (clk, rst, el_latch_output, engine_output); end rtl; B6 level_l_tb.vhd (Level 1 testbench) -- Space Sciences Laboratory, UC Berkeley (c) 1999 -- Michigan State University -- STAR Trigger Electronics -- Filename: level_l_tb.vhd 126 -- Description: Testbench for Level 1 -- Author: Andrew Vander Molen -- Author: Brian Foulds -- Board Engineer: Krista Marks -- History: -- 03/01/99 Version 1.0.0 (Initial) -- 03/20/00 Removed TB Data component and provided random generation -- of test data library IEEE; library WORK; use IEEE.std_logic_l 164.All; use IEEE.std_logic_unsigned.All; use IEEE.std_logic_arith.All; use WORK.emc.all; use WORK.RndNumGen.all; -- PORT DECLARATION entity level_l_tb is end level_l_tb; -- ARCHITECTURE DECLARATION architecture behavioral of level_l_tb is -- COMPONENT DECLARATION component level_l Port( clk: in std_logic; rst: in std_logic; vme_select_engine_n: in std_logic; vme_write_n: in std_logic; engine_ack_n: out std_logic; ia: in std_logic_vector( 4 downto 0); id: in std_logic_vector(lS downto 0); trigger_tower_O: in std_logic_vector(S downto 0); 127 trigger_tower_l : trigger_tower_2: trigger_tower_3 : trigger_tower_4: tri g ger_tower_5 : trigger_tower_6: trigger_tower_7: trigger_tower_8: trigger_tower_9: hi gh__tower_0: high_tower_l : hi gh_tower_2: hi gh_tower_3 : hi gh_tower_4: hi gh_tower_5: high_tower_6: hi gh_tower_7: hi gh_tower__8: high_tower_9: engine_output: ); end component; in std_logic_vector(S downto 0); in std_logic_vector(S downto 0); in std_logic_vector(S downto 0); in std_logic_vector(S downto 0); in std_logic_vector(S downto O); in std_logic_vector(S downto 0); in std_logic_vector(S downto 0); in std_logic_vector(S downto 0); in std_logic_vector(S downto 0); in std_logic_vector(S downto 0); in std_logic_vector(S downto 0); in std_logic_vector(S downto 0); in std_logic_vector(S downto 0); in std_logic_vector(S downto 0); in std_logic_vector(S downto 0); in std_logic_vector(S downto 0); in std_logic_vector(S downto 0); in std_logic_vector(S downto 0); in std_logic_vector(S downto 0); out std_logic_vector( l 5 downto 0) -- TYPE DECLARATION type clk36_st is (reset, lo, ei, e0, e1, e0); type tb_trigger_tower_vector is array(0 to 9) of emc_trigger_energy; type tb_high_tower_vector is array(0 to 9) of ernc_high_energy; —- SIGNAL DECLARATION -- Level 1 signals signal clk36: std_logic := '0'; signal rst: std_logic := '1'; signal vme_select_engine_n: std_logic := '1'; signal vme_write_n: std_logic := '1'; signal engine_ack_n: std_logic; signal ia: emc_ia; signal id: emc_id; signal trigger_tower: tb_trigger_tower_vector; signal high_tower: tb_high__tower_vector; signal engine_output: emc_level_l_output; -- Testbench signals signal level _pc: signal rst__level_pc: signal ST: signal ei_flag: signal trnp_triglev: signal trnp_highlev: signal trnp_ratiolev: signal level_l_ratiolev: signal level_l_triglev: signal level_l_highlev: signal ratio: signal tb_output: signal tb_output_assert: integer; boolean; clk3 6_st; std_logic; std_logic_vector(2 downto 0); std_logic_vector(2 downto 0); std_logic_vector(2 downto 0); emc_level_1_ratiolev_vector; emc_level_l_triglev_vector; emc_level_1_highlev_vector; emc_ratio_vector; emc_level_l_output; emc_level_l_output; -- CONSTANT DECLARATION begin -- Level 1 component tb_level_l: level_l port map (clk36, rst, vme_select_engine_n, vme_write_n, engine_ack_n, ia, id, trigger_tower(0), trigger_tower( l ), trigger_tower(2), trigger_tower(3), trigger_tower(4), trigger__tower(5), trigger_tower(6), trigger_tower(7), trigger_tower(8), trigger_tower(9), high_tower(0), hi gh_tower(1), high_tower(2), hi gh_tower(3), high_tower(4), 129 high_tower(5), high_tower(6), high_tower(7), high_tower(8), high_tower(9), engine_output); -- Clock signal clk36 <= not clk36 after 13.125ns; -- Reset signal rst <= '0' after 5ns; -- Trigger tower sum tb_output(9 downto 0) <= ("0000" & trigger_tower(0)) + ("0000" & trigger_tower(1)) + ("0000" & trigger_tower(2)) + ("0000" & trigger_tower(3)) + ("0000" & trigger_tower(4)) + ("0000" & trigger_tower(5)) + ("0000" & trigger_tower(6)) + ("0000" & trigger_tower(7)) + ("0000" & trigger_tower(8)) + ("0000" & trigger_tower(9)); -- Process control blocks for compares tb_level_l_triglev_control: process(trigger_tower, level_l_triglev) begin -- Compare to 3 thresholds if ((trigger_tower(O) >=level_1_triglev(0)) or (trigger_tower(l) >=leve1_1_triglev(0)) or (trigger_tower(Z) >= level_l_triglev(0)) or (trigger_tower(3) >= 1evel_1_triglev(0)) or (trigger_tower(4) >= level_l_triglev(0)) or (trigger_tower(S) >= level_l_triglev(0)) or (trigger_tower(6) >= level_l_triglev(0)) or (trigger_tower(7) >= level_l_triglev(0)) or (trigger_tower(8) >= level_l_triglev(0)) or (trigger_tower(9) >= level_l_triglev(0))) then trnp_triglev(0) <= '1 '; else trnp_triglev(0) <= '0'; end if; if ((trigger_tower(O) >= 1eve1_l_triglev(1)) or 130 (trigger_tower( 1) >= level_l _triglev( 1 )) or (trigger_tower(2) >= level_l_triglev(l)) or (trigger_tower(3) >= level_l_triglev(l)) or (trigger_tower(4) >= level_l_triglev( 1)) or (trigger_tower(S) >= level_l_triglev(l)) or (trigger_tower(6) >= level_l_triglev(l)) or (trigger_tower(7) >= level_l_triglev(l)) or (trigger_tower(8) >= level_l_triglev( 1)) or (trigger_tower(9) >= level_l_triglev(l))) then trnp_triglev(l) <= '1'; else trnp_triglev(l) <= '0'; end if; if ((trigger_tower(O) >= level_l_triglev(2)) or (trigger_tower(l) >= level_l_triglev(2)) or (trigger_tower(2) >= level_l_triglev(2)) or (trigger_tower(3) >= level_l_triglev(2)) or (trigger_tower(4) >= level_l_triglev(2)) or (trigger_tower(S) >= level_l_triglev(2)) or (trigger_tower(6) >= level_l_triglev(2)) or (trigger_tower(7) >= level_l_triglev(2)) or (trigger_tower(8) >= level_l_triglev(2)) or (trigger_tower(9) >= level_l_triglev(2)» then trnp_triglev(2) <= '1'; else trnp_triglev(2) <= '0'; end if; end process tb_level_1_tri g1ev_control; tb_level_1_highlev_control: process(high_tower, level_l_highlev) begin -- Compare to 3 thresholds if ((high_tower(O) >= level_l_highlev(0)) or (high_tower(l) >= level_l_highlev(0)) or (high_tower(2) >= level_l_highlev(0)) or (high_tower(3) >=level_1_highlev(0)) or (high_tower(4) >= level_l_highlev(0)) or (high_tower(S) >= level_l_highlev(0)) or (high_tower(6) >= level_l_highlev(0)) or (high_tower(7) >=level_1_high1ev(0)) or (high_tower(8) >= level_l_highlev(0)) or (high_tower(9) >= level_l_highlev(0))) then 131 trnp_highlev(0) <= '1'; else trnp_highlev(0) <= '0'; end if; if ((high_tower(O) >= level_l_highlev(l )) or (hi gh_tower( 1 ) >= level_l _highlev( 1)) or (high_tower(2) >= level_l_highlev(l)) or (high_tower(3) >= level_l_highlev(l)) or (hi gh_tower(4) >= level_l_highlev(l)) or (high_tower(S) >= level_l_highlev(l)) or (high_tower(6) >= level_l_highlev(l)) or (high_tower(7) >= level_l_highlev(l)) or (high_tower(8) >= level_l_highlev(l)) or (high_tower(9) >= level_l_highlev(l))) then trnp_highlev(l) <= '1'; else trnp_highlev(l) <= '0'; end if; if ((high_tower(O) >= level_l_highlev(2)) or (high_tower(l) >= level_l_highlev(2)) or (high_tower(2) >= level_l_highlev(2)) or (high_tower(3) >= level_l_highlev(2)) or (high_tower(4) >= level_l_highlev(2)) or (high_tower(S) >= level_l_highlev(2)) or (high_tower(6) >= level_l_highlev(2)) or (high_tower(7) >= level_l_highlev(2)) or (high_tower(8) >= level_l_highlev(2)) or (high_tower(9) >= level_l_highlev(2))) then trnp_highlev(2) <= '1'; else trnp_highlev(2) <= '0'; end if; end process tb_level_1_highlev_control; tb_level_1_gen_ratiolev: process(trigger_tower, hi gh_tower) begin -- Generate the ratios tb_ratio_gen: for i in 0 to 9 loop if (high_tower(i) = "000000") then ratio(i) <= "11111111"; elsif (trigger_tower(i) = high_tower(i)) then ratio(i) <= "11111111"; 132 else ratio(i) <= CONV_STD_LOGIC_VECTOR (CONV_INTEGER( trigger_tower(i) & "00000000")/ CONV_INTEGER(high_tower(i)), 8); end if; end loop; end process tb_level_1_gen_ratiolev; tb_level_l_ratiolev_control: process(ratio, level_l_ratiolev) begin -- Compare to 3 thresholds if ((ratio(O) >= level_l_ratiolev(0)) or (ratio(l) >= level_l_ratiolev(0)) or (ratio(2) >= level_l_ratiolev(0)) or (ratio(3) >= level_l_ratiolev(0)) or (ratio(4) >= level_l_ratiolev(0)) or (ratio(S) >= level_l_ratiolev(0)) or (ratio(6) >= level_l_ratiolev(0)) or (ratio(7) >= level_l_ratiolev(0)) or (ratio(8) >= level_l_ratiolev(0)) or (ratio(9) >= level_l_ratiolev(0))) then trnp_ratiolev(O) <= '1'; else trnp_ratiolev(O) <= '0'; end if; if ((ratio(O) >= level_l_ratiolev(l)) or (ratio(l) >= level_l_ratiolev( 1)) or (ratio(2) >= level_l_ratiolev( 1 )) or (ratio(3) >= level_l_ratiolev(l)) or (ratio(4) >= level_l_ratiolev(l)) or (ratio(S) >= level_l_ratiolev( 1 )) or (ratio(6) >= level_l_ratiolev( l )) or (ratio(7) >= level_l_ratiolev(l)) or (ratio(8) >= level_l_ratiolev( l )) or (ratio(9) >= level_l_ratiolev(l))) then trnp_ratiolev(l) <= '1‘; else trnp_ratiolev( 1) <= '0'; end if; if ((ratio(O) >= level_l_ratiolev(2)) or 133 (ratio(l) >= level_l_ratiolev(2)) or (ratio(2) >= level_l_ratiolev(2)) or (ratio(3) >= level_l_ratiolev(2)) or (ratio(4) >= level_l_ratiolev(2)) or (ratio(S) >= level_l_ratiolev(2)) or (ratio(6) >= level_l_ratiolev(2)) or (ratio(7) >= level_l_ratiolev(2)) or (ratio(8) >=1evel_l_ratiolev(2)) or (ratio(9) >= level_l_ratiolev(2)» then trnp_ratiolev(2) <= '1'; else trnp_ratiolev(2) <= '0'; end if; end process tb_level_l_ratiolev_control; tb_level_1_compress: process (trnp_triglev, trnp_highlev, tmp_ratiolev) begin case trnp_triglev is when "001" | "010" | "100" => tb_output(ll downto 10) <= "01"; when "011" l "101" | "110" => tb_output(ll downto 10) <= "10"; when "111" => tb_output(ll downto 10) <= "11"; when others => tb_output(ll downto 10) <= "00"; end case; case trnp_highlev is when "001" | "010" | "100" => tb_output(13 downto 12) <= "01"; when "011" | "101" | "110" => tb_output(13 downto 12) <= "10"; when "111" => tb_output(13 downto 12) <= "11"; when others => tb_output(13 downto 12) <= "00"; end case; case tmp_ratiolev is when "001" | "010" | "100" => tb_output(IS downto l4) <= "01"; when "011" | "101" | "110" => tb_output(15 downto 14) <= "10"; when "111" => 134 tb_output(15 downto 14) <= "11"; when others => tb_output(15 downto 14) <= "00"; end case; end process tb_level_1_compress; -- Process control block for state tb_clk36_control: process (clk36, rst) type tower_array is array (0 to 9) of md_int; variable tt: tower_array; variable ht: tower_array; variable ttl: md_int; variable htl: md_int; variable r1: md_int; variable seed: md_int; begin -- Positive-edge clock if (clk36'event and clk36 = '1' and rst = '0') then case ST is when reset => if (rst = '1') then ST <= reset; else ST <= ei; end if; when eo => ST <= ei; -- Check Trigger Energy Sum assert tb_output_assert(9 downto 0) = engine_output(9 downto 0) report "Trigger Energy Sum Failure"; -- Check Trigger Tower Level Trigger assert tb_output_assert(ll downto 10) = engine_output(ll downto 10) report "Trigger Tower Level Trigger Failure"; -- Check High Tower Level Trigger assert tb_output_assert( l 3 downto 12) = engine_output(l3 downto 12) report "High Tower Level Trigger Failure"- 135 -- Check Ratio Level Trigger assert tb_output_assert(IS downto 14) = engine_output( l 5 downto 14) report "Ratio Level Trigger Failure"; when others => null; end case; end if; -- Negative-edge clock if (clk36'event and clk36 = '0' and rst = '0') then case ST is when ei => if (ei_flag = '1') then ST <= e0; ei_flag <= '0'; else ei_flag <= '1'; end if; when e0 => ST <= e1; when e1 => ST <= eo; -- Save the TestBench output for Assertion tb_output_assert <= tb_output; -- Generate new data for i in 0 to 9 loop -- generate the high tower Geand(ht(i)); -- reset the maximum trigger tower values tt(i).max := ht(i).value; -- generate the trigger tower Geand(tt(i)); -- output the values high_tower(i) <= CONV_STD_LOGIC_VECTOR (ht(i).value, 6); trigger_tower(i) <= CONV_STD_LOGIC_VECTOR (tt(i).value, 6); 136 end 100p; when 10 => -- Generate & assign the levels the levels case level _pc is when 0 to 2 => if (level _pc = 0) then report "Assigning Trigger Levels"; end if; Geand(ttl); level_l_triglev(level__pc) <= CONV_STD_LOGIC_VECTOR (ttl.value, 8); ia <= CONV_STD_LOGIC_VECTOR (level __pc, 5); id <= "00000000" & CONV_STD_LOGIC_VECTOR (ttl.value, 8); vme_select_engine_n <= '0'; vme_write_n <= '0'; when 3 to 5 => Geand(htl); level_l_highlev(level__pc - 3) <= CONV_STD_LOGIC_VECTOR( htl.value, 8); ia <= CONV_STD_LOGIC_VECTOR (level _pc, 5); id <= "00000000" & CONV_STD_LOGIC_VECTOR (htl.value, 8); vme_select_engine_n <= '0'; vme_write_n <= '0'; when 6 to 8 => 137 Geand(rl); level_l_ratiolev(level_pc - 6) <= CONV_STD_LOGIC_VECTOR (rl.value, 8); ia <= CONV_STD_LOGIC_VECTOR (level _pc, 5); id <= "00000000" & CONV_STD_LOGIC_VECTOR (rl.value, 8); vme_select_engine_n <= '0'; vme_write_n <= '0'; when others => ST <= ei; vme_select_engine_n <= '1'; vme_write_n <= '1'; if (level _pc = 9) then report "Trigger Levels Assigned, Beginning Engine"; Endifi end case; -- Adjust the level pc If (level _pc <= 8) then level _pc <= level _pc + 1; else level _pc <= 0; end if; when others => null; end case; end if; -- Reset if(rst = '1') then ST <= 10; level _pc <= 0; ei_flag <= '0'; -- reset the seeding value seed.init := 14321; seed.min := 0; 138 seed.max := 50000; fori in 0 to 9 loop -- set the default minimum value ht(i).min := 0; tt(i).min := 0; -- set the default maximum values ht(i).max := 63; tt(i).max := 63; -- set the initial seed Geand(seed); ht(i).init := seed.value; Geand(seed); tt(i).init := seed.value; end loop; -- Generate new data for i in 0 to 9 loop -- generate the high tower Geand(ht(i)); -- reset the maximum trigger tower values tt(i).max := ht(i).value; -- generate the trigger tower Geand(tt(i)); -- output the values high_tower(i) <= CONV_STD_LOGIC_VECTOR (ht(i).value, 6); trigger_tower(i) <= CONV_STD_LOGIC_VECTOR (tt(i).value, 6); end loop; -- Set the default mins for the levels ttl.min := 0; htl.min := 0; rl.min := 0; -- Set the default maxs for the levels ttl.max := 63; htl.max := 63; rl.max := 255; 139 -- Set the initial seed for the levels Geand(seed); Geand(seed); ttl.init := seed.value; Geand(seed); htl.init := seed.value; Geand(seed); rl.init := seed.value; end if; end process tb_clk3 6_control; end behavioral; 140 APPENDIX C Level 2 Synthesis Code C1 level_2_triglev.vhd (Level 2 Trigger Level operations) -- Space Sciences Laboratory, UC Berkeley (c) 1999 -- Michigan State University -- STAR Trigger Electronics -- F ilenarne: level_2_trigger_level.vhd -- Description: Sets the trigger levels and determines the highest -- trigger level for level 2 -- Input: clk - 38Mhz Clock (clk36) -- rst - Global reset -- vme_select_engine_n - From op controller; -- VME w/r engine registers -- vme_write_n__3 - From op controller; -- Write = 0, Read = 1 -- engine_ack_n - To op controller - done; -- VME w/r to registers -- ia - From VME, instruction address -- id - From VME, instruction data -- Inout: level_2_triglev - The array of trigger level -- thresholds -- Output: engine_ack_n - To op controller - done; -- VME w/r to registers -- Author: Andrew Vander Molen -- Author: Brian Foulds -- Board Engineer: Krista Marks -- History: -- 05/20/99 Version 1.0.0 (Initial) -- 06/08/99 Changed id signal to input only -- 03/22/00 Removed highest signal library IEEE; use IEEE.std_logic_l l64.all; use IEEE.std_logic_arith.all; library WORK; use WORK.emc.all; 141 -- PORT DECLARATION entity Ievel_2_trigger_level is port ( clk: in std_logic; rst: in std_logic; vme_select_engine_n: in std_logic; vme_write_n: in std_logic; ia: in emc_ia; id: in emc_id; level_2_triglev: inout emc_level_2_triglev_vector; engine_ack_n: out std_logic ); end level_2_trigger_level; -- ARCHITECTURE DECLARATION architecture behavioral of level_2_trigger__level is begin -- PROCESS STATEMENTS level_2_triglev_control: process(clk, rst) begin if (clk'event and clk = '1') then if (vme_select_engine_n = '0' and vme_write_n = '0') then if (ia = emc_level_2_triglev_0_adr) then level_2_triglev(0)(15 downto l4) <= "00"; level_2_triglev(0)(13 downto 0) <= id(13 downto 0); elsif (ia = emc_level_2_triglev_l_adr) then level_2_triglev(1)(15 downto l4) <= "00"; level_2_triglev(1)(13 downto 0) <= id(13 downto 0); elsif (ia = emc_level_2_tri g1ev_2_adr) then level_2_triglev(2)(15 downto l4) <= "00"; level_2_triglev(2)(13 downto 0) <= 142 id(13 downto 0); end if; engine_ack_n <= '0'; else engine_ack_n <= '1'; end if; end if; if (rst = '1') then level_2_triglev(0) <= (others => '0'); level_2_triglev(1) <= (others => '0'); level_2_triglev(2) <= (others => '0'); engine_ack_n <= '1'; end if; end process level_2_triglev_control; end behavioral; C2 half_sum_level_l_energy.vhd (Half sum of Level 1 energy) -- Space Sciences Laboratory, UC Berkeley (c) 1999 -- Michigan State University -- STAR Trigger Electronics -- Filename: half_sum_level_1_energy.vhd - Description: Unsigned summation of four level 1 energies -- Input: op_x - Level 1 energy -- Output: sum - Half energy sum -- Structure: -- fa - Full Adder Component -- Author: Andrew Vander Molen -- Author: Brian F oulds -— Board Engineer: Krista Marks -- History: -- 05/12/99 Version 1.0.0 (Initial) library IEEE; use IEEE.std_logic_l l64.all; use IEEE.std_logic_unsigned.all; library WORK; use WORK.emc.all; 143 - -_ ' mun? -- PORT DECLARATION entity half_sum_level_1_energy is port( op_0: in emc_level_l_energy; op_lz in emc_level_l_energy; op_2: in emc_level_l_energy; op_3: in emc_level_l_energy; sum: out four_nibbles ); end half_sum_level_1_energy; -- ARCHITECTURE DECLARATION architecture structural of half_sum_level_1_energy is -- COMPONENT DECLARATION component fa port ( x: y: cin: s: cout: ); end component; in std_logic; in std_logic; in std_logic; out std_logic; out std_logic -- SIGNAL DECLARATION signal op_l l_c0_b0 : : std_logic; signal op_l l_c l_bl signal op_ll_cl_bO : : std_logic; signal op_l 1_c2_bl signal op_l 1_c2_b0 : : std_logic; signal op_ll_c3_bl signal op_ll_c3_b0 : std_logic; std_logic; std_logic; std_logic; 144 signal op_ll_c4_b1 : std_logic; signal op_ll_c4_b0 : std_logic; signal op_ll_c5_bl : std_logic; signal op_ll_cS_b0 : std_logic; signal op_ll_c6_bl : std_logic; signal op_ll_c6_b0 : std_logic; signal op_l l_c7_b1 : std_logic; signal op_ll_c7_b0 : std_logic; signal op_11_c8_bl : std_logic; signal op_ll_c8_b0 : std_logic; signal op_ll_c9_b1 : std_logic; signal op_ll_c9_b0 : std_logic; signal sum_O: emc_level_2_quarter_energy; signal sum_l: emc_level_2_quarter_energy; signal gnd: std_logic; begin -- CONCURRENT STATEMENTS gnd <= 10'; -- CSA structure declaration -- Level 0, Bit 0 csa_fa_10_c0_0: fa port map (op_0(0), op_1(0), op_2(0), op_ll_c0_b0, op_ll_cl_bl); -— Level 0, Bit 1 csa_fa_10_cl_0: fa port map (op_0(1), op_1(1), op_2(1), op_ll_cl_bO, op_ll_c2_b1); -- Level 0, Bit 2 csa_fa_10_c2_0: fa port map (op_0(2), op_1(2), op_2(2), op_l l_c2_b0, op_ll_c3_b1); -- Level 0, Bit 3 csa_fa_10_c3_0: fa port map (op_0(3), op_1(3), op_2(3), op_ll_c3_b0, op_ll_c4_b1); -- Level 0, Bit 4 csa_fa_10_c4_0: fa port map (op_0(4), op_1(4), op_2(4), 0p_l l_c4_b0, 0p_11_c5_b1); -- Level 0, Bit 5 csa_fa_10__c5_0: fa 145 port map (op_0(5), op_1(5), op_2(5), op_ll_c5_b0, op_ll_c6_bl); -- Level 0, Bit 6 csa_fa_10_c6_0: fa port map (op_0(6), op_1(6), op_2(6), op_ll_c6_b0, op_l l_c7_b1); -- Level 0, Bit 7 csa_fa_10_c7_0: fa port map (op_0(7), op_1(7), op_2(7), op_ll_c7_b0, op_l l_c8_b1); -- Level 0, Bit 8 csa_fa_10_c8_0: fa port map (op_0(8), op_1(8), op_2(8), op_ll_c8_b0, op_l l_c9__b1); -- Level 0, Bit 9 csa_fa_10_c9_0: fa port map (op_0(9), op_1(9), op_2(9), op_ll_c9__b0, sum_0(10)); -- Level 1, Bit 0 csa_fa_l 1_c0_0: fa port map (op_ll_c0_b0, op_3(0), gnd, sum_0(0), sum_l(1)); -- Level 1, Bit 1 csa_fa_l l_c1_0: fa port map (op_ll_cl_bO, op_ll_cl_bl, op_3(l), sum_0(l), sum_l(2)); -- Level 1, Bit 2 csa_fa_l 1_c2_0: fa port map (op_ll_c2_b0, op_ll_c2_bl, op_3(2), sum_0(2), sum_l(3)); -- Level 1, Bit 3 csa_fa_l 1_c3_0: fa port map (op_ll_c3_b0, op_ll_c3_bl, op_3(3), sum_0(3), sum_l(4)); -- Level 1, Bit 4 csa_fa_l l_c4_0: fa port map (op_ll_c4_b0, op_l l_c4_b1 , op_3(4), sum_0(4), sum_l(5)); -- Level 1, Bit 5 csa_fa_l 1_c5_0: fa port map (op_ll_c5_b0, op_ll_c5_bl, op_3(5), sum_0(5), sum_l(6)); -- Level 1, Bit 6 csa_fa_11_c6_0: fa port map (op_ll_c6_b0, op_ll_c6_bl, op_3(6), sum_0(6), sum_l(7)); 146 -- Level 1, Bit 7 csa_fa_l l_c7_0: fa port map (op_ll_c7_b0, op_ll_c7_bl, op_3(7), sum_0(7), sum_l(8)); -- Level 1, Bit 8 csa_fa_l 1_c8_0: fa port map (op_ll_c8_b0, op_ll_c8_b1, op_3(8), sum_0(8), sum_l(9)); -- Level 1, Bit 9 csa_fa_l 1_c9_0: fa port map (op_ll_c9_b0, op_l l_c9_b1, op_3(9), sum_0(9), sum_l(10)); -- Grounded Sum Operand Outputs sum_0(11) <= gnd; sum_l(O) <= gnd; sum_l(l 1) <= gnd; -- Final CPA sum <= ("0000" & sum_0) + ("0000" & sum_l); end structural; C3 sum_level_1__energy.vhd (Sum of Level 1 energy) -- Space Sciences Laboratory, UC Berkeley (c) 1999 -- Michigan State University -- STAR Trigger Electronics -- Filename: sum_level_l_energy.vhd -- Description: Unsigned summation of eight level 1 energies -- Input: op_x - Level 1 energy -- Output: sum - Final level 2 energy sum -- Structure: -- fa - Full Adder Component -- Author: Andrew Vander Molen -- Author: Brian F oulds -- Board Engineer: Krista Marks -- History: -- 05/20/99 Initial Version library IEEE; use IEEE.std_logic_l l64.all; 147 use IEEE.std_logic_unsigned.all; library WORK; use WORK.emc.all; -- PORT DECLARATION entity sum_level_1_energy is port( 0: in emc_level_l_energy; l: in emc_level_l_energy; 2: in emc_level_l_energy; 3: in emc_level_l_energy; 4: in emc_level_l_energy; 5: in emc_level_l_energy; 6: in emc_level_l_energy; op_ 7. in emc_level_l_energy; sum: out emc_level_2_energy 0P_ 0_P 0_P 0__P 0P_ 0__P 0_P ); end sum_level_1_energy; architecture structural of sum_level_1_energy is -- COMPONENT DECLARATION component fa port ( x: in std_logic; y: in std_logic; cin: in std_logic; s: out std_logic; cout: out std_logic ); end component; -- SIGNAL DECLARATION signal op_ 11 c_0_ b0: std _logic; signal op_ 11 _c1 _bB: std _logic; signal op_l 1_c0_b1: std_logic; 148 signal op_l l_c1_b4 : signal op_ll_c0_b2 : signal op_ll_cl_bS : signal op_ll_cl_bO : : std_logic; : std_logic; signal op_l l_cZ_b3 signal op_l l_c1_b 1 signal op_l l_c2_b4 : signal op_ll_cl_b2 : signal op_ll_c2_b5 : signal op_l l_c2_b0 : : std_logic; : std_logic; signal op_ll_c3_b4 : signal op_l 1_c2_b2 : signal op_ll_c3_b5 : signal op_ll_c3_b0 : : std_logic; : std_logic; signal op_ll_c4_b4 : signal op_ll_c3_b2 : signal op_l 1_c4_b5 : signal op_ll_c4_b0 : : std_logic; : std_logic; signal op_ll_c3_b3 signal op_l 1_c2_b1 signal op_ll_c4_b3 signal op_ll_c3_bl signal op_l l_c5_b3 signal op_l l_c4_bl signal op_ll_c5_b4 : signal op_ll_c4_b2 : signal op_ll_c5_b5 : signal op_ll_c5_b0 : : std_logic; : std_logic; signal op_l 1_c6_b3 signal op_l l_c5_bl signal op_l l_c6_b4 : : std_logic; : std_logic; signal op_ll_c5_b2 signal op_l 1_c6_b5 signal op_l l_c6_b0 : : std_logic; : std_logic; signal op_l l_c7_b3 signal op_ll_c6_bl signal op_ll_c7_b4 : : std_logic; : std_logic; signal op_l l_c6_b2 signal op_l 1_c7_b5 signal op_ll_c7_b0 : : std_logic; : std_logic; signal op_l l_c8_b3 signal op_l l_c7_bl signal op_ll_c8_b4 : signal op_ll_c7_b2 : signal op_ll_c8_b5 : signal 0p_ll_c8__b0 : std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; 149 signal op_l l_c9_b3 signal op_l l_c8_b1 signal op_ll_c9_b4 : signal op_ll_c8_b2 : signal op_l l_c9_b5 : signal op_ll_c9_b0 : signal op_ll_c10_b0 : std_logic; signal op_ll_c9_bl : signal op_l l_c10_b1 : std_logic; signal op_l l_c9_b2 : signal op_ll_c10_b2 : std_logic; signal op_l2_c0_b0 : signal op_12_c1_b2 : signal op_12_c1_b0 : signal op_12_c2_b2 : : std_logic; : std_logic; signal op_12_c1_b1 signal op_12_c2_b3 signal op_12_c2_b0 : signal op_12_c3_b2 : : std_logic; : std_logic; signal op_12_c3_b0 : signal op_12_c4_b2 : : std_logic; : std_logic; signal op_12_c4_b0 : signal op_12_05_b2 : : std_logic; : std_logic; signal op_12_c5_b0 : signal op_12_c6_b2 : : std_logic; : std_logic; signal op_12_c6_b0 : signal op_12_c7_b2 : : std_logic; : std_logic; signal op_12_c7_b0 : signal op_12_c8_b2 : : std_logic; signal op_12_c8_b3 : signal op_12_c8_b0 : signal op_12_c9_b2 : : std_logic; : std_logic; signal op_12_c2_b1 signal op_12_c3_b3 signal op_12_c3_b 1 signal op_12_c4_b3 signal op_12_c4_b1 signal op_12_c5_b3 signal op_12_05_b1 signal op_12_c6_b3 signal op_12_c6_bl signal op_12_c7_b3 signal op_12_c7_b1 signal op_12_c8_bl signal op_12_c9_b3 signal op_12_c9_b0 : : std_logic; : std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; 150 ‘ signal op_12_c10_bl : std_logic; signal op_12_c9_bl : std_logic; signal op_12_c10_b2 : std_logic; signal op_12_c10_b0 : std_logic; signal op_12_cl l_b0 : std_logic; signal op_l3_cl_b0 : std_logic; signal op_l3_c2_b1 : std_logic; signal op_l3_c2_b0 : std_logic; signal op_13_c3_bl : std_logic; signal op_l3_c3_b0 : std_logic; signal op_l3_c4_b] : std_logic; signal op_l3_c4_b0 : std_logic; signal op_l3_c5_bl : std_logic; signal op_l3_c5_b0 : std_logic; signal op_l3_c6_bl : std_logic; signal op_l3_c6_b0 : std_logic; signal op_l3_c7_b1 : std_logic; signal op_13_c7_b0 : std_logic; signal op_l3_c8_b1 : std_logic; signal op_l3_c8_b0 : std_logic; signal op_l3_c9__bl : std_logic; signal op_l3_c9_b0 : std_logic; signal op_l3_c10_bl : std_logic; signal op_l3_clO_b0 : std_logic; signal op_l3_c11_b0 : std_logic; signal op_l4_c2_b0 : std_logic; signal op_l4_c3_b] : std_logic; signal op_l4_c3_b0 : std_logic; signal op_l4_c4_b1 : std_logic; signal op_l4_c4_b0 : std_logic; signal op_l4_c5_b1 : std_logic; signal op_l4_c5_b0 : std_logic; signal op_14_c6_bl : std_logic; signal op_l4_c6_b0 : std_logic; signal op_l4_c7_b] : std_logic; signal op_l4_c7_b0 : std_logic; signal op_l4_c8_bl : std_logic; signal op_l4_c8_b0 : std_logic; signal op_l4_c9_b1 : std_logic; signal op_l4_c9_b0 : std_logic; signal op_l4_c10__b1 : std_logic; signal op_l4_c10_b0 : std_logic; signal op_l4_cl l_bl : std_logic; signal op_14_cll_b0 : std_logic; signal op_l4_012_b0 : std_logic; signal sum_O: emc_level_2_half_energy; 151 signal sum_l: emc_level_2_half_energy; signal sum_int: four_nibbles; signal gnd: std_logic; begin -- CONCURRENT STATEMENTS gnd <= '0'; -- CSA structure declaration -- Level 0, Bit 0 csa_fa_10_c0_0: fa port map (op_0(0), op_1(0), op_2(0), op_l 1_c0_b0, 0p_ll_cl_b3); csa_fa_10_c0_l: fa port map (op_3(0), op_4(0), op_5(0), op_ll_c0_b1, op_ll_cl_b4); csa_fa_10_c0_2: fa port map (op_6(0), op_7(0), gnd, op_ll_c0_b2, op_ll_cl_b5); -- Level 0, Bit 1 csa_fa_10_cl_0: fa port map (op_0(1), op_1(1), op_2(1), op_l l_cl_b0, op_ll_c2_b3); csa_fa_10_c1_1: fa port map (op_3(l ), op_4(l), op_5(l), op_ll_cl_bl, op_ll_c2_b4); csa_fa_10_cl_2: fa port map (op_6(1), op_7(1), gnd, op_ll_cl_b2, op_ll_c2_b5); -- Level 0, Bit 2 csa_fa_10_c2__0: fa port map (op_0(2), op_1(2), op_2(2), op_ll_c2_b0, op_ll_c3_b3); csa_fa_10_c2_l: fa port map (op_3(2), op_4(2), op_5(2), op_ll_c2_b1, op_ll_c3_b4); csa_fa_10_c2_2: fa port map (op_6(2), op_7(2), gnd, op_l l_c2_b2, op_l 1_c3_b5); -- Level 0, Bit 3 csa_fa_10_c3_0: fa port map (op_0(3), op_1(3), op_2(3), op_l 1_c3_b0, op_ll_c4_b3); 152 csa_fa_10_c3_l: fa port map (op_3(3), op_4(3), op_5(3), op_l l_c3_b1, op_ll_c4_b4); csa_fa_10_c3_2: fa port map (op_6(3), op_7(3), gnd, op_ll_c3_b2, op_ll_c4_b5); -- Level 0, Bit 4 csa_fa_10_c4_0: fa port map (op_0(4), op_1(4), op_2(4), op_ll_c4_b0, op_ll_c5_b3); csa_fa_10_c4_l: fa port map (op_3(4), op_4(4), op_5(4), op_ll_c4_bl, op_ll_c5_b4); csa_fa_10_c4_2: fa port map (op_6(4), op_7(4), gnd, op_ll_c4_b2, op_ll_c5_b5); -- Level 0, Bit 5 csa_fa_10_c5_0: fa port map (op_0(5), op_1(5), op_2(5), op_ll_c5_b0, op_ll_c6_b3); csa_fa_10_c5_l: fa port map (op_3(5), op_4(5), 0p_5(5), op_l 1_c5_bl, op_ll_c6_b4); csa_fa_10_c5_2: fa port map (op_6(5), op_7(5), gnd, 0p_ll_c5_b2, op_l l_c6_b5); -- Level 0, Bit 6 csa_fa_10_c6_0: fa port map (op_0(6), op_1(6), op_2(6), op_ll_c6_b0, op_l 1_c7_b3); csa_fa_10_c6_l: fa port map (op_3(6), op_4(6), op_5(6), op_ll_c6_bl, op_ll_c7_b4); csa_fa_10_c6_2: fa port map (op_6(6), op__7(6), gnd, op_ll_c6_b2, op_ll_c7_b5); —- Level 0, Bit 7 csa_fa_10_c7__0: fa port map (op_0(7), op_1(7), op_2(7), op_ll_c7_b0, op_ll_c8_b3); csa_fa_10_c7_1: fa port map (op_3(7), op_4(7), op_5(7), op_ll_c7_bl, op_l 1_c8_b4); csa_fa_10_c7_2: fa port map (op_6(7), op_7(7), gnd, op_ll_c7_b2, op_l 1_08_b5); 153 n E?“ 1_54 i -- Level 0, Bit 8 csa_fa_10_c8_0: fa port map (op_0(8), op_1(8), op_2(8), op_l l_c8_b0, op_l l_c9_b3); csa_fa_10_c8_l: fa port map (op_3(8), op_4(8), op_5(8), op_l 1_c8_bl , op_ll_c9_b4); csa_fa_10_c8_2: fa port map (op_6(8), op_7(8), gnd, op_l l_c8_b2, op_ll_c9_b5); -- Level 0, Bit 9 csa_fa_10_c9_0: fa port map (op_0(9), op_1(9), op_2(9), op_ll_c9_b0, op_11_clO_b0); csa_fa_10_c9_l: fa port map (op_3(9), op_4(9), op_5(9), op_ll_c9_bl, op_11_clO_b1); csa_fa_10_c9_2: fa port map (op_6(9), op_7(9), grd, op_ll_c9_b2, op_11_clO_b2); -- Level 1, Bit 0 csa_fa_l 1_c0_0: fa port map (op_ll_cO_b0, op_ll_c0_b1, op_11_c0__b2, sum_0(0), op_12_c1_b2); -- Level 1, Bit 1 csa_fa_11_cl_0: fa port map (op_ll_cl_bO, op_ll_cl_bl, op_l l_c1_b2, op_12_c1_b0, op_12_c2_b2); csa_fa_l l_c1_1 : fa port map (op_ll_cl_b3, op_ll_cl_b4, op_l l_c1_b5, op_12_c1_b 1 , op_12_c2_b3); -- Level 1, Bit 2 csa_fa_l 1_c2_0: fa port map (op_ll_c2_b0, op_ll_c2_bl, op_11_c2_b2, op_12_c2_b0, op_12_c3_b2); csa_fa_l l_c2_l : fa port map (op_ll_c2_b3, op_ll_c2_b4, op_l 1_c2_b5, op_12_c2_b 1 , op_12_c3_b3); -- Level 1, Bit 3 csa_fa_l l_c3_0: fa port map (0p___l l_c3_b0, op_l l_c3_b1, op_11_c3__b2, 154 ‘ op_12_c3_b0, op_12_c4_b2); csa_fa_l 1_c3_l : fa port map (op_11_c3_b3, op_ll_c3_b4, op_l l_c3_b5, op_12_03_b 1 , op_12_c4_b3); -- Level 1, Bit 4 csa_fa_l l_c4_0: fa port map (op_ll_c4_b0, op_ll_c4_b1, op_l 1_c4_b2, op_12_c4_b0, op_12_c5_b2); csa_fa_l 1_c4_1: fa port map (op_ll_c4_b3, op_l 1_c4_b4, op_l 1 _c4_b5, op_12_c4_b 1 , op_12_c5_b3); -- Level 1, Bit 5 csa_fa_l 1_c5_0: fa port map (op_ll_c5_b0, op_ll_c5_bl, op_l 1_c5_b2, op_12_c5_b0, op_12_c6_b2); csa_fa_11_c5_l : fa port map (op_ll_c5_b3, op_ll_cS_b4, op_l l_c5_b5, op_12_c5_b 1 , op_12_c6_b3); -- Level 1, Bit 6 csa_fa_l l_c6_0: fa port map (op_l l_c6_b0, op_l l_c6_b l , 0p_l 1_c6_b2, op_12_c6_b0, op_12_c7_b2); csa_fa_l 1_c6_1 : fa port map (op_ll_c6_b3, op_ll_c6_b4, op_ll_c6_b5, op_12_c6_b l , op_12_c7_b3); -- Level 1, Bit 7 csa_fa_l 1_c7_0: fa port map (op_ll_c7_b0, op_ll_c7_b1, 0p_ll_c7_b2, op_12_c7_b0, op_12_c8_b2); csa_fa_l l_c7_l : fa port map (op_l l_c7_b3, op_l l_c7_b4, op_l 1_c7_b5_. op_12_c7_b l , op_12_c8_b3); -- Level 1, Bit 8 csa_fa_l l_c8_0: fa port map (op_ll_c8_b0, op_ll_c8_b1, op_l 1_c8_b2, op_12_c8_b0, op_12_c9_b2); 155 csa_fa_l 1_c8_l : fa port map (op_l l_c8_b3, op_l l_c8_b4, op_l 1_c8_b5, op_12_c8_b1, op_12_c9_b3); -- Level 1, Bit 9 csa_fa_l 1_c9_0: fa port map (op_l l_c9_b0, op_ll_c9_b1, op_l l_c9_b2, op_12_c9_b0, op_12_c 1 0_b l ); csa_fa_l l_c9_1: fa port map (op_ll_c9_b3, op_ll_c9_b4, op_l l_c9_b5, op_12_c9_bl , op_12_010_b2); -- Level 1, Bit 10 csa_fa_l l_c10_0: fa port map (op_11_clO_b0, op_11_clO_bl , op_11_clO_b2, op_12_c10_b0, op_12_c] 1_b0); -- Level 2, Bit 1 csa_fa_12_c1_0: fa port map (op_12_c1_b0, op_12_c1_bl, op_12_c1_b2, sum_0(l), op_l3_c2_bl); -- Level 2, Bit 2 csa_fa_12_c2_0: fa port map (op_12_c2_b0, op_12_c2_b l , op_12_c2_b2, op_l3_02_b0, op_13_c3_b 1 ); -- Level 2, Bit 3 csa_fa_12_c3_0: fa port map (op_12_c3_b0, op_12_c3_b] , op_12_c3_b2, op_l3_c3_b0, op_l3_c4_b 1); -- Level 2, Bit 4 csa_fa_12_c4_0: fa port map (op_12_c4_b0, op_12_c4_b l , op_12_c4_b2, op_l3_c4_b0, op_13_c5_b 1); -- Level 2, Bit 5 csa_fa_12_c5_0: fa port map (op_12_c5_b0, op_12_c5_b1, 0p_12_c5_b2, op_l3_c5_b0, op_l3_c6_b 1 ); -- Level 2, Bit 6 csa_fa_12_c6__0: fa 156 port map (op_12_c6_b0, op_12_c6_bl, op_12_c6_b2, op_l3_c6_b0, op_l3_c7_b l ); -- Level 2, Bit 7 csa_fa_12_c7_0: fa port map (op_12_c7_b0, op_12_c7_b], op_12_c7_b2, op_l3_c7_b0, op_l3_c8_b l ); -- Level 2, Bit 8 csa_fa_12_c8_0: fa port map (op_12_c8_b0, op_12_c8_bl, op_12_c8_b2, op_l3_c8_b0, op_13_c9_b1); -- Level 2, Bit 9 csa_fa_12_c9_0: fa port map (op_12_c9_b0, op_12_c9_bl, op_12_c9_b2, op_l3_c9_b0, op_l3_c1 0_b l ); -- Level 2, Bit 10 csa_fa_12_c10_0: fa port map (op_12_c10_b0, op_12_c10_bl, op_12_c10_b2, op_l3_c10_b0, op_l3_cl 1_b0); -- Level 3, Bit 2 csa_fa_l3_c2_0: fa port map (0p_l3_c2_b0, op_13_c2__bl, op_12_c2_b3, sum_0(2), sum_l(3)); -- Level 3, Bit 3 csa_fa_13_c3__0: fa port map (op_13_c3_b0, op_l3_c3_b1, op_12_c3_b3, sum_0(3), sum_l(4)); -- Level 3, Bit 4 csa_fa_13_c4_0: fa port map (op_l3_c4_b0, op_l3_c4_b1, op_12_c4_b3, sum_0(4), sum_l(5)); -- Level 3, Bit 5 csa_fa_l3_c5_0: fa port map (op_l3_c5_b0, op_l3_c5_bl, op_12_c5_b3, sum_0(5), sum_l(6)); -- Level 3, Bit 6 csa_fa_13_c6_0: fa port map (op_l3_c6_b0, op_13_c6_bl , op_12_c6_b3, 157 sum_0(6), sum_l(7)); -- Level 3, Bit 7 csa_fa_l3_c7_0: fa port map (op_l3_c7_b0, op_13_c7_bl, op_12_c7_b3, sum_0(7), sum_l(8)); -- Level 3, Bit 8 csa_fa_13_c8_0: fa port map (op_13_c8_b0, op_l3_08_bl, op_12_c8_b3, sum_0(8), sum_l(9)); -- Level 3, Bit 9 csa_fa_13_c9_0: fa port map (op_13_c9_b0, op_l3_c9_b 1 , op_12_c9_b3, sum_0(9), sum_l(10)); -- Level 3, Bit 10 csa_fa_l3__c10__0: fa port map (op_l3_c10_b0, op_l3_c10_bl, gnd, sum_0(10), sum_l(l 1)); -- Level 3, Bit ll csa_fa_l3_cl 1_0: fa port map (op_l3_c1 1_b0, op_12_c11_b0, gnd, sum_0(l l), sum_l(l2)); -- Grounded Sum Operand Outputs sum_0(12) <= grd; sum_l(O) <= gnd; sum_l(1)<= gnd; sum_l(2) <= gnd; -- Final CPA sum sum_int <= ("000" & sum_l) + ("000" & sum_O); sum <= sum_int(13 downto 0); end structural; C4 level_l_triglev_or.vhd (ORing of Level 1 Trigger levels) -- Space Sciences Laboratory, UC Berkeley (c) 1999 -- Michigan State University -- STAR Trigger Electronics -- F ilename: level_l_triglev_or.vhd -- Description: Provides ORing of the Level 1 level bits 158 -- Input: level_l_triglev_x - Level 1 level bits -- Output: level_l_triglev_or - The re-encoded OR'd level bits -— from the first level -- Author: Andrew Vander Molen -- Author: Brian F oulds -- Board Engineer: Krista Marks -- History: —- 06/11/99 Initial Version library IEEE; use IEEE.std_logic_l l64.all; library WORK; use WORK.emc.all; -- PORT DECLARATION entity level_l_triglev_or is port( level_l_triglev_O: in emc_level_l_triglev_bits; level_l_triglev_I: in emc_level_l_triglev_bits; level_l_triglev_2: in emc_level_l_triglev_bits; level_l_triglev_3: in emc_level_l_triglev_bits; level_l_triglev_4: in emc_level_l_triglev_bits; level_l_triglev_S: in emc_level_l_triglev_bits; level_l_triglev_6: in emc_level_l_triglev_bits; level_l_triglev_7: in emc_level_l_triglev_bits; level_l_triglev_or: out emc_level_l_triglev_bits ). end level_l_triglev_or; architecture structural of level_l_triglev_or is -- SIGNAL DECLARATION signal level_l_trigger_O: emc_compare_expand; signal level_l_trigger_lz emc_compare_expand; signal level_l_trigger_2: emc_compare_expand; signal level_l_trigger_3: emc_compare_expand; signal level_l_trigger_4: emc_compare_expand; 159 signal level_l_trigger_S: emc_compare_expand; signal level_l_trigger_6: emc_compare_expand; signal level_l_trigger_7: emc_compare_expand; signal level_1__tri gger__or: emc_compare_expand; signal level_l_high_O: emc_compare_expand; signal level_l_high_l: emc_compare_expand; signal level_l_high_2: emc_compare_expand; signal level_l_high_3: emc_compare_expand; signal level_l_high_4: emc_compare_expand; signal level_l_high_S: emc_compare_expand; signal level_l_high_6: emc_compare_expand; signal level_l_high_7: emc_compare_expand; signal level_l_high_or: emc_compare_expand; signal level_l _ratio_0: emc_compare_expand; signal level_l_ratio_lz emc_compare_expand; signal level_l_ratio_2: emc_compare_expand; signal level_l_ratio_3: emc_compare_expand; signal level_l_ratio_4: emc_compare_expand; signal level_l_ratio_S: emc_compare_expand; signal level_l_ratio_6: emc_compare_expand; signal level_l_ratio_7: emc_compare_expand; signal level_l_ratio_or: emc_compare_expand; begin -- CONCURRENT STATEMENTS -- Expand all of the encoded trigger bits level_l_trigger_O <= "100" when level_l_triglev_0(1 downto 0) = "11" else "010" when level_l_triglev_0(l downto 0) = "10" else "001" when level_l_triglev_0(1 downto 0) = "01" else "000"; level_l_trigger_l <= "100" when level_l_triglev_1(l downto 0) = "l 1" else "010" when level_l_triglev_l(l downto 0) = "10" else "001" when level_l_triglev_l(1 downto 0) = "01" else "000"; level_l_trigger_2 <= "100" when level_l_triglev_2(l downto 0) = "11" else "010" when level_l_triglev_2(1 downto 0) = "10" else "001" when 1evel_l_triglev_2(1 downto 0) = "01" else "000"; level_l_trigger_3 <= "100" when level_l_triglev_3(1 downto 0) = "11" else "010" when level_l_triglev_3(l downto 0) = "10" 160 else "001" when level_l_triglev_3(1 downto 0) = "01" else "000"; level_l_trigger_4 <= "100" when level_l_triglev_4(l downto 0) = "l 1" else "010" when level_l_triglev_4(l downto 0) = "10" else "001" when level_l_triglev_4(l downto 0) = "01" else "000"; level_l_trigger_S <= "100" when level_l_triglev_5(l downto 0) = "11" else "010" when level_l_triglev_5(l downto 0) = "10" else "001" when level_l_triglev_5(l downto 0) = "01" else "000"; level_l_trigger_6 <= "100" when level_l_triglev_6(l downto 0) = "l 1" else "010" when level_l_triglev_6(1 downto 0) = "10" else "001" when level_l_triglev_6(l downto 0) = "01" else "000"; level_l_trigger_7 <= "100" when level_l_triglev_7(l downto 0) = "11" else "010" when level_l_triglev_7(l downto 0) = "10" else "001" when level_l_triglev_7(l downto 0) = "01" else "000"; -- or the bits level_l_trigger_or <= level_l_trigger_O or level_l_trigger_l or level_l_trigger_2 or level_l_trigger_3 or level_l_trigger_4 or level_l_trigger_S or level_l_trigger_6 or level_l_trigger_7; -- Re—encode the bits level_l_triglev_or( l downto 0) <= "1 1" when (level_l_trigger_or = "100") or (level_l_trigger_or = "101") or (level_l_trigger_or = "l 10") or (level_l_trigger_or = "l l 1") else "10" when (level_l_trigger_or = "010") or (level_l_trigger_or = "01 1") else "01" when (level_l_trigger_or = "001") else "00"; -- Expand all of the high level bits level_l_high_O <= "100" when level_l_triglev_0(3 downto 2) = "l 1" else "010" when level_l_triglev_0(3 downto 2) = "10" else "001" when level_l_triglev_0(3 downto 2) = "01" else "000"; level_lfihigh__l <= "100" when 1evel_l_triglev___l(3 downto 2) = "11" 161 else "010" when level_l_triglev_l(3 downto 2) = "10" else "001" when level_l_triglev_l(3 downto 2) = "01" else "000"; level_l_high_2 <= "100" when level_l_triglev_2(3 downto 2) = "11" else "010" when level_l_triglev_2(3 downto 2) = "10" else "001" when level_l_triglev_2(3 downto 2) = "01" else "000"; level_l_high_3 <= "100" when level_l_triglev_3(3 downto 2) = "11" else "010" when level_l_triglev_3(3 downto 2) = "10" else "001" when level_l_triglev_3(3 downto 2) = "01" else "000"; level_l_high_4 <= "100" when level_l_triglev_4(3 downto 2) = "l 1" else "010" when level_l_triglev_4(3 downto 2) = "10" else "001" when level_l_triglev_4(3 downto 2) = "01" else "000"; level_l_high_S <= "100" when level_l_triglev_5(3 downto 2) = "11" else "010" when level_l_triglev_5(3 downto 2) = "10" else "001" when level_l_triglev_5(3 downto 2) = "01" else "000"; level_l_high_6 <= "100" when level_l_triglev_6(3 downto 2) = "l 1" else "010" when level_l_triglev_6(3 downto 2) = "10" else "001" when level_l_triglev_6(3 downto 2) = "01" else "000"; level_l_high_7 <= "100" when level_l_triglev_7(3 downto 2) = "11" else "010" when level_l_triglev_7(3 downto 2) = "10" else "001" when level_l_triglev_7(3 downto 2) = "01" else "000"; -- or the bits level_l_high_or <= level_l_high_O orlevel_1_high_1 or level_l_high_2 or level_l_high_3 or level_l_high_4 or level_l_high_S or level_l_high_6 or level_l_high_7; -- Re-encode the bits level_l_triglev_or(3 downto 2) <= "1 1" when (level_l_high_or = "100") or (level_l_high_or = "101") or (level_l_high_or = "l 10") or (level_l_high_or = "1 1 1") else "10" when (level_l_high_or = "010") or (level_l_high_or = "01 1") 162 else "01" when (level_l_high_or = "001 "1 else "00"; -- Expand all of the ratio level bits level_l_ratio_O <= "100" when level_l_triglev_0(5 downto 4) = "11" else "010" when level_l_triglev_0(5 downto 4) = "10" else "001" when level_l_triglev_0(5 downto 4) = "01" else "000"; level_l_ratio_l <= "100" when level_l_triglev_l(S downto 4) = "11" else "010" when level_l_triglev_l(S downto 4) = "10" else "001" when level_l_triglev_l(S downto 4) = "01" else "000"; level_l_ratio_2 <= "100" when level_l_triglev_2(5 downto 4) = "l 1" else "010" when level_l_triglev_2(5 downto 4) = "10" else "001" when level_l_triglev_2(5 downto 4) = "01" else "000"; level_l_ratio_3 <= "100" when level_l_triglev_3(5 downto 4) = "11" else "010" when level_l_triglev_3(5 downto 4) = "10" else "001" when level_l_triglev_3(5 downto 4) = "01" else "000"; level_l_ratio_4 <= "100" when level_l_triglev_4(5 downto 4) = "l 1" else "010" when level_l_triglev_4(5 downto 4) = "10" else "001" when level_l_triglev_4(5 downto 4) = "01" else "000"; level_l_ratio_S <= "100" when level_l_triglev_5(5 downto 4) = "1 1" else "010" when level_l_triglev_5(5 downto 4) = "10" else "001" when level_l_triglev_5(5 downto 4) = "01" else "000"; level_l_ratio_6 <= "100" when level_l_triglev_6(5 downto 4) = "1 1" else "010" when level_l_triglev_6(5 downto 4) = "10" else "001" when level_l_triglev_6(5 downto 4) = "01" else "000"; level_l_ratio_7 <= "100" when level_l_triglev_7(5 downto 4) = "l 1" else "010" when level_l_triglev_7(5 downto 4) = "10" else "001" when level_l_triglev_7(5 downto 4) = "01" else "000"; -- or the bits 163 level_l_ratio_or <= level_l_ratio_O or level_l_ratio_l or level_l_ratio_2 or level_l_ratio_3 or level_l_ratio_4 or level_l_ratio_S or level_l_ratio_6 or level_l_ratio_7; -- Re-encode the bits level_l_triglev_or(S downto 4) <= "1 1" when end structural; (level_l_ratio_or = "100") or (level_l_ratio_or = "101") or (level_l_ratio_or = "l 10") or (level_l_ratio_or = "1 1 1") else " 10" when (level_l_ratio_or = "010") or (level_l_ratio_or = "01 1") else "01 " when (level_l_ratio_or = "001") else "00"; C5 level_2.vhd (Top of design) -- Space Sciences Laboratory, UC Berkeley (c) 1999 -- Michigan State University —- STAR Trigger Electronics - Filename: level_2.vhd -- Description: Computational engine for Level 2 of ernc detector -- Input: clk - 38Mhz Clock (clk36) -- rst - Global reset -- vme_select_engine_n - From op controller; -- VME w/r engine registers -- vme_write_n_3 - From op controller; -- Write = 0, Read = 1 -- engine_ack_n - To op controller - done; -- VME w/r to registers -- ia - From VME, instruction address -- id - From VME, instruction data -- level_l_energy_x - Energy from level 1 -- level_l_triglev_x - Trigger level bits from -- level 1 -- Output: engine_output - Level 2 engine output -- Structure: -- latch_clk36_p - Positive-edge triggered -- latch for clk36 -- latch_clk36_n - Negative-edge triggered -- latch for clk36 164 -- * level_2_trigger_level - Sets the trigger levels for -- level 2 -- * level_l_triglev_or - Or's the encoded level bits -- * half_sum_level_1_energy - Unsigned summation of four -- level 1 energies -- * sum_level_1_energy - Unsigned summation of eight -- level 1 energies -- compare_20ps - Compares 2 operands to a -- specified level and generates -- '1' if the operand is geater -- than or equal to the level -- compare_encoder - Encodes trigger level -- comparisons into the -- following manner: -- Zero - Compare error or -- no level -- threshold met -- One - Lowest trigger -- compare -- threshold met -- Two - Middle & Lowest -- trigger compare -- threshold met -- Three - All trigger -- compare -- thresholds met -- * note - component specific only to level 2 -- Comments: -- lo - Indicates components belonging to -- the computational engine trigger level -- operations -- ei - Indicates signals or components belonging -- to the computational engine input stage -- e0 - Indicates signals or components belonging -- to the first computational engine stage -- e1 - Indicates signals or components belonging -- to the second computational engine stage -- eo - Indicates signals or components belonging -- to the computational engine output state -- Author: Andrew Vander Molen -- Author: Brian Foulds -- Board Engineer: Krista Marks -- History: 165 05/26/99 Version 1.0.0 (Initial) 06/08/99 Changed id signal to input only 06/1 1/99 Added component level_l_triglev_or library IEEE; use IEEE.std_logic_l l64.all; library WORK; use WORK.emc.all; -- PORT DECLARATION entity level_2 is port( ). end leve 1_2; clk: rst: vme_select_engine_n: vme_write_n: engine_ack_n: ia: id: level_l_energy_O: level_l_energy_l : level_l_energy_2: level_l_energy_3: level_l_energy_4: level_l_energy_S: level_l_energy_6: level_l_energy_7: level_l_triglev_O: level_l_triglev_l : level_l_triglev_2: level_ 1 _triglev_3 : level_l_triglev_4: level-_l_triglev_5: level_l_triglev_6: level_l_triglev_7: engine_output: in std_logic; in std_logic; in std_logic; in std_logic; out std_logic; in emc_ia; in emc_id; in emc_level_l_energy; in emc_level_l_energy; in emc_level_l_energy; in emc_level_l_energy; in emc_level_l_energy; in emc_level_l_energy; in emc_level_l_energy; in emc_level_l_energy; in emc_level_l_triglev_bits; in emc_level_l_triglev_bits; in emc_level_l_triglev_bits; in emc_level_l_triglev_bits; in emc_level_l_triglev_bits; in emc_level_l_triglev_bits; in emc_level_l_triglev_bits; in emc_level_l_triglev_bits; out emc_level_2_output -- ARCHITECTURE DECLARATION 166 m a“ a architecture rtl of level_2 is -- SIGNAL DECLARATION emc_level_2_triglev_vector; emc_level_1_energy_vector; emc_level_1_triglev_bits_vector; four_nibbles; four_nibbles; emc_level_2_energy; four_nibbles; four_nibbles; emc_level_2_energy; emc_triglev_compare; emc_triglev_compare; emc_tri g1ev_compare; signal level_2_triglev: signal ei_level_l_energy_latched: signal ei_level_l_triglev_latched: signal eO__half_energy_0: signal eO_half_energy_l: signal e0_energy: signal el_half__energy__0: signal e1_half_energy_l: signal el_energy: signal el_triglev_compare_O: signal e1_triglev_compare_l: signal el_triglev_compare: signal el_compare_encode: signal el_level_1_triglev_ord: signal el_latch_input: signal el_latch_output: emc_compare_encode; emc_level_l_triglev_bits; emc_level_2_output; emc_level_2_output; -- COMPONENT DECLARATION component latch_clk3 6 _p generic (width: integer); port ( clk: in std_logic; rst: in std_logic; input: in std_logic_vector ((width - 1) downto 0); output: out std_logic_vector ((width - 1) downto 0) ); end component; component latch_clk3 6_n generic (width: integer); port ( clk: in std_logic; rst: in std_logic; input: in std_logic_vector ((width - 1) downto 0); output: out std_logic_vector ((width - l) downto 0) 167 ); end component; component level_2_trigger_level p01“ clk: in std_logic; rst: in std_logic; vme_select_engine_n: in std_logic; vme_write_n: in std_logic; ia: in emc_ia; id: in emc_id; level_2_triglev: inout emc_level_2_triglev_vector; engine_ack_n: out std_logic ); end component; component level_l_triglev_or port( level_l_triglev_O: in emc_level_l_triglev_bits; level_l_triglev_l: in emc_level_l_triglev_bits; level_l_triglev_2: in emc_level_l_triglev_bits; level_l_triglev_3: in emc_level_l_triglev_bits; level_l_triglev_4: in emc_level_l_triglev_bits; level_l_triglev_S: in emc_level_l_triglev_bits; level_l_triglev_6: in emc_level_l_triglev_bits; level_l_triglev_7: in emc_level_l_triglev_bits; level_l_triglev_or: out emc_level_l_triglev_bits ); end component; component half_sum_level_1_energy port ( op_0: in emc_level_l_energy; op_1: in emc_level_l_energy; op_2: in emc_level_l_energy; op_3: in emc_level_l_energy; sum: out four_nibbles ); end component; component sum_level_1_energy port ( op_0: in emc_level_l_energy; op_l: in emc_level_l_energy; op_2: in emc_level_l_energy; op_3: in emc_level_l_energy; 168 op_4: in emc_level_l_energy; op_5: in emc_level_l_energy; op_6: in emc_level_l_energy; op_7: in emc_level_l_energy; sum: out emc_level_2_energy ); end component; component compare_20ps generic(nibble_cnt: integer); port( level: in std_logic_vector((4 * nibble_cnt - l) downto 0); op: in std_logic_vector((4 * nibble_cnt - l) downto 0); result: out std_logic ); end component; component compare_encoder port ( triglev_compare: in emc_triglev_compare; compare_encode: out emc_compare_encode ); end component; begin -- LEVEL OPERATIONS OF COMPUTATIONAL ENGINE level_2_lo: level_2_trigger_level port map (clk, rst, vme_select_engine_n, vme_write_n, ia, id, level_2_triglev, engine_ack_n); -- INPUT LATCH STAGE OF COMPUTATIONAL ENGINE (ei) -- Latches for level 1 energies level_2_ei_energy_input_latch_0: latch_clk3 6_n generic map (10) port map (clk, rst, level_l_energy_O, ei_level_l_energy_latched(0)); level_2_ei_energy_latch_l: latch_clk3 6_n generic map (10) port map (clk, rst, level_l_energy_l , 169 ei_level_l_energy_latched( 1 )); level_2_ei_energy_latch_2: latch_clk3 6_n generic map (10) port map (clk, rst, level_l_energy_2, ei_level_l_energy_latched(2)); level_2_ei_energy_latch_3: latch_clk3 6_n generic map (10) port map (clk, rst, level_l_energy_3, ei_level_l_energy_latched(3)); level_2_ei_energy_latch_4: latch_clk3 6_n generic map (10) port map (clk, rst, level_l_energy_4, ei_level_l_energy__latched(4)); level_2_ei_energy_latch_5: latch_clk3 6_n generic map (10) port map (clk, rst, level_l_energy_S, ei_level_l_energy_latched(5)); level_2_ei_energy_latch_6: latch_clk3 6_n generic map (10) port map (clk, rst, level_l_energy_6, ei_level_l_energy_latched(6)); 1evel_2__ei__energy_latch_7: latch_clk36_n generic map (10) port map (clk, rst, level_l_energy_7, ei_level_l_energy_latched(7)); -- Latches for level 1 level triggers level_2_ei_trigger_latch_0: latch_clk3 6_n generic map (6) port map (clk, rst, level_l_triglev_O, ei_level_l_triglev_latched(0)); level_2_ei_tri gger_latch_1: latch_clk36_n generic map (6) port map (clk, rst, level_l_triglev_l , ei_level_ l _triglev_latched( l )); level_2_ei_trigger_latch_2: latch_clk3 6_n generic map (6) port map (clk, rst, level_l_tri g1ev_2, 170 ei_level_l_triglev_latched(2)); level_2_ei_trigger_latch_3: latch_clk3 6_n generic map (6) port map (clk, rst, level_l_triglev_3, ei_level_l_triglev_latched(3)); level_2_ei_trigger_latch_4: latch_clk3 6_n generic map (6) port map (clk, rst, level_l_triglev_4, ei_level_l_triglev_latched(4)); level_2_ei_trigger_latch_5: latch_clk3 6_n generic map (6) port map (clk, rst, level_l_triglev_S, ei_level_l_triglev_latched(5)); level_2_ei_trigger_latch_6: latch_clk3 6_n generic map (6) port map (clk, rst, level_l_triglev_6, ei_level_l_triglev_latched(6)); level_2_ei_trigger_latch_7: latch_clk3 6_n generic map (6) port map (clk, rst, level_l_triglev_7, ei_level_l_triglev_latched(7)); -- FIRST STAGE OF COMPUTATIONAL ENGINE (e0) -- Compute the half energy sum level_2_e0_half_sum_0 : half_sum_level_1_energy port map (ei_level_l _energy_latched(0), ei_level_ l _energy_latched( l ), ei_level_l_energy_latched(2), ei_level_l_energy_latched(3), e0_half_energy_0); level_2_e0_half_sum_1 : half_sum_level_1_energy port map (ei_level_l_energy_latched(4), ei_level_l_energy_latched(S), ei_level_l_energy_latched(6), ei_level_l_energy_latched(7), e0_half_energy_l ); 171 -- Compute the energy sum level_2_e0_sum: sum_level_1_energy port map (ei_level_l_energy_latched(0), ei_level_ l _energy_latched( 1 ), ei_level_l_energy_latched(Z), ei_level_l_energy_latched(3), ei_level_l_energy_latched(4), ei_level_l_energy_latched(5), ei_level_l_energy_latched(6), ei_level_l_energy_latched(7), e0_energy); -- Save the e0 state for e1 level_2_e0_half_energy_latch_0: latch_clk3 6_n generic map (16) port map (clk, rst, e0_half_energy_0, el_half_energy_0); level_2_e0_half_energy_latch_l: latch_clk3 6_n generic map (16) port map (clk, rst, e0_half_energy_1, e1_half_energy_l ); level_2_e0_energy_latch: latch_clk3 6_n generic map (14) port map (clk, rst, eO_energy, el_energy); -- SECOND STAGE OF COMPUTATIONAL ENGINE (el) - Compare half energies to 3 thresholds level_2_ei_energy_compare: for i in 0 to 2 generate cells_0: compare_20ps generic map (4) port map (level_2_triglev(i), el_half_energy_0, e1_triglev_compare_0(i)); cells_l: compare_20ps generic map (4) port map (level_2_triglev(i), el_half_energy_l , e l _niglev_compare__l (i)); end generate; -- OR the two results 172 el_triglev_compare <= el_triglev_compare_O or el_triglev_compare_l; -- Encode the trigger level compare level_2_e1_compare_encode_0: compare_encoder port map (el_triglev_compare, el_compare_encode); -- OR level 1 trigger level encodes level_2_level_l_triglev_or: level_l_triglev_or port map(ei_level_1_triglev_latched(O), ei_level_ l _triglev_latched( 1 ), ei_level_l_triglev_latched(2), ei_level_l_triglev_latched(3), ei_level_l_triglev_latched(4), _ ei_level_l_triglev_latched(S), ei_level_l_triglev_latched(6), ei_level_l_tri glev_1atched(7), el_level_1_triglev_ord); -- Save e1 state for output el_latch_input <= el_compare_encode & el_level_1_triglev_ord & el_energy; level_2_el_latch: latch_clk3 6_n generic map (22) port map (clk, rst, el_latch_input, el_latch_output); -- OUTPUT LATCH STAGE OF COMPUTATIONAL ENGINE (e0) -- Engine output latch level_2_engine_output_latch: latch_clk3 6 _p generic map (22) port map (clk, rst, el_latch_output, engine_output); end rtl; C6 level_2_tb.vhd (Level 2 testbench) -- Space Sciences Laboratory, UC Berkeley (c) 1999 -- Michigan State University -- STAR Trigger Electronics -- Filename: level_2_tb.vhd 173 -- Description: Testbench for Level 2 -- Author: Andrew Vander Molen -- Author: Brian Foulds -- Board Engineer: Krista Marks -- History: -- 03/25/00 Version 1.0.0 (Initial) library IEEE; library WORK; use IEEE.std_logic_l l64.All; use IEEE.std_logic_unsigned.All; use IEEE.std_logic_arith.All; use WORK.emc.all; use WORK.RndNumGen.all; -- PORT DECLARATION entity level_2_tb is end level_2_tb; -- ARCHITECTURE DECLARATION architecture behavioral of level_2_tb is -- COMPONENT DECLARATION component level_2 port ( clk: in std_logic; rst: in std_logic; vme_select_engine_n: in std_logic; vme_write_n : in std_logic; engine_ack_n: out std_lo gi c; ia: in std_logic_vector(4 downto 0); id: in std_logic_vector(] 5 downto 0) level_l_energy_O: in std_logic_vector(9 downto 0); level_l_energy_l: in std_logic_vector(9 downto 0); level_l_energy_2: in std_logic_vector(9 downto 0); 174 level_l_energy_3: level_l_energy_4: level_l_energy_S: level_l_energy_6: level_l_energy_7: level_l_triglev_O: level_l_triglev_l : level_l_triglev_2: level_ 1 _tri g1 ev_3 : level_l_triglev_4: level_l_triglev_S: level_l_triglev_6: level_l_triglev_7: engine_output: ); end component; in std_logic_vector(9 downto 0); in std_logic_vector(9 downto 0); in std_logic_vector(9 downto 0); in std_logic_vector(9 downto 0); in std_logic_vector(9 downto 0); in std_logic_vector(S downto 0); in std_logic_vector(S downto O); in std_logic_vector(S downto 0); in std_logic_vector(S downto 0); in std_logic_vector(S downto 0); in std_logic_vector(S downto 0); in std_logic_vector(S downto 0); in std_logic_vector(S downto 0); out std_logic_vector(21 downto 0) -- TYPE DECLARATION type clk36_st is (reset, lo, ei, e0, e1, e0); -- SIGNAL DECLARATION -- Level 2 signals signal clk36: std_logic := '0'; signal rst: std_logic := '1'; Signal vme_select_engine_n: std_logic := '1'; signal vme_write_n: std_logic := '1'; signal engine_ack_n: std_logic; signal ia: emc_ia; signal id: emc_id; signal level_l_energy: signal level_l_triglev: signal engine_output: -- Internal level 2 signals signal half_energy_0: signal half_energy_1: emc_level_1_energy_vector; emc_leve1_l_triglev_bits_vector; emc_level_2_output; four_nibbles; four_nibbles; -- Testbench signals signal level _pc: integer := 0; signal ST: clk36_st; 175 begin signal ei_flag: signal trnp_triglev: signal level_2_triglev: signal tb_output: signal tb_output_assert: -— Level 2 component tb_level_2: level_2 std_logic; std_logic_vector(2 downto 0); emc_level_2_triglev_vector; emc_level_2_output; emc_level_2_output; port map (clk36, -- Clock signal rst, vme_select_engine_n, vme_write_n, engine_ack_n, ia, id, level_l_energy(0), level_ 1 _energy( 1 ), level_l_energy(2), level_l_energy(3), level_l_energy(4), level_l_energy(S), level_l_energy(6), level_l_energy(7), level_l_triglev(O), level_ 1 _triglev( l ), level_l_triglev(2), level_l_triglev(3), level_l_triglev(4), level_l_triglev(S), level_l_triglev(6), level_l_triglev(7), engine_output); clk36 <= not clk36 afier 13.125ns; -- Reset signal rst <= '1' after Ons, '0' after 5ns; -- Energy sums for Level 2 tb_output(13 downto 0) <= ("0000" & level_l_energy(0)) + ("0000" & level_l_energy(l)) + ("0000" & level_l_energy(2)) + ("0000" & level_l_energy(3)) + ("0000" & level_l_energy(4)) + 176 ("0000" & level_l_energy(S» + ("0000" & level_l_energy(6)) + ("0000" & ICVCI_ l _energy(7)) ; half_energy_0 <= ("000000" & level_l_energy(0)) + ("000000" & level_l_energy(l)) + ("000000" & level_l_energy(2)) + ("000000" & level_l_energy(3)); half_energy_l <= ("000000" & level_l_energy(4)) + ("000000" & level_l_energy(5)) + ("000000" & level_l_energy(6)) + ("000000" & level_l_energy(7)); -- Process control blocks for compares tb_level_2_triglev_control: process(half_energy_0, half_energy_l , level_2_triglev) begin -- Determine the triglev output if any if((half_energy_0 >= level_2_triglev(2)) or half_energy_l >= level_2_triglev(2)) then trnp_triglev(O) <= '1'; else trnp_triglev(O) <= '0'; end if; if((half_energy_0 >= level_2_triglev(1)) or half_energy_l >= level_2_triglev(1)) then trnp_triglev(l) <= '1'; else trnp_triglev(l) <= '0'; end if; if((half_energy_0 >= level_2_triglev(0)) or half_energy_l >= level_2_triglev(0)) then trnp_triglev(2) <= '1'; else trnp_triglev(2) <= '0'; end if; end process tb_level_2_triglev_control; tb_level_2_compress: process(tmp_triglev) begin 177 case trnp_triglev is when "001" | "010" | "100" => tb_output(21 downto 20) <= "01"; when "011" | "101" | "110" => tb_output(21 downto 20) <= "10"; when "111" => tb_output(21 downto 20) <= "11"; when others => tb_output(21 downto 20) <= "00"; end case; end process tb_level_2_compress; -- OR trigger level bits fiom level 1 tb_triglev_or: process(level_l_triglev) begin if ((level_l_triglev(0)(l downto 0) = "11") or (level_l_triglev(l)(l downto 0) = "11") or (level_l_triglev(2)(l downto 0) = "11") or(level_l_triglev(3)(l downto 0) = "11") or (level_l_triglev(4)(l downto 0) = "11") or (level_l_triglev(5)(1 downto 0) = "11") or (level_l_triglev(6)(l downto 0) = "11") or (level_l_triglev(7)(l downto 0) = "11")) then tb_output(15 downto 14) <= "1 1"; elsif ((level_l_triglev(0)(1 downto 0) = " 10") or (level_l_triglev(l)(l downto 0) = "10") or (level_l_triglev(2)(l downto 0) = "10") or (level_l_triglev(3)(l downto 0) = "10") or (level_l_triglev(4)(l downto 0) = "10") or (level_l_triglev(5)(l downto 0) = "10") or (level_l_triglev(6)(l downto 0) = "10") or (level_l_triglev(7)(l downto 0) = "10")) then tb_output(15 downto l4) <= "10"; elsif ((1evel_l_triglev(0)(1 downto 0) = "01") or (level_l_triglev(l)(1 downto 0) = "01") or (level_l_triglev(2)(l downto 0) = "01") or (level_l_triglev(3)(l downto 0) = "01") or (level_l_triglev(4)(1 downto 0) = "01") or (level_l_triglev(5)(l downto 0) = "01") or (level_l_triglev(6)(l downto 0) = "01") or (level_l_triglev(7)(l downto 0) = "01")) then tb_output(15 downto 14) <= "01"; else 178 end if; tb_output(15 downto 14) <= "00"; if ((level_l_triglev(0)(3 downto 2) = "11") or (level_l_triglev(l)(3 downto 2) = "11") or (level_l_triglev(2)(3 downto 2) = "11") or (level_l_triglev(3)(3 downto 2) = "11") or (level_l_triglev(4)(3 downto 2) = "11") or (level_l_triglev(5)(3 downto 2) = "11") or (level_l_triglev(6)(3 downto 2) = "11") or(leve1_l_triglev(7)(3 downto 2) = "1 1")) then tb_output(l7 downto 16) <= "11"; elsif ((level_l_triglev(0)(3 downto 2) = "10") or (level_l_triglev(l)(3 downto 2) = "10") or (level_l_triglev(2)(3 downto 2) = "10") or (level_l_triglev(3)(3 downto 2) = "10") or (level_l_triglev(4)(3 downto 2) = "10") or (level_l_triglev(5)(3 downto 2) = "10") or (level_l_triglev(6)(3 downto 2) = "10") or (level_l_triglev(7)(3 downto 2) = "10")) then tb_output(l7 downto l6) <= "10"; elsif ((level_l_triglev(0)(3 downto 2) = "01") or else end if; (level_l_triglev(l)(3 downto 2) = "01") or (level_l_triglev(2)(3 downto 2) = "01") or (level_l_triglev(3)(3 downto 2) = "01") or (level_l_triglev(4)(3 downto 2) = "01") or (level_l_triglev(5)(3 downto 2) = "01") or (level_l_triglev(6)(3 downto 2) = "01") or (level_l_triglev(7)(3 downto 2) = "01")) then tb_output(l7 downto 16) <= "01"; tb_output(l 7 downto 16) <= "00"; if ((level_l_triglev(0)(5 downto 4) = "l 1") or (level_l_triglev(l)(S downto 4) = "11") or (level_l_triglev(2)(5 downto 4) = "11") or(level_1_triglev(3)(5 downto 4) = "11") or (level_l_triglev(4)(5 downto 4) = "1 1") or (level_l_triglev(5)(5 downto 4) = "l 1") or (level_l_triglev(6)(5 downto 4) = "1 1") or (level_l_triglev(7)(5 downto 4) = "11")) then 179 tb_output(l9 downto l8) <= "11"; elsif ((level_l_triglev(0)(5 downto 4) = "10") or (level_l_triglev(l)(S downto 4) = "10") or (level_l_triglev(2)(5 downto 4) = "10") or (level_l_triglev(3)(5 downto 4) = "10") or (level_l_triglev(4)(5 downto 4) = "10") or (level_l_triglev(5)(5 downto 4) = "10") or (level_l_triglev(6)(5 downto 4) = "10") or (level_l_triglev(7)(5 downto 4) = "10")) then tb_output(l9 downto 18) <= "10"; elsif ((level_l_triglev(0)(5 downto 4) = "01") or (level_l_triglev(l)(S downto 4) = "01") or (level_l_triglev(2)(5 downto 4) = "01") or (level_l_triglev(3)(5 downto 4) = "01") or (level_l_triglev(4)(5 downto 4) = "01") or (level_l_triglev(5)(5 downto 4) = "01") or (level_l_triglev(6)(5 downto 4) = "01") or (level_l_triglev(7)(5 downto 4) = "01")) then tb_output(l9 downto 18) <= "01"; else tb_output(l9 downto 18) <= "00"; end if; end process tb_triglev_or; -- Process control block for state tb_clk36_control: process (clk36, rst) type energy_array is array (0 to 7) of md_int; type triglev_array is array (0 to 7) of md_int; variable e: energy_array; variable tl: triglev_array; variable 121: md_int; variable seed: md_int; begin -- Positive-edge clock if (clk36'event and clk36 = 'l' and rst = '0') then case ST is when reset => if (rst = '1') then ST <= reset; else ST <= ei; end if; 180 when eo => ST <= ei; -- Check Level 1 Energy Sum assert tb_output_assert( 1 3 downto 0) == engine_output(] 3 downto 0) report "Level 1 Energy Sum Failure"; -- Check Level 1 OR assert tb_output_assert(19 downto 14) = engine_output(l9 downto 14) report "Level 1 Trigger Level OR Failure"; -- Check Level 2 Trigger Level assert tb_output_assert(21 downto 20) = engine_output(21 downto 20) report "Level 2 Trigger Level Failure"; when others => null; end case; end if; -- Negative-edge clock if (clk36'event and clk36 = '0' and rst = '0') then case ST is when ei => if (ei_flag = '1') then ST <= e0; ei_flag <= '0'; else ei_flag <= '1'; end if; when e0 => ST <= e1; when e1 => ST <= eo; -- Save the TestBench output for Assertion tb_output_assert <= tb_output; -- Generate new data for i in 0 to 7 loop -- generate the level 1 energy Geand(e(i)); Geand(tl(i)); 181 -- output the values level_l_energy(i) <= CONV_STD_LOGIC_VECTOR(e(i).value, 10); level_l_triglev(i) <= CONV_STD_LOGIC_VECTOR(tl(i).value, 6); end loop; when 10 => -- Generate & assign the levels the levels case level _pc is when 0 to 2 => if (level _pc = 0) then report "Assigning Trigger Levels"; end if; Geand(121); level_2_triglev(level_pc) <= CONV_STD_LOGIC_VECTOR( 121.value, 16); ia <= CONV_STD_LOGIC_VECTOR( level _pc, 5); Id <= "000" & CONV_STD_LOGIC_VECTOR( 121.value, l3); vme_select_engine_n <= '0'; vme_write_n <= '0'; when others => ST <= ei; vme_select_engine_n <= '1'; vme_write_n <= '1'; if (level _pc = 3) then report "Trigger Levels Assigned, Beginning Engine"; Endifi end case; 182 -- Adjust the level pc If (level _pc <= 2) then level _pc <= level _pc + 1; else level __pc <= 0; end if; when others => null; end case; end if; «Rad if(rst = '1') then ST <= 10; level _pc <= 0; ei_flag <= '0'; -- reset the seeding value seed.init := 7812; seed.min := 0; seed.max := 50000; fori in 0 to 7 loop -- set the default minimum value e(i).min := 0; tl(i).min := 0; -- set the default maximum values e(i).max := 1023; tl(i).max := 63; -- set the initial seed Geand(seed); e(i).init := seed.value; Geand(seed); tl(i).init := seed.value; end loop; -- Generate new data for i in 0 to 7 loop -- generate the data Geand(e(i)); Geand(tl(i)); -- output the values 183 level_l_energy(i) <= CONV_STD_LOGIC_VECTOR (e(i).value, 10); level_l_triglev(i) <= CONV_STD_LOGIC_VECTOR (tl(i).value, 6); endloop; -- Set the default mins for the levels 121.min := 0; -- Set the default maxs for the levels 121.max := 1023; -- Set the initial seed for the levels Geand(seed); 121.init := seed.value; end if; end process tb_clk36_control; end behavioral; 184 APPENDIX D Level 3 Synthesis Code D1 level_3_triglev.vhd (Level 3 Trigger Level operations) -- Space Sciences Laboratory, UC Berkeley (c) 1999 -- Michigan State University -- STAR Trigger Electronics -- Filename: level_3_t1igger_level.vhd -- Description: Sets the trigger levels and determines the highest -- trigger level for level 3 -- Input: clk - 38Mhz Clock (clk36) -- rst - Global reset -- vme_select_engine_n - From op controller; -- VME w/r engine registers -- vme_write_n_3 - From op controller; -- Write = 0, Read = 1 -- engine_ack_n - To op controller - done; -- VME w/r to registers -- ia - From VME, instruction address -- id - From VME, instruction data -- Inout: level_3_triglev - The array of trigger level -- thresholds -- Output: engine_ack_n - To op controller - done; -- VME w/r to registers -- Author: Andrew Vander Molen -- Author: Brian Foulds -- Board Engineer: Krista Marks -- History: -- 05/20/99 Version 1.0.0 (Initial) -- 06/08/99 Changed id signal to input only library IEEE; use IEEE.std_logic_l l64.all; use IEEE.std_logic_arith.all; library WORK; use WORK.emc.all; 185 -- PORT DECLARATION entity level_3_trigger_level is port ( clk: in std_logic; rst: in std_logic; vme_select_engine_n: in std_logic; vme_write_n: in std_logic; ia: in emc_ia; id: in emc_id; level_3_triglev: inout emc_level_3_triglev_vector; engine_ack_n: out std_logic ); end level_3_trigger_level; -- ARCHITECTURE DECLARATION architecture behavioral of level_3_tri gger_leve1 is begin -- PROCESS STATEMENTS level_3_triglev_control: process(clk, rst) begin if (clk'event and clk = '1') then if (vme_select_engine_n = '0' and vme_write_n = '0') then if (ia = emc_level_3_triglev_0_adr) then level_3_triglev(0) <= id; elsif (ia = emc_level_3_triglev_1_adr) then level_3_triglev(l) <= id; elsif (ia = emc_level_3_triglev_2_adr) then level_3_triglev(2) <= id; end if; engine_ack_n <= '0'; else engine_ack_n <= '1'; end if; end if; 186 if (rst = '1') then level_3_triglev(0) <= (others => '0'); level_3_triglev(l) <= (others => '0'); level_3_triglev(2) <= (others => '0'); engine_ack_n <= '1'; end if; end process level_3_triglev_control; end behavioral; D2 sum_level_2_energy.vhd (Sum of Level 2 energy) -- Space Sciences Laboratory, UC Berkeley (c) 1999 -- Michigan State University -- STAR Trigger Electronics -- Filename: sum_level_2_energy.vhd -- Description: Unsigned sum of 4 level 2 energies -- Input: op_x - Level 2 energy -- Output: sum - Final level 2 energy -- Structure: -- fa - Full Adder Component -- Author: Andrew Vander Molen -- Author: Brian Foulds -- Board Engineer: Krista Marks -- History: -- 05/12/99 Version 1.0.0 (Initial) library IEEE; use IEEE.std_logic_l l64.all; use IEEE.std_logic_unsigned.all; library WORK; use WORK.emc.all; -- PORT DECLARATION entity sum_level_2_energy is port ( 187 op_0: in emc_level_2_energy; op_l: in emc_level_2_energy; op_2: in emc_level_2_energy; op_3: in emc_level_2_energy; sum: out emc_level_3_energy ); end sum_level_2_energy; architecture structural of sum_level_2_energy is -- COMPONENT DECLARATION component fa port ( x: in std_logic; y: in std_logic; cin: in std_logic; s: out std_logic; cout: out std_logic ); end component; -- SIGNAL DECLARATION signal op_l l_c0_b0 : : std_logic; signal op_ll_cl_bl signal op_ll_cl_bO : : std_logic; signal op_ll_c2_b1 signal op_ll_c2_b0 : : std_logic; signal op_ll_c3_b1 signal op_ll_c3_b0 : : std_logic; signal op_l 1_c4 b0 : : std_logic; signal op_ll_c4_b1 signal op_l l_c5:bl signal op_ll_cS_b0 : : std_logic; signal op_ll_c6_bl signal op_ll_c6_b0 : : std_logic; signal op_l l _c7_b 1 signal op_ll_c7_b0 : : std_logic; signal op_l l_c8_bl signal op_ll_c8_b0 : : std_logic; signal op_l l_c9_bl std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; std_logic; 188 signal op_ll_c9_b0 : std_logic; signal op_11_clO_b1 : std_logic; signal op__l l_c10_b0 : std_logic; signal op_ll_c11_bl : std_logic; signal op_ll_cl l_b0 : std_logic; signal op_ll_c12_bl : std_logic; signal op_ll_c12_b0 : std_logic; signal op_l l_c13_bl : std_logic; signal op_ll_cl3_b0 : std_logic; signal op_11_c14__b0 : std_logic; signal sum_O: emc_level_3_half_energy; signal sum_l: emc_level_3_half_energy; signal gnd: std_logic; begin - CONCURRENT STATEMENTS and <= '0'; -- CSA structure declaration -- Level 0, Bit 0 csa_fa_10_c0_0: fa port map (op_0(0), op_1(0), op_2(0), op_ll_c0_b0, op_ll_cl_bl); -- Level 0, Bit 1 csa_fa_10_cl_0: fa port map (op_0(1), op_1(1), op_2(1), op_ll_cl_bO, 0p_ll_c2_bl); -- Level 0, Bit 2 csa_fa_10_02_0: fa port map (op_0(2), op_1(2), op_2(2), op_ll_c2_b0, op_ll_c3_b1); -- Level 0, Bit 3 csa_fa_10_c3_0: fa port map (op_0(3), op_1(3), op_2(3), op_l 1_c3_b0, op_l l_c4_bl); -- Level 0, Bit 4 csa_fa_10_c4_0: fa port map (op_0(4), op_1(4), op_2(4), op_l l_c4_b0, op_ll_c5_bl); -- Level 0, Bit 5 csa_fa_10_c5_0: fa port map (op_0(5), op_1(5), op_2(5), op_ll_c5_b0, op_ll_c6_bl); 189 -- Level 0, Bit 6 csa_fa_10_c6_0: fa port map (op_0(6), op_1(6), op_2(6), op_l 1_c6_b0, op_l l_c7_b1); -- Level 0, Bit 7 csa_fa_10_c7_0: fa port map (op_0(7), op_1(7), op_2(7), op_ll_c7_b0, op_ll_c8_bl); -- Level 0, Bit 8 . csa_fa_10_c8_0: fa port map (op_0(8), op_1(8), op_2(8), op_ll_c8_b0, op_ll_c9_bl); ' -- Level 0, Bit 9 csa_fa_10_c9_0: fa port map (op_0(9), op_1(9), op_2(9), op_ll_c9_b0, op_11_clO_bl); I -- Level 0, Bit 10 csa_fa_10_c10_0: fa port map (op_0(10), op_1(10), op_2(10), op_11_clO_b0, op_l l_cl l_bl); -- Level 0, Bit ll csa_fa_10_c11_0: fa port map (op_0(l l), op_1(l 1), op_2(l l), op_ll_cl l_b0, op_ll_c12_b1); -- Level 0, Bit 12 csa_fa_10_c12__0: fa port map (op_0(12), op_1(12), op_2(12), op_ll_c12_b0, op_11_cl3_b1); -- Level 0, Bit l3 csa_fa_10_cl 3_0: fa port map (op_0(l3), op_1(l3), op_2(l3), op_11_cl3_b0, sum_0(l4)); -- Level 1, Bit 0 csa_fa_l l_c0_0: fa port map (op_ll_cO_b0, op_3(0), grd, sum_0(0), sum_l(l)); -- Level 1, Bit 1 csa_fa_l l_c1_0: fa port map (op_ll_cl_bO, op_ll_cl_bl, op_3(l), sum_0(1), sum_l(2)); -- Level 1, Bit 2 csa_fa_l l_c2_0: fa port map (op_l l_c2_b0, op_l 1_c2_b1, op_3(2), sum_0(2), sum_l(3)); -- Level 1, Bit 3 csa_fa_11__c3_0: fa 190 port map (op_ll_c3_b0, op_ll_c3_bl, op_3(3), sum_0(3), sum_l(4)); -- Level 1, Bit 4 csa_fa_l l_c4_0: fa port map (op_11_c4_b0, op_l l_c4_b1, op_3(4), sum_0(4), sum_l(5)); -- Level 1, Bit 5 csa_fa_l l_c5_0: fa port map (op_ll_c5_b0, 0p_ll_c5_b1, op_3(5), sum_0(5), sum_l(6)); -- Level 1, Bit 6 l csa_fa_11_c6_0: fa port map (op_ll_c6_b0, op_ll_c6_b1, op_3(6), sum_0(6), sum_l(7)); -- Level 1, Bit 7 csa_fa_l l_c7_0: fa " ‘ port map (op_ll_c7_b0, op_ll_c7_b1, op_3(7), sum_0(7), sum_l(8)); -- Level 1, Bit 8 csa_fa_11_c8_0: fa port map (op_ll_c8_b0, op_ll_c8_bl, op_3(8), sum_0(8), sum_l(9)); -- Level 1, Bit 9 csa_fa_l l_c9_0: fa port map (op_ll_c9_b0, op_ll_c9_b1, op_3(9), sum_0(9), sum_l(10)); -- Level 1, Bit 10 csa_fa_l l_c10_0: fa port map (op_11_clO_b0, op_11_clO_bl, op_3(10), sum_0(10), sum_l(l 1)); -- Level 1, Bit ll csa_fa_11_c1 1_0: fa port map (op_ll_c11__b0, op_ll_cl l_bl, op_3(] 1), sum_0(l 1), sum_l(12)); -- Level 1, Bit 12 csa_fa_l l_c12_0: fa port map (op_11_c12_b0, op_ll_c12_b1, op_3(12), sum_0(12), sum_l(l3)); -- Level 1, Bit 13 csa_fa_l l_cl 3_0: fa port map (op_ll_c13_b0, op_l l_c13_bl, op_3( I 3), sum_0(13), sum_l(l4)); 191 -- Grounded Sum Operand Outputs sum_l(O) <= gnd; —- Final CPA sum <= ('0' & sum_O) + ('0' & sum_l); end structural; D3 level_2_triglev_or.vhd (ORing of Level 2 Trigger level bits) -- Space Sciences Laboratory, UC Berkeley (c) 1999 -- Michigan State University -- STAR Trigger Electronics -- Filename: level_2_triglev_or.vhd -- Description: Provides ORing of the Level 2 level bits -- Input: level_2_triglev_x - Level 2 level bits -- Output: level_2_triglev_or - The re-encoded OR'd level bits -- fi'om the second level -- Author: Andrew Vander Molen -- Author: Brian F oulds -- Board Engineer: Krista Marks -- History: -- 06/11/99 Initial Version library IEEE; use IEEE.std_logic_l l64.all; library WORK; use WORK.emc.all; -- PORT DECLARATION entity level_2_triglev_or is p0rt( level_2_triglev_0: in emc_level_2_triglev_bits; level_2_triglev_l: in emc_level_2_triglev_bits; level_2_triglev_2: in emc_level_2_triglev_bits; level_2_triglev_3: in emc_level_2_triglev_bits; level_2_triglev_or: out emc_level_2_tri g1ev_bits 192 end level_2_triglev_or; -- ARCHITECTURE DECLARATION architecture structural of level_2_triglev_or is -- SIGNAL DECLARATION signal level_l_trigger_O: emc_compare_expand; signal level_l_trigger_l: emc_compare_expand; signal level_l_trigger_2: emc_compare_expand; signal level_l_trigger_3: emc_compare_expand; signal level_l_trigger_or: emc_compare_expand; signal level_l_high_O: emc_compare_expand; signal level_l_high_l: emc_compare_expand; signal level_l_high_2: emc_compare_expand; signal level_l_high_3: emc_compare_expand; signal level_l_high_or: emc_compare_expand; signal level_l_ratio_O: emc_compare_expand; signal level_l_ratio_l: emc_compare_expand; signal level_l_ratio_2: emc_compare_expand; signal level_l_ratio_3: emc_compare_expand; signal level_l_ratio_or: emc_compare_expand; signal level_2_trigger_0: emc_compare_expand; signal level_2_trigger_l: emc_compare_expand; signal level_2_trigger_2: emc_compare_expand; signal level_2_trigger_3: emc_compare_expand; signal level_2_trigger_or: emc_compare_expand; begin -- CONCURRENT STATEMENTS -- Expand all of the encoded trigger bits level_l_trigger_O <= "100" when level_2_triglev_0(1 downto 0) = "l 1" else "010" when level_2_triglev_0(l downto 0) = "10" else "001" when level_2_triglev_0(l downto 0) = "01" else "000"; level_l_trigger_l <= "100" when level_2_triglev_l(l downto 0) = "l 1" else "010" when level_2_triglev_l(1 downto 0) = "10" 193 else "001" when level_2_triglev_l(l downto 0) = "01" else "000"; level_l_trigger_2 <= "100" when level_2_triglev_2(1 downto 0) = "l 1" else "010" when level_2_triglev_2(l downto 0) = "10" else "001" when level_2_triglev_2(l downto 0) = "01" else "000"; level_l_trigger_3 <= "100" when level_2_triglev_3(l downto 0) = "11" else "010" when level_2_triglev_3(l downto 0) = "10" else "001" when level_2_triglev_3(l downto 0) = "01" else "000"; -- or the bits level_l_trigger_or <= level_l_trigger_O or level_l_trigger_l or level_l_trigger_2 or level_l_trigger_3; -- Re-encode the bits level_2_tri glev__or(1 downto 0) <= "1 1" when (level_l_trigger_or = "100") or (level_l_trigger_or = "101") or (level_l_trigger_or = "110") or (level_l_trigger_or = "1 1 1") else "10" when (level_l_trigger_or = "010") or(level_1_t1igger_or = "011") else "01" when (level_l_trigger_or = "001") else "00"; -- Expand all of the high level bits level_l_high_O <= "100" when level_2_triglev_0(3 downto 2) = "11" else "010" when level_2_triglev_0(3 downto 2) = "10" else "001" when level_2_triglev_0(3 downto 2) = "01" else "000"; level_l_high_l <= "100" when level_2_triglev_l(3 downto 2) = "l 1" else "010" when level_2_triglev_l(3 downto 2) = "10" else "001" when level_2_triglev_l(3 downto 2) = "01" else "000"; level_l_high_2 <= "100" when level_2_triglev_2(3 downto 2) = "11" else "010" when level_2_triglev_2(3 downto 2) = "10" else "001" when level_2_triglev_2(3 downto 2) = "01" else "000"; level_l_high_3 <= "100" when level_2_triglev_3(3 downto 2) = "l 1" else "010" when level_2_triglev_3(3 downto 2) = "10" else "001" when level_2_triglev_3(3 downto 2) = "01" 194 else "000"; -- or the bits level_l_high_or <= level_l_high_O or level_l_hi gh_1 or level_l_high_2 or level_l_high_3; -- Re-encode the bits level_2_triglev_or(3 downto 2) <= "1 1" when (level_l_high_or = "100") or (level_l_high_or = "101") or (level_l_high_or = "l 10") or (level_l_high_or = "l l 1") else "10" when (level_l_high_or = "010") or (level_l_high_or = "01 1") else "01" when (level_l_high_or = "001") else "00"; -- Expand all of the ratio level bits level_l_ratio_O <= "100" when level_2_triglev_0(5 downto 4) = "1 1" else "010" when level_2_triglev_0(5 downto 4) = "10" else "001" when level_2_triglev_0(5 downto 4) = "01" else "000"; level_l_ratio_l <= "100" when level_2_triglev_l(5 downto 4) = "l 1" else "010" when level_2_triglev_l(5 downto 4) = "10" else "001" when level_2_triglev_l(5 downto 4) = "01 " else "000"; level_l_ratio_2 <= "100" when level_2_triglev_2(5 downto 4) = "11" else "010" when level_2_triglev_2(5 downto 4) = "10" else "001" when level_2_triglev_2(5 downto 4) = "01 " else "000"; level_l_ratio_3 <= "100" when level_2_triglev_3(5 downto 4) = "11" else "010" when level_2_triglev_3(5 downto 4) = "10" else "001" when level_2_triglev_3(5 downto 4) = "01" else "000"; -- or the bits level_l_ratio_or <= level_l_ratio_O or level_l_ratio_l or level_l_ratio_2 or level_l_ratio_3; -- Re-encode the bits level_2_triglev_or(5 downto 4) <= "11" when (level_l_ratio_or = "100") or (level_l_ratio_or = "101") or (level_l_ratio_or = "1 10") or (level_l_ratio_or = "l l 1") else "10" when 195 (level_l_ratio_or = "010") or (level_l_ratio_or = "01 1") else "01" when (level_l_ratio_or = "001") else "00"; -- Expand all of the encoded trigger bits level_2_trigger_0 <= "100" when level_2_triglev_0(7 downto 6) = "11" else "010" when level_2_triglev_0(7 downto 6) = "10" else "001" when level_2_triglev_0(7 downto 6) = "01" else "000"; level_2_trigger_l <= "100" when level_2_triglev_l(7 downto 6) = "1 1" else "010" when level_2_triglev_l(7 downto 6) = "10" else "001" when level_2_triglev_l(7 downto 6) = "01" else "000"; level_2_trigger_2 <= " 100" when level_2_triglev_2(7 downto 6) = "l 1" else "010" when level_2_triglev_2(7 downto 6) = "10" else "001" when level_2_triglev_2(7 downto 6) = "01" else "000"; level_2_trigger_3 <= "100" when level_2_triglev_3(7 downto 6) = "1 1" else "010" when level_2_triglev_3(7 downto 6) = "10" else "001" when level_2_triglev_3(7 downto 6) = "01" else "000"; -- or the bits level_2_trigger_or <= level_2_trigger_0 or level_2_trigger_l or level_2_trigger_2 or level_2_trigger_3; -- Re-encode the bits level_2_triglev_or(7 downto 6) <= "11" when (level_2_trigger_or = "100") or (level_2_trigger_or = "101") or (level_2_trigger_or = "l 10") or (level_2_trigger_or = "1 l 1") else "10" when (level_2_trigger_or = "010") or (level_2_trigger_or = "01 1") else "01" when (level_2_trigger_or = "001") else "00"; end structural; D4 level_3.vhd (Top of Design) -- Space Sciences Laboratory, UC Berkeley (c) 1999 196 -- Michigan State University -- STAR Trigger Electronics -- F ilenarne: level_3.vhd -- Description: Computational engine for Level 3 of ernc detector -- Input: clk - 38Mhz Clock (clk36) -- rst - Global reset -- vme_select_engine_n - From op controller; -- VME w/r engine registers -- vme_write_n_3 - From op controller; -- Write = 0, Read = l -- engine_ack_n - To op controller - done; -- VME w/r to registers -- ia - From VME, instruction address -- id - From VME, instruction data -- level_2_energy_x - Energy from level 2 -- level_2_triglev_bits__x- Trigger level bits from -- level 2 -- Output: engine_output - Level 3 engine output -- Structure: -- latch_clk36_p - Positive-edge triggered -- latch for clk36 -- latch_clk36_n - Negative-edge triggered -- latch for clk36 -- * level_3_trigger_level - Sets the trigger levels -- for level 3 -- * level_2_triglev_or - OR's level bits from level 2 -- * sum_level_2_energy - Unsigned summation of eight -- level 2 energies -- sum_20ps - Unsigned sum of 2 operands -- compare_20ps - Compares 2 operands to a specified level and generates '1' if the operand is geater than or equal to the level compare_encoder - Encodes trigger level comparisons into the following manner: Zero - Compare error or no level threshold met One - Lowest trigger compare threshold met Two - Middle & Lowest trigger compare 197 -- threshold met -- Three - All trigger -- compare -- thresholds met -- "' note - component specific only to level 3 -- Comments: -- lo - Indicates components belonging to -- the computational engine trigger level -- operations -- ei - Indicates signals or components belonging -- to the computational engine input stage -- e0 - Indicates signals or components belonging -- to the first computational engine stage -- e1 - Indicates signals or components belonging -- to the second computational engine stage -- eo - Indicates signals or components belonging -- to the computational engine output state -- Author: Andrew Vander Molen -- Author: Brian Foulds -- Board Engineer: Krista Marks -- History: -- 05/26/99 Version 1.0.0 (Initial) -- 06/08/99 Changed id signal to input only -- 06/11/99 Added component level_2_triglev_or library IEEE; use IEEE.std_logic_l l64.all; library WORK; use WORK.emc.all; -- PORT DECLARATION entity level_3 is port( clk: in std_logic; rst: in std_logic; vme_select_engine_n: in std_logic; vme_write_n: in std_logic; engine_ack_n: out std_logic; 198 ia: in emc_ia; id: in emc_id; level_2_energy_0: level_2_energy_1 : level_2_energy_2: level_2_energy_3 : level_2_triglev_0: level_2_triglev_l : level_2_triglev_2: level_2_tri glev_3 : engine_output: ) . end level_3; in emc_level_2_energy; in emc_level_2_energy; in emc_level_2_energy; in emc_level_2_energy; in emc_level_2_triglev_bits; in emc_level_2_triglev_bits; in emc_level_2_triglev_bits; in emc_level_2_triglev_bits; out emc_level_3_output -- ARCHITECTURE DECLARATION architecture rtl of level_3 is -- SIGNAL DECLARATION signal level_3_triglev: signal ei_level_2_energy_latched: signal ei_level_2_triglev_latched: signal e0_energy: signal el_energy: signal el_triglev_compare: signal el_compare_encode: signal el_level_2_triglev_ord: signal e l_latch_input: signal el_latch_output: emc_level_3_triglev_vector; emc_level_2_energy_vector; emc_level_2_triglev_bits_vector; emc_level_3_energy; emc_level_3_energy; emc_triglev_compare; emc_compare_encode; emc_level_2_triglev_bits; emc_level_3_output; emc_level_3_output; -- COMPONENT DECLARATION component latch_clk36_p generic (width: integer); port ( clk: in std_logic; rst: in std_logic; input: in std_logic_vector ((width - l) downto 0); output: out std_logic_vector ((width - 1) downto 0) 199 ); end component; component latch_clk3 6_n generic (width: integer); port ( clk: in std_logic; rst: in std_logic; input: in std_logic_vector ((width - l) downto 0); output: out std_logic_vector ((width - l) downto 0) ); ' end component; component level_3_trigger_level port ( clk: in std_logic; rst: in std_logic; vme_select_engine_n: in std_logic; vme_write_n: in std_logic; ia: in emc_ia; id: in emc_id; level_3_triglev: inout emc_level_3_triglev_vector; engine_ack_n: out std_logic ); end component; component level_2_triglev_or port( level_2_triglev_0: in emc_level_2_triglev_bits; level_2_triglev_l: in emc_level_2_triglev_bits; level_2_triglev_2: in emc_level_2_triglev_bits; level_2_triglev_3: in emc_level_2_tri g1 ev_bits; level_2_triglev_or: out emc_level_2_tri g1 ev_bits ); end component; component sum_level_2_energy port ( op_O: in emc_level_2_energy; op_l: in emc_level_2_energy; op_2: in emc_level_2_energy; op_3: in emc_level_2_energy; sum: out emc_level_3_energy ); end component; 200 begin component compare_20ps generic(nibble_cnt: integer); port( level: in std_logic_vector((4 * nibble_cnt - 1) downto 0); op: in std_logic_vector((4 * nibble_cnt - 1) downto 0); result: out std_logic ); end component; component compare_encoder port ( triglev_compare: in emc_triglev_compare; compare_encode: out emc_compare_encode ); end component; -- LEVEL OPERATIONS OF COMPUTATIONAL ENGINE level_3_lo: level_3_trigger__level port map (clk, rst, vme_select_engine_n, vme_write_n, ia, id, level_3_triglev, engine_ack_n); -- INPUT LATCH STAGE OF COMPUTATIONAL ENGINE (ei) -- Latches for level 2 energies 1evel_3_ei_energy_input_latch_0: latch_clk3 6_n generic map (14) port map (clk, rst, level_2_energy_0, ei_level_2__energy_latched(0)); level_3_ei_energy_latch_l: latch_clk3 6_n generic map (14) port map (clk, rst, level_2_energy_l , ei_level_2_energy_latched( 1 )); level_3_ei_energy_latch_2: latch_clk3 6_n generic map (14) port map (clk, rst, level_2_energy_2, ei_level_2_energy_latched(2)); level_3_ei_energy__latch__3: latch_clk36_n 201 generic map ( 14) port map (clk, rst, level_2_energy_3, ei_level_2_energy_latched(3)); -- Latches for level 2 level triggers level_3_ei_trigger_latch_0: latch_clk3 6_n generic map (8) port map (clk, rst, level_2_triglev_0, ei_level_2_triglev_latched(0)); level_3_ei_trigger_latch_1: latch_clk3 6_n generic map (8) port map (clk, rst, level_2_triglev_l , ei_level_2_triglev_latched( 1)); level_3_ei_trigger_latch_2: latch_clk3 6_n generic map (8) port map (clk, rst, level_2_triglev_2, ei_level_2_triglev_latched(2)); level_3_ei_trigger_latch_3: latch_clk3 6_n generic map (8) port map (clk, rst, level_2_triglev_3, ei_level_2_triglev_latched(3)); -- FIRST STAGE OF COMPUTATIONAL ENGINE (e0) -- Compute the energy sum level_3_e0_sum: sum_level_2_energy port map (ei_level_2_energy_latched(0), ei_level_2_energy_latched( 1 ), ei_level_2_energy_latched(2), ei_level_2_energy_latched(3), e0_energy); -- Save the e0 state for e1 1evel_3_e0__energy_latch: latch_clk3 6_n generic map (1 6) port map (clk, rst, e0_energy, el_energy); -- SECOND STAGE OF COMPUTATIONAL ENGINE (e1) 202 -- Compare half energies to 3 thresholds level_3_e1_energy_compare: for i in 0 to 2 generate cells: compare_20ps generic map (4) port map (level_3_triglev(i), el_energy, el_triglev_compare(i)); end generate; -- Encode the trigger level compare level_3_e1_compare_encode: compare_encoder port map (el_triglev_compare, el_compare_encode); - OR level 2 trigger level encodes level_3_level_2_triglev_or: level_2_triglev_or port map (ei_level_2_triglev_latched(0), ei_level_2_triglev_latched(1 ), ei_level_2_triglev_latched(2), ei_level_2_triglev_latched(3), e1_level_2_triglev_ord); -- Save e1 state for output el_latch_input <= el_compare_encode & e1_level_2_triglev_ord & e 1 _energy; level_3_e1_latch: latch_clk3 6_n generic map (26) port map (clk, rst, el_latch_input, el_latch_output); -- OUTPUT LATCH STAGE OF COMPUTATIONAL ENGINE (eo) -- Engine output latch level_3_engine_output_latch: latch_clk3 6 _p generic map (26) port map (clk, rst, el_latch_output, engine_output); end rtl; D5 level_3_tb.vhd (Level 3 testbench) -- Space Sciences Laboratory, UC Berkeley (c) 1999 -- Michigan State University 203 -- STAR Trigger Electronics -- Filename: level_3_tb.vhd -- Description: Testbench for Level 3 -- Author: Andrew Vander Molen -- Author: Brian F oulds -- Board Engineer: Krista Marks -- History: -- 05/26/99 Initial Version -- 03/25/00 Added random number generation to data. -- Changed testing of trigger levels to reflect changes -- in design. library IEEE; library WORK; use IEEE.std_logic_1164.All; use IEEE.std_logic_unsigned.All; use IEEE.std_logic_arith.All; use WORK.emc.all; use WORK.RndenGen.all; -- PORT DECLARATION entity level_3_tb is end level_3_tb; -- ARCHITECTURE DECLARATION architecture behavioral of level_3_tb is -- COMPONENT DECLARATION component level_3 port ( clk: in std_logic; rst: in std_logic; vme_select_engine_n: in std_logic; vme_write_n : in std_logic; 204 engine_ack_n: out std_logic; ia: in std_logic_vector(4 downto 0); id: in std_logic_vector( 1 5 downto 0); level_2_energy_0: in std_logic_vector( 1 3 downto 0); level_2_energy_l: in std_logic_vector( l 3 downto 0); level_2_energy_2: in std_logic_vector( 1 3 downto 0); level_2_energy_3: in std_logic_vector( l 3 downto 0); level_2_triglev_0: in std_logic_vector(7 downto 0); level_2_triglev_l: in std_logic_vector(7 downto 0); level_2_triglev_2: in std_logic_vector(7 downto 0); level_2_triglev_3: in std_logic_vector(7 downto O); engine_output: out std_logic_vector(25 downto 0) ); end component; -- TYPE DECLARATION type clk36_st is (reset, lo, ei, e0, e1, eo); -- SIGNAL DECLARATION -- Level 3 signals signal clk36: std_logic := '0'; signal rst: std_logic := '1'; signal vme_select_engine_n: std_logic := '1'; signal vme_write_n: std_logic := '1 '; signal engine_ack_n: std_logic; signal ia: emc_ia; signal id: emc_id; signal level_2_energy: emc_level_2_energy_vector; signal level_2_triglev: emc_level_2_triglev_bits_vector; signal engine_output: emc_level_3_output; -- Internal level 3 signals signal level_3_energy: four_nibbles; -- Testbench signals signal level _pc: integer := 0; signal ST: clk36_st; signal ei_flag: std_logic; signal trnp_triglev: std_logic_vector(2 downto 0); signal level_3_triglev: emc_level_3_triglev_vector; 205 begin signal tb_output: emc_level_3_output; signal tb_output_assert: emc_level_3_output; -- Level 3 component tb_level_3: level_3 port map (clk36, rst, vme_select_engine_n, vme_write_n, engine_ack_n, ia, id, level_2_energy(0), level_2_energy( l ), level_2_energy(2), level_2_energy(3), level_2_triglev(0), level_2_tri glev( 1 ), level_2_triglev(2), level_2_triglev(3), engine_output); -- Clock signal clk36 <= not clk36 after 13.125ns; -- Reset signal rst <= '1' after Ons, '0' after 5ns; -- Energy sums for Level 3 level_3_energy <= ("00" & level_2_energy(0)) + ("00" & level_2_energy(l)) + ("00" & level_2_energy(2)) + ("00" & level_2_energy(3)); tb_output(15 downto 0) <= level_3_energy; -- Process control blocks for compares tb_level_3_triglev_control: process(level_3_energy, level_3_triglev) begin —- Determine the triglev output if any if(level_3_energy >= level_3_triglev(2)) then trnp_triglev(O) <= '1'; else trnp_triglev(O) <= '0'; end if; 206 if(level_3_energy >= level_3_triglev( 1 )) then trnp_triglev(l) <= '1'; else trnp_triglev(l) <= '0'; end if; if(level_3_energy >= level_3_triglev(0)) then trnp_triglev(2) <= '1'; else trnp_triglev(2) <= '0'; end if; end process tb_level_3_triglev_control; tb_level_3_compress: process(tmp__triglev) begin case trnp_triglev is When "001" I "010" I "100" => tb_output(25 downto 24) <= "01"; when "011" | "101" | "110" => tb_output(25 downto 24) <= "10"; when "l 1 1" => tb_output(25 downto 24) <= "1 1"; when others => tb_output(25 downto 24) <= "00"; end case; end process tb_level_3_compress; -- OR trigger level bits from level 2 tb_triglev_or: process(level_2_triglev) begin if ((level_2_triglev(0)(l downto 0) = "11") or (level_2_triglev(1)(l downto 0) = "11") or (level_2_triglev(2)(l downto 0) = "1 1") or (level_2_triglev(3)(1 downto 0) = "11")) then tb_output(l7 downto l6) <= "1 1"; elsif ((level_2_triglev(0)(l downto 0) = "10") or (level_2_triglev(1)(1 downto 0) = "10") or (level_2_triglev(2)(l downto 0) = "10") or (level_2_triglev(3)(l downto 0) = "10")) then tb_output(l7 downto 16) <= "10"; elsif ((level_2_triglev(0)(l downto 0) = "01") or (level_2_triglev(1)(l downto 0) = "01") 207 or (level_2__triglev(2)(l downto 0) = "01") or (level_2_triglev(3)(l downto 0) = "01")) then tb_output(l7 downto 16)<= "01"; else tb_output(l7 downto l6) <= "00"; end if; if ((1evel_2__triglev(0)(3 downto 2) = "11") or (level_2_triglev(1)(3 downto 2) = "11") or (level_2_triglev(2)(3 downto 2) = "l 1") or (level_2_triglev(3)(3 downto 2) = "l 1")) then tb_output(l9 downto 18) <= "1 l"; elsif ((level_2_triglev(0)(3 downto 2) = "10") or (level_2_triglev(1)(3 downto 2) = "10") or (level_2_triglev(2)(3 downto 2) = "10") or (level_2_triglev(3)(3 downto 2) = "10")) then tb_output( l 9 downto 18) <= "10"; elsif ((level_2_triglev(0)(3 downto 2) = "01") or (level_2_triglev(1)(3 downto 2) = "01") or (level_2_triglev(2)(3 downto 2) = "01") or (level_2_triglev(3)(3 downto 2) = "01")) then tb_output( 1 9 downto l8) <= "01"; else tb_output(19 downto 18) <= "00"; end if; if ((level_2_triglev(0)(5 downto 4) = "11") or (level_2_triglev(1)(5 downto 4) = "11") or (level_2_triglev(2)(5 downto 4) = "11") or (level_2_triglev(3)(5 downto 4) = "l 1")) then tb_output(21 downto 20) <= "11"; elsif ((level_2_triglev(0)(5 downto 4) = " 10") or (level_2_triglev(1)(5 downto 4) = "10") or (level_2_triglev(2)(5 downto 4) = "10") or (level_2_triglev(3)(5 downto 4) = "10")) then tb_output(21 downto 20) <= "10"; elsif ((level_2_triglev(0)(5 downto 4) = "01") or (level_2_triglev(1)(5 downto 4) = "01") or (level_2_triglev(2)(5 downto 4) = "01") or (level_2_triglev(3)(5 downto 4) = "01 ")) tlnen 208 1r tb_output(21 downto 20) <= "01"; else tb_output(21 downto 20) <= "00"; end if; if ((level_2_triglev(0)(7 downto 6) = "11") or (level_2_triglev(1)(7 downto 6) = "11") or (level_2_triglev(2)(7 downto 6) = "11") or (level_2_triglev(3)(7 downto 6) = "1 1")) then tb_output(23 downto 22) <= "11"; elsif ((level_2_triglev(0)(7 downto 6) = "10") or (level_2_triglev(1)(7 downto 6) = "10") or (level_2_triglev(2)(7 downto 6) = " 10") or (level_2_triglev(3 )(7 downto 6) = "10")) then tb_output(23 downto 22) <= "10"; elsif ((level_2_triglev(0)(7 downto 6) = "01") or (level_2_triglev(1)(7 downto 6) = "01") or (level_2_triglev(2)(7 downto 6) = "01 ") or (level_2_triglev(3)(7 downto 6) = "01")) then tb_output(23 downto 22) <= "01"; else tb_output(23 downto 22) <= "00"; end if; end process tb_triglev_or; -- Process control block for state tb_clk36_control: process (clk36, rst) begin type energy_array is array (0 to 3) of md_int; type triglev_array is array (0 to 3) of md_int; variable e: energy_array; variable t1: triglev_array; variable 131: md_int; variable seed: md_int; -- Positive-edge clock if (clk36'event and clk36 = '1' and rst = '0') then case ST is when reset => if(rst = '1') then ST <= reset; 209 else ST <= ei; end if; when eo => ST <= ei; -- Check Level 2 Energy Sum assert tb_output_assert(lS downto 0) = engine_output(] 5 downto 0) report "Level 2 Energy Sum Failure"; -- Check Level 2 OR assert tb_output_assert(23 downto 16) = engine_output(23 downto 16) report "Level 2 Trigger Level OR Failure"; -- Check Level 3 Trigger Level assert tb_output_assert(25 downto 24) = engine_output(25 downto 24) report "Level 3 Trigger Level Failure"; when others => null; end case; end if; -- Negative-edge clock if (clk36'event and clk36 = '0' and rst = '0') then case ST is when ei => if (ei_flag = '1') then ST <= e0; ei_flag <= '0'; else ei_flag <= '1'; end if; when e0 => ST <= e1; when e1 => ST <= eo; -- Save the TestBench output for Assertion tb_output_assert <= tb_output; -- Generate new data for i in 0 to 3 loop -- generate the level 1 energy 210 G(3111014040); Geand(tl(i)); -- output the values level_2_energy(i) <= CONV_STD_LOGIC_VECTOR (e(i).value, l4); level_2_triglev(i) <= CONV_STD_LOGIC_VECTOR end loop; when 10 => (tl(i).value, 8); -- Generate & assign the levels the levels case level _pc is when 0 to 2 => if (level _pc = 0) then report "Assigning Trigger Levels"; end if; Geand(131); level_3_triglev(level_pc) <= CONV_STD_LOGIC_VECTOR (l3l.value, l6); ia <= CONV_STD_LOGIC_VECTOR (level _pc, 5); id <= CONV_STD_LOGIC_VECTOR (l3l.value, l6); vme_select_engine_n <= '0'; vme_write_n <= '0'; when others => 211 ST <= ei; vme_select_engine_n <= '1'; vme_write_n <= '1'; if (level _pc = 3) then report "Trigger Levels Assigned, Beginning Engine"; V Endifi end case; -- Adjust the level pc If (level _pc <= 2) then level _pc <= level _pc + 1; else level _pc <= 0; end if; when others => null; end case; end if; -- Reset if(rst = '1') then ST <= lo; level _pc <= 0; ei_flag <= '0'; -- reset the seeding value seed.init := 7812; seed.min := 0; seed.max := 50000; for i in 0 to 3 loop -- set the default minimum value e(i).min := 0; tl(i).min := 0; -- set the default maximum values e(i).max := 65534; tl(i).max := 255; -- set the initial seed Geand(seed); e(i).init := seed.value; Geand(seed); tl(i).init := seed.value; end loop; -- Generate new data for i in 0 to 3 loop -- generate the data G<’~'an€1(6(i)); 212 V Geand(tl(i)); -- output the values level_2_energy(i) <= CONV_STD_LOGIC_VECTOR (e(i).value, l4); level_2_triglev(i) <= CONV_STD_LOGIC_VECT OR (tl(i).value, 8); endloop; -- Set the default mins for the levels l3l.min := 0; -- Set the default maxs for the levels 131.max := 65534; -- Set the initial seed for the levels Geand(seed); l3l.init := seed.value; end if; end process tb_clk3 6_control; end behavioral; 213 APPENDIX E PC Implementation Code E1 emc.h (C-H- Header file for emc dll) #ifindef _EMC_H #define _EMC_H #ifdef _EMC_ #define _EMCLIB_ _declspec( dllexport ) #else #define _EMCLIB_ _declspec( dllimport ) #endif // define all vb datatypes #define vbInt short int #define vaong long #define vbDouble double // define all data constants #define LEFT__SHIFT 4294967296 #define MAX_RAND 32767 // returns the estimated clock speed of system _EMCLIB_ vbDouble GetClockSpeed( vbInt Seconds, vbInt ClockOffset ); // returns the clock offset inbetween start & stop timestamp calls _EMCLIB_ vbInt GetClockOffset( vbInt Iterations ); // returns Level 1 execution time _EMCLIB_ vbDouble GetExecutionTime( vbInt Iterations, vbDouble ClockSpeed, vbInt ClockOffset ); #endif E2 emc.cpp (C-H- source file for emc dll) //********************************************************************** ******* // // DLL Name: emc.dll // Author: Brian Foulds // Description: Supplemental dll for EMC VB progam 214 // Created On: 07/19/99 // Modified On: 07/19/99 // Version: 1.0.0 (initial) // ”********************************************************************** ******* #include #include #include #define _EMC_ #include "emc.h" ”*****************************#**********#****#*******#**************** ******* // // Function Name: GetClockSpeed // Argument List: Seconds (vbInt), ClockOffset (vbInt) // Return: ClockSpeed (vbDouble) // Author: Brian Foulds // Description: Determines the approximate clock speed of the system // Created On: 07/19/99 // Modified On: 07/19/99 // Version: 1.0.0 (initial) // ”*#******#******¢**************#****************¥***********#*t******** ******* _EMCLIB_ vbDouble GetClockSpeed( vbInt Seconds, vbInt ClockOffset ) { long pcheck; . unsigned long start_upper, start_lower; unsigned long end_upper, end_lower; double clocks, scale; // serialize the CPU & determine if it is a P5 or geater asm { mov eax, 0h cpuid mov pcheck, eax } if (pcheck == 0) { 215 exit(0); } // get the starting time-stamp _asm { cpuid // clear the pipe rdtsc // get the time-stamp mov start_upper, edx // save the time-stamp mov start_lower, eax } // sleep Sleep(1000 * Seconds); // get the ending time-stamp _asm { rdtsc // get the time-stamp mov end_upper, edx // save the time-stamp mov end_lower, eax } // determine the processor speed clocks = (double)(LEFT_SHIFT * end_upper + end_lower) - (LEFT_SHIFT * start_upper + start_lower - ClockOffset); scale = (double)(Seconds * 1000000); return clocks / scale; } //***************#********t*I"*******************#********************** ******* // // Function Name: GetClockOffset // Argument List: Iterations (vbInt) // Return: ClockOffset (vbInt) // Author: Brian Foulds // Description: Determines the number of clock inbetween two subsequent // calls of the time-stamp. Provides for more accurate // time determination. // Created On: 07/19/99 // Modified On: 07/19/99 // Version: 1.0.0 // 216 //********************************************************************** ******* _EMCLIB_ vbInt GetClockOffset( vbInt Iterations ) { e 0 mt 1; long pcheck; unsigned long start_upper, start_lower; unsigned long end_upper, end_lower; _int64 clocks = 0; // serialize the CPU & deterrrnine if it is a P5 or geater _asm { mov eax, 0h cpuid mov pcheck, eax } if (pcheck == 0) { exit(0); } for(i=0; i= level_l_triglev[kD temp += 1; } if(temp >= level_l_triglev_compare) level_l_triglev_compare = temp; // determine high tower level bits temp = 0; for(k=0; k<3; k++) { if(high_tower[j] >= level_l_highlev[k]) 220 temp += 1; } if(temp >= level_l_highlev_compare) level_l_highlev_compare = temp; // determine ratio level bits temp = 0; for(k=0; k<3; k++) { if(ratio[j] >= level_l_“ratiolev[k]) temp += 1; } if(temp >= level_l_ratiolev_compare) level_l_ratiolev_compare = temp; } // compute the middle level 2 energy sums f0r(j=0; j<40; j++) { level_2_energy[0] += trigger_tower[i]; level_2_energy[ l] += trigger_tower[40 +1]; level_2_energy[2] += trigger_tower[80 + j]; level_2_energy[4] += trigger_tower[150 + j]; level_2_energy[5] += trigger_tower[ l 90 + j]; level_2_energy[6] += trigger_tower[230 + j]; } for(j=0; j<30; j++) { level_2_energy[3] += trigger_tower[IZO + j 1; level_2_energy[7] += trigger_tower[270 + j]; } // compute the final energy sum f0r0=0;1'<8;1'++) { level_3_energy += level_2_energy[j]; // determine level 2 energy level bits temp = 0; for(k=0; k<3; k++) { if(level_2_energy[j] >= level_2_triglev[k]) temp += 1; 221 } } if(temp >= level_2_triglev_compare) level_l_triglev_compare = temp; } // determine level 3 energy level bits temp = 0; for(k=0; k<3; k++) { if(level_3_energy >= level_3_triglev[k]) temp += 1; } if(temp >= level_3_triglev_compare) level_3_triglev_compare = temp; // assign the final engine output engine_output = level_3_energy + (65536 * level_l_triglev_compare) + (262144 * level_l_highlev_compare) + (1048576 * level_l _ratiolev_compare) + (4194304 * level_2_triglev_compare) + (16777216 * level_3_triglev_compare); // get the ending time-stamp _asm { rdtsc // get the time-stamp mov end_upper, edx // save the time-stamp mov end_lower, eax } // determine the computation time total += ((LEFT_SHIFT * end_upper + end_lower) - (LEFT _SHIFT * start_upper + start_lower) - ClockOffset); return ((double)total / (double)Iterations) * (1000 / ClockSpeed); E3 modPublicAPIs.bas (VB Public module with API definitions) Option Explicit ' Public Custom Declares 222 Public Declare Function GetClockSpeed Lib "emc.dll" _ (ByVal Seconds As Integer, ByVal ClockOffset As Integer) As Double Public Declare Function GetClockOffset Lib "emc.dll" _ (ByVal Iterations As Integer) As Integer Public Declare Function GetExecutionTime Lib "emc.dll" _ (ByVal Iterations As Integer, ByVal ClockSpeed As Double, _ ByVal ClockOffset As Integer) As Double ' Public Windows API Declares Public Declare Function GetCurrentProcessId Lib "kernel32" () As Long Public Declare Function OpenProcess Lib "kernel32" _ (ByVal deesiredAccess As Long, ByVal bInheritHandle As Long, _ ByVal derocessId As Long) As Long Public Declare Function SetPriorityClass Lib "kemel32" _ (ByVal hProcess As Long, ByVal deriorityClass As Long) As Long Public Declare Function CloseHandle Lib "kerne132" (ByVal hObject As Long) As Long Public Declare Function GetPriorityClass Lib "kemel32" (ByVal hProcess As Long) _ As Long E4 modPublicConstants.bas (VB Public module with constant defs) Option Explicit ' Public Windows API Constants Public Const NORMAL_PRIORITY_CLASS = &H20 Public Const IDLE_PRIORITY_CLASS = &H40 Public Const HIGH_PRIORITY_CLASS = &H80 Public Const REALTIME_PRIORITY_CLASS = &HlOO Public Const PROCESS_DUP_HANDLE = &H40 E5 modPublicData.bas (VB Public module with data variables) Option Explicit ' Public Data Public bollnitialized As Boolean E6 frmMain.frm (Main VB form code) Option Explicit Private Sub Form_Resize() ' set the listview size 223 lvaain.Left = 0 lvaain.Top = 0 lvaain.Width = Me.Width - 113 lvaain.Height = Me.Height - 220 End Sub Private Sub lvaain_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader) Static SortOrder As Boolean ' perform sort by the specified column clicked If SortOrder Then lvaain.SortOrder = lvascending SortOrder = False Else lvaain.SortOrder = lvaescending SortOrder = True End If lvaain.SortKey = ColumnHeader.Index - l lvaain.Sorted = True End Sub Private Sub mnuAbout_Click() ' show the about form fi'mAbout.Show vbModal End Sub Private Sub mnuCalibrate_Click() ' show the hourglass mousepointer Screen.MousePointer = vaourglass ' disable the main form Me.Enabled = False ' show calibration splash frmCalibrate.Show DoEvents ' call the clock offset function SaveSetting App.EXEName, "Settings", "ClockOffset", GetClockOffset(lOOO) ' call calibration function SaveSetting App.EXEName, "Settings", "ClockSpeed", GetClockSpeed(lO, _ CInt(GetSetting(App.EXEName, "Settings", "ClockOffset", 33))) ' unload calibration splash 224 Unload fimCalibrate ' enable the main form Me.Enabled = True ' show the default mousepointer Screen.MousePointer = vbDefault End Sub Private Sub mnuChangePriority_Click(Index As Integer) Dim i As Integer Dim pid As Long Dim hProcess As Long Dim priority As Long ' get the apps pid pid = GetCurrentProcessId ' get a handle to the process hProcess = OpenProcess(PROCESS_DUP_HANDLE, True, pid) If (hProcess <> 0) Then ' set the current priority class Select Case Index Case Is = 0 priority = SetPriorityClass(hProcess, IDLE_PRIORITY_CLASS) Case Is = 1 priority = SetPriorityClass(hProcess, NORMAL_PRIORITY_CLASS) Case Is = 2 priority = SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS) Case Is = 3 priority = SetPriorityClass(hProcess, REALTIME_PRIORITY_CLASS) End Select If (priority <> 0) Then For i = 0 To 3 If (Index = i) Then mnuChangePriority(i).Checked = True Else mnuChangePriority(i).Checked = False End If Next 1 End If ' close the handle to the process Call CloseHandle(hProcess) 225 End If End Sub Private Sub mnuClearList_Click() ' clear out the listview lvaain.ListItems.Clear End Sub Private Sub mnuCompEngine_Click() Dim strTemp As String Dim Iterations As Integer Dim ClockSpeed As Double Dim ClockOffset As Integer Dim ExecutionTime As Double Dim MyListItem As Listltem ' get the clock speed ClockSpeed = GetSetting(App.EXEName, "Settings", "ClockSpeed", 0) ' get the clock offset ClockOffset = GetSetting(App.EXEName, "Settings", "ClockOffset", 0) ' get the number of iterations strTemp = CStr(InputBox("Number of Iterations to Determine Level 1 “ & _ ”Execution Time?", "Number Of Iterations", "100")) If IsNumeric(strTemp) Then Iterations = CInt(strTemp) Else ' user pressed cancel, exit sub Exit Sub End If ' show the hourglass mousepointer Screen.MousePointer = vaourglass ' disable the main form Me.Enabled = False If (Iterations > 0) Then ' perform the analysis ExecutionTime = GetExecutionTime(Iterations, ClockSpeed, ClockOffset) ' add to listview Set MyListItem = lvaain.ListItems.Add(, , CStr(Iterations» MyListItem.SubItems( 1) = CStr(ExecutionTime) MyListItem.SubItems(2) = _ 226 Left(CStr(450 * (l / (ExecutionTime * 10 A -9)) / 2 A 20), 4) ' release the object from memory Set MyListItem = Nothing End If ' enable the main form Me.Enabled = True ' show the default mousepointer Screen.MousePointer = vbDefault End Sub Private Sub mnuExit_Click() Dim i As Integer ' Terminate the progam For i = 0 To Me.Count - 1 If (TypeOf Me.Controls(i) Is Form) Then Unload Me.Controls(i) End If Next 1 ' unload main form Unload Me End Sub Private Sub mnulnitialize_Click() Dim dblTemp As Double ' show the hourglass mousepointer Screen.MousePointer = vaourglass ' disable the main form Me.Enabled = False ' initialize the system dblTemp = GetExecutionTime(IOOO, 450, 35) ' set the initialized flag bollnitialized = True ' enable the main form Me.Enabled = True ' show the default mousepointer 227 Screen.MousePointer = vbDefault End Sub Private Sub mnuPriority_Click() Dim pid As Long Dim hProcess As Long Dim priority As Long ' get the apps pid pid = GetCurrentProcessId ' get a handle to the process hProcess = OpenProcess(PROCESS_DUP_HANDLE, True, pid) If (hProcess <> 0) Then ' get the current priority class priority = GetPriorityClass(hProcess) If (priority 0 0) Then Select Case priority Case Is = IDLE_PRIORITY_CLASS mnuChangePriority(O).Checked = True mnuChangePriority(l).Checked = False mnuChangePriority(2).Checked = False mnuChangePriority(3).Checked = False Case Is = NORMAL_PRIORITY_CLASS mnuChangePriority(O).Checked = False mnuChangePriority( 1 ).Checked = True mnuChangePriority(2).Checked = False mnuChangePriority(3).Checked = False Case Is = HIGH_PRIORITY_CLASS mnuChangePriority(O).Checked = False mnuChangePriority( 1 ).Checked = False mnuChangePriority(2).Checked = True mnuChangePriority(3).Checked = False Case Is = REALTIME_PRIORITY_CLASS mnuChangePriority(O).Checked = False mnuChangePriority( 1 ).Checked = False mnuChangePriority(2).Checked = False mnuChangePriority(3).Checked = True End Select End If ' close the handle to the process Call CloseHandle(hProcess) End If 228 End Sub Private Sub mnuRun_Click() Dim strTemp As String ' Check to see if system has been calibrated strTemp = GetSetting(App.EXEName, "Settings", "ClockSpeed", "None") If ((strTemp = "None") Or (bollrnitialized = False)) Then mnuCompEngine.Enabled = False Else mnuCompEngine.Enabled = True End If If (lvaain.ListItems.Count <= 0) Then mnuClearList.Enabled = False Else mnuClearList.Enabled = True End If End Sub 229 Appendix F Synthesis Simulation Results F1 Simulation of Level 1 0 to 500 ns | 15.01 | 11901 I 1‘?“ | 12901 | 125301 I 132»: I 131.501 | 1‘2”: 1 l‘§ol '1 clk36 ST "‘T‘ "‘ "Jr" ""' "' g: “"' "' -.... "‘ 2'" "' ""“ "'—_ ...... ... ..-.. .... .m. -.- .n.‘ .. ... .--“ ... .--.. -. ..... ... ..-.. ... ..-.- --. ....o --. ”... ... .. -. vine." _select_erngirne_ n In” boom... OW “...-...“ .lnm..-..... . vrnewrien l -- ...-. ... ..‘ .. ... ---.o .. ... ..- --.O. ... 0.... ... 0.-.. ... ..-.O ... ..-.. .-- ..u. ..- ..-.0 ... 0.--- .-. .. Ti" 1 -.. ... “... ... .... ..- ..--. ... ....d 13593223411053”) (41434769561057 39) l l I I “331;“. F0 96) 702.20.» 54,150 00.216.ka 251"; I _level '1/e1m _ratio_ 1 .. Ioo.oo.oo.oo.oo.oo.oo.oo.oo.ao1 _ “I _level_1/e0_retio_adjust pFEIoeom 100° ..-” ... ..-” ... ....- ... ..-.O ... ....- ... .0... .0. ... .... ... mo. ... OC‘ ..--C ... ——"— [in level 1161 _ratio" I IrmzomueocchmAE) I whom - ---- . -- ..“(DA35AE 55. E3 “..CC. ZAFF, EE BE)g I WI- ..- ...0. ..- ..-. . ... Om. ... ..1. 0.... ... ..- tb_ouMeseert ...- ... .. ... ... 0...- ... ..-”... . ..-. .... ...-c .- -. ... ..--. -.. 0.-.. ... u-.. ... .0... engrne_outpu .oooo fcoo rear" 230 F2 Simulation of Level 1 501 to 1000 ns I .550. I .m. I .650. I ITOOI I ITSOI I .800. I IESOI I .m. I I950I fl clk36 ”...-O mmmmmum.. cm “...“... ‘ WW. ST m ....- ” ...“ ... .0... ... .. ... ... ”-.. ... .. :‘pjsff1:."""'j;o"}:;'"j"j;"'““1'.'3"j;{‘1"];"""1;.2"1;;"fi:"“”};3 '13?” me_select.engm_n me_unne__n engire_ack_n trigger_touer ....mmm..-»nu.....m-.......... ... 0.... _ J rc- cocoon—0.... ...- ...uouooonoocooc ...- I. ...u ... ..-.. ... ..- 'fiLtower ml m.................................--o ... “... ... ... b. ... .. level_1_ra1iolev )ummmmmmu- "mm“.mmnq bmlevel1le1mfio_0 ...“ O .0... ... ..-.O ... ..-” ... ..-O‘ _ 1”" T b" ...”...mmmmm... .m- .-...1-..-... tb_leveL 1191mm 1 loo.oo,ootoo.oo,oo.oo.oo.oa, mm. .mmmm Cum-mmmmmMHOOOO mmm“... .....- 1b___|eveI1le0ratio_aqmt ...-......” ....m............................ -1....... .1200 ....“ .0. co. m tb_level_fleLtatio m ...u........................ ...-......O ratio .. ... ...” ... “... ... C... m ....- ... a... ... ..-.. ... ..-“ ... ”-.. ... CO... ... CO... ... ..-“ ... ..-.- ...................................o-..-..-...-...q .....- 1b -oupuLassen 008 002 492 t........................................ ......- ..‘OOOOOO . ..-“ ... ..- ...... ... ...” ... ...-C ... ..... ... ..-" ... ..-.( m_m 91 £658 1 Eccz""'""1""}m 1 km 1 re 231 F3 Simulation of Level 1 1001 to 1500 ns |‘050|1‘00|‘150'1200|125°|‘300'1350|1m"450 '1 dk36 b.S...r.................................-... .. .. iéijéiiji I'Jw FIE: I :EEEE 3 :15: :39 EU‘ 1° vme _selecLengine_ n" boo ...- ..- .u..- cu. .0...- .0... ... .--..- I..." ..- ..1 O. O me_wrie_n Mmmmuomumo—o. ... .0-.. . ... eno’nejckm flifimm‘ " ........ _IBVBL 1IeO_ rub _adiust ”-..-“mu”... .mummuummm lawLfleerio féE ..."... I???“ USE; .. ' FE: :jffi . 232 F4 Simulation of Level 1 1501 to 2000 ns . 1550.1000. 16501170011750. 18001185011900.1950 nil clk36 ST 11 1 1 1 1 vme _select_9119ine_ 11" wne_ mie_ n ...... ... D... .0. ..-.. ... ..1 .. _ ... ..-.. ... ..... ... 9.-.. ... ..-.. .. "..- ... ...“ ... ..... ... ”-.. ... ....- ... ..... ... “... ... ..... ... ....1 MLW .-. .... ..... ... ..... ... CC... 0.. ..-.. ... ..... ... ..d . ... ..-.. ... ..-.. ... “... ... ..-.- ... “... ... ..-.. ... ---.. ... ..--. ... ..-.. ... ..-.. ... ..-.. ... ...“ ... u... ... ...“ ... .... “Oh—W I I I I I .. ...“ ... ...” ... .0... .0 on... ... ..-.. ... ..-“ ... ..d .. ... ..-.. ... ..... ... ..-" .-. ..-.. ... ..--. ... ..... ... ...“ ... ..-.. ... ....- ... ....- ... ..... ... ....1 "_10'1101_1'101' _101'1'0_o “”1“”..me _r—T' -..............-.......u......... 'i'"""'"'"""”"" _10'1'101_1/01_'_"10110: '1'" '""'""' """'"“"""""'"'"”"°” "”7"" "'""""""'"'""""" M10101 1100" "1011B"0'01'1'01"“mmj030""m .............-..............._... 11110 7"m"'7"""jb'SomwmmijJT 110_101101_1}01_10110 1 l l l 0&7”"”"'”""°'"""“'”fin”""""""""f'"'"'7""7"""7""“”“mmmmmm”mm"""7 1070mm””mmmmmm ........... :FEB1"M"W labialémwmm""""m’mm"""mMWMMEX" O. 0.... ... 0.... ... DO... ... ”... ... ....C ... ...“ ... “11...... ... ..-.. ... ..-.. ... ..-..- ..--- ... ..-.. ... ..... ... ..... ... ..-.- ... ..... ... ”... ... “... .. ... ...“ .- ..-. -0001 Fem ] [am [80135 | 1mm MIBCCA 233 _ _ F5 Simulation of Level 2 0 to 500 us | 15.01 I ”(P1 | 11§01 I 121.301 I 125.301 I 13901 I 13.501 I 1W1 I 14?» select_et191ne_11 ... ...“ ... ...“ ... ..... ... .... ... . . . .. .--.- ... a-.. ... ..... ... ....C ... ”... ... ..... ... .m. ... ...“ ... ..-.I ... _Mle_n ... ”... ... .... ... ..... ... .... ... ... “-.. ... -.--u can ----. --. ..-.. ... ... "... ... "... ... ...-I ... m ... C O. . ..-” ... “-.. ... -.-.D ... .C-C‘ ... ..--I ... O...- ..O .C-C- ... ...“ ... . _aok_n Lemmy 0110 329. an are zae 14119911 05.00.23.3F,35.0o) ”... ... ...” ... ...-O ... .... ... ..... ... CC... ... “... ... ..-.O ... ”-.. ... .0... ... ...-O ... DO-.. ... ....o ... C. .. ... I- .0“ "... ... ”... ... .... ... ...“ ... .... ... ...“ ... 0.... ... ..-.- ... 0.-.. ... .0... ... .“O. ... ..--I ... ....- --. O. O. ... I. I. ... -. _OUMM _oulpu F6 Simulation of Level 2 501 to 1000 ns I 155.01 I 15ml I 16§01 | 17901 | 17§01 I .KPO. I 18§O1 I 19901 I 19,2501 .. u... ... .... ... ..... ... ....- ... ..... ... .1 ... ... ..... .-. ...“ ... ..-.. ... ..-.. ... ”... ... ..... ... ..... ... ....O ... ..... ... ...“ ... . ..... ... .—.. ... m b.. ...... ... ..-.. ... ..-.. .. ....-- ... ”... ... .4 ... ... ..-.. ... ..-.. ... ..-.I ... ..... ... ..-.. ... ...“ ... ..-.. ... ..-.. ... ..... ... ..-.. .-. ..-” ... — ...“ .- 0..-. p.. ..-.. ... “.-. .... .... ... .... -. ..... ... -1 ... ... ...“ ... ...-. ... ...” ... ...“ ... ..." ..I. ..-.. ... ..-.. ... ..-.. .. ..-- .-. -.... ... ..-“ ... ..... ... ....- ... ..—.. ... ..... ... ..--1 11111931110311 iam ..-.. ... “... ... ..-.. ... ..... ... ....- ... .1 ... ... ..-.. ... ..-" ... ..-.. ... ..... ... ”-.. ... ..-.. ... ..-.. -.. 0.--. ... ..--o ... .--.. ... ..-” ... ....O ... .--.. -.. ..-.. ... ..-.. ... ....1 id ..... ... u... ... ”... ... .... ... ....- ... .1 ... ... ..-.. ... “-.. ... ..-.O ... ..-.. ... ”... ... ..-.. ... ..-.. ... ..-.- .. ..... ... "... ... ...“ ... ....- ... ...-o. ... ..-.. .-. .-.. ... ..-.d engine_ack_n ....O ... .--.. ... ....- ... M ... ..... ..- .. ... ... ..... ... ..-“ ... ...“ ... ..-.. ... -.-.. ... "-.. ... “... -.. ..-.. .- .... ... ...“ ... .... ... ....- ... ..-I- ... ..--. ... .-.. ... ....I W—LMV I l l 1 l ..-.. ... ..... .. ...-.. ... ...” -. ...CO ... .1 ... ... ..... ... ....- ... .--.. ... ..--. ... ..-.- ... ..-.- ... ..-.. ... ..-.. ... ....- ... ..." ... ..-.. ... ...“ ... 0.-.. ... ..--. .-. ....O ... ..-.l Ievel_1_0im9v I I I I 121.113.1111.: 81' 1 1 1 1 1 i 16:0131’061mmmmmm ppo1nmm'mEEEEEI [000120 ....-.... "1300030000?" 115 _oupuLassen ”finesse “MESS; "1000201 1010120 11150200 L... ..... ... ..... ... ...” ... .... ... ..." ... .1 ... .-. ..-.. ... OI-.. ... ..-.I ... ..-.. ..- .--.. .-- ..-.. .. .--0. ... .. ... ... ..-. O. .. ..-.C . . ....- ... ..--. ... ...-. ... ..-.q 9119019311011! 590 [3901113 “1300291 75:04:11) .. [31:02:19 234 F7 Simulation of Level 2 1001 to 1500 ns .1050.11oo.11so.1200.1250.1300,1350,14oo.1450 DO-.. ... ..-- ... "-.. m ..--I ... “... ... _select_engine_n ....- ... ”... ... ..-” ... ”... ... ...-- _wrie_n ...“ ... .... ... "... ... ..-.. ... ...-. ..- ”.-- .-. .9--- ... ..--- .-- afififéfiéfimm ' ' ...............-..............................-............................................ m1_triuev 0.... ... .... ... ..... ... ”--. ... .. _outpu ...O. ... ...“ ... ...” ... ...“ ... ... . ... .. ... .- .. .. . ... .. ... .0 .. . .. ... .. .. ... .. .. ... ..-.. ... ..-“ ... IO-.. ... ..-.. ... ..-” ... “--. ... _Massert m -- --.. I” ..--O .. -.-O. ... _oulpu F8 Simulation of Level 2 1501 to 2000 ns .1550,1aoo.1eso.1100.1750.1aoo.1950.1900.1950 m:se1ec1m"""§i€ifié:n " " " " ...... .............-._.....-...........-...-........,... . . _ack_n .... .. .... ... ”... ... ...“ ... . 1_energy 1_trigev .... ... ..-.- ... ..--. ... _Oulpu 23S F9 Simulation of Level 3 0 to 500 ns ' '50. | .1“). | .150. | .200. | .250. ' I300| I .350. | .‘m' ' .450. 0‘ 3633:1919; net1g;re_ad(_n ”O O... ... O... O... OOOOO OOO OOOOO OO. “... ... O‘ ......“01 a [ I FM 3613 9eIeoI""'é}°{éEne 11 WW" W" " "' .. " " " OOO OOO OOOO. O“ OOOOO O“ OO... OOO OOOOO OOO .OOOO OOO OOOOO OO. OOOOO OOO O. OO ...“ ... OOOO. OOO ..." ... ...0. OO. O.“ Id IwIflll-I F0101III0I'IIII F0111”! I-OI .... “.00 “O 0.. OO ”O ...-.. OOO O. OO. CO... ... ....O ... OOOO. O... OO- OOOO OOOO IST (OF‘AJZABIMUK33CAE) _IIIII ...........-..... IIII IIIIIII ..... 99239;“M 993399"”“““ ooh 371 CID) Iowan») I63. 71:93“ I991 .. .. ...... ... ...... ...... ... -..-.... “...-.1 IIeveLI 3_1riglev 9ma O. _O O“ OO-.. ..O O. -- ‘1'-po- ----- --- ----- no -- ...... ...... .... I I IFF1o 19999992) ..- OOOOOOOOOOOOOOOOO O... “O I1FF9908 ....- ... o. 00.0 .. ...-.. ... ..-.q ".I‘IFTSBBB I1FA9431 engne_outpu ”Hf Ema: III I1FF9909 "I." ”I1F73999 I F10 Simulation of Level 3 501 to 1000 ns | 155Io1 I 16901 I 165301 I 175.01 I 17§01 | 18901 I IBSIOI I 19901 | 19§01 11:36 N. .0... 0.0 .0... 00. 0.-.. ... ..-0. .0. l3! .OOO. OOO .O... OO. “... “O “... ... OOOOO ... OOOOO OIOO OOOO. OO. .O... OO. ...“ ... OOOO. ... ..-O. OO. OO-.. OO. O." ... O...‘ 00.00 0.. --.. ... ..-.- ... -.--. ..- I.. .. .0. ..-- ... ..... ... ..-.. .00 0.-.. ... .0 .. ... ...“ b.- ... .. 0. -.- no--. ... co..— 0.. ..-.. .0. ..--- .0. -.--0 .-. .--.. ... ..-.- ... .0-.. .-. .--.- .0. ..-0. ... .0-.. ... ..--. ... .0--. .0. ..-.. ... ....- id ).- ”...-......0..- ......- ....... ......o...‘ _0 ... 0.-.. ... u-.. ... ..-.. ... ..--0 ... 0.-.. .- ...- ... .... ... OOOOO .0. .0-.. 0.. 0.... ... .... ... ..." ... ”... 00. O--. .00 ...“ 0.. 0000‘ me_sdect_enghe_n LO. ...... ... ..-.O "O ..--O ... OO... ... ”... ... O‘ .0. 000 00.00 000 00-.. ... ..-.. ... OOOOO OOOOOOOO u..............................0................0....0..0..0001 me_write_n .1........ 0.. ... .0-.. .0. 0.-.. ... ....0 .0. ..." ... ..-.. .0. .0-.. 0.. .0... ... ..... ... ...0. ... ..-0. ... ..-.o .-. .--0- ... ..-0. 0.- 0.... ... 0.... emuieackn ....-.. ...... ...........................J L... ............... .. OO -O. ......0....00-.00.. ......”mmmmmmmmmmmmde ST n‘IILId IMJIMII!I POI-1II-IIII-0I1'IIGI‘ 1”}LIE ).o no-.. ... level_2_enecgyIII .... ... .0-.. ... “-.. ... 0.... .0. -d I ..-...“ 0..- "m. ‘""]93251'.BEI&>I:" I I [(9937 99 ,Fa')m I319? FE D9)"- [(5991.0137)” WI97IICEI4C ...-.. ... ..- ... ..-...O...... 0.. .... .. ..... 00.0.00. .00.000000.0. ... .OO “-.. OO. OOOOO ... ...-O OO. ...O. ... ..--O “O ..-.O OOO O... O... ... ....O ... ...-O OO .O OOOOOO O“ OOOOO OO. .OOO‘ I18F330I3 [195534FII mI1F9A29F IIFFBSDIfim I1FB9CTA ieJaI 2339917” ' " 19119133339 " .. ... 19:'oupuz"mmassenm ... .... " 18F3303 .ImnI135534me]. I1FBA28F ”I mI1FF9905 I" IEEET' 236 F11 Simulation of Level 3 1001 to 1500 ns '1050.1100.1150.1200,125O,1300l1350.14OOI1450 fl id L.- ..o. o ... ...-.- H.- .u m ...-o no .4 .- ... .--" ... ..--- ... 0.--. -.. u-.. ... ..-.0 ... u... ... ..-.- -0. --.... .. u-.. - .. .... - vme selecl_engine_ n vme_ Me n .O 00.- .00. ....0 ... 0.-. . 0.. ..-.0 ... ....- 00. 0‘ h“ ... .0... .0. ...00 000 0.-.. 0.. ...-0 ..0 00-.. 0.. O... .00 .... .00 0.... OD. 0.-.. Ienghe_ ack_ n -_.................... -.. .... ............. .J 9?"'"""”""'"" “-..”. IIIIIIII.III1IIII ”1‘... 133131 “ll: ""19 In 11- I93 .131. [Tu _Ilgo I311? 0... ... 00..- .. 00.... 0.0 ...... 0.. .0... ...- 0--. -0 O... ...-"mm“.mumm“ IWiZTW I I I I I 19131:? mew” ........... "W TIL—"”"IE'EfizXéXi" ”191:3?sz 92) 1197953999) I05 492929) IIAaI. 11 level_3_t7v9v 0.. 0.... 0.. 00-0. 0.. 0.... 0.0.-. ... ”... .. I”. .0. 0.... ... ....0 O... .0. OOOOO 0.. .. .OOOOOOOOOOO-OOOOOOOOOOOOOOOOOOOOOOOOOOm“.-.-O... b_ouw_assel1".|101=501=:c |1EF5520 I1EFAA97I [1995494 "1qu9} OH...” OOO O... ...”..- OOOOO O” ..-.O OO. O... ..O... OO. ....O ... O‘ .OO .O ' _oulpu I I1chcec “I; "I19F5520 [1EFAM7 F12 Simulation of Level 3 1501 to 2000 ns ,1550.1soo.1950.1700.1750.1900.1950.1900.1950 n1 O‘ O- ... O-O. OOO OOOOO ... OOOO‘. ... ..--O ... ..-.- ..O ..--O ... OOOOO ... CO... O.- OO... OO. O... ... OOOOO OOO OO... ... OOOO' ... OOOOO ”O OO... OO. ..-O‘ 0 0.0 .0... .0. 00-0. 0.. 0.-.. 00. ..-. I DO. .00 00.-. 0.. .0-00 ... 0.-.. 0.. 00... 00. 00-0. ... u... .0. 00-00 0.. 00-.. 0.. .0... .00 0.-.. 0.. 0---- 000 .--. O OOO OO... ... ...O. ... ”... ... OOOO. OO. ..-.O ... ..-.O ... ..-OO OOO OOOOO ... 00... ... OO... ... ..-” ... ..-OO OOO OO-OO ... OOIOOO OOO OOOOO OOO OOOO‘ - «”4 ... O- ....- ..O ....- .O. OOOOO OOO ..-.O ... ...-O OO. ..-O. ... ....O ... OOOOO O.- OO... ... ..-O. O- ....O ... OOOOO OOO OOOOO ... OO... ... OO-O. .O 0 0. ho. 0.. 0.... ... 0.-.. 0.. .0-.. ... ..--0 ... ..-.- .-. .--.. ... .0-.. .0. .0--. .0- .0..- ..- ..-.0 .0. 0.-.. ... 0...- ... 0.... .0. 00-00 0.. ...-0 ... 0.-. b... ....-. ... O. O” OO. "... ... OO-OO EFIF 9919 bhlh MMIF MM ......“ O... O... O... O. ...-O OOO .-.. H... O... O... ... O.-. ”"Hr'"'I”'"'"' "W :i"""'"' —I___I ambaImzasrom I92 EE 91F3MWI91§§991° Imfios) ’95"‘""'j¥£é31§}:” {1253' "“111'ESaZS‘II': ”IBEERBWMI 111F99197 "1..--.me WI "111999923 I "118917510 I I 237 BIBLIOGRAPHY 238 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] BIBLIOGRAPHY P.J. Ashenden. The Designer’s Guide to VHDL. Morgan Kaufmann, San Francisco, CA, 1996. Brookhaven National Laboratory. EMC Front End Electronics. [Online] Available http://www.rhic.bnl.gov/STAR/html/emc_l/tdrfiles/emcreq.pdf, October 26, 2000. Brookhaven National Laboratory. Experiments at RHIC. [Online] Available http://www.rhic.bnl.gov/htle/experimentshtml, October 26, 2000. Brookhaven National Laboratory. Introduction to STAR Physics. [Online] Available http://www.star.bnl.gov/afs/rhic/star/doc/www/physics/Introduction.html, October 26, 2000. Brookhaven National Laboratory. Physics Primer. [Online] Available http://www.rhic.bnl.gov/htle/primer.html, October 26, 2000. Brookhaven National Laboratory. Relativistic Heavy Ion Collider. [Online] Available http://www.rhjc.bnl.gov/, October 26, 2000. Brookhaven National Laboratory. RHIC History. [Online] Available http://www.rhic.bnl.gov/htle/history.html, October 26, 2000. Brookhaven National Laboratory. RHIC Physics. [Online] Available http://www.rhic.bnl.gov/htle/rhicphysics.html, October 26, 2000. Brookhaven National Laboratory. Scientific Motivation for STAR. [Online] Available http://www.rhic.bnl.gov/STAR/html/emc_l/tdrfiles/chapin.pdf, October 26, 2000. KC. Chang. Digital Systems Design with VHDL and Synthesis. IEEE Computer Society Press, Los Alamitos, CA, 1999. M. Gschwind. A VHDL Design Methodology for F PGAs. [Online] Available http://www.cos.ufrj.br/~gabriel/vhdl4fpga.ps.gz, March 23, 1999. J .L. Hennessy and DA. Patterson. Computer Organization & Design: The Hardware/ Software Interface. Morgan Kaufmann, San Francisco, CA, 1994. Intel Corporation. Intel Architecture Software Developer’s Manual Volume 2: Instruction Set Reference. [Online] Avaliable fip://download.intel.com, design/PentiumII/manuals/243 1 9102.PDF, June 10, 1999. 239 [14] [15] [16] [17] [18] I. Koren. Computer Arithmetic Algorithms. Prentice Hall, Englewood Cliffs, NJ 1993. Lucent Technologies Inc. ORCA Series 2 Field-Programmable Gate Arrays Data Sheet. [Online] Available http://www.lucent.com/micro/fpga/orcapdfs/DS99- O94.pdf, April 14, 1999. D. Mann. Efficient FPGA Design with Logic Synthesis. In Electronic Engineering, vol. 69, pp. 66-68, May 1997. STAR Detector Diagram. [Online Image] Available http://www.rhic.bn1.gov/STAR/img/images/star/star_detector.gif, October 26, 2000. Xilinx Corporation. XC4000E and XC4000X Series Filed Programmable Gate Arrays Data Sheet. [Online] Available http://www.xilinx.com/partinfo/4000.pdf, October 26, 2000. 240