动手设计 CPU(三)—— 微程序控制的存储器读写系统设计

一、架构设计

在设计完第一个练习架构 — 微程序控制的运算器设计 之后,我们进入了第二个架构的设计过程 — 微程序控制的存储器读写系统设计,接下来我们来探讨一下如何进行实现。

下图为我们将要设计的微程序控制的运算器的整体架构。

动手设计 CPU(三)—— 微程序控制的存储器读写系统设计
根据上述的架构,我们暂用下述的指令进行设计。
动手设计 CPU(三)—— 微程序控制的存储器读写系统设计
上述架构的整体逻辑是,uPC+CROM+uIR 选出一个指令,然后根据 XPCXMAR 两个信号从数据选择器中选出 PC 中或 MAR 中的地址,根据选出的地址,对 RAM 进行读取或写入。

其中 R 寄存器 用于存数,MAR 用于存地址,因此我们需要利用上述这个架构实现下述 4 个指令。

  1. 从 0 号单元中取出 Ad1 放入 MAR
  2. 将 MAR 地址传入 RAM 中,取出对应数据,存入 R 寄存器
  3. 从 1 号单元中取出 Ad2 放入 MAR
  4. 将 R 寄存器中数据存入 MAR 中对应的地址单元

我们再次将上述电路中的元件分离,逐一实现 R、MAR、PC、RAM、数据选择器,具体实现逻辑如下所示。

二、元件实现

(1) R 寄存器

我们通过封装 74374 — 锁存器的输入输出来实现 R 寄存器,该寄存器的主要特点在于 OEN 的三态允许控制端,比普通的寄存器更适合应用在 CPU 设计中。
动手设计 CPU(三)—— 微程序控制的存储器读写系统设计
封装一下,即可得到下述的 R 寄存器。
动手设计 CPU(三)—— 微程序控制的存储器读写系统设计

(2) MAR 地址寄存器

对比 R 寄存器使用了锁存器,MAR 寄存器则可以直接使用普通的寄存器完成,即直接调用 74273 进行实现,主要目的就是封装输入、输出端。
动手设计 CPU(三)—— 微程序控制的存储器读写系统设计
封装一下,即可得到下述的 MAR 寄存器。
动手设计 CPU(三)—— 微程序控制的存储器读写系统设计

(3) PC 指令寄存器

PC 指令寄存器与第二篇文章中所实现的 uPC 没有较大差别,因此我们直接对 74161 进行封装即可,主要目的仍然是封装输入、输出端,让电路设计地更加间接。
动手设计 CPU(三)—— 微程序控制的存储器读写系统设计
封装一下,即可得到下述的 PC 指令寄存器。
动手设计 CPU(三)—— 微程序控制的存储器读写系统设计

(4) RAM

与 ROM 的设计过程一致,点击下图的按钮,根据流程即可设计 1-port 的 RAM,此处设计部分为 Quartus 应用的操作,不明白的可以继续查询网上资料,此处不再赘言。
动手设计 CPU(三)—— 微程序控制的存储器读写系统设计
最后的设计成果如下所示。
动手设计 CPU(三)—— 微程序控制的存储器读写系统设计
这里有两个地方需要注意一下。

  • wren 低电平时读允许,高电平时写允许。
  • CLK 下降沿打入

(5) 数据选择器

此处我们需要实现二选一的数据选择器,即按照每一位进行与运算,从而选出我们想要的数据,实现思路较为简单,具体电路如下所示。
动手设计 CPU(三)—— 微程序控制的存储器读写系统设计
封装一下,即可得到对应的二选一数据选择器。
动手设计 CPU(三)—— 微程序控制的存储器读写系统设计

三、完整电路实现

设计完上述的 5 个元件之后,再根据最开始给出的架构,即可搭建出我们要设计的架构 微程序控制的存储器读写系统设计,具体搭建电路如下。
动手设计 CPU(三)—— 微程序控制的存储器读写系统设计
其中可以发现,指令中的 WR 和 RD 被合并成了一个 bitbit,其实 XPC 和 XMAR 也可以合成一个 bitbit,但是为了设计方便,此处没有进行合并。

除此之外,需要仔细关注三个时钟输入端。在一开始的设计中,CLK1 和 CLK2 其实是设计成同一个输入端的,但是由于延迟的存在,可能会发生 IR 的信号还没传过来,CLK2 的上升沿就到了,导致传递出去的信号仍然是旧的 IR 信号,从而导致错误。

如下图所示,PC 突然发生了变化便是由于延迟的问题,调了好久才找到原因…T^T
动手设计 CPU(三)—— 微程序控制的存储器读写系统设计
正因为上述的原因,最后将 CLK1、CLK2、CLK_ram 三个时钟端进行了分离,才成功仿真成功!

四、仿真测试

CROM 指令预存

动手设计 CPU(三)—— 微程序控制的存储器读写系统设计
此处的 4 条指令便执行了文章开头要求实现的 4 条指令。

  1. 从 0 号单元中取出 Ad1 放入 MAR
  2. 将 MAR 地址传入 RAM 中,取出对应数据,存入 R 寄存器
  3. 从 1 号单元中取出 Ad2 放入 MAR
  4. 将 R 寄存器中数据存入 MAR 中对应的地址单元

RAM 数据预存

动手设计 CPU(三)—— 微程序控制的存储器读写系统设计

仿真结果

将上述数据导入存储器中,再按下述波形调整 CLK1、CLK2、CLK_ram 三个波形,即每一次先执行 CLK1 传入指令,再执行 CLK_ram 输出结果,最后执行 CLK2 将数据传入对应寄存器中。

观察 PC_out、mar_out、R_out、ran_out 不难发现上述指令均执行成功!
动手设计 CPU(三)—— 微程序控制的存储器读写系统设计

五、总结

至此,我们即实现了 微程序控制的存储器读写系统设计 的架构,与上一个架构一致,没有太大难度,主要的目的仍然是熟悉环境,并且设计一些基础元件,例如 MAR、PC、RAM 等。

除此之外,对比第一个架构,这个架构的设计过程中,时钟安排对结果的影响更加明显,这要求我们在之后的设计中,一定要仔细观察时钟,不能将时钟瞎合并,否则会因为延迟导致出错。

CPU 设计第三篇结束,旅程仍在继续!????????????