CPU设计与实现(8位)

软件:Quartus II

Altera公司的综合性CPLD/FPGA开发软件,原理图、VHDL、VerilogHDL以及AHDL(Altera Hardware 支持Description Language)等多种设计输入形式,内嵌自有的综合器以及仿真器,可以完成从设计输入到硬件配置的完整PLD设计流程。

语言: VHDL(Very-High-Speed Integrated Circuit Hardware Description Language 超高速集成电路硬件描述语言)

一种用于电路设计的高级语言。出现在在80年代的后期,最初是由美国国防部开发出来供美军用来提高设计的可靠性和缩减开发周期的一种使用范围较小的设计语言 。VHDL主要用于描述数字系统的结构,行为,功能和接口。除了含有许多具有硬件特征的语句外,VHDL的语言形式、描述风格以及语法是十分类似于一般的计算机高级语言

CPU整体结构

整个系统可划分为控制器寄存器ALU通用寄存器组数据选择器相关时序部件组合逻辑部件等。

整个CPU系统以控制器为中心,负责指令的译码及发出各种相关控制信号。节拍发生器控制着整个系统的时钟信号,系统的相关部件在统一的节拍控制下发挥自己的作用。IR为指令寄存器,负责存储即将执行的下一条指令,AR为地址寄存器,存放被访问存储单元的地址。PC为程序计数器,存放现行指令的地址,具有计数功能。ALU负责处理相关数据运算操作。寄存器组负责存放相关操作数和中间临时变量。多路数据选择器在相关控制信号的作用下将相关数据输入ALU处理。

CPU设计与实现(8位)_第1张图片

指令系统设计

1. 指令格式分类

此处先列举指令,稍后的表格中有功能说明

①单字单操作数指令:DEC,SHL,JR,JRC,JRNZ

②单字双操作数指令:ADD,AND,CMP,MVRR,ADC,LDRR,STRR,LDRR,STRR

③单字无操作数指令:CLC,STC

④双字单操作数指令:JMPA

⑤双字双操作数指令:MVRD

2. 指令的分组及节拍

指令的基本执行周期为: 读取指令 -->分析指令–> 执行指令

根据指令的执行周期,将16条指令分为A、B类

  1. 完成通用寄存器之间的数据运算或传送

  2. 完成一次内存读写操作

在编码的时候以指令操作码的最高2位来区分 A、B组指令,最高两位为”11”则为B组,否则为A组。

​ 在控制器方面我们选用了组合逻辑控制器方案。使用节拍来标记每条指令的执行步骤。由指令而定,在我们的系统种不同的执行步骤只有5个,故使用3位节拍。

CPU设计与实现(8位)_第2张图片

CPU设计与实现(8位)_第3张图片

逻辑设计

CPU模块表

CPU设计与实现(8位)_第4张图片

各指令的控制信号值

CPU设计与实现(8位)_第5张图片

组合逻辑控制器主要由4个部件组成:

  1. 程序计数器:保存指令在内存中的地址

  2. 指令寄存器,保存从内存读来的指令内容,在指令执行过程中提供指令本身的主要信息

  3. 节拍发生器,用于标记出每条指令的各执行步骤的相对次序关系

  4. 控制逻辑,它根据指令内容和指令的执行步骤及其他一些条件信号,形成并提供出计算机各部件当前时刻要用到的控制信号

1. 取指令逻辑

CPU执行指令时,把指令从存储器中取出来。

利用PC存储指令地址来给出指令地址,从存储器得到的指令再存储到IR中,再利用ALU计算出下一条指令的地址。

2. 指令译码逻辑

在得到了指令字之后,将转入指令译码阶段。

根据不同的指令给出各种控制信号。根据指令从相应的源数据寄存器中取出操作数,为下一步的指令执行做好准备。

指令译码由controller完成。

3. 指令执行逻辑

经过指令译码操作,正在处理的指令需要使用ALU执行何种操作以及由信号alu_func[2…0]确定下来。

经过bus_muxALU需要使用的操作数也已经准备好。

4. 存储器访问逻辑

在指令执行阶段之后, CPU 指令处理将进入到存储器访问阶段。

在本节设计的CPU 中,通过LDRR、STRR指令来访问存储器。读写由CONTROLLER给出的wr信号来控制,数据地址为ALU的计算结果alu_out[7…0]。

5. 结果写回逻辑

完成了指令执行阶段和存储器访问阶段后,进入到结果写回阶段。

要写入的数据为ALU的计算结果alu_out[7…0]或存储器的数据。寄存器的使能信号ren_en由CONTROLLER给出以控制是否执行写入操作。

各模块说明

(1) ALU

算术逻辑单元是CPU的执行单元,是所有中央处理器的核心组成部分。在计算机中,ALU是专门执行算术和逻辑运算的数字电路。组合逻辑部件,对两个16位的输入及进位输入Cin可进行由3位控制信号控制。

(2) 数据选择器BUS_MUX

组合逻辑器件,其输入包括:源寄存器数据,目标寄存器数据,带符号位扩展的偏移地址,PC,以及从内存读取的立即数、跳转地址等数据。在3位控制信号的控制下它进行ALU 模块A、B端输入的选择

(3) 器件T1

组合逻辑器件,用于产生ALU的进位输入Cin,受两位控制信号SCI的选择控制,输入为标志寄存的输出FLAG_C

(4) 标志寄存器FLAG_REG

时序逻辑部件,带有清零端RESET,输出只在时钟正跳变时发生变化;接收ALU的标志位输出,在控制信号SST的控制下输出实际需要的标志位

(5) T2

组合逻辑器件,将8位的OFFSET(来自指令的低8位)带符号位扩展到16位

(6) 程序计数器PC

时序逻辑器件,16位寄存器,在控制信号pc_en的控制下可接收ALU的运算结果(高电平接收,否则保持不变)。输出送往地址寄存器(读取指令内容)以及数据选择器(进行自增运算)。

(7) 地址寄存器AR和指令寄存器IR

都是16位的寄存器,地址寄存器用于存放要读写的内存地址单元的地址,输出送往地址总线,输入可能为PC内容,也可能为ALU的输出(对读写内存指令);指令寄存器存放当前执行指令的内容,它的输入来自从内存读取的指令和数据,输出送往控制逻辑。

(8) 寄存器、寄存器组和寄存器的选择

本实验中的寄存器都为16位,带有清零端和使能端,实际上在写VHDL程序时,通用寄存器以及AR、IR、PC使用的都是同一个模板。按照我们的设计,通用寄存器共有16个,由指令的低8位的全部或其中的高4位或低4位来从寄存器组中选择源寄存器和目的寄存器。安排寄存器选择器件reg_mux,为组合逻辑器件,用于输出选定寄存器的内容。另外,由控制逻辑给出1位控制信号reg_en,控制是否对选中寄存器进行写操作,也须由寄存器选择器件给出对特定寄存器的写使能信号。

(9) 节拍发生器TIMER

时序逻辑器件,作用是用多位触发器的输出信号的不同组合状态,来标识每条指令的执行步骤。其功能相当于一个状态机。前文已述,我们设计的节拍发生器共有3位触发器。在编码方面,遵循了这样的原则:从一个状态变到下一个状态时,状态发生变化的触发器数目应尽量少。

(10) 控制逻辑

组合逻辑器件,根据指令内容(由IR提供)和指令的执行步骤(由节拍发生器提供)及其他一些条件信号(标志寄存器输出),形成并提供出计算机各部件当前时刻要用到的控制信号。根据前面所总结的全部控制信号的意义、作用和数值,可以比较容易地写出控制逻辑部件。

(11) T3

组合逻辑器件,作用相当于一个双向门,是为了解决数据总线的冲突问题设置的。控制信号就是控制逻辑输出的读写控制信号wr,进行读操作时输出高阻态,写操作时输出ALU的运算结果。

(12) REG_OUT

对外输出寄存器内容的译码电路,组合逻辑器件,根据外部输入的寄存器选择信号输出制定的寄存器内容(包括为了便于观察引出的内部信号寄存器)。

连通模块

CPU设计与实现(8位)_第6张图片

测试

CPU设计与实现(8位)_第7张图片

CPU设计与实现(8位)_第8张图片

CPU设计与实现(8位)_第9张图片

经软件测试后数据证明CPU运行正常且正确执行指令

源代码

(1) controller

library ieee;

use ieee.std_logic_1164.all;



entity controller is

port(timer:          in std_logic_vector(2 downto 0);

  instruction:       in std_logic_vector(7 downto 0);

  c,z,v,s:         in std_logic;

  dest_reg,sour_reg:    out std_logic_vector(1 downto 0);

  offset:         out std_logic_vector(3 downto 0);

  sst,sci,rec:       out std_logic_vector(1 downto 0);

  alu_func,alu_in_sel:   out std_logic_vector(2 downto 0);

  en_reg,en_pc,wr:     out std_logic);

end controller;



architecture behave of controller is

begin

​    process(timer,instruction,c,z,v,s)

​    variable temp1,temp2 : std_logic_vector(3 downto 0) ;

​    variable temp3,temp4 : std_logic_vector(1 downto 0) ;

​    variable alu_out_sel: std_logic_vector(1 downto 0);

​    begin

​      for I in 3 downto 0 loop

​         temp1(I):=instruction(I+4);

​         temp2(I):=instruction(I);

​      end loop;

​      for I in 1 downto 0 loop

​         temp3(I):=instruction(I+2);

​         temp4(I):=instruction(I);

​      end loop;

​       case timer is

​       

​         when "100"=>

​              dest_reg<="00";

​              sour_reg<="00";

​              offset<="0000";

​              sci<="00";       --c=0

​              sst<="11";          --null

​              alu_out_sel:="00";

​              alu_in_sel<="000";  -- SR DR

​              alu_func<="000";       -- A+B+Cin

​              wr<='1';         --读

​              rec<="00";   

​              

​           when "000"=>

​              dest_reg<="00";

​              sour_reg<="00";

​              offset<="0000";

​              sci<="01";       -- c=1

​              sst<="11";       --null

​              alu_out_sel:="10";  --输入pc

​              alu_in_sel<="100";  -- 0 pc

​              alu_func<="000";      --A+B+Cin

​              wr<='1';        --读

​              rec<="01";          --输出pc

​              

​           when "001"=>

​              dest_reg<="00";   

​              sour_reg<="00";

​              offset<="0000";

​              sci<="00";       --c=0

​              sst<="11";          --null

​              alu_out_sel:="00";  

​              alu_in_sel<="000"; --SR DR

​              alu_func<="000";      --A+B+Cin

​              wr<='1';

​              rec<="10";          --读入IR

​              

​           when "011"=>

​              wr<='1';

​              rec<="00";              

​              case temp1 is

​              

​                  when "0000"=> --ADD dr sr

​                  dest_reg<=temp3;

​                  sour_reg<=temp4;

​                  offset<="0000";

​                  sci<="00";       --c=0

​                  sst<="00";          --正常

​                  alu_out_sel:="01";  --输入寄存器

​                  alu_in_sel<="000"; --sr dr

​                  alu_func<="000";      --A+B+Cin

​                  

​                  

​                  when "0001"=> --AND dr sr

​                  dest_reg<=temp3;

​                  sour_reg<=temp4;

​                  offset<="0000";

​                  sci<="00";       --c=0

​                  sst<="00";          --正常

​                  alu_out_sel:="01";  --输入寄存器

​                  alu_in_sel<="000"; --sr dr

​                  alu_func<="010";      --A与B

​                  

​                  when "0010"=> --CMP dr sr

​                  dest_reg<=temp3;

​                  sour_reg<=temp4;

​                  offset<="0000";

​                  sci<="00";       --c=0

​                  sst<="00";          --正常

​                  alu_out_sel:="00";

​                  alu_in_sel<="000"; --sr dr

​                  alu_func<="001";      --B-A-Cin

​                                   

​                  when "0011"=> --MVRR dr sr

​                  dest_reg<=temp3;

​                  sour_reg<=temp4;

​                  offset<="0000";

​                  sci<="00";       --c=0

​                  sst<="11";          --null

​                  alu_out_sel:="01";  --输入寄存器

​                  alu_in_sel<="001"; --sr 0

​                  alu_func<="000";      --A+B+Cin

​                  

​                  when "0100"=> --DEC dr

​                  dest_reg<=temp3;

​                  sour_reg<=temp4;

​                  offset<="0000";

​                  sci<="01";       --c=1

​                  sst<="00";          --正常

​                  alu_out_sel:="01";  --输入寄存器

​                  alu_in_sel<="010"; --0 dr

​                  alu_func<="001";      --B-1

​                                   

​                  when "0101"=> --SHL dr

​                  dest_reg<=temp3;

​                  sour_reg<=temp4;

​                  offset<="0000";

​                  sci<="00";       --c=0

​                  sst<="00";          --正常

​                  alu_out_sel:="01";  --输入寄存器

​                  alu_in_sel<="010"; --0 DR

​                  alu_func<="101";      --左移

​                                   

​                  when "0110"=> --ADC dr sr

​                  dest_reg<=temp3;

​                  sour_reg<=temp4;

​                  offset<="0000";

​                  sci<="10";       --c

​                  sst<="00";          --正常

​                  alu_out_sel:="01";  --输入寄存器

​                  alu_in_sel<="000"; --dr sr

​                  alu_func<="000";      --A+B+Cin

​                                   

​                  when "0111"=>    --JR addr

​                  dest_reg<="00";

​                  sour_reg<="00";

​                  offset<=temp2;    

​                  sci<="00";       --c=0

​                  sst<="11";          --null

​                  alu_out_sel:="10";  --输入pc

​                  alu_in_sel<="011"; --offset pc

​                  alu_func<="000";      --A+B+Cin

​                  

​                  when "1000"=> --JRC addr

​                  dest_reg<="00";

​                  sour_reg<="00";

​                  offset<=temp2;

​                  sci<="00";       --c=0

​                  sst<="11";          --null

​                  alu_out_sel:=c&"0"; --c=1时输入pc

​                  alu_in_sel<="011"; --offset pc

​                  alu_func<="000";      --A+B+Cin

​                                   

​                  when "1001"=> --JRNZ addr

​                  dest_reg<="00";

​                  sour_reg<="00";

​                  offset<=temp2;    

​                  sci<="00";       --c=0

​                  sst<="11";          --null

​                  alu_out_sel:=(not z)&"0"; --z=1时输入pc

​                  alu_in_sel<="011"; --offset pc

​                  alu_func<="000";      --A+B+Cin

​                                   

​                  when "1010"=> --CLC

​                  dest_reg<="00";

​                  sour_reg<="00";

​                  offset<=temp2;

​                  sci<="00";       --c=0

​                  sst<="01";          --c=0

​                  alu_out_sel:="00";

​                  alu_in_sel<="000"; --sr dr

​                  alu_func<="000";      --A+B+Cin

​                  

​                  when "1011"=> --STC

​                  dest_reg<="00";

​                  sour_reg<="00";

​                  offset<=temp2;

​                  sci<="00";       --c=0

​                  sst<="10";          --c=1

​                  alu_out_sel:="00";

​                  alu_in_sel<="000"; --sr dr

​                  alu_func<="000";      --A+B+Cin

​                  

​                  when others=>

​                  null;

​              end case;

​              

​           when "101"=>

​              alu_func<="000";      --A+B+Cin

​              wr<='1';

​              sst<="11";          --null

​              dest_reg<=temp3;

​              sour_reg<=temp4;

​              offset<="0000";

​              case temp1 is

​                  when "1100" | "1111"=>  --JMPA addr/MVRD dr,data

​                  sci<="01";       --c=1

​                  alu_out_sel:="10";  --输入pc

​                  alu_in_sel<="100"; --0 pc

​                  rec<="01";          --输出pc

​                  

​                  when "1101"=>    --LDRR dr,sr   DR<-[SR]

​                  sci<="00";       --c=0

​                  alu_out_sel:="00";

​                  alu_in_sel<="001"; --sr 0

​                  rec<="11";          --输出alu_out

​              

​                  when "1110"=> --STRR dr,sr   [DR]<-SR

​                  sci<="00";       --c=0

​                  alu_out_sel:="00";

​                  alu_in_sel<="010"; --0 dr

​                  rec<="11";          --输出alu_out

​                  

​                  when others=>

​                  null;

​              end case;

​              

​           when "111"=>

​              dest_reg<=temp3;

​              sour_reg<=temp4;

​              offset<="0000";

​              sci<="00";           --c=0

​              sst<="11";              --null

​              alu_func<="000";         --A+B+Cin

​              rec<="00";              --null

​              case temp1 is

​                  when "1101" | "1111"=>  --LDRR dr,sr   DR<-[SR]/MVRD dr,data

​                  alu_out_sel:="01";         --输入寄存器

​                  alu_in_sel<="101";        --0 DATA

​                  wr<='1';               

​                  

​                  when "1100"=>           --JMPA addr

​                  alu_out_sel:="10";         --输入pc

​                  alu_in_sel<="101";        --0 DATA

​                  wr<='1';

​                  

​                  when "1110"=>       --STRR dr,sr   [DR]<-SR

​                  alu_out_sel:="00";     

​                  alu_in_sel<="001";        --sr 0

​                  wr<='0';               --写

​                  

​                  when others=>

​                  null;

​              end case;

​              

​           when others=>

​           null;

​           

​       end case;

​       en_reg<=alu_out_sel(0);

​       en_pc<=alu_out_sel(1);

​    end process;

end behave;

(2)timer

library ieee;

use ieee.std_logic_1164.all;



entity timer is

 port(

  clk   : in std_logic;

  reset  : in std_logic;

  ins   : in std_logic_vector(7 downto 0);

  output  : out std_logic_vector(2 downto 0));

end timer;



architecture behave of timer is

​    type state_type is(s0,s1,s2,s3,s4,s5);

​    signal state:state_type;

begin

​    process(clk,reset,ins)

​    begin

​       if reset='0' then state<=s0;

​       elsif (clk'event and clk='1') then

​           case state is

​              when s0=>

​                  state<=s1;

​              when s1=>

​                  state<=s2;

​              when s2=>

​                  if ins(7)='1' and ins(6)='1' then

​                  state<=s4;

​                  else state<=s3;

​                  end if;

​              when s3=>

​                  state<=s1;

​              when s4=>

​                  state<=s5;

​              when s5=>

​                  state<=s1;

​           end case;

​    end if;

​    end process;

​    process(state)

​    begin

​       case state is

​           when s0=>

​           output<="100";

​           when s1=>

​           output<="000";

​           when s2=>

​           output<="001";

​           when s3=>

​           output<="011";

​           when s4=>

​           output<="101";

​           when s5=>

​           output<="111";

​       end case;

​    end process;

end behave;   

(3)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(cin:in std_logic;

  alu_a,alu_b:in std_logic_vector(7 downto 0);

  alu_func:in std_logic_vector(2 downto 0);

  alu_out:out std_logic_vector(7 downto 0);

  c,z,v,s:out std_logic);

end alu;



architecture behave of alu is

begin

​    process(alu_a,alu_b,cin,alu_func)

​    variable temp1,temp2,temp3 : std_logic_vector(7 downto 0) ;

​    begin

​       temp1 := "0000000"&cin;

​       case alu_func is

​           when "000"=>

​           temp2 := alu_b+alu_a+temp1;

​           when "001"=>

​           temp2 := alu_b-alu_a-temp1;

​           when "010"=>

​           temp2 := alu_a and alu_b;

​           when "011"=>

​           temp2 := alu_a or alu_b;

​           when "100"=>

​           temp2 := alu_a xor alu_b;

​           when "101"=>

​           temp2(0) := '0';

​           for I in 7 downto 1 loop

​           temp2(I) := alu_b(I-1);

​           end loop;

​           when "110"=>

​           temp2(7) := '0';

​           for I in 6 downto 0 loop

​           temp2(I) := alu_b(I+1);

​           end loop;

​           when others=>

​           temp2 := "00000000";

​       end case;

​       alu_out <= temp2;

​       if temp2 = "00000000" then z<='1';

​       else z<='0';

​       end if;

​       if temp2(7) = '1' then s<='1';

​       else s<='0';

​       end if;

​       case alu_func is

​           when "000" | "001"=>

​           if (alu_a(7)= '1' and alu_b(7)= '1' and temp2(7) = '0') or

​             (alu_a(7)= '0' and alu_b(7)= '0' and temp2(7) = '1') then

​           v<='1';

​           else v<='0';

​           end if;

​           when others=>

​           v<='0';

​       end case;

​       case alu_func is

​           when "000"=>

​           temp3 := "11111111"-alu_b-temp1;

​           if temp3

​           if alu_b

​           c <= alu_b(7);

​           when "110"=>

​           c <= alu_b(0);

​           when others=>

​           c<='0';

​       end case;

​    end process;

end behave;

(4)bus_mux

library ieee;
use ieee.std_logic_1164.all;

entity bus_mux is
   port(alu_in_sel            : in std_logic_vector(2 downto 0);
        data,pc,offset,sr,dr  : in std_logic_vector(7 downto 0);
        alu_sr,alu_dr         : out std_logic_vector(7 downto 0));
end bus_mux;

architecture behave of bus_mux is
begin
   process(alu_in_sel,data,pc,offset,sr,dr)
   begin
   	case alu_in_sel is
   	when "000"=>
   	alu_sr<=sr;
   	alu_dr<=dr;
   	when "001"=>
   	alu_sr<=sr;
   	alu_dr<="00000000";
   	when "010"=>
   	alu_sr<="00000000";
   	alu_dr<=dr;
   	when "011"=>
   	alu_sr<=offset;
   	alu_dr<=pc;
   	when "100"=>
   	alu_sr<="00000000";
   	alu_dr<=pc;
   	when "101"=>
   	alu_sr<="00000000";
   	alu_dr<=data;
   	when others=>
   	alu_sr<="00000000";
   	alu_dr<="00000000";
   	end case;
   end process;
end behave;

(5)flag_reg

library ieee;

use ieee.std_logic_1164.all;



entity flag_reg is

​    port(sst:             in std_logic_vector(1 downto 0);

​       c,z,v,s,clk,reset:      in std_logic;

​       flag_c,flag_z,flag_v,flag_s: out std_logic);

end flag_reg;



architecture behave of flag_reg is

begin

​    process(clk,reset)

​    begin

​       if reset = '0' then

​           flag_c<='0';

​           flag_z<='0';

​           flag_v<='0';

​           flag_s<='0';

​       elsif clk'event and clk = '1' then

​           case sst is

​              when "00"=>

​              flag_c<=c;

​              flag_z<=z;

​              flag_v<=v;

​              flag_s<=s;

​              when "01"=>

​              flag_c<='0';

​              when "10"=>

​              flag_c<='1';

​              when "11"=>

​              null;

​           end case;

​       end if;

​    end process;

end behave;

(6)reg

library ieee;

use ieee.std_logic_1164.all;



entity reg is

​    port(d:      in std_logic_vector(7 downto 0);

​       clk,reset,en: in std_logic;

​       q:out std_logic_vector(7 downto 0));

end reg;



architecture behave of reg is

begin

​    process(clk,reset,en)

​    begin

​       if reset = '0' then      

​     q <= "00000000";

​    elsif clk'event and clk = '1' then

​     if en = '1' then

​           q <= d;

​        end if;

​    end if;

​    end process;

end behave;

(7)reg_mux

library ieee;

use ieee.std_logic_1164.all;



entity reg_mux is

​    port(reg_0:  in std_logic_vector(7 downto 0);

​       reg_1:  in std_logic_vector(7 downto 0);

​        reg_2:  in std_logic_vector(7 downto 0);

​        reg_3:  in std_logic_vector(7 downto 0);

​        dest_reg:in std_logic_vector(1 downto 0);

​        sour_reg:in std_logic_vector(1 downto 0);

​        reg_sel: in std_logic_vector(1 downto 0);

​        en:   in std_logic;

​        en_0:  out std_logic;

​       en_1:  out std_logic;

​        en_2:  out std_logic;

​        en_3:  out std_logic;

​        dr:   out std_logic_vector(7 downto 0);

​       sr:   out std_logic_vector(7 downto 0);

​       reg_out: out std_logic_vector(7 downto 0));

end reg_mux;



architecture behave of reg_mux is

begin

​    process(dest_reg,sour_reg,reg_sel,reg_0,reg_1,

​        reg_2,reg_3,en)

​    variable temp : std_logic_vector(3 downto 0);

​    begin

​       case dest_reg is

​       when "00"=>

​           dr<=reg_0;

​           temp := "0001";

​       when "01"=>

​           dr<=reg_1;

​           temp := "0010";

​       when "10"=>

​           dr<=reg_2;

​           temp := "0100";

​       when "11"=>

​           dr<=reg_3;

​           temp := "1000";

​       end case;

​       if en = '0' then

​           temp := "0000";

​       end if;

​       en_0 <= temp(0);

​       en_1 <= temp(1);

​       en_2 <= temp(2);

​       en_3 <= temp(3);

​       case sour_reg is

​       when "00"=>

​           sr<=reg_0;

​       when "01"=>

​           sr<=reg_1;

​       when "10"=>

​           sr<=reg_2;

​       when "11"=>

​           sr<=reg_3;

​       end case;

​       case reg_sel is

​       when "00"=>

​           reg_out<=reg_0;

​       when "01"=>

​           reg_out<=reg_1;

​       when "10"=>

​           reg_out<=reg_2;

​       when "11"=>

​           reg_out<=reg_3;

​       end case;

​    end process;

end behave;

(8)t1

library ieee;

use ieee.std_logic_1164.all;



entity t1 is

​    port(flag_c:in std_logic;

​       sci:in std_logic_vector(1 downto 0);

​       alu_cin:out std_logic);

end t1;



architecture behave of t1 is

begin

​    process(sci,flag_c)

​    begin

​       case sci is

​       

​       when "00"=>

​       alu_cin<='0';

​       

​       when "01"=>

​       alu_cin<='1';

​       

​       when "10"=>

​       alu_cin<=flag_c;

​       

​       when others=>

​       alu_cin<='0';

​       

​       end case;

​    end process;

end behave;

(9)t2

library ieee;

use ieee.std_logic_1164.all;



entity t2 is

port(offset_4:in std_logic_vector(3 downto 0);

  offset_8:out std_logic_vector(7 downto 0));

end t2;



architecture behave of t2 is

begin

​    process(offset_4)

​    begin

​    if offset_4(3) = '1' then offset_8 <= "1111" & offset_4;

​    else offset_8 <= "0000" & offset_4;

​    end if;

​    end process;

end behave;

(10)t3

library ieee;

use ieee.std_logic_1164.all;



entity t3 is

port(wr     : in std_logic;

  alu_out   : in std_logic_vector(7 downto 0);

  output   : out std_logic_vector(7 downto 0));

end t3;



architecture behave of t3 is

begin

​    process(wr,alu_out)

​    begin

​       case wr is

​       when '1'=>

​           output<="ZZZZZZZZ";

​       when '0'=>

​           output<=alu_out;

​       end case;

​    end process;

end behave;

(11)ir

library ieee;

use ieee.std_logic_1164.all;



entity ir is

​    port(mem_data: in std_logic_vector(7 downto 0);

​       rec:    in std_logic_vector(1 downto 0);

​       clk,reset: in std_logic;

​       q:     out std_logic_vector(7 downto 0));

end ir;



architecture behave of ir is

begin

​    process(clk,reset)

​    begin

​       if reset = '0' then      

​     q <= "00000000";

​    elsif clk'event and clk = '1' then

​           case rec is

​              when "10"=>

​              q <= mem_data;

​              when others=>

​              null;

​           end case;    

​    end if;

​    end process;

end behave;

(12)pc

library ieee;

use ieee.std_logic_1164.all;



entity pc is

​    port(alu_out:  in std_logic_vector(7 downto 0);

​       en:    in std_logic;

​       clk,reset: in std_logic;

​       q:     out std_logic_vector(7 downto 0));

end pc;



architecture behave of pc is

begin

​    process(clk,reset)

​    begin

​       if reset = '0' then      

​           q <= "00000000";

​    elsif clk'event and clk = '1' then

​           if en = '1' then

​              q <= alu_out;

​           end if;

​    end if;

​    end process;

end behave;

(13)ar

library ieee;

use ieee.std_logic_1164.all;



entity ar is

​    port(alu_out:  in std_logic_vector(7 downto 0);

​       pc:    in std_logic_vector(7 downto 0);

​       rec:    in std_logic_vector(1 downto 0);

​       clk,reset: in std_logic;

​       q:     out std_logic_vector(7 downto 0));

end ar;



architecture behave of ar is

begin

​    process(clk,reset)

​    begin

​       if reset = '0' then      

​     q <= "00000000";

​    elsif clk'event and clk = '1' then

​           case rec is

​              when "01"=>

​              q <= pc;

​              when "11"=>

​              q <= alu_out;

​              when others=>

​               null;

​           end case;    

​    end if;

​    end process;

end behave;

你可能感兴趣的:(计算机组成原理,cpu)