基于FPGA的实验平台Altera Quatars II的16位单周期CPU设计
声明:最近很多学校的学弟学妹看到了这篇文章。这篇文章的本意是帮助学弟学妹能够更好地完成组原课设,毕竟当时我也是完成这个课设时非常痛苦,同时这还是基于我比较认真地完成了实验课的基础上,因此分享这篇文章不仅是对自己痛苦熬大夜的纪念,也希望可以起到帮助的作用,本篇文章也只是提供一个我个人设计的思路,我同届同学还有其他比我更巧妙更聪明的设计。今天查了后台发现很多私信求文件压缩包和电路图,我这边在完成这篇文章后都删除了有关文件,其实与其寄希望于我这模糊的电路图,不如多与老师交流,组原的老师们真的都很好,或者有可能的话录屏老师的讲解(实测非常有用,其实很多面临的问题老师第一节课都讲过的)。
如果有设计上的问题,欢迎评论区留言。佛系回复。
提示:此文档仅用于记录我本学期计算机组成原理课设文档,可能我们学校比较水吧,有幸拿到了优。本文档仅用于参考!
基于FPGA的实验平台Altera Quatars II的16位单周期CPU设计
- 前言
- 1、课程设计题目
- 2、课程设计的目的与意义
- 3、课程设计的内容
- 3.1 平台介绍
- 3.2 单周期CPU的主要技术指标
- 3.3 R型指令
- 3.4 I型指令
- 3.5 LOAD指令
- 3.6 STO指令
- 3.7 JUMP指令
- 3.8 HALT指令
- 4、课程设计步骤
- 4.1 选择要设计的指令
- 4.2 设计数据通路
- 4.3 分析控制信号取值
- 4.4 设计控制单元
- 4.4.1 WE
- 4.4.2 S
- 4.4.3 Exop
- 4.4.4 MUX_LOAD
- 4.4.5 MUX_S
- 4.4.6 MUX_R
- 4.4.7 MUX_STR
- 4.4.8 R_TY
- 4.4.9 JUMP
- 4.4.9 HALT
- 4.5 各部分的代码及分析
- 4.5.1 一级译码器
- 4.5.2 运算器ALU
- 4.5.3 二级译码器
- 4.5.4 扩展器
- 4.5.5 寄存器选择
- 4.5.6 寄存器
- 4.5.7 数码管
- 4.5.8 J_PC程序地址器
- 4.6 设计各部分元件及主电路
- 4.6.1功能码func译码器
- 4.6.2运算方式的二路选择器MUX_S
- 4.6.3寄存器组译码器
- 4.6.4寄存器组4路选择器
- 4.6.5立即数扩展
- 4.6.6第二个运算数的二路选择器
- 4.6.7 ROM
- 4.6.8 RAM
- 4.6.9 程序计数器PC
- 4.6.10 选择写入寄存器组的数据的二路选择器
- 4.6.11 主译码器decoder
- 4.6.12 总电路图
- 4.7 引脚分配
- 4.8功能测试
- 4.8.1 准备程序
- 4.8.2 准备数据
- 4.8.3 测试
- 5、实验结果与分析
- 5.1实验数据分析
- 5.1.1 数据存储器地址及内容
- 5.1.2 程序清单以及功能说明
- 5.2 运行结果和分析
- 5.2.1 加载数据
- 5.2.2 R型指令执行结果
- 5.2.3 I型指令执行结果
- 5.2.4 Load型指令执行结果
- 5.2.5 STO型指令执行结果
- 5.2.6 JUMP型指令执行结果
- 5.2.7 HALT型指令执行结果
- 5.3错误或异常现象分析
- 6、总结体会
- 7、参考文献
- 8、问得多的问题
- 8.1 ROM.mif
前言
设计16位的单周期CPU有很多种方法,此处展示的方法并不是最优。
提示:以下是本篇文章正文内容,下面案例可供参考
1、课程设计题目
基于FPGA的实验平台Altera Quatars II的16位单周期CPU设计。
2、课程设计的目的与意义
本课程设计是学完计算机组成原理课程并进行了多个单元实验后,综合利用所学的理论知识,并结合在单元实验中所积累的计算机部件设计和调试方法,设计出一台具有自定义指令系统的简单计算机系统。所设计的系统能在基于FPGA的实验平台Quatars上运行一段程序,通过检查程序结果的正确性来判断所设计计算机系统正确性。
本课程设计属于设计型实验,不仅锻炼学生简单计算机系统的设计能力,而且通过进行主机系统底层电路的实现、故障分析与定位、系统调式等环节的锻炼,进一步提高学生分析和解决问题的能力。
3、课程设计的内容
设计单周期CPU,并调试通过。题目可以根据自己的设计内容、实现方式、所设计的计算机系统的结构为基于FPGA实验平台的单周期CPU设计与实现。
3.1 平台介绍
本课程设计的实验平台为Altera Quartus II 软件和Altera Cyclone V Starter 工具箱。实验平台要点如下:
Cyclone V是Altera FPGAs家族的一类,它面向低功耗应用。Cyclone V GX 5CSEMA5F31C6芯片有不同的转换器,按钮,LED灯,七段显示器,HDMI接口,SD卡读卡器以及其他链接等。Cyclone V GX 5CSEMA5F31C6是Starter工具箱的重要组件。
3.2 单周期CPU的主要技术指标
①支持表1中至少10条指令,其中,至少要选择1条R型指令、1条立即数运算指令、Load指令、Store指令、1条分支指令和无条件转移指令;
②能运行由自己所设计的指令系统构成的一段测试程序,测试程序应能涵盖所有指令,程序执行功能正确,并对运行结果与理论运算结果对比(本实验采用表格对比),每一步判断对错。
# | 指令 | 15~12 | 11~10 | 9~8 | 7~6 | 5~3 | 2~0 | 指令功能 |
---|---|---|---|---|---|---|---|---|
1 | or | 0 | rs | rt | rd | 0 | 0 | $rd= $rs or $rt |
2 | and | 0 | rs | rt | rd | 0 | 1 | $rd = $rs & $rt |
3 | add | 0 | rs | rt | rd | 0 | 2 | $rd = $rs + $rt |
4 | sub | 0 | rs | rt | rd | 0 | 3 | $rd = $rs - $rt |
5 | sllv | 0 | rs | rt | rd | 0 | 4 | $rd = $rs - $rt |
6 | srlv | 0 | rs | rt | rd | 0 | 5 | $rd = $rs >> $rt |
7 | srav | 0 | rs | rt | rd | 0 | 6 | $rd = $rs >> $rt 算术右移 |
8 | slt | 0 | rs | rt | rd | 0 | 7 | r d = ( rd = ( rd=(rs < $rt) ? 1 :0 |
# | 指令 | 15~12 | 11~10 | 9~8 | 7~0 | 指令功能 |
---|---|---|---|---|---|---|
9 | DISP | 1 | rs | rt | immediate-u | DISP[imm] = $rs |
10 | lui | 2 | 0 | rt | immediate-u | $rt = imm << 8 |
11 | ori | 3 | rs | rt | immediate-u | $rt = $rs |
12 | andi | 4 | rs | rt | immediate-u | $rt = $rs & imm |
13 | addi | 5 | rs | rt | immediate-s | $rt = $rs + imm |
14 | lw | 6 | rs | rt | immediate-s | r t = M E M [ rt = MEM[ rt=MEM[rs + imm] |
15 | sw | 7 | rs | rt | immediate-s | MEM[$rs+imm] = $rt |
16 | beq | 8 | rs | rt | offset-s | beq =? |
17 | bne | 9 | rs | rt | offset-s | bne != ? |
18 | bqt | 10 | rs | rt | offset-s | bgt >?(有符号比较) |
|#| 指令 | 15~12 | 11~0 |指令功能|
|–|–|–|–|–|–|–|
| 19 | jump | 11 |jump address|jump|
| 20 | halt | 12 |0|halt (时钟暂停) |
代码如下(示例):
3.3 R型指令
R型指令有4位操作码,两个源寄存器选择码,右操作数选择码,目标寄存器选择码,功能码。R型指令操作码func都为0000,用功能码区别每个指令。具体如图1、表2、表3、表4所示。
# | 指令 | 15~12 | 11~10 | 9~8 | 7~6 | 5~3 | 2~0 | 指令功能 |
---|---|---|---|---|---|---|---|---|
1 | or | 0 | rs | rt | rd | 0 | 0 | $rd= $rs or $rt |
2 | and | 0 | rs | rt | rd | 0 | 1 | $rd = $rs & $rt |
3 | add | 0 | rs | rt | rd | 0 | 2 | $rd = $rs + $rt |
4 | sub | 0 | rs | rt | rd | 0 | 3 | $rd = $rs - $rt |
5 | sllv | 0 | rs | rt | rd | 0 | 4 | $rd = $rs - $rt |
6 | srlv | 0 | rs | rt | rd | 0 | 5 | $rd = $rs >> $rt |
7 | srav | 0 | rs | rt | rd | 0 | 6 | $rd = $rs >> $rt 算术右移 |
8 | slt | 0 | rs | rt | rd | 0 | 7 | r d = ( rd = ( rd=(rs < $rt) ? 1 :0 |
指令 | op | func | 功能说明 | 指令操作结果 |
---|---|---|---|---|
or | 0000 | 0000 | $rd = $rs or $rt | 运算结果返回目标寄存器rd |
and | 0000 | 0001 | $rd = $rs & $rt | 运算结果返回目标寄存器rd |
add | 0000 | 0010 | $rd = $rs + $rt | 运算结果返回目标寄存器rd |
sub | 0000 | 0011 | $rd = $rs - $rt | 运算结果返回目标寄存器rd |
sllv | 0000 | 0100 | rt寄存器数据逻辑左移位rs位,回写到rd | 运算结果返回目标寄存器rd |
srlv | 0000 | 0101 | rt寄存器数据逻辑右移位rs位,回写到rd | 运算结果返回目标寄存器rd |
srav | 0000 | 0110 | rt寄存器数据算数右移位rs位,回写到rd | 运算结果返回目标寄存器rd |
slt | 0000 | 0111 | r d = ( rd = ( rd=(rs < $rt) ? 1 :0 | 运算结果返回目标寄存器rd |
汇编码 | 预期执行结果 |
---|---|
add $r0 $r1 #r0 | $r0=0x000A |
sub $r2 $r1 #r2 | $r2=0x0000 |
or $r3 $r1 #r2 | $r2=0x0005 |
and $r1 $r3 #r0 | $r0=0x0005 |
sllv $r0 $r2 #r3 | $r3=0x0100 |
srlv $r1 $r2 #r3 | $r3=0x0000 |
srav $r0 $r2 #r3 | $r2=0x0005 |
srav $r0 $r2 #r3 | $r2=0x0005 |
3.4 I型指令
I型指令有4位操作码,一个源寄存器选择码,目标寄存器选择码,八位立即数。I型指令与立即数进行与、或、加、位移运算。具体如图2、表5、表6、表7所示。
|#| 指令 |15~12| 11~10| 9~8| 7~0| 指令功能|
|–|–|–|–|–|–|–|–|
|9| lui |1 |0 |rt| immediate-u | r t = i m m < < 8 ∣ 10 ∣ o r i ∣ 2 ∣ r s ∣ r t ∣ i m m e d i a t e − u ∣ rt = imm << 8 |10| ori |2| rs| rt |immediate-u | rt=imm<<8∣10∣ori∣2∣rs∣rt∣immediate−u∣rt = $rs | imm
|11| andi| 3| rs| rt |immediate-u| $rt = $rs & imm
|12| addi| 4| rs| rt| immediate-s| $rt = $rs + imm
指令 | op | 功能说明 | 执行结果 |
---|---|---|---|
lui | 0001 | $rt = imm << 8 | 运算结果回写寄存器rt |
ori | 0010 | $rt = $rs imm | 运算结果回写寄存器rt |
andi | 0011 | $rt = $rs & imm | 运算结果回写寄存器rt |
addi | 0100 | $rt = $rs + imm | 运算结果回写寄存器rt |
汇编码 | 预期执行结果 |
---|---|
add $r0 $r1 #r0 | $r0=0x000A |
sub $r2 $r1 #r2 | $r2=0x0000 |
or $r3 $r1 #r2 | $r2=0x0005 |
and $r1 $r3 #r0 | $r0=0x0005 |
3.5 LOAD指令
# | 指令 | 15~12 | 11~10 | 9~8 | 7~0 | 指令功能 |
---|---|---|---|---|---|---|
13 | lw | 0101 | 00 | 10 | immediate-s | r t = M E M [ rt = MEM[ rt=MEM[rs + imm] |
|lw| 0101 | r t = M E M [ rt = MEM[ rt=MEM[rs + imm] |read data from ram to $rt
|–|–|–|-|–|
汇编码 | 预期执行结果 |
---|---|
Load $r0 $r1 #r0 | $r0=0xFF01 |
3.6 STO指令
将源寄存器RS中的值和有符号立即数0x0000进行相加作为地址,将RT中的值写入RAM中对应位置去。具体如图4、表11、表12、表13所示。
# | 指令 | 15~12 | 11~10 | 9~8 | 7~0 | 指令功能 |
---|---|---|---|---|---|---|
14 | sw | 0110 | 00 | 10 | immediate-s | MEM[$rs+imm] = $rt |
sw | 0101 | r t = M E M [ rt = MEM[ rt=MEM[rs + imm] | read data from ram to $rt |
---|
|汇编码 |预期执行结果|
|–|–|–
|Load $r0 $r1 #r0| $r0=0xFF01
3.7 JUMP指令
3.8 HALT指令
4、课程设计步骤
4.1 选择要设计的指令
从表1中选择至少10条指令作为设计的指令系统。
4.2 设计数据通路
①分别为算术逻辑部件、取指令部件、R-型指令、立即数运算指令、Load/Store指令、分支指令、无条件转移指令及取指令部件设计数据通路。
②综合各指令的数据通路为一个整体。
4.3 分析控制信号取值
根据取指令阶段、R-型指令执行阶段、立即数运算指令执行阶段、Load/Store指令执行阶段、分支指令执行阶段、无条件转移指令执行阶段的分析,确定每个控制信号的取值,并在课程设计报告中列出如下表所示:
操作码表OP | 译码信号表 |
---|
指令 | op3 | op2 | op1 | op0 | func | WE | S3 | S2 | S1 | S0 | Exop | LOAD | mux_s | mux_r | ram_str | r_ty | jump | halt |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
or | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 |
and | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 |
add | 0 | 0 | 0 | 0 | 2 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 |
sub | 0 | 0 | 0 | 0 | 3 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 |
sllv | 0 | 0 | 0 | 0 | 4 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 |
srlv | 0 | 0 | 0 | 0 | 5 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 |
srav | 0 | 0 | 0 | 0 | 6 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 |
slt | 0 | 0 | 0 | 0 | 7 | 1 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 |
lui | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | |
ori | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | |
andi | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | |
addi | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | |
lw | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | |
sw | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | |
jump | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | ||
halt | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
4.4 设计控制单元
4.4.1 WE
WE为读写信号。当WE=1时,从RAM中读取数据,当WE=0时,向RAM中写数据。
4.4.2 S
用三位的S来控制ALU中的运算方式。当S=000时,进行或运算。当S=001时,进行与运算。当S=010时,进行加运算。当S=011时,进行减运算。当S=100时,进行逻辑左移运算。当S=101时,进行逻辑右移运算。当S=110时,进行算术右移运算。当S=111时,进行slt运算。
4.4.3 Exop
Exop为选择扩展方式。当Exop=1时,将8位立即数扩展为16位。当Exop=0时,不进行扩展。
4.4.4 MUX_LOAD
MUX_LOAD为是否读取RAM信号。当 MUX_LOAD=1时,进行读操作,读取RAM。当 MUX_LOAD=0时,不读取RAM。
4.4.5 MUX_S
MUX_S为ALU使能信号。当MUX_S=1时,为R型指令。当MUX_S=0时,不是R型指令。
4.4.6 MUX_R
MUX_R为存取位置选择端。当MUX_R=1时,选择存取位置为ALU运算后的结果。当MUX_R=0时,选择存取位置为RAM中的数据。
4.4.7 MUX_STR
MUX_STR为是否向RAM存取数据。当MUX_STR=1时,向RAM中存取数据。当MUX_STR=0时,不向RAM中存取数据。
4.4.8 R_TY
R_TY为是否R型指令判断信号。当MUX_STR=1时,不是R型指令。当R_TY=0时,是R型指令。
4.4.9 JUMP
JUMP为跳转信号。当JUMP=1时,执行跳转指令。当JUMP=0时,不进行跳转指令。
4.4.9 HALT
HALT为宕机信号。当HALT=1时,执行宕机指令。当HALT=0时,继续执行指令。
4.5 各部分的代码及分析
4.5.1 一级译码器
①一级译码器代码
ENTITY decoder ISPORT(OP : IN STD_LOGIC_VECTOR(3 DOWNTO 0);S : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);WE : OUT STD_LOGIC; EXOP : OUT STD_LOGIC;--选择扩展方式RAM_LOAD :OUT STD_LOGIC;--读取RAMMUX_S : OUT STD_LOGIC;--ALU的使能MUX_R : OUT STD_LOGIC;--存取位置选择端RAM_STR :OUT STD_LOGIC;--向RAM存取数据R_TY : OUT STD_LOGIC;--选择立即数或者寄存器中的数据JUMP : OUT STD_LOGIC;HALT : OUT STD_LOGIC);END decoder;
ARCHITECTURE behav OF decoder IS
BEGIN
PROCESS(OP)
BEGINCASE OP ISWHEN "0000" => S <= "0000"; WE <='1'; EXOP<='0';RAM_LOAD<='0';MUX_S<='1';MUX_R<='1';RAM_STR<='0';R_TY<='0';JUMP<='0';HALT<='0';WHEN "0001" => S <= "1001"; WE <='1'; EXOP<='0';RAM_LOAD<='0';MUX_S<='0';MUX_R<='1';RAM_STR<='0';R_TY<='1';JUMP<='0';HALT<='0'; --lui立即数左移WHEN "0010" => S <= "0011"; WE <='1'; EXOP<='0';RAM_LOAD<='0';MUX_S<='0';MUX_R<='1';RAM_STR<='0';R_TY<='1';JUMP<='0';HALT<='0'; --oriWHEN "0011" => S <= "0010"; WE <='1'; EXOP<='0';RAM_LOAD<='0';MUX_S<='0';MUX_R<='1';RAM_STR<='0';R_TY<='1';JUMP<='0';HALT<='0'; --andiWHEN "0100" => S <= "0000"; WE <='1'; EXOP<='1';RAM_LOAD<='0';MUX_S<='0';MUX_R<='1';RAM_STR<='0';R_TY<='1';JUMP<='0';HALT<='0'; --addiWHEN "0101" => S <= "0000"; WE <='1'; EXOP<='1';RAM_LOAD<='1';MUX_S<='0';MUX_R<='0';RAM_STR<='0';R_TY<='1';JUMP<='0';HALT<='0'; --lwWHEN "0110" => S <= "0000"; WE <='0'; EXOP<='1';RAM_LOAD<='0';MUX_S<='0';MUX_R<='1';RAM_STR<='1';R_TY<='1';JUMP<='0';HALT<='0'; --swWHEN "1010" => S <= "0000"; WE <='1'; EXOP<='0';RAM_LOAD<='0';MUX_S<='0';MUX_R<='1';RAM_STR<='0';R_TY<='1';JUMP<='1';HALT<='0'; --jumpWHEN "1011" => S <= "0000"; WE <='0'; EXOP<='0';RAM_LOAD<='0';MUX_S<='0';MUX_R<='0';RAM_STR<='0';R_TY<='1';JUMP<='0';HALT<='1'; --haltWHEN "1111" => S <= "1111"; WE <='1'; EXOP<='1';RAM_LOAD<='0';MUX_S<='0';MUX_R<='1';RAM_STR<='0';R_TY<='1';JUMP<='0';HALT<='0'; --加载数据WHEN OTHERS => S <= "0000";
END CASE;
END PROCESS;
END behav;
②一级译码器代码功能分析:根据操作码OP,给出对应操作的控制信号。
4.5.2 运算器ALU
①运算器ALU代码
ENTITY ALU ISPORT(S : IN STD_LOGIC_VECTOR (3 DOWNTO 0);A : IN STD_LOGIC_VECTOR (15 DOWNTO 0);B : IN STD_LOGIC_VECTOR (15 DOWNTO 0);F : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);SE : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);CO : OUT STD_LOGIC);
END ALU;ARCHITECTURE behav OF ALU IS
SIGNAL A9 : STD_LOGIC_VECTOR (16 DOWNTO 0);
SIGNAL B9 : STD_LOGIC_VECTOR (16 DOWNTO 0);
SIGNAL F9 : STD_LOGIC_VECTOR (16 DOWNTO 0);
BEGINA9 <= '0' & A ; B9 <= '0' & B ;PROCESS(A9,B9,A)BEGINCASE S ISWHEN "0000" => F9 <= A9+B9;WHEN "0001" => F9 <= A9-B9;WHEN "0010" => F9 <= (A9 AND B9);WHEN "0011" => F9 <= (A9 OR B9);WHEN "0100" => F9 <= (A9 AND NOT B9);WHEN "0101" => F9 <= (A9 XOR B9);WHEN "0110" => F9 <= TO_STDLOGICVECTOR(TO_BITVECTOR(A9) SLL CONV_INTEGER(B9));--逻辑左移WHEN "0111" => F9 <= TO_STDLOGICVECTOR(TO_BITVECTOR(A9) SRL CONV_INTEGER(B9));--逻辑右移WHEN "1000" => F9 <= TO_STDLOGICVECTOR(TO_BITVECTOR(A9) SRA CONV_INTEGER(B9));--算数右移WHEN "1001" => F9 <= TO_STDLOGICVECTOR(TO_BITVECTOR(B9) SLL 8);--逻辑左移8位WHEN "1010" => IF A9 < B9 THEN SE <= "0000000000000001";ELSE SE <= "0000000000000000";END IF; --第八条指令WHEN "1111"=> F9<="00000000000000101";--用于加载数据WHEN OTHERS => F9 <= "00000000000000000";END CASE;END PROCESS;F<= F9(15 DOWNTO 0); CO <= F9(16);END behav;
②运算器ALU功能分析:根据功能码S,执行对应的运算。
4.5.3 二级译码器
①二级译码器代码
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY Rcoder ISPORT(INPUT : IN STD_LOGIC_VECTOR(2 DOWNTO 0);S : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);ISW : OUT STD_LOGIC);END Rcoder;
ARCHITECTURE behav OF Rcoder IS
BEGIN
PROCESS(INPUT)
BEGINCASE INPUT ISWHEN "000" => S <= "0011";ISW <= '0';--orWHEN "001" => S <= "0010";ISW <= '0';--andWHEN "010" => S <= "0000";ISW <= '0';-- +WHEN "011" => S <= "0001";ISW <= '0';-- -WHEN "100" => S <= "0110";ISW <= '0';--逻辑左WHEN "101" => S <= "0111";ISW <= '0';--逻辑右WHEN "110" => S <= "1000";ISW <= '0';--算数右WHEN "111" => S <= "1010";ISW <= '1';--sltEND CASE;END PROCESS;END behav;
②二级译码器功能分析:根据指令的低三位,给出对应的S码。
4.5.4 扩展器
①扩展器代码
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY double ISPORT (in_c : IN STD_LOGIC_VECTOR(7 DOWNTO 0);out_c : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);went : IN std_LOGIC_VECTOR(0 DOWNTO 0) );END double;
ARCHITECTURE behav OF double ISBEGINPROCESS(in_c)BEGINCASE went ISWHEN "0"=> out_c<=("0000000000000000"+in_c);WHEN "1"=> out_c<=("1111111100000000"+in_c);END CASE;END PROCESS;
END behav;
②扩展器功能分析:根据指令设计要求,需要将8位的立即数扩展为16位,方便运算。
4.5.5 寄存器选择
①寄存器选择代码代码
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY YM ISPORT( CO : IN STD_LOGIC_VECTOR(1 DOWNTO 0);C0 : OUT STD_LOGIC;C1 : OUT STD_LOGIC;C2 : OUT STD_LOGIC;C3 : OUT STD_LOGIC);END YM;
ARCHITECTURE behav OF YM IS
BEGIN
PROCESS(CO)
BEGINCASE CO ISWHEN "00" => C0 <='1'; C1 <='0';C2<='0';C3<='0';WHEN "01" => C0 <='0'; C1 <='1';C2<='0';C3<='0';WHEN "10" => C0 <='0'; C1 <='0';C2<='1';C3<='0';WHEN "11" => C0 <='0'; C1 <='0';C2<='0';C3<='1';END CASE;
END PROCESS;
END behav;
②寄存器选择代码功能分析:根据对应的控制信号,选择对应的寄存器。
4.5.6 寄存器
①寄存器代码
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;entity AC_A is
port(LOAD_A:IN STD_LOGIC;clk:IN STD_LOGIC;Data_in:IN STD_LOGIC_VECTOR(15 DOWNTO 0);A:OUT STD_LOGIC_VECTOR(15 DOWNTO 0)
);
end AC_A;
ARCHITECTURE accu OF AC_A IS
BEGINPROCESS(clk,LOAD_A,data_in)BEGINIF clk'event AND clk='1' THENIF LOAD_A='1' THENA<=Data_in;END IF;END IF;END PROCESS;
END accu;
②寄存器功能分析:用于存放要使用的数值。
4.5.7 数码管
①数码管代码
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;entity seg7_16b is
port (Blank : STD_LOGIC;Test : STD_LOGIC;Data :IN STD_LOGIC_VECTOR(7 DOWNTO 0);RQ1 : OUT STD_LOGIC_VECTOR(6 DOWNTO 0);RQ2 : OUT STD_LOGIC_VECTOR(6 DOWNTO 0)
);
END seg7_16b;ARCHITECTURE behav OF seg7_16b IS
SIGNAL DH : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL DL : STD_LOGIC_VECTOR(3 DOWNTO 0);BEGIN DH <= Data(7)&Data(6)&Data(5)&Data(4);DL <= Data(3)&Data(2)&Data(1)&Data(0);PROCESS (DH,DL)BEGINIF Blank ='1' THEN RQ1 <="1111111"; RQ2 <="1111111";ELSIF Blank ='0' AND Test ='0' THEN RQ1 <= "1111110" ; RQ2 <="1111110" ;ELSIF Blank ='0' AND Test ='1' THENCASE DL ISWHEN "0000" => RQ1 <= "0000001";WHEN "0001" => RQ1 <= "1001111";WHEN "0010" => RQ1 <= "0010010";WHEN "0011" => RQ1 <= "0000110";WHEN "0100" => RQ1 <= "1001100";WHEN "0101" => RQ1 <= "0100100";WHEN "0110" => RQ1 <= "0100000";WHEN "0111" => RQ1 <= "0001111";WHEN "1000" => RQ1 <= "0000000";WHEN "1001" => RQ1 <= "0000100";WHEN "1010" => RQ1 <= "0001000";WHEN "1011" => RQ1 <= "1100000";WHEN "1100" => RQ1 <= "0110001";WHEN "1101" => RQ1 <= "1000010";WHEN "1110" => RQ1 <= "0110000";WHEN "1111" => RQ1 <= "0111000";END CASE ;CASE DH ISWHEN "0000" => RQ2 <= "0000001";WHEN "0001" => RQ2 <= "1001111";WHEN "0010" => RQ2 <= "0010010";WHEN "0011" => RQ2 <= "0000110";WHEN "0100" => RQ2 <= "1001100";WHEN "0101" => RQ2 <= "0100100";WHEN "0110" => RQ2 <= "0100000";WHEN "0111" => RQ2 <= "0001111";WHEN "1000" => RQ2 <= "0000000";WHEN "1001" => RQ2 <= "0000100";WHEN "1010" => RQ2 <= "0001000";WHEN "1011" => RQ2 <= "1100000";WHEN "1100" => RQ2 <= "0110001";WHEN "1101" => RQ2 <= "1000010";WHEN "1110" => RQ2 <= "0110000";WHEN "1111" => RQ2 <= "0111000";END CASE ;ELSE RQ1<="0000000";RQ2<="0000000";END IF;END PROCESS;END Behav;
②数码管功能分析:将结果显示在数码管上。
4.5.8 J_PC程序地址器
①J_PC程序地址器代码
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;entity J_PC is
port
(J : in std_logic;ZF : in std_logic;NOW_PC : in std_logic_vector(15 downto 0);ADRESS :in std_logic_vector(11 downto 0);OFFSET : in std_logic_vector(7 downto 0);NEXT_PC : out std_logic_vector(15 downto 0)
);
end J_PC;architecture behave of J_PC is begin process(J,ZF,NOW_PC,OFFSET,ADRESS)begin if J = '1' then NEXT_PC <= (NOW_PC and X"F000") or ADRESS;else NEXT_PC <= NOW_PC + X"0001" + OFFSET;end if;end process;
end behave;
②J_PC程序地址器功能分析:根据控制信号JUMP,给出对应的PC地址。
4.6 设计各部分元件及主电路
4.6.1功能码func译码器
分析:R型指令与I型指令、Load/Store指令、分支指令、无条件转移指令等指令不同,需要单独的二级译码器对R型指令对func码进行译码,具体如图7所示。
4.6.2运算方式的二路选择器MUX_S
分析:主译码器的MUX_S信号用于控制该二路选择器。该二路选择器用于控制ALU输入的运算方式。具体如图8所示。
4.6.3寄存器组译码器
分析:寄存器组用2-4译码电路和读写信号控制目标寄存器的写入操作。具体如图9所示。
4.6.4寄存器组4路选择器
分析:寄存器组用2-4译码电路和读写信号控制目标寄存器的写入操作。具体如图10所示。
4.6.5立即数扩展
分析:由于设计的原因,操作数为八位,而要求进行运算的数为16位,因此需要立即数扩展将立即数扩展成16位方便运算。如果控制信号Exop为1时,立即数扩展后高八位为FF,否则高八位为00。具体如图11所示。
4.6.6第二个运算数的二路选择器
分析:如果当前的指令为R型指令,那么直接用DATA_B进行运算。如果当前的指令不是R型指令,那么用刚刚立即数扩展后的16位数进行运算。具体如图12所示。
4.6.7 ROM
分析:如果当前的指令为R型指令,那么直接用DATA_B进行运算。如果当前的指令不是R型指令,那么用刚刚立即数扩展后的16位数进行运算。具体如图13所示。
4.6.8 RAM
分析:如果当前的指令为R型指令,那么直接用DATA_B进行运算。如果当前的指令不是R型指令,那么用立即数扩展后的16位数进行运算。具体如图14所示。
4.6.9 程序计数器PC
分析:如果当前的指令为R型指令,那么直接用DATA_B进行运算。如果当前的指令不是R型指令,那么用刚刚立即数扩展后的16位数进行运算。具体如图15所示。
4.6.10 选择写入寄存器组的数据的二路选择器
分析:如果当前的指令为R型指令,那么直接用DATA_B进行运算。如果当前的指令不是R型指令,那么用刚刚立即数扩展后的16位数进行运算。具体如图16所示。
4.6.11 主译码器decoder
分析:如果当前的指令为R型指令,那么直接用DATA_B进行运算。如果当前的指令不是R型指令,那么用刚刚立即数扩展后的16位数进行运算。具体如图17所示。
4.6.12 总电路图
4.7 引脚分配
4.8功能测试
4.8.1 准备程序
首先,用设计的指令设计一个程序(至少有一条指令要使用2次),要求写出助记符形式的源代码(汇编代码)及机器代码,并在程序中以注释的形式列出每条指令的操作。其次,将程序的机器代码放入指令存储器中。
4.8.2 准备数据
将程序运行过程要使用的数据放入数据存储器中。
4.8.3 测试
逐条指令测试功能,检查预期执行结果与实际执行结果是否一致,如果不一致,分析不一致的原因,修改数据通路或控制单元或程序后再测试,直到每条指令的预期执行结果与实际执行结果一致为止。
5、实验结果与分析
5.1实验数据分析
5.1.1 数据存储器地址及内容
表14 RAM数据内容
地址 | 数据 |
---|---|
0x00 | 0x0005 |
0x01 | 0x0002 |
0x02 | 0x0003 |
0x03 | 0x0004 |
0x04 | 0x0048 |
0x05 | 0x0087 |
0x06 | 0x0092 |
5.1.2 程序清单以及功能说明
BEGIN
In $r0,5 --向R0放入5
In $r1,5 --向R1放入5
In $r2,5 --向R2放入5
In $r3,5 --向R3放入5
Add $r0 $r1 #r0 --R0的值和R1的值做ADD运算,将结果存入R0中。
Sub $r2 $r1 #r2 --R2的值和R1的值做SUB运算,将结果存入R2中。
Or $r3 $r1 #r2 --R3的值和R1的值做OR运算,将结果存入R2中。
And $r0 $r2 #r0 --R0的值和R2的值做AND运算,将结果存入R0中。
Sllv $r0 $r2 #r3 --R0的值和R2的值做SLLV运算,将结果存入R3中。
Srlv $r1 $r2 #r3 --R1的值和R2的值做SRLV运算,将结果存入R3中。
Srav $r0 $r2 #r3 --R0的值和R2的值做SRAV运算,将结果存入R3中。
Stl $r1 $r2 #r3 --R1的值和R2的值做STL运算,将结果存入R3中。
Lui $r0,01 #r2 --R0的值和立即数01做SLLV运算,将结果存入R2中。
Ori $r0 0A#r2 --R0的值和立即数0A做OR运算,将结果存入R2中。
Andi $r1 01 #r2 --R1的值和立即数01做AND运算,将结果存入R2中。
Addi $r1 01 #r2 --R1的值和立即数01做ADD运算,将结果存入R2中。
Load $r1 00 #r2 --R1的值和立即数00做ADD运算得到某个地址,从 RAM中将该地址中的数读出,并将结果存入R2中。
Sto $r1 04 #r2 --R1的值和立即数04做ADD运算得到某个地址,将 R2中该地址中的数写入RAM中。
Jump F 4 --跳转到第20条指令,即为B000指令。
Halt clock --宕机。
5.2 运行结果和分析
5.2.1 加载数据
分析:预先向4个寄存器中打入数据,本实验设计均打入数据5。具体执行结果如图21、22、23、24所示。
5.2.2 R型指令执行结果
分析:本实验实现了8条R型指令。分别进行或、与、加、减、逻辑左移、逻辑右移、算术右移、比较数等操作,具体执行结果如图25、26、27、28、29、30、31、32所示。
5.2.3 I型指令执行结果
分析:本实验实现了4条I型指令。分别实现了立即数左移8位、或、与、加等操作,具体执行结果如图33、34、35、36所示。
5.2.4 Load型指令执行结果
分析:实现了从RAM中读取数据操作,寄存器R1中的数据5与立即数01相加,得到地址06,显示RAM第六个地址中的数据,并进行位扩展。具体执行结果如图37所示。
5.2.5 STO型指令执行结果
分析:实现了从RAM中读取数据操作,寄存器R1中的数据5与立即数01相加,得到地址06,显示RAM第六个地址中的数据,并进行位扩展。具体执行结果如图38、39、40所示。其中,图38为数码管显示结果,图39为执行STO型指令前RAM
中的数据,图40为执行STO型指令后RAM中的数据。
5.2.6 JUMP型指令执行结果
分析:实现了跳转操作,本实验设计跳转到在ROM地址中为0xF4的指令,即为B000(HALT)指令。具体执行结果如图41所示。
5.2.7 HALT型指令执行结果
分析:实现了宕机操作,执行后系统宕机,不再执行任何操作,也不能够重置操作。具体执行结果如图41所示。
5.3错误或异常现象分析
问题1:引脚图连接不对,数码管显示的数据顺序错误;
解决方法:对照指导书上的硬件图和之前实验中分配的引脚,挨个对照连接。
问题2:数码管显示的内容与LED灯的显示不一致;
解决方法: RAM、PC以及AC的时钟分配控制混乱,将这三个时钟分给三个独立按键来控制。同时更改引脚分配。
问题3:实验时一直出现了未知的问题,实在不知道如何解决;
解决方法:在询问老师和同学之后,在同学的帮助下,发现是设计电路图时出现了错误,参照老师课上举例的电路图进行了修改,并再次确认了连线是否正确。
6、总结体会
本次课程设计,我完成了MIPS16指令集中R型指令、I型指令、Load/Store指令、J型指令、无条件转移指令五个类型指令16条,并且均通过了仿真测试。在课程设计过程中,采用了VHDL硬件描述语言来实现16位单周期CPU的设计。
作为组成原理课程设计改革的第二年,本门课程首次使用硬件描述语言VHDL以及FPGA开发板,课程设计的难度相对来说有很大幅度的增加。得益于早期组成原理课堂积累,《计算机组成原理实验指导书-FPGA-v1.3(含课程设计)》对于计算机组成原理实验和VHDL语言的详细讲解,最终完成了本次的课程设计。虽然困难重重,却也收获满满,经过本次课程设计对计算机组成原理有了进一步的理解。整个课程设计也有不足的地方,由于时间太紧、难度较大,课程设计和期末考试复习时间重合,两者都需要花费大量的时间学习,只能尽量平衡二者的时间,但是皆不尽人意,最终课程设计在我努力了一周后,才勉强完成。
最后,总体而言,这学期计算机组成原理的教学课和本次计算机组成原理课程设计让我受益匪浅,学到了很多新的知识,更深刻地理解了CPU的运作模式,也明确了学习的方向.
7、参考文献
1、(美)Arnold S. Berger著. 吴伟民等译. 《计算机硬件及组成原理》. 机械工程出版社,2006
2、白中英等.《计算机组成原理》. 科学出版社出版,2008
…
9、(美)John L.Hennessy, David A. Patterson. 《计算机组织与设计硬件/软件接口(英文版·第2版)》.机械工业出版社,1999
10、外网:http://wps.aw.com/aw_carpinelli_compsys_1
8、问得多的问题
8.1 ROM.mif
主要写的是指令(十六进制)。
建议去问石老师班上的同学,石老师这块当时是给我们讲过的。
其中具体还是要根据自己对指令的设计来编写,我个人的设计见表14。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!