Các opcodes của họ --- Họ đến từ đâu?


12

Khi các kỹ sư đang thiết kế một kiến ​​trúc tập lệnh, theo thủ tục hoặc giao thức nào, nếu có, họ sẽ làm theo khi chỉ định một số mã nhị phân nhất định làm hướng dẫn. Ví dụ, nếu tôi có một ISA nói 10110 là một lệnh tải, thì số nhị phân đó đến từ đâu? Có phải nó được mô hình hóa từ một bảng trạng thái cho một máy trạng thái hữu hạn đại diện cho một hoạt động tải?

Chỉnh sửa: Sau khi thực hiện nhiều nghiên cứu hơn, tôi tin rằng những gì tôi đang cố gắng quan tâm làm thế nào các opcode cho các hướng dẫn CPU khác nhau được chỉ định. ADD có thể được chỉ định với opcode là 10011; một lệnh tải có thể được chỉ định là 10110. Quá trình suy nghĩ nào được đưa vào để gán các mã nhị phân này cho tập lệnh?


8
"Thiết kế bộ vi xử lý sử dụng Verilog HDL" của Monte Dalrymple cung cấp cách tiếp cận thiết kế rất chi tiết cho CPU Z80 và từ đó tôi nghĩ bạn sẽ tìm hiểu rất nhiều về câu hỏi của mình. Nhưng có nhiều cân nhắc đi vào một lựa chọn cụ thể, bao gồm phân tích thống kê các tập lệnh khác, đầu ra trình biên dịch, v.v. Tuy nhiên, tôi khuyên bạn nên bắt đầu với cuốn sách đó. Mặc dù nó bắt đầu với một thiết kế đã biết, anh ấy đi sâu vào chi tiết về nó và tôi nghĩ rằng bạn sẽ chọn một vài thứ. Cuốn sách hay.
jonk

Hoặc, có lẽ, bạn đang hỏi về thiết kế công cụ thực thi và tự hỏi làm thế nào các bit trong hướng dẫn có thể phát vào đó? Không chắc chắn từ từ ngữ của bạn.
jonk

2
Một số người khác hỏi câu hỏi này. Phải là thứ ba.
Ignacio Vazquez-Abrams

5
@Steven Hãy nghĩ về nó. Nếu bạn phải thiết kế một ISA, bạn sẽ nghĩ gì? Nếu hướng dẫn của bạn không có cùng độ dài, làm thế nào bạn chọn từ hướng dẫn ngắn hơn hoặc dài hơn, cho hướng dẫn nào? Nếu bạn phải thiết kế một giai đoạn giải mã , bạn muốn điều gì cho ISA của bạn trông như thế nào? Tôi nghĩ rằng câu hỏi rộng một cách không cần thiết (và do đó, gần như không thể trả lời hoàn toàn), nhưng bạn có thể cải thiện nó rất nhiều bằng cách đặt một số suy nghĩ của riêng mình vào đó và hỏi một câu hỏi chính xác sẽ không yêu cầu chúng tôi viết một cuốn sách để trả lời nó
Marcus Müller

3
Các thông số kỹ thuật của RISC-V nói về các quyết định thiết kế mà họ đưa ra ở tất cả các cấp, bao gồm một chút công bằng về mã hóa các hướng dẫn máy. (Điều này là bất thường đối với hướng dẫn sử dụng bộ xử lý; RISC-V là bài tập học thuật đầu tiên và kiến ​​trúc CPU thứ hai, không giống như hầu hết.)
zwol

Câu trả lời:


5

Trong rất nhiều trường hợp, sự lựa chọn khá tùy tiện hoặc dựa trên "bất cứ nơi nào phù hợp nhất" khi ISAs phát triển theo thời gian. Tuy nhiên, MOS 6502 là một ví dụ tuyệt vời về một con chip trong đó thiết kế của ISA bị ảnh hưởng nặng nề bằng cách cố gắng nén càng nhiều càng tốt ra khỏi các bóng bán dẫn hạn chế.

Xem video này giải thích cách 6502 được thiết kế ngược , đặc biệt là từ 34:20 trở đi.

6502 là bộ vi xử lý 8 bit được giới thiệu vào năm 1975. Mặc dù nó có cổng ít hơn 60% so với Z80 nhưng nó nhanh gấp đôi và mặc dù nó bị hạn chế hơn (về mặt đăng ký, v.v.), nhưng nó đã bù lại bằng một bộ hướng dẫn thanh lịch.

Nó chỉ chứa 3510 bóng bán dẫn, được rút ra bằng tay , bởi một nhóm nhỏ người đang bò trên một số tấm nhựa lớn sau đó được thu nhỏ về mặt quang học, tạo thành các lớp khác nhau của 6502.

Như bạn có thể thấy bên dưới, 6502 chuyển opcode hướng dẫn và dữ liệu thời gian vào ROM giải mã, sau đó chuyển nó thành một thành phần "logic điều khiển ngẫu nhiên" có mục đích có thể ghi đè đầu ra của ROM trong một số tình huống phức tạp.

Sơ đồ khối 6502

Vào lúc 37:00 trong video, bạn có thể thấy một bảng ROM giải mã cho biết những điều kiện đầu vào phải đáp ứng để có "1" cho đầu ra điều khiển nhất định. Bạn cũng có thể tìm thấy nó trên trang này .

Bạn có thể thấy rằng hầu hết những thứ trong bảng này đều có X ở các vị trí khác nhau. Hãy lấy ví dụ

011XXXXX 2 X RORRORA

Điều này có nghĩa là 3 bit đầu tiên của opcode phải là 011 và G phải là 2; không có gì khác Nếu vậy, đầu ra có tên RORRORA sẽ thành sự thật. Tất cả các mã ROR bắt đầu bằng 011; nhưng có những hướng dẫn khác cũng bắt đầu bằng 011. Chúng có thể cần được lọc ra bởi đơn vị "logic điều khiển ngẫu nhiên".

Vì vậy, về cơ bản, opcodes đã được chọn sao cho các hướng dẫn cần thực hiện tương tự như nhau có điểm chung trên mẫu bit của chúng. Bạn có thể thấy điều này bằng cách nhìn vào một bảng opcode ; tất cả các hướng dẫn OR bắt đầu bằng 000, tất cả các hướng dẫn Store bắt đầu bằng 010, tất cả các hướng dẫn sử dụng địa chỉ trang không đều có dạng xxxx01xx. Tất nhiên, một số hướng dẫn dường như không "phù hợp", vì mục đích không phải là định dạng opcode hoàn toàn thông thường mà là cung cấp một bộ hướng dẫn mạnh mẽ. Và đây là lý do tại sao "logic điều khiển ngẫu nhiên" là cần thiết.

Trang tôi đã đề cập ở trên nói rằng một số dòng đầu ra trong ROM xuất hiện hai lần, "Chúng tôi cho rằng điều này đã được thực hiện vì chúng không có cách định tuyến đầu ra của một số dòng mà chúng muốn, vì vậy chúng đặt cùng một dòng ở một dòng khác vị trí một lần nữa. " Tôi chỉ có thể tưởng tượng các kỹ sư vẽ tay từng cánh cổng một và đột nhiên nhận ra một lỗ hổng trong thiết kế và cố gắng đưa ra một cách để tránh bắt đầu lại toàn bộ quá trình.


22

Nó phụ thuộc vào độ tuổi của ISA.

Trong những ngày đầu của thiết kế tay, và thậm chí còn hơn thế khi các CPU được lắp ráp từ logic rời rạc, thiết kế logic sẽ xuất hiện trước và được giảm thiểu rộng rãi, và sau đó các mẫu bit của ISA sẽ là bất kỳ giá trị nào được yêu cầu để làm cho tối thiểu công việc logic.

Vì vậy, có thể có một mẫu tín hiệu điều khiển cụ thể cho phép một số bộ ghép kênh kết nối đầu ra ALU với đầu vào của tệp thanh ghi GP, một vài tín hiệu điều khiển khác hướng dẫn ALU thêm, trừ, AND, OR, v.v. địa chỉ bit vào tập tin đăng ký. Ba nhóm tín hiệu này sẽ tạo thành các trường trong hướng dẫn. Mỗi nhóm sẽ được giữ cùng nhau và ý nghĩa chi tiết của chúng phát sinh từ thiết kế cho đơn vị đó (ALU, v.v.) nhưng các nhóm có thể theo bất kỳ thứ tự nào, cho đến khi bạn thiết kế bộ giải mã lệnh. (x86 đủ cũ để bạn có thể phát hiện một số thứ này nếu bạn nhìn đúng chỗ - đó không phải là một thiết kế hoàn toàn mới, nhưng được vẽ từ 8080 cũ hơn)

Các ISA sau này có thể được "dọn dẹp" và sử dụng thường xuyên và đơn giản hơn, với phần cứng để dịch giữa chúng và các tín hiệu điều khiển mức phần cứng thực tế, đôi khi thông qua "microcode". Chúng được gọi là "CISC" hoặc "Mã hóa tập lệnh phức tạp". Tiền tố lệnh "Rep" x86 là một ví dụ đơn giản về điều này - nó khiến cho lệnh sau được lặp lại một số lần, để tiết kiệm việc phải viết một vòng lặp FOR.

Sau đó (vào những năm 1980) đã chuyển sang một kiểu mã hóa trực tiếp đơn giản hơn (RISC - Mã hóa tập lệnh giảm) mà bạn có thể thấy trong các bộ xử lý ARM. Điều này được thúc đẩy bởi kích thước nhỏ của ASIC vào thời điểm đó và mong muốn đặt CPU 32 bit cho chúng, do đó không có dung lượng dự phòng cho bộ giải mã tập lệnh phức tạp, để đưa CPU hoàn chỉnh xuống còn khoảng 20.000 cổng. (Cũng có một sự gia tăng hiệu suất tạm thời, bởi vì mọi người chưa phát triển các kỹ thuật để làm cho bộ giải mã CISC nhanh chóng - đó là vào năm 1995 với Pentium Pro)

Và ngày nay điều đó không thành vấn đề - CPU đọc một số hướng dẫn cùng một lúc và dành hàng triệu bóng bán dẫn để giải mã chúng, sắp xếp lại chúng và thực hiện càng nhiều càng tốt, để tăng tốc các chương trình có thể được viết cho lâu đời nhất phong cách của ISA.


2
Tôi không chắc chắn tôi thực sự gọi CISC là "dễ sử dụng hơn". Đó có thể là ý định ban đầu, nhưng 30 năm sau, chúng là loại phản đề "dễ sử dụng" (ít nhất là so với RISC ISAs, ít nhất).
tonysdg

2
Có những khía cạnh mà chúng dễ sử dụng hơn ... hoặc tính đều đặn (tính trực giao là một chủ đề lớn) khi trình biên dịch là các chương trình tương đối tầm thường, hoặc thông qua hỗ trợ trực tiếp các hoạt động cấp cao hơn, yêu cầu dịch thuật ít hơn từ trình biên dịch. Nhưng đó là một thời gian dài trước đây và bất kỳ CISC nào còn sót lại có rất nhiều lớp sửa đổi trên đầu tập lệnh ban đầu của nó. Trình biên dịch cũng đã thay đổi tất cả sự công nhận - hàng ngàn lượt tối ưu hóa được thực hiện bởi gcc sẽ không thể tưởng tượng được trước đó. Vì vậy, những gì đã "dễ dàng" sau đó và bây giờ có rất ít quan hệ.
Brian Drumond

4
Sự khác biệt đã bị xói mòn (bộ RISC "thêm các hướng dẫn) và được áp dụng bởi các kiến ​​trúc mới, thậm chí phức tạp hơn như VLIW; thực sự đồng thuận duy nhất là x86 (16 và 32 bit) khó sử dụng
pjc50

1
@tonysdg: Có khó sử dụng RISC và khó sử dụng CISC. Một so sánh tốt về "sự thân thiện với lập trình viên" là so sánh 68k với ARM. ARM được thiết kế cho trình biên dịch, do đó bạn phải thực hiện nhiều công việc thủ công để lấy dữ liệu từ RAM và ghi lại vào RAM. 68k được thiết kế cho các lập trình viên lắp ráp và cho phép bạn hoạt động trực tiếp trên dữ liệu trong RAM. Nếu bạn nhìn vào 68k ISA, bạn sẽ thấy rằng nó trông rất giống với RISC hiện đại với một ngoại lệ - bạn có thể hoạt động trực tiếp trên RAM trong khi RISC chỉ cho phép bạn hoạt động trên các thanh ghi.
slebetman

1
Microcode chủ yếu là một thuộc tính CISC. Tuy nhiên, bạn có thể triển khai CISC mà không cần microcode: bộ giải mã lệnh sẽ phức tạp hơn. Bạn cũng sẽ thấy một số CISC từ Pentium-Pro trở đi được mô tả là RISC trong nội bộ; dịch từng lệnh CISC thành một hoặc nhiều op RISC nội bộ: tên gọi khác của microcode (mặc dù sự khác biệt bị mờ trong các đơn vị thực thi siêu khối)
Brian Drumond

9

Nếu bạn nhóm các hướng dẫn tương tự lại với nhau, các mẫu sẽ xuất hiện. Điều này rất rõ ràng trong ARM, trong đó hướng dẫn sử dụng ISA thực sự cho bạn thấy bit nào của từ lệnh tương ứng với chức năng, lựa chọn đăng ký, v.v. Nhưng nó cũng có thể được suy ra cho X86 .

Cuối cùng, phần "chức năng" của opcodes đi vào một số bộ giải mã nhị phân-to-one thực sự kích hoạt một chức năng cụ thể hoặc chuỗi các hoạt động đường ống. Chúng thường không liên quan đến nội dung của bất kỳ máy trạng thái nào, trừ khi chúng tôi đang xem xét các hướng dẫn có độ dài thay đổi yêu cầu máy trạng thái để giải mã.


Về cơ bản, bạn đang nói rằng họ đang sử dụng số lượng bóng bán dẫn thấp nhất có thể trên chip. Tôi hoàn toàn đồng ý trong bối cảnh câu hỏi của OP, nơi họ không thể mua hàng trăm bóng bán dẫn bổ sung cho một bộ hướng dẫn gọn gàng hơn. Các CPU hàng triệu bóng bán dẫn không có nhiều lý do để quan tâm, nhưng tất nhiên nhiều người giữ nó để tương thích ngược.
Harper - Tái lập Monica

@Harper Vẫn còn lý do, bởi vì trong khi các bóng bán dẫn nhỏ hơn, chúng vẫn có kích thước - và tốc độ xung nhịp tăng lên rất nhiều trong thời gian đó. Vì vậy, một bộ giải mã lệnh quá lớn vẫn có thể là nút cổ chai cho hiệu năng (một trong những lý do khiến nhiều CPU chọn cách sử dụng các lệnh trước mã hóa trước thời hạn). Đó không phải (chỉ) về số lượng bóng bán dẫn, mà nhiều hơn về tốc độ xung nhịp kết hợp với khu vực chết. Thông tin vẫn cần thời gian để truyền bá và trong khi các CPU hiện đại không chạy ở tốc độ ánh sáng, chúng không đủ giới hạn tốc độ để mong đợi những cải tiến đáng kể.
Luaan

@Luaan: Thật ra, "chúng ta làm gì với tất cả các bóng bán dẫn này" là một câu hỏi thực sự ngày nay. Nhìn vào tất cả các bộ đệm L2 / L3 hiện nay. Đó là một sự thừa nhận thầm lặng, chúng tôi không sử dụng tốt hơn cho tất cả hàng triệu bóng bán dẫn đó. Xeon mới nhất dành hơn 2 tỷ bóng bán dẫn cho bộ đệm!
MSalters

6

Ai đó tại một số điểm ngồi xuống và xác định chúng.

Một ISA tốt sẽ làm cho bộ giải mã đơn giản nhất có thể.

Ví dụ, với lệnh ALU, bạn có thể để một số bit của opcode được gửi trực tiếp vào các dòng điều khiển của ALU.


Cảm ơn tất cả các câu trả lời tuyệt vời. Tất cả các bạn đã giúp tôi hiểu điều này tốt hơn rất nhiều.
Steven

4
Thực tế có khá nhiều yếu tố khác ngoài sự đơn giản của bộ giải mã cần tính đến. Tùy thuộc vào hoàn cảnh và mục đích sử dụng, những người khác (ví dụ, mật độ mã) có thể quan trọng hơn sự đơn giản của bộ giải mã. Trong một bộ xử lý hiện đại, mật độ mã có thể vượt xa sự đơn giản của bộ giải mã trong hầu hết các trường hợp.
Jerry Coffin

5

Thông thường, bạn sẽ chia ISA của bạn thành các nhóm chức năng. Điều này có ý nghĩa (để tối ưu hóa logic hoặc chỉ gọn gàng) rằng các cặp miễn phí được phân biệt bằng một thay đổi bit duy nhất (tải so với lưu trữ) và rằng bạn có một số phân cấp các bit ảnh hưởng đến cây quyết định giải mã.

Vào cuối ngày, việc phân bổ bit tùy ý cho khối chức năng (trái ngược với việc đặt các trường 'dữ liệu' trong hướng dẫn sẽ chỉ có tác động nhỏ đến hiệu quả thiết kế chung của bạn - nhưng bạn có nhiều lựa chọn về cách 'Tối ưu hóa' mã hóa ISA của bạn tùy thuộc vào những gì bạn cảm thấy là một tham số quan trọng.


1

Mã hóa hướng dẫn là một sự thỏa hiệp xấu xí giữa.

Làm cho việc giải mã trở nên đơn giản, vì điều này bạn muốn có một tập hợp các trường đơn giản, mỗi trường có thể được giải mã riêng biệt và được chuyển đến một phần riêng biệt của công cụ thực thi.

Đóng gói càng nhiều chức năng càng tốt vào một kích thước giới hạn của từ hướng dẫn. Điều này dẫn đến những thứ như các định dạng không đổi đặc biệt có thể mã hóa nhiều loại số phổ biến.

Tương thích tiến và lùi. Nếu bạn gán chức năng cho mọi opcode có thể, bạn sẽ không có chỗ để mở rộng kiến ​​trúc sau này. Nếu bạn đang thêm vào một kiến ​​trúc hiện có, bạn phải đưa các hướng dẫn mới của mình vào các opcodes dự phòng.


1

Sự xuất sắc của Randy Hyde (nếu có ngày tháng) Nghệ thuật lắp ráp đi vào tập lệnh x86 một số chi tiết trong chương 3.3.4 Bộ điều khiển và Bộ hướng dẫn và sau đây.

Các chương trình trong các hệ thống máy tính đầu tiên (tiền Von Neumann) thường được "kết nối cứng" vào mạch điện. Đó là, hệ thống dây điện của máy tính đã xác định vấn đề nào máy tính sẽ giải quyết. Người ta phải tua lại mạch điện để thay đổi chương trình. Một nhiệm vụ rất khó khăn. Bước tiến tiếp theo trong thiết kế máy tính là hệ thống máy tính có thể lập trình, một hệ thống cho phép lập trình viên máy tính dễ dàng "tua lại" hệ thống máy tính bằng cách sử dụng một chuỗi các ổ cắm và dây cắm. Một chương trình máy tính bao gồm một tập hợp các hàng lỗ (ổ cắm), mỗi hàng đại diện cho một thao tác trong quá trình thực thi chương trình. Lập trình viên có thể chọn một trong một số hướng dẫn bằng cách cắm dây vào ổ cắm cụ thể cho hướng dẫn mong muốn.

Sau đó, anh ta chứng minh khá hấp dẫn và về chiều dài, đôi phích cắm đầu tiên đại diện cho hướng dẫn, các phích cắm tiếp theo mã hóa nguồn và đích. Tất nhiên, ngày nay không còn ai "cắm" nữa, nhưng đối với các ISA thực sự cũ, các bit trong opcode về cơ bản thực hiện công việc tương tự như các lần cắm trước đó.

Bạn kết thúc với một cái gì đó như thế này:

nhập mô tả hình ảnh ở đây


Cảm ơn bạn đã liên kết từ Hyde! Nó rất nhiều thông tin và anh ấy dường như có một phong cách giảng dạy tuyệt vời.
Steven
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.