【问题标题】:Bus protocol for a microcontroller in VHDLVHDL中微控制器的总线协议
【发布时间】:2013-10-12 15:00:39
【问题描述】:

我正在用 VHDL 设计一个微控制器。我现在了解每个组件(ALU/内存...)的作用,以及如何实现它们的一些想法。我基本上想实现一个冯诺依曼架构。

但这是我不明白的:组件如何通信?我不知道如何设计我的公共汽车(公共汽车?)。因此,我正在寻找一种简单的总线实现和协议。

我未解决的问题:

  • 使用一条总线处理所有事情更简单还是分离不同类型的数据更简单?
  • 每个组件如何知道何时“听”和何时“写”?

重点在于设计(以及实现)的简单性。我不在乎速度。我想从头开始做所有事情(即没有预先制作的软核)。

我不知道这在这个阶段是否重要,但它不需要运行“真正的”编译代码,与现有的任何东西有任何兼容性。另外,我什么时候开始考虑我的“组装”指令?我想我会把它们直接加载到内存中。

感谢您的帮助。

编辑: 我最终从Picoblaze 中获得了(很多)灵感,因为它是:

  • 简单易懂
  • 根据 BSD 许可证

具体来说,我首先添加了一些指令。

【问题讨论】:

    标签: vhdl microcontroller fpga bus


    【解决方案1】:

    由于您的主要关注点似乎是学习微控制器设计,一个好的方法可能是研究一些早期的微处理器模型。以 Z80 为例:

    为了回答您的第一个问题(单总线与多总线),该芯片对所有事物都使用单总线,并且设计非常简单。您可能可以使用类似的东西。为了明确术语,单个系统总线可能由子总线(它们也称为总线)组成。图中显示了由双向数据总线(8 位宽)和地址总线(16 位宽)组成的系统总线。

    要回答您的第二个问题(组件如何知道它们何时处于活动状态), 在上图中,您会看到两个不同的信号,内存请求和 I/O 请求。一次只有一个处于活动状态,当 I/O 请求处于活动状态时,即可能访问外围设备。

    如果您没有很多外围设备,则不需要使用全部 16 个地址线(一些 Z80 具有 8 位 I/O 空间)。每个外围设备都将通过该空间中的一些地址进行访问。例如,在一个非常简单的系统中:

    • 定时器外设可以使用从 00h 到 03h 的地址
    • 一个 uart 可以寻址从 08h 到 0Fh

    在这个简单的例子中,您需要提供两个电路:一个会检测地址何时在 00-03h 范围内,另一个会检测 08-0Fh。如果您在每个检测器的输出和 I/O 请求信号之间执行逻辑“与”,那么您将有两个信号指示何时访问每个外围设备。您的外围硬件应该主要监听这个信号。

    最后,关于您关于指令的问题,您的微处理器内部的数据流将分为几个阶段。这通常称为处理器的数据路径。通常将阶段分为:

    1. FETCH:从程序存储器中读取一条指令
    2. 解码:检查指令中的特定位,并确定它是什么类型的指令
    3. 执行:执行指令要求的操作(例如 ALU 操作)
    4. 内存:对于某些指令,您需要进行数据读取或写入
    5. 回写:使用受指令影响的新值更新 CPU 寄存器

    来源:https://www.cs.umd.edu/class/fall2001/cmsc411/projects/DLX/proj.html

    您处理单个指令的大部分工作将在解码和执行阶段完成。至于数据路径控制,您将需要一个状态机来控制 5 个阶段的操作顺序。该功能块通常称为控制单元。在这里你有几个选择:

    1. 您的状态机可以按顺序通过所有阶段,一次一个。一条指令需要几个时钟周期才能执行。
    2. 与上述选择类似,但如果您想让事情变得更简单、更快捷,可以在一个周期中组合两个或多个阶段。
    3. 流水线化指令的执行。这可以大大提高速度,但也许最好留到以后,因为事情可能会变得相当复杂。

    至于实现,我建议将功能块保持为单独的实体,并且确保为每个块编写一个测试台。如果您编写这些测试平台,您的工作会更快。

    至于块,寄存器文件很容易编码。如果您清楚地了解指令布局和操作码,指令解码器也很容易。如果您知道 ALU 需要执行的操作,它也很容易。

    我将从为指令解码器和寄存器文件编写测试平台开始。然后我会编写一个脚本来运行所有的测试平台并自动检查它们的结果。只有这样我才会专注于功能块本身的实现。

    【讨论】:

    • +1 您解决了我的疑虑 :) 我还没有完全理解您的回答,但我认为这是一个明确的进步。我在第一个示意图上看到两条总线,我怎么了?此外,谁控制数据路径(CPU?)的顺序执行?以及如何确保正确启动(重置?)?另外,您对首先开始实施什么有什么建议吗?
    • 编辑了解决这些问题的答案 (@nha) 并希望让事情变得更清晰
    • 更清楚了 :) 我可能会发布一个关于实际实现的后续问题。
    【解决方案2】:

    基本上片上总线将使用并行总线进行地址和数据输入和输出。通常会有某种仲裁器来决定允许哪个组件写入总线。所以常见的做法是:

    • 想要写入的组件会将连接到仲裁器的数据线设置为高或低,以发出它想要访问总线的信号。
    • 仲裁者决定谁可以访问总线
    • 仲裁器设置接下来应该允许访问总线的组件的片选。

    通常您的片上总线将使用主/从概念,因此只有主设备可以访问总线。 slave 只等待 master 的请求。

    我喜欢 AMBA AHB/APB 设计,但这对于您的应用程序来说可能有点过头了。你可以看看这个book 寻找关于如何实现你的总线的想法

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-27
      • 2013-02-17
      • 2015-03-31
      • 2019-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多