Samplers (top-level = sampencbank):

Description:

The PMT inputs, in00..03AB, are sampled on two 500MHz interleaved clocks, clk_ab0t or clk_ab0b, by comparing the inputs to the seven voltage references, Vref[6:0]. For each PMT pixel, this generates two 7-bit thermometer code streams on the a and b clocks. These are copied and perform three functions in parallel:
  1. Astronomy -- A set of muxes steer data from a particular pixel address (set by pix_add_ast[3:0]) and voltage threshold (set by c_ast[6:0]) to the astronomy module, iff pix_blk_ast[0]=1 (i.e. this block is chosen).
  2. Coincidence detection -- One bit from each 1-of-7 data stream is chosen by the 1-of-7 address c_coinc[6:0]. For both clocks (a and b), these bits are compared for matched pixels (A and B) with and AND gate array. The output of the AND gate array is coinc_add_ab0[3:0], which is sent to membank.
  3. Encoding and shift register buffering -- Meanwhile, each 1-of-7 data stream is gray encoded to 3-bits, and then put into a shift register bank. There are 32 PMT pixels (16 pair), 2 clock edges, and 3 bits per pixel/clock, for a total of 192 shift registers (which are 8 bits deep). When a coincidence is detected, the address of the coincident pixel is passed back from membank on cp_add[3:0], which instructs a mux to put the appropriate data coming out of the shift registers on GABab0[2:0] (12 bits).


Below is a capture of the sampencbank schematic. One can see the eight sampler_encoder blocks vertically aligned on the left. The input clocks are shown at the top left (one pair of triangles) and bottom left (a second pair of triangles). Each sampler_encoder takes one analog input and processes it. The sampler_encoders' outputs do several things. (Captures below show closeups.) The encoded samples (GabAB0..3) are sent through a shift register array (stacked rectangles in center). The output of the astronomy voltage threshold muxes (ab_ast0AB0) are sent another mux ("astmux"; trapezoid in the middle) that chooses a pixel to send to the astronomy module. The output of the coincidence voltage threshold muxes (ab_coinc0AB0) are sent to the coinc_detect module (lower right) to look for coincidences. If a coincidence is detected, the appropriate outputs of the shift registers (GabA_0..3B) are sent to the membank module.

Module: sampencbank
Hierarchy: pulsenet: sampencbank

It's useful to look at the icon for sampencbank, so that we can clearly see the inputs and outputs.

Module: sampencbank (icon)
Hierarchy: pulsenet: sampencbank


The capture below shows a closeup of one of eight sampler_encoders in each sampencbank module.

Module: sampencbank (closeup of sampencbank - lower left in top-level capture)
Hierarchy: pulsenet: sampencbank


The capture below shows a closeup of the coinc_detect module.

Module: sampencbank (closeup of coinc_detect - lower right in top-level capture)
Hierarchy: pulsenet: sampencbank

Here's a capture of the inside of the coinc_detect block. It's rather simple: an array of AND gates to detect the coincidences, clocked D-flip-flops to latch the coincidences, and an inverter horn to drive a large output.

Module: coinc_detect
Hierarchy: pulsenet: sampencbank: coinc_detect


The capture below shows a closeup of the astmux module and several assorted drivers.

Module: sampencbank (closeup of astmux - middle in top-level capture)
Hierarchy: pulsenet: sampencbank

Here's a capture of the inside of the top quater of the astmux block. The triangular modules that are gated by pix_add_ast[0] are just pass gates.

Module: astmux
Hierarchy: pulsenet: sampencbank: astmux

Here's a capture of the pass gate. in passes to out when control is high.

Module: pass
Hierarchy: pulsenet: sampencbank: astmux: pass (elsewhere, too)


The capture below shows a closeup of one of three coincmuxes.

Module: sampencbank (closeup of coincmux - one of three in upper right in top-level capture)
Hierarchy: pulsenet: sampencbank

Here's a capture of coincmux. It's also just a bunch of pass gates.

Module: coincmux
Hierarchy: pulsenet: sampencbank: coincmux


The capture below show a closeup of the shift register chains.

Module: sampencbank (closeup shift register delay lines - middle in top-level capture)
Hierarchy: pulsenet: sampencbank

Here's a capture of shiftmem2. It contains the same shift register elements (2X lev1 = 8 stages) as membank..

Module: shiftmem2
Hierarchy: pulsenet: sampencbank: shiftmem2



Now let's go through the hierarchy levels of sampler_encoder. Here's a look inside. We can see the single analog input ("in"), Vref[6:0], and the two clocks enter on the left. The sampling happens in two sampler_7 blocks. The 7-bit outputs of these blocks are encoded to 3-bit Gray code in the encoder blocks. The outputs also go to the sampmux block where c_ast[6:0] and c_coinc[6:0] determine which bit of the 7 bit streams will pass to the astronomy module and coinc_detect (in sampencbank), respectively.

The encoder is not shown in detail because it was was synthesized from verilog.

Module: sampler_encoder
Hierarchy: pulsenet: sampencbank: sampler_encoder


Here's the inside of sampmux. It contains two 1-of-7 muxes ("mux7" -- just a bunch of pass gates) that act to select 1-of-seven bits from each of the data streams.

Module: sampmux (top half)
Hierarchy: pulsenet: sampencbank: sampler_encoder: sampmux


sampler_7 is one level deeper still into the sampler. It just distributes the single analog input to seven samplers ("senselatch") along with the seven voltages for comparison. Note that Vref[0] is apparently wired backwards (in on "+", not "-"); this is not an error. Vref[0] is the veto voltage threshold. Since it is positive with respect to in's DC voltage, the inputs have to be reversed to that a veto produces out[0]=1.

Module: sampler_7
Hierarchy: pulsenet: sampencbank: sampler_encoder: sampler_7


senselatch is basically two comparitors (strongarm and sarmlatch) and a latch (srmod).

Module: senselatch
Hierarchy: pulsenet: sampencbank: sampler_encoder: sampler_7: senselatch


strongarm is a gate-isolated sense amplifier. The output nodes (xp and xn) are precharged high when ck is low. The input pair (an and ap) converts the differential input voltage into a differential current, which is integrated on bn and bp. When the source node corresponding to the high input, say bn, reaches a threshold drop below Vdd the transistor above this node begins conducting, transferring charge imbalance to xn and xp. This starts the regenerative action of the cross-coupled inverters at the top and the circuit quickly latches the state.

(Note of interest: It's called strongarm because it was originally used as a flip-flop in the StrongArm microprocessor.)

Module: strongarm
Hierarchy: pulsenet: sampencbank: sampler_encoder: sampler_7: senselatch: strongarm


sarmlatch is similiar to strongarm, and was included for the extra gain it provides.

Module: sarmlatch
Hierarchy: pulsenet: sampencbank: sampler_encoder: sampler_7: senselatch: sarmlatch


srmod stores the 1-bit comparitor measurement when clock goes low.

Module: srmod
Hierarchy: pulsenet: sampencbank: sampler_encoder: sampler_7: senselatch: srmod


Testing:

In the design review, someone raised the concern that the 2nd stage of gain in senselatch (sarmlatch) would latch before the 1st stage had a chance to latch. An offset voltage in the 2nd stage could exaccerbate this problem. The simulations below examine the issue.

For reference, here are links to the schematics shown above:

The nodes in the simulations of senselatch (the three stages above cascaded) below are named with a stage prefix (s1, s2, s3). For example, the node ap in sarmlatch (stage 1) would be s1_ap.

Below is the extraction technique I used to get accurate model (C within 0.1fF). Note that the accuracy is needed. When I tried these simulations with parasitic capacitances to within 1fF, I observed slightly different results and unusual behavior.

      in magic: extract do all
      in magic: extract
   commandline: ext2spice -c 0.1 filename.ext
   commandline: sed 's/fet/mos/g' filename.spice > filename.spi

Simulation 0 -- No Parasitic Capacitance:
s1_ap = 1.475V to 1.525V in 50 clock cycles (100ns), 0.5mv/ns (1mv/clock)
s1_an = 1.500V
Use layout netlist (senselatch_test.{mag, ext, spi} with all capacitor lines removed from .spi)

Simulation 1 -- Basic Performance:
s1_ap = 1.475V to 1.525V in 50 clock cycles (100ns), 0.5mv/ns (1mv/clock)
s1_an = 1.500V
Use layout netlist (senselatch_test.{mag, ext, spi}) with the capacitor lines included. (Compare with Simulation 0.)

Symmetry in senselatch_test.spi:

What is the origin of the asymmetry between Simulations 1 and 2? Specifically, why is there a -6mV offset for stage 1 in Simulation 2? The table below shows all of the parasitic capacitance lines from the spice file for senselatch (senselatch_test.spi). I sorted it by node and grouped by stage (s1 on the left, etc.). Note that in stage 1, there is total symmetry between the p and n sides for the inputs (s1_ap/s1_an). There is a slight asymmetry in for the integrating nodes of s1 (s1_bp/s1_bn) -- a little extra capacitance between s1_bn and all nodes compared with s1_bp and all nodes.

I manually changed the capacitance values for s1_bp/s1_bn so that they were pairwise equal and ran the simulation again. The -6mV voltage offset disappeared! I then tried changing the capacitance values one at a time, to see if one of them was critical, but it appears that they all matter, as one would expect. So, perhaps I should look for the asymmetry in layout and try to fix it?

Stage 1Stage 2Stage 3
s1_ap/s1_an (diff = 0.0fF)
namenode1node2capcap diff(p-n)
C41s1_apGND 0.8fF 0.0fF
C5s1_anGND 0.8fF
C79s1_apGND 2.2fF 0.0fF
C78s1_anGND 2.2fF
C14s1_aps1_tail 0.8fF 0.0fF
C58s1_ans1_tail 0.8fF

s1_bp/s1_bn (diff = -0.3fF)
namenode1node2capcap diff(p-n)
C73s1_bpGND 0.6fF 0.0fF
C33s1_bnGND 0.6fF
C82s1_bpGND 3.1fF +0.1fF
C81s1_bnGND 3.0fF
C49s1_bpVdd 2.2fF +0.3fF
C13s1_bnVdd 1.9fF
C72s1_bpclk 0.6fF -0.7fF
C34s1_bnclk 1.3fF
C43s1_bps1_tail 1.4fF 0.0fF
C6s1_bns1_tail 1.4fF
C32s1_bps1_ap 0.2fF +0.2fF (C42)
C42s1_bns1_an 0.2fF -0.2fF (C32)
C29s1_bps1_bn 0.3fF (cross term)

s1_xp/s1_xn (diff = -0.4fF)
namenode1node2capcap diff(p-n)
C67s1_xpGND 2.8fF +0.1fF
C28s1_xnGND 2.7fF
C89s1_xpGND10.6fF -0.4fF
C83s1_xnGND11.0fF
C40s1_xpVdd 6.8fF -0.5fF
C4s1_xnVdd 7.3fF
C66s1_xpclk 1.3fF +0.3fF
C27s1_xnclk 1.0fF
C56s1_xps1_bp 0.6fF -1.9fF
C19s1_xns1_bp 2.5fF
C20s1_xps1_bn 2.6fF +2.0fF
C65s1_xns1_bn 0.6fF
C12s1_xps1_xn12.4fF (cross term)
C10s1_xps2_bn 0.5fF -0.5fF (C75)
C75s1_xns2_bp 0.5fF +0.5fF (C10)

s1_tail (symmetric node)
namenode1node2capcap diff(p-n)
C50s1_tailclk 2.4fF (symmetric node)
C51s1_tailGND 2.5fF (symmetric node)
C77s1_tailGND 6.0fF (symmetric node)

s2_bp/s2_bn (diff = 0.0fF)
namenode1node2capcap diff(p-n)
C48s2_bpclk 0.6fF 0.0fF
C22s2_bnclk 0.6fF
C26s2_bpVdd 0.4fF 0.0fF
C3s2_bnVdd 0.4fF
C47s2_bpGND 0.8fF 0.0fF
C23s2_bnGND 0.8fF
C85s2_bpGND 1.5fF 0.0fF
C87s2_bnGND 1.5fF
C30s2_bps2_xp 0.4fF 0.0fF
C1s2_bns2_xn 0.4fF
C24s2_bps2_xn 0.2fF 0.0fF
C7s2_bns2_xp 0.2fF
C11s2_bns2_tail 0.6fF 0.0fF
C36s2_bps2_tail 0.6fF
C74s2_bns2_bp 0.1fF (cross term)

s2_xp/s2_xn (diff = -0.1fF)
namenode1node2capcap diff(p-n)
C39s2_xpVdd 3.6fF 0.0fF
C31s2_xnVdd 3.6fF
C61s2_xpGND 1.8fF -0.7fF
C53s2_xnGND 2.5fF
C92s2_xpGND 6.5fF +0.2fF
C95s2_xnGND 6.3fF
C62s2_xpclk 0.9fF +0.2fF
C54s2_xnclk 0.7fF
C25s2_xps3_q 0.7fF 0.0fF
C18s2_xns3_q 0.7fF
C63s2_xps3_qbar 0.7fF +0.3fF
C59s2_xns3_qbar 0.4fF
C71s2_xps3_s 0.5fF -0.1fF
C64s2_xns3_s 0.6fF
C17s2_xps3_r 0.5fF +0.1fF
C15s2_xns3_r 0.4fF
C37s2_xns2_xp 2.2fF (cross term)

s2_tail (symmetric node)
namenode1node2capcap diff(p-n)
C69s2_tailGND 1.1fF (symmetric node)
C86s2_tailGND 1.4fF (symmetric node)
C70s2_tailclk 0.4fF (symmetric node)

s3_r/s3_s(diff = -0.4fF)
namenode1node2capcap diff(p-n)
C94s3_rGND 2.6fF +0.1fF
C90s3_sGND 2.5fF
C35s3_rGND 0.8fF +0.1fF
C8s3_sGND 0.7fF
C16s3_rVdd 0.6fF 0.0fF
C68s3_sVdd 0.6fF
C2s3_rs3_q 0.5fF +0.1fF
C52s3_ss3_q 0.4fF
C38s3_rs3_qbar 0.4fF -0.2fF
C9s3_ss3_qbar 0.6fF
C46s3_rs3_s 1.9fF (cross term)

s3_q/s3_qbar (diff = -0.3fF)
namenode1node2capcap diff(p-n)
C21s3_qVdd 0.8fF 0.0fF
C60s3_qbarVdd 0.8fF
C44s3_qGND 1.4fF -0.4fF
C0s3_qbarGND 1.8fF
C91s3_qGND 2.5fF +0.1fF
C93s3_qbarGND 2.4fF
C45s3_qbars3_q 1.3fF (cross term)

clk/GND/Vdd
namenode1node2capcap diff(p-n)
C55VddGND59.9fF
C84VddGND61.4fF
C57clkVdd 7.0fF
C76clkGND 2.6fF
C88clkGND 9.2fF
C80GNDGND22.0fF

Simulation 2 -- Negative Offset Voltage:
s1_ap = 1.475V to 1.525V in 50 clock cycles (100ns), 0.5mv/ns (1mv/clock)
s1_an = 1.500V
Use layout netlist (senselatch_test2.spi) in which connections between s1_xn/s2_an and s1_xp/s2_ap were cut in layout and an offset voltage was inserted between the nodes as shown in the HSPICE lines below:

    voffsetp  s1_xp  s2_ap  -0.020
    voffsetn  s1_xn  s2_an  +0.020

Simulation 3: Positive Offset Voltage
s1_ap = 1.475V to 1.525V in 50 clock cycles (100ns), 0.5mv/ns (1mv/clock)
s1_an = 1.500V
Use layout netlist (senselatch_test2.spi) in which connections between s1_xn/s2_an and s1_xp/s2_ap were cut in layout and an offset voltage was inserted between the nodes as shown in the HSPICE lines below:

    voffsetp  s1_xp  s2_ap  +0.020
    voffsetn  s1_xn  s2_an  -0.020

Simulation 4: Add Capacitance to x2_bp
s1_ap = 1.475V to 1.525V in 50 clock cycles (100ns), 0.5mv/ns (1mv/clock)
s1_an = 1.500V
Use layout netlist (senselatch_test.spi)
Add 3fF between s2_bp and GND.
No offset voltages

Simulation 5: Add Capacitance to x2_bn
s1_ap = 1.475V to 1.525V in 50 clock cycles (100ns), 0.5mv/ns (1mv/clock)
s1_an = 1.500V
Use layout netlist (senselatch_test.spi)
Add 3fF between s2_bn and GND.
No offset voltages

Simulation 6: Add MORE Capacitance to x2_bn
s1_ap = 1.475V to 1.525V in 50 clock cycles (100ns), 0.5mv/ns (1mv/clock)
s1_an = 1.500V
Use layout netlist (senselatch_test.spi)
Add 10fF between s2_bn and GND.
No offset voltages

Simulation 7: Decrease Tail Transistor Size
s1_ap = 1.475V to 1.525V in 50 clock cycles (100ns), 0.5mv/ns (1mv/clock)
s1_an = 1.500V
Use layout netlist (senselatch_test3.spi)
change transistor size of tail transistor in stage2 (gate=ck, source=tail, drain=GND) to 6-lambda. The default size is 10-lambda.
no offset voltages

Simulation 8: Decrease Tail Transistor Size AND add 10fF to s2_bn
s1_ap = 1.475V to 1.525V in 50 clock cycles (100ns), 0.5mv/ns (1mv/clock)
s1_an = 1.500V
Use layout netlist (senselatch_test3.spi)
change transistor size of tail transistor in stage2 (gate=ck, source=tail, drain=GND) to 6-lambda. The default size is 10-lambda.
no offset voltages

sim9: add inverters between clocks, keep voffsets


Last updated: 12/01/2004
Back to main page