"
module P2075A

title 'P2075A'

"Version 6"

"[01-MAY-15] We use the test points to connect to pin 11 of the FLEX"
"cable to control a transistor on a custom minimal head.  This controls"
"LEDs acting as a source (device type 6) on the minimal head."
"This version is for use in the 'fiber optic plate' setup."

"Version 5"

"[04-MAR-13] We correct the CCD selection for the A3025A. Now we have"
"the rear-facing camera being selected when the CCD1 bit is set."

"Version 4" 

"[01-FEB-13] We add support for six sources and two image sensors."
"We apply these new outputs in the A3025A BCAM Head. In order to fit"
"the added gates into the logic chip we remove the # RST term from"
"the asynchronous clear of both ring oscillators."

"Version 3"

"[21-JUN-12] We re-write the command and address receiver so that it no"
"longer runs on CK, but rather is clocked by various signals like AA"
"and CA, which is more similar to the implementation in VHC logic of"
"circuits like the A2036. The result is a more efficient and simpler"
"system."

"We use a second ring oscillator to generate the timing for the horzontal"
"clock pulses. This oscillator runs only shen the DC2 bit is set and when"
"we see a falling edge on A."

"The resulting circuit has a quiescent current of 2 mA (not counting the"
"current flowing in the 100-ohm LVDS terminating resistance). Of this,"
"almost all is used by the LVDS chip."

"Version 2"

"[14-JUN-12] Make sure all logic chip outputs to the level-shifting op-amps"
"are LO when the board is asleep. This avoids 40 mA of current flowing out"
"of the logic chip into the un-powered op-amps during sleep."

"One in ten times we plug the circuit into the LWDAQ during live acquisition,"
"This turns out to be the ring oscillator getting into a double-frequency mode"
"so that the timing of decoding the incoming command is all wrong. We fix this"
"by allowing the oscillator to run only after a rising edge of A for long enough"
"to generate DA and DDA. This same precaution serves to decrease the quiescent"
"current from 7 ma to 2 mA (from 5 V)."


"Loop back did not work on long cables because the negative pulse on A was too"
"short to be picked up by the synchronising clock in the logic. So we now run"
"the DA and DDA timer with the help of the RUN flag. Loopback is now reliable."

"We still get bad images over an 80-m cable."


"Version 1"

"[08-MAR-12] Choose command allocations for ICX424 and ICX424Q devices. Device"
"supports single and quadruple pixel readout. Quadruple pixel readout requiers"
"the driver to transfer two rows at a time into the output register, and to set"
"the DC16 bit for the device. With DC16, the device transfers two columns at a"
"time into the output gate, so as to produce a quadruple pixel."


declarations

"Constants"
da_delay = 7; "CK periods to DA"
dda_delay = 16; "CK periods to DDA"
run_time = dda_delay+3; "CK periods to run"
hbcam = 1; 

"Inputs"
A pin 2; "LVDS Input"
!RST pin 24;"Power-Up Reset"

"Outputs"
LB pin 3 istype 'com'; "Loop Back"			
WAKE pin 14 istype 'com'; "Wake"
TP1,TP2 pin 47,48 istype 'com';
!V1,!V2,!V3 pin 27,31,32 istype 'com'; "Vertical Clocks"
RDP pin 28 istype 'com'; "Read Pulse"
H1,H2 pin 39,38 istype 'com'; "Horizontal Clocks"
S1,S2 pin 23,22 istype 'com'; "Substrate Clocks"
R pin 26 istype 'com'; "Reset Clock"
!CCD1 pin 33 istype 'com';
ON1..ON6 pin 16, 46, 9, 10, 20, 8 istype 'com'; 

"Command Receiver Nodes"
SA node istype 'reg'; "Synchronized A"
DSA node istype 'reg'; "Delayed SA"
DA node istype 'reg'; "Delayed A Rising Edge"
DDA node istype 'reg'; "Delayed DA"
AA node istype 'reg'; "Address Active"
CA node istype 'reg'; "Command Active"
ER,Q1..Q16 node istype 'reg'; "Receiver Bits"
LT4..LT0 node istype 'reg'; "LWDAQ Timer"
lt = [LT4..LT0];
DS node istype 'com'; "Data Strobe"
DC1..DC16 node istype 'reg';"Device Command Bits"
DA0..DA15 node istype 'reg';"Device Address Bits"

"Ring Oscillator Notes"
RO1,RO2 node istype 'com,keep'; "Ring Oscillator"
CK node istype 'reg,keep'; "Clock"
RUN node istype 'reg,keep';
equations 


"Clock Generation"
"----------------"

"The RUN flag controls the ring oscillator. When the ring"
"oscillator runs, it causes lt to increment. When lt reaches"
"a threshold, we clear the RUN flag."
RUN.aclr = (lt == run_time);
RUN := 1;
RUN.clk = A;

"Here we generate our clock with a ring oscillator."
"The ring oscillator consists of two combinatorial gates."
RO1 = RO2;
RO2 = !RO1 & RUN;
CK.clk = RO1;
CK:=!CK;


"Command and Address Decoding"
"----------------------------"

"This LWDAQ receiver uses the 40-MHz data clock to generate"
"the DA and DDA signals. We synchronise the incoming serial"
"logic signal, A, with the data clock."


"We synchronize A with DCK, and provide a delayed"
"version of A that allows us to detect edges."
[SA,DSA].clk = CK;
[SA,DSA].aclr = RST;
SA := A;
DSA := SA;

"This timer allows us to generate the Delayed A (DA)"
"and Double-Delayed A (DDA) signals for serial reception."
lt.clk = CK;
lt.aclr = !RUN;
lt := lt+1;
DA.clk = !CK;
DA.aclr = RST;
DA := (lt==da_delay);
DDA.clk = !CK;
DDA.aclr = RST;
DDA := (lt==dda_delay);

"The command or address bits enter a sixteen-bit shift register."
[ER,Q1..Q16].clk = DA;
[ER,Q1..Q16].aclr = RST;
[ER,Q1..Q16] := [SA,ER,Q1..Q15];

"Address Active, or AA, provides a pulse that begins with DDA"
"on the start bit of an address transmission, and ends with DDA"
"on the stop bit of an address transmission. We clock the receiver"
"bits into the address register on a rising edge of AS."
AA.clk = DDA;
AA := (!AA & !CA & !SA & !ER) # (AA & !SA);
[DA0..DA15].clk = !AA;
[DA0..DA15].aclr = RST;
[DA0..DA15] := [Q1..Q16];

"Command Active, or CA, provides a pulse that begins with DDA"
"on the start bit of a command transmission, and ends with DDA"
"on the stop bit of a command transmission. We clock the receiver"
"bits into the command register on a rising edge of CS."
CA.clk = DDA;
CA := (!AA & !CA & !SA & ER) # (CA & !SA);
[DC1..DC16].clk = !CA;
[DC1..DC16].aclr = RST;
[DC1..DC16] := [Q1..Q16];

"Data Strobe identifies a solitary low pulse on A. A"
"solitary low pulse, combined with DTX, indicates that"
"the drivers is expecting this device to upload eight"
"bits of data."
DS = DDA & SA & !AA & !CA;


"Command Bit Allocation"
"----------------------"

"WAKE bit."
WAKE = DC8;

"We enable the return LVDS driver when DC7 is set."
LB = DC7;

"The read pulse, substrate clock, and vertical phases"
"we receive directly from the driver in the command bits."
"When the board is asleep, however, we must make sure that"
"all the logic chip outputs are 0V, to avoid driving curren"
"into the level-shifting op-amp inputs."
RDP = DC1 & WAKE;
S1 = DC6 & WAKE;
S2 = !DC6 & WAKE;
V3 = DC5 # !WAKE;
V2 = DC4 # !WAKE;
V1 = DC3 # !WAKE;

declarations
H node istype 'com';
HCS0..HCS3 node istype 'reg';
hcs=[HCS3..HCS0];
HRO1,HRO2 node istype 'com,keep';
HCK node istype 'reg';
HRUN node istype 'reg';
equations

"The Horizontal Ring Osicllator provides timing for the horizontal"
"clock of the image sensor. We use the same system we use for the"
"main ring oscillator. Here we start the ring when DC2 is set and
"we see a falling edge on A."
HRUN.aclr = (hcs == 12);
HRUN := 1;
HRUN.clk = !A & DC2;
HRO1 = HRO2;
HRO2 = !HRO1 & HRUN;
HCK.clk = HRO1;
HCK := !HCK;

"The Horizontal Clock state machine provides the timing we need"
"to generate the horizontal clock pulses and reset pulse."
hcs.clk = HCK;
hcs.aclr = !HRUN;
hcs := hcs+1;

"The H bit controls the horizontal clock phases. When DC2 is unasserted, we"
"always assert H, which drives H1 lo and H2 hi. This is the state we are in"
"during vertical transfer. But once DC2 goes hi, in preparation for horizontal"
"transfer, H will be unasserted for a while, until the first negative pulse on"
"SA clocks the first pixel into the output gate."
H = !DC2 
  # (hcs==1) 
  # ((hcs==2)&!DC16) 
  # (hcs==3)
  # (hcs==4)
  # (hcs==5)
  # (hcs==6)
  # (hcs==7);

"When we create the horizontal clock outputs, we make sure they are 0V when"
"the board is alseep."
H2 = H & WAKE;
H1 = !H & WAKE;

"The reset pulse follows the horizontal clock pulse.
R = ((hcs==8) # (hcs==9)) & WAKE;


when hbcam then {
  CCD1 = DC9;
  ON1 = DC10;
  ON2 = DC11;

}

"Test Points"
"-----------"

TP1 = DC10;
TP2 = DC11;

end