由于您主要关心的似乎是学习微控制器设计,因此一个好的方法可能是查看一些早期的微处理器模型。以Z80为例:
为了回答您的第一个问题(单总线与多总线),该芯片对所有事物都使用单总线,并且设计非常简单。您可能可以使用类似的东西。为了明确术语,单个系统总线可能由子总线(它们也称为总线)组成。该图显示了由双向数据总线(8 位宽)和地址总线(16 位宽)组成的系统总线。
要回答您的第二个问题(组件如何知道它们何时处于活动状态),在上图中,您会看到两个不同的信号,内存请求和 I/O 请求。一次只有一个处于活动状态,当 I/O 请求处于活动状态时,即可能访问外围设备。
如果您没有很多外围设备,则不需要使用所有 16 个地址线(一些 Z80 具有 8 位 I/O 空间)。每个外围设备都将通过该空间中的一些地址进行访问。例如,在一个非常简单的系统中:
- 定时器外设可以使用从 00h 到 03h 的地址
- 一个uart可以寻址08h到0Fh
在这个简单的例子中,您需要提供两个电路:一个会检测地址何时在 00-03h 范围内,另一个会检测 08-0Fh。如果您在每个检测器的输出和 I/O 请求信号之间执行逻辑“与”,那么您将有两个信号指示何时访问每个外围设备。您的外围硬件应主要收听此信号。
最后,关于您关于指令的问题,微处理器内部的数据流将有几个阶段。这通常称为处理器的数据路径。通常将阶段分为:
- FETCH:从程序存储器中读取一条指令
- 解码:检查指令中的特定位,并确定它是什么类型的指令
- EXECUTE:执行指令要求的动作(例如,ALU 操作)
- MEMORY:对于某些指令,您需要进行数据读取或写入
- 写回:用受指令影响的新值更新你的 CPU 寄存器
资料来源:https ://www.cs.umd.edu/class/fall2001/cmsc411/projects/DLX/proj.html
您处理单个指令的大部分工作将在解码和执行阶段完成。至于数据路径控制,您将需要一个状态机来控制 5 个阶段的操作顺序。该功能块通常称为控制单元。在这里你有几个选择:
- 您的状态机可以按顺序通过所有阶段,一次一个。一条指令需要几个时钟周期才能执行。
- 与上面的选择类似,但如果您想让事情变得更简单和更快,可以在一个周期中组合两个或多个阶段。
- 流水线指令的执行。这可以大大提高速度,但也许最好留到以后,因为事情会变得相当复杂。
至于实现,我建议将功能块保留为单独的实体,并确保为每个块编写一个测试台。如果您编写这些测试平台,您的工作会更快。
至于块,寄存器文件很容易编码。如果您清楚地了解指令布局和操作码,指令解码器也很容易。如果您知道它需要执行的操作,ALU 也很容易。
我将从为指令解码器和寄存器文件编写测试平台开始。然后我会编写一个脚本来运行所有的测试平台并自动检查它们的结果。只有这样我才会专注于功能块本身的实现。