微控制器的Verilog代码(第2部分-设计)

在这篇文章中,介绍了微控制器的架构设计。 Verilog代码 为了 微控制器 被张贴在 部分3。

下图是微控制器的体系结构。数据路径显示为黑色箭头,控制信号显示为红色箭头。

微控制器的Verilog代码
以下两种类型的组件包含编程上下文。
  • 程序计数器,程序存储器,数据存储器,累加器,状态寄存器(绿色框)。它们是程序员可见的寄存器和存储器。
  • 指令寄存器和数据寄存器(紫色框)。它们是程序员看不见的寄存器。
以下两种类型的组件是 进行实际计算工作的布尔逻辑。他们是无国籍的
  • ALU ,MUX1,MUX2,加法器(蓝色框),用作功能单元。
  • 控制逻辑(黄色框),用于表示所有控制信号(红色信号)
时序和状态转换如下图所示。
微控制器的Verilog代码
每条指令需要3个时钟周期才能完成,即FETCH阶段,DECODE阶段和EXECUTE阶段。请注意,它不是流水线。与初始LOAD状态一起,可以将其视为3个状态(技术上为4个状态)的FSM。
状态:
1. 加载(initial state): 将程序加载到程序存储器,每条加载指令需要1个周期;
2. 取(first cycle): 从程序存储器中获取当前指令;
3. 解码(第二个周期): 解码指令以生成控制逻辑,为操作数读取数据存储器;
4. 执行(第三周期): 执行指令

过渡:
  1. 加载→  FETCH(初始化完成):
    1. 清除PC,IR,DR,Acc,SR的内容;不需要清除DMem。
  2. 取→解码(第二个周期的上升沿):
    1. IR = PMem [PC]
  3. 解码→ 执行
    1. DR = DMem [IR [3:0]];
  4. 执行 →FETCH(第一周期和第四周期的上升沿)
    1. 对于非分支指令,PC = PC +1;对于分支指令,如果采用分支,则PC = IR [7:0],否则PC = PC +1;
    2. 对于ALU指令,如果结果目标是累加器,则Acc = ALU .Out;如果结果目标是数据存储器,则DMem [IR [3:0]] = ALU .Out。
    3. 对于ALU指令,SR = ALU .Status;

可以使用相应寄存器的使能端口来简化转换,例如如果将Acc.E设置为1,则在每个时钟上升沿将ALU.Out分配给Acc。这样的控制信号Acc.E生成为当前状态和当前指令的布尔函数。

组件

寄存器

微控制器具有3个编程器可见寄存器:
  1. 程序计数器(8位,表示为PC): 包含当前执行指令的索引。
  2. 累加器(8位,表示为Acc):保存算术或逻辑计算的结果和1个操作数。
  3. 状态寄存器(4位,表示为SR): 拥有4个状态位,即Z,C,S,O。
    1. Z(零标志,SR [3]): 如果结果为零,则为1,否则为0。
    2. C(进位标志,SR [2]):如果产生进位,则为1,否则为0。
    3. S(标志标志,SR [1]):1如果结果为负(如2’s的补码),否则为0。
    4. O(溢出标志,SR [0]):如果结果产生溢出,则为1,否则为0。
这些寄存器中的每一个都有一个使能端口,作为标志是否应在状态转换中更新寄存器的值。它们分别表示为PC.E,Acc.E和SR.E。
该微控制器具有2个编程器不可见寄存器(即它们不能被编程器操纵):
  1. 指令寄存器(12位,表示为IR): 包含当前执行指令。
  2. 数据寄存器(8位,表示为DR): 包含从数据存储器读取的操作数。
同样,这些寄存器中的每一个都有一个使能端口作为标志,用于指示是否应在状态转换中更新寄存器的值。它们分别表示为IR.E和DR.E。

程序记忆


微控制器具有256个条目程序存储器,用于存储表示为PMem的程序指令。每个条目为12位,第i个条目表示为PMem [i]。程序存储器具有以下输入/输出端口。

  • 启用端口 (1位,输入,表示为PMem.E):使能设备,即如果它为1,则将读出地址端口指定的条目,否则不读出任何内容。
  • 地址端口 (8位,输入,表示为PMem.Addr):指定要读出的指令条目,并连接到PC。
  • 指令口 (12位,输出,表示为PMem.I):读出的指令条目,连接到IR。
  • 3个特殊端口用于将程序加载到存储器,而不用于执行指令。
  • 加载使能端口 (1位,输入,表示为PMem.LE):启用加载,即如果为1,则将使用加载指令输入端口指定的值加载地址端口指定的条目,并提供指令端口具有相同的值;否则,地址端口指定的条目将在指令端口上读出,而指令加载端口上的值将被忽略。
  • 加载地址端口 (8位输入,表示为PMem.LA):指定要加载的指令条目。
  • 加载指令端口 (12位,输入,表示为PMem.LI):加载的指令。
例如,如果地址点带有8’b0000_0011并将启用设置为1,在指令端口上读出第四个条目。
注意,程序加载仅在时钟上升沿生效,而指令读取则始终发生。

资料储存


微控制器具有一个16项数据存储器,表示为DMem。每个条目为8位,第i个条目表示为DMem [i]。程序存储器具有以下输入/输出端口。
  • 启用端口 (1位,输入,表示为DMem.E):使能设备,即如果它为1,则将读取或写入地址端口指定的条目;否则,不会读取或写入任何内容。
  • 写使能端口(1位,输入,表示为DMem.WE): 启用写操作,即如果它为1,那么将使用数据输入端口指定的值写入地址端口指定的条目,并且为数据输出端口提供相同的值;否则,地址端口指定的条目将在数据输出端口上读出,而数据输入端口上的值将被忽略。
  • 地址端口(4位,输入,表示为DMem.Addr): 指定连接到IR [3:0]的数据条目被读出。
  • 数据输入端口(8位,输入,表示为DMem.DI):写入的值,连接到ALU.Out。
  • 数据输出端口(8位,输出,表示为DMem.DO): 读出的数据条目,连接到MUX2.In1。
例如,如果地址点带有8’0000_0011,数据输入端口随附8个’0000_0000,使能设置为1,写使能设置为1,数据存储器的第四项写入值0,数据输出端口显示8’0000_0000.
再举一个例子,如果地址点提供了8’0000_0011,数据输入端口随附8个’0000_0000,使能设置为1,而写使能设置为0,则在数据输出端口上读取数据存储器的第四项。

请注意,写操作仅在时钟上升沿生效,而读操作始终在发生,类似于程序存储器。

PC加法器

PC加法器用于将PC加1,即移至下一条指令。该组件是纯组合的。它具有以下端口。
  • 加法器输入端口 (8位,输入,表示为Adder.In):连接到PC。
  • 加法器输出端口 (8位,输出,表示为Adder.Out):连接到MUX1.In2。

MUX1

MUX1用于选择更新PC的源。如果当前指令不是分支指令,或者是分支指令,但未采用分支指令,则PC递增1;否则将PC设置为跳跃目标,即IR [7:0]。它具有以下端口。
  • MUX1输入1端口 (8位,输入,表示为MUX1.In1):连接到IR [7:0]。
  • MUX1输入2端口 (8位,输入,表示为MUX1.In2):连接到Adder.Out。
  • MUX1选择端口 (1位,输入,表示为MUX1.Sel):连接到控制逻辑。
  • MUX1输出端口 (8位,输出,表示为MUX1.Out):连接到PC。

ALU


ALU 用于执行当前指令的实际计算。该组件是纯组合的。它具有以下端口。下表列出了ALU的模式。
  • ALU 操作数1端口 (8位,输入,表示为ALU.Operand1):连接到Acc。
  • ALU 操作数2端口 (8位,输入,表示为ALU.Operand2):连接到MUX2.Out。
  • ALU 使能端口(1位,输入,表示为ALU.E):连接至控制逻辑。
  • ALU 模式端口 (4位,输入,表示为ALU.Mode):连接到控制逻辑。
  • 当前标志端口 (4位,输入,表示为ALU.CFlags):连接到SR。
  • ALU 输出端口 (8位,输出,表示为ALU.Out):连接到DMem.DI。
  • ALU 标志端口 (4位,输出,表示为ALU.Flags):从MSB到LSB的Z(零),C(进位),S(符号),O(溢出)位连接到状态寄存器。

微控制器的Verilog代码

MUX2

MUX2用于选择ALU的操作数2的来源。如果当前指令为M型,则ALU的操作数2来自数据存储器;如果当前指令是I类型,则ALU的操作数2来自该指令,即IR [7:0]。它具有以下端口。
  • MUX2输入1端口 (8位,输入,表示为MUX2.In1):连接到IR [7:0]。
  • MUX2输入2端口 (8位,输入,表示为MUX2.In2):连接到DR。
  • MUX2选择端口 (1位,输入,表示为MUX2.Sel):连接到控制逻辑。
  • MUX2输出端口 (8位,输出,表示为MUX2.Out):连接到ALU.Operand2。

控制单元设计


控制信号来自当前状态和当前指令。控制逻辑组件是纯粹的组合。共有12个控制信号,如下所示。
  • PC.E:启用程序计数器(PC)的端口;
  • Acc.E:启用累加器端口(Acc);
  • SR.E:启用状态寄存器(SR)的端口;
  • IR.E:使能指令寄存器(IR)的端口;
  • DR.E:启用数据寄存器(DR)的端口;
  • PMem.E:启用程序存储器的端口(PMem);
  • DMem.E:启用数据存储器(DMem)的端口;
  • DMem.WE:数据存储器的写使能端口(DMem);
  • ALU .E:启用ALU的端口;
  • ALU .Mode:ALU的模式选择端口;
  • MUX1.Sel:MUX1的选择端口;
  • MUX2.Sel:MUX2的选择端口;

下表详细记录了如何生成这些控制信号,重要信号用红色标记。

微控制器的Verilog代码

评论:

1.请注意,在条件转移指令的EXECUTE状态下,MUX1.Sel的值实际上是SR [IR [9:8]];
2.请注意,在ALU I类型指令的EXECUTE阶段,ALU.Mode的值实际上为{0,IR [10:8]}。在上表中,假设扩展为0。
3.请注意,此表中未显示PMem.LE。如果处理器未处于LOAD状态,则PMem.LE始终设置为0。

指令的类型和类别可以由指令的前4位(即IR [11:8])标识,如上表的第一列所示。

此外,在加载程序时,如下产生控制信号。

微控制器的Verilog代码

如果处理器处于LOAD状态,则PMem.LE始终设置为1。

微控制器的指令集架构(第1部分)
第3部分将是整个微控制器的Verilog代码。

您可能会这样:
推荐的 Verilog projects:
2. FIFO存储器的Verilog代码
3. 用于16位单周期MIPS处理器的Verilog代码
4. Verilog HDL中的可编程数字延迟计时器
5. 用于数字电路中基本逻辑组件的Verilog代码
6. 用于32位无符号除法器的Verilog代码
7. 用于定点矩阵乘法的Verilog代码
8. Verilog HDL中的车牌许可证识别
9. 提前进位乘法器的Verilog代码
10。  微处理器的Verilog代码
11。  4x4乘法器的Verilog代码
12  停车场系统的Verilog代码
13  使用Verilog HDL在FPGA上进行图像处理
14。  如何使用Verilog HDL将文本文件加载到FPGA中
15  交通信号灯控制器的Verilog代码
16。  FPGA上的闹钟的Verilog代码
17。  比较器设计的Verilog代码
18岁  D触发器的Verilog代码
19  Full Adder的Verilog代码
20  带testbench的计数器的Verilog代码
21  16位RISC处理器的Verilog代码
22  用于在FPGA上反跳按钮的Verilog代码
23。  如何为双向/输入端口编写Verilog Testbench
28。  解码器的Verilog代码
29。  复用器的Verilog代码
FPGA Verilog VHDL课程

4条评论:

  1. 回覆
    1. 请访问下一部分:
      //fpga4student.blogspot.com/2016/11/verilog-code-for-microcontroller.html

      删除
  2. 错误:Xst:2355-"06.微控制器_main.v"第24行:在第1行中找到的值167479828在系统任务$ readmemb的调用中不是二进制的。

    收到此错误。请帮我。

    回复 删除
  3. "program_mem.dat"。您是否在项目文件夹中创建了此文件?创建此文件,然后将提供的测试程序复制到该文件中并运行仿真。

    回复 删除

热门FPGA项目