天天看點

CPU設計與實作(8位)CPU整體結構指令系統設計邏輯設計連通子產品測試源代碼

文章目錄

  • CPU整體結構
  • 指令系統設計
    • 1. 指令格式分類
    • 2. 指令的分組及節拍
  • 邏輯設計
    • CPU子產品表
    • 各指令的控制信号值
      • 1. 取指令邏輯
      • 2. 指令譯碼邏輯
      • 3. 指令執行邏輯
      • 4. 存儲器通路邏輯
      • 5. 結果寫回邏輯
    • 各子產品說明
      • (1) ALU
      • (2) 資料選擇器BUS_MUX
      • (3) 器件T1
      • (4) 标志寄存器FLAG_REG
      • (5) T2
      • (6) 程式計數器PC
      • (7) 位址寄存器AR和指令寄存器IR
      • (8) 寄存器、寄存器組和寄存器的選擇
      • (9) 節拍發生器TIMER
      • (10) 控制邏輯
      • (11) T3
      • (12) REG_OUT
  • 連通子產品
  • 測試
  • 源代碼
    • (1) controller
    • (2)timer
    • (3)alu
    • (4)bus_mux
    • (5)flag_reg
    • (6)reg
    • (7)reg_mux
    • (8)t1
    • (9)t2
    • (10)t3
    • (11)ir
    • (12)pc
    • (13)ar

軟體: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位)CPU整體結構指令系統設計邏輯設計連通子產品測試源代碼

指令系統設計

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位)CPU整體結構指令系統設計邏輯設計連通子產品測試源代碼
CPU設計與實作(8位)CPU整體結構指令系統設計邏輯設計連通子產品測試源代碼

邏輯設計

CPU子產品表

CPU設計與實作(8位)CPU整體結構指令系統設計邏輯設計連通子產品測試源代碼

各指令的控制信号值

CPU設計與實作(8位)CPU整體結構指令系統設計邏輯設計連通子產品測試源代碼

組合邏輯控制器主要由4個部件組成:

  1. 程式計數器

    :儲存指令在記憶體中的位址
  2. 指令寄存器

    ,儲存從記憶體讀來的指令内容,在指令執行過程中提供指令本身的主要資訊
  3. 節拍發生器

    ,用于标記出每條指令的各執行步驟的相對次序關系
  4. 控制邏輯

    ,它根據指令内容和指令的執行步驟及其他一些條件信号,形成并提供出計算機各部件目前時刻要用到的控制信号

1. 取指令邏輯

CPU執行指令時,把指令從存儲器中取出來。

利用

PC

存儲指令位址來給出指令位址,從

存儲器

得到的指令再存儲到

IR

中,再利用

ALU

計算出下一條指令的位址。

2. 指令譯碼邏輯

在得到了指令字之後,将轉入指令譯碼階段。

根據不同的指令給出各種控制信号。根據指令從相應的源資料寄存器中取出操作數,為下一步的指令執行做好準備。

指令譯碼由controller完成。

3. 指令執行邏輯

經過指令譯碼操作,正在處理的指令需要使用

ALU

執行何種操作以及由信号alu_func[2…0]确定下來。

經過

bus_mux

ALU

需要使用的操作數也已經準備好。

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位)CPU整體結構指令系統設計邏輯設計連通子產品測試源代碼

測試

CPU設計與實作(8位)CPU整體結構指令系統設計邏輯設計連通子產品測試源代碼
CPU設計與實作(8位)CPU整體結構指令系統設計邏輯設計連通子產品測試源代碼
CPU設計與實作(8位)CPU整體結構指令系統設計邏輯設計連通子產品測試源代碼

經軟體測試後資料證明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<alu_a then

​           c<='1';

​           else c<='0';

​           end if;

​           when "001"=>

​           if alu_b<alu_a then

​           c<='1';

​           else c<='0';

​           end if;

​           when "101"=>

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

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<alu_a then

​           c<='1';

​           else c<='0';

​           end if;

​           when "001"=>

​           if alu_b<alu_a then

​           c<='1';

​           else c<='0';

​           end if;

​           when "101"=>

​           c <= alu_b(7);

​           when "110"=>

​           c <= alu_b(0);

​           when others=>

​           c<='0';

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

繼續閱讀