"
module P2086A

title 'P2086A'

"Version 1: [30-JAN-18] Based on P302501A. We eliminate the ON5 and ON6 signals used on the A3025 to"
"drive the two LED arrays. Instead of !CCD1 we have CCD1 and CCD2 to close the two analog switches"
"made by U5 and U6 respectively. There is no power-up reset: we rely upon the internal reset of the"
"LC4064ZE. We use Q16 for PXBN instead of DC16 so as to free up one logic output, which we need to"
"drive B with A. We add TP3 to the design, but we cannot run a signal through it without adding another:"
"output to the design. Meanwhile, removeing the TP1 and TP2 outputs DA and DDA does not free up any"
"further outputs."

"Version 2: [01-FEB-18] Restore DC16 as PXBN and remove loopback B = A, instead wire A to B on"
"the circuit itself."

declarations

"Constants"
da_delay = 9; "CK periods to DA"
dda_delay = 18; "CK periods to DDA"
run_time = dda_delay+3; "CK periods to run"

"Inputs"
A pin 33; "LVDS Input"

"Outputs"
B pin 28 istype 'com'; "LVDS output"
LB pin 24 istype 'com'; "Loop Back"			
WAKE pin 45 istype 'com'; "Wake"
TP1,TP2,TP3 pin 32,9,46 istype 'com';
!V1,!V2,!V3 pin 10,2,40 istype 'com'; "Vertical Clocks"
RDP pin 38 istype 'com'; "Read Pulse"
H1,H2 pin 26,27 istype 'com'; "Horizontal Clocks"
S1,S2 pin 34,31 istype 'com'; "Substrate Clocks, called S and !S on schematic."
R pin 39 istype 'com'; "Reset Clock"
CCD1,CCD2 pin 8,7 istype 'com';
L1..L4 pin 14,23,4,3 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."

"The outgoing logic is used only for loop-back."
"B = A;

"We synchronize A with DCK, and provide a delayed"
"version of A that allows us to detect edges."
[SA,DSA].clk = CK;
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 := (lt==da_delay);
DDA.clk = !CK;
DDA := (lt==dda_delay);

"The command or address bits enter a sixteen-bit shift register."
[ER,Q1..Q16].clk = DA;
[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] := [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] := [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. The DC16 bit is PXBN, which"
"bins four pixels together. Here we bin two horizontal neighbors together with"
"an extra H pulse. We don't use DC16, but Q16 instead, to free one logic cell"
"so this code will fit in the LC4064. Q16 won't be changing during the direct"
"clocking of H by rising edges on A, because direct clocking consists only of"
"the transmission of stop bits."
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;

"Select one of the image sensors using analog switches."
CCD1 = DC9;
CCD2 = !DC9;

"Turn on one or more lasers."
L1 = DC10;
L2 = DC11;
L3 = DC12;
L4 = DC13;


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

TP1 = DA;
TP2 = DDA;
"TP3 = CK;

end