计组实验报告

更新时间:2024-03-09 00:43:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

武汉大学计算机学院 计算机科学与技术专业

CPU设计实验报告

实验名称:开放式实验CPU设计 课题名称: 计算机组成原理 班 级:

指导教师: 徐 爱 萍 组 长: 组 员:

二零一五年三月

目录

目录 .................................................................................................................................................. 1 1 实验环境 ..................................................................................................................................... 2

1.1 Quartus Ⅱ介绍 .................................................................................................................. 2 1.2 硬件描述语言(VHDL) ................................................................................................. 3 1.3实验的主要成果 ................................................................................................................. 3 2 实验要求....................................................................................................................................... 5

2. 1 指令格式要求 ................................................................................................................... 5 2. 2 指令流程及微信号序列分析 ........................................................................................... 6

2.2.1 ADD指令分析 ..................................................................................................... 6 2.2.2 ADC指令分析 ..................................................................................................... 7 2.2.3 SUB指令分析 ...................................................................................................... 7 2.2.4 SBC指令分析 ...................................................................................................... 7 2.2.5 INC指令分析 ....................................................................................................... 7 2.2.6 DEC指令分析 ...................................................................................................... 8 2.2.7 SHL指令分析 ...................................................................................................... 8 2.2.8 SHR指令分析 ...................................................................................................... 8 2.2.9 MOVR指令分析 .................................................................................................. 8 2.2.10 MOVD指令分析................................................................................................ 9 2.2.11 LDRR指令分析 ................................................................................................. 9 2.2.12 STRR指令分析 ................................................................................................ 10 2.2.13 JMP指令分析 .................................................................................................. 10 2.2.14 JRC指令分析 ................................................................................................... 11 2.2.15 JRZ指令分析 ................................................................................................... 11 2.2.16 JRS指令分析 ................................................................................................... 11 2.2.17 CLC指令分析 .................................................................................................. 11 2.2.18 STC指令分析 .................................................................................................. 11

3.部件仿真实验 .............................................................................................................................. 11

3.1 八个通用寄存器设计与仿真 .......................................................................................... 11

3.1.1 设计代码 ............................................................................................................... 11 3.1.2 RTL连接图 ........................................................................................................... 17 3.1.3 仿真过程 ............................................................................................................... 17 3.2算术逻辑单元设计与仿真 ............................................................................................... 18

3.2.1 设计代码 ............................................................................................................... 18 3.2.2 RTL连接图 ........................................................................................................... 21 3.2.3 仿真过程 ............................................................................................................... 22

4. CPU设计 .................................................................................................................................... 23

4.1取指设计 ........................................................................................................................... 23 4.2指令译码的设计 ............................................................................................................... 25 4.3执行部分设计 ................................................................................................................... 28 4.4存储器部分设计 ............................................................................................................... 31 4.5通用寄存器组设计 ........................................................................................................... 32

1

4.6寄存器输出设计 ............................................................................................................... 36 4.7 程序包设计 ...................................................................................................................... 37 4.8顶层实体设计 ................................................................................................................... 41 5. 测试报告 .................................................................................................................................... 45

5.1规则文件 ........................................................................................................................... 45 5.2测试文件 ........................................................................................................................... 45 5.3指令测试 ........................................................................................................................... 46 6 实验总结..................................................................................................................................... 53

1 实验环境

1.1 Quartus Ⅱ介绍

QuartusⅡ是Altera公司的综合性PLD/FPGA开发软件,原理图、VHDL、VerilogHDL以及AHDL等多种设计输入形式,内嵌自有的综合器以及仿真器,可以完成从设计输入到硬件配置的完整PLD设计流程。QuartusⅡ提供了方便的设计输入方式、快速的编译和直接易懂的器件编程。能够支持逻辑门数在百万门以

2

上的逻辑器件的开发,并且为第三方工具提供了无缝接口。QuartusⅡ支持多种器件系列。QuartusⅡ软件包的编程器是系统的核心,提供功能强大的设计处理,设计者可以添加特定的约束条件来提高芯片的利用率。

1.2 硬件描述语言(VHDL)

在自顶向下的设计方法中,硬件描述语言如VHDL可以在高于逻辑级的抽象层次上用简练的方式提供精确的描述。

把设计任务分解到可控制的规模的方法形成了层次结构。层次结构的优点如下:

(1)在希望抽象的层次上,可以对设计进行精确而简练的描述。 (2)在同一时刻,只需设计系统某一部分的细节,这有利于组织并行的设计工作,开展大规模工程设计,而不是个人单兵作战。

(3)把注意力集中在系统可以控制的一部分,有助于减少设计错误和排错时间。

(4)对各个模块分别进行仿真、测试、功能校验。 (5)分阶段地进行设计,逐步加入各个构造模块。

VHDL的功能非常强大,不仅适合仿真,构建一个大的系统,对系统的行为进行描述,也适合设计具体的硬件电路。VHDL的全称是Very High Speed Integrated Circuit Hardware Description Language,即超高速集成电路描述语言。硬件描述语言有许多种,如ABEL、Verilog等,VHDL是其中著名的一种硬件描述语言。VHDL要适用于许多复杂的情况,还要适应各种硬件设计人员原先的习惯方式和设计风格,因此设计得比较全面。

1.3实验的主要成果

整个实验的过程可以被分为三个部分:通用寄存器组仿真、算术逻辑单元仿真、实验CPU设计及调试。

(1)通用寄存器组仿真。

了解通用寄存器组的用途及对CPU的重要性;掌握通用寄存器组的设计方法;其中共有4个16位的寄存器,具有复位功能和写入读出功能。

3

4个16位寄存器的通用寄存器组的框图如下图:

(2)算术逻辑单元仿真。掌握运算器的工作原理;验证运算器的功能;实现了对二进制数据进行定点算术运算、逻辑运算和传送数据操作。

算术运算包括定点加减运算;逻辑运算主要有逻辑与、逻辑或、逻辑非操作。 具体操作码及其实现的操作见下表:

4

2.2.12 STRR指令分析

T2:Mem_Addr<-DR

T3:we<-0 ob<-SR pc<-pc_inc

T2将DR送入存储器地址总线。T3时we为0时写存储器;将SR值写入存储器。

访存指令流程图:

将寄存器中数据经数

据总线送入MDA 将地址经地址总线送 入MAR,并读写使能 端为写

将MDR中数据存入存

储器

2.2.13 JMP指令分析

T2:Mem_Addr<-pc_inc

T3:we<-1 data_read<-ob pc<-data_read

T2将ADR送入存储器地址总线。T3时we为1时读存储器;将所得数据送入pc。

跳转指令流程图:

取指令中立即数送

入ALU的A端,将

PC得值送入B端

ALU完成加运算将结 果送到暂存器Y中

将Y中数据经数据总

线送入PC

10

2.2.14 JRC指令分析

T2:generate c_z_j_flag generate sjmp_addr

T3:if c_z_j_flag=1 then pc<- sjmp_addr else pc<-pc_inc T3如果C为0,则pc<-ADR;C为1,则顺序执行。

2.2.15 JRZ指令分析

T2:generate c_z_j_flag generate sjmp_addr

T3:if c_z_j_flag=1 then pc<- sjmp_addr else pc<-pc_inc T3如果Z为0,则pc<-ADR;Z为1,则顺序执行。

2.2.16 JRS指令分析

与上面两条指令类似。

2.2.17 CLC指令分析

T2:c_tmp<-0

T3:pc<-pc_inc c_out<-c_ tmp 改变C值为0。

2.2.18 STC指令分析

与上面一条指令类似。

3.部件仿真实验

3.1 八个通用寄存器设计与仿真

3.1.1 设计代码 (1)设计实体reg

library ieee;

use ieee.std_logic_1164.all;

entity reg is

11

port ( clr: in std_logic; D: in std_logic_vector(15 downto 0); clock: in std_logic; write: in std_logic; sel: in std_logic; Q: out std_logic_vector(15 downto 0) ); end reg;

architecture behav of reg is begin process(clr,clock) begin if clr = '0' then Q <= x\ elsif (clock'event and clock = '1') then if sel = '1' and write = '1' then Q <= D; end if; end if; end process; end behav;

(2)设计实体decoder2_to_4

Library ieee;

use ieee.std_logic_1164.all;

entity decoder_2_to_4 is port ( sel: in std_logic_vector(1 downto 0); sel00: out std_logic; sel01: out std_logic; sel02: out std_logic; sel03: out std_logic );

end decoder_2_to_4;

12

architecture behav 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 behav;

(3)设计实体mux4_to_1

library ieee;

use ieee.std_logic_1164.all;

entity mux_4_to_1 is port ( input0, input1, input2, input3: in std_logic_vector(15 downto 0); sel: in std_logic_vector(1 downto 0); out_put: out std_logic_vector(15 downto 0)); end mux_4_to_1;

architecture behav of mux_4_to_1 is begin

mux: process(sel, input0, input1, input2, input3) begin case sel is when \ out_put <= input0; when \ out_put <= input1; when \ out_put <= input2; when \ out_put <= input3; end case; end process; end behav;

(4)顶层设计实体register

library IEEE;

13

use IEEE.STD_LOGIC_1164.ALL;

entity regfile is Port ( DR: in std_logic_vector(1 downto 0); SR: in std_logic_vector(1 downto 0); reset: in std_logic; DRWr: in std_logic; clk: in std_logic; d_input: in std_logic_vector(15 downto 0); DR_data: out std_logic_vector(15 downto 0); SR_data: out std_logic_vector(15 downto 0) ); end regfile;

architecture struct of regfile is -- components

-- 16 bit Register for register file component reg port ( clr: in std_logic; D: in std_logic_vector(15 downto 0); clock: in std_logic; write: in std_logic; sel: in std_logic; Q: out std_logic_vector(15 downto 0) ); end component;

-- 2 to 4 Decoder

component decoder_2_to_4 port( sel: in std_logic_vector(1 downto 0); sel00: out std_logic; sel01: out std_logic; sel02: out std_logic; sel03: out std_logic ); end component;

-- 4 to 1 line multiplexer component mux_4_to_1 port ( input0, input1,

14

input2, input3: in std_logic_vector(15 downto 0); sel: in std_logic_vector(1 downto 0); out_put: out std_logic_vector(15 downto 0)); end component;

signal reg00, reg01, reg02, reg03

:std_logic_vector(15 downto 0); signal sel00 ,sel01 ,sel02 ,sel03 : std_logic;

begin

Areg00: reg port map( clr => reset, D => d_input , clock => clk , write => DRWr , sel => sel00 , Q => reg00 );

Areg01: reg port map( clr => reset, D => d_input , clock => clk , write => DRWr , sel => sel01 , Q => reg01 );

Areg02: reg port map( clr => reset, D => d_input , clock => clk , write => DRWr , sel => sel02 , Q => reg02 );

Areg03: reg port map( clr => reset, D => d_input , clock => clk , write => DRWr , sel => sel03 , Q => reg03

15

);

-- decoder

des_decoder: decoder_2_to_4 port map ( sel => DR, sel00 => sel00 , sel01 => sel01 , sel02 => sel02 , sel03 => sel03 );

mux1: mux_4_to_1 PORT MAP( Input0 => reg00 , Input1 => reg01 , Input2 => reg02 , Input3 => reg03 , sel => DR , out_put => DR_data );

mux2: mux_4_to_1 PORT MAP( input0 => reg00 , input1 => reg01 , input2 => reg02 , input3 => reg03 , sel => SR , out_put => SR_data ); end struct;

16

3.1.2 RTL连接图

3.1.3 仿真过程

(1)数据含义

Clk:时钟信号 Reset:复位信号 d_input:数据输入 DRWr:允许写入信号

DR:2-4译码器输入端,第一个4选1多路器选择端 SR:第二个4选1多路器选择端 DR_data:目的操作数 SR_data:源操作数 (2)运算过程分析

前四个周期,数据输出并无规律,此时主要执行的操作是将d_input输入的4个数据0000、0001、0002、0003分别存到R0R1R2R3;

从第五个周期开始往后,数据输出呈现规律,此时,前半周期DR为00选中R0,读出第一个周期时就存入的数据0000,SR为01选中R1,读出第

17

二周期就存入的数据0001。后半周期,由于clk上升沿,将此时的d_input即0004存入R0,改变了R0中的数据,DR_data就显示0004。

第六周期,前半周期DR为01选中R1,读出第二个周期时就存入的数据0001,SR为02选中R2,读出第二周期就存入的数据0002。后半周期,由于clk上升沿,将此时的d_input即0005存入R1,改变了R1中的数据,DR_data就显示0005。

以此类推。

3.2算术逻辑单元设计与仿真

3.2.1 设计代码 (1)设计实体reg

library ieee;

use ieee.std_logic_1164.all;

entity reg is port ( clr: in std_logic; D: in std_logic_vector(15 downto 0); clock: in std_logic; write: in std_logic; sel: in std_logic; Q: out std_logic_vector(15 downto 0) ); end reg;

architecture behav of reg is begin process(clr,clock) begin if clr = '0' then Q <= x\ elsif (clock'event and clock = '1') then if sel = '1' and write = '1' then Q <= D; end if; end if; end process; end behav;

18

(2)顶层设计实体ALU

library ieee;

use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all;

entity ALU is port( reset,clk : in std_logic; OP: in std_logic_vector(2 downto 0); sel: in std_logic; write: in std_logic; C,Z: out std_logic; Dinput: in std_logic_vector(15 downto 0); result: out std_logic_vector(15 downto 0) ); end ALU;

architecture behav of alu is component reg is port ( clr: in std_logic; D: in std_logic_vector(15 downto 0); clock: in std_logic; write: in std_logic; sel: in std_logic; Q: out std_logic_vector(15 downto 0) );

end component;

signal z_tmp :std_logic;

signal A,B :std_logic_vector(15 downto 0);

signal result_t: std_logic_vector(16 downto 0);

begin

A_reg: reg port map (clr => reset, D => Dinput, clock => clk, write => write, sel => (not sel), Q => A

19

);

B_reg: reg port map (clr => reset, D => Dinput, clock => clk, write => write, sel => sel, Q => B );

alu_proc:process(OP,A,B) begin case OP is when \ result_t <= ('0' & A) + ('0' & B); when \ result_t <= ('0' & A) + '1'; when \ result_t <= ('0' & A) - ('0' & B); when \ result_t <= ('0' & A) - '1'; when \ result_t <= ('0' & A) and ('0' & B); when \ result_t <= ('0' & A) or ('0' & B); when \ result_t <= not ('0' & B); when \ result_t <= ('0' & B); end case; end process;

result <= result_t(15 downto 0);

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));

c_proc: Process(reset,clk,result_t,OP)

20

begin

if reset = '0' then C <= '0'; elsif clk'event and clk = '1' then if OP(2) = '0' then C <= result_t(16); end if; end if; end process;

z_proc: process(reset,clk,z_tmp,OP) begin

if reset = '0' then Z <= '0'; elsif clk'event and clk = '1' then if OP /= \ Z <= z_tmp; end if; end if; end process;

end behav;

3.2.2 RTL连接图

21

3.2.3 仿真过程

(1)各项数据

clk:时钟信号 reset:复位信号 Dinput:数据输入 write:允许写入信号 OP:运算操作码 sel:寄存器选择信号 result:运算结果

Z:标志位z(结果是否为0) C:标志位c(运算进位)

(2)运算过程分析

第一个时钟周期,write=0,A、B不送入数据,OP=000,result = A+B = 0000+0000 = 0000,结果为0,在clk上升沿置z为1,无进位,c为0;

第二个时钟周期,write=0,A、B不送入数据,OP=001,result=A+1=0001,结果不为0,在clk上升沿置z为0,无进位,c为0;

第三个时钟周期,write为1,sel为0,dinput=0003在clk上升沿送入A中,OP=010,clk为0,result = A-B = 0000 - 0000 = 0000,clk为1,result=A-B=0003-0000=0003,clk为0时,result为0,在clk上升沿改变z的值置为1,无进位,c为0;

第四个周期,write为1,sel为1,dinput=0004在clk上升沿送入B中, OP=011,result=A-1=0002, 结果不为0,在clk上升沿置z为0,无进位,c为0;…………

22

4. CPU设计

4.1取指设计

(1)设计代码

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 instru_fetch is

port(reset,clk: in std_logic; data_read: in std_logic_vector(15 downto 0); --存储器读出的数 lj_instruct: in std_logic; --长转移指令 DW_intruct: in std_logic; c_z_j_flag: in std_logic; --为1时进行条件转移 sjmp_addr: in std_logic_vector(15 downto 0); --条件转移指令的转移地址 t1,t2,t3: buffer std_logic; pc: buffer std_logic_vector(15 downto 0); pc_inc: buffer std_logic_vector(15 downto 0); IR: out std_logic_vector(15 downto 0) );

end instru_fetch;

architecture behav of instru_fetch is signal start : std_logic;

begin

IR_poc: process(reset,t2) begin

if reset = '0' then IR <= x\ --nop指令 elsif t2'event and t2 = '1' then IR <= data_read; end if;

end process;

process(reset,clk) begin

if reset = '0' then start <= '1';

23

else if clk'event and clk ='0' then start <= '0'; end if; end if;

end process;

process(reset,clk) begin

if reset = '0' then t1 <= '0'; t2 <= '0'; t3 <= '0';

elsif clk'event and clk = '1' then t1 <= start or t3; t2 <= t1; t3 <= t2; end if;

end process;

pc_inc <= pc + '1'; --为取双字指令的第2个字或者计算相对转移地址做准备 PC_proc: process(reset,t3) begin

if reset = '0' then pc <= x\

elsif t3'event and t3 = '0' then if lj_instruct = '1' then pc <= data_read; elsif c_z_j_flag ='1' then pc <= sjmp_addr; elsif DW_intruct = '1' then pc <= pc + \ else pc <= pc_inc; end if; end if;

end process;

end behav;

24

(2)转换后的符号

4.2指令译码的设计

(1)设计代码

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); SR: out std_logic_vector(2 downto 0); DR: out std_logic_vector(2 downto 0); op_code: out std_logic_vector(3 downto 0); zj_instruct: out std_logic; cj_instruct: out std_logic; lj_instruct: out std_logic; DRWr: buffer std_logic; --为1时写DR寄存器 Mem_Write: out std_logic; DW_intruct: buffer std_logic; change_z: out std_logic; change_c: out std_logic; sel_memdata: out std_logic; --为1时存储器的读出数据作为写入DR的数据 r_sjmp_addr: out std_logic_vector(15 downto 0); --相对转移地址 c_sign : out std_logic_vector(1 downto 0)-- );

end decoder_unit;

architecture behav of decoder_unit is

25

begin

SR <= IR(2 downto 0); DR <= IR(5 downto 3);

sel_memdata <= ((not IR(10)) and IR(9) and (not IR(8)) and IR(7) and (not IR(6)))or ((not IR(10)) and IR(9) and (not IR(8)) and (not IR(7)) and IR(6)); change_z <= (not IR(10)) and (not IR(9)); change_c <= (not IR(9));

DRWr_proc: process(IR) begin

if IR(10) = '0' and IR(9) = '0' then --算术逻辑指令 DRWr <= '1';

elsif IR(10) = '0' and IR(9) = '1' and IR(8) = '0' then --MOVR DR,SR;MVRD DR,DATA;LDR DR,SR;

if IR(7) = '1' and IR(6) ='1' then DRWr <= '0'; else DRWr <= '1'; end if; else DRWr <= '0'; end if;

end process;

sj_addr_proc: process(IR) --条件转移指令的相对转移地址从6位扩展到16位 begin

case IR(10 downto 6) is when \ if IR(5)='1' then r_sjmp_addr <= \ else r_sjmp_addr <= \ end if; when others => r_sjmp_addr <= \ end case; end process;

M_instruct:process(IR) begin

case IR(10 downto 6) is when \ dr,data; Mem_Write <= '0'; DW_intruct <= '1';

26

when \ -- str sr,dr 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(10) = '0' and IR(9) = '0'then op_code <= IR(9 downto 6); else op_code <= \ end if;

end process;

Jinstruct_PROC: process(IR) begin

case IR(10 downto 6) is when \ zj_instruct <= '0'; cj_instruct <= '0'; lj_instruct <= '1'; when \ zj_instruct <= '0'; cj_instruct <= '1'; lj_instruct <= '0'; when \ zj_instruct <= '1'; cj_instruct <= '0'; lj_instruct <= '0'; when others => zj_instruct <= '0'; cj_instruct <= '0'; lj_instruct <= '0'; end case; end process;

C_instruct: process(IR) begin

if IR(10 downto 6) = \ c_sign(1) <= '1';

--clc 27

c_sign(0) <= '0';

elsif IR(10 downto 6) = \ --stc c_sign(1) <= '1'; c_sign(0) <= '1'; else c_sign(1) <= '0'; c_sign(0) <= '0'; end if;

end process;

end behav;

(2)转换后的符号

4.3执行部分设计

(1)设计代码

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 exe_unit is port(

t1: in std_logic;

28

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: in std_logic_vector(15 downto 0); c_in: in std_logic; --以前指令产生的进位C z_in: in std_logic; --以前指令产生的Z Mem_Write: in std_logic; --为1时,写存储器 c_tmp: out std_logic; z_tmp: out std_logic; c_z_j_flag: out std_logic; --为1时进行条件转移 r_sjmp_addr: in std_logic_vector(15 downto 0); --相对转移地址 DW_intruct: in std_logic; sjmp_addr: out std_logic_vector(15 downto 0); --条件转移指令的转移地址 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); --运算结果 c_sign: in std_logic_vector(1 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;

29

end if;

end process;

alu_proc:process(op_code,A,B,c_in) begin

case op_code is when \ result_t <= ('0' & A) + ('0' & B); when \ result_t <= ('0' & A) + ('0' & B) + c_in; when \ result_t <= ('0' & A) - ('0' & B); when \ result_t <= ('0' & A) - ('0' & B) - c_in; when \ result_t <= ('0' & A) + '1'; when \ result_t <= ('0' & A) - '1'; when \ result_t <= ('0' & A) + ('0' & A); when \

result_t(16) <= '0'; result_t(15) <= A(15); result_t( 14 downto 0) <= A( 15 downto 1); when others => result_t <= ('0' & B); end case; end process;

result <= result_t(15 downto 0);

c_tmp <= (result_t(16) and (not c_sign(1))) or (c_sign(1) and c_sign(0)); 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;

30

4.4存储器部分设计

(1)设计代码

library ieee;

use ieee.std_logic_1164.all;

use work.exp_cpu_components.all;

entity memory_unit is port( reset: in std_logic; clk,t3: in std_logic; Mem_addr: in std_logic_vector(15 downto 0); Mem_Write: in std_logic; sel_memdata: in std_logic; --为1时存储器的读出数据作为写入DR的数据 SR_data: in std_logic_vector(15 downto 0); --写存储器的数据 result: in std_logic_vector(15 downto 0); --运算结果 rw: out std_logic; ob: inout std_logic_vector(15 downto 0); ar: out std_logic_vector(15 downto 0); data_read: buffer std_logic_vector(15 downto 0); --从存储器读出的指令或者数据 DR_data_out: out std_logic_vector(15 downto 0) --写入DR的数据 );

end memory_unit;

architecture behav of memory_unit is begin

ar <= Mem_addr;

R_W_Memory_proc: process(reset,ob,SR_data,clk,t3,Mem_Write) --读写存储器处理 begin

if reset = '0' then rw <= '1'; ob <= \ --将存储器数据总线置为高阻,读存储器 else

if Mem_Write = '1' and t3 = '1' then ob <= SR_DATA; --写存储器 rw <= clk; else ob <= \ --将存储器数据总线置为高阻,读存储器 rw <= '1'; data_read <= ob; end if;

31

end if;

end process;

sele_DR_proc: process(sel_memdata,data_read,result) begin

if sel_memdata = '1' then DR_data_out <= data_read; --存储器数据作为写DR的数据 else DR_data_out <= result; --运算结果作为写DR的数据 end if;

end process;

end behav;

(2)转换后的符号

4.5通用寄存器组设计

(1)设计代码

library ieee;

use ieee.std_logic_1164.all;

use work.exp_cpu_components.all;

entity regfile is

Port ( DR: in std_logic_vector(2 downto 0); --目的寄存器号 SR: in std_logic_vector(2 downto 0); --源寄存器号 reset: in std_logic; write: in std_logic; --写寄存器信号 clk: in std_logic; d_input: in std_logic_vector(15 downto 0); --写寄存器的数据 change_z: in std_logic; --如果为1,则重新设置z标志 change_c: in std_logic; c_in: in std_logic;

32

z_in: in std_logic;

R0,R1,R2,R3,R4,R5,R6,R7 : out std_logic_vector(15 downto 0); output_DR: out std_logic_vector(15 downto 0); output_SR: out std_logic_vector(15 downto 0); c_out: out std_logic; z_out: out std_logic );

end regfile;

architecture struct of regfile is

signal reg00, reg01, reg02, reg03, reg04, reg05, reg06, reg07: std_logic_vector(15 downto 0); signal sel00, sel01, sel02, sel03, sel04, sel05, sel06, sel07: std_logic; begin

R0 <= reg00; R1 <= reg01; R2 <= reg02; R3 <= reg03; R4 <= reg04; R5 <= reg05; R6 <= reg06; R7 <= reg07;

z_c_proc: process(reset,clk) --对指令执行结束后的z、c标志进行处理 begin

if reset = '0' then z_out <= '0'; c_out <= '0';

elsif clk'event and clk = '0' then if change_z = '1' then z_out <= z_in; end if; if change_c = '1' then c_out <= c_in; end if; end if;

end process;

Areg00: reg port map( --寄存器R0 reset => reset, d_input => d_input, clk => clk, write => write, sel => sel00,

33

q_output => reg00 );

Areg01: reg port map( reset => reset, d_input => d_input, clk => clk,

write => write, sel => sel01, q_output => reg01 );

Areg02: reg port map( reset => reset, d_input => d_input, clk => clk,

write => write, sel => sel02, q_output => reg02 );

Areg03: reg port map( reset => reset, d_input => d_input, clk => clk,

write => write, sel => sel03, q_output => reg03 );

Areg04: reg port map( reset => reset, d_input => d_input, clk => clk,

write => write, sel => sel04, q_output => reg04 );

Areg05: reg port map( reset => reset, d_input => d_input, clk => clk,

write => write,

--寄存器R1

--寄存器R2

--寄存器R3

--寄存器R4

--寄存器R5

34

sel => sel05, q_output => reg05 );

Areg06: reg port map( --寄存器R6 reset => reset, d_input => d_input, clk => clk, write => write, sel => sel06, q_output => reg06 );

Areg07: reg port map( --寄存器R7 reset => reset, d_input => d_input, clk => clk, write => write, sel => sel07, q_output => reg07 );

des_decoder: decoder_3_to_8 port map( --3 8译码器 sel => DR,

sel00 => sel00, sel01 => sel01, sel02 => sel02, sel03 => sel03, sel04 => sel04, sel05 => sel05, sel06 => sel06, sel07 => sel07 );

muxA: mux_8_to_1 port map( --目的寄存器读出8选1选择器 input0 => reg00, input1 => reg01, input2 => reg02, input3 => reg03, input4 => reg04, input5 => reg05, input6 => reg06, input7 => reg07, sel => DR,

35

out_put => output_DR );

muxB: mux_8_to_1 port map( input0 => reg00, input1 => reg01, input2 => reg02, input3 => reg03, input4 => reg04, input5 => reg05, input6 => reg06, input7 => reg07, sel => SR, out_put => output_SR );

end struct;

--源寄存器读出8选1选择器

(2)转换后的符号

4.6寄存器输出设计

(1)设计代码

library ieee;

use ieee.std_logic_1164.all;

entity reg is port (reset: in std_logic; d_input: in std_logic_vector(15 downto 0);

36

clk: in std_logic; write: in std_logic; sel: in std_logic; q_output: out std_logic_vector(15 downto 0) );

end reg;

architecture a OF reg is begin

process(reset,clk) begin IF reset = '0' then q_output <= x\ elsif clk'event and clk = '0' then --时钟下降沿触发 if sel ='1' and write = '1' then q_output <= d_input; end if; end if; end process; end a;

4.7 程序包设计

(1)设计代码

library ieee;

use ieee.std_logic_1164.all;

package exp_cpu_components is component reg port ( reset: in std_logic; d_input: in std_logic_vector(15 downto 0); clk: in std_logic; write: in std_logic; sel: in std_logic; q_output: out std_logic_vector(15 downto 0) );

end component;

component mux_8_to_1 port ( input0,

37

input1, input2, input3, input4, input5, input6,

input7: in std_logic_vector(15 downto 0); sel: in std_logic_vector(2 downto 0);

out_put: out std_logic_vector(15 downto 0) );

end component;

component decoder_3_to_8 port ( sel: in std_logic_vector(2 downto 0); sel00: out std_logic; sel01: out std_logic; sel02: out std_logic; sel03: out std_logic; sel04: out std_logic; sel05: out std_logic; sel06: out std_logic; sel07: out std_logic );

end component;

component regfile Port (DR: in std_logic_vector(2 downto 0); SR: in std_logic_vector(2 downto 0); reset: in std_logic; write: in std_logic; clk: in std_logic; d_input: in std_logic_vector(15 downto 0); change_z: in std_logic; change_c: in std_logic; c_in: in std_logic; z_in: in std_logic;

R0,R1,R2,R3,R4,R5,R6,R7 : out std_logic_vector(15 downto 0); output_DR: out std_logic_vector(15 downto 0); output_SR: out std_logic_vector(15 downto 0); c_out: out std_logic; z_out: out std_logic );

end component;

38

component instru_fetch port ( reset,clk: in std_logic; data_read: in std_logic_vector(15 downto 0); --存储器读出的数 lj_instruct: in std_logic; --长转移指令 DW_intruct: in std_logic; --双字指令 c_z_j_flag: in std_logic; --为1时进行条件转移 sjmp_addr: in std_logic_vector(15 downto 0); --条件转移指令的转移地址 t1,t2,t3: buffer std_logic; pc: buffer std_logic_vector(15 downto 0); pc_inc: buffer std_logic_vector(15 downto 0); IR: out std_logic_vector(15 downto 0) );

end component;

component decoder_unit port (IR: in std_logic_vector(15 downto 0); SR: out std_logic_vector(2 downto 0); DR: out std_logic_vector(2 downto 0); op_code: out std_logic_vector(3 downto 0); zj_instruct: out std_logic; cj_instruct: out std_logic; lj_instruct: out std_logic; DRWr: buffer std_logic; --为1时写DR寄存器 Mem_Write: out std_logic; DW_intruct: buffer std_logic; change_z: out std_logic; change_c: out std_logic; sel_memdata: out std_logic; --为1时存储器的读出数据作为写入DR的数据 r_sjmp_addr: out std_logic_vector(15 downto 0); --相对转移地址 c_sign: out std_logic_vector(1 downto 0)--修改C的值 );

end component;

component exe_unit port (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: in std_logic_vector(15 downto 0); c_in: in std_logic; --以前指令产生的进位C z_in: in std_logic; --以前指令产生的Z

39

Mem_Write: in std_logic; --为1时,写存储器 c_tmp: out std_logic; z_tmp: out std_logic; c_z_j_flag: out std_logic; --为1时进行条件转移 r_sjmp_addr: in std_logic_vector(15 downto 0); --相对转移地址 DW_intruct: in std_logic; sjmp_addr: out std_logic_vector(15 downto 0); --条件转移指令的转移地址 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); --运算结果 c_sign: in std_logic_vector(1 downto 0) --clc,stc中的进位,来自decoder );

end component;

component memory_unit port (reset: in std_logic; clk,t3: in std_logic; Mem_addr: in std_logic_vector(15 downto 0); Mem_Write: in std_logic; sel_memdata: in std_logic; --为1时存储器的读出数据作为写入DR的数据 SR_data: in std_logic_vector(15 downto 0); --写存储器的数据 result: in std_logic_vector(15 downto 0); --运算结果 rw: out std_logic; ob: inout std_logic_vector(15 downto 0); ar: out std_logic_vector(15 downto 0); data_read: buffer std_logic_vector(15 downto 0); --从存储器读出的指令或者数据 DR_data_out: out std_logic_vector(15 downto 0) --写入DR的数据 );

end component;

component test_out port

(reg_sel : in std_logic_vector(5 downto 0);

reg_content : out std_logic_vector(15 downto 0);

R0,R1,R2,R3,R4,R5,R6,R7: in std_logic_vector(15 downto 0); pc,IR: in std_logic_vector(15 downto 0); t1,t2,t3: in std_logic );

end component;

end exp_cpu_components;

40

4.8顶层实体设计

(1)设计代码

library ieee;

use ieee.std_logic_1164.all;

use work.exp_cpu_components.all;

entity exp_cpu is port ( clk :in std_logic; --系统时钟 reset :in std_logic; --系统复位信号 reg_sel :in std_logic_vector(5 downto 0);

reg_content :out std_logic_vector(15 downto 0); c_flag :out std_logic; z_flag :out std_logic; WE :out std_logic; --读写内存控制信号 AR :out std_logic_vector(15 downto 0); --读写内存地址 OB :inout std_logic_vector(15 downto 0) --外部总线 );

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(2 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: std_logic; signal change_c,sel_memdata: std_logic;

signal r_sjmp_addr: std_logic_vector(15 downto 0); signal c_sign: std_logic_vector(1 downto 0); --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

signal output_DR,output_SR: std_logic_vector(15 downto 0); signal c_out,z_out: std_logic;

signal R0,R1,R2,R3,R4,R5,R6,R7 : std_logic_vector(15 downto 0);

41

begin

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, --ALU运算的操作码 zj_instruct => zj_instruct, --为1时是如果Z=0则转移指令 cj_instruct => cj_instruct, --为1时是如果C=0则转移指令 lj_instruct => lj_instruct, --为1时是无条件长转移指令 DRWr => DRWr, --为1时在t3下降沿写DR寄存器,送往regfile Mem_Write => Mem_Write, --为1时对存储器进行写操作。 DW_intruct => DW_intruct, --为1时是双字指令 change_z => change_z, --为1时在t3下降沿根据指令执行结果置Z标志 change_c => change_c, --为1时在t3下降沿根据指令执行结果置Z标志 sel_memdata => sel_memdata, --为1时存储器的读出数据作为写入DR的数据 r_sjmp_addr => r_sjmp_addr, --相对转移地址 c_sign => c_sign --clc,stc中进位c的值,送往exe );

G_EXE: exe_unit port map (

t1 => t1, op_code => op_code, --ALU运算的操作码,来自decoder zj_instruct => zj_instruct, --为1时是如果Z=1则转移指令,来自decoder cj_instruct => cj_instruct, --为1时是如果C=1则转移指令,来自decoder pc => pc, --来自instru_fetch pc_inc => pc_inc, --来自instru_fetch c_in => c_out,--以前指令产生的进位C,来自regfile

42

z_in => z_out, --以前指令产生的Z,来自regfile Mem_Write => Mem_Write, --存储器写,来自decoder_unit c_tmp => c_tmp, --本条指令产生的Z标志送往regfile z_tmp => z_tmp, --本条指令产生的Z标志送往regfile c_z_j_flag => c_z_j_flag, --为1时进行条件转移,送往instru_fetch r_sjmp_addr => r_sjmp_addr, --相对转移地址,来自decoder DW_intruct => DW_intruct, --双字指令标志,来自decoder,送往 sjmp_addr => sjmp_addr,--条件转移指令的转移地址instru_fetch SR_data => output_SR, --SR寄存器值,来自regfile DR_data => output_DR, --SR寄存器值,来自regfile Mem_Addr => Mem_Addr, --存储器地址,送往memory result => result, --运算结果,送往regfile c_sign => c_sign --clc,stc中的进位,来自decoder );

G_MEMORY: memory_unit port map (reset => reset, clk => clk, t3 => t3, Mem_addr => Mem_addr, --存储器地址,来自exe_unit Mem_Write => Mem_Write, --存储器写,来自decoder_unit sel_memdata => sel_memdata, --为1时存储器的读出数据作为写入DR的数据,来自decoder

SR_data => output_SR,--写存储器的数据,来自regfile result => result, --运算结果,来自exe_unit rw => WE, --存储器读写信号,送往芯片外部 ob => ob, --存储器数据总线,和芯片外部存储器数据总线连接 ar => AR, --存储器地址,送往芯片外部和存储器地址总线连接 data_read => data_read, --从存储器读出的指令,送往instru_fetch DR_data_out => DR_data_out --写入DR的数据,送往regfile );

G_REGFILE: regfile port map

(DR => DR, --DR寄存器号,来自decoder SR => SR, --SR寄存器号,来自decoder reset => reset, write => DRWr, --寄存器写控制信号,来自decoder clk => t3, --寄存器写入脉冲,来自instru_fetch,下降沿写入 d_input => DR_data_out, --写入寄存器的数据,来自memory change_z => change_z, --为1时在t4下降沿根据Z_tmp置Z标志,来自decoder change_c => change_c, --为1时在t4下降沿根据C_tmp置C标志,来自decoder c_in => c_tmp, --本条指令得到的c,来自decoder z_in => z_tmp, --本条指令得到的c,来自decoder R0 => R0,

43

R1 => R1, R2 => R2, R3 => R3, R4 => R4, R5 => R5, R6 => R6, R7 => R7, output_DR => output_DR, --DR寄存器内容,送往exe和memory output_SR => output_SR, --SR寄存器内容,送往exe c_out => c_out, --C标志,送往exe和exp z_out => z_out --Z标志,送往exe和exp );

G_TEST_OUT: test_out port map (reg_sel => reg_sel ,

reg_content => reg_content, R0 => R0, R1 => R1, R2 => R2, R3 => R3, R4 => R4, R5 => R5, R6 => R6, R7 => R7, pc => pc, IR => IR, t1 => t1, t2 => t2, t3 => t3 ); end behav;

(2)整体连接图

44

5. 测试报告

5.1规则文件

ADD DR,SR \ADC DR,SR \SUB DR,SR \SBC DR,SR \INC DR \DEC DR \SHL DR \SHR DR \

MOVR DR,SR \

MOVD DR,DATA \LDRR DR,SR \STRR DR,SR \JMP ADR \JRZ ADR \JRC ADR \CLC 0 \STC 1 \R0 = 0 R1 = 1 R2 = 2 R3 = 3 R4 = 4 R5 = 5 R6 = 6 R7 = 7

5.2测试文件

1运算测试 ○

main: MOVD R2,0x5555 MOVD R3,0xffff ADD R3,R2 ADC R3,R2 SUB R3,R2 SBC R3,R2 INC R2 DEC R2 SHL R2

45

SHR R2

○2传送测试

main: MOVD R1,0x5555

MOVD R3,0x4444 LDRR R1,R3 STRR R1,R3 MOVR R1,R3

○3转移测试

main: MOVD R0,0x002

T1: DEC R0 JRZ T1

MOVD R0,0xfffe T2: INC R0 JRC T2

MOVD R0,0x7ffe T3: INC R0 JMP main

○4进位指令测试(STC,CLC)

main: MOVD R1,0x1111

T1: INC R1 JRC T2

MOVD R2,0x2222 T2: STC 1 MOVD R3,0xffff JRC T1 INC R3 CLC 0 JRC T1

MOVD R4,0x4444

5.3指令测试

1运算测试 ○

5555->R2 ,ffff->R3

46

R3+R2->R3(5555+ffff=5554)

R3+R2+c->R3(5554+5555+1=aaaa)

R3-R2->R3(aaaa-5555=5555)

47

R3-R2-c->R3(5555-5555-0=0000); R2+1->R2(5555+1=5556);R2-1->R2(5556-1=5555)

R2左移一位,十六进制5555(0101010101010101)二进制左移一位变成十六进制aaaa

R2右移一位,aaaa(1010101010101010)右移一位,因为首位为1,视为负,右移后在首位补1,则变为d555(1101010101010101)

48

○2传送测试

5555->R1,4444->R3

把R3当作地址,把[4444]中存的数据存到R2中,在地址栏搜索可知[4444]存的数据确实是c83d

把R1当作地址,R3存的数据4444放到[R1]即[c83d]中

R3->R1(4444->R1)

49

本文来源:https://www.bwwdw.com/article/rc3a.html

Top