计算机组成原理实验报告
——CPU 综合实验
姓名:赵悦梅 学号:2008432002 专业:网络工程 成绩:
实验地点:主楼 502 时间:2010-10-18
指导老师: 张芳
一、 实验要求:
用 VHDL 语言编写具有一定功能的 CPU.
二、 实验目的:
使学生掌握计算机整机的工作原理,通过 CPU 设计实例,使学生能够深
入的掌握计算机的整机的工作原理。
三、 实验原理:
实验 CPU 采用 16 位字长,指令系统只有 15 条指令。
0000
DR
SR
0000
0111
(1)设指令名为 IR,从左到右的编号从 15 到 0. IR[ 15]到 IR[12]代表执行是
什么功能的指令,DR、SR 为所要操作的数.IR[15]为 0 时,运算指令;IR[15]、
IR[14]为 10 时转移指令;IR[15]、IR[14]为 11 时存储指令。算术逻辑指令
的 IR14 到 IR12 对应运算器 ALU 的 3 为运算操作。当 IR[0]=1 时,本指
令中有对 DR 的写操作;当 IR[1] =1 时,本指令影响标志位 Z;IR[2]=1 时,
本指令影响标志位 C.
(2)一条指令执行需要 3 拍时间。T1: 取值。在 t2 的上升沿,奖从存储器
取出的指令写入指令寄存器 IR 中。T2:根据指令寄存器 IR 的内容进行指
令译码;根据指令译码得到的控制信号进行运算和其他操作。T3:存储
器读、写操作;在 t3 的下降沿将运算结果写入目的寄存器,改变 C 标志
和 Z 标志;在 T3 的下降沿,改变 PC 的值,为取下一条指令做准备。
(3)CPU 由五部分组成,包括取指部分、指令译码部分、执行部分、存
储器部分和通用寄存器组。还有一个程序包,将各低层设计实体作为元件
存储,供各个设计实体使用。还有一个顶层设计实体完成 5 部分的链接。
四、 实验内容:
完成具有简单功能的 CPU,主要进行的运算指令有加法、自加 1、减法、
自减 1、与、或、取反、算术左移一位的功能。还有转移指令,包括 JMP、
JNC、JNZ。还包括存储功能,包括 MVRD、LDR、STR、和 NOP。
(1) 先执行 MVRD DR,DATA 指令即 1100 0000 0000 0000,摁两个节拍,
然后输入想要运算的数,在摁一个节拍,便把这个数存进去了,代表
为 R0;如果想将值存进 R1 中,便将上述指令 1100 0100 0000 0000。
(2) 然后再想做执行的操作,例如,R1 和 R2 进行加操作,则需要的输入
指令 0000 0001 0000 0111,然后摁三个节拍,便可显示结果。
(3) 用 R5—R0,可以分别查看 R0,R1,R2,R3,R4,PC,IR 在任意时刻的值。
五、 程序源码
decoder_2_to_4.cs
Library ieee;
use ieee.std_logic_1164.all;
entity decoder_2_to_4 is
port (
in std_logic_vector(1 downto 0);
sel:
sel00: out std_logic;
sel01: out std_logic;
sel02: out std_logic;
sel03: out std_logic
);
end decoder_2_to_4;
architecture Behavioral of decoder_2_to_4 is
begin
sel00 <= (not sel(1)) and (not sel(0));
sel01 <= (not sel(1)) and sel(0) ;
sel02 <= sel(1) and (not sel(0)) ;
sel03 <= sel(1) and sel(0) ;
end Behavioral;
decoder_unit.cs
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use work.exp_cpu_components.all;
entity decoder_unit is
port
(IR:
in std_logic_vector(15 downto 0);
out std_logic_vector(1 downto 0);
out std_logic_vector(1 downto 0);
SR:
DR:
op_code: out std_logic_vector(3 downto 0);
zj_instruct: out std_logic;
cj_instruct: out std_logic;
lj_instruct: out std_logic;
buffer std_logic;
DRWr:
out std_logic;
Mem_Write:
buffer std_logic;
DW_intruct:
out std_logic;
change_z:
change_c:
out std_logic;
sel_memdata: out std_logic;
r_sjmp_addr: out std_logic_vector(15 downto 0) --相对转移地址
);
end decoder_unit;
--为 1 时写 DR 寄存器
architecture behav of decoder_unit is
--为 1 时存储器的读出数据作为写入 DR 的数据
begin
SR <= IR(9 downto 8);
DR <= IR(11 downto 10);
sel_memdata <= IR(15) and IR(14) and (not IR(13));
change_z <= not IR(15) and IR(1);
change_c <= not IR(15) and IR(2);
DRWr_proc: process(IR)
begin
if IR(15) = '0' then
if IR(0) ='1' then
DRWr <= '1';
else
DRWr <= '0';
end if;
elsif IR(14) = '1' and IR(13) = '0' then
else
DRWr <= '1';
DRWr <= '0';
end if;
end process;
sj_addr_proc: process(IR)
begin
if IR(7) ='1' then
--条件转移指令的相对转移地址从 8 位扩展到 16 位
else
r_sjmp_addr <= "11111111" & IR(7 downto 0);
r_sjmp_addr <= "00000000" & IR(7 downto 0);
end if;
end process;
M_instruct:process(IR)
begin
case IR(15 downto 12) is
when "1000" | "1100" => --jmp addr;mvDR dr,data
Mem_Write <= '0';
DW_intruct <= '1';
when "1110" => -- str dr,sr
Mem_Write <= '1';
DW_intruct <= '0';
when others =>
Mem_Write <= '0';
DW_intruct <= '0';
end case;
end process;
ALUOP_CODE_PROC:PROCESS(IR)
begin
if IR(15) = '0' then
op_code <= IR(15 downto 12);
else
op_code <= "1111";
end if;
end process;
Jinstruct_PROC:
begin
process(IR)
case IR(15 downto 12) is
when "1000" => --jmp adr
zj_instruct <= '0';
cj_instruct <= '0';
lj_instruct <= '1';
when "1001" => --jnc addr
zj_instruct <= '0';
cj_instruct <= '1';
lj_instruct <= '0';
when "1010" => --jnz addr
zj_instruct <= '1';
cj_instruct <= '0';
lj_instruct <= '0';
when others =>
zj_instruct <= '0';
cj_instruct <= '0';
lj_instruct <= '0';
end case;
end process;
end behav;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use work.exp_cpu_components.all;
exe_unit.cs
entity exe_unit is
port(
--为 1 时,写存储器
out std_logic;
out std_logic;
in std_logic_vector(15 downto 0);
--以前指令产生的进位 C
--以前指令产生的 Z
t1: in std_logic;
op_code: in std_logic_vector(3 downto 0);
zj_instruct: in std_logic;
cj_instruct: in std_logic;
pc: in std_logic_vector(15 downto 0);
pc_inc:
c_in: in std_logic;
z_in: in std_logic;
Mem_Write: in std_logic;
c_tmp:
z_tmp:
c_z_j_flag: out std_logic; --为 1 时进行条件转移
r_sjmp_addr:
DW_intruct: in std_logic;
sjmp_addr:
SR_data: in std_logic_vector(15 downto 0);
DR_data: in std_logic_vector(15 downto 0);
Mem_Addr: out std_logic_vector(15 downto 0);
result: out std_logic_vector(15 downto 0)
);
in std_logic_vector(15 downto 0); --相对转移地址
out std_logic_vector(15 downto 0); --条件转移指令的转移地址
--运算结果
end exe_unit;
architecture behav of exe_unit is
signal A,B :std_logic_vector(15 downto 0);
signal result_t:
std_logic_vector(16 downto 0);
begin
c_z_j_flag <= ( (not c_in) and cj_instruct) or ((not z_in) and zj_instruct);
A <= DR_data;
B <= SR_data;
sjmp_addr <= pc_inc + r_sjmp_addr;
Mem_Addr_proc: process(t1,SR_DATA,pc,DW_intruct)
begin
if t1 = '1' then
Mem_Addr <= pc;
else
if DW_intruct = '1' then
Mem_Addr <= pc_inc;
elsif Mem_Write = '1' then
Mem_Addr <= DR_data;
else
Mem_Addr <= SR_data;
end if;
end if;
end process;
alu_proc:process(op_code,A,B)
begin
case op_code is
when "0000" =>
result_t <= ('0' & A) + ('0' & B);
when "0001" =>
result_t <= ('0' & A) + '1';
when "0010" =>
result_t <= ('0' & A) - ('0' & B);
when "0011" =>
result_t <= ('0' & A) -
'1';
when "0100" =>
result_t <= ('0' & A) and ('0' & B);
when "0101" =>
result_t <= ('0' & A) or ('0' & B);
when "0110" =>
result_t <= not ('0' & A);
when "1111" =>
result_t <= ('0' & B);
when "0111"=>
result_t<=('0'&A(14 downto 0)&A(0));
when others=>
result_t<=('0'&X"0000");
end case;
end process;
result <= result_t(15 downto 0);
c_tmp <= result_t(16);
z_tmp <= (not result_t(15)) and (not result_t(14)) and
(not result_t(13)) and (not result_t(12)) and
(not result_t(11)) and (not result_t(10)) and
(not result_t(9)) and (not result_t(8)) and
(not result_t(7)) and (not result_t(6)) and
(not result_t(5)) and (not result_t(4)) and
(not result_t(3)) and (not result_t(2)) and
(not result_t(1)) and (not result_t(0));
end behav;
exp_cpu.cs
library ieee;
use ieee.std_logic_1164.all;
use work.exp_cpu_components.all;
entity exp_cpu is port
--//系统时钟
--//系统复位信号
in std_logic;
in std_logic;
in std_logic_vector(5 downto 0); --选择寄存器
(
clk:
reset:
reg_sel:
reg_content: out std_logic_vector(15 downto 0); --寄存器输出
c_flag:
z_flag:
WE:
AR:
OB:
);
out std_logic_vector(15 downto 0);
inout std_logic_vector(15 downto 0)
out std_logic;
out std_logic;
out std_logic;
--//读写内存控制信号
--//读写内存地址
--//外部总线
end exp_cpu;
architecture behav of exp_cpu is
--instru_fetch out
signal t1,t2,t3: std_logic;
signal pc,pc_inc,IR: std_logic_vector(15 downto 0);
--decoder_unit out
signal SR,DR: std_logic_vector(1 downto 0);
signal op_code:
std_logic_vector(3 downto 0);
signal zj_instruct,cj_instruct,lj_instruct: std_logic;
signal DRWr,Mem_Write,DW_intruct,change_z:
signal change_c,sel_memdata: std_logic;
signal r_sjmp_addr: std_logic_vector(15 downto 0);
std_logic;
--exe_unit out
signal c_tmp,z_tmp,c_z_j_flag: std_logic;
signal Mem_Addr,result,sjmp_addr: std_logic_vector(15 downto 0);
--memory out
signal data_read,DR_data_out:
std_logic_vector(15 downto 0);
--regfile out
std_logic_vector(15 downto 0);
std_logic_vector(15 downto 0);
signal R0,R1,R2,R3:
signal output_DR,output_SR:
signal c_out,z_out:
std_logic;
begin
c_flag <= c_out;
z_flag <= z_out;
TEST_OUT: process(reg_sel)
begin
case reg_sel is
--被测信号以寄存器内容输出
when "000000" =>
reg_content <= R0;
when "000001" =>
reg_content <= R1;
when "000010" =>
reg_content <= R2;
when "000011" =>
reg_content <= R3;
when "000100" =>
reg_content <= "0000000" & t3 & "000" & t2 & "000" & t1;
when "111110" =>
reg_content <= pc;
when "111111" =>
reg_content <= IR;
when others =>
reg_content <= x"0000";
end case;
end process;
G_INSTRU_FETCH:
instru_fetch port map
--存储器读出的数
(reset => reset,
clk => clk,
data_read => data_read,
lj_instruct => lj_instruct, --来自 decoder 的长转移指令标志
DW_intruct => DW_intruct, --来自 decoder 的双字指令标志
c_z_j_flag => c_z_j_flag, --为 1 时进行条件转移,来自 EXE
sjmp_addr => sjmp_addr, --条件转移指令的转移地址,来自 EXE
t1 => t1,
t2 => t2,
t3 => t3,
pc => pc,
pc_inc => pc_inc,
IR => IR
);
G_DECODER:
decoder_unit port map
(IR => IR, --来自 instru_fetch
--源寄存器号
SR => SR,
DR => DR,
--目的寄存器号
op_code => op_code,
zj_instruct => zj_instruct, --为 1 时是如果 Z=0 则转移指令
--ALU 运算的操作码