其中信号说明如下:
m2reg:把存储器数据写到寄存器 PCsource:下一条指令的来源
wmem:写存储器信号 aluc:运算器控制信号
Shift:移位信号 aluimm:操作数b的数据来源
Wreg:写寄存器信号 regrt:写到rd/rt
sext:符号扩展/0扩展
一、实验方法
1.设计ALU
设计一个32位ALU,能够实现基本的算术运算、逻辑运算和移位运算。ALU物理结构如下图。
(1)功能描述:ALU是负责运算的电路模块,该ALU的输入为两个32位的操作数a和b,输出结果是32位r。ALU的操作是由ALUctr控制信号产生,即为图中的aluc[3:0],z是零标志。此次设计的ALU主要可进行9种运算。
(2)操作说明:在设计中,KEY按下为0,不按为1。KEY[0]按下为a和b赋初值,之后可用于计算,运算方式aluc[3:0]由SW[3:0]控制,共支持9种运算。拨动开关后运算方式会改变。
- 设计寄存器
寄存器逻辑结构如下:
功能描述:给alu提供运算需要的数据;将alu运算产生的数据保存在寄存器中。用5位作为地址选择32个32位寄存器。
3.设计控制器
功能描述:根据op,func产生正确的运算控制信号。
4.指令存储器设计
功能描述:采用存储程序的设计思想,将待执行的指令放在一组寄存器中,根据PC的变化执行相应的指令。
5.数据存储器设计
功能描述:存放数据的存储器,即内存单元。当指令为Load/Store时,需要访问内存单元的内容,即访问该寄存器组。
二、实验结果
完全编译,编译完成后下载.sof 文件到开发板,下载完成后点击一次运行按钮,按KEY[0]键抓取信号。运用Signal TapⅡ抓取到的部分信号如下:
通过观察指令与PC时钟周期的变化,判断实验结果的正确性,结果正确。
编译步骤:
- 打开Quartus14.0,点击file,点击open project,打开自己文件中的.qpf,运行(需要大概五分钟)
- 运行完成后,打开tools点击signal tapII,等待弹出界面
- 点击驱动,连接驱动,下载到开发板
- 点击一次运行按钮,按key[0],捕捉到信号
- 结束
三、分析讨论
(1)开发板的处理芯片是Altera的FPGA芯片,选择器件的时候差一个字符也不可以,选择5CSEMA5F31C6。
(2)增加PLL时一定注意把operation Mode设为normal,不然在后续会出错,管脚建立不正确,在建立LPM_MUX时,要注意点击第二个create,否则在Project中找不到对应项目。
(3)分配管脚前应运行processing>start>start analysis &Elaboration,否则找不到管脚。
(4)命名时注意与顶层文件相同以及扩展类型。
(5)在Signal Tap II的节点栏中添加节点后可以观察到节点的类型,名字,数据使能,触发使能(拨动开关或按下按钮等)和触发器的状态。
(6)再查看Sccpu代码时首先从顶层文件DE1_SOC_golden_top.v中开始看,最重要的是例化数据通路sccpu_dataflow,于是应该看文件sccpu_dataflow .v,在该文件中倒数第二行有alu的例化,于是应该看alu.v,打开该文件发现正是我们之前的实验用到的alu(a,b,aluc,r,z) ,参数含义和实现方法都已经知道。
(7)回到sccpu_dataflow .v可以看到控制器的例化sccu_dataflow cu 打开sccu_dataflow.v 的参数表如下:(op,func,z,wmem,wreg,regrt,m2reg,aluc,shift,aluimm,pcsource,jal,sext)
其中op,func,z为输入,其余为输出的控制信号。
(8)在结合Signal TapII波形图查看代码时,sccpu_dataflow.slpc[31..0]随着时钟周期的变化可以准确的反映出具体实现到哪一行代码,可以通过时钟的变化对比查看代码的执行过程。由波形图可知,顺序执行代码则每一条代码运行之后PC=PC+4,这是因为每一条指令是4个字节。
(9)每一个操作第一步时取指令,分析指令,最后一步是PC+4。
(10)在执行LOAD指令时,wmem的信号为1,则m2reg的信号也为1。
(11)I型指令中操作数immediate只有16位,所以进行运算的时候需要扩展为16为,在进行逻辑运算时进行0扩展(逻辑运算操作数没有负数),进行LOAD/STORE和Branch指令时进行符号扩展。
(12)Beq的指令运算方式为:PC+4+(sign(imm))*4。