
The address (NTA) decoder may be most conveniently implemented in
a PLA. The following is an example written in ABEL for a simple slave:
module NTA_DEC
title 'Address Decoder'
PLA1 device 'P16P8' ;
" Inputs
OA31,OA30 pin 1,2 ; " from OA on most-significant ADI
OA29_16 pin 3 ; " Wire-OR of OACA, OACB on most-significant ADI (with
" 10k pullup resistor to VCC. High when all of
" OA(29:16) are low.
OA15_8 pin 5 ; " from OACB of least-significant ADI (with pullup)
" High when all OA(15:8) are low
OA7_4 pin 6 ; " from OACA of least-significant ADI (with pullup)
" High when all OA(7:4) are low
OA3,OA2,OA1,OA0 pin 7,8,9,11 ; "from OA of least-significant ADI
OCND pin 13 ; " CSR/Not Dataspace from PCL
OUST pin 14 ; " User Strobe from PCL
ORD pin 15 ; " read line from PCL
" Outputs
MEMW pin 12 ; " negative-going Write pulse to user RAM
MEMR pin 16 ; " negative-going Read pulse to user RAM
IAC2,IAC1,IAC0 pin 17,18,19 ; " Address Code to PCL
IAC1 istype 'neg' ; IAC2, IAC0 istype 'pos' ;
MEMW, MEMR istype 'neg' ;
" Definitions
IAC = [IAC2..IAC0] ;
X=.X. ;
LOW256 macro { !OA31 & !OA30 & OA29_16 & OA15_8 } ; " lowest 256 locations
" selected
equations
truth_table ([LOW256,OA7_4,[OA3..OA0],OCND,OUST,ORD] -> [IAC,MEMW,MEMR])
[1,X,X,0,0,X] -> [1,1,1] ; " user RAM (addressed only) (dataspace)
[1,X,X,0,1,0] -> [1,0,1] ; " user RAM write
[1,X,X,0,1,1] -> [1,1,0] ; " user RAM read
[1,1,7,1,X,X] -> [7,1,1] ; " CSR #7
[1,1,3,1,X,X] -> [3,1,1] ; " CSR #3
[1,1,0,1,X,X] -> [0,1,1] ; " CSR #0
" all unimplemented locations should produce an IAC of 2
test_vectors
([OA31,OA30,OA29_16,OA15_8,OA7_4,OA3,OA2,OA1,OA0,OCND,OUST,ORD] ->
[MEMW,MEMR,IAC2,IAC1,IAC0])
" O O O O O O O O O O O O M M I I I
" A A A A A A A A A C U R E E A A A
" 3 3 2 1 7 3 2 1 0 N S D M M C C C
" 1 0 9 5 4 D T W R 2 1 0
" 1 8
" 6
[0,0,1,1,0,1,0,1,0,0,0,0] -> [1,1,0,0,1] ; " RAM address IAC=1 1
[0,0,1,1,1,0,1,0,1,0,0,1] -> [1,1,0,0,1] ; " RAM address IAC=1 2
[0,0,1,1,0,1,0,1,0,0,1,0] -> [0,1,0,0,1] ; " RAM write st IAC=1 3
[0,0,1,1,1,0,1,0,1,0,1,0] -> [0,1,0,0,1] ; " RAM write st IAC=1 4
[0,0,1,1,0,1,0,1,0,0,1,1] -> [1,0,0,0,1] ; " RAM read st IAC=1 5
[0,0,1,1,1,0,1,0,1,0,1,1] -> [1,0,0,0,1] ; " RAM read st IAC=1 6
[0,0,1,1,1,0,1,1,1,1,1,1] -> [1,1,1,1,1] ; " CSR#7 IAC=7 7
[0,0,1,1,1,0,1,1,1,1,0,0] -> [1,1,1,1,1] ; " CSR#7 IAC=7 8
[0,0,1,1,1,0,0,1,1,1,0,1] -> [1,1,0,1,1] ; " CSR#3 IAC=3 9
[0,0,1,1,1,0,0,1,1,1,1,1] -> [1,1,0,1,1] ; " CSR#3 IAC=3 10
[0,0,1,1,1,0,0,0,0,1,0,0] -> [1,1,0,0,0] ; " CSR#0 IAC=0 11
[0,0,1,1,1,0,0,0,0,1,1,0] -> [1,1,0,0,0] ; " CSR#0 IAC=0 12
[0,0,1,1,1,1,0,0,0,1,0,0] -> [1,1,0,1,0] ; " CSR#8 BAD IAC=2 13
[0,0,1,1,1,1,0,1,0,1,0,0] -> [1,1,0,1,0] ; " CSR#10 BAD IAC=2 14
[0,0,1,1,1,1,0,1,0,1,0,0] -> [1,1,0,1,0] ; " CSR#4 BAD IAC=2 15
[1,0,1,1,1,1,0,0,0,0,0,0] -> [1,1,0,1,0] ; " high dsp bad IAC=2 16
[0,1,1,1,1,1,0,0,0,1,0,0] -> [1,1,0,1,0] ; " user CSR bad IAC=2 17
end NTA_DEC
Note that use is made of the OACA, OACB outputs of the ADIs,
which reduce the number of input terms required in the PLA. A device with
programmable output polarity is used since it is convenient to set all
`unused' addresses to give IAC=2 (Bad Address).
