“…พร้อมทั้งขาที่อยู่ ข้อมูล และสัญญาณที่เกี่ยวข้องมาทั้งหมด” — ประโยคนี้แปลว่า กรรมการตรวจจะไล่นับว่ามี address bus, data bus และ control signal ครบไหม ไม่ได้ดูแค่ว่ากล่องวางสวยหรือเปล่า
Z80 เป็น DIP 40 ขา แบ่งได้ 6 กลุ่ม กดที่ชื่อขาเพื่อดูว่าแต่ละขาทำอะไร และมีจุดไหนที่คนมักเข้าใจผิด
ชิปหน่วยความจำทุกตัว ไม่ว่าจะ ROM หรือ RAM ยี่ห้อไหน ขนาดเท่าไร มีขาแค่ 4 กลุ่มเหมือนกันหมด — ดูภาพนี้แล้วจะเห็นว่าแต่ละกลุ่มทำอะไร
ROM ย่อมาจาก Read Only Memory — “หน่วยความจำอ่านอย่างเดียว” ชื่อบอกตรงตัวเลย คือเขียนไม่ได้ จึงไม่มีขา WE ติดมาตั้งแต่โรงงาน ไม่ใช่ว่าเราไม่ได้ต่อ — คือมันไม่มีขานั้นอยู่บนตัวชิปเลย (ลองดูผังขาของ 2732 ด้านล่างเทียบกับ 6116 ได้)
| ROM / EPROM | RAM / RWM | |
|---|---|---|
| ชื่อเต็ม | Read Only Memory | Random Access Memory (อาจารย์เรียก RWM = Read/Write Memory) |
| ขาที่มี | A, D, CE, OE | A, D, CE, OE, WE |
| CPU เขียนได้ไหม | ไม่ได้ | ได้ |
| ไฟดับแล้วข้อมูล | ยังอยู่ (non-volatile) | หายหมด (volatile) |
| ใช้เก็บอะไร | โปรแกรม, ตารางค่าคงที่, ข้อความ — ของที่ต้องอยู่ตอนเปิดเครื่อง | ตัวแปร, stack, buffer — ของที่เปลี่ยนไปมาระหว่างทำงาน |
| วางที่ไหนในแผนที่ | 0000H (เพราะ reset แล้ว PC = 0000H) | ที่ไหนก็ได้ที่ไม่ชนกัน |
LD A, 55H
LD (0500H), A ; 0500H อยู่ในช่วง ROM
ไม่มีอะไรเกิดขึ้นเลย — CPU ทำ Memory Write cycle ตามปกติ วาง address และ data ลงบัส ดึง MEMWR ลง แต่ไม่มีใครรับ เพราะ ROM ไม่มีขาที่จะรับคำสั่งเขียน ข้อมูลก็หายไปเฉย ๆ
ที่อันตรายคือ CPU ไม่รู้ตัว — ไม่มี error ไม่มี exception โปรแกรมเดินต่อเหมือนไม่มีอะไรเกิดขึ้น พอไปอ่านกลับมาก็ได้ค่าเดิมใน ROM ⇒ บั๊กแบบนี้หายาก · เวลาเขียนโปรแกรมจึงต้องรู้แผนที่หน่วยความจำของตัวเองให้แม่น
เขียนด้วย CPU ไม่ได้ แต่เขียนด้วยเครื่องโปรแกรมเมอร์แยกต่างหากได้ — ต้องถอดชิปออกจากวงจรไปเสียบเครื่อง แล้วจ่ายไฟพิเศษที่ขา VPP (12.5V ถึง 25V แล้วแต่รุ่น สูงกว่าไฟเลี้ยงปกติ 5V) — นี่คือเหตุผลที่ 2716 ถึงมีขา VPP แยกออกมา
| ชนิด | เขียนยังไง | ลบยังไง |
|---|---|---|
| Mask ROM | โรงงานทำมาตอนผลิตชิป | ลบไม่ได้เลย |
| PROM | เผาฟิวส์ครั้งเดียว | ลบไม่ได้ (OTP) |
| EPROM (2716–27256) | เครื่องโปรแกรมเมอร์ + VPP | ฉาย แสง UV ผ่านหน้าต่างควอตซ์บนตัวชิป ~20 นาที |
| EEPROM | เขียนด้วยไฟฟ้าได้ทีละไบต์ | ลบด้วยไฟฟ้าได้ (ช้า) |
| Flash | เขียนด้วยไฟฟ้า | ลบด้วยไฟฟ้าทีละบล็อก (เร็ว) |
ชิป EPROM ที่เห็นมีหน้าต่างกระจกกลม ๆ ตรงกลาง — นั่นคือช่องให้แสง UV เข้าไปลบข้อมูล เวลาใช้งานจริงต้องแปะสติกเกอร์ปิดไว้ ไม่งั้นแสงแดดจะค่อย ๆ ลบข้อมูลทิ้ง
กดเลือกเบอร์เพื่อดูว่าขาไหนอยู่ตรงไหนจริง ๆ — สังเกตว่าตำแหน่งขาเกือบทั้งหมดตรงกัน ระหว่างเบอร์ต่าง ๆ ผู้ผลิตตั้งใจออกแบบให้เปลี่ยนชิปขนาดใหญ่ขึ้นได้โดยแก้ลายวงจรน้อยที่สุด
output ของ decoder มี glitch ตอน address เปลี่ยน จะเขียนข้อมูลมั่ว — WR ของ Z80 ถูกออกแบบมาให้ปลอดภัยแล้ว (ลงหลัง data นิ่ง และปลดก่อน address เปลี่ยนครึ่ง T)
| ขนาด | ช่วง (จากศูนย์) | สายที่เข้าชิป (n) | เหลือให้ decode |
|---|---|---|---|
| 1 KB | 0000–03FF | 10 (A9–A0) | 6 |
| 2 KB | 0000–07FF | 11 (A10–A0) | 5 |
| 4 KB | 0000–0FFF | 12 (A11–A0) | 4 |
| 8 KB | 0000–1FFF | 13 (A12–A0) | 3 |
| 16 KB | 0000–3FFF | 14 (A13–A0) | 2 |
| 32 KB | 0000–7FFF | 15 (A14–A0) | 1 |
| 64 KB | 0000–FFFF | 16 (A15–A0) | 0 |
สูตรเดียวที่ต้องจำ: ชิปขนาด 2n ไบต์ ⇒ ใช้ A0 ถึง An−1 ที่เหลือคือ An…A15 ไว้ให้ decoder
| เบอร์ | ชนิด | ขนาด | สาย address | ขา | หมายเหตุ |
|---|---|---|---|---|---|
| 2716 | EPROM | 2K × 8 | A10–A0 | 24 | มี CE (ขา 18) กับ OE (ขา 20) แยกกันอยู่แล้ว |
| 2732 | EPROM | 4K × 8 | A11–A0 | 24 | ยุบ VPP เข้ากับ OE เพื่อเอาขา 21 มาเป็น A11 |
| 2764 | EPROM | 8K × 8 | A12–A0 | 28 | ขึ้น 28 ขา · ขา 26 = NC |
| 27128 | EPROM | 16K × 8 | A13–A0 | 28 | ขา 26 กลายเป็น A13 |
| 27256 | EPROM | 32K × 8 | A14–A0 | 28 | ขา 27 กลายเป็น A14 |
| 6116 | SRAM | 2K × 8 | A10–A0 | 24 | CE 18, OE 20, WE 21 |
| 6264 | SRAM | 8K × 8 | A12–A0 | 28 | มี 2 ขาเลือกชิป: CS1 (ขา 20) และ CS2 (ขา 26, active HIGH) |
| 62256 | SRAM | 32K × 8 | A14–A0 | 28 | ขา 1 = A14, ขา 26 = A13 — ไม่ใช่ drop-in ของ 6264 |
อ้างอิง: datasheet Intel 27128A / Cypress CY6264 / Hitachi HM62256 — ในเอกสารเรียนมีพิมพ์ผิดเป็น “27120” ซึ่งไม่มีเบอร์นี้จริง เบอร์ที่ถูกคือ 27128 (ดูหน้า สไลด์ผิด)
Z80 ให้มาแค่ MREQ, IORQ, RD, WR แต่ชิปปลายทางอยากได้สัญญาณรวมที่บอกทั้ง “ที่ไหน” และ “ทำอะไร” พร้อมกัน จึงต้องเอามาผสม 4 คู่
; รูปที่ต้องวาด: NAND ที่มี "วงกลม" ทั้งสองขาเข้า (LectureNote หน้า 57)
MEMRD = NAND( MREQ⚬ , RD⚬ ) = MREQ + RD ; อ่านหน่วยความจำ
MEMWR = NAND( MREQ⚬ , WR⚬ ) = MREQ + WR ; เขียนหน่วยความจำ
IORD = NAND( IORQ⚬ , RD⚬ ) = IORQ + RD ; อ่านพอร์ต I/O
IOWR = NAND( IORQ⚬ , WR⚬ ) = IORQ + WR ; เขียนพอร์ต I/O
; ⚬ = วงกลมเล็กที่ขาเข้า แปลว่า "ขานี้ทำงานเมื่อสัญญาณเป็น 0"
; ทั้งสองรูปเป็นวงจรเดียวกัน — เท่ากันด้วย De Morgan
ที่ต้องวาดคือ NAND ที่มีวงกลมที่ขาเข้าทั้งสองขา ผลคือ
NOT( NOT A · NOT B ) = A + B → ออก 0 เมื่อ input เป็น 0 ทั้งคู่ ✓
ถ้าวาด NAND เปล่า ๆ (ไม่มีวงกลมขาเข้า) จะได้ NOT(A · B)
ซึ่งออก 1 ตอนที่ควรจะ active → ตรรกะกลับด้าน ไม่ตรงกับชื่อที่มีขีดบน
· วงกลมที่ขาเข้าคือหัวใจ อย่าลืมวาด
กดเปลี่ยนสถานะสัญญาณจาก Z80 แล้วดูว่าสัญญาณรวมออกมาเป็นอะไร (0 = active)
อาจารย์ไม่ได้วาด OR gate เลยสักตัวเดียวทั้งบทที่ 6 และ 7 — ทุกเกตวาดเป็น ตัว AND แล้วเติมวงกลมบอกระดับ active ซึ่งเป็นวงจรเดียวกับ OR ทุกประการ
นี่เป็นจุดที่คำอธิบายสั้น ๆ ว่า “input เป็น active-low ก็เลยใช้เกตตัวนี้” ทำให้เข้าใจผิดได้ เพราะเดี๋ยวจะเจอเกตที่เอา A15 A14 A13 A12 (ซึ่งไม่มีขีดบน) มาใส่รวมกับ MREQ (ซึ่งมีขีดบน) — แล้วยังใส่วงกลมเหมือนกันหมดได้อยู่ ทำไม
เป็นสัญญาณที่มีความหมายว่า “ทำงาน / ไม่ทำงาน”
เช่น MREQ, RD, WR,
CE, OE, WE
พวกนี้ต้องบอกได้ว่า “ทำงานตอนเป็น 0 หรือ 1” จึงมีคำว่า active LOW / active HIGH
/MREQ, MREQ#, MREQ_n ก็ความหมายเดียวกันเช่น A15–A0 และ D7–D0
พวกนี้เป็นแค่ “ตัวเลข” — บิตหนึ่งจะเป็น 0 หรือ 1 ก็มีความหมายพอ ๆ กัน
ไม่มีค่าไหนแปลว่า “ทำงาน” หรือ “ไม่ทำงาน”
A12 = 0 ไม่ได้แปลว่า “A12 ไม่ทำงาน”
แต่แปลว่า “บิตที่ 12 ของเลขที่อยู่ เป็นศูนย์” เท่านั้น
ถ้าขีดจะกลายเป็นบอกว่ามันเป็นสัญญาณควบคุม active-low ซึ่งผิด — ในข้อสอบข้อ 1 กรรมการดูตรงนี้ด้วย
NAND ให้ output = 0 ก็ต่อเมื่อ input ที่เข้าตัว AND ทุกตัว เป็น 1
วงกลมที่ขาเข้าคือตัวแปลง — มันทำให้ขาที่ “ต้องเป็น 0” กลายเป็น 1 ให้ AND เพราะฉะนั้นเทคนิคคือ ใส่วงกลมที่ขาไหนก็ตามที่เงื่อนไขต้องการค่า 0 แล้วขาออกจะเป็น 0 ก็ต่อเมื่อเงื่อนไขเป็นจริงครบทุกข้อ พอดี
| เงื่อนไขที่เราต้องการ | ต่อเข้าขา NAND ยังไง | ทำไมถึงใช้ได้ |
|---|---|---|
| A12 ต้องเป็น 0 | ใส่วงกลมที่ขาเข้า | ตอน A12 = 0 วงกลมกลับเป็น 1 ให้ AND ✓ |
| A12 ต้องเป็น 1 | ต่อตรง ๆ ไม่มีวงกลม | ตอน A12 = 1 เข้า AND เป็น 1 อยู่แล้ว ✓ |
| MREQ ต้องทำงาน | ใส่วงกลมที่ขาเข้า | มันเป็น active-low ตอนทำงานเป็น 0 → วงกลมกลับเป็น 1 ✓ |
| สัญญาณ active-HIGH ต้องทำงาน | ต่อตรง ๆ ไม่มีวงกลม | ตอนทำงานมันเป็น 1 อยู่แล้ว ✓ |
กฎเดียวที่ต้องจำ: “ขาไหนที่เงื่อนไขต้องการ 0 ใส่วงกลม · ต้องการ 1 ต่อตรง ๆ” — ใช้ได้ทั้งกับ address line และสัญญาณควบคุม ไม่ต้องแยกคิด และไม่ต้องวาด inverter แยกเลยสักตัว
เราอยากได้ “ชิปถูกเลือก” เมื่อ:
A15=0 และ A14=0 และ A13=0 และ A12=0 และ MREQ=0
เขียนเป็นสมการแบบ active-high (select = 1 เมื่อถูกเลือก):
select = A15 · A14 · A13 · A12 · MREQ'
(ขีดบนตรงนี้แปลว่า NOT ของค่าบิต ไม่ได้แปลว่า active-low)
แต่ขา CE ของชิปเป็น active-low ⇒ ต้องกลับด้าน:
CE = NOT( select )
= NOT( A15 · A14 · A13 · A12 · MREQ' )
ใช้ De Morgan: NOT(a · b) = NOT(a) + NOT(b)
CE = A15 + A14 + A13 + A12 + MREQ
⇒ ได้ OR gate ออกมาตรง ๆ จากพีชคณิต ไม่ต้องท่องกฎอะไรเลย
แต่บรรทัดก่อนใช้ De Morgan คือรูปที่เราต้องวาด:
CE = NOT( A15 · A14 · A13 · A12 · MREQ' )
= NAND ที่มีวงกลมครบทั้ง 5 ขาเข้า ; แบบที่ LectureNote หน้า 60 วาด
⇒ สองบรรทัดนี้คือวงจรเดียวกัน · เขียนสมการด้วย OR ก็ได้ แต่ตอนวาดให้วาดแบบ NAND
สลับบิต A15–A12 แล้วดูว่าค่าที่เข้าตัว AND เปลี่ยนยังไง และ CE ออกมาเป็นอะไร — ลองสลับไปดูเกตของ RWM ด้วย จะเห็นว่า A12 เป็นขาเดียวที่ไม่มีวงกลม
ที่เขียนว่า “input เป็น active-low ทั้งคู่ จึงใส่วงกลมทั้งคู่” — ถูกเฉพาะกับเกตชุด MEMRD/MEMWR/IORD/IOWR เพราะบังเอิญ input ทั้งสองตัวเป็น active-low พอดีจริง ๆ
แต่กับเกต decode ที่มี address line ปนอยู่ ต้องดูทีละบิตว่า เงื่อนไขต้องการ 0 หรือ 1 — ต้องการ 0 ใส่วงกลม ต้องการ 1 ต่อตรง ๆ อย่าท่องว่า “active-low ⇒ ใส่วงกลมหมด”
เกต NAND ที่มีวงกลมขาเข้าในกรอบเส้นประนั่นแหละคือวงจร decode — คำว่า “decoder” ไม่ได้แปลว่าต้องเป็นชิปสำเร็จรูปเสมอไป แต่หมายถึงวงจรอะไรก็ได้ที่ทำหน้าที่ “แปลงบิตบนของ address ให้กลายเป็นสัญญาณ CE”
ในผังของเรามีชิปหน่วยความจำแค่ 2 ตัว ใช้ NAND 2 ตัว (ใส่วงกลมที่ขาเข้าตามเงื่อนไข) ก็จบ ไม่ต้องมี inverter แยกเลย — ถูกกว่าและกินที่น้อยกว่าการใส่ 74LS138 ทั้งตัว แต่ถ้ามีชิป 4–8 ตัวเมื่อไร การใช้ 74LS138 จะคุ้มกว่าทันที
แบ่ง address bus เป็น 2 ส่วนเสมอ
วิธี decode high address มี 3 แบบที่เอกสารเรียนระบุไว้
ใช้ NAND ที่มีวงกลมขาเข้าต่อกันเอง เหมาะเมื่อมีชิป 2–3 ตัว เขียนสมการได้ตรง ๆ จากค่าบิตที่ต้องการ
ข้อดี: ยืดหยุ่น · ข้อเสีย: ชิปเยอะแล้วเกตบาน
2-to-4 → 74LS139/155/156
3-to-8 → 74LS138/538/137
4-to-16 → 74LS154/159
เหมาะเมื่อบล็อกทุกก้อนขนาดเท่ากัน
เช่น 74LS85 เอา high address เทียบกับค่าที่ตั้งไว้ (ตั้งด้วย DIP switch ได้ → เปลี่ยน address ได้ภายหลัง)
ใช้กับการเลือก address ของ I/O ก็ได้
ROM 4KB 0000H = 0000 0000 0000 0000
0FFFH = 0000 1111 1111 1111CEROM = A15 + A14 + A13 + A12 + MREQ
CERAM = A15 + A14 + A13 + A12 + MREQ ; RAM อยู่ 1000–1FFF → A12 ต้องเป็น 1Decoder คือวงจรที่รับเลขฐานสองเข้ามา n บิต แล้วเลือกขาออกให้ทำงานทีละ 1 ขา จาก 2n ขา — เหมือนสวิตช์เลือกช่องทีวี ใส่เลข 3 ก็ได้ช่อง 3 ช่องเดียว ช่องอื่นเงียบหมด
74LS139 (มี 2 ชุดในตัวเดียว), 74LS155, 74LS156
74LS138 ← ตัวที่ออกสอบบ่อยที่สุด · 74LS538, 74LS137
74LS154, 74LS159
เพราะปัญหาของเราคือ “มีชิปหลายตัวต่อบัสเดียวกัน จะให้ตัวไหนตอบ”
ซึ่งก็คือปัญหาเลือก 1 ใน N เป๊ะ ๆ
เอาบิตบนของ address ป้อนเข้า decoder แล้วเอาขาออกแต่ละขาไปต่อ CE ของชิปแต่ละตัว
— จบ ไม่ต้องนั่งออกแบบเกตเอง
เป็น IC 16 ขา ราคาไม่กี่บาท ข้างในคือตรรกะที่แปลงเลข 3 บิตเป็นการเลือก 1 ใน 8 ลองกดเปลี่ยนค่าบิตดูว่าขาออกตัวไหนทำงาน
| G1 | G2A | G2B | C | B | A | ขาที่เป็น 0 | บล็อก address (ถ้าต่อ A15 A14 A13) |
|---|---|---|---|---|---|---|---|
| 0 | × | × | × | × | × | ไม่มีเลย (ปิดอยู่) | — |
| × | 1 | × | × | × | × | ไม่มีเลย (ปิดอยู่) | — |
| 1 | 0 | 0 | 0 | 0 | 0 | Y0 | 0000–1FFF |
| 1 | 0 | 0 | 0 | 0 | 1 | Y1 | 2000–3FFF |
| 1 | 0 | 0 | 0 | 1 | 0 | Y2 | 4000–5FFF |
| 1 | 0 | 0 | 0 | 1 | 1 | Y3 | 6000–7FFF |
| 1 | 0 | 0 | 1 | 0 | 0 | Y4 | 8000–9FFF |
| 1 | 0 | 0 | 1 | 0 | 1 | Y5 | A000–BFFF |
| 1 | 0 | 0 | 1 | 1 | 0 | Y6 | C000–DFFF |
| 1 | 0 | 0 | 1 | 1 | 1 | Y7 | E000–FFFF |
× = เป็นอะไรก็ได้ (don't care) · ขาออกที่ไม่ถูกเลือกจะเป็น 1 ทั้งหมด
| ขา | ชื่อ | ทำงานเมื่อ |
|---|---|---|
| 6 | G1 | HIGH |
| 4 | G2A | LOW |
| 5 | G2B | LOW |
| 3 / 2 / 1 | C / B / A | C คือ MSB |
Decoder ทำงานเมื่อ G1 · G2A · G2B
output Y0–Y7 เป็น active LOW ทีละตัว
A15 → C (ขา 3) ← MSB!
A14 → B (ขา 2)
A13 → A (ขา 1) ← LSB!
MREQ → G2A
GND → G2B
RFSH → G1 ← ปิด decoder ตอน refresh ฟรี ๆ
ได้ 8 บล็อกละ 8 KB: Y0 = 0000–1FFF, Y1 = 2000–3FFF, … Y7 = E000–FFFF
รูปผังระบบรุ่นก่อนหน้าวาดเส้นเดียวเขียนว่า A7–A0 พุ่งเข้าเกตตัวเดียว
ซึ่งทำให้เข้าใจผิด เพราะถ้าอ่านตามรูปนั้นตรง ๆ จะได้ว่า
SEL = A7 + A6 + A5 + A4 + A3 + A2 + A1 + A0
แล้วสายไหนเป็น 1 ก็ดันขาออกให้เป็น 1 ทันที — ถูกต้องตามที่สงสัยเลย
วงจรแบบนั้นจะออก 0 ได้กรณีเดียวคือ A7–A0 = 00000000
แปลว่ามันจับได้แค่พอร์ต 00H พอร์ตเดียวในโลก ใช้กับ 40H ไม่ได้
รูปได้ถูกแก้แล้ว — ตอนนี้วาดเป็น NAND ครบทั้ง 8 เส้น โดยบิตที่ต้องเป็น 0 มีวงกลมที่ขาเข้า
และบิตที่ต้องเป็น 1 ต่อตรง ๆ
| ค่าที่เข้าตัว AND (หลังผ่านวงกลมแล้ว) | ขาออก | |
|---|---|---|
| 1 1 1 1 1 1 1 1 1 | 0 | กรณีเดียวที่ได้ 0 = ตรงเงื่อนไขครบ |
| 1 1 1 0 1 1 1 1 1 | 1 | พลาดขาเดียวก็ไม่ผ่าน |
| 0 1 1 1 1 1 1 1 1 | 1 | — |
| 0 0 0 0 0 0 0 0 0 | 1 | — |
กฎเดียวที่ต้องจำ: NAND ออก 0 ก็ต่อเมื่อขาเข้า (หลังผ่านวงกลม) เป็น 1 ทุกขา พร้อมกัน — ซึ่งก็คือ “เงื่อนไขทุกข้อเป็นจริงพร้อมกัน” นั่นเอง
เราต้องการวงจรที่ออก 0 เฉพาะ ตอน address ตรงเป๊ะเลขเดียว
ซึ่งตรงกับพฤติกรรมของ NAND พอดี — ขอแค่ทำให้ทุกขาที่เข้าตัว AND กลายเป็น 1 เมื่อเงื่อนไขของบิตนั้นเป็นจริง
บิตที่ต้องเป็น 1 ก็ต่อตรง ๆ (ตรงเงื่อนไข = สายเป็น 1 = เข้า AND เป็น 1 ✓)
บิตที่ต้องเป็น 0 ถ้าต่อตรง ๆ มันจะเป็น 0 แล้วพัง — จึงต้องใส่วงกลมที่ขาเข้า
เพื่อกลับเป็น 1 ก่อน (วงกลม = inverter ที่ถูกย่อรูป)
วงจรนี้ไม่มีที่ไหนเก็บเลข 40H เอาไว้เลย ไม่มีรีจิสเตอร์ ไม่มีหน่วยความจำ —
เลข 40H ถูกบัดกรีฝังไว้ใน “ตำแหน่งของวงกลมที่ขาเข้า”
พอร์ต 40H = 0100 0000 ⇒ มี 1 อยู่ที่บิต A6 ตัวเดียว ⇒
A6 เป็นขาเดียวที่ไม่มีวงกลม อีก 7 ขามีวงกลมหมด
พอร์ต 84H = 1000 0100 ⇒ มี 1 ที่ A7 กับ A2 ⇒ สองขานี้ไม่มีวงกลม ที่เหลือมีวงกลม
ถ้าอยากเปลี่ยนเป็นพอร์ตอื่น ก็แค่ย้ายตำแหน่งวงกลม ไม่ต้องแก้อะไรอย่างอื่นเลย
| เงื่อนไขของบิตนั้น | วาดยังไง | ตอนตรงเงื่อนไข ค่าที่เข้า AND | ตอนไม่ตรง |
|---|---|---|---|
| บิตนี้ต้องเป็น 0 | ใส่วงกลมที่ขาเข้า | 1 ✓ | 0 → ขาออกเด้งเป็น 1 ทันที |
| บิตนี้ต้องเป็น 1 | ต่อตรง ๆ ไม่มีวงกลม | 1 ✓ | 0 → ขาออกเด้งเป็น 1 ทันที |
| สัญญาณคุม active-LOW (IOWR, IORD, MREQ) | ใส่วงกลมที่ขาเข้า | 1 ✓ | 0 → ไม่ผ่าน |
| สัญญาณคุม active-HIGH (เช่น G1 ของ 74LS138) | ต่อตรง ๆ ไม่มีวงกลม | 1 ✓ | 0 |
พูดเป็นประโยคเดียว: “ขาไหนเงื่อนไขต้องการ 0 ใส่วงกลม · ต้องการ 1 ต่อตรง ๆ · แล้วใส่วงกลมที่ขาออกด้วยถ้าปลายทางเป็น active-LOW” — ขาออกจะเป็น 0 ก็ต่อเมื่อเงื่อนไขทุกข้อเป็นจริงพร้อมกัน
วาดตามแบบใน LectureNote: ตัว AND + วงกลมที่ขาออก (= NAND) และวงกลมที่ขาเข้าเฉพาะบิตที่ต้องเป็น 0 — ไม่มี inverter แยกสักตัว
สังเกตว่าโครงวงจรของสองพอร์ตนี้เหมือนกันเป๊ะ ต่างกันแค่ว่าขาไหนไม่มีวงกลม และสัญญาณคุมเป็น IOWR (เขียน) หรือ IORD (อ่าน)
ลองตั้งเลขให้ตรงพอร์ตดูก่อน แล้วลองสลับแค่บิตเดียว (เช่นกด 41H) จะเห็นว่า OR เด้งเป็น 1 ทันที และดูกล่องล่างสุดเทียบกับวงจรแบบ “ไม่ใส่ inverter เลย” ไปด้วย
ได้ และคำนวณง่ายกว่าด้วย — SEL = A7 + A6′ + A5 + … + IOWR
(บิตที่ต้องเป็น 1 ใส่ขีดบน) เป็นวงจรเดียวกันเป๊ะกับ NAND ที่มีวงกลม
แต่ตอนวาดรูปให้วาดแบบ NAND เพราะเป็นแบบที่ LectureNote ใช้ทั้งเล่ม
และมันประหยัดกว่าจริง ๆ ในการวาด — วงกลมหนึ่งวงแทน inverter ทั้งตัว
⇒ คิดด้วย OR วาดด้วย NAND จำแค่นี้พอ
มี — 74LS688 เป็น 8-bit magnitude comparator
รับเข้า 2 ชุด (P0–P7 กับ Q0–Q7) แล้วออก P=Q เป็น active-LOW
เอา A7–A0 เข้าฝั่ง P แล้วผูก Q ไว้กับ +5V/GND ตามเลขพอร์ต ก็ได้ตัวเทียบทันทีโดยไม่ต้องนับ inverter
แต่ในข้อสอบให้วาดด้วยเกต เพราะต้องการวัดว่าเข้าใจ active-low กับ De Morgan จริงหรือเปล่า
ถ้าเขียนกำกับไว้ว่า “ใช้ 74LS688 แทนได้” จะได้คะแนนความเข้าใจเพิ่ม
คำสั่ง OUT (n),A และ IN A,(n) จะวางเลขพอร์ต n ไว้ที่ A7–A0
ส่วน A15–A8 Z80 จะใส่ค่าใน register A ลงไป (ไม่ใช่ 0 และไม่ใช่ค่าขยะ — เป็นพฤติกรรมที่กำหนดไว้ในสถาปัตยกรรม)
ส่วนคำสั่ง IN r,(C) / OUT (C),r จะวาง C ที่ A7–A0 และ B ที่ A15–A8
⇒ วงจร decode ของ I/O จึงดูแค่ A7–A0 พอ ไม่ต้องแตะ A15–A8 เลย
(ถ้าไปดูด้วยจะพังทันทีเพราะค่าบน A15–A8 เปลี่ยนไปตามค่าใน A หรือ B)
ปัญหาของสองฝั่งนี้คนละเรื่องกันคนละแบบ จึงต้องใช้ IC คนละชนิด — ดูภาพรวมก่อน
Latch คือวงจรจำค่า · หน้าที่เดียวของมันคือ “รับค่าเข้ามาแล้วค้างไว้”
จนกว่าจะมีคนสั่งให้เปลี่ยน
ลองกด เริ่มจำลอง ด้านล่างเพื่อดูข้อมูลวิ่งบนบัสจริง ๆ
แล้วกด ลองถอด latch ออกดู เพื่อเทียบว่าต่างกันยังไง
Tri-state buffer คือประตูไฟฟ้า · ขาออกของมันมี 3 สถานะ ไม่ใช่ 2 —
นอกจาก 0 กับ 1 แล้วยังมี Z (high impedance)
ซึ่งแปลว่า “ตัดขาดออกจากวงจร” เหมือนถอดสายทิ้ง
ลองสลับ OE และลองถอด buffer ออกดูว่าเกิดอะไรขึ้น
Latch คือวงจรจำค่า — รับข้อมูลเข้ามาแล้วค้างไว้
จนกว่าจะมีคนสั่งให้เปลี่ยน เหมือนกระดานที่เขียนแล้วค้างไว้จนกว่าจะลบ
ต้องใช้เพราะข้อมูลอยู่บน data bus แค่ประมาณ 1 ไมโครวินาที ต่อรอบ
ถ้าต่อ LED ตรง ๆ มันจะติดแวบเดียวแล้วดับ ตามองไม่ทัน
| เบอร์ | ชนิด | สั่งเก็บด้วย | พิเศษ |
|---|---|---|---|
| 74LS273 | D flip-flop × 8 | CLK ขอบขาขึ้น (ขา 11) | มี MR (ขา 1) ล้างค่าเป็น 0 ได้ |
| 74LS373 | Transparent latch × 8 | LE ระดับ HIGH (ขา 11) | มี OE ทำ tri-state ได้ |
| 7475 | Latch × 4 | ระดับ HIGH | ตัวเล็ก ใช้ 2 ตัวถึงจะครบ 8 บิต |
เลือก 74LS273 จะสะดวกกว่า เพราะต่อ MR เข้า RESET ของ Z80 ได้ → LED ดับหมดตอนเปิดเครื่องโดยอัตโนมัติ
Tri-state buffer คือประตูไฟฟ้า — เปิดให้สัญญาณผ่าน
หรือตัดขาดออกจากวงจรไปเลย (สถานะที่สามคือ high impedance ไม่ใช่ 0 และไม่ใช่ 1)
ต้องใช้เพราะถ้าต่อสวิตช์เข้าบัสตรง ๆ มันจะขับบัสตลอดเวลา
ชนกับ ROM/RAM ที่กำลังส่งข้อมูลอยู่ → กระแสไหลลัด ชิปพัง
| เบอร์ | ชนิด | ควบคุมด้วย |
|---|---|---|
| 74LS244 | Buffer ทางเดียว × 8 | OE 2 ขา (ขา 1 และ 19) คุมข้างละ 4 บิต |
| 74LS245 | Transceiver สองทาง × 8 | OE + ขา DIR เลือกทิศทาง |
3 สถานะของขาออก: 0 · 1 · Z (ลอยตัว) — คำว่า “tri-state” มาจากตรงนี้
ออก (CPU → โลกภายนอก) ปัญหาคือ “ข้อมูลอยู่แวบเดียว” ⇒ ต้องมีตัวจำ ⇒ latch
เข้า (โลกภายนอก → CPU) ปัญหาคือ “จะไปชนกับคนอื่นบนบัส” ⇒ ต้องมีตัวตัดขาด ⇒ tri-state buffer
ข้อมูลอยู่บน data bus แค่ไม่กี่ร้อยนาโนวินาที ถ้าไม่มีตัวจำ LED จะกะพริบแวบเดียว จึงต้องใช้ 74LS273 (D flip-flop, clock ขอบขาขึ้น) หรือ 74LS373 (transparent latch, LE active HIGH)
เงื่อนไขที่ latch ต้องเก็บค่า:
1) A7–A0 ตรงกับเลขพอร์ต ⇒ SEL = 0
2) IOWR = 0
; 74LS273 — CLK ทำงานที่ขอบขาขึ้น (แนะนำ)
CLK = NAND( SEL⚬ , IOWR⚬ ) = SEL + IOWR
; NAND มีวงกลมขาเข้า + วงกลมขาออก → พัลส์ active-low
; ขอบขาขึ้นตอนจบ cycle = จังหวะ latch พอดี
; 74LS373 — LE เป็น active HIGH (แบบที่ LectureNote รูป 7.3 วาด)
LE = AND( SEL⚬ , IOWR⚬ ) = SEL NOR IOWR
; มีวงกลมที่ขาเข้าทั้งสอง แต่ "ไม่มี" วงกลมที่ขาออก
; เพราะ LE ต้อง active HIGH
ถ้าใส่วงกลมที่ขาออกด้วย จะกลายเป็น NAND เต็มตัว ให้ผล 1 ถึง 3 ใน 4 กรณี —
LE จะขึ้นทุกครั้งที่มี I/O write ไปพอร์ตไหนก็ได้ LED จะ latch ค่าขยะ
LE เป็น active HIGH ⇒ ต้องเป็น AND ที่มีวงกลมเฉพาะขาเข้า (negative-AND = NOR)
ซึ่งให้ 1 เฉพาะตอน input เป็น 0 ทั้งคู่ — ตรงกับรูป 7.3 ใน LectureNote เป๊ะ
74LS273 มีขา MR ต่อ RESET ได้ → latch เคลียร์เป็น 00H ตอนเปิดเครื่อง (LED ที่ต่อแบบ active-high จะดับหมด) เป็นข้อได้เปรียบเหนือ 74LS373 ที่ไม่มีขา clear
สวิตช์ต่อ data bus ตรง ๆ ไม่ได้ เพราะจะขับบัสตลอดเวลาแล้วชนกับชิปอื่น ต้องผ่าน 74LS244 (octal tri-state buffer) หรือ 74LS245 (transceiver)
เงื่อนไขที่ buffer ต้องปล่อยข้อมูลออก:
1) A7–A0 ตรงกับเลขพอร์ต
2) IORD = 0
OE = NAND( SEL⚬ , IORD⚬ ) = SEL + IORD
; NAND มีวงกลมครบ ขาออก active LOW
; ตรงกับรูป 7.5 ใน LectureNote
ถ้า OE ไม่ active → output ของ buffer เป็น high impedance ปล่อยบัสให้คนอื่นใช้
ตอน interrupt acknowledge ของ Z80 สัญญาณ IORQ จะลงพร้อม M1
โดยที่ address bus เป็นค่า PC ไม่ใช่เลขพอร์ต ถ้า decoder ดูแค่ IORQ + address จะเลือกพอร์ตมั่ว
แล้ว buffer อาจขับบัสชนกับ interrupt vector
แต่ ถ้าเรา gate ด้วย RD/WR อยู่แล้ว (คือใช้ IORD/IOWR)
ก็ปลอดภัยแล้ว เพราะระหว่าง INTACK ทั้ง RD และ WR เป็น 1 ทั้งคู่ —
เขียนประโยคนี้ลงไปในข้อสอบได้คะแนนความเข้าใจแน่นอน
ระบบ Z80 ประกอบด้วย
0000H40H84Hจงวาดรูปการออกแบบต่อประสาน พร้อมทั้งขาที่อยู่ ข้อมูล และสัญญาณที่เกี่ยวข้องมาทั้งหมด
| อุปกรณ์ | ขนาด | ช่วง address | เข้าชิป | ต้อง decode |
|---|---|---|---|---|
| ROM (2732) | 4 KB | 0000H – 0FFFH | A11–A0 (12 เส้น) | A15 A14 A13 A12 = 0 0 0 0 |
| RWM (6116×2 หรือ 4K SRAM) | 4 KB | 1000H – 1FFFH | A11–A0 (12 เส้น) | A15 A14 A13 A12 = 0 0 0 1 |
| LED (74LS273) | 1 พอร์ต | พอร์ต 40H | — | A7–A0 = 0100 0000 |
| Switch (74LS244) | 1 พอร์ต | พอร์ต 84H | — | A7–A0 = 1000 0100 |
A15 A14 A13 A12 │ A11 … A0
ROM 0000H → 0 0 0 0 │ 0 … 0
0FFFH → 0 0 0 0 │ 1 … 1 ⇒ A15–A12 คงที่ = 0000
RWM 1000H → 0 0 0 1 │ 0 … 0
1FFFH → 0 0 0 1 │ 1 … 1 ⇒ A15–A12 คงที่ = 0001
-- สัญญาณรวม --
MEMRD = MREQ + RD MEMWR = MREQ + WR
IORD = IORQ + RD IOWR = IORQ + WR
-- เลือกชิปหน่วยความจำ --
CEROM = A15 + A14 + A13 + A12 + MREQ
CERAM = A15 + A14 + A13 + A12 + MREQ
OEROM = MEMRD
OERAM = MEMRD WERAM = MEMWR
-- เลือกพอร์ต I/O (decode ครบ 8 บิต) --
SEL40 = A7 + A6 + A5 + A4 + A3 + A2 + A1 + A0 ; 0100 0000
SEL84 = A7 + A6 + A5 + A4 + A3 + A2 + A1 + A0 ; 1000 0100
CLKLED = SEL40 + IOWR ; 74LS273 latch ที่ขอบขาขึ้น
(ถ้าใช้ 74LS373: LE = AND ที่มีวงกลมเฉพาะขาเข้า = NOR)
OESW = SEL84 + IORD ; 74LS244 ปล่อยข้อมูลขึ้นบัส
ระบบมี ROM 8 KB ที่ 0000H–1FFFH และ RAM 8 KB ที่ 2000H–3FFFH จงออกแบบวงจร decode ด้วย 74LS138 ตัวเดียว พร้อมระบุว่าขา output ตัวไหนต่อชิปไหน และเหลือช่องว่างเผื่อขยายกี่บล็อก
ชิป 8 KB ⇒ n = 13 ⇒ A12–A0 เข้าชิป เหลือ A15 A14 A13 พอดี 3 เส้น = input ของ 74LS138 ครบเป๊ะ
A15 → C (ขา 3, MSB)
A14 → B (ขา 2)
A13 → A (ขา 1, LSB)
MREQ → G2A (ขา 4)
GND → G2B (ขา 5)
RFSH → G1 (ขา 6) ; ปิด decoder ตอน refresh
Y0 (ขา 15) → CE ของ ROM 2764 → 0000–1FFF
Y1 (ขา 14) → CS1 ของ RAM 6264 → 2000–3FFF (CS2 ต่อ +5V)
OE ทั้งคู่ ← MEMRD WE ของ RAM ← MEMWR
ตรวจ foldback: n = 13, k = 3 ⇒ d = 16 − 13 − 3 = 0 ⇒ 20 = 1 ภาพ → decode เต็ม ไม่มี foldback
เหลือเผื่อขยาย: Y2–Y7 = 6 บล็อก × 8 KB = 48 KB ตั้งแต่ 4000H ถึง FFFFH
ระบบมี ROM 1 KB ที่ 0000H–03FFH และ RAM 1 KB ที่ 0400H–07FFH
จงเขียนสมการ CE ของทั้งสองชิปแบบ decode เต็ม
แล้วบอกว่า address 013CH ตกอยู่ที่ชิปไหน ตำแหน่งภายในชิปเท่าไร
ชิป 1 KB ⇒ n = 10 ⇒ A9–A0 เข้าชิป เหลือ A15–A10 = 6 เส้นให้ decode
A15 … A10 │ A9 … A0
0000H = 0000 00 │ 00 0000 0000 A15–A10 = 000000
03FFH = 0000 00 │ 11 1111 1111
0400H = 0000 01 │ 00 0000 0000 A15–A10 = 000001
07FFH = 0000 01 │ 11 1111 1111
CEROM = A15+A14+A13+A12+A11+A10 + MREQ
CERAM = A15+A14+A13+A12+A11+A10 + MREQ
013CH = 0000 0001 0011 1100 ⇒ A15–A10 = 000000 ⇒ ตรงกับ ROM
ตำแหน่งภายในชิป = A9–A0 = 01 0011 1100 = 13CH
(เพราะ ROM เริ่มที่ 0000H พอดี ตำแหน่งภายในจึงเท่ากับ address ที่ CPU ใช้)
ระบบมี ROM 16 KB ที่ 0000H และ RAM 32 KB ที่ 8000H จงระบุจำนวนสาย address ที่เข้าแต่ละชิป, สมการ CE ที่สั้นที่สุดที่ยัง decode เต็ม และช่วง address ที่ยังว่าง
00 (0000–3FFF)1 (8000–FFFF)CEROM = A15 + A14 + MREQ ; k = 2 → d = 16−14−2 = 0
CSRAM = A15 + MREQ ; k = 1 → d = 16−15−1 = 0
ช่วงว่าง: 4000H–7FFFH (16 KB) เพราะ A15 A14 = 01 ไม่มีชิปไหนตอบ — ถ้าอ่านจะได้ค่าขยะจาก floating bus เขียนจะหายไปเฉย ๆ
จงออกแบบวงจรต่อ 7-segment 2 หลักที่พอร์ต B0H และ B1H
กับปุ่มกด 4 ปุ่มที่พอร์ต C0H ให้ระบุ IC ที่ใช้ สมการเลือกพอร์ต และวิธีต่อสัญญาณควบคุม
B0H = 1011 0000, B1H = 1011 0001 ⇒ ต่างกันแค่ A0 ⇒ decode A7–A1 ร่วมกัน แล้วใช้ A0 แยกสองหลัก
SELB = A7 + A6 + A5 + A4 + A3 + A2 + A1 ; ตรงกับ 1011 000x
CLKหลักหน่วย = SELB + IOWR + A0 ; ต้องการ A0 = 0 → ใส่ A0 ตรง ๆ (พอร์ต B0H)
CLKหลักสิบ = SELB + IOWR + A0 ; ต้องการ A0 = 1 → ใส่ A0 ที่กลับด้าน (พอร์ต B1H)
SELC0 = A7 + A6 + A5 + A4 + A3 + A2 + A1 + A0 ; 1100 0000
OEปุ่ม = SELC0 + IORD
จงออกแบบให้อุปกรณ์เอาต์พุตอยู่ที่ตำแหน่ง 8000H แบบ memory-mapped I/O
แทนการใช้พอร์ต แล้วอธิบายว่าต่างจากแบบ isolated I/O อย่างไร ใช้คำสั่งอะไรเขียนข้อมูล
Memory-mapped I/O = ใช้ MREQ แทน IORQ และ decode ครบ 16 บิต
SEL8000 = A15 + A14 + A13 + A12 + A11 + A10 + A9 + A8
+ A7 + A6 + A5 + A4 + A3 + A2 + A1 + A0
CLK = SEL8000 + MEMWR ; 74LS273 · latch ที่ขอบขาขึ้นตอนจบ
; คำสั่งที่ใช้เปลี่ยนจาก OUT เป็น LD
LD A, 0FFH
LD (8000H), A ; opcode 32 00 80
| Isolated (port-mapped) I/O | Memory-mapped I/O | |
|---|---|---|
| สัญญาณ | IORQ | MREQ |
| สาย address | A0–A7 (256 พอร์ต) | A0–A15 กินพื้นที่หน่วยความจำ |
| คำสั่ง | IN / OUT เท่านั้น | LD ทุกแบบ, INC (HL), LDIR, … |
| ความยาว cycle | 4 T (มี Tw แถม) | 3 T เร็วกว่า |
| ข้อควรระวัง | IORQ ลงตอน INTACK ด้วย | MREQ ลงตอน refresh ด้วย |
| เสีย | ทำ read-modify-write ไม่ได้ | เสียพื้นที่ address ไป |
ในเอกสารเรียนรูปที่ 7.7 ใช้ 74LS138 สองตัว ตัวบน decode A12–A10 ตัวล่างเอา RD/WR/MREQ มาเข้า C/B/A ได้ตำแหน่งเอาต์พุต 82FFH และอินพุต 86FFH