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).