NAND2Tetris:带你从零开始手搓计算机之项目3——搭建RAM:内存
总述
在前面两个项目中,我们构建的布尔芯片(最基本的逻辑门)和算术芯片(ALU)本质上都是组合芯片,即用组合逻辑电路实现的,这些芯片可以通过逻辑运算来实现对应的逻辑功能,但是它们却不能维持自身的状态。计算机不能仅仅只能计算值,还需要存储数据,这些芯片需要配备记忆单元来保存数据,这些记忆单元就是由时序芯片来组成的。
在本个项目中,我们将通过一个简单的D触发器,来一步步构建一个一位寄存器、十六位的寄存器、再通过寄存器来构建大的随机存储内存单元,也就是RAM(Random access memory),在RAM上,我们可以随机访问被选择的字,而不会受限访问顺序(这要求我们查找存储地址)。这个项目的重点和难点在于在满足电路逻辑功能的基础上,我们添加了时钟这一增量,如何在我们的HDL代码中体现时钟的作用,就需要我们进一步深入的思考。
在这个项目中,我们会构建一个由8个寄存器堆叠的RAM8,然后进一步构建一个64个存储器堆叠的RAM64,然后到RAM512、RAM4K、RAM16K,这里涉及到一个分层设计的思想,拾级而上,对我们解决大型的项目有帮助。
Bit——一位的寄存器
1 | /** |
dffOut是D触发器在时钟触发的输出,我们用一个Mux选择器,来实现对D触发器输入的更改。
当load=0的时候,muxOut = dffOut,也就是说不管我的in如何修改,我们都不会存储这个数据,下一次的输出还是和上一次保持一样,当load=1的时候,muxOut = in,也就是存储功能开启,存储器会保存这个输入数据到输出。
最后一个Or门其实就是让out=dffOut,因为在我们的语法中,不允许out作为另外门的输入。
Register
1 | /** |
这个没什么好说的,16位的寄存器。
RAM8
1 | /** |
RAM是由寄存器堆叠而成的存储单元,我们可以对其中的每一个寄存器进行操作,所以要求我们必须去寻址,找到我们对应操作的那个寄存器的地址。
这是一个由8个寄存器堆叠而成的存储单元。第一步我们用DMux8分路器来告诉我们的存储单元要操作哪个寄存器(把load赋给我们想操作的那个数),如果load=0,输入再怎么变都是没有用的。
最后呢,我们用一个16位的8路多路复用器来进行输出的挑选。
RAM64
1 | /** |
我们思路是这样的:把64个寄存器分8组,我们用address的最高三位来表示选择哪组的8个寄存器。然后再用RAM8对着8个寄存器进行操作,总体的方法还是一样的。弄懂了这个,整个分层设计的思路就没有任何问题了。
RAM512
1 | /** |
RAM4K
1 | /** |
RAM16K
1 | /** |
PC——计数器
1 | /** |
其实计数器的芯片接口和寄存器的很类似,但是计数器芯片有两个附加的控制位reset和inc。当inc=1,计数器在每个时间周期自加;如果想要把计数器赋值为0,就把reset置为1;如果想要将计数器保持在某个值d,那就应该在输入端赋给in这个值,然后load置为1。
-------------本文结束感谢您的阅读-------------
本文链接: https://blog.visionary-5.top/2024/10/28/NAND2Tetris%E2%80%94%E2%80%94project3/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!
