"===================================================================================================
#TITLE    'C&C, PLD1: A SIMPLE VME INTERFACE';
#ENGINEER 'Dominic A Hayes';
#COMPANY  'University College London';
#COMMENT  'Tidied version of PLD1';
"===================================================================================================
"     A simple D16:A24 VME SLAVE interface.
"     Not quite VME compliant as D8(EO) or D8(O) not catered for.
"
"          ***   USES EXTERNAL DATA LATCHES (74ALS996)  ***
"
" 01MAR99 now with added nstop_clk.  [100% of RDA (100% more than sugar puffs)] 
" 27OCT99  balb clocked by dl1 not dl0.
" 03NOV99   removed registering of wr and rd signals (previously clocked by ds and reset by /ds !).
"
"===================================================================================================
"                                        SIGNAL DECLARATIONS
"===================================================================================================
LOW_TRUE INPUT  lwordb;                   "Buffered VME signal.
LOW_TRUE INPUT  writeb;                   "Buffered VME Data Write.
LOW_TRUE INPUT  berrb;                    "Buffered VME Bus ERRor.
LOW_TRUE INPUT  ds0b, ds1b;               "Buffered VME Data Strobes.
LOW_TRUE INPUT  iackb;                    "Buffered VME Interupt ACKnowledge.
         INPUT  amb[5..0];                "Buffered VME Address Modifier (amb[2] not used).
         INPUT  alb[7..0];                "Buffered VME Low Address bus: addresses board's registers.
         INPUT  ahb[23..16];              "Buffered VME High Address bus: addresses board.
         INPUT  dl1;                      "delayed Data Strobe.
         INPUT  dl2;                      "delayed Data Strobe.
         INPUT  dl3;                      "delayed Data Strobe.
         INPUT  base_addr[23..16];        "selected base address from DIP(SY) switch (8bit address).

         NODE   ds;                       " - "OR'ed" ds0/1b.
         NODE   stam                      "STandard Address Modifier.
                   CLOCKED_BY dl1
                   RESET_BY /ds;          "Falling edge of ds (cycle finished).
         NODE   addr_OK                   "VME address = base address.
                   CLOCKED_BY dl1
                   RESET_BY /ds;
         NODE   balb[7..0]                "alb Latched.
                   CLOCKED_BY dl1
                   RESET_BY /ds;
         NODE   bdsel;                    "Board Select.

         OUTPUT dl0;                      " "OR'ed" ds0/1b, Data Strobe, to delay line.
         OUTPUT ack;                      "Data Transfer ACK (to external OC device).
LOW_TRUE OUTPUT oein, oeout;              "Output Enables for external data bus latches.
LOW_TRUE OUTPUT le1;                      "external latch clock (/LEAB = /LEBA).
LOW_TRUE OUTPUT nle1;                     "inverted le1.
LOW_TRUE OUTPUT le2;                      "external latch clock.
LOW_TRUE OUTPUT load;                     "external data latch signal.
LOW_TRUE OUTPUT errorled;                 "BERR when board addressed.
LOW_TRUE OUTPUT reg00, reg02, reg04, reg06, reg08, reg0A, reg0C, reg0E
                  DEFAULT_TO 0;
LOW_TRUE OUTPUT bwrite;                   "pld1 generated latched writeb.
LOW_TRUE OUTPUT bread;                    "pld1 generated ReaD signal to registers.
LOW_TRUE OUTPUT stop_clk;                 "input to PLD2, stop clocks when reg08 write accessed.
         OUTPUT nstop_clk;                "inverted stop_clk.

"===================================================================================================
"                                            EQUATIONS
"===================================================================================================
ds     = ds0b + ds1b;  " - OR'ed  Data Strobes
dl0    = ds;

balb   = alb;                       "Latched low address signals.
bwrite = writeb;                    "Latched writeb signal.
bread  = /writeb;                   "

stam   =  /iackb * /lwordb * amb[5] * amb[4] * amb[3] * amb[1] * /amb[0]      "STandard Address Modifier.
       +  /iackb * /lwordb * amb[5] * amb[4] * amb[3] * /amb[1] * amb[0];     "decodes  57/61 or 58/62.

IF (ahb[23..16] = base_addr) THEN   "====================
   addr_OK = 1;                     "Board address decode
ELSE                                "====================
   addr_OK = 0;
END IF;

bdsel  = stam * addr_OK;            "BoarD SELected when both VME addr and amb OK.

IF bdsel THEN
   CASE balb[7..1]
      WHEN 0 => reg00 = 1;          "=======================
      WHEN 1 => reg02 = 1;          "REGISTER ADDRESS DECODE
      WHEN 2 => reg04 = 1;          "=======================
      WHEN 3 => reg06 = 1;
      WHEN 4 => reg08 = 1;          "NB alb[0] not used.
      WHEN 5 => reg0A = 1;
      WHEN 6 => reg0C = 1;
      WHEN 7 => reg0E = 1;
   END CASE;
END IF;

le1      = bdsel * /dl2;
nle1     = /le1;
le2      = le1   * bwrite;
load     = dl3   * bwrite;
oein     = bdsel * bwrite;
oeout    = bdsel * bread * dl2;
errorled = berrb * addr_OK;
stop_clk = reg08 * bwrite;
nstop_clk= stop_clk;               "inversion done by LOW_TRUE statement.

ack      = (oein * dl2) + oeout;
"==================================================================================================
