课程设计报告
课 程 片上计算机系统 题 目 cpu的设计 班 级 4班 专 业 集成
学生学号 1314020406 指导教师
2015 年 7月 9 日
索 引:
1.课程设计的目的及要求………………………………………3 2.处理器的设计思想和设计内容………………………………3 3.设计处理器的结构和实现方法………………………………3
<1>
4.模型机的指令系统……………………………………………4 5.处理器的状态跳转操作过程…………………………………4 6. CPU的VHDL代码……………………………………………7 7. Quartus II环境下的应用步骤…………………………14 8. 仿真波形………………………………………………………15 9. 课程设计的总结………………………………………………17
课程设计的目的及要求
1.目的:设计目的:了解Quartus II软件的应用,学习Quartus II环境下设计CPU的基本过程;掌握CPU设计代码的含义以及CPU的工作原理;了解CPU与内存RAM间的连接数据的传输过程;学习在Quartus II环境下建立模型机的具体过程。融会贯通本课程各章节的内容,通过知识的综合运用,加深对计算机系统各模块的工作原理及相互联系的认识。学习设计和调试计算机的基本步骤和
<2>
方法,提高使用软件仿真工具和集成电路的基本技能。培养科学研究的工作能力,取得工程设计与组装调试的实践和经验。
2.要求:以《计算机组成与设计》书中123页的简化模型为基础,更改其指令系统,形成设计者的CPU,在Quartus II环境下与主存连接,调试程序,观察指令的执行是否达到设计构想。
一. 处理器的设计思想和设计内容
处理器的字长为16b;包括四种指令格式,格式1、格式2、格式3的指令字长度为8b,格式4的指令字长度为16b;处理器内部的状态机包括6个状态。
关于CPU:
操作码4位,一共设计16条指令,主要包括空操作指令、中断指令、加法指令、减法指令、三种逻辑运算指令、循环移位操作指令,数据传输指令,转移类指令,特权指令等等。
关于RAM:
地址线设置成16bits,主存空间为words。 书中原CPU的主要修改:
(1)模型机CPU指令集中的逻辑左移与逻辑右移改成算术左移与算术右移左移。
(2)模型机CPU指令集中的add实现减法,sub实现加法。 (3)模型机CPU指令集中的Jmp,Jz改为skp,not指令。 (4)模型机CPU指令的执行流程及状态跳转。
二. 计处理器的结构和实现方法
(指令格式)
格式1:寄存器寻址方式
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 OP Rx Ry 空白 格式2:立即数寻址方式 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 OP I 空白 格式3:无操作数寻址方式 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 OP 空白 空白 格式4:直接寻址方式 <3>
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 OP
Addr 模型机的指令系统
操作码OP (15~~12) 指令格式 3 2 1 1 1 1 1 1 1 1 1 1 3 4 4 Idle 指令 操作 PC=PC+1 R0←I PC=PC+1 Rx←(Ry)PC=PC+1 Rx←(Rx)+(Ry)PC=PC+1 Rx←(Rx)AND(Ry)PC=PC+1 Rx←(Rx)NAND(Ry)PC=PC+1 Rx←(Rx)OR(Ry)PC=PC+1 Rx←(Rx)XNOR(Ry)PC=PC+1 Rx←(Ry)算术右移PC=PC+1 Rx←(Ry)算术左移PC=PC+1 A←(Ry);Ry←(Rx);Rx←(A);PC=PC+1 PC←Adder PC=PC+1 If(R0)=0 then PC←Adder Else PC=PC+1 PC=PC+1 R0←(Addr) PC=PC+1 PC=PC+1 (Addr)←R0 PC=PC +1 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 Load data Move Rx Ry Add Rx Ry AND Rx Ry NAND Rx Ry OR Rx Ry XNOR Rx Ry Shrp Rx Ry Shlp Rx Ry Swap Rx Ry Jamp Adder Jz Adder Read Addr Write Addr <4>
1111 3 Stop 无操作,PC不变 处理器的状态跳转操作过程:
(一)、模型机每一状态下的操作及状态跳转 当前状态 执行操作 St_0 St_1 次态与读下一条指令的有关的操作 取指令 St_1 IR(15..0)M_data_in&‘00000000’ Write-Read’0’ PC=PC+1 IF OP=Load THEN MARPC R0IR(11..8)||”000000000000” IF(OP=Stop)THEN IF OP=Move THEN Rx St_1 ELSE St_2 (Ry) IF OP= Sra THEN Ry END IF (Ry) 算术右移 IF OP= Sla THEN Ry (Ry) 算术左移 IF OP= Add THEN A(Ry) IF OP=And THEN A(Ry) IF OP=Nand THEN A(Ry) IF OP=Or THEN A(Ry) IF OP=Xnor THEN A(Ry) IF OP= Swap THEN A(Ry) IF OP=Stop THEN NULL IF OP=Idle THEN NULL IF OP=Jmp THEN NULL IF OP=Jz THEN NULL IF OP=Read THEN NULL IF OP=Write THEN NULL IF OP= Load OR OP=Move OR St_0 OP= Sra OR OP= Sla OR OP=Idle Write-Read’0’ THEN NULL IF OP= Add THEN Rx (Rx)+A IF OP= AND THEN Rx (Rx)ANDA IF OP=NAND THEN Rx (Rx) NANDA IF OP= AND THEN Rx (Rx)ANDA St_2 <5>
St_3 St_4 St_5 St_6 (二)、简单指令执行状态描述
读内存指令:
(1)St_0:取指令执行以下操作;
1)M_address(MAR) 把指令地址送到地址总线
2)令Write-Read’0’ 向内存发出读命令(取指令)
3)IR(15..0)M_data_in(15..0) 将读出的指令加载于IR(15..0)
4)PC=PC+1 至此指令已经全部取出,存在于IR(15..0),为取下一条指令准备地址
(2)St_1:NULL 直接跳转到下一状态
(3)St_2:MARIR(11..0)将数据地址加载于MAR (4)St_3:
1)M_address(MAR)把数据地址送到地址总线
2)令Write-Read’0’ 向内存发出读命令(取数据)
<6>
IF OP= OR THEN Rx (Rx) OR A IF OP= XNOR THEN Rx (Rx) XNORA IF OP= Swap THEN Ry(Rx) St_3 Write-Read’0’ IF OP= Skp THEN (PCIR(1..0) IF OP= Read THEN MARIR(11..0) IF OP= Write THEN MARIR(11..0) MDAR0 IF OP= Swap THEN Rx(A) St_0 Write-Read’0’ IF OP= Skp St_0 MARPC Write-Read’0’ IF OP= Write St_4 MARPC Write-Read’0’ IF OP= Read St_4 MARPC Write-Read’0’ IF OP= Read THEN St_0 R0M_data_in Write-Read’0’ IF OP=Write THEN St_0 R0M_data_in Write-Read’0’ MAR <= PC; If Read R0 := M_data_in;
3)MARPC 把下一条指令地址加载于MAR (5)St_4:
1)R0M_data_in 将来自内存的数据加载于R0,本指令执行完毕 2)M_address(MAR) 把下一条指令地址送到地址总线
3)令Write-Read’0’ 向内存发出读命令(取下一条指令) 4)下一状态跳转到St_0
无条件转移指令
(1)St_0:取指令执行以下操作;
1)M_address(MAR) 把指令地址送到地址总线
2)令Write-Read’0’ 向内存发出读命令(取指令)
3)IR(15..0)M_data_in(15..0) 将读出的指令加载于IR(15..0)
4)PC=PC+1 (此语句无用,因为程序计数器后续重新复制达到无条件转移目的)
(2)St_1:NULL 直接跳转到下一状态 (3)St_2:
1)MARIR(11..0) 将转移目标地址加载于MAR 2)PCIR(11..0) 将转移目标地址加载于PC (4)St_3:
1) M_address(MAR) 把下一条指令地址送到地址总线 2)令Write-Read’0’ 向内存发出读命令(取下一条指令) 3)下一状态跳转到St_0
三. CPU的VHDL代码 LIBRARY ieee;
USE ieee.std_logic_11.ALL;
<7>
PACKAGE namespack IS
CONSTANT idle : std_logic_vector(3 DOWNTO 0) :=\"0000\";
CONSTANT load : std_logic_vector(3 DOWNTO 0) :=\"0001\";
CONSTANT move 0) :=\"0010\";
CONSTANT addP 0) :=\"0011\";
CONSTANT andp 0) :=\"0100\";
CONSTANT nandp 0) :=\"0101\";
CONSTANT orp 0) :=\"0110\";
CONSTANT xnorp 0) :=\"0111\";
CONSTANT shrp 0) :=\"1000\";
CONSTANT shlp 0) :=\"1001\";
CONSTANT swap std_logic_vector(3 std_logic_vector(3 std_logic_vector(3 : std_logic_vector(3 : std_logic_vector(3 : std_logic_vector(3 std_logic_vector(3 std_logic_vector(3 std_logic_vector(3 DOWNTO DOWNTO DOWNTO DOWNTO DOWNTO DOWNTO DOWNTO DOWNTO DOWNTO
<8>
: : : : : :
0) :=\"1010\";
CONSTANT jmp : std_logic_vector(3 DOWNTO 0) :=\"1011\";
CONSTANT jz : std_logic_vector(3 DOWNTO 0) :=\"1100\";
CONSTANT read : std_logic_vector(3 DOWNTO 0) :=\"1101\"; CONSTANT
write
:
std_logic_vector(3
DOWNTO
0) :=\"1110\";
CONSTANT stop : std_logic_vector(3 DOWNTO 0) :=\"1111\"; END namespack;
LIBRARY ieee;
USE ieee.std_logic_11.ALL; USE ieee.std_logic_unsigned.ALL; USE WORK.namespack.ALL;
------------------------cpu
实
体
声
明
--------------------------------- ENTITY cpu IS PORT(
<9>
reset --清零信号低有效 clock --时钟信号 Write_Read: --读写信号,'1'为写
: IN std_logic;
: IN std_logic;
OUT std_logic;
M_address: OUT std_logic_vector(11 DOWNTO 0); --地址线
M_data_in: IN std_logic_vector(7 DOWNTO 0); --数据输入线
M_data_out: OUT std_logic_vector(7 DOWNTO 0); --数据输出线
overflow: OUT std_logic); --溢出标志 END cpu;
------------------------cpu寄存器传输级行为描述--------------------------------
ARCHITECTURE RTL OF cpu IS
SIGNAL IR: std_logic_vector(15 DOWNTO 0); --指令寄存器
<10>
SIGNAL MDR: std_logic_vector(7 DOWNTO 0);
--数据寄存器 SIGNAL
MAR:
std_logic_vector(11
DOWNTO
0);
--地址寄存器 SIGNAL
status:
integer
RANGE
0
TO
6;
--状态寄存器 BEGIN
status_change: PROCESS(reset, clock, status ) BEGIN
IF reset = '0' THEN status <= 0 ; -- 进入初始状态
ELSIF clock'EVENT AND clock = '0' THEN CASE status IS WHEN 0 => status <= 1; WHEN 1 =>
IF IR(15 DOWNTO 12)= Stop THEN status <= 1; ELSE
status <= 2;
<11>
END IF; WHEN 2 =>
CASE IR(15 DOWNTO 12) IS WHEN Swap|Jmp|Jz|Read|Write => status <= 3; WHEN OTHERS => status <= 0; END CASE; WHEN 3 =>
IF IR(15 DOWNTO 12)= Swap THEN status <= 0; ELSE
status <= 4; END IF; WHEN 4 => status <= 5; WHEN 5 =>
CASE IR(15 DOWNTO 12) IS WHEN Read|Write => status <= 6; WHEN OTHERS => status <= 0;
<12>
END CASE; WHEN OTHERS => status <= 0; END CASE; ELSE NULL; END IF;
END PROCESS status_change;
seq: PROCESS(reset,clock)
VARIABLE PC:std_logic_vector(11 DOWNTO 0); --程序计数器
VARIABLE R0,R1,R2,R3: std_logic_vector(7 DOWNTO 0); --通用寄存器
VARIABLE A: std_logic_vector(7 DOWNTO 0); --临时寄存器
VARIABLE temp: std_logic_vector(8 DOWNTO 0); --临时变量 BEGIN
IF(reset='0') THEN -- 进入初始状态 IR <= (OTHERS=>'0'); PC := (OTHERS=>'0');
<13>
R0 := (OTHERS=>'0'); R1 := (OTHERS=>'0'); R2 := (OTHERS=>'0'); R3 := (OTHERS=>'0'); A := (OTHERS=>'0'); MAR <= (OTHERS=>'0'); MDR <= (OTHERS=>'0');
ELSIF(clock'event AND clock='1') THEN overflow <= '0'; CASE status IS WHEN --状态0
IR <= M_data_in & \"00000000\"; --取指令
PC := PC+1; --程序计数器加1
WHEN --状态1
IF (IR(15 DOWNTO 12) /= Stop) THEN MAR <= PC; END IF;
<14>
0=>
1=>
CASE IR(15 DOWNTO 12) IS
WHEN Load => R0:=\"0000\" & IR(11 DOWNTO 8); WHEN Move =>
--Move Rx,Ry;
CASE IR(11 DOWNTO 8) IS WHEN \"0001\"=> R0:=R1; WHEN \"0010\"=> R0:=R2; WHEN \"0011\"=> R0:=R3; WHEN \"0100\"=> R1:=R0; WHEN \"0110\"=> R1:=R2; WHEN \"0111\"=> R1:=R3; WHEN \"1000\"=> R2:=R0; WHEN \"1001\"=> R2:=R1; WHEN \"1011\"=> R2:=R3; WHEN \"1100\"=> R3:=R0;
WHEN \"1101\"=> R3:=R1; WHEN \"1110\"=> R3:=R2; WHEN OTHERS=> NULL; END CASE; WHEN Shrp --算术右移;
=>
<15>
CASE IR(11 DOWNTO 10) IS WHEN \"00\"=>
R0:=\"000\"&R0(5 DOWNTO 1); WHEN \"01\"=>
R1:=\"000\"&R1(5 DOWNTO 1); WHEN \"10\"=>
R2:=\"000\"&R2(5 DOWNTO 1); WHEN OTHERS=>
R3:=\"000\"&R3(5 DOWNTO 1); END CASE; WHEN --算术左移; CASE IR(11 DOWNTO 10) IS WHEN \"00\"=>
R0:=R0(4 DOWNTO 0)&\"000\"; WHEN \"01\"=>
R1:=R1(4 DOWNTO 0)&\"000\"; WHEN \"10\"=>
R2:=R2(4 DOWNTO 0)&\"000\"; WHEN OTHERS=>
R3:=R3(4 DOWNTO 0)&\"000\"; END CASE;
Shlp =>
<16>
WHEN Addp|Andp|Nandp|Orp|Xnorp|Swap =>
CASE IR(9 DOWNTO 8) IS WHEN \"00\"=> A:=R0; WHEN \"01\"=> A:=R1; WHEN \"10\"=> A:=R2; WHEN OTHERS=> A:=R3; END CASE;
WHEN OTHERS => NULL; END CASE; WHEN --状态2
CASE IR(15 DOWNTO 12) IS WHEN --Rx:= Rx+A;
CASE IR(11 DOWNTO 10) IS WHEN \"00\"=>
temp := (R0(7) & R0(7 DOWNTO 0)) + NOT(A(7) & A(7 DOWNTO 0))+1; R0:=temp(7 DOWNTO 0);
overflow <= temp(8) XOR temp(7);
<17>
2=>
Addp =>
WHEN \"01\"=>
temp :=(R1(7) & R1(7 DOWNTO 0)) + NOT(A(7) & A(7 DOWNTO 0))+1; R1:=temp(7 DOWNTO 0);
overflow <= temp(8) XOR temp(7); WHEN \"10\"=>
temp :=(R2(7) & R2(7 DOWNTO 0)) + NOT(A(7) & A(7 DOWNTO 0))+1; R2:=temp(7 DOWNTO 0);
overflow <= temp(8) XOR temp(7); WHEN OTHERS=>
temp :=(R3(7) & R3(7 DOWNTO 0)) + NOT(A(7) & A(7 DOWNTO 0))+1; R3:=temp(7 DOWNTO 0);
overflow <= temp(8) XOR temp(7); END CASE; WHEN -- Rx:= Rx AND A;
CASE IR(11 DOWNTO 10) IS WHEN \"00\"=> R0:=R0 and A; WHEN \"01\"=>
<18>
Andp =>
R1:=R1 and A; WHEN \"10\"=> R2:=R2 and A; WHEN OTHERS=> R3:=R3 and A; END CASE; WHEN Nandp -- Rx:= Rx NAND A;
CASE IR(11 DOWNTO 10) IS WHEN \"00\"=> R0:=R0 nand A; WHEN \"01\"=> R1:=R1 nand A; WHEN \"10\"=> R2:=R2 nand A; WHEN OTHERS=> R3:=R3 nand A; END CASE; WHEN Orp -- Rx := Rx OR A;
CASE IR(11 DOWNTO 10) IS WHEN \"00\"=>
=>
=>
<19>
R0:=R0 or A; WHEN \"01\"=> R1:=R1 or A; WHEN \"10\"=> R2:=R2 or A; WHEN OTHERS=> R3:=R3 or A; END CASE; WHEN Xnorp --Rx=Rx XNOR A;
CASE IR(11 DOWNTO 10) IS WHEN \"00\"=> R0:=R0 XNOR A; WHEN \"01\"=> R1:=R1 XNOR A; WHEN \"10\"=> R2:=R2 XNOR A; WHEN OTHERS=> R3:=R3 XNOR A; END CASE; WHEN Swap --Swap: Rx to Ry;
=>
=>
<20>
CASE IR(11 DOWNTO 8) IS WHEN \"0100\"=> R0:=R1; WHEN \"1000\"=> R0:=R2; WHEN \"1100\"=> R0:=R3; WHEN \"0001\"=> R1:=R0; WHEN \"1001\"=> R1:=R2; WHEN \"1101\"=> R1:=R3; WHEN \"0010\"=> R2:=R0; WHEN \"0110\"=> R2:=R1; WHEN \"1110\"=> R2:=R3; WHEN \"0111\"=> R3:=R1; WHEN \"1011\"=>
<21>
R3:=R2; WHEN \"0011\"=> R3:=R0; WHEN OTHERS=> NULL; END CASE;
WHEN OTHERS => NULL; END CASE; WHEN --状态3
CASE IR(15 DOWNTO 12) IS WHEN --Swap
CASE IR(11 DOWNTO 10) IS WHEN \"00\"=> R0:=A; WHEN \"01\"=> R1:=A; WHEN \"10\"=> R2:=A; WHEN OTHERS=> R3:=A; END CASE;
3=>
\"1010\"=>
WHEN Jmp|Jz|Read|Write => IR(7 DOWNTO 0)<= M_data_in; -- 取双字节指令的后半部
<22>
PC := PC+1; WHEN OTHERS => NULL; END CASE; WHEN 4=>
--状态4
CASE IR(15 DOWNTO 12) IS
WHEN Jmp => PC := IR(11 DOWNTO 0); MAR <= IR(11 DOWNTO 0); WHEN Jz => IF(R0=\"00000000\") THEN PC := IR(11 DOWNTO 0); MAR <= IR(11 DOWNTO 0); ELSE
MAR <= PC; END IF;
WHEN Read => MAR <= IR(11 DOWNTO 0);
WHEN Write => MAR <= IR(11 DOWNTO 0); MDR <= R0; WHEN OTHERS => NULL;
<23>
END CASE; WHEN --状态5
MAR <= PC; WHEN 5=>
6=>
--状态6
CASE IR(15 DOWNTO 12) IS
WHEN Read => R0 := M_data_in; WHEN OTHERS=> NULL; END CASE; END CASE;
END IF; END PROCESS seq;
M_address <= MAR; M_data_out <= MDR;
Write_Read <= '1' WHEN reset = '1' AND status 5 AND IR(15 downto 12) = Write ELSE '0' ;
= <24>
END RTL;
四. Quartus II环境下的应用步骤
1.建立工程:工程名cpu
2.编写cpu的VHDL代码,将其添加到工程 3.生成cpu的符号图
4.建立内存数据的mif文件 5.生成16bits的ram
6.建立computer的block进行编译 7.对computer进行功能模拟 8.分析仿真波形
五. 仿真波形:
1) cpu的编译报告
2) mif文件
3) computer(由cpu和ram组成)的连接图
<25>
4)功能模拟的波段
<26>
<27>
六. 课程设计的总结:
通过这次课程设计,我不仅提高了系统设计与软件编程反面的能力,还对本学科有了更深入的认识。本次课程设计增加了我对计算机的了解,扩大了我知识面,还提高了我的个人动手与自学的能力,使我对quartusII软件运用的更加熟练,对本专业有了更大的兴趣。
最后感谢指导老师的耐心的指导与不断的讲解,使得我们在本学科知识领域有了大大的提高。
设计者班级:
姓名: 学号:
<28>
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- oldu.cn 版权所有 浙ICP备2024123271号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务