module P2064F title 'TCPIP-VME Interface' "Version 3: [31-JAN-08] Add hardware id and version read- "back. The hardware id is 64 for the 2064, and the version "number is 1 for the F-version, 0 being the A-version. declarations firmware_version_num=3; test_version=0; "set to 1 to compile the test code" "Rabbit Controller Module" !LNK pin 48; "ethernet link from rcm3200" !ACT pin 37; "ethernet active from rcm3200" !LED1..!LED4 pin 5..8; CSW pin 175; "configuration switch" "Test Pins" !TP1..!TP8 pin 9..12,14..17 istype 'com,pos'; "Control Address/Data from RCM" CA0..CA5 pin 62,63,60,61,58,59 istype 'com'; RCD0..RCD7 pin 49,50,36,52,51,54,53,57; !CDSIN pin 38; "control data strobe input" !CW pin 35; "control write" !RESET pin 161; "hardware reset" "VME Bus" VA1..VA31 pin 82,84,86,93,95,97,99,81,83,85,87,94,96,98,100,103,105,107, 109,112,114,116,118,77,76,75,74,73,72,71,70 istype 'com'; "vme address" !DS0,!DS1 pin 117,115 istype 'reg,pos'; "vme data strobes" !AS pin 80 istype 'reg,pos'; "vme address strobe" !LWORD pin 113; "vme longword" !IACK pin 111 istype 'pos,keep'; "vme interrupt acknowledge" VAM0..VAM5 pin 108,106,104,102,125,126 istype 'reg,keep'; "vme address modifier" !WRITE pin 127 istype 'com,keep'; "vme write" VD0..VD7 pin 145,141,140,139,138,137,136,135 istype 'com'; "vme data" !VDEN0..!VDEN1 pin 150,142 istype 'com'; "vme data enable" VDCK0..VDCK1 pin 149,147 istype 'com'; "vme data clock" VDIR pin 148 istype 'com'; "vme direction" "VME Address Buffers" !AB pin 123 istype 'com'; "select real time data transfer A->B" !BA pin 120 istype 'com'; "select real time data transfer B->A" ADIR pin 121 istype 'com'; "address buffer direction, assert for A->B" !OE pin 174; "buffer output enable" ACLKAB pin 124 istype 'com'; "clock data from A->B" ACLKBA pin 122 istype 'com'; "clock data from B->A" "Clock Bus" FCK pin 66; "fast clock (80 MHz) in from oscillator" CKOUT pin 64 istype 'com';"clock (80 MHz) out" CK pin 68; "clock (80 MHz) in from CKOUT" "Nodes" CDS node istype 'reg,keep'; "control data strobe" DBA0..DBA31 node istype 'reg,keep'; "slave driver base address" !LDA node istype 'com,keep'; "local data access" BAZ node istype 'com,keep'; "base address zero" RCMOE node istype 'com,keep'; "rcm data output enable" VA0 node istype 'com'; "vme address bit zero" VMEOE node istype 'com'; "vme data output enable" RPD0..RPD7 node istype 'reg'; "ram portal virtual data" RPDC node istype 'com'; "ram portal data clock" "Constants" id_addr=0; "hardware id location (byte)" hv_addr=18; "hardware version number location (byte)" fv_addr=19; "firmware version number location (byte)" cs_addr=40; "configuration switch address (byte)" dba_addr=42;"driver base address location (byte)" vam_addr=46;"vme addr modifier location (byte)" ram_portal_addr=63; "ram portal address location" hardware_id=64; "A2064 hardware identifier" hardware_version_num=1; "A2064F" "Sets" control_addr=[CA5..CA0]; "control address" driver_base_addr=[DBA31..DBA0]; "slave driver base address" vme_addr_modifier=[VAM5..VAM0]; "vme address modifier" dba0=[DBA7..DBA0]; "first byte of vme address" dba1=[DBA15..DBA8]; "second byte of vme address" dba2=[DBA23..DBA16]; "third byte of vme address" dba3=[DBA31..DBA24]; "fourth byte of vme address" vme_data=[VD7..VD0]; "vme data bus" rcm_data=[RCD0..RCD7]; "rcm interface data" ram_portal_data=[RPD7..RPD0]; "ram portal virtual data" equations "Clocks" "======" "CKOUT drives the CK global clock input." CKOUT=FCK; "Relay to Controller Interface" "=============================" "We synchronize the Relay data strobe, which is K1, to CK." CDS.clk=CK; CDS:=CDSIN; "We drive the RCM data lines on any Control Interface read." RCMOE = !CW & CDS; rcm_data.oe = RCMOE; "The rcm_data is equal to the vme_data only when the master is" "communicating with a slave." when CDS & !CW & !LDA then rcm_data=vme_data.pin; "We drive the VME data lines on any Control Interface write." VMEOE = CW & CDS; vme_data.oe=VMEOE; when CW then vme_data=rcm_data.pin; "VME Interface Configuration" "===========================" "We arrange the bytes of the VME Base Address in little-endian order" "within the Controller's address space." driver_base_addr.clk=CK; driver_base_addr.aclr=RESET; when CDS & CW & (control_addr==dba_addr+3) then dba0:=rcm_data.pin; else dba0:=dba0.fb; when CDS & CW & (control_addr==dba_addr+2) then dba1:=rcm_data.pin; else dba1:=dba1.fb; when CDS & CW & (control_addr==dba_addr+1) then dba2:=rcm_data.pin; else dba2:=dba2.fb; when CDS & CW & (control_addr==dba_addr+0) then dba3:=rcm_data.pin; else dba3:=dba3.fb; vme_addr_modifier.clk=CK; when RESET then vme_addr_modifier:=^h3D else { when CDS & CW & (control_addr==vam_addr) then vme_addr_modifier:=[RCD5..RCD0].pin; else vme_addr_modifier:=vme_addr_modifier; } "Base address zero helps our logic compiler." BAZ = (driver_base_addr==0); "We access local data when the driver base address is zero," "or we write to the driver base address or the vme modifier." LDA = BAZ # (control_addr==dba_addr+3) # (control_addr==dba_addr+2) # (control_addr==dba_addr+1) # (control_addr==dba_addr+0) # (control_addr==vam_addr); "Here we compute the VME address from the RCM3200 interface" "address and the drier base address." [VA31..VA1]=[DBA31..DBA6,CA5..CA1]; "VME Address Buffers" "===================" "VME Address buffers are set to place the address bits onto" "the VME backplane in realtime and function as outputs only." "A is the output from this chip, B is the address on the" "backplane." OE=1; "enable buffer outputs" ADIR=1; "set buffer direction A->B" AB=1; "enable realtime operation A->B" BA=1; "enable realtime operation B->A" ACLKAB=0; "never clock data A->B" ACLKBA=0; "never clock data B->A" "VME Data Buffers" "===============" LWORD=0; IACK=0; VDIR=CW; WRITE=CW; VA0=CA0; VDEN0=DS0; VDEN1=DS1; VDCK0=DS0; VDCK1=DS1; [DS0,DS1,AS].clk=CK; when CDS & !LDA then { DS0:=VA0; DS1:=!VA0; AS:=1; } "Readback Registers" "=================" when CDS & !CW & LDA & (control_addr==cs_addr) then rcm_data=[0,0,0,0,0,0,0,!CSW]; when CDS & !CW & LDA & (control_addr==fv_addr) then rcm_data=firmware_version_num; when CDS & !CW & LDA & (control_addr==id_addr) then rcm_data=hardware_id; when CDS & !CW & LDA & (control_addr==hv_addr) then rcm_data=hardware_version_num; "The local ram portal provides virtual data for" "a local ram portal. Every time we read from the" "local ram portal at address ram_portal_addr, the" "data increments by one." RPDC = CDS & !CW & LDA & (control_addr==ram_portal_addr); ram_portal_data.aclr = RESET; ram_portal_data.clk = RPDC; ram_portal_data := ram_portal_data + 1; when RPDC then rcm_data=ram_portal_data; "LEDs" "====" "The LEDs provide diagnostic signals. The test point" "LEDs have pins on the board you can use with a scope" "probe." when (!CSW # !RESET) & (test_version!=1) then { LED1 = 1; LED2 = LNK; LED3 = ACT; LED4 = !LDA; TP1 = CSW; TP2 = VD0; TP3 = RCD0; TP4 = WRITE; TP5 = CDS; TP6 = DS0 # DS1; TP7 = CDS & !CW & (control_addr==ram_portal_addr); TP8 = CDS & CW & (control_addr==ram_portal_addr); } declarations T24..T0 node istype 'reg'; "timer" timer=[T24..T0]; "timer" countbits=[T24..T21]; "top timer bits" equations "The test firmware creates a moving spot of light" "on the front panel LEDs. The spot changes direction" "when you press the configuration switch, and stops" "when you press reset." "Because this timer just counts up, we can define it" "as one counter and trust that the compiler will figure" "out that it can impement the counter with T-type" "flip-flops and no fancy logic." timer.clk=CK; timer.aclr=RESET; timer:=timer+1; "We use the counter top four bits to drive the LEDs." when !CSW & (test_version==1) then { LED1=(countbits==15); LED2=(countbits==14); LED3=(countbits==13); LED4=(countbits==12); TP1=(countbits==11); TP2=(countbits==10); TP3=(countbits==9); TP4=(countbits==8); TP5=(countbits==7); TP6=(countbits==6); TP7=(countbits==5); TP8=(countbits==4); } "We change direction when we press the CSW switch." when CSW & (test_version==1) then { LED1=(countbits==4); LED2=(countbits==5); LED3=(countbits==6); LED4=(countbits==7); TP1=(countbits==8); TP2=(countbits==9); TP3=(countbits==10); TP4=(countbits==11); TP5=(countbits==12); TP6=(countbits==13); TP7=(countbits==14); TP8=(countbits==15); } end