2009-06-10 40 views
8

Tôi cần tạo một ứng dụng để tạo các mạch logic và xem kết quả. Điều này chủ yếu được sử dụng trong các khóa học điện toán A-Level (Anh, 16-18 tuổi nói chung). Tôi không bao giờ thực hiện bất kỳ ứng dụng như thế này, vì vậy tôi không chắc chắn về thiết kế tốt nhất để lưu trữ mạch và đánh giá kết quả (ở tốc độ có thể phục hồi, nói 100Hz trên máy tính lõi đơn 1.6Ghz). Thay vì có mạch được xây dựng từ các cổng cơ bản (và, hoặc, và, vv) Tôi muốn cho phép các cổng này được sử dụng để tạo "chip", sau đó có thể được sử dụng trong các mạch khác (ví dụ: bạn có thể muốn để tạo chip đăng ký 8 bit hoặc bộ thêm 16 bit).Tạo trình mô phỏng cổng logic

Vấn đề là số cổng tăng ồ ạt với các mạch như vậy, nếu mô phỏng làm việc trên mỗi cổng riêng biệt, nó sẽ có 1000 cổng để mô phỏng, vì vậy tôi cần đơn giản hóa các thành phần này mạch để chúng có thể được mô phỏng nhanh chóng.

Tôi nghĩ về việc tạo bảng chân lý cho từng thành phần, sau đó mô phỏng có thể sử dụng bảng tra cứu để tìm kết quả đầu ra cho một đầu vào nhất định. Vấn đề xảy ra với tôi mặc dù kích thước của các bảng như vậy tăng mạnh với đầu vào. Nếu một chip có 32 đầu vào, thì bảng chân lý cần 2^32 hàng. Điều này sử dụng một lượng lớn bộ nhớ trong nhiều trường hợp hơn là sử dụng như vậy là không thực tế cho các thành phần không tầm thường, nó cũng sẽ không hoạt động với các chip có thể lưu trữ trạng thái của chúng (ví dụ như các thanh ghi) vì chúng không thể được biểu diễn đơn giản bảng đầu vào và đầu ra.

Tôi biết tôi chỉ có thể mã hóa những thứ như chip đăng ký, tuy nhiên vì mục đích giáo dục tôi muốn nó để mọi người có thể tạo thành phần của riêng họ cũng như xem và chỉnh sửa triển khai cho các chuẩn. Tôi đã xem xét cho phép tạo ra và chỉnh sửa các thành phần như vậy bằng cách sử dụng mã (ví dụ: dll hoặc ngôn ngữ kịch bản), để một trình bổ sung ví dụ có thể được biểu diễn dưới dạng "output = inputA + inputB", tuy nhiên giả định rằng các sinh viên đã thực hiện đủ chương trình ngôn ngữ đã cho để có thể hiểu và viết các plugin như vậy để bắt chước các kết quả của mạch của chúng, đó là không phải là trường hợp ...

Có cách nào khác để thực hiện một mạch logic boolean và đơn giản hóa nó một cách tự động sao cho mô phỏng có thể xác định đầu ra của một thành phần một cách nhanh chóng?

Để lưu trữ các thành phần, tôi đã nghĩ đến việc lưu trữ một số loại cấu trúc cây, sao cho mỗi thành phần được đánh giá khi tất cả các thành phần liên kết với đầu vào của nó được đánh giá.

ví dụ như xem xét: AB + C Các mô phỏng sẽ đầu tiên đánh giá cổng AND, và sau đó đánh giá HOẶC cổng sử dụng đầu ra của cổng AND và C.

Tuy nhiên nó chỉ xảy ra với tôi rằng trong trường hợp các kết quả đầu ra liên kết ngược với đầu vào, sẽ gây ra bế tắc vì có đầu vào sẽ không bao giờ được đánh giá ... Làm thế nào tôi có thể khắc phục điều này, vì chương trình chỉ có thể đánh giá một cổng tại một thời điểm?

+0

Tôi tự hỏi ... trong một trình mô phỏng phổ quát như vậy, sẽ không thể tạo ra "buzzer" (thuật ngữ tự phát minh)? Đó là một số mạch mà bật và tắt càng nhanh càng tốt. Nếu vậy, bạn cũng sẽ cần phải thiết lập một cái gì đó giống như một khung tham chiếu thời gian, nếu không kết quả có thể không được xác định ... –

+0

Ahh, tôi đã nghĩ về một kế hoạch như vậy. Hãy tưởng tượng một cổng XOR nơi đầu ra của nó được kết nối với một trong các đầu vào của nó và đầu vào khác là điều khiển do người dùng điều khiển. Ngay khi người dùng đưa 1 cho đầu vào có thể điều khiển, cổng XOR sẽ tự động. Hành vi đúng trong trường hợp này là gì? –

+0

Err, không xác định. Chắc chắn điều duy nhất để làm sau đó là phát hiện ra nó và nói với người sử dụng nó không được phép? Actaully theo một mô phỏng hiện tại (http://www.tetzl.de/java_logic_simulator.html) đầu ra là số không, mà im chắc chắn là không thực sự là trường hợp ... –

Trả lời

1

Nếu bạn không thể cho phép vòng lặp (đầu ra liên kết ngược lại đầu vào), bạn có thể đơn giản hóa đáng kể sự cố. Trong trường hợp đó, đối với mọi đầu vào sẽ có chính xác một đầu ra xác định. Chu kỳ tuy nhiên có thể làm cho sản lượng không thể tách rời (hay đúng hơn, liên tục thay đổi).

Đánh giá mạch không có vòng phải dễ dàng - chỉ cần sử dụng thuật toán BFS với "nút nối" (kết nối giữa các cổng logic) như các mục trong danh sách. Bắt đầu với tất cả các yếu tố đầu vào cho tất cả các cổng trong trạng thái "không xác định". Ngay sau khi một cổng có tất cả các đầu vào "được xác định" (hoặc 1 hoặc 0), tính toán đầu ra của nó và thêm các nút đầu ra của nó vào danh sách BFS. Bằng cách này bạn chỉ phải đánh giá mỗi cổng và mỗi điểm giao nhau một lần.

Nếu có vòng, các thuật toán tương tự có thể được sử dụng, nhưng các mạch có thể được xây dựng theo cách như vậy mà nó không bao giờ nói đến một "nghỉ ngơi" và một số nút giao thông luôn luôn thay đổi giữa 1 và 0.

OOps, trên thực tế, thuật toán này không thể được sử dụng trong trường hợp này bởi vì các cổng lặp (và cổng tùy thuộc vào chúng) sẽ mãi mãi ở lại là "không xác định".

+0

Có vẻ như một kế hoạch tốt, tôi chỉ cần một số loại phát hiện vòng lặp vô tuyến để bắt mạch không ổn định, do đó quá trình đánh giá không bị kẹt trong vòng lặp vô tuyến, vì tôi không muốn đi sâu vào chi tiết về thời gian thay đổi trạng thái và nội dung như thế. –

+0

Giả sử tôi có thể bắt sự kết hợp không ổn định, những gì về việc chỉ có một danh sách các cửa "bẩn". Khi đầu vào cho một cổng được thay đổi, nó được đánh dấu là bẩn. Nếu sau khi đánh giá nó đầu ra là khác nhau từ đầu ra trước đó, đánh dấu cửa whoose đầu vào chỉ thay đổi bẩn. Vòng lặp đó có thể đạt được kết quả ổn định một cách chính xác không? –

+0

Huh? Không bắt được ý tưởng của bạn ở đó. Nói - bạn sẽ sẵn sàng trả bao nhiêu cho một ứng dụng như vậy? Có lẽ tôi có thể viết nó cho bạn? :) –

5

Bạn đã xem Richard Bowles's simulator chưa?

+0

Tìm kiếm tuyệt vời! Tôi đã có điều này trong lớp thiết kế kỹ thuật số của mình ... – samoz

+0

Theo như tôi có thể nói những giới hạn của việc ngăn chặn các vấn đề tôi gặp phải (ví dụ số cổng hạn chế trong mạch do lưới nhỏ, và không có dây dẫn từ phải sang trái, vì vậy bạn không thể tạo vòng giữa các cửa khi cần thiết bằng cách nói một Flip Flop D thực hiện với cổng NAND) –

1

Bạn có thể mã hóa tất cả các thông dụng phổ biến. Sau đó, cho phép họ xây dựng riêng của họ ra khỏi những người được mã hóa cứng (trong đó sẽ bao gồm các cổng cấp thấp), mà sẽ được đánh giá bằng cách đánh giá từng thành phần phụ. Cuối cùng, nếu một trong các "chip" của họ có ít hơn X đầu vào/đầu ra, bạn có thể "tối ưu hóa" nó vào bảng tra cứu. Có thể phát hiện mức độ phổ biến của nó và chỉ làm điều này cho các chip Y được sử dụng nhiều nhất? Bằng cách này bạn có một sự cân bằng tốc độ/không gian tốt.

Bạn luôn có thể biên dịch các mạch ...Khi tôi chưa thực sự nghĩ về nó, tôi không thực sự chắc chắn phương pháp tiếp cận tôi sẽ mất .. nhưng nó sẽ có thể là một phương pháp lai và tôi chắc chắn sẽ khó mã phổ biến "chip" trong quá.

+0

Đó là một kế hoạch tốt, tôi cũng có thể có triển khai mạch logic cho những người hardcoded, để họ không "xuất hiện" hardcoded (tức là các sinh viên vẫn có thể đi sâu vào chúng để xem cách đăng ký được thực hiện). –

+0

"Bạn luôn có thể JIT biên dịch các mạch ..." thats loại của những gì tôi đã suy nghĩ của "tự động đơn giản chỉ cần nó". Tuy nhiên Ive không bao giờ viết một trình biên dịch hay thông dịch viên trong cuộc sống của tôi. Sẽ có bao nhiêu công việc để phân tích một mạch và tạo ra mã cần thiết để biểu diễn nó, cho rằng kết quả của một mạch có thể phức tạp hơn nhiều so với một biểu thức đơn giản cho rằng các vòng có thể lưu trữ các bit. –

+0

Tôi sẽ sử dụng LLVM hoặc một số "công cụ JIT" khác để thực hiện các biên dịch JIT. LLVM "bytecode" cũng có thể gọi hàm C. Bạn có thể phân tích một cách thô sơ mạch để tạo ra một chuỗi các phép toán boolean - điều này sẽ khá dễ dàng để chuyển sang LLVM sau đó. Làm thế nào dễ dàng hoặc khó khăn là để xác định các hoạt động logic, tôi không biết - đặc biệt là nếu bạn có vòng phản hồi và như vậy. Sẽ khá thú vị mặc dù! Nếu bạn cuối cùng làm "cái gì đó" như thế, tôi rất muốn nghe về nó. – Dan

1

Bạn có thể giới thiệu khái niệm về bản đồ Karnaugh, điều này sẽ giúp họ đơn giản hóa các giá trị chân lý cho bản thân.

2

Bạn có thể muốn xem qua phần mềm Từ Nand To Tetris trong 12 bước. Có một video nói về nó trên youtube.

Trang dĩ nhiên là tại địa chỉ: http://www1.idc.ac.il/tecs/

+0

Tôi không thể khuyên bạn nên cuốn sách này đủ cao và điều này cũng có vẻ là sự đồng thuận của tất cả những người khác đã đọc nó. (Kiểm tra đánh giá của mình trên Amazon.) – Dinah

2

Bạn không phải là người đầu tiên muốn xây dựng mô phỏng mạch của mình ;-).

Đề xuất của tôi là giải quyết trên một nhóm tối thiểu các nguyên thủy. Khi tôi bắt đầu tôi (mà tôi dự định sẽ tiếp tục là một trong những ngày này ...) Tôi có hai nguyên thủy:

  • Nguồn: zero đầu vào, một đầu ra đó là luôn 1.
  • Transistor: hai đầu vào AB , một đầu ra là A and not B.

Rõ ràng là tôi đang lạm dụng thuật ngữ một chút, chưa kể đến việc bỏ qua những tính năng của thiết bị điện tử. Vào điểm thứ hai, tôi khuyên bạn nên tóm tắt các dây mang 1s và 0 như tôi đã làm. Tôi đã có rất nhiều biểu đồ vẽ thú vị của cổng và người bổ sung từ chúng. Khi bạn có thể lắp ráp chúng thành các mạch và vẽ một hộp tròn đặt (với đầu vào và đầu ra), bạn có thể bắt đầu xây dựng những thứ lớn hơn như nhân.

Nếu bạn muốn bất cứ điều gì với các vòng bạn cần phải kết hợp một số loại chậm trễ - vì vậy mỗi thành phần cần lưu trữ trạng thái đầu ra của nó. Trên mỗi chu kỳ bạn cập nhật tất cả các trạng thái mới từ trạng thái hiện tại của các thành phần ngược dòng.

Sửa Về mối quan tâm của bạn về khả năng mở rộng, làm thế nào về mặc định cho các nguyên tắc đầu tiên phương pháp mô phỏng mỗi thành phần về xóm nhà nước và thượng nguồn của nó, nhưng cung cấp cách subcircuits tối ưu hóa:

  • Nếu bạn có một subcircuit S với đầu vào A[m] với m < 8 (nói, cho tối đa 256 hàng) và đầu ra B[n] và không có vòng lặp nào, tạo bảng chân lý cho S và sử dụng. Điều này có thể được thực hiện tự động cho các mạng con được xác định (và được tái sử dụng nếu subcircuit xuất hiện nhiều lần) hoặc theo sự lựa chọn.

  • Nếu bạn có một mạng con với vòng lặp, bạn vẫn có thể tạo bảng chân lý. Có các phương pháp tìm điểm cố định có thể trợ giúp ở đây.

  • Nếu subcircuit của bạn có sự chậm trễ (và chúng quan trọng đối với mạch kèm theo) bảng chân lý có thể kết hợp các cột trạng thái. Ví dụ.nếu subcircuit có đầu vào A, trạng thái bên trong B và đầu ra C, trong đó C < - A và B, B < - A, bảng chân lý có thể là:

    A B | B C
    0 0 | 0 0
    0 1 | 0 0
    1 0 | 1 0
    1 1 | 1 1

  • Nếu bạn có một subcircuit mà người dùng khẳng định thực hiện một mô hình cụ thể được biết đến như "adder", cung cấp một tùy chọn để sử dụng thực thi mã hóa cứng để cập nhật subcircuit thay vì bằng cách mô phỏng các phần bên trong của nó.

+0

Vâng, tôi đã lên kế hoạch cho mỗi dây, cũng chỉ có một dây. Cá nhân tôi thích cái nhìn của 8 dây song song với một màu cho 1 hoặc 0 trên một dây mà "đại diện" 8 và màu không mã hóa như được thấy trong một số mô phỏng. Obv Tôi sẽ bắt đầu chỉ với một công tắc, đèn LED, các cổng và dây cơ bản. Tuy nhiên tôi cần một thiết kế mà sẽ quy mô cho các thành phần phức tạp hơn, và ý tưởng đầu tiên của tôi về các bảng chân lý không. –

1

Khi tôi đang chơi xung quanh tạo ra môi trường mô phỏng "mạch kỹ thuật số", tôi đã có từng mạch được xác định (cổng cơ bản, mux, demux và một vài nguyên thủy khác) liên quan đến chức năng truyền (tức là, chức năng tính toán tất cả các kết quả đầu ra, dựa trên các đầu vào hiện tại), một cấu trúc "chương trình nghị sự" (về cơ bản là một danh sách liên kết "khi nào kích hoạt một chức năng truyền cụ thể), dây ảo và đồng hồ toàn cầu",

Tôi tự ý đặt dây để sửa đổi cứng đầu vào bất cứ khi nào đầu ra thay đổi và hành động thay đổi đầu vào trên bất kỳ mạch nào để lên lịch cho chức năng truyền được gọi sau khi trì hoãn cổng. phần tử được đặt để có chức năng truyền của nó chạy ở "ne xt đồng hồ chuyển đổi, cộng với cổng chậm trễ ", bất kỳ yếu tố không bị ép nào chỉ phụ thuộc vào độ trễ cổng).

Không bao giờ thực sự có xung quanh để xây dựng một GUI cho nó, vì vậy tôi đã không bao giờ phát hành mã.

+0

Đối với bao nhiêu người trong chúng ta đã bắt đầu một dự án như thế này, nó đáng kinh ngạc như thế nào vài người đã phát hành nó. Tôi cũng có tội. – Dinah

2

Khi tôi thực hiện một mô phỏng mạch (buồn thay, cũng không đầy đủ và cũng chưa được phát hành), dưới đây là cách tôi xử lý vòng:

  • Mỗi phần tử mạch lưu trữ giá trị boolean của nó
  • Khi một yếu tố "E0" thay đổi của nó giá trị, nó sẽ thông báo (qua mô hình quan sát viên) tất cả những ai phụ thuộc vào nó
  • Mỗi phần tử quan sát đánh giá giá trị mới của nó và làm tương tự như vậy

Khi thay đổi E0 xảy ra, một level-1 danh sách được lưu giữ của tất cả các yếu tố bị ảnh hưởng.Nếu một phần tử đã xuất hiện trong danh sách này, nó sẽ được ghi nhớ trong một danh sách cấp 2 mới nhưng không tiếp tục thông báo cho các quan sát viên của nó. Khi chuỗi E0 bắt đầu đã ngừng thông báo cho các phần tử mới, mức xếp hàng tiếp theo sẽ được xử lý. Tức là: trình tự được theo sau và hoàn thành cho phần tử đầu tiên được thêm vào cấp 2, sau đó được thêm vào cấp 2, v.v. cho đến khi tất cả cấp độ x hoàn tất, sau đó bạn chuyển sang cấp- (x + 1)

Điều này hoàn toàn không có cách nào. Nếu bạn đã từng có nhiều bộ dao động làm vòng lặp vô hạn, thì dù bạn đặt chúng theo thứ tự nào đi chăng nữa, người ta có thể ngăn cản người kia đến lượt nó. Mục tiêu tiếp theo của tôi là giảm bớt điều này bằng cách giới hạn các bước với đồng bộ hóa dựa trên đồng hồ thay vì kết hợp tầng, nhưng tôi chưa bao giờ đạt được điều này trong dự án của mình.

Các vấn đề liên quan