LogiSim 中非常简单的 CPU 设计

电器工程 设计 微处理器 逻辑西姆
2022-02-04 13:55:22

我目前正在读高中,我一直对计算机/电气工程感兴趣,特别是微处理器设计。我已经阅读了 Charles Petzold 的 Code,并开始阅读Microprocessor Design Wikibook(似乎不完整)。通过阅读Code,我了解了 CPU 背后的基本逻辑,并开始在 LogiSim 中构建一个。代码中的第 17 章详细介绍了我想要构建的 CPU,但电路缺少关键组件——时钟信号和指令解码。一些时钟信号似乎很明显(PC 似乎需要一个稳定的时钟信号)但其他的(比如如何锁存 RAM 值)我必须仔细考虑并尝试开始工作。

我可以构建一个工作累加器(我认为它不能准确地称为 ALU,因为它缺少 L 部分)通过单个输入在加法和减法之间切换,我知道这就是算术部分所需要的全部-- 一旦我让跳转操作码工作,我就可以在代码中实现乘法和除法。我正在努力的部分是指令解码。通过一些谷歌搜索,我看到每个操作码都需要被解释为多个微指令,但我不知道我需要如何工作。目前,我的指令解码器只是一个组合分析电路,每个操作码都有一个二进制输出——总共 13 个。

代码的工作方式是它有一个 8 位代码值(我只使用低端字节),然后是两个单独的 8 位地址值,然后我将它们组合为 RAM 的 16 位地址输入。为了锁存这些值,我有一个单独的计数器,最多计数 10b,然后重置为 00b。依次是每个锁存器的时钟输入(对于三个锁存器,有a、b和c。第二个时钟a为1,b&c为0,则b为1,1&c为0,则c 为 1 且 1 & b 为 0,然后重置)。但是在诸如 ADD 000Ah 之类的指令上,PC 会跳转到 000AH……这应该是添加到累加器中的,但实际上被锁到了代码锁存器中,然后被解释为下一个操作码,这使得整个事情顺利进行疯狂的。

我觉得我错过了一些关于指令解码以及我需要如何处理时钟信号的重要信息......

以下是 LogiSim .circ 文件: https://dl.dropboxusercontent.com/u/61676438/PetzoldMk5/8BitAdder.circ https://dl.dropboxusercontent.com/u/61676438/PetzoldMk5/8BitAdderSubtractor.circ https:// dl.dropboxusercontent.com/u/61676438/PetzoldMk5/8BitInverter.circ https://dl.dropboxusercontent.com/u/61676438/PetzoldMk5/8BitLatch.circ https://dl.dropboxusercontent.com/u/61676438/PetzoldMk5/ ID.circ https://dl.dropboxusercontent.com/u/61676438/PetzoldMk5/PetzoldMk5.circ

PetzoldMk5 是主 CPU,依赖于其他文件作为库导入。

以下是操作码列表(均为二进制):

Load                 0001
Add                  0010
Add w/ Carry         0011
Sub                  0100
Sub w/ Borrow        0101
Jump                 0110
Jump w/ Carry        0111
Jump W/ 0            1000
Jump w/o C           1001
Jump W/o 0           1010
Store                1011
Halt                 1100
Reset                1101
3个回答

讨厌发布“仅链接”之类的答案,但我认为您应该了解 Warren Toomey 在 Logisim 中使用 CPU 的工作,因为它可能正是您正在寻找的。

他有几个教程建立一个相当简单的 CPU 在这里......

http://minnie.tuhs.org/CompArch/Tutes/

如果这不能让你的船浮起来,他在这里有一个更复杂的 CPU……

http://minnie.tuhs.org/Programs/UcodeCPU/

...所有这些都得到了很好的解释,并且可以下载到 .circ 文件。


另一个很棒的、可以说功能更强大的 DIY CPU/计算机是http://www.homebrewcpu.com/上的Magic-1 虽然它不是在 Logisim 中完成的,但它有很好的文档记录,包括图片、示意图、描述。它也不仅仅是模拟器中的 CPU。它有一个 ANSI C 编译器、一个操作系统和一些软件。它还具有实际内置硬件的明显优势。事实上,它目前已启动并运行并提供网页服务!


最后,计算系统的元素和相关网站nand2tetris.org是我每次研究时从头开始构建自己的计算机的第一推荐信息资源。我相信很多(全部?)内容都是免费的。YouTube 会同意;许多人从这一来源开始制作项目。

我认为您错过了 ALU 如何工作的一个关键方面。通常累加器的每一位通过解复用器连接到各种功能块中的每一个。使用命令字节选择功能,累加器的每一位都连接到功能块的正确输入。解复用器的大小决定了 ALU 可以处理多少功能。在下面显示的非常粗略的示例中,具有 4 位输入的 ALU 可以使用解复用器引用 16 个不同的函数:

将累加器连接到 ALU 中的各种功能块

请注意,在大多数 CPU 中,这种设计被优化成一堆门,以减少晶体管数量。

拥有更大的命令寄存器可以使用更多的功能,但这也需要更多的时钟周期来加载命令。

如果您想了解有关数字设计的更多信息,我强烈建议您阅读以下书籍:逻辑设计基础第 7 版。

看来你是在正确的道路上。

当您计划您的微指令时,您需要在自己的脑海中清楚地定义数据通过各个块移动的“流量”模式。执行 ADD 需要多个步骤。如果您有两个 ALU 操作数的保存寄存器,那么需要从 RAM 或某个寄存器或总线加载这些寄存器。如果您有共享的内部总线,那么您可能需要一次加载一个操作数。一旦您知道哪些字节(地址、立即数、RAM 数据、指针)需要移动到哪里,就可以计划字节通过总线进出各个寄存器的顺序。您可能会卡住并需要添加一个内部保持寄存器,因为必须保留一些中间值直到下一个微指令步骤。

我认为您怀疑缺少的是逻辑将指令或操作码转换为 CPU 内的多个状态所需的复杂性。它可能很复杂,但可以创建一个稍微简单的状态机,然后用基本的逻辑概念对其进行扩展。

例如,假设您正在为 MOVE 操作创建微指令步骤。这可以通过 3 个步骤大致描述:1)将源寄存器内容断言到内部总线,2)选通目标寄存器的写时钟,3)从内部总线取消断言源寄存器内容。步骤 1) 到 3) 描述了寄存器输出使能 (OE) 和寄存器写使能 (WE) 的时序,它们可以选择性地分配到任何源寄存器和任何目标寄存器,这些寄存器连接到具有多路分解器的共享内部总线。

如果您没有太多创建有限状态机的实践,那么查看不同的方法可能会很有用,这些方法可以为您提供另一个构建块,以从您的微序列器生成控制信号。

坚持下去。你获得的知识量将是惊人的。希望你会玩得开心。