"
module P3007C title 'P3007C' "Verion 1, Last modified 20-DEC-07" "Version 1 is based upon P3007C04." declarations firmware_version=4; fake_data=0; equations "Pins" declarations A pin 3; "LVDS input" B pin 10 istype 'com'; "LVDS output" LB pin 8 istype 'com'; "Loop Back" RCK pin 38; "Reference Clock, 32.768 kHz" MCK pin 39; "Master Clock, 80 MHz" !RESET pin 22;"Hardware Reset" !RW pin 59 istype 'com'; "RAM Write" !RCE pin 66 istype 'reg'; "RAM Chip Enable" !ROE pin 6 istype 'com'; "RAM Output Enable" RA18..RA0 pin 85,80,79,78,16,17,19,31,30,53, 54,55,56,58,67,69,70,71,72 istype 'reg'; "RAM Address" ram_addr = [RA18..RA0]; RD7..RD0 pin 9,11,14,15,60,61,64,65 istype 'com'; "RAM Data" ram_data = [RD7..RD0]; RECORD pin 97 istype 'reg'; "Record Indicator, through monostable" UPLOAD pin 94 istype 'com'; "Upload Indicator, through monostable" EMPTY pin 98 istype 'com'; "Empty Indicator, direct to LED" TP1 pin 47 istype 'com'; "Test Point 7" TP2 pin 48 istype 'com'; "Test Point 8" equations "Data Clock Generation" "---------------------" declarations DCK node istype 'reg'; "Data Clock" equations DCK.clk=MCK; DCK:=!DCK; "Reference Clock" "---------------" "LWDAQ 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." declarations SA node istype 'reg'; "Synchronized A" DSA node istype 'reg'; "Delayed SA" DA node istype 'com,keep'; "Delayed A Rising Edge" DDA node istype 'com,keep'; "Delayed DA" AA node istype 'reg'; "Address Active" DAA node istype 'reg'; "Delayed AA" CA node istype 'reg'; "Command Active" DCA node istype 'reg'; "Delayed CA" ER,Q1..Q16 node istype 'reg'; "Receiver Bits" LT3..LT0 node istype 'reg'; "LWDAQ Timer" lt = [LT3..LT0]; AS node istype 'reg'; "Address Strobe" CS node istype 'reg'; "Command Strobe" DS node istype 'reg'; "Data Strobe" DC1..DC16 node istype 'reg';"Device Command Bits" DA0..DA15 node istype 'reg';"Device Address Bits" WAKE node istype 'com'; "Wake" DTX node istype 'com'; "Device Transmit" RAR node istype 'com'; "RAM Address Reset" equations "We synchronize A with DCK, and provide a delayed" "version of A that allows us to detect edges." [SA,DSA].clk = DCK; [SA,DSA].aclr = RESET; 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 = DCK; lt.aclr = RESET; when lt==0 then { when SA & !DSA then lt:=1 else lt:=0; } else { when lt==9 then lt:=0 else lt:=lt+1; } DA = (lt==4); DDA = (lt==9); "We use DCK to clock the receiver registers, and RESET to" "clear them." [ER,Q1..Q16,AA,DAA,AS,CA,DCA,CS,DS,DC1..DC16,DA0..DA15].clk = DCK; [ER,Q1..Q16,AA,DAA,AS,CA,DCA,CS,DS,DC1..DC16,DA0..DA15].aclr = RESET; "We move bits along the shift register on DA." when DA then [ER,Q1..Q16] := [SA,ER,Q1..Q15]; else [ER,Q1..Q16] := [ER,Q1..Q16]; "Address Active provides a pulse that begins with DDA" "on the start bit of an address transmission, and ends" "with the stop bit of an address transmission. Delayed" "AA allows us to create Address Strobe, or AS. Address" "Strobe provides a pulse at the end of an address" "reception. We clock the receiver bits into the address" "register on a rusing edge of AS." when DDA then AA := (!AA & !CA & !SA & !ER) # (AA & !SA) else AA := AA; DAA := AA; AS := DAA & !AA; when AS then [DA0..DA15] := [Q1..Q16] else [DA0..DA15] := [DA0..DA15]; "Command Active provides a pulse that begins with DDA" "on the start bit of a command transmission, and ends" "with the stop bit of a command transmission. Delayed" "CA allows us to create Command Strobe, or CS. Command" "strobe provides a pulse at the end of each command" "reception. We clock the receiver bits into the command" "register on a rusing edge of CS." when DDA then CA := (!AA & !CA & !SA & ER) # (CA & !SA) else CA := CA; DCA := CA; CS := DCA & !CA; when CS then [DC1..DC16] := [Q1..Q16] else [DC1..DC16] := [DC1..DC16]; "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; "RAM Address Reset" RAR = DC1 # RESET; "Device Transmit Bit" DTX = DC5; "We loop back A to B so long as DTX is not set." when !DTX then B = A; "We enable the return LVDS driver when DC7 is set." LB = DC7; "WAKE bit." WAKE = DC8; "Data Transmitter" "----------------" "The transmitter sends bytes back to the driver. It waits for" "DS combined with DTX (DC5). When it receives DS and DTX, it" "waits for Transmission Byte Load (TBL). The transmitter uses" "DCK to time its serial transmission to the driver. It transmits" "a leading zero followed by the eight bits of the transmission" "byte (tb)." declarations TS4..TS0 node istype 'reg'; "Transmit State" TB7..TB0 node istype 'reg'; "Transmission Bits" ts=[TS4..TS0];"Transmission State" tb=[TB7..TB0]; "Transmission Byte" TBL node istype 'reg'; "Transmitter Byte Load" TBO node istype 'com,keep'; "Transmitter Bit Out" TBFD1,TBFD0 node istype 'reg'; "TB Fake Data Counter" tbfd=[TBFD1,TBFD0]; equations "We assert Transmit Byte Load, TBL, elsewhere in the code" "when we want to clock ram_data.pin into the Transmit Byte." TBL.clk = DCK; TBL.aclr = RESET; "The Transmit Byte, tb, holds a byte for transmission to" "the LWDAQ driver." tb.clk = DCK; tb.aclr = RESET; "The Transmitter State, ts, controls serial transmission" "to the LWDAQ driver of the Transmi Byte." ts.clk = DCK; ts.aclr = RESET; state_diagram ts; state 0:if DS & DTX then 1 else 0; state 1: if !DTX then 0; if DTX & TBL then 2; if DTX & !TBL then 1; state 2:goto 3;"Start Bit" state 3:goto 4;"Start Bit" state 4:goto 5;"TB7" state 5:goto 6;"TB7" state 6:goto 7; state 7:goto 8; state 8:goto 9; state 9:goto 10; state 10:goto 11; state 11:goto 12; state 12:goto 13; state 13:goto 14; state 14:goto 15; state 15:goto 16; state 16:goto 17; state 17:goto 18; state 18:goto 19;"TB0" state 19:goto 20;"TB0" state 20:goto 0;"Stop Bit" equations; "TBO is the output of the bit transmitter. It passes through" "the LVDS return and so along the cables to the driver." TBO = ( (ts==0) & 1 "Idle Bit 1" # (ts==1) & 1 "Idle Bit 1" # (ts==2) & 0 # (ts==3) & 0 # (ts==4) & TB7 # (ts==5) & TB7 # (ts==6) & TB6 # (ts==7) & TB6 # (ts==8) & TB5 # (ts==9) & TB5 # (ts==10) & TB4 # (ts==11) & TB4 # (ts==12) & TB3 # (ts==13) & TB3 # (ts==14) & TB2 # (ts==15) & TB2 # (ts==16) & TB1 # (ts==17) & TB1 # (ts==18) & TB0 # (ts==19) & TB0 # (ts==20) & 1 "Stop Bit 1" ); "We return TBO to the driver when DTX is set." when DTX then B = TBO; "We load the transmitter byte from the RAM data bus. When" "some other part of the firmware asserts TBL." when !fake_data then { tb.clk = DCK; tb.aclr = RESET; when TBL then tb:=ram_data.pin; else tb:=tb; } "We can generate fake data to check for errors in the" "upload to the LWDAQ driver, as opposed to errors in" "RF reception. The Recorder instrument will interpret" "the fake data as a time stamp." tbfd.clk=DCK; tbfd.aclr=RESET; when fake_data then { TBL=1; when (ts==20) then tbfd:=tbfd+1 else tbfd:=tbfd; when (tbfd==0) then tb:=^h05; when (tbfd==1) then tb:=^hAA; when (tbfd==2) then tb:=^hFF; when (tbfd==3) then tb:=^d0; } "Address Counters" "----------------" declarations RAI node istype 'reg'; "Data Address Increment" equations "The data address is the RAM address at which we write" "or read bytes." ram_addr.clk = DCK; ram_addr.aclr = RAR; RAI.clk = DCK; when RAI then { ram_addr:=ram_addr+1; } else { ram_addr:=ram_addr; } "RAM Controller" "--------------" declarations RDOE node istype 'com'; "RAM Data Output Enable (from this chip)" RCS4..RCS0 node istype 'reg'; "Ram Controller State" rcs=[RCS4..RCS0]; equations "The RAM Controller records incoming ADC data in RAM and" "reads stored ADC data out of RAM. It receives data from" "the ADC Receiver and transmits data to the LWDAQ interface." "When the A2100 is recording data in RAM, the RAM Controller" "answers any reads by the LWDAQ interface with byte value" "255." rcs.clk = DCK; rcs.aclr = RESET; state_diagram rcs; state 0: if (ts==1) then 1 else 0; state 1:goto 2; "load transmit byte" state 2:goto 0; "increment data address" state 3:goto 4; "store sample ID" state 4:goto 5; "increment data address" state 5:goto 6; "store high sample byte" state 6:goto 7; "increment data address" state 7:goto 8; "store middle sample byte" state 8:goto 9; "increment data address" state 9:goto 10; "store low sample byte" state 10:goto 0; "increment data address" equations ram_data.oe = RDOE; RCE.clk = DCK; when (rcs==0) then { ram_data = 0; RW = 1; ROE = 0; RCE := 0; RAI := 0; TBL := 0; RDOE = 1; } when (rcs==1) then { ram_data = 0; RW = 0; ROE = 1; RCE := 1; RAI := 0; TBL := 1; RDOE = 0; } when (rcs==2) then { ram_data = 0; RW = 0; ROE = 1; RCE := 0; RAI := 1; TBL := 0; RDOE = 0; } when (rcs==3) then { ram_data = 0; RW = 1; ROE = 0; RCE := 1; RAI := 1; TBL := 0; RDOE = 1; } when (rcs==4) then { ram_data = 0; RW = 1; ROE = 0; RCE := 1; RAI := 0; TBL := 0; RDOE = 1; } when (rcs==5) then { ram_data = [0,0,0,0,0,RA18,RA17,RA16]; RW = 1; ROE = 0; RCE := 1; RAI := 1; TBL := 0; RDOE = 1; } when (rcs==6) then { ram_data = [0,0,0,0,0,RA18,RA17,RA16]; RW = 1; ROE = 0; RCE := 0; RAI := 0; TBL := 0; RDOE = 1; } when (rcs==7) then { ram_data = [RA15..RA8]; RW = 1; ROE = 0; RCE := 1; RAI := 1; TBL := 0; RDOE = 1; } when (rcs==8) then { ram_data = [RA15..RA8]; RW = 1; ROE = 0; RCE := 0; RAI := 0; TBL := 0; RDOE = 1; } when (rcs==9) then { ram_data = [RA7..RA0]; RW = 1; ROE = 0; RCE := 1; RAI := 1; TBL := 0; RDOE = 1; } when (rcs==10) then { ram_data = [RA7..RA0]; RW = 1; ROE = 0; RCE := 0; RAI := 0; TBL := 0; RDOE = 1; } "Indicators Lamps" RECORD.clk = DCK; RECORD := (rcs==10); UPLOAD = DS; EMPTY = (ram_addr==0); "Test Points" end